diff -Nru nspr-4.9.5/debian/changelog nspr-4.10.7/debian/changelog --- nspr-4.9.5/debian/changelog 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/changelog 2014-09-22 11:33:17.000000000 +0000 @@ -1,3 +1,16 @@ +nspr (4.10.7-0ubuntu0.10.04.1) lucid-security; urgency=medium + + * Update to 4.10.7 to support nss security update. + * Removed unneeded patches: + - debian/patches/30_config_64bits.patch: no longer needed + - debian/patches/99_configure.patch: no longer needed + - debian/patches/CVE-2013-5607.patch: included upstream. + - debian/patches/CVE-2014-1545.patch: included upstream. + * debian/libnspr4-0d.symbols: updated for new version. + * debian/rules: adjust paths, add --enable-64bit when appropriate. + + -- Marc Deslauriers Fri, 19 Sep 2014 08:25:13 -0400 + nspr (4.9.5-0ubuntu0.10.04.3) lucid-security; urgency=medium * SECURITY UPDATE: denial of service or arbitrary code execution via diff -Nru nspr-4.9.5/debian/libnspr4-0d.symbols nspr-4.10.7/debian/libnspr4-0d.symbols --- nspr-4.9.5/debian/libnspr4-0d.symbols 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/libnspr4-0d.symbols 2014-09-22 11:33:17.000000000 +0000 @@ -345,6 +345,7 @@ PR_SubtractFromCounter@Base 4.7.3-0ubuntu1~ PR_SuspendAll@Base 4.7.3-0ubuntu1~ PR_Sync@Base 4.7.3-0ubuntu1~ + PR_SyncMemMap@Base 4.10.3 PR_TLockFile@Base 4.7.3-0ubuntu1~ PR_ThreadScanStackPointers@Base 4.7.3-0ubuntu1~ PR_TicksPerSecond@Base 4.7.3-0ubuntu1~ @@ -460,5 +461,6 @@ PL_HashTableRawRemove@Base 4.7.3-0ubuntu1~ PL_HashTableRemove@Base 4.7.3-0ubuntu1~ PL_InitArenaPool@Base 4.7.3-0ubuntu1~ + PL_SizeOfArenaPoolExcludingPool@Base 4.9.6~ PL_NewHashTable@Base 4.7.3-0ubuntu1~ libVersionPoint@Base 4.7.3-0ubuntu1~ diff -Nru nspr-4.9.5/debian/patches/30_config_64bits.patch nspr-4.10.7/debian/patches/30_config_64bits.patch --- nspr-4.9.5/debian/patches/30_config_64bits.patch 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/patches/30_config_64bits.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ ---- - mozilla/nsprpub/configure.in | 21 ++++++++++++++++++--- - 1 file changed, 18 insertions(+), 3 deletions(-) - -Index: nspr-4.9.5/mozilla/nsprpub/configure.in -=================================================================== ---- nspr-4.9.5.orig/mozilla/nsprpub/configure.in 2012-12-19 13:21:31.000000000 -0600 -+++ nspr-4.9.5/mozilla/nsprpub/configure.in 2013-03-13 10:38:00.000000000 -0500 -@@ -22,7 +22,7 @@ - USE_USER_PTHREADS= - USE_NSPR_THREADS= - USE_N32= --USE_64= -+USE_64=maybe - USE_CPLUS= - USE_IPV6= - USE_MDUPDATE= -@@ -389,11 +389,26 @@ - fi ]) - - AC_ARG_ENABLE(64bit, -- [ --enable-64bit Enable 64-bit support (on certain platforms)], -- [ if test "$enableval" = "yes"; then -+ [ --disable-64bit Disable 64-bit support (on 64-bit platforms)], -+ [ if test "$enableval" = "no"; then -+ USE_64= -+ else - USE_64=1 - fi ]) - -+if test "${USE_64}"; then -+ AC_MSG_CHECKING(for 64-bit OS) -+ AC_TRY_COMPILE([],[int assert[(sizeof(long) == 8) ? 1: -1]], -+ result="yes", result="no") -+ AC_MSG_RESULT("$result") -+ if test "$result" = "no" && test "$USE_64" = 1; then -+ AC_MSG_ERROR([Can't --enable-64bit on non 64-bit platforms]) -+ fi -+ if test "$result" = "yes"; then -+ USE_64=1 -+ fi -+fi -+ - AC_ARG_ENABLE(mdupdate, - [ --enable-mdupdate Enable use of certain compilers' mdupdate feature], - [ if test "$enableval" = "yes"; then diff -Nru nspr-4.9.5/debian/patches/30_pkgconfig.patch nspr-4.10.7/debian/patches/30_pkgconfig.patch --- nspr-4.9.5/debian/patches/30_pkgconfig.patch 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/patches/30_pkgconfig.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ ---- - mozilla/nsprpub/config/Makefile.in | 4 ++++ - mozilla/nsprpub/config/nspr.pc.in | 10 ++++++++++ - mozilla/nsprpub/configure.in | 1 + - 3 files changed, 15 insertions(+) - -Index: nspr-4.7.2~b2/mozilla/nsprpub/config/Makefile.in -=================================================================== ---- nspr-4.7.2~b2.orig/mozilla/nsprpub/config/Makefile.in -+++ nspr-4.7.2~b2/mozilla/nsprpub/config/Makefile.in -@@ -141,8 +141,12 @@ - - $(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) - $(CC) $(XCFLAGS) $< $(LDFLAGS) $(XLDOPTS) $(OUTOPTION)$@ - - install:: nspr.m4 - $(NSINSTALL) -D $(DESTDIR)$(datadir)/aclocal - $(NSINSTALL) -t -m 0644 $< $(DESTDIR)$(datadir)/aclocal -+ -+install:: nspr.pc -+ $(NSINSTALL) -D $(DESTDIR)$(libdir)/pkgconfig -+ $(NSINSTALL) -t -m 0644 $< $(DESTDIR)$(libdir)/pkgconfig -Index: nspr-4.7.2~b2/mozilla/nsprpub/config/nspr.pc.in -=================================================================== ---- /dev/null -+++ nspr-4.7.2~b2/mozilla/nsprpub/config/nspr.pc.in -@@ -0,0 +1,10 @@ -+prefix=@prefix@ -+exec_prefix=@exec_prefix@ -+libdir=@libdir@ -+includedir=@includedir@ -+ -+Name: NSPR -+Description: The Netscape Portable Runtime -+Version: @MOD_MAJOR_VERSION@.@MOD_MINOR_VERSION@.@MOD_PATCH_VERSION@ -+Libs: -L@libdir@ -lplds@MOD_MAJOR_VERSION@ -lplc@MOD_MAJOR_VERSION@ -lnspr@MOD_MAJOR_VERSION@ @OS_LIBS@ -+Cflags: -I@includedir@ -Index: nspr-4.7.2~b2/mozilla/nsprpub/configure.in -=================================================================== ---- nspr-4.7.2~b2.orig/mozilla/nsprpub/configure.in -+++ nspr-4.7.2~b2/mozilla/nsprpub/configure.in -@@ -2809,16 +2809,17 @@ - dnl ======================================================== - MAKEFILES=" - Makefile - config/Makefile - config/autoconf.mk - config/nsprincl.mk - config/nsprincl.sh - config/nspr-config -+config/nspr.pc - lib/Makefile - lib/ds/Makefile - lib/libc/Makefile - lib/libc/include/Makefile - lib/libc/src/Makefile - lib/tests/Makefile - pkg/Makefile - pkg/linux/Makefile diff -Nru nspr-4.9.5/debian/patches/99_configure.patch nspr-4.10.7/debian/patches/99_configure.patch --- nspr-4.9.5/debian/patches/99_configure.patch 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/patches/99_configure.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,969 +0,0 @@ ---- - mozilla/nsprpub/configure | 256 +++++++++++++++++++++++++--------------------- - 1 file changed, 144 insertions(+), 112 deletions(-) - -Index: nspr-4.9.5/mozilla/nsprpub/configure -=================================================================== ---- nspr-4.9.5.orig/mozilla/nsprpub/configure 2012-12-19 13:21:31.000000000 -0600 -+++ nspr-4.9.5/mozilla/nsprpub/configure 2013-03-13 10:38:59.000000000 -0500 -@@ -55,7 +55,7 @@ - ac_help="$ac_help - --enable-n32 Enable n32 ABI support (IRIX only)" - ac_help="$ac_help -- --enable-64bit Enable 64-bit support (on certain platforms)" -+ --disable-64bit Disable 64-bit support (on 64-bit platforms)" - ac_help="$ac_help - --enable-mdupdate Enable use of certain compilers' mdupdate feature" - ac_help="$ac_help -@@ -743,7 +743,7 @@ - USE_USER_PTHREADS= - USE_NSPR_THREADS= - USE_N32= --USE_64= -+USE_64=maybe - USE_CPLUS= - USE_IPV6= - USE_MDUPDATE= -@@ -1173,12 +1173,44 @@ - # Check whether --enable-64bit or --disable-64bit was given. - if test "${enable_64bit+set}" = set; then - enableval="$enable_64bit" -- if test "$enableval" = "yes"; then -+ if test "$enableval" = "no"; then -+ USE_64= -+ else - USE_64=1 - fi - fi - - -+if test "${USE_64}"; then -+ echo $ac_n "checking for 64-bit OS""... $ac_c" 1>&6 -+echo "configure:1187: checking for 64-bit OS" >&5 -+ cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then -+ rm -rf conftest* -+ result="yes" -+else -+ echo "configure: failed program was:" >&5 -+ cat conftest.$ac_ext >&5 -+ rm -rf conftest* -+ result="no" -+fi -+rm -f conftest* -+ echo "$ac_t"""$result"" 1>&6 -+ if test "$result" = "no" && test "$USE_64" = 1; then -+ { echo "configure: error: Can't --enable-64bit on non 64-bit platforms" 1>&2; exit 1; } -+ fi -+ if test "$result" = "yes"; then -+ USE_64=1 -+ fi -+fi -+ - # Check whether --enable-mdupdate or --disable-mdupdate was given. - if test "${enable_mdupdate+set}" = set; then - enableval="$enable_mdupdate" -@@ -1312,7 +1344,7 @@ - # Extract the first word of "$WHOAMI whoami", so it can be a program name with args. - set dummy $WHOAMI whoami; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1316: checking for $ac_word" >&5 -+echo "configure:1348: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_path_WHOAMI'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1384,13 +1416,13 @@ - _SAVE_LDFLAGS="$LDFLAGS" - - echo $ac_n "checking for $host compiler""... $ac_c" 1>&6 --echo "configure:1388: checking for $host compiler" >&5 -+echo "configure:1420: checking for $host compiler" >&5 - for ac_prog in $HOST_CC gcc cc /usr/ucb/cc - do - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1394: checking for $ac_word" >&5 -+echo "configure:1426: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_HOST_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1436,16 +1468,16 @@ - LDFLAGS="$HOST_LDFLAGS" - - echo $ac_n "checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works""... $ac_c" 1>&6 --echo "configure:1440: checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works" >&5 -+echo "configure:1472: checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works" >&5 - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then -+if { (eval echo configure:1481: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_prog_host_cc_works=1 echo "$ac_t""yes" 1>&6 - else -@@ -1480,7 +1512,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1484: checking for $ac_word" >&5 -+echo "configure:1516: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1514,7 +1546,7 @@ - # Extract the first word of "gcc", so it can be a program name with args. - set dummy gcc; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1518: checking for $ac_word" >&5 -+echo "configure:1550: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1544,7 +1576,7 @@ - # Extract the first word of "cc", so it can be a program name with args. - set dummy cc; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1548: checking for $ac_word" >&5 -+echo "configure:1580: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1595,7 +1627,7 @@ - # Extract the first word of "cl", so it can be a program name with args. - set dummy cl; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1599: checking for $ac_word" >&5 -+echo "configure:1631: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1627,7 +1659,7 @@ - fi - - echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 --echo "configure:1631: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 -+echo "configure:1663: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - - ac_ext=c - # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -@@ -1638,12 +1670,12 @@ - - cat > conftest.$ac_ext << EOF - --#line 1642 "configure" -+#line 1674 "configure" - #include "confdefs.h" - - main(){return(0);} - EOF --if { (eval echo configure:1647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -+if { (eval echo configure:1679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then -@@ -1669,12 +1701,12 @@ - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } - fi - echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 --echo "configure:1673: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -+echo "configure:1705: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 - echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 - cross_compiling=$ac_cv_prog_cc_cross - - echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 --echo "configure:1678: checking whether we are using GNU C" >&5 -+echo "configure:1710: checking whether we are using GNU C" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1683,7 +1715,7 @@ - yes; - #endif - EOF --if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1687: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then -+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1719: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes - else - ac_cv_prog_gcc=no -@@ -1702,7 +1734,7 @@ - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 --echo "configure:1706: checking whether ${CC-cc} accepts -g" >&5 -+echo "configure:1738: checking whether ${CC-cc} accepts -g" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1739,7 +1771,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1743: checking for $ac_word" >&5 -+echo "configure:1775: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1775,7 +1807,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1779: checking for $ac_word" >&5 -+echo "configure:1811: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1807,7 +1839,7 @@ - - - echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 --echo "configure:1811: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 -+echo "configure:1843: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 - - ac_ext=C - # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -@@ -1818,12 +1850,12 @@ - - cat > conftest.$ac_ext << EOF - --#line 1822 "configure" -+#line 1854 "configure" - #include "confdefs.h" - - int main(){return(0);} - EOF --if { (eval echo configure:1827: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -+if { (eval echo configure:1859: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cxx_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then -@@ -1849,12 +1881,12 @@ - { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } - fi - echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 --echo "configure:1853: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 -+echo "configure:1885: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 - echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 - cross_compiling=$ac_cv_prog_cxx_cross - - echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 --echo "configure:1858: checking whether we are using GNU C++" >&5 -+echo "configure:1890: checking whether we are using GNU C++" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1863,7 +1895,7 @@ - yes; - #endif - EOF --if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1867: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then -+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1899: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gxx=yes - else - ac_cv_prog_gxx=no -@@ -1882,7 +1914,7 @@ - ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS= - echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 --echo "configure:1886: checking whether ${CXX-g++} accepts -g" >&5 -+echo "configure:1918: checking whether ${CXX-g++} accepts -g" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1927,7 +1959,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1931: checking for $ac_word" >&5 -+echo "configure:1963: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1962,7 +1994,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:1966: checking for $ac_word" >&5 -+echo "configure:1998: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -1997,7 +2029,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2001: checking for $ac_word" >&5 -+echo "configure:2033: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2032,7 +2064,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2036: checking for $ac_word" >&5 -+echo "configure:2068: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2067,7 +2099,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2071: checking for $ac_word" >&5 -+echo "configure:2103: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2102,7 +2134,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2106: checking for $ac_word" >&5 -+echo "configure:2138: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2137,7 +2169,7 @@ - # Extract the first word of "gcc", so it can be a program name with args. - set dummy gcc; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2141: checking for $ac_word" >&5 -+echo "configure:2173: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2167,7 +2199,7 @@ - # Extract the first word of "cc", so it can be a program name with args. - set dummy cc; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2171: checking for $ac_word" >&5 -+echo "configure:2203: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2218,7 +2250,7 @@ - # Extract the first word of "cl", so it can be a program name with args. - set dummy cl; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2222: checking for $ac_word" >&5 -+echo "configure:2254: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2250,7 +2282,7 @@ - fi - - echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 --echo "configure:2254: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 -+echo "configure:2286: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - - ac_ext=c - # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -@@ -2261,12 +2293,12 @@ - - cat > conftest.$ac_ext << EOF - --#line 2265 "configure" -+#line 2297 "configure" - #include "confdefs.h" - - main(){return(0);} - EOF --if { (eval echo configure:2270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -+if { (eval echo configure:2302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then -@@ -2292,12 +2324,12 @@ - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } - fi - echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 --echo "configure:2296: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -+echo "configure:2328: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 - echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 - cross_compiling=$ac_cv_prog_cc_cross - - echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 --echo "configure:2301: checking whether we are using GNU C" >&5 -+echo "configure:2333: checking whether we are using GNU C" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2306,7 +2338,7 @@ - yes; - #endif - EOF --if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2310: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then -+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2342: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes - else - ac_cv_prog_gcc=no -@@ -2325,7 +2357,7 @@ - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 --echo "configure:2329: checking whether ${CC-cc} accepts -g" >&5 -+echo "configure:2361: checking whether ${CC-cc} accepts -g" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2365,7 +2397,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2369: checking for $ac_word" >&5 -+echo "configure:2401: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2397,7 +2429,7 @@ - - - echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 --echo "configure:2401: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 -+echo "configure:2433: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 - - ac_ext=C - # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -@@ -2408,12 +2440,12 @@ - - cat > conftest.$ac_ext << EOF - --#line 2412 "configure" -+#line 2444 "configure" - #include "confdefs.h" - - int main(){return(0);} - EOF --if { (eval echo configure:2417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -+if { (eval echo configure:2449: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cxx_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then -@@ -2439,12 +2471,12 @@ - { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } - fi - echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 --echo "configure:2443: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 -+echo "configure:2475: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 - echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 - cross_compiling=$ac_cv_prog_cxx_cross - - echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 --echo "configure:2448: checking whether we are using GNU C++" >&5 -+echo "configure:2480: checking whether we are using GNU C++" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2453,7 +2485,7 @@ - yes; - #endif - EOF --if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:2457: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then -+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:2489: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gxx=yes - else - ac_cv_prog_gxx=no -@@ -2472,7 +2504,7 @@ - ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS= - echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 --echo "configure:2476: checking whether ${CXX-g++} accepts -g" >&5 -+echo "configure:2508: checking whether ${CXX-g++} accepts -g" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2506,7 +2538,7 @@ - fi - fi - echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 --echo "configure:2510: checking how to run the C preprocessor" >&5 -+echo "configure:2542: checking how to run the C preprocessor" >&5 - # On Suns, sometimes $CPP names a directory. - if test -n "$CPP" && test -d "$CPP"; then - CPP= -@@ -2521,13 +2553,13 @@ - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext < - Syntax Error - EOF - ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:2531: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -+{ (eval echo configure:2563: \"$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 - : -@@ -2538,13 +2570,13 @@ - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext < - Syntax Error - EOF - ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:2548: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -+{ (eval echo configure:2580: \"$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 - : -@@ -2555,13 +2587,13 @@ - rm -rf conftest* - CPP="${CC-cc} -nologo -E" - cat > conftest.$ac_ext < - Syntax Error - EOF - ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:2565: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -+{ (eval echo configure:2597: \"$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 - : -@@ -2588,7 +2620,7 @@ - # Extract the first word of "ranlib", so it can be a program name with args. - set dummy ranlib; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2592: checking for $ac_word" >&5 -+echo "configure:2624: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2620,7 +2652,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2624: checking for $ac_word" >&5 -+echo "configure:2656: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_path_AS'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2661,7 +2693,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2665: checking for $ac_word" >&5 -+echo "configure:2697: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2702,7 +2734,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2706: checking for $ac_word" >&5 -+echo "configure:2738: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2743,7 +2775,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2747: checking for $ac_word" >&5 -+echo "configure:2779: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_path_STRIP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2784,7 +2816,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:2788: checking for $ac_word" >&5 -+echo "configure:2820: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_path_WINDRES'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2852,7 +2884,7 @@ - fi - - echo $ac_n "checking for gcc -pipe support""... $ac_c" 1>&6 --echo "configure:2856: checking for gcc -pipe support" >&5 -+echo "configure:2888: checking for gcc -pipe support" >&5 - if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then - echo '#include ' > dummy-hello.c - echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c -@@ -2867,14 +2899,14 @@ - _SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -pipe" - cat > conftest.$ac_ext < - int main() { - printf("Hello World\n"); - ; return 0; } - EOF --if { (eval echo configure:2878: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -+if { (eval echo configure:2910: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - _res_gcc_pipe="yes" - else -@@ -2904,16 +2936,16 @@ - CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction" - - echo $ac_n "checking whether C compiler supports -fprofile-generate""... $ac_c" 1>&6 --echo "configure:2908: checking whether C compiler supports -fprofile-generate" >&5 -+echo "configure:2940: checking whether C compiler supports -fprofile-generate" >&5 - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then -+if { (eval echo configure:2949: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - PROFILE_GEN_CFLAGS="-fprofile-generate" - result="yes" -@@ -2936,7 +2968,7 @@ - - if test "$GNU_CC"; then - echo $ac_n "checking for visibility(hidden) attribute""... $ac_c" 1>&6 --echo "configure:2940: checking for visibility(hidden) attribute" >&5 -+echo "configure:2972: checking for visibility(hidden) attribute" >&5 - if eval "test \"`echo '$''{'ac_cv_visibility_hidden'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -2960,7 +2992,7 @@ - EOF - - echo $ac_n "checking for visibility pragma support""... $ac_c" 1>&6 --echo "configure:2964: checking for visibility pragma support" >&5 -+echo "configure:2996: checking for visibility pragma support" >&5 - if eval "test \"`echo '$''{'ac_cv_visibility_pragma'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -3013,7 +3045,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:3017: checking for $ac_word" >&5 -+echo "configure:3049: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -3335,14 +3367,14 @@ - _SAVE_CFLAGS="$CFLAGS" - CFLAGS="$arch_flag" - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then -+if { (eval echo configure:3378: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - MOZ_THUMB2=1 - else -@@ -3404,16 +3436,16 @@ - _SAVE_CFLAGS="$CFLAGS" - CFLAGS="$all_flags" - echo $ac_n "checking whether the chosen combination of compiler flags ($all_flags) works""... $ac_c" 1>&6 --echo "configure:3408: checking whether the chosen combination of compiler flags ($all_flags) works" >&5 -+echo "configure:3440: checking whether the chosen combination of compiler flags ($all_flags) works" >&5 - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then -+if { (eval echo configure:3449: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - echo "$ac_t""yes" 1>&6 - else -@@ -3470,17 +3502,17 @@ - DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib' - ac_safe=`echo "sys/atomic_op.h" | sed 'y%./+-%__p_%'` - echo $ac_n "checking for sys/atomic_op.h""... $ac_c" 1>&6 --echo "configure:3474: checking for sys/atomic_op.h" >&5 -+echo "configure:3506: checking for sys/atomic_op.h" >&5 - if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else - cat > conftest.$ac_ext < - EOF - ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:3484: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -+{ (eval echo configure:3516: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } - ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` - if test -z "$ac_err"; then - rm -rf conftest* -@@ -3637,7 +3669,7 @@ - _DEBUG_FLAGS='-gdwarf-2 -O0' - MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@' - echo $ac_n "checking for gethostbyaddr in -lbind""... $ac_c" 1>&6 --echo "configure:3641: checking for gethostbyaddr in -lbind" >&5 -+echo "configure:3673: checking for gethostbyaddr in -lbind" >&5 - ac_lib_var=`echo bind'_'gethostbyaddr | sed 'y%./+-%__p_%'` - if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -@@ -3645,7 +3677,7 @@ - ac_save_LIBS="$LIBS" - LIBS="-lbind $LIBS" - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -+if { (eval echo configure:3692: \"$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 -@@ -3865,17 +3897,17 @@ - fi - ac_safe=`echo "crt_externs.h" | sed 'y%./+-%__p_%'` - echo $ac_n "checking for crt_externs.h""... $ac_c" 1>&6 --echo "configure:3869: checking for crt_externs.h" >&5 -+echo "configure:3901: checking for crt_externs.h" >&5 - if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else - cat > conftest.$ac_ext < - EOF - ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:3879: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -+{ (eval echo configure:3911: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } - ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` - if test -z "$ac_err"; then - rm -rf conftest* -@@ -4919,17 +4951,17 @@ - _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000" - ac_safe=`echo "machine/builtins.h" | sed 'y%./+-%__p_%'` - echo $ac_n "checking for machine/builtins.h""... $ac_c" 1>&6 --echo "configure:4923: checking for machine/builtins.h" >&5 -+echo "configure:4955: checking for machine/builtins.h" >&5 - if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else - cat > conftest.$ac_ext < - EOF - ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:4933: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -+{ (eval echo configure:4965: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } - ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` - if test -z "$ac_err"; then - rm -rf conftest* -@@ -5488,7 +5520,7 @@ - ;; - *) - echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 --echo "configure:5492: checking for dlopen in -ldl" >&5 -+echo "configure:5524: 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 -@@ -5496,7 +5528,7 @@ - ac_save_LIBS="$LIBS" - LIBS="-ldl $LIBS" - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -+if { (eval echo configure:5543: \"$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 -@@ -5524,17 +5556,17 @@ - echo "$ac_t""yes" 1>&6 - ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'` - echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6 --echo "configure:5528: checking for dlfcn.h" >&5 -+echo "configure:5560: checking for dlfcn.h" >&5 - if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else - cat > conftest.$ac_ext < - EOF - ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5538: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -+{ (eval echo configure:5570: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } - ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` - if test -z "$ac_err"; then - rm -rf conftest* -@@ -5567,13 +5599,13 @@ - - if test $ac_cv_prog_gcc = yes; then - echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 --echo "configure:5571: checking whether ${CC-cc} needs -traditional" >&5 -+echo "configure:5603: 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 < - Autoconf TIOCGETP -@@ -5591,7 +5623,7 @@ - - if test $ac_cv_prog_gcc_traditional = no; then - cat > conftest.$ac_ext < - Autoconf TCGETA -@@ -5617,12 +5649,12 @@ - for ac_func in lchown strerror dladdr - do - echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:5621: checking for $ac_func" >&5 -+echo "configure:5653: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -+if { (eval echo configure:5681: \"$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 -@@ -5697,7 +5729,7 @@ - # Extract the first word of "$ac_prog", so it can be a program name with args. - set dummy $ac_prog; ac_word=$2 - echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:5701: checking for $ac_word" >&5 -+echo "configure:5733: checking for $ac_word" >&5 - if eval "test \"`echo '$''{'ac_cv_path_CCACHE'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -5756,7 +5788,7 @@ - if test -z "$GNU_CC"; then - - echo $ac_n "checking for +Olit support""... $ac_c" 1>&6 --echo "configure:5760: checking for +Olit support" >&5 -+echo "configure:5792: checking for +Olit support" >&5 - if eval "test \"`echo '$''{'ac_cv_hpux_usable_olit_option'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else -@@ -5798,7 +5830,7 @@ - *) - - echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6 --echo "configure:5802: checking for pthread_create in -lpthreads" >&5 -+echo "configure:5834: checking for pthread_create in -lpthreads" >&5 - echo " - #include - void *foo(void *v) { return v; } -@@ -5820,7 +5852,7 @@ - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6 --echo "configure:5824: checking for pthread_create in -lpthread" >&5 -+echo "configure:5856: checking for pthread_create in -lpthread" >&5 - echo " - #include - void *foo(void *v) { return v; } -@@ -5842,7 +5874,7 @@ - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6 --echo "configure:5846: checking for pthread_create in -lc_r" >&5 -+echo "configure:5878: checking for pthread_create in -lc_r" >&5 - echo " - #include - void *foo(void *v) { return v; } -@@ -5864,7 +5896,7 @@ - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for pthread_create in -lc""... $ac_c" 1>&6 --echo "configure:5868: checking for pthread_create in -lc" >&5 -+echo "configure:5900: checking for pthread_create in -lc" >&5 - echo " - #include - void *foo(void *v) { return v; } -@@ -5982,7 +6014,7 @@ - rm -f conftest* - ac_cv_have_dash_pthread=no - echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6 --echo "configure:5986: checking whether ${CC-cc} accepts -pthread" >&5 -+echo "configure:6018: 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 -@@ -6005,7 +6037,7 @@ - ac_cv_have_dash_pthreads=no - if test "$ac_cv_have_dash_pthread" = "no"; then - echo $ac_n "checking whether ${CC-cc} accepts -pthreads""... $ac_c" 1>&6 --echo "configure:6009: checking whether ${CC-cc} accepts -pthreads" >&5 -+echo "configure:6041: checking whether ${CC-cc} accepts -pthreads" >&5 - echo 'int main() { return 0; }' | cat > conftest.c - ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1 - if test $? -eq 0; then diff -Nru nspr-4.9.5/debian/patches/CVE-2013-5607.patch nspr-4.10.7/debian/patches/CVE-2013-5607.patch --- nspr-4.9.5/debian/patches/CVE-2013-5607.patch 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/patches/CVE-2013-5607.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -Description: fix denial of service and possible code execution via - integer overflow in PL_ArenaAllocate. -Origin: backport, https://hg.mozilla.org/projects/nspr/rev/4df6bc35be64 -Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=927687 (private) - -Index: nspr-4.9.5/mozilla/nsprpub/lib/ds/plarena.c -=================================================================== ---- nspr-4.9.5.orig/mozilla/nsprpub/lib/ds/plarena.c 2012-05-31 17:54:48.000000000 -0400 -+++ nspr-4.9.5/mozilla/nsprpub/lib/ds/plarena.c 2014-01-22 15:56:14.231639457 -0500 -@@ -196,8 +196,12 @@ - /* attempt to allocate from the heap */ - { - PRUint32 sz = PR_MAX(pool->arenasize, nb); -- sz += sizeof *a + pool->mask; /* header and alignment slop */ -- a = (PLArena*)PR_MALLOC(sz); -+ if (PR_UINT32_MAX - sz < sizeof *a + pool->mask) { -+ a = NULL; -+ } else { -+ sz += sizeof *a + pool->mask; /* header and alignment slop */ -+ a = (PLArena*)PR_MALLOC(sz); -+ } - if ( NULL != a ) { - a->limit = (PRUword)a + sz; - a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1); diff -Nru nspr-4.9.5/debian/patches/CVE-2014-1545.patch nspr-4.10.7/debian/patches/CVE-2014-1545.patch --- nspr-4.9.5/debian/patches/CVE-2014-1545.patch 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/patches/CVE-2014-1545.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -Description: fix denial of service or arbitrary code execution via sprintf -Origin: upstream, https://hg.mozilla.org/projects/nspr/rev/74eb616c618e - -Index: nspr-4.9.5/mozilla/nsprpub/pr/src/io/prprf.c -=================================================================== ---- nspr-4.9.5.orig/mozilla/nsprpub/pr/src/io/prprf.c 2012-05-08 18:55:12.000000000 -0400 -+++ nspr-4.9.5/mozilla/nsprpub/pr/src/io/prprf.c 2014-06-27 11:06:26.430686964 -0400 -@@ -304,7 +304,7 @@ - ** Convert a double precision floating point number into its printable - ** form. - ** --** XXX stop using sprintf to convert floating point -+** XXX stop using snprintf to convert floating point - */ - static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) - { -@@ -312,15 +312,14 @@ - char fout[300]; - int amount = fmt1 - fmt0; - -- PR_ASSERT((amount > 0) && (amount < sizeof(fin))); -- if (amount >= sizeof(fin)) { -- /* Totally bogus % command to sprintf. Just ignore it */ -+ if (amount <= 0 || amount >= sizeof(fin)) { -+ /* Totally bogus % command to snprintf. Just ignore it */ - return 0; - } - memcpy(fin, fmt0, amount); - fin[amount] = 0; - -- /* Convert floating point using the native sprintf code */ -+ /* Convert floating point using the native snprintf code */ - #ifdef DEBUG - { - const char *p = fin; -@@ -330,14 +329,11 @@ - } - } - #endif -- sprintf(fout, fin, d); -- -- /* -- ** This assert will catch overflow's of fout, when building with -- ** debugging on. At least this way we can track down the evil piece -- ** of calling code and fix it! -- */ -- PR_ASSERT(strlen(fout) < sizeof(fout)); -+ memset(fout, 0, sizeof(fout)); -+ snprintf(fout, sizeof(fout), fin, d); -+ /* Explicitly null-terminate fout because on Windows snprintf doesn't -+ * append a null-terminator if the buffer is too small. */ -+ fout[sizeof(fout) - 1] = '\0'; - - return (*ss->stuff)(ss, fout, strlen(fout)); - } -Index: nspr-4.9.5/mozilla/nsprpub/pr/tests/Makefile.in -=================================================================== ---- nspr-4.9.5.orig/mozilla/nsprpub/pr/tests/Makefile.in 2012-11-13 18:18:00.000000000 -0500 -+++ nspr-4.9.5/mozilla/nsprpub/pr/tests/Makefile.in 2014-06-27 11:06:26.430686964 -0400 -@@ -106,6 +106,7 @@ - poll_nm.c \ - poll_to.c \ - pollable.c \ -+ prfdbl.c \ - prftest.c \ - prftest1.c \ - prftest2.c \ -Index: nspr-4.9.5/mozilla/nsprpub/pr/tests/prfdbl.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ nspr-4.9.5/mozilla/nsprpub/pr/tests/prfdbl.c 2014-06-27 11:06:26.430686964 -0400 -@@ -0,0 +1,28 @@ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+/* -+ * This is a simple test of the PR_fprintf() function for doubles. -+ */ -+ -+#include "prprf.h" -+ -+int main() -+{ -+ double pi = 3.1415926; -+ double e = 2.71828; -+ double root2 = 1.414; -+ double nan = 0.0 / 0.0; -+ -+ PR_fprintf(PR_STDOUT, "pi is %f.\n", pi); -+ PR_fprintf(PR_STDOUT, "e is %f.\n", e); -+ PR_fprintf(PR_STDOUT, "The square root of 2 is %f.\n", root2); -+ PR_fprintf(PR_STDOUT, "NaN is %f.\n", nan); -+ -+ PR_fprintf(PR_STDOUT, "pi is %301f.\n", pi); -+ PR_fprintf(PR_STDOUT, "e is %65416.123f.\n", e); -+ PR_fprintf(PR_STDOUT, "e is %0000000000000000000065416.123f.\n", e); -+ PR_fprintf(PR_STDOUT, "NaN is %1024.1f.\n", nan); -+ return 0; -+} diff -Nru nspr-4.9.5/debian/patches/series nspr-4.10.7/debian/patches/series --- nspr-4.9.5/debian/patches/series 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -30_config_64bits.patch -99_configure.patch -CVE-2013-5607.patch -CVE-2014-1545.patch diff -Nru nspr-4.9.5/debian/rules nspr-4.10.7/debian/rules --- nspr-4.9.5/debian/rules 2014-09-22 11:33:17.000000000 +0000 +++ nspr-4.10.7/debian/rules 2014-09-22 11:33:17.000000000 +0000 @@ -24,19 +24,24 @@ DEBUGFLAGS := --disable-debug endif +ifeq (64,$(shell dpkg-architecture -qDEB_HOST_ARCH_BITS)) + CONFIGURE_FLAGS += --enable-64bit +endif + libnspr4_0d_EXPORTED_LIBS = \ libnspr4.so \ libplc4.so \ libplds4.so \ $(NULL) -configure: mozilla/nsprpub/config.status -mozilla/nsprpub/config.status: mozilla/nsprpub/configure +configure: nspr/config.status +nspr/config.status: nspr/configure dh_testdir CFLAGS="$(CFLAGS)" \ LDFLAGS="-Wl,--as-needed" \ - cd mozilla/nsprpub && \ - ./configure --host=$(DEB_HOST_GNU_TYPE) \ + cd nspr && \ + ./configure $(CONFIGURE_FLAGS) \ + --host=$(DEB_HOST_GNU_TYPE) \ --build=$(DEB_BUILD_GNU_TYPE) \ --enable-optimize="$(OPTCFLAGS)" \ --prefix=/usr \ @@ -48,10 +53,10 @@ if [ ! -h patches ] ; then ln -s $(CURDIR)/debian/patches ; fi build: build-stamp -build-stamp: patches $(QUILT_STAMPFN) mozilla/nsprpub/config.status +build-stamp: patches $(QUILT_STAMPFN) nspr/config.status dh_testdir - $(MAKE) -C mozilla/nsprpub + $(MAKE) -C nspr touch build-stamp @@ -60,7 +65,7 @@ dh_testdir dh_testroot - -$(MAKE) -C mozilla/nsprpub distclean + -$(MAKE) -C nspr distclean rm -f patches dh_clean build-stamp install-stamp @@ -71,7 +76,7 @@ dh_clean -k dh_installdirs - $(MAKE) -C mozilla/nsprpub install DESTDIR=$(CURDIR)/debian/tmp + $(MAKE) -C nspr install DESTDIR=$(CURDIR)/debian/tmp touch install-stamp @@ -99,9 +104,9 @@ binary: binary-arch -debian/patches/99_configure.patch: mozilla/nsprpub/configure.in - -$(MAKE) -f /usr/share/quilt/quilt.make patch - cd mozilla/nsprpub && autoconf - QUILT_PATCHES=$(QUILT_PATCH_DIR) quilt --quiltrc /dev/null refresh --diffstat -U8 --strip-trailing-whitespace +# debian/patches/99_configure.patch: mozilla/nsprpub/configure.in +# -$(MAKE) -f /usr/share/quilt/quilt.make patch +# cd mozilla/nsprpub && autoconf +# QUILT_PATCHES=$(QUILT_PATCH_DIR) quilt --quiltrc /dev/null refresh --diffstat -U8 --strip-trailing-whitespace .PHONY: configure clean build install clean-patched binary-indep binary-arch binary diff -Nru nspr-4.9.5/mozilla/nsprpub/aclocal.m4 nspr-4.10.7/mozilla/nsprpub/aclocal.m4 --- nspr-4.9.5/mozilla/nsprpub/aclocal.m4 2010-09-24 18:10:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/aclocal.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -dnl -dnl Local autoconf macros used with Mozilla. -dnl The contents of this file are under the Public Domain. -dnl - -builtin(include, build/autoconf/acwinpaths.m4) diff -Nru nspr-4.9.5/mozilla/nsprpub/admin/explode.pl nspr-4.10.7/mozilla/nsprpub/admin/explode.pl --- nspr-4.9.5/mozilla/nsprpub/admin/explode.pl 2012-03-06 13:13:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/admin/explode.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -#!/bin/perl -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# ----------------------------------------------------------------- -# -# explode.pl -- Unpack .jar files into bin, lib, include directories -# -# syntax: perl explode.pl -# -# Description: -# explode.pl unpacks the .jar files created by the NSPR build -# procedure. -# -# Suggested use: After copying the platform directories to -# /s/b/c/nspr20/. CD to /s/b/c/nspr20/ and -# run explode.pl. This will unpack the jar files into bin, lib, -# include directories. -# -# ----------------------------------------------------------------- - -@dirs = `ls -d *.OBJ*`; - -foreach $dir (@dirs) { - chop($dir); - if (-l $dir) { - print "Skipping symbolic link $dir\n"; - next; - } - print "Unzipping $dir/mdbinary.jar\n"; - system ("unzip", "-o", "$dir/mdbinary.jar", - "-d", "$dir"); - system ("rm", "-rf", "$dir/META-INF"); - mkdir "$dir/include", 0755; - print "Unzipping $dir/mdheader.jar\n"; - system ("unzip", "-o", "-aa", - "$dir/mdheader.jar", - "-d", "$dir/include"); - system ("rm", "-rf", "$dir/include/META-INF"); -} -# --- end explode.pl ---------------------------------------------- diff -Nru nspr-4.9.5/mozilla/nsprpub/admin/makeTargetDirs.sh nspr-4.10.7/mozilla/nsprpub/admin/makeTargetDirs.sh --- nspr-4.9.5/mozilla/nsprpub/admin/makeTargetDirs.sh 2012-03-06 13:13:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/admin/makeTargetDirs.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -#!/bin/sh -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# ----------------------------------------------------------------- -# makeTargetDirs.sh -- Create target directories for building NSPR -# -# syntax: makeTargetDirs.sh -# -# Description: -# makeTargetDirs.sh creates a set of directories intended for use -# with NSPR's autoconf based build system. -# -# The enumerated directories are the same as those built for NSPR -# 4.1.1. Adjust as needed. -# -# ----------------------------------------------------------------- - -mkdir AIX4.3_64_DBG.OBJ -mkdir AIX4.3_64_OPT.OBJ -mkdir AIX4.3_DBG.OBJ -mkdir AIX4.3_OPT.OBJ -mkdir HP-UXB.11.00_64_DBG.OBJ -mkdir HP-UXB.11.00_64_OPT.OBJ -mkdir HP-UXB.11.00_DBG.OBJ -mkdir HP-UXB.11.00_OPT.OBJ -mkdir IRIX6.5_n32_PTH_DBG.OBJ -mkdir IRIX6.5_n32_PTH_OPT.OBJ -mkdir Linux2.2_x86_glibc_PTH_DBG.OBJ -mkdir Linux2.2_x86_glibc_PTH_OPT.OBJ -mkdir Linux2.4_x86_glibc_PTH_DBG.OBJ -mkdir Linux2.4_x86_glibc_PTH_OPT.OBJ -mkdir OSF1V4.0D_DBG.OBJ -mkdir OSF1V4.0D_OPT.OBJ -mkdir SunOS5.6_DBG.OBJ -mkdir SunOS5.6_OPT.OBJ -mkdir SunOS5.7_64_DBG.OBJ -mkdir SunOS5.7_64_OPT.OBJ -mkdir WIN954.0_DBG.OBJ -mkdir WIN954.0_DBG.OBJD -mkdir WIN954.0_OPT.OBJ -mkdir WINNT4.0_DBG.OBJ -mkdir WINNT4.0_DBG.OBJD -mkdir WINNT4.0_OPT.OBJ -# --- end makeTargetDirs.sh --------------------------------------- diff -Nru nspr-4.9.5/mozilla/nsprpub/admin/symlinks.sh nspr-4.10.7/mozilla/nsprpub/admin/symlinks.sh --- nspr-4.9.5/mozilla/nsprpub/admin/symlinks.sh 2012-03-06 13:13:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/admin/symlinks.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -#!/bin/sh -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# ----------------------------------------------------------------- -# symlinks.sh -- create links from NSPR builds -# -# syntax: symlinks.sh -# -# Description: -# symlinks.sh creates some symbolic links for NSPR build targets -# that are not actually build, but for which there are NSPR -# binaries suitable for running on the intended target. ... got -# that? -# -# Suggested use: After copying NSPR binaries to -# /s/b/c/nspr20/ run symlinks.sh to create the links -# for all supported platforms. -# -# The symlinks in this script correspond to the NSPR 4.1.1 -# release. Adjust as necessary. -# -# ----------------------------------------------------------------- - -ln -s SunOS5.6_DBG.OBJ SunOS5.7_DBG.OBJ -ln -s SunOS5.6_OPT.OBJ SunOS5.7_OPT.OBJ - -ln -s SunOS5.6_DBG.OBJ SunOS5.8_DBG.OBJ -ln -s SunOS5.6_OPT.OBJ SunOS5.8_OPT.OBJ - -ln -s SunOS5.7_64_DBG.OBJ SunOS5.8_64_DBG.OBJ -ln -s SunOS5.7_64_OPT.OBJ SunOS5.8_64_OPT.OBJ - -ln -s OSF1V4.0D_DBG.OBJ OSF1V5.0_DBG.OBJ -ln -s OSF1V4.0D_OPT.OBJ OSF1V5.0_OPT.OBJ - -ln -s WINNT4.0_DBG.OBJ WINNT5.0_DBG.OBJ -ln -s WINNT4.0_DBG.OBJD WINNT5.0_DBG.OBJD -ln -s WINNT4.0_OPT.OBJ WINNT5.0_OPT.OBJ -# --- end symlinks.sh --------------------------------------------- - diff -Nru nspr-4.9.5/mozilla/nsprpub/build/autoconf/acwinpaths.m4 nspr-4.10.7/mozilla/nsprpub/build/autoconf/acwinpaths.m4 --- nspr-4.9.5/mozilla/nsprpub/build/autoconf/acwinpaths.m4 2012-03-06 13:13:37.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/build/autoconf/acwinpaths.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -dnl This Source Code Form is subject to the terms of the Mozilla Public -dnl License, v. 2.0. If a copy of the MPL was not distributed with this -dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. - -define(GENERATE_SUB_ABS, [ -define([AC_OUTPUT_FILES_SUB1], [ -patsubst($@, [/\*)], [/* | ?:/*)]) -]) -]) -GENERATE_SUB_ABS(defn([AC_OUTPUT_FILES])) - -define(GENERATE_SUB_NOSPLIT, [ -define([AC_OUTPUT_FILES], [ -patsubst($@, [-e "s%:% \$ac_given_srcdir/%g"], []) -]) -]) -GENERATE_SUB_NOSPLIT(defn([AC_OUTPUT_FILES_SUB1])) - -define(GENERATE_HEADER_NOSPLIT, [ -define([AC_OUTPUT_HEADER], [ -patsubst($@, [-e "s%:% \$ac_given_srcdir/%g"], []) -]) -]) -GENERATE_HEADER_NOSPLIT(defn([AC_OUTPUT_HEADER])) - -define(GENERATE_SUBDIRS_ABS, [ -define([AC_OUTPUT_SUBDIRS], [ -patsubst($@, [/\*)], [/* | ?:/*)]) -]) -]) -GENERATE_SUBDIRS_ABS(defn([AC_OUTPUT_SUBDIRS])) diff -Nru nspr-4.9.5/mozilla/nsprpub/build/autoconf/config.guess nspr-4.10.7/mozilla/nsprpub/build/autoconf/config.guess --- nspr-4.9.5/mozilla/nsprpub/build/autoconf/config.guess 2009-05-01 23:08:01.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/build/autoconf/config.guess 1970-01-01 00:00:00.000000000 +0000 @@ -1,1471 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-10-13' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; -#### MozillaHack -# Netscape's hacked uname - xx:WINNT:* | xx:WIN95:*) - echo i586-pc-msvc - exit ;; -### End MozillaHack - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff -Nru nspr-4.9.5/mozilla/nsprpub/build/autoconf/config.sub nspr-4.10.7/mozilla/nsprpub/build/autoconf/config.sub --- nspr-4.9.5/mozilla/nsprpub/build/autoconf/config.sub 2011-12-21 00:33:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/build/autoconf/config.sub 1970-01-01 00:00:00.000000000 +0000 @@ -1,1708 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -# Free Software Foundation, Inc. - -timestamp='2011-01-03' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova* | wince-winmo*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nios | nios2 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze) - basic_machine=microblaze-xilinx - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tile*) - basic_machine=tile-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -kopensolaris* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -winmo*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince-winmo*) - os=-wince-winmo - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -android*) - os=-android - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - *-android*|*-linuxandroid*) - vendor=linux- - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff -Nru nspr-4.9.5/mozilla/nsprpub/build/autoconf/install-sh nspr-4.10.7/mozilla/nsprpub/build/autoconf/install-sh --- nspr-4.9.5/mozilla/nsprpub/build/autoconf/install-sh 2012-03-06 13:13:37.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/build/autoconf/install-sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -#!/bin/sh -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -# -# install - install a program, script, or datafile -# This comes from X11R5; it is not part of GNU. -# -# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" - -instcmd="$mvprog" -chmodcmd="" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -fi - -if [ x"$dst" = x ] -then - echo "install: no destination specified" - exit 1 -fi - - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - -if [ -d $dst ] -then - dst="$dst"/`basename $src` -fi - -# Make a temp file name in the proper directory. - -dstdir=`dirname $dst` -dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - -$doit $instcmd $src $dsttmp - -# and set any options; do chmod last to preserve setuid bits - -if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi -if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi -if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi -if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi - -# Now rename the file to the real destination. - -$doit $rmcmd $dst -$doit $mvcmd $dsttmp $dst - - -exit 0 diff -Nru nspr-4.9.5/mozilla/nsprpub/build/cygwin-wrapper nspr-4.10.7/mozilla/nsprpub/build/cygwin-wrapper --- nspr-4.9.5/mozilla/nsprpub/build/cygwin-wrapper 2012-03-06 13:13:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/build/cygwin-wrapper 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -#!/bin/sh -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# -# Stupid wrapper to avoid win32 dospath/cygdrive issues -# Try not to spawn programs from within this file. If the stuff in here looks royally -# confusing, see bug: http://bugzilla.mozilla.org/show_bug.cgi?id=206643 -# and look at the older versions of this file that are easier to read, but -# do basically the same thing -# - -prog=$1 -shift -if test -z "$prog"; then - exit 0 -fi - -# If $CYGDRIVE_MOUNT was not set in configure, give $mountpoint the results of mount -p -mountpoint=$CYGDRIVE_MOUNT -if test -z "$mountpoint"; then - mountpoint=`mount -p` - if test -z "$mountpoint"; then - print "Cannot determine cygwin mount points. Exiting" - exit 1 - fi -fi - -# Delete everything but "/cygdrive" (or other mountpoint) from mount=`mount -p` -mountpoint=${mountpoint#*/} -mountpoint=/${mountpoint%%[!A-Za-z0-9_]*} -mountpoint=${mountpoint%/} - -args="" -up="" -if test "${prog}" = "-up"; then - up=1 - prog=${1} - shift -fi - -process=1 - -# Convert the mountpoint in parameters to Win32 filenames -# For instance: /cygdrive/c/foo -> c:/foo -for i in "${@}" -do - if test "${i}" = "-wrap"; then - process=1 - else - if test "${i}" = "-nowrap"; then - process= - else - if test -n "${process}"; then - if test -n "${up}"; then - pathname=${i#-I[a-zA-Z]:/} - if ! test "${pathname}" = "${i}"; then - no_i=${i#-I} - driveletter=${no_i%%:*} - i=-I${mountpoint}/${driveletter}/${pathname} - fi - else - eval 'leader=${i%%'${mountpoint}'/[a-zA-Z]/*}' - if ! test "${leader}" = "${i}"; then - eval 'pathname=${i#'${leader}${mountpoint}'/[a-zA-Z]/}' - eval 'no_mountpoint=${i#'${leader}${mountpoint}'/}' - driveletter=${no_mountpoint%%/*} - i=${leader}${driveletter}:/${pathname} - fi - fi - fi - - args="${args} ${i}" - fi - fi -done - -exec $prog $args diff -Nru nspr-4.9.5/mozilla/nsprpub/build/win32/pgomerge.py nspr-4.10.7/mozilla/nsprpub/build/win32/pgomerge.py --- nspr-4.9.5/mozilla/nsprpub/build/win32/pgomerge.py 2012-03-06 13:13:37.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/build/win32/pgomerge.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -#!/usr/bin/python -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Usage: pgomerge.py -# Gathers .pgc files from dist/bin and merges them into -# $PWD/$basename.pgd using pgomgr, then deletes them. -# No errors if any of these files don't exist. - -import sys, os, os.path, subprocess -if not sys.platform == "win32": - raise Exception("This script was only meant for Windows.") - -def MergePGOFiles(basename, pgddir, pgcdir): - """Merge pgc files produced from an instrumented binary - into the pgd file for the second pass of profile-guided optimization - with MSVC. |basename| is the name of the DLL or EXE without the - extension. |pgddir| is the path that contains .pgd - (should be the objdir it was built in). |pgcdir| is the path - containing basename!N.pgc files, which is probably dist/bin. - Calls pgomgr to merge each pgc file into the pgd, then deletes - the pgc files.""" - if not os.path.isdir(pgddir) or not os.path.isdir(pgcdir): - return - pgdfile = os.path.abspath(os.path.join(pgddir, basename + ".pgd")) - if not os.path.isfile(pgdfile): - return - for file in os.listdir(pgcdir): - if file.startswith(basename+"!") and file.endswith(".pgc"): - try: - pgcfile = os.path.normpath(os.path.join(pgcdir, file)) - subprocess.call(['pgomgr', '-merge', - pgcfile, - pgdfile]) - os.remove(pgcfile) - except OSError: - pass - -if __name__ == '__main__': - if len(sys.argv) != 3: - print >>sys.stderr, "Usage: pgomerge.py " - sys.exit(1) - MergePGOFiles(sys.argv[1], os.getcwd(), sys.argv[2]) diff -Nru nspr-4.9.5/mozilla/nsprpub/config/autoconf.mk.in nspr-4.10.7/mozilla/nsprpub/config/autoconf.mk.in --- nspr-4.9.5/mozilla/nsprpub/config/autoconf.mk.in 2012-03-06 13:13:38.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/autoconf.mk.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ -# -*- Mode: Makefile -*- -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -INCLUDED_AUTOCONF_MK = 1 -USE_AUTOCONF = 1 -@SHELL_OVERRIDE@ -MOZILLA_CLIENT = @MOZILLA_CLIENT@ - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -includedir = @includedir@ -libdir = @libdir@ -datadir = @datadir@ - -dist_prefix = @dist_prefix@ -dist_bindir = @dist_bindir@ -dist_includedir = @dist_includedir@ -dist_libdir = @dist_libdir@ - -DIST = $(dist_prefix) - -RELEASE_OBJDIR_NAME = @RELEASE_OBJDIR_NAME@ -OBJDIR_NAME = @OBJDIR_NAME@ -OBJDIR = @OBJDIR@ -# We do magic with OBJ_SUFFIX in config.mk, the following ensures we don't -# manually use it before config.mk inclusion -OBJ_SUFFIX = $(error config/config.mk needs to be included before using OBJ_SUFFIX) -_OBJ_SUFFIX = @OBJ_SUFFIX@ -LIB_SUFFIX = @LIB_SUFFIX@ -DLL_SUFFIX = @DLL_SUFFIX@ -ASM_SUFFIX = @ASM_SUFFIX@ -MOD_NAME = @NSPR_MODNAME@ - -MOD_MAJOR_VERSION = @MOD_MAJOR_VERSION@ -MOD_MINOR_VERSION = @MOD_MINOR_VERSION@ -MOD_PATCH_VERSION = @MOD_PATCH_VERSION@ - -LIBNSPR = @LIBNSPR@ -LIBPLC = @LIBPLC@ - -CROSS_COMPILE = @CROSS_COMPILE@ -MOZ_OPTIMIZE = @MOZ_OPTIMIZE@ -MOZ_DEBUG = @MOZ_DEBUG@ -MOZ_DEBUG_SYMBOLS = @MOZ_DEBUG_SYMBOLS@ - -USE_CPLUS = @USE_CPLUS@ -USE_IPV6 = @USE_IPV6@ -USE_N32 = @USE_N32@ -USE_64 = @USE_64@ -ENABLE_STRIP = @ENABLE_STRIP@ - -USE_PTHREADS = @USE_PTHREADS@ -USE_BTHREADS = @USE_BTHREADS@ -PTHREADS_USER = @USE_USER_PTHREADS@ -CLASSIC_NSPR = @USE_NSPR_THREADS@ - -AS = @AS@ -ASFLAGS = @ASFLAGS@ -CC = @CC@ -CCC = @CXX@ -NS_USE_GCC = @GNU_CC@ -GCC_USE_GNU_LD = @GCC_USE_GNU_LD@ -MSC_VER = @MSC_VER@ -AR = @AR@ -AR_FLAGS = @AR_FLAGS@ -LD = @LD@ -RANLIB = @RANLIB@ -PERL = @PERL@ -RC = @RC@ -RCFLAGS = @RCFLAGS@ -STRIP = @STRIP@ -NSINSTALL = @NSINSTALL@ -FILTER = @FILTER@ -IMPLIB = @IMPLIB@ -CYGWIN_WRAPPER = @CYGWIN_WRAPPER@ -MT = @MT@ - -OS_CPPFLAGS = @CPPFLAGS@ -OS_CFLAGS = $(OS_CPPFLAGS) @CFLAGS@ $(DSO_CFLAGS) -OS_CXXFLAGS = $(OS_CPPFLAGS) @CXXFLAGS@ $(DSO_CFLAGS) -OS_LIBS = @OS_LIBS@ -OS_LDFLAGS = @LDFLAGS@ -OS_DLLFLAGS = @OS_DLLFLAGS@ -DLLFLAGS = @DLLFLAGS@ -EXEFLAGS = @EXEFLAGS@ -OPTIMIZER = @OPTIMIZER@ - -PROFILE_GEN_CFLAGS = @PROFILE_GEN_CFLAGS@ -PROFILE_GEN_LDFLAGS = @PROFILE_GEN_LDFLAGS@ -PROFILE_USE_CFLAGS = @PROFILE_USE_CFLAGS@ -PROFILE_USE_LDFLAGS = @PROFILE_USE_LDFLAGS@ - -MKSHLIB = @MKSHLIB@ -WRAP_LDFLAGS = @WRAP_LDFLAGS@ -DSO_CFLAGS = @DSO_CFLAGS@ -DSO_LDOPTS = @DSO_LDOPTS@ - -RESOLVE_LINK_SYMBOLS = @RESOLVE_LINK_SYMBOLS@ - -HOST_CC = @HOST_CC@ -HOST_CFLAGS = @HOST_CFLAGS@ -HOST_LDFLAGS = @HOST_LDFLAGS@ - -DEFINES = @DEFINES@ @DEFS@ - -MDCPUCFG_H = @MDCPUCFG_H@ -PR_MD_CSRCS = @PR_MD_CSRCS@ -PR_MD_ASFILES = @PR_MD_ASFILES@ -PR_MD_ARCH_DIR = @PR_MD_ARCH_DIR@ -CPU_ARCH = @CPU_ARCH@ - -OS_TARGET = @OS_TARGET@ -OS_ARCH = @OS_ARCH@ -OS_RELEASE = @OS_RELEASE@ -OS_TEST = @OS_TEST@ - -NOSUCHFILE = @NOSUCHFILE@ -AIX_LINK_OPTS = @AIX_LINK_OPTS@ -MOZ_OBJFORMAT = @MOZ_OBJFORMAT@ -ULTRASPARC_LIBRARY = @ULTRASPARC_LIBRARY@ - -OBJECT_MODE = @OBJECT_MODE@ -ifdef OBJECT_MODE -export OBJECT_MODE -endif - -VISIBILITY_FLAGS = @VISIBILITY_FLAGS@ -WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCLUDES@ - -MACOSX_DEPLOYMENT_TARGET = @MACOSX_DEPLOYMENT_TARGET@ -ifdef MACOSX_DEPLOYMENT_TARGET -export MACOSX_DEPLOYMENT_TARGET -endif - -MACOS_SDK_DIR = @MACOS_SDK_DIR@ - -SYMBIAN_SDK_DIR = @SYMBIAN_SDK_DIR@ - -NEXT_ROOT = @NEXT_ROOT@ -ifdef NEXT_ROOT -export NEXT_ROOT -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/config/config.mk nspr-4.10.7/mozilla/nsprpub/config/config.mk --- nspr-4.9.5/mozilla/nsprpub/config/config.mk 2012-03-06 13:13:38.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/config.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,169 +0,0 @@ -#! gmake -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Configuration information for building in the NSPR source module - -# Define an include-at-most-once-flag -NSPR_CONFIG_MK = 1 - -# -# The variable definitions in this file are inputs to NSPR's -# build system. This file, if present, is included at the -# beginning of config.mk. -# -# For example: -# -# MOZ_OPTIMIZE=1 -# USE_PTHREADS=1 -# NS_USE_GCC= -# -ifndef topsrcdir -topsrcdir=$(MOD_DEPTH) -endif - -ifndef srcdir -srcdir=. -endif - -NFSPWD = $(MOD_DEPTH)/config/nfspwd - -CFLAGS = $(VISIBILITY_FLAGS) $(CC_ONLY_FLAGS) $(OPTIMIZER)\ - $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS) -CCCFLAGS = $(VISIBILITY_FLAGS) $(CCC_ONLY_FLAGS) $(OPTIMIZER)\ - $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS) -# For purify -NOMD_CFLAGS = $(CC_ONLY_FLAGS) $(OPTIMIZER) $(NOMD_OS_CFLAGS)\ - $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS) -NOMD_CCFLAGS = $(CCC_ONLY_FLAGS) $(OPTIMIZER) $(NOMD_OS_CFLAGS)\ - $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS) - -LDFLAGS = $(OS_LDFLAGS) - -# Enable profile-guided optimization -ifndef NO_PROFILE_GUIDED_OPTIMIZE -ifdef MOZ_PROFILE_GENERATE -CFLAGS += $(PROFILE_GEN_CFLAGS) -LDFLAGS += $(PROFILE_GEN_LDFLAGS) -DLLFLAGS += $(PROFILE_GEN_LDFLAGS) -ifeq (WINNT,$(OS_ARCH)) -AR_FLAGS += -LTCG -endif -endif # MOZ_PROFILE_GENERATE - -ifdef MOZ_PROFILE_USE -CFLAGS += $(PROFILE_USE_CFLAGS) -LDFLAGS += $(PROFILE_USE_LDFLAGS) -DLLFLAGS += $(PROFILE_USE_LDFLAGS) -ifeq (WINNT,$(OS_ARCH)) -AR_FLAGS += -LTCG -endif -endif # MOZ_PROFILE_USE -endif # NO_PROFILE_GUIDED_OPTIMIZE - -define MAKE_OBJDIR -if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi -endef - -LINK_DLL = $(LD) $(OS_DLLFLAGS) $(DLLFLAGS) - -ifeq ($(OS_ARCH),Darwin) -PWD := $(shell pwd) -endif - -ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2, $(OS_ARCH))) -INSTALL = $(NSINSTALL) -else -ifeq ($(NSDISTMODE),copy) -# copy files, but preserve source mtime -INSTALL = $(NSINSTALL) -t -else -ifeq ($(NSDISTMODE),absolute_symlink) -# install using absolute symbolic links -ifeq ($(OS_ARCH),Darwin) -INSTALL = $(NSINSTALL) -L $(PWD) -else -INSTALL = $(NSINSTALL) -L `$(NFSPWD)` -endif -else -# install using relative symbolic links -INSTALL = $(NSINSTALL) -R -endif -endif -endif # (WINNT || OS2) && !CROSS_COMPILE - -DEPENDENCIES = $(OBJDIR)/.md - -ifdef BUILD_DEBUG_GC -DEFINES += -DDEBUG_GC -endif - -GARBAGE += $(DEPENDENCIES) core $(wildcard core.[0-9]*) - -DIST_GARBAGE += Makefile - -#################################################################### -# -# The NSPR-specific configuration -# -#################################################################### - -DEFINES += -DFORCE_PR_LOG - -ifeq ($(_PR_NO_CLOCK_TIMER),1) -DEFINES += -D_PR_NO_CLOCK_TIMER -endif - -ifeq ($(USE_PTHREADS), 1) -DEFINES += -D_PR_PTHREADS -UHAVE_CVAR_BUILT_ON_SEM -endif - -ifeq ($(PTHREADS_USER), 1) -DEFINES += -DPTHREADS_USER -UHAVE_CVAR_BUILT_ON_SEM -endif - -ifeq ($(USE_IPV6),1) -DEFINES += -D_PR_INET6 -endif - -ifeq ($(MOZ_UNICODE),1) -DEFINES += -DMOZ_UNICODE -endif - -#################################################################### -# -# Configuration for the release process -# -#################################################################### - -MDIST = /m/dist -ifeq ($(OS_ARCH),WINNT) -MDIST = //helium/dist -MDIST_DOS = $(subst /,\\,$(MDIST)) -endif - -# RELEASE_DIR is ns/dist/ - -RELEASE_DIR = $(MOD_DEPTH)/dist/release/$(MOD_NAME) - -RELEASE_INCLUDE_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/include -RELEASE_BIN_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/bin -RELEASE_LIB_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/lib - -# autoconf.mk sets OBJ_SUFFIX to an error to avoid use before including -# this file -OBJ_SUFFIX := $(_OBJ_SUFFIX) - -# PGO builds with GCC build objects with instrumentation in a first pass, -# then objects optimized, without instrumentation, in a second pass. If -# we overwrite the ojects from the first pass with those from the second, -# we end up not getting instrumentation data for better optimization on -# incremental builds. As a consequence, we use a different object suffix -# for the first pass. -ifdef MOZ_PROFILE_GENERATE -ifdef NS_USE_GCC -OBJ_SUFFIX := i_o -endif -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/config/.cvsignore nspr-4.10.7/mozilla/nsprpub/config/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/config/.cvsignore 2001-07-20 00:22:11.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -nfspwd -revdepth -my_config.mk -my_overrides.mk -autoconf.mk -nsprincl.mk -nsprincl.sh -now -Makefile -nsinstall -nspr-config diff -Nru nspr-4.9.5/mozilla/nsprpub/config/gcc_hidden.h nspr-4.10.7/mozilla/nsprpub/config/gcc_hidden.h --- nspr-4.9.5/mozilla/nsprpub/config/gcc_hidden.h 2012-03-06 13:13:38.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/gcc_hidden.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Begin all files as hidden visibility */ -#pragma GCC visibility push(hidden) diff -Nru nspr-4.9.5/mozilla/nsprpub/config/libc_r.h nspr-4.10.7/mozilla/nsprpub/config/libc_r.h --- nspr-4.9.5/mozilla/nsprpub/config/libc_r.h 2012-03-06 13:13:38.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/libc_r.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* libc_r.h -- macros, defines, etc. to make using reentrant libc calls */ -/* a bit easier. This was initially done for AIX pthreads, */ -/* but should be usable for anyone... */ - -/* Most of these use locally defined space instead of static library space. */ -/* Because of this, we use the _INIT_R to declare/allocate space (stack), */ -/* and the plain routines to actually do it..._WARNING_: avoid allocating */ -/* memory wherever possible. Memory allocation is fairly expensive, at */ -/* least on AIX...use arrays instead (which allocate from the stack.) */ -/* I know the names are a bit strange, but I wanted to be fairly certain */ -/* that we didn't have any namespace corruption...in general, the inits are */ -/* R__INIT_R(), and the actual calls are R__R(). */ - -#ifndef _LIBC_R_H -#define _LIBC_R_H - -/************/ -/* strtok */ -/************/ -#define R_STRTOK_INIT_R() \ - char *r_strtok_r=NULL - -#define R_STRTOK_R(return,source,delim) \ - return=strtok_r(source,delim,&r_strtok_r) - -#define R_STRTOK_NORET_R(source,delim) \ - strtok_r(source,delim,&r_strtok_r) - -/**************/ -/* strerror */ -/**************/ -#define R_MAX_STRERROR_LEN_R 8192 /* Straight from limits.h */ - -#define R_STRERROR_INIT_R() \ - char r_strerror_r[R_MAX_STRERROR_LEN_R] - -#define R_STRERROR_R(val) \ - strerror_r(val,r_strerror_r,R_MAX_STRERROR_LEN_R) - -/*****************/ -/* time things */ -/*****************/ -#define R_ASCTIME_INIT_R() \ - char r_asctime_r[26] - -#define R_ASCTIME_R(val) \ - asctime_r(val,r_asctime_r) - -#define R_CTIME_INIT_R() \ - char r_ctime_r[26] - -#define R_CTIME_R(val) \ - ctime_r(val,r_ctime_r) - -#define R_GMTIME_INIT_R() \ - struct tm r_gmtime_r - -#define R_GMTIME_R(time) \ - gmtime_r(time,&r_gmtime_r) - -#define R_LOCALTIME_INIT_R() \ - struct tm r_localtime_r - -#define R_LOCALTIME_R(val) \ - localtime_r(val,&r_localtime_r) - -/***********/ -/* crypt */ -/***********/ -#include -#define R_CRYPT_INIT_R() \ - CRYPTD r_cryptd_r; \ - bzero(&r_cryptd_r,sizeof(CRYPTD)) - -#define R_CRYPT_R(pass,salt) \ - crypt_r(pass,salt,&r_cryptd_r) - -/**************/ -/* pw stuff */ -/**************/ -#define R_MAX_PW_LEN_R 1024 -/* The following must be after the last declaration, but */ -/* before the first bit of code... */ -#define R_GETPWNAM_INIT_R(pw_ptr) \ - struct passwd r_getpwnam_pw_r; \ - char r_getpwnam_line_r[R_MAX_PW_LEN_R]; \ - pw_ptr = &r_getpwnam_pw_r - -#define R_GETPWNAM_R(name) \ - getpwnam_r(name,&r_getpwnam_pw_r,r_getpwnam_line_r,R_MAX_PW_LEN_R) - -/*******************/ -/* gethost stuff */ -/*******************/ -#define R_GETHOSTBYADDR_INIT_R() \ - struct hostent r_gethostbyaddr_r; \ - struct hostent_data r_gethostbyaddr_data_r - -#define R_GETHOSTBYADDR_R(addr,len,type,xptr_ent) \ - bzero(&r_gethostbyaddr_r,sizeof(struct hostent)); \ - bzero(&r_gethostbyaddr_data_r,sizeof(struct hostent_data)); \ - xptr_ent = &r_gethostbyaddr_r; \ - if (gethostbyaddr_r(addr,len,type, \ - &r_gethostbyaddr_r,&r_gethostbyaddr_data_r) == -1) { \ - xptr_ent = NULL; \ - } - -#define R_GETHOSTBYNAME_INIT_R() \ - struct hostent r_gethostbyname_r; \ - struct hostent_data r_gethostbyname_data_r - -#define R_GETHOSTBYNAME_R(name,xptr_ent) \ - bzero(&r_gethostbyname_r,sizeof(struct hostent)); \ - bzero(&r_gethostbyname_data_r,sizeof(struct hostent_data)); \ - xptr_ent = &r_gethostbyname_r; \ - if (gethostbyname_r(name, \ - &r_gethostbyname_r,&r_gethostbyname_data_r) == -1) { \ - xptr_ent = NULL; \ - } - -#endif /* _LIBC_R_H */ diff -Nru nspr-4.9.5/mozilla/nsprpub/config/Makefile.in nspr-4.10.7/mozilla/nsprpub/config/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/config/Makefile.in 2012-11-13 23:17:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ -#! gmake -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -MOD_DEPTH = .. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -# Indicate that this directory builds build tools. -INTERNAL_TOOLS = 1 - -# For sanity's sake, we compile nsinstall without the wrapped system -# headers, so that we can use it to set up the wrapped system headers. -VISIBILITY_FLAGS = - -# autoconf.mk must be deleted last (from the top-level directory) -# because it is included by every makefile. -DIST_GARBAGE = nsprincl.mk nsprincl.sh nspr-config nspr.pc - -RELEASE_BINS = nspr-config - -include $(topsrcdir)/config/config.mk - -CSRCS = now.c - -# This version hasn't been ported for us; the one in mozilla/config has -ifneq ($(OS_ARCH),OS2) -CSRCS += nsinstall.c - -PLSRCS = nfspwd.pl -endif - -ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2,$(OS_ARCH))) -PROG_SUFFIX = .exe -else -PROG_SUFFIX = -endif - -# Temporary workaround to disable the generation of -# library build time because now.c uses the 'long long' -# data type that's not available on some platforms. -ifeq (,$(filter-out QNX SCOOS UNIXWARE,$(OS_ARCH))) -DEFINES += -DOMIT_LIB_BUILD_TIME -endif - -ifeq ($(OS_ARCH), IRIX) - ifeq ($(basename $(OS_RELEASE)),6) - ifndef NS_USE_GCC - ifeq ($(USE_N32),1) - XLDOPTS += -n32 -Wl,-woff,85 - else - ifeq ($(USE_64),1) - XLDOPTS += -64 - else - XLDOPTS += -32 - endif - endif - endif - endif -endif - -ifeq ($(OS_ARCH), HP-UX) - ifeq ($(USE_64),1) - XLDOPTS += +DD64 - endif -endif - -ifeq ($(OS_ARCH), OS2) -XCFLAGS = $(OS_CFLAGS) -endif - -include $(topsrcdir)/config/rules.mk - -PROGS = $(OBJDIR)/now$(PROG_SUFFIX) - -ifeq (,$(CROSS_COMPILE)$(filter-out OS2 WINNT,$(OS_ARCH))) -TARGETS = $(PROGS) -else -ifeq (,$(filter-out SYMBIAN WINCE,$(OS_ARCH))) -TARGETS = $(PROGS) -else -PROGS += $(OBJDIR)/nsinstall$(PROG_SUFFIX) -TARGETS = $(PROGS) $(PLSRCS:.pl=) -endif -endif - -OUTOPTION = -o # end of the line -ifeq (,$(filter-out WINNT WIN95 WINCE,$(OS_TARGET))) -ifndef NS_USE_GCC -OUTOPTION = -Fe -endif -endif - -# Redefine MAKE_OBJDIR for just this directory -define MAKE_OBJDIR -if test ! -d $(@D); then rm -rf $(@D); mkdir $(@D); else true; fi -endef - -export:: $(TARGETS) - rm -f $(dist_bindir)/nspr-config - -ifdef WRAP_SYSTEM_INCLUDES -export:: - if test ! -d system_wrappers; then mkdir system_wrappers; fi - $(PERL) $(srcdir)/make-system-wrappers.pl system_wrappers < $(srcdir)/system-headers - $(INSTALL) system_wrappers $(dist_includedir) -endif - -$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) - $(CC) $(XCFLAGS) $< $(LDFLAGS) $(XLDOPTS) $(OUTOPTION)$@ - -install:: nspr.m4 - $(NSINSTALL) -D $(DESTDIR)$(datadir)/aclocal - $(NSINSTALL) -t -m 0644 $< $(DESTDIR)$(datadir)/aclocal - -install:: nspr.pc - $(NSINSTALL) -D $(DESTDIR)$(libdir)/pkgconfig - $(NSINSTALL) -t -m 0644 $< $(DESTDIR)$(libdir)/pkgconfig diff -Nru nspr-4.9.5/mozilla/nsprpub/config/make-system-wrappers.pl nspr-4.10.7/mozilla/nsprpub/config/make-system-wrappers.pl --- nspr-4.9.5/mozilla/nsprpub/config/make-system-wrappers.pl 2012-03-06 13:13:38.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/make-system-wrappers.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -#!/usr/bin/perl -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -$output_dir = shift; - -while () { - chomp; - if (-e "$output_dir/$_") { - next; - } - - if (/(.*)\/[^\/*]/) { - mkdir "$output_dir/$1"; - } - - open OUT, ">$output_dir/$_"; - print OUT "#pragma GCC system_header\n"; # suppress include_next warning - print OUT "#pragma GCC visibility push(default)\n"; - print OUT "#include_next \<$_\>\n"; - print OUT "#pragma GCC visibility pop\n"; - close OUT; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/config/nfspwd.pl nspr-4.10.7/mozilla/nsprpub/config/nfspwd.pl --- nspr-4.9.5/mozilla/nsprpub/config/nfspwd.pl 2012-03-06 13:13:38.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/nfspwd.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -#! perl -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -require "fastcwd.pl"; - -$_ = &fastcwd; -if (m@^/[uh]/@o || s@^/tmp_mnt/@/@o) { - print("$_\n"); -} elsif ((($user, $rest) = m@^/usr/people/(\w+)/(.*)@o) - && readlink("/u/$user") eq "/usr/people/$user") { - print("/u/$user/$rest\n"); -} else { - chop($host = `hostname`); - print("/h/$host$_\n"); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/config/now.c nspr-4.10.7/mozilla/nsprpub/config/now.c --- nspr-4.9.5/mozilla/nsprpub/config/now.c 2012-03-06 13:13:39.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/now.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) -#include -#elif defined(_WIN32) -#include -#else -#error "Architecture not supported" -#endif - - -int main(int argc, char **argv) -{ -#if defined(OMIT_LIB_BUILD_TIME) - /* - * Some platforms don't have any 64-bit integer type - * such as 'long long'. Because we can't use NSPR's - * PR_snprintf in this program, it is difficult to - * print a static initializer for PRInt64 (a struct). - * So we print nothing. The makefiles that build the - * shared libraries will detect the empty output string - * of this program and omit the library build time - * in PRVersionDescription. - */ -#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) - long long now; - struct timeval tv; -#ifdef HAVE_SVID_GETTOD - gettimeofday(&tv); -#else - gettimeofday(&tv, NULL); -#endif - now = ((1000000LL) * tv.tv_sec) + (long long)tv.tv_usec; -#if defined(OSF1) - fprintf(stdout, "%ld", now); -#elif defined(BEOS) && defined(__POWERPC__) - fprintf(stdout, "%Ld", now); /* Metroworks on BeOS PPC */ -#else - fprintf(stdout, "%lld", now); -#endif - -#elif defined(_WIN32) - __int64 now; - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - CopyMemory(&now, &ft, sizeof(now)); - /* - * 116444736000000000 is the number of 100-nanosecond intervals - * between Jan. 1, 1601 and Jan. 1, 1970. - */ -#ifdef __GNUC__ - now = (now - 116444736000000000LL) / 10LL; - fprintf(stdout, "%lld", now); -#else - now = (now - 116444736000000000i64) / 10i64; - fprintf(stdout, "%I64d", now); -#endif - -#else -#error "Architecture not supported" -#endif - - return 0; -} /* main */ - -/* now.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/config/nsinstall.c nspr-4.10.7/mozilla/nsprpub/config/nsinstall.c --- nspr-4.9.5/mozilla/nsprpub/config/nsinstall.c 2012-11-13 23:17:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/nsinstall.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,526 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Netscape portable install command. -** -** Brendan Eich, 7/20/95 -*/ -#include /* OSF/1 requires this before grp.h, so put it first */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_REENTRANT_LIBC -#include "libc_r.h" -#endif /* USE_REENTRANT_LIBC */ - -#include "pathsub.h" - -#define HAVE_FCHMOD - -#if defined(BEOS) -#undef HAVE_FCHMOD -#endif - -/* - * Does getcwd() take NULL as the first argument and malloc - * the result buffer? - */ -#if !defined(DARWIN) -#define GETCWD_CAN_MALLOC -#endif - -#if defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) -#include -#endif - -#if defined(SCO) || defined(UNIXWARE) -#if !defined(S_ISLNK) && defined(S_IFLNK) -#define S_ISLNK(a) (((a) & S_IFMT) == S_IFLNK) -#endif -#endif - -#ifdef QNX -#define d_ino d_stat.st_ino -#endif - -static void -usage(void) -{ - fprintf(stderr, - "usage: %s [-C cwd] [-L linkprefix] [-m mode] [-o owner] [-g group]\n" - " %*s [-DdltR] file [file ...] directory\n", - program, (int)strlen(program), ""); - exit(2); -} - -static int -mkdirs(char *path, mode_t mode) -{ - char *cp; - struct stat sb; - int res; - - while (*path == '/' && path[1] == '/') - path++; - for (cp = strrchr(path, '/'); cp && cp != path && cp[-1] == '/'; cp--) - ; - if (cp && cp != path) { - *cp = '\0'; - if ((stat(path, &sb) < 0 || !S_ISDIR(sb.st_mode)) && - mkdirs(path, mode) < 0) { - return -1; - } - *cp = '/'; - } - res = mkdir(path, mode); - if ((res != 0) && (errno == EEXIST)) - return 0; - else - return res; -} - -static uid_t -touid(char *owner) -{ - struct passwd *pw; - uid_t uid; - char *cp; - - pw = getpwnam(owner); - if (pw) - return pw->pw_uid; - uid = strtol(owner, &cp, 0); - if (uid == 0 && cp == owner) - fail("cannot find uid for %s", owner); - return uid; -} - -static gid_t -togid(char *group) -{ - struct group *gr; - gid_t gid; - char *cp; - - gr = getgrnam(group); - if (gr) - return gr->gr_gid; - gid = strtol(group, &cp, 0); - if (gid == 0 && cp == group) - fail("cannot find gid for %s", group); - return gid; -} - -int -main(int argc, char **argv) -{ - int onlydir, dodir, dolink, dorelsymlink, dotimes, opt, len, lplen, tdlen, bnlen, exists, fromfd, tofd, cc, wc; - mode_t mode = 0755; - char *linkprefix, *owner, *group, *cp, *cwd, *todir, *toname, *name, *base, *linkname, *bp, buf[BUFSIZ]; - uid_t uid; - gid_t gid; - struct stat sb, tosb; - struct utimbuf utb; - - program = argv[0]; - cwd = linkname = linkprefix = owner = group = 0; - onlydir = dodir = dolink = dorelsymlink = dotimes = lplen = 0; - - while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) { - switch (opt) { - case 'C': - cwd = optarg; - break; - case 'D': - onlydir = 1; - break; - case 'd': - dodir = 1; - break; - case 'l': - dolink = 1; - break; - case 'L': - linkprefix = optarg; - lplen = strlen(linkprefix); - dolink = 1; - break; - case 'R': - dolink = dorelsymlink = 1; - break; - case 'm': - mode = strtoul(optarg, &cp, 8); - if (mode == 0 && cp == optarg) - usage(); - break; - case 'o': - owner = optarg; - break; - case 'g': - group = optarg; - break; - case 't': - dotimes = 1; - break; - default: - usage(); - } - } - - argc -= optind; - argv += optind; - if (argc < 2 - onlydir) - usage(); - - todir = argv[argc-1]; - if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) && - mkdirs(todir, 0777) < 0) { - fail("cannot make directory %s", todir); - } - if (onlydir) - return 0; - - if (!cwd) { -#ifdef GETCWD_CAN_MALLOC - cwd = getcwd(0, PATH_MAX); -#else - cwd = malloc(PATH_MAX + 1); - cwd = getcwd(cwd, PATH_MAX); -#endif - } - xchdir(todir); -#ifdef GETCWD_CAN_MALLOC - todir = getcwd(0, PATH_MAX); -#else - todir = malloc(PATH_MAX + 1); - todir = getcwd(todir, PATH_MAX); -#endif - tdlen = strlen(todir); - xchdir(cwd); - tdlen = strlen(todir); - - uid = owner ? touid(owner) : -1; - gid = group ? togid(group) : -1; - - while (--argc > 0) { - name = *argv++; - len = strlen(name); - base = xbasename(name); - bnlen = strlen(base); - toname = (char*)xmalloc(tdlen + 1 + bnlen + 1); - sprintf(toname, "%s/%s", todir, base); - exists = (lstat(toname, &tosb) == 0); - - if (dodir) { - /* -d means create a directory, always */ - if (exists && !S_ISDIR(tosb.st_mode)) { - (void) unlink(toname); - exists = 0; - } - if (!exists && mkdir(toname, mode) < 0) - fail("cannot make directory %s", toname); - if ((owner || group) && chown(toname, uid, gid) < 0) - fail("cannot change owner of %s", toname); - } else if (dolink) { - if (*name == '/') { - /* source is absolute pathname, link to it directly */ - linkname = 0; - } else { - if (linkprefix) { - /* -L implies -l and prefixes names with a $cwd arg. */ - len += lplen + 1; - linkname = (char*)xmalloc(len + 1); - sprintf(linkname, "%s/%s", linkprefix, name); - } else if (dorelsymlink) { - /* Symlink the relative path from todir to source name. */ - linkname = (char*)xmalloc(PATH_MAX); - - if (*todir == '/') { - /* todir is absolute: skip over common prefix. */ - lplen = relatepaths(todir, cwd, linkname); - strcpy(linkname + lplen, name); - } else { - /* todir is named by a relative path: reverse it. */ - reversepath(todir, name, len, linkname); - xchdir(cwd); - } - - len = strlen(linkname); - } - name = linkname; - } - - /* Check for a pre-existing symlink with identical content. */ - if (exists && - (!S_ISLNK(tosb.st_mode) || - readlink(toname, buf, sizeof buf) != len || - strncmp(buf, name, len) != 0)) { - (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); - exists = 0; - } - if (!exists && symlink(name, toname) < 0) - fail("cannot make symbolic link %s", toname); -#ifdef HAVE_LCHOWN - if ((owner || group) && lchown(toname, uid, gid) < 0) - fail("cannot change owner of %s", toname); -#endif - - if (linkname) { - free(linkname); - linkname = 0; - } - } else { - /* Copy from name to toname, which might be the same file. */ - fromfd = open(name, O_RDONLY); - if (fromfd < 0 || fstat(fromfd, &sb) < 0) - fail("cannot access %s", name); - if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0)) - (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); - tofd = open(toname, O_CREAT | O_WRONLY, 0666); - if (tofd < 0) - fail("cannot create %s", toname); - - bp = buf; - while ((cc = read(fromfd, bp, sizeof buf)) > 0) { - while ((wc = write(tofd, bp, cc)) > 0) { - if ((cc -= wc) == 0) - break; - bp += wc; - } - if (wc < 0) - fail("cannot write to %s", toname); - } - if (cc < 0) - fail("cannot read from %s", name); - - if (ftruncate(tofd, sb.st_size) < 0) - fail("cannot truncate %s", toname); - if (dotimes) { - utb.actime = sb.st_atime; - utb.modtime = sb.st_mtime; - if (utime(toname, &utb) < 0) - fail("cannot set times of %s", toname); - } -#ifdef HAVE_FCHMOD - if (fchmod(tofd, mode) < 0) -#else - if (chmod(toname, mode) < 0) -#endif - fail("cannot change mode of %s", toname); - if ((owner || group) && fchown(tofd, uid, gid) < 0) - fail("cannot change owner of %s", toname); - - /* Must check for delayed (NFS) write errors on close. */ - if (close(tofd) < 0) - fail("cannot write to %s", toname); - close(fromfd); - } - - free(toname); - } - - free(cwd); - free(todir); - return 0; -} - -/* -** Pathname subroutines. -** -** Brendan Eich, 8/29/95 -*/ - -char *program; - -void -fail(char *format, ...) -{ - int error; - va_list ap; - -#ifdef USE_REENTRANT_LIBC - R_STRERROR_INIT_R(); -#endif - - error = errno; - fprintf(stderr, "%s: ", program); - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - if (error) - -#ifdef USE_REENTRANT_LIBC - R_STRERROR_R(errno); - fprintf(stderr, ": %s", r_strerror_r); -#else - fprintf(stderr, ": %s", strerror(errno)); -#endif - - putc('\n', stderr); - exit(1); -} - -char * -getcomponent(char *path, char *name) -{ - if (*path == '\0') - return 0; - if (*path == '/') { - *name++ = '/'; - } else { - do { - *name++ = *path++; - } while (*path != '/' && *path != '\0'); - } - *name = '\0'; - while (*path == '/') - path++; - return path; -} - -#ifdef UNIXWARE_READDIR_BUFFER_TOO_SMALL -/* Sigh. The static buffer in Unixware's readdir is too small. */ -struct dirent * readdir(DIR *d) -{ - static struct dirent *buf = NULL; -#define MAX_PATH_LEN 1024 - - - if(buf == NULL) - buf = (struct dirent *) malloc(sizeof(struct dirent) + MAX_PATH_LEN) -; - return(readdir_r(d, buf)); -} -#endif - -char * -ino2name(ino_t ino, char *dir) -{ - DIR *dp; - struct dirent *ep; - char *name; - - dp = opendir(".."); - if (!dp) - fail("cannot read parent directory"); - for (;;) { - if (!(ep = readdir(dp))) - fail("cannot find current directory"); - if (ep->d_ino == ino) - break; - } - name = xstrdup(ep->d_name); - closedir(dp); - return name; -} - -void * -xmalloc(size_t size) -{ - void *p = malloc(size); - if (!p) - fail("cannot allocate %u bytes", size); - return p; -} - -char * -xstrdup(char *s) -{ - return strcpy((char*)xmalloc(strlen(s) + 1), s); -} - -char * -xbasename(char *path) -{ - char *cp; - - while ((cp = strrchr(path, '/')) && cp[1] == '\0') - *cp = '\0'; - if (!cp) return path; - return cp + 1; -} - -void -xchdir(char *dir) -{ - if (chdir(dir) < 0) - fail("cannot change directory to %s", dir); -} - -int -relatepaths(char *from, char *to, char *outpath) -{ - char *cp, *cp2; - int len; - char buf[NAME_MAX]; - - assert(*from == '/' && *to == '/'); - for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++) - if (*cp == '\0') - break; - while (cp[-1] != '/') - cp--, cp2--; - if (cp - 1 == to) { - /* closest common ancestor is /, so use full pathname */ - len = strlen(strcpy(outpath, to)); - if (outpath[len] != '/') { - outpath[len++] = '/'; - outpath[len] = '\0'; - } - } else { - len = 0; - while ((cp2 = getcomponent(cp2, buf)) != 0) { - strcpy(outpath + len, "../"); - len += 3; - } - while ((cp = getcomponent(cp, buf)) != 0) { - sprintf(outpath + len, "%s/", buf); - len += strlen(outpath + len); - } - } - return len; -} - -void -reversepath(char *inpath, char *name, int len, char *outpath) -{ - char *cp, *cp2; - char buf[NAME_MAX]; - struct stat sb; - - cp = strcpy(outpath + PATH_MAX - (len + 1), name); - cp2 = inpath; - while ((cp2 = getcomponent(cp2, buf)) != 0) { - if (strcmp(buf, ".") == 0) - continue; - if (strcmp(buf, "..") == 0) { - if (stat(".", &sb) < 0) - fail("cannot stat current directory"); - name = ino2name(sb.st_ino, ".."); - len = strlen(name); - cp -= len + 1; - strcpy(cp, name); - cp[len] = '/'; - free(name); - xchdir(".."); - } else { - cp -= 3; - strncpy(cp, "../", 3); - xchdir(buf); - } - } - strcpy(outpath, cp); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/config/nspr-config.in nspr-4.10.7/mozilla/nsprpub/config/nspr-config.in --- nspr-4.9.5/mozilla/nsprpub/config/nspr-config.in 2012-03-06 13:13:39.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/nspr-config.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -#!/bin/sh -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -prefix=@prefix@ - -major_version=@MOD_MAJOR_VERSION@ -minor_version=@MOD_MINOR_VERSION@ -patch_version=@MOD_PATCH_VERSION@ - -usage() -{ - cat <&2 -fi - -lib_nspr=yes -lib_plc=yes -lib_plds=yes - -while test $# -gt 0; do - case "$1" in - -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - case $1 in - --prefix=*) - prefix=$optarg - ;; - --prefix) - echo_prefix=yes - ;; - --exec-prefix=*) - exec_prefix=$optarg - ;; - --exec-prefix) - echo_exec_prefix=yes - ;; - --includedir=*) - includedir=$optarg - ;; - --includedir) - echo_includedir=yes - ;; - --libdir=*) - libdir=$optarg - ;; - --libdir) - echo_libdir=yes - ;; - --version) - echo ${major_version}.${minor_version}.${patch_version} - ;; - --cflags) - echo_cflags=yes - ;; - --libs) - echo_libs=yes - ;; - nspr) - lib_nspr=yes - ;; - plc) - lib_plc=yes - ;; - plds) - lib_plds=yes - ;; - *) - usage 1 1>&2 - ;; - esac - shift -done - -# Set variables that may be dependent upon other variables -if test -z "$exec_prefix"; then - exec_prefix=@exec_prefix@ -fi -if test -z "$includedir"; then - includedir=@includedir@ -fi -if test -z "$libdir"; then - libdir=@libdir@ -fi - -if test "$echo_prefix" = "yes"; then - echo $prefix -fi - -if test "$echo_exec_prefix" = "yes"; then - echo $exec_prefix -fi - -if test "$echo_includedir" = "yes"; then - echo $includedir -fi - -if test "$echo_libdir" = "yes"; then - echo $libdir -fi - -if test "$echo_cflags" = "yes"; then - echo -I$includedir -fi - -if test "$echo_libs" = "yes"; then - libdirs=-L$libdir - if test -n "$lib_plds"; then - libdirs="$libdirs -lplds${major_version}" - fi - if test -n "$lib_plc"; then - libdirs="$libdirs -lplc${major_version}" - fi - if test -n "$lib_nspr"; then - libdirs="$libdirs -lnspr${major_version}" - fi - os_ldflags="@LDFLAGS@" - for i in $os_ldflags ; do - if echo $i | grep \^-L >/dev/null; then - libdirs="$libdirs $i" - fi - done - echo $libdirs @OS_LIBS@ -fi - diff -Nru nspr-4.9.5/mozilla/nsprpub/config/nsprincl.mk.in nspr-4.10.7/mozilla/nsprpub/config/nsprincl.mk.in --- nspr-4.9.5/mozilla/nsprpub/config/nsprincl.mk.in 2012-03-06 13:13:39.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/nsprincl.mk.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Include in Makefiles to define NSPR variables - -NSPR_VERSION = @NSPR_VERSION@ -NSPR_LIB = -lnspr@NSPR_VERSION@ -NSPR_EXTRA_LIBS = @EXTRA_LIBS@ diff -Nru nspr-4.9.5/mozilla/nsprpub/config/nsprincl.sh.in nspr-4.10.7/mozilla/nsprpub/config/nsprincl.sh.in --- nspr-4.9.5/mozilla/nsprpub/config/nsprincl.sh.in 2012-03-06 13:13:39.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/nsprincl.sh.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Include in shell scripts to define NSPR variables - -NSPR_VERSION=@NSPR_VERSION@ -NSPR_LIB=-lnspr$NSPR_VERSION -NSPR_EXTRA_LIBS="@EXTRA_LIBS@" diff -Nru nspr-4.9.5/mozilla/nsprpub/config/nspr.m4 nspr-4.10.7/mozilla/nsprpub/config/nspr.m4 --- nspr-4.9.5/mozilla/nsprpub/config/nspr.m4 2007-12-11 18:39:39.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/nspr.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -# -*- tab-width: 4; -*- -# Configure paths for NSPR -# Public domain - Chris Seawood 2001-04-05 -# Based upon gtk.m4 (also PD) by Owen Taylor - -dnl AM_PATH_NSPR([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for NSPR, and define NSPR_CFLAGS and NSPR_LIBS -AC_DEFUN([AM_PATH_NSPR], -[dnl - -AC_ARG_WITH(nspr-prefix, - [ --with-nspr-prefix=PFX Prefix where NSPR is installed], - nspr_config_prefix="$withval", - nspr_config_prefix="") - -AC_ARG_WITH(nspr-exec-prefix, - [ --with-nspr-exec-prefix=PFX - Exec prefix where NSPR is installed], - nspr_config_exec_prefix="$withval", - nspr_config_exec_prefix="") - - if test -n "$nspr_config_exec_prefix"; then - nspr_config_args="$nspr_config_args --exec-prefix=$nspr_config_exec_prefix" - if test -z "$NSPR_CONFIG"; then - NSPR_CONFIG=$nspr_config_exec_prefix/bin/nspr-config - fi - fi - if test -n "$nspr_config_prefix"; then - nspr_config_args="$nspr_config_args --prefix=$nspr_config_prefix" - if test -z "$NSPR_CONFIG"; then - NSPR_CONFIG=$nspr_config_prefix/bin/nspr-config - fi - fi - - unset ac_cv_path_NSPR_CONFIG - AC_PATH_PROG(NSPR_CONFIG, nspr-config, no) - min_nspr_version=ifelse([$1], ,4.0.0,$1) - AC_MSG_CHECKING(for NSPR - version >= $min_nspr_version) - - no_nspr="" - if test "$NSPR_CONFIG" = "no"; then - no_nspr="yes" - else - NSPR_CFLAGS=`$NSPR_CONFIG $nspr_config_args --cflags` - NSPR_LIBS=`$NSPR_CONFIG $nspr_config_args --libs` - - nspr_config_major_version=`$NSPR_CONFIG $nspr_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - nspr_config_minor_version=`$NSPR_CONFIG $nspr_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - nspr_config_micro_version=`$NSPR_CONFIG $nspr_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - min_nspr_major_version=`echo $min_nspr_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - min_nspr_minor_version=`echo $min_nspr_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - min_nspr_micro_version=`echo $min_nspr_version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "$nspr_config_major_version" -ne "$min_nspr_major_version"; then - no_nspr="yes" - elif test "$nspr_config_major_version" -eq "$min_nspr_major_version" && - test "$nspr_config_minor_version" -lt "$min_nspr_minor_version"; then - no_nspr="yes" - elif test "$nspr_config_major_version" -eq "$min_nspr_major_version" && - test "$nspr_config_minor_version" -eq "$min_nspr_minor_version" && - test "$nspr_config_micro_version" -lt "$min_nspr_micro_version"; then - no_nspr="yes" - fi - fi - - if test -z "$no_nspr"; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - fi - - - AC_SUBST(NSPR_CFLAGS) - AC_SUBST(NSPR_LIBS) - -]) diff -Nru nspr-4.9.5/mozilla/nsprpub/config/nspr.pc.in nspr-4.10.7/mozilla/nsprpub/config/nspr.pc.in --- nspr-4.9.5/mozilla/nsprpub/config/nspr.pc.in 2012-05-18 22:26:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/nspr.pc.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: NSPR -Description: The Netscape Portable Runtime -Version: @MOD_MAJOR_VERSION@.@MOD_MINOR_VERSION@.@MOD_PATCH_VERSION@ -Libs: -L@libdir@ -lplds@MOD_MAJOR_VERSION@ -lplc@MOD_MAJOR_VERSION@ -lnspr@MOD_MAJOR_VERSION@ -Cflags: -I@includedir@ diff -Nru nspr-4.9.5/mozilla/nsprpub/config/pathsub.h nspr-4.10.7/mozilla/nsprpub/config/pathsub.h --- nspr-4.9.5/mozilla/nsprpub/config/pathsub.h 2012-10-24 22:19:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/pathsub.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef pathsub_h___ -#define pathsub_h___ -/* -** Pathname subroutines. -** -** Brendan Eich, 8/29/95 -*/ -#include -#include - -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - -/* - * Just prevent stupidity - */ -#undef NAME_MAX -#define NAME_MAX 256 - -extern char *program; - -extern void fail(char *format, ...); -extern char *getcomponent(char *path, char *name); -extern char *ino2name(ino_t ino, char *dir); -extern void *xmalloc(size_t size); -extern char *xstrdup(char *s); -extern char *xbasename(char *path); -extern void xchdir(char *dir); - -/* Relate absolute pathnames from and to returning the result in outpath. */ -extern int relatepaths(char *from, char *to, char *outpath); - -/* XXX changes current working directory -- caveat emptor */ -extern void reversepath(char *inpath, char *name, int len, char *outpath); - -#endif /* pathsub_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/config/prdepend.h nspr-4.10.7/mozilla/nsprpub/config/prdepend.h --- nspr-4.9.5/mozilla/nsprpub/config/prdepend.h 2012-12-07 21:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/prdepend.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * A dummy header file that is a dependency for all the object files. - * Used to force a full recompilation of NSPR in Mozilla's Tinderbox - * depend builds. See comments in rules.mk. - */ - -#error "Do not include this header file." - diff -Nru nspr-4.9.5/mozilla/nsprpub/config/rules.mk nspr-4.10.7/mozilla/nsprpub/config/rules.mk --- nspr-4.9.5/mozilla/nsprpub/config/rules.mk 2012-03-06 13:13:39.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/rules.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,522 +0,0 @@ -#! gmake -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -################################################################################ -# We used to have a 4 pass build process. Now we do everything in one pass. -# -# export - Create generated headers and stubs. Publish public headers to -# dist//include. -# Create libraries. Publish libraries to dist//lib. -# Create programs. -# -# libs - obsolete. Now a synonym of "export". -# -# all - the default makefile target. Now a synonym of "export". -# -# install - Install headers, libraries, and programs on the system. -# -# Parameters to this makefile (set these before including): -# -# a) -# TARGETS -- the target to create -# (defaults to $LIBRARY $PROGRAM) -# b) -# DIRS -- subdirectories for make to recurse on -# (the 'all' rule builds $TARGETS $DIRS) -# c) -# CSRCS -- .c files to compile -# (used to define $OBJS) -# d) -# PROGRAM -- the target program name to create from $OBJS -# ($OBJDIR automatically prepended to it) -# e) -# LIBRARY -- the target library name to create from $OBJS -# ($OBJDIR automatically prepended to it) -# -################################################################################ - -ifndef topsrcdir -topsrcdir=$(MOD_DEPTH) -endif - -ifndef srcdir -srcdir=. -endif - -ifndef NSPR_CONFIG_MK -include $(topsrcdir)/config/config.mk -endif - -ifdef USE_AUTOCONF -ifdef CROSS_COMPILE -ifdef INTERNAL_TOOLS -CC=$(HOST_CC) -CCC=$(HOST_CXX) -CFLAGS=$(HOST_CFLAGS) -CXXFLAGS=$(HOST_CXXFLAGS) -LDFLAGS=$(HOST_LDFLAGS) -endif -endif -endif - -# -# This makefile contains rules for building the following kinds of -# libraries: -# - LIBRARY: a static (archival) library -# - SHARED_LIBRARY: a shared (dynamic link) library -# - IMPORT_LIBRARY: an import library, used only on Windows and OS/2 -# -# The names of these libraries can be generated by simply specifying -# LIBRARY_NAME and LIBRARY_VERSION. -# - -ifdef LIBRARY_NAME -ifeq (,$(filter-out WINNT WINCE OS2,$(OS_ARCH))) - -# -# Win95 and OS/2 require library names conforming to the 8.3 rule. -# other platforms do not. -# -ifeq (,$(filter-out WIN95 WINCE WINMO OS2,$(OS_TARGET))) -LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX) -SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) -IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX) -SHARED_LIB_PDB = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).pdb -else -LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX) -SHARED_LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) -IMPORT_LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX) -SHARED_LIB_PDB = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).pdb -endif - -else - -LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX) -ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1) -SHARED_LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_shr.a -else -ifdef MKSHLIB -SHARED_LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) -endif -endif - -endif -endif - -ifndef TARGETS -ifeq (,$(filter-out WINNT WINCE OS2,$(OS_ARCH))) -TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) -ifdef MOZ_DEBUG_SYMBOLS -ifdef MSC_VER -ifneq (,$(filter-out 1100 1200,$(MSC_VER))) -TARGETS += $(SHARED_LIB_PDB) -endif -endif -endif -else -TARGETS = $(LIBRARY) $(SHARED_LIBRARY) -endif -endif - -# -# OBJS is the list of object files. It can be constructed by -# specifying CSRCS (list of C source files) and ASFILES (list -# of assembly language source files). -# - -ifndef OBJS -OBJS = $(addprefix $(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \ - $(addprefix $(OBJDIR)/,$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))) -endif - -ALL_TRASH = $(TARGETS) $(OBJS) $(RES) $(filter-out . .., $(OBJDIR)) LOGS TAGS $(GARBAGE) \ - $(NOSUCHFILE) \ - $(OBJS:.$(OBJ_SUFFIX)=.i_o) \ - so_locations - -ifndef RELEASE_LIBS_DEST -RELEASE_LIBS_DEST = $(RELEASE_LIB_DIR) -endif - -define MAKE_IN_DIR - $(MAKE) -C $(dir) $@ - -endef # do not remove the blank line! - -ifdef DIRS -LOOP_OVER_DIRS = $(foreach dir,$(DIRS),$(MAKE_IN_DIR)) -endif - -################################################################################ - -all:: export - -export:: - +$(LOOP_OVER_DIRS) - -libs:: export - -clean:: - rm -rf $(OBJS) $(RES) so_locations $(NOSUCHFILE) $(GARBAGE) - +$(LOOP_OVER_DIRS) - -clobber:: - rm -rf $(OBJS) $(RES) $(TARGETS) $(filter-out . ..,$(OBJDIR)) $(GARBAGE) so_locations $(NOSUCHFILE) - +$(LOOP_OVER_DIRS) - -realclean clobber_all:: - rm -rf $(wildcard *.OBJ *.OBJD) dist $(ALL_TRASH) - +$(LOOP_OVER_DIRS) - -distclean:: - rm -rf $(wildcard *.OBJ *.OBJD) dist $(ALL_TRASH) $(DIST_GARBAGE) - +$(LOOP_OVER_DIRS) - -install:: $(RELEASE_BINS) $(RELEASE_HEADERS) $(RELEASE_LIBS) -ifdef RELEASE_BINS - $(NSINSTALL) -t -m 0755 $(RELEASE_BINS) $(DESTDIR)$(bindir) -endif -ifdef RELEASE_HEADERS - $(NSINSTALL) -t -m 0644 $(RELEASE_HEADERS) $(DESTDIR)$(includedir)/$(include_subdir) -endif -ifdef RELEASE_LIBS - $(NSINSTALL) -t -m 0755 $(RELEASE_LIBS) $(DESTDIR)$(libdir)/$(lib_subdir) -endif - +$(LOOP_OVER_DIRS) - -release:: export -ifdef RELEASE_BINS - @echo "Copying executable programs and scripts to release directory" - @if test -z "$(BUILD_NUMBER)"; then \ - echo "BUILD_NUMBER must be defined"; \ - false; \ - else \ - true; \ - fi - @if test ! -d $(RELEASE_BIN_DIR); then \ - rm -rf $(RELEASE_BIN_DIR); \ - $(NSINSTALL) -D $(RELEASE_BIN_DIR);\ - else \ - true; \ - fi - cp $(RELEASE_BINS) $(RELEASE_BIN_DIR) -endif -ifdef RELEASE_LIBS - @echo "Copying libraries to release directory" - @if test -z "$(BUILD_NUMBER)"; then \ - echo "BUILD_NUMBER must be defined"; \ - false; \ - else \ - true; \ - fi - @if test ! -d $(RELEASE_LIBS_DEST); then \ - rm -rf $(RELEASE_LIBS_DEST); \ - $(NSINSTALL) -D $(RELEASE_LIBS_DEST);\ - else \ - true; \ - fi - cp $(RELEASE_LIBS) $(RELEASE_LIBS_DEST) -endif -ifdef RELEASE_HEADERS - @echo "Copying header files to release directory" - @if test -z "$(BUILD_NUMBER)"; then \ - echo "BUILD_NUMBER must be defined"; \ - false; \ - else \ - true; \ - fi - @if test ! -d $(RELEASE_HEADERS_DEST); then \ - rm -rf $(RELEASE_HEADERS_DEST); \ - $(NSINSTALL) -D $(RELEASE_HEADERS_DEST);\ - else \ - true; \ - fi - cp $(RELEASE_HEADERS) $(RELEASE_HEADERS_DEST) -endif - +$(LOOP_OVER_DIRS) - -alltags: - rm -f TAGS tags - find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs etags -a - find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs ctags -a - -$(NFSPWD): - cd $(@D); $(MAKE) $(@F) - -$(PROGRAM): $(OBJS) - @$(MAKE_OBJDIR) -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) -ifdef MOZ_PROFILE_USE -# In the second pass, we need to merge the pgc files into the pgd file. -# The compiler would do this for us automatically if they were in the right -# place, but they're in dist/bin. - python $(topsrcdir)/build/win32/pgomerge.py \ - $(notdir $(PROGRAM:.exe=)) $(DIST)/bin -endif # MOZ_PROFILE_USE - $(CC) $(OBJS) -Fe$@ -link $(LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) -ifdef MT - @if test -f $@.manifest; then \ - $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ - rm -f $@.manifest; \ - fi -endif # MSVC with manifest tool -ifdef MOZ_PROFILE_GENERATE -# touch it a few seconds into the future to work around FAT's -# 2-second granularity - touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink -endif # MOZ_PROFILE_GENERATE -else # WINNT && !GCC - $(CC) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS) $(WRAP_LDFLAGS) -endif # WINNT && !GCC -ifdef ENABLE_STRIP - $(STRIP) $@ -endif - -$(LIBRARY): $(OBJS) - @$(MAKE_OBJDIR) - rm -f $@ - $(AR) $(AR_FLAGS) $(OBJS) $(AR_EXTRA_ARGS) - $(RANLIB) $@ - -ifeq ($(OS_TARGET), OS2) -$(IMPORT_LIBRARY): $(MAPFILE) - rm -f $@ - $(IMPLIB) $@ $(MAPFILE) -else -ifeq (,$(filter-out WIN95 WINCE WINMO,$(OS_TARGET))) -# PDBs and import libraries need to depend on the shared library to -# order dependencies properly. -$(IMPORT_LIBRARY): $(SHARED_LIBRARY) -$(SHARED_LIB_PDB): $(SHARED_LIBRARY) -endif -endif - -$(SHARED_LIBRARY): $(OBJS) $(RES) $(MAPFILE) - @$(MAKE_OBJDIR) - rm -f $@ -ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1) - echo "#!" > $(OBJDIR)/lib$(LIBRARY_NAME)_syms - nm -B -C -g $(OBJS) \ - | awk '/ [T,D] / {print $$3}' \ - | sed -e 's/^\.//' \ - | sort -u >> $(OBJDIR)/lib$(LIBRARY_NAME)_syms - $(LD) $(XCFLAGS) -o $@ $(OBJS) -bE:$(OBJDIR)/lib$(LIBRARY_NAME)_syms \ - -bM:SRE -bnoentry $(OS_LIBS) $(EXTRA_LIBS) -else # AIX 4.1 -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) -ifdef MOZ_PROFILE_USE - python $(topsrcdir)/build/win32/pgomerge.py \ - $(notdir $(SHARED_LIBRARY:.$(DLL_SUFFIX)=)) $(DIST)/bin -endif # MOZ_PROFILE_USE - $(LINK_DLL) -MAP $(DLLBASE) $(DLL_LIBS) $(EXTRA_LIBS) $(OBJS) $(RES) -ifdef MT - @if test -f $@.manifest; then \ - $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;2; \ - rm -f $@.manifest; \ - fi -endif # MSVC with manifest tool -ifdef MOZ_PROFILE_GENERATE - touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink -endif # MOZ_PROFILE_GENERATE -else # WINNT && !GCC - $(MKSHLIB) $(OBJS) $(RES) $(LDFLAGS) $(WRAP_LDFLAGS) $(EXTRA_LIBS) -endif # WINNT && !GCC -endif # AIX 4.1 -ifdef ENABLE_STRIP - $(STRIP) $@ -endif - -################################################################################ - -ifdef MOZ_PROFILE_USE -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) -# When building with PGO, we have to make sure to re-link -# in the MOZ_PROFILE_USE phase if we linked in the -# MOZ_PROFILE_GENERATE phase. We'll touch this pgo.relink -# file in the link rule in the GENERATE phase to indicate -# that we need a relink. -$(SHARED_LIBRARY): pgo.relink - -$(PROGRAM): pgo.relink - -endif # WINNT && !GCC -endif # MOZ_PROFILE_USE - -ifneq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE)) -ifdef NS_USE_GCC -# Force rebuilding libraries and programs in both passes because each -# pass uses different object files. -$(PROGRAM) $(SHARED_LIBRARY) $(LIBRARY): FORCE -.PHONY: FORCE -endif -endif - -################################################################################ - -ifdef MOZ_PROFILE_GENERATE -# Clean up profiling data during PROFILE_GENERATE phase -export:: -ifeq ($(OS_ARCH)_$(NS_USE_GCC), WINNT_) - $(foreach pgd,$(wildcard *.pgd),pgomgr -clear $(pgd);) -else -ifdef NS_USE_GCC - -$(RM) *.gcda -endif -endif -endif - -################################################################################ - -ifeq ($(OS_ARCH),WINNT) -$(RES): $(RESNAME) - @$(MAKE_OBJDIR) -# The resource compiler does not understand the -U option. -ifdef NS_USE_GCC - $(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) -o $@ $< -else - $(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES) -Fo$@ $< -endif # GCC - @echo $(RES) finished -endif - -$(MAPFILE): $(LIBRARY_NAME).def - @$(MAKE_OBJDIR) -ifeq ($(OS_ARCH),SunOS) - grep -v ';-' $< | \ - sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ -endif -ifeq ($(OS_ARCH),OS2) - echo LIBRARY $(LIBRARY_NAME)$(LIBRARY_VERSION) INITINSTANCE TERMINSTANCE > $@ - echo PROTMODE >> $@ - echo CODE LOADONCALL MOVEABLE DISCARDABLE >> $@ - echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@ - echo EXPORTS >> $@ - grep -v ';+' $< | grep -v ';-' | \ - sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,\([\t ]*\),\1_,' | \ - awk 'BEGIN {ord=1;} { print($$0 " @" ord " RESIDENTNAME"); ord++;}' >> $@ - $(ADD_TO_DEF_FILE) -endif - -# -# Translate source filenames to absolute paths. This is required for -# debuggers under Windows and OS/2 to find source files automatically. -# - -ifeq (,$(filter-out AIX OS2,$(OS_ARCH))) -NEED_ABSOLUTE_PATH = 1 -endif - -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) -NEED_ABSOLUTE_PATH = 1 -endif - -ifdef NEED_ABSOLUTE_PATH -# The quotes allow absolute paths to contain spaces. -pr_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))" -endif - -$(OBJDIR)/%.$(OBJ_SUFFIX): %.cpp - @$(MAKE_OBJDIR) -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - $(CCC) -Fo$@ -c $(CCCFLAGS) $(call pr_abspath,$<) -else -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINCE) - $(CCC) -Fo$@ -c $(CCCFLAGS) $< -else -ifdef NEED_ABSOLUTE_PATH - $(CCC) -o $@ -c $(CCCFLAGS) $(call pr_abspath,$<) -else - $(CCC) -o $@ -c $(CCCFLAGS) $< -endif -endif -endif - -WCCFLAGS1 = $(subst /,\\,$(CFLAGS)) -WCCFLAGS2 = $(subst -I,-i=,$(WCCFLAGS1)) -WCCFLAGS3 = $(subst -D,-d,$(WCCFLAGS2)) -$(OBJDIR)/%.$(OBJ_SUFFIX): %.c - @$(MAKE_OBJDIR) -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - $(CC) -Fo$@ -c $(CFLAGS) $(call pr_abspath,$<) -else -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINCE) - $(CC) -Fo$@ -c $(CFLAGS) $< -else -ifdef NEED_ABSOLUTE_PATH - $(CC) -o $@ -c $(CFLAGS) $(call pr_abspath,$<) -else - $(CC) -o $@ -c $(CFLAGS) $< -endif -endif -endif - - -$(OBJDIR)/%.$(OBJ_SUFFIX): %.s - @$(MAKE_OBJDIR) - $(AS) -o $@ $(ASFLAGS) -c $< - -%.i: %.c - $(CC) -C -E $(CFLAGS) $< > $*.i - -%: %.pl - rm -f $@; cp $< $@; chmod +x $@ - -# -# HACK ALERT -# -# The only purpose of this rule is to pass Mozilla's Tinderbox depend -# builds (http://tinderbox.mozilla.org/showbuilds.cgi). Mozilla's -# Tinderbox builds NSPR continuously as part of the Mozilla client. -# Because NSPR's make depend is not implemented, whenever we change -# an NSPR header file, the depend build does not recompile the NSPR -# files that depend on the header. -# -# This rule makes all the objects depend on a dummy header file. -# Touch this dummy header file to force the depend build to recompile -# everything. -# -# This rule should be removed when make depend is implemented. -# - -DUMMY_DEPEND_H = $(topsrcdir)/config/prdepend.h - -$(filter $(OBJDIR)/%.$(OBJ_SUFFIX),$(OBJS)): $(OBJDIR)/%.$(OBJ_SUFFIX): $(DUMMY_DEPEND_H) - -# END OF HACK - -################################################################################ -# Special gmake rules. -################################################################################ - -# -# Disallow parallel builds with MSVC < 8 since it can't open the PDB file in -# parallel. -# -ifeq (,$(filter-out 1200 1300 1310,$(MSC_VER))) -.NOTPARALLEL: -endif - -# -# Re-define the list of default suffixes, so gmake won't have to churn through -# hundreds of built-in suffix rules for stuff we don't need. -# -.SUFFIXES: -.SUFFIXES: .a .$(OBJ_SUFFIX) .c .cpp .s .h .i .pl - -# -# Fake targets. Always run these rules, even if a file/directory with that -# name already exists. -# -.PHONY: all alltags clean export install libs realclean release - -# -# List the target pattern of an implicit rule as a dependency of the -# special target .PRECIOUS to preserve intermediate files made by -# implicit rules whose target patterns match that file's name. -# (See GNU Make documentation, Edition 0.51, May 1996, Sec. 10.4, -# p. 107.) -# -.PRECIOUS: $(OBJDIR)/%.$(OBJ_SUFFIX) diff -Nru nspr-4.9.5/mozilla/nsprpub/config/system-headers nspr-4.10.7/mozilla/nsprpub/config/system-headers --- nspr-4.9.5/mozilla/nsprpub/config/system-headers 2005-05-06 18:46:10.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/config/system-headers 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ -Aliases.h -arpa/inet.h -assert.h -bsd/libc.h -bsd/syscall.h -bstring.h -builtin.h -c_asm.h -cf.h -CFBundle.h -CFData.h -CFDictionary.h -CFString.h -CFURL.h -CodeFragments.h -commdlg.h -crt_externs.h -crypt.h -ctype.h -descrip.h -Devices.h -direct.h -dirent.h -dlfcn.h -dl.h -DriverServices.h -dvidef.h -errno.h -Errors.h -Events.h -fcntl.h -fibdef.h -files.h -Files.h -float.h -Folders.h -Gestalt.h -getopt.h -grp.h -ia64/sys/inline.h -ifaddrs.h -image.h -ints.h -iodef.h -io.h -iostream.h -kernel/OS.h -lib$routines.h -limits.h -loader.h -locale.h -LowMem.h -MacErrors.h -machine/builtins.h -machine/clock.h -machine/endian.h -machine/inline.h -mach/mach_init.h -mach/mach_host.h -mach-o/dyld.h -MacTypes.h -Math64.h -math.h -mbstring.h -memory.h -MixedMode.h -model.h -mswsock.h -Multiprocessing.h -mutex.h -netdb.h -net/if.h -netinet/in.h -netinet/in_systm.h -netinet/tcp.h -OpenTptInternet.h -OpenTransport.h -os2.h -OS.h -osreldate.h -OSUtils.h -poll.h -PPCToolbox.h -Processes.h -process.h -pthread.h -pwd.h -QDOffscreen.h -Resources.h -rld_interface.h -rpc/types.h -semaphore.h -setjmp.h -share.h -signal.h -ssdef.h -starlet.h -stat.h -stdarg.h -stddef.h -stdio.h -stdlib.h -string.h -stropts.h -stsdef.h -support/SupportDefs.h -support/TLS.h -synch.h -sys/atomic_op.h -syscall.h -sys/cfgodm.h -sys/file.h -sys/filio.h -sys/immu.h -sys/ioctl.h -sys/ipc.h -sys/ldr.h -sys/locking.h -sys/lwp.h -sys/mman.h -sys/mpctl.h -sys/param.h -sys/pda.h -sys/poll.h -sys/prctl.h -sys/priv.h -sys/procfs.h -sys/pstat.h -sys/regset.h -sys/resource.h -sys/sched.h -sys/select.h -sys/sem.h -sys/sendfile.h -sys/shm.h -sys/socket.h -sys/stack.h -sys/stat.h -sys/statvfs.h -sys/syscall.h -sys/sysctl.h -sys/sysmp.h -sys/syssgi.h -sys/systeminfo.h -sys/timeb.h -sys/time.h -sys/times.h -sys/types.h -sys/ucontext.h -sys/uio.h -sys/utsname.h -sys/wait.h -task.h -TextUtils.h -thread.h -time.h -Timer.h -types.h -Types.h -ucontext.h -ucx$inetdef.h -ulocks.h -unistd.h -unix.h -unixlib.h -utime.h -wchar.h -winbase.h -win/compobj.h -windef.h -windows.h -winsock.h diff -Nru nspr-4.9.5/mozilla/nsprpub/configure nspr-4.10.7/mozilla/nsprpub/configure --- nspr-4.9.5/mozilla/nsprpub/configure 2012-12-19 19:21:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/configure 1970-01-01 00:00:00.000000000 +0000 @@ -1,6883 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.13 -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_help="$ac_help - --with-android-ndk=DIR - location where the Android NDK can be found" -ac_help="$ac_help - --with-android-toolchain=DIR - location of the Android toolchain" -ac_help="$ac_help - --with-android-version=VER - Android platform version, default 5" -ac_help="$ac_help - --with-android-platform=DIR - location of platform dir" -ac_help="$ac_help - --with-gonk=DIR location of gonk dir" -ac_help="$ac_help - --with-dist-prefix=DIST_PREFIX - place build files in DIST_PREFIX [dist]" -ac_help="$ac_help - --with-dist-bindir=DIR build execuatables in DIR [DIST_PREFIX/bin]" -ac_help="$ac_help - --with-dist-includedir=DIR - build include files in DIR [DIST_PREFIX/include/nspr]" -ac_help="$ac_help - --with-dist-libdir=DIR build library files in DIR [DIST_PREFIX/lib]" -ac_help="$ac_help - --with-mozilla Compile NSPR with Mozilla support" -ac_help="$ac_help - --enable-optimize[=OPT] Enable code optimizations (ie. -O2) " -ac_help="$ac_help - --enable-debug[=DBG] Enable debugging (using compiler flags DBG)" -ac_help="$ac_help - --enable-debug-symbols[=DBG] Enable debugging symbols - (using compiler flags DBG)" -ac_help="$ac_help - --enable-win32-target=\$t - Specify win32 flavor. (WIN95 or WINNT)" -ac_help="$ac_help - --enable-symbian-target=\$t - Specify symbian flavor. (WINSCW or GCCE)" -ac_help="$ac_help - --enable-debug-rtl Use the MSVC debug runtime library" -ac_help="$ac_help - --enable-n32 Enable n32 ABI support (IRIX only)" -ac_help="$ac_help - --enable-64bit Enable 64-bit support (on certain platforms)" -ac_help="$ac_help - --enable-mdupdate Enable use of certain compilers' mdupdate feature" -ac_help="$ac_help - --enable-cplus Enable some c++ api routines" -ac_help="$ac_help - --with-arm-kuser Use kuser helpers (Linux/ARM only) - (Requires kernel 2.6.13 or later)" -ac_help="$ac_help - --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)" -ac_help="$ac_help - --enable-macos-target=VER - Set the minimum MacOS version needed at runtime - [10.2 for ppc, 10.4 for x86]" -ac_help="$ac_help - --disable-os2-high-mem Disable high-memory support on OS/2" -ac_help="$ac_help -" -ac_help="$ac_help - --with-thumb[[=yes|no|toolchain-default]] - Use Thumb instruction set (-mthumb)" -ac_help="$ac_help - --with-thumb-interwork[[=yes|no|toolchain-default]] - Use Thumb/ARM instuctions interwork (-mthumb-interwork)" -ac_help="$ac_help - --with-arch=[[type|toolchain-default]] - Use specific CPU features (-march=type)" -ac_help="$ac_help - --with-fpu=[[type|toolchain-default]] - Use specific FPU type (-mfpu=type)" -ac_help="$ac_help - --with-float-abi=[[type|toolchain-default]] - Use specific arm float ABI (-mfloat-abi=type)" -ac_help="$ac_help - --with-soft-float[[=yes|no|toolchain-default]] - Use soft float library (-msoft-float)" -ac_help="$ac_help - --with-symbian-sdk=SYMBIAN_SDK_DIR - The path to the Symbian SDK" -ac_help="$ac_help - --with-ccache[=path/to/ccache] - Enable compiling with ccache" -ac_help="$ac_help - --enable-strip Enable stripping of shared libs and programs" -ac_help="$ac_help - --with-pthreads Use system pthreads library as thread subsystem" -ac_help="$ac_help - --enable-user-pthreads Build using userland pthreads" -ac_help="$ac_help - --enable-nspr-threads Build using classic nspr threads" -ac_help="$ac_help - --with-bthreads Use system bthreads library as thread subsystem - (BeOS only)" -ac_help="$ac_help - --enable-ipv6 Compile ipv6 support" -ac_help="$ac_help - --enable-wrap-malloc Wrap malloc calls (gnu linker only)" -ac_help="$ac_help - --with-wrap-malloc=SHAREDLIB Location of malloc wrapper library" - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} -# Maximum number of lines to put in a shell here document. -ac_max_here_lines=12 - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.13" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set these to C if already set. These must not be set unconditionally -# because not all systems understand e.g. LANG=C (notably SCO). -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! -# Non-C LC_CTYPE values break the ctype check. -if test "${LANG+set}" = set; then LANG=C; export LANG; fi -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=config/libc_r.h - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -ac_exeext= -ac_objext=o -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - - -ac_aux_dir= -for ac_dir in ${srcdir}/build/autoconf $srcdir/${srcdir}/build/autoconf; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in ${srcdir}/build/autoconf $srcdir/${srcdir}/build/autoconf" 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - - -# Do some error checking and defaulting for the host and target type. -# The inputs are: -# configure --host=HOST --target=TARGET --build=BUILD NONOPT -# -# The rules are: -# 1. You are not allowed to specify --host, --target, and nonopt at the -# same time. -# 2. Host defaults to nonopt. -# 3. If nonopt is not specified, then host defaults to the current host, -# as determined by config.guess. -# 4. Target and build default to nonopt. -# 5. If nonopt is not specified, then target and build default to host. - -# The aliases save the names the user supplied, while $host etc. -# will get canonicalized. -case $host---$target---$nonopt in -NONE---*---* | *---NONE---* | *---*---NONE) ;; -*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; -esac - - -# Make sure we can run config.sub. -if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : -else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } -fi - -echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:676: checking host system type" >&5 - -host_alias=$host -case "$host_alias" in -NONE) - case $nonopt in - NONE) - if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : - else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } - fi ;; - *) host_alias=$nonopt ;; - esac ;; -esac - -host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` -host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$host" 1>&6 - -echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:697: checking target system type" >&5 - -target_alias=$target -case "$target_alias" in -NONE) - case $nonopt in - NONE) target_alias=$host_alias ;; - *) target_alias=$nonopt ;; - esac ;; -esac - -target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` -target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$target" 1>&6 - -echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:715: checking build system type" >&5 - -build_alias=$build -case "$build_alias" in -NONE) - case $nonopt in - NONE) build_alias=$host_alias ;; - *) build_alias=$nonopt ;; - esac ;; -esac - -build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` -build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$build" 1>&6 - -test "$host_alias" != "$target_alias" && - test "$program_prefix$program_suffix$program_transform_name" = \ - NONENONEs,x,x, && - program_prefix=${target_alias}- - - -MOD_MAJOR_VERSION=4 -MOD_MINOR_VERSION=9 -MOD_PATCH_VERSION=5 -NSPR_MODNAME=nspr20 -_HAVE_PTHREADS= -USE_PTHREADS= -USE_USER_PTHREADS= -USE_NSPR_THREADS= -USE_N32= -USE_64= -USE_CPLUS= -USE_IPV6= -USE_MDUPDATE= -_MACOSX_DEPLOYMENT_TARGET= -_OPTIMIZE_FLAGS=-O -_DEBUG_FLAGS=-g -MOZ_DEBUG=1 -MOZ_OPTIMIZE= -OBJDIR='$(OBJDIR_NAME)' -OBJDIR_NAME=. -OBJDIR_SUFFIX=OBJ -NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall' -NOSUCHFILE=/no-such-file -LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)' -LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)' -CYGWIN_WRAPPER= -MACOS_SDK_DIR= -NEXT_ROOT= -MT= -MOZ_OS2_HIGH_MEMORY=1 -PROFILE_GEN_CFLAGS= -PROFILE_GEN_LDFLAGS= -PROFILE_USE_CFLAGS= -PROFILE_USE_LDFLAGS= - -RESOLVE_LINK_SYMBOLS= - -CFLAGS="${CFLAGS=}" -CXXFLAGS="${CXXFLAGS=}" -LDFLAGS="${LDFLAGS=}" -DLLFLAGS="${DLLFLAGS=}" -HOST_CFLAGS="${HOST_CFLAGS=}" -HOST_LDFLAGS="${HOST_LDFLAGS=}" - -case "$target" in -*-cygwin*|*-mingw*) - # Check to see if we are really running in a msvc environemnt - _WIN32_MSVC= - for ac_prog in cl -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:791: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$CC" && break -done - - if test "$CC" = "cl"; then - echo 'main() { return 0; }' > dummy.c - ${CC} -o dummy dummy.c >/dev/null 2>&1 - if test $? = 0; then - _WIN32_MSVC=1 - CXX=$CC - else - echo "configure: warning: $(CC) test failed. Using normal feature tests" 1>&2 - fi - rm -f dummy dummy.o dummy.obj dummy.exe dummy.c - fi - ;; -*-msvc*) - _WIN32_MSVC=1 - ;; -*-mks*) - _WIN32_MSVC=1 - ;; -esac - -if test -n "$_WIN32_MSVC"; then - SKIP_PATH_CHECKS=1 - SKIP_COMPILER_CHECKS=1 - SKIP_LIBRARY_CHECKS=1 -fi - - -# Check whether --with-android-ndk or --without-android-ndk was given. -if test "${with_android_ndk+set}" = set; then - withval="$with_android_ndk" - android_ndk=$withval -fi - - -# Check whether --with-android-toolchain or --without-android-toolchain was given. -if test "${with_android_toolchain+set}" = set; then - withval="$with_android_toolchain" - android_toolchain=$withval -fi - - -# Check whether --with-android-version or --without-android-version was given. -if test "${with_android_version+set}" = set; then - withval="$with_android_version" - android_version=$withval -else - android_version=5 -fi - - -# Check whether --with-android-platform or --without-android-platform was given. -if test "${with_android_platform+set}" = set; then - withval="$with_android_platform" - android_platform=$withval -fi - - -case "$target" in -arm-linux*-android*|*-linuxandroid*) - android_tool_prefix="arm-linux-androideabi" - ;; -i?86-*android*) - android_tool_prefix="i686-linux-android" - ;; -mipsel-*android*) - android_tool_prefix="mipsel-linux-android" - ;; -*) - android_tool_prefix="$target_os" - ;; -esac - - -# Check whether --with-gonk or --without-gonk was given. -if test "${with_gonk+set}" = set; then - withval="$with_gonk" - gonkdir=$withval -fi - - -if test -n "$gonkdir" ; then - - if test -z "$HOST_CPPFLAGS" ; then - HOST_CPPFLAGS=" " - fi - if test -z "$HOST_CFLAGS" ; then - HOST_CFLAGS=" " - fi - if test -z "$HOST_CXXFLAGS" ; then - HOST_CXXFLAGS=" " - fi - if test -z "$HOST_LDFLAGS" ; then - HOST_LDFLAGS=" " - fi - - cat >> confdefs.h <<\EOF -#define ANDROID 1 -EOF - -else -case "$target" in -*-android*|*-linuxandroid*) - if test -z "$android_ndk" ; then - { echo "configure: error: You must specify --with-android-ndk=/path/to/ndk when targeting Android." 1>&2; exit 1; } - fi - - if test -z "$android_toolchain" ; then - echo $ac_n "checking for android toolchain directory""... $ac_c" 1>&6 -echo "configure:928: checking for android toolchain directory" >&5 - - kernel_name=`uname -s | tr "[:upper:]" "[:lower:]"` - - case "$target_cpu" in - arm) - target_name=arm-linux-androideabi-4.4.3 - ;; - i?86) - target_name=x86-4.4.3 - ;; - mipsel) - target_name=mipsel-linux-android-4.4.3 - ;; - esac - android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86 - - if test -d "$android_toolchain" ; then - echo "$ac_t""$android_toolchain" 1>&6 - else - { echo "configure: error: not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain." 1>&2; exit 1; } - fi - fi - - if test -z "$android_platform" ; then - echo $ac_n "checking for android platform directory""... $ac_c" 1>&6 -echo "configure:954: checking for android platform directory" >&5 - - case "$target_cpu" in - arm) - target_name=arm - ;; - i?86) - target_name=x86 - ;; - mipsel) - target_name=mips - ;; - esac - - android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name" - - if test -d "$android_platform" ; then - echo "$ac_t""$android_platform" 1>&6 - else - { echo "configure: error: not found. You have to specify --with-android-platform=/path/to/ndk/platform." 1>&2; exit 1; } - fi - fi - - case "$target_cpu" in - i?86) - if ! test -e "$android_toolchain"/bin/"$android_tool_prefix"-gcc; then - android_tool_prefix="i686-android-linux" - fi - ;; - esac - - AS="$android_toolchain"/bin/"$android_tool_prefix"-as - CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc - CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++ - CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp - LD="$android_toolchain"/bin/"$android_tool_prefix"-ld - AR="$android_toolchain"/bin/"$android_tool_prefix"-ar - RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib - STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip - - CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS" - CFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CFLAGS" - CXXFLAGS="-mandroid -I$android_platform/usr/include -fpic -fno-short-enums -fno-exceptions $CXXFLAGS" - LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform $LDFLAGS" - - if test -z "$HOST_CPPFLAGS" ; then - HOST_CPPFLAGS=" " - fi - if test -z "$HOST_CFLAGS" ; then - HOST_CFLAGS=" " - fi - if test -z "$HOST_CXXFLAGS" ; then - HOST_CXXFLAGS=" " - fi - if test -z "$HOST_LDFLAGS" ; then - HOST_LDFLAGS=" " - fi - - cat >> confdefs.h <<\EOF -#define ANDROID 1 -EOF - - cat >> confdefs.h <> confdefs.h <<\EOF -#define MOZILLA_CLIENT 1 -EOF - - MOZILLA_CLIENT=1 - else - MOZILLA_CLIENT= - fi -else - if test -n "$MOZILLA_CLIENT"; then - cat >> confdefs.h <<\EOF -#define MOZILLA_CLIENT 1 -EOF - - fi -fi - - -# Check whether --enable-optimize or --disable-optimize was given. -if test "${enable_optimize+set}" = set; then - enableval="$enable_optimize" - if test "$enableval" != "no"; then - MOZ_OPTIMIZE=1 - if test -n "$enableval" -a "$enableval" != "yes"; then - _OPTIMIZE_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` - _SAVE_OPTIMIZE_FLAGS=$_OPTIMIZE_FLAGS - fi - else - MOZ_OPTIMIZE= - fi -fi - - -# Check whether --enable-debug or --disable-debug was given. -if test "${enable_debug+set}" = set; then - enableval="$enable_debug" - if test "$enableval" != "no"; then - MOZ_DEBUG=1 - MOZ_DEBUG_SYMBOLS=1 - if test -n "$enableval" -a "$enableval" != "yes"; then - _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` - _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS - fi - else - MOZ_DEBUG= - fi -else - MOZ_DEBUG_SYMBOLS=1 -fi - - -# Check whether --enable-debug-symbols or --disable-debug-symbols was given. -if test "${enable_debug_symbols+set}" = set; then - enableval="$enable_debug_symbols" - if test "$enableval" != "no"; then - MOZ_DEBUG_SYMBOLS=1 - if test -n "$enableval" -a "$enableval" != "yes"; then - if test -z "$_SAVE_DEBUG_FLAGS"; then - _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` - _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS - else - { echo "configure: error: --enable-debug-symbols flags cannot be used with --enable-debug flags" 1>&2; exit 1; } - fi - fi - else - MOZ_DEBUG_SYMBOLS= - fi -fi - - -# Check whether --enable-win32-target or --disable-win32-target was given. -if test "${enable_win32_target+set}" = set; then - enableval="$enable_win32_target" - OS_TARGET=`echo $enableval | tr a-z A-Z` -fi - - -# Check whether --enable-symbian-target or --disable-symbian-target was given. -if test "${enable_symbian_target+set}" = set; then - enableval="$enable_symbian_target" - OS_TARGET=`echo $enableval | tr a-z A-Z` -fi - - -# Check whether --enable-debug-rtl or --disable-debug-rtl was given. -if test "${enable_debug_rtl+set}" = set; then - enableval="$enable_debug_rtl" - if test "$enableval" = "yes"; then - USE_DEBUG_RTL=1 - fi -fi - - -# Check whether --enable-n32 or --disable-n32 was given. -if test "${enable_n32+set}" = set; then - enableval="$enable_n32" - if test "$enableval" = "yes"; then - USE_N32=1 - else if test "$enableval" = "no"; then - USE_N32= - fi - fi -fi - - -# Check whether --enable-64bit or --disable-64bit was given. -if test "${enable_64bit+set}" = set; then - enableval="$enable_64bit" - if test "$enableval" = "yes"; then - USE_64=1 - fi -fi - - -# Check whether --enable-mdupdate or --disable-mdupdate was given. -if test "${enable_mdupdate+set}" = set; then - enableval="$enable_mdupdate" - if test "$enableval" = "yes"; then - USE_MDUPDATE=1 - fi -fi - - -# Check whether --enable-cplus or --disable-cplus was given. -if test "${enable_cplus+set}" = set; then - enableval="$enable_cplus" - if test "$enableval" = "yes"; then - USE_CPLUS=1 - fi -fi - - -# Check whether --with-arm-kuser or --without-arm-kuser was given. -if test "${with_arm_kuser+set}" = set; then - withval="$with_arm_kuser" - if test "$withval" = "yes"; then - cat >> confdefs.h <<\EOF -#define _PR_ARM_KUSER 1 -EOF - - fi -fi - - -# Check whether --with-macos-sdk or --without-macos-sdk was given. -if test "${with_macos_sdk+set}" = set; then - withval="$with_macos_sdk" - MACOS_SDK_DIR=$withval -fi - - -# Check whether --enable-macos-target or --disable-macos-target was given. -if test "${enable_macos_target+set}" = set; then - enableval="$enable_macos_target" - _MACOSX_DEPLOYMENT_TARGET=$enableval -fi - - -case "$target" in - -*-aix*) - case "${target_os}" in - aix3.2*) - USE_NSPR_THREADS=1 - ;; - *) - USE_PTHREADS=1 - ;; - esac - ;; - -esac - -if test -z "$CC"; then - case "$target" in - - *-aix*) - if test -z "$USE_NSPR_THREADS"; then - CC=xlc_r - else - CC=xlc - fi - ;; - - *-hpux*) - CC=cc - ;; - - *-irix*) - CC=cc - ;; - - *-osf*) - CC=cc - ;; - - *-solaris*) - CC=cc - ;; - - esac -fi - -if test -z "$CXX"; then - case "$target" in - - *-aix*) - if test -z "$USE_NSPR_THREADS"; then - CXX=xlC_r - else - CXX=xlC - fi - ;; - - *-hpux*) - case "${target_os}" in - hpux10.30) - CXX=aCC - ;; - hpux11.*) - CXX=aCC - ;; - *) - CXX=CC - ;; - esac - ;; - - *-irix*) - CXX=CC - ;; - - *-osf*) - CXX=cxx - ;; - - *-solaris*) - CXX=CC - ;; - - esac -fi - -if test -z "$SKIP_PATH_CHECKS"; then - # Extract the first word of "$WHOAMI whoami", so it can be a program name with args. -set dummy $WHOAMI whoami; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1316: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_WHOAMI'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$WHOAMI" in - /*) - ac_cv_path_WHOAMI="$WHOAMI" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_WHOAMI="$WHOAMI" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_WHOAMI="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_path_WHOAMI" && ac_cv_path_WHOAMI="echo not_whoami" - ;; -esac -fi -WHOAMI="$ac_cv_path_WHOAMI" -if test -n "$WHOAMI"; then - echo "$ac_t""$WHOAMI" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -fi - -if test -n "$MOZ_DEBUG"; then - cat >> confdefs.h <<\EOF -#define DEBUG 1 -EOF - - DEFINES="$DEFINES -UNDEBUG" - - case "${target_os}" in - beos*) - DEFINES="$DEFINES -DDEBUG_${USER}" - ;; - msvc*|mks*|cygwin*|mingw*|wince*|winmo*|os2*) - DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`" - ;; - *) - DEFINES="$DEFINES -DDEBUG_`$WHOAMI`" - ;; - esac -else - cat >> confdefs.h <<\EOF -#define NDEBUG 1 -EOF - - DEFINES="$DEFINES -UDEBUG" -fi - -if test -z "$SKIP_COMPILER_CHECKS"; then - -if test "$target" != "$host" -o -n "$CROSS_COMPILE"; then - echo "cross compiling from $host to $target" - cross_compiling=yes - - _SAVE_CC="$CC" - _SAVE_CFLAGS="$CFLAGS" - _SAVE_LDFLAGS="$LDFLAGS" - - echo $ac_n "checking for $host compiler""... $ac_c" 1>&6 -echo "configure:1388: checking for $host compiler" >&5 - for ac_prog in $HOST_CC gcc cc /usr/ucb/cc -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1394: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_HOST_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$HOST_CC"; then - ac_cv_prog_HOST_CC="$HOST_CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_HOST_CC="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -HOST_CC="$ac_cv_prog_HOST_CC" -if test -n "$HOST_CC"; then - echo "$ac_t""$HOST_CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$HOST_CC" && break -done -test -n "$HOST_CC" || HOST_CC="""" - - if test -z "$HOST_CC"; then - { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } - fi - echo "$ac_t""$HOST_CC" 1>&6 - if test -z "$HOST_CFLAGS"; then - HOST_CFLAGS="$CFLAGS" - fi - if test -z "$HOST_LDFLAGS"; then - HOST_LDFLAGS="$LDFLAGS" - fi - - CC="$HOST_CC" - CFLAGS="$HOST_CFLAGS" - LDFLAGS="$HOST_LDFLAGS" - - echo $ac_n "checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1440: checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works" >&5 - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_prog_host_cc_works=1 echo "$ac_t""yes" 1>&6 -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - { echo "configure: error: installation or configuration problem: $host compiler $HOST_CC cannot create executables." 1>&2; exit 1; } -fi -rm -f conftest* - - CC=$_SAVE_CC - CFLAGS=$_SAVE_CFLAGS - LDFLAGS=$_SAVE_LDFLAGS - - case "$build:$target" in - powerpc-apple-darwin8*:i?86-apple-darwin*) - _SAVE_CFLAGS=$CFLAGS - _SAVE_CXXFLAGS=$CXXFLAGS - CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CFLAGS" - CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS" - ;; - *:arm*-apple-darwin*) - _SAVE_CFLAGS=$CFLAGS - _SAVE_CXXFLAGS=$CXXFLAGS - CFLAGS="-isysroot $MACOS_SDK_DIR $CFLAGS" - CXXFLAGS="-isysroot $MACOS_SDK_DIR $CXXFLAGS" - ;; - esac - - for ac_prog in $CC "${target_alias}-gcc" "${target}-gcc" -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1484: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$CC" && break -done -test -n "$CC" || CC="echo" - - unset ac_cv_prog_CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1518: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1548: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_prog_rejected=no - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - if test -z "$CC"; then - case "`uname -s`" in - *win32* | *WIN32*) - # Extract the first word of "cl", so it can be a program name with args. -set dummy cl; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1599: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="cl" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - ;; - esac - fi - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1631: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -cat > conftest.$ac_ext << EOF - -#line 1642 "configure" -#include "confdefs.h" - -main(){return(0);} -EOF -if { (eval echo configure:1647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cc_cross=no - else - ac_cv_prog_cc_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cc_works=no -fi -rm -fr conftest* -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 -if test $ac_cv_prog_cc_works = no; then - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1673: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 -cross_compiling=$ac_cv_prog_cc_cross - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1678: checking whether we are using GNU C" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 - -if test $ac_cv_prog_gcc = yes; then - GCC=yes -else - GCC= -fi - -ac_test_CFLAGS="${CFLAGS+set}" -ac_save_CFLAGS="$CFLAGS" -CFLAGS= -echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1706: checking whether ${CC-cc} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_cc_g=yes -else - ac_cv_prog_cc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi - - if test -n "$USE_CPLUS"; then - for ac_prog in $CXX "${target_alias}-g++" "${target}-g++" -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1743: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CXX="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CXX="$ac_cv_prog_CXX" -if test -n "$CXX"; then - echo "$ac_t""$CXX" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$CXX" && break -done -test -n "$CXX" || CXX="echo" - - unset ac_cv_prog_CXX - for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1779: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CXX="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CXX="$ac_cv_prog_CXX" -if test -n "$CXX"; then - echo "$ac_t""$CXX" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$CXX" && break -done -test -n "$CXX" || CXX="gcc" - - -echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1811: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 - -ac_ext=C -# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cxx_cross - -cat > conftest.$ac_ext << EOF - -#line 1822 "configure" -#include "confdefs.h" - -int main(){return(0);} -EOF -if { (eval echo configure:1827: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cxx_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cxx_cross=no - else - ac_cv_prog_cxx_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cxx_works=no -fi -rm -fr conftest* -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 -if test $ac_cv_prog_cxx_works = no; then - { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1853: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 -cross_compiling=$ac_cv_prog_cxx_cross - -echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 -echo "configure:1858: checking whether we are using GNU C++" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.C <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gxx=yes -else - ac_cv_prog_gxx=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gxx" 1>&6 - -if test $ac_cv_prog_gxx = yes; then - GXX=yes -else - GXX= -fi - -ac_test_CXXFLAGS="${CXXFLAGS+set}" -ac_save_CXXFLAGS="$CXXFLAGS" -CXXFLAGS= -echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 -echo "configure:1886: checking whether ${CXX-g++} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.cc -if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then - ac_cv_prog_cxx_g=yes -else - ac_cv_prog_cxx_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS="$ac_save_CXXFLAGS" -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi - - fi - - case "$build:$target" in - powerpc-apple-darwin8*:i?86-apple-darwin*|*:arm*-apple-darwin*) - CFLAGS=$_SAVE_CFLAGS - CXXFLAGS=$_SAVE_CXXFLAGS - ;; - esac - - for ac_prog in $RANLIB "${target_alias}-ranlib" "${target}-ranlib" -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1931: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$RANLIB" && break -done -test -n "$RANLIB" || RANLIB="echo" - - for ac_prog in $AR "${target_alias}-ar" "${target}-ar" -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1966: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_AR="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -AR="$ac_cv_prog_AR" -if test -n "$AR"; then - echo "$ac_t""$AR" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$AR" && break -done -test -n "$AR" || AR="echo" - - for ac_prog in $AS "${target_alias}-as" "${target}-as" -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2001: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$AS"; then - ac_cv_prog_AS="$AS" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_AS="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -AS="$ac_cv_prog_AS" -if test -n "$AS"; then - echo "$ac_t""$AS" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$AS" && break -done -test -n "$AS" || AS="echo" - - for ac_prog in $LD "${target_alias}-ld" "${target}-ld" -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2036: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$LD"; then - ac_cv_prog_LD="$LD" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_LD="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -LD="$ac_cv_prog_LD" -if test -n "$LD"; then - echo "$ac_t""$LD" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$LD" && break -done -test -n "$LD" || LD="echo" - - for ac_prog in $STRIP "${target_alias}-strip" "${target}-strip" -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2071: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_STRIP="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -STRIP="$ac_cv_prog_STRIP" -if test -n "$STRIP"; then - echo "$ac_t""$STRIP" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$STRIP" && break -done -test -n "$STRIP" || STRIP="echo" - - for ac_prog in $WINDRES "${target_alias}-windres" "${target}-windres" -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2106: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$WINDRES"; then - ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_WINDRES="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -WINDRES="$ac_cv_prog_WINDRES" -if test -n "$WINDRES"; then - echo "$ac_t""$WINDRES" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$WINDRES" && break -done -test -n "$WINDRES" || WINDRES="echo" - - -else - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2141: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2171: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_prog_rejected=no - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - if test -z "$CC"; then - case "`uname -s`" in - *win32* | *WIN32*) - # Extract the first word of "cl", so it can be a program name with args. -set dummy cl; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2222: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="cl" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - ;; - esac - fi - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:2254: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -cat > conftest.$ac_ext << EOF - -#line 2265 "configure" -#include "confdefs.h" - -main(){return(0);} -EOF -if { (eval echo configure:2270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cc_cross=no - else - ac_cv_prog_cc_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cc_works=no -fi -rm -fr conftest* -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 -if test $ac_cv_prog_cc_works = no; then - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:2296: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 -cross_compiling=$ac_cv_prog_cc_cross - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:2301: checking whether we are using GNU C" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 - -if test $ac_cv_prog_gcc = yes; then - GCC=yes -else - GCC= -fi - -ac_test_CFLAGS="${CFLAGS+set}" -ac_save_CFLAGS="$CFLAGS" -CFLAGS= -echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:2329: checking whether ${CC-cc} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_cc_g=yes -else - ac_cv_prog_cc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi - - if test -n "$USE_CPLUS"; then - if test "$CC" = "cl" -a -z "$CXX"; then - CXX=$CC - else - for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2369: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CXX="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CXX="$ac_cv_prog_CXX" -if test -n "$CXX"; then - echo "$ac_t""$CXX" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$CXX" && break -done -test -n "$CXX" || CXX="gcc" - - -echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:2401: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 - -ac_ext=C -# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cxx_cross - -cat > conftest.$ac_ext << EOF - -#line 2412 "configure" -#include "confdefs.h" - -int main(){return(0);} -EOF -if { (eval echo configure:2417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cxx_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cxx_cross=no - else - ac_cv_prog_cxx_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cxx_works=no -fi -rm -fr conftest* -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 -if test $ac_cv_prog_cxx_works = no; then - { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:2443: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 -cross_compiling=$ac_cv_prog_cxx_cross - -echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 -echo "configure:2448: checking whether we are using GNU C++" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.C <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gxx=yes -else - ac_cv_prog_gxx=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gxx" 1>&6 - -if test $ac_cv_prog_gxx = yes; then - GXX=yes -else - GXX= -fi - -ac_test_CXXFLAGS="${CXXFLAGS+set}" -ac_save_CXXFLAGS="$CXXFLAGS" -CXXFLAGS= -echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 -echo "configure:2476: checking whether ${CXX-g++} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.cc -if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then - ac_cv_prog_cxx_g=yes -else - ac_cv_prog_cxx_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS="$ac_save_CXXFLAGS" -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi - - fi - fi - echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:2510: 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 < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2531: \"$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 < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2548: \"$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 < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2565: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2592: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="ranlib" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - for ac_prog in as -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2624: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_AS'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$AS" in - /*) - ac_cv_path_AS="$AS" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_AS="$AS" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_AS="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - ;; -esac -fi -AS="$ac_cv_path_AS" -if test -n "$AS"; then - echo "$ac_t""$AS" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$AS" && break -done -test -n "$AS" || AS="$CC" - - for ac_prog in ar -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2665: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$AR" in - /*) - ac_cv_path_AR="$AR" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_AR="$AR" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_AR="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - ;; -esac -fi -AR="$ac_cv_path_AR" -if test -n "$AR"; then - echo "$ac_t""$AR" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$AR" && break -done -test -n "$AR" || AR="echo not_ar" - - for ac_prog in ld link -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2706: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$LD" in - /*) - ac_cv_path_LD="$LD" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_LD="$LD" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_LD="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - ;; -esac -fi -LD="$ac_cv_path_LD" -if test -n "$LD"; then - echo "$ac_t""$LD" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$LD" && break -done -test -n "$LD" || LD="echo not_ld" - - for ac_prog in strip -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2747: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_STRIP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$STRIP" in - /*) - ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_STRIP="$STRIP" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_STRIP="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - ;; -esac -fi -STRIP="$ac_cv_path_STRIP" -if test -n "$STRIP"; then - echo "$ac_t""$STRIP" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$STRIP" && break -done -test -n "$STRIP" || STRIP="echo not_strip" - - for ac_prog in windres -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2788: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_WINDRES'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$WINDRES" in - /*) - ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_WINDRES="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - ;; -esac -fi -WINDRES="$ac_cv_path_WINDRES" -if test -n "$WINDRES"; then - echo "$ac_t""$WINDRES" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$WINDRES" && break -done -test -n "$WINDRES" || WINDRES="echo not_windres" - - if test -z "$HOST_CC"; then - HOST_CC="$CC" - fi - if test -z "$HOST_CFLAGS"; then - HOST_CFLAGS="$CFLAGS" - fi -fi - -if test "$GCC" = "yes"; then - GNU_CC=1 -fi -if test "$GXX" = "yes"; then - GNU_CXX=1 -fi -if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then - GNU_AS=1 -fi -rm -f a.out - -case "$build:$target" in - i?86-apple-darwin*:powerpc-apple-darwin*) - cross_compiling=yes - ;; -esac - -if test "$cross_compiling" = "yes"; then - CROSS_COMPILE=1 -else - CROSS_COMPILE= -fi - -echo $ac_n "checking for gcc -pipe support""... $ac_c" 1>&6 -echo "configure:2856: checking for gcc -pipe support" >&5 -if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then - echo '#include ' > dummy-hello.c - echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c - ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5 - cat dummy-hello.s | ${AS} -o dummy-hello.S - 2>&5 - if test $? = 0; then - _res_as_stdin="yes" - else - _res_as_stdin="no" - fi - if test "$_res_as_stdin" = "yes"; then - _SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -pipe" - cat > conftest.$ac_ext < -int main() { -printf("Hello World\n"); -; return 0; } -EOF -if { (eval echo configure:2878: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - _res_gcc_pipe="yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - _res_gcc_pipe="no" -fi -rm -f conftest* - CFLAGS=$_SAVE_CFLAGS - fi - if test "$_res_as_stdin" = "yes" && test "$_res_gcc_pipe" = "yes"; then - _res="yes"; - CFLAGS="$CFLAGS -pipe" - CXXFLAGS="$CXXFLAGS -pipe" - else - _res="no" - fi - rm -f dummy-hello.c dummy-hello.s dummy-hello.S dummy-hello a.out - echo "$ac_t""$_res" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -_SAVE_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction" - -echo $ac_n "checking whether C compiler supports -fprofile-generate""... $ac_c" 1>&6 -echo "configure:2908: checking whether C compiler supports -fprofile-generate" >&5 -cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - PROFILE_GEN_CFLAGS="-fprofile-generate" - result="yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - result="no" -fi -rm -f conftest* -echo "$ac_t""$result" 1>&6 - -if test $result = "yes"; then - PROFILE_GEN_LDFLAGS="-fprofile-generate" - PROFILE_USE_CFLAGS="-fprofile-use -fprofile-correction -Wcoverage-mismatch" - PROFILE_USE_LDFLAGS="-fprofile-use" -fi - -CFLAGS="$_SAVE_CFLAGS" - -if test "$GNU_CC"; then - echo $ac_n "checking for visibility(hidden) attribute""... $ac_c" 1>&6 -echo "configure:2940: checking for visibility(hidden) attribute" >&5 -if eval "test \"`echo '$''{'ac_cv_visibility_hidden'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c </dev/null 2>&1; then - if grep '\.hidden.*foo' conftest.s >/dev/null; then - ac_cv_visibility_hidden=yes - fi - fi - rm -f conftest.cs - -fi - -echo "$ac_t""$ac_cv_visibility_hidden" 1>&6 - if test "$ac_cv_visibility_hidden" = "yes"; then - cat >> confdefs.h <<\EOF -#define HAVE_VISIBILITY_HIDDEN_ATTRIBUTE 1 -EOF - - echo $ac_n "checking for visibility pragma support""... $ac_c" 1>&6 -echo "configure:2964: checking for visibility pragma support" >&5 -if eval "test \"`echo '$''{'ac_cv_visibility_pragma'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c </dev/null 2>&1; then - if grep '\.hidden.*foo_hidden' conftest.s >/dev/null; then - if ! grep '\.hidden.*foo_default' conftest.s > /dev/null; then - ac_cv_visibility_pragma=yes - fi - fi - fi - rm -f conftest.cs - -fi - -echo "$ac_t""$ac_cv_visibility_pragma" 1>&6 - if test "$ac_cv_visibility_pragma" = "yes"; then - cat >> confdefs.h <<\EOF -#define HAVE_VISIBILITY_PRAGMA 1 -EOF - - # To work around a build problem on Linux x86-64 (Bugzilla bug - # 293438), we use the -fvisibility=hidden flag. This flag is less - # optimal than #pragma GCC visibility push(hidden) because the flag - # assumes that symbols defined outside the current source file have - # the default visibility. This has the advantage that we don't need - # to wrap system header files, but has the disadvantage that calls - # to hidden symbols defined in other source files cannot be - # optimized by the compiler. The -fvisibility=hidden flag does - # hide and export symbols correctly. - #VISIBILITY_FLAGS='-I$(dist_includedir)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' - #WRAP_SYSTEM_INCLUDES=1 - VISIBILITY_FLAGS="-fvisibility=hidden" - WRAP_SYSTEM_INCLUDES= - fi - fi -fi # GNU_CC - -fi # SKIP_COMPILER_CHECKS - -if test -z "$SKIP_PATH_CHECKS"; then - for ac_prog in perl5 perl -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3017: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$PERL" in - /*) - ac_cv_path_PERL="$PERL" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_PERL="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - ;; -esac -fi -PERL="$ac_cv_path_PERL" -if test -n "$PERL"; then - echo "$ac_t""$PERL" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$PERL" && break -done -test -n "$PERL" || PERL="echo not_perl" - -elif test -z "$PERL"; then - PERL=perl -fi - -OBJ_SUFFIX=o -LIB_SUFFIX=a -DLL_SUFFIX=so -ASM_SUFFIX=s -MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@' -PR_MD_ASFILES= -PR_MD_CSRCS= -PR_MD_ARCH_DIR=unix -AR_FLAGS='cr $@' -AS='$(CC)' -ASFLAGS='$(CFLAGS)' - -if test -n "$CROSS_COMPILE"; then - OS_ARCH=`echo $target_os | sed -e 's|/|_|g'` - OS_RELEASE= - OS_TEST="${target_cpu}" - case "${target_os}" in - linux*) OS_ARCH=Linux ;; - solaris*) OS_ARCH=SunOS OS_RELEASE=5 ;; - mingw*) OS_ARCH=WINNT ;; - wince*) OS_ARCH=WINCE ;; - winmo*) OS_ARCH=WINCE ;; - darwin*) OS_ARCH=Darwin ;; - riscos*) OS_ARCH=RISCOS ;; - esac -else - OS_ARCH=`uname -s | sed -e 's|/|_|g'` - OS_RELEASE=`uname -r` - OS_TEST=`uname -m` -fi - -if test "$OS_ARCH" = "IRIX64"; then - OS_ARCH=IRIX -fi - -if test "$OS_ARCH" = "AIX"; then - OS_RELEASE=`uname -v`.`uname -r` -fi - -if test "$OS_ARCH" = "FreeBSD"; then - OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'` -fi - -if test "$OS_ARCH" = "Linux"; then - OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'` - OS_RELEASE=`echo $OS_RELEASE | awk -F\. '{ print $1 "." $2 }'` -fi - -####################################################################### -# Master "Core Components" macros for getting the OS target # -####################################################################### - -# -# Note: OS_TARGET should be specified on the command line for gmake. -# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built. -# The difference between the Win95 target and the WinNT target is that -# the WinNT target uses Windows NT specific features not available -# in Windows 95. The Win95 target will run on Windows NT, but (supposedly) -# at lesser performance (the Win95 target uses threads; the WinNT target -# uses fibers). -# -# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no -# cross-compilation. -# - -# -# The following hack allows one to build on a WIN95 machine (as if -# s/he were cross-compiling on a WINNT host for a WIN95 target). -# It also accomodates for MKS's uname.exe. If you never intend -# to do development on a WIN95 machine, you don't need this hack. -# -case "$OS_ARCH" in -WIN95) - OS_ARCH=WINNT - OS_TARGET=WIN95 - ;; -Windows_95) - OS_ARCH=Windows_NT - OS_TARGET=WIN95 - ;; -Windows_98) - OS_ARCH=Windows_NT - OS_TARGET=WIN95 - ;; -CYGWIN_9*|CYGWIN_ME*) - OS_ARCH='CYGWIN_NT-4.0' - OS_TARGET=WIN95 - ;; -OS_2) - OS_ARCH=OS2 - OS_TARGET=OS2 - ;; -esac - -# -# On WIN32, we also define the variable CPU_ARCH. -# - -case "$OS_ARCH" in -WINNT) - CPU_ARCH=`uname -p` - if test "$CPU_ARCH" = "I386"; then - CPU_ARCH=x86 - fi - ;; -Windows_NT) -# -# If uname -s returns "Windows_NT", we assume that we are using -# the uname.exe in MKS toolkit. -# -# The -r option of MKS uname only returns the major version number. -# So we need to use its -v option to get the minor version number. -# Moreover, it doesn't have the -p option, so we need to use uname -m. -# - OS_ARCH=WINNT - OS_MINOR_RELEASE=`uname -v` - if test "$OS_MINOR_RELEASE" = "00"; then - OS_MINOR_RELEASE=0 - fi - OS_RELEASE="${OS_RELEASE}.${OS_MINOR_RELEASE}" - CPU_ARCH=`uname -m` - # - # MKS's uname -m returns "586" on a Pentium machine. - # - if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then - CPU_ARCH=x86 - fi - ;; -CYGWIN_NT*|MINGW*_NT*) -# -# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using -# the uname.exe in the Cygwin tools. -# If uname -s returns MINGW32_NT-5.1, we assume that we are using -# the uname.exe in the MSYS tools. -# - OS_RELEASE=`expr $OS_ARCH : '.*NT-\(.*\)'` - OS_ARCH=WINNT - CPU_ARCH=`uname -m` - # - # Cygwin's uname -m returns "i686" on a Pentium Pro machine. - # - if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then - CPU_ARCH=x86 - fi - ;; -esac - -if test -n "$MOZILLA_CLIENT" && test "$OS_ARCH" = "WINNT"; then - OS_TARGET=WIN95 - if test -n "$MOZ_DEBUG"; then - USE_DEBUG_RTL=1 - fi -fi -if test -z "$OS_TARGET"; then - OS_TARGET=$OS_ARCH -fi -if test "$OS_TARGET" = "WIN95"; then - OS_RELEASE="4.0" -fi -OS_CONFIG="${OS_TARGET}${OS_RELEASE}" - -# Check whether --enable-os2-high-mem or --disable-os2-high-mem was given. -if test "${enable_os2_high_mem+set}" = set; then - enableval="$enable_os2_high_mem" - if test "$enableval" = "no"; then - MOZ_OS2_HIGH_MEMORY= - else - MOZ_OS2_HIGH_MEMORY=1 - fi -fi - - - -case "$target" in -arm*-android*|arm*-linuxandroid*) - MOZ_THUMB=yes - MOZ_ARCH=armv7-a - MOZ_FPU=vfp - MOZ_FLOAT_ABI=softfp - MOZ_SOFT_FLOAT=yes - ;; -arm*-*) - if test -n "$MOZ_PLATFORM_MAEMO"; then - MOZ_THUMB=no - MOZ_ARCH=armv7-a - MOZ_FLOAT_ABI=softfp - fi - if test "$MOZ_PLATFORM_MAEMO" = 6; then - MOZ_THUMB=yes - fi - ;; -esac - -# Check whether --enable-thumb2 or --disable-thumb2 was given. -if test "${enable_thumb2+set}" = set; then - enableval="$enable_thumb2" - MOZ_THUMB=$enableval -fi - - -# Check whether --with-thumb or --without-thumb was given. -if test "${with_thumb+set}" = set; then - withval="$with_thumb" - if test -z "$GNU_CC"; then - { echo "configure: error: --with-thumb is not supported on non-GNU toolchain-defaults" 1>&2; exit 1; } - fi - MOZ_THUMB=$withval -fi - - -# Check whether --with-thumb-interwork or --without-thumb-interwork was given. -if test "${with_thumb_interwork+set}" = set; then - withval="$with_thumb_interwork" - if test -z "$GNU_CC"; then - { echo "configure: error: --with-thumb-interwork is not supported on non-GNU toolchain-defaults" 1>&2; exit 1; } - fi - MOZ_THUMB_INTERWORK=$withval -fi - - -# Check whether --with-arch or --without-arch was given. -if test "${with_arch+set}" = set; then - withval="$with_arch" - if test -z "$GNU_CC"; then - { echo "configure: error: --with-arch is not supported on non-GNU toolchain-defaults" 1>&2; exit 1; } - fi - MOZ_ARCH=$withval -fi - - -# Check whether --with-fpu or --without-fpu was given. -if test "${with_fpu+set}" = set; then - withval="$with_fpu" - if test -z "$GNU_CC"; then - { echo "configure: error: --with-fpu is not supported on non-GNU toolchain-defaults" 1>&2; exit 1; } - fi - MOZ_FPU=$withval -fi - - -# Check whether --with-float-abi or --without-float-abi was given. -if test "${with_float_abi+set}" = set; then - withval="$with_float_abi" - if test -z "$GNU_CC"; then - { echo "configure: error: --with-float-abi is not supported on non-GNU toolchain-defaults" 1>&2; exit 1; } - fi - MOZ_FLOAT_ABI=$withval -fi - - -# Check whether --with-soft-float or --without-soft-float was given. -if test "${with_soft_float+set}" = set; then - withval="$with_soft_float" - if test -z "$GNU_CC"; then - { echo "configure: error: --with-soft-float is not supported on non-GNU toolchain-defaults" 1>&2; exit 1; } - fi - MOZ_SOFT_FLOAT=$withval -fi - - -case "$MOZ_ARCH" in -toolchain-default|"") - arch_flag="" - ;; -*) - arch_flag="-march=$MOZ_ARCH" - ;; -esac - -case "$MOZ_THUMB" in -yes) - MOZ_THUMB2=1 - thumb_flag="-mthumb" - ;; -no) - MOZ_THUMB2= - thumb_flag="-marm" - ;; -*) - _SAVE_CFLAGS="$CFLAGS" - CFLAGS="$arch_flag" - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - MOZ_THUMB2=1 -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - MOZ_THUMB2= -fi -rm -f conftest* - CFLAGS="$_SAVE_CFLAGS" - thumb_flag="" - ;; -esac - -case "$MOZ_THUMB_INTERWORK" in -yes) - thumb_interwork_flag="-mthumb-interwork" - ;; -no) - thumb_interwork_flag="-mno-thumb-interwork" - ;; -*) # toolchain-default - thumb_interwork_flag="" - ;; -esac - -case "$MOZ_FPU" in -toolchain-default|"") - fpu_flag="" - ;; -*) - fpu_flag="-mfpu=$MOZ_FPU" - ;; -esac - -case "$MOZ_FLOAT_ABI" in -toolchain-default|"") - float_abi_flag="" - ;; -*) - float_abi_flag="-mfloat-abi=$MOZ_FLOAT_ABI" - ;; -esac - -case "$MOZ_SOFT_FLOAT" in -yes) - soft_float_flag="-msoft-float" - ;; -no) - soft_float_flag="-mno-soft-float" - ;; -*) # toolchain-default - soft_float_flag="" - ;; -esac - -all_flags=`echo $arch_flag $thumb_flag $thumb_interwork_flag $fpu_flag $float_abi_flag $soft_float_flag` -if test -n "$all_flags"; then - _SAVE_CFLAGS="$CFLAGS" - CFLAGS="$all_flags" - echo $ac_n "checking whether the chosen combination of compiler flags ($all_flags) works""... $ac_c" 1>&6 -echo "configure:3408: checking whether the chosen combination of compiler flags ($all_flags) works" >&5 - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - echo "$ac_t""yes" 1>&6 -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - { echo "configure: error: no" 1>&2; exit 1; } -fi -rm -f conftest* - - CFLAGS="$_SAVE_CFLAGS $all_flags" - CXXFLAGS="$CXXFLAGS $all_flags" - ASFLAGS="$ASFLAGS $all_flags" - if test -n "$thumb_flag"; then - LDFLAGS="$LDFLAGS $thumb_flag" - fi -fi - -case "$host" in -*-mingw*) - NSINSTALL=nsinstall - ;; -*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*) - NSINSTALL='$(CYGWIN_WRAPPER) nsinstall' - if test `echo "${PATH}" | grep -c \;` = 0; then - CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper' - fi - ;; -*-beos*) - HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE" - ;; -*os2*) - ;; -*) - HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX" - ;; -esac - -case "$target" in - -*-aix*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define AIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define SYSV 1 -EOF - - DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib' - ac_safe=`echo "sys/atomic_op.h" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for sys/atomic_op.h""... $ac_c" 1>&6 -echo "configure:3474: checking for sys/atomic_op.h" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3484: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define AIX_HAVE_ATOMIC_OP_H 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi - - case "${target_os}" in - aix3.2*) - cat >> confdefs.h <<\EOF -#define AIX_RENAME_SELECT 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_NO_LARGE_FILES 1 -EOF - - AIX_LINK_OPTS='-bnso -berok' - PR_MD_ASFILES=os_AIX.s - ;; - aix4.1*) - cat >> confdefs.h <<\EOF -#define AIX_TIMERS 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_NO_LARGE_FILES 1 -EOF - - cat >> confdefs.h <<\EOF -#define AIX4_1 1 -EOF - - MKSHLIB= - DSO_LDOPTS= - AIX_LINK_OPTS='-bnso -berok' - LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)_shr' - LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)_shr' - ;; - aix4.2*) - cat >> confdefs.h <<\EOF -#define AIX_TIMERS 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_OFF64_T 1 -EOF - - AIX_LINK_OPTS='-brtl -bnso -berok' - ;; - aix4.3*) - cat >> confdefs.h <<\EOF -#define AIX_TIMERS 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_OFF64_T 1 -EOF - - cat >> confdefs.h <<\EOF -#define AIX4_3_PLUS 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_SOCKLEN_T 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_FCNTL_FILE_LOCKING 1 -EOF - - USE_IPV6=1 - AIX_LINK_OPTS='-brtl -bnso -berok' - ;; - *) - cat >> confdefs.h <<\EOF -#define AIX_TIMERS 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_OFF64_T 1 -EOF - - cat >> confdefs.h <<\EOF -#define AIX4_3_PLUS 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_SOCKLEN_T 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_FCNTL_FILE_LOCKING 1 -EOF - - USE_IPV6=1 - AIX_LINK_OPTS='-brtl -bnso -berok' - ;; - esac - CFLAGS="$CFLAGS -qro -qroconst" - AIX_WRAP='$(DIST)/lib/aixwrap.o' - AIX_TMP='./_aix_tmp.o' - if test -n "$USE_64"; then - MDCPUCFG_H=_aix64.cfg - OBJECT_MODE=64 - else - MDCPUCFG_H=_aix32.cfg - fi - PR_MD_CSRCS=aix.c - RESOLVE_LINK_SYMBOLS=1 - ;; - -*-beos*) - cat >> confdefs.h <<\EOF -#define XP_BEOS 1 -EOF - - cat >> confdefs.h <<\EOF -#define BeOS 1 -EOF - - cat >> confdefs.h <<\EOF -#define BEOS 1 -EOF - - cat >> confdefs.h <<\EOF -#define _POSIX_SOURCE 1 -EOF - - DSO_LDOPTS=-nostart - MDCPUCFG_H=_beos.cfg - USE_BTHREADS=1 - PR_MD_ARCH_DIR=beos - RESOLVE_LINK_SYMBOLS=1 - case "${target_cpu}" in - i*86) - _OPTIMIZE_FLAGS=-O2 - _DEBUG_FLAGS='-gdwarf-2 -O0' - MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@' - echo $ac_n "checking for gethostbyaddr in -lbind""... $ac_c" 1>&6 -echo "configure:3641: checking for gethostbyaddr in -lbind" >&5 -ac_lib_var=`echo bind'_'gethostbyaddr | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lbind $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - OS_LIBS="$OS_LIBS -lbind -lsocket" -else - echo "$ac_t""no" 1>&6 -fi - - ;; - powerpc) - CC=mwcc - CCC=mwcc - LD=mwld - DSO_LDOPTS='-xms -export pragma -init _init_routine_ -term _term_routine_ -lroot -lnet /boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o /boot/develop/lib/ppc/start_dyn.o' - _OPTIMIZE_FLAGS=-O2 - _DEBUG_FLAGS='-g -O0' - ;; - esac - ;; - -*-bsdi*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define BSDI 1 -EOF - - cat >> confdefs.h <<\EOF -#define NEED_BSDREGEX 1 -EOF - - - CFLAGS="$CFLAGS -Wall -Wno-format" - CXXFLAGS="$CXXFLAGS -Wall -Wno-format" - - if echo "$OS_TEST" | grep -c 86 >/dev/null; then - CPU_ARCH=x86 - elif echo "$OS_TEST" | grep -c sparc >/dev/null; then - CPU_ARCH=sparc - fi - - MDCPUCFG_H=_bsdi.cfg - PR_MD_CSRCS=bsdi.c - - DSO_LDOPTS=-r - - case "$target_os" in - bsdi1.1*) - cat >> confdefs.h <<\EOF -#define _PR_BSDI_JMPBUF_IS_ARRAY 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_STAT_HAS_ONLY_ST_ATIME 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_NEED_H_ERRNO 1 -EOF - - MKSHLIB= - DSO_CFLAGS= - DSO_LDOPTS= - ;; - - bsdi2.1*) - cat >> confdefs.h <<\EOF -#define _PR_TIMESPEC_HAS_TS_SEC 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_BSDI_JMPBUF_IS_ARRAY 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_DLL 1 -EOF - - cat >> confdefs.h <<\EOF -#define USE_DLFCN 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_STAT_HAS_ST_ATIMESPEC 1 -EOF - - PR_MD_ASFILES=os_BSD_OS_386_2.s - ;; - - bsdi4.* | bsdi5.*) - cat >> confdefs.h <<\EOF -#define _PR_SELECT_CONST_TIMEVAL 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_BSDI_JMPBUF_IS_STRUCT 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_DLL 1 -EOF - - cat >> confdefs.h <<\EOF -#define USE_DLFCN 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_STAT_HAS_ST_ATIMESPEC 1 -EOF - - MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)' - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-shared -Wl,-soname,$(@:$(OBJDIR)/%.so=%.so)' - STRIP="$STRIP -d" - case "$target_os" in - bsdi4.2* | bsdi4.3* | bsdi5.*) - cat >> confdefs.h <<\EOF -#define _PR_HAVE_GETPROTO_R 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_GETPROTO_R_POINTER 1 -EOF - - ;; - esac - ;; - *) - cat >> confdefs.h <<\EOF -#define _PR_SELECT_CONST_TIMEVAL 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_BSDI_JMPBUF_IS_STRUCT 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_DLL 1 -EOF - - cat >> confdefs.h <<\EOF -#define USE_DLFCN 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_STAT_HAS_ST_ATIMESPEC 1 -EOF - - ;; - esac - - ;; - -*-darwin*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define DARWIN 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_BSD_FLOCK 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_SOCKLEN_T 1 -EOF - - AS='$(CC) -x assembler-with-cpp' - CFLAGS="$CFLAGS -Wall -fno-common" - case "${target_cpu}" in - arm*) - CPU_ARCH=arm - ;; - i*86*) - if test -n "$USE_64"; then - CPU_ARCH=x86_64 - else - CPU_ARCH=i386 - fi - ;; - x86_64) - CPU_ARCH=x86_64 - ;; - *) - CPU_ARCH=ppc - ;; - esac - if test "`echo $CC | grep -c '\-arch '`" = "0"; then - CC="$CC -arch $CPU_ARCH" - fi - ac_safe=`echo "crt_externs.h" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for crt_externs.h""... $ac_c" 1>&6 -echo "configure:3869: checking for crt_externs.h" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3879: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - : -else - echo "$ac_t""no" 1>&6 -fi - - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names' - _OPTIMIZE_FLAGS=-O2 - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - STRIP="$STRIP -x -S" - DLL_SUFFIX=dylib - USE_PTHREADS=1 - MDCPUCFG_H=_darwin.cfg - PR_MD_CSRCS=darwin.c - PR_MD_ASFILES=os_Darwin.s - - # Add Mac OS X support for loading CFM & CFBundle plugins - if test -f "${MACOS_SDK_DIR}/System/Library/Frameworks/Carbon.framework/Carbon"; then - cat >> confdefs.h <<\EOF -#define XP_MACOSX 1 -EOF - - OS_TARGET=MacOSX - - if test -n "$_MACOSX_DEPLOYMENT_TARGET" ; then - export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET - elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then - case "${target_cpu}" in - powerpc*) - export MACOSX_DEPLOYMENT_TARGET=10.2 - ;; - i*86*) - export MACOSX_DEPLOYMENT_TARGET=10.4 - ;; - esac - fi - - - if test "$MACOS_SDK_DIR"; then - - if test ! -d "$MACOS_SDK_DIR"; then - { echo "configure: error: SDK not found. When using --with-macos-sdk, you must -specify a valid SDK. SDKs are installed when the optional cross-development -tools are selected during the Xcode/Developer Tools installation." 1>&2; exit 1; } - fi - - - CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'` - GCC_VERSION_FULL=`echo $CC_VERSION | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'` - GCC_VERSION=`echo $GCC_VERSION_FULL | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'` - - GCC_VERSION_MAJOR=`echo $GCC_VERSION_FULL | $PERL -pe 's/(^\d*).*/$1/;'` - if test "$GCC_VERSION_MAJOR" -lt "4" ; then - SDK_C_FRAMEWORK="-F${MACOS_SDK_DIR}/System/Library/Frameworks" - if test -d "${MACOS_SDK_DIR}/Library/Frameworks" ; then - SDK_C_FRAMEWORK="$SDK_C_FRAMEWORK -F${MACOS_SDK_DIR}/Library/Frameworks" - fi - - SDK_C_INCLUDE="-isystem ${MACOS_SDK_DIR}/usr/include/gcc/darwin/${GCC_VERSION} -isystem ${MACOS_SDK_DIR}/usr/include ${SDK_C_FRAMEWORK}" - - CFLAGS="$CFLAGS -nostdinc ${SDK_C_INCLUDE}" - - CPP="$CPP -nostdinc ${SDK_C_INCLUDE}" - - - HOST_DARWIN_MAJOR=`echo "$build_os" | sed -E -e 's/^darwin([0-9]+).*$/\1/'` - - if test "$HOST_DARWIN_MAJOR" -lt 9 ; then - MACOS_SDK_LIBS="-L${MACOS_SDK_DIR}/usr/lib/gcc/darwin -L${MACOS_SDK_DIR}/usr/lib/gcc/darwin/${GCC_VERSION_FULL} -L${MACOS_SDK_DIR}/usr/lib ${SDK_C_FRAMEWORK}" - else - MACOS_SDK_LIBS="-Wl,-syslibroot,${MACOS_SDK_DIR}" - fi - - LDFLAGS="${MACOS_SDK_LIBS} $LDFLAGS" - export NEXT_ROOT=$MACOS_SDK_DIR - - if test -n "$CROSS_COMPILE" ; then - HOST_CC="NEXT_ROOT= $HOST_CC" - HOST_CXX="NEXT_ROOT= $HOST_CXX" - fi - else - CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}" - - CPP="$CPP -isysroot ${MACOS_SDK_DIR}" - - if test "$GCC_VERSION_FULL" != "4.0.0" ; then - LDFLAGS="$LDFLAGS -isysroot ${MACOS_SDK_DIR}" - else - LDFLAGS="$LDFLAGS -Wl,-syslibroot,${MACOS_SDK_DIR}" - fi - fi - fi - fi - ;; - -*-dgux*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_LOCAL_THREADS_ONLY 1 -EOF - - cat >> confdefs.h <<\EOF -#define SVR4 1 -EOF - - cat >> confdefs.h <<\EOF -#define SYSV 1 -EOF - - cat >> confdefs.h <<\EOF -#define DGUX 1 -EOF - - cat >> confdefs.h <<\EOF -#define _DGUX_SOURCE 1 -EOF - - cat >> confdefs.h <<\EOF -#define _POSIX4A_DRAFT6_SOURCE 1 -EOF - - DSO_LDOPTS=-G - _OPTIMIZE_FLAGS=-O2 - _DEBUG_FLAGS= - MDCPUCFG_H=_dgux.cfg - PR_MD_CSRCS=dgux.c - ;; - -*-freebsd*) - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - fi - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define FREEBSD 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_BSD_FLOCK 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_SOCKLEN_T 1 -EOF - - CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall" - MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf` - if test "$MOZ_OBJFORMAT" = "elf"; then - DLL_SUFFIX=so - else - DLL_SUFFIX=so.1.0 - fi - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' - MDCPUCFG_H=_freebsd.cfg - PR_MD_CSRCS=freebsd.c - ;; - -*-hpux*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define HPUX 1 -EOF - - cat >> confdefs.h <<\EOF -#define _HPUX_SOURCE 1 -EOF - - # OSF1 and HPUX report the POLLHUP event for a socket when the - # shutdown(SHUT_WR) operation is called for the remote end, even though - # the socket is still writeable. Use select(), instead of poll(), to - # workaround this problem. - cat >> confdefs.h <<\EOF -#define _PR_POLL_WITH_SELECT 1 -EOF - - cat >> confdefs.h <<\EOF -#define _USE_BIG_FDS 1 -EOF - - DSO_LDOPTS='-b +h $(notdir $@)' - PR_MD_CSRCS=hpux.c - if test "$OS_TEST" = "ia64"; then - DLL_SUFFIX=so - DSO_LDOPTS="$DSO_LDOPTS +b '\$\$ORIGIN'" - CPU_ARCH_TAG=_$OS_TEST - if test -z "$USE_64"; then - COMPILER_TAG=_32 - fi - PR_MD_ASFILES=os_HPUX_ia64.s - else - cat >> confdefs.h <<\EOF -#define hppa 1 -EOF - - DLL_SUFFIX=sl - PR_MD_ASFILES=os_HPUX.s - fi - if test -n "$USE_64"; then - MDCPUCFG_H=_hpux64.cfg - else - MDCPUCFG_H=_hpux32.cfg - fi - if test -z "$GNU_CC"; then - CC="$CC -Ae" - CXX="$CXX -ext" - DSO_CFLAGS=+Z - else - DSO_CFLAGS=-fPIC - ASFLAGS="$ASFLAGS -x assembler-with-cpp" - fi - - if test -n "$MOZILLA_CLIENT"; then - DEFAULT_IMPL_STRATEGY=_EMU - fi - - if echo "$OS_RELEASE" | grep ^A.09 >/dev/null; then - cat >> confdefs.h <<\EOF -#define _PR_NEED_H_ERRNO 1 -EOF - - cat >> confdefs.h <<\EOF -#define HPUX9 1 -EOF - - DEFAULT_IMPL_STRATEGY=_EMU - USE_NSPR_THREADS=1 - fi - - if echo "$OS_RELEASE" | egrep '^(A.09|B.10)' >/dev/null; then - cat >> confdefs.h <<\EOF -#define _PR_NO_LARGE_FILES 1 -EOF - - fi - - if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then - cat >> confdefs.h <<\EOF -#define _PR_NEED_H_ERRNO 1 -EOF - - fi - - if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then - cat >> confdefs.h <<\EOF -#define HAVE_INT_LOCALTIME_R 1 -EOF - - fi - - if echo "$OS_RELEASE" | egrep '^(B.10.30|B.11)' >/dev/null; then - cat >> confdefs.h <<\EOF -#define HAVE_POINTER_LOCALTIME_R 1 -EOF - - fi - - # HP-UX 11i v2 (B.11.23) or higher - - case "$OS_RELEASE" in - [C-Z]*|B.[2-9]*|B.1[2-9]*|B.11.[3-9]*|B.11.2[3-9]*) - USE_IPV6=1 - ;; - esac - - - if test "$OS_RELEASE" = "B.10.01"; then - cat >> confdefs.h <<\EOF -#define HPUX10 1 -EOF - - DEFAULT_IMPL_STRATEGY=_EMU - fi - - if test "$OS_RELEASE" = "B.10.10"; then - cat >> confdefs.h <<\EOF -#define HPUX10 1 -EOF - - cat >> confdefs.h <<\EOF -#define HPUX10_10 1 -EOF - - DEFAULT_IMPL_STRATEGY=_PTH - fi - - if test "$OS_RELEASE" = "B.10.20"; then - cat >> confdefs.h <<\EOF -#define HPUX10 1 -EOF - - cat >> confdefs.h <<\EOF -#define HPUX10_20 1 -EOF - - if test -z "$GNU_CC"; then - CFLAGS="$CFLAGS +DAportable +DS1.1" - CXXFLAGS="$CXXFLAGS +DAportable +DS1.1" - fi - DEFAULT_IMPL_STRATEGY=_PTH - fi - - if test "$OS_RELEASE" = "B.10.30"; then - cat >> confdefs.h <<\EOF -#define HPUX10 1 -EOF - - cat >> confdefs.h <<\EOF -#define HPUX10_30 1 -EOF - - if test -z "$GNU_CC"; then - CFLAGS="$CFLAGS +DAportable +DS1.1" - CXXFLAGS="$CXXFLAGS +DAportable +DS1.1" - fi - DEFAULT_IMPL_STRATEGY=_PTH - fi - - if echo "$OS_RELEASE" | grep ^B.11 >/dev/null; then - cat >> confdefs.h <<\EOF -#define HPUX10 1 -EOF - - cat >> confdefs.h <<\EOF -#define HPUX11 1 -EOF - - cat >> confdefs.h <<\EOF -#define _LARGEFILE64_SOURCE 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_OFF64_T 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_FCNTL_FILE_LOCKING 1 -EOF - - if test -z "$GNU_CC"; then - if test -z "$USE_64"; then - if test "$OS_TEST" = "ia64"; then - CFLAGS="$CFLAGS +DD32" - CXXFLAGS="$CXXFLAGS +DD32" - else - CFLAGS="$CFLAGS +DAportable +DS2.0" - CXXFLAGS="$CXXFLAGS +DAportable +DS2.0" - fi - else - if test "$OS_TEST" = "ia64"; then - CFLAGS="$CFLAGS +DD64" - CXXFLAGS="$CXXFLAGS +DD64" - else - CFLAGS="$CFLAGS +DA2.0W +DS2.0" - CXXFLAGS="$CXXFLAGS +DA2.0W +DS2.0" - fi - fi - fi - DEFAULT_IMPL_STRATEGY=_PTH - fi - - if test "$DEFAULT_IMPL_STRATEGY" = "_EMU"; then - USE_NSPR_THREADS=1 - USE_PTHREADS= - USE_USER_PTHREADS= - elif test "$DEFAULT_IMPL_STRATEGY" = "_PTH"; then - USE_PTHREADS=1 - if test "$USE_NSPR_THREADS"; then - USE_PTHREADS= - fi - if test "$USE_USER_PTHREADS"; then - USE_PTHREADS= - fi - fi - ;; - -*-irix*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define IRIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define SVR4 1 -EOF - - cat >> confdefs.h <<\EOF -#define _SGI_MP_SOURCE 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_FCNTL_FILE_LOCKING 1 -EOF - - PR_MD_CSRCS=irix.c - PR_MD_ASFILES=os_Irix.s - MKSHLIB='$(LD) $(DSO_LDOPTS) -rdata_shared -shared -soname $(notdir $@) -o $@' - STRIP="$STRIP -f" - RESOLVE_LINK_SYMBOLS=1 - if test -n "$USE_64"; then - MDCPUCFG_H=_irix64.cfg - else - MDCPUCFG_H=_irix32.cfg - fi - case "${target_os}" in - irix6*) - cat >> confdefs.h <<\EOF -#define IRIX6 1 -EOF - - USE_PTHREADS=1 - USE_N32=1 - COMPILER_TAG=_n32 - IMPL_STRATEGY=_PTH - ;; - irix5*) - cat >> confdefs.h <<\EOF -#define IRIX5 1 -EOF - - USE_NSPR_THREADS=1 - ;; - *) - USE_PTHREADS=1 - USE_N32=1 - ;; - esac - if test "$GNU_CC"; then - AS='$(CC) -Wp,-P -x assembler-with-cpp -D_ASM -mips2 $(INCLUDES)' - CFLAGS="$CFLAGS -Wall -Wno-format" - _OPTIMIZE_FLAGS="-O6" - else - if test -n "$USE_N32"; then - AS='as -D_ASM $(INCLUDES) -n32' - else - AS='as -D_ASM $(INCLUDES)' - fi - CFLAGS="$CFLAGS -fullwarn -xansi" - if test "$USE_N32"; then - _OPTIMIZE_FLAGS="-O -OPT:Olimit=4000" - else - _OPTIMIZE_FLAGS="-O -Olimit 4000" - fi - if test "$USE_MDUPDATE"; then - CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)" - fi - case "${target}" in - *-irix6.*) - CFLAGS="$CFLAGS -multigot" - DSO_LDOPTS="-no_unresolved" - if test "$USE_N32"; then - CFLAGS="$CFLAGS -n32 -woff 1209" - DSO_LDOPTS="$DSO_LDOPTS -n32" - else - if test "$USE_64"; then - CFLAGS="$CFLAGS -64" - else - CFLAGS="$CFLAGS -32" - fi - fi - ;; - *) - CFLAGS="$CFLAGS -xgot" - ;; - esac - fi - if test "${target_os}" = "irix5.3"; then - cat >> confdefs.h <<\EOF -#define IRIX5_3 1 -EOF - - fi - case "${target_os}" in - irix6.5) - if test -z "$GNU_CC"; then - CFLAGS="$CFLAGS -mips3" - fi - cat >> confdefs.h <<\EOF -#define _PR_HAVE_GETPROTO_R 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_GETPROTO_R_POINTER 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_SGI_PRDA_PROCMASK 1 -EOF - - ;; - irix5*) - ;; - *) - cat >> confdefs.h <<\EOF -#define _PR_HAVE_SGI_PRDA_PROCMASK 1 -EOF - - ;; - esac - ;; - -*-linux*|*-gnu*|*-k*bsd*-gnu|*-android*|*-linuxandroid*) - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - IMPL_STRATEGY=_PTH - fi - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define _GNU_SOURCE 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_FCNTL_FILE_LOCKING 1 -EOF - - case "${target}" in - *-android*|*-linuxandroid*) - OS_TARGET=Android - cat >> confdefs.h <<\EOF -#define LINUX 1 -EOF - - ;; - *-linux*) - cat >> confdefs.h <<\EOF -#define LINUX 1 -EOF - - ;; - esac - CFLAGS="$CFLAGS -Wall" - CXXFLAGS="$CXXFLAGS -Wall" - MDCPUCFG_H=_linux.cfg - PR_MD_CSRCS=linux.c - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' - _OPTIMIZE_FLAGS=-O2 - _DEBUG_FLAGS="-g -fno-inline" # most people on linux use gcc/gdb, and that - # combo is not yet good at debugging inlined - # functions (even when using DWARF2 as the - # debugging format) - COMPILER_TAG=_glibc - if echo "$OS_TEST" | grep -c 86 >/dev/null; then - CPU_ARCH=x86 - else - CPU_ARCH=$OS_TEST - fi - CPU_ARCH_TAG=_${CPU_ARCH} - case "${target_cpu}" in - alpha) - cat >> confdefs.h <<\EOF -#define _ALPHA_ 1 -EOF - - cat >> confdefs.h <<\EOF -#define __alpha 1 -EOF - - CFLAGS="$CFLAGS -mieee" - CXXFLAGS="$CXXFLAGS -mieee" - ;; - i*86) - cat >> confdefs.h <<\EOF -#define i386 1 -EOF - - PR_MD_ASFILES=os_Linux_x86.s - ;; - ia64) - PR_MD_ASFILES=os_Linux_ia64.s - ;; - x86_64) - if test -n "$USE_64"; then - PR_MD_ASFILES=os_Linux_x86_64.s - else - cat >> confdefs.h <<\EOF -#define i386 1 -EOF - - PR_MD_ASFILES=os_Linux_x86.s - CC="$CC -m32" - CXX="$CXX -m32" - fi - ;; - ppc|powerpc) - PR_MD_ASFILES=os_Linux_ppc.s - ;; - powerpc64) - if test -n "$USE_64"; then - CC="$CC -m64" - CXX="$CXX -m64" - else - PR_MD_ASFILES=os_Linux_ppc.s - fi - ;; - m68k) - CFLAGS="$CFLAGS -m68020-60" - CXXFLAGS="$CXXFLAGS -m68020-60" - ;; - esac - ;; - -*-mingw*|*-cygwin*|*-msvc*|*-mks*) - cat >> confdefs.h <<\EOF -#define XP_PC 1 -EOF - - cat >> confdefs.h <<\EOF -#define WIN32 1 -EOF - - PR_MD_ARCH_DIR=windows - RESOLVE_LINK_SYMBOLS=1 - - if test -n "$GNU_CC"; then - CC="$CC -mwindows" - CXX="$CXX -mwindows" - DLL_SUFFIX=dll - MKSHLIB='$(CC) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(IMPORT_LIBRARY) $(DLLBASE) -o $(subst $(OBJDIR)/,,$(SHARED_LIBRARY))' - RC=$WINDRES - # Use temp file for windres (bug 213281) - RCFLAGS='-O coff --use-temp-file' - else - CC=cl - CXX=cl - LD=link - AR='lib -NOLOGO -OUT:"$@"' - AR_FLAGS= - RANLIB='echo not_ranlib' - STRIP='echo not_strip' - RC=rc.exe - GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb' - OBJ_SUFFIX=obj - LIB_SUFFIX=lib - DLL_SUFFIX=dll - - # Determine compiler version - - _MSVC_VER_FILTER='s|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p' - - CC_VERSION=`"${CC}" -v 2>&1 | sed -ne "$_MSVC_VER_FILTER"` - _CC_MAJOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $1 }'` - _CC_MINOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $2 }'` - _CC_RELEASE=`echo ${CC_VERSION} | awk -F\. '{ print $3 }'` - _CC_BUILD=`echo ${CC_VERSION} | awk -F\. '{ print $4 }'` - MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION} - - if test "$_CC_MAJOR_VERSION" -eq "14"; then - if test $_CC_RELEASE -gt 50727; then - _USE_DYNAMICBASE=1 - elif test $_CC_BUILD -ge 762; then - _USE_DYNAMICBASE=1 - fi - cat >> confdefs.h <<\EOF -#define _CRT_SECURE_NO_DEPRECATE 1 -EOF - - cat >> confdefs.h <<\EOF -#define _CRT_NONSTDC_NO_DEPRECATE 1 -EOF - - elif test $_CC_MAJOR_VERSION -ge 15; then - _USE_DYNAMICBASE=1 - cat >> confdefs.h <<\EOF -#define _CRT_SECURE_NO_WARNINGS 1 -EOF - - cat >> confdefs.h <<\EOF -#define _CRT_NONSTDC_NO_WARNINGS 1 -EOF - - fi - - if test -n "$_USE_DYNAMICBASE"; then - DLLFLAGS="$DLLFLAGS -DYNAMICBASE" - fi - - # Ensure that mt is Microsoft (R) Manifest Tool and not magnetic - # tape manipulation utility (or something else) - if test "$MSC_VER" -ge "1400"; then - - _MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p' - - - MSMT_TOOL=`mt 2>&1|grep 'Microsoft (R) Manifest Tool'` - if test -n "$MSMT_TOOL"; then - MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"` - if test -z "$MSMANIFEST_TOOL_VERSION"; then - echo "configure: warning: Unknown version of the Microsoft (R) Manifest Tool." 1>&2 - fi - MT=mt - unset MSMT_TOOL - else - { echo "configure: error: Microsoft (R) Manifest Tool must be in your \$PATH." 1>&2; exit 1; } - fi - fi - - CFLAGS="$CFLAGS -W3 -nologo -GF -Gy" - DLLFLAGS="$DLLFLAGS -OUT:\"\$@\"" - _DEBUG_FLAGS=-Zi - _OPTIMIZE_FLAGS=-O2 - - PROFILE_GEN_CFLAGS="-GL" - PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT" - PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952" - PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE" - - if test -z "$MOZ_OPTIMIZE"; then - CFLAGS="$CFLAGS -Od" - fi - - if test -n "$USE_DEBUG_RTL"; then - CFLAGS="$CFLAGS -MDd" - else - CFLAGS="$CFLAGS -MD" - fi - - if test -n "$MOZ_DEBUG"; then - cat >> confdefs.h <<\EOF -#define _DEBUG 1 -EOF - - else - DEFINES="$DEFINES -U_DEBUG" - fi - - if test -n "$MOZ_DEBUG_SYMBOLS"; then - if test -n "$MOZ_OPTIMIZE"; then - DLLFLAGS="$DLLFLAGS -DEBUG -OPT:REF" - LDFLAGS="$LDFLAGS -DEBUG -OPT:REF" - else - DLLFLAGS="$DLLFLAGS -DEBUG" - LDFLAGS="$LDFLAGS -DEBUG" - fi - fi - - OS_DLLFLAGS="-nologo -DLL -SUBSYSTEM:WINDOWS" - if test "$MSC_VER" -le "1200" -a -z "$MOZ_DEBUG_SYMBOLS"; then - OS_DLLFLAGS="$OS_DLLFLAGS -PDB:NONE" - fi - - if test "$OS_TARGET" = "WINNT"; then - CFLAGS="$CFLAGS -GT" - LIBNSPR='$(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - LIBPLC='$(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - else - LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - fi - fi # GNU_CC - - if test -n "$USE_STATIC_TLS"; then - cat >> confdefs.h <<\EOF -#define _PR_USE_STATIC_TLS 1 -EOF - - fi - - if test "$OS_TARGET" = "WINNT"; then - cat >> confdefs.h <<\EOF -#define WINNT 1 -EOF - - else - cat >> confdefs.h <<\EOF -#define WIN95 1 -EOF - - # undefine WINNT as some versions of mingw gcc define it by default - DEFINES="$DEFINES -UWINNT" - cat >> confdefs.h <<\EOF -#define _PR_GLOBAL_THREADS_ONLY 1 -EOF - - fi - - if test "$CPU_ARCH" = "x86"; then - CPU_ARCH_TAG= - else - CPU_ARCH_TAG=$CPU_ARCH - fi - - if test -n "$USE_DEBUG_RTL"; then - OBJDIR_SUFFIX=OBJD - fi - - case "$OS_TARGET" in - WINNT) - MDCPUCFG_H=_winnt.cfg - ;; - WIN95) - MDCPUCFG_H=_win95.cfg - ;; - *) - { echo "configure: error: Missing OS_TARGET for ${target}. Use --enable-win32-target to set." 1>&2; exit 1; } - ;; - esac - - case "$target_cpu" in - i*86) - if test -n "$USE_64"; then - cat >> confdefs.h <<\EOF -#define _AMD64_ 1 -EOF - - else - cat >> confdefs.h <<\EOF -#define _X86_ 1 -EOF - - fi - ;; - x86_64) - cat >> confdefs.h <<\EOF -#define _AMD64_ 1 -EOF - - USE_64=1 - ;; - ia64) - cat >> confdefs.h <<\EOF -#define _IA64_ 1 -EOF - - USE_64=1 - ;; - *) - cat >> confdefs.h <<\EOF -#define _CPU_ARCH_NOT_DEFINED 1 -EOF - - ;; - esac - ;; - -*-wince*|*-winmo*) - cat >> confdefs.h <<\EOF -#define XP_PC 1 -EOF - - cat >> confdefs.h <<\EOF -#define WIN32 1 -EOF - - cat >> confdefs.h <<\EOF -#define WINCE 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_GLOBAL_THREADS_ONLY 1 -EOF - - - AR_FLAGS='-NOLOGO -OUT:"$@"' - - OBJ_SUFFIX=obj - LIB_SUFFIX=lib - DLL_SUFFIX=dll - MKSHLIB='$(LD) -DLL $(DSO_LDOPTS) -OUT:$@' - - PR_MD_ARCH_DIR=windows - RESOLVE_LINK_SYMBOLS=1 - - MDCPUCFG_H=_win95.cfg - LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - - DLLFLAGS='-OUT:"$@"' - if test -n "$MOZ_DEBUG_SYMBOLS"; then - OS_LDFLAGS='-DEBUG -DEBUGTYPE:CV' - OS_DLLFLAGS='-DEBUG -DEBUGTYPE:CV' - DSO_LDOPTS='-DEBUG -DEBUGTYPE:CV' - fi - _DEBUG_FLAGS=-Zi - _OPTIMIZE_FLAGS=-O2 - ;; - -*-netbsd*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define NETBSD 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_BSD_FLOCK 1 -EOF - - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - fi - MDCPUCFG_H=_netbsd.cfg - PR_MD_CSRCS=netbsd.c - - DSO_CFLAGS='-fPIC -DPIC' - CFLAGS="$CFLAGS -ansi -Wall" - CXXFLAGS="$CXXFLAGS -ansi -Wall" - MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)' - - if test -z "$OBJECT_FMT"; then - if echo __ELF__ | ${CC-cc} -E - | grep -q __ELF__ 2>/dev/null; then - OBJECT_FMT=a.out - DLL_SUFFIX=so.1.0 - DSO_LDOPTS='-shared' - else - OBJECT_FMT=ELF - DLL_SUFFIX=so - DSO_LDOPTS='-shared -Wl,-soname,$(notdir $@)' - fi - fi - - if test "$LIBRUNPATH"; then - DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH" - fi - ;; - -*-nto*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define NTO 1 -EOF - - cat >> confdefs.h <<\EOF -#define _QNX_SOURCE 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_POINTER_LOCALTIME_R 1 -EOF - - MDCPUCFG_H=_nto.cfg - PR_MD_CSRCS=nto.c - MKSHLIB='$(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(notdir $@) -o $@' - DSO_CFLAGS=-fPIC - DSO_LDOPTS=-shared - OS_LIBS="$OS_LIBS -lsocket" - _OPTIMIZE_FLAGS="-O1" - _DEBUG_FLAGS="-gstabs" - ;; - -*-openbsd*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define OPENBSD 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_BSD_FLOCK 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_SOCKLEN_T 1 -EOF - - CFLAGS="$CFLAGS -ansi -Wall" - CXXFLAGS="$CXXFLAGS -ansi -Wall" - DLL_SUFFIX=so.1.0 - DSO_CFLAGS=-fPIC - MDCPUCFG_H=_openbsd.cfg - PR_MD_CSRCS=openbsd.c - OS_LIBS="-lc" - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - fi - DSO_LDOPTS='-shared -fPIC' - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - ;; - -*-osf*) - SHELL_OVERRIDE="SHELL = /usr/bin/ksh" - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define OSF1 1 -EOF - - cat >> confdefs.h <<\EOF -#define _REENTRANT 1 -EOF - - # OSF1 and HPUX report the POLLHUP event for a socket when the - # shutdown(SHUT_WR) operation is called for the remote end, even though - # the socket is still writeable. Use select(), instead of poll(), to - # workaround this problem. - cat >> confdefs.h <<\EOF -#define _PR_POLL_WITH_SELECT 1 -EOF - - - if echo "$OS_RELEASE" | egrep -c '(V2.0|V3.2)' 2>/dev/null ; then - USE_NSPR_THREADS=1 - fi - - if test -z "$GNU_CC"; then - CC="$CC -std1 -ieee_with_inexact" - if test "$OS_RELEASE" != "V2.0"; then - CC="$CC -readonly_strings" - fi - _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000" - ac_safe=`echo "machine/builtins.h" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for machine/builtins.h""... $ac_c" 1>&6 -echo "configure:4923: checking for machine/builtins.h" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4933: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define OSF1_HAVE_MACHINE_BUILTINS_H 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi - - else - CFLAGS="$CFLAGS -mieee" - CXXFLAGS="$CXXFLAGS -mieee" - fi - - if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then - cat >> confdefs.h <<\EOF -#define HAVE_INT_LOCALTIME_R 1 -EOF - - else - cat >> confdefs.h <<\EOF -#define HAVE_FCNTL_FILE_LOCKING 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_POINTER_LOCALTIME_R 1 -EOF - - fi - if echo $OS_RELEASE | grep -c V4.0 >/dev/null; then - cat >> confdefs.h <<\EOF -#define OSF1V4_MAP_PRIVATE_BUG 1 -EOF - - fi - DSO_LDOPTS='-shared -all -expect_unresolved "*" -soname $(notdir $@)' - MDCPUCFG_H=_osf1.cfg - PR_MD_CSRCS=osf1.c - ;; - -*-qnx*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define QNX 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_NEED_H_ERRNO 1 -EOF - - USE_NSPR_THREADS=1 - MDCPUCFG_H=_qnx.cfg - PR_MD_CSRCS=qnx.c - ;; - -*-riscos*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define RISCOS 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_NEED_H_ERRNO 1 -EOF - - USE_PTHREADS=1 - MDCPUCFG_H=_riscos.cfg - PR_MD_CSRCS=riscos.c - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - ;; - -*-*-sco*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define SCO 1 -EOF - - cat >> confdefs.h <<\EOF -#define sco 1 -EOF - - cat >> confdefs.h <<\EOF -#define SYSV 1 -EOF - - cat >> confdefs.h <<\EOF -#define _SVID3 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_NEED_H_ERRNO 1 -EOF - - CC='cc -b elf -KPIC' - CXX='$(NSDEPTH)/build/hcpp CC +.cpp +w' - USE_NSPR_THREADS=1 - CPU_ARCH=x86 - DSO_LDOPTS='-b elf -G' - MDCPUCFG_H=_scoos.cfg - PR_MD_SRCS=scoos.c - ;; - -*-solaris*) - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - fi - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define SVR4 1 -EOF - - cat >> confdefs.h <<\EOF -#define SYSV 1 -EOF - - cat >> confdefs.h <<\EOF -#define __svr4 1 -EOF - - cat >> confdefs.h <<\EOF -#define __svr4__ 1 -EOF - - cat >> confdefs.h <<\EOF -#define SOLARIS 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_FCNTL_FILE_LOCKING 1 -EOF - - CPU_ARCH=`uname -p` - MDCPUCFG_H=_solaris.cfg - PR_MD_CSRCS=solaris.c - LD=/usr/ccs/bin/ld - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - RESOLVE_LINK_SYMBOLS=1 - case "${OS_RELEASE}" in - 5.8|5.9) - ;; - *) - # It is safe to use the -Bdirect linker flag on Solaris 10 or later. - USE_B_DIRECT=1 - ;; - esac - if test -n "$GNU_CC"; then - DSO_CFLAGS=-fPIC - if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then - GCC_USE_GNU_LD=1 - fi - DSO_LDOPTS='-shared -Wl,-h,$(notdir $@),-z,combreloc,-z,defs,-z,ignore' - if test -n "$USE_B_DIRECT"; then - DSO_LDOPTS="$DSO_LDOPTS,-Bdirect" - fi - else - DSO_CFLAGS=-KPIC - DSO_LDOPTS='-G -h $(notdir $@) -z combreloc -z defs -z ignore' - if test -n "$USE_B_DIRECT"; then - DSO_LDOPTS="$DSO_LDOPTS -Bdirect" - fi - fi - if test -n "$GNU_CC"; then - CFLAGS="$CFLAGS -Wall" - CXXFLAGS="$CXXFLAGS -Wall" - if test -n "$USE_MDUPDATE"; then - CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)" - CXXFLAGS="$CXXFLAGS -MDupdate \$(DEPENDENCIES)" - fi - GCC_AS=`$CC -print-prog-name=as` - if test "`echo | $GCC_AS -v 2>&1 | grep -c GNU`" != "0"; then - GNU_AS=1 - fi - else - CFLAGS="$CFLAGS -xstrconst" - CXXFLAGS="$CXXFLAGS -Qoption cg -xstrconst -features=tmplife" - if test -z "$MOZ_OPTIMIZE"; then - CFLAGS="$CFLAGS -xs" - CXXFLAGS="$CXXFLAGS -xs" - fi - _OPTIMIZE_FLAGS=-xO4 - fi - if test -z "$GNU_AS"; then - ASFLAGS="$ASFLAGS -Wa,-P" - fi - if test -n "$USE_64"; then - if test -n "$GNU_CC"; then - CC="$CC -m64" - CXX="$CXX -m64" - else - if test "$OS_TEST" = "i86pc"; then - CC="$CC -xarch=amd64" - CXX="$CXX -xarch=amd64" - else - CC="$CC -xarch=v9" - CXX="$CXX -xarch=v9" - fi - fi - fi - if test "$OS_TEST" = "i86pc"; then - if test -z "$USE_64"; then - cat >> confdefs.h <<\EOF -#define i386 1 -EOF - - fi - CPU_ARCH_TAG=_$OS_TEST - # The default debug format, DWARF (-g), is not supported by gcc - # on i386-ANY-sysv4/solaris, but the stabs format is. It is - # assumed that the Solaris assembler /usr/ccs/bin/as is used. - # If your gcc uses GNU as, you do not need the -Wa,-s option. - if test -n "$MOZ_DEBUG" && test -n "$GNU_CC"; then - _DEBUG_FLAGS=-gstabs - if test -z "$GNU_AS"; then - _DEBUG_FLAGS="$_DEBUG_FLAGS -Wa,-s" - fi - fi - fi - case "${target_os}" in - solaris2.3*) - cat >> confdefs.h <<\EOF -#define _PR_NO_LARGE_FILES 1 -EOF - - ;; - solaris2.4*) - cat >> confdefs.h <<\EOF -#define _PR_NO_LARGE_FILES 1 -EOF - - ;; - solaris2.5*) - cat >> confdefs.h <<\EOF -#define SOLARIS2_5 1 -EOF - - ;; - *) - cat >> confdefs.h <<\EOF -#define _PR_HAVE_OFF64_T 1 -EOF - - # The lfcompile64(5) man page on Solaris 2.6 says: - # For applications that do not wish to conform to the POSIX or - # X/Open specifications, the 64-bit transitional interfaces - # are available by default. No compile-time flags need to be - # set. - # But gcc 2.7.2.x fails to define _LARGEFILE64_SOURCE by default. - # The native compiler, gcc 2.8.x, and egcs don't have this problem. - if test -n "$GNU_CC"; then - cat >> confdefs.h <<\EOF -#define _LARGEFILE64_SOURCE 1 -EOF - - fi - ;; - esac - case "${target_os}" in - solaris2.3*) - ;; - solaris2.4*) - ;; - solaris2.5*) - ;; - solaris2.6*) - ;; - solaris2.7*) - ;; - *) - # Solaris 8 or higher has IPv6. - cat >> confdefs.h <<\EOF -#define _PR_INET6 1 -EOF - - ;; - esac - if test "$CPU_ARCH" = "sparc"; then - # 64-bit Solaris SPARC requires V9 architecture, so the following - # is not needed. - if test -z "$USE_64"; then - ULTRASPARC_LIBRARY=nspr_flt - fi - fi - # Purify requires that binaries linked against nspr also - # be linked against -lrt (or -lposix4) so add it to OS_LIBS - _rev=`uname -r` - _librt=`echo $_rev 5.6 | awk '{ if ($1 > $2) print "-lrt"; else print "-lposix4" }'` - OS_LIBS="$OS_LIBS $_librt" - ;; - -*-sco-sysv5*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define UNIXWARE 1 -EOF - - cat >> confdefs.h <<\EOF -#define SVR4 1 -EOF - - cat >> confdefs.h <<\EOF -#define SYSV 1 -EOF - - USE_NSPR_THREADS=1 - if echo $OS_RELEASE | grep -c 2.1 2>/dev/null; then - cat >> confdefs.h <<\EOF -#define _PR_NO_LARGE_FILES 1 -EOF - - CC='$(NSDEPTH)/build/hcc cc' - CXX='$(NSDEPTH)/build/hcpp CC' - MDCPUCFG_H=_unixware.cfg - else - cat >> confdefs.h <<\EOF -#define _LARGEFILE64_SOURCE 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_OFF64_T 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_SOCKADDR_LEN 1 -EOF - - MDCPUCFG_H=_unixware7.cfg - fi - PR_MD_CSRCS=unixware.c - DSO_LDOPTS=-G - CPU_ARCH=x86 - ;; - -*-symbian*) - # Check whether --with-symbian-sdk or --without-symbian-sdk was given. -if test "${with_symbian_sdk+set}" = set; then - withval="$with_symbian_sdk" - SYMBIAN_SDK_DIR=$withval -fi - - - echo ----------------------------------------------------------------------------- - echo Building with Symbian SDK in: $SYMBIAN_SDK_DIR - echo ----------------------------------------------------------------------------- - - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - cat >> confdefs.h <<\EOF -#define SYMBIAN 1 -EOF - - cat >> confdefs.h <<\EOF -#define __arm__ 1 -EOF - - cat >> confdefs.h <<\EOF -#define __SYMBIAN32__ 1 -EOF - - cat >> confdefs.h <<\EOF -#define _UNICODE 1 -EOF - - cat >> confdefs.h <<\EOF -#define NDEBUG 1 -EOF - - cat >> confdefs.h <<\EOF -#define __SUPPORT_CPP_EXCEPTIONS__ 1 -EOF - - cat >> confdefs.h <<\EOF -#define MOZ_STDERR_TO_STDOUT 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_FCNTL_FILE_LOCKING 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_SOCKLEN_T 1 -EOF - - USE_PTHREADS=1 - LIB_SUFFIX=lib - DLL_SUFFIX=dll - MKSHLIB= - DSO_LDOPTS= - DSO_CFLAGS= - VISIBILITY_FLAGS= - MDCPUCFG_H=_symbian.cfg - PR_MD_CSRCS=symbian.c - NSINSTALL=nsinstall - RANLIB='echo no ranlib ' - CPU_ARCH=ARM - OS_ARCH=SYMBIAN - OS_EXE_CFLAGS="$OS_EXE_CFLAGS -D__EXE__" - CFLAGS="$CFLAGS -MD -nostdinc" - SYMBIAN_SYS_INCLUDE="-I$SYMBIAN_SDK_DIR/Epoc32/include/variant -I$SYMBIAN_SDK_DIR/Epoc32/include -I$SYMBIAN_SDK_DIR/Epoc32/include/stdapis" - echo ------------------------------------------------------- - echo SYMBIAN_SYS_INCLUDE is: $SYMBIAN_SYS_INCLUDE - echo ------------------------------------------------------- - case "$OS_TARGET" in - WINSCW) - CC=mwccsym2.exe - CXX=mwccsym2.exe - LD=mwldsym2.exe - AR=mwldsym2.exe - WINSCW_LD_DIR="\$(SYMBIAN_SDK_DIR)/EPOC32/RELEASE/WINSCW/UDEB" - CFLAGS="$CFLAGS -O0 -inline off -wchar_t off -align 4 -warnings on -w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostderr -gccdep -cwd source -i- -I\$(VPATH)" - SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include Symbian_OS_v9.2.hrh" - AR_FLAGS="-library -msgstyle gcc -stdlib -subsystem windows -noimplib -o \$@" - cat >> confdefs.h <<\EOF -#define _DEBUG 1 -EOF - - cat >> confdefs.h <<\EOF -#define __CW32__ 1 -EOF - - cat >> confdefs.h <<\EOF -#define __WINS__ 1 -EOF - - cat >> confdefs.h <<\EOF -#define __WINSCW__ 1 -EOF - - DEFINES="$DEFINES -U_WIN32" - ;; - GCCE) - CFLAGS="$CFLAGS -Wall -Wno-unknown-pragmas -fexceptions -march=armv5t -mapcs -pipe -x c -msoft-float" - CXXFLAGS="$CXXFLAGS $CFLAGS -Wno-ctor-dtor-privacy" - SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include $SYMBIAN_SDK_DIR/EPOC32/INCLUDE/GCCE/GCCE.h" - cat >> confdefs.h <<\EOF -#define __GCCE__ 1 -EOF - - cat >> confdefs.h <<\EOF -#define __EABI__ 1 -EOF - - DEFINES="$DEFINES -D__PRODUCT_INCLUDE__=$SYMBIAN_SDK_DIR/Epoc32/include/variant/Symbian_OS_v9.2.hrh" - ;; - *) - { echo "configure: error: Missing OS_TARGET for ${target}. Set --enable-symbian-target to with 'WINSCW' or 'GCCE'." 1>&2; exit 1; } - ;; - esac - CFLAGS="$CFLAGS ${SYMBIAN_SYS_INCLUDE}" - ;; - -*-os2*) - cat >> confdefs.h <<\EOF -#define XP_OS2 1 -EOF - - cat >> confdefs.h <<\EOF -#define XP_PC 1 -EOF - - cat >> confdefs.h <<\EOF -#define BSD_SELECT 1 -EOF - - cat >> confdefs.h <<\EOF -#define TCPV40HDRS 1 -EOF - - LIB_SUFFIX=lib - DLL_SUFFIX=dll - RC=rc.exe - PR_MD_ARCH_DIR=os2 - PROG_SUFFIX=.exe - NSINSTALL=nsinstall - MDCPUCFG_H=_os2.cfg - RESOLVE_LINK_SYMBOLS=1 - - cat >> confdefs.h <<\EOF -#define OS2 1 -EOF - - AR=emxomfar - AR_FLAGS='r $@' - CFLAGS="$CFLAGS -Wall -Zomf" - CXXFLAGS="$CFLAGS -Wall -Zomf" - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - DSO_CFLAGS= - DSO_LDOPTS='-Zomf -Zdll' - LDFLAGS='-Zmap' - _OPTIMIZE_FLAGS="-O2 -s" - _DEBUG_FLAGS="-g -fno-inline" - if test -n "$MOZ_OPTIMIZE"; then - DSO_LDOPTS="$DSO_LDOPTS -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA" - fi - IMPLIB='emximp -o' - FILTER='emxexp -o' - if test -n "$MOZ_OS2_HIGH_MEMORY"; then - LDFLAGS="$LDFLAGS -Zhigh-mem" - cat >> confdefs.h <<\EOF -#define MOZ_OS2_HIGH_MEMORY 1 -EOF - - fi - - # GCC for OS/2 currently predefines these, but we don't want them - DEFINES="$DEFINES -Uunix -U__unix -U__unix__" - ;; - -*) - cat >> confdefs.h <<\EOF -#define XP_UNIX 1 -EOF - - ;; - -esac - -if test -z "$SKIP_LIBRARY_CHECKS"; then - - - -case $target in -*-darwin*|*-beos*|*-os2*) - ;; -*) - echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:5492: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6 -echo "configure:5528: checking for dlfcn.h" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5538: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - OS_LIBS="-ldl $OS_LIBS" -else - echo "$ac_t""no" 1>&6 -fi - -else - echo "$ac_t""no" 1>&6 -fi - - ;; -esac - - - - -if test $ac_cv_prog_gcc = yes; then - echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 -echo "configure:5571: 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 < -Autoconf TIOCGETP -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "$ac_pattern" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_prog_gcc_traditional=yes -else - rm -rf conftest* - ac_cv_prog_gcc_traditional=no -fi -rm -f conftest* - - - if test $ac_cv_prog_gcc_traditional = no; then - cat > conftest.$ac_ext < -Autoconf TCGETA -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "$ac_pattern" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_prog_gcc_traditional=yes -fi -rm -f conftest* - - fi -fi - -echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 - if test $ac_cv_prog_gcc_traditional = yes; then - CC="$CC -traditional" - fi -fi - -_SAVE_LIBS="$LIBS" -LIBS="$LIBS $OS_LIBS" -for ac_func in lchown strerror dladdr -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5621: 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 < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -$ac_func(); -#endif - -; return 0; } -EOF -if { (eval echo configure:5649: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_$ac_func=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <&6 -fi -done - -LIBS="$_SAVE_LIBS" - - - -# Check whether --with-ccache or --without-ccache was given. -if test "${with_ccache+set}" = set; then - withval="$with_ccache" - CCACHE=$withval -else - CCACHE="no" -fi - - -if test "$CCACHE" != "no"; then - if test -n "$CCACHE"; then - if test "$CCACHE" = "yes"; then - CCACHE= - else - if test ! -e "$CCACHE"; then - { echo "configure: error: $CCACHE not found" 1>&2; exit 1; } - fi - fi - fi - for ac_prog in $CCACHE ccache -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5701: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_CCACHE'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$CCACHE" in - /*) - ac_cv_path_CCACHE="$CCACHE" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_CCACHE="$CCACHE" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_CCACHE="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - ;; -esac -fi -CCACHE="$ac_cv_path_CCACHE" -if test -n "$CCACHE"; then - echo "$ac_t""$CCACHE" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$CCACHE" && break -done - - if test -z "$CCACHE" -o "$CCACHE" = ":"; then - { echo "configure: error: ccache not found" 1>&2; exit 1; } - elif test -x "$CCACHE"; then - CC="$CCACHE $CC" - CXX="$CCACHE $CXX" - else - { echo "configure: error: $CCACHE is not executable" 1>&2; exit 1; } - fi -fi - -# Check whether --enable-strip or --disable-strip was given. -if test "${enable_strip+set}" = set; then - enableval="$enable_strip" - if test "$enableval" = "yes"; then - ENABLE_STRIP=1 - fi -fi - - -case "${target_os}" in -hpux*) -if test -z "$GNU_CC"; then - - echo $ac_n "checking for +Olit support""... $ac_c" 1>&6 -echo "configure:5760: checking for +Olit support" >&5 -if eval "test \"`echo '$''{'ac_cv_hpux_usable_olit_option'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_cv_hpux_usable_olit_option=no - rm -f conftest* - echo 'int main() { return 0; }' | cat > conftest.c - ${CC-cc} ${CFLAGS} +Olit=all -o conftest conftest.c > conftest.out 2>&1 - if test $? -eq 0; then - if test -z "`egrep -i '(unrecognize|unknown)' conftest.out`"; then - ac_cv_hpux_usable_olit_option=yes - fi - fi - rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_hpux_usable_olit_option" 1>&6 - - if test "$ac_cv_hpux_usable_olit_option" = "yes"; then - CFLAGS="$CFLAGS +Olit=all" - CXXFLAGS="$CXXFLAGS +Olit=all" - else - CFLAGS="$CFLAGS +ESlit" - CXXFLAGS="$CXXFLAGS +ESlit" - fi -fi -;; -esac - - - -case "$target_os" in -darwin*) - _HAVE_PTHREADS=1 - ;; -wince*) - _HAVE_PTHREADS= - ;; -*) - -echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6 -echo "configure:5802: checking for pthread_create in -lpthreads" >&5 -echo " - #include - void *foo(void *v) { return v; } - int main() { - pthread_t t; - if (!pthread_create(&t, 0, &foo, 0)) { - pthread_join(t, 0); - } - return 0; - }" > dummy.c ; - echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthreads $LDFLAGS $LIBS" 1>&5; - ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthreads $LDFLAGS $LIBS 2>&5; - _res=$? ; - rm -f dummy.c dummy${ac_exeext} ; - if test "$_res" = "0"; then - echo "$ac_t""yes" 1>&6 - _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads" - else - echo "$ac_t""no" 1>&6 - -echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6 -echo "configure:5824: checking for pthread_create in -lpthread" >&5 -echo " - #include - void *foo(void *v) { return v; } - int main() { - pthread_t t; - if (!pthread_create(&t, 0, &foo, 0)) { - pthread_join(t, 0); - } - return 0; - }" > dummy.c ; - echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthread $LDFLAGS $LIBS" 1>&5; - ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthread $LDFLAGS $LIBS 2>&5; - _res=$? ; - rm -f dummy.c dummy${ac_exeext} ; - if test "$_res" = "0"; then - echo "$ac_t""yes" 1>&6 - _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread" - else - echo "$ac_t""no" 1>&6 - -echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6 -echo "configure:5846: checking for pthread_create in -lc_r" >&5 -echo " - #include - void *foo(void *v) { return v; } - int main() { - pthread_t t; - if (!pthread_create(&t, 0, &foo, 0)) { - pthread_join(t, 0); - } - return 0; - }" > dummy.c ; - echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc_r $LDFLAGS $LIBS" 1>&5; - ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc_r $LDFLAGS $LIBS 2>&5; - _res=$? ; - rm -f dummy.c dummy${ac_exeext} ; - if test "$_res" = "0"; then - echo "$ac_t""yes" 1>&6 - _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r" - else - echo "$ac_t""no" 1>&6 - -echo $ac_n "checking for pthread_create in -lc""... $ac_c" 1>&6 -echo "configure:5868: checking for pthread_create in -lc" >&5 -echo " - #include - void *foo(void *v) { return v; } - int main() { - pthread_t t; - if (!pthread_create(&t, 0, &foo, 0)) { - pthread_join(t, 0); - } - return 0; - }" > dummy.c ; - echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc $LDFLAGS $LIBS" 1>&5; - ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc $LDFLAGS $LIBS 2>&5; - _res=$? ; - rm -f dummy.c dummy${ac_exeext} ; - if test "$_res" = "0"; then - echo "$ac_t""yes" 1>&6 - _HAVE_PTHREADS=1 - - else - echo "$ac_t""no" 1>&6 - - fi - - - fi - - - fi - - - fi - - ;; -esac - -# Check whether --with-pthreads or --without-pthreads was given. -if test "${with_pthreads+set}" = set; then - withval="$with_pthreads" - if test "$withval" = "yes"; then - if test -n "$_HAVE_PTHREADS"; then - USE_PTHREADS=1 - USE_USER_PTHREADS= - USE_NSPR_THREADS= - else - { echo "configure: error: --with-pthreads specified for a system without pthread support " 1>&2; exit 1; }; - fi - else - USE_PTHREADS= - _PTHREAD_LDFLAGS= - fi -else - if test -n "$_HAVE_PTHREADS" && test -z "$USE_USER_PTHREADS" && test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - USE_USER_PTHREADS= - USE_NSPR_THREADS= - fi -fi - - -# Check whether --enable-user-pthreads or --disable-user-pthreads was given. -if test "${enable_user_pthreads+set}" = set; then - enableval="$enable_user_pthreads" - if test "$enableval" = "yes"; then - if test -n "$_HAVE_PTHREADS"; then - USE_PTHREADS= - USE_USER_PTHREADS=1 - USE_NSPR_THREADS= - else - { echo "configure: error: --enable-user-pthreads specified for a system without pthread support " 1>&2; exit 1; }; - fi - fi -fi - - -# Check whether --enable-nspr-threads or --disable-nspr-threads was given. -if test "${enable_nspr_threads+set}" = set; then - enableval="$enable_nspr_threads" - if test "$enableval" = "yes"; then - USE_PTHREADS= - USE_USER_PTHREADS= - USE_NSPR_THREADS=1 - fi -fi - - -case "$target" in -*-beos*) - # Check whether --with-bthreads or --without-bthreads was given. -if test "${with_bthreads+set}" = set; then - withval="$with_bthreads" - if test "$withval" = "yes"; then - USE_BTHREADS=1 - USE_USER_PTHREADS= - USE_PTHREADS= - fi -fi - - ;; -esac - -fi # SKIP_LIBRARY_CHECKS - -# Check whether --enable-ipv6 or --disable-ipv6 was given. -if test "${enable_ipv6+set}" = set; then - enableval="$enable_ipv6" - if test "$enableval" = "yes"; then - USE_IPV6=1 - else - USE_IPV6= - fi -fi - - -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:5986: checking whether ${CC-cc} accepts -pthread" >&5 - echo 'int main() { return 0; }' | cat > conftest.c - ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1 - if test $? -eq 0; then - if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthread`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then - ac_cv_have_dash_pthread=yes - case "$target_os" in - freebsd*) -# Freebsd doesn't use -pthread for compiles, it uses them for linking - ;; - *) - CFLAGS="$CFLAGS -pthread" - CXXFLAGS="$CXXFLAGS -pthread" - ;; - esac - fi - fi - rm -f conftest* - echo "$ac_t""$ac_cv_have_dash_pthread" 1>&6 - - ac_cv_have_dash_pthreads=no - if test "$ac_cv_have_dash_pthread" = "no"; then - echo $ac_n "checking whether ${CC-cc} accepts -pthreads""... $ac_c" 1>&6 -echo "configure:6009: checking whether ${CC-cc} accepts -pthreads" >&5 - echo 'int main() { return 0; }' | cat > conftest.c - ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1 - if test $? -eq 0; then - if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthreads`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then - ac_cv_have_dash_pthreads=yes - CFLAGS="$CFLAGS -pthreads" - CXXFLAGS="$CXXFLAGS -pthreads" - fi - fi - rm -f conftest* - echo "$ac_t""$ac_cv_have_dash_pthreads" 1>&6 - fi - - case "$target" in - *-solaris*) - if test "$ac_cv_have_dash_pthreads" = "yes"; then - _PTHREAD_LDFLAGS= - fi - ;; - *-freebsd*) - cat >> confdefs.h <<\EOF -#define _REENTRANT 1 -EOF - - cat >> confdefs.h <<\EOF -#define _THREAD_SAFE 1 -EOF - - if test "$ac_cv_have_dash_pthread" = "yes"; then - _PTHREAD_LDFLAGS="-pthread" - else - _PTHREAD_LDFLAGS="-lc_r" - fi - ;; - *-netbsd*) - if test "$ac_cv_have_dash_pthread" = "yes"; then - _PTHREAD_LDFLAGS="-pthread" - fi - ;; - *-bsdi*) - cat >> confdefs.h <<\EOF -#define _THREAD_SAFE 1 -EOF - - if test "$ac_cv_have_dash_pthread" = "yes"; then - _PTHREAD_LDFLAGS= - fi - ;; - *-openbsd*) - if test "$ac_cv_have_dash_pthread" = "yes"; then - _PTHREAD_LDFLAGS=-pthread - fi - ;; - *-linux*|*-gnu*|*-k*bsd*-gnu) - cat >> confdefs.h <<\EOF -#define _REENTRANT 1 -EOF - - ;; - esac - -else - if test -n "$USE_USER_PTHREADS"; then - USE_PTHREADS= - USE_NSPR_THREADS= - else - _PTHREAD_LDFLAGS= - fi -fi - -case "$target" in -*-aix*) - if test -n "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_LOCAL_THREADS_ONLY 1 -EOF - - fi - case "$target_os" in - aix4.1*) - if test -z "$USE_PTHREADS"; then - cat >> confdefs.h <<\EOF -#define AIX_RENAME_SELECT 1 -EOF - - fi - ;; - aix4.2*) - if test -z "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define HAVE_POINTER_LOCALTIME_R 1 -EOF - - fi - ;; - aix4.3*) - if test -z "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define HAVE_POINTER_LOCALTIME_R 1 -EOF - - fi - if test -n "$USE_PTHREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_HAVE_THREADSAFE_GETHOST 1 -EOF - - fi - ;; - *) - if test -z "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define HAVE_POINTER_LOCALTIME_R 1 -EOF - - fi - if test -n "$USE_PTHREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_HAVE_THREADSAFE_GETHOST 1 -EOF - - fi - ;; - esac - ;; -*-bsdi*) - if test -n "$USE_PTHREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_NEED_PTHREAD_INIT 1 -EOF - - fi - ;; -*-freebsd*) - if test -n "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_LOCAL_THREADS_ONLY 1 -EOF - - fi - ;; -*-hpux*) - if test -n "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_LOCAL_THREADS_ONLY 1 -EOF - - fi - if test "$USE_PTHREADS"; then - if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then - cat >> confdefs.h <<\EOF -#define _REENTRANT 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_DCETHREADS 1 -EOF - - else - cat >> confdefs.h <> confdefs.h <<\EOF -#define _PR_HAVE_THREADSAFE_GETHOST 1 -EOF - - fi - fi - if test "$USE_USER_PTHREADS"; then - cat >> confdefs.h <> confdefs.h <<\EOF -#define _PR_HAVE_GETHOST_R 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_GETHOST_R_POINTER 1 -EOF - - fi - fi - ;; -*-linux*|*-gnu*|*-k*bsd*-gnu) - if test -n "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_LOCAL_THREADS_ONLY 1 -EOF - - fi - ;; -*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*|*-os2*|*-beos*) - USE_PTHREADS= - _PTHREAD_LDFLAGS= - USE_USER_PTHREADS= - ;; -*-netbsd*|*-openbsd*) - if test -n "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_LOCAL_THREADS_ONLY 1 -EOF - - fi - ;; -*-osf*) - if test -n "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_LOCAL_THREADS_ONLY 1 -EOF - - fi - if test -n "$USE_PTHREADS"; then - if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then - : - else - cat >> confdefs.h <<\EOF -#define _PR_HAVE_THREADSAFE_GETHOST 1 -EOF - - fi - fi - ;; -*-solaris*) - if test -n "$USE_NSPR_THREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_LOCAL_THREADS_ONLY 1 -EOF - - fi - if test -n "$USE_PTHREADS"; then - cat >> confdefs.h <<\EOF -#define _REENTRANT 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_POINTER_LOCALTIME_R 1 -EOF - - if test "$OS_TEST" = "i86pc"; then - if test -n "$USE_64"; then - PR_MD_ASFILES=os_SunOS_x86_64.s - else - PR_MD_ASFILES=os_SunOS_x86.s - fi - else - if test -n "$USE_64"; then - PR_MD_ASFILES=os_SunOS_sparcv9.s - fi - fi - fi - ;; -*-nto*) - if test -n "$USE_PTHREADS"; then - cat >> confdefs.h <<\EOF -#define _PR_HAVE_GETHOST_R 1 -EOF - - cat >> confdefs.h <<\EOF -#define _PR_HAVE_GETHOST_R_POINTER 1 -EOF - - fi - ;; -esac - -OS_LIBS="$_PTHREAD_LDFLAGS $OS_LIBS" - -if test -n "$_SAVE_OPTIMIZE_FLAGS"; then - _OPTIMIZE_FLAGS="$_SAVE_OPTIMIZE_FLAGS" -fi - -if test -n "$_SAVE_DEBUG_FLAGS"; then - _DEBUG_FLAGS="$_SAVE_DEBUG_FLAGS" -fi - -if test -n "$MOZ_OPTIMIZE"; then - CFLAGS="$CFLAGS $_OPTIMIZE_FLAGS" - CXXFLAGS="$CXXFLAGS $_OPTIMIZE_FLAGS" -fi - -if test -n "$MOZ_DEBUG_SYMBOLS"; then - CFLAGS="$CFLAGS $_DEBUG_FLAGS" - CXXFLAGS="$CXXFLAGS $_DEBUG_FLAGS" -fi - -if test -n "$MOZ_OPTIMIZE"; then - OBJDIR_TAG=_OPT -else - OBJDIR_TAG=_DBG -fi - -if test -n "$USE_64"; then - COMPILER_TAG=_64 -fi - -RELEASE_OBJDIR_NAME="${OS_CONFIG}${CPU_ARCH_TAG}${COMPILER_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}.${OBJDIR_SUFFIX}" - -case "$target_os" in -cygwin*|msvc*|mks*) - CC="\$(CYGWIN_WRAPPER) $CC" - CXX="\$(CYGWIN_WRAPPER) $CXX" - RC="\$(CYGWIN_WRAPPER) $RC" - ;; -esac - -# Check whether --enable-wrap-malloc or --disable-wrap-malloc was given. -if test "${enable_wrap_malloc+set}" = set; then - enableval="$enable_wrap_malloc" - if test "$enableval" = "yes"; then - _WRAP_MALLOC=1 - fi -fi - - -if test -n "$_WRAP_MALLOC"; then - if test -n "$GNU_CC"; then - WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=malloc,--wrap=calloc,--wrap=valloc,--wrap=free,--wrap=realloc,--wrap=memalign" - WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=__builtin_new,--wrap=__builtin_vec_new,--wrap=__builtin_delete,--wrap=__builtin_vec_delete" - WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=strdup,--wrap=strndup" - WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=posix_memalign,--wrap=malloc_usable_size" - else - { echo "configure: error: --enable-wrap-malloc is not supported for non-GNU toolchains" 1>&2; exit 1; } - fi -fi - -# Check whether --with-wrap-malloc or --without-wrap-malloc was given. -if test "${with_wrap_malloc+set}" = set; then - withval="$with_wrap_malloc" - WRAP_LDFLAGS="${WRAP_LDFLAGS} $withval" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -MAKEFILES=" - Makefile - config/Makefile - config/autoconf.mk - config/nsprincl.mk - config/nsprincl.sh - config/nspr-config - config/nspr.pc - lib/Makefile - lib/ds/Makefile - lib/libc/Makefile - lib/libc/include/Makefile - lib/libc/src/Makefile - lib/tests/Makefile - pkg/Makefile - pr/Makefile - pr/include/Makefile - pr/include/md/Makefile - pr/include/obsolete/Makefile - pr/include/private/Makefile - pr/src/Makefile - pr/src/io/Makefile - pr/src/linking/Makefile - pr/src/malloc/Makefile - pr/src/md/Makefile - pr/src/md/${PR_MD_ARCH_DIR}/Makefile - pr/src/memory/Makefile - pr/src/misc/Makefile - pr/src/threads/Makefile - pr/tests/Makefile - pr/tests/dll/Makefile -" - -if test "$OS_TARGET" = "Linux"; then - MAKEFILES="$MAKEFILES - pkg/linux/Makefile - " -elif test "$OS_TARGET" = "SunOS"; then - MAKEFILES="$MAKEFILES - pkg/solaris/Makefile - pkg/solaris/SUNWpr/Makefile - pkg/solaris/SUNWprd/Makefile - " -fi - -if test -z "$USE_PTHREADS" && test -z "$USE_BTHREADS"; then - MAKEFILES="$MAKEFILES - pr/src/threads/combined/Makefile - " -elif test -n "$USE_PTHREADS"; then - MAKEFILES="$MAKEFILES - pr/src/pthreads/Makefile - " -elif test -n "$USE_BTHREADS"; then - MAKEFILES="$MAKEFILES - pr/src/bthreads/Makefile - " -fi - -if test -n "$USE_CPLUS"; then - MAKEFILES="$MAKEFILES - pr/src/cplus/Makefile - pr/src/cplus/tests/Makefile - " -fi - -echo $MAKEFILES > unallmakefiles - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g -EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs - - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.13" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir - -trap 'rm -fr `echo "$MAKEFILES" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@SHELL@%$SHELL%g -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@FFLAGS@%$FFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@host@%$host%g -s%@host_alias@%$host_alias%g -s%@host_cpu@%$host_cpu%g -s%@host_vendor@%$host_vendor%g -s%@host_os@%$host_os%g -s%@target@%$target%g -s%@target_alias@%$target_alias%g -s%@target_cpu@%$target_cpu%g -s%@target_vendor@%$target_vendor%g -s%@target_os@%$target_os%g -s%@build@%$build%g -s%@build_alias@%$build_alias%g -s%@build_cpu@%$build_cpu%g -s%@build_vendor@%$build_vendor%g -s%@build_os@%$build_os%g -s%@CC@%$CC%g -s%@dist_prefix@%$dist_prefix%g -s%@dist_bindir@%$dist_bindir%g -s%@dist_includedir@%$dist_includedir%g -s%@dist_libdir@%$dist_libdir%g -s%@WHOAMI@%$WHOAMI%g -s%@HOST_CC@%$HOST_CC%g -s%@CXX@%$CXX%g -s%@RANLIB@%$RANLIB%g -s%@AR@%$AR%g -s%@AS@%$AS%g -s%@LD@%$LD%g -s%@STRIP@%$STRIP%g -s%@WINDRES@%$WINDRES%g -s%@CPP@%$CPP%g -s%@PERL@%$PERL%g -s%@CCACHE@%$CCACHE%g -s%@SHELL_OVERRIDE@%$SHELL_OVERRIDE%g -s%@MOZILLA_CLIENT@%$MOZILLA_CLIENT%g -s%@HOST_CFLAGS@%$HOST_CFLAGS%g -s%@HOST_LDFLAGS@%$HOST_LDFLAGS%g -s%@GNU_CC@%$GNU_CC%g -s%@GCC_USE_GNU_LD@%$GCC_USE_GNU_LD%g -s%@MSC_VER@%$MSC_VER%g -s%@CROSS_COMPILE@%$CROSS_COMPILE%g -s%@MOZ_OPTIMIZE@%$MOZ_OPTIMIZE%g -s%@MOZ_DEBUG@%$MOZ_DEBUG%g -s%@MOZ_DEBUG_SYMBOLS@%$MOZ_DEBUG_SYMBOLS%g -s%@USE_CPLUS@%$USE_CPLUS%g -s%@USE_IPV6@%$USE_IPV6%g -s%@USE_N32@%$USE_N32%g -s%@USE_64@%$USE_64%g -s%@OBJECT_MODE@%$OBJECT_MODE%g -s%@ENABLE_STRIP@%$ENABLE_STRIP%g -s%@USE_PTHREADS@%$USE_PTHREADS%g -s%@USE_BTHREADS@%$USE_BTHREADS%g -s%@USE_USER_PTHREADS@%$USE_USER_PTHREADS%g -s%@USE_NSPR_THREADS@%$USE_NSPR_THREADS%g -s%@LIBNSPR@%$LIBNSPR%g -s%@LIBPLC@%$LIBPLC%g -s%@MOD_MAJOR_VERSION@%$MOD_MAJOR_VERSION%g -s%@MOD_MINOR_VERSION@%$MOD_MINOR_VERSION%g -s%@MOD_PATCH_VERSION@%$MOD_PATCH_VERSION%g -s%@NSPR_MODNAME@%$NSPR_MODNAME%g -s%@MDCPUCFG_H@%$MDCPUCFG_H%g -s%@PR_MD_CSRCS@%$PR_MD_CSRCS%g -s%@PR_MD_ASFILES@%$PR_MD_ASFILES%g -s%@PR_MD_ARCH_DIR@%$PR_MD_ARCH_DIR%g -s%@CPU_ARCH@%$CPU_ARCH%g -s%@OBJ_SUFFIX@%$OBJ_SUFFIX%g -s%@LIB_SUFFIX@%$LIB_SUFFIX%g -s%@DLL_SUFFIX@%$DLL_SUFFIX%g -s%@ASM_SUFFIX@%$ASM_SUFFIX%g -s%@WRAP_LDFLAGS@%$WRAP_LDFLAGS%g -s%@MKSHLIB@%$MKSHLIB%g -s%@DSO_CFLAGS@%$DSO_CFLAGS%g -s%@DSO_LDOPTS@%$DSO_LDOPTS%g -s%@OS_TARGET@%$OS_TARGET%g -s%@OS_ARCH@%$OS_ARCH%g -s%@OS_RELEASE@%$OS_RELEASE%g -s%@OS_TEST@%$OS_TEST%g -s%@MACOSX_DEPLOYMENT_TARGET@%$MACOSX_DEPLOYMENT_TARGET%g -s%@DEFINES@%$DEFINES%g -s%@AR_FLAGS@%$AR_FLAGS%g -s%@ASFLAGS@%$ASFLAGS%g -s%@FILTER@%$FILTER%g -s%@IMPLIB@%$IMPLIB%g -s%@PROFILE_GEN_CFLAGS@%$PROFILE_GEN_CFLAGS%g -s%@PROFILE_GEN_LDFLAGS@%$PROFILE_GEN_LDFLAGS%g -s%@PROFILE_USE_CFLAGS@%$PROFILE_USE_CFLAGS%g -s%@PROFILE_USE_LDFLAGS@%$PROFILE_USE_LDFLAGS%g -s%@OS_LIBS@%$OS_LIBS%g -s%@RESOLVE_LINK_SYMBOLS@%$RESOLVE_LINK_SYMBOLS%g -s%@AIX_LINK_OPTS@%$AIX_LINK_OPTS%g -s%@NOSUCHFILE@%$NOSUCHFILE%g -s%@MOZ_OBJFORMAT@%$MOZ_OBJFORMAT%g -s%@ULTRASPARC_LIBRARY@%$ULTRASPARC_LIBRARY%g -s%@OBJDIR@%$OBJDIR%g -s%@OBJDIR_NAME@%$OBJDIR_NAME%g -s%@RELEASE_OBJDIR_NAME@%$RELEASE_OBJDIR_NAME%g -s%@NSINSTALL@%$NSINSTALL%g -s%@OPTIMIZER@%$OPTIMIZER%g -s%@RC@%$RC%g -s%@RCFLAGS@%$RCFLAGS%g -s%@DLLFLAGS@%$DLLFLAGS%g -s%@EXEFLAGS@%$EXEFLAGS%g -s%@OS_DLLFLAGS@%$OS_DLLFLAGS%g -s%@CYGWIN_WRAPPER@%$CYGWIN_WRAPPER%g -s%@VISIBILITY_FLAGS@%$VISIBILITY_FLAGS%g -s%@WRAP_SYSTEM_INCLUDES@%$WRAP_SYSTEM_INCLUDES%g -s%@MACOS_SDK_DIR@%$MACOS_SDK_DIR%g -s%@SYMBIAN_SDK_DIR@%$SYMBIAN_SDK_DIR%g -s%@NEXT_ROOT@%$NEXT_ROOT%g -s%@MT@%$MT%g - -CEOF -EOF - -cat >> $CONFIG_STATUS <<\EOF - -# Split the substitutions into bite-sized pieces for seds with -# small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. -ac_file=1 # Number of current file. -ac_beg=1 # First line for current file. -ac_end=$ac_max_sed_cmds # Line after last line for current file. -ac_more_lines=: -ac_sed_cmds="" -while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file - else - sed "${ac_end}q" conftest.subs > conftest.s$ac_file - fi - if test ! -s conftest.s$ac_file; then - ac_more_lines=false - rm -f conftest.s$ac_file - else - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f conftest.s$ac_file" - else - ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" - fi - ac_file=`expr $ac_file + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_cmds` - fi -done -if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat -fi -EOF - -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /* | ?:/*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" ` - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file -fi; done -rm -f conftest.s* - - - -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -chmod +x config/nspr-config -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - diff -Nru nspr-4.9.5/mozilla/nsprpub/configure.in nspr-4.10.7/mozilla/nsprpub/configure.in --- nspr-4.9.5/mozilla/nsprpub/configure.in 2012-12-19 19:21:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/configure.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3256 +0,0 @@ -dnl -*- Mode: Autoconf; tab-width: 4; indent-tabs-mode: nil; -*- -dnl -dnl This Source Code Form is subject to the terms of the Mozilla Public -dnl License, v. 2.0. If a copy of the MPL was not distributed with this -dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. - -AC_PREREQ(2.12) -AC_INIT(config/libc_r.h) - -AC_CONFIG_AUX_DIR(${srcdir}/build/autoconf) -AC_CANONICAL_SYSTEM - -dnl ======================================================== -dnl = Defaults -dnl ======================================================== -MOD_MAJOR_VERSION=4 -MOD_MINOR_VERSION=9 -MOD_PATCH_VERSION=5 -NSPR_MODNAME=nspr20 -_HAVE_PTHREADS= -USE_PTHREADS= -USE_USER_PTHREADS= -USE_NSPR_THREADS= -USE_N32= -USE_64= -USE_CPLUS= -USE_IPV6= -USE_MDUPDATE= -_MACOSX_DEPLOYMENT_TARGET= -_OPTIMIZE_FLAGS=-O -_DEBUG_FLAGS=-g -MOZ_DEBUG=1 -MOZ_OPTIMIZE= -OBJDIR='$(OBJDIR_NAME)' -OBJDIR_NAME=. -OBJDIR_SUFFIX=OBJ -NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall' -NOSUCHFILE=/no-such-file -LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)' -LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)' -CYGWIN_WRAPPER= -MACOS_SDK_DIR= -NEXT_ROOT= -MT= -MOZ_OS2_HIGH_MEMORY=1 -PROFILE_GEN_CFLAGS= -PROFILE_GEN_LDFLAGS= -PROFILE_USE_CFLAGS= -PROFILE_USE_LDFLAGS= - -dnl Link in libraries necessary to resolve all symbols for shared libs -RESOLVE_LINK_SYMBOLS= - -dnl ======================================================== -dnl = -dnl = Dont change the following lines. Doing so breaks: -dnl = -dnl = CFLAGS="-foo" ./configure -dnl = -dnl ======================================================== -CFLAGS="${CFLAGS=}" -CXXFLAGS="${CXXFLAGS=}" -LDFLAGS="${LDFLAGS=}" -DLLFLAGS="${DLLFLAGS=}" -HOST_CFLAGS="${HOST_CFLAGS=}" -HOST_LDFLAGS="${HOST_LDFLAGS=}" - -case "$target" in -*-cygwin*|*-mingw*) - # Check to see if we are really running in a msvc environemnt - _WIN32_MSVC= - AC_CHECK_PROGS(CC, cl) - if test "$CC" = "cl"; then - echo 'main() { return 0; }' > dummy.c - ${CC} -o dummy dummy.c >/dev/null 2>&1 - if test $? = 0; then - _WIN32_MSVC=1 - CXX=$CC - else - AC_MSG_WARN([$(CC) test failed. Using normal feature tests]) - fi - rm -f dummy dummy.o dummy.obj dummy.exe dummy.c - fi - ;; -*-msvc*) - _WIN32_MSVC=1 - ;; -*-mks*) - _WIN32_MSVC=1 - ;; -esac - -if test -n "$_WIN32_MSVC"; then - SKIP_PATH_CHECKS=1 - SKIP_COMPILER_CHECKS=1 - SKIP_LIBRARY_CHECKS=1 -fi - -dnl ======================================================== -dnl = Android uses a very custom (hacky) toolchain; we need to do this -dnl = here, so that the compiler checks can succeed -dnl ======================================================== - -AC_ARG_WITH(android-ndk, -[ --with-android-ndk=DIR - location where the Android NDK can be found], - android_ndk=$withval) - -AC_ARG_WITH(android-toolchain, -[ --with-android-toolchain=DIR - location of the Android toolchain], - android_toolchain=$withval) - -AC_ARG_WITH(android-version, -[ --with-android-version=VER - Android platform version, default 5], - android_version=$withval, - android_version=5) - -AC_ARG_WITH(android-platform, -[ --with-android-platform=DIR - location of platform dir], - android_platform=$withval) - -case "$target" in -arm-linux*-android*|*-linuxandroid*) - android_tool_prefix="arm-linux-androideabi" - ;; -i?86-*android*) - android_tool_prefix="i686-linux-android" - ;; -mipsel-*android*) - android_tool_prefix="mipsel-linux-android" - ;; -*) - android_tool_prefix="$target_os" - ;; -esac - -dnl ======================================================== -dnl = Gonk is a fork of Android used for Mozilla's B2G project. -dnl = Configuration is done largely by the top level config -dnl = and the specified gonk directory doesn't matter here. -dnl ======================================================== - -AC_ARG_WITH(gonk, -[ --with-gonk=DIR location of gonk dir], - gonkdir=$withval) - -if test -n "$gonkdir" ; then - dnl Most things are directly configured by env vars when building for gonk - - dnl prevent cross compile section from using these flags as host flags - if test -z "$HOST_CPPFLAGS" ; then - HOST_CPPFLAGS=" " - fi - if test -z "$HOST_CFLAGS" ; then - HOST_CFLAGS=" " - fi - if test -z "$HOST_CXXFLAGS" ; then - HOST_CXXFLAGS=" " - fi - if test -z "$HOST_LDFLAGS" ; then - HOST_LDFLAGS=" " - fi - - AC_DEFINE(ANDROID) -else -case "$target" in -*-android*|*-linuxandroid*) - if test -z "$android_ndk" ; then - AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.]) - fi - - if test -z "$android_toolchain" ; then - AC_MSG_CHECKING([for android toolchain directory]) - - kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"` - - case "$target_cpu" in - arm) - target_name=arm-linux-androideabi-4.4.3 - ;; - i?86) - target_name=x86-4.4.3 - ;; - mipsel) - target_name=mipsel-linux-android-4.4.3 - ;; - esac - android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86 - - if test -d "$android_toolchain" ; then - AC_MSG_RESULT([$android_toolchain]) - else - AC_MSG_ERROR([not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain.]) - fi - fi - - if test -z "$android_platform" ; then - AC_MSG_CHECKING([for android platform directory]) - - case "$target_cpu" in - arm) - target_name=arm - ;; - i?86) - target_name=x86 - ;; - mipsel) - target_name=mips - ;; - esac - - android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name" - - if test -d "$android_platform" ; then - AC_MSG_RESULT([$android_platform]) - else - AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.]) - fi - fi - - dnl Old NDK support. If minimum requirement is changed to NDK r8b, - dnl please remove this. - case "$target_cpu" in - i?86) - if ! test -e "$android_toolchain"/bin/"$android_tool_prefix"-gcc; then - dnl Old NDK toolchain name - android_tool_prefix="i686-android-linux" - fi - ;; - esac - - dnl set up compilers - AS="$android_toolchain"/bin/"$android_tool_prefix"-as - CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc - CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++ - CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp - LD="$android_toolchain"/bin/"$android_tool_prefix"-ld - AR="$android_toolchain"/bin/"$android_tool_prefix"-ar - RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib - STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip - - CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS" - CFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CFLAGS" - CXXFLAGS="-mandroid -I$android_platform/usr/include -fpic -fno-short-enums -fno-exceptions $CXXFLAGS" - LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform $LDFLAGS" - - dnl prevent cross compile section from using these flags as host flags - if test -z "$HOST_CPPFLAGS" ; then - HOST_CPPFLAGS=" " - fi - if test -z "$HOST_CFLAGS" ; then - HOST_CFLAGS=" " - fi - if test -z "$HOST_CXXFLAGS" ; then - HOST_CXXFLAGS=" " - fi - if test -z "$HOST_LDFLAGS" ; then - HOST_LDFLAGS=" " - fi - - AC_DEFINE(ANDROID) - AC_DEFINE_UNQUOTED(ANDROID_VERSION, $android_version) - ;; -esac -fi - -dnl ======================================================== -dnl = -dnl = Check options that may affect the compiler -dnl = -dnl ======================================================== -dist_prefix='${MOD_DEPTH}/dist' -dist_bindir='${dist_prefix}/bin' -dist_includedir='${dist_prefix}/include/nspr' -dist_libdir='${dist_prefix}/lib' -dnl If the --includedir option was not specified, add '/nspr' to autoconf's -dnl default value of includedir. -if test "${includedir}" = '${prefix}/include'; then - includedir='${prefix}/include/nspr' -fi - -AC_ARG_WITH(dist-prefix, - [ --with-dist-prefix=DIST_PREFIX - place build files in DIST_PREFIX [dist]], - dist_prefix=$withval) - -AC_ARG_WITH(dist-bindir, - [ --with-dist-bindir=DIR build execuatables in DIR [DIST_PREFIX/bin]], - dist_bindir=$withval) - -AC_ARG_WITH(dist-includedir, - [ --with-dist-includedir=DIR - build include files in DIR [DIST_PREFIX/include/nspr]], - dist_includedir=$withval) - -AC_ARG_WITH(dist-libdir, - [ --with-dist-libdir=DIR build library files in DIR [DIST_PREFIX/lib]], - dist_libdir=$withval) - -AC_SUBST(dist_prefix) -AC_SUBST(dist_bindir) -AC_SUBST(dist_includedir) -AC_SUBST(dist_libdir) - -dnl Check if NSPR is being compiled for Mozilla -dnl Let --with-arg override environment setting -dnl -AC_ARG_WITH(mozilla, - [ --with-mozilla Compile NSPR with Mozilla support], - [ if test "$withval" = "yes"; then - AC_DEFINE(MOZILLA_CLIENT) - MOZILLA_CLIENT=1 - else - MOZILLA_CLIENT= - fi], - [ if test -n "$MOZILLA_CLIENT"; then - AC_DEFINE(MOZILLA_CLIENT) - fi]) - -AC_ARG_ENABLE(optimize, - [ --enable-optimize[=OPT] Enable code optimizations (ie. -O2) ], - [ if test "$enableval" != "no"; then - MOZ_OPTIMIZE=1 - if test -n "$enableval" -a "$enableval" != "yes"; then - _OPTIMIZE_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` - _SAVE_OPTIMIZE_FLAGS=$_OPTIMIZE_FLAGS - fi - else - MOZ_OPTIMIZE= - fi ]) - -AC_ARG_ENABLE(debug, - [ --enable-debug[=DBG] Enable debugging (using compiler flags DBG)], - [ if test "$enableval" != "no"; then - MOZ_DEBUG=1 - MOZ_DEBUG_SYMBOLS=1 - if test -n "$enableval" -a "$enableval" != "yes"; then - _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` - _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS - fi - else - MOZ_DEBUG= - fi ], - MOZ_DEBUG_SYMBOLS=1) - -AC_ARG_ENABLE(debug-symbols, - [ --enable-debug-symbols[=DBG] Enable debugging symbols - (using compiler flags DBG)], - [ if test "$enableval" != "no"; then - MOZ_DEBUG_SYMBOLS=1 - if test -n "$enableval" -a "$enableval" != "yes"; then - if test -z "$_SAVE_DEBUG_FLAGS"; then - _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` - _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS - else - AC_MSG_ERROR([--enable-debug-symbols flags cannot be used with --enable-debug flags]) - fi - fi - else - MOZ_DEBUG_SYMBOLS= - fi ]) - -AC_ARG_ENABLE(win32-target, - [ --enable-win32-target=\$t - Specify win32 flavor. (WIN95 or WINNT)], - OS_TARGET=`echo $enableval | tr a-z A-Z`) - -AC_ARG_ENABLE(symbian-target, - [ --enable-symbian-target=\$t - Specify symbian flavor. (WINSCW or GCCE)], - OS_TARGET=`echo $enableval | tr a-z A-Z`) - -AC_ARG_ENABLE(debug-rtl, - [ --enable-debug-rtl Use the MSVC debug runtime library], - [ if test "$enableval" = "yes"; then - USE_DEBUG_RTL=1 - fi ]) - -AC_ARG_ENABLE(n32, - [ --enable-n32 Enable n32 ABI support (IRIX only)], - [ if test "$enableval" = "yes"; then - USE_N32=1 - else if test "$enableval" = "no"; then - USE_N32= - fi - fi ]) - -AC_ARG_ENABLE(64bit, - [ --enable-64bit Enable 64-bit support (on certain platforms)], - [ if test "$enableval" = "yes"; then - USE_64=1 - fi ]) - -AC_ARG_ENABLE(mdupdate, - [ --enable-mdupdate Enable use of certain compilers' mdupdate feature], - [ if test "$enableval" = "yes"; then - USE_MDUPDATE=1 - fi ]) - -AC_ARG_ENABLE(cplus, - [ --enable-cplus Enable some c++ api routines], - [ if test "$enableval" = "yes"; then - USE_CPLUS=1 - fi]) - -AC_ARG_WITH(arm-kuser, - [ --with-arm-kuser Use kuser helpers (Linux/ARM only) - (Requires kernel 2.6.13 or later)], - [ if test "$withval" = "yes"; then - AC_DEFINE(_PR_ARM_KUSER) - fi ]) - -dnl ======================================================== -dnl = Mac OS X SDK support -dnl ======================================================== -AC_ARG_WITH(macos-sdk, - [ --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)], - MACOS_SDK_DIR=$withval) - -AC_ARG_ENABLE(macos-target, - [ --enable-macos-target=VER - Set the minimum MacOS version needed at runtime - [10.2 for ppc, 10.4 for x86]], - [_MACOSX_DEPLOYMENT_TARGET=$enableval]) - -dnl ======================================================== -dnl = -dnl = Set the threading model -dnl = -dnl ======================================================== -case "$target" in - -*-aix*) - case "${target_os}" in - aix3.2*) - USE_NSPR_THREADS=1 - ;; - *) - USE_PTHREADS=1 - ;; - esac - ;; - -esac - -dnl ======================================================== -dnl = -dnl = Set the default C compiler -dnl = -dnl ======================================================== -if test -z "$CC"; then - case "$target" in - - *-aix*) - if test -z "$USE_NSPR_THREADS"; then - CC=xlc_r - else - CC=xlc - fi - ;; - - *-hpux*) - CC=cc - ;; - - *-irix*) - CC=cc - ;; - - *-osf*) - CC=cc - ;; - - *-solaris*) - CC=cc - ;; - - esac -fi - -dnl ======================================================== -dnl = -dnl = Set the default C++ compiler -dnl = -dnl ======================================================== -if test -z "$CXX"; then - case "$target" in - - *-aix*) - if test -z "$USE_NSPR_THREADS"; then - CXX=xlC_r - else - CXX=xlC - fi - ;; - - *-hpux*) - case "${target_os}" in - hpux10.30) - CXX=aCC - ;; - hpux11.*) - CXX=aCC - ;; - *) - CXX=CC - ;; - esac - ;; - - *-irix*) - CXX=CC - ;; - - *-osf*) - CXX=cxx - ;; - - *-solaris*) - CXX=CC - ;; - - esac -fi - -if test -z "$SKIP_PATH_CHECKS"; then - AC_PATH_PROG(WHOAMI, $WHOAMI whoami, echo not_whoami) -fi - -if test -n "$MOZ_DEBUG"; then - AC_DEFINE(DEBUG) - DEFINES="$DEFINES -UNDEBUG" - - case "${target_os}" in - beos*) - DEFINES="$DEFINES -DDEBUG_${USER}" - ;; - msvc*|mks*|cygwin*|mingw*|wince*|winmo*|os2*) - DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`" - ;; - *) - DEFINES="$DEFINES -DDEBUG_`$WHOAMI`" - ;; - esac -else - AC_DEFINE(NDEBUG) - DEFINES="$DEFINES -UDEBUG" -fi - -if test -z "$SKIP_COMPILER_CHECKS"; then -dnl ======================================================== -dnl Checks for compilers. -dnl ======================================================== - -dnl Explicitly honor $CROSS_COMPILE to allow cross-compiling -dnl between toolkits on the same architecture, as when -dnl targeting the iOS Simulator from OS X. -if test "$target" != "$host" -o -n "$CROSS_COMPILE"; then - echo "cross compiling from $host to $target" - cross_compiling=yes - - _SAVE_CC="$CC" - _SAVE_CFLAGS="$CFLAGS" - _SAVE_LDFLAGS="$LDFLAGS" - - AC_MSG_CHECKING([for $host compiler]) - AC_CHECK_PROGS(HOST_CC, $HOST_CC gcc cc /usr/ucb/cc, "") - if test -z "$HOST_CC"; then - AC_MSG_ERROR([no acceptable cc found in \$PATH]) - fi - AC_MSG_RESULT([$HOST_CC]) - if test -z "$HOST_CFLAGS"; then - HOST_CFLAGS="$CFLAGS" - fi - if test -z "$HOST_LDFLAGS"; then - HOST_LDFLAGS="$LDFLAGS" - fi - - CC="$HOST_CC" - CFLAGS="$HOST_CFLAGS" - LDFLAGS="$HOST_LDFLAGS" - - AC_MSG_CHECKING([whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works]) - AC_TRY_COMPILE([], [return(0);], - [ac_cv_prog_host_cc_works=1 AC_MSG_RESULT([yes])], - AC_MSG_ERROR([installation or configuration problem: $host compiler $HOST_CC cannot create executables.]) ) - - CC=$_SAVE_CC - CFLAGS=$_SAVE_CFLAGS - LDFLAGS=$_SAVE_LDFLAGS - - case "$build:$target" in - powerpc-apple-darwin8*:i?86-apple-darwin*) - dnl The Darwin cross compiler doesn't necessarily point itself at a - dnl root that has libraries for the proper architecture, it defaults - dnl to the system root. The libraries in the system root on current - dnl versions of PPC OS X 10.4 aren't fat, so these target compiler - dnl checks will fail. Fake a working SDK in that case. - _SAVE_CFLAGS=$CFLAGS - _SAVE_CXXFLAGS=$CXXFLAGS - CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CFLAGS" - CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS" - ;; - *:arm*-apple-darwin*) - dnl The arm compiler doesn't appear to know about its root by default, - dnl so explicitly pass it one here. Later on we'll put this in CFLAGS - dnl anyway. - _SAVE_CFLAGS=$CFLAGS - _SAVE_CXXFLAGS=$CXXFLAGS - CFLAGS="-isysroot $MACOS_SDK_DIR $CFLAGS" - CXXFLAGS="-isysroot $MACOS_SDK_DIR $CXXFLAGS" - ;; - esac - - AC_CHECK_PROGS(CC, $CC "${target_alias}-gcc" "${target}-gcc", echo) - unset ac_cv_prog_CC - AC_PROG_CC - if test -n "$USE_CPLUS"; then - AC_CHECK_PROGS(CXX, $CXX "${target_alias}-g++" "${target}-g++", echo) - unset ac_cv_prog_CXX - AC_PROG_CXX - fi - - case "$build:$target" in - powerpc-apple-darwin8*:i?86-apple-darwin*|*:arm*-apple-darwin*) - dnl Revert the changes made above. From this point on, the target - dnl compiler will never be used without applying the SDK to CFLAGS - dnl (see --with-macos-sdk below). - CFLAGS=$_SAVE_CFLAGS - CXXFLAGS=$_SAVE_CXXFLAGS - ;; - esac - - AC_CHECK_PROGS(RANLIB, $RANLIB "${target_alias}-ranlib" "${target}-ranlib", echo) - AC_CHECK_PROGS(AR, $AR "${target_alias}-ar" "${target}-ar", echo) - AC_CHECK_PROGS(AS, $AS "${target_alias}-as" "${target}-as", echo) - AC_CHECK_PROGS(LD, $LD "${target_alias}-ld" "${target}-ld", echo) - AC_CHECK_PROGS(STRIP, $STRIP "${target_alias}-strip" "${target}-strip", echo) - AC_CHECK_PROGS(WINDRES, $WINDRES "${target_alias}-windres" "${target}-windres", echo) - -else - AC_PROG_CC - if test -n "$USE_CPLUS"; then - if test "$CC" = "cl" -a -z "$CXX"; then - CXX=$CC - else - AC_PROG_CXX - fi - fi - AC_PROG_CPP - AC_PROG_RANLIB - AC_PATH_PROGS(AS, as, $CC) - AC_PATH_PROGS(AR, ar, echo not_ar) - AC_PATH_PROGS(LD, ld link, echo not_ld) - AC_PATH_PROGS(STRIP, strip, echo not_strip) - AC_PATH_PROGS(WINDRES, windres, echo not_windres) - if test -z "$HOST_CC"; then - HOST_CC="$CC" - fi - if test -z "$HOST_CFLAGS"; then - HOST_CFLAGS="$CFLAGS" - fi -fi - -if test "$GCC" = "yes"; then - GNU_CC=1 -fi -if test "$GXX" = "yes"; then - GNU_CXX=1 -fi -if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then - GNU_AS=1 -fi -rm -f a.out - -case "$build:$target" in - i?86-apple-darwin*:powerpc-apple-darwin*) - dnl cross_compiling will have erroneously been set to "no" in this - dnl case, because the x86 build host is able to run ppc code in a - dnl translated environment, making a cross compiler appear native. - cross_compiling=yes - ;; -esac - -if test "$cross_compiling" = "yes"; then - CROSS_COMPILE=1 -else - CROSS_COMPILE= -fi - -dnl ======================================================== -dnl Check for gcc -pipe support -dnl ======================================================== -AC_MSG_CHECKING([for gcc -pipe support]) -if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then - echo '#include ' > dummy-hello.c - echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c - ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5 - cat dummy-hello.s | ${AS} -o dummy-hello.S - 2>&5 - if test $? = 0; then - _res_as_stdin="yes" - else - _res_as_stdin="no" - fi - if test "$_res_as_stdin" = "yes"; then - _SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -pipe" - AC_TRY_COMPILE( [ #include ], - [printf("Hello World\n");], - [_res_gcc_pipe="yes"], - [_res_gcc_pipe="no"] ) - CFLAGS=$_SAVE_CFLAGS - fi - if test "$_res_as_stdin" = "yes" && test "$_res_gcc_pipe" = "yes"; then - _res="yes"; - CFLAGS="$CFLAGS -pipe" - CXXFLAGS="$CXXFLAGS -pipe" - else - _res="no" - fi - rm -f dummy-hello.c dummy-hello.s dummy-hello.S dummy-hello a.out - AC_MSG_RESULT([$_res]) -else - AC_MSG_RESULT([no]) -fi - -dnl ======================================================== -dnl Profile guided optimization -dnl ======================================================== -dnl Test for profiling options -dnl Under gcc 3.4+, use -fprofile-generate/-fprofile-use - -_SAVE_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction" - -AC_MSG_CHECKING([whether C compiler supports -fprofile-generate]) -AC_TRY_COMPILE([], [return 0;], - [ PROFILE_GEN_CFLAGS="-fprofile-generate" - result="yes" ], result="no") -AC_MSG_RESULT([$result]) - -if test $result = "yes"; then - PROFILE_GEN_LDFLAGS="-fprofile-generate" - PROFILE_USE_CFLAGS="-fprofile-use -fprofile-correction -Wcoverage-mismatch" - PROFILE_USE_LDFLAGS="-fprofile-use" -fi - -CFLAGS="$_SAVE_CFLAGS" - -dnl =============================================================== -dnl Check for .hidden assembler directive and visibility attribute. -dnl Borrowed from glibc configure.in -dnl =============================================================== -if test "$GNU_CC"; then - AC_CACHE_CHECK(for visibility(hidden) attribute, - ac_cv_visibility_hidden, - [cat > conftest.c </dev/null 2>&1; then - if grep '\.hidden.*foo' conftest.s >/dev/null; then - ac_cv_visibility_hidden=yes - fi - fi - rm -f conftest.[cs] - ]) - if test "$ac_cv_visibility_hidden" = "yes"; then - AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) - AC_CACHE_CHECK(for visibility pragma support, - ac_cv_visibility_pragma, - [cat > conftest.c </dev/null 2>&1; then - if grep '\.hidden.*foo_hidden' conftest.s >/dev/null; then - if ! grep '\.hidden.*foo_default' conftest.s > /dev/null; then - ac_cv_visibility_pragma=yes - fi - fi - fi - rm -f conftest.[cs] - ]) - if test "$ac_cv_visibility_pragma" = "yes"; then - AC_DEFINE(HAVE_VISIBILITY_PRAGMA) - # To work around a build problem on Linux x86-64 (Bugzilla bug - # 293438), we use the -fvisibility=hidden flag. This flag is less - # optimal than #pragma GCC visibility push(hidden) because the flag - # assumes that symbols defined outside the current source file have - # the default visibility. This has the advantage that we don't need - # to wrap system header files, but has the disadvantage that calls - # to hidden symbols defined in other source files cannot be - # optimized by the compiler. The -fvisibility=hidden flag does - # hide and export symbols correctly. - #VISIBILITY_FLAGS='-I$(dist_includedir)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' - #WRAP_SYSTEM_INCLUDES=1 - VISIBILITY_FLAGS="-fvisibility=hidden" - WRAP_SYSTEM_INCLUDES= - fi - fi -fi # GNU_CC - -fi # SKIP_COMPILER_CHECKS - -dnl ======================================================== -dnl Checks for programs. -dnl ======================================================== -if test -z "$SKIP_PATH_CHECKS"; then - AC_PATH_PROGS(PERL, perl5 perl, echo not_perl) -elif test -z "$PERL"; then - PERL=perl -fi - -dnl ======================================================== -dnl Default platform specific options -dnl ======================================================== -OBJ_SUFFIX=o -LIB_SUFFIX=a -DLL_SUFFIX=so -ASM_SUFFIX=s -MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@' -PR_MD_ASFILES= -PR_MD_CSRCS= -PR_MD_ARCH_DIR=unix -AR_FLAGS='cr $@' -AS='$(CC)' -ASFLAGS='$(CFLAGS)' - -if test -n "$CROSS_COMPILE"; then - OS_ARCH=`echo $target_os | sed -e 's|/|_|g'` - OS_RELEASE= - OS_TEST="${target_cpu}" - case "${target_os}" in - linux*) OS_ARCH=Linux ;; - solaris*) OS_ARCH=SunOS OS_RELEASE=5 ;; - mingw*) OS_ARCH=WINNT ;; - wince*) OS_ARCH=WINCE ;; - winmo*) OS_ARCH=WINCE ;; - darwin*) OS_ARCH=Darwin ;; - riscos*) OS_ARCH=RISCOS ;; - esac -else - OS_ARCH=`uname -s | sed -e 's|/|_|g'` - OS_RELEASE=`uname -r` - OS_TEST=`uname -m` -fi - -if test "$OS_ARCH" = "IRIX64"; then - OS_ARCH=IRIX -fi - -if test "$OS_ARCH" = "AIX"; then - OS_RELEASE=`uname -v`.`uname -r` -fi - -if test "$OS_ARCH" = "FreeBSD"; then - OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'` -fi - -if test "$OS_ARCH" = "Linux"; then - OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'` - OS_RELEASE=`echo $OS_RELEASE | awk -F\. '{ print $1 "." $2 }'` -fi - -####################################################################### -# Master "Core Components" macros for getting the OS target # -####################################################################### - -# -# Note: OS_TARGET should be specified on the command line for gmake. -# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built. -# The difference between the Win95 target and the WinNT target is that -# the WinNT target uses Windows NT specific features not available -# in Windows 95. The Win95 target will run on Windows NT, but (supposedly) -# at lesser performance (the Win95 target uses threads; the WinNT target -# uses fibers). -# -# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no -# cross-compilation. -# - -# -# The following hack allows one to build on a WIN95 machine (as if -# s/he were cross-compiling on a WINNT host for a WIN95 target). -# It also accomodates for MKS's uname.exe. If you never intend -# to do development on a WIN95 machine, you don't need this hack. -# -case "$OS_ARCH" in -WIN95) - OS_ARCH=WINNT - OS_TARGET=WIN95 - ;; -Windows_95) - OS_ARCH=Windows_NT - OS_TARGET=WIN95 - ;; -Windows_98) - OS_ARCH=Windows_NT - OS_TARGET=WIN95 - ;; -CYGWIN_9*|CYGWIN_ME*) - OS_ARCH='CYGWIN_NT-4.0' - OS_TARGET=WIN95 - ;; -OS_2) - OS_ARCH=OS2 - OS_TARGET=OS2 - ;; -esac - -# -# On WIN32, we also define the variable CPU_ARCH. -# - -case "$OS_ARCH" in -WINNT) - CPU_ARCH=`uname -p` - if test "$CPU_ARCH" = "I386"; then - CPU_ARCH=x86 - fi - ;; -Windows_NT) -# -# If uname -s returns "Windows_NT", we assume that we are using -# the uname.exe in MKS toolkit. -# -# The -r option of MKS uname only returns the major version number. -# So we need to use its -v option to get the minor version number. -# Moreover, it doesn't have the -p option, so we need to use uname -m. -# - OS_ARCH=WINNT - OS_MINOR_RELEASE=`uname -v` - if test "$OS_MINOR_RELEASE" = "00"; then - OS_MINOR_RELEASE=0 - fi - OS_RELEASE="${OS_RELEASE}.${OS_MINOR_RELEASE}" - CPU_ARCH=`uname -m` - # - # MKS's uname -m returns "586" on a Pentium machine. - # - if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then - CPU_ARCH=x86 - fi - ;; -CYGWIN_NT*|MINGW*_NT*) -# -# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using -# the uname.exe in the Cygwin tools. -# If uname -s returns MINGW32_NT-5.1, we assume that we are using -# the uname.exe in the MSYS tools. -# - OS_RELEASE=`expr $OS_ARCH : '.*NT-\(.*\)'` - OS_ARCH=WINNT - CPU_ARCH=`uname -m` - # - # Cygwin's uname -m returns "i686" on a Pentium Pro machine. - # - if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then - CPU_ARCH=x86 - fi - ;; -esac - -if test -n "$MOZILLA_CLIENT" && test "$OS_ARCH" = "WINNT"; then - OS_TARGET=WIN95 - if test -n "$MOZ_DEBUG"; then - USE_DEBUG_RTL=1 - fi -fi -if test -z "$OS_TARGET"; then - OS_TARGET=$OS_ARCH -fi -if test "$OS_TARGET" = "WIN95"; then - OS_RELEASE="4.0" -fi -OS_CONFIG="${OS_TARGET}${OS_RELEASE}" - -dnl ======================================================== -dnl Enable high-memory support on OS/2 by default. -dnl ======================================================== -AC_ARG_ENABLE(os2-high-mem, - [ --disable-os2-high-mem Disable high-memory support on OS/2], - [ if test "$enableval" = "no"; then - MOZ_OS2_HIGH_MEMORY= - else - MOZ_OS2_HIGH_MEMORY=1 - fi ]) - -dnl ======================================================== -dnl = ARM toolchain tweaks -dnl ======================================================== - -dnl Defaults -case "$target" in -arm*-android*|arm*-linuxandroid*) - MOZ_THUMB=yes - MOZ_ARCH=armv7-a - MOZ_FPU=vfp - MOZ_FLOAT_ABI=softfp - MOZ_SOFT_FLOAT=yes - ;; -arm*-*) - if test -n "$MOZ_PLATFORM_MAEMO"; then - MOZ_THUMB=no - MOZ_ARCH=armv7-a - MOZ_FLOAT_ABI=softfp - fi - if test "$MOZ_PLATFORM_MAEMO" = 6; then - MOZ_THUMB=yes - fi - ;; -esac - -dnl Kept for compatibility with some buildbot mozconfig -AC_ARG_ENABLE(thumb2, [], MOZ_THUMB=$enableval) - -AC_ARG_WITH(thumb, -[ --with-thumb[[=yes|no|toolchain-default]]] -[ Use Thumb instruction set (-mthumb)], - if test -z "$GNU_CC"; then - AC_MSG_ERROR([--with-thumb is not supported on non-GNU toolchain-defaults]) - fi - MOZ_THUMB=$withval) - -AC_ARG_WITH(thumb-interwork, -[ --with-thumb-interwork[[=yes|no|toolchain-default]] - Use Thumb/ARM instuctions interwork (-mthumb-interwork)], - if test -z "$GNU_CC"; then - AC_MSG_ERROR([--with-thumb-interwork is not supported on non-GNU toolchain-defaults]) - fi - MOZ_THUMB_INTERWORK=$withval) - -AC_ARG_WITH(arch, -[ --with-arch=[[type|toolchain-default]] - Use specific CPU features (-march=type)], - if test -z "$GNU_CC"; then - AC_MSG_ERROR([--with-arch is not supported on non-GNU toolchain-defaults]) - fi - MOZ_ARCH=$withval) - -AC_ARG_WITH(fpu, -[ --with-fpu=[[type|toolchain-default]] - Use specific FPU type (-mfpu=type)], - if test -z "$GNU_CC"; then - AC_MSG_ERROR([--with-fpu is not supported on non-GNU toolchain-defaults]) - fi - MOZ_FPU=$withval) - -AC_ARG_WITH(float-abi, -[ --with-float-abi=[[type|toolchain-default]] - Use specific arm float ABI (-mfloat-abi=type)], - if test -z "$GNU_CC"; then - AC_MSG_ERROR([--with-float-abi is not supported on non-GNU toolchain-defaults]) - fi - MOZ_FLOAT_ABI=$withval) - -AC_ARG_WITH(soft-float, -[ --with-soft-float[[=yes|no|toolchain-default]] - Use soft float library (-msoft-float)], - if test -z "$GNU_CC"; then - AC_MSG_ERROR([--with-soft-float is not supported on non-GNU toolchain-defaults]) - fi - MOZ_SOFT_FLOAT=$withval) - -case "$MOZ_ARCH" in -toolchain-default|"") - arch_flag="" - ;; -*) - arch_flag="-march=$MOZ_ARCH" - ;; -esac - -case "$MOZ_THUMB" in -yes) - MOZ_THUMB2=1 - thumb_flag="-mthumb" - ;; -no) - MOZ_THUMB2= - thumb_flag="-marm" - ;; -*) - _SAVE_CFLAGS="$CFLAGS" - CFLAGS="$arch_flag" - AC_TRY_COMPILE([],[return sizeof(__thumb2__);], - MOZ_THUMB2=1, - MOZ_THUMB2=) - CFLAGS="$_SAVE_CFLAGS" - thumb_flag="" - ;; -esac - -case "$MOZ_THUMB_INTERWORK" in -yes) - thumb_interwork_flag="-mthumb-interwork" - ;; -no) - thumb_interwork_flag="-mno-thumb-interwork" - ;; -*) # toolchain-default - thumb_interwork_flag="" - ;; -esac - -case "$MOZ_FPU" in -toolchain-default|"") - fpu_flag="" - ;; -*) - fpu_flag="-mfpu=$MOZ_FPU" - ;; -esac - -case "$MOZ_FLOAT_ABI" in -toolchain-default|"") - float_abi_flag="" - ;; -*) - float_abi_flag="-mfloat-abi=$MOZ_FLOAT_ABI" - ;; -esac - -case "$MOZ_SOFT_FLOAT" in -yes) - soft_float_flag="-msoft-float" - ;; -no) - soft_float_flag="-mno-soft-float" - ;; -*) # toolchain-default - soft_float_flag="" - ;; -esac - -dnl Use echo to avoid accumulating space characters -all_flags=`echo $arch_flag $thumb_flag $thumb_interwork_flag $fpu_flag $float_abi_flag $soft_float_flag` -if test -n "$all_flags"; then - _SAVE_CFLAGS="$CFLAGS" - CFLAGS="$all_flags" - AC_MSG_CHECKING(whether the chosen combination of compiler flags ($all_flags) works) - AC_TRY_COMPILE([],[return 0;], - AC_MSG_RESULT([yes]), - AC_MSG_ERROR([no])) - - CFLAGS="$_SAVE_CFLAGS $all_flags" - CXXFLAGS="$CXXFLAGS $all_flags" - ASFLAGS="$ASFLAGS $all_flags" - if test -n "$thumb_flag"; then - LDFLAGS="$LDFLAGS $thumb_flag" - fi -fi - -dnl ======================================================== -dnl Override of system specific host options -dnl ======================================================== -case "$host" in -*-mingw*) - NSINSTALL=nsinstall - ;; -*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*) - NSINSTALL='$(CYGWIN_WRAPPER) nsinstall' - if test `echo "${PATH}" | grep -c \;` = 0; then - CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper' - fi - ;; -*-beos*) - HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE" - ;; -*os2*) - ;; -*) - HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX" - ;; -esac - -dnl ======================================================== -dnl Override of system specific target options -dnl ======================================================== -case "$target" in - -*-aix*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(AIX) - AC_DEFINE(SYSV) - DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib' - AC_CHECK_HEADER(sys/atomic_op.h, AC_DEFINE(AIX_HAVE_ATOMIC_OP_H)) - case "${target_os}" in - aix3.2*) - AC_DEFINE(AIX_RENAME_SELECT) - AC_DEFINE(_PR_NO_LARGE_FILES) - AIX_LINK_OPTS='-bnso -berok' - PR_MD_ASFILES=os_AIX.s - ;; - aix4.1*) - AC_DEFINE(AIX_TIMERS) - AC_DEFINE(_PR_NO_LARGE_FILES) - AC_DEFINE(AIX4_1) - MKSHLIB= - DSO_LDOPTS= - AIX_LINK_OPTS='-bnso -berok' - LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)_shr' - LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)_shr' - ;; - aix4.2*) - AC_DEFINE(AIX_TIMERS) - AC_DEFINE(_PR_HAVE_OFF64_T) - AIX_LINK_OPTS='-brtl -bnso -berok' - ;; - aix4.3*) - AC_DEFINE(AIX_TIMERS) - AC_DEFINE(_PR_HAVE_OFF64_T) - AC_DEFINE(AIX4_3_PLUS) - AC_DEFINE(HAVE_SOCKLEN_T) - AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) - USE_IPV6=1 - AIX_LINK_OPTS='-brtl -bnso -berok' - ;; - *) - AC_DEFINE(AIX_TIMERS) - AC_DEFINE(_PR_HAVE_OFF64_T) - AC_DEFINE(AIX4_3_PLUS) - AC_DEFINE(HAVE_SOCKLEN_T) - AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) - USE_IPV6=1 - AIX_LINK_OPTS='-brtl -bnso -berok' - ;; - esac - CFLAGS="$CFLAGS -qro -qroconst" - AIX_WRAP='$(DIST)/lib/aixwrap.o' - AIX_TMP='./_aix_tmp.o' - if test -n "$USE_64"; then - MDCPUCFG_H=_aix64.cfg - OBJECT_MODE=64 - else - MDCPUCFG_H=_aix32.cfg - fi - PR_MD_CSRCS=aix.c - RESOLVE_LINK_SYMBOLS=1 - ;; - -*-beos*) - AC_DEFINE(XP_BEOS) - AC_DEFINE(BeOS) - AC_DEFINE(BEOS) - AC_DEFINE(_POSIX_SOURCE) - DSO_LDOPTS=-nostart - MDCPUCFG_H=_beos.cfg - USE_BTHREADS=1 - PR_MD_ARCH_DIR=beos - RESOLVE_LINK_SYMBOLS=1 - case "${target_cpu}" in - i*86) - _OPTIMIZE_FLAGS=-O2 - _DEBUG_FLAGS='-gdwarf-2 -O0' - MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@' - AC_CHECK_LIB(bind, gethostbyaddr, [OS_LIBS="$OS_LIBS -lbind -lsocket"]) - ;; - powerpc) - CC=mwcc - CCC=mwcc - LD=mwld - DSO_LDOPTS='-xms -export pragma -init _init_routine_ -term _term_routine_ -lroot -lnet /boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o /boot/develop/lib/ppc/start_dyn.o' - _OPTIMIZE_FLAGS=-O2 - _DEBUG_FLAGS='-g -O0' - ;; - esac - ;; - -*-bsdi*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(BSDI) - AC_DEFINE(NEED_BSDREGEX) - - CFLAGS="$CFLAGS -Wall -Wno-format" - CXXFLAGS="$CXXFLAGS -Wall -Wno-format" - - if echo "$OS_TEST" | grep -c 86 >/dev/null; then - CPU_ARCH=x86 - elif echo "$OS_TEST" | grep -c sparc >/dev/null; then - CPU_ARCH=sparc - fi - - MDCPUCFG_H=_bsdi.cfg - PR_MD_CSRCS=bsdi.c - - DSO_LDOPTS=-r - - case "$target_os" in - bsdi1.1*) - AC_DEFINE(_PR_BSDI_JMPBUF_IS_ARRAY) - AC_DEFINE(_PR_STAT_HAS_ONLY_ST_ATIME) - AC_DEFINE(_PR_NEED_H_ERRNO) - MKSHLIB= - DSO_CFLAGS= - DSO_LDOPTS= - ;; - - bsdi2.1*) - AC_DEFINE(_PR_TIMESPEC_HAS_TS_SEC) - AC_DEFINE(_PR_BSDI_JMPBUF_IS_ARRAY) - AC_DEFINE(HAVE_DLL) - AC_DEFINE(USE_DLFCN) - AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC) - PR_MD_ASFILES=os_BSD_OS_386_2.s - ;; - - bsdi4.* | bsdi5.*) - AC_DEFINE(_PR_SELECT_CONST_TIMEVAL) - AC_DEFINE(_PR_BSDI_JMPBUF_IS_STRUCT) - AC_DEFINE(HAVE_DLL) - AC_DEFINE(USE_DLFCN) - AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC) - MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)' - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-shared -Wl,-soname,$(@:$(OBJDIR)/%.so=%.so)' - STRIP="$STRIP -d" - case "$target_os" in - bsdi4.2* | bsdi4.3* | bsdi5.*) - AC_DEFINE(_PR_HAVE_GETPROTO_R) - AC_DEFINE(_PR_HAVE_GETPROTO_R_POINTER) - ;; - esac - ;; - *) - AC_DEFINE(_PR_SELECT_CONST_TIMEVAL) - AC_DEFINE(_PR_BSDI_JMPBUF_IS_STRUCT) - AC_DEFINE(HAVE_DLL) - AC_DEFINE(USE_DLFCN) - AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC) - ;; - esac - - ;; - -*-darwin*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(DARWIN) - AC_DEFINE(HAVE_BSD_FLOCK) - AC_DEFINE(HAVE_SOCKLEN_T) - AS='$(CC) -x assembler-with-cpp' - CFLAGS="$CFLAGS -Wall -fno-common" - case "${target_cpu}" in - arm*) - CPU_ARCH=arm - ;; - i*86*) - if test -n "$USE_64"; then - CPU_ARCH=x86_64 - else - CPU_ARCH=i386 - fi - ;; - x86_64) - CPU_ARCH=x86_64 - ;; - *) - CPU_ARCH=ppc - ;; - esac - if test "`echo $CC | grep -c '\-arch '`" = "0"; then - CC="$CC -arch $CPU_ARCH" - fi - AC_CHECK_HEADER(crt_externs.h) - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names' - _OPTIMIZE_FLAGS=-O2 - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - STRIP="$STRIP -x -S" - DLL_SUFFIX=dylib - USE_PTHREADS=1 - MDCPUCFG_H=_darwin.cfg - PR_MD_CSRCS=darwin.c - PR_MD_ASFILES=os_Darwin.s - - # Add Mac OS X support for loading CFM & CFBundle plugins - if test -f "${MACOS_SDK_DIR}/System/Library/Frameworks/Carbon.framework/Carbon"; then - AC_DEFINE(XP_MACOSX) - OS_TARGET=MacOSX - - if test -n "$_MACOSX_DEPLOYMENT_TARGET" ; then - dnl Use the specified value - export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET - elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then - dnl No value specified on the command line or in the environment, - dnl use the lesser of the library's minimum or the architecture's - dnl minimum. - case "${target_cpu}" in - powerpc*) - dnl Architecture minimum 10.2 - export MACOSX_DEPLOYMENT_TARGET=10.2 - ;; - i*86*) - dnl Architecture minimum 10.4 - export MACOSX_DEPLOYMENT_TARGET=10.4 - ;; - esac - fi - - dnl MACOS_SDK_DIR will be set to the SDK location whenever one is - dnl in use. NEXT_ROOT will be set and exported if it's needed for - dnl ld. - - if test "$MACOS_SDK_DIR"; then - dnl Sync this section with the one in Mozilla's top level. - - if test ! -d "$MACOS_SDK_DIR"; then - AC_MSG_ERROR([SDK not found. When using --with-macos-sdk, you must -specify a valid SDK. SDKs are installed when the optional cross-development -tools are selected during the Xcode/Developer Tools installation.]) - fi - - changequote(,) - CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'` - GCC_VERSION_FULL=`echo $CC_VERSION | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'` - GCC_VERSION=`echo $GCC_VERSION_FULL | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'` - changequote([,]) - GCC_VERSION_MAJOR=`echo $GCC_VERSION_FULL | $PERL -pe 's/(^\d*).*/$1/;'` - if test "$GCC_VERSION_MAJOR" -lt "4" ; then - SDK_C_FRAMEWORK="-F${MACOS_SDK_DIR}/System/Library/Frameworks" - if test -d "${MACOS_SDK_DIR}/Library/Frameworks" ; then - SDK_C_FRAMEWORK="$SDK_C_FRAMEWORK -F${MACOS_SDK_DIR}/Library/Frameworks" - fi - - SDK_C_INCLUDE="-isystem ${MACOS_SDK_DIR}/usr/include/gcc/darwin/${GCC_VERSION} -isystem ${MACOS_SDK_DIR}/usr/include ${SDK_C_FRAMEWORK}" - - CFLAGS="$CFLAGS -nostdinc ${SDK_C_INCLUDE}" - - dnl CPP needs to be set for AC_CHECK_HEADER. - CPP="$CPP -nostdinc ${SDK_C_INCLUDE}" - - changequote(,) - HOST_DARWIN_MAJOR=`echo "$build_os" | sed -E -e 's/^darwin([0-9]+).*$/\1/'` - changequote([,]) - if test "$HOST_DARWIN_MAJOR" -lt 9 ; then - dnl The build host is running Tiger (10.4) or earlier. - dnl ld support for -syslibroot is compiler-agnostic, but - dnl only available on Tiger and later. On Tiger and - dnl earlier build hosts, just rely on NEXT_ROOT, because - dnl it's not been shown to cause any problems. - MACOS_SDK_LIBS="-L${MACOS_SDK_DIR}/usr/lib/gcc/darwin -L${MACOS_SDK_DIR}/usr/lib/gcc/darwin/${GCC_VERSION_FULL} -L${MACOS_SDK_DIR}/usr/lib ${SDK_C_FRAMEWORK}" - else - dnl The build host is running Leopard (10.5) or later. - dnl With NEXT_ROOT set, the linker will still not apply - dnl it when resolving dependencies. This causes problems - dnl on Leopard, where an SDK depends on frameworks which - dnl were present in earlier OS releases (and the associated - dnl SDK) but not in Leopard. -syslibroot does not have - dnl this problem, but it results in harmless warnings when - dnl NEXT_ROOT is set. NEXT_ROOT needs to remain set even - dnl on Leopard because the compiler uses it too. - MACOS_SDK_LIBS="-Wl,-syslibroot,${MACOS_SDK_DIR}" - fi - - LDFLAGS="${MACOS_SDK_LIBS} $LDFLAGS" - export NEXT_ROOT=$MACOS_SDK_DIR - - if test -n "$CROSS_COMPILE" ; then - dnl NEXT_ROOT will be in the environment, but it - dnl shouldn't be set for the build host. HOST_CXX is - dnl presently unused. - HOST_CC="NEXT_ROOT= $HOST_CC" - HOST_CXX="NEXT_ROOT= $HOST_CXX" - fi - else - dnl gcc >= 4.0 uses different paths than above, but knows - dnl how to find them itself. - CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}" - - dnl CPP needs to be set for AC_CHECK_HEADER. - CPP="$CPP -isysroot ${MACOS_SDK_DIR}" - - dnl If gcc >= 4.0.0, we're guaranteed to be on Tiger, which - dnl has an ld that supports -syslibroot. Don't set - dnl NEXT_ROOT because it will be ignored and cause - dnl warnings when -syslibroot is specified. - if test "$GCC_VERSION_FULL" != "4.0.0" ; then - dnl gcc > 4.0.0 will pass -syslibroot to ld automatically - dnl based on the -isysroot it receives. - LDFLAGS="$LDFLAGS -isysroot ${MACOS_SDK_DIR}" - else - dnl gcc 4.0.0 doesn't pass -syslibroot to ld, it needs - dnl to be explicit. - LDFLAGS="$LDFLAGS -Wl,-syslibroot,${MACOS_SDK_DIR}" - fi - fi - fi - fi - ;; - -*-dgux*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(_PR_LOCAL_THREADS_ONLY) - AC_DEFINE(SVR4) - AC_DEFINE(SYSV) - AC_DEFINE(DGUX) - AC_DEFINE(_DGUX_SOURCE) - AC_DEFINE(_POSIX4A_DRAFT6_SOURCE) - DSO_LDOPTS=-G - _OPTIMIZE_FLAGS=-O2 - _DEBUG_FLAGS= - MDCPUCFG_H=_dgux.cfg - PR_MD_CSRCS=dgux.c - ;; - -*-freebsd*) - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - fi - AC_DEFINE(XP_UNIX) - AC_DEFINE(FREEBSD) - AC_DEFINE(HAVE_BSD_FLOCK) - AC_DEFINE(HAVE_SOCKLEN_T) - CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall" - MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf` - if test "$MOZ_OBJFORMAT" = "elf"; then - DLL_SUFFIX=so - else - DLL_SUFFIX=so.1.0 - fi - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' - MDCPUCFG_H=_freebsd.cfg - PR_MD_CSRCS=freebsd.c - ;; - -*-hpux*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(HPUX) - AC_DEFINE(_HPUX_SOURCE) - # OSF1 and HPUX report the POLLHUP event for a socket when the - # shutdown(SHUT_WR) operation is called for the remote end, even though - # the socket is still writeable. Use select(), instead of poll(), to - # workaround this problem. - AC_DEFINE(_PR_POLL_WITH_SELECT) - AC_DEFINE(_USE_BIG_FDS) - DSO_LDOPTS='-b +h $(notdir $@)' - PR_MD_CSRCS=hpux.c - if test "$OS_TEST" = "ia64"; then - DLL_SUFFIX=so - DSO_LDOPTS="$DSO_LDOPTS +b '\$\$ORIGIN'" - CPU_ARCH_TAG=_$OS_TEST - if test -z "$USE_64"; then - COMPILER_TAG=_32 - fi - PR_MD_ASFILES=os_HPUX_ia64.s - else - AC_DEFINE(hppa) - DLL_SUFFIX=sl - PR_MD_ASFILES=os_HPUX.s - fi - if test -n "$USE_64"; then - MDCPUCFG_H=_hpux64.cfg - else - MDCPUCFG_H=_hpux32.cfg - fi - if test -z "$GNU_CC"; then - CC="$CC -Ae" - CXX="$CXX -ext" - DSO_CFLAGS=+Z - else - DSO_CFLAGS=-fPIC - ASFLAGS="$ASFLAGS -x assembler-with-cpp" - fi - - if test -n "$MOZILLA_CLIENT"; then - DEFAULT_IMPL_STRATEGY=_EMU - fi - - if echo "$OS_RELEASE" | grep ^A.09 >/dev/null; then - AC_DEFINE(_PR_NEED_H_ERRNO) - AC_DEFINE(HPUX9) - DEFAULT_IMPL_STRATEGY=_EMU - USE_NSPR_THREADS=1 - fi - - if echo "$OS_RELEASE" | egrep '^(A.09|B.10)' >/dev/null; then - AC_DEFINE(_PR_NO_LARGE_FILES) - fi - - if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then - AC_DEFINE(_PR_NEED_H_ERRNO) - fi - - if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then - AC_DEFINE(HAVE_INT_LOCALTIME_R) - fi - - if echo "$OS_RELEASE" | egrep '^(B.10.30|B.11)' >/dev/null; then - AC_DEFINE(HAVE_POINTER_LOCALTIME_R) - fi - - # HP-UX 11i v2 (B.11.23) or higher - changequote(<<,>>) - case "$OS_RELEASE" in - [C-Z]*|B.[2-9]*|B.1[2-9]*|B.11.[3-9]*|B.11.2[3-9]*) - USE_IPV6=1 - ;; - esac - changequote([,]) - - if test "$OS_RELEASE" = "B.10.01"; then - AC_DEFINE(HPUX10) - DEFAULT_IMPL_STRATEGY=_EMU - fi - - if test "$OS_RELEASE" = "B.10.10"; then - AC_DEFINE(HPUX10) - AC_DEFINE(HPUX10_10) - DEFAULT_IMPL_STRATEGY=_PTH - fi - - if test "$OS_RELEASE" = "B.10.20"; then - AC_DEFINE(HPUX10) - AC_DEFINE(HPUX10_20) - if test -z "$GNU_CC"; then - CFLAGS="$CFLAGS +DAportable +DS1.1" - CXXFLAGS="$CXXFLAGS +DAportable +DS1.1" - fi - DEFAULT_IMPL_STRATEGY=_PTH - fi - - if test "$OS_RELEASE" = "B.10.30"; then - AC_DEFINE(HPUX10) - AC_DEFINE(HPUX10_30) - if test -z "$GNU_CC"; then - CFLAGS="$CFLAGS +DAportable +DS1.1" - CXXFLAGS="$CXXFLAGS +DAportable +DS1.1" - fi - DEFAULT_IMPL_STRATEGY=_PTH - fi - - if echo "$OS_RELEASE" | grep ^B.11 >/dev/null; then - AC_DEFINE(HPUX10) - AC_DEFINE(HPUX11) - AC_DEFINE(_LARGEFILE64_SOURCE) - AC_DEFINE(_PR_HAVE_OFF64_T) - AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) - if test -z "$GNU_CC"; then - if test -z "$USE_64"; then - if test "$OS_TEST" = "ia64"; then - CFLAGS="$CFLAGS +DD32" - CXXFLAGS="$CXXFLAGS +DD32" - else - CFLAGS="$CFLAGS +DAportable +DS2.0" - CXXFLAGS="$CXXFLAGS +DAportable +DS2.0" - fi - else - if test "$OS_TEST" = "ia64"; then - CFLAGS="$CFLAGS +DD64" - CXXFLAGS="$CXXFLAGS +DD64" - else - CFLAGS="$CFLAGS +DA2.0W +DS2.0" - CXXFLAGS="$CXXFLAGS +DA2.0W +DS2.0" - fi - fi - fi - DEFAULT_IMPL_STRATEGY=_PTH - fi - - if test "$DEFAULT_IMPL_STRATEGY" = "_EMU"; then - USE_NSPR_THREADS=1 - USE_PTHREADS= - USE_USER_PTHREADS= - elif test "$DEFAULT_IMPL_STRATEGY" = "_PTH"; then - USE_PTHREADS=1 - if test "$USE_NSPR_THREADS"; then - USE_PTHREADS= - fi - if test "$USE_USER_PTHREADS"; then - USE_PTHREADS= - fi - fi - ;; - -*-irix*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(IRIX) - AC_DEFINE(SVR4) - AC_DEFINE(_SGI_MP_SOURCE) - AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) - PR_MD_CSRCS=irix.c - PR_MD_ASFILES=os_Irix.s - MKSHLIB='$(LD) $(DSO_LDOPTS) -rdata_shared -shared -soname $(notdir $@) -o $@' - STRIP="$STRIP -f" - RESOLVE_LINK_SYMBOLS=1 - if test -n "$USE_64"; then - MDCPUCFG_H=_irix64.cfg - else - MDCPUCFG_H=_irix32.cfg - fi - case "${target_os}" in - irix6*) - AC_DEFINE(IRIX6) - USE_PTHREADS=1 - USE_N32=1 - COMPILER_TAG=_n32 - IMPL_STRATEGY=_PTH - ;; - irix5*) - AC_DEFINE(IRIX5) - USE_NSPR_THREADS=1 - ;; - *) - USE_PTHREADS=1 - USE_N32=1 - ;; - esac - if test "$GNU_CC"; then - dnl - dnl If we are using gcc with native binutils, we need to - dnl suppress the - dnl #lineno "filename" num num - dnl lines, which confuse IRIX native as. Add -Wp,-P to the - dnl gcc command line, which passes -P to the preprocessor. - dnl - AS='$(CC) -Wp,-P -x assembler-with-cpp -D_ASM -mips2 $(INCLUDES)' - CFLAGS="$CFLAGS -Wall -Wno-format" - _OPTIMIZE_FLAGS="-O6" - else - if test -n "$USE_N32"; then - AS='as -D_ASM $(INCLUDES) -n32' - else - AS='as -D_ASM $(INCLUDES)' - fi - CFLAGS="$CFLAGS -fullwarn -xansi" - if test "$USE_N32"; then - _OPTIMIZE_FLAGS="-O -OPT:Olimit=4000" - else - _OPTIMIZE_FLAGS="-O -Olimit 4000" - fi - if test "$USE_MDUPDATE"; then - CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)" - fi - case "${target}" in - *-irix6.*) - CFLAGS="$CFLAGS -multigot" - DSO_LDOPTS="-no_unresolved" - if test "$USE_N32"; then - CFLAGS="$CFLAGS -n32 -woff 1209" - DSO_LDOPTS="$DSO_LDOPTS -n32" - else - if test "$USE_64"; then - CFLAGS="$CFLAGS -64" - else - CFLAGS="$CFLAGS -32" - fi - fi - ;; - *) - CFLAGS="$CFLAGS -xgot" - ;; - esac - fi - if test "${target_os}" = "irix5.3"; then - AC_DEFINE(IRIX5_3) - fi - case "${target_os}" in - irix6.5) - if test -z "$GNU_CC"; then - CFLAGS="$CFLAGS -mips3" - fi - AC_DEFINE(_PR_HAVE_GETPROTO_R) - AC_DEFINE(_PR_HAVE_GETPROTO_R_POINTER) - AC_DEFINE(_PR_HAVE_SGI_PRDA_PROCMASK) - ;; - irix5*) - ;; - *) - AC_DEFINE(_PR_HAVE_SGI_PRDA_PROCMASK) - ;; - esac - ;; - -*-linux*|*-gnu*|*-k*bsd*-gnu|*-android*|*-linuxandroid*) - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - IMPL_STRATEGY=_PTH - fi - AC_DEFINE(XP_UNIX) - AC_DEFINE(_GNU_SOURCE) - AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) - case "${target}" in - *-android*|*-linuxandroid*) - OS_TARGET=Android - AC_DEFINE(LINUX) - ;; - *-linux*) - AC_DEFINE(LINUX) - ;; - esac - CFLAGS="$CFLAGS -Wall" - CXXFLAGS="$CXXFLAGS -Wall" - MDCPUCFG_H=_linux.cfg - PR_MD_CSRCS=linux.c - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' - _OPTIMIZE_FLAGS=-O2 - _DEBUG_FLAGS="-g -fno-inline" # most people on linux use gcc/gdb, and that - # combo is not yet good at debugging inlined - # functions (even when using DWARF2 as the - # debugging format) - COMPILER_TAG=_glibc - if echo "$OS_TEST" | grep -c 86 >/dev/null; then - CPU_ARCH=x86 - else - CPU_ARCH=$OS_TEST - fi - CPU_ARCH_TAG=_${CPU_ARCH} - case "${target_cpu}" in - alpha) - AC_DEFINE(_ALPHA_) - AC_DEFINE(__alpha) - CFLAGS="$CFLAGS -mieee" - CXXFLAGS="$CXXFLAGS -mieee" - ;; - i*86) - AC_DEFINE(i386) - PR_MD_ASFILES=os_Linux_x86.s - ;; - ia64) - PR_MD_ASFILES=os_Linux_ia64.s - ;; - x86_64) - if test -n "$USE_64"; then - PR_MD_ASFILES=os_Linux_x86_64.s - else - AC_DEFINE(i386) - PR_MD_ASFILES=os_Linux_x86.s - CC="$CC -m32" - CXX="$CXX -m32" - fi - ;; - ppc|powerpc) - PR_MD_ASFILES=os_Linux_ppc.s - ;; - powerpc64) - if test -n "$USE_64"; then - CC="$CC -m64" - CXX="$CXX -m64" - else - PR_MD_ASFILES=os_Linux_ppc.s - fi - ;; - m68k) - CFLAGS="$CFLAGS -m68020-60" - CXXFLAGS="$CXXFLAGS -m68020-60" - ;; - esac - ;; - -*-mingw*|*-cygwin*|*-msvc*|*-mks*) - AC_DEFINE(XP_PC) - AC_DEFINE(WIN32) - PR_MD_ARCH_DIR=windows - RESOLVE_LINK_SYMBOLS=1 - - if test -n "$GNU_CC"; then - CC="$CC -mwindows" - CXX="$CXX -mwindows" - DLL_SUFFIX=dll - MKSHLIB='$(CC) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(IMPORT_LIBRARY) $(DLLBASE) -o $(subst $(OBJDIR)/,,$(SHARED_LIBRARY))' - RC=$WINDRES - # Use temp file for windres (bug 213281) - RCFLAGS='-O coff --use-temp-file' - else - CC=cl - CXX=cl - LD=link - AR='lib -NOLOGO -OUT:"$@"' - AR_FLAGS= - RANLIB='echo not_ranlib' - STRIP='echo not_strip' - RC=rc.exe - GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb' - OBJ_SUFFIX=obj - LIB_SUFFIX=lib - DLL_SUFFIX=dll - - # Determine compiler version - changequote(,) - _MSVC_VER_FILTER='s|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p' - changequote([,]) - CC_VERSION=`"${CC}" -v 2>&1 | sed -ne "$_MSVC_VER_FILTER"` - _CC_MAJOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $1 }'` - _CC_MINOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $2 }'` - _CC_RELEASE=`echo ${CC_VERSION} | awk -F\. '{ print $3 }'` - _CC_BUILD=`echo ${CC_VERSION} | awk -F\. '{ print $4 }'` - MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION} - - if test "$_CC_MAJOR_VERSION" -eq "14"; then - dnl -DYNAMICBASE is only supported on VC8SP1 or newer, - dnl so be very specific here! - dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762 - if test $_CC_RELEASE -gt 50727; then - _USE_DYNAMICBASE=1 - elif test $_CC_BUILD -ge 762; then - _USE_DYNAMICBASE=1 - fi - AC_DEFINE(_CRT_SECURE_NO_DEPRECATE) - AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE) - elif test $_CC_MAJOR_VERSION -ge 15; then - _USE_DYNAMICBASE=1 - AC_DEFINE(_CRT_SECURE_NO_WARNINGS) - AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS) - fi - - if test -n "$_USE_DYNAMICBASE"; then - DLLFLAGS="$DLLFLAGS -DYNAMICBASE" - fi - - # Ensure that mt is Microsoft (R) Manifest Tool and not magnetic - # tape manipulation utility (or something else) - if test "$MSC_VER" -ge "1400"; then - changequote(,) - _MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p' - changequote([,]) - - MSMT_TOOL=`mt 2>&1|grep 'Microsoft (R) Manifest Tool'` - if test -n "$MSMT_TOOL"; then - MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"` - if test -z "$MSMANIFEST_TOOL_VERSION"; then - AC_MSG_WARN([Unknown version of the Microsoft (R) Manifest Tool.]) - fi - MT=mt - unset MSMT_TOOL - else - AC_MSG_ERROR([Microsoft (R) Manifest Tool must be in your \$PATH.]) - fi - fi - - CFLAGS="$CFLAGS -W3 -nologo -GF -Gy" - DLLFLAGS="$DLLFLAGS -OUT:\"\$@\"" - _DEBUG_FLAGS=-Zi - _OPTIMIZE_FLAGS=-O2 - - PROFILE_GEN_CFLAGS="-GL" - PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT" - PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952" - PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE" - - if test -z "$MOZ_OPTIMIZE"; then - CFLAGS="$CFLAGS -Od" - fi - - if test -n "$USE_DEBUG_RTL"; then - CFLAGS="$CFLAGS -MDd" - else - CFLAGS="$CFLAGS -MD" - fi - - if test -n "$MOZ_DEBUG"; then - AC_DEFINE(_DEBUG) - else - DEFINES="$DEFINES -U_DEBUG" - fi - - if test -n "$MOZ_DEBUG_SYMBOLS"; then - if test -n "$MOZ_OPTIMIZE"; then - DLLFLAGS="$DLLFLAGS -DEBUG -OPT:REF" - LDFLAGS="$LDFLAGS -DEBUG -OPT:REF" - else - DLLFLAGS="$DLLFLAGS -DEBUG" - LDFLAGS="$LDFLAGS -DEBUG" - fi - fi - - OS_DLLFLAGS="-nologo -DLL -SUBSYSTEM:WINDOWS" - if test "$MSC_VER" -le "1200" -a -z "$MOZ_DEBUG_SYMBOLS"; then - OS_DLLFLAGS="$OS_DLLFLAGS -PDB:NONE" - fi - - if test "$OS_TARGET" = "WINNT"; then - CFLAGS="$CFLAGS -GT" - LIBNSPR='$(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - LIBPLC='$(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - else - LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - fi - fi # GNU_CC - - if test -n "$USE_STATIC_TLS"; then - AC_DEFINE(_PR_USE_STATIC_TLS) - fi - - if test "$OS_TARGET" = "WINNT"; then - AC_DEFINE(WINNT) - else - AC_DEFINE(WIN95) - # undefine WINNT as some versions of mingw gcc define it by default - DEFINES="$DEFINES -UWINNT" - AC_DEFINE(_PR_GLOBAL_THREADS_ONLY) - fi - - if test "$CPU_ARCH" = "x86"; then - CPU_ARCH_TAG= - else - CPU_ARCH_TAG=$CPU_ARCH - fi - - if test -n "$USE_DEBUG_RTL"; then - OBJDIR_SUFFIX=OBJD - fi - - case "$OS_TARGET" in - WINNT) - MDCPUCFG_H=_winnt.cfg - ;; - WIN95) - MDCPUCFG_H=_win95.cfg - ;; - *) - AC_MSG_ERROR([Missing OS_TARGET for ${target}. Use --enable-win32-target to set.]) - ;; - esac - - case "$target_cpu" in - i*86) - if test -n "$USE_64"; then - AC_DEFINE(_AMD64_) - else - AC_DEFINE(_X86_) - fi - ;; - x86_64) - AC_DEFINE(_AMD64_) - USE_64=1 - ;; - ia64) - AC_DEFINE(_IA64_) - USE_64=1 - ;; - *) - AC_DEFINE(_CPU_ARCH_NOT_DEFINED) - ;; - esac - ;; - -*-wince*|*-winmo*) - AC_DEFINE(XP_PC) - AC_DEFINE(WIN32) - AC_DEFINE(WINCE) - AC_DEFINE(_PR_GLOBAL_THREADS_ONLY) - - AR_FLAGS='-NOLOGO -OUT:"$@"' - - OBJ_SUFFIX=obj - LIB_SUFFIX=lib - DLL_SUFFIX=dll - MKSHLIB='$(LD) -DLL $(DSO_LDOPTS) -OUT:$@' - - PR_MD_ARCH_DIR=windows - RESOLVE_LINK_SYMBOLS=1 - - MDCPUCFG_H=_win95.cfg - LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' - - DLLFLAGS='-OUT:"$@"' - if test -n "$MOZ_DEBUG_SYMBOLS"; then - OS_LDFLAGS='-DEBUG -DEBUGTYPE:CV' - OS_DLLFLAGS='-DEBUG -DEBUGTYPE:CV' - DSO_LDOPTS='-DEBUG -DEBUGTYPE:CV' - fi - _DEBUG_FLAGS=-Zi - _OPTIMIZE_FLAGS=-O2 - ;; - -*-netbsd*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(NETBSD) - AC_DEFINE(HAVE_BSD_FLOCK) - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - fi - MDCPUCFG_H=_netbsd.cfg - PR_MD_CSRCS=netbsd.c - - DSO_CFLAGS='-fPIC -DPIC' - CFLAGS="$CFLAGS -ansi -Wall" - CXXFLAGS="$CXXFLAGS -ansi -Wall" - MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)' - - if test -z "$OBJECT_FMT"; then - if echo __ELF__ | ${CC-cc} -E - | grep -q __ELF__ 2>/dev/null; then - OBJECT_FMT=a.out - DLL_SUFFIX=so.1.0 - DSO_LDOPTS='-shared' - else - OBJECT_FMT=ELF - DLL_SUFFIX=so - DSO_LDOPTS='-shared -Wl,-soname,$(notdir $@)' - fi - fi - - if test "$LIBRUNPATH"; then - DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH" - fi - ;; - -*-nto*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(NTO) - AC_DEFINE(_QNX_SOURCE) - AC_DEFINE(HAVE_POINTER_LOCALTIME_R) - MDCPUCFG_H=_nto.cfg - PR_MD_CSRCS=nto.c - MKSHLIB='$(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(notdir $@) -o $@' - DSO_CFLAGS=-fPIC - DSO_LDOPTS=-shared - OS_LIBS="$OS_LIBS -lsocket" - _OPTIMIZE_FLAGS="-O1" - _DEBUG_FLAGS="-gstabs" - ;; - -*-openbsd*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(OPENBSD) - AC_DEFINE(HAVE_BSD_FLOCK) - AC_DEFINE(HAVE_SOCKLEN_T) - CFLAGS="$CFLAGS -ansi -Wall" - CXXFLAGS="$CXXFLAGS -ansi -Wall" - DLL_SUFFIX=so.1.0 - DSO_CFLAGS=-fPIC - MDCPUCFG_H=_openbsd.cfg - PR_MD_CSRCS=openbsd.c - OS_LIBS="-lc" - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - fi - DSO_LDOPTS='-shared -fPIC' - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - ;; - -*-osf*) - SHELL_OVERRIDE="SHELL = /usr/bin/ksh" - AC_DEFINE(XP_UNIX) - AC_DEFINE(OSF1) - AC_DEFINE(_REENTRANT) - # OSF1 and HPUX report the POLLHUP event for a socket when the - # shutdown(SHUT_WR) operation is called for the remote end, even though - # the socket is still writeable. Use select(), instead of poll(), to - # workaround this problem. - AC_DEFINE(_PR_POLL_WITH_SELECT) - - if echo "$OS_RELEASE" | egrep -c '(V2.0|V3.2)' 2>/dev/null ; then - USE_NSPR_THREADS=1 - fi - - if test -z "$GNU_CC"; then - CC="$CC -std1 -ieee_with_inexact" - if test "$OS_RELEASE" != "V2.0"; then - CC="$CC -readonly_strings" - fi - _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000" - AC_CHECK_HEADER(machine/builtins.h, AC_DEFINE(OSF1_HAVE_MACHINE_BUILTINS_H)) - else - CFLAGS="$CFLAGS -mieee" - CXXFLAGS="$CXXFLAGS -mieee" - fi - - if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then - AC_DEFINE(HAVE_INT_LOCALTIME_R) - else - AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) - AC_DEFINE(HAVE_POINTER_LOCALTIME_R) - fi - if echo $OS_RELEASE | grep -c V4.0 >/dev/null; then - AC_DEFINE(OSF1V4_MAP_PRIVATE_BUG) - fi - DSO_LDOPTS='-shared -all -expect_unresolved "*" -soname $(notdir $@)' - MDCPUCFG_H=_osf1.cfg - PR_MD_CSRCS=osf1.c - ;; - -*-qnx*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(QNX) - AC_DEFINE(_PR_NEED_H_ERRNO) - USE_NSPR_THREADS=1 - MDCPUCFG_H=_qnx.cfg - PR_MD_CSRCS=qnx.c - ;; - -*-riscos*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(RISCOS) - AC_DEFINE(_PR_NEED_H_ERRNO) - USE_PTHREADS=1 - MDCPUCFG_H=_riscos.cfg - PR_MD_CSRCS=riscos.c - DSO_CFLAGS=-fPIC - DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - ;; - -*-*-sco*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(SCO) - AC_DEFINE(sco) - AC_DEFINE(SYSV) - AC_DEFINE(_SVID3) - AC_DEFINE(_PR_NEED_H_ERRNO) - CC='cc -b elf -KPIC' - CXX='$(NSDEPTH)/build/hcpp CC +.cpp +w' - USE_NSPR_THREADS=1 - CPU_ARCH=x86 - DSO_LDOPTS='-b elf -G' - MDCPUCFG_H=_scoos.cfg - PR_MD_SRCS=scoos.c - ;; - -*-solaris*) - if test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - fi - AC_DEFINE(XP_UNIX) - AC_DEFINE(SVR4) - AC_DEFINE(SYSV) - AC_DEFINE(__svr4) - AC_DEFINE(__svr4__) - AC_DEFINE(SOLARIS) - AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) - CPU_ARCH=`uname -p` - MDCPUCFG_H=_solaris.cfg - PR_MD_CSRCS=solaris.c - LD=/usr/ccs/bin/ld - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - RESOLVE_LINK_SYMBOLS=1 - case "${OS_RELEASE}" in - 5.8|5.9) - ;; - *) - # It is safe to use the -Bdirect linker flag on Solaris 10 or later. - USE_B_DIRECT=1 - ;; - esac - if test -n "$GNU_CC"; then - DSO_CFLAGS=-fPIC - if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then - GCC_USE_GNU_LD=1 - fi - DSO_LDOPTS='-shared -Wl,-h,$(notdir $@),-z,combreloc,-z,defs,-z,ignore' - if test -n "$USE_B_DIRECT"; then - DSO_LDOPTS="$DSO_LDOPTS,-Bdirect" - fi - else - DSO_CFLAGS=-KPIC - DSO_LDOPTS='-G -h $(notdir $@) -z combreloc -z defs -z ignore' - if test -n "$USE_B_DIRECT"; then - DSO_LDOPTS="$DSO_LDOPTS -Bdirect" - fi - fi - if test -n "$GNU_CC"; then - CFLAGS="$CFLAGS -Wall" - CXXFLAGS="$CXXFLAGS -Wall" - if test -n "$USE_MDUPDATE"; then - CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)" - CXXFLAGS="$CXXFLAGS -MDupdate \$(DEPENDENCIES)" - fi - GCC_AS=`$CC -print-prog-name=as` - if test "`echo | $GCC_AS -v 2>&1 | grep -c GNU`" != "0"; then - GNU_AS=1 - fi - else - CFLAGS="$CFLAGS -xstrconst" - CXXFLAGS="$CXXFLAGS -Qoption cg -xstrconst -features=tmplife" - if test -z "$MOZ_OPTIMIZE"; then - CFLAGS="$CFLAGS -xs" - CXXFLAGS="$CXXFLAGS -xs" - fi - _OPTIMIZE_FLAGS=-xO4 - fi - if test -z "$GNU_AS"; then - ASFLAGS="$ASFLAGS -Wa,-P" - fi - if test -n "$USE_64"; then - if test -n "$GNU_CC"; then - CC="$CC -m64" - CXX="$CXX -m64" - else - if test "$OS_TEST" = "i86pc"; then - CC="$CC -xarch=amd64" - CXX="$CXX -xarch=amd64" - else - CC="$CC -xarch=v9" - CXX="$CXX -xarch=v9" - fi - fi - fi - if test "$OS_TEST" = "i86pc"; then - if test -z "$USE_64"; then - AC_DEFINE(i386) - fi - CPU_ARCH_TAG=_$OS_TEST - # The default debug format, DWARF (-g), is not supported by gcc - # on i386-ANY-sysv4/solaris, but the stabs format is. It is - # assumed that the Solaris assembler /usr/ccs/bin/as is used. - # If your gcc uses GNU as, you do not need the -Wa,-s option. - if test -n "$MOZ_DEBUG" && test -n "$GNU_CC"; then - _DEBUG_FLAGS=-gstabs - if test -z "$GNU_AS"; then - _DEBUG_FLAGS="$_DEBUG_FLAGS -Wa,-s" - fi - fi - fi - case "${target_os}" in - solaris2.3*) - AC_DEFINE(_PR_NO_LARGE_FILES) - ;; - solaris2.4*) - AC_DEFINE(_PR_NO_LARGE_FILES) - ;; - solaris2.5*) - AC_DEFINE(SOLARIS2_5) - ;; - *) - AC_DEFINE(_PR_HAVE_OFF64_T) - # The lfcompile64(5) man page on Solaris 2.6 says: - # For applications that do not wish to conform to the POSIX or - # X/Open specifications, the 64-bit transitional interfaces - # are available by default. No compile-time flags need to be - # set. - # But gcc 2.7.2.x fails to define _LARGEFILE64_SOURCE by default. - # The native compiler, gcc 2.8.x, and egcs don't have this problem. - if test -n "$GNU_CC"; then - AC_DEFINE(_LARGEFILE64_SOURCE) - fi - ;; - esac - case "${target_os}" in - solaris2.3*) - ;; - solaris2.4*) - ;; - solaris2.5*) - ;; - solaris2.6*) - ;; - solaris2.7*) - ;; - *) - # Solaris 8 or higher has IPv6. - AC_DEFINE(_PR_INET6) - ;; - esac - if test "$CPU_ARCH" = "sparc"; then - # 64-bit Solaris SPARC requires V9 architecture, so the following - # is not needed. - if test -z "$USE_64"; then - ULTRASPARC_LIBRARY=nspr_flt - fi - fi - # Purify requires that binaries linked against nspr also - # be linked against -lrt (or -lposix4) so add it to OS_LIBS - _rev=`uname -r` - _librt=`echo $_rev 5.6 | awk '{ if ($1 > $2) print "-lrt"; else print "-lposix4" }'` - OS_LIBS="$OS_LIBS $_librt" - ;; - -*-sco-sysv5*) - AC_DEFINE(XP_UNIX) - AC_DEFINE(UNIXWARE) - AC_DEFINE(SVR4) - AC_DEFINE(SYSV) - USE_NSPR_THREADS=1 - if echo $OS_RELEASE | grep -c 2.1 2>/dev/null; then - AC_DEFINE(_PR_NO_LARGE_FILES) - CC='$(NSDEPTH)/build/hcc cc' - CXX='$(NSDEPTH)/build/hcpp CC' - MDCPUCFG_H=_unixware.cfg - else - AC_DEFINE(_LARGEFILE64_SOURCE) - AC_DEFINE(_PR_HAVE_OFF64_T) - AC_DEFINE(_PR_HAVE_SOCKADDR_LEN) - MDCPUCFG_H=_unixware7.cfg - fi - PR_MD_CSRCS=unixware.c - DSO_LDOPTS=-G - CPU_ARCH=x86 - ;; - -*-symbian*) - AC_ARG_WITH(symbian-sdk, - [ --with-symbian-sdk=SYMBIAN_SDK_DIR - The path to the Symbian SDK], - SYMBIAN_SDK_DIR=$withval) - - echo ----------------------------------------------------------------------------- - echo Building with Symbian SDK in: $SYMBIAN_SDK_DIR - echo ----------------------------------------------------------------------------- - - AC_DEFINE(XP_UNIX) - AC_DEFINE(SYMBIAN) - AC_DEFINE(__arm__) - AC_DEFINE(__SYMBIAN32__) - AC_DEFINE(_UNICODE) - AC_DEFINE(NDEBUG) - AC_DEFINE(__SUPPORT_CPP_EXCEPTIONS__) - AC_DEFINE(MOZ_STDERR_TO_STDOUT) - AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) - AC_DEFINE(HAVE_SOCKLEN_T) - USE_PTHREADS=1 - LIB_SUFFIX=lib - DLL_SUFFIX=dll - MKSHLIB= - DSO_LDOPTS= - DSO_CFLAGS= - VISIBILITY_FLAGS= - MDCPUCFG_H=_symbian.cfg - PR_MD_CSRCS=symbian.c - NSINSTALL=nsinstall - RANLIB='echo no ranlib ' - CPU_ARCH=ARM - OS_ARCH=SYMBIAN - OS_EXE_CFLAGS="$OS_EXE_CFLAGS -D__EXE__" - CFLAGS="$CFLAGS -MD -nostdinc" - SYMBIAN_SYS_INCLUDE="-I$SYMBIAN_SDK_DIR/Epoc32/include/variant -I$SYMBIAN_SDK_DIR/Epoc32/include -I$SYMBIAN_SDK_DIR/Epoc32/include/stdapis" - echo ------------------------------------------------------- - echo SYMBIAN_SYS_INCLUDE is: $SYMBIAN_SYS_INCLUDE - echo ------------------------------------------------------- - case "$OS_TARGET" in - WINSCW) - CC=mwccsym2.exe - CXX=mwccsym2.exe - LD=mwldsym2.exe - AR=mwldsym2.exe - WINSCW_LD_DIR="\$(SYMBIAN_SDK_DIR)/EPOC32/RELEASE/WINSCW/UDEB" - CFLAGS="$CFLAGS -O0 -inline off -wchar_t off -align 4 -warnings on -w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostderr -gccdep -cwd source -i- -I\$(VPATH)" - SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include Symbian_OS_v9.2.hrh" - AR_FLAGS="-library -msgstyle gcc -stdlib -subsystem windows -noimplib -o \$@" - AC_DEFINE(_DEBUG) - AC_DEFINE(__CW32__) - AC_DEFINE(__WINS__) - AC_DEFINE(__WINSCW__) - DEFINES="$DEFINES -U_WIN32" - ;; - GCCE) - CFLAGS="$CFLAGS -Wall -Wno-unknown-pragmas -fexceptions -march=armv5t -mapcs -pipe -x c -msoft-float" - CXXFLAGS="$CXXFLAGS $CFLAGS -Wno-ctor-dtor-privacy" - SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include $SYMBIAN_SDK_DIR/EPOC32/INCLUDE/GCCE/GCCE.h" - AC_DEFINE(__GCCE__) - AC_DEFINE(__EABI__) - DEFINES="$DEFINES -D__PRODUCT_INCLUDE__=$SYMBIAN_SDK_DIR/Epoc32/include/variant/Symbian_OS_v9.2.hrh" - ;; - *) - AC_MSG_ERROR([Missing OS_TARGET for ${target}. Set --enable-symbian-target to with 'WINSCW' or 'GCCE'.]) - ;; - esac - CFLAGS="$CFLAGS ${SYMBIAN_SYS_INCLUDE}" - ;; - -*-os2*) - AC_DEFINE(XP_OS2) - AC_DEFINE(XP_PC) - AC_DEFINE(BSD_SELECT) - AC_DEFINE(TCPV40HDRS) - LIB_SUFFIX=lib - DLL_SUFFIX=dll - RC=rc.exe - PR_MD_ARCH_DIR=os2 - PROG_SUFFIX=.exe - NSINSTALL=nsinstall - MDCPUCFG_H=_os2.cfg - RESOLVE_LINK_SYMBOLS=1 - - AC_DEFINE(OS2) - AR=emxomfar - AR_FLAGS='r $@' - CFLAGS="$CFLAGS -Wall -Zomf" - CXXFLAGS="$CFLAGS -Wall -Zomf" - MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' - DSO_CFLAGS= - DSO_LDOPTS='-Zomf -Zdll' - LDFLAGS='-Zmap' - _OPTIMIZE_FLAGS="-O2 -s" - _DEBUG_FLAGS="-g -fno-inline" - if test -n "$MOZ_OPTIMIZE"; then - DSO_LDOPTS="$DSO_LDOPTS -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA" - fi - IMPLIB='emximp -o' - FILTER='emxexp -o' - if test -n "$MOZ_OS2_HIGH_MEMORY"; then - LDFLAGS="$LDFLAGS -Zhigh-mem" - AC_DEFINE(MOZ_OS2_HIGH_MEMORY) - fi - - # GCC for OS/2 currently predefines these, but we don't want them - DEFINES="$DEFINES -Uunix -U__unix -U__unix__" - ;; - -*) - AC_DEFINE(XP_UNIX) - ;; - -esac - -if test -z "$SKIP_LIBRARY_CHECKS"; then -dnl ======================================================== -dnl Check for system libraries -dnl ======================================================== -dnl AC_CHECK_LIB(C, main) -dnl AC_CHECK_LIB(C_r, main) -dnl AC_CHECK_LIB(c, main) -dnl AC_CHECK_LIB(c_r, main) -dnl AC_CHECK_LIB(dce, main) -dnl AC_CHECK_LIB(dl, main) -dnl AC_CHECK_LIB(dld, main) -dnl AC_CHECK_LIB(gen, main) -dnl AC_CHECK_LIB(ip6, main) -dnl AC_CHECK_LIB(l, main) -dnl AC_CHECK_LIB(m, main) -dnl AC_CHECK_LIB(nsl, main) -dnl AC_CHECK_LIB(posix4, main) -dnl AC_CHECK_LIB(prstrms, main) -dnl AC_CHECK_LIB(prstrms_shr, main) -dnl AC_CHECK_LIB(pthread, main) -dnl AC_CHECK_LIB(pthreads, main) -dnl AC_CHECK_LIB(resolv, main) -dnl AC_CHECK_LIB(rt, main) -dnl AC_CHECK_LIB(socket, main) -dnl AC_CHECK_LIB(svld, main) -dnl AC_CHECK_LIB(thread, main) -dnl AC_CHECK_LIB(vms_jackets, main) - - -dnl We don't want anything to link with libdl even if it's present on OS X, -dnl since it's not used and not part of the default installation. -dnl The same goes for BeOS. -dnl OS/2 has dlfcn in libc. - -case $target in -*-darwin*|*-beos*|*-os2*) - ;; -*) - AC_CHECK_LIB(dl, dlopen, - AC_CHECK_HEADER(dlfcn.h, - OS_LIBS="-ldl $OS_LIBS")) - ;; -esac - - -dnl ======================================================== -dnl Check for system header files. -dnl ======================================================== -dnl AC_HEADER_DIRENT -dnl AC_HEADER_STDC -dnl AC_HEADER_SYS_WAIT -dnl AC_CHECK_HEADERS(fcntl.h limits.h sys/file.h sys/ioctl.h sys/time.h unistd.h) - -dnl ======================================================== -dnl Check for typedefs and structs -dnl ======================================================== -dnl AC_C_CONST -dnl AC_TYPE_UID_T -dnl AC_TYPE_MODE_T -dnl AC_TYPE_OFF_T -dnl AC_TYPE_PID_T -dnl AC_TYPE_SIZE_T -dnl AC_STRUCT_ST_BLKSIZE -dnl AC_STRUCT_ST_BLOCKS -dnl AC_STRUCT_ST_RDEV -dnl AC_HEADER_TIME -dnl AC_STRUCT_TM - -dnl ======================================================== -dnl Checks for library functions. -dnl ======================================================== -AC_PROG_GCC_TRADITIONAL -_SAVE_LIBS="$LIBS" -LIBS="$LIBS $OS_LIBS" -AC_CHECK_FUNCS(lchown strerror dladdr) -LIBS="$_SAVE_LIBS" - -dnl AC_FUNC_MEMCMP -dnl AC_FUNC_MMAP -dnl AC_FUNC_SETVBUF_REVERSED -dnl AC_FUNC_STRCOLL -dnl AC_FUNC_STRFTIME -dnl AC_FUNC_UTIME_NULL -dnl AC_FUNC_VPRINTF -dnl AC_CHECK_FUNCS(ftime getcwd gethostname gettimeofday getwd mkdir mktime putenv rmdir select socket strdup strerror strstr strtol strtoul uname) - -dnl ======================================================== -dnl Check options -dnl ======================================================== - -dnl ====================================================== -dnl = Enable compiling with ccache -dnl ====================================================== -AC_ARG_WITH(ccache, -[ --with-ccache[=path/to/ccache] - Enable compiling with ccache], - CCACHE=$withval, CCACHE="no") - -if test "$CCACHE" != "no"; then - if test -n "$CCACHE"; then - if test "$CCACHE" = "yes"; then - CCACHE= - else - if test ! -e "$CCACHE"; then - AC_MSG_ERROR([$CCACHE not found]) - fi - fi - fi - AC_PATH_PROGS(CCACHE, $CCACHE ccache) - if test -z "$CCACHE" -o "$CCACHE" = ":"; then - AC_MSG_ERROR([ccache not found]) - elif test -x "$CCACHE"; then - CC="$CCACHE $CC" - CXX="$CCACHE $CXX" - else - AC_MSG_ERROR([$CCACHE is not executable]) - fi -fi - -dnl ======================================================== -dnl = -dnl = --enable-strip -dnl = -dnl = Enable stripping of libs and executables -dnl = -dnl ======================================================== -AC_ARG_ENABLE(strip, - [ --enable-strip Enable stripping of shared libs and programs], - [ if test "$enableval" = "yes"; then - ENABLE_STRIP=1 - fi ]) - -dnl Check for hpux options -case "${target_os}" in -hpux*) -if test -z "$GNU_CC"; then - - AC_CACHE_CHECK(for +Olit support, - ac_cv_hpux_usable_olit_option, - dnl since aCC doesn't throw an error on invalid options, - dnl we have to test this the hard way - [ac_cv_hpux_usable_olit_option=no - rm -f conftest* - echo 'int main() { return 0; }' | cat > conftest.c - ${CC-cc} ${CFLAGS} +Olit=all -o conftest conftest.c > conftest.out 2>&1 - if test $? -eq 0; then - if test -z "`egrep -i '(unrecognize|unknown)' conftest.out`"; then - ac_cv_hpux_usable_olit_option=yes - fi - fi - rm -f conftest* - ]) - - if test "$ac_cv_hpux_usable_olit_option" = "yes"; then - CFLAGS="$CFLAGS +Olit=all" - CXXFLAGS="$CXXFLAGS +Olit=all" - else - CFLAGS="$CFLAGS +ESlit" - CXXFLAGS="$CXXFLAGS +ESlit" - fi -fi -;; -esac - -dnl -dnl Apparently, some systems cannot properly check for the pthread -dnl library unless is included so we need to test -dnl using it -dnl -dnl MOZ_CHECK_PTHREADS(lib, success, failure) -AC_DEFUN(MOZ_CHECK_PTHREADS, -[ -AC_MSG_CHECKING([for pthread_create in -l$1]) -echo " - #include - void *foo(void *v) { return v; } - int main() { - pthread_t t; - if (!pthread_create(&t, 0, &foo, 0)) { - pthread_join(t, 0); - } - return 0; - }" > dummy.c ; - echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS" 1>&5; - ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS 2>&5; - _res=$? ; - rm -f dummy.c dummy${ac_exeext} ; - if test "$_res" = "0"; then - AC_MSG_RESULT([yes]) - [$2] - else - AC_MSG_RESULT([no]) - [$3] - fi -]) - -case "$target_os" in -darwin*) - _HAVE_PTHREADS=1 - ;; -wince*) - _HAVE_PTHREADS= - ;; -*) - MOZ_CHECK_PTHREADS(pthreads, - _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads", - MOZ_CHECK_PTHREADS(pthread, - _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread", - MOZ_CHECK_PTHREADS(c_r, - _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r", - MOZ_CHECK_PTHREADS(c, - _HAVE_PTHREADS=1 - ) - ) - ) - ) - ;; -esac - -AC_ARG_WITH(pthreads, - [ --with-pthreads Use system pthreads library as thread subsystem], - [ if test "$withval" = "yes"; then - if test -n "$_HAVE_PTHREADS"; then - USE_PTHREADS=1 - USE_USER_PTHREADS= - USE_NSPR_THREADS= - else - AC_MSG_ERROR([ --with-pthreads specified for a system without pthread support ]); - fi - else - USE_PTHREADS= - _PTHREAD_LDFLAGS= - fi], - [ if test -n "$_HAVE_PTHREADS" && test -z "$USE_USER_PTHREADS" && test -z "$USE_NSPR_THREADS"; then - USE_PTHREADS=1 - USE_USER_PTHREADS= - USE_NSPR_THREADS= - fi]) - -AC_ARG_ENABLE(user-pthreads, - [ --enable-user-pthreads Build using userland pthreads], - [ if test "$enableval" = "yes"; then - if test -n "$_HAVE_PTHREADS"; then - USE_PTHREADS= - USE_USER_PTHREADS=1 - USE_NSPR_THREADS= - else - AC_MSG_ERROR([ --enable-user-pthreads specified for a system without pthread support ]); - fi - fi]) - -AC_ARG_ENABLE(nspr-threads, - [ --enable-nspr-threads Build using classic nspr threads], - [ if test "$enableval" = "yes"; then - USE_PTHREADS= - USE_USER_PTHREADS= - USE_NSPR_THREADS=1 - fi]) - -case "$target" in -*-beos*) - AC_ARG_WITH(bthreads, - [ --with-bthreads Use system bthreads library as thread subsystem - (BeOS only)], - [ if test "$withval" = "yes"; then - USE_BTHREADS=1 - USE_USER_PTHREADS= - USE_PTHREADS= - fi]) - ;; -esac - -fi # SKIP_LIBRARY_CHECKS - -AC_ARG_ENABLE(ipv6, - [ --enable-ipv6 Compile ipv6 support], - [ if test "$enableval" = "yes"; then - USE_IPV6=1 - else - USE_IPV6= - fi]) - -if test -n "$USE_PTHREADS"; then - dnl See if -pthread is supported. - rm -f conftest* - ac_cv_have_dash_pthread=no - AC_MSG_CHECKING(whether ${CC-cc} accepts -pthread) - echo 'int main() { return 0; }' | cat > conftest.c - ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1 - if test $? -eq 0; then - if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthread`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then - ac_cv_have_dash_pthread=yes - case "$target_os" in - freebsd*) -# Freebsd doesn't use -pthread for compiles, it uses them for linking - ;; - *) - CFLAGS="$CFLAGS -pthread" - CXXFLAGS="$CXXFLAGS -pthread" - ;; - esac - fi - fi - rm -f conftest* - AC_MSG_RESULT($ac_cv_have_dash_pthread) - - dnl - dnl See if -pthreads is supported. - dnl - ac_cv_have_dash_pthreads=no - if test "$ac_cv_have_dash_pthread" = "no"; then - AC_MSG_CHECKING(whether ${CC-cc} accepts -pthreads) - echo 'int main() { return 0; }' | cat > conftest.c - ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1 - if test $? -eq 0; then - if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthreads`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then - ac_cv_have_dash_pthreads=yes - CFLAGS="$CFLAGS -pthreads" - CXXFLAGS="$CXXFLAGS -pthreads" - fi - fi - rm -f conftest* - AC_MSG_RESULT($ac_cv_have_dash_pthreads) - fi - - case "$target" in - *-solaris*) - if test "$ac_cv_have_dash_pthreads" = "yes"; then - _PTHREAD_LDFLAGS= - fi - ;; - *-freebsd*) - AC_DEFINE(_REENTRANT) - AC_DEFINE(_THREAD_SAFE) - dnl -pthread links in -lc_r, so don't specify it explicitly. - if test "$ac_cv_have_dash_pthread" = "yes"; then - _PTHREAD_LDFLAGS="-pthread" - else - _PTHREAD_LDFLAGS="-lc_r" - fi - ;; - *-netbsd*) - if test "$ac_cv_have_dash_pthread" = "yes"; then - _PTHREAD_LDFLAGS="-pthread" - fi - ;; - *-bsdi*) - AC_DEFINE(_THREAD_SAFE) - dnl -pthread links in -lc_r, so don't specify it explicitly. - if test "$ac_cv_have_dash_pthread" = "yes"; then - _PTHREAD_LDFLAGS= - fi - ;; - *-openbsd*) - if test "$ac_cv_have_dash_pthread" = "yes"; then - _PTHREAD_LDFLAGS=-pthread - fi - ;; - *-linux*|*-gnu*|*-k*bsd*-gnu) - AC_DEFINE(_REENTRANT) - ;; - esac - -else - if test -n "$USE_USER_PTHREADS"; then - USE_PTHREADS= - USE_NSPR_THREADS= - else - _PTHREAD_LDFLAGS= - fi -fi -dnl Special thread exceptions - -case "$target" in -*-aix*) - if test -n "$USE_NSPR_THREADS"; then - AC_DEFINE(_PR_LOCAL_THREADS_ONLY) - fi - case "$target_os" in - aix4.1*) - if test -z "$USE_PTHREADS"; then - AC_DEFINE(AIX_RENAME_SELECT) - fi - ;; - aix4.2*) - if test -z "$USE_NSPR_THREADS"; then - AC_DEFINE(HAVE_POINTER_LOCALTIME_R) - fi - ;; - aix4.3*) - if test -z "$USE_NSPR_THREADS"; then - AC_DEFINE(HAVE_POINTER_LOCALTIME_R) - fi - if test -n "$USE_PTHREADS"; then - AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST) - fi - ;; - *) - if test -z "$USE_NSPR_THREADS"; then - AC_DEFINE(HAVE_POINTER_LOCALTIME_R) - fi - if test -n "$USE_PTHREADS"; then - AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST) - fi - ;; - esac - ;; -*-bsdi*) - if test -n "$USE_PTHREADS"; then - AC_DEFINE(_PR_NEED_PTHREAD_INIT) - fi - ;; -*-freebsd*) - if test -n "$USE_NSPR_THREADS"; then - AC_DEFINE(_PR_LOCAL_THREADS_ONLY) - fi - ;; -*-hpux*) - if test -n "$USE_NSPR_THREADS"; then - AC_DEFINE(_PR_LOCAL_THREADS_ONLY) - fi - if test "$USE_PTHREADS"; then - if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then - AC_DEFINE(_REENTRANT) - AC_DEFINE(_PR_DCETHREADS) - else - AC_DEFINE_UNQUOTED(_POSIX_C_SOURCE,199506L) - AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST) - fi - fi - if test "$USE_USER_PTHREADS"; then - AC_DEFINE_UNQUOTED(_POSIX_C_SOURCE,199506L) - fi - ;; -*-irix*) - if test "${target_os}" = "irix6.5"; then - if test -n "$USE_PTHREADS"; then - AC_DEFINE(_PR_HAVE_GETHOST_R) - AC_DEFINE(_PR_HAVE_GETHOST_R_POINTER) - fi - fi - ;; -*-linux*|*-gnu*|*-k*bsd*-gnu) - if test -n "$USE_NSPR_THREADS"; then - AC_DEFINE(_PR_LOCAL_THREADS_ONLY) - fi - ;; -*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*|*-os2*|*-beos*) - dnl win32, wince, os2 & beos cannot use pthreads - USE_PTHREADS= - _PTHREAD_LDFLAGS= - USE_USER_PTHREADS= - ;; -*-netbsd*|*-openbsd*) - if test -n "$USE_NSPR_THREADS"; then - AC_DEFINE(_PR_LOCAL_THREADS_ONLY) - fi - ;; -*-osf*) - if test -n "$USE_NSPR_THREADS"; then - AC_DEFINE(_PR_LOCAL_THREADS_ONLY) - fi - if test -n "$USE_PTHREADS"; then - if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then - : - else - AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST) - fi - fi - ;; -*-solaris*) - if test -n "$USE_NSPR_THREADS"; then - AC_DEFINE(_PR_LOCAL_THREADS_ONLY) - fi - if test -n "$USE_PTHREADS"; then - AC_DEFINE(_REENTRANT) - AC_DEFINE(HAVE_POINTER_LOCALTIME_R) - if test "$OS_TEST" = "i86pc"; then - if test -n "$USE_64"; then - PR_MD_ASFILES=os_SunOS_x86_64.s - else - PR_MD_ASFILES=os_SunOS_x86.s - fi - else - if test -n "$USE_64"; then - PR_MD_ASFILES=os_SunOS_sparcv9.s - fi - fi - fi - ;; -*-nto*) - if test -n "$USE_PTHREADS"; then - AC_DEFINE(_PR_HAVE_GETHOST_R) - AC_DEFINE(_PR_HAVE_GETHOST_R_POINTER) - fi - ;; -esac - -OS_LIBS="$_PTHREAD_LDFLAGS $OS_LIBS" - -dnl If the user passed in arg to --enable-optimize or --enable-debug, -dnl make sure that we use it. -if test -n "$_SAVE_OPTIMIZE_FLAGS"; then - _OPTIMIZE_FLAGS="$_SAVE_OPTIMIZE_FLAGS" -fi - -if test -n "$_SAVE_DEBUG_FLAGS"; then - _DEBUG_FLAGS="$_SAVE_DEBUG_FLAGS" -fi - -if test -n "$MOZ_OPTIMIZE"; then - CFLAGS="$CFLAGS $_OPTIMIZE_FLAGS" - CXXFLAGS="$CXXFLAGS $_OPTIMIZE_FLAGS" -fi - -if test -n "$MOZ_DEBUG_SYMBOLS"; then - CFLAGS="$CFLAGS $_DEBUG_FLAGS" - CXXFLAGS="$CXXFLAGS $_DEBUG_FLAGS" -fi - -if test -n "$MOZ_OPTIMIZE"; then - OBJDIR_TAG=_OPT -else - OBJDIR_TAG=_DBG -fi - -if test -n "$USE_64"; then - COMPILER_TAG=_64 -fi - -RELEASE_OBJDIR_NAME="${OS_CONFIG}${CPU_ARCH_TAG}${COMPILER_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}.${OBJDIR_SUFFIX}" - -dnl ======================================================== -dnl Use cygwin wrapper for win32 builds, except MSYS/MinGW -dnl ======================================================== -case "$target_os" in -cygwin*|msvc*|mks*) - CC="\$(CYGWIN_WRAPPER) $CC" - CXX="\$(CYGWIN_WRAPPER) $CXX" - RC="\$(CYGWIN_WRAPPER) $RC" - ;; -esac - -dnl ======================================================== -dnl = Use malloc wrapper lib -dnl ======================================================== -AC_ARG_ENABLE(wrap-malloc, -[ --enable-wrap-malloc Wrap malloc calls (gnu linker only)], -[ if test "$enableval" = "yes"; then - _WRAP_MALLOC=1 - fi ]) - -if test -n "$_WRAP_MALLOC"; then - if test -n "$GNU_CC"; then - WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=malloc,--wrap=calloc,--wrap=valloc,--wrap=free,--wrap=realloc,--wrap=memalign" - WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=__builtin_new,--wrap=__builtin_vec_new,--wrap=__builtin_delete,--wrap=__builtin_vec_delete" - WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=strdup,--wrap=strndup" - WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=posix_memalign,--wrap=malloc_usable_size" - else - AC_MSG_ERROR([--enable-wrap-malloc is not supported for non-GNU toolchains]) - fi -fi - -dnl ======================================================== -dnl = Location of malloc wrapper lib -dnl ======================================================== -AC_ARG_WITH(wrap-malloc, -[ --with-wrap-malloc=SHAREDLIB Location of malloc wrapper library], - WRAP_LDFLAGS="${WRAP_LDFLAGS} $withval") - -dnl ======================================================== -dnl Substitution of found variables. -dnl ======================================================== -AC_SUBST(SHELL_OVERRIDE) - -AC_SUBST(MOZILLA_CLIENT) -AC_SUBST(CC) -AC_SUBST(CXX) -AC_SUBST(CFLAGS) -AC_SUBST(CXXFLAGS) -AC_SUBST(CPPFLAGS) -AC_SUBST(HOST_CC) -AC_SUBST(HOST_CFLAGS) -AC_SUBST(LDFLAGS) -AC_SUBST(HOST_LDFLAGS) -AC_SUBST(GNU_CC) -AC_SUBST(GCC_USE_GNU_LD) -AC_SUBST(MSC_VER) -AC_SUBST(CROSS_COMPILE) - -AC_SUBST(MOZ_OPTIMIZE) -AC_SUBST(MOZ_DEBUG) -AC_SUBST(MOZ_DEBUG_SYMBOLS) - -AC_SUBST(USE_CPLUS) -AC_SUBST(USE_IPV6) -AC_SUBST(USE_N32) -AC_SUBST(USE_64) -AC_SUBST(OBJECT_MODE) -AC_SUBST(ENABLE_STRIP) - -AC_SUBST(USE_PTHREADS) -AC_SUBST(USE_BTHREADS) -AC_SUBST(USE_USER_PTHREADS) -AC_SUBST(USE_NSPR_THREADS) - -AC_SUBST(LIBNSPR) -AC_SUBST(LIBPLC) - -AC_SUBST(MOD_MAJOR_VERSION) -AC_SUBST(MOD_MINOR_VERSION) -AC_SUBST(MOD_PATCH_VERSION) -AC_SUBST(NSPR_MODNAME) -AC_SUBST(MDCPUCFG_H) -AC_SUBST(PR_MD_CSRCS) -AC_SUBST(PR_MD_ASFILES) -AC_SUBST(PR_MD_ARCH_DIR) -AC_SUBST(CPU_ARCH) - -AC_SUBST(OBJ_SUFFIX) -AC_SUBST(LIB_SUFFIX) -AC_SUBST(DLL_SUFFIX) -AC_SUBST(ASM_SUFFIX) -AC_SUBST(WRAP_LDFLAGS) -AC_SUBST(MKSHLIB) -AC_SUBST(DSO_CFLAGS) -AC_SUBST(DSO_LDOPTS) - -AC_SUBST(OS_TARGET) -AC_SUBST(OS_ARCH) -AC_SUBST(OS_RELEASE) -AC_SUBST(OS_TEST) -AC_SUBST(MACOSX_DEPLOYMENT_TARGET) - -AC_SUBST(DEFINES) -AC_SUBST(DEFS) -AC_SUBST(AR) -AC_SUBST(AR_FLAGS) -AC_SUBST(AS) -AC_SUBST(ASFLAGS) -AC_SUBST(LD) -AC_SUBST(RANLIB) -AC_SUBST(PERL) -AC_SUBST(STRIP) -AC_SUBST(FILTER) -AC_SUBST(IMPLIB) - -AC_SUBST(PROFILE_GEN_CFLAGS) -AC_SUBST(PROFILE_GEN_LDFLAGS) -AC_SUBST(PROFILE_USE_CFLAGS) -AC_SUBST(PROFILE_USE_LDFLAGS) - -AC_SUBST(OS_LIBS) -AC_SUBST(RESOLVE_LINK_SYMBOLS) -AC_SUBST(AIX_LINK_OPTS) -AC_SUBST(NOSUCHFILE) -AC_SUBST(MOZ_OBJFORMAT) -AC_SUBST(ULTRASPARC_LIBRARY) - -AC_SUBST(OBJDIR) -AC_SUBST(OBJDIR_NAME) -AC_SUBST(RELEASE_OBJDIR_NAME) -AC_SUBST(NSINSTALL) -AC_SUBST(OPTIMIZER) -AC_SUBST(RC) -AC_SUBST(RCFLAGS) -AC_SUBST(DLLFLAGS) -AC_SUBST(EXEFLAGS) -AC_SUBST(OS_DLLFLAGS) -AC_SUBST(CYGWIN_WRAPPER) -AC_SUBST(VISIBILITY_FLAGS) -AC_SUBST(WRAP_SYSTEM_INCLUDES) -AC_SUBST(MACOS_SDK_DIR) -AC_SUBST(SYMBIAN_SDK_DIR) -AC_SUBST(NEXT_ROOT) -AC_SUBST(MT) - -dnl ======================================================== -dnl Generate output files. -dnl ======================================================== -MAKEFILES=" - Makefile - config/Makefile - config/autoconf.mk - config/nsprincl.mk - config/nsprincl.sh - config/nspr-config - config/nspr.pc - lib/Makefile - lib/ds/Makefile - lib/libc/Makefile - lib/libc/include/Makefile - lib/libc/src/Makefile - lib/tests/Makefile - pkg/Makefile - pr/Makefile - pr/include/Makefile - pr/include/md/Makefile - pr/include/obsolete/Makefile - pr/include/private/Makefile - pr/src/Makefile - pr/src/io/Makefile - pr/src/linking/Makefile - pr/src/malloc/Makefile - pr/src/md/Makefile - pr/src/md/${PR_MD_ARCH_DIR}/Makefile - pr/src/memory/Makefile - pr/src/misc/Makefile - pr/src/threads/Makefile - pr/tests/Makefile - pr/tests/dll/Makefile -" - -if test "$OS_TARGET" = "Linux"; then - MAKEFILES="$MAKEFILES - pkg/linux/Makefile - " -elif test "$OS_TARGET" = "SunOS"; then - MAKEFILES="$MAKEFILES - pkg/solaris/Makefile - pkg/solaris/SUNWpr/Makefile - pkg/solaris/SUNWprd/Makefile - " -fi - -if test -z "$USE_PTHREADS" && test -z "$USE_BTHREADS"; then - MAKEFILES="$MAKEFILES - pr/src/threads/combined/Makefile - " -elif test -n "$USE_PTHREADS"; then - MAKEFILES="$MAKEFILES - pr/src/pthreads/Makefile - " -elif test -n "$USE_BTHREADS"; then - MAKEFILES="$MAKEFILES - pr/src/bthreads/Makefile - " -fi - -if test -n "$USE_CPLUS"; then - MAKEFILES="$MAKEFILES - pr/src/cplus/Makefile - pr/src/cplus/tests/Makefile - " -fi - -echo $MAKEFILES > unallmakefiles - -AC_OUTPUT([$MAKEFILES], [chmod +x config/nspr-config]) diff -Nru nspr-4.9.5/mozilla/nsprpub/.cvsignore nspr-4.10.7/mozilla/nsprpub/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/.cvsignore 2001-05-12 00:53:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -Makefile -config-defs.h -config.cache -config.log -config.status diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/.cvsignore nspr-4.10.7/mozilla/nsprpub/lib/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/lib/.cvsignore 2001-05-12 01:02:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/.cvsignore nspr-4.10.7/mozilla/nsprpub/lib/ds/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/lib/ds/.cvsignore 2001-05-14 22:12:54.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Makefile -_pl_bld.h diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/Makefile.in nspr-4.10.7/mozilla/nsprpub/lib/ds/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/lib/ds/Makefile.in 2012-11-13 23:17:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include - -CSRCS = \ - plarena.c \ - plhash.c \ - plvrsion.c \ - $(NULL) - -HEADERS = \ - plarenas.h \ - plarena.h \ - plhash.h \ - $(NULL) - -HEADERS := $(addprefix $(srcdir)/, $(HEADERS)) - -ifeq ($(OS_ARCH), WINNT) -RES=$(OBJDIR)/plds.res -RESNAME=plds.rc -endif # WINNT - -ifeq ($(OS_ARCH), AIX) -ifeq ($(CLASSIC_NSPR),1) -OS_LIBS = -lc -else -OS_LIBS = -lc_r -endif -endif - -ifeq ($(OS_ARCH),IRIX) -OS_LIBS = -lc -endif - -ifeq ($(OS_ARCH),SunOS) -OS_LIBS = -lc -MAPFILE = $(OBJDIR)/pldsmap.sun -GARBAGE += $(MAPFILE) -ifdef NS_USE_GCC -ifdef GCC_USE_GNU_LD -MKSHLIB += -Wl,--version-script,$(MAPFILE) -else -MKSHLIB += -Wl,-M,$(MAPFILE) -endif -else -MKSHLIB += -M $(MAPFILE) -endif -# The -R '$ORIGIN' linker option instructs this library to search for its -# dependencies in the same directory where it resides. -MKSHLIB += -R '$$ORIGIN' -endif - -ifeq ($(OS_ARCH),OS2) -MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def -GARBAGE += $(MAPFILE) -MKSHLIB += $(MAPFILE) -endif - -EXTRA_LIBS = $(LIBNSPR) - -# On SCOOS, we can't link with extra libraries when -# we build a shared library. If we do so, the linker doesn't -# complain, but we would run into weird problems at run-time. -# Therefore on these platforms, we link just the .o files. -ifeq ($(OS_ARCH),SCOOS) -EXTRA_LIBS = -endif - -ifdef RESOLVE_LINK_SYMBOLS -EXTRA_LIBS += $(OS_LIBS) -endif - -LIBRARY_NAME = plds -LIBRARY_VERSION = $(MOD_MAJOR_VERSION) - -RELEASE_HEADERS = $(HEADERS) -RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR) -RELEASE_LIBS = $(TARGETS) - -include $(topsrcdir)/config/rules.mk - -# -# Version information generation (begin) -# -ECHO = echo -TINC = $(OBJDIR)/_pl_bld.h -PROD = $(notdir $(SHARED_LIBRARY)) -NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now -SH_DATE = $(shell date "+%Y-%m-%d %T") -SH_NOW = $(shell $(NOW)) - -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - SUF = i64 -else - SUF = LL -endif - -GARBAGE += $(TINC) - -$(TINC): - @$(MAKE_OBJDIR) - @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC) - @if test ! -z "$(SH_NOW)"; then \ - $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \ - else \ - true; \ - fi - @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) - - -$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC) -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $< -else - $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< -endif -# -# Version information generation (end) -# - -# -# The Client build wants the shared libraries in $(dist_bindir), -# so we also install them there. -# - -export:: $(TARGETS) - $(INSTALL) -m 444 $(HEADERS) $(dist_includedir) - $(INSTALL) -m 444 $(TARGETS) $(dist_libdir) -ifdef SHARED_LIBRARY -ifeq ($(OS_ARCH),HP-UX) - $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir) - $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir) -else - $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir) -endif -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/plarena.c nspr-4.10.7/mozilla/nsprpub/lib/ds/plarena.c --- nspr-4.9.5/mozilla/nsprpub/lib/ds/plarena.c 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/plarena.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,418 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Lifetime-based fast allocation, inspired by much prior art, including - * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes" - * David R. Hanson, Software -- Practice and Experience, Vol. 20(1). - */ -#include -#include -#include "plarena.h" -#include "prmem.h" -#include "prbit.h" -#include "prlog.h" -#include "prlock.h" -#include "prinit.h" - -static PLArena *arena_freelist; - -#ifdef PL_ARENAMETER -static PLArenaStats *arena_stats_list; - -#define COUNT(pool,what) (pool)->stats.what++ -#else -#define COUNT(pool,what) /* nothing */ -#endif - -#define PL_ARENA_DEFAULT_ALIGN sizeof(double) - -static PRLock *arenaLock; -static PRCallOnceType once; -static const PRCallOnceType pristineCallOnce; - -/* -** InitializeArenas() -- Initialize arena operations. -** -** InitializeArenas() is called exactly once and only once from -** LockArena(). This function creates the arena protection -** lock: arenaLock. -** -** Note: If the arenaLock cannot be created, InitializeArenas() -** fails quietly, returning only PR_FAILURE. This percolates up -** to the application using the Arena API. He gets no arena -** from PL_ArenaAllocate(). It's up to him to fail gracefully -** or recover. -** -*/ -static PRStatus InitializeArenas( void ) -{ - PR_ASSERT( arenaLock == NULL ); - arenaLock = PR_NewLock(); - if ( arenaLock == NULL ) - return PR_FAILURE; - else - return PR_SUCCESS; -} /* end ArenaInitialize() */ - -static PRStatus LockArena( void ) -{ - PRStatus rc = PR_CallOnce( &once, InitializeArenas ); - - if ( PR_FAILURE != rc ) - PR_Lock( arenaLock ); - return(rc); -} /* end LockArena() */ - -static void UnlockArena( void ) -{ - PR_Unlock( arenaLock ); - return; -} /* end UnlockArena() */ - -PR_IMPLEMENT(void) PL_InitArenaPool( - PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align) -{ - /* - * Look-up table of PR_BITMASK(PR_CeilingLog2(align)) values for - * align = 1 to 32. - */ - static const PRUint8 pmasks[33] = { - 0, /* not used */ - 0, 1, 3, 3, 7, 7, 7, 7,15,15,15,15,15,15,15,15, /* 1 ... 16 */ - 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31}; /* 17 ... 32 */ - - if (align == 0) - align = PL_ARENA_DEFAULT_ALIGN; - - if (align < sizeof(pmasks)/sizeof(pmasks[0])) - pool->mask = pmasks[align]; - else - pool->mask = PR_BITMASK(PR_CeilingLog2(align)); - - pool->first.next = NULL; - pool->first.base = pool->first.avail = pool->first.limit = - (PRUword)PL_ARENA_ALIGN(pool, &pool->first + 1); - pool->current = &pool->first; - /* - * Compute the net size so that each arena's gross size is |size|. - * sizeof(PLArena) + pool->mask is the header and alignment slop - * that PL_ArenaAllocate adds to the net size. - */ - if (size > sizeof(PLArena) + pool->mask) - pool->arenasize = size - (sizeof(PLArena) + pool->mask); - else - pool->arenasize = size; -#ifdef PL_ARENAMETER - memset(&pool->stats, 0, sizeof pool->stats); - pool->stats.name = strdup(name); - pool->stats.next = arena_stats_list; - arena_stats_list = &pool->stats; -#endif -} - - -/* -** PL_ArenaAllocate() -- allocate space from an arena pool -** -** Description: PL_ArenaAllocate() allocates space from an arena -** pool. -** -** First, try to satisfy the request from arenas starting at -** pool->current. -** -** If there is not enough space in the arena pool->current, try -** to claim an arena, on a first fit basis, from the global -** freelist (arena_freelist). -** -** If no arena in arena_freelist is suitable, then try to -** allocate a new arena from the heap. -** -** Returns: pointer to allocated space or NULL -** -** Notes: The original implementation had some difficult to -** solve bugs; the code was difficult to read. Sometimes it's -** just easier to rewrite it. I did that. larryh. -** -** See also: bugzilla: 45343. -** -*/ - -PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb) -{ - PLArena *a; - char *rp; /* returned pointer */ - - PR_ASSERT((nb & pool->mask) == 0); - - nb = (PRUword)PL_ARENA_ALIGN(pool, nb); /* force alignment */ - - /* attempt to allocate from arenas at pool->current */ - { - a = pool->current; - do { - if ( a->avail +nb <= a->limit ) { - pool->current = a; - rp = (char *)a->avail; - a->avail += nb; - return rp; - } - } while( NULL != (a = a->next) ); - } - - /* attempt to allocate from arena_freelist */ - { - PLArena *p; /* previous pointer, for unlinking from freelist */ - - /* lock the arena_freelist. Make access to the freelist MT-Safe */ - if ( PR_FAILURE == LockArena()) - return(0); - - for ( a = arena_freelist, p = NULL; a != NULL ; p = a, a = a->next ) { - if ( a->base +nb <= a->limit ) { - if ( p == NULL ) - arena_freelist = a->next; - else - p->next = a->next; - UnlockArena(); - a->avail = a->base; - rp = (char *)a->avail; - a->avail += nb; - /* the newly allocated arena is linked after pool->current - * and becomes pool->current */ - a->next = pool->current->next; - pool->current->next = a; - pool->current = a; - if ( NULL == pool->first.next ) - pool->first.next = a; - return(rp); - } - } - UnlockArena(); - } - - /* attempt to allocate from the heap */ - { - PRUint32 sz = PR_MAX(pool->arenasize, nb); - sz += sizeof *a + pool->mask; /* header and alignment slop */ - a = (PLArena*)PR_MALLOC(sz); - if ( NULL != a ) { - a->limit = (PRUword)a + sz; - a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1); - rp = (char *)a->avail; - a->avail += nb; - /* the newly allocated arena is linked after pool->current - * and becomes pool->current */ - a->next = pool->current->next; - pool->current->next = a; - pool->current = a; - if ( NULL == pool->first.next ) - pool->first.next = a; - PL_COUNT_ARENA(pool,++); - COUNT(pool, nmallocs); - return(rp); - } - } - - /* we got to here, and there's no memory to allocate */ - return(NULL); -} /* --- end PL_ArenaAllocate() --- */ - -PR_IMPLEMENT(void *) PL_ArenaGrow( - PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr) -{ - void *newp; - - PL_ARENA_ALLOCATE(newp, pool, size + incr); - if (newp) - memcpy(newp, p, size); - return newp; -} - -static void ClearArenaList(PLArena *a, PRInt32 pattern) -{ - - for (; a; a = a->next) { - PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); - a->avail = a->base; - PL_CLEAR_UNUSED_PATTERN(a, pattern); - } -} - -PR_IMPLEMENT(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern) -{ - ClearArenaList(pool->first.next, pattern); -} - -/* - * Free tail arenas linked after head, which may not be the true list head. - * Reset pool->current to point to head in case it pointed at a tail arena. - */ -static void FreeArenaList(PLArenaPool *pool, PLArena *head, PRBool reallyFree) -{ - PLArena **ap, *a; - - ap = &head->next; - a = *ap; - if (!a) - return; - -#ifdef DEBUG - ClearArenaList(a, PL_FREE_PATTERN); -#endif - - if (reallyFree) { - do { - *ap = a->next; - PL_CLEAR_ARENA(a); - PL_COUNT_ARENA(pool,--); - PR_DELETE(a); - } while ((a = *ap) != 0); - } else { - /* Insert the whole arena chain at the front of the freelist. */ - do { - ap = &(*ap)->next; - } while (*ap); - LockArena(); - *ap = arena_freelist; - arena_freelist = a; - head->next = 0; - UnlockArena(); - } - - pool->current = head; -} - -PR_IMPLEMENT(void) PL_ArenaRelease(PLArenaPool *pool, char *mark) -{ - PLArena *a; - - for (a = &pool->first; a; a = a->next) { - if (PR_UPTRDIFF(mark, a->base) <= PR_UPTRDIFF(a->avail, a->base)) { - a->avail = (PRUword)PL_ARENA_ALIGN(pool, mark); - FreeArenaList(pool, a, PR_FALSE); - return; - } - } -} - -PR_IMPLEMENT(void) PL_FreeArenaPool(PLArenaPool *pool) -{ - FreeArenaList(pool, &pool->first, PR_FALSE); - COUNT(pool, ndeallocs); -} - -PR_IMPLEMENT(void) PL_FinishArenaPool(PLArenaPool *pool) -{ - FreeArenaList(pool, &pool->first, PR_TRUE); -#ifdef PL_ARENAMETER - { - PLArenaStats *stats, **statsp; - - if (pool->stats.name) - PR_DELETE(pool->stats.name); - for (statsp = &arena_stats_list; (stats = *statsp) != 0; - statsp = &stats->next) { - if (stats == &pool->stats) { - *statsp = stats->next; - return; - } - } - } -#endif -} - -PR_IMPLEMENT(void) PL_CompactArenaPool(PLArenaPool *ap) -{ -} - -PR_IMPLEMENT(void) PL_ArenaFinish(void) -{ - PLArena *a, *next; - - for (a = arena_freelist; a; a = next) { - next = a->next; - PR_DELETE(a); - } - arena_freelist = NULL; - - if (arenaLock) { - PR_DestroyLock(arenaLock); - arenaLock = NULL; - } - once = pristineCallOnce; -} - -#ifdef PL_ARENAMETER -PR_IMPLEMENT(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb) -{ - pool->stats.nallocs++; - pool->stats.nbytes += nb; - if (nb > pool->stats.maxalloc) - pool->stats.maxalloc = nb; - pool->stats.variance += nb * nb; -} - -PR_IMPLEMENT(void) PL_ArenaCountInplaceGrowth( - PLArenaPool *pool, PRUint32 size, PRUint32 incr) -{ - pool->stats.ninplace++; -} - -PR_IMPLEMENT(void) PL_ArenaCountGrowth( - PLArenaPool *pool, PRUint32 size, PRUint32 incr) -{ - pool->stats.ngrows++; - pool->stats.nbytes += incr; - pool->stats.variance -= size * size; - size += incr; - if (size > pool->stats.maxalloc) - pool->stats.maxalloc = size; - pool->stats.variance += size * size; -} - -PR_IMPLEMENT(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark) -{ - pool->stats.nreleases++; -} - -PR_IMPLEMENT(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark) -{ - pool->stats.nfastrels++; -} - -#include -#include - -PR_IMPLEMENT(void) PL_DumpArenaStats(FILE *fp) -{ - PLArenaStats *stats; - double mean, variance; - - for (stats = arena_stats_list; stats; stats = stats->next) { - if (stats->nallocs != 0) { - mean = (double)stats->nbytes / stats->nallocs; - variance = fabs(stats->variance / stats->nallocs - mean * mean); - } else { - mean = variance = 0; - } - - fprintf(fp, "\n%s allocation statistics:\n", stats->name); - fprintf(fp, " number of arenas: %u\n", stats->narenas); - fprintf(fp, " number of allocations: %u\n", stats->nallocs); - fprintf(fp, " number of free arena reclaims: %u\n", stats->nreclaims); - fprintf(fp, " number of malloc calls: %u\n", stats->nmallocs); - fprintf(fp, " number of deallocations: %u\n", stats->ndeallocs); - fprintf(fp, " number of allocation growths: %u\n", stats->ngrows); - fprintf(fp, " number of in-place growths: %u\n", stats->ninplace); - fprintf(fp, "number of released allocations: %u\n", stats->nreleases); - fprintf(fp, " number of fast releases: %u\n", stats->nfastrels); - fprintf(fp, " total bytes allocated: %u\n", stats->nbytes); - fprintf(fp, " mean allocation size: %g\n", mean); - fprintf(fp, " standard deviation: %g\n", sqrt(variance)); - fprintf(fp, " maximum allocation size: %u\n", stats->maxalloc); - } -} -#endif /* PL_ARENAMETER */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/plarena.h nspr-4.10.7/mozilla/nsprpub/lib/ds/plarena.h --- nspr-4.9.5/mozilla/nsprpub/lib/ds/plarena.h 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/plarena.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef plarena_h___ -#define plarena_h___ -/* - * Lifetime-based fast allocation, inspired by much prior art, including - * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes" - * David R. Hanson, Software -- Practice and Experience, Vol. 20(1). - * - * Also supports LIFO allocation (PL_ARENA_MARK/PL_ARENA_RELEASE). - */ -#include "prtypes.h" -#include "plarenas.h" - -PR_BEGIN_EXTERN_C - -typedef struct PLArena PLArena; - -struct PLArena { - PLArena *next; /* next arena for this lifetime */ - PRUword base; /* aligned base address, follows this header */ - PRUword limit; /* one beyond last byte in arena */ - PRUword avail; /* points to next available byte */ -}; - -#ifdef PL_ARENAMETER -typedef struct PLArenaStats PLArenaStats; - -struct PLArenaStats { - PLArenaStats *next; /* next in arenaStats list */ - char *name; /* name for debugging */ - PRUint32 narenas; /* number of arenas in pool */ - PRUint32 nallocs; /* number of PL_ARENA_ALLOCATE() calls */ - PRUint32 nreclaims; /* number of reclaims from freeArenas */ - PRUint32 nmallocs; /* number of malloc() calls */ - PRUint32 ndeallocs; /* number of lifetime deallocations */ - PRUint32 ngrows; /* number of PL_ARENA_GROW() calls */ - PRUint32 ninplace; /* number of in-place growths */ - PRUint32 nreleases; /* number of PL_ARENA_RELEASE() calls */ - PRUint32 nfastrels; /* number of "fast path" releases */ - PRUint32 nbytes; /* total bytes allocated */ - PRUint32 maxalloc; /* maximum allocation size in bytes */ - PRFloat64 variance; /* size variance accumulator */ -}; -#endif - -struct PLArenaPool { - PLArena first; /* first arena in pool list */ - PLArena *current; /* arena from which to allocate space */ - PRUint32 arenasize; /* net exact size of a new arena */ - PRUword mask; /* alignment mask (power-of-2 - 1) */ -#ifdef PL_ARENAMETER - PLArenaStats stats; -#endif -}; - -/* - * If the including .c file uses only one power-of-2 alignment, it may define - * PL_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions - * per ALLOCATE and GROW. - */ -#ifdef PL_ARENA_CONST_ALIGN_MASK -#define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + PL_ARENA_CONST_ALIGN_MASK) \ - & ~PL_ARENA_CONST_ALIGN_MASK) - -#define PL_INIT_ARENA_POOL(pool, name, size) \ - PL_InitArenaPool(pool, name, size, PL_ARENA_CONST_ALIGN_MASK + 1) -#else -#define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + (pool)->mask) & ~(pool)->mask) -#endif - -#define PL_ARENA_ALLOCATE(p, pool, nb) \ - PR_BEGIN_MACRO \ - PLArena *_a = (pool)->current; \ - PRUint32 _nb = PL_ARENA_ALIGN(pool, nb); \ - PRUword _p = _a->avail; \ - PRUword _q = _p + _nb; \ - if (_q > _a->limit) \ - _p = (PRUword)PL_ArenaAllocate(pool, _nb); \ - else \ - _a->avail = _q; \ - p = (void *)_p; \ - PL_ArenaCountAllocation(pool, nb); \ - PR_END_MACRO - -#define PL_ARENA_GROW(p, pool, size, incr) \ - PR_BEGIN_MACRO \ - PLArena *_a = (pool)->current; \ - PRUint32 _incr = PL_ARENA_ALIGN(pool, incr); \ - PRUword _p = _a->avail; \ - PRUword _q = _p + _incr; \ - if (_p == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \ - _q <= _a->limit) { \ - _a->avail = _q; \ - PL_ArenaCountInplaceGrowth(pool, size, incr); \ - } else { \ - p = PL_ArenaGrow(pool, p, size, incr); \ - } \ - PL_ArenaCountGrowth(pool, size, incr); \ - PR_END_MACRO - -#define PL_ARENA_MARK(pool) ((void *) (pool)->current->avail) -#define PR_UPTRDIFF(p,q) ((PRUword)(p) - (PRUword)(q)) - -#define PL_CLEAR_UNUSED_PATTERN(a, pattern) \ - (PR_ASSERT((a)->avail <= (a)->limit), \ - memset((void*)(a)->avail, (pattern), (a)->limit - (a)->avail)) -#ifdef DEBUG -#define PL_FREE_PATTERN 0xDA -#define PL_CLEAR_UNUSED(a) PL_CLEAR_UNUSED_PATTERN((a), PL_FREE_PATTERN) -#define PL_CLEAR_ARENA(a) memset((void*)(a), PL_FREE_PATTERN, \ - (a)->limit - (PRUword)(a)) -#else -#define PL_CLEAR_UNUSED(a) -#define PL_CLEAR_ARENA(a) -#endif - -#define PL_ARENA_RELEASE(pool, mark) \ - PR_BEGIN_MACRO \ - char *_m = (char *)(mark); \ - PLArena *_a = (pool)->current; \ - if (PR_UPTRDIFF(_m, _a->base) <= PR_UPTRDIFF(_a->avail, _a->base)) { \ - _a->avail = (PRUword)PL_ARENA_ALIGN(pool, _m); \ - PL_CLEAR_UNUSED(_a); \ - PL_ArenaCountRetract(pool, _m); \ - } else { \ - PL_ArenaRelease(pool, _m); \ - } \ - PL_ArenaCountRelease(pool, _m); \ - PR_END_MACRO - -#ifdef PL_ARENAMETER -#define PL_COUNT_ARENA(pool,op) ((pool)->stats.narenas op) -#else -#define PL_COUNT_ARENA(pool,op) -#endif - -#define PL_ARENA_DESTROY(pool, a, pnext) \ - PR_BEGIN_MACRO \ - PL_COUNT_ARENA(pool,--); \ - if ((pool)->current == (a)) (pool)->current = &(pool)->first; \ - *(pnext) = (a)->next; \ - PL_CLEAR_ARENA(a); \ - free(a); \ - (a) = 0; \ - PR_END_MACRO - -#ifdef PL_ARENAMETER - -#include - -PR_EXTERN(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb); - -PR_EXTERN(void) PL_ArenaCountInplaceGrowth( - PLArenaPool *pool, PRUint32 size, PRUint32 incr); - -PR_EXTERN(void) PL_ArenaCountGrowth( - PLArenaPool *pool, PRUint32 size, PRUint32 incr); - -PR_EXTERN(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark); - -PR_EXTERN(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark); - -PR_EXTERN(void) PL_DumpArenaStats(FILE *fp); - -#else /* !PL_ARENAMETER */ - -#define PL_ArenaCountAllocation(ap, nb) /* nothing */ -#define PL_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */ -#define PL_ArenaCountGrowth(ap, size, incr) /* nothing */ -#define PL_ArenaCountRelease(ap, mark) /* nothing */ -#define PL_ArenaCountRetract(ap, mark) /* nothing */ - -#endif /* !PL_ARENAMETER */ - -PR_END_EXTERN_C - -#endif /* plarena_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/plarenas.h nspr-4.10.7/mozilla/nsprpub/lib/ds/plarenas.h --- nspr-4.9.5/mozilla/nsprpub/lib/ds/plarenas.h 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/plarenas.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef PLARENAS_H -#define PLARENAS_H - -PR_BEGIN_EXTERN_C - -typedef struct PLArenaPool PLArenaPool; - -/* -** Initialize an arena pool with the given name for debugging and metering, -** with a minimum gross size per arena of size bytes. The net size per arena -** is smaller than the gross size by a header of four pointers plus any -** necessary padding for alignment. -** -** Note: choose a gross size that's a power of two to avoid the heap allocator -** rounding the size up. -**/ -PR_EXTERN(void) PL_InitArenaPool( - PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align); - -/* -** Finish using arenas, freeing all memory associated with them. -**/ -PR_EXTERN(void) PL_ArenaFinish(void); - -/* -** Free the arenas in pool. The user may continue to allocate from pool -** after calling this function. There is no need to call PL_InitArenaPool() -** again unless PL_FinishArenaPool(pool) has been called. -**/ -PR_EXTERN(void) PL_FreeArenaPool(PLArenaPool *pool); - -/* -** Free the arenas in pool and finish using it altogether. -**/ -PR_EXTERN(void) PL_FinishArenaPool(PLArenaPool *pool); - -/* -** Compact all of the arenas in a pool so that no space is wasted. -** NOT IMPLEMENTED. Do not use. -**/ -PR_EXTERN(void) PL_CompactArenaPool(PLArenaPool *pool); - -/* -** Friend functions used by the PL_ARENA_*() macros. -**/ -PR_EXTERN(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb); - -PR_EXTERN(void *) PL_ArenaGrow( - PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr); - -PR_EXTERN(void) PL_ArenaRelease(PLArenaPool *pool, char *mark); - -/* -** memset contents of all arenas in pool to pattern -*/ -PR_EXTERN(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern); - -PR_END_EXTERN_C - -#endif /* PLARENAS_H */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/plds.def nspr-4.10.7/mozilla/nsprpub/lib/ds/plds.def --- nspr-4.9.5/mozilla/nsprpub/lib/ds/plds.def 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/plds.def 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -;+# -;+# This Source Code Form is subject to the terms of the Mozilla Public -;+# License, v. 2.0. If a copy of the MPL was not distributed with this -;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -;+# -;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS -;+# 1. For all unix platforms, the string ";-" means "remove this line" -;+# 2. For all unix platforms, the string " DATA " will be removed from any -;+# line on which it occurs. -;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. -;+# On AIX, lines containing ";+" will be removed. -;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. -;+# 5. For all unix platforms, after the above processing has taken place, -;+# all characters after the first ";" on the line will be removed. -;+# And for AIX, the first ";" will also be removed. -;+# This file is passed directly to windows. Since ';' is a comment, all UNIX -;+# directives are hidden behind ";", ";+", and ";-" -;+NSPR_4.0 { -;+ global: -LIBRARY plds4 ;- -EXPORTS ;- -PL_ArenaAllocate; -PL_ArenaFinish; -PL_ArenaGrow; -PL_ArenaRelease; -PL_CompactArenaPool; -PL_CompareStrings; -PL_CompareValues; -PL_FinishArenaPool; -PL_FreeArenaPool; -PL_HashString; -PL_HashTableAdd; -PL_HashTableDestroy; -PL_HashTableDump; -PL_HashTableEnumerateEntries; -PL_HashTableLookup; -PL_HashTableRawAdd; -PL_HashTableRawLookup; -PL_HashTableRawRemove; -PL_HashTableRemove; -PL_InitArenaPool; -PL_NewHashTable; -libVersionPoint; -;+ local: *; -;+}; -;+ -;+NSPR_4.1 { -;+ global: -PL_HashTableLookupConst; -PL_HashTableRawLookupConst; -;+} NSPR_4.0; -;+ -;+NSPR_4.8.5 { -;+ global: -PL_ClearArenaPool; -;+} NSPR_4.1; diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/plds.rc nspr-4.10.7/mozilla/nsprpub/lib/ds/plds.rc --- nspr-4.9.5/mozilla/nsprpub/lib/ds/plds.rc 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/plds.rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include - -#define MY_LIBNAME "plds" -#define MY_FILEDESCRIPTION "PLDS Library" - -#define STRINGIZE(x) #x -#define STRINGIZE2(x) STRINGIZE(x) -#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR) - -#ifdef _DEBUG -#define MY_DEBUG_STR " (debug)" -#define MY_FILEFLAGS_1 VS_FF_DEBUG -#else -#define MY_DEBUG_STR "" -#define MY_FILEFLAGS_1 0x0L -#endif -#if PR_BETA -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE -#else -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 -#endif - -#ifdef WINNT -#define MY_FILEOS VOS_NT_WINDOWS32 -#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR -#else -#define MY_FILEOS VOS__WINDOWS32 -#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR -#endif - -///////////////////////////////////////////////////////////////////////////// -// -// Version-information resource -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 - PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS MY_FILEFLAGS_2 - FILEOS MY_FILEOS - FILETYPE VFT_DLL - FILESUBTYPE 0x0L // not used - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" // Lang=US English, CharSet=Unicode - BEGIN - VALUE "CompanyName", "Mozilla Foundation\0" - VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" - VALUE "FileVersion", PR_VERSION "\0" - VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" - VALUE "ProductName", "Netscape Portable Runtime\0" - VALUE "ProductVersion", PR_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/plhash.c nspr-4.10.7/mozilla/nsprpub/lib/ds/plhash.c --- nspr-4.9.5/mozilla/nsprpub/lib/ds/plhash.c 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/plhash.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,483 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * PL hash table package. - */ -#include "plhash.h" -#include "prbit.h" -#include "prlog.h" -#include "prmem.h" -#include "prtypes.h" -#include -#include - -/* Compute the number of buckets in ht */ -#define NBUCKETS(ht) (1 << (PL_HASH_BITS - (ht)->shift)) - -/* The smallest table has 16 buckets */ -#define MINBUCKETSLOG2 4 -#define MINBUCKETS (1 << MINBUCKETSLOG2) - -/* Compute the maximum entries given n buckets that we will tolerate, ~90% */ -#define OVERLOADED(n) ((n) - ((n) >> 3)) - -/* Compute the number of entries below which we shrink the table by half */ -#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0) - -/* -** Stubs for default hash allocator ops. -*/ -static void * PR_CALLBACK -DefaultAllocTable(void *pool, PRSize size) -{ - return PR_MALLOC(size); -} - -static void PR_CALLBACK -DefaultFreeTable(void *pool, void *item) -{ - PR_Free(item); -} - -static PLHashEntry * PR_CALLBACK -DefaultAllocEntry(void *pool, const void *key) -{ - return PR_NEW(PLHashEntry); -} - -static void PR_CALLBACK -DefaultFreeEntry(void *pool, PLHashEntry *he, PRUintn flag) -{ - if (flag == HT_FREE_ENTRY) - PR_Free(he); -} - -static PLHashAllocOps defaultHashAllocOps = { - DefaultAllocTable, DefaultFreeTable, - DefaultAllocEntry, DefaultFreeEntry -}; - -PR_IMPLEMENT(PLHashTable *) -PL_NewHashTable(PRUint32 n, PLHashFunction keyHash, - PLHashComparator keyCompare, PLHashComparator valueCompare, - const PLHashAllocOps *allocOps, void *allocPriv) -{ - PLHashTable *ht; - PRSize nb; - - if (n <= MINBUCKETS) { - n = MINBUCKETSLOG2; - } else { - n = PR_CeilingLog2(n); - if ((PRInt32)n < 0) - return 0; - } - - if (!allocOps) allocOps = &defaultHashAllocOps; - - ht = (PLHashTable*)((*allocOps->allocTable)(allocPriv, sizeof *ht)); - if (!ht) - return 0; - memset(ht, 0, sizeof *ht); - ht->shift = PL_HASH_BITS - n; - n = 1 << n; - nb = n * sizeof(PLHashEntry *); - ht->buckets = (PLHashEntry**)((*allocOps->allocTable)(allocPriv, nb)); - if (!ht->buckets) { - (*allocOps->freeTable)(allocPriv, ht); - return 0; - } - memset(ht->buckets, 0, nb); - - ht->keyHash = keyHash; - ht->keyCompare = keyCompare; - ht->valueCompare = valueCompare; - ht->allocOps = allocOps; - ht->allocPriv = allocPriv; - return ht; -} - -PR_IMPLEMENT(void) -PL_HashTableDestroy(PLHashTable *ht) -{ - PRUint32 i, n; - PLHashEntry *he, *next; - const PLHashAllocOps *allocOps = ht->allocOps; - void *allocPriv = ht->allocPriv; - - n = NBUCKETS(ht); - for (i = 0; i < n; i++) { - for (he = ht->buckets[i]; he; he = next) { - next = he->next; - (*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY); - } - } -#ifdef DEBUG - memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]); -#endif - (*allocOps->freeTable)(allocPriv, ht->buckets); -#ifdef DEBUG - memset(ht, 0xDB, sizeof *ht); -#endif - (*allocOps->freeTable)(allocPriv, ht); -} - -/* -** Multiplicative hash, from Knuth 6.4. -*/ -#define GOLDEN_RATIO 0x9E3779B9U /* 2/(1+sqrt(5))*(2^32) */ - -PR_IMPLEMENT(PLHashEntry **) -PL_HashTableRawLookup(PLHashTable *ht, PLHashNumber keyHash, const void *key) -{ - PLHashEntry *he, **hep, **hep0; - PLHashNumber h; - -#ifdef HASHMETER - ht->nlookups++; -#endif - h = keyHash * GOLDEN_RATIO; - h >>= ht->shift; - hep = hep0 = &ht->buckets[h]; - while ((he = *hep) != 0) { - if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) { - /* Move to front of chain if not already there */ - if (hep != hep0) { - *hep = he->next; - he->next = *hep0; - *hep0 = he; - } - return hep0; - } - hep = &he->next; -#ifdef HASHMETER - ht->nsteps++; -#endif - } - return hep; -} - -/* -** Same as PL_HashTableRawLookup but doesn't reorder the hash entries. -*/ -PR_IMPLEMENT(PLHashEntry **) -PL_HashTableRawLookupConst(PLHashTable *ht, PLHashNumber keyHash, - const void *key) -{ - PLHashEntry *he, **hep; - PLHashNumber h; - -#ifdef HASHMETER - ht->nlookups++; -#endif - h = keyHash * GOLDEN_RATIO; - h >>= ht->shift; - hep = &ht->buckets[h]; - while ((he = *hep) != 0) { - if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) { - break; - } - hep = &he->next; -#ifdef HASHMETER - ht->nsteps++; -#endif - } - return hep; -} - -PR_IMPLEMENT(PLHashEntry *) -PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep, - PLHashNumber keyHash, const void *key, void *value) -{ - PRUint32 i, n; - PLHashEntry *he, *next, **oldbuckets; - PRSize nb; - - /* Grow the table if it is overloaded */ - n = NBUCKETS(ht); - if (ht->nentries >= OVERLOADED(n)) { - oldbuckets = ht->buckets; - nb = 2 * n * sizeof(PLHashEntry *); - ht->buckets = (PLHashEntry**) - ((*ht->allocOps->allocTable)(ht->allocPriv, nb)); - if (!ht->buckets) { - ht->buckets = oldbuckets; - return 0; - } - memset(ht->buckets, 0, nb); -#ifdef HASHMETER - ht->ngrows++; -#endif - ht->shift--; - - for (i = 0; i < n; i++) { - for (he = oldbuckets[i]; he; he = next) { - next = he->next; - hep = PL_HashTableRawLookup(ht, he->keyHash, he->key); - PR_ASSERT(*hep == 0); - he->next = 0; - *hep = he; - } - } -#ifdef DEBUG - memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); -#endif - (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); - hep = PL_HashTableRawLookup(ht, keyHash, key); - } - - /* Make a new key value entry */ - he = (*ht->allocOps->allocEntry)(ht->allocPriv, key); - if (!he) - return 0; - he->keyHash = keyHash; - he->key = key; - he->value = value; - he->next = *hep; - *hep = he; - ht->nentries++; - return he; -} - -PR_IMPLEMENT(PLHashEntry *) -PL_HashTableAdd(PLHashTable *ht, const void *key, void *value) -{ - PLHashNumber keyHash; - PLHashEntry *he, **hep; - - keyHash = (*ht->keyHash)(key); - hep = PL_HashTableRawLookup(ht, keyHash, key); - if ((he = *hep) != 0) { - /* Hit; see if values match */ - if ((*ht->valueCompare)(he->value, value)) { - /* key,value pair is already present in table */ - return he; - } - if (he->value) - (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE); - he->value = value; - return he; - } - return PL_HashTableRawAdd(ht, hep, keyHash, key, value); -} - -PR_IMPLEMENT(void) -PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he) -{ - PRUint32 i, n; - PLHashEntry *next, **oldbuckets; - PRSize nb; - - *hep = he->next; - (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY); - - /* Shrink table if it's underloaded */ - n = NBUCKETS(ht); - if (--ht->nentries < UNDERLOADED(n)) { - oldbuckets = ht->buckets; - nb = n * sizeof(PLHashEntry*) / 2; - ht->buckets = (PLHashEntry**)( - (*ht->allocOps->allocTable)(ht->allocPriv, nb)); - if (!ht->buckets) { - ht->buckets = oldbuckets; - return; - } - memset(ht->buckets, 0, nb); -#ifdef HASHMETER - ht->nshrinks++; -#endif - ht->shift++; - - for (i = 0; i < n; i++) { - for (he = oldbuckets[i]; he; he = next) { - next = he->next; - hep = PL_HashTableRawLookup(ht, he->keyHash, he->key); - PR_ASSERT(*hep == 0); - he->next = 0; - *hep = he; - } - } -#ifdef DEBUG - memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); -#endif - (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); - } -} - -PR_IMPLEMENT(PRBool) -PL_HashTableRemove(PLHashTable *ht, const void *key) -{ - PLHashNumber keyHash; - PLHashEntry *he, **hep; - - keyHash = (*ht->keyHash)(key); - hep = PL_HashTableRawLookup(ht, keyHash, key); - if ((he = *hep) == 0) - return PR_FALSE; - - /* Hit; remove element */ - PL_HashTableRawRemove(ht, hep, he); - return PR_TRUE; -} - -PR_IMPLEMENT(void *) -PL_HashTableLookup(PLHashTable *ht, const void *key) -{ - PLHashNumber keyHash; - PLHashEntry *he, **hep; - - keyHash = (*ht->keyHash)(key); - hep = PL_HashTableRawLookup(ht, keyHash, key); - if ((he = *hep) != 0) { - return he->value; - } - return 0; -} - -/* -** Same as PL_HashTableLookup but doesn't reorder the hash entries. -*/ -PR_IMPLEMENT(void *) -PL_HashTableLookupConst(PLHashTable *ht, const void *key) -{ - PLHashNumber keyHash; - PLHashEntry *he, **hep; - - keyHash = (*ht->keyHash)(key); - hep = PL_HashTableRawLookupConst(ht, keyHash, key); - if ((he = *hep) != 0) { - return he->value; - } - return 0; -} - -/* -** Iterate over the entries in the hash table calling func for each -** entry found. Stop if "f" says to (return value & PR_ENUMERATE_STOP). -** Return a count of the number of elements scanned. -*/ -PR_IMPLEMENT(int) -PL_HashTableEnumerateEntries(PLHashTable *ht, PLHashEnumerator f, void *arg) -{ - PLHashEntry *he, **hep; - PRUint32 i, nbuckets; - int rv, n = 0; - PLHashEntry *todo = 0; - - nbuckets = NBUCKETS(ht); - for (i = 0; i < nbuckets; i++) { - hep = &ht->buckets[i]; - while ((he = *hep) != 0) { - rv = (*f)(he, n, arg); - n++; - if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) { - *hep = he->next; - if (rv & HT_ENUMERATE_REMOVE) { - he->next = todo; - todo = he; - } - } else { - hep = &he->next; - } - if (rv & HT_ENUMERATE_STOP) { - goto out; - } - } - } - -out: - hep = &todo; - while ((he = *hep) != 0) { - PL_HashTableRawRemove(ht, hep, he); - } - return n; -} - -#ifdef HASHMETER -#include -#include - -PR_IMPLEMENT(void) -PL_HashTableDumpMeter(PLHashTable *ht, PLHashEnumerator dump, FILE *fp) -{ - double mean, variance; - PRUint32 nchains, nbuckets; - PRUint32 i, n, maxChain, maxChainLen; - PLHashEntry *he; - - variance = 0; - nchains = 0; - maxChainLen = 0; - nbuckets = NBUCKETS(ht); - for (i = 0; i < nbuckets; i++) { - he = ht->buckets[i]; - if (!he) - continue; - nchains++; - for (n = 0; he; he = he->next) - n++; - variance += n * n; - if (n > maxChainLen) { - maxChainLen = n; - maxChain = i; - } - } - mean = (double)ht->nentries / nchains; - variance = fabs(variance / nchains - mean * mean); - - fprintf(fp, "\nHash table statistics:\n"); - fprintf(fp, " number of lookups: %u\n", ht->nlookups); - fprintf(fp, " number of entries: %u\n", ht->nentries); - fprintf(fp, " number of grows: %u\n", ht->ngrows); - fprintf(fp, " number of shrinks: %u\n", ht->nshrinks); - fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps - / ht->nlookups); - fprintf(fp, "mean hash chain length: %g\n", mean); - fprintf(fp, " standard deviation: %g\n", sqrt(variance)); - fprintf(fp, " max hash chain length: %u\n", maxChainLen); - fprintf(fp, " max hash chain: [%u]\n", maxChain); - - for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++) - if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT) - break; -} -#endif /* HASHMETER */ - -PR_IMPLEMENT(int) -PL_HashTableDump(PLHashTable *ht, PLHashEnumerator dump, FILE *fp) -{ - int count; - - count = PL_HashTableEnumerateEntries(ht, dump, fp); -#ifdef HASHMETER - PL_HashTableDumpMeter(ht, dump, fp); -#endif - return count; -} - -PR_IMPLEMENT(PLHashNumber) -PL_HashString(const void *key) -{ - PLHashNumber h; - const PRUint8 *s; - - h = 0; - for (s = (const PRUint8*)key; *s; s++) - h = PR_ROTATE_LEFT32(h, 4) ^ *s; - return h; -} - -PR_IMPLEMENT(int) -PL_CompareStrings(const void *v1, const void *v2) -{ - return strcmp((const char*)v1, (const char*)v2) == 0; -} - -PR_IMPLEMENT(int) -PL_CompareValues(const void *v1, const void *v2) -{ - return v1 == v2; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/plhash.h nspr-4.10.7/mozilla/nsprpub/lib/ds/plhash.h --- nspr-4.9.5/mozilla/nsprpub/lib/ds/plhash.h 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/plhash.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef plhash_h___ -#define plhash_h___ -/* - * API to portable hash table code. - */ -#include -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -typedef struct PLHashEntry PLHashEntry; -typedef struct PLHashTable PLHashTable; -typedef PRUint32 PLHashNumber; -#define PL_HASH_BITS 32 /* Number of bits in PLHashNumber */ -typedef PLHashNumber (PR_CALLBACK *PLHashFunction)(const void *key); -typedef PRIntn (PR_CALLBACK *PLHashComparator)(const void *v1, const void *v2); - -typedef PRIntn (PR_CALLBACK *PLHashEnumerator)(PLHashEntry *he, PRIntn i, void *arg); - -/* Flag bits in PLHashEnumerator's return value */ -#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */ -#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */ -#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */ -#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */ - -typedef struct PLHashAllocOps { - void * (PR_CALLBACK *allocTable)(void *pool, PRSize size); - void (PR_CALLBACK *freeTable)(void *pool, void *item); - PLHashEntry * (PR_CALLBACK *allocEntry)(void *pool, const void *key); - void (PR_CALLBACK *freeEntry)(void *pool, PLHashEntry *he, PRUintn flag); -} PLHashAllocOps; - -#define HT_FREE_VALUE 0 /* just free the entry's value */ -#define HT_FREE_ENTRY 1 /* free value and entire entry */ - -struct PLHashEntry { - PLHashEntry *next; /* hash chain linkage */ - PLHashNumber keyHash; /* key hash function result */ - const void *key; /* ptr to opaque key */ - void *value; /* ptr to opaque value */ -}; - -struct PLHashTable { - PLHashEntry **buckets; /* vector of hash buckets */ - PRUint32 nentries; /* number of entries in table */ - PRUint32 shift; /* multiplicative hash shift */ - PLHashFunction keyHash; /* key hash function */ - PLHashComparator keyCompare; /* key comparison function */ - PLHashComparator valueCompare; /* value comparison function */ - const PLHashAllocOps *allocOps; /* allocation operations */ - void *allocPriv; /* allocation private data */ -#ifdef HASHMETER - PRUint32 nlookups; /* total number of lookups */ - PRUint32 nsteps; /* number of hash chains traversed */ - PRUint32 ngrows; /* number of table expansions */ - PRUint32 nshrinks; /* number of table contractions */ -#endif -}; - -/* - * Create a new hash table. - * If allocOps is null, use default allocator ops built on top of malloc(). - */ -PR_EXTERN(PLHashTable *) -PL_NewHashTable(PRUint32 numBuckets, PLHashFunction keyHash, - PLHashComparator keyCompare, PLHashComparator valueCompare, - const PLHashAllocOps *allocOps, void *allocPriv); - -PR_EXTERN(void) -PL_HashTableDestroy(PLHashTable *ht); - -/* Higher level access methods */ -PR_EXTERN(PLHashEntry *) -PL_HashTableAdd(PLHashTable *ht, const void *key, void *value); - -PR_EXTERN(PRBool) -PL_HashTableRemove(PLHashTable *ht, const void *key); - -PR_EXTERN(void *) -PL_HashTableLookup(PLHashTable *ht, const void *key); - -PR_EXTERN(void *) -PL_HashTableLookupConst(PLHashTable *ht, const void *key); - -PR_EXTERN(PRIntn) -PL_HashTableEnumerateEntries(PLHashTable *ht, PLHashEnumerator f, void *arg); - -/* General-purpose C string hash function. */ -PR_EXTERN(PLHashNumber) -PL_HashString(const void *key); - -/* Compare strings using strcmp(), return true if equal. */ -PR_EXTERN(PRIntn) -PL_CompareStrings(const void *v1, const void *v2); - -/* Stub function just returns v1 == v2 */ -PR_EXTERN(PRIntn) -PL_CompareValues(const void *v1, const void *v2); - -/* Low level access methods */ -PR_EXTERN(PLHashEntry **) -PL_HashTableRawLookup(PLHashTable *ht, PLHashNumber keyHash, const void *key); - -PR_EXTERN(PLHashEntry **) -PL_HashTableRawLookupConst(PLHashTable *ht, PLHashNumber keyHash, - const void *key); - -PR_EXTERN(PLHashEntry *) -PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep, PLHashNumber keyHash, - const void *key, void *value); - -PR_EXTERN(void) -PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he); - -/* This can be trivially implemented using PL_HashTableEnumerateEntries. */ -PR_EXTERN(PRIntn) -PL_HashTableDump(PLHashTable *ht, PLHashEnumerator dump, FILE *fp); - -PR_END_EXTERN_C - -#endif /* plhash_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/ds/plvrsion.c nspr-4.10.7/mozilla/nsprpub/lib/ds/plvrsion.c --- nspr-4.9.5/mozilla/nsprpub/lib/ds/plvrsion.c 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/ds/plvrsion.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include "prvrsion.h" - -/************************************************************************/ -/**************************IDENTITY AND VERSIONING***********************/ -/************************************************************************/ -#include "_pl_bld.h" -#if !defined(_BUILD_TIME) -#ifdef HAVE_LONG_LONG -#define _BUILD_TIME 0 -#else -#define _BUILD_TIME {0, 0} -#endif -#endif -#if !defined(_BUILD_STRING) -#define _BUILD_STRING "" -#endif -#if !defined(_PRODUCTION) -#define _PRODUCTION "" -#endif -#if defined(DEBUG) -#define _DEBUG_STRING " (debug)" -#else -#define _DEBUG_STRING "" -#endif - -/* - * A trick to expand the PR_VMAJOR macro before concatenation. - */ -#define CONCAT(x, y) x ## y -#define CONCAT2(x, y) CONCAT(x, y) -#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplds, PR_VMAJOR) - -PRVersionDescription VERSION_DESC_NAME = -{ - /* version */ 2, /* this is the only one supported */ - /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */ - /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */ - /* vMajor */ PR_VMAJOR, /* NSPR's version number */ - /* vMinor */ PR_VMINOR, /* and minor version */ - /* vPatch */ PR_VPATCH, /* and patch */ - /* beta */ PR_BETA, /* beta build boolean */ -#if defined(DEBUG) - /* debug */ PR_TRUE, /* a debug build */ -#else - /* debug */ PR_FALSE, /* an optomized build */ -#endif - /* special */ PR_FALSE, /* they're all special, but ... */ - /* filename */ _PRODUCTION, /* the produced library name */ - /* description */ "Portable runtime", /* what we are */ - /* security */ "N/A", /* not applicable here */ - /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved", - /* comment */ "http://www.mozilla.org/MPL/", - /* specialString */ "" -}; - -#ifdef XP_UNIX - -/* - * Version information for the 'ident' and 'what commands - * - * NOTE: the first component of the concatenated rcsid string - * must not end in a '$' to prevent rcs keyword substitution. - */ -static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING - " " _BUILD_STRING " $"; -static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING - " " _BUILD_STRING; - -#endif /* XP_UNIX */ - -PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint() -{ -#ifdef XP_UNIX - /* - * Add dummy references to rcsid and sccsid to prevent them - * from being optimized away as unused variables. - */ - const char *dummy; - - dummy = rcsid; - dummy = sccsid; -#endif - return &VERSION_DESC_NAME; -} /* versionEntryPointType */ - -/* plvrsion.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/.cvsignore nspr-4.10.7/mozilla/nsprpub/lib/libc/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/lib/libc/.cvsignore 2001-05-12 01:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/include/.cvsignore nspr-4.10.7/mozilla/nsprpub/lib/libc/include/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/lib/libc/include/.cvsignore 2001-05-12 01:14:37.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/include/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/include/Makefile.in nspr-4.10.7/mozilla/nsprpub/lib/libc/include/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/lib/libc/include/Makefile.in 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/include/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk -include $(topsrcdir)/config/config.mk - -HEADERS = $(wildcard $(srcdir)/*.h) - -RELEASE_HEADERS = $(HEADERS) -RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR) - -include $(topsrcdir)/config/rules.mk - -export:: $(HEADERS) - $(INSTALL) -m 444 $(HEADERS) $(dist_includedir) diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/include/plbase64.h nspr-4.10.7/mozilla/nsprpub/lib/libc/include/plbase64.h --- nspr-4.9.5/mozilla/nsprpub/lib/libc/include/plbase64.h 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/include/plbase64.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _plbase64_h -#define _plbase64_h - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* - * PL_Base64Encode - * - * This routine encodes the data pointed to by the "src" parameter using the - * base64 algorithm, and returns a pointer to the result. If the "srclen" - * parameter is not zero, it specifies the length of the source data. If it - * is zero, the source data is assumed to be null-terminated, and PL_strlen - * is used to determine the source length. If the "dest" parameter is not - * null, it is assumed to point to a buffer of sufficient size (which may be - * calculated: ((srclen + 2)/3)*4) into which the encoded data is placed - * (without any termination). If the "dest" parameter is null, a buffer is - * allocated from the heap to hold the encoded data, and the result *will* - * be terminated with an extra null character. It is the caller's - * responsibility to free the result when it is allocated. A null is returned - * if the allocation fails. - * - * NOTE: when calculating ((srclen + 2)/3)*4), first ensure that - * srclen <= (PR_UINT32_MAX/4) * 3 - * to avoid PRUint32 overflow. - */ - -PR_EXTERN(char *) -PL_Base64Encode -( - const char *src, - PRUint32 srclen, - char *dest -); - -/* - * PL_Base64Decode - * - * This routine decodes the data pointed to by the "src" parameter using - * the base64 algorithm, and returns a pointer to the result. The source - * may either include or exclude any trailing '=' characters. If the - * "srclen" parameter is not zero, it specifies the length of the source - * data. If it is zero, PL_strlen will be used to determine the source - * length. If the "dest" parameter is not null, it is assumed to point to - * a buffer of sufficient size (which may be calculated: (srclen * 3)/4 - * when srclen includes the '=' characters) into which the decoded data - * is placed (without any termination). If the "dest" parameter is null, - * a buffer is allocated from the heap to hold the decoded data, and the - * result *will* be terminated with an extra null character. It is the - * caller's responsibility to free the result when it is allocated. A null - * is retuned if the allocation fails, or if the source is not well-coded. - * - * NOTE: when calculating (srclen * 3)/4, first ensure that - * srclen <= PR_UINT32_MAX/3 - * to avoid PRUint32 overflow. Alternatively, calculate - * (srclen/4) * 3 + ((srclen%4) * 3)/4 - * which is equivalent but doesn't overflow for any value of srclen. - */ - -PR_EXTERN(char *) -PL_Base64Decode -( - const char *src, - PRUint32 srclen, - char *dest -); - -PR_END_EXTERN_C - -#endif /* _plbase64_h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/include/plerror.h nspr-4.10.7/mozilla/nsprpub/lib/libc/include/plerror.h --- nspr-4.9.5/mozilla/nsprpub/lib/libc/include/plerror.h 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/include/plerror.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: plerror.h -** Description: Simple routine to print translate the calling thread's -** error numbers and print them. -*/ - -#if defined(PLERROR_H) -#else -#define PLERROR_H - -#include "prio.h" -#include "prtypes.h" - -PR_BEGIN_EXTERN_C -/* -** Print the messages to "syserr" prepending 'msg' if not NULL. -*/ -PR_EXTERN(void) PL_PrintError(const char *msg); - -/* -** Print the messages to specified output file prepending 'msg' if not NULL. -*/ -PR_EXTERN(void) PL_FPrintError(PRFileDesc *output, const char *msg); - -PR_END_EXTERN_C - -#endif /* defined(PLERROR_H) */ - -/* plerror.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/include/plgetopt.h nspr-4.10.7/mozilla/nsprpub/lib/libc/include/plgetopt.h --- nspr-4.9.5/mozilla/nsprpub/lib/libc/include/plgetopt.h 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/include/plgetopt.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: plgetopt.h -** Description: utilities to parse argc/argv -*/ - -#if defined(PLGETOPT_H_) -#else -#define PLGETOPT_H_ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -typedef struct PLOptionInternal PLOptionInternal; - -typedef enum -{ - PL_OPT_OK, /* all's well with the option */ - PL_OPT_EOL, /* end of options list */ - PL_OPT_BAD /* invalid option (and value) */ -} PLOptStatus; - -typedef struct PLLongOpt -{ - const char * longOptName; /* long option name string */ - PRIntn longOption; /* value put in PLOptState for this option. */ - PRBool valueRequired; /* If option name not followed by '=', */ - /* value is the next argument from argv. */ -} PLLongOpt; - -typedef struct PLOptState -{ - char option; /* the name of the option */ - const char *value; /* the value of that option | NULL */ - - PLOptionInternal *internal; /* private processing state */ - - PRIntn longOption; /* value from PLLongOpt put here */ - PRIntn longOptIndex; /* index into caller's array of PLLongOpts */ -} PLOptState; - -/* - * PL_CreateOptState - * - * The argument "options" points to a string of single-character option - * names. Option names that may have an option argument value must be - * followed immediately by a ':' character. - */ -PR_EXTERN(PLOptState*) PL_CreateOptState( - PRIntn argc, char **argv, const char *options); - -/* - * PL_CreateLongOptState - * - * Alternative to PL_CreateOptState. - * Allows caller to specify BOTH a string of single-character option names, - * AND an array of structures describing "long" (keyword) option names. - * The array is terminated by a structure in which longOptName is NULL. - * Long option values (arguments) may always be given as "--name=value". - * If PLLongOpt.valueRequired is not PR_FALSE, and the option name was not - * followed by '=' then the next argument from argv is taken as the value. - */ -PR_EXTERN(PLOptState*) PL_CreateLongOptState( - PRIntn argc, char **argv, const char *options, - const PLLongOpt *longOpts); -/* - * PL_DestroyOptState - * - * Call this to destroy the PLOptState returned from PL_CreateOptState or - * PL_CreateLongOptState. - */ -PR_EXTERN(void) PL_DestroyOptState(PLOptState *opt); - -/* - * PL_GetNextOpt - * - * When this function returns PL_OPT_OK, - * - opt->option will hold the single-character option name that was parsed, - * or zero. - * When opt->option is zero, the token parsed was either a "long" (keyword) - * option or a positional parameter. - * For a positional parameter, - * - opt->longOptIndex will contain -1, and - * - opt->value will point to the positional parameter string. - * For a long option name, - * - opt->longOptIndex will contain the non-negative index of the - * PLLongOpt structure in the caller's array of PLLongOpt structures - * corresponding to the long option name, and - * For a single-character or long option, - * - opt->longOption will contain the value of the single-character option - * name, or the value of the longOption from the PLLongOpt structure - * for that long option. See notes below. - * - opt->value will point to the argument option string, or will - * be NULL if option does not require argument. If option requires - * argument but it is not provided, PL_OPT_BAD is returned. - * When opt->option is non-zero, - * - opt->longOptIndex will be -1 - * When this function returns PL_OPT_EOL, or PL_OPT_BAD, the contents of - * opt are undefined. - * - * Notes: It is possible to ignore opt->option, and always look at - * opt->longOption instead. opt->longOption will contain the same value - * as opt->option for single-character option names, and will contain the - * value of longOption from the PLLongOpt structure for long option names. - * This means that it is possible to equivalence long option names to - * single character names by giving the longOption in the PLLongOpt struct - * the same value as the single-character option name. - * For long options that are NOT intended to be equivalent to any single- - * character option, the longOption value should be chosen to not match - * any possible single character name. It might be advisable to choose - * longOption values greater than 0xff for such long options. - */ -PR_EXTERN(PLOptStatus) PL_GetNextOpt(PLOptState *opt); - -PR_END_EXTERN_C - -#endif /* defined(PLGETOPT_H_) */ - -/* plgetopt.h */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/include/plstr.h nspr-4.10.7/mozilla/nsprpub/lib/libc/include/plstr.h --- nspr-4.9.5/mozilla/nsprpub/lib/libc/include/plstr.h 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/include/plstr.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,437 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _plstr_h -#define _plstr_h - -/* - * plstr.h - * - * This header file exports the API to the NSPR portable library or string- - * handling functions. - * - * This API was not designed as an "optimal" or "ideal" string library; it - * was based on the good ol' unix string.3 functions, and was written to - * - * 1) replace the libc functions, for cross-platform consistency, - * 2) complete the API on platforms lacking common functions (e.g., - * strcase*), and - * 3) to implement some obvious "closure" functions that I've seen - * people hacking around in our code. - * - * Point number three largely means that most functions have an "strn" - * limited-length version, and all comparison routines have a non-case- - * sensitive version available. - */ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C -/* - * PL_strlen - * - * Returns the length of the provided string, not including the trailing '\0'. - */ - -PR_EXTERN(PRUint32) -PL_strlen(const char *str); - -/* - * PL_strnlen - * - * Returns the length of the provided string, not including the trailing '\0', - * up to the indicated maximum. The string will not be examined beyond the - * maximum; if no terminating '\0' is found, the maximum will be returned. - */ - -PR_EXTERN(PRUint32) -PL_strnlen(const char *str, PRUint32 max); - -/* - * PL_strcpy - * - * Copies the source string, up to and including the trailing '\0', into the - * destination buffer. It does not (can not) verify that the destination - * buffer is large enough. It returns the "dest" argument. - */ - -PR_EXTERN(char *) -PL_strcpy(char *dest, const char *src); - -/* - * PL_strncpy - * - * Copies the source string into the destination buffer, up to and including - * the trailing '\0' or up to and including the max'th character, whichever - * comes first. It does not (can not) verify that the destination buffer is - * large enough. If the source string is longer than the maximum length, - * the result will *not* be null-terminated (JLRU). - */ - -PR_EXTERN(char *) -PL_strncpy(char *dest, const char *src, PRUint32 max); - -/* - * PL_strncpyz - * - * Copies the source string into the destination buffer, up to and including - * the trailing '\0' or up but not including the max'th character, whichever - * comes first. It does not (can not) verify that the destination buffer is - * large enough. The destination string is always terminated with a '\0', - * unlike the traditional libc implementation. It returns the "dest" argument. - * - * NOTE: If you call this with a source "abcdefg" and a max of 5, the - * destination will end up with "abcd\0" (i.e., its strlen length will be 4)! - * - * This means you can do this: - * - * char buffer[ SOME_SIZE ]; - * PL_strncpyz(buffer, src, sizeof(buffer)); - * - * and the result will be properly terminated. - */ - -PR_EXTERN(char *) -PL_strncpyz(char *dest, const char *src, PRUint32 max); - -/* - * PL_strdup - * - * Returns a pointer to a malloc'd extent of memory containing a duplicate - * of the argument string. The size of the allocated extent is one greater - * than the length of the argument string, because of the terminator. A - * null argument, like a zero-length argument, will result in a pointer to - * a one-byte extent containing the null value. This routine returns null - * upon malloc failure. - */ - -PR_EXTERN(char *) -PL_strdup(const char *s); - -/* - * PL_strfree - * - * Free memory allocated by PL_strdup - */ - -PR_EXTERN(void) -PL_strfree(char *s); - -/* - * PL_strndup - * - * Returns a pointer to a malloc'd extent of memory containing a duplicate - * of the argument string, up to the maximum specified. If the argument - * string has a length greater than the value of the specified maximum, the - * return value will be a pointer to an extent of memory of length one - * greater than the maximum specified. A null string, a zero-length string, - * or a zero maximum will all result in a pointer to a one-byte extent - * containing the null value. This routine returns null upon malloc failure. - */ - -PR_EXTERN(char *) -PL_strndup(const char *s, PRUint32 max); - -/* - * PL_strcat - * - * Appends a copy of the string pointed to by the second argument to the - * end of the string pointed to by the first. The destination buffer is - * not (can not be) checked for sufficient size. A null destination - * argument returns null; otherwise, the first argument is returned. - */ - -PR_EXTERN(char *) -PL_strcat(char *dst, const char *src); - -/* - * PL_strncat - * - * Appends a copy of the string pointed to by the second argument, up to - * the maximum size specified, to the end of the string pointed to by the - * first. The destination buffer is not (can not be) checked for sufficient - * size. A null destination argument returns null; otherwise, the first - * argument is returned. If the maximum size limits the copy, then the - * result will *not* be null-terminated (JLRU). A null destination - * returns null; otherwise, the destination argument is returned. - */ - -PR_EXTERN(char *) -PL_strncat(char *dst, const char *src, PRUint32 max); - -/* - * PL_strcatn - * - * Appends a copy of the string pointed to by the third argument, to the - * end of the string pointed to by the first. The second argument specifies - * the maximum size of the destination buffer, including the null termination. - * If the existing string in dst is longer than the max, no action is taken. - * The resulting string will be null-terminated. A null destination returns - * null; otherwise, the destination argument is returned. - */ - -PR_EXTERN(char *) -PL_strcatn(char *dst, PRUint32 max, const char *src); - -/* - * PL_strcmp - * - * Returns an integer, the sign of which -- positive, zero, or negative -- - * reflects the lexical sorting order of the two strings indicated. The - * result is positive if the first string comes after the second. The - * NSPR implementation is not i18n. - */ - -PR_EXTERN(PRIntn) -PL_strcmp(const char *a, const char *b); - -/* - * PL_strncmp - * - * Returns an integer, the sign of which -- positive, zero, or negative -- - * reflects the lexical sorting order of the two strings indicated, up to - * the maximum specified. The result is positive if the first string comes - * after the second. The NSPR implementation is not i18n. If the maximum - * is zero, only the existance or non-existance (pointer is null) of the - * strings is compared. - */ - -PR_EXTERN(PRIntn) -PL_strncmp(const char *a, const char *b, PRUint32 max); - -/* - * PL_strcasecmp - * - * Returns an integer, the sign of which -- positive, zero or negative -- - * reflects the case-insensitive lexical sorting order of the two strings - * indicated. The result is positive if the first string comes after the - * second. The NSPR implementation is not i18n. - */ - -PR_EXTERN(PRIntn) -PL_strcasecmp(const char *a, const char *b); - -/* - * PL_strncasecmp - * - * Returns an integer, the sign of which -- positive, zero or negative -- - * reflects the case-insensitive lexical sorting order of the first n characters - * of the two strings indicated. The result is positive if the first string comes - * after the second. The NSPR implementation is not i18n. - */ - -PR_EXTERN(PRIntn) -PL_strncasecmp(const char *a, const char *b, PRUint32 max); - -/* - * PL_strchr - * - * Returns a pointer to the first instance of the specified character in the - * provided string. It returns null if the character is not found, or if the - * provided string is null. The character may be the null character. - */ - -PR_EXTERN(char *) -PL_strchr(const char *s, char c); - -/* - * PL_strrchr - * - * Returns a pointer to the last instance of the specified character in the - * provided string. It returns null if the character is not found, or if the - * provided string is null. The character may be the null character. - */ - -PR_EXTERN(char *) -PL_strrchr(const char *s, char c); - -/* - * PL_strnchr - * - * Returns a pointer to the first instance of the specified character within the - * first n characters of the provided string. It returns null if the character - * is not found, or if the provided string is null. The character may be the - * null character. - */ - -PR_EXTERN(char *) -PL_strnchr(const char *s, char c, PRUint32 n); - -/* - * PL_strnrchr - * - * Returns a pointer to the last instance of the specified character within the - * first n characters of the provided string. It returns null if the character is - * not found, or if the provided string is null. The character may be the null - * character. - */ - -PR_EXTERN(char *) -PL_strnrchr(const char *s, char c, PRUint32 n); - -/* - * NOTE: Looking for strcasechr, strcaserchr, strncasechr, or strncaserchr? - * Use strpbrk, strprbrk, strnpbrk or strnprbrk. - */ - -/* - * PL_strpbrk - * - * Returns a pointer to the first instance in the first string of any character - * (not including the terminating null character) of the second string. It returns - * null if either string is null. - */ - -PR_EXTERN(char *) -PL_strpbrk(const char *s, const char *list); - -/* - * PL_strprbrk - * - * Returns a pointer to the last instance in the first string of any character - * (not including the terminating null character) of the second string. It returns - * null if either string is null. - */ - -PR_EXTERN(char *) -PL_strprbrk(const char *s, const char *list); - -/* - * PL_strnpbrk - * - * Returns a pointer to the first instance (within the first n characters) of any - * character (not including the terminating null character) of the second string. - * It returns null if either string is null. - */ - -PR_EXTERN(char *) -PL_strnpbrk(const char *s, const char *list, PRUint32 n); - -/* - * PL_strnprbrk - * - * Returns a pointer to the last instance (within the first n characters) of any - * character (not including the terminating null character) of the second string. - * It returns null if either string is null. - */ - -PR_EXTERN(char *) -PL_strnprbrk(const char *s, const char *list, PRUint32 n); - -/* - * PL_strstr - * - * Returns a pointer to the first instance of the little string within the - * big one. It returns null if either string is null. - */ - -PR_EXTERN(char *) -PL_strstr(const char *big, const char *little); - -/* - * PL_strrstr - * - * Returns a pointer to the last instance of the little string within the big one. - * It returns null if either string is null. - */ - -PR_EXTERN(char *) -PL_strrstr(const char *big, const char *little); - -/* - * PL_strnstr - * - * Returns a pointer to the first instance of the little string within the first - * n characters of the big one. It returns null if either string is null. It - * returns null if the length of the little string is greater than n. - */ - -PR_EXTERN(char *) -PL_strnstr(const char *big, const char *little, PRUint32 n); - -/* - * PL_strnrstr - * - * Returns a pointer to the last instance of the little string within the first - * n characters of the big one. It returns null if either string is null. It - * returns null if the length of the little string is greater than n. - */ - -PR_EXTERN(char *) -PL_strnrstr(const char *big, const char *little, PRUint32 max); - -/* - * PL_strcasestr - * - * Returns a pointer to the first instance of the little string within the big one, - * ignoring case. It returns null if either string is null. - */ - -PR_EXTERN(char *) -PL_strcasestr(const char *big, const char *little); - -/* - * PL_strcaserstr - * - * Returns a pointer to the last instance of the little string within the big one, - * ignoring case. It returns null if either string is null. - */ - -PR_EXTERN(char *) -PL_strcaserstr(const char *big, const char *little); - -/* - * PL_strncasestr - * - * Returns a pointer to the first instance of the little string within the first - * n characters of the big one, ignoring case. It returns null if either string is - * null. It returns null if the length of the little string is greater than n. - */ - -PR_EXTERN(char *) -PL_strncasestr(const char *big, const char *little, PRUint32 max); - -/* - * PL_strncaserstr - * - * Returns a pointer to the last instance of the little string within the first - * n characters of the big one, ignoring case. It returns null if either string is - * null. It returns null if the length of the little string is greater than n. - */ - -PR_EXTERN(char *) -PL_strncaserstr(const char *big, const char *little, PRUint32 max); - -/* - * PL_strtok_r - * - * Splits the string s1 into tokens, separated by one or more characters - * from the separator string s2. The argument lasts points to a - * user-supplied char * pointer in which PL_strtok_r stores information - * for it to continue scanning the same string. - * - * In the first call to PL_strtok_r, s1 points to a string and the value - * of *lasts is ignored. PL_strtok_r returns a pointer to the first - * token, writes '\0' into the character following the first token, and - * updates *lasts. - * - * In subsequent calls, s1 is null and lasts must stay unchanged from the - * previous call. The separator string s2 may be different from call to - * call. PL_strtok_r returns a pointer to the next token in s1. When no - * token remains in s1, PL_strtok_r returns null. - */ - -PR_EXTERN(char *) -PL_strtok_r(char *s1, const char *s2, char **lasts); - -/* - * Things not (yet?) included: strspn/strcspn, strsep. - * memchr, memcmp, memcpy, memccpy, index, rindex, bcmp, bcopy, bzero. - * Any and all i18n/l10n stuff. - */ - -PR_END_EXTERN_C - -#endif /* _plstr_h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/include/README nspr-4.10.7/mozilla/nsprpub/lib/libc/include/README --- nspr-4.9.5/mozilla/nsprpub/lib/libc/include/README 1998-03-28 03:36:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/include/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -NSPR 2.0 libc functions ------------------------ - -Last edited: AOF 04 March 1997 - -This directory contains the API for various libc-types of functions. - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/Makefile.in nspr-4.10.7/mozilla/nsprpub/lib/libc/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/lib/libc/Makefile.in 2012-05-31 21:54:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -export NSPR20=1 - -include $(topsrcdir)/config/config.mk - -DIRS = include src - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/README nspr-4.10.7/mozilla/nsprpub/lib/libc/README --- nspr-4.9.5/mozilla/nsprpub/lib/libc/README 1998-03-28 03:36:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -NSPR 2.0 libc functions ------------------------ - -Last edited: AOF 04 March 1997 - -This directory contains various libc-types of functions. All functions in -this directory are platform independent, thread friendly (both safe and -efficient). They are contributed from various sources, though the contri- -butions are monitored by the NSPR group (mailto:freier). - -All API items exported by these functions will contain the same three -character prefix, "PL_" (Portable Library). Internal function names -that are not exported (static) are of little concern, though some caution -must be used on those elements that are 'extern' but not really intended -to be part of the API. Those should all have a prefix of "_PL_" (is that -legal?). - -The responsibility for contributions in this area are distributed among -all interested parties. - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/base64.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/base64.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/base64.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/base64.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,416 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plbase64.h" -#include "prlog.h" /* For PR_NOT_REACHED */ -#include "prmem.h" /* for malloc / PR_MALLOC */ - -#include /* for strlen */ - -static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static void -encode3to4 -( - const unsigned char *src, - unsigned char *dest -) -{ - PRUint32 b32 = (PRUint32)0; - PRIntn i, j = 18; - - for( i = 0; i < 3; i++ ) - { - b32 <<= 8; - b32 |= (PRUint32)src[i]; - } - - for( i = 0; i < 4; i++ ) - { - dest[i] = base[ (PRUint32)((b32>>j) & 0x3F) ]; - j -= 6; - } - - return; -} - -static void -encode2to4 -( - const unsigned char *src, - unsigned char *dest -) -{ - dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ]; - dest[1] = base[ (PRUint32)(((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)) ]; - dest[2] = base[ (PRUint32)((src[1] & 0x0F) << 2) ]; - dest[3] = (unsigned char)'='; - return; -} - -static void -encode1to4 -( - const unsigned char *src, - unsigned char *dest -) -{ - dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ]; - dest[1] = base[ (PRUint32)((src[0] & 0x03) << 4) ]; - dest[2] = (unsigned char)'='; - dest[3] = (unsigned char)'='; - return; -} - -static void -encode -( - const unsigned char *src, - PRUint32 srclen, - unsigned char *dest -) -{ - while( srclen >= 3 ) - { - encode3to4(src, dest); - src += 3; - dest += 4; - srclen -= 3; - } - - switch( srclen ) - { - case 2: - encode2to4(src, dest); - break; - case 1: - encode1to4(src, dest); - break; - case 0: - break; - default: - PR_NOT_REACHED("coding error"); - } - - return; -} - -/* - * PL_Base64Encode - * - * If the destination argument is NULL, a return buffer is - * allocated, and the data therein will be null-terminated. - * If the destination argument is not NULL, it is assumed to - * be of sufficient size, and the contents will not be null- - * terminated by this routine. - * - * Returns null if the allocation fails. - */ - -PR_IMPLEMENT(char *) -PL_Base64Encode -( - const char *src, - PRUint32 srclen, - char *dest -) -{ - if( 0 == srclen ) - { - size_t len = strlen(src); - srclen = len; - /* Detect truncation. */ - if( srclen != len ) - { - return (char *)0; - } - } - - if( (char *)0 == dest ) - { - PRUint32 destlen; - /* Ensure all PRUint32 values stay within range. */ - if( srclen > (PR_UINT32_MAX/4) * 3 ) - { - return (char *)0; - } - destlen = ((srclen + 2)/3) * 4; - dest = (char *)PR_MALLOC(destlen + 1); - if( (char *)0 == dest ) - { - return (char *)0; - } - dest[ destlen ] = (char)0; /* null terminate */ - } - - encode((const unsigned char *)src, srclen, (unsigned char *)dest); - return dest; -} - -static PRInt32 -codetovalue -( - unsigned char c -) -{ - if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') ) - { - return (PRInt32)(c - (unsigned char)'A'); - } - else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') ) - { - return ((PRInt32)(c - (unsigned char)'a') +26); - } - else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') ) - { - return ((PRInt32)(c - (unsigned char)'0') +52); - } - else if( (unsigned char)'+' == c ) - { - return (PRInt32)62; - } - else if( (unsigned char)'/' == c ) - { - return (PRInt32)63; - } - else - { - return -1; - } -} - -static PRStatus -decode4to3 -( - const unsigned char *src, - unsigned char *dest -) -{ - PRUint32 b32 = (PRUint32)0; - PRInt32 bits; - PRIntn i; - - for( i = 0; i < 4; i++ ) - { - bits = codetovalue(src[i]); - if( bits < 0 ) - { - return PR_FAILURE; - } - - b32 <<= 6; - b32 |= bits; - } - - dest[0] = (unsigned char)((b32 >> 16) & 0xFF); - dest[1] = (unsigned char)((b32 >> 8) & 0xFF); - dest[2] = (unsigned char)((b32 ) & 0xFF); - - return PR_SUCCESS; -} - -static PRStatus -decode3to2 -( - const unsigned char *src, - unsigned char *dest -) -{ - PRUint32 b32 = (PRUint32)0; - PRInt32 bits; - PRUint32 ubits; - - bits = codetovalue(src[0]); - if( bits < 0 ) - { - return PR_FAILURE; - } - - b32 = (PRUint32)bits; - b32 <<= 6; - - bits = codetovalue(src[1]); - if( bits < 0 ) - { - return PR_FAILURE; - } - - b32 |= (PRUint32)bits; - b32 <<= 4; - - bits = codetovalue(src[2]); - if( bits < 0 ) - { - return PR_FAILURE; - } - - ubits = (PRUint32)bits; - b32 |= (ubits >> 2); - - dest[0] = (unsigned char)((b32 >> 8) & 0xFF); - dest[1] = (unsigned char)((b32 ) & 0xFF); - - return PR_SUCCESS; -} - -static PRStatus -decode2to1 -( - const unsigned char *src, - unsigned char *dest -) -{ - PRUint32 b32; - PRUint32 ubits; - PRInt32 bits; - - bits = codetovalue(src[0]); - if( bits < 0 ) - { - return PR_FAILURE; - } - - ubits = (PRUint32)bits; - b32 = (ubits << 2); - - bits = codetovalue(src[1]); - if( bits < 0 ) - { - return PR_FAILURE; - } - - ubits = (PRUint32)bits; - b32 |= (ubits >> 4); - - dest[0] = (unsigned char)b32; - - return PR_SUCCESS; -} - -static PRStatus -decode -( - const unsigned char *src, - PRUint32 srclen, - unsigned char *dest -) -{ - PRStatus rv; - - while( srclen >= 4 ) - { - rv = decode4to3(src, dest); - if( PR_SUCCESS != rv ) - { - return PR_FAILURE; - } - - src += 4; - dest += 3; - srclen -= 4; - } - - switch( srclen ) - { - case 3: - rv = decode3to2(src, dest); - break; - case 2: - rv = decode2to1(src, dest); - break; - case 1: - rv = PR_FAILURE; - break; - case 0: - rv = PR_SUCCESS; - break; - default: - PR_NOT_REACHED("coding error"); - } - - return rv; -} - -/* - * PL_Base64Decode - * - * If the destination argument is NULL, a return buffer is - * allocated and the data therein will be null-terminated. - * If the destination argument is not null, it is assumed - * to be of sufficient size, and the data will not be null- - * terminated by this routine. - * - * Returns null if the allocation fails, or if the source string is - * not well-formed. - */ - -PR_IMPLEMENT(char *) -PL_Base64Decode -( - const char *src, - PRUint32 srclen, - char *dest -) -{ - PRStatus status; - PRBool allocated = PR_FALSE; - - if( (char *)0 == src ) - { - return (char *)0; - } - - if( 0 == srclen ) - { - size_t len = strlen(src); - srclen = len; - /* Detect truncation. */ - if( srclen != len ) - { - return (char *)0; - } - } - - if( srclen && (0 == (srclen & 3)) ) - { - if( (char)'=' == src[ srclen-1 ] ) - { - if( (char)'=' == src[ srclen-2 ] ) - { - srclen -= 2; - } - else - { - srclen -= 1; - } - } - } - - if( (char *)0 == dest ) - { - /* The following computes ((srclen * 3) / 4) without overflow. */ - PRUint32 destlen = (srclen / 4) * 3 + ((srclen % 4) * 3) / 4; - dest = (char *)PR_MALLOC(destlen + 1); - if( (char *)0 == dest ) - { - return (char *)0; - } - dest[ destlen ] = (char)0; /* null terminate */ - allocated = PR_TRUE; - } - - status = decode((const unsigned char *)src, srclen, (unsigned char *)dest); - if( PR_SUCCESS != status ) - { - if( PR_TRUE == allocated ) - { - PR_DELETE(dest); - } - - return (char *)0; - } - - return dest; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/.cvsignore nspr-4.10.7/mozilla/nsprpub/lib/libc/src/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/.cvsignore 2001-05-14 22:11:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Makefile -_pl_bld.h diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/Makefile.in nspr-4.10.7/mozilla/nsprpub/lib/libc/src/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/Makefile.in 2012-11-13 23:17:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,152 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -INCLUDES = -I$(dist_includedir) - -CSRCS =\ - plvrsion.c \ - strlen.c \ - strcpy.c \ - strdup.c \ - strcase.c \ - strcat.c \ - strcmp.c \ - strchr.c \ - strpbrk.c \ - strstr.c \ - strtok.c \ - base64.c \ - plerror.c \ - plgetopt.c \ - $(NULL) - -LIBRARY_NAME = plc -LIBRARY_VERSION = $(MOD_MAJOR_VERSION) - -RELEASE_LIBS = $(TARGETS) - -ifeq ($(OS_ARCH),WINNT) -RES=$(OBJDIR)/plc.res -RESNAME=plc.rc -endif # WINNT - -ifeq ($(OS_ARCH), AIX) -ifeq ($(CLASSIC_NSPR),1) -OS_LIBS = -lc -else -OS_LIBS = -lc_r -endif -endif - -ifeq ($(OS_ARCH),IRIX) -OS_LIBS = -lc -endif - -ifeq ($(OS_ARCH),SunOS) -OS_LIBS = -lc -MAPFILE = $(OBJDIR)/plcmap.sun -GARBAGE += $(MAPFILE) -ifdef NS_USE_GCC -ifdef GCC_USE_GNU_LD -MKSHLIB += -Wl,--version-script,$(MAPFILE) -else -MKSHLIB += -Wl,-M,$(MAPFILE) -endif -else -MKSHLIB += -M $(MAPFILE) -endif -# The -R '$ORIGIN' linker option instructs this library to search for its -# dependencies in the same directory where it resides. -MKSHLIB += -R '$$ORIGIN' -endif - -ifeq ($(OS_ARCH),OS2) -MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def -GARBAGE += $(MAPFILE) -MKSHLIB += $(MAPFILE) -endif - -EXTRA_LIBS = $(LIBNSPR) - -# On SCOOS, we can't link with extra libraries when -# we build a shared library. If we do so, the linker doesn't -# complain, but we would run into weird problems at run-time. -# Therefore on these platforms, we link just the .o files. -ifeq ($(OS_ARCH),SCOOS) -EXTRA_LIBS = -endif - -ifdef RESOLVE_LINK_SYMBOLS -EXTRA_LIBS += $(OS_LIBS) -endif - -include $(topsrcdir)/config/rules.mk - -# -# Version information generation (begin) -# -ECHO = echo -TINC = $(OBJDIR)/_pl_bld.h -PROD = $(notdir $(SHARED_LIBRARY)) -NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now -SH_DATE = $(shell date "+%Y-%m-%d %T") -SH_NOW = $(shell $(NOW)) - -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - SUF = i64 -else - SUF = LL -endif - -GARBAGE += $(TINC) - -$(TINC): - @$(MAKE_OBJDIR) - @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC) - @if test ! -z "$(SH_NOW)"; then \ - $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \ - else \ - true; \ - fi - @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) - - -$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC) -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $< -else - $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< -endif -# -# Version information generation (end) -# - -# -# The Client build wants the shared libraries in $(dist_bindir), -# so we also install them there. -# - -export:: $(TARGETS) - $(INSTALL) -m 444 $(TARGETS) $(dist_libdir) -ifdef SHARED_LIBRARY -ifeq ($(OS_ARCH),HP-UX) - $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir) - $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir) -else - $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir) -endif -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plc.def nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plc.def --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plc.def 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plc.def 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -;+# -;+# This Source Code Form is subject to the terms of the Mozilla Public -;+# License, v. 2.0. If a copy of the MPL was not distributed with this -;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -;+# -;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS -;+# 1. For all unix platforms, the string ";-" means "remove this line" -;+# 2. For all unix platforms, the string " DATA " will be removed from any -;+# line on which it occurs. -;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. -;+# On AIX, lines containing ";+" will be removed. -;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. -;+# 5. For all unix platforms, after the above processing has taken place, -;+# all characters after the first ";" on the line will be removed. -;+# And for AIX, the first ";" will also be removed. -;+# This file is passed directly to windows. Since ';' is a comment, all UNIX -;+# directives are hidden behind ";", ";+", and ";-" -;+NSPR_4.0 { -;+ global: -LIBRARY plc4 ;- -EXPORTS ;- -PL_Base64Decode; -PL_Base64Encode; -PL_CreateOptState; -PL_DestroyOptState; -PL_FPrintError; -PL_GetNextOpt; -PL_PrintError; -PL_strcasecmp; -PL_strcaserstr; -PL_strcasestr; -PL_strcat; -PL_strcatn; -PL_strchr; -PL_strcmp; -PL_strcpy; -PL_strdup; -PL_strfree; -PL_strlen; -PL_strncasecmp; -PL_strncaserstr; -PL_strncasestr; -PL_strncat; -PL_strnchr; -PL_strncmp; -PL_strncpy; -PL_strncpyz; -PL_strndup; -PL_strnlen; -PL_strnpbrk; -PL_strnprbrk; -PL_strnrchr; -PL_strnrstr; -PL_strnstr; -PL_strpbrk; -PL_strprbrk; -PL_strrchr; -PL_strrstr; -PL_strstr; -libVersionPoint; -;+ local: *; -;+}; -;+ -;+NSPR_4.2 { -;+ global: -PL_strtok_r; -;+} NSPR_4.0; -;+ -;+NSPR_4.7 { -;+ global: -PL_CreateLongOptState; -;+} NSPR_4.2; diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plc.rc nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plc.rc --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plc.rc 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plc.rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -#include "prinit.h" -#include - -#define MY_LIBNAME "plc" -#define MY_FILEDESCRIPTION "PLC Library" - -#define STRINGIZE(x) #x -#define STRINGIZE2(x) STRINGIZE(x) -#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR) - -#ifdef _DEBUG -#define MY_DEBUG_STR " (debug)" -#define MY_FILEFLAGS_1 VS_FF_DEBUG -#else -#define MY_DEBUG_STR "" -#define MY_FILEFLAGS_1 0x0L -#endif -#if PR_BETA -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE -#else -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 -#endif - -#ifdef WINNT -#define MY_FILEOS VOS_NT_WINDOWS32 -#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR -#else -#define MY_FILEOS VOS__WINDOWS32 -#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR -#endif - -///////////////////////////////////////////////////////////////////////////// -// -// Version-information resource -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 - PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS MY_FILEFLAGS_2 - FILEOS MY_FILEOS - FILETYPE VFT_DLL - FILESUBTYPE 0x0L // not used - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" // Lang=US English, CharSet=Unicode - BEGIN - VALUE "CompanyName", "Mozilla Foundation\0" - VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" - VALUE "FileVersion", PR_VERSION "\0" - VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" - VALUE "ProductName", "Netscape Portable Runtime\0" - VALUE "ProductVersion", PR_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plerror.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plerror.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plerror.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plerror.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File:plerror.c -** Description: Simple routine to print translate the calling thread's -** error numbers and print them to "syserr". -*/ - -#include "plerror.h" - -#include "prprf.h" -#include "prerror.h" - -PR_IMPLEMENT(void) PL_FPrintError(PRFileDesc *fd, const char *msg) -{ -PRErrorCode error = PR_GetError(); -PRInt32 oserror = PR_GetOSError(); -const char *name = PR_ErrorToName(error); - - if (NULL != msg) PR_fprintf(fd, "%s: ", msg); - if (NULL == name) - PR_fprintf( - fd, " (%d)OUT OF RANGE, oserror = %d\n", error, oserror); - else - PR_fprintf( - fd, "%s(%d), oserror = %d\n", - name, error, oserror); -} /* PL_FPrintError */ - -PR_IMPLEMENT(void) PL_PrintError(const char *msg) -{ - static PRFileDesc *fd = NULL; - if (NULL == fd) fd = PR_GetSpecialFD(PR_StandardError); - PL_FPrintError(fd, msg); -} /* PL_PrintError */ - -/* plerror.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plgetopt.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plgetopt.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plgetopt.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plgetopt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: plgetopt.c -** Description: utilities to parse argc/argv -*/ - -#include "prmem.h" -#include "prlog.h" -#include "prerror.h" -#include "plstr.h" -#include "plgetopt.h" - -#include - -static char static_Nul = 0; - -struct PLOptionInternal -{ - const char *options; /* client options list specification */ - PRIntn argc; /* original number of arguments */ - char **argv; /* vector of pointers to arguments */ - PRIntn xargc; /* which one we're processing now */ - const char *xargv; /* where within *argv[xargc] */ - PRIntn minus; /* do we already have the '-'? */ - const PLLongOpt *longOpts; /* Caller's array */ - PRBool endOfOpts; /* have reached a "--" argument */ - PRIntn optionsLen; /* is strlen(options) */ -}; - -/* -** Create the state in which to parse the tokens. -** -** argc the sum of the number of options and their values -** argv the options and their values -** options vector of single character options w/ | w/o ': -*/ -PR_IMPLEMENT(PLOptState*) PL_CreateOptState( - PRIntn argc, char **argv, const char *options) -{ - return PL_CreateLongOptState( argc, argv, options, NULL); -} /* PL_CreateOptState */ - -PR_IMPLEMENT(PLOptState*) PL_CreateLongOptState( - PRIntn argc, char **argv, const char *options, - const PLLongOpt *longOpts) -{ - PLOptState *opt = NULL; - PLOptionInternal *internal; - - if (NULL == options) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return opt; - } - - opt = PR_NEWZAP(PLOptState); - if (NULL == opt) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return opt; - } - - internal = PR_NEW(PLOptionInternal); - if (NULL == internal) - { - PR_DELETE(opt); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - opt->option = 0; - opt->value = NULL; - opt->internal = internal; - opt->longOption = 0; - opt->longOptIndex = -1; - - internal->argc = argc; - internal->argv = argv; - internal->xargc = 0; - internal->xargv = &static_Nul; - internal->minus = 0; - internal->options = options; - internal->longOpts = longOpts; - internal->endOfOpts = PR_FALSE; - internal->optionsLen = PL_strlen(options); - - return opt; -} /* PL_CreateLongOptState */ - -/* -** Destroy object created by CreateOptState() -*/ -PR_IMPLEMENT(void) PL_DestroyOptState(PLOptState *opt) -{ - PR_DELETE(opt->internal); - PR_DELETE(opt); -} /* PL_DestroyOptState */ - -PR_IMPLEMENT(PLOptStatus) PL_GetNextOpt(PLOptState *opt) -{ - PLOptionInternal *internal = opt->internal; - - opt->longOption = 0; - opt->longOptIndex = -1; - /* - ** If the current xarg points to nul, advance to the next - ** element of the argv vector. If the vector index is equal - ** to argc, we're out of arguments, so return an EOL. - ** Note whether the first character of the new argument is - ** a '-' and skip by it if it is. - */ - while (0 == *internal->xargv) - { - internal->xargc += 1; - if (internal->xargc >= internal->argc) - { - opt->option = 0; - opt->value = NULL; - return PL_OPT_EOL; - } - internal->xargv = internal->argv[internal->xargc]; - internal->minus = 0; - if (!internal->endOfOpts && ('-' == *internal->xargv)) - { - internal->minus++; - internal->xargv++; /* and consume */ - if ('-' == *internal->xargv && internal->longOpts) - { - internal->minus++; - internal->xargv++; - if (0 == *internal->xargv) - { - internal->endOfOpts = PR_TRUE; - } - } - } - } - - /* - ** If we already have a '-' or '--' in hand, xargv points to the next - ** option. See if we can find a match in the list of possible - ** options supplied. - */ - if (internal->minus == 2) - { - char * foundEqual = strchr(internal->xargv,'='); - PRIntn optNameLen = foundEqual ? (foundEqual - internal->xargv) : - strlen(internal->xargv); - const PLLongOpt *longOpt = internal->longOpts; - PLOptStatus result = PL_OPT_BAD; - - opt->option = 0; - opt->value = NULL; - - for (; longOpt->longOptName; ++longOpt) - { - if (strncmp(longOpt->longOptName, internal->xargv, optNameLen)) - continue; /* not a possible match */ - if (strlen(longOpt->longOptName) != optNameLen) - continue; /* not a match */ - /* option name match */ - opt->longOptIndex = longOpt - internal->longOpts; - opt->longOption = longOpt->longOption; - /* value is part of the current argv[] element if = was found */ - /* note: this sets value even for long options that do not - * require option if specified as --long=value */ - if (foundEqual) - { - opt->value = foundEqual + 1; - } - else if (longOpt->valueRequired) - { - /* value is the next argv[] element, if any */ - if (internal->xargc + 1 < internal->argc) - { - opt->value = internal->argv[++(internal->xargc)]; - } - /* missing value */ - else - { - break; /* return PL_OPT_BAD */ - } - } - result = PL_OPT_OK; - break; - } - internal->xargv = &static_Nul; /* consume this */ - return result; - } - if (internal->minus) - { - PRIntn cop; - PRIntn eoo = internal->optionsLen; - for (cop = 0; cop < eoo; ++cop) - { - if (internal->options[cop] == *internal->xargv) - { - opt->option = *internal->xargv++; - opt->longOption = opt->option & 0xff; - /* - ** if options indicates that there's an associated - ** value, it must be provided, either as part of this - ** argv[] element or as the next one - */ - if (':' == internal->options[cop + 1]) - { - /* value is part of the current argv[] element */ - if (0 != *internal->xargv) - { - opt->value = internal->xargv; - } - /* value is the next argv[] element, if any */ - else if (internal->xargc + 1 < internal->argc) - { - opt->value = internal->argv[++(internal->xargc)]; - } - /* missing value */ - else - { - return PL_OPT_BAD; - } - - internal->xargv = &static_Nul; - internal->minus = 0; - } - else - opt->value = NULL; - return PL_OPT_OK; - } - } - internal->xargv += 1; /* consume that option */ - return PL_OPT_BAD; - } - - /* - ** No '-', so it must be a standalone value. The option is nul. - */ - opt->value = internal->argv[internal->xargc]; - internal->xargv = &static_Nul; - opt->option = 0; - return PL_OPT_OK; -} /* PL_GetNextOpt */ - -/* plgetopt.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plvrsion.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plvrsion.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/plvrsion.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/plvrsion.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include "prvrsion.h" - -/************************************************************************/ -/**************************IDENTITY AND VERSIONING***********************/ -/************************************************************************/ -#include "_pl_bld.h" -#if !defined(_BUILD_TIME) -#ifdef HAVE_LONG_LONG -#define _BUILD_TIME 0 -#else -#define _BUILD_TIME {0, 0} -#endif -#endif -#if !defined(_BUILD_STRING) -#define _BUILD_STRING "" -#endif -#if !defined(_PRODUCTION) -#define _PRODUCTION "" -#endif -#if defined(DEBUG) -#define _DEBUG_STRING " (debug)" -#else -#define _DEBUG_STRING "" -#endif - -/* - * A trick to expand the PR_VMAJOR macro before concatenation. - */ -#define CONCAT(x, y) x ## y -#define CONCAT2(x, y) CONCAT(x, y) -#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplc, PR_VMAJOR) - -PRVersionDescription VERSION_DESC_NAME = -{ - /* version */ 2, /* this is the only one supported */ - /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */ - /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */ - /* vMajor */ PR_VMAJOR, /* NSPR's version number */ - /* vMinor */ PR_VMINOR, /* and minor version */ - /* vPatch */ PR_VPATCH, /* and patch */ - /* beta */ PR_BETA, /* beta build boolean */ -#if defined(DEBUG) - /* debug */ PR_TRUE, /* a debug build */ -#else - /* debug */ PR_FALSE, /* an optomized build */ -#endif - /* special */ PR_FALSE, /* they're all special, but ... */ - /* filename */ _PRODUCTION, /* the produced library name */ - /* description */ "Portable runtime", /* what we are */ - /* security */ "N/A", /* not applicable here */ - /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved", - /* comment */ "http://www.mozilla.org/MPL/", - /* specialString */ "" -}; - -#ifdef XP_UNIX - -/* - * Version information for the 'ident' and 'what commands - * - * NOTE: the first component of the concatenated rcsid string - * must not end in a '$' to prevent rcs keyword substitution. - */ -static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING - " " _BUILD_STRING " $"; -static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING - " " _BUILD_STRING; - -#endif /* XP_UNIX */ - -PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint() -{ -#ifdef XP_UNIX - /* - * Add dummy references to rcsid and sccsid to prevent them - * from being optimized away as unused variables. - */ - const char *dummy; - - dummy = rcsid; - dummy = sccsid; -#endif - return &VERSION_DESC_NAME; -} /* versionEntryPointType */ - -/* plvrsion.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/README nspr-4.10.7/mozilla/nsprpub/lib/libc/src/README --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/README 1998-03-28 03:36:50.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -NSPR 2.0 libc functions ------------------------ - -Last edited: AOF 04 March 1997 - -This directory contains various libc-types of functions. All functions in -this directory are platform independent, thread friendly (both safe and -efficient). They are contributed from various sources, though the contri- -butions are monitored by the NSPR group (mailto:freier). - -All API items exported by these functions will contain the same three -character prefix, "PL_" (Portable Library). Internal function names -that are not exported (static) are of little concern, though some caution -must be used on those elements that are 'extern' but not really intended -to be part of the API. Those should all have a prefix of "_PL_" (is that -legal?). - -The responsibility for contributions in this area are distributed among -all interested parties. - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strcase.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strcase.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strcase.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strcase.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,170 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include - -static const unsigned char uc[] = -{ - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - ' ', '!', '"', '#', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', - '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '{', '|', '}', '~', '\177', - 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207, - 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217, - 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227, - 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237, - 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247, - 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257, - 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, - 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, - 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307, - 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317, - 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327, - 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, - 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347, - 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357, - 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, - 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377 -}; - -PR_IMPLEMENT(PRIntn) -PL_strcasecmp(const char *a, const char *b) -{ - const unsigned char *ua = (const unsigned char *)a; - const unsigned char *ub = (const unsigned char *)b; - - if( ((const char *)0 == a) || (const char *)0 == b ) - return (PRIntn)(a-b); - - while( (uc[*ua] == uc[*ub]) && ('\0' != *a) ) - { - a++; - ua++; - ub++; - } - - return (PRIntn)(uc[*ua] - uc[*ub]); -} - -PR_IMPLEMENT(PRIntn) -PL_strncasecmp(const char *a, const char *b, PRUint32 max) -{ - const unsigned char *ua = (const unsigned char *)a; - const unsigned char *ub = (const unsigned char *)b; - - if( ((const char *)0 == a) || (const char *)0 == b ) - return (PRIntn)(a-b); - - while( max && (uc[*ua] == uc[*ub]) && ('\0' != *a) ) - { - a++; - ua++; - ub++; - max--; - } - - if( 0 == max ) return (PRIntn)0; - - return (PRIntn)(uc[*ua] - uc[*ub]); -} - -PR_IMPLEMENT(char *) -PL_strcasestr(const char *big, const char *little) -{ - PRUint32 ll; - - if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; - if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; - - ll = strlen(little); - - for( ; *big; big++ ) - /* obvious improvement available here */ - if( 0 == PL_strncasecmp(big, little, ll) ) - return (char *)big; - - return (char *)0; -} - -PR_IMPLEMENT(char *) -PL_strcaserstr(const char *big, const char *little) -{ - const char *p; - PRUint32 bl, ll; - - if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; - if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; - - bl = strlen(big); - ll = strlen(little); - if( bl < ll ) return (char *)0; - p = &big[ bl - ll ]; - - for( ; p >= big; p-- ) - /* obvious improvement available here */ - if( 0 == PL_strncasecmp(p, little, ll) ) - return (char *)p; - - return (char *)0; -} - -PR_IMPLEMENT(char *) -PL_strncasestr(const char *big, const char *little, PRUint32 max) -{ - PRUint32 ll; - - if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; - if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; - - ll = strlen(little); - if( ll > max ) return (char *)0; - max -= ll; - max++; - - for( ; max && *big; big++, max-- ) - /* obvious improvement available here */ - if( 0 == PL_strncasecmp(big, little, ll) ) - return (char *)big; - - return (char *)0; -} - -PR_IMPLEMENT(char *) -PL_strncaserstr(const char *big, const char *little, PRUint32 max) -{ - const char *p; - PRUint32 ll; - - if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; - if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; - - ll = strlen(little); - - for( p = big; max && *p; p++, max-- ) - ; - - p -= ll; - if( p < big ) return (char *)0; - - for( ; p >= big; p-- ) - /* obvious improvement available here */ - if( 0 == PL_strncasecmp(p, little, ll) ) - return (char *)p; - - return (char *)0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strcat.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strcat.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strcat.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strcat.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include - -PR_IMPLEMENT(char *) -PL_strcat(char *dest, const char *src) -{ - if( ((char *)0 == dest) || ((const char *)0 == src) ) - return dest; - - return strcat(dest, src); -} - -PR_IMPLEMENT(char *) -PL_strncat(char *dest, const char *src, PRUint32 max) -{ - char *rv; - - if( ((char *)0 == dest) || ((const char *)0 == src) || (0 == max) ) - return dest; - - for( rv = dest; *dest; dest++ ) - ; - - (void)PL_strncpy(dest, src, max); - return rv; -} - -PR_IMPLEMENT(char *) -PL_strcatn(char *dest, PRUint32 max, const char *src) -{ - char *rv; - PRUint32 dl; - - if( ((char *)0 == dest) || ((const char *)0 == src) ) - return dest; - - for( rv = dest, dl = 0; *dest; dest++, dl++ ) - ; - - if( max <= dl ) return rv; - (void)PL_strncpyz(dest, src, max-dl); - - return rv; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strchr.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strchr.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strchr.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strchr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include - -PR_IMPLEMENT(char *) -PL_strchr(const char *s, char c) -{ - if( (const char *)0 == s ) return (char *)0; - - return strchr(s, c); -} - -PR_IMPLEMENT(char *) -PL_strrchr(const char *s, char c) -{ - if( (const char *)0 == s ) return (char *)0; - - return strrchr(s, c); -} - -PR_IMPLEMENT(char *) -PL_strnchr(const char *s, char c, PRUint32 n) -{ - if( (const char *)0 == s ) return (char *)0; - - for( ; n && *s; s++, n-- ) - if( *s == c ) - return (char *)s; - - if( ((char)0 == c) && (n > 0) && ((char)0 == *s) ) return (char *)s; - - return (char *)0; -} - -PR_IMPLEMENT(char *) -PL_strnrchr(const char *s, char c, PRUint32 n) -{ - const char *p; - - if( (const char *)0 == s ) return (char *)0; - - for( p = s; n && *p; p++, n-- ) - ; - - if( ((char)0 == c) && (n > 0) && ((char)0 == *p) ) return (char *)p; - - for( p--; p >= s; p-- ) - if( *p == c ) - return (char *)p; - - return (char *)0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strcmp.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strcmp.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strcmp.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strcmp.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include - -PR_IMPLEMENT(PRIntn) -PL_strcmp(const char *a, const char *b) -{ - if( ((const char *)0 == a) || (const char *)0 == b ) - return (PRIntn)(a-b); - - return (PRIntn)strcmp(a, b); -} - -PR_IMPLEMENT(PRIntn) -PL_strncmp(const char *a, const char *b, PRUint32 max) -{ - if( ((const char *)0 == a) || (const char *)0 == b ) - return (PRIntn)(a-b); - - return (PRIntn)strncmp(a, b, (size_t)max); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strcpy.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strcpy.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strcpy.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strcpy.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include - -PR_IMPLEMENT(char *) -PL_strcpy(char *dest, const char *src) -{ - if( ((char *)0 == dest) || ((const char *)0 == src) ) return (char *)0; - - return strcpy(dest, src); -} - -PR_IMPLEMENT(char *) -PL_strncpy(char *dest, const char *src, PRUint32 max) -{ - char *rv; - - if( (char *)0 == dest ) return (char *)0; - if( (const char *)0 == src ) return (char *)0; - - for( rv = dest; max && ((*dest = *src) != 0); dest++, src++, max-- ) - ; - -#ifdef JLRU - /* XXX I (wtc) think the -- and ++ operators should be postfix. */ - while( --max ) - *++dest = '\0'; -#endif /* JLRU */ - - return rv; -} - -PR_IMPLEMENT(char *) -PL_strncpyz(char *dest, const char *src, PRUint32 max) -{ - char *rv; - - if( (char *)0 == dest ) return (char *)0; - if( (const char *)0 == src ) return (char *)0; - if( 0 == max ) return (char *)0; - - for( rv = dest, max--; max && ((*dest = *src) != 0); dest++, src++, max-- ) - ; - - *dest = '\0'; - - return rv; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strdup.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strdup.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strdup.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strdup.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include "prmem.h" -#include - -PR_IMPLEMENT(char *) -PL_strdup(const char *s) -{ - char *rv; - size_t n; - - if( (const char *)0 == s ) - s = ""; - - n = strlen(s) + 1; - - rv = (char *)malloc(n); - if( (char *)0 == rv ) return rv; - - (void)memcpy(rv, s, n); - - return rv; -} - -PR_IMPLEMENT(void) -PL_strfree(char *s) -{ - free(s); -} - -PR_IMPLEMENT(char *) -PL_strndup(const char *s, PRUint32 max) -{ - char *rv; - size_t l; - - if( (const char *)0 == s ) - s = ""; - - l = PL_strnlen(s, max); - - rv = (char *)malloc(l+1); - if( (char *)0 == rv ) return rv; - - (void)memcpy(rv, s, l); - rv[l] = '\0'; - - return rv; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strlen.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strlen.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strlen.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strlen.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include "prtypes.h" -#include "prlog.h" -#include - -PR_IMPLEMENT(PRUint32) -PL_strlen(const char *str) -{ - size_t l; - - if( (const char *)0 == str ) return 0; - - l = strlen(str); - - /* error checking in case we have a 64-bit platform -- make sure - * we don't have ultra long strings that overflow an int32 - */ - if( sizeof(PRUint32) < sizeof(size_t) ) - { - if( l > PR_INT32_MAX ) - PR_Assert("l <= PR_INT32_MAX", __FILE__, __LINE__); - } - - return (PRUint32)l; -} - -PR_IMPLEMENT(PRUint32) -PL_strnlen(const char *str, PRUint32 max) -{ - register const char *s; - - if( (const char *)0 == str ) return 0; - for( s = str; max && *s; s++, max-- ) - ; - - return (PRUint32)(s - str); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strpbrk.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strpbrk.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strpbrk.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strpbrk.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include - -PR_IMPLEMENT(char *) -PL_strpbrk(const char *s, const char *list) -{ - if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0; - - return strpbrk(s, list); -} - -PR_IMPLEMENT(char *) -PL_strprbrk(const char *s, const char *list) -{ - const char *p; - const char *r; - - if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0; - - for( r = s; *r; r++ ) - ; - - for( r--; r >= s; r-- ) - for( p = list; *p; p++ ) - if( *r == *p ) - return (char *)r; - - return (char *)0; -} - -PR_IMPLEMENT(char *) -PL_strnpbrk(const char *s, const char *list, PRUint32 max) -{ - const char *p; - - if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0; - - for( ; max && *s; s++, max-- ) - for( p = list; *p; p++ ) - if( *s == *p ) - return (char *)s; - - return (char *)0; -} - -PR_IMPLEMENT(char *) -PL_strnprbrk(const char *s, const char *list, PRUint32 max) -{ - const char *p; - const char *r; - - if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0; - - for( r = s; max && *r; r++, max-- ) - ; - - for( r--; r >= s; r-- ) - for( p = list; *p; p++ ) - if( *r == *p ) - return (char *)r; - - return (char *)0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strstr.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strstr.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strstr.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strstr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include - -PR_IMPLEMENT(char *) -PL_strstr(const char *big, const char *little) -{ - if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; - if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; - - return strstr(big, little); -} - -PR_IMPLEMENT(char *) -PL_strrstr(const char *big, const char *little) -{ - const char *p; - size_t ll; - size_t bl; - - if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; - if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; - - ll = strlen(little); - bl = strlen(big); - if( bl < ll ) return (char *)0; - p = &big[ bl - ll ]; - - for( ; p >= big; p-- ) - if( *little == *p ) - if( 0 == strncmp(p, little, ll) ) - return (char *)p; - - return (char *)0; -} - -PR_IMPLEMENT(char *) -PL_strnstr(const char *big, const char *little, PRUint32 max) -{ - size_t ll; - - if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; - if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; - - ll = strlen(little); - if( ll > (size_t)max ) return (char *)0; - max -= (PRUint32)ll; - max++; - - for( ; max && *big; big++, max-- ) - if( *little == *big ) - if( 0 == strncmp(big, little, ll) ) - return (char *)big; - - return (char *)0; -} - -PR_IMPLEMENT(char *) -PL_strnrstr(const char *big, const char *little, PRUint32 max) -{ - const char *p; - size_t ll; - - if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; - if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; - - ll = strlen(little); - - for( p = big; max && *p; p++, max-- ) - ; - - p -= ll; - if( p < big ) return (char *)0; - - for( ; p >= big; p-- ) - if( *little == *p ) - if( 0 == strncmp(p, little, ll) ) - return (char *)p; - - return (char *)0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strtok.c nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strtok.c --- nspr-4.9.5/mozilla/nsprpub/lib/libc/src/strtok.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/libc/src/strtok.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" - -PR_IMPLEMENT(char *) -PL_strtok_r(char *s1, const char *s2, char **lasts) -{ - const char *sepp; - int c, sc; - char *tok; - - if( s1 == NULL ) - { - if( *lasts == NULL ) - return NULL; - - s1 = *lasts; - } - - for( ; (c = *s1) != 0; s1++ ) - { - for( sepp = s2 ; (sc = *sepp) != 0 ; sepp++ ) - { - if( c == sc ) - break; - } - if( sc == 0 ) - break; - } - - if( c == 0 ) - { - *lasts = NULL; - return NULL; - } - - tok = s1++; - - for( ; (c = *s1) != 0; s1++ ) - { - for( sepp = s2; (sc = *sepp) != 0; sepp++ ) - { - if( c == sc ) - { - *s1++ = '\0'; - *lasts = s1; - return tok; - } - } - } - *lasts = NULL; - return tok; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/Makefile.in nspr-4.10.7/mozilla/nsprpub/lib/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/lib/Makefile.in 2012-05-31 21:54:47.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = .. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -export NSPR20=1 - -include $(topsrcdir)/config/config.mk - -DIRS = ds libc - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/.cvsignore nspr-4.10.7/mozilla/nsprpub/lib/prstreams/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/.cvsignore 2001-05-12 06:36:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/Makefile.in nspr-4.10.7/mozilla/nsprpub/lib/prstreams/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/Makefile.in 2012-11-13 23:17:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -ifeq ($(OS_ARCH), IRIX) - ifneq ($(OS_RELEASE),5.3) - CCC_ONLY_FLAGS += -exceptions - endif -endif - -ifeq ($(OS_ARCH), BeOS) - CFLAGS += -frtti -fexceptions -endif - -INCLUDES = -I$(dist_includedir) - -HEADERS = $(wildcard $(srcdir)/*.h) - -CSRCS = \ - plvrsion.c \ - $(NULL) - -CXXSRCS = \ - prstrms.cpp \ - $(NULL) - -OBJS = $(addprefix $(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)) $(CXXSRCS:.cpp=.$(OBJ_SUFFIX))) - -ifeq ($(OS_ARCH), WINNT) - RES=$(OBJDIR)/prstrms.res - RESNAME=prstrms.rc - OS_LIBS = user32.lib -else - ifeq ($(OS_ARCH),OS2) - OS_LIBS = -lstdcpp - else - ifeq ($(OS_ARCH), AIX) - ifeq ($(OS_RELEASE), 4.1) - ifeq ($(CLASSIC_NSPR),1) - OS_LIBS += -lC -lc - else - OS_LIBS += -lC_r -lc_r - endif - else - # makeC++SharedLib(_r) is in either /usr/lpp/xlC/bin - # or /usr/ibmcxx/bin. - ifeq ($(CLASSIC_NSPR),1) - MKSHLIB = makeC++SharedLib -p 0 - else - MKSHLIB = makeC++SharedLib_r -p 0 - endif - OS_LIBS += -ldl - endif - endif - endif -endif - -ifeq ($(OS_ARCH),BeOS) - OS_LIBS = -lstdc++.r4 -endif - -ifeq ($(OS_ARCH), UNIXWARE) - OS_LIBS += -lC -endif - -EXTRA_LIBS = $(LIBNSPR) - -# On SCOOS, we can't link with extra libraries when -# we build a shared library. If we do so, the linker doesn't -# complain, but we would run into weird problems at run-time. -# Therefore on these platforms, we link just the object files. -ifeq ($(OS_ARCH),SCOOS) - EXTRA_LIBS = -endif - -ifdef RESOLVE_LINK_SYMBOLS -EXTRA_LIBS += $(OS_LIBS) -endif - -LIBRARY_NAME = prstrms -LIBRARY_VERSION = $(MOD_MAJOR_VERSION) - -RELEASE_HEADERS = $(HEADERS) -RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR) -RELEASE_LIBS = $(TARGETS) - -include $(topsrcdir)/config/rules.mk - -# -# Version information generation (begin) -# -ECHO = echo -TINC = $(OBJDIR)/_pl_bld.h -PROD = $(notdir $(SHARED_LIBRARY)) -NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now -SH_DATE = $(shell date "+%Y-%m-%d %T") -SH_NOW = $(shell $(NOW)) - -ifeq ($(OS_ARCH), WINNT) - SUF = i64 -else - SUF = LL -endif - -$(TINC): - @$(MAKE_OBJDIR) - @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC) - @if test ! -z "$(SH_NOW)"; then \ - $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \ - else \ - true; \ - fi - @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) - - -$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC) -ifeq ($(OS_ARCH), WINNT) - $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< -else - $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< -endif -# -# Version information generation (end) -# - -export:: $(TARGETS) $(HEADERS) - $(INSTALL) -m 444 $(HEADERS) $(dist_includedir) - $(INSTALL) -m 444 $(TARGETS) $(dist_libdir) -ifeq ($(OS_ARCH),OS2) - $(INSTALL) -m 444 $(TARGETS) $(dist_bindir) -endif -ifeq ($(OS_ARCH),HP-UX) -ifdef SHARED_LIBRARY - $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir) -endif -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/plvrsion.c nspr-4.10.7/mozilla/nsprpub/lib/prstreams/plvrsion.c --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/plvrsion.c 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/plvrsion.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include "prvrsion.h" - -/************************************************************************/ -/**************************IDENTITY AND VERSIONING***********************/ -/************************************************************************/ -#include "_pl_bld.h" -#if !defined(_BUILD_TIME) -#ifdef HAVE_LONG_LONG -#define _BUILD_TIME 0 -#else -#define _BUILD_TIME {0, 0} -#endif -#endif -#if !defined(_BUILD_STRING) -#define _BUILD_STRING "" -#endif -#if !defined(_PRODUCTION) -#define _PRODUCTION "" -#endif -#if defined(DEBUG) -#define _DEBUG_STRING " (debug)" -#else -#define _DEBUG_STRING "" -#endif - -/* - * A trick to expand the PR_VMAJOR macro before concatenation. - */ -#define CONCAT(x, y) x ## y -#define CONCAT2(x, y) CONCAT(x, y) -#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libprstrms, PR_VMAJOR) - -PRVersionDescription VERSION_DESC_NAME = -{ - /* version */ 2, /* this is the only one supported */ - /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */ - /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */ - /* vMajor */ PR_VMAJOR, /* NSPR's version number */ - /* vMinor */ PR_VMINOR, /* and minor version */ - /* vPatch */ PR_VPATCH, /* and patch */ - /* beta */ PR_BETA, /* beta build boolean */ -#if defined(DEBUG) - /* debug */ PR_TRUE, /* a debug build */ -#else - /* debug */ PR_FALSE, /* an optomized build */ -#endif - /* special */ PR_FALSE, /* they're all special, but ... */ - /* filename */ _PRODUCTION, /* the produced library name */ - /* description */ "Portable runtime", /* what we are */ - /* security */ "N/A", /* not applicable here */ - /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved", - /* comment */ "http://www.mozilla.org/MPL/", - /* specialString */ "" -}; - -#ifdef XP_UNIX - -/* - * Version information for the 'ident' and 'what commands - * - * NOTE: the first component of the concatenated rcsid string - * must not end in a '$' to prevent rcs keyword substitution. - */ -static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING - " " _BUILD_STRING " $"; -static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING - " " _BUILD_STRING; - -#endif /* XP_UNIX */ - -PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint() -{ -#ifdef XP_UNIX - /* - * Add dummy references to rcsid and sccsid to prevent them - * from being optimized away as unused variables. - */ - const char *dummy; - - dummy = rcsid; - dummy = sccsid; -#endif - return &VERSION_DESC_NAME; -} /* versionEntryPointType */ - -/* plvrsion.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/prstrms.cpp nspr-4.10.7/mozilla/nsprpub/lib/prstreams/prstrms.cpp --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/prstrms.cpp 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/prstrms.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,516 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Robin J. Maxwell 11-22-96 - * Fredrik Roubert 2010-07-23 - * Matt Austern 2010-07-23 - */ - -#include "prstrms.h" - -#include -#include -#include -#include - -using std::ios_base; -using std::iostream; -using std::istream; -using std::nothrow; -using std::ostream; -using std::streambuf; -using std::streamsize; - - -PRfilebuf::PRfilebuf(): - _fd(NULL), - _opened(false), - _allocated(false), - _unbuffered(false), - _user_buf(false), - _buf_base(NULL), - _buf_end(NULL) { } - - -PRfilebuf::PRfilebuf(PRFileDesc *fd): - _fd(fd), - _opened(false), - _allocated(false), - _unbuffered(false), - _user_buf(false), - _buf_base(NULL), - _buf_end(NULL) { } - - -PRfilebuf::PRfilebuf(PRFileDesc *fd, char_type *ptr, streamsize len): - _fd(fd), - _opened(false), - _allocated(false), - _unbuffered(false), - _user_buf(false), - _buf_base(NULL), - _buf_end(NULL) -{ - setbuf(ptr, len); -} - - -PRfilebuf::~PRfilebuf() -{ - if (_opened) { - close(); - } else { - sync(); - } - if (_allocated) { - delete _buf_base; - } -} - - -PRfilebuf *PRfilebuf::open( - const char *name, ios_base::openmode flags, PRIntn mode) -{ - if (_fd != NULL) { - return NULL; // Error if already open. - } - - // Translate flags argument. - PRIntn prflags = 0; - bool ate = (flags & ios_base::ate) != 0; - flags &= ~(ios_base::ate | ios_base::binary); - - // TODO: The flag PR_CREATE_FILE should probably be used for the cases - // (out), (out|app), (out|trunc) and (in|out|trunc) as the C++ standard - // specifies that these cases should open files 'as if by using fopen with - // "w"'. But adding that flag here will cause the unit test to leave files - // behind after running (which might or might not be an error in the unit - // test) so the matter needs further investigation before any changes are - // made. The old prstreams implementation used the non-standard flag - // ios::nocreate to control the use of PR_CREATE_FILE. - - if (flags == (ios_base::out)) { - prflags = PR_WRONLY | PR_TRUNCATE; - } else if (flags == (ios_base::out | ios_base::app)) { - prflags = PR_RDWR | PR_APPEND; - } else if (flags == (ios_base::out | ios_base::trunc)) { - prflags = PR_WRONLY | PR_TRUNCATE; - } else if (flags == (ios_base::in)) { - prflags = PR_RDONLY; - } else if (flags == (ios_base::in | ios_base::out)) { - prflags = PR_RDWR; - } else if (flags == (ios_base::in | ios_base::out | ios_base::trunc)) { - prflags = PR_RDWR | PR_TRUNCATE; - } else { - return NULL; // Unrecognized flag combination. - } - - if ((_fd = PR_Open(name, prflags, mode)) == NULL) { - return NULL; - } - - _opened = true; - - if (ate && - seekoff(0, ios_base::end, flags) == pos_type(traits_type::eof())) { - close(); - return NULL; - } - - return this; -} - - -PRfilebuf *PRfilebuf::attach(PRFileDesc *fd) -{ - if (_fd != NULL) { - return NULL; // Error if already open. - } - - _opened = false; - _fd = fd; - return this; -} - - -PRfilebuf *PRfilebuf::close() -{ - if (_fd == NULL) - return NULL; - - int status = sync(); - - if (PR_Close(_fd) == PR_FAILURE || - traits_type::eq_int_type(status, traits_type::eof())) { - return NULL; - } - - _fd = NULL; - return this; -} - - -streambuf *PRfilebuf::setbuf(char_type *ptr, streamsize len) -{ - if (is_open() && _buf_end) { - return NULL; - } - - if (!ptr || len <= 0) { - _unbuffered = true; - } else { - setb(ptr, ptr + len, false); - } - - return this; -} - - -streambuf::pos_type PRfilebuf::seekoff( - off_type offset, ios_base::seekdir dir, ios_base::openmode /*flags*/) -{ - if (PR_GetDescType(_fd) != PR_DESC_FILE) { - return traits_type::eof(); - } - - PRSeekWhence whence; - PRInt64 pos; - - switch (dir) { - case ios_base::beg: whence = PR_SEEK_SET; break; - case ios_base::cur: whence = PR_SEEK_CUR; break; - case ios_base::end: whence = PR_SEEK_END; break; - default: - return traits_type::eof(); // This should never happen. - } - - if (traits_type::eq_int_type(sync(), traits_type::eof())) { - return traits_type::eof(); - } - - if ((pos = PR_Seek64(_fd, offset, whence)) == -1) { - return traits_type::eof(); - } - - return pos; -} - - -int PRfilebuf::sync() -{ - if (_fd == NULL) { - return traits_type::eof(); - } - - if (!_unbuffered) { - // Sync write area. - PRInt32 waiting; - if ((waiting = pptr() - pbase()) != 0) { - PRInt32 nout; - if ((nout = PR_Write(_fd, pbase(), waiting)) != waiting) { - if (nout > 0) { - // Should set _pptr -= nout. - pbump(-nout); - memmove(pbase(), pbase() + nout, waiting - nout); - } - return traits_type::eof(); - } - } - setp(NULL, NULL); // Empty put area. - - if (PR_GetDescType(_fd) == PR_DESC_FILE) { - // Sockets can't seek; don't need this. - PROffset64 avail; - if ((avail = in_avail()) > 0) { - if (PR_Seek64(_fd, -avail, PR_SEEK_CUR) != -1) { - return traits_type::eof(); - } - } - } - setg(NULL, NULL, NULL); // Empty get area. - } - - return 0; -} - - -streambuf::int_type PRfilebuf::underflow() -{ - PRInt32 count; - char_type byte; - - if (gptr() != NULL && gptr() < egptr()) { - return traits_type::to_int_type(*gptr()); - } - - // Make sure there is a reserve area. - if (!_unbuffered && _buf_base == NULL && !allocate()) { - return traits_type::eof(); - } - - // Sync before new buffer created below. - if (traits_type::eq_int_type(sync(), traits_type::eof())) { - return traits_type::eof(); - } - - if (_unbuffered) { - if (PR_Read(_fd, &byte, 1) <= 0) { - return traits_type::eof(); - } - - return traits_type::to_int_type(byte); - } - - if ((count = PR_Read(_fd, _buf_base, _buf_end - _buf_base)) <= 0) { - return traits_type::eof(); // Reached EOF. - } - - setg(_buf_base, _buf_base, _buf_base + count); - return traits_type::to_int_type(*gptr()); -} - - -streambuf::int_type PRfilebuf::overflow(int_type c) -{ - // Make sure there is a reserve area. - if (!_unbuffered && _buf_base == NULL && !allocate()) { - return traits_type::eof(); - } - - // Sync before new buffer created below. - if (traits_type::eq_int_type(sync(), traits_type::eof())) { - return traits_type::eof(); - } - - if (!_unbuffered) { - setp(_buf_base, _buf_end); - } - - if (!traits_type::eq_int_type(c, traits_type::eof())) { - // Extract the byte to be written. - // (Required on big-endian architectures.) - char_type byte = traits_type::to_char_type(c); - if (!_unbuffered && pptr() < epptr()) { // Guard against recursion. - return sputc(byte); - } else { - if (PR_Write(_fd, &byte, 1) != 1) { - return traits_type::eof(); - } - } - } - - return traits_type::not_eof(c); -} - - -bool PRfilebuf::allocate() -{ - char_type *buf = new(nothrow) char_type[BUFSIZ]; - if (buf == NULL) { - return false; - } - - setb(buf, buf + BUFSIZ, true); - return true; -} - - -void PRfilebuf::setb(char_type *buf_base, char_type *buf_end, bool user_buf) -{ - if (_buf_base && !_user_buf) { - delete[] _buf_base; - } - - _buf_base = buf_base; - _buf_end = buf_end; - _user_buf = user_buf; -} - - -PRifstream::PRifstream(): - istream(NULL), - _filebuf() -{ - init(&_filebuf); -} - - -PRifstream::PRifstream(PRFileDesc *fd): - istream(NULL), - _filebuf(fd) -{ - init(&_filebuf); -} - - -PRifstream::PRifstream(PRFileDesc *fd, char_type *ptr, streamsize len): - istream(NULL), - _filebuf(fd, ptr, len) -{ - init(&_filebuf); -} - - -PRifstream::PRifstream(const char *name, openmode flags, PRIntn mode): - istream(NULL), - _filebuf() -{ - init(&_filebuf); - if (!_filebuf.open(name, flags | in, mode)) { - setstate(failbit); - } -} - - -PRifstream::~PRifstream() { } - - -void PRifstream::open(const char *name, openmode flags, PRIntn mode) -{ - if (is_open() || !_filebuf.open(name, flags | in, mode)) { - setstate(failbit); - } -} - - -void PRifstream::attach(PRFileDesc *fd) -{ - if (!_filebuf.attach(fd)) { - setstate(failbit); - } -} - - -void PRifstream::close() -{ - if (_filebuf.close() == NULL) { - setstate(failbit); - } -} - - -PRofstream::PRofstream(): - ostream(NULL), - _filebuf() -{ - init(&_filebuf); -} - - -PRofstream::PRofstream(PRFileDesc *fd): - ostream(NULL), - _filebuf(fd) -{ - init(&_filebuf); -} - - -PRofstream::PRofstream(PRFileDesc *fd, char_type *ptr, streamsize len): - ostream(NULL), - _filebuf(fd, ptr, len) -{ - init(&_filebuf); -} - - -PRofstream::PRofstream(const char *name, openmode flags, PRIntn mode): - ostream(NULL), - _filebuf() -{ - init(&_filebuf); - if (!_filebuf.open(name, flags | out, mode)) { - setstate(failbit); - } -} - - -PRofstream::~PRofstream() { } - - -void PRofstream::open(const char *name, openmode flags, PRIntn mode) -{ - if (is_open() || !_filebuf.open(name, flags | out, mode)) { - setstate(failbit); - } -} - - -void PRofstream::attach(PRFileDesc *fd) -{ - if (!_filebuf.attach(fd)) { - setstate(failbit); - } -} - - -void PRofstream::close() -{ - if (_filebuf.close() == NULL) { - setstate(failbit); - } -} - - -PRfstream::PRfstream(): - iostream(NULL), - _filebuf() -{ - init(&_filebuf); -} - - -PRfstream::PRfstream(PRFileDesc *fd): - iostream(NULL), - _filebuf(fd) -{ - init(&_filebuf); -} - - -PRfstream::PRfstream(PRFileDesc *fd, char_type *ptr, streamsize len): - iostream(NULL), - _filebuf(fd, ptr, len) -{ - init(&_filebuf); -} - - -PRfstream::PRfstream(const char *name, openmode flags, PRIntn mode): - iostream(NULL), - _filebuf() -{ - init(&_filebuf); - if (!_filebuf.open(name, flags | in | out, mode)) { - setstate(failbit); - } -} - - -PRfstream::~PRfstream() { } - - -void PRfstream::open(const char *name, openmode flags, PRIntn mode) -{ - if (is_open() || !_filebuf.open(name, flags | in | out, mode)) { - setstate(failbit); - } -} - - -void PRfstream::attach(PRFileDesc *fd) -{ - if (!_filebuf.attach(fd)) { - setstate(failbit); - } -} - - -void PRfstream::close() -{ - if (_filebuf.close() == NULL) { - setstate(failbit); - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/prstrms.h nspr-4.10.7/mozilla/nsprpub/lib/prstreams/prstrms.h --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/prstrms.h 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/prstrms.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Robin J. Maxwell 11-22-96 - * Fredrik Roubert 2010-07-23 - * Matt Austern 2010-07-23 - */ - -#ifndef _PRSTRMS_H -#define _PRSTRMS_H - -#include -#include -#include -#include - -#include "prio.h" - -#ifdef _MSC_VER -// http://support.microsoft.com/kb/q168958/ -class PR_IMPLEMENT(std::_Mutex); -class PR_IMPLEMENT(std::ios_base); -#endif - - -class PR_IMPLEMENT(PRfilebuf): public std::streambuf -{ -public: - PRfilebuf(); - PRfilebuf(PRFileDesc *fd); - PRfilebuf(PRFileDesc *fd, char_type *ptr, std::streamsize len); - virtual ~PRfilebuf(); - - bool is_open() const { return _fd != NULL; } - - PRfilebuf *open( - const char *name, - std::ios_base::openmode flags, - PRIntn mode); - PRfilebuf *attach(PRFileDesc *fd); - PRfilebuf *close(); - -protected: - virtual std::streambuf *setbuf(char_type *ptr, std::streamsize len); - virtual pos_type seekoff( - off_type offset, - std::ios_base::seekdir dir, - std::ios_base::openmode flags); - virtual pos_type seekpos( - pos_type pos, - std::ios_base::openmode flags) { - return seekoff(pos, std::ios_base::beg, flags); - } - virtual int sync(); - virtual int_type underflow(); - virtual int_type overflow(int_type c = traits_type::eof()); - - // TODO: Override pbackfail(), showmanyc(), uflow(), xsgetn(), and xsputn(). - -private: - bool allocate(); - void setb(char_type *buf_base, char_type *buf_end, bool user_buf); - - PRFileDesc *_fd; - bool _opened; - bool _allocated; - bool _unbuffered; - bool _user_buf; - char_type *_buf_base; - char_type *_buf_end; -}; - - -class PR_IMPLEMENT(PRifstream): public std::istream -{ -public: - PRifstream(); - PRifstream(PRFileDesc *fd); - PRifstream(PRFileDesc *fd, char_type *ptr, std::streamsize len); - PRifstream(const char *name, openmode flags = in, PRIntn mode = 0); - virtual ~PRifstream(); - - PRfilebuf *rdbuf() const { return &_filebuf; } - bool is_open() const { return _filebuf.is_open(); } - - void open(const char *name, openmode flags = in, PRIntn mode = 0); - void attach(PRFileDesc *fd); - void close(); - -private: - mutable PRfilebuf _filebuf; -}; - - -class PR_IMPLEMENT(PRofstream): public std::ostream -{ -public: - PRofstream(); - PRofstream(PRFileDesc *fd); - PRofstream(PRFileDesc *fd, char_type *ptr, std::streamsize len); - PRofstream(const char *name, openmode flags = out, PRIntn mode = 0); - virtual ~PRofstream(); - - PRfilebuf *rdbuf() const { return &_filebuf; } - bool is_open() const { return _filebuf.is_open(); } - - void open(const char *name, openmode flags = out, PRIntn mode = 0); - void attach(PRFileDesc *fd); - void close(); - -private: - mutable PRfilebuf _filebuf; -}; - - -class PR_IMPLEMENT(PRfstream): public std::iostream -{ -public: - PRfstream(); - PRfstream(PRFileDesc *fd); - PRfstream(PRFileDesc *fd, char_type *ptr, std::streamsize len); - PRfstream(const char *name, openmode flags = in | out, PRIntn mode = 0); - virtual ~PRfstream(); - - PRfilebuf *rdbuf() const { return &_filebuf; } - bool is_open() const { return _filebuf.is_open(); } - - void open(const char *name, openmode flags = in | out, PRIntn mode = 0); - void attach(PRFileDesc *fd); - void close(); - -private: - mutable PRfilebuf _filebuf; -}; - - -#endif /* _PRSTRMS_H */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/prstrms.rc nspr-4.10.7/mozilla/nsprpub/lib/prstreams/prstrms.rc --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/prstrms.rc 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/prstrms.rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include - -#define MY_LIBNAME "prstrms" -#define MY_FILEDESCRIPTION "PRSTRMS Library" - -#define STRINGIZE(x) #x -#define STRINGIZE2(x) STRINGIZE(x) -#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR) - -#ifdef _DEBUG -#define MY_DEBUG_STR " (debug)" -#define MY_FILEFLAGS_1 VS_FF_DEBUG -#else -#define MY_DEBUG_STR "" -#define MY_FILEFLAGS_1 0x0L -#endif -#if PR_BETA -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE -#else -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 -#endif - -#ifdef WINNT -#define MY_FILEOS VOS_NT_WINDOWS32 -#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR -#else -#define MY_FILEOS VOS__WINDOWS32 -#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR -#endif - -///////////////////////////////////////////////////////////////////////////// -// -// Version-information resource -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 - PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS MY_FILEFLAGS_2 - FILEOS MY_FILEOS - FILETYPE VFT_DLL - FILESUBTYPE 0x0L // not used - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" // Lang=US English, CharSet=Unicode - BEGIN - VALUE "CompanyName", "Mozilla Foundation\0" - VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" - VALUE "FileVersion", PR_VERSION "\0" - VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" - VALUE "ProductName", "Netscape Portable Runtime\0" - VALUE "ProductVersion", PR_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore nspr-4.10.7/mozilla/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore 2001-05-12 06:40:34.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in nspr-4.10.7/mozilla/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CXXSRCS = \ - testprstrm.cpp \ - $(NULL) - -OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX))) - -ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) -PROG_SUFFIX = .exe -else -PROG_SUFFIX = -endif - -PROGS = $(addprefix $(OBJDIR)/, $(CXXSRCS:.cpp=$(PROG_SUFFIX))) - -TARGETS = $(PROGS) $(OBJS) - -INCLUDES = -I$(dist_includedir) - -# Setting the variables LDOPTS and LIBPR. We first initialize -# them to the default values, then adjust them for some platforms. -LDOPTS = -L$(dist_libdir) -LIBPR = -lnspr$(MOD_MAJOR_VERSION) -LIBPRSTRMS = -lprstrms$(MOD_MAJOR_VERSION) - -ifeq ($(OS_ARCH), WINNT) - LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO - ifeq ($(OS_TARGET), WIN95) - LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - LIBPRSTRMS = $(dist_libdir)/prstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - else - LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - LIBPRSTRMS = $(dist_libdir)/libprstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - endif -endif - -ifeq ($(OS_ARCH),OS2) -LDOPTS += -Zomf -Zlinker /PM:VIO -lstdcpp -endif - -ifneq ($(OS_ARCH), WINNT) -PWD = $(shell pwd) -endif - -ifeq ($(OS_ARCH), IRIX) -LDOPTS += -rpath $(PWD)/$(dist_libdir) -endif - -ifeq ($(OS_ARCH), OSF1) -LDOPTS += -rpath $(PWD)/$(dist_libdir) -endif - -ifeq ($(OS_ARCH), HP-UX) -LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir) -endif - -# AIX -ifeq ($(OS_ARCH),AIX) -LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib -ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1) -LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr -LIBPRSTRMS = -lprstrms$(MOD_MAJOR_VERSION)_shr -else -LDOPTS += -brtl -EXTRA_LIBS = -ldl -endif -endif - -# Solaris -ifeq ($(OS_ARCH), SunOS) -ifdef NS_USE_GCC -LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir) -else -LDOPTS += -R $(PWD)/$(dist_libdir) -# CC on SunOS 5.5.x needs to link with -lpthread even though we already -# linked with this system library when we built libnspr.so. -ifdef USE_PTHREADS -EXTRA_LIBS = -lpthread -endif # USE_PTHREADS -endif # NS_USE_GCC -endif # SunOS - -ifeq ($(OS_ARCH), SCOOS) -# SCO Unix needs to link against -lsocket again even though we -# already linked with these system libraries when we built libnspr.so. -EXTRA_LIBS = -lsocket -# This hardcodes in the executable programs the directory to find -# libnspr.so etc. at program startup. Equivalent to the -R or -rpath -# option for ld on other platforms. -export LD_RUN_PATH = $(PWD)/$(dist_libdir) -endif - -ifeq ($(OS_ARCH), UNIXWARE) -export LD_RUN_PATH = $(PWD)/$(dist_libdir) -endif - -##################################################### -# -# The rules -# -##################################################### - -include $(topsrcdir)/config/rules.mk - -AIX_PRE_4_2 = 0 -ifeq ($(OS_ARCH),AIX) -ifneq ($(OS_RELEASE),4.2) -ifneq ($(USE_PTHREADS), 1) -#AIX_PRE_4_2 = 1 -endif -endif -endif - -ifeq ($(AIX_PRE_4_2),1) - -# AIX releases prior to 4.2 need a special two-step linking hack -# in order to both override the system select() and be able to -# get at the original system select(). -# -# We use a pattern rule in ns/nspr20/config/rules.mk to generate -# the .$(OBJ_SUFFIX) file from the .c source file, then do the -# two-step linking hack below. - -$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) - rm -f $@ $(AIX_TMP) - $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a - $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) - rm -f $(AIX_TMP) - -else - -# All platforms that are not AIX pre-4.2. - -$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) -ifeq ($(OS_ARCH), WINNT) - link $(LDOPTS) $< $(LIBPR) $(LIBPRSTRMS) wsock32.lib -out:$@ -else -ifeq ($(OS_ARCH),OS2) - $(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPR) $(LIBPRSTRMS) $(OS_LIBS) $(EXTRA_LIBS) -else - $(CCC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPRSTRMS) $(EXTRA_LIBS) -o $@ -endif -endif -endif - -export:: $(TARGETS) -clean:: - rm -f $(TARGETS) - -testlinker: - echo $(LINK) diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp nspr-4.10.7/mozilla/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp --- nspr-4.9.5/mozilla/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp 2012-05-31 21:54:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prstrms.h" - -#include "prinit.h" -#include "prio.h" -#include "prthread.h" - -#include -#include - -#ifdef XP_UNIX -#include -#endif - -using std::cout; -using std::endl; -using std::ios; - -const unsigned int MaxCnt = 1; - -typedef struct threadarg { - const char *mytag; -} threadarg; - -void threadwork(threadarg *arg); - -void -threadmain(void *mytag) -{ - threadarg arg; - - arg.mytag = static_cast(mytag); - - threadwork(&arg); -} - -void -threadwork(threadarg *arg) -{ - unsigned int i; - - char fname1[256]; - char fname2[256]; - - strcpy(fname1, arg->mytag); - strcpy(fname2, arg->mytag); - strcat(fname2, "2"); - PR_Delete(fname1); - PR_Delete(fname2); - - PRfilebuf *fb[MaxCnt]; - PRifstream *ifs[MaxCnt]; - PRofstream *ofs[MaxCnt]; - int mode = 0; -#ifdef XP_UNIX - mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; -#endif - - // - // Allocate a bunch - cout << "Testing unused filebufs ----------------" << endl; - for (i=0; i < MaxCnt; i++){ - fb[i] = new PRfilebuf; - } - // Delete them - for (i=0; i < MaxCnt; i++){ - delete fb[i]; - } - cout << "Unused filebufs complete ---------------" << endl; - - // - // Allocate a bunch - cout << "Testing unused ifstream -----------------" << endl; - for (i=0; i < MaxCnt; i++){ - ifs[i] = new PRifstream; - } - // - // Delete them - for (i=0; i < MaxCnt; i++){ - delete ifs[i]; - } - cout << "Unused ifstream complete ----------------" << endl; - // - // Allocate a bunch - cout << "Testing unused ofstream -----------------" << endl; - for (i=0; i < MaxCnt; i++){ - ofs[i] = new PRofstream; - } - for (i=0; i < MaxCnt; i++){ - *(ofs[i]) << "A"; // Write a bit - delete ofs[i]; // Delete it. - } - cout << "Unused ofstream complete ----------------" << endl; - - cout << "Testing use of ofstream 1 (extra filebuf allocated) ---------" << endl; - PRofstream *aos = new PRofstream(fname1, ios::out|ios::ate, mode); - for (i=0; i < MaxCnt; i++){ - for (int j=0; j < 8192; j++) - *aos << "AaBbCcDdEeFfGg" << endl; - fb[i] = new PRfilebuf; // Allocate as we go to hack at the heap - } - // - // Delete the extra foo we allocated - for (i=0; i < MaxCnt; i++){ - delete fb[i]; - } - aos->flush(); // Explicit flush - delete aos; - cout << "Testing use of ofstream 1 complete (extra filebuf deleted) --" << endl; - cout << "Testing use of ofstream 2 (extra filebuf allocated) ---------" << endl; - PRofstream *aos2 = new PRofstream(fname2, ios::out, mode); - - for (i=0; i < MaxCnt; i++){ - *aos2 << "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; - } - // Force flushing in the dtor - delete aos2; - cout << "Testing use of ofstream 2 complete (extra filebuf deleted) --" << endl; - char line[1024]; - cout << "Testing use of ifstream 1 (stack allocation) -------------" << endl; - PRifstream ais(fname1); - for (i=0; i < MaxCnt; i++){ - ais >> line; - } - cout << "Testing use of ifstream 1 complete -----------------------" << endl; - cout << "Testing use of ifstream 2 ----------------------" << endl; - PRifstream *ais2 = new PRifstream(fname2); - char achar; - for (i=0; i < MaxCnt*10; i++){ - *ais2 >> achar; - } - delete ais2; - cout << "Testing use of ifstream 2 complete -------------" << endl; -} - -#define STACKSIZE 1024*1024 -int -main() -{ - PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 256); - threadmain(const_cast("TestFile")); - PRThread *thr1 = PR_CreateThread(PR_SYSTEM_THREAD, - threadmain, - const_cast("TestFile1"), - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - STACKSIZE); - PRThread *thr2 = PR_CreateThread(PR_SYSTEM_THREAD, - threadmain, - const_cast("TestFile2"), - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - STACKSIZE); - PRThread *thr3 = PR_CreateThread(PR_SYSTEM_THREAD, - threadmain, - const_cast("TestFile3"), - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - STACKSIZE); - PR_JoinThread(thr1); - PR_JoinThread(thr2); - PR_JoinThread(thr3); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/tests/arena.c nspr-4.10.7/mozilla/nsprpub/lib/tests/arena.c --- nspr-4.9.5/mozilla/nsprpub/lib/tests/arena.c 2012-05-31 21:54:50.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/tests/arena.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,369 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: arena.c -** Description: Testing arenas -** -*/ - -#include -#include -#include -#include "nspr.h" -#include "plarena.h" -#include "plgetopt.h" - -PRLogModuleInfo *tLM; -PRIntn threadCount = 0; -PRMonitor *tMon; -PRBool failed_already = PR_FALSE; - -/* Arguments from the command line with default values */ -PRIntn debug_mode = 0; -PRIntn poolMin = 4096; -PRIntn poolMax = (100 * 4096); -PRIntn arenaMin = 40; -PRIntn arenaMax = (100 * 40); -PRIntn stressIterations = 15; -PRIntn maxAlloc = (1024 * 1024); -PRIntn stressThreads = 4; - -void DumpAll( void ) -{ - return; -} - -/* -** Test Arena allocation. -*/ -static void ArenaAllocate( void ) -{ - PLArenaPool ap; - void *ptr; - PRInt32 i; - - PL_InitArenaPool( &ap, "AllocArena", 2048, sizeof(double)); - PR_LOG( tLM, PR_LOG_DEBUG, ("AA, InitPool -- Pool: %p. first: %p, current: %p, size: %d", - &ap, ap.first, ap.current, ap.arenasize )); - - for( i = 0; i < 150; i++ ) - { - PL_ARENA_ALLOCATE( ptr, &ap, 512 ); - PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", - &ap, ap.first, ap.current, ap.arenasize )); - PR_LOG( tLM, PR_LOG_DEBUG,( - "AA -- Pool: %p. alloc: %p ", &ap, ptr )); - } - - PL_FreeArenaPool( &ap ); - - for( i = 0; i < 221; i++ ) - { - PL_ARENA_ALLOCATE( ptr, &ap, 512 ); - PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", - &ap, ap.first, ap.current, ap.arenasize )); - PR_LOG( tLM, PR_LOG_DEBUG,( - "AA -- Pool: %p. alloc: %p ", &ap, ptr )); - } - - PL_FreeArenaPool( &ap ); - - return; -} /* end ArenaGrow() */ -/* -** Test Arena grow. -*/ -static void ArenaGrow( void ) -{ - PLArenaPool ap; - void *ptr; - PRInt32 i; - - PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double)); - PL_ARENA_ALLOCATE( ptr, &ap, 512 ); - - PR_LOG( tLM, PR_LOG_DEBUG, ("Before growth -- Pool: %p. alloc: %p ", &ap, ptr )); - - for( i = 0; i < 10; i++ ) - { - PL_ARENA_GROW( ptr, &ap, 512, 7000 ); - PR_LOG( tLM, PR_LOG_DEBUG, ("After growth -- Pool: %p. alloc: %p ", &ap, ptr )); - } - - - return; -} /* end ArenaGrow() */ - - -/* -** Test arena Mark and Release. -*/ -static void MarkAndRelease( void ) -{ - PLArenaPool ap; - void *ptr = NULL; - void *mark0, *mark1; - PRIntn i; - - PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double)); - mark0 = PL_ARENA_MARK( &ap ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("mark0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m0: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark0 )); - - for( i = 0; i < 201; i++ ) - { - PL_ARENA_ALLOCATE( ptr, &ap, 512 ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr )); - } - - mark1 = PL_ARENA_MARK( &ap ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("mark1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m1: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark1 )); - - - for( i = 0; i < 225; i++ ) - { - PL_ARENA_ALLOCATE( ptr, &ap, 512 ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr )); - } - - PL_ARENA_RELEASE( &ap, mark1 ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("Release-1: %p -- Pool: %p. first: %p, current: %p, size: %d", - mark1, &ap, ap.first, ap.current, ap.arenasize )); - - for( i = 0; i < 20; i++ ) - { - PL_ARENA_ALLOCATE( ptr, &ap, 512 ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr )); - } - - PL_ARENA_RELEASE( &ap, mark1 ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("Release-1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr )); - - PL_ARENA_RELEASE( &ap, mark0 ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("Release-0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr )); - - PL_FreeArenaPool( &ap ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("Free. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr )); - - PL_FinishArenaPool( &ap ); - PR_LOG( tLM, PR_LOG_DEBUG, - ("Finish. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", - &ap, ap.first.next, ap.current, ap.arenasize, ptr )); - - return; -} /* end MarkAndRelease() */ - -/* -** RandSize() returns a random number in the range -** min..max, rounded to the next doubleword -** -*/ -static PRIntn RandSize( PRIntn min, PRIntn max ) -{ - PRIntn sz = (rand() % (max -min)) + min + sizeof(double); - - sz &= ~sizeof(double)-1; - - return(sz); -} - - -/* -** StressThread() -** A bunch of these beat on individual arenas -** This tests the free_list protection. -** -*/ -static void PR_CALLBACK StressThread( void *arg ) -{ - PLArenaPool ap; - PRIntn i; - PRIntn sz; - void *ptr; - PRThread *tp = PR_GetCurrentThread(); - - PR_LOG( tLM, PR_LOG_DEBUG, ("Stress Thread %p started\n", PR_GetCurrentThread())); - PL_InitArenaPool( &ap, "TheArena", RandSize( poolMin, poolMax), sizeof(double)); - - for ( i = 0; i < stressIterations; i++ ) - { - PRIntn allocated = 0; - - while ( allocated < maxAlloc ) - { - sz = RandSize( arenaMin, arenaMax ); - PL_ARENA_ALLOCATE( ptr, &ap, sz ); - if ( ptr == NULL ) - { - PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated)); - break; - } - allocated += sz; - } - PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp)); - PL_FreeArenaPool( &ap ); - } - PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp)); - PL_FinishArenaPool( &ap ); - PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp)); - - /* That's all folks! let's quit */ - PR_EnterMonitor(tMon); - threadCount--; - PR_Notify(tMon); - PR_ExitMonitor(tMon); - return; -} - -/* -** Stress() -** Flog the hell out of arenas multi-threaded. -** Do NOT pass an individual arena to another thread. -** -*/ -static void Stress( void ) -{ - PRThread *tt; - PRIntn i; - - tMon = PR_NewMonitor(); - - for ( i = 0 ; i < stressThreads ; i++ ) - { - PR_EnterMonitor(tMon); - tt = PR_CreateThread(PR_USER_THREAD, - StressThread, - NULL, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - threadCount++; - PR_ExitMonitor(tMon); - } - - /* Wait for all threads to exit */ - PR_EnterMonitor(tMon); - while ( threadCount != 0 ) - { - PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT); - } - PR_ExitMonitor(tMon); - PR_DestroyMonitor(tMon); - - return; -} /* end Stress() */ - -/* -** EvaluateResults() -** uses failed_already to display results and set program -** exit code. -*/ -static PRIntn EvaluateResults(void) -{ - PRIntn rc = 0; - - if ( failed_already == PR_TRUE ) - { - PR_LOG( tLM, PR_LOG_DEBUG, ("FAIL\n")); - rc =1; - } - else - { - PR_LOG( tLM, PR_LOG_DEBUG, ("PASS\n")); - } - return(rc); -} /* EvaluateResults() */ - -void Help( void ) -{ - printf("arena [options]\n"); - printf("where options are:\n"); - printf("-p minimum size of an arena pool. Default(%d)\n", poolMin); - printf("-P maximum size of an arena pool. Default(%d)\n", poolMax); - printf("-a minimum size of an arena allocation. Default(%d)\n", arenaMin); - printf("-A maximum size of an arena allocation. Default(%d)\n", arenaMax); - printf("-i number of iterations in a stress thread. Default(%d)\n", stressIterations); - printf("-s maximum allocation for a single stress thread. Default(%d)\n", maxAlloc); - printf("-t number of stress threads. Default(%d)\n", stressThreads ); - printf("-d enable debug mode\n"); - printf("\n"); - exit(1); -} - -PRIntn main(PRIntn argc, char *argv[]) -{ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dhp:P:a:A:i:s:t:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'a': /* arena Min size */ - arenaMin = atol( opt->value ); - break; - case 'A': /* arena Max size */ - arenaMax = atol( opt->value ); - break; - case 'p': /* pool Min size */ - poolMin = atol( opt->value ); - break; - case 'P': /* pool Max size */ - poolMax = atol( opt->value ); - break; - case 'i': /* Iterations in stress tests */ - stressIterations = atol( opt->value ); - break; - case 's': /* storage to get per iteration */ - maxAlloc = atol( opt->value ); - break; - case 't': /* Number of stress threads to create */ - stressThreads = atol( opt->value ); - break; - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'h': /* help */ - default: - Help(); - } /* end switch() */ - } /* end while() */ - PL_DestroyOptState(opt); - - srand( (unsigned)time( NULL ) ); /* seed random number generator */ - tLM = PR_NewLogModule("testcase"); - - -#if 0 - ArenaAllocate(); - ArenaGrow(); -#endif - - MarkAndRelease(); - - Stress(); - - return(EvaluateResults()); -} /* end main() */ - -/* arena.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/tests/base64t.c nspr-4.10.7/mozilla/nsprpub/lib/tests/base64t.c --- nspr-4.9.5/mozilla/nsprpub/lib/tests/base64t.c 2012-05-31 21:54:50.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/tests/base64t.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,3015 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plbase64.h" -#include "plstr.h" -#include "nspr.h" - -#include - -static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* PL_Base64Encode, single characters */ -PRBool test_001(void) -{ - PRUint32 a, b; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char result[ 8 ]; - char *rv; - - printf("Test 001 (PL_Base64Encode, single characters) ..."); fflush(stdout); - - plain[1] = plain[2] = plain[3] = (unsigned char)0; - cypher[2] = cypher[3] = (unsigned char)'='; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - - for( b = 0; b < 4; b++ ) - { - plain[0] = (unsigned char)(a * 4 + b); - cypher[1] = base[(b * 16)]; - - rv = PL_Base64Encode((char *)plain, 1, result); - if( rv != result ) - { - printf("FAIL\n\t(%d, %d): return value\n", a, b); - return PR_FALSE; - } - - if( 0 != PL_strncmp((char *)cypher, result, 4) ) - { - printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.4s.\"\n", - a, b, cypher, result); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, double characters */ -PRBool test_002(void) -{ - PRUint32 a, b, c, d; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char result[ 8 ]; - char *rv; - - printf("Test 002 (PL_Base64Encode, double characters) ..."); fflush(stdout); - - plain[2] = plain[3] = (unsigned char)0; - cypher[3] = (unsigned char)'='; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - cypher[2] = base[d*4]; - - rv = PL_Base64Encode((char *)plain, 2, result); - if( rv != result ) - { - printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d); - return PR_FALSE; - } - - if( 0 != PL_strncmp((char *)cypher, result, 4) ) - { - printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n", - a, b, c, d, cypher, result); - return PR_FALSE; - } - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, triple characters */ -PRBool test_003(void) -{ - PRUint32 a, b, c, d, e, f; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char result[ 8 ]; - char *rv; - - printf("Test 003 (PL_Base64Encode, triple characters) ..."); fflush(stdout); - - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - for( e = 0; e < 4; e++ ) - { - cypher[2] = base[d*4 + e]; - for( f = 0; f < 64; f++ ) - { - plain[2] = e * 64 + f; - cypher[3] = base[f]; - - rv = PL_Base64Encode((char *)plain, 3, result); - if( rv != result ) - { - printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): return value\n", a, b, c, d, e, f); - return PR_FALSE; - } - - if( 0 != PL_strncmp((char *)cypher, result, 4) ) - { - printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n", - a, b, c, d, e, f, cypher, result); - return PR_FALSE; - } - } - } - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - - static struct - { - const char *plaintext; - const char *cyphertext; - } array[] = - { - /* Cyphertexts generated with uuenview 0.5.13 */ - { " ", "IA==" }, - { ".", "Lg==" }, - { "/", "Lw==" }, - { "C", "Qw==" }, - { "H", "SA==" }, - { "S", "Uw==" }, - { "^", "Xg==" }, - { "a", "YQ==" }, - { "o", "bw==" }, - { "t", "dA==" }, - - { "AB", "QUI=" }, - { "AH", "QUg=" }, - { "AQ", "QVE=" }, - { "BD", "QkQ=" }, - { "CR", "Q1I=" }, - { "CS", "Q1M=" }, - { "DB", "REI=" }, - { "DC", "REM=" }, - { "EK", "RUs=" }, - { "ET", "RVQ=" }, - { "IM", "SU0=" }, - { "JR", "SlI=" }, - { "LO", "TE8=" }, - { "LW", "TFc=" }, - { "ML", "TUw=" }, - { "SB", "U0I=" }, - { "TO", "VE8=" }, - { "VS", "VlM=" }, - { "WP", "V1A=" }, - /* legitimate two-letter words */ - { "ad", "YWQ=" }, - { "ah", "YWg=" }, - { "am", "YW0=" }, - { "an", "YW4=" }, - { "as", "YXM=" }, - { "at", "YXQ=" }, - { "ax", "YXg=" }, - { "be", "YmU=" }, - { "by", "Ynk=" }, - { "do", "ZG8=" }, - { "go", "Z28=" }, - { "he", "aGU=" }, - { "hi", "aGk=" }, - { "if", "aWY=" }, - { "in", "aW4=" }, - { "is", "aXM=" }, - { "it", "aXQ=" }, - { "me", "bWU=" }, - { "my", "bXk=" }, - { "no", "bm8=" }, - { "of", "b2Y=" }, - { "on", "b24=" }, - { "or", "b3I=" }, - { "ox", "b3g=" }, - { "so", "c28=" }, - { "to", "dG8=" }, - { "up", "dXA=" }, - { "us", "dXM=" }, - { "we", "d2U=" }, - /* all three-letter entries in /usr/dict/words */ - { "1st", "MXN0" }, - { "2nd", "Mm5k" }, - { "3rd", "M3Jk" }, - { "4th", "NHRo" }, - { "5th", "NXRo" }, - { "6th", "NnRo" }, - { "7th", "N3Ro" }, - { "8th", "OHRo" }, - { "9th", "OXRo" }, - { "AAA", "QUFB" }, - { "AAU", "QUFV" }, - { "ABA", "QUJB" }, - { "abc", "YWJj" }, - { "Abe", "QWJl" }, - { "Abo", "QWJv" }, - { "ace", "YWNl" }, - { "ACM", "QUNN" }, - { "ACS", "QUNT" }, - { "act", "YWN0" }, - { "Ada", "QWRh" }, - { "add", "YWRk" }, - { "ado", "YWRv" }, - { "aft", "YWZ0" }, - { "age", "YWdl" }, - { "ago", "YWdv" }, - { "aid", "YWlk" }, - { "ail", "YWls" }, - { "aim", "YWlt" }, - { "air", "YWly" }, - { "ala", "YWxh" }, - { "alb", "YWxi" }, - { "ale", "YWxl" }, - { "Ali", "QWxp" }, - { "all", "YWxs" }, - { "alp", "YWxw" }, - { "A&M", "QSZN" }, - { "AMA", "QU1B" }, - { "ami", "YW1p" }, - { "amp", "YW1w" }, - { "Amy", "QW15" }, - { "amy", "YW15" }, - { "ana", "YW5h" }, - { "and", "YW5k" }, - { "ani", "YW5p" }, - { "Ann", "QW5u" }, - { "ant", "YW50" }, - { "any", "YW55" }, - { "A&P", "QSZQ" }, - { "ape", "YXBl" }, - { "Apr", "QXBy" }, - { "APS", "QVBT" }, - { "apt", "YXB0" }, - { "arc", "YXJj" }, - { "are", "YXJl" }, - { "ark", "YXJr" }, - { "arm", "YXJt" }, - { "art", "YXJ0" }, - { "a's", "YSdz" }, - { "ash", "YXNo" }, - { "ask", "YXNr" }, - { "ass", "YXNz" }, - { "ate", "YXRl" }, - { "Aug", "QXVn" }, - { "auk", "YXVr" }, - { "Ave", "QXZl" }, - { "awe", "YXdl" }, - { "awl", "YXds" }, - { "awn", "YXdu" }, - { "axe", "YXhl" }, - { "aye", "YXll" }, - { "bad", "YmFk" }, - { "bag", "YmFn" }, - { "bah", "YmFo" }, - { "bam", "YmFt" }, - { "ban", "YmFu" }, - { "bar", "YmFy" }, - { "bat", "YmF0" }, - { "bay", "YmF5" }, - { "bed", "YmVk" }, - { "bee", "YmVl" }, - { "beg", "YmVn" }, - { "bel", "YmVs" }, - { "Ben", "QmVu" }, - { "bet", "YmV0" }, - { "bey", "YmV5" }, - { "bib", "Ymli" }, - { "bid", "Ymlk" }, - { "big", "Ymln" }, - { "bin", "Ymlu" }, - { "bit", "Yml0" }, - { "biz", "Yml6" }, - { "BMW", "Qk1X" }, - { "boa", "Ym9h" }, - { "bob", "Ym9i" }, - { "bog", "Ym9n" }, - { "bon", "Ym9u" }, - { "boo", "Ym9v" }, - { "bop", "Ym9w" }, - { "bow", "Ym93" }, - { "box", "Ym94" }, - { "boy", "Ym95" }, - { "b's", "Yidz" }, - { "BTL", "QlRM" }, - { "BTU", "QlRV" }, - { "bub", "YnVi" }, - { "bud", "YnVk" }, - { "bug", "YnVn" }, - { "bum", "YnVt" }, - { "bun", "YnVu" }, - { "bus", "YnVz" }, - { "but", "YnV0" }, - { "buy", "YnV5" }, - { "bye", "Ynll" }, - { "cab", "Y2Fi" }, - { "Cal", "Q2Fs" }, - { "cam", "Y2Ft" }, - { "can", "Y2Fu" }, - { "cap", "Y2Fw" }, - { "car", "Y2Fy" }, - { "cat", "Y2F0" }, - { "caw", "Y2F3" }, - { "CBS", "Q0JT" }, - { "CDC", "Q0RD" }, - { "CEQ", "Q0VR" }, - { "chi", "Y2hp" }, - { "CIA", "Q0lB" }, - { "cit", "Y2l0" }, - { "cod", "Y29k" }, - { "cog", "Y29n" }, - { "col", "Y29s" }, - { "con", "Y29u" }, - { "coo", "Y29v" }, - { "cop", "Y29w" }, - { "cos", "Y29z" }, - { "cot", "Y290" }, - { "cow", "Y293" }, - { "cox", "Y294" }, - { "coy", "Y295" }, - { "CPA", "Q1BB" }, - { "cpu", "Y3B1" }, - { "CRT", "Q1JU" }, - { "cry", "Y3J5" }, - { "c's", "Yydz" }, - { "cub", "Y3Vi" }, - { "cud", "Y3Vk" }, - { "cue", "Y3Vl" }, - { "cup", "Y3Vw" }, - { "cur", "Y3Vy" }, - { "cut", "Y3V0" }, - { "dab", "ZGFi" }, - { "dad", "ZGFk" }, - { "dam", "ZGFt" }, - { "Dan", "RGFu" }, - { "Dar", "RGFy" }, - { "day", "ZGF5" }, - { "Dec", "RGVj" }, - { "Dee", "RGVl" }, - { "Del", "RGVs" }, - { "den", "ZGVu" }, - { "Des", "RGVz" }, - { "dew", "ZGV3" }, - { "dey", "ZGV5" }, - { "did", "ZGlk" }, - { "die", "ZGll" }, - { "dig", "ZGln" }, - { "dim", "ZGlt" }, - { "din", "ZGlu" }, - { "dip", "ZGlw" }, - { "Dis", "RGlz" }, - { "DNA", "RE5B" }, - { "DOD", "RE9E" }, - { "doe", "ZG9l" }, - { "dog", "ZG9n" }, - { "don", "ZG9u" }, - { "dot", "ZG90" }, - { "Dow", "RG93" }, - { "dry", "ZHJ5" }, - { "d's", "ZCdz" }, - { "dub", "ZHVi" }, - { "dud", "ZHVk" }, - { "due", "ZHVl" }, - { "dug", "ZHVn" }, - { "dun", "ZHVu" }, - { "dye", "ZHll" }, - { "ear", "ZWFy" }, - { "eat", "ZWF0" }, - { "ebb", "ZWJi" }, - { "EDT", "RURU" }, - { "eel", "ZWVs" }, - { "eft", "ZWZ0" }, - { "e.g", "ZS5n" }, - { "egg", "ZWdn" }, - { "ego", "ZWdv" }, - { "eke", "ZWtl" }, - { "Eli", "RWxp" }, - { "elk", "ZWxr" }, - { "ell", "ZWxs" }, - { "elm", "ZWxt" }, - { "Ely", "RWx5" }, - { "end", "ZW5k" }, - { "Eng", "RW5n" }, - { "EPA", "RVBB" }, - { "era", "ZXJh" }, - { "ere", "ZXJl" }, - { "erg", "ZXJn" }, - { "err", "ZXJy" }, - { "e's", "ZSdz" }, - { "EST", "RVNU" }, - { "eta", "ZXRh" }, - { "etc", "ZXRj" }, - { "Eva", "RXZh" }, - { "eve", "ZXZl" }, - { "ewe", "ZXdl" }, - { "eye", "ZXll" }, - { "FAA", "RkFB" }, - { "fad", "ZmFk" }, - { "fag", "ZmFn" }, - { "fan", "ZmFu" }, - { "far", "ZmFy" }, - { "fat", "ZmF0" }, - { "fay", "ZmF5" }, - { "FBI", "RkJJ" }, - { "FCC", "RkND" }, - { "FDA", "RkRB" }, - { "Feb", "RmVi" }, - { "fed", "ZmVk" }, - { "fee", "ZmVl" }, - { "few", "ZmV3" }, - { "fib", "Zmli" }, - { "fig", "Zmln" }, - { "fin", "Zmlu" }, - { "fir", "Zmly" }, - { "fit", "Zml0" }, - { "fix", "Zml4" }, - { "Flo", "Rmxv" }, - { "flu", "Zmx1" }, - { "fly", "Zmx5" }, - { "FMC", "Rk1D" }, - { "fob", "Zm9i" }, - { "foe", "Zm9l" }, - { "fog", "Zm9n" }, - { "fop", "Zm9w" }, - { "for", "Zm9y" }, - { "fox", "Zm94" }, - { "FPC", "RlBD" }, - { "fro", "ZnJv" }, - { "fry", "ZnJ5" }, - { "f's", "Zidz" }, - { "FTC", "RlRD" }, - { "fum", "ZnVt" }, - { "fun", "ZnVu" }, - { "fur", "ZnVy" }, - { "gab", "Z2Fi" }, - { "gad", "Z2Fk" }, - { "gag", "Z2Fn" }, - { "gal", "Z2Fs" }, - { "gam", "Z2Ft" }, - { "GAO", "R0FP" }, - { "gap", "Z2Fw" }, - { "gar", "Z2Fy" }, - { "gas", "Z2Fz" }, - { "gay", "Z2F5" }, - { "gee", "Z2Vl" }, - { "gel", "Z2Vs" }, - { "gem", "Z2Vt" }, - { "get", "Z2V0" }, - { "gig", "Z2ln" }, - { "Gil", "R2ls" }, - { "gin", "Z2lu" }, - { "GMT", "R01U" }, - { "GNP", "R05Q" }, - { "gnu", "Z251" }, - { "Goa", "R29h" }, - { "gob", "Z29i" }, - { "god", "Z29k" }, - { "gog", "Z29n" }, - { "GOP", "R09Q" }, - { "got", "Z290" }, - { "GPO", "R1BP" }, - { "g's", "Zydz" }, - { "GSA", "R1NB" }, - { "gum", "Z3Vt" }, - { "gun", "Z3Vu" }, - { "Gus", "R3Vz" }, - { "gut", "Z3V0" }, - { "guy", "Z3V5" }, - { "gym", "Z3lt" }, - { "gyp", "Z3lw" }, - { "had", "aGFk" }, - { "Hal", "SGFs" }, - { "ham", "aGFt" }, - { "Han", "SGFu" }, - { "hap", "aGFw" }, - { "hat", "aGF0" }, - { "haw", "aGF3" }, - { "hay", "aGF5" }, - { "hem", "aGVt" }, - { "hen", "aGVu" }, - { "her", "aGVy" }, - { "hew", "aGV3" }, - { "hex", "aGV4" }, - { "hey", "aGV5" }, - { "hid", "aGlk" }, - { "him", "aGlt" }, - { "hip", "aGlw" }, - { "his", "aGlz" }, - { "hit", "aGl0" }, - { "hob", "aG9i" }, - { "hoc", "aG9j" }, - { "hoe", "aG9l" }, - { "hog", "aG9n" }, - { "hoi", "aG9p" }, - { "Hom", "SG9t" }, - { "hop", "aG9w" }, - { "hot", "aG90" }, - { "how", "aG93" }, - { "hoy", "aG95" }, - { "h's", "aCdz" }, - { "hub", "aHVi" }, - { "hue", "aHVl" }, - { "hug", "aHVn" }, - { "huh", "aHVo" }, - { "hum", "aHVt" }, - { "Hun", "SHVu" }, - { "hut", "aHV0" }, - { "Ian", "SWFu" }, - { "IBM", "SUJN" }, - { "Ibn", "SWJu" }, - { "ICC", "SUND" }, - { "ice", "aWNl" }, - { "icy", "aWN5" }, - { "I'd", "SSdk" }, - { "Ida", "SWRh" }, - { "i.e", "aS5l" }, - { "iii", "aWlp" }, - { "Ike", "SWtl" }, - { "ill", "aWxs" }, - { "I'm", "SSdt" }, - { "imp", "aW1w" }, - { "Inc", "SW5j" }, - { "ink", "aW5r" }, - { "inn", "aW5u" }, - { "ion", "aW9u" }, - { "Ira", "SXJh" }, - { "ire", "aXJl" }, - { "irk", "aXJr" }, - { "IRS", "SVJT" }, - { "i's", "aSdz" }, - { "Ito", "SXRv" }, - { "ITT", "SVRU" }, - { "ivy", "aXZ5" }, - { "jab", "amFi" }, - { "jag", "amFn" }, - { "jam", "amFt" }, - { "Jan", "SmFu" }, - { "jar", "amFy" }, - { "jaw", "amF3" }, - { "jay", "amF5" }, - { "Jed", "SmVk" }, - { "jet", "amV0" }, - { "Jew", "SmV3" }, - { "jig", "amln" }, - { "Jim", "Smlt" }, - { "job", "am9i" }, - { "Joe", "Sm9l" }, - { "jog", "am9n" }, - { "Jon", "Sm9u" }, - { "jot", "am90" }, - { "joy", "am95" }, - { "j's", "aidz" }, - { "jug", "anVn" }, - { "jut", "anV0" }, - { "Kay", "S2F5" }, - { "keg", "a2Vn" }, - { "ken", "a2Vu" }, - { "key", "a2V5" }, - { "kid", "a2lk" }, - { "Kim", "S2lt" }, - { "kin", "a2lu" }, - { "kit", "a2l0" }, - { "k's", "aydz" }, - { "lab", "bGFi" }, - { "lac", "bGFj" }, - { "lad", "bGFk" }, - { "lag", "bGFn" }, - { "lam", "bGFt" }, - { "Lao", "TGFv" }, - { "lap", "bGFw" }, - { "law", "bGF3" }, - { "lax", "bGF4" }, - { "lay", "bGF5" }, - { "lea", "bGVh" }, - { "led", "bGVk" }, - { "lee", "bGVl" }, - { "leg", "bGVn" }, - { "Len", "TGVu" }, - { "Leo", "TGVv" }, - { "let", "bGV0" }, - { "Lev", "TGV2" }, - { "Lew", "TGV3" }, - { "lew", "bGV3" }, - { "lid", "bGlk" }, - { "lie", "bGll" }, - { "lim", "bGlt" }, - { "Lin", "TGlu" }, - { "lip", "bGlw" }, - { "lit", "bGl0" }, - { "Liz", "TGl6" }, - { "lob", "bG9i" }, - { "log", "bG9n" }, - { "lop", "bG9w" }, - { "Los", "TG9z" }, - { "lot", "bG90" }, - { "Lou", "TG91" }, - { "low", "bG93" }, - { "loy", "bG95" }, - { "l's", "bCdz" }, - { "LSI", "TFNJ" }, - { "Ltd", "THRk" }, - { "LTV", "TFRW" }, - { "lug", "bHVn" }, - { "lux", "bHV4" }, - { "lye", "bHll" }, - { "Mac", "TWFj" }, - { "mad", "bWFk" }, - { "Mae", "TWFl" }, - { "man", "bWFu" }, - { "Mao", "TWFv" }, - { "map", "bWFw" }, - { "mar", "bWFy" }, - { "mat", "bWF0" }, - { "maw", "bWF3" }, - { "Max", "TWF4" }, - { "max", "bWF4" }, - { "may", "bWF5" }, - { "MBA", "TUJB" }, - { "Meg", "TWVn" }, - { "Mel", "TWVs" }, - { "men", "bWVu" }, - { "met", "bWV0" }, - { "mew", "bWV3" }, - { "mid", "bWlk" }, - { "mig", "bWln" }, - { "min", "bWlu" }, - { "MIT", "TUlU" }, - { "mix", "bWl4" }, - { "mob", "bW9i" }, - { "Moe", "TW9l" }, - { "moo", "bW9v" }, - { "mop", "bW9w" }, - { "mot", "bW90" }, - { "mow", "bW93" }, - { "MPH", "TVBI" }, - { "Mrs", "TXJz" }, - { "m's", "bSdz" }, - { "mud", "bXVk" }, - { "mug", "bXVn" }, - { "mum", "bXVt" }, - { "nab", "bmFi" }, - { "nag", "bmFn" }, - { "Nan", "TmFu" }, - { "nap", "bmFw" }, - { "Nat", "TmF0" }, - { "nay", "bmF5" }, - { "NBC", "TkJD" }, - { "NBS", "TkJT" }, - { "NCO", "TkNP" }, - { "NCR", "TkNS" }, - { "Ned", "TmVk" }, - { "nee", "bmVl" }, - { "net", "bmV0" }, - { "new", "bmV3" }, - { "nib", "bmli" }, - { "NIH", "TklI" }, - { "nil", "bmls" }, - { "nip", "bmlw" }, - { "nit", "bml0" }, - { "NNE", "Tk5F" }, - { "NNW", "Tk5X" }, - { "nob", "bm9i" }, - { "nod", "bm9k" }, - { "non", "bm9u" }, - { "nor", "bm9y" }, - { "not", "bm90" }, - { "Nov", "Tm92" }, - { "now", "bm93" }, - { "NRC", "TlJD" }, - { "n's", "bidz" }, - { "NSF", "TlNG" }, - { "nun", "bnVu" }, - { "nut", "bnV0" }, - { "NYC", "TllD" }, - { "NYU", "TllV" }, - { "oaf", "b2Fm" }, - { "oak", "b2Fr" }, - { "oar", "b2Fy" }, - { "oat", "b2F0" }, - { "Oct", "T2N0" }, - { "odd", "b2Rk" }, - { "ode", "b2Rl" }, - { "off", "b2Zm" }, - { "oft", "b2Z0" }, - { "ohm", "b2ht" }, - { "oil", "b2ls" }, - { "old", "b2xk" }, - { "one", "b25l" }, - { "opt", "b3B0" }, - { "orb", "b3Ji" }, - { "ore", "b3Jl" }, - { "Orr", "T3Jy" }, - { "o's", "bydz" }, - { "Ott", "T3R0" }, - { "our", "b3Vy" }, - { "out", "b3V0" }, - { "ova", "b3Zh" }, - { "owe", "b3dl" }, - { "owl", "b3ds" }, - { "own", "b3du" }, - { "pad", "cGFk" }, - { "pal", "cGFs" }, - { "Pam", "UGFt" }, - { "pan", "cGFu" }, - { "pap", "cGFw" }, - { "par", "cGFy" }, - { "pat", "cGF0" }, - { "paw", "cGF3" }, - { "pax", "cGF4" }, - { "pay", "cGF5" }, - { "Paz", "UGF6" }, - { "PBS", "UEJT" }, - { "PDP", "UERQ" }, - { "pea", "cGVh" }, - { "pee", "cGVl" }, - { "peg", "cGVn" }, - { "pen", "cGVu" }, - { "pep", "cGVw" }, - { "per", "cGVy" }, - { "pet", "cGV0" }, - { "pew", "cGV3" }, - { "PhD", "UGhE" }, - { "phi", "cGhp" }, - { "pie", "cGll" }, - { "pig", "cGln" }, - { "pin", "cGlu" }, - { "pip", "cGlw" }, - { "pit", "cGl0" }, - { "ply", "cGx5" }, - { "pod", "cG9k" }, - { "Poe", "UG9l" }, - { "poi", "cG9p" }, - { "pol", "cG9s" }, - { "pop", "cG9w" }, - { "pot", "cG90" }, - { "pow", "cG93" }, - { "ppm", "cHBt" }, - { "pro", "cHJv" }, - { "pry", "cHJ5" }, - { "p's", "cCdz" }, - { "psi", "cHNp" }, - { "PTA", "UFRB" }, - { "pub", "cHVi" }, - { "PUC", "UFVD" }, - { "pug", "cHVn" }, - { "pun", "cHVu" }, - { "pup", "cHVw" }, - { "pus", "cHVz" }, - { "put", "cHV0" }, - { "PVC", "UFZD" }, - { "QED", "UUVE" }, - { "q's", "cSdz" }, - { "qua", "cXVh" }, - { "quo", "cXVv" }, - { "Rae", "UmFl" }, - { "rag", "cmFn" }, - { "raj", "cmFq" }, - { "ram", "cmFt" }, - { "ran", "cmFu" }, - { "rap", "cmFw" }, - { "rat", "cmF0" }, - { "raw", "cmF3" }, - { "ray", "cmF5" }, - { "RCA", "UkNB" }, - { "R&D", "UiZE" }, - { "reb", "cmVi" }, - { "red", "cmVk" }, - { "rep", "cmVw" }, - { "ret", "cmV0" }, - { "rev", "cmV2" }, - { "Rex", "UmV4" }, - { "rho", "cmhv" }, - { "rib", "cmli" }, - { "rid", "cmlk" }, - { "rig", "cmln" }, - { "rim", "cmlt" }, - { "Rio", "Umlv" }, - { "rip", "cmlw" }, - { "RNA", "Uk5B" }, - { "rob", "cm9i" }, - { "rod", "cm9k" }, - { "roe", "cm9l" }, - { "Ron", "Um9u" }, - { "rot", "cm90" }, - { "row", "cm93" }, - { "Roy", "Um95" }, - { "RPM", "UlBN" }, - { "r's", "cidz" }, - { "rub", "cnVi" }, - { "rue", "cnVl" }, - { "rug", "cnVn" }, - { "rum", "cnVt" }, - { "run", "cnVu" }, - { "rut", "cnV0" }, - { "rye", "cnll" }, - { "sac", "c2Fj" }, - { "sad", "c2Fk" }, - { "sag", "c2Fn" }, - { "Sal", "U2Fs" }, - { "Sam", "U2Ft" }, - { "San", "U2Fu" }, - { "Sao", "U2Fv" }, - { "sap", "c2Fw" }, - { "sat", "c2F0" }, - { "saw", "c2F3" }, - { "sax", "c2F4" }, - { "say", "c2F5" }, - { "Sci", "U2Np" }, - { "SCM", "U0NN" }, - { "sea", "c2Vh" }, - { "sec", "c2Vj" }, - { "see", "c2Vl" }, - { "sen", "c2Vu" }, - { "seq", "c2Vx" }, - { "set", "c2V0" }, - { "sew", "c2V3" }, - { "sex", "c2V4" }, - { "she", "c2hl" }, - { "Shu", "U2h1" }, - { "shy", "c2h5" }, - { "sib", "c2li" }, - { "sic", "c2lj" }, - { "sin", "c2lu" }, - { "sip", "c2lw" }, - { "sir", "c2ly" }, - { "sis", "c2lz" }, - { "sit", "c2l0" }, - { "six", "c2l4" }, - { "ski", "c2tp" }, - { "sky", "c2t5" }, - { "sly", "c2x5" }, - { "sob", "c29i" }, - { "Soc", "U29j" }, - { "sod", "c29k" }, - { "Sol", "U29s" }, - { "son", "c29u" }, - { "sop", "c29w" }, - { "sou", "c291" }, - { "sow", "c293" }, - { "soy", "c295" }, - { "spa", "c3Bh" }, - { "spy", "c3B5" }, - { "Sri", "U3Jp" }, - { "s's", "cydz" }, - { "SSE", "U1NF" }, - { "SST", "U1NU" }, - { "SSW", "U1NX" }, - { "Stu", "U3R1" }, - { "sub", "c3Vi" }, - { "sud", "c3Vk" }, - { "sue", "c3Vl" }, - { "sum", "c3Vt" }, - { "sun", "c3Vu" }, - { "sup", "c3Vw" }, - { "Sus", "U3Vz" }, - { "tab", "dGFi" }, - { "tad", "dGFk" }, - { "tag", "dGFn" }, - { "tam", "dGFt" }, - { "tan", "dGFu" }, - { "tao", "dGFv" }, - { "tap", "dGFw" }, - { "tar", "dGFy" }, - { "tat", "dGF0" }, - { "tau", "dGF1" }, - { "tax", "dGF4" }, - { "tea", "dGVh" }, - { "Ted", "VGVk" }, - { "ted", "dGVk" }, - { "tee", "dGVl" }, - { "Tel", "VGVs" }, - { "ten", "dGVu" }, - { "the", "dGhl" }, - { "thy", "dGh5" }, - { "tic", "dGlj" }, - { "tid", "dGlk" }, - { "tie", "dGll" }, - { "til", "dGls" }, - { "Tim", "VGlt" }, - { "tin", "dGlu" }, - { "tip", "dGlw" }, - { "tit", "dGl0" }, - { "TNT", "VE5U" }, - { "toe", "dG9l" }, - { "tog", "dG9n" }, - { "Tom", "VG9t" }, - { "ton", "dG9u" }, - { "too", "dG9v" }, - { "top", "dG9w" }, - { "tor", "dG9y" }, - { "tot", "dG90" }, - { "tow", "dG93" }, - { "toy", "dG95" }, - { "TRW", "VFJX" }, - { "try", "dHJ5" }, - { "t's", "dCdz" }, - { "TTL", "VFRM" }, - { "TTY", "VFRZ" }, - { "tub", "dHVi" }, - { "tug", "dHVn" }, - { "tum", "dHVt" }, - { "tun", "dHVu" }, - { "TVA", "VFZB" }, - { "TWA", "VFdB" }, - { "two", "dHdv" }, - { "TWX", "VFdY" }, - { "ugh", "dWdo" }, - { "UHF", "VUhG" }, - { "Uri", "VXJp" }, - { "urn", "dXJu" }, - { "U.S", "VS5T" }, - { "u's", "dSdz" }, - { "USA", "VVNB" }, - { "USC", "VVND" }, - { "use", "dXNl" }, - { "USN", "VVNO" }, - { "van", "dmFu" }, - { "vat", "dmF0" }, - { "vee", "dmVl" }, - { "vet", "dmV0" }, - { "vex", "dmV4" }, - { "VHF", "VkhG" }, - { "via", "dmlh" }, - { "vie", "dmll" }, - { "vii", "dmlp" }, - { "vis", "dmlz" }, - { "viz", "dml6" }, - { "von", "dm9u" }, - { "vow", "dm93" }, - { "v's", "didz" }, - { "WAC", "V0FD" }, - { "wad", "d2Fk" }, - { "wag", "d2Fn" }, - { "wah", "d2Fo" }, - { "wan", "d2Fu" }, - { "war", "d2Fy" }, - { "was", "d2Fz" }, - { "wax", "d2F4" }, - { "way", "d2F5" }, - { "web", "d2Vi" }, - { "wed", "d2Vk" }, - { "wee", "d2Vl" }, - { "Wei", "V2Vp" }, - { "wet", "d2V0" }, - { "who", "d2hv" }, - { "why", "d2h5" }, - { "wig", "d2ln" }, - { "win", "d2lu" }, - { "wit", "d2l0" }, - { "woe", "d29l" }, - { "wok", "d29r" }, - { "won", "d29u" }, - { "woo", "d29v" }, - { "wop", "d29w" }, - { "wow", "d293" }, - { "wry", "d3J5" }, - { "w's", "dydz" }, - { "x's", "eCdz" }, - { "yah", "eWFo" }, - { "yak", "eWFr" }, - { "yam", "eWFt" }, - { "yap", "eWFw" }, - { "yaw", "eWF3" }, - { "yea", "eWVh" }, - { "yen", "eWVu" }, - { "yet", "eWV0" }, - { "yin", "eWlu" }, - { "yip", "eWlw" }, - { "yon", "eW9u" }, - { "you", "eW91" }, - { "yow", "eW93" }, - { "y's", "eSdz" }, - { "yuh", "eXVo" }, - { "zag", "emFn" }, - { "Zan", "WmFu" }, - { "zap", "emFw" }, - { "Zen", "WmVu" }, - { "zig", "emln" }, - { "zip", "emlw" }, - { "Zoe", "Wm9l" }, - { "zoo", "em9v" }, - { "z's", "eidz" }, - /* the false rumors file */ - { "\"So when I die, the first thing I will see in heaven is a score list?\"", - "IlNvIHdoZW4gSSBkaWUsIHRoZSBmaXJzdCB0aGluZyBJIHdpbGwgc2VlIGluIGhlYXZlbiBpcyBhIHNjb3JlIGxpc3Q/Ig==" }, - { "1st Law of Hacking: leaving is much more difficult than entering.", - "MXN0IExhdyBvZiBIYWNraW5nOiBsZWF2aW5nIGlzIG11Y2ggbW9yZSBkaWZmaWN1bHQgdGhhbiBlbnRlcmluZy4=" }, - { "2nd Law of Hacking: first in, first out.", - "Mm5kIExhdyBvZiBIYWNraW5nOiBmaXJzdCBpbiwgZmlyc3Qgb3V0Lg==" }, - { "3rd Law of Hacking: the last blow counts most.", - "M3JkIExhdyBvZiBIYWNraW5nOiB0aGUgbGFzdCBibG93IGNvdW50cyBtb3N0Lg==" }, - { "4th Law of Hacking: you will find the exit at the entrance.", - "NHRoIExhdyBvZiBIYWNraW5nOiB5b3Ugd2lsbCBmaW5kIHRoZSBleGl0IGF0IHRoZSBlbnRyYW5jZS4=" }, - { "A chameleon imitating a mail daemon often delivers scrolls of fire.", - "QSBjaGFtZWxlb24gaW1pdGF0aW5nIGEgbWFpbCBkYWVtb24gb2Z0ZW4gZGVsaXZlcnMgc2Nyb2xscyBvZiBmaXJlLg==" }, - { "A cockatrice corpse is guaranteed to be untainted!", - "QSBjb2NrYXRyaWNlIGNvcnBzZSBpcyBndWFyYW50ZWVkIHRvIGJlIHVudGFpbnRlZCE=" }, - { "A dead cockatrice is just a dead lizard.", - "QSBkZWFkIGNvY2thdHJpY2UgaXMganVzdCBhIGRlYWQgbGl6YXJkLg==" }, - { "A dragon is just a snake that ate a scroll of fire.", - "QSBkcmFnb24gaXMganVzdCBhIHNuYWtlIHRoYXQgYXRlIGEgc2Nyb2xsIG9mIGZpcmUu" }, - { "A fading corridor enlightens your insight.", - "QSBmYWRpbmcgY29ycmlkb3IgZW5saWdodGVucyB5b3VyIGluc2lnaHQu" }, - { "A glowing potion is too hot to drink.", - "QSBnbG93aW5nIHBvdGlvbiBpcyB0b28gaG90IHRvIGRyaW5rLg==" }, - { "A good amulet may protect you against guards.", - "QSBnb29kIGFtdWxldCBtYXkgcHJvdGVjdCB5b3UgYWdhaW5zdCBndWFyZHMu" }, - { "A lizard corpse is a good thing to turn undead.", - "QSBsaXphcmQgY29ycHNlIGlzIGEgZ29vZCB0aGluZyB0byB0dXJuIHVuZGVhZC4=" }, - { "A long worm can be defined recursively. So how should you attack it?", - "QSBsb25nIHdvcm0gY2FuIGJlIGRlZmluZWQgcmVjdXJzaXZlbHkuIFNvIGhvdyBzaG91bGQgeW91IGF0dGFjayBpdD8=" }, - { "A monstrous mind is a toy forever.", - "QSBtb25zdHJvdXMgbWluZCBpcyBhIHRveSBmb3JldmVyLg==" }, - { "A nymph will be very pleased if you call her by her real name: Lorelei.", - "QSBueW1waCB3aWxsIGJlIHZlcnkgcGxlYXNlZCBpZiB5b3UgY2FsbCBoZXIgYnkgaGVyIHJlYWwgbmFtZTogTG9yZWxlaS4=" }, - { "A ring of dungeon master control is a great find.", - "QSByaW5nIG9mIGR1bmdlb24gbWFzdGVyIGNvbnRyb2wgaXMgYSBncmVhdCBmaW5kLg==" }, - { "A ring of extra ring finger is useless if not enchanted.", - "QSByaW5nIG9mIGV4dHJhIHJpbmcgZmluZ2VyIGlzIHVzZWxlc3MgaWYgbm90IGVuY2hhbnRlZC4=" }, - { "A rope may form a trail in a maze.", - "QSByb3BlIG1heSBmb3JtIGEgdHJhaWwgaW4gYSBtYXplLg==" }, - { "A staff may recharge if you drop it for awhile.", - "QSBzdGFmZiBtYXkgcmVjaGFyZ2UgaWYgeW91IGRyb3AgaXQgZm9yIGF3aGlsZS4=" }, - { "A visit to the Zoo is very educational; you meet interesting animals.", - "QSB2aXNpdCB0byB0aGUgWm9vIGlzIHZlcnkgZWR1Y2F0aW9uYWw7IHlvdSBtZWV0IGludGVyZXN0aW5nIGFuaW1hbHMu" }, - { "A wand of deaf is a more dangerous weapon than a wand of sheep.", - "QSB3YW5kIG9mIGRlYWYgaXMgYSBtb3JlIGRhbmdlcm91cyB3ZWFwb24gdGhhbiBhIHdhbmQgb2Ygc2hlZXAu" }, - { "A wand of vibration might bring the whole cave crashing about your ears.", - "QSB3YW5kIG9mIHZpYnJhdGlvbiBtaWdodCBicmluZyB0aGUgd2hvbGUgY2F2ZSBjcmFzaGluZyBhYm91dCB5b3VyIGVhcnMu" }, - { "A winner never quits. A quitter never wins.", - "QSB3aW5uZXIgbmV2ZXIgcXVpdHMuIEEgcXVpdHRlciBuZXZlciB3aW5zLg==" }, - { "A wish? Okay, make me a fortune cookie!", - "QSB3aXNoPyBPa2F5LCBtYWtlIG1lIGEgZm9ydHVuZSBjb29raWUh" }, - { "Afraid of mimics? Try to wear a ring of true seeing.", - "QWZyYWlkIG9mIG1pbWljcz8gVHJ5IHRvIHdlYXIgYSByaW5nIG9mIHRydWUgc2VlaW5nLg==" }, - { "All monsters are created evil, but some are more evil than others.", - "QWxsIG1vbnN0ZXJzIGFyZSBjcmVhdGVkIGV2aWwsIGJ1dCBzb21lIGFyZSBtb3JlIGV2aWwgdGhhbiBvdGhlcnMu" }, - { "Always attack a floating eye from behind!", - "QWx3YXlzIGF0dGFjayBhIGZsb2F0aW5nIGV5ZSBmcm9tIGJlaGluZCE=" }, - { "An elven cloak is always the height of fashion.", - "QW4gZWx2ZW4gY2xvYWsgaXMgYWx3YXlzIHRoZSBoZWlnaHQgb2YgZmFzaGlvbi4=" }, - { "Any small object that is accidentally dropped will hide under a larger object.", - "QW55IHNtYWxsIG9iamVjdCB0aGF0IGlzIGFjY2lkZW50YWxseSBkcm9wcGVkIHdpbGwgaGlkZSB1bmRlciBhIGxhcmdlciBvYmplY3Qu" }, - { "Balrogs do not appear above level 20.", - "QmFscm9ncyBkbyBub3QgYXBwZWFyIGFib3ZlIGxldmVsIDIwLg==" }, - { "Banana peels work especially well against Keystone Kops.", - "QmFuYW5hIHBlZWxzIHdvcmsgZXNwZWNpYWxseSB3ZWxsIGFnYWluc3QgS2V5c3RvbmUgS29wcy4=" }, - { "Be careful when eating bananas. Monsters might slip on the peels.", - "QmUgY2FyZWZ1bCB3aGVuIGVhdGluZyBiYW5hbmFzLiBNb25zdGVycyBtaWdodCBzbGlwIG9uIHRoZSBwZWVscy4=" }, - { "Better leave the dungeon; otherwise you might get hurt badly.", - "QmV0dGVyIGxlYXZlIHRoZSBkdW5nZW9uOyBvdGhlcndpc2UgeW91IG1pZ2h0IGdldCBodXJ0IGJhZGx5Lg==" }, - { "Beware of the potion of nitroglycerin -- it's not for the weak of heart.", - "QmV3YXJlIG9mIHRoZSBwb3Rpb24gb2Ygbml0cm9nbHljZXJpbiAtLSBpdCdzIG5vdCBmb3IgdGhlIHdlYWsgb2YgaGVhcnQu" }, - { "Beware: there's always a chance that your wand explodes as you try to zap it!", - "QmV3YXJlOiB0aGVyZSdzIGFsd2F5cyBhIGNoYW5jZSB0aGF0IHlvdXIgd2FuZCBleHBsb2RlcyBhcyB5b3UgdHJ5IHRvIHphcCBpdCE=" }, - { "Beyond the 23rd level lies a happy retirement in a room of your own.", - "QmV5b25kIHRoZSAyM3JkIGxldmVsIGxpZXMgYSBoYXBweSByZXRpcmVtZW50IGluIGEgcm9vbSBvZiB5b3VyIG93bi4=" }, - { "Changing your suit without dropping your sword? You must be kidding!", - "Q2hhbmdpbmcgeW91ciBzdWl0IHdpdGhvdXQgZHJvcHBpbmcgeW91ciBzd29yZD8gWW91IG11c3QgYmUga2lkZGluZyE=" }, - { "Cockatrices might turn themselves to stone faced with a mirror.", - "Q29ja2F0cmljZXMgbWlnaHQgdHVybiB0aGVtc2VsdmVzIHRvIHN0b25lIGZhY2VkIHdpdGggYSBtaXJyb3Iu" }, - { "Consumption of home-made food is strictly forbidden in this dungeon.", - "Q29uc3VtcHRpb24gb2YgaG9tZS1tYWRlIGZvb2QgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIGluIHRoaXMgZHVuZ2Vvbi4=" }, - { "Dark room? Your chance to develop your photographs!", - "RGFyayByb29tPyBZb3VyIGNoYW5jZSB0byBkZXZlbG9wIHlvdXIgcGhvdG9ncmFwaHMh" }, - { "Dark rooms are not *completely* dark: just wait and let your eyes adjust...", - "RGFyayByb29tcyBhcmUgbm90ICpjb21wbGV0ZWx5KiBkYXJrOiBqdXN0IHdhaXQgYW5kIGxldCB5b3VyIGV5ZXMgYWRqdXN0Li4u" }, - { "David London sez, \"Hey guys, *WIELD* a lizard corpse against a cockatrice!\"", - "RGF2aWQgTG9uZG9uIHNleiwgIkhleSBndXlzLCAqV0lFTEQqIGEgbGl6YXJkIGNvcnBzZSBhZ2FpbnN0IGEgY29ja2F0cmljZSEi" }, - { "Death is just life's way of telling you you've been fired.", - "RGVhdGggaXMganVzdCBsaWZlJ3Mgd2F5IG9mIHRlbGxpbmcgeW91IHlvdSd2ZSBiZWVuIGZpcmVkLg==" }, - { "Demi-gods don't need any help from the gods.", - "RGVtaS1nb2RzIGRvbid0IG5lZWQgYW55IGhlbHAgZnJvbSB0aGUgZ29kcy4=" }, - { "Demons *HATE* Priests and Priestesses.", - "RGVtb25zICpIQVRFKiBQcmllc3RzIGFuZCBQcmllc3Rlc3Nlcy4=" }, - { "Didn't you forget to pay?", - "RGlkbid0IHlvdSBmb3JnZXQgdG8gcGF5Pw==" }, - { "Didn't your mother tell you not to eat food off the floor?", - "RGlkbid0IHlvdXIgbW90aGVyIHRlbGwgeW91IG5vdCB0byBlYXQgZm9vZCBvZmYgdGhlIGZsb29yPw==" }, - { "Direct a direct hit on your direct opponent, directing in the right direction.", - "RGlyZWN0IGEgZGlyZWN0IGhpdCBvbiB5b3VyIGRpcmVjdCBvcHBvbmVudCwgZGlyZWN0aW5nIGluIHRoZSByaWdodCBkaXJlY3Rpb24u" }, - { "Do you want to make more money? Sure, we all do! Join the Fort Ludios guard!", - "RG8geW91IHdhbnQgdG8gbWFrZSBtb3JlIG1vbmV5PyBTdXJlLCB3ZSBhbGwgZG8hIEpvaW4gdGhlIEZvcnQgTHVkaW9zIGd1YXJkIQ==" }, - { "Don't eat too much: you might start hiccoughing!", - "RG9uJ3QgZWF0IHRvbyBtdWNoOiB5b3UgbWlnaHQgc3RhcnQgaGljY291Z2hpbmch" }, - { "Don't play hack at your work; your boss might hit you!", - "RG9uJ3QgcGxheSBoYWNrIGF0IHlvdXIgd29yazsgeW91ciBib3NzIG1pZ2h0IGhpdCB5b3Uh" }, - { "Don't tell a soul you found a secret door, otherwise it isn't a secret anymore.", - "RG9uJ3QgdGVsbCBhIHNvdWwgeW91IGZvdW5kIGEgc2VjcmV0IGRvb3IsIG90aGVyd2lzZSBpdCBpc24ndCBhIHNlY3JldCBhbnltb3JlLg==" }, - { "Drinking potions of booze may land you in jail if you are under 21.", - "RHJpbmtpbmcgcG90aW9ucyBvZiBib296ZSBtYXkgbGFuZCB5b3UgaW4gamFpbCBpZiB5b3UgYXJlIHVuZGVyIDIxLg==" }, - { "Drop your vanity and get rid of your jewels! Pickpockets about!", - "RHJvcCB5b3VyIHZhbml0eSBhbmQgZ2V0IHJpZCBvZiB5b3VyIGpld2VscyEgUGlja3BvY2tldHMgYWJvdXQh" }, - { "Eat 10 cloves of garlic and keep all humans at a two-square distance.", - "RWF0IDEwIGNsb3ZlcyBvZiBnYXJsaWMgYW5kIGtlZXAgYWxsIGh1bWFucyBhdCBhIHR3by1zcXVhcmUgZGlzdGFuY2Uu" }, - { "Eels hide under mud. Use a unicorn to clear the water and make them visible.", - "RWVscyBoaWRlIHVuZGVyIG11ZC4gVXNlIGEgdW5pY29ybiB0byBjbGVhciB0aGUgd2F0ZXIgYW5kIG1ha2UgdGhlbSB2aXNpYmxlLg==" }, - { "Engrave your wishes with a wand of wishing.", - "RW5ncmF2ZSB5b3VyIHdpc2hlcyB3aXRoIGEgd2FuZCBvZiB3aXNoaW5nLg==" }, - { "Eventually you will come to admire the swift elegance of a retreating nymph.", - "RXZlbnR1YWxseSB5b3Ugd2lsbCBjb21lIHRvIGFkbWlyZSB0aGUgc3dpZnQgZWxlZ2FuY2Ugb2YgYSByZXRyZWF0aW5nIG55bXBoLg==" }, - { "Ever heard hissing outside? I *knew* you hadn't!", - "RXZlciBoZWFyZCBoaXNzaW5nIG91dHNpZGU/IEkgKmtuZXcqIHlvdSBoYWRuJ3Qh" }, - { "Ever lifted a dragon corpse?", - "RXZlciBsaWZ0ZWQgYSBkcmFnb24gY29ycHNlPw==" }, - { "Ever seen a leocrotta dancing the tengu?", - "RXZlciBzZWVuIGEgbGVvY3JvdHRhIGRhbmNpbmcgdGhlIHRlbmd1Pw==" }, - { "Ever seen your weapon glow plaid?", - "RXZlciBzZWVuIHlvdXIgd2VhcG9uIGdsb3cgcGxhaWQ/" }, - { "Ever tamed a shopkeeper?", - "RXZlciB0YW1lZCBhIHNob3BrZWVwZXI/" }, - { "Ever tried digging through a Vault Guard?", - "RXZlciB0cmllZCBkaWdnaW5nIHRocm91Z2ggYSBWYXVsdCBHdWFyZD8=" }, - { "Ever tried enchanting a rope?", - "RXZlciB0cmllZCBlbmNoYW50aW5nIGEgcm9wZT8=" }, - { "Floating eyes can't stand Hawaiian shirts.", - "RmxvYXRpbmcgZXllcyBjYW4ndCBzdGFuZCBIYXdhaWlhbiBzaGlydHMu" }, - { "For any remedy there is a misery.", - "Rm9yIGFueSByZW1lZHkgdGhlcmUgaXMgYSBtaXNlcnku" }, - { "Giant bats turn into giant vampires.", - "R2lhbnQgYmF0cyB0dXJuIGludG8gZ2lhbnQgdmFtcGlyZXMu" }, - { "Good day for overcoming obstacles. Try a steeplechase.", - "R29vZCBkYXkgZm9yIG92ZXJjb21pbmcgb2JzdGFjbGVzLiBUcnkgYSBzdGVlcGxlY2hhc2Uu" }, - { "Half Moon tonight. (At least it's better than no Moon at all.)", - "SGFsZiBNb29uIHRvbmlnaHQuIChBdCBsZWFzdCBpdCdzIGJldHRlciB0aGFuIG5vIE1vb24gYXQgYWxsLik=" }, - { "Help! I'm being held prisoner in a fortune cookie factory!", - "SGVscCEgSSdtIGJlaW5nIGhlbGQgcHJpc29uZXIgaW4gYSBmb3J0dW5lIGNvb2tpZSBmYWN0b3J5IQ==" }, - { "Housecats have nine lives, kittens only one.", - "SG91c2VjYXRzIGhhdmUgbmluZSBsaXZlcywga2l0dGVucyBvbmx5IG9uZS4=" }, - { "How long can you tread water?", - "SG93IGxvbmcgY2FuIHlvdSB0cmVhZCB3YXRlcj8=" }, - { "Hungry? There is an abundance of food on the next level.", - "SHVuZ3J5PyBUaGVyZSBpcyBhbiBhYnVuZGFuY2Ugb2YgZm9vZCBvbiB0aGUgbmV4dCBsZXZlbC4=" }, - { "I guess you've never hit a mail daemon with the Amulet of Yendor...", - "SSBndWVzcyB5b3UndmUgbmV2ZXIgaGl0IGEgbWFpbCBkYWVtb24gd2l0aCB0aGUgQW11bGV0IG9mIFllbmRvci4uLg==" }, - { "If you are the shopkeeper, you can take things for free.", - "SWYgeW91IGFyZSB0aGUgc2hvcGtlZXBlciwgeW91IGNhbiB0YWtlIHRoaW5ncyBmb3IgZnJlZS4=" }, - { "If you can't learn to do it well, learn to enjoy doing it badly.", - "SWYgeW91IGNhbid0IGxlYXJuIHRvIGRvIGl0IHdlbGwsIGxlYXJuIHRvIGVuam95IGRvaW5nIGl0IGJhZGx5Lg==" }, - { "If you thought the Wizard was bad, just wait till you meet the Warlord!", - "SWYgeW91IHRob3VnaHQgdGhlIFdpemFyZCB3YXMgYmFkLCBqdXN0IHdhaXQgdGlsbCB5b3UgbWVldCB0aGUgV2FybG9yZCE=" }, - { "If you turn blind, don't expect your dog to be turned into a seeing-eye dog.", - "SWYgeW91IHR1cm4gYmxpbmQsIGRvbid0IGV4cGVjdCB5b3VyIGRvZyB0byBiZSB0dXJuZWQgaW50byBhIHNlZWluZy1leWUgZG9nLg==" }, - { "If you want to feel great, you must eat something real big.", - "SWYgeW91IHdhbnQgdG8gZmVlbCBncmVhdCwgeW91IG11c3QgZWF0IHNvbWV0aGluZyByZWFsIGJpZy4=" }, - { "If you want to float, you'd better eat a floating eye.", - "SWYgeW91IHdhbnQgdG8gZmxvYXQsIHlvdSdkIGJldHRlciBlYXQgYSBmbG9hdGluZyBleWUu" }, - { "If your ghost kills a player, it increases your score.", - "SWYgeW91ciBnaG9zdCBraWxscyBhIHBsYXllciwgaXQgaW5jcmVhc2VzIHlvdXIgc2NvcmUu" }, - { "Increase mindpower: Tame your own ghost!", - "SW5jcmVhc2UgbWluZHBvd2VyOiBUYW1lIHlvdXIgb3duIGdob3N0IQ==" }, - { "It furthers one to see the great man.", - "SXQgZnVydGhlcnMgb25lIHRvIHNlZSB0aGUgZ3JlYXQgbWFuLg==" }, - { "It's easy to overlook a monster in a wood.", - "SXQncyBlYXN5IHRvIG92ZXJsb29rIGEgbW9uc3RlciBpbiBhIHdvb2Qu" }, - { "Just below any trapdoor there may be another one. Just keep falling!", - "SnVzdCBiZWxvdyBhbnkgdHJhcGRvb3IgdGhlcmUgbWF5IGJlIGFub3RoZXIgb25lLiBKdXN0IGtlZXAgZmFsbGluZyE=" }, - { "Katanas are very sharp; watch you don't cut yourself.", - "S2F0YW5hcyBhcmUgdmVyeSBzaGFycDsgd2F0Y2ggeW91IGRvbid0IGN1dCB5b3Vyc2VsZi4=" }, - { "Keep a clear mind: quaff clear potions.", - "S2VlcCBhIGNsZWFyIG1pbmQ6IHF1YWZmIGNsZWFyIHBvdGlvbnMu" }, - { "Kicking the terminal doesn't hurt the monsters.", - "S2lja2luZyB0aGUgdGVybWluYWwgZG9lc24ndCBodXJ0IHRoZSBtb25zdGVycy4=" }, - { "Killer bees keep appearing till you kill their queen.", - "S2lsbGVyIGJlZXMga2VlcCBhcHBlYXJpbmcgdGlsbCB5b3Uga2lsbCB0aGVpciBxdWVlbi4=" }, - { "Killer bunnies can be tamed with carrots only.", - "S2lsbGVyIGJ1bm5pZXMgY2FuIGJlIHRhbWVkIHdpdGggY2Fycm90cyBvbmx5Lg==" }, - { "Latest news? Put `rec.games.roguelike.nethack' in your .newsrc!", - "TGF0ZXN0IG5ld3M/IFB1dCBgcmVjLmdhbWVzLnJvZ3VlbGlrZS5uZXRoYWNrJyBpbiB5b3VyIC5uZXdzcmMh" }, - { "Learn how to spell. Play NetHack!", - "TGVhcm4gaG93IHRvIHNwZWxsLiBQbGF5IE5ldEhhY2sh" }, - { "Leprechauns hide their gold in a secret room.", - "TGVwcmVjaGF1bnMgaGlkZSB0aGVpciBnb2xkIGluIGEgc2VjcmV0IHJvb20u" }, - { "Let your fingers do the walking on the yulkjhnb keys.", - "TGV0IHlvdXIgZmluZ2VycyBkbyB0aGUgd2Fsa2luZyBvbiB0aGUgeXVsa2pobmIga2V5cy4=" }, - { "Let's face it: this time you're not going to win.", - "TGV0J3MgZmFjZSBpdDogdGhpcyB0aW1lIHlvdSdyZSBub3QgZ29pbmcgdG8gd2luLg==" }, - { "Let's have a party, drink a lot of booze.", - "TGV0J3MgaGF2ZSBhIHBhcnR5LCBkcmluayBhIGxvdCBvZiBib296ZS4=" }, - { "Liquor sellers do not drink; they hate to see you twice.", - "TGlxdW9yIHNlbGxlcnMgZG8gbm90IGRyaW5rOyB0aGV5IGhhdGUgdG8gc2VlIHlvdSB0d2ljZS4=" }, - { "Lunar eclipse tonight. May as well quit now!", - "THVuYXIgZWNsaXBzZSB0b25pZ2h0LiBNYXkgYXMgd2VsbCBxdWl0IG5vdyE=" }, - { "Meeting your own ghost decreases your luck considerably!", - "TWVldGluZyB5b3VyIG93biBnaG9zdCBkZWNyZWFzZXMgeW91ciBsdWNrIGNvbnNpZGVyYWJseSE=" }, - { "Money to invest? Take it to the local branch of the Magic Memory Vault!", - "TW9uZXkgdG8gaW52ZXN0PyBUYWtlIGl0IHRvIHRoZSBsb2NhbCBicmFuY2ggb2YgdGhlIE1hZ2ljIE1lbW9yeSBWYXVsdCE=" }, - { "Monsters come from nowhere to hit you everywhere.", - "TW9uc3RlcnMgY29tZSBmcm9tIG5vd2hlcmUgdG8gaGl0IHlvdSBldmVyeXdoZXJlLg==" }, - { "Monsters sleep because you are boring, not because they ever get tired.", - "TW9uc3RlcnMgc2xlZXAgYmVjYXVzZSB5b3UgYXJlIGJvcmluZywgbm90IGJlY2F1c2UgdGhleSBldmVyIGdldCB0aXJlZC4=" }, - { "Most monsters prefer minced meat. That's why they are hitting you!", - "TW9zdCBtb25zdGVycyBwcmVmZXIgbWluY2VkIG1lYXQuIFRoYXQncyB3aHkgdGhleSBhcmUgaGl0dGluZyB5b3Uh" }, - { "Most of the bugs in NetHack are on the floor.", - "TW9zdCBvZiB0aGUgYnVncyBpbiBOZXRIYWNrIGFyZSBvbiB0aGUgZmxvb3Iu" }, - { "Much ado Nothing Happens.", - "TXVjaCBhZG8gTm90aGluZyBIYXBwZW5zLg==" }, - { "Multi-player NetHack is a myth.", - "TXVsdGktcGxheWVyIE5ldEhhY2sgaXMgYSBteXRoLg==" }, - { "NetHack is addictive. Too late, you're already hooked.", - "TmV0SGFjayBpcyBhZGRpY3RpdmUuIFRvbyBsYXRlLCB5b3UncmUgYWxyZWFkeSBob29rZWQu" }, - { "Never ask a shopkeeper for a price list.", - "TmV2ZXIgYXNrIGEgc2hvcGtlZXBlciBmb3IgYSBwcmljZSBsaXN0Lg==" }, - { "Never burn a tree, unless you like getting whacked with a +5 shovel.", - "TmV2ZXIgYnVybiBhIHRyZWUsIHVubGVzcyB5b3UgbGlrZSBnZXR0aW5nIHdoYWNrZWQgd2l0aCBhICs1IHNob3ZlbC4=" }, - { "Never eat with glowing hands!", - "TmV2ZXIgZWF0IHdpdGggZ2xvd2luZyBoYW5kcyE=" }, - { "Never mind the monsters hitting you: they just replace the charwomen.", - "TmV2ZXIgbWluZCB0aGUgbW9uc3RlcnMgaGl0dGluZyB5b3U6IHRoZXkganVzdCByZXBsYWNlIHRoZSBjaGFyd29tZW4u" }, - { "Never play leapfrog with a unicorn.", - "TmV2ZXIgcGxheSBsZWFwZnJvZyB3aXRoIGEgdW5pY29ybi4=" }, - { "Never step on a cursed engraving.", - "TmV2ZXIgc3RlcCBvbiBhIGN1cnNlZCBlbmdyYXZpbmcu" }, - { "Never swim with a camera: there's nothing to take pictures of.", - "TmV2ZXIgc3dpbSB3aXRoIGEgY2FtZXJhOiB0aGVyZSdzIG5vdGhpbmcgdG8gdGFrZSBwaWN0dXJlcyBvZi4=" }, - { "Never teach your pet rust monster to fetch.", - "TmV2ZXIgdGVhY2ggeW91ciBwZXQgcnVzdCBtb25zdGVyIHRvIGZldGNoLg==" }, - { "Never trust a random generator in magic fields.", - "TmV2ZXIgdHJ1c3QgYSByYW5kb20gZ2VuZXJhdG9yIGluIG1hZ2ljIGZpZWxkcy4=" }, - { "Never use a wand of death.", - "TmV2ZXIgdXNlIGEgd2FuZCBvZiBkZWF0aC4=" }, - { "No level contains two shops. The maze is no level. So...", - "Tm8gbGV2ZWwgY29udGFpbnMgdHdvIHNob3BzLiBUaGUgbWF6ZSBpcyBubyBsZXZlbC4gU28uLi4=" }, - { "No part of this fortune may be reproduced, stored in a retrieval system, ...", - "Tm8gcGFydCBvZiB0aGlzIGZvcnR1bmUgbWF5IGJlIHJlcHJvZHVjZWQsIHN0b3JlZCBpbiBhIHJldHJpZXZhbCBzeXN0ZW0sIC4uLg==" }, - { "Not all rumors are as misleading as this one.", - "Tm90IGFsbCBydW1vcnMgYXJlIGFzIG1pc2xlYWRpbmcgYXMgdGhpcyBvbmUu" }, - { "Nymphs and nurses like beautiful rings.", - "TnltcGhzIGFuZCBudXJzZXMgbGlrZSBiZWF1dGlmdWwgcmluZ3Mu" }, - { "Nymphs are blondes. Are you a gentleman?", - "TnltcGhzIGFyZSBibG9uZGVzLiBBcmUgeW91IGEgZ2VudGxlbWFuPw==" }, - { "Offering a unicorn a worthless piece of glass might prove to be fatal!", - "T2ZmZXJpbmcgYSB1bmljb3JuIGEgd29ydGhsZXNzIHBpZWNlIG9mIGdsYXNzIG1pZ2h0IHByb3ZlIHRvIGJlIGZhdGFsIQ==" }, - { "Old hackers never die: young ones do.", - "T2xkIGhhY2tlcnMgbmV2ZXIgZGllOiB5b3VuZyBvbmVzIGRvLg==" }, - { "One has to leave shops before closing time.", - "T25lIGhhcyB0byBsZWF2ZSBzaG9wcyBiZWZvcmUgY2xvc2luZyB0aW1lLg==" }, - { "One homunculus a day keeps the doctor away.", - "T25lIGhvbXVuY3VsdXMgYSBkYXkga2VlcHMgdGhlIGRvY3RvciBhd2F5Lg==" }, - { "One level further down somebody is getting killed, right now.", - "T25lIGxldmVsIGZ1cnRoZXIgZG93biBzb21lYm9keSBpcyBnZXR0aW5nIGtpbGxlZCwgcmlnaHQgbm93Lg==" }, - { "Only a wizard can use a magic whistle.", - "T25seSBhIHdpemFyZCBjYW4gdXNlIGEgbWFnaWMgd2hpc3RsZS4=" }, - { "Only adventurers of evil alignment think of killing their dog.", - "T25seSBhZHZlbnR1cmVycyBvZiBldmlsIGFsaWdubWVudCB0aGluayBvZiBraWxsaW5nIHRoZWlyIGRvZy4=" }, - { "Only chaotic evils kill sleeping monsters.", - "T25seSBjaGFvdGljIGV2aWxzIGtpbGwgc2xlZXBpbmcgbW9uc3RlcnMu" }, - { "Only real trappers escape traps.", - "T25seSByZWFsIHRyYXBwZXJzIGVzY2FwZSB0cmFwcy4=" }, - { "Only real wizards can write scrolls.", - "T25seSByZWFsIHdpemFyZHMgY2FuIHdyaXRlIHNjcm9sbHMu" }, - { "Operation OVERKILL has started now.", - "T3BlcmF0aW9uIE9WRVJLSUxMIGhhcyBzdGFydGVkIG5vdy4=" }, - { "PLEASE ignore previous rumor.", - "UExFQVNFIGlnbm9yZSBwcmV2aW91cyBydW1vci4=" }, - { "Polymorph into an ettin; meet your opponents face to face to face.", - "UG9seW1vcnBoIGludG8gYW4gZXR0aW47IG1lZXQgeW91ciBvcHBvbmVudHMgZmFjZSB0byBmYWNlIHRvIGZhY2Uu" }, - { "Praying will frighten demons.", - "UHJheWluZyB3aWxsIGZyaWdodGVuIGRlbW9ucy4=" }, - { "Row (3x) that boat gently down the stream, Charon (4x), death is but a dream.", - "Um93ICgzeCkgdGhhdCBib2F0IGdlbnRseSBkb3duIHRoZSBzdHJlYW0sIENoYXJvbiAoNHgpLCBkZWF0aCBpcyBidXQgYSBkcmVhbS4=" }, - { "Running is good for your legs.", - "UnVubmluZyBpcyBnb29kIGZvciB5b3VyIGxlZ3Mu" }, - { "Screw up your courage! You've screwed up everything else.", - "U2NyZXcgdXAgeW91ciBjb3VyYWdlISBZb3UndmUgc2NyZXdlZCB1cCBldmVyeXRoaW5nIGVsc2Uu" }, - { "Seepage? Leaky pipes? Rising damp? Summon the plumber!", - "U2VlcGFnZT8gTGVha3kgcGlwZXM/IFJpc2luZyBkYW1wPyBTdW1tb24gdGhlIHBsdW1iZXIh" }, - { "Segmentation fault (core dumped).", - "U2VnbWVudGF0aW9uIGZhdWx0IChjb3JlIGR1bXBlZCku" }, - { "Shopkeepers sometimes die from old age.", - "U2hvcGtlZXBlcnMgc29tZXRpbWVzIGRpZSBmcm9tIG9sZCBhZ2Uu" }, - { "Some mazes (especially small ones) have no solutions, says man 6 maze.", - "U29tZSBtYXplcyAoZXNwZWNpYWxseSBzbWFsbCBvbmVzKSBoYXZlIG5vIHNvbHV0aW9ucywgc2F5cyBtYW4gNiBtYXplLg==" }, - { "Some questions the Sphynx asks just *don't* have any answers.", - "U29tZSBxdWVzdGlvbnMgdGhlIFNwaHlueCBhc2tzIGp1c3QgKmRvbid0KiBoYXZlIGFueSBhbnN3ZXJzLg==" }, - { "Sometimes \"mu\" is the answer.", - "U29tZXRpbWVzICJtdSIgaXMgdGhlIGFuc3dlci4=" }, - { "Sorry, no fortune this time. Better luck next cookie!", - "U29ycnksIG5vIGZvcnR1bmUgdGhpcyB0aW1lLiBCZXR0ZXIgbHVjayBuZXh0IGNvb2tpZSE=" }, - { "Spare your scrolls of make-edible until it's really necessary!", - "U3BhcmUgeW91ciBzY3JvbGxzIG9mIG1ha2UtZWRpYmxlIHVudGlsIGl0J3MgcmVhbGx5IG5lY2Vzc2FyeSE=" }, - { "Suddenly, the dungeon will collapse...", - "U3VkZGVubHksIHRoZSBkdW5nZW9uIHdpbGwgY29sbGFwc2UuLi4=" }, - { "Taming a mail daemon may cause a system security violation.", - "VGFtaW5nIGEgbWFpbCBkYWVtb24gbWF5IGNhdXNlIGEgc3lzdGVtIHNlY3VyaXR5IHZpb2xhdGlvbi4=" }, - { "The crowd was so tough, the Stooges won't play the Dungeon anymore, nyuk nyuk.", - "VGhlIGNyb3dkIHdhcyBzbyB0b3VnaCwgdGhlIFN0b29nZXMgd29uJ3QgcGxheSB0aGUgRHVuZ2VvbiBhbnltb3JlLCBueXVrIG55dWsu" }, - { "The leprechauns hide their treasure in a small hidden room.", - "VGhlIGxlcHJlY2hhdW5zIGhpZGUgdGhlaXIgdHJlYXN1cmUgaW4gYSBzbWFsbCBoaWRkZW4gcm9vbS4=" }, - { "The longer the wand the better.", - "VGhlIGxvbmdlciB0aGUgd2FuZCB0aGUgYmV0dGVyLg==" }, - { "The magic word is \"XYZZY\".", - "VGhlIG1hZ2ljIHdvcmQgaXMgIlhZWlpZIi4=" }, - { "The meek shall inherit your bones files.", - "VGhlIG1lZWsgc2hhbGwgaW5oZXJpdCB5b3VyIGJvbmVzIGZpbGVzLg==" }, - { "The mines are dark and deep, and I have levels to go before I sleep.", - "VGhlIG1pbmVzIGFyZSBkYXJrIGFuZCBkZWVwLCBhbmQgSSBoYXZlIGxldmVscyB0byBnbyBiZWZvcmUgSSBzbGVlcC4=" }, - { "The use of dynamite is dangerous.", - "VGhlIHVzZSBvZiBkeW5hbWl0ZSBpcyBkYW5nZXJvdXMu" }, - { "There are no worms in the UNIX version.", - "VGhlcmUgYXJlIG5vIHdvcm1zIGluIHRoZSBVTklYIHZlcnNpb24u" }, - { "There is a trap on this level!", - "VGhlcmUgaXMgYSB0cmFwIG9uIHRoaXMgbGV2ZWwh" }, - { "They say that Demogorgon, Asmodeus, Orcus, Yeenoghu & Juiblex is no law firm.", - "VGhleSBzYXkgdGhhdCBEZW1vZ29yZ29uLCBBc21vZGV1cywgT3JjdXMsIFllZW5vZ2h1ICYgSnVpYmxleCBpcyBubyBsYXcgZmlybS4=" }, - { "They say that Geryon has an evil twin, beware!", - "VGhleSBzYXkgdGhhdCBHZXJ5b24gaGFzIGFuIGV2aWwgdHdpbiwgYmV3YXJlIQ==" }, - { "They say that Medusa would make a terrible pet.", - "VGhleSBzYXkgdGhhdCBNZWR1c2Egd291bGQgbWFrZSBhIHRlcnJpYmxlIHBldC4=" }, - { "They say that NetHack bugs are Seldon planned.", - "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGJ1Z3MgYXJlIFNlbGRvbiBwbGFubmVkLg==" }, - { "They say that NetHack comes in 256 flavors.", - "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGNvbWVzIGluIDI1NiBmbGF2b3JzLg==" }, - { "They say that NetHack is just a computer game.", - "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIGp1c3QgYSBjb21wdXRlciBnYW1lLg==" }, - { "They say that NetHack is more than just a computer game.", - "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIG1vcmUgdGhhbiBqdXN0IGEgY29tcHV0ZXIgZ2FtZS4=" }, - { "They say that NetHack is never what it used to be.", - "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIG5ldmVyIHdoYXQgaXQgdXNlZCB0byBiZS4=" }, - { "They say that a baby dragon is too small to hurt or help you.", - "VGhleSBzYXkgdGhhdCBhIGJhYnkgZHJhZ29uIGlzIHRvbyBzbWFsbCB0byBodXJ0IG9yIGhlbHAgeW91Lg==" }, - { "They say that a black pudding is simply a brown pudding gone bad.", - "VGhleSBzYXkgdGhhdCBhIGJsYWNrIHB1ZGRpbmcgaXMgc2ltcGx5IGEgYnJvd24gcHVkZGluZyBnb25lIGJhZC4=" }, - { "They say that a black sheep has 3 bags full of wool.", - "VGhleSBzYXkgdGhhdCBhIGJsYWNrIHNoZWVwIGhhcyAzIGJhZ3MgZnVsbCBvZiB3b29sLg==" }, - { "They say that a blank scroll is like a blank check.", - "VGhleSBzYXkgdGhhdCBhIGJsYW5rIHNjcm9sbCBpcyBsaWtlIGEgYmxhbmsgY2hlY2su" }, - { "They say that a cat named Morris has nine lives.", - "VGhleSBzYXkgdGhhdCBhIGNhdCBuYW1lZCBNb3JyaXMgaGFzIG5pbmUgbGl2ZXMu" }, - { "They say that a desperate shopper might pay any price in a shop.", - "VGhleSBzYXkgdGhhdCBhIGRlc3BlcmF0ZSBzaG9wcGVyIG1pZ2h0IHBheSBhbnkgcHJpY2UgaW4gYSBzaG9wLg==" }, - { "They say that a diamond dog is everybody's best friend.", - "VGhleSBzYXkgdGhhdCBhIGRpYW1vbmQgZG9nIGlzIGV2ZXJ5Ym9keSdzIGJlc3QgZnJpZW5kLg==" }, - { "They say that a dwarf lord can carry a pick-axe because his armor is light.", - "VGhleSBzYXkgdGhhdCBhIGR3YXJmIGxvcmQgY2FuIGNhcnJ5IGEgcGljay1heGUgYmVjYXVzZSBoaXMgYXJtb3IgaXMgbGlnaHQu" }, - { "They say that a floating eye can defeat Medusa.", - "VGhleSBzYXkgdGhhdCBhIGZsb2F0aW5nIGV5ZSBjYW4gZGVmZWF0IE1lZHVzYS4=" }, - { "They say that a fortune only has 1 line and you can't read between it.", - "VGhleSBzYXkgdGhhdCBhIGZvcnR1bmUgb25seSBoYXMgMSBsaW5lIGFuZCB5b3UgY2FuJ3QgcmVhZCBiZXR3ZWVuIGl0Lg==" }, - { "They say that a fortune only has 1 line, but you can read between it.", - "VGhleSBzYXkgdGhhdCBhIGZvcnR1bmUgb25seSBoYXMgMSBsaW5lLCBidXQgeW91IGNhbiByZWFkIGJldHdlZW4gaXQu" }, - { "They say that a fountain looks nothing like a regularly erupting geyser.", - "VGhleSBzYXkgdGhhdCBhIGZvdW50YWluIGxvb2tzIG5vdGhpbmcgbGlrZSBhIHJlZ3VsYXJseSBlcnVwdGluZyBnZXlzZXIu" }, - { "They say that a gold doubloon is worth more than its weight in gold.", - "VGhleSBzYXkgdGhhdCBhIGdvbGQgZG91Ymxvb24gaXMgd29ydGggbW9yZSB0aGFuIGl0cyB3ZWlnaHQgaW4gZ29sZC4=" }, - { "They say that a grid bug won't pay a shopkeeper for zapping you in a shop.", - "VGhleSBzYXkgdGhhdCBhIGdyaWQgYnVnIHdvbid0IHBheSBhIHNob3BrZWVwZXIgZm9yIHphcHBpbmcgeW91IGluIGEgc2hvcC4=" }, - { "They say that a gypsy could tell your fortune for a price.", - "VGhleSBzYXkgdGhhdCBhIGd5cHN5IGNvdWxkIHRlbGwgeW91ciBmb3J0dW5lIGZvciBhIHByaWNlLg==" }, - { "They say that a hacker named Alice once level teleported by using a mirror.", - "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBBbGljZSBvbmNlIGxldmVsIHRlbGVwb3J0ZWQgYnkgdXNpbmcgYSBtaXJyb3Iu" }, - { "They say that a hacker named David once slew a giant with a sling and a rock.", - "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBEYXZpZCBvbmNlIHNsZXcgYSBnaWFudCB3aXRoIGEgc2xpbmcgYW5kIGEgcm9jay4=" }, - { "They say that a hacker named Dorothy once rode a fog cloud to Oz.", - "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBEb3JvdGh5IG9uY2Ugcm9kZSBhIGZvZyBjbG91ZCB0byBPei4=" }, - { "They say that a hacker named Mary once lost a white sheep in the mazes.", - "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBNYXJ5IG9uY2UgbG9zdCBhIHdoaXRlIHNoZWVwIGluIHRoZSBtYXplcy4=" }, - { "They say that a helm of brilliance is not to be taken lightly.", - "VGhleSBzYXkgdGhhdCBhIGhlbG0gb2YgYnJpbGxpYW5jZSBpcyBub3QgdG8gYmUgdGFrZW4gbGlnaHRseS4=" }, - { "They say that a hot dog and a hell hound are the same thing.", - "VGhleSBzYXkgdGhhdCBhIGhvdCBkb2cgYW5kIGEgaGVsbCBob3VuZCBhcmUgdGhlIHNhbWUgdGhpbmcu" }, - { "They say that a lamp named Aladdin's Lamp contains a djinni with 3 wishes.", - "VGhleSBzYXkgdGhhdCBhIGxhbXAgbmFtZWQgQWxhZGRpbidzIExhbXAgY29udGFpbnMgYSBkamlubmkgd2l0aCAzIHdpc2hlcy4=" }, - { "They say that a large dog named Lassie will lead you to the amulet.", - "VGhleSBzYXkgdGhhdCBhIGxhcmdlIGRvZyBuYW1lZCBMYXNzaWUgd2lsbCBsZWFkIHlvdSB0byB0aGUgYW11bGV0Lg==" }, - { "They say that a long sword is not a light sword.", - "VGhleSBzYXkgdGhhdCBhIGxvbmcgc3dvcmQgaXMgbm90IGEgbGlnaHQgc3dvcmQu" }, - { "They say that a manes won't mince words with you.", - "VGhleSBzYXkgdGhhdCBhIG1hbmVzIHdvbid0IG1pbmNlIHdvcmRzIHdpdGggeW91Lg==" }, - { "They say that a mind is a terrible thing to waste.", - "VGhleSBzYXkgdGhhdCBhIG1pbmQgaXMgYSB0ZXJyaWJsZSB0aGluZyB0byB3YXN0ZS4=" }, - { "They say that a plain nymph will only wear a wire ring in one ear.", - "VGhleSBzYXkgdGhhdCBhIHBsYWluIG55bXBoIHdpbGwgb25seSB3ZWFyIGEgd2lyZSByaW5nIGluIG9uZSBlYXIu" }, - { "They say that a plumed hat could be a previously used crested helmet.", - "VGhleSBzYXkgdGhhdCBhIHBsdW1lZCBoYXQgY291bGQgYmUgYSBwcmV2aW91c2x5IHVzZWQgY3Jlc3RlZCBoZWxtZXQu" }, - { "They say that a potion of oil is difficult to grasp.", - "VGhleSBzYXkgdGhhdCBhIHBvdGlvbiBvZiBvaWwgaXMgZGlmZmljdWx0IHRvIGdyYXNwLg==" }, - { "They say that a potion of yogurt is a cancelled potion of sickness.", - "VGhleSBzYXkgdGhhdCBhIHBvdGlvbiBvZiB5b2d1cnQgaXMgYSBjYW5jZWxsZWQgcG90aW9uIG9mIHNpY2tuZXNzLg==" }, - { "They say that a purple worm is not a baby purple dragon.", - "VGhleSBzYXkgdGhhdCBhIHB1cnBsZSB3b3JtIGlzIG5vdCBhIGJhYnkgcHVycGxlIGRyYWdvbi4=" }, - { "They say that a quivering blob tastes different than a gelatinous cube.", - "VGhleSBzYXkgdGhhdCBhIHF1aXZlcmluZyBibG9iIHRhc3RlcyBkaWZmZXJlbnQgdGhhbiBhIGdlbGF0aW5vdXMgY3ViZS4=" }, - { "They say that a runed broadsword named Stormbringer attracts vortices.", - "VGhleSBzYXkgdGhhdCBhIHJ1bmVkIGJyb2Fkc3dvcmQgbmFtZWQgU3Rvcm1icmluZ2VyIGF0dHJhY3RzIHZvcnRpY2VzLg==" }, - { "They say that a scroll of summoning has other names.", - "VGhleSBzYXkgdGhhdCBhIHNjcm9sbCBvZiBzdW1tb25pbmcgaGFzIG90aGVyIG5hbWVzLg==" }, - { "They say that a shaman can bestow blessings but usually doesn't.", - "VGhleSBzYXkgdGhhdCBhIHNoYW1hbiBjYW4gYmVzdG93IGJsZXNzaW5ncyBidXQgdXN1YWxseSBkb2Vzbid0Lg==" }, - { "They say that a shaman will bless you for an eye of newt and wing of bat.", - "VGhleSBzYXkgdGhhdCBhIHNoYW1hbiB3aWxsIGJsZXNzIHlvdSBmb3IgYW4gZXllIG9mIG5ld3QgYW5kIHdpbmcgb2YgYmF0Lg==" }, - { "They say that a shimmering gold shield is not a polished silver shield.", - "VGhleSBzYXkgdGhhdCBhIHNoaW1tZXJpbmcgZ29sZCBzaGllbGQgaXMgbm90IGEgcG9saXNoZWQgc2lsdmVyIHNoaWVsZC4=" }, - { "They say that a spear will hit a neo-otyugh. (Do YOU know what that is?)", - "VGhleSBzYXkgdGhhdCBhIHNwZWFyIHdpbGwgaGl0IGEgbmVvLW90eXVnaC4gKERvIFlPVSBrbm93IHdoYXQgdGhhdCBpcz8p" }, - { "They say that a spotted dragon is the ultimate shape changer.", - "VGhleSBzYXkgdGhhdCBhIHNwb3R0ZWQgZHJhZ29uIGlzIHRoZSB1bHRpbWF0ZSBzaGFwZSBjaGFuZ2VyLg==" }, - { "They say that a stethoscope is no good if you can only hear your heartbeat.", - "VGhleSBzYXkgdGhhdCBhIHN0ZXRob3Njb3BlIGlzIG5vIGdvb2QgaWYgeW91IGNhbiBvbmx5IGhlYXIgeW91ciBoZWFydGJlYXQu" }, - { "They say that a succubus named Suzy will sometimes warn you of danger.", - "VGhleSBzYXkgdGhhdCBhIHN1Y2N1YnVzIG5hbWVkIFN1enkgd2lsbCBzb21ldGltZXMgd2FybiB5b3Ugb2YgZGFuZ2VyLg==" }, - { "They say that a wand of cancellation is not like a wand of polymorph.", - "VGhleSBzYXkgdGhhdCBhIHdhbmQgb2YgY2FuY2VsbGF0aW9uIGlzIG5vdCBsaWtlIGEgd2FuZCBvZiBwb2x5bW9ycGgu" }, - { "They say that a wood golem named Pinocchio would be easy to control.", - "VGhleSBzYXkgdGhhdCBhIHdvb2QgZ29sZW0gbmFtZWQgUGlub2NjaGlvIHdvdWxkIGJlIGVhc3kgdG8gY29udHJvbC4=" }, - { "They say that after killing a dragon it's time for a change of scenery.", - "VGhleSBzYXkgdGhhdCBhZnRlciBraWxsaW5nIGEgZHJhZ29uIGl0J3MgdGltZSBmb3IgYSBjaGFuZ2Ugb2Ygc2NlbmVyeS4=" }, - { "They say that an amulet of strangulation is worse than ring around the collar.", - "VGhleSBzYXkgdGhhdCBhbiBhbXVsZXQgb2Ygc3RyYW5ndWxhdGlvbiBpcyB3b3JzZSB0aGFuIHJpbmcgYXJvdW5kIHRoZSBjb2xsYXIu" }, - { "They say that an attic is the best place to hide your toys.", - "VGhleSBzYXkgdGhhdCBhbiBhdHRpYyBpcyB0aGUgYmVzdCBwbGFjZSB0byBoaWRlIHlvdXIgdG95cy4=" }, - { "They say that an axe named Cleaver once belonged to a hacker named Beaver.", - "VGhleSBzYXkgdGhhdCBhbiBheGUgbmFtZWQgQ2xlYXZlciBvbmNlIGJlbG9uZ2VkIHRvIGEgaGFja2VyIG5hbWVkIEJlYXZlci4=" }, - { "They say that an eye of newt and a wing of bat are double the trouble.", - "VGhleSBzYXkgdGhhdCBhbiBleWUgb2YgbmV3dCBhbmQgYSB3aW5nIG9mIGJhdCBhcmUgZG91YmxlIHRoZSB0cm91YmxlLg==" }, - { "They say that an incubus named Izzy sometimes makes women feel sensitive.", - "VGhleSBzYXkgdGhhdCBhbiBpbmN1YnVzIG5hbWVkIEl6enkgc29tZXRpbWVzIG1ha2VzIHdvbWVuIGZlZWwgc2Vuc2l0aXZlLg==" }, - { "They say that an opulent throne room is rarely a place to wish you'd be in.", - "VGhleSBzYXkgdGhhdCBhbiBvcHVsZW50IHRocm9uZSByb29tIGlzIHJhcmVseSBhIHBsYWNlIHRvIHdpc2ggeW91J2QgYmUgaW4u" }, - { "They say that an unlucky hacker once had a nose bleed at an altar and died.", - "VGhleSBzYXkgdGhhdCBhbiB1bmx1Y2t5IGhhY2tlciBvbmNlIGhhZCBhIG5vc2UgYmxlZWQgYXQgYW4gYWx0YXIgYW5kIGRpZWQu" }, - { "They say that and they say this but they never say never, never!", - "VGhleSBzYXkgdGhhdCBhbmQgdGhleSBzYXkgdGhpcyBidXQgdGhleSBuZXZlciBzYXkgbmV2ZXIsIG5ldmVyIQ==" }, - { "They say that any quantum mechanic knows that speed kills.", - "VGhleSBzYXkgdGhhdCBhbnkgcXVhbnR1bSBtZWNoYW5pYyBrbm93cyB0aGF0IHNwZWVkIGtpbGxzLg==" }, - { "They say that applying a unicorn horn means you've missed the point.", - "VGhleSBzYXkgdGhhdCBhcHBseWluZyBhIHVuaWNvcm4gaG9ybiBtZWFucyB5b3UndmUgbWlzc2VkIHRoZSBwb2ludC4=" }, - { "They say that blue stones are radioactive, beware.", - "VGhleSBzYXkgdGhhdCBibHVlIHN0b25lcyBhcmUgcmFkaW9hY3RpdmUsIGJld2FyZS4=" }, - { "They say that building a dungeon is a team effort.", - "VGhleSBzYXkgdGhhdCBidWlsZGluZyBhIGR1bmdlb24gaXMgYSB0ZWFtIGVmZm9ydC4=" }, - { "They say that chaotic characters never get a kick out of altars.", - "VGhleSBzYXkgdGhhdCBjaGFvdGljIGNoYXJhY3RlcnMgbmV2ZXIgZ2V0IGEga2ljayBvdXQgb2YgYWx0YXJzLg==" }, - { "They say that collapsing a dungeon often creates a panic.", - "VGhleSBzYXkgdGhhdCBjb2xsYXBzaW5nIGEgZHVuZ2VvbiBvZnRlbiBjcmVhdGVzIGEgcGFuaWMu" }, - { "They say that counting your eggs before they hatch shows that you care.", - "VGhleSBzYXkgdGhhdCBjb3VudGluZyB5b3VyIGVnZ3MgYmVmb3JlIHRoZXkgaGF0Y2ggc2hvd3MgdGhhdCB5b3UgY2FyZS4=" }, - { "They say that dipping a bag of tricks in a fountain won't make it an icebox.", - "VGhleSBzYXkgdGhhdCBkaXBwaW5nIGEgYmFnIG9mIHRyaWNrcyBpbiBhIGZvdW50YWluIHdvbid0IG1ha2UgaXQgYW4gaWNlYm94Lg==" }, - { "They say that dipping an eel and brown mold in hot water makes bouillabaisse.", - "VGhleSBzYXkgdGhhdCBkaXBwaW5nIGFuIGVlbCBhbmQgYnJvd24gbW9sZCBpbiBob3Qgd2F0ZXIgbWFrZXMgYm91aWxsYWJhaXNzZS4=" }, - { "They say that donating a doubloon is extremely pious charity.", - "VGhleSBzYXkgdGhhdCBkb25hdGluZyBhIGRvdWJsb29uIGlzIGV4dHJlbWVseSBwaW91cyBjaGFyaXR5Lg==" }, - { "They say that eating royal jelly attracts grizzly owlbears.", - "VGhleSBzYXkgdGhhdCBlYXRpbmcgcm95YWwgamVsbHkgYXR0cmFjdHMgZ3JpenpseSBvd2xiZWFycy4=" }, - { "They say that eggs, pancakes and juice are just a mundane breakfast.", - "VGhleSBzYXkgdGhhdCBlZ2dzLCBwYW5jYWtlcyBhbmQganVpY2UgYXJlIGp1c3QgYSBtdW5kYW5lIGJyZWFrZmFzdC4=" }, - { "They say that everyone knows why Medusa stands alone in the dark.", - "VGhleSBzYXkgdGhhdCBldmVyeW9uZSBrbm93cyB3aHkgTWVkdXNhIHN0YW5kcyBhbG9uZSBpbiB0aGUgZGFyay4=" }, - { "They say that everyone wanted rec.games.hack to undergo a name change.", - "VGhleSBzYXkgdGhhdCBldmVyeW9uZSB3YW50ZWQgcmVjLmdhbWVzLmhhY2sgdG8gdW5kZXJnbyBhIG5hbWUgY2hhbmdlLg==" }, - { "They say that finding a winning strategy is a deliberate move on your part.", - "VGhleSBzYXkgdGhhdCBmaW5kaW5nIGEgd2lubmluZyBzdHJhdGVneSBpcyBhIGRlbGliZXJhdGUgbW92ZSBvbiB5b3VyIHBhcnQu" }, - { "They say that finding worthless glass is worth something.", - "VGhleSBzYXkgdGhhdCBmaW5kaW5nIHdvcnRobGVzcyBnbGFzcyBpcyB3b3J0aCBzb21ldGhpbmcu" }, - { "They say that fortune cookies are food for thought.", - "VGhleSBzYXkgdGhhdCBmb3J0dW5lIGNvb2tpZXMgYXJlIGZvb2QgZm9yIHRob3VnaHQu" }, - { "They say that gold is only wasted on a pet dragon.", - "VGhleSBzYXkgdGhhdCBnb2xkIGlzIG9ubHkgd2FzdGVkIG9uIGEgcGV0IGRyYWdvbi4=" }, - { "They say that good things come to those that wait.", - "VGhleSBzYXkgdGhhdCBnb29kIHRoaW5ncyBjb21lIHRvIHRob3NlIHRoYXQgd2FpdC4=" }, - { "They say that greased objects will slip out of monsters' hands.", - "VGhleSBzYXkgdGhhdCBncmVhc2VkIG9iamVjdHMgd2lsbCBzbGlwIG91dCBvZiBtb25zdGVycycgaGFuZHMu" }, - { "They say that if you can't spell then you'll wish you had a spell book.", - "VGhleSBzYXkgdGhhdCBpZiB5b3UgY2FuJ3Qgc3BlbGwgdGhlbiB5b3UnbGwgd2lzaCB5b3UgaGFkIGEgc3BlbGwgYm9vay4=" }, - { "They say that if you live by the sword, you'll die by the sword.", - "VGhleSBzYXkgdGhhdCBpZiB5b3UgbGl2ZSBieSB0aGUgc3dvcmQsIHlvdSdsbCBkaWUgYnkgdGhlIHN3b3JkLg==" }, - { "They say that if you play like a monster you'll have a better game.", - "VGhleSBzYXkgdGhhdCBpZiB5b3UgcGxheSBsaWtlIGEgbW9uc3RlciB5b3UnbGwgaGF2ZSBhIGJldHRlciBnYW1lLg==" }, - { "They say that if you sleep with a demon you might awake with a headache.", - "VGhleSBzYXkgdGhhdCBpZiB5b3Ugc2xlZXAgd2l0aCBhIGRlbW9uIHlvdSBtaWdodCBhd2FrZSB3aXRoIGEgaGVhZGFjaGUu" }, - { "They say that if you step on a crack you could break your mother's back.", - "VGhleSBzYXkgdGhhdCBpZiB5b3Ugc3RlcCBvbiBhIGNyYWNrIHlvdSBjb3VsZCBicmVhayB5b3VyIG1vdGhlcidzIGJhY2su" }, - { "They say that if you're invisible you can still be heard!", - "VGhleSBzYXkgdGhhdCBpZiB5b3UncmUgaW52aXNpYmxlIHlvdSBjYW4gc3RpbGwgYmUgaGVhcmQh" }, - { "They say that if you're lucky you can feel the runes on a scroll.", - "VGhleSBzYXkgdGhhdCBpZiB5b3UncmUgbHVja3kgeW91IGNhbiBmZWVsIHRoZSBydW5lcyBvbiBhIHNjcm9sbC4=" }, - { "They say that in the big picture gold is only small change.", - "VGhleSBzYXkgdGhhdCBpbiB0aGUgYmlnIHBpY3R1cmUgZ29sZCBpcyBvbmx5IHNtYWxsIGNoYW5nZS4=" }, - { "They say that in the dungeon it's not what you know that really matters.", - "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiBpdCdzIG5vdCB3aGF0IHlvdSBrbm93IHRoYXQgcmVhbGx5IG1hdHRlcnMu" }, - { "They say that in the dungeon moon rocks are really dilithium crystals.", - "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiBtb29uIHJvY2tzIGFyZSByZWFsbHkgZGlsaXRoaXVtIGNyeXN0YWxzLg==" }, - { "They say that in the dungeon the boorish customer is never right.", - "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB0aGUgYm9vcmlzaCBjdXN0b21lciBpcyBuZXZlciByaWdodC4=" }, - { "They say that in the dungeon you don't need a watch to tell time.", - "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3UgZG9uJ3QgbmVlZCBhIHdhdGNoIHRvIHRlbGwgdGltZS4=" }, - { "They say that in the dungeon you need something old, new, burrowed and blue.", - "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3UgbmVlZCBzb21ldGhpbmcgb2xkLCBuZXcsIGJ1cnJvd2VkIGFuZCBibHVlLg==" }, - { "They say that in the dungeon you should always count your blessings.", - "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3Ugc2hvdWxkIGFsd2F5cyBjb3VudCB5b3VyIGJsZXNzaW5ncy4=" }, - { "They say that iron golem plate mail isn't worth wishing for.", - "VGhleSBzYXkgdGhhdCBpcm9uIGdvbGVtIHBsYXRlIG1haWwgaXNuJ3Qgd29ydGggd2lzaGluZyBmb3Iu" }, - { "They say that it takes four quarterstaffs to make one staff.", - "VGhleSBzYXkgdGhhdCBpdCB0YWtlcyBmb3VyIHF1YXJ0ZXJzdGFmZnMgdG8gbWFrZSBvbmUgc3RhZmYu" }, - { "They say that it's not over till the fat ladies sing.", - "VGhleSBzYXkgdGhhdCBpdCdzIG5vdCBvdmVyIHRpbGwgdGhlIGZhdCBsYWRpZXMgc2luZy4=" }, - { "They say that it's not over till the fat lady shouts `Off with its head'.", - "VGhleSBzYXkgdGhhdCBpdCdzIG5vdCBvdmVyIHRpbGwgdGhlIGZhdCBsYWR5IHNob3V0cyBgT2ZmIHdpdGggaXRzIGhlYWQnLg==" }, - { "They say that kicking a heavy statue is really a dumb move.", - "VGhleSBzYXkgdGhhdCBraWNraW5nIGEgaGVhdnkgc3RhdHVlIGlzIHJlYWxseSBhIGR1bWIgbW92ZS4=" }, - { "They say that kicking a valuable gem doesn't seem to make sense.", - "VGhleSBzYXkgdGhhdCBraWNraW5nIGEgdmFsdWFibGUgZ2VtIGRvZXNuJ3Qgc2VlbSB0byBtYWtlIHNlbnNlLg==" }, - { "They say that leprechauns know Latin and you should too.", - "VGhleSBzYXkgdGhhdCBsZXByZWNoYXVucyBrbm93IExhdGluIGFuZCB5b3Ugc2hvdWxkIHRvby4=" }, - { "They say that minotaurs get lost outside of the mazes.", - "VGhleSBzYXkgdGhhdCBtaW5vdGF1cnMgZ2V0IGxvc3Qgb3V0c2lkZSBvZiB0aGUgbWF6ZXMu" }, - { "They say that most trolls are born again.", - "VGhleSBzYXkgdGhhdCBtb3N0IHRyb2xscyBhcmUgYm9ybiBhZ2Fpbi4=" }, - { "They say that naming your cat Garfield will make you more attractive.", - "VGhleSBzYXkgdGhhdCBuYW1pbmcgeW91ciBjYXQgR2FyZmllbGQgd2lsbCBtYWtlIHlvdSBtb3JlIGF0dHJhY3RpdmUu" }, - { "They say that no one knows everything about everything in the dungeon.", - "VGhleSBzYXkgdGhhdCBubyBvbmUga25vd3MgZXZlcnl0aGluZyBhYm91dCBldmVyeXRoaW5nIGluIHRoZSBkdW5nZW9uLg==" }, - { "They say that no one plays NetHack just for the fun of it.", - "VGhleSBzYXkgdGhhdCBubyBvbmUgcGxheXMgTmV0SGFjayBqdXN0IGZvciB0aGUgZnVuIG9mIGl0Lg==" }, - { "They say that no one really subscribes to rec.games.roguelike.nethack.", - "VGhleSBzYXkgdGhhdCBubyBvbmUgcmVhbGx5IHN1YnNjcmliZXMgdG8gcmVjLmdhbWVzLnJvZ3VlbGlrZS5uZXRoYWNrLg==" }, - { "They say that no one will admit to starting a rumor.", - "VGhleSBzYXkgdGhhdCBubyBvbmUgd2lsbCBhZG1pdCB0byBzdGFydGluZyBhIHJ1bW9yLg==" }, - { "They say that nurses sometimes carry scalpels and never use them.", - "VGhleSBzYXkgdGhhdCBudXJzZXMgc29tZXRpbWVzIGNhcnJ5IHNjYWxwZWxzIGFuZCBuZXZlciB1c2UgdGhlbS4=" }, - { "They say that once you've met one wizard you've met them all.", - "VGhleSBzYXkgdGhhdCBvbmNlIHlvdSd2ZSBtZXQgb25lIHdpemFyZCB5b3UndmUgbWV0IHRoZW0gYWxsLg==" }, - { "They say that one troll is worth 10,000 newts.", - "VGhleSBzYXkgdGhhdCBvbmUgdHJvbGwgaXMgd29ydGggMTAsMDAwIG5ld3RzLg==" }, - { "They say that only David can find the zoo!", - "VGhleSBzYXkgdGhhdCBvbmx5IERhdmlkIGNhbiBmaW5kIHRoZSB6b28h" }, - { "They say that only angels play their harps for their pets.", - "VGhleSBzYXkgdGhhdCBvbmx5IGFuZ2VscyBwbGF5IHRoZWlyIGhhcnBzIGZvciB0aGVpciBwZXRzLg==" }, - { "They say that only big spenders carry gold.", - "VGhleSBzYXkgdGhhdCBvbmx5IGJpZyBzcGVuZGVycyBjYXJyeSBnb2xkLg==" }, - { "They say that orc shamans are healthy, wealthy and wise.", - "VGhleSBzYXkgdGhhdCBvcmMgc2hhbWFucyBhcmUgaGVhbHRoeSwgd2VhbHRoeSBhbmQgd2lzZS4=" }, - { "They say that playing NetHack is like walking into a death trap.", - "VGhleSBzYXkgdGhhdCBwbGF5aW5nIE5ldEhhY2sgaXMgbGlrZSB3YWxraW5nIGludG8gYSBkZWF0aCB0cmFwLg==" }, - { "They say that problem breathing is best treated by a proper diet.", - "VGhleSBzYXkgdGhhdCBwcm9ibGVtIGJyZWF0aGluZyBpcyBiZXN0IHRyZWF0ZWQgYnkgYSBwcm9wZXIgZGlldC4=" }, - { "They say that quaffing many potions of levitation can give you a headache.", - "VGhleSBzYXkgdGhhdCBxdWFmZmluZyBtYW55IHBvdGlvbnMgb2YgbGV2aXRhdGlvbiBjYW4gZ2l2ZSB5b3UgYSBoZWFkYWNoZS4=" }, - { "They say that queen bees get that way by eating royal jelly.", - "VGhleSBzYXkgdGhhdCBxdWVlbiBiZWVzIGdldCB0aGF0IHdheSBieSBlYXRpbmcgcm95YWwgamVsbHku" }, - { "They say that reading a scare monster scroll is the same as saying Elbereth.", - "VGhleSBzYXkgdGhhdCByZWFkaW5nIGEgc2NhcmUgbW9uc3RlciBzY3JvbGwgaXMgdGhlIHNhbWUgYXMgc2F5aW5nIEVsYmVyZXRoLg==" }, - { "They say that real hackers always are controlled.", - "VGhleSBzYXkgdGhhdCByZWFsIGhhY2tlcnMgYWx3YXlzIGFyZSBjb250cm9sbGVkLg==" }, - { "They say that real hackers never sleep.", - "VGhleSBzYXkgdGhhdCByZWFsIGhhY2tlcnMgbmV2ZXIgc2xlZXAu" }, - { "They say that shopkeepers are insured by Croesus himself!", - "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBhcmUgaW5zdXJlZCBieSBDcm9lc3VzIGhpbXNlbGYh" }, - { "They say that shopkeepers never carry more than 20 gold pieces, at night.", - "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBuZXZlciBjYXJyeSBtb3JlIHRoYW4gMjAgZ29sZCBwaWVjZXMsIGF0IG5pZ2h0Lg==" }, - { "They say that shopkeepers never sell blessed potions of invisibility.", - "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBuZXZlciBzZWxsIGJsZXNzZWQgcG90aW9ucyBvZiBpbnZpc2liaWxpdHku" }, - { "They say that soldiers wear kid gloves and silly helmets.", - "VGhleSBzYXkgdGhhdCBzb2xkaWVycyB3ZWFyIGtpZCBnbG92ZXMgYW5kIHNpbGx5IGhlbG1ldHMu" }, - { "They say that some Kops are on the take.", - "VGhleSBzYXkgdGhhdCBzb21lIEtvcHMgYXJlIG9uIHRoZSB0YWtlLg==" }, - { "They say that some guards' palms can be greased.", - "VGhleSBzYXkgdGhhdCBzb21lIGd1YXJkcycgcGFsbXMgY2FuIGJlIGdyZWFzZWQu" }, - { "They say that some monsters may kiss your boots to stop your drum playing.", - "VGhleSBzYXkgdGhhdCBzb21lIG1vbnN0ZXJzIG1heSBraXNzIHlvdXIgYm9vdHMgdG8gc3RvcCB5b3VyIGRydW0gcGxheWluZy4=" }, - { "They say that sometimes you can be the hit of the party when playing a horn.", - "VGhleSBzYXkgdGhhdCBzb21ldGltZXMgeW91IGNhbiBiZSB0aGUgaGl0IG9mIHRoZSBwYXJ0eSB3aGVuIHBsYXlpbmcgYSBob3JuLg==" }, - { "They say that the NetHack gods generally welcome your sacrifices.", - "VGhleSBzYXkgdGhhdCB0aGUgTmV0SGFjayBnb2RzIGdlbmVyYWxseSB3ZWxjb21lIHlvdXIgc2FjcmlmaWNlcy4=" }, - { "They say that the Three Rings are named Vilya, Nenya and Narya.", - "VGhleSBzYXkgdGhhdCB0aGUgVGhyZWUgUmluZ3MgYXJlIG5hbWVkIFZpbHlhLCBOZW55YSBhbmQgTmFyeWEu" }, - { "They say that the Wizard of Yendor has a death wish.", - "VGhleSBzYXkgdGhhdCB0aGUgV2l6YXJkIG9mIFllbmRvciBoYXMgYSBkZWF0aCB3aXNoLg==" }, - { "They say that the `hair of the dog' is sometimes an effective remedy.", - "VGhleSBzYXkgdGhhdCB0aGUgYGhhaXIgb2YgdGhlIGRvZycgaXMgc29tZXRpbWVzIGFuIGVmZmVjdGl2ZSByZW1lZHku" }, - { "They say that the best time to save your game is now before its too late.", - "VGhleSBzYXkgdGhhdCB0aGUgYmVzdCB0aW1lIHRvIHNhdmUgeW91ciBnYW1lIGlzIG5vdyBiZWZvcmUgaXRzIHRvbyBsYXRlLg==" }, - { "They say that the biggest obstacle in NetHack is your mind.", - "VGhleSBzYXkgdGhhdCB0aGUgYmlnZ2VzdCBvYnN0YWNsZSBpbiBOZXRIYWNrIGlzIHlvdXIgbWluZC4=" }, - { "They say that the gods are angry when they hit you with objects.", - "VGhleSBzYXkgdGhhdCB0aGUgZ29kcyBhcmUgYW5ncnkgd2hlbiB0aGV5IGhpdCB5b3Ugd2l0aCBvYmplY3RzLg==" }, - { "They say that the priesthood are specially favored by the gods.", - "VGhleSBzYXkgdGhhdCB0aGUgcHJpZXN0aG9vZCBhcmUgc3BlY2lhbGx5IGZhdm9yZWQgYnkgdGhlIGdvZHMu" }, - { "They say that the way to make a unicorn happy is to give it what it wants.", - "VGhleSBzYXkgdGhhdCB0aGUgd2F5IHRvIG1ha2UgYSB1bmljb3JuIGhhcHB5IGlzIHRvIGdpdmUgaXQgd2hhdCBpdCB3YW50cy4=" }, - { "They say that there are no black or white stones, only gray.", - "VGhleSBzYXkgdGhhdCB0aGVyZSBhcmUgbm8gYmxhY2sgb3Igd2hpdGUgc3RvbmVzLCBvbmx5IGdyYXku" }, - { "They say that there are no skeletons hence there are no skeleton keys.", - "VGhleSBzYXkgdGhhdCB0aGVyZSBhcmUgbm8gc2tlbGV0b25zIGhlbmNlIHRoZXJlIGFyZSBubyBza2VsZXRvbiBrZXlzLg==" }, - { "They say that there is a clever rogue in every hacker just dying to escape.", - "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBhIGNsZXZlciByb2d1ZSBpbiBldmVyeSBoYWNrZXIganVzdCBkeWluZyB0byBlc2NhcGUu" }, - { "They say that there is no such thing as free advice.", - "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBubyBzdWNoIHRoaW5nIGFzIGZyZWUgYWR2aWNlLg==" }, - { "They say that there is only one way to win at NetHack.", - "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBvbmx5IG9uZSB3YXkgdG8gd2luIGF0IE5ldEhhY2su" }, - { "They say that there once was a fearsome chaotic samurai named Luk No.", - "VGhleSBzYXkgdGhhdCB0aGVyZSBvbmNlIHdhcyBhIGZlYXJzb21lIGNoYW90aWMgc2FtdXJhaSBuYW1lZCBMdWsgTm8u" }, - { "They say that there was a time when cursed holy water wasn't water.", - "VGhleSBzYXkgdGhhdCB0aGVyZSB3YXMgYSB0aW1lIHdoZW4gY3Vyc2VkIGhvbHkgd2F0ZXIgd2Fzbid0IHdhdGVyLg==" }, - { "They say that there's no point in crying over a gray ooze.", - "VGhleSBzYXkgdGhhdCB0aGVyZSdzIG5vIHBvaW50IGluIGNyeWluZyBvdmVyIGEgZ3JheSBvb3plLg==" }, - { "They say that there's only hope left after you've opened Pandora's box.", - "VGhleSBzYXkgdGhhdCB0aGVyZSdzIG9ubHkgaG9wZSBsZWZ0IGFmdGVyIHlvdSd2ZSBvcGVuZWQgUGFuZG9yYSdzIGJveC4=" }, - { "They say that trapdoors should always be marked `Caution: Trap Door'.", - "VGhleSBzYXkgdGhhdCB0cmFwZG9vcnMgc2hvdWxkIGFsd2F5cyBiZSBtYXJrZWQgYENhdXRpb246IFRyYXAgRG9vcicu" }, - { "They say that using an amulet of change isn't a difficult operation.", - "VGhleSBzYXkgdGhhdCB1c2luZyBhbiBhbXVsZXQgb2YgY2hhbmdlIGlzbid0IGEgZGlmZmljdWx0IG9wZXJhdGlvbi4=" }, - { "They say that water walking boots are better if you are fast like Hermes.", - "VGhleSBzYXkgdGhhdCB3YXRlciB3YWxraW5nIGJvb3RzIGFyZSBiZXR0ZXIgaWYgeW91IGFyZSBmYXN0IGxpa2UgSGVybWVzLg==" }, - { "They say that when you wear a circular amulet you might resemble a troll.", - "VGhleSBzYXkgdGhhdCB3aGVuIHlvdSB3ZWFyIGEgY2lyY3VsYXIgYW11bGV0IHlvdSBtaWdodCByZXNlbWJsZSBhIHRyb2xsLg==" }, - { "They say that when you're hungry you can get a pizza in 30 moves or it's free.", - "VGhleSBzYXkgdGhhdCB3aGVuIHlvdSdyZSBodW5ncnkgeW91IGNhbiBnZXQgYSBwaXp6YSBpbiAzMCBtb3ZlcyBvciBpdCdzIGZyZWUu" }, - { "They say that when your god is angry you should try another one.", - "VGhleSBzYXkgdGhhdCB3aGVuIHlvdXIgZ29kIGlzIGFuZ3J5IHlvdSBzaG91bGQgdHJ5IGFub3RoZXIgb25lLg==" }, - { "They say that wielding a unicorn horn takes strength.", - "VGhleSBzYXkgdGhhdCB3aWVsZGluZyBhIHVuaWNvcm4gaG9ybiB0YWtlcyBzdHJlbmd0aC4=" }, - { "They say that with speed boots you never worry about hit and run accidents.", - "VGhleSBzYXkgdGhhdCB3aXRoIHNwZWVkIGJvb3RzIHlvdSBuZXZlciB3b3JyeSBhYm91dCBoaXQgYW5kIHJ1biBhY2NpZGVudHMu" }, - { "They say that you can defeat a killer bee with a unicorn horn.", - "VGhleSBzYXkgdGhhdCB5b3UgY2FuIGRlZmVhdCBhIGtpbGxlciBiZWUgd2l0aCBhIHVuaWNvcm4gaG9ybi4=" }, - { "They say that you can only cross the River Styx in Charon's boat.", - "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkgY3Jvc3MgdGhlIFJpdmVyIFN0eXggaW4gQ2hhcm9uJ3MgYm9hdC4=" }, - { "They say that you can only kill a lich once and then you'd better be careful.", - "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkga2lsbCBhIGxpY2ggb25jZSBhbmQgdGhlbiB5b3UnZCBiZXR0ZXIgYmUgY2FyZWZ1bC4=" }, - { "They say that you can only wish for things you've already had.", - "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkgd2lzaCBmb3IgdGhpbmdzIHlvdSd2ZSBhbHJlYWR5IGhhZC4=" }, - { "They say that you can train a cat by talking gently to it.", - "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRyYWluIGEgY2F0IGJ5IHRhbGtpbmcgZ2VudGx5IHRvIGl0Lg==" }, - { "They say that you can train a dog by talking firmly to it.", - "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRyYWluIGEgZG9nIGJ5IHRhbGtpbmcgZmlybWx5IHRvIGl0Lg==" }, - { "They say that you can trust your gold with the king.", - "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRydXN0IHlvdXIgZ29sZCB3aXRoIHRoZSBraW5nLg==" }, - { "They say that you can't wipe your greasy bare hands on a blank scroll.", - "VGhleSBzYXkgdGhhdCB5b3UgY2FuJ3Qgd2lwZSB5b3VyIGdyZWFzeSBiYXJlIGhhbmRzIG9uIGEgYmxhbmsgc2Nyb2xsLg==" }, - { "They say that you cannot trust scrolls of rumor.", - "VGhleSBzYXkgdGhhdCB5b3UgY2Fubm90IHRydXN0IHNjcm9sbHMgb2YgcnVtb3Iu" }, - { "They say that you could fall head over heels for an energy vortex.", - "VGhleSBzYXkgdGhhdCB5b3UgY291bGQgZmFsbCBoZWFkIG92ZXIgaGVlbHMgZm9yIGFuIGVuZXJneSB2b3J0ZXgu" }, - { "They say that you need a key in order to open locked doors.", - "VGhleSBzYXkgdGhhdCB5b3UgbmVlZCBhIGtleSBpbiBvcmRlciB0byBvcGVuIGxvY2tlZCBkb29ycy4=" }, - { "They say that you need a mirror to notice a mimic in an antique shop.", - "VGhleSBzYXkgdGhhdCB5b3UgbmVlZCBhIG1pcnJvciB0byBub3RpY2UgYSBtaW1pYyBpbiBhbiBhbnRpcXVlIHNob3Au" }, - { "They say that you really can use a pick-axe unless you really can't.", - "VGhleSBzYXkgdGhhdCB5b3UgcmVhbGx5IGNhbiB1c2UgYSBwaWNrLWF4ZSB1bmxlc3MgeW91IHJlYWxseSBjYW4ndC4=" }, - { "They say that you should always store your tools in the cellar.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGFsd2F5cyBzdG9yZSB5b3VyIHRvb2xzIGluIHRoZSBjZWxsYXIu" }, - { "They say that you should be careful while climbing the ladder to success.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGJlIGNhcmVmdWwgd2hpbGUgY2xpbWJpbmcgdGhlIGxhZGRlciB0byBzdWNjZXNzLg==" }, - { "They say that you should call your armor `rustproof'.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGNhbGwgeW91ciBhcm1vciBgcnVzdHByb29mJy4=" }, - { "They say that you should name your dog Spuds to have a cool pet.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5hbWUgeW91ciBkb2cgU3B1ZHMgdG8gaGF2ZSBhIGNvb2wgcGV0Lg==" }, - { "They say that you should name your weapon after your first monster kill.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5hbWUgeW91ciB3ZWFwb24gYWZ0ZXIgeW91ciBmaXJzdCBtb25zdGVyIGtpbGwu" }, - { "They say that you should never introduce a rope golem to a succubus.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIGludHJvZHVjZSBhIHJvcGUgZ29sZW0gdG8gYSBzdWNjdWJ1cy4=" }, - { "They say that you should never sleep near invisible ring wraiths.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIHNsZWVwIG5lYXIgaW52aXNpYmxlIHJpbmcgd3JhaXRocy4=" }, - { "They say that you should never try to leave the dungeon with a bag of gems.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIHRyeSB0byBsZWF2ZSB0aGUgZHVuZ2VvbiB3aXRoIGEgYmFnIG9mIGdlbXMu" }, - { "They say that you should remove your armor before sitting on a throne.", - "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIHJlbW92ZSB5b3VyIGFybW9yIGJlZm9yZSBzaXR0aW5nIG9uIGEgdGhyb25lLg==" }, - { "This fortune cookie is copy protected.", - "VGhpcyBmb3J0dW5lIGNvb2tpZSBpcyBjb3B5IHByb3RlY3RlZC4=" }, - { "This fortune cookie is the property of Fortune Cookies, Inc.", - "VGhpcyBmb3J0dW5lIGNvb2tpZSBpcyB0aGUgcHJvcGVydHkgb2YgRm9ydHVuZSBDb29raWVzLCBJbmMu" }, - { "Tired? Try a scroll of charging on yourself.", - "VGlyZWQ/IFRyeSBhIHNjcm9sbCBvZiBjaGFyZ2luZyBvbiB5b3Vyc2VsZi4=" }, - { "To achieve the next higher rating, you need 3 more points.", - "VG8gYWNoaWV2ZSB0aGUgbmV4dCBoaWdoZXIgcmF0aW5nLCB5b3UgbmVlZCAzIG1vcmUgcG9pbnRzLg==" }, - { "To reach heaven, escape the dungeon while wearing a ring of levitation.", - "VG8gcmVhY2ggaGVhdmVuLCBlc2NhcGUgdGhlIGR1bmdlb24gd2hpbGUgd2VhcmluZyBhIHJpbmcgb2YgbGV2aXRhdGlvbi4=" }, - { "Tourists wear shirts loud enough to wake the dead.", - "VG91cmlzdHMgd2VhciBzaGlydHMgbG91ZCBlbm91Z2ggdG8gd2FrZSB0aGUgZGVhZC4=" }, - { "Try calling your katana Moulinette.", - "VHJ5IGNhbGxpbmcgeW91ciBrYXRhbmEgTW91bGluZXR0ZS4=" }, - { "Ulch! That meat was painted!", - "VWxjaCEgVGhhdCBtZWF0IHdhcyBwYWludGVkIQ==" }, - { "Unfortunately, this message was left intentionally blank.", - "VW5mb3J0dW5hdGVseSwgdGhpcyBtZXNzYWdlIHdhcyBsZWZ0IGludGVudGlvbmFsbHkgYmxhbmsu" }, - { "Using a morning star in the evening has no effect.", - "VXNpbmcgYSBtb3JuaW5nIHN0YXIgaW4gdGhlIGV2ZW5pbmcgaGFzIG5vIGVmZmVjdC4=" }, - { "Want a hint? Zap a wand of make invisible on your weapon!", - "V2FudCBhIGhpbnQ/IFphcCBhIHdhbmQgb2YgbWFrZSBpbnZpc2libGUgb24geW91ciB3ZWFwb24h" }, - { "Want to ascend in a hurry? Apply at Gizmonic Institute.", - "V2FudCB0byBhc2NlbmQgaW4gYSBodXJyeT8gQXBwbHkgYXQgR2l6bW9uaWMgSW5zdGl0dXRlLg==" }, - { "Wanted: shopkeepers. Send a scroll of mail to Mage of Yendor/Level 35/Dungeon.", - "V2FudGVkOiBzaG9wa2VlcGVycy4gU2VuZCBhIHNjcm9sbCBvZiBtYWlsIHRvIE1hZ2Ugb2YgWWVuZG9yL0xldmVsIDM1L0R1bmdlb24u" }, - { "Warning: fortune reading can be hazardous to your health.", - "V2FybmluZzogZm9ydHVuZSByZWFkaW5nIGNhbiBiZSBoYXphcmRvdXMgdG8geW91ciBoZWFsdGgu" }, - { "We have new ways of detecting treachery...", - "V2UgaGF2ZSBuZXcgd2F5cyBvZiBkZXRlY3RpbmcgdHJlYWNoZXJ5Li4u" }, - { "Wet towels make great weapons!", - "V2V0IHRvd2VscyBtYWtlIGdyZWF0IHdlYXBvbnMh" }, - { "What a pity, you cannot read it!", - "V2hhdCBhIHBpdHksIHlvdSBjYW5ub3QgcmVhZCBpdCE=" }, - { "When a piercer drops in on you, you will be tempted to hit the ceiling!", - "V2hlbiBhIHBpZXJjZXIgZHJvcHMgaW4gb24geW91LCB5b3Ugd2lsbCBiZSB0ZW1wdGVkIHRvIGhpdCB0aGUgY2VpbGluZyE=" }, - { "When in a maze follow the right wall and you will never get lost.", - "V2hlbiBpbiBhIG1hemUgZm9sbG93IHRoZSByaWdodCB3YWxsIGFuZCB5b3Ugd2lsbCBuZXZlciBnZXQgbG9zdC4=" }, - { "When you have a key, you don't have to wait for the guard.", - "V2hlbiB5b3UgaGF2ZSBhIGtleSwgeW91IGRvbid0IGhhdmUgdG8gd2FpdCBmb3IgdGhlIGd1YXJkLg==" }, - { "Why are you wasting time reading fortunes?", - "V2h5IGFyZSB5b3Ugd2FzdGluZyB0aW1lIHJlYWRpbmcgZm9ydHVuZXM/" }, - { "Wish for a master key and open the Magic Memory Vault!", - "V2lzaCBmb3IgYSBtYXN0ZXIga2V5IGFuZCBvcGVuIHRoZSBNYWdpYyBNZW1vcnkgVmF1bHQh" }, - { "Wizard expects every monster to do its duty.", - "V2l6YXJkIGV4cGVjdHMgZXZlcnkgbW9uc3RlciB0byBkbyBpdHMgZHV0eS4=" }, - { "Wow! You could've had a potion of fruit juice!", - "V293ISBZb3UgY291bGQndmUgaGFkIGEgcG90aW9uIG9mIGZydWl0IGp1aWNlIQ==" }, - { "Yet Another Silly Message (YASM).", - "WWV0IEFub3RoZXIgU2lsbHkgTWVzc2FnZSAoWUFTTSku" }, - { "You are destined to be misled by a fortune.", - "WW91IGFyZSBkZXN0aW5lZCB0byBiZSBtaXNsZWQgYnkgYSBmb3J0dW5lLg==" }, - { "You can get a genuine Amulet of Yendor by doing the following: --More--", - "WW91IGNhbiBnZXQgYSBnZW51aW5lIEFtdWxldCBvZiBZZW5kb3IgYnkgZG9pbmcgdGhlIGZvbGxvd2luZzogLS1Nb3JlLS0=" }, - { "You can protect yourself from black dragons by doing the following: --More--", - "WW91IGNhbiBwcm90ZWN0IHlvdXJzZWxmIGZyb20gYmxhY2sgZHJhZ29ucyBieSBkb2luZyB0aGUgZm9sbG93aW5nOiAtLU1vcmUtLQ==" }, - { "You can't get by the snake.", - "WW91IGNhbid0IGdldCBieSB0aGUgc25ha2Uu" }, - { "You feel like someone is pulling your leg.", - "WW91IGZlZWwgbGlrZSBzb21lb25lIGlzIHB1bGxpbmcgeW91ciBsZWcu" }, - { "You have to outwit the Sphynx or pay her.", - "WW91IGhhdmUgdG8gb3V0d2l0IHRoZSBTcGh5bnggb3IgcGF5IGhlci4=" }, - { "You hear the fortune cookie's hissing!", - "WW91IGhlYXIgdGhlIGZvcnR1bmUgY29va2llJ3MgaGlzc2luZyE=" }, - { "You may get rich selling letters, but beware of being blackmailed!", - "WW91IG1heSBnZXQgcmljaCBzZWxsaW5nIGxldHRlcnMsIGJ1dCBiZXdhcmUgb2YgYmVpbmcgYmxhY2ttYWlsZWQh" }, - { "You offend Shai-Hulud by sheathing your crysknife without having drawn blood.", - "WW91IG9mZmVuZCBTaGFpLUh1bHVkIGJ5IHNoZWF0aGluZyB5b3VyIGNyeXNrbmlmZSB3aXRob3V0IGhhdmluZyBkcmF3biBibG9vZC4=" }, - { "You swallowed the fortune!", - "WW91IHN3YWxsb3dlZCB0aGUgZm9ydHVuZSE=" }, - { "You want to regain strength? Two levels ahead is a guesthouse!", - "WW91IHdhbnQgdG8gcmVnYWluIHN0cmVuZ3RoPyBUd28gbGV2ZWxzIGFoZWFkIGlzIGEgZ3Vlc3Rob3VzZSE=" }, - { "You will encounter a tall, dark, and gruesome creature...", - "WW91IHdpbGwgZW5jb3VudGVyIGEgdGFsbCwgZGFyaywgYW5kIGdydWVzb21lIGNyZWF0dXJlLi4u" }, - - { "The End", "VGhlIEVuZA==" } - }; - -/* PL_Base64Encode, random strings */ -PRBool test_004(void) -{ - int i; - char result[ 4096 ]; - - printf("Test 004 (PL_Base64Encode, random strings) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 plen = PL_strlen(array[i].plaintext); - PRUint32 clen = ((plen + 2)/3)*4; - - char *rv = PL_Base64Encode(array[i].plaintext, plen, result); - - if( rv != result ) - { - printf("FAIL\n\t(%d): return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strncmp(result, array[i].cyphertext, clen) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", - i, array[i].plaintext, array[i].cyphertext, clen, result); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, single characters, malloc */ -PRBool test_005(void) -{ - PRUint32 a, b; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char *rv; - - printf("Test 005 (PL_Base64Encode, single characters, malloc) ..."); fflush(stdout); - - plain[1] = plain[2] = plain[3] = (unsigned char)0; - cypher[2] = cypher[3] = (unsigned char)'='; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - - for( b = 0; b < 4; b++ ) - { - plain[0] = (unsigned char)(a * 4 + b); - cypher[1] = base[(b * 16)]; - - rv = PL_Base64Encode((char *)plain, 1, (char *)0); - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d, %d): no return value\n", a, b); - return PR_FALSE; - } - - if( 0 != PL_strcmp((char *)cypher, rv) ) - { - printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n", - a, b, cypher, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, double characters, malloc */ -PRBool test_006(void) -{ - PRUint32 a, b, c, d; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char *rv; - - printf("Test 006 (PL_Base64Encode, double characters, malloc) ..."); fflush(stdout); - - plain[2] = plain[3] = (unsigned char)0; - cypher[3] = (unsigned char)'='; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - cypher[2] = base[d*4]; - - rv = PL_Base64Encode((char *)plain, 2, (char *)0); - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d); - return PR_FALSE; - } - - if( 0 != PL_strcmp((char *)cypher, rv) ) - { - printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n", - a, b, c, d, cypher, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, triple characters, malloc */ -PRBool test_007(void) -{ - PRUint32 a, b, c, d, e, f; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char *rv; - - printf("Test 007 (PL_Base64Encode, triple characters, malloc) ..."); fflush(stdout); - - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - for( e = 0; e < 4; e++ ) - { - cypher[2] = base[d*4 + e]; - for( f = 0; f < 64; f++ ) - { - plain[2] = e * 64 + f; - cypher[3] = base[f]; - - rv = PL_Base64Encode((char *)plain, 3, (char *)0); - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): no return value\n", a, b, c, d, e, f); - return PR_FALSE; - } - - if( 0 != PL_strcmp((char *)cypher, rv) ) - { - printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n", - a, b, c, d, e, f, cypher, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - } - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, random strings, malloc */ -PRBool test_008(void) -{ - int i; - - printf("Test 008 (PL_Base64Encode, random strings, malloc) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 plen = PL_strlen(array[i].plaintext); - PRUint32 clen = ((plen + 2)/3)*4; - - char *rv = PL_Base64Encode(array[i].plaintext, plen, (char *)0); - - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d): no return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strcmp(rv, array[i].cyphertext) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", - i, array[i].plaintext, array[i].cyphertext, rv); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, single characters */ -PRBool test_009(void) -{ - PRUint32 a, b; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char result[ 8 ]; - char *rv; - - printf("Test 009 (PL_Base64Decode, single characters, equals) ..."); fflush(stdout); - - plain[1] = plain[2] = plain[3] = (unsigned char)0; - cypher[2] = cypher[3] = (unsigned char)'='; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - - for( b = 0; b < 4; b++ ) - { - plain[0] = (unsigned char)(a * 4 + b); - cypher[1] = base[(b * 16)]; - - rv = PL_Base64Decode((char *)cypher, 4, result); - if( rv != result ) - { - printf("FAIL\n\t(%d, %d): return value\n", a, b); - return PR_FALSE; - } - - if( 0 != PL_strncmp((char *)plain, result, 1) ) - { - printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.1s.\"\n", - a, b, plain, result); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, single characters */ -PRBool test_010(void) -{ - PRUint32 a, b; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char result[ 8 ]; - char *rv; - - printf("Test 010 (PL_Base64Decode, single characters, no equals) ..."); fflush(stdout); - - plain[1] = plain[2] = plain[3] = (unsigned char)0; - cypher[2] = cypher[3] = (unsigned char)0; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - - for( b = 0; b < 4; b++ ) - { - plain[0] = (unsigned char)(a * 4 + b); - cypher[1] = base[(b * 16)]; - - rv = PL_Base64Decode((char *)cypher, 2, result); - if( rv != result ) - { - printf("FAIL\n\t(%d, %d): return value\n", a, b); - return PR_FALSE; - } - - if( 0 != PL_strncmp((char *)plain, result, 1) ) - { - printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.1s.\"\n", - a, b, plain, result); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, double characters */ -PRBool test_011(void) -{ - PRUint32 a, b, c, d; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char result[ 8 ]; - char *rv; - - printf("Test 011 (PL_Base64Decode, double characters, equals) ..."); fflush(stdout); - - plain[2] = plain[3] = (unsigned char)0; - cypher[3] = (unsigned char)'='; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - cypher[2] = base[d*4]; - - rv = PL_Base64Decode((char *)cypher, 4, result); - if( rv != result ) - { - printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d); - return PR_FALSE; - } - - if( 0 != PL_strncmp((char *)plain, result, 2) ) - { - printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.2s.\"\n", - a, b, c, d, plain, result); - return PR_FALSE; - } - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, double characters */ -PRBool test_012(void) -{ - PRUint32 a, b, c, d; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char result[ 8 ]; - char *rv; - - printf("Test 012 (PL_Base64Decode, double characters, no equals) ..."); fflush(stdout); - - plain[2] = plain[3] = (unsigned char)0; - cypher[3] = (unsigned char)0; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - cypher[2] = base[d*4]; - - rv = PL_Base64Decode((char *)cypher, 3, result); - if( rv != result ) - { - printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d); - return PR_FALSE; - } - - if( 0 != PL_strncmp((char *)plain, result, 2) ) - { - printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.2s.\"\n", - a, b, c, d, cypher, result); - return PR_FALSE; - } - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, triple characters */ -PRBool test_013(void) -{ - PRUint32 a, b, c, d, e, f; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char result[ 8 ]; - char *rv; - - printf("Test 013 (PL_Base64Decode, triple characters) ..."); fflush(stdout); - - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - for( e = 0; e < 4; e++ ) - { - cypher[2] = base[d*4 + e]; - for( f = 0; f < 64; f++ ) - { - plain[2] = e * 64 + f; - cypher[3] = base[f]; - - rv = PL_Base64Decode((char *)cypher, 4, result); - if( rv != result ) - { - printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): return value\n", a, b, c, d, e, f); - return PR_FALSE; - } - - if( 0 != PL_strncmp((char *)plain, result, 3) ) - { - printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.3s.\"\n", - a, b, c, d, e, f, plain, result); - return PR_FALSE; - } - } - } - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, random strings */ -PRBool test_014(void) -{ - int i; - char result[ 4096 ]; - - printf("Test 014 (PL_Base64Decode, random strings, equals) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 clen = PL_strlen(array[i].cyphertext); - PRUint32 plen = (clen * 3) / 4; - - char *rv = PL_Base64Decode(array[i].cyphertext, clen, result); - - if( rv != result ) - { - printf("FAIL\n\t(%d): return value\n", i); - return PR_FALSE; - } - - if( 0 == (clen & 3) ) - { - if( '=' == array[i].cyphertext[clen-1] ) - { - if( '=' == array[i].cyphertext[clen-2] ) - { - plen -= 2; - } - else - { - plen -= 1; - } - } - } - - if( 0 != PL_strncmp(result, array[i].plaintext, plen) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", - i, array[i].cyphertext, array[i].plaintext, plen, result); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, random strings */ -PRBool test_015(void) -{ - int i; - char buffer[ 4096 ]; - char result[ 4096 ]; - char *rv; - - printf("Test 015 (PL_Base64Decode, random strings, no equals) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 clen, plen; - - PL_strcpy(buffer, array[i].cyphertext); - clen = PL_strlen(buffer); - - if( 0 == (clen & 3) ) - { - if( '=' == buffer[clen-1] ) - { - if( '=' == buffer[clen-2] ) - { - buffer[clen-2] = buffer[clen-1] = (char)0; - clen -= 2; - } - else - { - buffer[clen-1] = (char)0; - clen -= 1; - } - } - } - - plen = (clen * 3) / 4; - - rv = PL_Base64Decode(buffer, clen, result); - - if( rv != result ) - { - printf("FAIL\n\t(%d): return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strncmp(result, array[i].plaintext, plen) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", - i, array[i].cyphertext, array[i].plaintext, plen, result); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, single characters, malloc */ -PRBool test_016(void) -{ - PRUint32 a, b; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char *rv; - - printf("Test 016 (PL_Base64Decode, single characters, equals, malloc) ..."); fflush(stdout); - - plain[1] = plain[2] = plain[3] = (unsigned char)0; - cypher[2] = cypher[3] = (unsigned char)'='; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - - for( b = 0; b < 4; b++ ) - { - plain[0] = (unsigned char)(a * 4 + b); - cypher[1] = base[(b * 16)]; - - rv = PL_Base64Decode((char *)cypher, 4, (char *)0); - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d, %d): no return value\n", a, b); - return PR_FALSE; - } - - if( 0 != PL_strcmp((char *)plain, rv) ) - { - printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n", - a, b, plain, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, single characters, malloc */ -PRBool test_017(void) -{ - PRUint32 a, b; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char *rv; - - printf("Test 017 (PL_Base64Decode, single characters, no equals, malloc) ..."); fflush(stdout); - - plain[1] = plain[2] = plain[3] = (unsigned char)0; - cypher[2] = cypher[3] = (unsigned char)0; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - - for( b = 0; b < 4; b++ ) - { - plain[0] = (unsigned char)(a * 4 + b); - cypher[1] = base[(b * 16)]; - - rv = PL_Base64Decode((char *)cypher, 2, (char *)0); - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d, %d): no return value\n", a, b); - return PR_FALSE; - } - - if( 0 != PL_strcmp((char *)plain, rv) ) - { - printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n", - a, b, plain, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, double characters, malloc */ -PRBool test_018(void) -{ - PRUint32 a, b, c, d; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char *rv; - - printf("Test 018 (PL_Base64Decode, double characters, equals, malloc) ..."); fflush(stdout); - - plain[2] = plain[3] = (unsigned char)0; - cypher[3] = (unsigned char)'='; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - cypher[2] = base[d*4]; - - rv = PL_Base64Decode((char *)cypher, 4, (char *)0); - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d); - return PR_FALSE; - } - - if( 0 != PL_strcmp((char *)plain, rv) ) - { - printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n", - a, b, c, d, plain, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, double characters, malloc */ -PRBool test_019(void) -{ - PRUint32 a, b, c, d; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char *rv; - - printf("Test 019 (PL_Base64Decode, double characters, no equals, malloc) ..."); fflush(stdout); - - plain[2] = plain[3] = (unsigned char)0; - cypher[3] = (unsigned char)0; - cypher[4] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - cypher[2] = base[d*4]; - - rv = PL_Base64Decode((char *)cypher, 3, (char *)0); - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d); - return PR_FALSE; - } - - if( 0 != PL_strcmp((char *)plain, rv) ) - { - printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n", - a, b, c, d, cypher, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, triple characters, malloc */ -PRBool test_020(void) -{ - PRUint32 a, b, c, d, e, f; - unsigned char plain[ 4 ]; - unsigned char cypher[ 5 ]; - char *rv; - - printf("Test 020 (PL_Base64Decode, triple characters, malloc) ..."); fflush(stdout); - - cypher[4] = (unsigned char)0; - plain[3] = (unsigned char)0; - - for( a = 0; a < 64; a++ ) - { - cypher[0] = base[a]; - for( b = 0; b < 4; b++ ) - { - plain[0] = (a*4) + b; - for( c = 0; c < 16; c++ ) - { - cypher[1] = base[b*16 + c]; - for( d = 0; d < 16; d++ ) - { - plain[1] = c*16 + d; - for( e = 0; e < 4; e++ ) - { - cypher[2] = base[d*4 + e]; - for( f = 0; f < 64; f++ ) - { - plain[2] = e * 64 + f; - cypher[3] = base[f]; - - rv = PL_Base64Decode((char *)cypher, 4, (char *)0); - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): no return value\n", a, b, c, d, e, f); - return PR_FALSE; - } - - if( 0 != PL_strcmp((char *)plain, rv) ) - { - printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.3s.\"\n", - a, b, c, d, e, f, plain, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - } - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, random strings, malloc */ -PRBool test_021(void) -{ - int i; - - printf("Test 021 (PL_Base64Decode, random strings, equals, malloc) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 clen = PL_strlen(array[i].cyphertext); - - char *rv = PL_Base64Decode(array[i].cyphertext, clen, (char *)0); - - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d): no return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strcmp(rv, array[i].plaintext) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", - i, array[i].cyphertext, array[i].plaintext, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, random strings, malloc */ -PRBool test_022(void) -{ - int i; - char buffer[ 4096 ]; - char *rv; - - printf("Test 022 (PL_Base64Decode, random strings, no equals, malloc) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 clen; - - PL_strcpy(buffer, array[i].cyphertext); - clen = PL_strlen(buffer); - - if( 0 == (clen & 3) ) - { - if( '=' == buffer[clen-1] ) - { - if( '=' == buffer[clen-2] ) - { - buffer[clen-2] = buffer[clen-1] = (char)0; - clen -= 2; - } - else - { - buffer[clen-1] = (char)0; - clen -= 1; - } - } - } - - rv = PL_Base64Decode(buffer, clen, (char *)0); - - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d): no return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strcmp(rv, array[i].plaintext) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", - i, array[i].cyphertext, array[i].plaintext, rv); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, random strings */ -PRBool test_023(void) -{ - int i; - char result[ 4096 ]; - - printf("Test 023 (PL_Base64Encode, random strings, strlen) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 plen = PL_strlen(array[i].plaintext); - PRUint32 clen = ((plen + 2)/3)*4; - - char *rv = PL_Base64Encode(array[i].plaintext, 0, result); - - if( rv != result ) - { - printf("FAIL\n\t(%d): return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strncmp(result, array[i].cyphertext, clen) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", - i, array[i].plaintext, array[i].cyphertext, clen, result); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, random strings, malloc */ -PRBool test_024(void) -{ - int i; - - printf("Test 024 (PL_Base64Encode, random strings, malloc, strlen) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 plen = PL_strlen(array[i].plaintext); - PRUint32 clen = ((plen + 2)/3)*4; - - char *rv = PL_Base64Encode(array[i].plaintext, 0, (char *)0); - - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d): no return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strcmp(rv, array[i].cyphertext) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", - i, array[i].plaintext, array[i].cyphertext, rv); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, random strings */ -PRBool test_025(void) -{ - int i; - char result[ 4096 ]; - - printf("Test 025 (PL_Base64Decode, random strings, equals, strlen) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 clen = PL_strlen(array[i].cyphertext); - PRUint32 plen = (clen * 3) / 4; - - char *rv = PL_Base64Decode(array[i].cyphertext, 0, result); - - if( rv != result ) - { - printf("FAIL\n\t(%d): return value\n", i); - return PR_FALSE; - } - - if( 0 == (clen & 3) ) - { - if( '=' == array[i].cyphertext[clen-1] ) - { - if( '=' == array[i].cyphertext[clen-2] ) - { - plen -= 2; - } - else - { - plen -= 1; - } - } - } - - if( 0 != PL_strncmp(result, array[i].plaintext, plen) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", - i, array[i].cyphertext, array[i].plaintext, plen, result); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, random strings */ -PRBool test_026(void) -{ - int i; - char buffer[ 4096 ]; - char result[ 4096 ]; - char *rv; - - printf("Test 026 (PL_Base64Decode, random strings, no equals, strlen) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 clen, plen; - - PL_strcpy(buffer, array[i].cyphertext); - clen = PL_strlen(buffer); - - if( 0 == (clen & 3) ) - { - if( '=' == buffer[clen-1] ) - { - if( '=' == buffer[clen-2] ) - { - buffer[clen-2] = buffer[clen-1] = (char)0; - clen -= 2; - } - else - { - buffer[clen-1] = (char)0; - clen -= 1; - } - } - } - - plen = (clen * 3) / 4; - - rv = PL_Base64Decode(buffer, 0, result); - - if( rv != result ) - { - printf("FAIL\n\t(%d): return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strncmp(result, array[i].plaintext, plen) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", - i, array[i].cyphertext, array[i].plaintext, plen, result); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Decode, random strings, malloc */ -PRBool test_027(void) -{ - int i; - - printf("Test 027 (PL_Base64Decode, random strings, equals, malloc, strlen) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 clen = PL_strlen(array[i].cyphertext); - - char *rv = PL_Base64Decode(array[i].cyphertext, 0, (char *)0); - - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d): no return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strcmp(rv, array[i].plaintext) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", - i, array[i].cyphertext, array[i].plaintext, rv); - PR_DELETE(rv); - return PR_FALSE; - } - - PR_DELETE(rv); - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_Base64Encode, random strings, malloc */ -PRBool test_028(void) -{ - int i; - char buffer[ 4096 ]; - char *rv; - - printf("Test 028 (PL_Base64Decode, random strings, no equals, malloc, strlen) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRUint32 clen; - - PL_strcpy(buffer, array[i].cyphertext); - clen = PL_strlen(buffer); - - if( 0 == (clen & 3) ) - { - if( '=' == buffer[clen-1] ) - { - if( '=' == buffer[clen-2] ) - { - buffer[clen-2] = buffer[clen-1] = (char)0; - clen -= 2; - } - else - { - buffer[clen-1] = (char)0; - clen -= 1; - } - } - } - - rv = PL_Base64Decode(buffer, 0, (char *)0); - - if( (char *)0 == rv ) - { - printf("FAIL\n\t(%d): no return value\n", i); - return PR_FALSE; - } - - if( 0 != PL_strcmp(rv, array[i].plaintext) ) - { - printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", - i, array[i].cyphertext, array[i].plaintext, rv); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -int -main -( - int argc, - char *argv[] -) -{ - printf("Testing the Portable Library base64 functions:\n"); - printf("(warning: the \"triple characters\" tests are slow)\n"); - - if( 1 - && test_001() - && test_002() - && test_003() - && test_004() - && test_005() - && test_006() - && test_007() - && test_008() - && test_009() - && test_010() - && test_011() - && test_012() - && test_013() - && test_014() - && test_015() - && test_016() - && test_017() - && test_018() - && test_019() - && test_020() - && test_021() - && test_022() - && test_023() - && test_024() - && test_025() - && test_026() - && test_027() - && test_028() - ) - { - printf("Suite passed.\n"); - return 0; - } - else - { - printf("Suite failed.\n"); - return 1; - } - - /*NOTREACHED*/ -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/tests/.cvsignore nspr-4.10.7/mozilla/nsprpub/lib/tests/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/lib/tests/.cvsignore 2001-05-12 01:31:18.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/tests/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/tests/getopt.c nspr-4.10.7/mozilla/nsprpub/lib/tests/getopt.c --- nspr-4.9.5/mozilla/nsprpub/lib/tests/getopt.c 2012-05-31 21:54:50.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/tests/getopt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include - -#include "nspr.h" -#include "plgetopt.h" - - - -static const PLLongOpt optArray[] = { - { "longa", 'a' , PR_TRUE }, - { "longb", 'b' , PR_TRUE }, - { "longc", 'c' , PR_FALSE }, - { "longd", 'd' | 0x100, PR_TRUE }, - { "longe", 'e' | 0x100, PR_FALSE }, - { NULL, } -}; - -int -main(int argc, char **argv) -{ - PLOptState *opt; - PLOptStatus ostat; - - opt = PL_CreateLongOptState(argc, argv, "a:b:c", optArray); - - while (PL_OPT_OK == (ostat = PL_GetNextOpt(opt))) { - if (opt->option == 0 && opt->longOptIndex < 0) - printf("Positional parameter: \"%s\"\n", opt->value); - else - printf("%s option: %x (\'%c\', index %d), argument: \"%s\"\n", - (ostat == PL_OPT_BAD) ? "BAD" : "GOOD", - opt->longOption, opt->option ? opt->option : ' ', - opt->longOptIndex, opt->value); - - } - printf("last result was %s\n", (ostat == PL_OPT_BAD) ? "BAD" : "EOL"); - PL_DestroyOptState(opt); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/tests/Makefile.in nspr-4.10.7/mozilla/nsprpub/lib/tests/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/lib/tests/Makefile.in 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/tests/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CSRCS = \ - arena.c \ - base64t.c \ - getopt.c \ - string.c - -ifeq (,$(filter-out WINCE WINNT OS2,$(OS_ARCH))) -CSRCS += arena.c -endif - -ifeq (,$(filter-out WINCE WINNT OS2,$(OS_ARCH))) -PROG_SUFFIX = .exe -else -PROG_SUFFIX = -endif - -PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX))) - -TARGETS = $(PROGS) $(OBJS) - -INCLUDES = -I$(dist_includedir) - -# Setting the variables LDOPTS and LIBPR. We first initialize -# them to the default values, then adjust them for some platforms. -LDOPTS = -L$(dist_libdir) -LIBPR = -lnspr$(MOD_MAJOR_VERSION) -LIBPLC = -lplc$(MOD_MAJOR_VERSION) -LIBPLDS = -lplds$(MOD_MAJOR_VERSION) - -ifeq (,$(filter-out WINCE WINNT, $(OS_ARCH))) - LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO - ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET))) - LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - LIBPLC= $(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - LIBPLDS= $(dist_libdir)/plds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - else - LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - LIBPLC= $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - LIBPLDS= $(dist_libdir)/libplds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - endif -endif - -ifeq ($(OS_ARCH),OS2) -LDOPTS += -Zomf -Zlinker /PM:VIO -endif - -ifneq ($(OS_ARCH), WINNT) -PWD = $(shell pwd) -endif - -ifeq ($(OS_ARCH), IRIX) -LDOPTS += -rpath $(PWD)/$(dist_libdir) -endif - -ifeq ($(OS_ARCH), Linux) - ifeq ($(OS_RELEASE), 1.2) - EXTRA_LIBS = -ldl - else - LDOPTS += -Xlinker -rpath $(PWD)/$(dist_libdir) - ifeq ($(USE_PTHREADS),1) - EXTRA_LIBS = -lpthread - endif - endif -endif - -ifeq (,$(filter-out OpenBSD,$(OS_ARCH))) - ifeq ($(USE_PTHREADS),1) - EXTRA_LIBS = -lpthread - endif -endif - -ifeq ($(OS_ARCH), OSF1) -LDOPTS += -rpath $(PWD)/$(dist_libdir) -lpthread -endif - -ifeq ($(OS_ARCH), HP-UX) -LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir) -endif - -# AIX -ifeq ($(OS_ARCH),AIX) -LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib -LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr -LIBPLC = -lplc$(MOD_MAJOR_VERSION)_shr -endif - -# Solaris -ifeq ($(OS_ARCH), SunOS) -ifdef NS_USE_GCC -LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir) -else -LDOPTS += -R $(PWD)/$(dist_libdir) -endif - -# SunOS 5.5 needs to link with -lpthread, even though we already -# linked with this system library when we built libnspr.so. -ifeq ($(OS_RELEASE), 5.5) -ifdef USE_PTHREADS -EXTRA_LIBS = -lpthread -endif -endif -endif # SunOS - -##################################################### -# -# The rules -# -##################################################### - -include $(topsrcdir)/config/rules.mk - -AIX_PRE_4_2 = 0 -ifeq ($(OS_ARCH),AIX) -ifneq ($(OS_RELEASE),4.2) -ifneq ($(USE_PTHREADS), 1) -#AIX_PRE_4_2 = 1 -endif -endif -endif - -ifeq ($(AIX_PRE_4_2),1) - -# AIX releases prior to 4.2 need a special two-step linking hack -# in order to both override the system select() and be able to -# get at the original system select(). -# -# We use a pattern rule in ns/nspr20/config/rules.mk to generate -# the .$(OBJ_SUFFIX) file from the .c source file, then do the -# two-step linking hack below. - -$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) - rm -f $@ $(AIX_TMP) - $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a - $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) - rm -f $(AIX_TMP) - -else - -# All platforms that are not AIX pre-4.2. - -$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) - -ifeq ($(OS_ARCH), WINNT) - link $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) wsock32.lib -out:$@ -else -ifeq ($(OS_ARCH), WINCE) - $(LD) $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) ws2.lib -out:$@ -else -ifeq ($(OS_ARCH),OS2) - $(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS) -else - $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPLDS) $(LIBPR) $(EXTRA_LIBS) -o $@ -endif -endif -endif -endif - -export:: $(TARGETS) -clean:: - rm -f $(TARGETS) diff -Nru nspr-4.9.5/mozilla/nsprpub/lib/tests/string.c nspr-4.10.7/mozilla/nsprpub/lib/tests/string.c --- nspr-4.9.5/mozilla/nsprpub/lib/tests/string.c 2012-05-31 21:54:50.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/lib/tests/string.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,3084 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plstr.h" -#include "nspr.h" - -#include - -/* PL_strlen */ -PRBool test_001(void) -{ - static struct - { - const char *str; - PRUint32 len; - } array[] = - { - { (const char *)0, 0 }, - { "", 0 }, - { "a", 1 }, - { "abcdefg", 7 }, - { "abcdefg\0hijk", 7 } - }; - - int i; - - printf("Test 001 (PL_strlen) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - if( PL_strlen(array[i].str) != array[i].len ) - { - printf("FAIL (%d: %s->%d, %d)\n", i, - array[i].str ? array[i].str : "(null)", - PL_strlen(array[i].str), array[i].len); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strnlen */ -PRBool test_002(void) -{ - static struct - { - const char *str; - PRUint32 max; - PRUint32 len; - } array[] = - { - { (const char *)0, 0, 0 }, - { (const char *)0, 12, 0 }, - { "", 0, 0 }, - { "", 12, 0 }, - { "a", 0, 0 }, - { "a", 1, 1 }, - { "a", 12, 1 }, - { "abcdefg", 0, 0 }, - { "abcdefg", 1, 1 }, - { "abcdefg", 7, 7 }, - { "abcdefg", 12, 7 }, - { "abcdefg\0hijk", 0, 0 }, - { "abcdefg\0hijk", 1, 1 }, - { "abcdefg\0hijk", 7, 7 }, - { "abcdefg\0hijk", 12, 7 }, - }; - - int i; - - printf("Test 002 (PL_strnlen) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - if( PL_strnlen(array[i].str, array[i].max) != array[i].len ) - { - printf("FAIL (%d: %s,%d->%d, %d)\n", i, - array[i].str ? array[i].str : "(null)", array[i].max, - PL_strnlen(array[i].str, array[i].max), array[i].len); - return PR_FALSE; - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strcpy */ -PRBool test_003(void) -{ - static char buffer[ 1024 ]; - - static struct - { - const char *str; - char *dest; - char *rv; - PRBool comp; - } array[] = - { - { (const char *)0, (char *)0, (char *)0, PR_FALSE }, - { (const char *)0, buffer, (char *)0, PR_FALSE }, - { "", (char *)0, (char *)0, PR_FALSE }, - { "", buffer, buffer, PR_TRUE }, - { "a", (char *)0, (char *)0, PR_FALSE }, - { "a", buffer, buffer, PR_TRUE }, - { "abcdefg", (char *)0, (char *)0, PR_FALSE }, - { "abcdefg", buffer, buffer, PR_TRUE }, - { "wxyz\0abcdefg", (char *)0, (char *)0, PR_FALSE }, - { "wxyz\0abcdefg", buffer, buffer, PR_TRUE } - }; - - int i; - - printf("Test 003 (PL_strcpy) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv; - const char *a = array[i].str; - const char *b = (const char *)array[i].dest; - - rv = PL_strcpy(array[i].dest, array[i].str); - if( array[i].rv != rv ) - { - printf("FAIL %d: (0x%x, %s)->0x%x\n", i, array[i].dest, - array[i].str ? array[i].str : "(null)", rv); - return PR_FALSE; - } - - if( array[i].comp ) - { - while( 1 ) - { - if( *a != *b ) - { - printf("FAIL %d: %s->%.32s\n", i, - array[i].str ? array[i].str : "(null)", - array[i].dest ? array[i].dest : "(null)"); - return PR_FALSE; - } - - if( (char)0 == *a ) break; - - a++; - b++; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strncpy */ -PRBool test_004(void) -{ - static char buffer[ 1024 ]; - - static struct - { - const char *str; - PRUint32 len; - char *dest; - char *rv; - PRBool comp; - const char *result; - PRBool nulled; - } array[] = - { - { (const char *)0, 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { (const char *)0, 0, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { (const char *)0, 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { (const char *)0, 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { (const char *)0, 1, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { (const char *)0, 7, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, - { "", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "", 1, buffer, buffer, PR_TRUE, "", PR_TRUE }, - { "", 7, buffer, buffer, PR_TRUE, "", PR_TRUE }, - { "a", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "a", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, - { "a", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "a", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "b", 1, buffer, buffer, PR_TRUE, "b", PR_FALSE }, - { "c", 7, buffer, buffer, PR_TRUE, "c", PR_TRUE }, - { "de", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "de", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, - { "de", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "de", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "fg", 1, buffer, buffer, PR_TRUE, "f", PR_FALSE }, - { "hi", 7, buffer, buffer, PR_TRUE, "hi", PR_TRUE }, - { "jklmnopq", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "jklmnopq", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, - { "jklmnopq", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "jklmnopq", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "rstuvwxy", 1, buffer, buffer, PR_TRUE, "r", PR_FALSE }, - { "zABCDEFG", 7, buffer, buffer, PR_TRUE, "zABCDEF", PR_FALSE }, - { "a\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "a\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, - { "a\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "a\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "b\0XXX", 1, buffer, buffer, PR_TRUE, "b", PR_FALSE }, - { "c\0XXX", 7, buffer, buffer, PR_TRUE, "c", PR_TRUE }, - { "de\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "de\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, - { "de\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "de\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "fg\0XXX", 1, buffer, buffer, PR_TRUE, "f", PR_FALSE }, - { "hi\0XXX", 7, buffer, buffer, PR_TRUE, "hi", PR_TRUE }, - { "jklmnopq\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "jklmnopq\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, - { "jklmnopq\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "jklmnopq\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, - { "rstuvwxy\0XXX", 1, buffer, buffer, PR_TRUE, "r", PR_FALSE }, - { "zABCDEFG\0XXX", 7, buffer, buffer, PR_TRUE, "zABCDEF", PR_FALSE }, - }; - - int i; - - printf("Test 004 (PL_strncpy) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv; - int j; - - for( j = 0; j < sizeof(buffer); j++ ) - buffer[j] = '-'; - - rv = PL_strncpy(array[i].dest, array[i].str, array[i].len); - if( array[i].rv != rv ) - { - printf("FAIL %d: (0x%x, %s, %lu)->0x%x\n", i, array[i].dest, - array[i].str ? array[i].str : "(null)", array[i].len, rv); - return PR_FALSE; - } - - if( array[i].comp ) - { - const char *a = array[i].result; - const char *b = array[i].dest; - - while( *a ) - { - if( *a != *b ) - { - printf("FAIL %d: %s != %.32s\n", i, - array[i].result, array[i].dest); - return PR_FALSE; - } - - a++; - b++; - } - - if( array[i].nulled ) - { - if( *b != '\0' ) - { - printf("FAIL %d: not terminated\n", i); - return PR_FALSE; - } - } - else - { - if( *b != '-' ) - { - printf("FAIL %d: overstepped\n", i); - return PR_FALSE; - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strncpyz */ -PRBool test_005(void) -{ - static char buffer[ 1024 ]; - - static struct - { - const char *str; - PRUint32 len; - char *dest; - char *rv; - PRBool comp; - const char *result; - } array[] = - { - { (const char *)0, 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { (const char *)0, 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { (const char *)0, 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { (const char *)0, 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { (const char *)0, 1, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { (const char *)0, 7, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { "", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { "", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "", 1, buffer, buffer, PR_TRUE, "" }, - { "", 7, buffer, buffer, PR_TRUE, "" }, - { "a", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "a", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { "a", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "a", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "b", 1, buffer, buffer, PR_TRUE, "" }, - { "c", 7, buffer, buffer, PR_TRUE, "c" }, - { "de", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "de", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { "de", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "de", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "fg", 1, buffer, buffer, PR_TRUE, "" }, - { "hi", 7, buffer, buffer, PR_TRUE, "hi" }, - { "jklmnopq", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "jklmnopq", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { "jklmnopq", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "jklmnopq", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "rstuvwxy", 1, buffer, buffer, PR_TRUE, "" }, - { "zABCDEFG", 7, buffer, buffer, PR_TRUE, "zABCDE" }, - { "a\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "a\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { "a\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "a\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "b\0XXX", 1, buffer, buffer, PR_TRUE, "" }, - { "c\0XXX", 7, buffer, buffer, PR_TRUE, "c" }, - { "de\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "de\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { "de\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "de\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "fg\0XXX", 1, buffer, buffer, PR_TRUE, "" }, - { "hi\0XXX", 7, buffer, buffer, PR_TRUE, "hi" }, - { "jklmnopq\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "jklmnopq\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, - { "jklmnopq\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "jklmnopq\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, - { "rstuvwxy\0XXX", 1, buffer, buffer, PR_TRUE, "" }, - { "zABCDEFG\0XXX", 7, buffer, buffer, PR_TRUE, "zABCDE" }, - }; - - int i; - - printf("Test 005 (PL_strncpyz) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv; - int j; - - for( j = 0; j < sizeof(buffer); j++ ) - buffer[j] = '-'; - - rv = PL_strncpyz(array[i].dest, array[i].str, array[i].len); - if( array[i].rv != rv ) - { - printf("FAIL %d: (0x%x, %s, %lu)->0x%x\n", i, array[i].dest, - array[i].str ? array[i].str : "(null)", array[i].len, rv); - return PR_FALSE; - } - - if( array[i].comp ) - { - const char *a = array[i].result; - const char *b = array[i].dest; - - while( 1 ) - { - if( *a != *b ) - { - printf("FAIL %d: %s != %.32s\n", i, - array[i].result, array[i].dest); - return PR_FALSE; - } - - if( (char)0 == *a ) break; - - a++; - b++; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strdup */ -PRBool test_006(void) -{ - static const char *array[] = - { - (const char *)0, - "", - "a", - "abcdefg" - }; - - int i; - - printf("Test 006 (PL_strdup) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strdup(array[i]); - - if( (char *)0 == rv ) - { - printf("FAIL %d: 0x%x -> 0\n", i, array[i]); - return PR_FALSE; - } - - if( (const char *)0 == array[i] ) - { - if( (char)0 != *rv ) - { - printf("FAIL %d: (const char *)0 -> %.32s\n", i, rv); - return PR_FALSE; - } - } - else - { - const char *a = array[i]; - const char *b = (const char *)rv; - - while( 1 ) - { - if( *a != *b ) - { - printf("FAIL %d: %s != %.32s\n", i, array[i], rv); - return PR_FALSE; - } - - if( (char)0 == *a ) break; - - a++; - b++; - } - - } - PL_strfree(rv); - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strndup */ -PRBool test_007(void) -{ - static struct - { - const char *str; - PRUint32 len; - const char *result; - } array[] = - { - { (const char *)0, 0, "" }, - { (const char *)0, 1, "" }, - { (const char *)0, 7, "" }, - { "", 0, "" }, - { "", 1, "" }, - { "", 7, "" }, - { "a", 0, "" }, - { "a", 1, "a" }, - { "a", 7, "a" }, - { "ab", 0, "" }, - { "ab", 1, "a" }, - { "ab", 7, "ab" }, - { "abcdefg", 0, "" }, - { "abcdefg", 1, "a" }, - { "abcdefg", 7, "abcdefg" }, - { "abcdefghijk", 0, "" }, - { "abcdefghijk", 1, "a" }, - { "abcdefghijk", 7, "abcdefg" }, - { "abcdef\0ghijk", 0, "" }, - { "abcdef\0ghijk", 1, "a" }, - { "abcdef\0ghijk", 7, "abcdef" } - }; - - int i; - - printf("Test 007 (PL_strndup) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strndup(array[i].str, array[i].len); - const char *a; - const char *b; - - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%lu -> 0\n", i, - array[i].str ? array[i].str : "(null)", array[i].len); - return PR_FALSE; - } - - a = array[i].result; - b = (const char *)rv; - - while( 1 ) - { - if( *a != *b ) - { - printf("FAIL %d: %s != %.32s\n", i, array[i].result, rv); - return PR_FALSE; - } - - if( (char)0 == *a ) break; - - a++; - b++; - } - - free(rv); - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strcat */ -PRBool test_008(void) -{ - static struct - { - const char *first; - const char *second; - const char *result; - } array[] = - { - { (const char *)0, (const char *)0, (const char *)0 }, - { (const char *)0, "xyz", (const char *)0 }, - { "", (const char *)0, "" }, - { "", "", "" }, - { "ab", "", "ab" }, - { "cd", "ef", "cdef" }, - { "gh\0X", "", "gh" }, - { "ij\0X", "kl", "ijkl" }, - { "mn\0X", "op\0X", "mnop" }, - { "qr", "st\0X", "qrst" }, - { "uv\0X", "wx\0X", "uvwx" } - }; - - int i; - - printf("Test 008 (PL_strcat) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char buffer[ 1024 ]; - int j; - char *rv; - - for( j = 0; j < sizeof(buffer); j++ ) - buffer[j] = '-'; - - if( (const char *)0 != array[i].first ) - (void)PL_strcpy(buffer, array[i].first); - - rv = PL_strcat(((const char *)0 == array[i].first) ? (char *)0 : buffer, - array[i].second); - - if( (const char *)0 == array[i].result ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s+%s -> %.32s, not zero\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s+%s -> null, not %s\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].result); - return PR_FALSE; - } - else - { - const char *a = array[i].result; - const char *b = (const char *)rv; - - while( 1 ) - { - if( *a != *b ) - { - printf("FAIL %d: %s+%s -> %.32s, not %s\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - rv, array[i].result); - return PR_FALSE; - } - - if( (char)0 == *a ) break; - - a++; - b++; - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strncat */ -PRBool test_009(void) -{ - static struct - { - const char *first; - const char *second; - PRUint32 length; - PRBool nulled; - const char *result; - } array[] = - { - { (const char *)0, (const char *)0, 0, PR_FALSE, (const char *)0 }, - { (const char *)0, (const char *)0, 1, PR_FALSE, (const char *)0 }, - { (const char *)0, (const char *)0, 7, PR_FALSE, (const char *)0 }, - { (const char *)0, "", 0, PR_FALSE, (const char *)0 }, - { (const char *)0, "", 1, PR_FALSE, (const char *)0 }, - { (const char *)0, "", 7, PR_FALSE, (const char *)0 }, - { (const char *)0, "stuff", 0, PR_FALSE, (const char *)0 }, - { (const char *)0, "stuff", 1, PR_FALSE, (const char *)0 }, - { (const char *)0, "stuff", 7, PR_FALSE, (const char *)0 }, - { "", (const char *)0, 0, PR_TRUE, "" }, - { "", (const char *)0, 1, PR_TRUE, "" }, - { "", (const char *)0, 7, PR_TRUE, "" }, - { "", "", 0, PR_TRUE, "" }, - { "", "", 1, PR_TRUE, "" }, - { "", "", 7, PR_TRUE, "" }, - { "", "abcdefgh", 0, PR_TRUE, "" }, - { "", "abcdefgh", 1, PR_FALSE, "a" }, - { "", "abcdefgh", 7, PR_FALSE, "abcdefg" }, - { "xyz", (const char *)0, 0, PR_TRUE, "xyz" }, - { "xyz", (const char *)0, 1, PR_TRUE, "xyz" }, - { "xyz", (const char *)0, 7, PR_TRUE, "xyz" }, - { "xyz", "", 0, PR_TRUE, "xyz" }, - { "xyz", "", 1, PR_TRUE, "xyz" }, - { "xyz", "", 7, PR_TRUE, "xyz" }, - { "xyz", "abcdefgh", 0, PR_TRUE, "xyz" }, - { "xyz", "abcdefgh", 1, PR_FALSE, "xyza" }, - { "xyz", "abcdefgh", 7, PR_FALSE, "xyzabcdefg" } - }; - - int i; - - printf("Test 009 (PL_strncat) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char buffer[ 1024 ]; - int j; - char *rv; - - for( j = 0; j < sizeof(buffer); j++ ) - buffer[j] = '-'; - - if( (const char *)0 != array[i].first ) - (void)PL_strcpy(buffer, array[i].first); - - rv = PL_strncat(((const char *)0 == array[i].first) ? (char *)0 : buffer, - array[i].second, array[i].length); - - if( (const char *)0 == array[i].result ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s+%s/%lu -> %.32s, not zero\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].length, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s+%s/%lu -> null, not %s\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].length, array[i].result); - return PR_FALSE; - } - else - { - const char *a = array[i].result; - const char *b = (const char *)rv; - - while( *a ) - { - if( *a != *b ) - { - printf("FAIL %d: %s+%s/%lu -> %.32s, not %s\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].length, rv, array[i].result); - return PR_FALSE; - } - - a++; - b++; - } - - if( array[i].nulled ) - { - if( (char)0 != *b ) - { - printf("FAIL %d: %s+%s/%lu -> not nulled\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].length); - return PR_FALSE; - } - } - else - { - if( (char)0 == *b ) - { - printf("FAIL %d: %s+%s/%lu -> overrun\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].length); - return PR_FALSE; - } - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strcatn */ -PRBool test_010(void) -{ - static struct - { - const char *first; - const char *second; - PRUint32 length; - const char *result; - } array[] = - { - { (const char *)0, (const char *)0, 0, (const char *)0 }, - { (const char *)0, (const char *)0, 1, (const char *)0 }, - { (const char *)0, (const char *)0, 7, (const char *)0 }, - { (const char *)0, "", 0, (const char *)0 }, - { (const char *)0, "", 1, (const char *)0 }, - { (const char *)0, "", 7, (const char *)0 }, - { (const char *)0, "stuff", 0, (const char *)0 }, - { (const char *)0, "stuff", 1, (const char *)0 }, - { (const char *)0, "stuff", 7, (const char *)0 }, - { "", (const char *)0, 0, "" }, - { "", (const char *)0, 1, "" }, - { "", (const char *)0, 7, "" }, - { "", "", 0, "" }, - { "", "", 1, "" }, - { "", "", 7, "" }, - { "", "abcdefgh", 0, "" }, - { "", "abcdefgh", 1, "" }, - { "", "abcdefgh", 7, "abcdef" }, - { "xyz", (const char *)0, 0, "xyz" }, - { "xyz", (const char *)0, 1, "xyz" }, - { "xyz", (const char *)0, 7, "xyz" }, - { "xyz", "", 0, "xyz" }, - { "xyz", "", 1, "xyz" }, - { "xyz", "", 7, "xyz" }, - { "xyz", "abcdefgh", 0, "xyz" }, - { "xyz", "abcdefgh", 1, "xyz" }, - { "xyz", "abcdefgh", 7, "xyzabc" } - }; - - int i; - - printf("Test 010 (PL_strcatn) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char buffer[ 1024 ]; - int j; - char *rv; - - for( j = 0; j < sizeof(buffer); j++ ) - buffer[j] = '-'; - - if( (const char *)0 != array[i].first ) - (void)PL_strcpy(buffer, array[i].first); - - rv = PL_strcatn(((const char *)0 == array[i].first) ? (char *)0 : buffer, - array[i].length, array[i].second); - - if( (const char *)0 == array[i].result ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s+%s/%lu -> %.32s, not zero\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].length, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s+%s/%lu -> null, not %s\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].length, array[i].result); - return PR_FALSE; - } - else - { - const char *a = array[i].result; - const char *b = (const char *)rv; - - while( 1 ) - { - if( *a != *b ) - { - printf("FAIL %d: %s+%s/%lu -> %.32s, not %s\n", i, - array[i].first ? array[i].first : "(null)", - array[i].second ? array[i].second : "(null)", - array[i].length, rv, array[i].result); - return PR_FALSE; - } - - if( (char)0 == *a ) break; - - a++; - b++; - } - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strcmp */ -PRBool test_011(void) -{ - static struct - { - const char *one; - const char *two; - PRIntn sign; - } array[] = - { - { (const char *)0, (const char *)0, 0 }, - { (const char *)0, "word", -1 }, - { "word", (const char *)0, 1 }, - { "word", "word", 0 }, - { "aZYXVUT", "bZYXVUT", -1 }, - { "aZYXVUT", "bAAAAAA", -1 }, - { "a", "aa", -1 }, - { "a", "a", 0 }, - { "a", "A", 1 }, - { "aaaaa", "baaaa", -1 }, - { "aaaaa", "abaaa", -1 }, - { "aaaaa", "aabaa", -1 }, - { "aaaaa", "aaaba", -1 }, - { "aaaaa", "aaaab", -1 }, - { "bZYXVUT", "aZYXVUT", 1 }, - { "bAAAAAA", "aZYXVUT", 1 }, - { "aa", "a", 1 }, - { "A", "a", -1 }, - { "baaaa", "aaaaa", 1 }, - { "abaaa", "aaaaa", 1 }, - { "aabaa", "aaaaa", 1 }, - { "aaaba", "aaaaa", 1 }, - { "aaaab", "aaaaa", 1 }, - { "word", "Word", 1 }, - { "word", "wOrd", 1 }, - { "word", "woRd", 1 }, - { "word", "worD", 1 }, - { "WORD", "wORD", -1 }, - { "WORD", "WoRD", -1 }, - { "WORD", "WOrD", -1 }, - { "WORD", "WORd", -1 } - }; - - int i; - - printf("Test 011 (PL_strcmp) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRIntn rv = PL_strcmp(array[i].one, array[i].two); - - switch( array[i].sign ) - { - case -1: - if( rv < 0 ) continue; - break; - case 1: - if( rv > 0 ) continue; - break; - case 0: - if( 0 == rv ) continue; - break; - default: - PR_NOT_REACHED("static data inconsistancy"); - break; - } - - printf("FAIL %d: %s-%s -> %d, not %d\n", i, - array[i].one ? array[i].one : "(null)", - array[i].two ? array[i].two : "(null)", - rv, array[i].sign); - return PR_FALSE; - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strncmp */ -PRBool test_012(void) -{ - static struct - { - const char *one; - const char *two; - PRUint32 max; - PRIntn sign; - } array[] = - { - { (const char *)0, (const char *)0, 0, 0 }, - { (const char *)0, (const char *)0, 1, 0 }, - { (const char *)0, (const char *)0, 4, 0 }, - { (const char *)0, "word", 0, -1 }, - { (const char *)0, "word", 1, -1 }, - { (const char *)0, "word", 4, -1 }, - { "word", (const char *)0, 0, 1 }, - { "word", (const char *)0, 1, 1 }, - { "word", (const char *)0, 4, 1 }, - { "word", "word", 0, 0 }, - { "word", "word", 1, 0 }, - { "word", "word", 3, 0 }, - { "word", "word", 5, 0 }, - { "aZYXVUT", "bZYXVUT", 0, 0 }, - { "aZYXVUT", "bZYXVUT", 1, -1 }, - { "aZYXVUT", "bZYXVUT", 4, -1 }, - { "aZYXVUT", "bZYXVUT", 9, -1 }, - { "aZYXVUT", "bAAAAAA", 0, 0 }, - { "aZYXVUT", "bAAAAAA", 1, -1 }, - { "aZYXVUT", "bAAAAAA", 4, -1 }, - { "aZYXVUT", "bAAAAAA", 5, -1 }, - { "a", "aa", 0, 0 }, - { "a", "aa", 1, 0 }, - { "a", "aa", 4, -1 }, - { "a", "a", 0, 0 }, - { "a", "a", 1, 0 }, - { "a", "a", 4, 0 }, - { "a", "A", 0, 0 }, - { "a", "A", 1, 1 }, - { "a", "A", 4, 1 }, - { "aaaaa", "baaaa", 0, 0 }, - { "aaaaa", "baaaa", 1, -1 }, - { "aaaaa", "baaaa", 4, -1 }, - { "aaaaa", "abaaa", 0, 0 }, - { "aaaaa", "abaaa", 1, 0 }, - { "aaaaa", "abaaa", 4, -1 }, - { "aaaaa", "aabaa", 0, 0 }, - { "aaaaa", "aabaa", 1, 0 }, - { "aaaaa", "aabaa", 4, -1 }, - { "aaaaa", "aaaba", 0, 0 }, - { "aaaaa", "aaaba", 1, 0 }, - { "aaaaa", "aaaba", 4, -1 }, - { "aaaaa", "aaaab", 0, 0 }, - { "aaaaa", "aaaab", 1, 0 }, - { "aaaaa", "aaaab", 4, 0 }, - { "bZYXVUT", "aZYXVUT", 0, 0 }, - { "bZYXVUT", "aZYXVUT", 1, 1 }, - { "bZYXVUT", "aZYXVUT", 4, 1 }, - { "bAAAAAA", "aZYXVUT", 0, 0 }, - { "bAAAAAA", "aZYXVUT", 1, 1 }, - { "bAAAAAA", "aZYXVUT", 4, 1 }, - { "aa", "a", 0, 0 }, - { "aa", "a", 1, 0 }, - { "aa", "a", 4, 1 }, - { "A", "a", 0, 0 }, - { "A", "a", 1, -1 }, - { "A", "a", 4, -1 }, - { "baaaa", "aaaaa", 0, 0 }, - { "baaaa", "aaaaa", 1, 1 }, - { "baaaa", "aaaaa", 4, 1 }, - { "abaaa", "aaaaa", 0, 0 }, - { "abaaa", "aaaaa", 1, 0 }, - { "abaaa", "aaaaa", 4, 1 }, - { "aabaa", "aaaaa", 0, 0 }, - { "aabaa", "aaaaa", 1, 0 }, - { "aabaa", "aaaaa", 4, 1 }, - { "aaaba", "aaaaa", 0, 0 }, - { "aaaba", "aaaaa", 1, 0 }, - { "aaaba", "aaaaa", 4, 1 }, - { "aaaab", "aaaaa", 0, 0 }, - { "aaaab", "aaaaa", 1, 0 }, - { "aaaab", "aaaaa", 4, 0 }, - { "word", "Word", 0, 0 }, - { "word", "Word", 1, 1 }, - { "word", "Word", 3, 1 }, - { "word", "wOrd", 0, 0 }, - { "word", "wOrd", 1, 0 }, - { "word", "wOrd", 3, 1 }, - { "word", "woRd", 0, 0 }, - { "word", "woRd", 1, 0 }, - { "word", "woRd", 3, 1 }, - { "word", "worD", 0, 0 }, - { "word", "worD", 1, 0 }, - { "word", "worD", 3, 0 }, - { "WORD", "wORD", 0, 0 }, - { "WORD", "wORD", 1, -1 }, - { "WORD", "wORD", 3, -1 }, - { "WORD", "WoRD", 0, 0 }, - { "WORD", "WoRD", 1, 0 }, - { "WORD", "WoRD", 3, -1 }, - { "WORD", "WOrD", 0, 0 }, - { "WORD", "WOrD", 1, 0 }, - { "WORD", "WOrD", 3, -1 }, - { "WORD", "WORd", 0, 0 }, - { "WORD", "WORd", 1, 0 }, - { "WORD", "WORd", 3, 0 } - - }; - - int i; - - printf("Test 012 (PL_strncmp) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRIntn rv = PL_strncmp(array[i].one, array[i].two, array[i].max); - - switch( array[i].sign ) - { - case -1: - if( rv < 0 ) continue; - break; - case 1: - if( rv > 0 ) continue; - break; - case 0: - if( 0 == rv ) continue; - break; - default: - PR_NOT_REACHED("static data inconsistancy"); - break; - } - - printf("FAIL %d: %s-%s/%ld -> %d, not %d\n", i, - array[i].one ? array[i].one : "(null)", - array[i].two ? array[i].two : "(null)", - array[i].max, rv, array[i].sign); - return PR_FALSE; - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strcasecmp */ -PRBool test_013(void) -{ - static struct - { - const char *one; - const char *two; - PRIntn sign; - } array[] = - { - { (const char *)0, (const char *)0, 0 }, - { (const char *)0, "word", -1 }, - { "word", (const char *)0, 1 }, - { "word", "word", 0 }, - { "aZYXVUT", "bZYXVUT", -1 }, - { "aZYXVUT", "bAAAAAA", -1 }, - { "a", "aa", -1 }, - { "a", "a", 0 }, - { "a", "A", 0 }, - { "aaaaa", "baaaa", -1 }, - { "aaaaa", "abaaa", -1 }, - { "aaaaa", "aabaa", -1 }, - { "aaaaa", "aaaba", -1 }, - { "aaaaa", "aaaab", -1 }, - { "bZYXVUT", "aZYXVUT", 1 }, - { "bAAAAAA", "aZYXVUT", 1 }, - { "aa", "a", 1 }, - { "A", "a", 0 }, - { "baaaa", "aaaaa", 1 }, - { "abaaa", "aaaaa", 1 }, - { "aabaa", "aaaaa", 1 }, - { "aaaba", "aaaaa", 1 }, - { "aaaab", "aaaaa", 1 }, - { "word", "Word", 0 }, - { "word", "wOrd", 0 }, - { "word", "woRd", 0 }, - { "word", "worD", 0 }, - { "WORD", "wORD", 0 }, - { "WORD", "WoRD", 0 }, - { "WORD", "WOrD", 0 }, - { "WORD", "WORd", 0 } - }; - - int i; - - printf("Test 013 (PL_strcasecmp) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRIntn rv = PL_strcasecmp(array[i].one, array[i].two); - - switch( array[i].sign ) - { - case -1: - if( rv < 0 ) continue; - break; - case 1: - if( rv > 0 ) continue; - break; - case 0: - if( 0 == rv ) continue; - break; - default: - PR_NOT_REACHED("static data inconsistancy"); - break; - } - - printf("FAIL %d: %s-%s -> %d, not %d\n", i, - array[i].one ? array[i].one : "(null)", - array[i].two ? array[i].two : "(null)", - rv, array[i].sign); - return PR_FALSE; - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strncasecmp */ -PRBool test_014(void) -{ - static struct - { - const char *one; - const char *two; - PRUint32 max; - PRIntn sign; - } array[] = - { - { (const char *)0, (const char *)0, 0, 0 }, - { (const char *)0, (const char *)0, 1, 0 }, - { (const char *)0, (const char *)0, 4, 0 }, - { (const char *)0, "word", 0, -1 }, - { (const char *)0, "word", 1, -1 }, - { (const char *)0, "word", 4, -1 }, - { "word", (const char *)0, 0, 1 }, - { "word", (const char *)0, 1, 1 }, - { "word", (const char *)0, 4, 1 }, - { "word", "word", 0, 0 }, - { "word", "word", 1, 0 }, - { "word", "word", 3, 0 }, - { "word", "word", 5, 0 }, - { "aZYXVUT", "bZYXVUT", 0, 0 }, - { "aZYXVUT", "bZYXVUT", 1, -1 }, - { "aZYXVUT", "bZYXVUT", 4, -1 }, - { "aZYXVUT", "bZYXVUT", 9, -1 }, - { "aZYXVUT", "bAAAAAA", 0, 0 }, - { "aZYXVUT", "bAAAAAA", 1, -1 }, - { "aZYXVUT", "bAAAAAA", 4, -1 }, - { "aZYXVUT", "bAAAAAA", 5, -1 }, - { "a", "aa", 0, 0 }, - { "a", "aa", 1, 0 }, - { "a", "aa", 4, -1 }, - { "a", "a", 0, 0 }, - { "a", "a", 1, 0 }, - { "a", "a", 4, 0 }, - { "a", "A", 0, 0 }, - { "a", "A", 1, 0 }, - { "a", "A", 4, 0 }, - { "aaaaa", "baaaa", 0, 0 }, - { "aaaaa", "baaaa", 1, -1 }, - { "aaaaa", "baaaa", 4, -1 }, - { "aaaaa", "abaaa", 0, 0 }, - { "aaaaa", "abaaa", 1, 0 }, - { "aaaaa", "abaaa", 4, -1 }, - { "aaaaa", "aabaa", 0, 0 }, - { "aaaaa", "aabaa", 1, 0 }, - { "aaaaa", "aabaa", 4, -1 }, - { "aaaaa", "aaaba", 0, 0 }, - { "aaaaa", "aaaba", 1, 0 }, - { "aaaaa", "aaaba", 4, -1 }, - { "aaaaa", "aaaab", 0, 0 }, - { "aaaaa", "aaaab", 1, 0 }, - { "aaaaa", "aaaab", 4, 0 }, - { "bZYXVUT", "aZYXVUT", 0, 0 }, - { "bZYXVUT", "aZYXVUT", 1, 1 }, - { "bZYXVUT", "aZYXVUT", 4, 1 }, - { "bAAAAAA", "aZYXVUT", 0, 0 }, - { "bAAAAAA", "aZYXVUT", 1, 1 }, - { "bAAAAAA", "aZYXVUT", 4, 1 }, - { "aa", "a", 0, 0 }, - { "aa", "a", 1, 0 }, - { "aa", "a", 4, 1 }, - { "A", "a", 0, 0 }, - { "A", "a", 1, 0 }, - { "A", "a", 4, 0 }, - { "baaaa", "aaaaa", 0, 0 }, - { "baaaa", "aaaaa", 1, 1 }, - { "baaaa", "aaaaa", 4, 1 }, - { "abaaa", "aaaaa", 0, 0 }, - { "abaaa", "aaaaa", 1, 0 }, - { "abaaa", "aaaaa", 4, 1 }, - { "aabaa", "aaaaa", 0, 0 }, - { "aabaa", "aaaaa", 1, 0 }, - { "aabaa", "aaaaa", 4, 1 }, - { "aaaba", "aaaaa", 0, 0 }, - { "aaaba", "aaaaa", 1, 0 }, - { "aaaba", "aaaaa", 4, 1 }, - { "aaaab", "aaaaa", 0, 0 }, - { "aaaab", "aaaaa", 1, 0 }, - { "aaaab", "aaaaa", 4, 0 }, - { "word", "Word", 0, 0 }, - { "word", "Word", 1, 0 }, - { "word", "Word", 3, 0 }, - { "word", "wOrd", 0, 0 }, - { "word", "wOrd", 1, 0 }, - { "word", "wOrd", 3, 0 }, - { "word", "woRd", 0, 0 }, - { "word", "woRd", 1, 0 }, - { "word", "woRd", 3, 0 }, - { "word", "worD", 0, 0 }, - { "word", "worD", 1, 0 }, - { "word", "worD", 3, 0 }, - { "WORD", "wORD", 0, 0 }, - { "WORD", "wORD", 1, 0 }, - { "WORD", "wORD", 3, 0 }, - { "WORD", "WoRD", 0, 0 }, - { "WORD", "WoRD", 1, 0 }, - { "WORD", "WoRD", 3, 0 }, - { "WORD", "WOrD", 0, 0 }, - { "WORD", "WOrD", 1, 0 }, - { "WORD", "WOrD", 3, 0 }, - { "WORD", "WORd", 0, 0 }, - { "WORD", "WORd", 1, 0 }, - { "WORD", "WORd", 3, 0 } - }; - - int i; - - printf("Test 014 (PL_strncasecmp) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - PRIntn rv = PL_strncasecmp(array[i].one, array[i].two, array[i].max); - - switch( array[i].sign ) - { - case -1: - if( rv < 0 ) continue; - break; - case 1: - if( rv > 0 ) continue; - break; - case 0: - if( 0 == rv ) continue; - break; - default: - PR_NOT_REACHED("static data inconsistancy"); - break; - } - - printf("FAIL %d: %s-%s/%ld -> %d, not %d\n", i, - array[i].one ? array[i].one : "(null)", - array[i].two ? array[i].two : "(null)", - array[i].max, rv, array[i].sign); - return PR_FALSE; - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strchr */ -PRBool test_015(void) -{ - static struct - { - const char *str; - char chr; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, 'a', PR_FALSE, 0 }, - { (const char *)0, '\0', PR_FALSE, 0 }, - { "abcdefg", 'a', PR_TRUE, 0 }, - { "abcdefg", 'b', PR_TRUE, 1 }, - { "abcdefg", 'c', PR_TRUE, 2 }, - { "abcdefg", 'd', PR_TRUE, 3 }, - { "abcdefg", 'e', PR_TRUE, 4 }, - { "abcdefg", 'f', PR_TRUE, 5 }, - { "abcdefg", 'g', PR_TRUE, 6 }, - { "abcdefg", 'h', PR_FALSE, 0 }, - { "abcdefg", '\0', PR_TRUE, 7 }, - { "abcdefg", 'A', PR_FALSE, 0 }, - { "abcdefg", 'B', PR_FALSE, 0 }, - { "abcdefg", 'C', PR_FALSE, 0 }, - { "abcdefg", 'D', PR_FALSE, 0 }, - { "abcdefg", 'E', PR_FALSE, 0 }, - { "abcdefg", 'F', PR_FALSE, 0 }, - { "abcdefg", 'G', PR_FALSE, 0 }, - { "abcdefg", 'H', PR_FALSE, 0 }, - { "abcdefgabcdefg", 'a', PR_TRUE, 0 }, - { "abcdefgabcdefg", 'b', PR_TRUE, 1 }, - { "abcdefgabcdefg", 'c', PR_TRUE, 2 }, - { "abcdefgabcdefg", 'd', PR_TRUE, 3 }, - { "abcdefgabcdefg", 'e', PR_TRUE, 4 }, - { "abcdefgabcdefg", 'f', PR_TRUE, 5 }, - { "abcdefgabcdefg", 'g', PR_TRUE, 6 }, - { "abcdefgabcdefg", 'h', PR_FALSE, 0 }, - { "abcdefgabcdefg", '\0', PR_TRUE, 14 } - }; - - int i; - - printf("Test 015 (PL_strchr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strchr(array[i].str, array[i].chr); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%c -> %.32s, not zero\n", i, array[i].str, - array[i].chr, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%c -> null, not +%lu\n", i, array[i].str, - array[i].chr, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%c -> 0x%x, not 0x%x+%lu\n", i, array[i].str, - array[i].chr, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strrchr */ -PRBool test_016(void) -{ - static struct - { - const char *str; - char chr; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, 'a', PR_FALSE, 0 }, - { (const char *)0, '\0', PR_FALSE, 0 }, - { "abcdefg", 'a', PR_TRUE, 0 }, - { "abcdefg", 'b', PR_TRUE, 1 }, - { "abcdefg", 'c', PR_TRUE, 2 }, - { "abcdefg", 'd', PR_TRUE, 3 }, - { "abcdefg", 'e', PR_TRUE, 4 }, - { "abcdefg", 'f', PR_TRUE, 5 }, - { "abcdefg", 'g', PR_TRUE, 6 }, - { "abcdefg", 'h', PR_FALSE, 0 }, - { "abcdefg", '\0', PR_TRUE, 7 }, - { "abcdefg", 'A', PR_FALSE, 0 }, - { "abcdefg", 'B', PR_FALSE, 0 }, - { "abcdefg", 'C', PR_FALSE, 0 }, - { "abcdefg", 'D', PR_FALSE, 0 }, - { "abcdefg", 'E', PR_FALSE, 0 }, - { "abcdefg", 'F', PR_FALSE, 0 }, - { "abcdefg", 'G', PR_FALSE, 0 }, - { "abcdefg", 'H', PR_FALSE, 0 }, - { "abcdefgabcdefg", 'a', PR_TRUE, 7 }, - { "abcdefgabcdefg", 'b', PR_TRUE, 8 }, - { "abcdefgabcdefg", 'c', PR_TRUE, 9 }, - { "abcdefgabcdefg", 'd', PR_TRUE, 10 }, - { "abcdefgabcdefg", 'e', PR_TRUE, 11 }, - { "abcdefgabcdefg", 'f', PR_TRUE, 12 }, - { "abcdefgabcdefg", 'g', PR_TRUE, 13 }, - { "abcdefgabcdefg", 'h', PR_FALSE, 0 }, - { "abcdefgabcdefg", '\0', PR_TRUE, 14 } - }; - - int i; - - printf("Test 016 (PL_strrchr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strrchr(array[i].str, array[i].chr); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%c -> %.32s, not zero\n", i, array[i].str, - array[i].chr, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%c -> null, not +%lu\n", i, array[i].str, - array[i].chr, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%c -> 0x%x, not 0x%x+%lu\n", i, array[i].str, - array[i].chr, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strnchr */ -PRBool test_017(void) -{ - static struct - { - const char *str; - char chr; - PRUint32 max; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, 'a', 2, PR_FALSE, 0 }, - { (const char *)0, '\0', 2, PR_FALSE, 0 }, - { "abcdefg", 'a', 5, PR_TRUE, 0 }, - { "abcdefg", 'b', 5, PR_TRUE, 1 }, - { "abcdefg", 'c', 5, PR_TRUE, 2 }, - { "abcdefg", 'd', 5, PR_TRUE, 3 }, - { "abcdefg", 'e', 5, PR_TRUE, 4 }, - { "abcdefg", 'f', 5, PR_FALSE, 0 }, - { "abcdefg", 'g', 5, PR_FALSE, 0 }, - { "abcdefg", 'h', 5, PR_FALSE, 0 }, - { "abcdefg", '\0', 5, PR_FALSE, 0 }, - { "abcdefg", '\0', 15, PR_TRUE, 7 }, - { "abcdefg", 'A', 5, PR_FALSE, 0 }, - { "abcdefg", 'B', 5, PR_FALSE, 0 }, - { "abcdefg", 'C', 5, PR_FALSE, 0 }, - { "abcdefg", 'D', 5, PR_FALSE, 0 }, - { "abcdefg", 'E', 5, PR_FALSE, 0 }, - { "abcdefg", 'F', 5, PR_FALSE, 0 }, - { "abcdefg", 'G', 5, PR_FALSE, 0 }, - { "abcdefg", 'H', 5, PR_FALSE, 0 }, - { "abcdefgabcdefg", 'a', 10, PR_TRUE, 0 }, - { "abcdefgabcdefg", 'b', 10, PR_TRUE, 1 }, - { "abcdefgabcdefg", 'c', 10, PR_TRUE, 2 }, - { "abcdefgabcdefg", 'd', 10, PR_TRUE, 3 }, - { "abcdefgabcdefg", 'e', 10, PR_TRUE, 4 }, - { "abcdefgabcdefg", 'f', 10, PR_TRUE, 5 }, - { "abcdefgabcdefg", 'g', 10, PR_TRUE, 6 }, - { "abcdefgabcdefg", 'h', 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", '\0', 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", '\0', 14, PR_FALSE, 0 }, - { "abcdefgabcdefg", '\0', 15, PR_TRUE, 14 } - }; - - int i; - - printf("Test 017 (PL_strnchr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strnchr(array[i].str, array[i].chr, array[i].max); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%c/%lu -> %.32s, not zero\n", i, array[i].str, - array[i].chr, array[i].max, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%c/%lu -> null, not +%lu\n", i, array[i].str, - array[i].chr, array[i].max, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%c/%lu -> 0x%x, not 0x%x+%lu\n", i, array[i].str, - array[i].chr, array[i].max, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strnrchr */ -PRBool test_018(void) -{ - static struct - { - const char *str; - char chr; - PRUint32 max; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, 'a', 2, PR_FALSE, 0 }, - { (const char *)0, '\0', 2, PR_FALSE, 0 }, - { "abcdefg", 'a', 5, PR_TRUE, 0 }, - { "abcdefg", 'b', 5, PR_TRUE, 1 }, - { "abcdefg", 'c', 5, PR_TRUE, 2 }, - { "abcdefg", 'd', 5, PR_TRUE, 3 }, - { "abcdefg", 'e', 5, PR_TRUE, 4 }, - { "abcdefg", 'f', 5, PR_FALSE, 0 }, - { "abcdefg", 'g', 5, PR_FALSE, 0 }, - { "abcdefg", 'h', 5, PR_FALSE, 0 }, - { "abcdefg", '\0', 5, PR_FALSE, 0 }, - { "abcdefg", '\0', 15, PR_TRUE, 7 }, - { "abcdefg", 'A', 5, PR_FALSE, 0 }, - { "abcdefg", 'B', 5, PR_FALSE, 0 }, - { "abcdefg", 'C', 5, PR_FALSE, 0 }, - { "abcdefg", 'D', 5, PR_FALSE, 0 }, - { "abcdefg", 'E', 5, PR_FALSE, 0 }, - { "abcdefg", 'F', 5, PR_FALSE, 0 }, - { "abcdefg", 'G', 5, PR_FALSE, 0 }, - { "abcdefg", 'H', 5, PR_FALSE, 0 }, - { "abcdefgabcdefg", 'a', 10, PR_TRUE, 7 }, - { "abcdefgabcdefg", 'b', 10, PR_TRUE, 8 }, - { "abcdefgabcdefg", 'c', 10, PR_TRUE, 9 }, - { "abcdefgabcdefg", 'd', 10, PR_TRUE, 3 }, - { "abcdefgabcdefg", 'e', 10, PR_TRUE, 4 }, - { "abcdefgabcdefg", 'f', 10, PR_TRUE, 5 }, - { "abcdefgabcdefg", 'g', 10, PR_TRUE, 6 }, - { "abcdefgabcdefg", 'h', 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", '\0', 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", '\0', 14, PR_FALSE, 0 }, - { "abcdefgabcdefg", '\0', 15, PR_TRUE, 14 } - }; - - int i; - - printf("Test 018 (PL_strnrchr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strnrchr(array[i].str, array[i].chr, array[i].max); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%c/%lu -> %.32s, not zero\n", i, array[i].str, - array[i].chr, array[i].max, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%c/%lu -> null, not +%lu\n", i, array[i].str, - array[i].chr, array[i].max, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%c/%lu -> 0x%x, not 0x%x+%lu\n", i, array[i].str, - array[i].chr, array[i].max, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strpbrk */ -PRBool test_019(void) -{ - static struct - { - const char *str; - const char *chrs; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, PR_FALSE, 0 }, - { (const char *)0, "abc", PR_FALSE, 0 }, - { "abc", (const char *)0, PR_FALSE, 0 }, - { "abcdefg", "", PR_FALSE, 0 }, - { "", "aeiou", PR_FALSE, 0 }, - { "abcdefg", "ae", PR_TRUE, 0 }, - { "abcdefg", "ei", PR_TRUE, 4 }, - { "abcdefg", "io", PR_FALSE, 0 }, - { "abcdefg", "bcd", PR_TRUE, 1 }, - { "abcdefg", "cbd", PR_TRUE, 1 }, - { "abcdefg", "dbc", PR_TRUE, 1 }, - { "abcdefg", "ghi", PR_TRUE, 6 }, - { "abcdefg", "AE", PR_FALSE, 0 }, - { "abcdefg", "EI", PR_FALSE, 0 }, - { "abcdefg", "IO", PR_FALSE, 0 }, - { "abcdefg", "BCD", PR_FALSE, 0 }, - { "abcdefg", "CBD", PR_FALSE, 0 }, - { "abcdefg", "DBC", PR_FALSE, 0 }, - { "abcdefg", "GHI", PR_FALSE, 0 }, - { "abcdefgabcdefg", "ae", PR_TRUE, 0 }, - { "abcdefgabcdefg", "ei", PR_TRUE, 4 }, - { "abcdefgabcdefg", "io", PR_FALSE, 0 }, - { "abcdefgabcdefg", "bcd", PR_TRUE, 1 }, - { "abcdefgabcdefg", "cbd", PR_TRUE, 1 }, - { "abcdefgabcdefg", "dbc", PR_TRUE, 1 }, - { "abcdefgabcdefg", "ghi", PR_TRUE, 6 }, - { "abcdefgabcdefg", "AE", PR_FALSE, 0 }, - { "abcdefgabcdefg", "EI", PR_FALSE, 0 }, - { "abcdefgabcdefg", "IO", PR_FALSE, 0 }, - { "abcdefgabcdefg", "BCD", PR_FALSE, 0 }, - { "abcdefgabcdefg", "CBD", PR_FALSE, 0 }, - { "abcdefgabcdefg", "DBC", PR_FALSE, 0 }, - { "abcdefgabcdefg", "GHI", PR_FALSE, 0 } - }; - - int i; - - printf("Test 019 (PL_strpbrk) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strpbrk(array[i].str, array[i].chrs); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s -> null, not +%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strprbrk */ -PRBool test_020(void) -{ - static struct - { - const char *str; - const char *chrs; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, PR_FALSE, 0 }, - { (const char *)0, "abc", PR_FALSE, 0 }, - { "abc", (const char *)0, PR_FALSE, 0 }, - { "abcdefg", "", PR_FALSE, 0 }, - { "", "aeiou", PR_FALSE, 0 }, - { "abcdefg", "ae", PR_TRUE, 4 }, - { "abcdefg", "ei", PR_TRUE, 4 }, - { "abcdefg", "io", PR_FALSE, 0 }, - { "abcdefg", "bcd", PR_TRUE, 3 }, - { "abcdefg", "cbd", PR_TRUE, 3 }, - { "abcdefg", "dbc", PR_TRUE, 3 }, - { "abcdefg", "ghi", PR_TRUE, 6 }, - { "abcdefg", "AE", PR_FALSE, 0 }, - { "abcdefg", "EI", PR_FALSE, 0 }, - { "abcdefg", "IO", PR_FALSE, 0 }, - { "abcdefg", "BCD", PR_FALSE, 0 }, - { "abcdefg", "CBD", PR_FALSE, 0 }, - { "abcdefg", "DBC", PR_FALSE, 0 }, - { "abcdefg", "GHI", PR_FALSE, 0 }, - { "abcdefgabcdefg", "ae", PR_TRUE, 11 }, - { "abcdefgabcdefg", "ei", PR_TRUE, 11 }, - { "abcdefgabcdefg", "io", PR_FALSE, 0 }, - { "abcdefgabcdefg", "bcd", PR_TRUE, 10 }, - { "abcdefgabcdefg", "cbd", PR_TRUE, 10 }, - { "abcdefgabcdefg", "dbc", PR_TRUE, 10 }, - { "abcdefgabcdefg", "ghi", PR_TRUE, 13 }, - { "abcdefgabcdefg", "AE", PR_FALSE, 0 }, - { "abcdefgabcdefg", "EI", PR_FALSE, 0 }, - { "abcdefgabcdefg", "IO", PR_FALSE, 0 }, - { "abcdefgabcdefg", "BCD", PR_FALSE, 0 }, - { "abcdefgabcdefg", "CBD", PR_FALSE, 0 }, - { "abcdefgabcdefg", "DBC", PR_FALSE, 0 }, - { "abcdefgabcdefg", "GHI", PR_FALSE, 0 } - }; - - int i; - - printf("Test 020 (PL_strprbrk) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strprbrk(array[i].str, array[i].chrs); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s -> null, not +%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strnpbrk */ -PRBool test_021(void) -{ - static struct - { - const char *str; - const char *chrs; - PRUint32 max; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, 3, PR_FALSE, 0 }, - { (const char *)0, "abc", 3, PR_FALSE, 0 }, - { "abc", (const char *)0, 3, PR_FALSE, 0 }, - { "abcdefg", "", 3, PR_FALSE, 0 }, - { "", "aeiou", 3, PR_FALSE, 0 }, - { "abcdefg", "ae", 0, PR_FALSE, 0 }, - { "abcdefg", "ae", 1, PR_TRUE, 0 }, - { "abcdefg", "ae", 4, PR_TRUE, 0 }, - { "abcdefg", "ae", 5, PR_TRUE, 0 }, - { "abcdefg", "ae", 6, PR_TRUE, 0 }, - { "abcdefg", "ei", 4, PR_FALSE, 0 }, - { "abcdefg", "io", 10, PR_FALSE, 0 }, - { "abcdefg", "bcd", 2, PR_TRUE, 1 }, - { "abcdefg", "cbd", 2, PR_TRUE, 1 }, - { "abcdefg", "dbc", 2, PR_TRUE, 1 }, - { "abcdefg", "ghi", 6, PR_FALSE, 0 }, - { "abcdefg", "ghi", 7, PR_TRUE, 6 }, - { "abcdefg", "AE", 9, PR_FALSE, 0 }, - { "abcdefg", "EI", 9, PR_FALSE, 0 }, - { "abcdefg", "IO", 9, PR_FALSE, 0 }, - { "abcdefg", "BCD", 9, PR_FALSE, 0 }, - { "abcdefg", "CBD", 9, PR_FALSE, 0 }, - { "abcdefg", "DBC", 9, PR_FALSE, 0 }, - { "abcdefg", "GHI", 9, PR_FALSE, 0 }, - { "abcdefgabcdefg", "ae", 10, PR_TRUE, 0 }, - { "abcdefgabcdefg", "ei", 10, PR_TRUE, 4 }, - { "abcdefgabcdefg", "io", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "bcd", 10, PR_TRUE, 1 }, - { "abcdefgabcdefg", "cbd", 10, PR_TRUE, 1 }, - { "abcdefgabcdefg", "dbc", 10, PR_TRUE, 1 }, - { "abcdefgabcdefg", "ghi", 10, PR_TRUE, 6 }, - { "abcdefgabcdefg", "AE", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "EI", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "IO", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "BCD", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "CBD", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "DBC", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "GHI", 10, PR_FALSE, 0 } - }; - - int i; - - printf("Test 021 (PL_strnpbrk) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strnpbrk(array[i].str, array[i].chrs, array[i].max); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - array[i].max, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s/%lu -> null, not +%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - array[i].max, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - array[i].max, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strnprbrk */ -PRBool test_022(void) -{ - static struct - { - const char *str; - const char *chrs; - PRUint32 max; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, 3, PR_FALSE, 0 }, - { (const char *)0, "abc", 3, PR_FALSE, 0 }, - { "abc", (const char *)0, 3, PR_FALSE, 0 }, - { "abcdefg", "", 3, PR_FALSE, 0 }, - { "", "aeiou", 3, PR_FALSE, 0 }, - { "abcdefg", "ae", 0, PR_FALSE, 0 }, - { "abcdefg", "ae", 1, PR_TRUE, 0 }, - { "abcdefg", "ae", 4, PR_TRUE, 0 }, - { "abcdefg", "ae", 5, PR_TRUE, 4 }, - { "abcdefg", "ae", 6, PR_TRUE, 4 }, - { "abcdefg", "ei", 4, PR_FALSE, 0 }, - { "abcdefg", "io", 10, PR_FALSE, 0 }, - { "abcdefg", "bcd", 2, PR_TRUE, 1 }, - { "abcdefg", "cbd", 2, PR_TRUE, 1 }, - { "abcdefg", "dbc", 2, PR_TRUE, 1 }, - { "abcdefg", "bcd", 3, PR_TRUE, 2 }, - { "abcdefg", "cbd", 3, PR_TRUE, 2 }, - { "abcdefg", "dbc", 3, PR_TRUE, 2 }, - { "abcdefg", "bcd", 5, PR_TRUE, 3 }, - { "abcdefg", "cbd", 5, PR_TRUE, 3 }, - { "abcdefg", "dbc", 5, PR_TRUE, 3 }, - { "abcdefg", "bcd", 15, PR_TRUE, 3 }, - { "abcdefg", "cbd", 15, PR_TRUE, 3 }, - { "abcdefg", "dbc", 15, PR_TRUE, 3 }, - { "abcdefg", "ghi", 6, PR_FALSE, 0 }, - { "abcdefg", "ghi", 7, PR_TRUE, 6 }, - { "abcdefg", "AE", 9, PR_FALSE, 0 }, - { "abcdefg", "EI", 9, PR_FALSE, 0 }, - { "abcdefg", "IO", 9, PR_FALSE, 0 }, - { "abcdefg", "BCD", 9, PR_FALSE, 0 }, - { "abcdefg", "CBD", 9, PR_FALSE, 0 }, - { "abcdefg", "DBC", 9, PR_FALSE, 0 }, - { "abcdefg", "GHI", 9, PR_FALSE, 0 }, - { "abcdefgabcdefg", "ae", 10, PR_TRUE, 7 }, - { "abcdefgabcdefg", "ei", 10, PR_TRUE, 4 }, - { "abcdefgabcdefg", "io", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "bcd", 10, PR_TRUE, 9 }, - { "abcdefgabcdefg", "cbd", 10, PR_TRUE, 9 }, - { "abcdefgabcdefg", "dbc", 10, PR_TRUE, 9 }, - { "abcdefgabcdefg", "ghi", 10, PR_TRUE, 6 }, - { "abcdefgabcdefg", "AE", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "EI", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "IO", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "BCD", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "CBD", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "DBC", 10, PR_FALSE, 0 }, - { "abcdefgabcdefg", "GHI", 10, PR_FALSE, 0 } - }; - - int i; - - printf("Test 022 (PL_strnprbrk) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strnprbrk(array[i].str, array[i].chrs, array[i].max); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - array[i].max, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s/%lu -> null, not +%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - array[i].max, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].chrs ? array[i].chrs : "(null)", - array[i].max, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strstr */ -PRBool test_023(void) -{ - static struct - { - const char *str; - const char *sub; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, PR_FALSE, 0 }, - { (const char *)0, "blah", PR_FALSE, 0 }, - { "blah-de-blah", (const char *)0, PR_FALSE, 0 }, - { "blah-de-blah", "blah", PR_TRUE, 0 }, - { "", "blah", PR_FALSE, 0 }, - { "blah-de-blah", "", PR_FALSE, 0 }, - { "abcdefg", "a", PR_TRUE, 0 }, - { "abcdefg", "c", PR_TRUE, 2 }, - { "abcdefg", "e", PR_TRUE, 4 }, - { "abcdefg", "g", PR_TRUE, 6 }, - { "abcdefg", "i", PR_FALSE, 0 }, - { "abcdefg", "ab", PR_TRUE, 0 }, - { "abcdefg", "cd", PR_TRUE, 2 }, - { "abcdefg", "ef", PR_TRUE, 4 }, - { "abcdefg", "gh", PR_FALSE, 0 }, - { "abcdabc", "bc", PR_TRUE, 1 }, - { "abcdefg", "abcdefg", PR_TRUE, 0 }, - { "abcdefgabcdefg", "a", PR_TRUE, 0 }, - { "abcdefgabcdefg", "c", PR_TRUE, 2 }, - { "abcdefgabcdefg", "e", PR_TRUE, 4 }, - { "abcdefgabcdefg", "g", PR_TRUE, 6 }, - { "abcdefgabcdefg", "i", PR_FALSE, 0 }, - { "abcdefgabcdefg", "ab", PR_TRUE, 0 }, - { "abcdefgabcdefg", "cd", PR_TRUE, 2 }, - { "abcdefgabcdefg", "ef", PR_TRUE, 4 }, - { "abcdefgabcdefg", "gh", PR_FALSE, 0 }, - { "abcdabcabcdabc", "bc", PR_TRUE, 1 }, - { "abcdefgabcdefg", "abcdefg", PR_TRUE, 0 }, - { "ABCDEFG", "a", PR_FALSE, 0 }, - { "ABCDEFG", "c", PR_FALSE, 0 }, - { "ABCDEFG", "e", PR_FALSE, 0 }, - { "ABCDEFG", "g", PR_FALSE, 0 }, - { "ABCDEFG", "i", PR_FALSE, 0 }, - { "ABCDEFG", "ab", PR_FALSE, 0 }, - { "ABCDEFG", "cd", PR_FALSE, 0 }, - { "ABCDEFG", "ef", PR_FALSE, 0 }, - { "ABCDEFG", "gh", PR_FALSE, 0 }, - { "ABCDABC", "bc", PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "a", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "c", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "e", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "g", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ab", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "cd", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ef", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", PR_FALSE, 0 } - }; - - int i; - - printf("Test 023 (PL_strstr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strstr(array[i].str, array[i].sub); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].str, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strrstr */ -PRBool test_024(void) -{ - static struct - { - const char *str; - const char *sub; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, PR_FALSE, 0 }, - { (const char *)0, "blah", PR_FALSE, 0 }, - { "blah-de-blah", (const char *)0, PR_FALSE, 0 }, - { "blah-de-blah", "blah", PR_TRUE, 8 }, - { "", "blah", PR_FALSE, 0 }, - { "blah-de-blah", "", PR_FALSE, 0 }, - { "abcdefg", "a", PR_TRUE, 0 }, - { "abcdefg", "c", PR_TRUE, 2 }, - { "abcdefg", "e", PR_TRUE, 4 }, - { "abcdefg", "g", PR_TRUE, 6 }, - { "abcdefg", "i", PR_FALSE, 0 }, - { "abcdefg", "ab", PR_TRUE, 0 }, - { "abcdefg", "cd", PR_TRUE, 2 }, - { "abcdefg", "ef", PR_TRUE, 4 }, - { "abcdefg", "gh", PR_FALSE, 0 }, - { "abcdabc", "bc", PR_TRUE, 5 }, - { "abcdefg", "abcdefg", PR_TRUE, 0 }, - { "abcdefgabcdefg", "a", PR_TRUE, 7 }, - { "abcdefgabcdefg", "c", PR_TRUE, 9 }, - { "abcdefgabcdefg", "e", PR_TRUE, 11 }, - { "abcdefgabcdefg", "g", PR_TRUE, 13 }, - { "abcdefgabcdefg", "i", PR_FALSE, 0 }, - { "abcdefgabcdefg", "ab", PR_TRUE, 7 }, - { "abcdefgabcdefg", "cd", PR_TRUE, 9 }, - { "abcdefgabcdefg", "ef", PR_TRUE, 11 }, - { "abcdefgabcdefg", "gh", PR_FALSE, 0 }, - { "abcdabcabcdabc", "bc", PR_TRUE, 12 }, - { "abcdefgabcdefg", "abcdefg", PR_TRUE, 7 }, - { "ABCDEFG", "a", PR_FALSE, 0 }, - { "ABCDEFG", "c", PR_FALSE, 0 }, - { "ABCDEFG", "e", PR_FALSE, 0 }, - { "ABCDEFG", "g", PR_FALSE, 0 }, - { "ABCDEFG", "i", PR_FALSE, 0 }, - { "ABCDEFG", "ab", PR_FALSE, 0 }, - { "ABCDEFG", "cd", PR_FALSE, 0 }, - { "ABCDEFG", "ef", PR_FALSE, 0 }, - { "ABCDEFG", "gh", PR_FALSE, 0 }, - { "ABCDABC", "bc", PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "a", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "c", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "e", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "g", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ab", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "cd", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ef", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", PR_FALSE, 0 } - }; - - int i; - - printf("Test 024 (PL_strrstr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strrstr(array[i].str, array[i].sub); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].str, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strnstr */ -PRBool test_025(void) -{ - static struct - { - const char *str; - const char *sub; - PRUint32 max; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, 12, PR_FALSE, 0 }, - { (const char *)0, "blah", 12, PR_FALSE, 0 }, - { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 0, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 2, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 3, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 4, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 5, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 12, PR_TRUE, 0 }, - { "", "blah", 12, PR_FALSE, 0 }, - { "blah-de-blah", "", 12, PR_FALSE, 0 }, - { "abcdefg", "a", 5, PR_TRUE, 0 }, - { "abcdefg", "c", 5, PR_TRUE, 2 }, - { "abcdefg", "e", 5, PR_TRUE, 4 }, - { "abcdefg", "g", 5, PR_FALSE, 0 }, - { "abcdefg", "i", 5, PR_FALSE, 0 }, - { "abcdefg", "ab", 5, PR_TRUE, 0 }, - { "abcdefg", "cd", 5, PR_TRUE, 2 }, - { "abcdefg", "ef", 5, PR_FALSE, 0 }, - { "abcdefg", "gh", 5, PR_FALSE, 0 }, - { "abcdabc", "bc", 5, PR_TRUE, 1 }, - { "abcdabc", "bc", 6, PR_TRUE, 1 }, - { "abcdabc", "bc", 7, PR_TRUE, 1 }, - { "abcdefg", "abcdefg", 6, PR_FALSE, 0 }, - { "abcdefg", "abcdefg", 7, PR_TRUE, 0 }, - { "abcdefg", "abcdefg", 8, PR_TRUE, 0 }, - { "abcdefgabcdefg", "a", 12, PR_TRUE, 0 }, - { "abcdefgabcdefg", "c", 12, PR_TRUE, 2 }, - { "abcdefgabcdefg", "e", 12, PR_TRUE, 4 }, - { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 }, - { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 }, - { "abcdefgabcdefg", "ab", 12, PR_TRUE, 0 }, - { "abcdefgabcdefg", "cd", 12, PR_TRUE, 2 }, - { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 }, - { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 }, - { "abcdabcabcdabc", "bc", 5, PR_TRUE, 1 }, - { "abcdabcabcdabc", "bc", 6, PR_TRUE, 1 }, - { "abcdabcabcdabc", "bc", 7, PR_TRUE, 1 }, - { "abcdefgabcdefg", "abcdefg", 6, PR_FALSE, 0 }, - { "abcdefgabcdefg", "abcdefg", 7, PR_TRUE, 0 }, - { "abcdefgabcdefg", "abcdefg", 8, PR_TRUE, 0 }, - { "ABCDEFG", "a", 5, PR_FALSE, 0 }, - { "ABCDEFG", "c", 5, PR_FALSE, 0 }, - { "ABCDEFG", "e", 5, PR_FALSE, 0 }, - { "ABCDEFG", "g", 5, PR_FALSE, 0 }, - { "ABCDEFG", "i", 5, PR_FALSE, 0 }, - { "ABCDEFG", "ab", 5, PR_FALSE, 0 }, - { "ABCDEFG", "cd", 5, PR_FALSE, 0 }, - { "ABCDEFG", "ef", 5, PR_FALSE, 0 }, - { "ABCDEFG", "gh", 5, PR_FALSE, 0 }, - { "ABCDABC", "bc", 5, PR_FALSE, 0 }, - { "ABCDABC", "bc", 6, PR_FALSE, 0 }, - { "ABCDABC", "bc", 7, PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", 7, PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", 8, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "a", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "c", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "e", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "g", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ab", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "cd", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ef", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", 5, PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", 6, PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", 7, PR_FALSE, }, - { "ABCDEFGABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", 7, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", 8, PR_FALSE, 0 } - }; - - int i; - - printf("Test 025 (PL_strnstr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strnstr(array[i].str, array[i].sub, array[i].max); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, array[i].str, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strnrstr */ -PRBool test_026(void) -{ - static struct - { - const char *str; - const char *sub; - PRUint32 max; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, 12, PR_FALSE, 0 }, - { (const char *)0, "blah", 12, PR_FALSE, 0 }, - { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 0, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 2, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 3, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 4, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 5, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 11, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 12, PR_TRUE, 8 }, - { "blah-de-blah", "blah", 13, PR_TRUE, 8 }, - { "", "blah", 12, PR_FALSE, 0 }, - { "blah-de-blah", "", 12, PR_FALSE, 0 }, - { "abcdefg", "a", 5, PR_TRUE, 0 }, - { "abcdefg", "c", 5, PR_TRUE, 2 }, - { "abcdefg", "e", 5, PR_TRUE, 4 }, - { "abcdefg", "g", 5, PR_FALSE, 0 }, - { "abcdefg", "i", 5, PR_FALSE, 0 }, - { "abcdefg", "ab", 5, PR_TRUE, 0 }, - { "abcdefg", "cd", 5, PR_TRUE, 2 }, - { "abcdefg", "ef", 5, PR_FALSE, 0 }, - { "abcdefg", "gh", 5, PR_FALSE, 0 }, - { "abcdabc", "bc", 5, PR_TRUE, 1 }, - { "abcdabc", "bc", 6, PR_TRUE, 1 }, - { "abcdabc", "bc", 7, PR_TRUE, 5 }, - { "abcdefg", "abcdefg", 6, PR_FALSE, 0 }, - { "abcdefg", "abcdefg", 7, PR_TRUE, 0 }, - { "abcdefg", "abcdefg", 8, PR_TRUE, 0 }, - { "abcdefgabcdefg", "a", 12, PR_TRUE, 7 }, - { "abcdefgabcdefg", "c", 12, PR_TRUE, 9 }, - { "abcdefgabcdefg", "e", 12, PR_TRUE, 11 }, - { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 }, - { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 }, - { "abcdefgabcdefg", "ab", 12, PR_TRUE, 7 }, - { "abcdefgabcdefg", "cd", 12, PR_TRUE, 9 }, - { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 }, - { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 }, - { "abcdabcabcdabc", "bc", 12, PR_TRUE, 8 }, - { "abcdabcabcdabc", "bc", 13, PR_TRUE, 8 }, - { "abcdabcabcdabc", "bc", 14, PR_TRUE, 12 }, - { "abcdefgabcdefg", "abcdefg", 13, PR_TRUE, 0 }, - { "abcdefgabcdefg", "abcdefg", 14, PR_TRUE, 7 }, - { "abcdefgabcdefg", "abcdefg", 15, PR_TRUE, 7 }, - { "ABCDEFG", "a", 5, PR_FALSE, 0 }, - { "ABCDEFG", "c", 5, PR_FALSE, 0 }, - { "ABCDEFG", "e", 5, PR_FALSE, 0 }, - { "ABCDEFG", "g", 5, PR_FALSE, 0 }, - { "ABCDEFG", "i", 5, PR_FALSE, 0 }, - { "ABCDEFG", "ab", 5, PR_FALSE, 0 }, - { "ABCDEFG", "cd", 5, PR_FALSE, 0 }, - { "ABCDEFG", "ef", 5, PR_FALSE, 0 }, - { "ABCDEFG", "gh", 5, PR_FALSE, 0 }, - { "ABCDABC", "bc", 5, PR_FALSE, 0 }, - { "ABCDABC", "bc", 6, PR_FALSE, 0 }, - { "ABCDABC", "bc", 7, PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", 7, PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", 8, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "a", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "c", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "e", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "g", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ab", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "cd", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ef", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", 12, PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", 13, PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", 14, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", 13, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", 14, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", 15, PR_FALSE, 0 } - }; - - int i; - - printf("Test 026 (PL_strnrstr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strnrstr(array[i].str, array[i].sub, array[i].max); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, array[i].str, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strcasestr */ -PRBool test_027(void) -{ - static struct - { - const char *str; - const char *sub; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, PR_FALSE, 0 }, - { (const char *)0, "blah", PR_FALSE, 0 }, - { "blah-de-blah", (const char *)0, PR_FALSE, 0 }, - { "blah-de-blah", "blah", PR_TRUE, 0 }, - { "", "blah", PR_FALSE, 0 }, - { "blah-de-blah", "", PR_FALSE, 0 }, - { "abcdefg", "a", PR_TRUE, 0 }, - { "abcdefg", "c", PR_TRUE, 2 }, - { "abcdefg", "e", PR_TRUE, 4 }, - { "abcdefg", "g", PR_TRUE, 6 }, - { "abcdefg", "i", PR_FALSE, 0 }, - { "abcdefg", "ab", PR_TRUE, 0 }, - { "abcdefg", "cd", PR_TRUE, 2 }, - { "abcdefg", "ef", PR_TRUE, 4 }, - { "abcdefg", "gh", PR_FALSE, 0 }, - { "abcdabc", "bc", PR_TRUE, 1 }, - { "abcdefg", "abcdefg", PR_TRUE, 0 }, - { "abcdefgabcdefg", "a", PR_TRUE, 0 }, - { "abcdefgabcdefg", "c", PR_TRUE, 2 }, - { "abcdefgabcdefg", "e", PR_TRUE, 4 }, - { "abcdefgabcdefg", "g", PR_TRUE, 6 }, - { "abcdefgabcdefg", "i", PR_FALSE, 0 }, - { "abcdefgabcdefg", "ab", PR_TRUE, 0 }, - { "abcdefgabcdefg", "cd", PR_TRUE, 2 }, - { "abcdefgabcdefg", "ef", PR_TRUE, 4 }, - { "abcdefgabcdefg", "gh", PR_FALSE, 0 }, - { "abcdabcabcdabc", "bc", PR_TRUE, 1 }, - { "abcdefgabcdefg", "abcdefg", PR_TRUE, 0 }, - { "ABCDEFG", "a", PR_TRUE, 0 }, - { "ABCDEFG", "c", PR_TRUE, 2 }, - { "ABCDEFG", "e", PR_TRUE, 4 }, - { "ABCDEFG", "g", PR_TRUE, 6 }, - { "ABCDEFG", "i", PR_FALSE, 0 }, - { "ABCDEFG", "ab", PR_TRUE, 0 }, - { "ABCDEFG", "cd", PR_TRUE, 2 }, - { "ABCDEFG", "ef", PR_TRUE, 4 }, - { "ABCDEFG", "gh", PR_FALSE, 0 }, - { "ABCDABC", "bc", PR_TRUE, 1 }, - { "ABCDEFG", "abcdefg", PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "a", PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "c", PR_TRUE, 2 }, - { "ABCDEFGABCDEFG", "e", PR_TRUE, 4 }, - { "ABCDEFGABCDEFG", "g", PR_TRUE, 6 }, - { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ab", PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "cd", PR_TRUE, 2 }, - { "ABCDEFGABCDEFG", "ef", PR_TRUE, 4 }, - { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", PR_TRUE, 1 }, - { "ABCDEFGABCDEFG", "abcdefg", PR_TRUE, 0 } - }; - - int i; - - printf("Test 027 (PL_strcasestr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strcasestr(array[i].str, array[i].sub); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].str, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strcaserstr */ -PRBool test_028(void) -{ - static struct - { - const char *str; - const char *sub; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, PR_FALSE, 0 }, - { (const char *)0, "blah", PR_FALSE, 0 }, - { "blah-de-blah", (const char *)0, PR_FALSE, 0 }, - { "blah-de-blah", "blah", PR_TRUE, 8 }, - { "", "blah", PR_FALSE, 0 }, - { "blah-de-blah", "", PR_FALSE, 0 }, - { "abcdefg", "a", PR_TRUE, 0 }, - { "abcdefg", "c", PR_TRUE, 2 }, - { "abcdefg", "e", PR_TRUE, 4 }, - { "abcdefg", "g", PR_TRUE, 6 }, - { "abcdefg", "i", PR_FALSE, 0 }, - { "abcdefg", "ab", PR_TRUE, 0 }, - { "abcdefg", "cd", PR_TRUE, 2 }, - { "abcdefg", "ef", PR_TRUE, 4 }, - { "abcdefg", "gh", PR_FALSE, 0 }, - { "abcdabc", "bc", PR_TRUE, 5 }, - { "abcdefg", "abcdefg", PR_TRUE, 0 }, - { "abcdefgabcdefg", "a", PR_TRUE, 7 }, - { "abcdefgabcdefg", "c", PR_TRUE, 9 }, - { "abcdefgabcdefg", "e", PR_TRUE, 11 }, - { "abcdefgabcdefg", "g", PR_TRUE, 13 }, - { "abcdefgabcdefg", "i", PR_FALSE, 0 }, - { "abcdefgabcdefg", "ab", PR_TRUE, 7 }, - { "abcdefgabcdefg", "cd", PR_TRUE, 9 }, - { "abcdefgabcdefg", "ef", PR_TRUE, 11 }, - { "abcdefgabcdefg", "gh", PR_FALSE, 0 }, - { "abcdabcabcdabc", "bc", PR_TRUE, 12 }, - { "abcdefgabcdefg", "abcdefg", PR_TRUE, 7 }, - { "ABCDEFG", "a", PR_TRUE, 0 }, - { "ABCDEFG", "c", PR_TRUE, 2 }, - { "ABCDEFG", "e", PR_TRUE, 4 }, - { "ABCDEFG", "g", PR_TRUE, 6 }, - { "ABCDEFG", "i", PR_FALSE, 0 }, - { "ABCDEFG", "ab", PR_TRUE, 0 }, - { "ABCDEFG", "cd", PR_TRUE, 2 }, - { "ABCDEFG", "ef", PR_TRUE, 4 }, - { "ABCDEFG", "gh", PR_FALSE, 0 }, - { "ABCDABC", "bc", PR_TRUE, 5 }, - { "ABCDEFG", "abcdefg", PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "a", PR_TRUE, 7 }, - { "ABCDEFGABCDEFG", "c", PR_TRUE, 9 }, - { "ABCDEFGABCDEFG", "e", PR_TRUE, 11 }, - { "ABCDEFGABCDEFG", "g", PR_TRUE, 13 }, - { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ab", PR_TRUE, 7 }, - { "ABCDEFGABCDEFG", "cd", PR_TRUE, 9 }, - { "ABCDEFGABCDEFG", "ef", PR_TRUE, 11 }, - { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", PR_TRUE, 12 }, - { "ABCDEFGABCDEFG", "abcdefg", PR_TRUE, 7 } - }; - - int i; - - printf("Test 028 (PL_strcaserstr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strcaserstr(array[i].str, array[i].sub); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].str, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strncasestr */ -PRBool test_029(void) -{ - static struct - { - const char *str; - const char *sub; - PRUint32 max; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, 12, PR_FALSE, 0 }, - { (const char *)0, "blah", 12, PR_FALSE, 0 }, - { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 0, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 2, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 3, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 4, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 5, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 12, PR_TRUE, 0 }, - { "", "blah", 12, PR_FALSE, 0 }, - { "blah-de-blah", "", 12, PR_FALSE, 0 }, - { "abcdefg", "a", 5, PR_TRUE, 0 }, - { "abcdefg", "c", 5, PR_TRUE, 2 }, - { "abcdefg", "e", 5, PR_TRUE, 4 }, - { "abcdefg", "g", 5, PR_FALSE, 0 }, - { "abcdefg", "i", 5, PR_FALSE, 0 }, - { "abcdefg", "ab", 5, PR_TRUE, 0 }, - { "abcdefg", "cd", 5, PR_TRUE, 2 }, - { "abcdefg", "ef", 5, PR_FALSE, 0 }, - { "abcdefg", "gh", 5, PR_FALSE, 0 }, - { "abcdabc", "bc", 5, PR_TRUE, 1 }, - { "abcdabc", "bc", 6, PR_TRUE, 1 }, - { "abcdabc", "bc", 7, PR_TRUE, 1 }, - { "abcdefg", "abcdefg", 6, PR_FALSE, 0 }, - { "abcdefg", "abcdefg", 7, PR_TRUE, 0 }, - { "abcdefg", "abcdefg", 8, PR_TRUE, 0 }, - { "abcdefgabcdefg", "a", 12, PR_TRUE, 0 }, - { "abcdefgabcdefg", "c", 12, PR_TRUE, 2 }, - { "abcdefgabcdefg", "e", 12, PR_TRUE, 4 }, - { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 }, - { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 }, - { "abcdefgabcdefg", "ab", 12, PR_TRUE, 0 }, - { "abcdefgabcdefg", "cd", 12, PR_TRUE, 2 }, - { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 }, - { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 }, - { "abcdabcabcdabc", "bc", 5, PR_TRUE, 1 }, - { "abcdabcabcdabc", "bc", 6, PR_TRUE, 1 }, - { "abcdabcabcdabc", "bc", 7, PR_TRUE, 1 }, - { "abcdefgabcdefg", "abcdefg", 6, PR_FALSE, 0 }, - { "abcdefgabcdefg", "abcdefg", 7, PR_TRUE, 0 }, - { "abcdefgabcdefg", "abcdefg", 8, PR_TRUE, 0 }, - { "ABCDEFG", "a", 5, PR_TRUE, 0 }, - { "ABCDEFG", "c", 5, PR_TRUE, 2 }, - { "ABCDEFG", "e", 5, PR_TRUE, 4 }, - { "ABCDEFG", "g", 5, PR_FALSE, 0 }, - { "ABCDEFG", "i", 5, PR_FALSE, 0 }, - { "ABCDEFG", "ab", 5, PR_TRUE, 0 }, - { "ABCDEFG", "cd", 5, PR_TRUE, 2 }, - { "ABCDEFG", "ef", 5, PR_FALSE, 0 }, - { "ABCDEFG", "gh", 5, PR_FALSE, 0 }, - { "ABCDABC", "bc", 5, PR_TRUE, 1 }, - { "ABCDABC", "bc", 6, PR_TRUE, 1 }, - { "ABCDABC", "bc", 7, PR_TRUE, 1 }, - { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", 7, PR_TRUE, 0 }, - { "ABCDEFG", "abcdefg", 8, PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "a", 12, PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "c", 12, PR_TRUE, 2 }, - { "ABCDEFGABCDEFG", "e", 12, PR_TRUE, 4 }, - { "ABCDEFGABCDEFG", "g", 12, PR_TRUE, 6 }, - { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ab", 12, PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "cd", 12, PR_TRUE, 2 }, - { "ABCDEFGABCDEFG", "ef", 12, PR_TRUE, 4 }, - { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", 5, PR_TRUE, 1 }, - { "ABCDABCABCDABC", "bc", 6, PR_TRUE, 1 }, - { "ABCDABCABCDABC", "bc", 7, PR_TRUE, 1 }, - { "ABCDEFGABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", 7, PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", 8, PR_TRUE, 0 } - }; - - int i; - - printf("Test 029 (PL_strncasestr) ..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strncasestr(array[i].str, array[i].sub, array[i].max); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, array[i].str, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strncaserstr */ -PRBool test_030(void) -{ - static struct - { - const char *str; - const char *sub; - PRUint32 max; - PRBool ret; - PRUint32 off; - } array[] = - { - { (const char *)0, (const char *)0, 12, PR_FALSE, 0 }, - { (const char *)0, "blah", 12, PR_FALSE, 0 }, - { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 0, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 2, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 3, PR_FALSE, 0 }, - { "blah-de-blah", "blah", 4, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 5, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 11, PR_TRUE, 0 }, - { "blah-de-blah", "blah", 12, PR_TRUE, 8 }, - { "blah-de-blah", "blah", 13, PR_TRUE, 8 }, - { "", "blah", 12, PR_FALSE, 0 }, - { "blah-de-blah", "", 12, PR_FALSE, 0 }, - { "abcdefg", "a", 5, PR_TRUE, 0 }, - { "abcdefg", "c", 5, PR_TRUE, 2 }, - { "abcdefg", "e", 5, PR_TRUE, 4 }, - { "abcdefg", "g", 5, PR_FALSE, 0 }, - { "abcdefg", "i", 5, PR_FALSE, 0 }, - { "abcdefg", "ab", 5, PR_TRUE, 0 }, - { "abcdefg", "cd", 5, PR_TRUE, 2 }, - { "abcdefg", "ef", 5, PR_FALSE, 0 }, - { "abcdefg", "gh", 5, PR_FALSE, 0 }, - { "abcdabc", "bc", 5, PR_TRUE, 1 }, - { "abcdabc", "bc", 6, PR_TRUE, 1 }, - { "abcdabc", "bc", 7, PR_TRUE, 5 }, - { "abcdefg", "abcdefg", 6, PR_FALSE, 0 }, - { "abcdefg", "abcdefg", 7, PR_TRUE, 0 }, - { "abcdefg", "abcdefg", 8, PR_TRUE, 0 }, - { "abcdefgabcdefg", "a", 12, PR_TRUE, 7 }, - { "abcdefgabcdefg", "c", 12, PR_TRUE, 9 }, - { "abcdefgabcdefg", "e", 12, PR_TRUE, 11 }, - { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 }, - { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 }, - { "abcdefgabcdefg", "ab", 12, PR_TRUE, 7 }, - { "abcdefgabcdefg", "cd", 12, PR_TRUE, 9 }, - { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 }, - { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 }, - { "abcdabcabcdabc", "bc", 12, PR_TRUE, 8 }, - { "abcdabcabcdabc", "bc", 13, PR_TRUE, 8 }, - { "abcdabcabcdabc", "bc", 14, PR_TRUE, 12 }, - { "abcdefgabcdefg", "abcdefg", 13, PR_TRUE, 0 }, - { "abcdefgabcdefg", "abcdefg", 14, PR_TRUE, 7 }, - { "abcdefgabcdefg", "abcdefg", 15, PR_TRUE, 7 }, - { "ABCDEFG", "a", 5, PR_TRUE, 0 }, - { "ABCDEFG", "c", 5, PR_TRUE, 2 }, - { "ABCDEFG", "e", 5, PR_TRUE, 4 }, - { "ABCDEFG", "g", 5, PR_FALSE, 0 }, - { "ABCDEFG", "i", 5, PR_FALSE, 0 }, - { "ABCDEFG", "ab", 5, PR_TRUE, 0 }, - { "ABCDEFG", "cd", 5, PR_TRUE, 2 }, - { "ABCDEFG", "ef", 5, PR_FALSE, 0 }, - { "ABCDEFG", "gh", 5, PR_FALSE, 0 }, - { "ABCDABC", "bc", 5, PR_TRUE, 1 }, - { "ABCDABC", "bc", 6, PR_TRUE, 1 }, - { "ABCDABC", "bc", 7, PR_TRUE, 5 }, - { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, - { "ABCDEFG", "abcdefg", 7, PR_TRUE, 0 }, - { "ABCDEFG", "abcdefg", 8, PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "a", 12, PR_TRUE, 7 }, - { "ABCDEFGABCDEFG", "c", 12, PR_TRUE, 9 }, - { "ABCDEFGABCDEFG", "e", 12, PR_TRUE, 11 }, - { "ABCDEFGABCDEFG", "g", 12, PR_TRUE, 6 }, - { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 }, - { "ABCDEFGABCDEFG", "ab", 12, PR_TRUE, 7 }, - { "ABCDEFGABCDEFG", "cd", 12, PR_TRUE, 9 }, - { "ABCDEFGABCDEFG", "ef", 12, PR_TRUE, 4 }, - { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 }, - { "ABCDABCABCDABC", "bc", 12, PR_TRUE, 8 }, - { "ABCDABCABCDABC", "bc", 13, PR_TRUE, 8 }, - { "ABCDABCABCDABC", "bc", 14, PR_TRUE, 12 }, - { "ABCDEFGABCDEFG", "abcdefg", 13, PR_TRUE, 0 }, - { "ABCDEFGABCDEFG", "abcdefg", 14, PR_TRUE, 7 }, - { "ABCDEFGABCDEFG", "abcdefg", 15, PR_TRUE, 7 } - }; - - int i; - - printf("Test 030 (PL_strncaserstr)..."); fflush(stdout); - - for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) - { - char *rv = PL_strncaserstr(array[i].str, array[i].sub, array[i].max); - - if( PR_FALSE == array[i].ret ) - { - if( (char *)0 != rv ) - { - printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, rv); - return PR_FALSE; - } - } - else - { - if( (char *)0 == rv ) - { - printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, array[i].str, array[i].off); - return PR_FALSE; - } - - if( &array[i].str[ array[i].off ] != rv ) - { - printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, - array[i].str ? array[i].str : "(null)", - array[i].sub ? array[i].sub : "(null)", - array[i].max, rv, array[i].str, array[i].off); - return PR_FALSE; - } - } - } - - printf("PASS\n"); - return PR_TRUE; -} - -/* PL_strtok_r */ -PRBool test_031(void) -{ - static const char *tokens[] = { - "wtc", "relyea", "nelsonb", "jpierre", "nicolson", - "ian.mcgreer", "kirk.erickson", "sonja.mirtitsch", "mhein" - }; - - static const char *seps[] = { - ", ", ",", " ", "\t", ",,,", " ,", " ", " \t\t", "," - }; - - static const char s2[] = ", \t"; - - char string[ 1024 ]; - char *s1; - char *token; - char *lasts; - unsigned int i; - - printf("Test 031 (PL_strtok_r) ..."); fflush(stdout); - - /* Build the string. */ - string[0] = '\0'; - for( i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++ ) - { - PL_strcat(string, tokens[i]); - PL_strcat(string, seps[i]); - } - - /* Scan the string for tokens. */ - i = 0; - s1 = string; - while( (token = PL_strtok_r(s1, s2, &lasts)) != NULL) - { - if( PL_strcmp(token, tokens[i]) != 0 ) - { - printf("FAIL wrong token scanned\n"); - return PR_FALSE; - } - i++; - s1 = NULL; - } - if( i != sizeof(tokens)/sizeof(tokens[0]) ) - { - printf("FAIL wrong number of tokens scanned\n"); - return PR_FALSE; - } - - printf("PASS\n"); - return PR_TRUE; -} - -int -main -( - int argc, - char *argv[] -) -{ - printf("Testing the Portable Library string functions:\n"); - - if( 1 - && test_001() - && test_001() - && test_002() - && test_003() - && test_004() - && test_005() - && test_006() - && test_007() - && test_008() - && test_009() - && test_010() - && test_011() - && test_012() - && test_013() - && test_014() - && test_015() - && test_016() - && test_017() - && test_018() - && test_019() - && test_020() - && test_021() - && test_022() - && test_023() - && test_024() - && test_025() - && test_026() - && test_027() - && test_028() - && test_029() - && test_030() - && test_031() - ) - { - printf("Suite passed.\n"); - return 0; - } - else - { - printf("Suite failed.\n"); - return 1; - } - - /*NOTREACHED*/ -} diff -Nru nspr-4.9.5/mozilla/nsprpub/LICENSE nspr-4.10.7/mozilla/nsprpub/LICENSE --- nspr-4.9.5/mozilla/nsprpub/LICENSE 2012-03-06 13:16:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/LICENSE 1970-01-01 00:00:00.000000000 +0000 @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff -Nru nspr-4.9.5/mozilla/nsprpub/Makefile.in nspr-4.10.7/mozilla/nsprpub/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/Makefile.in 2012-03-06 13:13:35.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -#! gmake - -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -MOD_DEPTH = . -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -DIRS = config pr lib - -ifdef MOZILLA_CLIENT -# Make nsinstall use absolute symlinks by default for Mozilla OSX builds -# http://bugzilla.mozilla.org/show_bug.cgi?id=193164 -ifeq ($(OS_ARCH),Darwin) -ifndef NSDISTMODE -NSDISTMODE=absolute_symlink -export NSDISTMODE -endif -endif -endif - -DIST_GARBAGE = config.cache config.log config.status - -all:: config.status export - -include $(topsrcdir)/config/rules.mk - -config.status:: configure -ifeq ($(OS_ARCH),WINNT) - sh $(srcdir)/configure --no-create --no-recursion -else - ./config.status --recheck && ./config.status -endif - -# -# The -ll option of zip converts CR LF to LF. -# -ifeq ($(OS_ARCH),WINNT) -ZIP_ASCII_OPT = -ll -endif - -# Delete config/autoconf.mk last because it is included by every makefile. -distclean:: - @echo "cd pr/tests; $(MAKE) $@" - @$(MAKE) -C pr/tests $@ - rm -f config/autoconf.mk - rm -f `cat unallmakefiles` unallmakefiles - -release:: - echo $(BUILD_NUMBER) > $(RELEASE_DIR)/$(BUILD_NUMBER)/version.df - @if test -f imports.df; then \ - echo "cp -f imports.df $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df"; \ - cp -f imports.df $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df; \ - else \ - echo "echo > $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df"; \ - echo > $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df; \ - fi - cd $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \ - rm -rf META-INF; mkdir META-INF; cd META-INF; \ - echo "Manifest-Version: 1.0" > MANIFEST.MF; \ - echo "" >> MANIFEST.MF; \ - cd ..; rm -f mdbinary.jar; zip -r mdbinary.jar META-INF bin lib; \ - rm -rf META-INF; \ - cd include; \ - rm -rf META-INF; mkdir META-INF; cd META-INF; \ - echo "Manifest-Version: 1.0" > MANIFEST.MF; \ - echo "" >> MANIFEST.MF; \ - cd ..; rm -f mdheader.jar; zip $(ZIP_ASCII_OPT) -r mdheader.jar *; \ - rm -rf META-INF -ifeq ($(OS_ARCH),WINNT) - @if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); then \ - rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ - echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)"; \ - mkdir -p $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ - fi - @if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); then \ - rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ - echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)"; \ - mkdir -p $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ - fi -else - @if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); then \ - rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ - echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)"; \ - $(NSINSTALL) -D $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ - chmod 775 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ - fi - @if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); then \ - rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ - echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)"; \ - $(NSINSTALL) -D $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ - chmod 775 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ - fi -endif - cd $(RELEASE_DIR)/$(BUILD_NUMBER); \ - cp -f version.df imports.df $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ - chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/version.df; \ - chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/imports.df; \ - cd $(OBJDIR_NAME); \ - cp -f mdbinary.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ - chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)/mdbinary.jar; \ - cd include; \ - cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ - chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)/mdheader.jar - -package: - @echo "cd pkg; $(MAKE) publish" - $(MAKE) -C pkg publish - -depend: - @echo "NSPR20 has no dependencies. Skipped." diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/linux/Makefile.in nspr-4.10.7/mozilla/nsprpub/pkg/linux/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pkg/linux/Makefile.in 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/linux/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: Makefile.in,v 1.12 2012/03/06 13:13:40 gerv%gerv.net Exp $" -# - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -NAME = sun-nspr -ifndef RPM_RELEASE -RPM_RELEASE = 1 -endif -TOPDIR = /usr/src/redhat -VERSION = `grep PR_VERSION $(dist_includedir)/prinit.h \ - | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'` - -SPECFILE = $(NAME).spec - -include $(MOD_DEPTH)/config/autoconf.mk - -# Force i386 for non 64 bit build -ifneq ($(USE_64),1) - RPMTARGET = "--target=i386" - RPMLIBDIR = lib -else - RPMLIBDIR = lib64 -endif - -publish: - $(MAKE) clean - mkdir -p SOURCES SRPMS RPMS BUILD - (cd $(dist_libdir) && tar cphf - libnspr4.so libplds4.so libplc4.so) \ - | (mkdir -p opt/sun/private/$(RPMLIBDIR) && cd opt/sun/private/$(RPMLIBDIR) && tar xvfBp -) - (cd $(dist_includedir) && tar cphf - .) \ - | (mkdir -p opt/sun/private/include/nspr && cd opt/sun/private/include/nspr && tar xvfBp -) - (cd opt/sun/private/include/nspr && \ - rm -rf md) - tar czvf SOURCES/$(NAME)-$(VERSION).tar.gz opt - echo "%define name $(NAME)" >$(SPECFILE) - echo "%define version $(VERSION)" >>$(SPECFILE) - echo "%define release $(RPM_RELEASE)" >>$(SPECFILE) - echo "%define buildroot `pwd`/$(NAME)-root" >>$(SPECFILE) - echo "%define _topdir `pwd`" >>$(SPECFILE) - echo "%define _unpackaged_files_terminate_build 0" >>$(SPECFILE) - cat $(srcdir)/$(NAME).spec >>$(SPECFILE) - echo "" >>$(SPECFILE) - echo "%files" >>$(SPECFILE) - echo "%defattr(-,root,root)" >>$(SPECFILE) - echo "%dir /opt" >>$(SPECFILE) - echo "%dir /opt/sun" >>$(SPECFILE) - echo "%dir /opt/sun/private" >>$(SPECFILE) - echo "%dir /opt/sun/private/$(RPMLIBDIR)" >>$(SPECFILE) - find opt \( -name "*.so" \) | sed -e "s-^-/-" >>$(SPECFILE) - echo "" >>$(SPECFILE) - echo "%files devel" >>$(SPECFILE) - echo "%defattr(-,root,root)" >>$(SPECFILE) - echo "%dir /opt" >>$(SPECFILE) - echo "%dir /opt/sun" >>$(SPECFILE) - echo "%dir /opt/sun/private" >>$(SPECFILE) - echo "%dir /opt/sun/private/include" >>$(SPECFILE) - echo "%dir /opt/sun/private/include/nspr" >>$(SPECFILE) - echo "%dir /opt/sun/private/include/nspr/obsolete" >>$(SPECFILE) - echo "%dir /opt/sun/private/include/nspr/private" >>$(SPECFILE) - find opt -type f \( -name "*.h" \) \ - | sed -e "s-^-/-" >>$(SPECFILE) - rpmbuild $(RPMTARGET) -bb $(SPECFILE) - -clean: - rm -rf $(TOPDIR)/BUILD/$(NAME) - rm -rf SOURCES SRPMS RPMS BUILD - rm -rf RPMS SRPMS opt - rm -f $(NAME)-$(VERSION).tar.gz diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/linux/sun-nspr.spec nspr-4.10.7/mozilla/nsprpub/pkg/linux/sun-nspr.spec --- nspr-4.9.5/mozilla/nsprpub/pkg/linux/sun-nspr.spec 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/linux/sun-nspr.spec 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -Summary: Netscape Portable Runtime -Name: %{name} -Vendor: Sun Microsystems, Inc. -Version: %{version} -Release: %{release} -Copyright: Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Also under other license(s) as shown at the Description field. -Distribution: Sun Java(TM) Enterprise System -URL: http://www.sun.com -Group: System Environment/Base -Source: %{name}-%{version}.tar.gz -ExclusiveOS: Linux -BuildRoot: /var/tmp/%{name}-root - -%description - -NSPR provides platform independence for non-GUI operating system -facilities. These facilities include threads, thread synchronization, -normal file and network I/O, interval timing and calendar time, basic -memory management (malloc and free) and shared library linking. - -See: http://www.mozilla.org/projects/nspr/about-nspr.html - -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. - -%package devel -Summary: Development Libraries for the Netscape Portable Runtime -Group: Development/Libraries -Requires: %{name} = %{version}-%{release} - -%description devel -Header files for doing development with the Netscape Portable Runtime. - -Under "MPL/GPL" license. - -%prep -%setup -c - -%build - -%install -rm -rf $RPM_BUILD_ROOT -mkdir $RPM_BUILD_ROOT -cd $RPM_BUILD_ROOT -tar xvzf $RPM_SOURCE_DIR/%{name}-%{version}.tar.gz - -%clean -rm -rf $RPM_BUILD_ROOT diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/Makefile.in nspr-4.10.7/mozilla/nsprpub/pkg/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pkg/Makefile.in 2012-03-06 13:13:39.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = .. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -DIRS = -ifeq ($(OS_TARGET),Linux) -DIRS = linux -endif -ifeq ($(OS_TARGET),SunOS) -DIRS = solaris -endif - -publish:: - +$(LOOP_OVER_DIRS) - -include $(topsrcdir)/config/rules.mk diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh nspr-4.10.7/mozilla/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -#!/usr/bin/ksh -p -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: bld_awk_pkginfo.ksh,v 1.4 2012/03/06 13:13:40 gerv%gerv.net Exp $" -# -# Simple script which builds the awk_pkginfo awk script. This awk script -# is used to convert the pkginfo.tmpl files into pkginfo files -# for the build. -# - -usage() -{ - cat <<-EOF -usage: bld_awk_pkginfo -p -m -o [-v ] -EOF -} - -# -# Awk strings -# -# two VERSION patterns: one for Dewey decimal, one for Dewey plus ,REV=n -# the first has one '=' the second has two or more '=' -# -VERSION1="VERSION=[^=]*$" -VERSION2="VERSION=[^=]*=.*$" -PRODVERS="^SUNW_PRODVERS=" -ARCH='ARCH=\"ISA\"' - -# -# parse command line -# -mach="" -prodver="" -awk_script="" -version="NSPRVERS" - -while getopts o:p:m:v: c -do - case $c in - o) - awk_script=$OPTARG - ;; - m) - mach=$OPTARG - ;; - p) - prodver=$OPTARG - ;; - v) - version=$OPTARG - ;; - \?) - usage - exit 1 - ;; - esac -done - -if [[ ( -z $prodver ) || ( -z $mach ) || ( -z $awk_script ) ]] -then - usage - exit 1 -fi - -if [[ -f $awk_script ]] -then - rm -f $awk_script -fi - -# -# Build REV= field based on date -# -rev=$(date "+%Y.%m.%d.%H.%M") - -# -# Build awk script which will process all the -# pkginfo.tmpl files. -# -# the first VERSION pattern is replaced with a leading quotation mark -# -rm -f $awk_script -cat << EOF > $awk_script -/$VERSION1/ { - sub(/\=[^=]*$/,"=\"$rev\"") - print - next - } -/$VERSION2/ { - sub(/\=[^=]*$/,"=$rev\"") - sub(/NSPRVERS/,"$version") - print - next - } -/$PRODVERS/ { - printf "SUNW_PRODVERS=\"%s\"\n", "$prodver" - next - } -/$ARCH/ { - printf "ARCH=\"%s\"\n", "$mach" - next - } -{ print } -EOF diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/common_files/copyright nspr-4.10.7/mozilla/nsprpub/pkg/solaris/common_files/copyright --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/common_files/copyright 2012-05-31 21:54:55.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/common_files/copyright 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -Copyright 2005 Sun Microsystems, Inc. All rights reserved. -Use is subject to license terms. - -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile.com nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile.com --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile.com 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile.com 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: Makefile.com,v 1.9 2012/03/06 13:13:40 gerv%gerv.net Exp $" -# - -MACH = $(shell mach) - -PUBLISH_ROOT = $(DIST) -ifeq ($(MOD_DEPTH),../..) -ROOT = ROOT -else -ROOT = $(subst ../../,,$(MOD_DEPTH))/ROOT -endif - -PKGARCHIVE = $(dist_prefix)/pkgarchive -DATAFILES = copyright -FILES = $(DATAFILES) pkginfo - -PACKAGE = $(shell basename `pwd`) - -PRODUCT_VERSION = $(shell grep PR_VERSION $(dist_includedir)/prinit.h \ - | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') - -LN = /usr/bin/ln -CP = /usr/bin/cp - -CLOBBERFILES = $(FILES) - -include $(topsrcdir)/config/rules.mk - -# vim: ft=make diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile-devl.com nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile-devl.com --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile-devl.com 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile-devl.com 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: Makefile-devl.com,v 1.4 2012/03/06 13:13:40 gerv%gerv.net Exp $" -# - -MACH = $(shell mach) - -PUBLISH_ROOT = $(DIST) -ifeq ($(MOD_DEPTH),../..) -ROOT = ROOT -else -ROOT = $(subst ../../,,$(MOD_DEPTH))/ROOT -endif - -PKGARCHIVE = $(dist_prefix)/pkgarchive -DATAFILES = copyright -FILES = $(DATAFILES) pkginfo - -PACKAGE = $(shell basename `pwd`) - -PRODUCT_VERSION = "$(MOD_VERSION).$(MOD_MINOR).$(MOD_PATCH)$(MOD_BETA)" -LN = /usr/bin/ln - -CLOBBERFILES = $(FILES) - -include $(topsrcdir)/config/rules.mk - -# vim: ft=make diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile-devl.targ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile-devl.targ --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile-devl.targ 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile-devl.targ 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: Makefile-devl.targ,v 1.4 2012/03/06 13:13:40 gerv%gerv.net Exp $" -# - -include $(srcdir)/../proto64.mk - -pkginfo: pkginfo.tmpl ../awk_pkginfo - $(RM) $@; nawk -f ../awk_pkginfo $(srcdir)/$@.tmpl > $@ - -pkg: $(PKGARCHIVE) - cat $(srcdir)/prototype | sed $(sed_proto64) > prototype - cp $(srcdir)/depend . - pkgmk -f prototype -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE) - -$(PKGARCHIVE): - [ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE) - -$(DATAFILES): %: $(srcdir)/../common_files/% - $(RM) $@; cp $(srcdir)/../common_files/$@ $@ - -$(MACHDATAFILES): %: $(srcdir)/../common_files/%_$(MACH) - $(RM) $@; cp $(srcdir)/../common_files/$@_$(MACH) $@ - -clobber clean:: - -$(RM) $(CLOBBERFILES) $(CLEANFILES) - -.PHONY: pkg diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile.in nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile.in 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: Makefile.in,v 1.4 2012/03/06 13:13:40 gerv%gerv.net Exp $" -# - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -abs_dist_libdir := $(shell (cd $(dist_libdir);pwd)) -abs_dist_includedir := $(shell (cd $(dist_includedir);pwd)) - -%: %.ksh - $(RM) $@ - cp $< $@ - chmod +x $@ - -DIRS = \ - SUNWpr \ - SUNWprd - -include $(srcdir)/Makefile.com - -PROTO = \ - $(ROOT) \ - $(ROOT)/usr/lib/mps \ - $(ROOT)/usr/include/mps - -ifeq ($(MACH), sparc) - PROTO += $(ROOT)/usr/lib/mps/cpu/sparcv8plus -endif - -ifeq ($(USE_64), 1) -ifeq ($(MACH), sparc) -# Sparc - PROTO += $(ROOT)/usr/lib/mps/sparcv9 -else -# AMD64 - PROTO += $(ROOT)/usr/lib/mps/amd64 -endif - abs_dist64_libdir = $(abs_dist_libdir) - abs_dist32_libdir = $(shell echo $(abs_dist_libdir) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g") - abs_dist64_includedir = $(abs_dist_includedir) - abs_dist32_includedir = $(shell echo $(abs_dist_includedir) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g") -else - abs_dist32_libdir = $(abs_dist_libdir) - abs_dist64_libdir = $(shell echo $(abs_dist_libdir) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g") - abs_dist32_includedir = $(abs_dist_includedir) - abs_dist64_includedir = $(shell echo $(abs_dist_includedir) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g") -endif - -awk_pkginfo: bld_awk_pkginfo - ./bld_awk_pkginfo -m $(MACH) -p "$(PRODUCT_VERSION)" -o $@ -v $(PRODUCT_VERSION) - -all:: awk_pkginfo $(PROTO) -publish: awk_pkginfo $(PROTO) - +$(LOOP_OVER_DIRS) - -clean clobber:: - $(RM) awk_pkginfo bld_awk_pkginfo - $(RM) -r $(ROOT) - -$(ROOT): - mkdir -p $@ - -$(ROOT)/usr/lib/mps/sparcv9: - mkdir -p $@ - $(CP) -r $(abs_dist64_libdir)/*.so $@ -$(ROOT)/usr/lib/mps/amd64: - mkdir -p $@ - $(CP) -r $(abs_dist64_libdir)/*.so $@ -$(ROOT)/usr/lib/mps: - mkdir -p $@ - $(CP) -r $(abs_dist32_libdir)/*.so $@ -$(ROOT)/usr/lib/mps/cpu/sparcv8plus: - mkdir -p $@ - $(CP) -r $(abs_dist32_libdir)/cpu/sparcv8plus/*.so $@ -$(ROOT)/usr/include/mps: - mkdir -p $@ - $(CP) -r $(abs_dist32_includedir)/* $@ diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile.targ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile.targ --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/Makefile.targ 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/Makefile.targ 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: Makefile.targ,v 1.7 2012/03/06 13:13:40 gerv%gerv.net Exp $" -# - -include $(srcdir)/../proto64.mk - -pkginfo: pkginfo.tmpl ../awk_pkginfo - $(RM) $@; nawk -f ../awk_pkginfo $< > $@ - -pkg: $(PKGARCHIVE) prototype_$(MACH) - cp $(srcdir)/prototype_com . - cat $(srcdir)/prototype_$(MACH) | sed $(sed_proto64) > prototype_$(MACH) - cp $(srcdir)/depend . - pkgmk -f prototype_$(MACH) -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE) - -$(PKGARCHIVE): - [ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE) - -$(DATAFILES): %: $(srcdir)/../common_files/% - $(RM) $@; cp $(srcdir)/../common_files/$@ $@ - -clobber clean:: - -$(RM) $(CLOBBERFILES) $(CLEANFILES) - -.PHONY: pkg diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/proto64.mk nspr-4.10.7/mozilla/nsprpub/pkg/solaris/proto64.mk --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/proto64.mk 2012-03-06 13:13:40.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/proto64.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: proto64.mk,v 1.4 2012/03/06 13:13:40 gerv%gerv.net Exp $" -# - -ifeq ($(USE_64), 1) - # Remove 64 tag - sed_proto64='s/\#64\#//g' -else - # Strip 64 lines - sed_proto64='/\#64\#/d' -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/depend nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/depend --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/depend 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/depend 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# $Id: depend,v 1.4 2012/03/06 13:13:41 gerv%gerv.net Exp $ -# -# This package information file defines software dependencies associated -# with the pkg. You can define three types of pkg dependencies with this file: -# P indicates a prerequisite for installation -# I indicates an incompatible package -# R indicates a reverse dependency -# see pkginfo(4), PKG parameter -# see pkginfo(4), NAME parameter -# see pkginfo(4), VERSION parameter -# see pkginfo(4), ARCH parameter -# -# () -# () -# ... -# -# ... - -P SUNWcar Core Architecture, (Root) -P SUNWkvm Core Architecture, (Kvm) -P SUNWcsr Core Solaris, (Root) -P SUNWcsu Core Solaris, (Usr) -P SUNWcsd Core Solaris Devices -P SUNWcsl Core Solaris Libraries diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/Makefile.in nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/Makefile.in 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: Makefile.in,v 1.3 2012/03/06 13:13:41 gerv%gerv.net Exp $" -# - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(srcdir)/../Makefile.com - -DATAFILES += - -all:: $(FILES) -publish:: all pkg - -include $(srcdir)/../Makefile.targ diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: pkginfo.tmpl,v 1.4 2012/03/06 13:13:41 gerv%gerv.net Exp $" -# -# -# This required package information file describes characteristics of the -# package, such as package abbreviation, full package name, package version, -# and package architecture. -# -PKG="SUNWpr" -NAME="Netscape Portable Runtime" -ARCH="ISA" -VERSION="NSPRVERS,REV=0.0.0" -SUNW_PRODNAME="Netscape Portable Runtime" -SUNW_PRODVERS="NSPRVERS" -SUNW_PKGTYPE="usr" -MAXINST="1000" -CATEGORY="system" -DESC="Netscape Portable Runtime Interface" -VENDOR="Sun Microsystems, Inc." -HOTLINE="Please contact your local service provider" -EMAIL="" -CLASSES="none" -BASEDIR=/ -SUNW_PKGVERS="1.0" -#VSTOCK="" -#ISTATES="" -#RSTATES='' -#ULIMIT="" -#ORDER="" -#PSTAMP="" -#INTONLY="" diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_com nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_com --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_com 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_com 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: prototype_com,v 1.5 2012/03/06 13:13:41 gerv%gerv.net Exp $" -# -# This required package information file contains a list of package contents. -# The 'pkgmk' command uses this file to identify the contents of a package -# and their location on the development machine when building the package. -# Can be created via a text editor or through use of the 'pkgproto' command. - -#!search # where to find pkg objects -#!include # include another 'prototype' file -#!default # default used if not specified on entry -#!= # puts parameter in pkg environment - -# packaging files -i copyright -i pkginfo -i depend -# -# source locations relative to the prototype file -# -# SUNWpr -# -d none usr 755 root sys -d none usr/lib 755 root bin -d none usr/lib/mps 755 root bin -d none usr/lib/mps/secv1 755 root bin -f none usr/lib/mps/libnspr4.so 755 root bin -f none usr/lib/mps/libplc4.so 755 root bin -f none usr/lib/mps/libplds4.so 755 root bin -s none usr/lib/mps/secv1/libnspr4.so=../libnspr4.so -s none usr/lib/mps/secv1/libplc4.so=../libplc4.so -s none usr/lib/mps/secv1/libplds4.so=../libplds4.so diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_i386 nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_i386 --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_i386 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_i386 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: prototype_i386,v 1.5 2012/03/06 13:13:41 gerv%gerv.net Exp $" -# -# This required package information file contains a list of package contents. -# The 'pkgmk' command uses this file to identify the contents of a package -# and their location on the development machine when building the package. -# Can be created via a text editor or through use of the 'pkgproto' command. - -#!search # where to find pkg objects -#!include # include another 'prototype' file -#!default # default used if not specified on entry -#!= # puts parameter in pkg environment - -# -# Include ISA independent files (prototype_com) -# -!include prototype_com -# -# -# -# List files which are i386 specific here -# -# source locations relative to the prototype file -# -# -# SUNWpr -# -#64#s none usr/lib/mps/64=amd64 -#64#s none usr/lib/mps/secv1/64=amd64 -#64#d none usr/lib/mps/amd64 755 root bin -#64#d none usr/lib/mps/secv1/amd64 755 root bin -#64#f none usr/lib/mps/amd64/libnspr4.so 755 root bin -#64#f none usr/lib/mps/amd64/libplc4.so 755 root bin -#64#f none usr/lib/mps/amd64/libplds4.so 755 root bin -#64#s none usr/lib/mps/secv1/amd64/libnspr4.so=../../amd64/libnspr4.so -#64#s none usr/lib/mps/secv1/amd64/libplc4.so=../../amd64/libplc4.so -#64#s none usr/lib/mps/secv1/amd64/libplds4.so=../../amd64/libplds4.so - diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_sparc nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_sparc --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_sparc 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWpr/prototype_sparc 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: prototype_sparc,v 1.5 2012/03/06 13:13:41 gerv%gerv.net Exp $" -# -# This required package information file contains a list of package contents. -# The 'pkgmk' command uses this file to identify the contents of a package -# and their location on the development machine when building the package. -# Can be created via a text editor or through use of the 'pkgproto' command. - -#!search # where to find pkg objects -#!include # include another 'prototype' file -#!default # default used if not specified on entry -#!= # puts parameter in pkg environment - -# -# Include ISA independent files (prototype_com) -# -!include prototype_com -# -# -# -# List files which are SPARC specific here -# -# source locations relative to the prototype file -# -# -# SUNWpr -# -d none usr/lib/mps/cpu 755 root bin -d none usr/lib/mps/cpu/sparcv8plus 755 root bin -d none usr/lib/mps/secv1/cpu 755 root bin -d none usr/lib/mps/secv1/cpu/sparcv8plus 755 root bin -f none usr/lib/mps/cpu/sparcv8plus/libnspr_flt4.so 755 root bin -s none usr/lib/mps/secv1/cpu/sparcv8plus/libnspr_flt4.so=../../../cpu/sparcv8plus/libnspr_flt4.so -#64#s none usr/lib/mps/64=sparcv9 -#64#s none usr/lib/mps/secv1/64=sparcv9 -#64#d none usr/lib/mps/sparcv9 755 root bin -#64#d none usr/lib/mps/secv1/sparcv9 755 root bin -#64#f none usr/lib/mps/sparcv9/libnspr4.so 755 root bin -#64#f none usr/lib/mps/sparcv9/libplc4.so 755 root bin -#64#f none usr/lib/mps/sparcv9/libplds4.so 755 root bin -#64#s none usr/lib/mps/secv1/sparcv9/libnspr4.so=../../sparcv9/libnspr4.so -#64#s none usr/lib/mps/secv1/sparcv9/libplc4.so=../../sparcv9/libplc4.so -#64#s none usr/lib/mps/secv1/sparcv9/libplds4.so=../../sparcv9/libplds4.so - diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWprd/depend nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWprd/depend --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWprd/depend 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWprd/depend 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# $Id: depend,v 1.4 2012/03/06 13:13:41 gerv%gerv.net Exp $ -# -# This package information file defines software dependencies associated -# with the pkg. You can define three types of pkg dependencies with this file: -# P indicates a prerequisite for installation -# I indicates an incompatible package -# R indicates a reverse dependency -# see pkginfo(4), PKG parameter -# see pkginfo(4), NAME parameter -# see pkginfo(4), VERSION parameter -# see pkginfo(4), ARCH parameter -# -# () -# () -# ... -# -# ... - -P SUNWpr Netscape Portable Runtime diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWprd/Makefile.in nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWprd/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWprd/Makefile.in 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWprd/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: Makefile.in,v 1.4 2012/03/06 13:13:41 gerv%gerv.net Exp $" -# - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(srcdir)/../Makefile-devl.com - -DATAFILES += - -all:: $(FILES) -publish:: all pkg - -include $(srcdir)/../Makefile-devl.targ diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: pkginfo.tmpl,v 1.4 2012/03/06 13:13:41 gerv%gerv.net Exp $" -# -# -# This required package information file describes characteristics of the -# package, such as package abbreviation, full package name, package version, -# and package architecture. -# -PKG="SUNWprd" -NAME="Netscape Portable Runtime Development" -ARCH="ISA" -VERSION="NSPRVERS,REV=0.0.0" -SUNW_PRODNAME="Netscape Portable Runtime Development" -SUNW_PRODVERS="NSPRVERS" -SUNW_PKGTYPE="usr" -MAXINST="1000" -CATEGORY="system" -DESC="Netscape Portable Runtime Interface Files for Development" -VENDOR="Sun Microsystems, Inc." -HOTLINE="Please contact your local service provider" -EMAIL="" -CLASSES="none" -BASEDIR=/ -SUNW_PKGVERS="1.0" -#VSTOCK="" -#ISTATES="" -#RSTATES='' -#ULIMIT="" -#ORDER="" -#PSTAMP="" -#INTONLY="" diff -Nru nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWprd/prototype nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWprd/prototype --- nspr-4.9.5/mozilla/nsprpub/pkg/solaris/SUNWprd/prototype 2012-03-06 13:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pkg/solaris/SUNWprd/prototype 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -#ident "$Id: prototype,v 1.7 2012/03/06 13:13:41 gerv%gerv.net Exp $" -# -# This required package information file contains a list of package contents. -# The 'pkgmk' command uses this file to identify the contents of a package -# and their location on the development machine when building the package. -# Can be created via a text editor or through use of the 'pkgproto' command. - -#!search # where to find pkg objects -#!include # include another 'prototype' file -#!default # default used if not specified on entry -#!= # puts parameter in pkg environment - -# packaging files -i copyright -i pkginfo -i depend -# -# source locations relative to .h 0644 root bine prototype file -# -# SUNWprd -# -d none usr 0755 root sys -d none usr/include 0755 root bin -d none usr/include/mps 0755 root bin -d none usr/include/mps/obsolete 0755 root bin -d none usr/include/mps/private 0755 root bin -f none usr/include/mps/obsolete/pralarm.h 0644 root bin -f none usr/include/mps/obsolete/probslet.h 0644 root bin -f none usr/include/mps/obsolete/protypes.h 0644 root bin -f none usr/include/mps/obsolete/prsem.h 0644 root bin -f none usr/include/mps/prcpucfg.h 0644 root bin -f none usr/include/mps/nspr.h 0644 root bin -f none usr/include/mps/pratom.h 0644 root bin -f none usr/include/mps/prbit.h 0644 root bin -f none usr/include/mps/prclist.h 0644 root bin -f none usr/include/mps/prcmon.h 0644 root bin -f none usr/include/mps/prcountr.h 0644 root bin -f none usr/include/mps/prcvar.h 0644 root bin -f none usr/include/mps/prdtoa.h 0644 root bin -f none usr/include/mps/prenv.h 0644 root bin -f none usr/include/mps/prerr.h 0644 root bin -f none usr/include/mps/prerror.h 0644 root bin -f none usr/include/mps/prinet.h 0644 root bin -f none usr/include/mps/prinit.h 0644 root bin -f none usr/include/mps/prinrval.h 0644 root bin -f none usr/include/mps/prio.h 0644 root bin -f none usr/include/mps/pripcsem.h 0644 root bin -f none usr/include/mps/private/pprio.h 0644 root bin -f none usr/include/mps/private/pprthred.h 0644 root bin -f none usr/include/mps/private/prpriv.h 0644 root bin -f none usr/include/mps/prlink.h 0644 root bin -f none usr/include/mps/prlock.h 0644 root bin -f none usr/include/mps/prlog.h 0644 root bin -f none usr/include/mps/prlong.h 0644 root bin -f none usr/include/mps/prmem.h 0644 root bin -f none usr/include/mps/prmon.h 0644 root bin -f none usr/include/mps/prmwait.h 0644 root bin -f none usr/include/mps/prnetdb.h 0644 root bin -f none usr/include/mps/prolock.h 0644 root bin -f none usr/include/mps/prpdce.h 0644 root bin -f none usr/include/mps/prprf.h 0644 root bin -f none usr/include/mps/prproces.h 0644 root bin -f none usr/include/mps/prrng.h 0644 root bin -f none usr/include/mps/prrwlock.h 0644 root bin -f none usr/include/mps/prshm.h 0644 root bin -f none usr/include/mps/prshma.h 0644 root bin -f none usr/include/mps/prsystem.h 0644 root bin -f none usr/include/mps/prthread.h 0644 root bin -f none usr/include/mps/prtime.h 0644 root bin -f none usr/include/mps/prtpool.h 0644 root bin -f none usr/include/mps/prtrace.h 0644 root bin -f none usr/include/mps/prtypes.h 0644 root bin -f none usr/include/mps/prvrsion.h 0644 root bin -f none usr/include/mps/prwin16.h 0644 root bin -f none usr/include/mps/plarenas.h 0644 root bin -f none usr/include/mps/plarena.h 0644 root bin -f none usr/include/mps/plbase64.h 0644 root bin -f none usr/include/mps/plerror.h 0644 root bin -f none usr/include/mps/plgetopt.h 0644 root bin -f none usr/include/mps/plhash.h 0644 root bin -f none usr/include/mps/plstr.h 0644 root bin diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/.cvsignore 2001-05-12 01:41:04.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/include/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/include/.cvsignore 2001-05-12 01:41:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/gencfg.c nspr-4.10.7/mozilla/nsprpub/pr/include/gencfg.c --- nspr-4.9.5/mozilla/nsprpub/pr/include/gencfg.c 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/gencfg.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,265 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#if defined(sgi) -#ifndef IRIX - error - IRIX is not defined -#endif -#endif - -#if defined(__sun) -#ifndef SOLARIS - error - SOLARIS is not defined -#endif -#endif - -#if defined(__hpux) -#ifndef HPUX - error - HPUX is not defined -#endif -#endif - -#if defined(__alpha) -#if !(defined(_WIN32)) && !(defined(OSF1)) && !(defined(__linux)) && !(defined(__FreeBSD__)) - error - None of OSF1, _WIN32, __linux, or __FreeBSD__ is defined -#endif -#endif - -#if defined(_IBMR2) -#ifndef AIX - error - AIX is not defined -#endif -#endif - -#if defined(linux) -#ifndef LINUX - error - LINUX is not defined -#endif -#endif - -#if defined(bsdi) -#ifndef BSDI - error - BSDI is not defined -#endif -#endif - -#if defined(M_UNIX) -#ifndef SCO - error - SCO is not defined -#endif -#endif -#if !defined(M_UNIX) && defined(_USLC_) -#ifndef UNIXWARE - error - UNIXWARE is not defined -#endif -#endif - -#if defined(__APPLE__) -#ifndef DARWIN - error - DARWIN is not defined -#endif -#endif - -/************************************************************************/ - -/* Generate cpucfg.h */ - -#ifdef XP_PC -#ifdef WIN32 -#define INT64 _PRInt64 -#else -#define INT64 long -#endif -#else -#if defined(HPUX) || defined(SCO) || defined(UNIXWARE) -#define INT64 long -#else -#define INT64 long long -#endif -#endif - -struct align_short { - char c; - short a; -}; -struct align_int { - char c; - int a; -}; -struct align_long { - char c; - long a; -}; -struct align_PRInt64 { - char c; - INT64 a; -}; -struct align_fakelonglong { - char c; - struct { - long hi, lo; - } a; -}; -struct align_float { - char c; - float a; -}; -struct align_double { - char c; - double a; -}; -struct align_pointer { - char c; - void *a; -}; - -#define ALIGN_OF(type) \ - (((char*)&(((struct align_##type *)0)->a)) - ((char*)0)) - -int bpb; - -/* Used if shell doesn't support redirection. By default, assume it does. */ -FILE *stream; - -static int Log2(int n) -{ - int log2 = 0; - - if (n & (n-1)) - log2++; - if (n >> 16) - log2 += 16, n >>= 16; - if (n >> 8) - log2 += 8, n >>= 8; - if (n >> 4) - log2 += 4, n >>= 4; - if (n >> 2) - log2 += 2, n >>= 2; - if (n >> 1) - log2++; - return log2; -} - -/* We assume that int's are 32 bits */ -static void do64(void) -{ - union { - int i; - char c[4]; - } u; - - u.i = 0x01020304; - if (u.c[0] == 0x01) { - fprintf(stream, "#undef IS_LITTLE_ENDIAN\n"); - fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n"); - } else { - fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n"); - fprintf(stream, "#undef IS_BIG_ENDIAN\n\n"); - } -} - -static void do32(void) -{ - union { - long i; - char c[4]; - } u; - - u.i = 0x01020304; - if (u.c[0] == 0x01) { - fprintf(stream, "#undef IS_LITTLE_ENDIAN\n"); - fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n"); - } else { - fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n"); - fprintf(stream, "#undef IS_BIG_ENDIAN\n\n"); - } -} - -/* -** Concievably this could actually be used; but there is lots of code out -** there with and's and shift's in it that assumes a byte is 8 bits, so -** forget about porting THIS code to those non 8 bit byte machines. -*/ -static void BitsPerByte(void) -{ - bpb = 8; -} - -int main(int argc, char **argv) -{ - BitsPerByte(); - - /* If we got a command line argument, try to use it as the stream. */ - ++argv; - if(*argv) { - if(!(stream = fopen ( *argv, "wt" ))) { - fprintf(stderr, "Could not write to output file %s.\n", *argv); - return 1; - } - } else { - stream = stdout; - } - - fprintf(stream, "#ifndef nspr_cpucfg___\n"); - fprintf(stream, "#define nspr_cpucfg___\n\n"); - - fprintf(stream, "/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n"); - - if (sizeof(long) == 8) { - do64(); - } else { - do32(); - } - fprintf(stream, "#define PR_BYTES_PER_BYTE %d\n", sizeof(char)); - fprintf(stream, "#define PR_BYTES_PER_SHORT %d\n", sizeof(short)); - fprintf(stream, "#define PR_BYTES_PER_INT %d\n", sizeof(int)); - fprintf(stream, "#define PR_BYTES_PER_INT64 %d\n", 8); - fprintf(stream, "#define PR_BYTES_PER_LONG %d\n", sizeof(long)); - fprintf(stream, "#define PR_BYTES_PER_FLOAT %d\n", sizeof(float)); - fprintf(stream, "#define PR_BYTES_PER_DOUBLE %d\n\n", sizeof(double)); - - fprintf(stream, "#define PR_BITS_PER_BYTE %d\n", bpb); - fprintf(stream, "#define PR_BITS_PER_SHORT %d\n", bpb * sizeof(short)); - fprintf(stream, "#define PR_BITS_PER_INT %d\n", bpb * sizeof(int)); - fprintf(stream, "#define PR_BITS_PER_INT64 %d\n", bpb * 8); - fprintf(stream, "#define PR_BITS_PER_LONG %d\n", bpb * sizeof(long)); - fprintf(stream, "#define PR_BITS_PER_FLOAT %d\n", bpb * sizeof(float)); - fprintf(stream, "#define PR_BITS_PER_DOUBLE %d\n\n", - bpb * sizeof(double)); - - fprintf(stream, "#define PR_BITS_PER_BYTE_LOG2 %d\n", Log2(bpb)); - fprintf(stream, "#define PR_BITS_PER_SHORT_LOG2 %d\n", - Log2(bpb * sizeof(short))); - fprintf(stream, "#define PR_BITS_PER_INT_LOG2 %d\n", - Log2(bpb * sizeof(int))); - fprintf(stream, "#define PR_BITS_PER_INT64_LOG2 %d\n", 6); - fprintf(stream, "#define PR_BITS_PER_LONG_LOG2 %d\n", - Log2(bpb * sizeof(long))); - fprintf(stream, "#define PR_BITS_PER_FLOAT_LOG2 %d\n", - Log2(bpb * sizeof(float))); - fprintf(stream, "#define PR_BITS_PER_DOUBLE_LOG2 %d\n\n", - Log2(bpb * sizeof(double))); - - fprintf(stream, "#define PR_ALIGN_OF_SHORT %d\n", ALIGN_OF(short)); - fprintf(stream, "#define PR_ALIGN_OF_INT %d\n", ALIGN_OF(int)); - fprintf(stream, "#define PR_ALIGN_OF_LONG %d\n", ALIGN_OF(long)); - if (sizeof(INT64) < 8) { - /* this machine doesn't actually support PRInt64's */ - fprintf(stream, "#define PR_ALIGN_OF_INT64 %d\n", - ALIGN_OF(fakelonglong)); - } else { - fprintf(stream, "#define PR_ALIGN_OF_INT64 %d\n", ALIGN_OF(PRInt64)); - } - fprintf(stream, "#define PR_ALIGN_OF_FLOAT %d\n", ALIGN_OF(float)); - fprintf(stream, "#define PR_ALIGN_OF_DOUBLE %d\n", ALIGN_OF(double)); - fprintf(stream, "#define PR_ALIGN_OF_POINTER %d\n\n", ALIGN_OF(pointer)); - - fprintf(stream, "#endif /* nspr_cpucfg___ */\n"); - fclose(stream); - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/include/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/include/Makefile.in 2012-03-06 13:13:42.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -DIRS = md private obsolete - -include $(topsrcdir)/config/config.mk - -HEADERS = $(wildcard $(srcdir)/*.h) - -RELEASE_HEADERS = $(HEADERS) -RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR) - -include $(topsrcdir)/config/rules.mk - -export:: $(RELEASE_HEADERS) - $(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir) diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_aix32.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_aix32.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_aix32.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_aix32.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef AIX -#define AIX -#endif - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -/* used by protypes.h only */ -#define _PR_AIX_HAVE_BSD_INT_TYPES - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_aix64.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_aix64.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_aix64.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_aix64.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef AIX -#define AIX -#endif - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 8 - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -/* used by protypes.h only */ -#define _PR_AIX_HAVE_BSD_INT_TYPES - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_aix.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_aix.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_aix.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_aix.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,225 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_aix_defs_h___ -#define nspr_aix_defs_h___ - -#include -#if defined(_PR_PTHREADS) || defined(PTHREADS_USER) -#include -#endif - -/* - * To pick up fd_set and the poll events. - */ -#include -#include - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "aix" -#define _PR_SI_SYSNAME "AIX" -#define _PR_SI_ARCHITECTURE "rs6000" -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE (2*65536L) -#define _MD_MINIMUM_STACK_SIZE (2*65536L) -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#define NEED_TIME_R -#undef HAVE_STACK_GROWING_UP -#undef HAVE_WEAK_IO_SYMBOLS -#undef HAVE_WEAK_MALLOC_SYMBOLS -#define HAVE_DLL -#define USE_DLFCN -#define _PR_HAVE_SOCKADDR_LEN -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_STAT_HAS_ONLY_ST_ATIME -#ifdef _PR_INET6 -#define _PR_HAVE_INET_NTOP -#define _PR_HAVE_GETHOSTBYNAME2 -#ifdef _AIX51 /* AIX 4.3.3 does not have AI_NUMERICHOST. */ -#define _PR_HAVE_GETADDRINFO -#endif -#endif -#define _PR_HAVE_SYSV_SEMAPHORES -#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY -#define _PR_ACCEPT_INHERIT_NONBLOCK - -/* Timer operations */ -#if defined(AIX_TIMERS) -#define _MD_INTERVAL_INIT() - -extern PRIntervalTime _MD_AixGetInterval(void); -#define _MD_GET_INTERVAL _MD_AixGetInterval - -extern PRIntervalTime _MD_AixIntervalPerSec(void); -#define _MD_INTERVAL_PER_SEC _MD_AixIntervalPerSec - -#else /* defined(AIX_TIMERS) */ -#define _MD_INTERVAL_USE_GTOD -#endif /* defined(AIX_TIMERS) */ - -#ifdef AIX_HAVE_ATOMIC_OP_H -/* The atomic operations */ -#include -#define _PR_HAVE_ATOMIC_OPS -#ifndef IS_64 -#define _PR_HAVE_ATOMIC_CAS -#endif -#define _MD_INIT_ATOMIC() -#define _MD_ATOMIC_INCREMENT(val) ((PRInt32)fetch_and_add((atomic_p)val, 1) + 1) -#define _MD_ATOMIC_ADD(ptr, val) ((PRInt32)fetch_and_add((atomic_p)ptr, val) + val) -#define _MD_ATOMIC_DECREMENT(val) ((PRInt32)fetch_and_add((atomic_p)val, -1) - 1) -#define _MD_ATOMIC_SET(val, newval) _AIX_AtomicSet(val, newval) -#endif /* AIX_HAVE_ATOMIC_OP_H */ - -#define USE_SETJMP - -#include - -#define _MD_GET_SP(_t) (_t)->md.jb[3] -#define _MD_SET_THR_SP(_t, _sp) ((_t)->md.jb[3] = (int) (_sp - 2 * 64)) -#define PR_NUM_GCREGS _JBLEN - -#define CONTEXT(_th) ((_th)->md.jb) -#define SAVE_CONTEXT(_th) _setjmp(CONTEXT(_th)) -#define GOTO_CONTEXT(_th) _longjmp(CONTEXT(_th), 1) - -#ifdef PTHREADS_USER -#include "_nspr_pthread.h" -#else - -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - *status = PR_TRUE; \ - if (setjmp(CONTEXT(_thread))) { \ - (*_main)(); \ - } \ - _MD_GET_SP(_thread) = (int) (_sp - 2 * 64); \ - PR_END_MACRO - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!setjmp(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - longjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - jmp_buf jb; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#if !defined(_PR_PTHREADS) -#define _MD_INIT_LOCKS() -#endif - -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) -#endif /* PTHREADS_USER */ - -#ifdef AIX_RENAME_SELECT -#define _MD_SELECT select -#define _MD_POLL poll -#endif - -extern void _MD_aix_map_sendfile_error(int err); - -#endif /* nspr_aix_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_beos.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_beos.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_beos.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_beos.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_BEOS -#define XP_BEOS -#undef XP_UNIX -#endif - -#ifndef BEOS -#define BEOS -#endif - -#define PR_AF_INET6 5 /* same as AF_INET6 */ - -#ifdef __powerpc__ -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#else -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#endif - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -/* - * XXX These two macros need to be investigated for different architectures. - */ -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_beos.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_beos.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_beos.h 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_beos.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,583 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_beos_defs_h___ -#define nspr_beos_defs_h___ - -#include "prtypes.h" -#include "prio.h" -#include "prthread.h" -#include "prproces.h" -#include "prmem.h" -#include "obsolete/prsem.h" -#include - -#include -#include -#include - -/* - * Internal configuration macros - */ - -#ifdef BONE_VERSION -#define _PR_HAVE_SOCKADDR_LEN -#define HAVE_NETINET_TCP_H -#endif - -#define PR_LINKER_ARCH "beos" -#define _PR_SI_SYSNAME "BEOS" -#ifdef __powerpc__ -#define _PR_SI_ARCHITECTURE "ppc" -#else -#define _PR_SI_ARCHITECTURE "x86" -#endif -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#undef HAVE_STACK_GROWING_UP -#define HAVE_DLL -#define _PR_NO_CLOCK_TIMER - -/* - * The Atomic operations - */ - -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC _MD_AtomicInit -#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement -#define _MD_ATOMIC_ADD _MD_AtomicAdd -#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement -#define _MD_ATOMIC_SET _MD_AtomicSet - -#define HAVE_CVAR_BUILT_ON_SEM -#define _PR_GLOBAL_THREADS_ONLY -#define _PR_BTHREADS -#define _PR_NEED_FAKE_POLL -#define _PR_HAVE_PEEK_BUFFER -#define _PR_PEEK_BUFFER_MAX (16 * 1024) -#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) 1 -#define _PR_CONNECT_DOES_NOT_BIND -#define _PR_HAVE_O_APPEND - -/* Define threading functions and objects as native BeOS */ -struct _MDThread { - thread_id tid; /* BeOS thread handle */ - sem_id joinSem; /* sems used to synchronzie joining */ - PRBool is_joining; /* TRUE if someone is currently waiting to - join this thread */ -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -/* - * Lock and Semaphore related definitions - */ - -struct _MDLock { - sem_id semaphoreID; - int32 benaphoreCount; -}; - -struct _MDCVar { - sem_id sem1; - sem_id sem2; - int16 count; -}; - -struct _MDSemaphore { - sem_id sid; -}; - -/* -** CPU-related definitions -*/ -struct _MDCPU { - int8 unused; -}; - -/* -** Process-related definitions -*/ -struct _MDProcess { - pid_t pid; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* -** File- and directory-related definitions -*/ - -#ifndef BONE_VERSION -#define BE_SOCK_SHUTDOWN_READ 0x01 -#define BE_SOCK_SHUTDOWN_WRITE 0x02 -#endif - -struct _MDFileDesc { - PRInt32 osfd; - PRInt32 sock_state; - PRBool accepted_socket; - PRNetAddr peer_addr; -#ifndef BONE_VERSION - PRBool connectValueValid; - int connectReturnValue; - int connectReturnError; -#endif -}; - -struct _MDDir { - DIR *d; -}; - -#define PR_DIRECTORY_SEPARATOR '/' -#define PR_DIRECTORY_SEPARATOR_STR "/" -#define PR_PATH_SEPARATOR ':' -#define PR_PATH_SEPARATOR_STR ":" - -#define GETTIMEOFDAY(tp) gettimeofday((tp), NULL) - -/* --- Memory-mapped files stuff --- not implemented on BeOS */ - -struct _MDFileMap { - PRInt8 unused; -}; - -/* - * Network related definitions. - */ - -#ifndef BONE_VERSION -#define IPPROTO_IP 0 -#define AF_UNIX 2 -#define TCP_NODELAY SO_NONBLOCK -#define SO_LINGER -1 -#define SO_ERROR 4 -#endif - -#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 - -#ifndef BONE_VERSION -/* these aren't actually used. if they are, we're screwed */ -struct protoent { - char *p_name; /* official protocol name */ - char **p_aliases; /* alias list */ - int p_proto; /* protocol # */ -}; - -struct protoent* getprotobyname(const char* name); -struct protoent* getprotobynumber(int number); -#endif - -/* - * malloc() related definitions. - */ - -#undef _PR_OVERRIDE_MALLOC - -/* Miscellaneous */ - -#define _MD_ERRNO() (errno) - -#define _MD_CLEANUP_BEFORE_EXIT _MD_cleanup_before_exit -#define _MD_EXIT _MD_exit - -#define _MD_GET_ENV getenv -#define _MD_PUT_ENV putenv - -#define _MD_EARLY_INIT _MD_early_init -#define _MD_FINAL_INIT _MD_final_init -#define _MD_EARLY_CLEANUP() - -/* CPU Stuff */ - -#define _MD_INIT_CPUS _MD_init_cpus -#define _MD_WAKEUP_CPUS _MD_wakeup_cpus -#define _MD_START_INTERRUPTS _MD_start_interrupts -#define _MD_STOP_INTERRUPTS _MD_stop_interrupts -#define _MD_DISABLE_CLOCK_INTERRUPTS _MD_disable_clock_interrupts -#define _MD_BLOCK_CLOCK_INTERRUPTS _MD_block_clock_interrupts -#define _MD_UNBLOCK_CLOCK_INTERRUPTS _MD_unblock_clock_interrupts -#define _MD_CLOCK_INTERRUPT _MD_clock_interrupt -#define _MD_INIT_STACK _MD_init_stack -#define _MD_CLEAR_STACK _MD_clear_stack -// #define _MD_GET_INTSOFF _MD_get_intsoff -// #define _MD_SET_INTSOFF _MD_set_intsoff -#define _MD_CURRENT_CPU _MD_current_cpu -#define _MD_SET_CURRENT_CPU _MD_set_current_cpu -#define _MD_INIT_RUNNING_CPU _MD_init_running_cpu -#define _MD_PAUSE_CPU _MD_pause_cpu - -/* Thread stuff */ - -#define _MD_CURRENT_THREAD() PR_GetCurrentThread() -// #define _MD_GET_ATTACHED_THREAD _MD_get_attached_thread -#define _MD_LAST_THREAD _MD_last_thread -#define _MD_SET_CURRENT_THREAD _MD_set_current_THREAD -#define _MD_SET_LAST_THREAD _MD_set_last_thread -#define _MD_INIT_THREAD _MD_init_thread -#define _MD_EXIT_THREAD _MD_exit_thread -#define _MD_INIT_ATTACHED_THREAD _MD_init_attached_thread - -#define _MD_SUSPEND_THREAD _MD_suspend_thread -#define _MD_RESUME_THREAD _MD_resume_thread -#define _MD_SUSPEND_CPU _MD_suspend_cpu -#define _MD_RESUME_CPU _MD_resume_cpu -#define _MD_BEGIN_SUSPEND_ALL _MD_begin_suspend_all -#define _MD_END_SUSPEND_ALL _MD_end_suspend_all -#define _MD_BEGIN_RESUME_ALL _MD_begin_resume_all -#define _MD_END_RESUME_ALL _MD_end_resume_all - -#define _MD_GET_SP _MD_get_sp - -#define _MD_CLEAN_THREAD _MD_clean_thread -#define _MD_CREATE_PRIMORDIAL_USER_THREAD _MD_create_primordial_user_thread -#define _MD_CREATE_USER_THREAD _MD_create_user_thread -#define _MD_INIT_PRIMORDIAL_THREAD _MD_init_primordial_thread -#define _MD_CREATE_THREAD _MD_create_thread -#define _MD_YIELD _MD_yield -#define _MD_SET_PRIORITY _MD_set_priority - -#define _MD_SUSPENDALL _MD_suspendall -#define _MD_RESUMEALL _MD_resumeall - -#define _MD_SWITCH_CONTEXT _MD_switch_context -#define _MD_RESTORE_CONTEXT _MD_restore_context - -#define _MD_WAIT _MD_wait -#define _MD_WAKEUP_WAITER _MD_wakeup_waiter - -#define _MD_SETTHREADAFFINITYMASK _MD_setthreadaffinitymask -#define _MD_GETTHREADAFFINITYMASK _MD_getthreadaffinitymask - -/* Thread Synchronization */ - -#define _MD_INIT_LOCKS _MD_init_locks -#define _MD_NEW_LOCK _MD_new_lock -#define _MD_FREE_LOCK _MD_free_lock -#define _MD_LOCK _MD_lock -#define _MD_TEST_AND_LOCK _MD_test_and_lock -#define _MD_UNLOCK _MD_unlock -#define _MD_IOQ_LOCK _MD_ioq_lock -#define _MD_IOQ_UNLOCK _MD_ioq_unlock -#define _MD_NEW_SEM _MD_new_sem -#define _MD_DESTROY_SEM _MD_destroy_sem -#define _MD_TIMED_WAIT_SEM _MD_timed_wait_sem -#define _MD_WAIT_SEM _MD_wait_sem -#define _MD_POST_SEM _MD_post_sem -// #define _MD_NEW_CV _MD_new_cv -// #define _MD_FREE_CV _MD_free_cv -// #define _MD_WAIT_CV _MD_wait_cv -// #define _MD_NOTIFY_CV _MD_notify_cv -// #define _MD_NOTIFYALL_CV _MD_notifyall_cv - -/* File I/O */ - -/* don't need any I/O initializations */ -#define _MD_INIT_IO() -#define _MD_INIT_FILEDESC(fd) - -#define _MD_OPEN_DIR _MD_open_dir -#define _MD_READ_DIR _MD_read_dir -#define _MD_CLOSE_DIR _MD_close_dir -#define _MD_MAKE_NONBLOCK _MD_make_nonblock -#define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable -#define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable -#define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable -#define _MD_OPEN _MD_open -#define _MD_OPEN_FILE _MD_open -#define _MD_CLOSE_FILE _MD_close_file -#define _MD_READ _MD_read -#define _MD_WRITE _MD_write -#define _MD_WRITEV _MD_writev -#define _MD_LSEEK _MD_lseek -#define _MD_LSEEK64 _MD_lseek64 -#define _MD_FSYNC _MD_fsync -#define _MD_DELETE _MD_delete -#define _MD_GETFILEINFO _MD_getfileinfo -#define _MD_GETFILEINFO64 _MD_getfileinfo64 -#define _MD_GETOPENFILEINFO _MD_getopenfileinfo -#define _MD_GETOPENFILEINFO64 _MD_getopenfileinfo64 -#define _MD_RENAME _MD_rename -#define _MD_ACCESS _MD_access -#define _MD_STAT stat -#define _MD_MKDIR _MD_mkdir -#define _MD_MAKE_DIR _MD_mkdir -#define _MD_RMDIR _MD_rmdir -#define _MD_PR_POLL _MD_pr_poll - -/* Network I/O */ - -#define _MD_CLOSE_SOCKET _MD_close_socket -#define _MD_CONNECT _MD_connect -#define _MD_ACCEPT _MD_accept -#define _MD_BIND _MD_bind -#define _MD_LISTEN _MD_listen -#define _MD_SHUTDOWN _MD_shutdown -#define _MD_RECV _MD_recv -#define _MD_SEND _MD_send -#define _MD_ACCEPT_READ _MD_accept_read -#define _MD_GETSOCKNAME _MD_getsockname -#define _MD_GETPEERNAME _MD_getpeername -#define _MD_GETSOCKOPT _MD_getsockopt -#define _MD_SETSOCKOPT _MD_setsockopt -#define _MD_RECVFROM _MD_recvfrom -#define _MD_SENDTO _MD_sendto -#define _MD_SOCKETPAIR _MD_socketpair -#define _MD_SOCKET _MD_socket -#define _MD_SOCKETAVAILABLE _MD_socketavailable -#define _MD_PIPEAVAILABLE _MD_socketavailable - -#define _MD_GET_SOCKET_ERROR() (errno) -#define _MD_GETHOSTNAME _MD_gethostname - -#define _MD_SELECT select - -/* Process management */ - -#define _MD_CREATE_PROCESS _MD_create_process -#define _MD_DETACH_PROCESS _MD_detach_process -#define _MD_WAIT_PROCESS _MD_wait_process -#define _MD_KILL_PROCESS _MD_kill_process - -/* Atomic data operations */ - -// #define _MD_INIT_ATOMIC _MD_init_atomic -// #define _MD_ATOMIC_INCREMENT _MD_atomic_increment -// #define _MD_ATOMIC_DECREMENT _MD_atomic_decrement -// #define _MD_ATOMIC_SET _MD_atomic_set - -/* memory management */ - -#define _MD_INIT_SEGS _MD_init_segs -#define _MD_ALLOC_SEGMENT _MD_alloc_segment -#define _MD_FREE_SEGMENT _MD_free_segment - -/* Memory mapped file I/O */ - -#define _MD_CREATE_FILE_MAP _MD_create_file_map -#define _MD_GET_MEM_MAP_ALIGNMENT _MD_get_mem_map_alignment -#define _MD_MEM_MAP _MD_mem_map -#define _MD_MEM_UNMAP _MD_mem_unmap -#define _MD_CLOSE_FILE_MAP _MD_close_file_map - -/* Time related */ - -#define _MD_NOW _MD_now -#define _MD_INTERVAL_INIT _MD_interval_init -#define _MD_GET_INTERVAL _MD_get_interval -#define _MD_INTERVAL_PER_SEC _MD_interval_per_sec - -/* File locking */ - -#define _MD_LOCKFILE _MD_lockfile -#define _MD_TLOCKFILE _MD_tlockfile -#define _MD_UNLOCKFILE _MD_unlockfile - -/** - * Prototypes for machine dependent function implementations. (Too bad - * NSPR's MD system blows so much that we have to reiterate every stinking - * thing we implement here in our MD header file.) - */ - -/* Miscellaneous */ - -NSPR_API(void) _MD_cleanup_before_exit(void); -NSPR_API(void) _MD_exit(PRIntn status); - -NSPR_API(char*) _MD_get_env(const char *name); -NSPR_API(PRIntn) _MD_put_env(const char *name); - -NSPR_API(void) _MD_early_init(void); -NSPR_API(void) _MD_final_init(void); - -/* CPU Stuff */ - -NSPR_API(void) _MD_init_cpus(); -NSPR_API(void) _MD_wakeup_cpus(); -NSPR_API(void) _MD_start_interrupts(void); -NSPR_API(void) _MD_stop_interrupts(void); -NSPR_API(void) _MD_disable_clock_interrupts(void); -NSPR_API(void) _MD_block_clock_interrupts(void); -NSPR_API(void) _MD_unblock_clock_interrupts(void); -NSPR_API(void) _MD_clock_interrupt(void); -// NSPR_API(void) _MD_init_stack(PRThreadStack *ts, PRIntn redzone); -// NSPR_API(void) _MD_clear_stack(PRThreadStack* ts); -// NSPR_API(PRInt32) _MD_get_intsoff(void); -// NSPR_API(void) _MD_set_intsoff(PRInt32 _val); -// NSPR_API(_PRCPU*) _MD_current_cpu(void); -// NSPR_API(void) _MD_set_current_cpu(_PRCPU *cpu); -// NSPR_API(void) _MD_init_running_cpu(_PRCPU *cpu); -NSPR_API(PRInt32) _MD_pause_cpu(PRIntervalTime timeout); - -/* Thread stuff */ - -// NSPR_API(PRThread*) _MD_current_thread(void); -NSPR_API(PRThread*) _MD_get_attached_thread(void); -NSPR_API(PRThread*) _MD_last_thread(void); -NSPR_API(void) _MD_set_current_thread(PRThread *thread); -NSPR_API(void) _MD_set_last_thread(PRThread *thread); -NSPR_API(PRStatus) _MD_init_thread(PRThread *thread); -NSPR_API(void) _MD_exit_thread(PRThread *thread); -NSPR_API(PRStatus) _MD_init_attached_thread(PRThread *thread); - -NSPR_API(void) _MD_suspend_thread(PRThread *thread); -NSPR_API(void) _MD_resume_thread(PRThread *thread); -// NSPR_API(void) _MD_suspend_cpu(_PRCPU *cpu); -// NSPR_API(void) _MD_resume_cpu(_PRCPU *cpu); -NSPR_API(void) _MD_begin_suspend_all(void); -NSPR_API(void) _MD_end_suspend_all(void); -NSPR_API(void) _MD_begin_resume_all(void); -NSPR_API(void) _MD_end_resume_all(void); - -NSPR_API(void *) _MD_get_sp(PRThread *thread); - -NSPR_API(void) _MD_clean_thread(PRThread *thread); -NSPR_API(void) _MD_create_primordial_user_thread(PRThread *); -NSPR_API(PRThread*) _MD_create_user_thread(PRUint32 stacksize, void (*start)(void *), void *arg); -NSPR_API(void) _MD_init_primordial_thread(PRThread *thread); -NSPR_API(PRStatus) _MD_create_thread(PRThread *thread, void (*start)(void *), PRThreadPriority priority, PRThreadScope scope, PRThreadState state, PRUint32 stackSize); -NSPR_API(void) _MD_yield(void); -NSPR_API(void) _MD_set_priority(struct _MDThread *md, PRThreadPriority newPri); - -NSPR_API(void) _MD_suspendall(void); -NSPR_API(void) _MD_resumeall(void); - -NSPR_API(void) _MD_init_context(PRThread *thread, char *top, void (*start) (void), PRBool *status); -NSPR_API(void) _MD_switch_context(PRThread *thread); -NSPR_API(void) _MD_restore_context(PRThread *thread); - -NSPR_API(PRStatus) _MD_wait(PRThread *, PRIntervalTime timeout); -NSPR_API(PRStatus) _MD_wakeup_waiter(PRThread *); - -NSPR_API(PRInt32) _MD_setthreadaffinitymask(PRThread *thread, PRUint32 mask ); -NSPR_API(PRInt32) _MD_getthreadaffinitymask(PRThread *thread, PRUint32 *mask); - -/* Thread Synchronization */ - -NSPR_API(void) _MD_init_locks(void); -NSPR_API(PRStatus) _MD_new_lock(struct _MDLock *md); -NSPR_API(void) _MD_free_lock(struct _MDLock *md); -NSPR_API(void) _MD_lock(struct _MDLock *md); -NSPR_API(PRIntn) _MD_test_and_lock(struct _MDLock *md); -NSPR_API(void) _MD_unlock(struct _MDLock *md); -NSPR_API(void) _MD_ioq_lock(void); -NSPR_API(void) _MD_ioq_unlock(void); -NSPR_API(void) _MD_new_sem(struct _MDSemaphore *md, PRUintn value); -NSPR_API(void) _MD_destroy_sem(struct _MDSemaphore *md); -NSPR_API(PRStatus) _MD_timed_wait_sem(struct _MDSemaphore *md, PRIntervalTime timeout); -NSPR_API(PRStatus) _MD_wait_sem(struct _MDSemaphore *md); -NSPR_API(void) _MD_post_sem(struct _MDSemaphore *md); -// NSPR_API(PRInt32) _MD_new_cv(struct _MDCVar *md); -// NSPR_API(void) _MD_free_cv(struct _MDCVar *md); -// NSPR_API(void) _MD_wait_cv(struct _MDCVar *mdCVar, struct _MDLock *mdLock, PRIntervalTime timeout); -// NSPR_API(void) _MD_notify_cv(struct _MDCVar *md, struct _MDLock *lock); -// NSPR_API(void) _MD_notifyall_cv(struct _MDCVar *md, struct _MDLock *lock); - -/* File I/O */ - -// NSPR_API(void) _MD_init_io(void); -NSPR_API(PRStatus) _MD_open_dir(struct _MDDir *md,const char *name); -NSPR_API(char *) _MD_read_dir(struct _MDDir *md, PRIntn flags); -NSPR_API(PRInt32) _MD_close_dir(struct _MDDir *md); -NSPR_API(void) _MD_make_nonblock(PRFileDesc *fd); -NSPR_API(void) _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported); -NSPR_API(void) _MD_query_fd_inheritable(PRFileDesc *fd); -NSPR_API(PRInt32) _MD_open(const char *name, PRIntn osflags, PRIntn mode); -NSPR_API(PRInt32) _MD_close_file(PRInt32 osfd); -NSPR_API(PRInt32) _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount); -NSPR_API(PRInt32) _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount); -NSPR_API(PRInt32) _MD_writev(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout); -NSPR_API(PRInt32) _MD_lseek(PRFileDesc *fd, PRInt32 offset, int whence); -NSPR_API(PRInt64) _MD_lseek64(PRFileDesc *fd, PRInt64 offset, int whence); -NSPR_API(PRInt32) _MD_fsync(PRFileDesc *fd); -NSPR_API(PRInt32) _MD_delete(const char *name); -NSPR_API(PRInt32) _MD_getfileinfo(const char *fn, PRFileInfo *info); -NSPR_API(PRInt32) _MD_getfileinfo64(const char *fn, PRFileInfo64 *info); -NSPR_API(PRInt32) _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info); -NSPR_API(PRInt32) _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info); -NSPR_API(PRInt32) _MD_rename(const char *from, const char *to); -NSPR_API(PRInt32) _MD_access(const char *name, PRIntn how); -NSPR_API(PRInt32) _MD_stat(const char *name, struct stat *buf); -NSPR_API(PRInt32) _MD_mkdir(const char *name, PRIntn mode); -NSPR_API(PRInt32) _MD_rmdir(const char *name); -NSPR_API(PRInt32) _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout); - -/* Network I/O */ -NSPR_API(PRInt32) _MD_close_socket(PRInt32 osfd); -NSPR_API(PRInt32) _MD_connect(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); -NSPR_API(PRInt32) _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout); -NSPR_API(PRInt32) _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen); -NSPR_API(PRInt32) _MD_listen(PRFileDesc *fd, PRIntn backlog); -NSPR_API(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how); -NSPR_API(PRInt32) _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout); -NSPR_API(PRInt32) _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout); -NSPR_API(PRInt32) _MD_accept_read(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout); -// NSPR_API(PRInt32) _MD_fast_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout, PRBool fast, _PR_AcceptTimeoutCallback callback, void *callbackArg); -// NSPR_API(PRInt32) _MD_fast_accept_read(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout, PRBool fast, _PR_AcceptTimeoutCallback callback, void *callbackArg); -// NSPR_API(void) _MD_update_accept_context(PRInt32 s, PRInt32 ls); -NSPR_API(PRStatus) _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); -NSPR_API(PRStatus) _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); -NSPR_API(PRStatus) _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen); -NSPR_API(PRStatus) _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen); -NSPR_API(PRInt32) _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout); -NSPR_API(PRInt32) _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); -NSPR_API(PRInt32) _MD_socketpair(int af, int type, int flags, PRInt32 *osfd); -NSPR_API(PRInt32) _MD_socket(int af, int type, int flags); -NSPR_API(PRInt32) _MD_socketavailable(PRFileDesc *fd); - -// NSPR_API(PRInt32) _MD_get_socket_error(void); -NSPR_API(PRStatus) _MD_gethostname(char *name, PRUint32 namelen); - -/* Process management */ - -NSPR_API(PRProcess *) _MD_create_process(const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr); -NSPR_API(PRStatus) _MD_detach_process(PRProcess *process); -NSPR_API(PRStatus) _MD_wait_process(PRProcess *process, PRInt32 *exitCode); -NSPR_API(PRStatus) _MD_kill_process(PRProcess *process); - -/* Atomic data operations */ - -// NSPR_API(void) _MD_init_atomic(void); -// NSPR_API(PRInt32) _MD_atomic_increment(PRInt32 *); -// NSPR_API(PRInt32) _MD_atomic_decrement(PRInt32 *); -// NSPR_API(PRInt32) _MD_atomic_set(PRInt32 *, PRInt32); - -/* Memory management */ - -NSPR_API(void) _MD_init_segs(void); -NSPR_API(PRStatus) _MD_alloc_segment(PRSegment *seg, PRUint32 size, void *vaddr); -NSPR_API(void) _MD_free_segment(PRSegment *seg); - -/* Memory mapped file I/O */ - -NSPR_API(PRStatus) _MD_create_file_map(PRFileMap *fmap, PRInt64 size); -NSPR_API(PRInt32) _MD_get_mem_map_alignment(void); -NSPR_API(void *) _MD_mem_map(PRFileMap *fmap, PRInt64 offset, PRUint32 len); -NSPR_API(PRStatus) _MD_mem_unmap(void *addr, PRUint32 size); -NSPR_API(PRStatus) _MD_close_file_map(PRFileMap *fmap); - -/* Time related */ - -NSPR_API(PRTime) _MD_now(void); -NSPR_API(void) _MD_interval_init(void); -NSPR_API(PRIntervalTime) _MD_get_interval(void); -NSPR_API(PRIntervalTime) _MD_interval_per_sec(void); - -/* File locking */ - -NSPR_API(PRStatus) _MD_lockfile(PRInt32 osfd); -NSPR_API(PRStatus) _MD_tlockfile(PRInt32 osfd); -NSPR_API(PRStatus) _MD_unlockfile(PRInt32 osfd); - -#endif /* _nspr_beos_defs_h___*/ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_bsdi.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_bsdi.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_bsdi.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_bsdi.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,170 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef BSDI -#define BSDI -#endif - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#if defined(__i386__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__sparc__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#else - -#error "Unknown CPU architecture" - -#endif - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_bsdi.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_bsdi.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_bsdi.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_bsdi.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_bsdi_defs_h___ -#define nspr_bsdi_defs_h___ - -/* - * Internal configuration macros - */ - -#include /* for _BSDI_VERSION */ - -#define PR_LINKER_ARCH "bsdi" -#define _PR_SI_SYSNAME "BSDI" -#if defined(__i386__) -#define _PR_SI_ARCHITECTURE "x86" -#elif defined(__sparc__) -#define _PR_SI_ARCHITECTURE "sparc" -#else -#error "Unknown CPU architecture" -#endif -#define PR_DLL_SUFFIX ".so" - -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#define HAVE_BSD_FLOCK -#define NEED_TIME_R -#define _PR_HAVE_SOCKADDR_LEN -#define _PR_NO_LARGE_FILES - -#define USE_SETJMP - -/* BSD/OS 4.3 and newer all have IPv6 support */ -#if _BSDI_VERSION >= 200105 -#define _PR_INET6 -#define _PR_HAVE_INET_NTOP -#define _PR_HAVE_GETIPNODEBYNAME -#define _PR_HAVE_GETIPNODEBYADDR -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE -#endif - -#ifndef _PR_PTHREADS - -#include - -#if defined(_PR_BSDI_JMPBUF_IS_ARRAY) -#define _MD_GET_SP(_t) (_t)->md.context[2] -#elif defined(_PR_BSDI_JMPBUF_IS_STRUCT) -#define _MD_GET_SP(_t) (_t)->md.context[0].jb_esp -#else -#error "Unknown BSDI jmp_buf type" -#endif - -#define PR_NUM_GCREGS _JBLEN -#define PR_CONTEXT_TYPE jmp_buf - -#define CONTEXT(_th) ((_th)->md.context) - -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (setjmp(CONTEXT(_thread))) { \ - _main(); \ - } \ - _MD_GET_SP(_thread) = (int) (_sp - 64); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!setjmp(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - longjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -#endif /* ! _PR_PTHREADS */ - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit - -#include -#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) - -#define _MD_INTERVAL_USE_GTOD - -#endif /* nspr_bsdi_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/include/md/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/.cvsignore 2001-05-12 01:47:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_darwin.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_darwin.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_darwin.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_darwin.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,165 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#define PR_AF_INET6 30 /* same as AF_INET6 */ - -#ifdef __LITTLE_ENDIAN__ -#undef IS_BIG_ENDIAN -#define IS_LITTLE_ENDIAN 1 -#else -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#endif - -#ifdef __x86_64__ -#define IS_64 -#endif - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#undef HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS 1 - -#ifdef IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 -#define PR_BITS_PER_DWORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 -#define PR_BITS_PER_DWORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 -#define PR_ALIGN_OF_DWORD 8 - -#else /* IS_64 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 -#define PR_BITS_PER_DWORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#endif /* IS_64 */ - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_darwin.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_darwin.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_darwin.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_darwin.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,301 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_darwin_defs_h___ -#define nspr_darwin_defs_h___ - -#include "prthread.h" - -#include -#include - -#ifdef __APPLE__ -#include -#include -#endif - -#define PR_LINKER_ARCH "darwin" -#define _PR_SI_SYSNAME "DARWIN" -#ifdef __i386__ -#define _PR_SI_ARCHITECTURE "x86" -#elif defined(__x86_64__) -#define _PR_SI_ARCHITECTURE "x86-64" -#elif defined(__ppc__) -#define _PR_SI_ARCHITECTURE "ppc" -#elif defined(__arm__) -#define _PR_SI_ARCHITECTURE "arm" -#else -#error "Unknown CPU architecture" -#endif -#define PR_DLL_SUFFIX ".dylib" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#undef HAVE_STACK_GROWING_UP -#define HAVE_DLL -#if defined(__x86_64__) || TARGET_OS_IPHONE -#define USE_DLFCN -#else -#define USE_MACH_DYLD -#endif -#define _PR_HAVE_SOCKADDR_LEN -#define _PR_STAT_HAS_ST_ATIMESPEC -#define _PR_HAVE_LARGE_OFF_T -#define _PR_HAVE_SYSV_SEMAPHORES -#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY - -#define _PR_INET6 -/* - * I'd prefer to use getipnodebyname and getipnodebyaddr but the - * getipnodebyname(3) man page on Mac OS X 10.2 says they are not - * thread-safe. AI_V4MAPPED|AI_ADDRCONFIG doesn't work either. - */ -#define _PR_HAVE_GETHOSTBYNAME2 -#define _PR_HAVE_GETADDRINFO -/* - * On Mac OS X 10.2, gethostbyaddr fails with h_errno=NO_RECOVERY - * if you pass an IPv4-mapped IPv6 address to it. - */ -#define _PR_GHBA_DISALLOW_V4MAPPED -#ifdef __APPLE__ -#if !defined(MAC_OS_X_VERSION_10_3) || \ - MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 -/* - * socket(AF_INET6) fails with EPROTONOSUPPORT on Mac OS X 10.1. - * IPv6 under OS X 10.2 and below is not complete (see bug 222031). - */ -#define _PR_INET6_PROBE -#endif /* DT < 10.3 */ -#if defined(MAC_OS_X_VERSION_10_2) && \ - MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_2 -/* Mac OS X 10.2 has inet_ntop and inet_pton. */ -#define _PR_HAVE_INET_NTOP -#endif /* DT >= 10.2 */ -#endif /* __APPLE__ */ -#define _PR_IPV6_V6ONLY_PROBE -/* The IPV6_V6ONLY socket option is not defined on Mac OS X 10.1. */ -#ifndef IPV6_V6ONLY -#define IPV6_V6ONLY 27 -#endif - -#ifdef __ppc__ -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -extern PRInt32 _PR_DarwinPPC_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT(val) _PR_DarwinPPC_AtomicIncrement(val) -extern PRInt32 _PR_DarwinPPC_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT(val) _PR_DarwinPPC_AtomicDecrement(val) -extern PRInt32 _PR_DarwinPPC_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET(val, newval) _PR_DarwinPPC_AtomicSet(val, newval) -extern PRInt32 _PR_DarwinPPC_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD(ptr, val) _PR_DarwinPPC_AtomicAdd(ptr, val) -#endif /* __ppc__ */ - -#ifdef __i386__ -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -extern PRInt32 _PR_Darwin_x86_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT(val) _PR_Darwin_x86_AtomicIncrement(val) -extern PRInt32 _PR_Darwin_x86_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT(val) _PR_Darwin_x86_AtomicDecrement(val) -extern PRInt32 _PR_Darwin_x86_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET(val, newval) _PR_Darwin_x86_AtomicSet(val, newval) -extern PRInt32 _PR_Darwin_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD(ptr, val) _PR_Darwin_x86_AtomicAdd(ptr, val) -#endif /* __i386__ */ - -#ifdef __x86_64__ -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -extern PRInt32 _PR_Darwin_x86_64_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT(val) _PR_Darwin_x86_64_AtomicIncrement(val) -extern PRInt32 _PR_Darwin_x86_64_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT(val) _PR_Darwin_x86_64_AtomicDecrement(val) -extern PRInt32 _PR_Darwin_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET(val, newval) _PR_Darwin_x86_64_AtomicSet(val, newval) -extern PRInt32 _PR_Darwin_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD(ptr, val) _PR_Darwin_x86_64_AtomicAdd(ptr, val) -#endif /* __x86_64__ */ - -#ifdef __arm__ -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -#define _MD_ATOMIC_INCREMENT(val) OSAtomicIncrement32(val) -#define _MD_ATOMIC_DECREMENT(val) OSAtomicDecrement32(val) -static inline PRInt32 _MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) -{ - PRInt32 oldval; - do { - oldval = *val; - } while (!OSAtomicCompareAndSwap32(oldval, newval, val)); - return oldval; -} -#define _MD_ATOMIC_ADD(ptr, val) OSAtomicAdd32(val, ptr) -#endif /* __arm__ */ - -#define USE_SETJMP - -#if !defined(_PR_PTHREADS) - -#include - -#define PR_CONTEXT_TYPE jmp_buf - -#define CONTEXT(_th) ((_th)->md.context) -#define _MD_GET_SP(_th) (((struct sigcontext *) (_th)->md.context)->sc_onstack) -#define PR_NUM_GCREGS _JBLEN - -/* -** Initialize a thread context to run "_main()" when started -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (setjmp(CONTEXT(_thread))) { \ - _main(); \ - } \ - _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!setjmp(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - longjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -extern PRStatus _MD_InitializeThread(PRThread *thread); - -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread -#define _MD_RESUME_THREAD(thread) _MD_resume_thread -#define _MD_CLEAN_THREAD(_thread) - -extern PRStatus _MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize); -extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri); -extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout); -extern PRStatus _MD_WAKEUP_WAITER(PRThread *); -extern void _MD_YIELD(void); - -#endif /* ! _PR_PTHREADS */ - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INTERVAL_INIT _PR_Mach_IntervalInit -#define _MD_GET_INTERVAL _PR_Mach_GetInterval -#define _MD_INTERVAL_PER_SEC _PR_Mach_TicksPerSecond - -extern void _MD_EarlyInit(void); -extern void _PR_Mach_IntervalInit(void); -extern PRIntervalTime _PR_Mach_GetInterval(void); -extern PRIntervalTime _PR_Mach_TicksPerSecond(void); - -/* - * We wrapped the select() call. _MD_SELECT refers to the built-in, - * unwrapped version. - */ -#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) - -/* For writev() */ -#include - -#endif /* nspr_darwin_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_dgux.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_dgux.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_dgux.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_dgux.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef DGUX -#define DGUX -#endif - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_dgux.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_dgux.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_dgux.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_dgux.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,188 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_dgux_defs_h___ -#define nspr_dgux_defs_h___ - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "dgux" -#define _PR_SI_SYSNAME "DGUX" -#define _PR_SI_ARCHITECTURE "x86" -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#ifndef HAVE_WEAK_IO_SYMBOLS -#define HAVE_WEAK_IO_SYMBOLS -#endif - -#undef HAVE_STACK_GROWING_UP -#define HAVE_NETCONFIG -#define HAVE_DLL -#define USE_DLFCN -#define NEED_STRFTIME_LOCK -#define NEED_TIME_R -#define _PR_NEED_STRCASECMP -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_NO_LARGE_FILES -#define _PR_STAT_HAS_ONLY_ST_ATIME - -#define USE_SETJMP - -#include - -#define _SETJMP setjmp -#define _LONGJMP longjmp -#define _PR_CONTEXT_TYPE jmp_buf -#define _MD_GET_SP(_t) (_t)->md.context[4] -#define _PR_NUM_GCREGS _JBLEN - -#define CONTEXT(_th) ((_th)->md.context) - -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ - _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!_SETJMP(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - _LONGJMP(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures. - * Don't use SVR4 native threads (yet). - */ - -struct _MDThread { - _PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -/* - * The following are copied from _sunos.h, _aix.h. This means - * some of them should probably be moved into _unixos.h. But - * _irix.h seems to be quite different in regard to these macros. - */ -#define _MD_INTERVAL_USE_GTOD - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -/* - * We wrapped the select() call. _MD_SELECT refers to the built-in, - * unwrapped version. - */ -#include -#include -#include -extern int _select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *execptfds, struct timeval *timeout); -#define _MD_SELECT _select - -#define _MD_POLL _poll -#include -#include -extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); - -#endif /* nspr_dgux_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_freebsd.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_freebsd.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_freebsd.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_freebsd.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,305 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef FREEBSD -#define FREEBSD -#endif - -#define PR_AF_INET6 28 /* same as AF_INET6 */ - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif - -#if defined(__i386__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#elif defined(__alpha__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#elif defined(__sparc__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#elif defined(__ia64__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#elif defined(__amd64__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#else - -#error "Unknown CPU architecture" - -#endif - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_freebsd.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_freebsd.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_freebsd.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_freebsd.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,243 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_freebsd_defs_h___ -#define nspr_freebsd_defs_h___ - -#include "prthread.h" - -#if __FreeBSD__ >= 2 -#include /* for __FreeBSD_version */ -#endif -#include - -#define PR_LINKER_ARCH "freebsd" -#define _PR_SI_SYSNAME "FREEBSD" -#if defined(__i386__) -#define _PR_SI_ARCHITECTURE "x86" -#elif defined(__alpha__) -#define _PR_SI_ARCHITECTURE "alpha" -#elif defined(__sparc__) -#define _PR_SI_ARCHITECTURE "sparc" -#elif defined(__ia64__) -#define _PR_SI_ARCHITECTURE "ia64" -#elif defined(__amd64__) -#define _PR_SI_ARCHITECTURE "amd64" -#else -#error "Unknown CPU architecture" -#endif -#if defined(__ELF__) -#define PR_DLL_SUFFIX ".so" -#else -#define PR_DLL_SUFFIX ".so.1.0" -#endif - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#undef HAVE_STACK_GROWING_UP -#define HAVE_DLL -#define USE_DLFCN -#define _PR_HAVE_SOCKADDR_LEN -#define _PR_STAT_HAS_ST_ATIMESPEC -#define _PR_HAVE_LARGE_OFF_T - -#if defined(_PR_PTHREADS) -#if __FreeBSD_version >= 400008 -/* - * libc_r before this version of FreeBSD doesn't have poll(). - * Although libc has poll(), it is not thread-safe so we can't - * use it in the pthreads version. - */ -#define _PR_POLL_AVAILABLE -#endif -#else -#if __FreeBSD_version >= 300000 -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#endif -#endif - -#define _PR_HAVE_SYSV_SEMAPHORES -#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY - -#if __FreeBSD_version >= 400014 -#define _PR_INET6 -#define _PR_HAVE_INET_NTOP -#define _PR_HAVE_GETHOSTBYNAME2 -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE -#define _PR_IPV6_V6ONLY_PROBE -#endif - -#define USE_SETJMP - -#ifndef _PR_PTHREADS -#include - -#define PR_CONTEXT_TYPE sigjmp_buf - -#define CONTEXT(_th) ((_th)->md.context) - -#define _MD_GET_SP(_th) (_th)->md.context[0]._sjb[2] -#define PR_NUM_GCREGS _JBLEN - -/* -** Initialize a thread context to run "_main()" when started -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (sigsetjmp(CONTEXT(_thread), 1)) { \ - _main(); \ - } \ - _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!sigsetjmp(CONTEXT(_thread), 1)) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - siglongjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -extern PRStatus _MD_InitializeThread(PRThread *thread); - -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread -#define _MD_RESUME_THREAD(thread) _MD_resume_thread -#define _MD_CLEAN_THREAD(_thread) - -extern PRStatus _MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize); -extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri); -extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout); -extern PRStatus _MD_WAKEUP_WAITER(PRThread *); -extern void _MD_YIELD(void); - -#endif /* ! _PR_PTHREADS */ - -extern void _MD_EarlyInit(void); - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INTERVAL_USE_GTOD - -/* - * We wrapped the select() call. _MD_SELECT refers to the built-in, - * unwrapped version. - */ -#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) - -#if defined(_PR_POLL_AVAILABLE) -#include -#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout) -#endif - -/* freebsd has INADDR_LOOPBACK defined, but in /usr/include/rpc/types.h, and I didn't - want to be including that.. */ -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK (u_long)0x7F000001 -#endif - -/* For writev() */ -#include - -#endif /* nspr_freebsd_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_hpux32.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_hpux32.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_hpux32.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_hpux32.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef HPUX -#define HPUX -#endif - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_AF_INET6 22 /* same as AF_INET6 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_hpux64.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_hpux64.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_hpux64.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_hpux64.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef HPUX -#define HPUX -#endif - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define IS_64 - -#define PR_AF_INET6 22 /* same as AF_INET6 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_hpux.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_hpux.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_hpux.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_hpux.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,288 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_xhppa_defs_h___ -#define nspr_xhppa_defs_h___ - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "hpux" -#define _PR_SI_SYSNAME "HPUX" -#ifdef __ia64 -#define _PR_SI_ARCHITECTURE "ia64" -#define PR_DLL_SUFFIX ".so" -#else -/* - * _PR_SI_ARCHITECTURE must be "hppa1.1" for backward compatibility. - * It was changed to "hppa" in NSPR 4.6.2, but was changed back in - * NSPR 4.6.4. - */ -#define _PR_SI_ARCHITECTURE "hppa1.1" -#define PR_DLL_SUFFIX ".sl" -#endif - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -/* - * _USE_BIG_FDS increases the size of fd_set from 256 bytes to - * about 7500 bytes. PR_Poll allocates three fd_sets on the - * stack, so it is safer to also increase the default thread - * stack size. - */ -#define _MD_DEFAULT_STACK_SIZE (2*65536L) -#define _MD_MINIMUM_STACK_SIZE (2*65536L) -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#define NEED_TIME_R - -#define HAVE_STACK_GROWING_UP -#undef HAVE_WEAK_IO_SYMBOLS -#undef HAVE_WEAK_MALLOC_SYMBOLS -#define HAVE_DLL -#ifdef IS_64 -#define USE_DLFCN -#else -#define USE_HPSHL -#endif -#ifndef HAVE_STRERROR -#define HAVE_STRERROR -#endif -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_STAT_HAS_ONLY_ST_ATIME -#define _PR_HAVE_POSIX_SEMAPHORES -#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY -#define _PR_ACCEPT_INHERIT_NONBLOCK - -#if defined(__ia64) -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT _PR_ia64_AtomicIncrement -extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT _PR_ia64_AtomicDecrement -extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD _PR_ia64_AtomicAdd -extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET _PR_ia64_AtomicSet -#endif - -#define _PR_HAVE_GETIPNODEBYNAME -#define _PR_HAVE_GETIPNODEBYADDR -#define _PR_HAVE_GETADDRINFO -#ifdef _PR_INET6 -#define _PR_HAVE_INET_NTOP -#else -#define _PR_INET6_PROBE - -/* for HP-UX 11.11 without IPv6 */ -#ifndef AF_INET6 -#define AF_INET6 22 -#define AI_CANONNAME 2 -#define AI_NUMERICHOST 4 -#define AI_NUMERICSERV 8 -#define AI_V4MAPPED 0x00000010 -#define AI_ADDRCONFIG 0x00000040 -#define AI_ALL 0x00000020 -#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) -#define NI_NUMERICHOST 2 -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* IPPROTO_xxx for IPv4 and IPv6 */ - socklen_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for host */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif /* for HP-UX 11.11 without IPv6 */ - -#define _PR_HAVE_MD_SOCKADDR_IN6 -/* isomorphic to struct in6_addr on HP-UX B.11.23 */ -struct _md_in6_addr { - union { - PRUint8 _S6_u8[16]; - PRUint16 _S6_u16[8]; - PRUint32 _S6_u32[4]; - PRUint32 __S6_align; - } _s6_un; -}; -/* isomorphic to struct sockaddr_in6 on HP-UX B.11.23 */ -struct _md_sockaddr_in6 { - PRUint16 sin6_family; - PRUint16 sin6_port; - PRUint32 sin6_flowinfo; - struct _md_in6_addr sin6_addr; - PRUint32 sin6_scope_id; -}; -#endif - -#if !defined(_PR_PTHREADS) - -#include -#include - -#define USE_SETJMP - -#define _MD_GET_SP(_t) (*((int *)((_t)->md.jb) + 1)) -#define PR_NUM_GCREGS _JBLEN -/* Caveat: This makes jmp_buf full of doubles. */ -#define CONTEXT(_th) ((_th)->md.jb) - - /* Stack needs two frames (64 bytes) at the bottom */ \ -#define _MD_SET_THR_SP(_t, _sp) ((_MD_GET_SP(_t)) = (int) (_sp + 64 *2)) -#define SAVE_CONTEXT(_th) _setjmp(CONTEXT(_th)) -#define GOTO_CONTEXT(_th) _longjmp(CONTEXT(_th), 1) - -#if !defined(PTHREADS_USER) - -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *(status) = PR_TRUE; \ - if (_setjmp(CONTEXT(_thread))) (*_main)(); \ - /* Stack needs two frames (64 bytes) at the bottom */ \ - (_MD_GET_SP(_thread)) = (int) ((_sp) + 64*2); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!_setjmp(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - _longjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures. HP-UX has no native threads. */ - -struct _MDThread { - jmp_buf jb; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread -#define _MD_RESUME_THREAD(thread) _MD_resume_thread -#define _MD_CLEAN_THREAD(_thread) - -#else /* PTHREADS_USER */ - -#include "_nspr_pthread.h" - -#endif /* PTHREADS_USER */ - -#endif /* !defined(_PR_PTHREADS) */ - -#if !defined(PTHREADS_USER) -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#endif - -#if defined(HPUX_LW_TIMER) -extern void _PR_HPUX_LW_IntervalInit(void); -extern PRIntervalTime _PR_HPUX_LW_GetInterval(void); -#define _MD_INTERVAL_INIT _PR_HPUX_LW_IntervalInit -#define _MD_GET_INTERVAL _PR_HPUX_LW_GetInterval -#define _MD_INTERVAL_PER_SEC() 1000 -#else -#define _MD_INTERVAL_USE_GTOD -#endif - -/* - * We wrapped the select() call. _MD_SELECT refers to the built-in, - * unwrapped version. - */ -#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) - -#include -#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout) - -#ifdef HPUX11 -extern void _MD_hpux_map_sendfile_error(int err); -#endif /* HPUX11 */ - -#endif /* nspr_xhppa_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_irix32.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_irix32.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_irix32.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_irix32.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef _SGI_MP_SOURCE -#define _SGI_MP_SOURCE -#endif - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef IRIX -#define IRIX -#endif - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#define _PR_POLL_BACKCOMPAT - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_irix64.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_irix64.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_irix64.cfg 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_irix64.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef _SGI_MP_SOURCE -#define _SGI_MP_SOURCE -#endif - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef IRIX -#define IRIX -#endif - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define IS_64 - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_irix.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_irix.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_irix.h 2012-03-06 13:13:51.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_irix.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,438 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_irix_defs_h___ -#define nspr_irix_defs_h___ - -#define _PR_HAVE_ATOMIC_CAS - -/* - * MipsPro assembler defines _LANGUAGE_ASSEMBLY - */ -#ifndef _LANGUAGE_ASSEMBLY - -#include "prclist.h" -#include "prthread.h" -#include - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "irix" -#define _PR_SI_SYSNAME "IRIX" -#define _PR_SI_ARCHITECTURE "mips" -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _PR_NUM_GCREGS 9 -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MIN_STACK_SIZE 16384L - -#undef HAVE_STACK_GROWING_UP -#define HAVE_WEAK_IO_SYMBOLS -#define HAVE_WEAK_MALLOC_SYMBOLS -#define HAVE_DLL -#define USE_DLFCN -#define _PR_HAVE_ATOMIC_OPS -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_STAT_HAS_ST_ATIM -#define _PR_HAVE_OFF64_T -#define HAVE_POINTER_LOCALTIME_R -#define _PR_HAVE_POSIX_SEMAPHORES -#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY -#define _PR_ACCEPT_INHERIT_NONBLOCK - -#ifdef _PR_INET6 -#define _PR_HAVE_INET_NTOP -#define _PR_HAVE_GETIPNODEBYNAME -#define _PR_HAVE_GETIPNODEBYADDR -#define _PR_HAVE_GETADDRINFO -#endif - -/* Initialization entry points */ -NSPR_API(void) _MD_EarlyInit(void); -#define _MD_EARLY_INIT _MD_EarlyInit - -NSPR_API(void) _MD_IrixInit(void); -#define _MD_FINAL_INIT _MD_IrixInit - -#define _MD_INIT_IO() - -/* Timer operations */ -NSPR_API(PRIntervalTime) _MD_IrixGetInterval(void); -#define _MD_GET_INTERVAL _MD_IrixGetInterval - -NSPR_API(PRIntervalTime) _MD_IrixIntervalPerSec(void); -#define _MD_INTERVAL_PER_SEC _MD_IrixIntervalPerSec - -/* GC operations */ -NSPR_API(void *) _MD_GetSP(PRThread *thread); -#define _MD_GET_SP _MD_GetSP - -/* The atomic operations */ -#include -#define _MD_INIT_ATOMIC() -#define _MD_ATOMIC_INCREMENT(val) add_then_test((unsigned long*)val, 1) -#define _MD_ATOMIC_ADD(ptr, val) add_then_test((unsigned long*)ptr, (unsigned long)val) -#define _MD_ATOMIC_DECREMENT(val) add_then_test((unsigned long*)val, 0xffffffff) -#define _MD_ATOMIC_SET(val, newval) test_and_set((unsigned long*)val, newval) - -#if defined(_PR_PTHREADS) -#else /* defined(_PR_PTHREADS) */ - -/************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - - -/* - * Data region private to each sproc. This region is setup by calling - * mmap(...,MAP_LOCAL,...). The private data is mapped at the same - * address in every sproc, but every sproc gets a private mapping. - * - * Just make sure that this structure fits in a page, as only one page - * is allocated for the private region. - */ -struct sproc_private_data { - struct PRThread *me; - struct _PRCPU *cpu; - struct PRThread *last; - PRUintn intsOff; - int sproc_pid; -}; - -extern char *_nspr_sproc_private; - -#define _PR_PRDA() ((struct sproc_private_data *) _nspr_sproc_private) -#define _MD_SET_CURRENT_THREAD(_thread) _PR_PRDA()->me = (_thread) -#define _MD_THIS_THREAD() (_PR_PRDA()->me) -#define _MD_LAST_THREAD() (_PR_PRDA()->last) -#define _MD_SET_LAST_THREAD(_thread) _PR_PRDA()->last = (_thread) -#define _MD_CURRENT_CPU() (_PR_PRDA()->cpu) -#define _MD_SET_CURRENT_CPU(_cpu) _PR_PRDA()->cpu = (_cpu) -#define _MD_SET_INTSOFF(_val) (_PR_PRDA()->intsOff = _val) -#define _MD_GET_INTSOFF() (_PR_PRDA()->intsOff) - -#define _MD_SET_SPROC_PID(_val) (_PR_PRDA()->sproc_pid = _val) -#define _MD_GET_SPROC_PID() (_PR_PRDA()->sproc_pid) - -NSPR_API(struct PRThread*) _MD_get_attached_thread(void); -NSPR_API(struct PRThread*) _MD_get_current_thread(void); -#define _MD_GET_ATTACHED_THREAD() _MD_get_attached_thread() -#define _MD_CURRENT_THREAD() _MD_get_current_thread() - -#define _MD_CHECK_FOR_EXIT() { \ - if (_pr_irix_exit_now) { \ - _PR_POST_SEM(_pr_irix_exit_sem); \ - _MD_Wakeup_CPUs(); \ - _exit(0); \ - } \ - } - -#define _MD_ATTACH_THREAD(threadp) - -#define _MD_SAVE_ERRNO(_thread) (_thread)->md.errcode = errno; -#define _MD_RESTORE_ERRNO(_thread) errno = (_thread)->md.errcode; - -extern struct _PRCPU *_pr_primordialCPU; -extern usema_t *_pr_irix_exit_sem; -extern PRInt32 _pr_irix_exit_now; -extern int _pr_irix_primoridal_cpu_fd[]; -extern PRInt32 _pr_irix_process_exit; -extern PRInt32 _pr_irix_process_exit_code; - -/* Thread operations */ -#define _PR_LOCK_HEAP() { \ - PRIntn _is; \ - if (_pr_primordialCPU) { \ - if (_MD_GET_ATTACHED_THREAD() && \ - !_PR_IS_NATIVE_THREAD( \ - _MD_GET_ATTACHED_THREAD())) \ - _PR_INTSOFF(_is); \ - _PR_LOCK(_pr_heapLock); \ - } - -#define _PR_UNLOCK_HEAP() if (_pr_primordialCPU) { \ - _PR_UNLOCK(_pr_heapLock); \ - if (_MD_GET_ATTACHED_THREAD() && \ - !_PR_IS_NATIVE_THREAD( \ - _MD_GET_ATTACHED_THREAD())) \ - _PR_INTSON(_is); \ - } \ - } - -#define _PR_OPEN_POLL_SEM(_sem) usopenpollsema(_sem, 0666) -#define _PR_WAIT_SEM(_sem) uspsema(_sem) -#define _PR_POST_SEM(_sem) usvsema(_sem) - -#define _MD_CVAR_POST_SEM(threadp) usvsema((threadp)->md.cvar_pollsem) - -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -struct _MDLock { - ulock_t lock; - usptr_t *arena; -}; - -/* - * disable pre-emption for the LOCAL threads when calling the arena lock - * routines - */ - -#define _PR_LOCK(lock) { \ - PRIntn _is; \ - PRThread *me = _MD_GET_ATTACHED_THREAD(); \ - if (me && !_PR_IS_NATIVE_THREAD(me)) \ - _PR_INTSOFF(_is); \ - ussetlock(lock); \ - if (me && !_PR_IS_NATIVE_THREAD(me)) \ - _PR_FAST_INTSON(_is); \ - } - -#define _PR_UNLOCK(lock) { \ - PRIntn _is; \ - PRThread *me = _MD_GET_ATTACHED_THREAD(); \ - if (me && !_PR_IS_NATIVE_THREAD(me)) \ - _PR_INTSOFF(_is); \ - usunsetlock(lock); \ - if (me && !_PR_IS_NATIVE_THREAD(me)) \ - _PR_FAST_INTSON(_is); \ - } - -NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md); -NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp); - -#define _MD_LOCK(_lockp) _PR_LOCK((_lockp)->lock) -#define _MD_UNLOCK(_lockp) _PR_UNLOCK((_lockp)->lock) -#define _MD_TEST_AND_LOCK(_lockp) (uscsetlock((_lockp)->lock, 1) == 0) - -extern ulock_t _pr_heapLock; - -struct _MDThread { - jmp_buf jb; - usptr_t *pollsem_arena; - usema_t *cvar_pollsem; - PRInt32 cvar_pollsemfd; - PRInt32 cvar_pollsem_select; /* acquire sem by calling select */ - PRInt32 cvar_wait; /* if 1, thread is waiting on cvar Q */ - PRInt32 id; - PRInt32 suspending_id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDSemaphore { - usema_t *sem; -}; - -struct _MDCVar { - ulock_t mdcvar_lock; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - - -struct _MDCPU { - PRInt32 id; - PRInt32 suspending_id; - struct _MDCPU_Unix md_unix; -}; - -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - int *jb = (_thread)->md.jb; \ - *status = PR_TRUE; \ - (void) setjmp(jb); \ - (_thread)->md.jb[JB_SP] = (int) ((_sp) - 64); \ - (_thread)->md.jb[JB_PC] = (int) _main; \ - _thread->no_sched = 0; \ - PR_END_MACRO - -/* -** Switch away from the current thread context by saving its state and -** calling the thread scheduler. Reload cpu when we come back from the -** context switch because it might have changed. -* -* XXX RUNQ lock needed before clearing _PR_NO_SCHED flag, because the -* thread may be unr RUNQ? -*/ -#define _MD_SWITCH_CONTEXT(_thread) \ - PR_BEGIN_MACRO \ - PR_ASSERT(_thread->no_sched); \ - if (!setjmp(_thread->md.jb)) { \ - _MD_SAVE_ERRNO(_thread) \ - _MD_SET_LAST_THREAD(_thread); \ - _PR_Schedule(); \ - } else { \ - PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \ - _MD_LAST_THREAD()->no_sched = 0; \ - } \ - PR_END_MACRO - -/* -** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or -** initialized by _MD_INIT_CONTEXT. -*/ -#define _MD_RESTORE_CONTEXT(_newThread) \ - PR_BEGIN_MACRO \ - int *jb = (_newThread)->md.jb; \ - _MD_RESTORE_ERRNO(_newThread) \ - _MD_SET_CURRENT_THREAD(_newThread); \ - _newThread->no_sched = 1; \ - longjmp(jb, 1); \ - PR_END_MACRO - -NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread, - PRBool wakeup_parent); -NSPR_API(PRStatus) _MD_InitAttachedThread(struct PRThread *thread, - PRBool wakeup_parent); -#define _MD_INIT_THREAD(thread) _MD_InitThread(thread, PR_TRUE) -#define _MD_INIT_ATTACHED_THREAD(thread) \ - _MD_InitAttachedThread(thread, PR_FALSE) - -NSPR_API(void) _MD_ExitThread(struct PRThread *thread); -#define _MD_EXIT_THREAD _MD_ExitThread - -NSPR_API(void) _MD_SuspendThread(struct PRThread *thread); -#define _MD_SUSPEND_THREAD _MD_SuspendThread - -NSPR_API(void) _MD_ResumeThread(struct PRThread *thread); -#define _MD_RESUME_THREAD _MD_ResumeThread - -NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread); -#define _MD_SUSPEND_CPU _MD_SuspendCPU - -NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread); -#define _MD_RESUME_CPU _MD_ResumeCPU - -#define _MD_BEGIN_SUSPEND_ALL() -#define _MD_END_SUSPEND_ALL() -#define _MD_BEGIN_RESUME_ALL() -#define _MD_END_RESUME_ALL() - -NSPR_API(void) _MD_InitLocks(void); -#define _MD_INIT_LOCKS _MD_InitLocks - -NSPR_API(void) _MD_CleanThread(struct PRThread *thread); -#define _MD_CLEAN_THREAD _MD_CleanThread - -#define _MD_YIELD() sginap(0) - -/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and - * awaken a thread which is waiting on a lock or cvar. - */ -NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout); -#define _MD_WAIT _MD_wait - -NSPR_API(void) _PR_MD_primordial_cpu(); -NSPR_API(void) _PR_MD_WAKEUP_PRIMORDIAL_CPU(); - -NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *); -#define _MD_WAKEUP_WAITER _MD_WakeupWaiter - -NSPR_API(void ) _MD_exit(PRIntn status); -#define _MD_EXIT _MD_exit - -#include "prthread.h" - -NSPR_API(void) _MD_SetPriority(struct _MDThread *thread, - PRThreadPriority newPri); -#define _MD_SET_PRIORITY _MD_SetPriority - -NSPR_API(PRStatus) _MD_CreateThread( - struct PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize); -#define _MD_CREATE_THREAD _MD_CreateThread - -extern void _MD_CleanupBeforeExit(void); -#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit - -NSPR_API(void) _PR_MD_PRE_CLEANUP(PRThread *me); - - -/* The following defines the unwrapped versions of select() and poll(). */ -extern int _select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout); -#define _MD_SELECT _select - -#include -#include -#define _MD_POLL _poll -extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); - - -#define HAVE_THREAD_AFFINITY 1 - -NSPR_API(PRInt32) _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask); -#define _MD_GETTHREADAFFINITYMASK _MD_GetThreadAffinityMask - -NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu); -#define _MD_INIT_RUNNING_CPU _MD_InitRunningCPU - -#endif /* defined(_PR_PTHREADS) */ - -#endif /* _LANGUAGE_ASSEMBLY */ - -#endif /* nspr_irix_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_linux.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_linux.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_linux.cfg 2012-10-19 23:36:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_linux.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,925 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This file is used by not only Linux but also other glibc systems - * such as GNU/Hurd and GNU/k*BSD. - */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#if !defined(LINUX) && defined(__linux__) -#define LINUX -#endif - -#ifdef __FreeBSD_kernel__ -#define PR_AF_INET6 28 /* same as AF_INET6 */ -#elif defined(__GNU__) -#define PR_AF_INET6 26 /* same as AF_INET6 */ -#else -#define PR_AF_INET6 10 /* same as AF_INET6 */ -#endif - -#ifdef __powerpc64__ - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__powerpc__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__alpha) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__ia64__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__x86_64__) - -#ifdef __ILP32__ - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#else - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#endif - -#elif defined(__mc68000__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 2 -#define PR_ALIGN_OF_LONG 2 -#define PR_ALIGN_OF_INT64 2 -#define PR_ALIGN_OF_FLOAT 2 -#define PR_ALIGN_OF_DOUBLE 2 -#define PR_ALIGN_OF_POINTER 2 -#define PR_ALIGN_OF_WORD 2 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__sparc__) && defined (__arch64__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__sparc__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__i386__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__mips__) - -#ifdef __MIPSEB__ -#define IS_BIG_ENDIAN 1 -#undef IS_LITTLE_ENDIAN -#elif defined(__MIPSEL__) -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#else -#error "Unknown MIPS endianness." -#endif - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__arm__) - -#ifdef __ARMEB__ -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#elif defined(__ARMEL__) -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#else -#error "Unknown ARM endianness." -#endif - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__hppa__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__s390x__) - -#define IS_BIG_ENDIAN 1 -#undef IS_LITTLE_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__s390__) - -#define IS_BIG_ENDIAN 1 -#undef IS_LITTLE_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__sh__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__avr32__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__m32r__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#else - -#error "Unknown CPU architecture" - -#endif - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#if PR_ALIGN_OF_DOUBLE == 8 -#define HAVE_ALIGNED_DOUBLES -#endif -#if PR_ALIGN_OF_INT64 == 8 -#define HAVE_ALIGNED_LONGLONGS -#endif - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_linux.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_linux.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_linux.h 2012-11-10 11:48:55.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_linux.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,652 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This file is used by not only Linux but also other glibc systems - * such as GNU/Hurd and GNU/k*BSD. - */ - -#ifndef nspr_linux_defs_h___ -#define nspr_linux_defs_h___ - -#include "prthread.h" - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "linux" -#define _PR_SI_SYSNAME "LINUX" -#ifdef __powerpc64__ -#define _PR_SI_ARCHITECTURE "ppc64" -#elif defined(__powerpc__) -#define _PR_SI_ARCHITECTURE "ppc" -#elif defined(__alpha) -#define _PR_SI_ARCHITECTURE "alpha" -#elif defined(__ia64__) -#define _PR_SI_ARCHITECTURE "ia64" -#elif defined(__x86_64__) -#define _PR_SI_ARCHITECTURE "x86-64" -#elif defined(__mc68000__) -#define _PR_SI_ARCHITECTURE "m68k" -#elif defined(__sparc__) && defined(__arch64__) -#define _PR_SI_ARCHITECTURE "sparc64" -#elif defined(__sparc__) -#define _PR_SI_ARCHITECTURE "sparc" -#elif defined(__i386__) -#define _PR_SI_ARCHITECTURE "x86" -#elif defined(__mips__) -#define _PR_SI_ARCHITECTURE "mips" -#elif defined(__arm__) -#define _PR_SI_ARCHITECTURE "arm" -#elif defined(__hppa__) -#define _PR_SI_ARCHITECTURE "hppa" -#elif defined(__s390x__) -#define _PR_SI_ARCHITECTURE "s390x" -#elif defined(__s390__) -#define _PR_SI_ARCHITECTURE "s390" -#elif defined(__sh__) -#define _PR_SI_ARCHITECTURE "sh" -#elif defined(__avr32__) -#define _PR_SI_ARCHITECTURE "avr32" -#elif defined(__m32r__) -#define _PR_SI_ARCHITECTURE "m32r" -#else -#error "Unknown CPU architecture" -#endif -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#undef HAVE_STACK_GROWING_UP - -/* - * Elf linux supports dl* functions - */ -#define HAVE_DLL -#define USE_DLFCN -#if defined(ANDROID) -#define NO_DLOPEN_NULL -#endif - -#ifdef __FreeBSD_kernel__ -#define _PR_HAVE_SOCKADDR_LEN -#endif - -#if defined(__i386__) -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -extern PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT _PR_x86_AtomicIncrement -extern PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT _PR_x86_AtomicDecrement -extern PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD _PR_x86_AtomicAdd -extern PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET _PR_x86_AtomicSet -#endif - -#if defined(__ia64__) -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT _PR_ia64_AtomicIncrement -extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT _PR_ia64_AtomicDecrement -extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD _PR_ia64_AtomicAdd -extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET _PR_ia64_AtomicSet -#endif - -#if defined(__x86_64__) -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -extern PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT _PR_x86_64_AtomicIncrement -extern PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT _PR_x86_64_AtomicDecrement -extern PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD _PR_x86_64_AtomicAdd -extern PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET _PR_x86_64_AtomicSet -#endif - -#if defined(__powerpc__) && !defined(__powerpc64__) -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -extern PRInt32 _PR_ppc_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT _PR_ppc_AtomicIncrement -extern PRInt32 _PR_ppc_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT _PR_ppc_AtomicDecrement -extern PRInt32 _PR_ppc_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD _PR_ppc_AtomicAdd -extern PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET _PR_ppc_AtomicSet -#endif - -#if defined(__alpha) -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -#define _MD_ATOMIC_ADD(ptr, i) ({ \ - PRInt32 __atomic_tmp, __atomic_ret; \ - __asm__ __volatile__( \ - "1: ldl_l %[ret], %[val] \n" \ - " addl %[ret], %[inc], %[tmp] \n" \ - " addl %[ret], %[inc], %[ret] \n" \ - " stl_c %[tmp], %[val] \n" \ - " beq %[tmp], 2f \n" \ - ".subsection 2 \n" \ - "2: br 1b \n" \ - ".previous" \ - : [ret] "=&r" (__atomic_ret), \ - [tmp] "=&r" (__atomic_tmp), \ - [val] "=m" (*ptr) \ - : [inc] "Ir" (i), "m" (*ptr)); \ - __atomic_ret; \ -}) -#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1) -#define _MD_ATOMIC_DECREMENT(ptr) ({ \ - PRInt32 __atomic_tmp, __atomic_ret; \ - __asm__ __volatile__( \ - "1: ldl_l %[ret], %[val] \n" \ - " subl %[ret], 1, %[tmp] \n" \ - " subl %[ret], 1, %[ret] \n" \ - " stl_c %[tmp], %[val] \n" \ - " beq %[tmp], 2f \n" \ - ".subsection 2 \n" \ - "2: br 1b \n" \ - ".previous" \ - : [ret] "=&r" (__atomic_ret), \ - [tmp] "=&r" (__atomic_tmp), \ - [val] "=m" (*ptr) \ - : "m" (*ptr)); \ - __atomic_ret; \ -}) -#define _MD_ATOMIC_SET(ptr, n) ({ \ - PRInt32 __atomic_tmp, __atomic_ret; \ - __asm__ __volatile__( \ - "1: ldl_l %[ret], %[val] \n" \ - " mov %[newval], %[tmp] \n" \ - " stl_c %[tmp], %[val] \n" \ - " beq %[tmp], 2f \n" \ - ".subsection 2 \n" \ - "2: br 1b \n" \ - ".previous" \ - : [ret] "=&r" (__atomic_ret), \ - [tmp] "=&r"(__atomic_tmp), \ - [val] "=m" (*ptr) \ - : [newval] "Ir" (n), "m" (*ptr)); \ - __atomic_ret; \ -}) -#endif - -#if defined(__arm__) -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) -/* Use GCC built-in functions */ -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() - -#define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) -#define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) -#define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) -#define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) - -#elif defined(_PR_ARM_KUSER) -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() - -/* - * The kernel provides this helper function at a fixed address with a fixed - * ABI signature, directly callable from user space. - * - * Definition: - * Atomically store newval in *ptr if *ptr is equal to oldval. - * Return zero if *ptr was changed or non-zero if no exchange happened. - */ -typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); -#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) - -#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1) -#define _MD_ATOMIC_DECREMENT(ptr) _MD_ATOMIC_ADD(ptr, -1) - -static inline PRInt32 _MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 n) -{ - PRInt32 ov, nv; - volatile PRInt32 *vp = ptr; - - do { - ov = *vp; - nv = ov + n; - } while (__kernel_cmpxchg(ov, nv, vp)); - - return nv; -} - -static inline PRInt32 _MD_ATOMIC_SET(PRInt32 *ptr, PRInt32 nv) -{ - PRInt32 ov; - volatile PRInt32 *vp = ptr; - - do { - ov = *vp; - } while (__kernel_cmpxchg(ov, nv, vp)); - - return ov; -} -#endif -#endif /* __arm__ */ - -#define USE_SETJMP -#if (defined(__GLIBC__) && __GLIBC__ >= 2) || defined(ANDROID) -#define _PR_POLL_AVAILABLE -#endif -#undef _PR_USE_POLL -#define _PR_STAT_HAS_ONLY_ST_ATIME -#if defined(__alpha) || defined(__ia64__) -#define _PR_HAVE_LARGE_OFF_T -#elif (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \ - || defined(ANDROID) -#define _PR_HAVE_OFF64_T -#else -#define _PR_NO_LARGE_FILES -#endif -#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \ - || defined(ANDROID) -#define _PR_INET6 -#define _PR_HAVE_INET_NTOP -#define _PR_HAVE_GETHOSTBYNAME2 -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE -#endif -#ifndef ANDROID -#define _PR_HAVE_SYSV_SEMAPHORES -#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY -#endif -/* Android has gethostbyname_r but not gethostbyaddr_r or gethostbyname2_r. */ -#if (__GLIBC__ >= 2) && defined(_PR_PTHREADS) -#define _PR_HAVE_GETHOST_R -#define _PR_HAVE_GETHOST_R_INT -#endif - -#ifdef _PR_PTHREADS - -extern void _MD_CleanupBeforeExit(void); -#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit - -#else /* ! _PR_PTHREADS */ - -#include - -#define PR_CONTEXT_TYPE sigjmp_buf - -#define CONTEXT(_th) ((_th)->md.context) - -#ifdef __powerpc__ -/* - * PowerPC based MkLinux - * - * On the PowerPC, the new style jmp_buf isn't used until glibc - * 2.1. - */ -#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_GPR1] -#else -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__misc[0] -#endif /* glibc 2.1 or later */ -#define _MD_SET_FP(_t, val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) ((void *) 0) -/* aix = 64, macos = 70 */ -#define PR_NUM_GCREGS 64 - -#elif defined(__alpha) -/* Alpha based Linux */ - -#if defined(__GLIBC__) && __GLIBC__ >= 2 -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] -#define _MD_SET_FP(_t, val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) ((void *) 0) -#define _MD_SP_TYPE long int -#else -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp -#define _MD_SET_FP(_t, val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) ((void *) 0) -#define _MD_SP_TYPE __ptr_t -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ - -/* XXX not sure if this is correct, or maybe it should be 17? */ -#define PR_NUM_GCREGS 9 - -#elif defined(__ia64__) - -#define _MD_GET_SP(_t) ((long *)((_t)->md.context[0].__jmpbuf)[0]) -#define _MD_SET_FP(_t, val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) ((void *) 0) -#define _MD_SP_TYPE long int - -#define PR_NUM_GCREGS _JBLEN - -#elif defined(__mc68000__) -/* m68k based Linux */ - -/* - * On the m68k, glibc still uses the old style sigjmp_buf, even - * in glibc 2.0.7. - */ -#if defined(__GLIBC__) && __GLIBC__ >= 2 -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp -#define _MD_SET_FP(_t, val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) ((void *) 0) -#define _MD_SP_TYPE int -#else -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp -#define _MD_SET_FP(_t, val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) ((void *) 0) -#define _MD_SP_TYPE __ptr_t -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ - -/* XXX not sure if this is correct, or maybe it should be 17? */ -#define PR_NUM_GCREGS 9 - -#elif defined(__sparc__) -/* Sparc */ -#if defined(__GLIBC__) && __GLIBC__ >= 2 -/* - * You need glibc2-2.0.7-25 or later. The libraries that came with - * Red Hat 5.1 are not new enough, but they are in 5.2. - */ -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] -#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_FP] = val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_FP]) -#define _MD_SP_TYPE int -#else -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__fp -#define _MD_SET_FP(_t, val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) ((void *) 0) -#define _MD_SP_TYPE __ptr_t -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ - -#elif defined(__i386__) -/* Intel based Linux */ -#if defined(__GLIBC__) && __GLIBC__ >= 2 -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] -#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_BP] = val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_BP]) -#define _MD_SP_TYPE int -#else -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp -#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__bp = val) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) &((_t)->md.context[0].__jmpbuf[0].__bp) -#define _MD_SP_TYPE __ptr_t -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ -#define PR_NUM_GCREGS 6 - -#elif defined(__mips__) -/* Linux/MIPS */ -#if defined(__GLIBC__) && __GLIBC__ >= 2 -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp -#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__fp = (val)) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__fp) -#define _MD_SP_TYPE __ptr_t -#else -#error "Linux/MIPS pre-glibc2 not supported yet" -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ - -#elif defined(__arm__) -/* ARM/Linux */ -#if defined(__GLIBC__) && __GLIBC__ >= 2 -#ifdef __ARM_EABI__ -/* EABI */ -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[8] -#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[7] = (val)) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[7]) -#define _MD_SP_TYPE __ptr_t -#else /* __ARM_EABI__ */ -/* old ABI */ -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[20] -#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[19] = (val)) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[19]) -#define _MD_SP_TYPE __ptr_t -#endif /* __ARM_EABI__ */ -#else -#error "ARM/Linux pre-glibc2 not supported yet" -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ - -#elif defined(__sh__) -/* SH/Linux */ -#if defined(__GLIBC__) && __GLIBC__ >= 2 -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[7] -#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[6] = (val)) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[6]) -#define _MD_SP_TYPE __ptr_t -#else -#error "SH/Linux pre-glibc2 not supported yet" -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ - -#elif defined(__m32r__) -/* Linux/M32R */ -#if defined(__GLIBC__) && __GLIBC__ >= 2 -#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__regs[JB_SP] -#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__regs[JB_FP] = (val)) -#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) -#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__regs[JB_FP]) -#define _MD_SP_TYPE __ptr_t -#else -#error "Linux/M32R pre-glibc2 not supported yet" -#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ - -#else - -#error "Unknown CPU architecture" - -#endif /*__powerpc__*/ - -/* -** Initialize a thread context to run "_main()" when started -*/ -#ifdef __powerpc__ - -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (sigsetjmp(CONTEXT(_thread), 1)) { \ - _main(); \ - } \ - _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 128); \ - _thread->md.sp = _MD_GET_SP_PTR(_thread); \ - _thread->md.fp = _MD_GET_FP_PTR(_thread); \ - _MD_SET_FP(_thread, 0); \ -} - -#elif defined(__mips__) - -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - (void) sigsetjmp(CONTEXT(_thread), 1); \ - _thread->md.context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \ - _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \ - _thread->md.sp = _MD_GET_SP_PTR(_thread); \ - _thread->md.fp = _MD_GET_FP_PTR(_thread); \ - _MD_SET_FP(_thread, 0); \ -} - -#else - -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (sigsetjmp(CONTEXT(_thread), 1)) { \ - _main(); \ - } \ - _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \ - _thread->md.sp = _MD_GET_SP_PTR(_thread); \ - _thread->md.fp = _MD_GET_FP_PTR(_thread); \ - _MD_SET_FP(_thread, 0); \ -} - -#endif /*__powerpc__*/ - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!sigsetjmp(CONTEXT(_thread), 1)) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - siglongjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - PR_CONTEXT_TYPE context; - void *sp; - void *fp; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#include /* for FD_SETSIZE */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -extern PRStatus _MD_InitializeThread(PRThread *thread); - -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread -#define _MD_RESUME_THREAD(thread) _MD_resume_thread -#define _MD_CLEAN_THREAD(_thread) - -extern PRStatus _MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize); -extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri); -extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout); -extern PRStatus _MD_WAKEUP_WAITER(PRThread *); -extern void _MD_YIELD(void); - -#endif /* ! _PR_PTHREADS */ - -extern void _MD_EarlyInit(void); - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define HAVE_CLOCK_MONOTONIC - -/* - * We wrapped the select() call. _MD_SELECT refers to the built-in, - * unwrapped version. - */ -#define _MD_SELECT __select - -#ifdef _PR_POLL_AVAILABLE -#include -extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds, - int timeout); -#define _MD_POLL __syscall_poll -#endif - -/* For writev() */ -#include - -extern void _MD_linux_map_sendfile_error(int err); - -#endif /* nspr_linux_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/include/md/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/Makefile.in 2012-03-06 13:13:50.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -# The .cfg files need to be exported and installed to support -# cross-compilation. -CONFIGS = $(wildcard $(srcdir)/*.cfg) - -include $(topsrcdir)/config/rules.mk - -export:: $(MDCPUCFG_H) - $(INSTALL) -m 444 $(CONFIGS) $(dist_includedir)/md - $(INSTALL) -m 444 $(srcdir)/$(MDCPUCFG_H) $(dist_includedir) - mv -f $(dist_includedir)/$(MDCPUCFG_H) $(dist_includedir)/prcpucfg.h - -install:: - $(NSINSTALL) -D $(DESTDIR)$(includedir)/md - $(NSINSTALL) -t -m 644 $(CONFIGS) $(DESTDIR)$(includedir)/md - $(NSINSTALL) -t -m 644 $(srcdir)/$(MDCPUCFG_H) $(DESTDIR)$(includedir) - mv -f $(DESTDIR)$(includedir)/$(MDCPUCFG_H) $(DESTDIR)$(includedir)/prcpucfg.h - -release:: export - @echo "Copying machine-dependent prcpucfg.h" - @if test -z "$(BUILD_NUMBER)"; then \ - echo "BUILD_NUMBER must be defined"; \ - false; \ - fi - @if test ! -d $(RELEASE_INCLUDE_DIR); then \ - rm -rf $(RELEASE_INCLUDE_DIR); \ - $(NSINSTALL) -D $(RELEASE_INCLUDE_DIR);\ - fi - cp $(srcdir)/$(MDCPUCFG_H) $(RELEASE_INCLUDE_DIR)/prcpucfg.h diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_netbsd.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_netbsd.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_netbsd.cfg 2012-03-06 13:13:52.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_netbsd.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,351 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef NETBSD -#define NETBSD -#endif - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif - -#if defined(__i386__) || defined(__arm32__) || defined(__ARMEL__) || \ - defined(__MIPSEL__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#elif defined(__sparc_v9__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#elif defined(__sparc__) || defined(__MIPSEB__) || defined(__ARMEB__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 - -#elif defined(__alpha__) -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__amd64__) -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__powerpc__) || defined(__m68k__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#else - -#error Must define constants for type sizes here. - -#endif - - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_netbsd.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_netbsd.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_netbsd.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_netbsd.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_netbsd_defs_h___ -#define nspr_netbsd_defs_h___ - -#include -#include /* for __NetBSD_Version__ */ - -#define PR_LINKER_ARCH "netbsd" -#define _PR_SI_SYSNAME "NetBSD" -#if defined(__i386__) -#define _PR_SI_ARCHITECTURE "x86" -#elif defined(__alpha__) -#define _PR_SI_ARCHITECTURE "alpha" -#elif defined(__amd64__) -#define _PR_SI_ARCHITECTURE "amd64" -#elif defined(__m68k__) -#define _PR_SI_ARCHITECTURE "m68k" -#elif defined(__powerpc__) -#define _PR_SI_ARCHITECTURE "powerpc" -#elif defined(__sparc_v9__) -#define _PR_SI_ARCHITECTURE "sparc64" -#elif defined(__sparc__) -#define _PR_SI_ARCHITECTURE "sparc" -#elif defined(__mips__) -#define _PR_SI_ARCHITECTURE "mips" -#elif defined(__arm32__) || defined(__arm__) || defined(__armel__) \ - || defined(__armeb__) -#define _PR_SI_ARCHITECTURE "arm" -#endif - -#if defined(__ELF__) -#define PR_DLL_SUFFIX ".so" -#else -#define PR_DLL_SUFFIX ".so.1.0" -#endif - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#undef HAVE_STACK_GROWING_UP -#define HAVE_DLL -#define USE_DLFCN -#define _PR_HAVE_SOCKADDR_LEN -#define _PR_NO_LARGE_FILES -#define _PR_STAT_HAS_ST_ATIMESPEC -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_HAVE_SYSV_SEMAPHORES -#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY - -#if __NetBSD_Version__ >= 105000000 -#define _PR_INET6 -#define _PR_HAVE_INET_NTOP -#define _PR_HAVE_GETHOSTBYNAME2 -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE -#endif - -#define USE_SETJMP - -#ifndef _PR_PTHREADS -#include - -#define PR_CONTEXT_TYPE sigjmp_buf - -#define CONTEXT(_th) ((_th)->md.context) - -#if defined(__i386__) || defined(__sparc__) || defined(__m68k__) || defined(__powerpc__) -#define JB_SP_INDEX 2 -#elif defined(__mips__) -#define JB_SP_INDEX 4 -#elif defined(__alpha__) -#define JB_SP_INDEX 34 -#elif defined(__arm32__) -/* - * On the arm32, the jmpbuf regs underwent a name change after NetBSD 1.3. - */ -#ifdef JMPBUF_REG_R13 -#define JB_SP_INDEX JMPBUF_REG_R13 -#else -#define JB_SP_INDEX _JB_REG_R13 -#endif -#else -#error "Need to define SP index in jmp_buf here" -#endif -#define _MD_GET_SP(_th) (_th)->md.context[JB_SP_INDEX] - -#define PR_NUM_GCREGS _JBLEN - -/* -** Initialize a thread context to run "_main()" when started -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (sigsetjmp(CONTEXT(_thread), 1)) { \ - _main(); \ - } \ - _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!sigsetjmp(CONTEXT(_thread), 1)) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - siglongjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread -#define _MD_RESUME_THREAD(thread) _MD_resume_thread -#define _MD_CLEAN_THREAD(_thread) - -#endif /* ! _PR_PTHREADS */ - -extern void _MD_EarlyInit(void); - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INTERVAL_USE_GTOD - -/* - * We wrapped the select() call. _MD_SELECT refers to the built-in, - * unwrapped version. - */ -#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) -#if defined(_PR_POLL_AVAILABLE) -#include -#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout) -#endif - -#if NetBSD1_3 == 1L -typedef unsigned int nfds_t; -#endif - -#endif /* nspr_netbsd_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_nspr_pthread.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_nspr_pthread.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_nspr_pthread.h 2012-03-06 13:13:52.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_nspr_pthread.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,251 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_pthread_defs_h___ -#define nspr_pthread_defs_h___ - -#include -#include "prthread.h" - -#if defined(PTHREADS_USER) -/* -** Thread Local Storage -*/ -extern pthread_key_t current_thread_key; -extern pthread_key_t current_cpu_key; -extern pthread_key_t last_thread_key; -extern pthread_key_t intsoff_key; - -#define _MD_CURRENT_THREAD() \ - ((struct PRThread *) pthread_getspecific(current_thread_key)) -#define _MD_CURRENT_CPU() \ - ((struct _PRCPU *) pthread_getspecific(current_cpu_key)) -#define _MD_LAST_THREAD() \ - ((struct PRThread *) pthread_getspecific(last_thread_key)) - -#define _MD_SET_CURRENT_THREAD(newval) \ - pthread_setspecific(current_thread_key, (void *)newval) - -#define _MD_SET_CURRENT_CPU(newval) \ - pthread_setspecific(current_cpu_key, (void *)newval) - -#define _MD_SET_LAST_THREAD(newval) \ - pthread_setspecific(last_thread_key, (void *)newval) - -#define _MD_SET_INTSOFF(_val) -#define _MD_GET_INTSOFF() 1 - -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - *status = PR_TRUE; \ - if (SAVE_CONTEXT(_thread)) { \ - (*_main)(); \ - } \ - _MD_SET_THR_SP(_thread, _sp); \ - _thread->no_sched = 0; \ - PR_END_MACRO - -#define _MD_SWITCH_CONTEXT(_thread) \ - PR_BEGIN_MACRO \ - PR_ASSERT(_thread->no_sched); \ - if (!SAVE_CONTEXT(_thread)) { \ - (_thread)->md.errcode = errno; \ - _MD_SET_LAST_THREAD(_thread); \ - _PR_Schedule(); \ - } else { \ - (_MD_LAST_THREAD())->no_sched = 0; \ - } \ - PR_END_MACRO - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ - PR_BEGIN_MACRO \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - _thread->no_sched = 1; \ - GOTO_CONTEXT(_thread); \ - PR_END_MACRO - - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - jmp_buf jb; - int id; - int errcode; - pthread_t pthread; - pthread_mutex_t pthread_mutex; - pthread_cond_t pthread_cond; - int wait; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - pthread_mutex_t mutex; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - pthread_mutex_t mutex; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - jmp_buf jb; - pthread_t pthread; - struct _MDCPU_Unix md_unix; -}; - -/* -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -*/ - -extern pthread_mutex_t _pr_heapLock; - -#define _PR_LOCK(lock) pthread_mutex_lock(lock) - -#define _PR_UNLOCK(lock) pthread_mutex_unlock(lock) - - -#define _PR_LOCK_HEAP() { \ - if (_pr_primordialCPU) { \ - _PR_LOCK(_pr_heapLock); \ - } - -#define _PR_UNLOCK_HEAP() if (_pr_primordialCPU) { \ - _PR_UNLOCK(_pr_heapLock); \ - } \ - } - -NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md); -NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp); - -#define _MD_LOCK(_lockp) _PR_LOCK(&(_lockp)->mutex) -#define _MD_UNLOCK(_lockp) _PR_UNLOCK(&(_lockp)->mutex) - -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() -#define _MD_CHECK_FOR_EXIT() - -NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread); -#define _MD_INIT_THREAD _MD_InitThread -#define _MD_INIT_ATTACHED_THREAD _MD_InitThread - -NSPR_API(void) _MD_ExitThread(struct PRThread *thread); -#define _MD_EXIT_THREAD _MD_ExitThread - -NSPR_API(void) _MD_SuspendThread(struct PRThread *thread); -#define _MD_SUSPEND_THREAD _MD_SuspendThread - -NSPR_API(void) _MD_ResumeThread(struct PRThread *thread); -#define _MD_RESUME_THREAD _MD_ResumeThread - -NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread); -#define _MD_SUSPEND_CPU _MD_SuspendCPU - -NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread); -#define _MD_RESUME_CPU _MD_ResumeCPU - -#define _MD_BEGIN_SUSPEND_ALL() -#define _MD_END_SUSPEND_ALL() -#define _MD_BEGIN_RESUME_ALL() -#define _MD_END_RESUME_ALL() - -NSPR_API(void) _MD_EarlyInit(void); -#define _MD_EARLY_INIT _MD_EarlyInit - -#define _MD_FINAL_INIT _PR_UnixInit - -NSPR_API(void) _MD_InitLocks(void); -#define _MD_INIT_LOCKS _MD_InitLocks - -NSPR_API(void) _MD_CleanThread(struct PRThread *thread); -#define _MD_CLEAN_THREAD _MD_CleanThread - -NSPR_API(PRStatus) _MD_CreateThread( - struct PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize); -#define _MD_CREATE_THREAD _MD_CreateThread - -extern void _MD_CleanupBeforeExit(void); -#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit - -NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu); -#define _MD_INIT_RUNNING_CPU _MD_InitRunningCPU - -/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and - * awaken a thread which is waiting on a lock or cvar. - */ -NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout); -#define _MD_WAIT _MD_wait - -NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *); -#define _MD_WAKEUP_WAITER _MD_WakeupWaiter - -NSPR_API(void) _MD_SetPriority(struct _MDThread *thread, - PRThreadPriority newPri); -#define _MD_SET_PRIORITY _MD_SetPriority - -#endif /* PTHREADS_USER */ - -#endif /* nspr_pthread_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_nto.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_nto.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_nto.cfg 2012-03-06 13:13:52.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_nto.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef NTO -#define NTO -#endif - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#ifdef __i386__ - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1L -#define PR_BYTES_PER_SHORT 2L -#define PR_BYTES_PER_INT 4L -#define PR_BYTES_PER_INT64 8L -#define PR_BYTES_PER_LONG 4L -#define PR_BYTES_PER_FLOAT 4L -#define PR_BYTES_PER_DOUBLE 8L -#define PR_BYTES_PER_WORD 4L -#define PR_BYTES_PER_DWORD 8L - -#define PR_BITS_PER_BYTE 8L -#define PR_BITS_PER_SHORT 16L -#define PR_BITS_PER_INT 32L -#define PR_BITS_PER_INT64 64L -#define PR_BITS_PER_LONG 32L -#define PR_BITS_PER_FLOAT 32L -#define PR_BITS_PER_DOUBLE 64L -#define PR_BITS_PER_WORD 32L - -#define PR_BITS_PER_BYTE_LOG2 3L -#define PR_BITS_PER_SHORT_LOG2 4L -#define PR_BITS_PER_INT_LOG2 5L -#define PR_BITS_PER_INT64_LOG2 6L -#define PR_BITS_PER_LONG_LOG2 5L -#define PR_BITS_PER_FLOAT_LOG2 5L -#define PR_BITS_PER_DOUBLE_LOG2 6L -#define PR_BITS_PER_WORD_LOG2 5L - -#define PR_ALIGN_OF_SHORT 2L -#define PR_ALIGN_OF_INT 4L -#define PR_ALIGN_OF_LONG 4L -#define PR_ALIGN_OF_INT64 4L -#define PR_ALIGN_OF_FLOAT 4L -#define PR_ALIGN_OF_DOUBLE 4L -#define PR_ALIGN_OF_POINTER 4L -#define PR_ALIGN_OF_WORD 4L - -#define PR_BYTES_PER_WORD_LOG2 2L -#define PR_BYTES_PER_DWORD_LOG2 3L -#define PR_WORDS_PER_DWORD_LOG2 1L - -#else - -#error Undefined CPU Architecture - -#endif - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_nto.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_nto.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_nto.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_nto.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,188 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_nto_defs_h___ -#define nspr_nto_defs_h___ - -/* -** Internal configuration macros -*/ -#define PR_LINKER_ARCH "nto" -#define _PR_SI_SYSNAME "NTO" -#define _PR_SI_ARCHITECTURE "x86" -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MINIMUM_STACK_SIZE 131072L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#ifndef HAVE_WEAK_IO_SYMBOLS -#define HAVE_WEAK_IO_SYMBOLS -#endif - -#undef _PR_POLL_AVAILABLE -#undef _PR_USE_POLL -#define _PR_HAVE_SOCKADDR_LEN -#undef HAVE_BSD_FLOCK -#define HAVE_FCNTL_FILE_LOCKING -#define _PR_NO_LARGE_FILES -#define _PR_STAT_HAS_ONLY_ST_ATIME -#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY -#define _PR_HAVE_POSIX_SEMAPHORES - -#undef FD_SETSIZE -#define FD_SETSIZE 4096 -#include -#include -#include - -#undef HAVE_STACK_GROWING_UP -#define HAVE_DLL -#define USE_DLFCN -#define NEED_STRFTIME_LOCK -#define NEED_TIME_R -#define _PR_NEED_STRCASECMP - -#ifndef HAVE_STRERROR -#define HAVE_STRERROR -#endif - -#define USE_SETJMP - -#include - -#define _SETJMP setjmp -#define _LONGJMP longjmp -#define _PR_CONTEXT_TYPE jmp_buf -#define _PR_NUM_GCREGS _JBLEN -#define _MD_GET_SP(_t) (_t)->md.context[7] - -#define CONTEXT(_th) ((_th)->md.context) - - -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ - _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!_SETJMP(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - _LONGJMP(CONTEXT(_thread), 1); \ -} - -/* -** Machine-dependent (MD) data structures. -*/ -struct _MDThread { - _PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* -** md-specific cpu structure field -*/ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_INTERVAL_USE_GTOD -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -/* -** We wrapped the select() call. _MD_SELECT refers to the built-in, -** unwrapped version. -*/ -#define _MD_SELECT select - -#define SA_RESTART 0 - -#endif /* nspr_nto_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_openbsd.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_openbsd.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_openbsd.cfg 2012-03-06 13:13:52.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_openbsd.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,353 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef OPENBSD -#define OPENBSD -#endif - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif - -#if defined(__i386__) || defined(__arm__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#elif defined(__amd64__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 -#define PR_ALIGN_OF_WORD 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#elif defined(__sparc_v9__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__sparc__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 4 - -#elif defined(__alpha__) -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__powerpc__) || defined(__m68k__) - -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#else - -#error Must define constants for type sizes here. - -#endif - - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_openbsd.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_openbsd.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_openbsd.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_openbsd.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_openbsd_defs_h___ -#define nspr_openbsd_defs_h___ - -#include - -#define PR_LINKER_ARCH "openbsd" -#define _PR_SI_SYSNAME "OPENBSD" -#if defined(__i386__) -#define _PR_SI_ARCHITECTURE "x86" -#elif defined(__alpha__) -#define _PR_SI_ARCHITECTURE "alpha" -#elif defined(__amd64__) -#define _PR_SI_ARCHITECTURE "amd64" -#elif defined(__m68k__) -#define _PR_SI_ARCHITECTURE "m68k" -#elif defined(__powerpc__) -#define _PR_SI_ARCHITECTURE "powerpc" -#elif defined(__sparc__) -#define _PR_SI_ARCHITECTURE "sparc" -#elif defined(__arm__) -#define _PR_SI_ARCHITECTURE "arm" -#endif - -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#undef HAVE_STACK_GROWING_UP -#define HAVE_DLL -#define USE_DLFCN -#define _PR_HAVE_SOCKADDR_LEN -#define _PR_HAVE_LARGE_OFF_T -#define _PR_STAT_HAS_ST_ATIMESPEC -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_HAVE_SYSV_SEMAPHORES -#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY - -#define _PR_INET6 -#define _PR_HAVE_INET_NTOP -#define _PR_HAVE_GETHOSTBYNAME2 -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE - -#define USE_SETJMP - -#ifndef _PR_PTHREADS -#include - -#define PR_CONTEXT_TYPE sigjmp_buf - -#define CONTEXT(_th) ((_th)->md.context) - -#if defined(__i386__) || defined(__sparc__) || defined(__m68k__) -#define JB_SP_INDEX 2 -#elif defined(__powerpc__) -#define JB_SP_INDEX 1 -#elif defined(__alpha__) -#define JB_SP_INDEX 34 -#elif defined(__amd64__) -#define JB_SP_INDEX 6 -#elif defined(__arm__) -#define JB_SP_INDEX 23 -#else -#error "Need to define SP index in jmp_buf here" -#endif -#define _MD_GET_SP(_th) (_th)->md.context[JB_SP_INDEX] - -#define PR_NUM_GCREGS _JBLEN - -/* -** Initialize a thread context to run "_main()" when started -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (sigsetjmp(CONTEXT(_thread), 1)) { \ - _main(); \ - } \ - _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!sigsetjmp(CONTEXT(_thread), 1)) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - siglongjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread -#define _MD_RESUME_THREAD(thread) _MD_resume_thread -#define _MD_CLEAN_THREAD(_thread) - -#endif /* ! _PR_PTHREADS */ - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INTERVAL_USE_GTOD - -/* - * We wrapped the select() call. _MD_SELECT refers to the built-in, - * unwrapped version. - */ -#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) -#include -#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout) - -#if OpenBSD1_3 == 1L -typedef unsigned int nfds_t; -#endif - -#endif /* nspr_openbsd_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_os2.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_os2.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_os2.cfg 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_os2.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_PC -#define XP_PC -#endif - -#ifndef XP_OS2 -#define XP_OS2 -#endif - -#ifndef OS2 -#define OS2 -#endif - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#ifdef NO_LONG_LONG -#undef HAVE_LONG_LONG -#else -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG 1 -#endif -#endif - -#define PR_AF_INET6 24 /* same as AF_INET6 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_WORD 32 -#define PR_BITS_PER_DWORD 64 -#define PR_BITS_PER_DOUBLE 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_WORD_LOG2 5 -#define PR_BITS_PER_DWORD_LOG2 6 -#define PR_BITS_PER_DOUBLE_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_WORD 4 -#define PR_ALIGN_OF_DWORD 8 -#define PR_ALIGN_OF_POINTER 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 2 - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_os2_errors.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_os2_errors.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_os2_errors.h 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_os2_errors.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_os2_errors_h___ -#define nspr_os2_errors_h___ - -#include "md/_os2.h" -#ifndef assert - #include -#endif - -NSPR_API(void) _MD_os2_map_default_error(PRInt32 err); -#define _PR_MD_MAP_DEFAULT_ERROR _MD_os2_map_default_error - -NSPR_API(void) _MD_os2_map_opendir_error(PRInt32 err); -#define _PR_MD_MAP_OPENDIR_ERROR _MD_os2_map_opendir_error - -NSPR_API(void) _MD_os2_map_closedir_error(PRInt32 err); -#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_os2_map_closedir_error - -NSPR_API(void) _MD_os2_readdir_error(PRInt32 err); -#define _PR_MD_MAP_READDIR_ERROR _MD_os2_readdir_error - -NSPR_API(void) _MD_os2_map_delete_error(PRInt32 err); -#define _PR_MD_MAP_DELETE_ERROR _MD_os2_map_delete_error - -NSPR_API(void) _MD_os2_map_stat_error(PRInt32 err); -#define _PR_MD_MAP_STAT_ERROR _MD_os2_map_stat_error - -NSPR_API(void) _MD_os2_map_fstat_error(PRInt32 err); -#define _PR_MD_MAP_FSTAT_ERROR _MD_os2_map_fstat_error - -NSPR_API(void) _MD_os2_map_rename_error(PRInt32 err); -#define _PR_MD_MAP_RENAME_ERROR _MD_os2_map_rename_error - -NSPR_API(void) _MD_os2_map_access_error(PRInt32 err); -#define _PR_MD_MAP_ACCESS_ERROR _MD_os2_map_access_error - -NSPR_API(void) _MD_os2_map_mkdir_error(PRInt32 err); -#define _PR_MD_MAP_MKDIR_ERROR _MD_os2_map_mkdir_error - -NSPR_API(void) _MD_os2_map_rmdir_error(PRInt32 err); -#define _PR_MD_MAP_RMDIR_ERROR _MD_os2_map_rmdir_error - -NSPR_API(void) _MD_os2_map_read_error(PRInt32 err); -#define _PR_MD_MAP_READ_ERROR _MD_os2_map_read_error - -NSPR_API(void) _MD_os2_map_transmitfile_error(PRInt32 err); -#define _PR_MD_MAP_TRANSMITFILE_ERROR _MD_os2_map_transmitfile_error - -NSPR_API(void) _MD_os2_map_write_error(PRInt32 err); -#define _PR_MD_MAP_WRITE_ERROR _MD_os2_map_write_error - -NSPR_API(void) _MD_os2_map_lseek_error(PRInt32 err); -#define _PR_MD_MAP_LSEEK_ERROR _MD_os2_map_lseek_error - -NSPR_API(void) _MD_os2_map_fsync_error(PRInt32 err); -#define _PR_MD_MAP_FSYNC_ERROR _MD_os2_map_fsync_error - -NSPR_API(void) _MD_os2_map_close_error(PRInt32 err); -#define _PR_MD_MAP_CLOSE_ERROR _MD_os2_map_close_error - -NSPR_API(void) _MD_os2_map_socket_error(PRInt32 err); -#define _PR_MD_MAP_SOCKET_ERROR _MD_os2_map_socket_error - -NSPR_API(void) _MD_os2_map_recv_error(PRInt32 err); -#define _PR_MD_MAP_RECV_ERROR _MD_os2_map_recv_error - -NSPR_API(void) _MD_os2_map_recvfrom_error(PRInt32 err); -#define _PR_MD_MAP_RECVFROM_ERROR _MD_os2_map_recvfrom_error - -NSPR_API(void) _MD_os2_map_send_error(PRInt32 err); -#define _PR_MD_MAP_SEND_ERROR _MD_os2_map_send_error - -NSPR_API(void) _MD_os2_map_sendto_error(PRInt32 err); -#define _PR_MD_MAP_SENDTO_ERROR _MD_os2_map_sendto_error - -NSPR_API(void) _MD_os2_map_writev_error(int err); -#define _PR_MD_MAP_WRITEV_ERROR _MD_os2_map_writev_error - -NSPR_API(void) _MD_os2_map_accept_error(PRInt32 err); -#define _PR_MD_MAP_ACCEPT_ERROR _MD_os2_map_accept_error - -NSPR_API(void) _MD_os2_map_acceptex_error(PRInt32 err); -#define _PR_MD_MAP_ACCEPTEX_ERROR _MD_os2_map_acceptex_error - -NSPR_API(void) _MD_os2_map_connect_error(PRInt32 err); -#define _PR_MD_MAP_CONNECT_ERROR _MD_os2_map_connect_error - -NSPR_API(void) _MD_os2_map_bind_error(PRInt32 err); -#define _PR_MD_MAP_BIND_ERROR _MD_os2_map_bind_error - -NSPR_API(void) _MD_os2_map_listen_error(PRInt32 err); -#define _PR_MD_MAP_LISTEN_ERROR _MD_os2_map_listen_error - -NSPR_API(void) _MD_os2_map_shutdown_error(PRInt32 err); -#define _PR_MD_MAP_SHUTDOWN_ERROR _MD_os2_map_shutdown_error - -NSPR_API(void) _MD_os2_map_socketpair_error(int err); -#define _PR_MD_MAP_SOCKETPAIR_ERROR _MD_os2_map_socketpair_error - -NSPR_API(void) _MD_os2_map_getsockname_error(PRInt32 err); -#define _PR_MD_MAP_GETSOCKNAME_ERROR _MD_os2_map_getsockname_error - -NSPR_API(void) _MD_os2_map_getpeername_error(PRInt32 err); -#define _PR_MD_MAP_GETPEERNAME_ERROR _MD_os2_map_getpeername_error - -NSPR_API(void) _MD_os2_map_getsockopt_error(PRInt32 err); -#define _PR_MD_MAP_GETSOCKOPT_ERROR _MD_os2_map_getsockopt_error - -NSPR_API(void) _MD_os2_map_setsockopt_error(PRInt32 err); -#define _PR_MD_MAP_SETSOCKOPT_ERROR _MD_os2_map_setsockopt_error - -NSPR_API(void) _MD_os2_map_open_error(PRInt32 err); -#define _PR_MD_MAP_OPEN_ERROR _MD_os2_map_open_error - -NSPR_API(void) _MD_os2_map_gethostname_error(PRInt32 err); -#define _PR_MD_MAP_GETHOSTNAME_ERROR _MD_os2_map_gethostname_error - -NSPR_API(void) _MD_os2_map_select_error(PRInt32 err); -#define _PR_MD_MAP_SELECT_ERROR _MD_os2_map_select_error - -NSPR_API(void) _MD_os2_map_lockf_error(int err); -#define _PR_MD_MAP_LOCKF_ERROR _MD_os2_map_lockf_error - -#endif /* nspr_os2_errors_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_os2.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_os2.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_os2.h 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_os2.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,504 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_os2_defs_h___ -#define nspr_os2_defs_h___ - -#ifndef NO_LONG_LONG -#define INCL_LONGLONG -#endif -#define INCL_DOS -#define INCL_DOSPROCESS -#define INCL_DOSERRORS -#define INCL_WIN -#define INCL_WPS -#include -#include - -#include "prio.h" - -#include - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "os2" -#define _PR_SI_SYSNAME "OS2" -#define _PR_SI_ARCHITECTURE "x86" /* XXXMB hardcode for now */ - -#define HAVE_DLL -#define _PR_GLOBAL_THREADS_ONLY -#undef HAVE_THREAD_AFFINITY -#define _PR_HAVE_THREADSAFE_GETHOST -#define _PR_HAVE_ATOMIC_OPS -#define HAVE_NETINET_TCP_H - -#define HANDLE unsigned long -#define HINSTANCE HMODULE - -/* --- Common User-Thread/Native-Thread Definitions --------------------- */ - -/* --- Globals --- */ -extern struct PRLock *_pr_schedLock; - -/* --- Typedefs --- */ -typedef void (*FiberFunc)(void *); - -#define PR_NUM_GCREGS 8 -typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS]; -#define GC_VMBASE 0x40000000 -#define GC_VMLIMIT 0x00FFFFFF -typedef int (*FARPROC)(); - -#define _MD_MAGIC_THREAD 0x22222222 -#define _MD_MAGIC_THREADSTACK 0x33333333 -#define _MD_MAGIC_SEGMENT 0x44444444 -#define _MD_MAGIC_DIR 0x55555555 -#define _MD_MAGIC_CV 0x66666666 - -struct _MDSemaphore { - HEV sem; -}; - -struct _MDCPU { - int unused; -}; - -struct _MDThread { - HEV blocked_sema; /* Threads block on this when waiting - * for IO or CondVar. - */ - PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the - * wait queue of some cond var. - * PR_FALSE otherwise. */ - TID handle; /* OS/2 thread handle */ - void *sp; /* only valid when suspended */ - PRUint32 magic; /* for debugging */ - PR_CONTEXT_TYPE gcContext; /* Thread context for GC */ - struct PRThread *prev, *next; /* used by the cvar wait queue to - * chain the PRThread structures - * together */ -}; - -struct _MDThreadStack { - PRUint32 magic; /* for debugging */ -}; - -struct _MDSegment { - PRUint32 magic; /* for debugging */ -}; - -#undef PROFILE_LOCKS - -struct _MDDir { - HDIR d_hdl; - union { - FILEFINDBUF3 small; - FILEFINDBUF3L large; - } d_entry; - PRBool firstEntry; /* Is this the entry returned - * by FindFirstFile()? */ - PRUint32 magic; /* for debugging */ -}; - -struct _MDCVar { - PRUint32 magic; - struct PRThread *waitHead, *waitTail; /* the wait queue: a doubly- - * linked list of threads - * waiting on this condition - * variable */ - PRIntn nwait; /* number of threads in the - * wait queue */ -}; - -#define _MD_CV_NOTIFIED_LENGTH 6 -typedef struct _MDNotified _MDNotified; -struct _MDNotified { - PRIntn length; /* # of used entries in this - * structure */ - struct { - struct _MDCVar *cv; /* the condition variable notified */ - PRIntn times; /* and the number of times notified */ - struct PRThread *notifyHead; /* list of threads to wake up */ - } cv[_MD_CV_NOTIFIED_LENGTH]; - _MDNotified *link; /* link to another of these, or NULL */ -}; - -struct _MDLock { - HMTX mutex; /* this is recursive on OS/2 */ - - /* - * When notifying cvars, there is no point in actually - * waking up the threads waiting on the cvars until we've - * released the lock. So, we temporarily record the cvars. - * When doing an unlock, we'll then wake up the waiting threads. - */ - struct _MDNotified notified; /* array of conditions notified */ -#ifdef PROFILE_LOCKS - PRInt32 hitcount; - PRInt32 misscount; -#endif -}; - -struct _MDFileDesc { - PRInt32 osfd; /* The osfd can come from one of three spaces: - * - For stdin, stdout, and stderr, we are using - * the libc file handle (0, 1, 2), which is an int. - * - For files and pipes, we are using OS/2 handles, - * which is a void*. - * - For sockets, we are using int - */ -}; - -struct _MDProcess { - PID pid; -}; - -/* --- Misc stuff --- */ -#define _MD_GET_SP(thread) (thread)->md.gcContext[6] - -/* --- IO stuff --- */ - -#define _MD_OPEN (_PR_MD_OPEN) -#define _MD_OPEN_FILE (_PR_MD_OPEN) -#define _MD_READ (_PR_MD_READ) -#define _MD_WRITE (_PR_MD_WRITE) -#define _MD_WRITEV (_PR_MD_WRITEV) -#define _MD_LSEEK (_PR_MD_LSEEK) -#define _MD_LSEEK64 (_PR_MD_LSEEK64) -extern PRInt32 _MD_CloseFile(PRInt32 osfd); -#define _MD_CLOSE_FILE _MD_CloseFile -#define _MD_GETFILEINFO (_PR_MD_GETFILEINFO) -#define _MD_GETFILEINFO64 (_PR_MD_GETFILEINFO64) -#define _MD_GETOPENFILEINFO (_PR_MD_GETOPENFILEINFO) -#define _MD_GETOPENFILEINFO64 (_PR_MD_GETOPENFILEINFO64) -#define _MD_STAT (_PR_MD_STAT) -#define _MD_RENAME (_PR_MD_RENAME) -#define _MD_ACCESS (_PR_MD_ACCESS) -#define _MD_DELETE (_PR_MD_DELETE) -#define _MD_MKDIR (_PR_MD_MKDIR) -#define _MD_MAKE_DIR (_PR_MD_MKDIR) -#define _MD_RMDIR (_PR_MD_RMDIR) -#define _MD_LOCKFILE (_PR_MD_LOCKFILE) -#define _MD_TLOCKFILE (_PR_MD_TLOCKFILE) -#define _MD_UNLOCKFILE (_PR_MD_UNLOCKFILE) - -/* --- Socket IO stuff --- */ - -/* The ones that don't map directly may need to be re-visited... */ -#define _MD_EACCES EACCES -#define _MD_EADDRINUSE EADDRINUSE -#define _MD_EADDRNOTAVAIL EADDRNOTAVAIL -#define _MD_EAFNOSUPPORT EAFNOSUPPORT -#define _MD_EAGAIN EWOULDBLOCK -#define _MD_EALREADY EALREADY -#define _MD_EBADF EBADF -#define _MD_ECONNREFUSED ECONNREFUSED -#define _MD_ECONNRESET ECONNRESET -#define _MD_EFAULT SOCEFAULT -#define _MD_EINPROGRESS EINPROGRESS -#define _MD_EINTR EINTR -#define _MD_EINVAL EINVAL -#define _MD_EISCONN EISCONN -#define _MD_ENETUNREACH ENETUNREACH -#define _MD_ENOENT ENOENT -#define _MD_ENOTCONN ENOTCONN -#define _MD_ENOTSOCK ENOTSOCK -#define _MD_EOPNOTSUPP EOPNOTSUPP -#define _MD_EWOULDBLOCK EWOULDBLOCK -#define _MD_GET_SOCKET_ERROR() sock_errno() -#ifndef INADDR_LOOPBACK /* For some reason this is not defined in OS2 tcpip */ -/* #define INADDR_LOOPBACK INADDR_ANY */ -#endif - -#define _MD_INIT_FILEDESC(fd) -extern void _MD_MakeNonblock(PRFileDesc *f); -#define _MD_MAKE_NONBLOCK _MD_MakeNonblock -#define _MD_INIT_FD_INHERITABLE (_PR_MD_INIT_FD_INHERITABLE) -#define _MD_QUERY_FD_INHERITABLE (_PR_MD_QUERY_FD_INHERITABLE) -#define _MD_SHUTDOWN (_PR_MD_SHUTDOWN) -#define _MD_LISTEN _PR_MD_LISTEN -extern PRInt32 _MD_CloseSocket(PRInt32 osfd); -#define _MD_CLOSE_SOCKET _MD_CloseSocket -#define _MD_SENDTO (_PR_MD_SENDTO) -#define _MD_RECVFROM (_PR_MD_RECVFROM) -#define _MD_SOCKETPAIR (_PR_MD_SOCKETPAIR) -#define _MD_GETSOCKNAME (_PR_MD_GETSOCKNAME) -#define _MD_GETPEERNAME (_PR_MD_GETPEERNAME) -#define _MD_GETSOCKOPT (_PR_MD_GETSOCKOPT) -#define _MD_SETSOCKOPT (_PR_MD_SETSOCKOPT) - -#define _MD_FSYNC _PR_MD_FSYNC -#define _MD_SET_FD_INHERITABLE (_PR_MD_SET_FD_INHERITABLE) - -#ifdef _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -#define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT -#define _MD_ATOMIC_ADD _PR_MD_ATOMIC_ADD -#define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT -#define _MD_ATOMIC_SET _PR_MD_ATOMIC_SET -#endif - -#define _MD_INIT_IO (_PR_MD_INIT_IO) -#define _MD_PR_POLL (_PR_MD_PR_POLL) - -#define _MD_SOCKET (_PR_MD_SOCKET) -extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd); -#define _MD_SOCKETAVAILABLE _MD_SocketAvailable -#define _MD_PIPEAVAILABLE _MD_SocketAvailable -#define _MD_CONNECT (_PR_MD_CONNECT) -extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, - PRIntervalTime timeout); -#define _MD_ACCEPT _MD_Accept -#define _MD_BIND (_PR_MD_BIND) -#define _MD_RECV (_PR_MD_RECV) -#define _MD_SEND (_PR_MD_SEND) - -/* --- Scheduler stuff --- */ -/* #define _MD_PAUSE_CPU _PR_MD_PAUSE_CPU */ -#define _MD_PAUSE_CPU - -/* --- DIR stuff --- */ -#define PR_DIRECTORY_SEPARATOR '\\' -#define PR_DIRECTORY_SEPARATOR_STR "\\" -#define PR_PATH_SEPARATOR ';' -#define PR_PATH_SEPARATOR_STR ";" -#define _MD_ERRNO() errno -#define _MD_OPEN_DIR (_PR_MD_OPEN_DIR) -#define _MD_CLOSE_DIR (_PR_MD_CLOSE_DIR) -#define _MD_READ_DIR (_PR_MD_READ_DIR) - -/* --- Segment stuff --- */ -#define _MD_INIT_SEGS() -#define _MD_ALLOC_SEGMENT(seg, size, vaddr) 0 -#define _MD_FREE_SEGMENT(seg) - -/* --- Environment Stuff --- */ -#define _MD_GET_ENV (_PR_MD_GET_ENV) -#define _MD_PUT_ENV (_PR_MD_PUT_ENV) - -/* --- Threading Stuff --- */ -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_INIT_THREAD (_PR_MD_INIT_THREAD) -#define _MD_INIT_ATTACHED_THREAD (_PR_MD_INIT_THREAD) -#define _MD_CREATE_THREAD (_PR_MD_CREATE_THREAD) -#define _MD_YIELD (_PR_MD_YIELD) -#define _MD_SET_PRIORITY (_PR_MD_SET_PRIORITY) -#define _MD_CLEAN_THREAD (_PR_MD_CLEAN_THREAD) -#define _MD_SETTHREADAFFINITYMASK (_PR_MD_SETTHREADAFFINITYMASK) -#define _MD_GETTHREADAFFINITYMASK (_PR_MD_GETTHREADAFFINITYMASK) -#define _MD_EXIT_THREAD (_PR_MD_EXIT_THREAD) -#define _MD_SUSPEND_THREAD (_PR_MD_SUSPEND_THREAD) -#define _MD_RESUME_THREAD (_PR_MD_RESUME_THREAD) -#define _MD_SUSPEND_CPU (_PR_MD_SUSPEND_CPU) -#define _MD_RESUME_CPU (_PR_MD_RESUME_CPU) -#define _MD_WAKEUP_CPUS (_PR_MD_WAKEUP_CPUS) -#define _MD_BEGIN_SUSPEND_ALL() -#define _MD_BEGIN_RESUME_ALL() -#define _MD_END_SUSPEND_ALL() -#define _MD_END_RESUME_ALL() - -/* --- Lock stuff --- */ -#define _PR_LOCK _MD_LOCK -#define _PR_UNLOCK _MD_UNLOCK - -#define _MD_NEW_LOCK (_PR_MD_NEW_LOCK) -#define _MD_FREE_LOCK(lock) (DosCloseMutexSem((lock)->mutex)) -#define _MD_LOCK(lock) (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT)) -#define _MD_TEST_AND_LOCK(lock) (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0) -#define _MD_UNLOCK (_PR_MD_UNLOCK) - -/* --- lock and cv waiting --- */ -#define _MD_WAIT (_PR_MD_WAIT) -#define _MD_WAKEUP_WAITER (_PR_MD_WAKEUP_WAITER) - -/* --- CVar ------------------- */ -#define _MD_WAIT_CV (_PR_MD_WAIT_CV) -#define _MD_NEW_CV (_PR_MD_NEW_CV) -#define _MD_FREE_CV (_PR_MD_FREE_CV) -#define _MD_NOTIFY_CV (_PR_MD_NOTIFY_CV ) -#define _MD_NOTIFYALL_CV (_PR_MD_NOTIFYALL_CV) - - /* XXXMB- the IOQ stuff is certainly not working correctly yet. */ -/* extern struct _MDLock _pr_ioq_lock; */ -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - - -/* --- Initialization stuff --- */ -#define _MD_START_INTERRUPTS() -#define _MD_STOP_INTERRUPTS() -#define _MD_DISABLE_CLOCK_INTERRUPTS() -#define _MD_ENABLE_CLOCK_INTERRUPTS() -#define _MD_BLOCK_CLOCK_INTERRUPTS() -#define _MD_UNBLOCK_CLOCK_INTERRUPTS() -#define _MD_EARLY_INIT (_PR_MD_EARLY_INIT) -#define _MD_FINAL_INIT() -#define _MD_EARLY_CLEANUP() -#define _MD_INIT_CPUS() -#define _MD_INIT_RUNNING_CPU(cpu) - -struct PRProcess; -struct PRProcessAttr; - -#define _MD_CREATE_PROCESS _PR_CreateOS2Process -extern struct PRProcess * _PR_CreateOS2Process( - const char *path, - char *const *argv, - char *const *envp, - const struct PRProcessAttr *attr -); - -#define _MD_DETACH_PROCESS _PR_DetachOS2Process -extern PRStatus _PR_DetachOS2Process(struct PRProcess *process); - -/* --- Wait for a child process to terminate --- */ -#define _MD_WAIT_PROCESS _PR_WaitOS2Process -extern PRStatus _PR_WaitOS2Process(struct PRProcess *process, - PRInt32 *exitCode); - -#define _MD_KILL_PROCESS _PR_KillOS2Process -extern PRStatus _PR_KillOS2Process(struct PRProcess *process); - -#define _MD_CLEANUP_BEFORE_EXIT() -#define _MD_EXIT (_PR_MD_EXIT) -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - *status = PR_TRUE; \ - PR_END_MACRO -#define _MD_SWITCH_CONTEXT -#define _MD_RESTORE_CONTEXT - -/* --- Intervals --- */ -#define _MD_INTERVAL_INIT (_PR_MD_INTERVAL_INIT) -#define _MD_GET_INTERVAL (_PR_MD_GET_INTERVAL) -#define _MD_INTERVAL_PER_SEC (_PR_MD_INTERVAL_PER_SEC) -#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) -#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) - -/* --- Native-Thread Specific Definitions ------------------------------- */ - -typedef struct __NSPR_TLS -{ - struct PRThread *_pr_thread_last_run; - struct PRThread *_pr_currentThread; - struct _PRCPU *_pr_currentCPU; -} _NSPR_TLS; - -extern _NSPR_TLS* pThreadLocalStorage; -NSPR_API(void) _PR_MD_ENSURE_TLS(void); - -#define _MD_GET_ATTACHED_THREAD() pThreadLocalStorage->_pr_currentThread -extern struct PRThread * _MD_CURRENT_THREAD(void); -#define _MD_SET_CURRENT_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentThread = (_thread) - -#define _MD_LAST_THREAD() pThreadLocalStorage->_pr_thread_last_run -#define _MD_SET_LAST_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_thread_last_run = (_thread) - -#define _MD_CURRENT_CPU() pThreadLocalStorage->_pr_currentCPU -#define _MD_SET_CURRENT_CPU(_cpu) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentCPU = (_cpu) - -/* lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) */ -/* lth. #define _MD_GET_INTSOFF() _pr_ints_off */ -/* lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++) */ -/* lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--) */ - -/* --- Scheduler stuff --- */ -#define LOCK_SCHEDULER() 0 -#define UNLOCK_SCHEDULER() 0 -#define _PR_LockSched() 0 -#define _PR_UnlockSched() 0 - -/* --- Initialization stuff --- */ -#define _MD_INIT_LOCKS() - -/* --- Stack stuff --- */ -#define _MD_INIT_STACK(stack, redzone) -#define _MD_CLEAR_STACK(stack) - -/* --- Memory-mapped files stuff --- */ -/* ReadOnly and WriteCopy modes are simulated on OS/2; - * ReadWrite mode is not supported. - */ -struct _MDFileMap { - PROffset64 maxExtent; -}; - -extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); -#define _MD_CREATE_FILE_MAP _MD_CreateFileMap - -extern PRInt32 _MD_GetMemMapAlignment(void); -#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment - -extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, - PRUint32 len); -#define _MD_MEM_MAP _MD_MemMap - -extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); -#define _MD_MEM_UNMAP _MD_MemUnmap - -extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); -#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap - -/* Some stuff for setting up thread contexts */ -typedef ULONG DWORD, *PDWORD; - -/* The following definitions and two structures are new in OS/2 Warp 4.0. - */ -#ifndef CONTEXT_CONTROL -#define CONTEXT_CONTROL 0x00000001 -#define CONTEXT_INTEGER 0x00000002 -#define CONTEXT_SEGMENTS 0x00000004 -#define CONTEXT_FLOATING_POINT 0x00000008 -#define CONTEXT_FULL 0x0000000F - -#pragma pack(2) -typedef struct _FPREG { - ULONG losig; /* Low 32-bits of the significand. */ - ULONG hisig; /* High 32-bits of the significand. */ - USHORT signexp; /* Sign and exponent. */ -} FPREG; -typedef struct _CONTEXTRECORD { - ULONG ContextFlags; - ULONG ctx_env[7]; - FPREG ctx_stack[8]; - ULONG ctx_SegGs; /* GS register. */ - ULONG ctx_SegFs; /* FS register. */ - ULONG ctx_SegEs; /* ES register. */ - ULONG ctx_SegDs; /* DS register. */ - ULONG ctx_RegEdi; /* EDI register. */ - ULONG ctx_RegEsi; /* ESI register. */ - ULONG ctx_RegEax; /* EAX register. */ - ULONG ctx_RegEbx; /* EBX register. */ - ULONG ctx_RegEcx; /* ECX register. */ - ULONG ctx_RegEdx; /* EDX register. */ - ULONG ctx_RegEbp; /* EBP register. */ - ULONG ctx_RegEip; /* EIP register. */ - ULONG ctx_SegCs; /* CS register. */ - ULONG ctx_EFlags; /* EFLAGS register. */ - ULONG ctx_RegEsp; /* ESP register. */ - ULONG ctx_SegSs; /* SS register. */ -} CONTEXTRECORD, *PCONTEXTRECORD; -#pragma pack() -#endif - -extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD); - -/* -#define _pr_tid (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid) -#define _pr_current_Thread (_system_tls[_pr_tid-1].__pr_current_thread) -*/ - -/* Some simple mappings of Windows API's to OS/2 API's to make our lives a - * little bit easier. Only add one here if it is a DIRECT mapping. We are - * not emulating anything. Just mapping. - */ -#define FreeLibrary(x) DosFreeModule((HMODULE)x) -#define OutputDebugStringA(x) - -extern int _MD_os2_get_nonblocking_connect_error(int osfd); - -#endif /* nspr_os2_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_osf1.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_osf1.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_osf1.cfg 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_osf1.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef OSF1 -#define OSF1 -#endif - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS -#ifndef IS_64 -#define IS_64 -#endif - -#define PR_AF_INET6 26 /* same as AF_INET6 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#define _PR_POLL_BACKCOMPAT - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_osf1.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_osf1.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_osf1.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_osf1.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,222 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_osf1_defs_h___ -#define nspr_osf1_defs_h___ - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "osf" -#define _PR_SI_SYSNAME "OSF" -#define _PR_SI_ARCHITECTURE "alpha" -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 131072L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#undef HAVE_STACK_GROWING_UP -#undef HAVE_WEAK_IO_SYMBOLS -#undef HAVE_WEAK_MALLOC_SYMBOLS -#define HAVE_DLL -#define HAVE_BSD_FLOCK - -#define NEED_TIME_R -#define USE_DLFCN - -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_STAT_HAS_ONLY_ST_ATIME -#define _PR_HAVE_LARGE_OFF_T -#define _PR_HAVE_GETIPNODEBYNAME -#define _PR_HAVE_GETIPNODEBYADDR -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE -#ifdef _PR_INET6 -#define _PR_HAVE_INET_NTOP -#else -#define AF_INET6 26 -#ifndef AI_CANONNAME -#define AI_CANONNAME 0x00000002 -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - char *ai_canonname; - struct sockaddr *ai_addr; - struct addrinfo *ai_next; -}; -#endif -#define AI_V4MAPPED 0x00000010 -#define AI_ALL 0x00000008 -#define AI_ADDRCONFIG 0x00000020 -#endif -#define _PR_HAVE_POSIX_SEMAPHORES -#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY - -#define USE_SETJMP - -#include - -/* - * A jmp_buf is actually a struct sigcontext. The sc_sp field of - * struct sigcontext is the stack pointer. - */ -#define _MD_GET_SP(_t) (((struct sigcontext *) (_t)->md.context)->sc_sp) -#define PR_NUM_GCREGS _JBLEN -#define CONTEXT(_th) ((_th)->md.context) - -/* -** Initialize a thread context to run "_main()" when started -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (setjmp(CONTEXT(_thread))) { \ - (*_main)(); \ - } \ - _MD_GET_SP(_thread) = (long) ((_sp) - 64); \ - _MD_GET_SP(_thread) &= ~15; \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!setjmp(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - longjmp(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures */ - -struct _MDThread { - jmp_buf context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#ifndef _PR_PTHREADS -#define _MD_INIT_LOCKS() -#endif -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -/* - * The following are copied from _sunos.h, _aix.h. This means - * some of them should probably be moved into _unixos.h. But - * _irix.h seems to be quite different in regard to these macros. - */ -#define _MD_INTERVAL_USE_GTOD - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -/* The following defines unwrapped versions of select() and poll(). */ -#include -extern int __select (int, fd_set *, fd_set *, fd_set *, struct timeval *); -#define _MD_SELECT __select - -#include -#define _MD_POLL __poll -extern int __poll(struct pollfd filedes[], unsigned int nfds, int timeout); - -/* - * Atomic operations - */ -#ifdef OSF1_HAVE_MACHINE_BUILTINS_H -#include -#define _PR_HAVE_ATOMIC_OPS -#define _MD_INIT_ATOMIC() -#define _MD_ATOMIC_INCREMENT(val) (__ATOMIC_INCREMENT_LONG(val) + 1) -#define _MD_ATOMIC_ADD(ptr, val) (__ATOMIC_ADD_LONG(ptr, val) + val) -#define _MD_ATOMIC_DECREMENT(val) (__ATOMIC_DECREMENT_LONG(val) - 1) -#define _MD_ATOMIC_SET(val, newval) __ATOMIC_EXCH_LONG(val, newval) -#endif /* OSF1_HAVE_MACHINE_BUILTINS_H */ - -#endif /* nspr_osf1_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_pcos.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_pcos.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_pcos.h 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_pcos.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prpcos_h___ -#define prpcos_h___ - -#define PR_DLL_SUFFIX ".dll" - -#include - -#define DIRECTORY_SEPARATOR '\\' -#define DIRECTORY_SEPARATOR_STR "\\" -#define PATH_SEPARATOR ';' - -/* -** Routines for processing command line arguments -*/ -PR_BEGIN_EXTERN_C -#ifndef XP_OS2 -extern char *optarg; -extern int optind; -extern int getopt(int argc, char **argv, char *spec); -#endif -PR_END_EXTERN_C - - -/* -** Definitions of directory structures amd functions -** These definitions are from: -** -*/ -#ifdef XP_OS2 -#include -#endif -#include -#include -#include /* O_BINARY */ - -#ifdef OS2 -extern PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen); -#define _MD_GETHOSTNAME _MD_OS2GetHostName -#else -extern PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen); -#define _MD_GETHOSTNAME _MD_WindowsGetHostName -extern PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen); -#define _MD_GETSYSINFO _MD_WindowsGetSysInfo -#endif - -#endif /* prpcos_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/prosdep.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/prosdep.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/prosdep.h 2012-10-24 22:19:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/prosdep.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prosdep_h___ -#define prosdep_h___ - -/* -** Get OS specific header information -*/ -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -#ifdef XP_PC - -#include "md/_pcos.h" -#ifdef WINNT -#include "md/_winnt.h" -#include "md/_win32_errors.h" -#elif defined(WIN95) || defined(WINCE) -#include "md/_win95.h" -#include "md/_win32_errors.h" -#elif defined(OS2) -#include "md/_os2.h" -#include "md/_os2_errors.h" -#else -#error unknown Windows platform -#endif - -#elif defined(XP_UNIX) - -#if defined(AIX) -#include "md/_aix.h" - -#elif defined(FREEBSD) -#include "md/_freebsd.h" - -#elif defined(NETBSD) -#include "md/_netbsd.h" - -#elif defined(OPENBSD) -#include "md/_openbsd.h" - -#elif defined(BSDI) -#include "md/_bsdi.h" - -#elif defined(HPUX) -#include "md/_hpux.h" - -#elif defined(IRIX) -#include "md/_irix.h" - -#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) -#include "md/_linux.h" - -#elif defined(OSF1) -#include "md/_osf1.h" - -#elif defined(DARWIN) -#include "md/_darwin.h" - -#elif defined(SOLARIS) -#include "md/_solaris.h" - -#elif defined(SCO) -#include "md/_scoos.h" - -#elif defined(UNIXWARE) -#include "md/_unixware.h" - -#elif defined(DGUX) -#include "md/_dgux.h" - -#elif defined(QNX) -#include "md/_qnx.h" - -#elif defined(NTO) -#include "md/_nto.h" - -#elif defined(RISCOS) -#include "md/_riscos.h" - -#elif defined(SYMBIAN) -#include "md/_symbian.h" - -#else -#error unknown Unix flavor - -#endif - -#include "md/_unixos.h" -#include "md/_unix_errors.h" - -#elif defined(XP_BEOS) - -#include "md/_beos.h" -#include "md/_unix_errors.h" - -#else - -#error "The platform is not BeOS, Unix, Windows, or Mac" - -#endif - -#ifdef _PR_PTHREADS -#include "md/_pth.h" -#endif - -PR_END_EXTERN_C - -#endif /* prosdep_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_pth.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_pth.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_pth.h 2012-10-23 01:03:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_pth.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,270 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_pth_defs_h_ -#define nspr_pth_defs_h_ - -/* -** Appropriate definitions of entry points not used in a pthreads world -*/ -#define _PR_MD_BLOCK_CLOCK_INTERRUPTS() -#define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS() -#define _PR_MD_DISABLE_CLOCK_INTERRUPTS() -#define _PR_MD_ENABLE_CLOCK_INTERRUPTS() - -/* In good standards fashion, the DCE threads (based on posix-4) are not - * quite the same as newer posix implementations. These are mostly name - * changes and small differences, so macros usually do the trick - */ -#ifdef _PR_DCETHREADS -#define _PT_PTHREAD_MUTEXATTR_INIT pthread_mutexattr_create -#define _PT_PTHREAD_MUTEXATTR_DESTROY pthread_mutexattr_delete -#define _PT_PTHREAD_MUTEX_INIT(m, a) pthread_mutex_init(&(m), a) -#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (0 == pthread_mutex_trylock(&(m))) -#define _PT_PTHREAD_CONDATTR_INIT pthread_condattr_create -#define _PT_PTHREAD_COND_INIT(m, a) pthread_cond_init(&(m), a) -#define _PT_PTHREAD_CONDATTR_DESTROY pthread_condattr_delete - -/* Notes about differences between DCE threads and pthreads 10: - * 1. pthread_mutex_trylock returns 1 when it locks the mutex - * 0 when it does not. The latest pthreads has a set of errno-like - * return values. - * 2. return values from pthread_cond_timedwait are different. - * - * - * - */ -#elif defined(BSDI) -/* - * Mutex and condition attributes are not supported. The attr - * argument to pthread_mutex_init() and pthread_cond_init() must - * be passed as NULL. - * - * The memset calls in _PT_PTHREAD_MUTEX_INIT and _PT_PTHREAD_COND_INIT - * are to work around BSDI's using a single bit to indicate a mutex - * or condition variable is initialized. This entire BSDI section - * will go away when BSDI releases updated threads libraries for - * BSD/OS 3.1 and 4.0. - */ -#define _PT_PTHREAD_MUTEXATTR_INIT(x) 0 -#define _PT_PTHREAD_MUTEXATTR_DESTROY(x) /* */ -#define _PT_PTHREAD_MUTEX_INIT(m, a) (memset(&(m), 0, sizeof(m)), \ - pthread_mutex_init(&(m), NULL)) -#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (EBUSY == pthread_mutex_trylock(&(m))) -#define _PT_PTHREAD_CONDATTR_INIT(x) 0 -#define _PT_PTHREAD_CONDATTR_DESTROY(x) /* */ -#define _PT_PTHREAD_COND_INIT(m, a) (memset(&(m), 0, sizeof(m)), \ - pthread_cond_init(&(m), NULL)) -#else -#define _PT_PTHREAD_MUTEXATTR_INIT pthread_mutexattr_init -#define _PT_PTHREAD_MUTEXATTR_DESTROY pthread_mutexattr_destroy -#define _PT_PTHREAD_MUTEX_INIT(m, a) pthread_mutex_init(&(m), &(a)) -#if defined(FREEBSD) -#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) pt_pthread_mutex_is_locked(&(m)) -#else -#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (EBUSY == pthread_mutex_trylock(&(m))) -#endif -#if defined(ANDROID) -/* Conditional attribute init and destroy aren't implemented in bionic. */ -#define _PT_PTHREAD_CONDATTR_INIT(x) 0 -#define _PT_PTHREAD_CONDATTR_DESTROY(x) /* */ -#else -#define _PT_PTHREAD_CONDATTR_INIT pthread_condattr_init -#define _PT_PTHREAD_CONDATTR_DESTROY pthread_condattr_destroy -#endif -#define _PT_PTHREAD_COND_INIT(m, a) pthread_cond_init(&(m), &(a)) -#endif - -/* The pthreads standard does not specify an invalid value for the - * pthread_t handle. (0 is usually an invalid pthread identifier - * but there are exceptions, for example, DG/UX.) These macros - * define a way to set the handle to or compare the handle with an - * invalid identifier. These macros are not portable and may be - * more of a problem as we adapt to more pthreads implementations. - * They are only used in the PRMonitor functions. Do not use them - * in new code. - * - * Unfortunately some of our clients depend on certain properties - * of our PRMonitor implementation, preventing us from replacing - * it by a portable implementation. - * - High-performance servers like the fact that PR_EnterMonitor - * only calls PR_Lock and PR_ExitMonitor only calls PR_Unlock. - * (A portable implementation would use a PRLock and a PRCondVar - * to implement the recursive lock in a monitor and call both - * PR_Lock and PR_Unlock in PR_EnterMonitor and PR_ExitMonitor.) - * Unfortunately this forces us to read the monitor owner field - * without holding a lock. - * - One way to make it safe to read the monitor owner field - * without holding a lock is to make that field a PRThread* - * (one should be able to read a pointer with a single machine - * instruction). However, PR_GetCurrentThread calls calloc if - * it is called by a thread that was not created by NSPR. The - * malloc tracing tools in the Mozilla client use PRMonitor for - * locking in their malloc, calloc, and free functions. If - * PR_EnterMonitor calls any of these functions, infinite - * recursion ensues. - */ -#if defined(_PR_DCETHREADS) -#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) \ - memset(&(t), 0, sizeof(pthread_t)) -#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) \ - (!memcmp(&(t), &pt_zero_tid, sizeof(pthread_t))) -#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt) (dt) = (st) -#elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(SOLARIS) \ - || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ - || defined(HPUX) || defined(FREEBSD) \ - || defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \ - || defined(NTO) || defined(DARWIN) \ - || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) -#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) (t) = 0 -#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) (t) == 0 -#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt) (dt) = (st) -#else -#error "pthreads is not supported for this architecture" -#endif - -#if defined(_PR_DCETHREADS) -#define _PT_PTHREAD_ATTR_INIT pthread_attr_create -#define _PT_PTHREAD_ATTR_DESTROY pthread_attr_delete -#define _PT_PTHREAD_CREATE(t, a, f, r) pthread_create(t, a, f, r) -#define _PT_PTHREAD_KEY_CREATE pthread_keycreate -#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY pthread_attr_setsched -#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) \ - (*(s) = pthread_attr_getstacksize(*(a)), 0) -#define _PT_PTHREAD_GETSPECIFIC(k, r) \ - pthread_getspecific((k), (pthread_addr_t *) &(r)) -#elif defined(_PR_PTHREADS) -#define _PT_PTHREAD_ATTR_INIT pthread_attr_init -#define _PT_PTHREAD_ATTR_DESTROY pthread_attr_destroy -#define _PT_PTHREAD_CREATE(t, a, f, r) pthread_create(t, &a, f, r) -#define _PT_PTHREAD_KEY_CREATE pthread_key_create -#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY pthread_attr_setschedpolicy -#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) pthread_attr_getstacksize(a, s) -#define _PT_PTHREAD_GETSPECIFIC(k, r) (r) = pthread_getspecific(k) -#else -#error "Cannot determine pthread strategy" -#endif - -#if defined(_PR_DCETHREADS) -#define _PT_PTHREAD_EXPLICIT_SCHED _PT_PTHREAD_DEFAULT_SCHED -#endif - -/* - * pthread_mutex_trylock returns different values in DCE threads and - * pthreads. - */ -#if defined(_PR_DCETHREADS) -#define PT_TRYLOCK_SUCCESS 1 -#define PT_TRYLOCK_BUSY 0 -#else -#define PT_TRYLOCK_SUCCESS 0 -#define PT_TRYLOCK_BUSY EBUSY -#endif - -/* - * These platforms don't have sigtimedwait() - */ -#if (defined(AIX) && !defined(AIX4_3_PLUS)) \ - || defined(LINUX) || defined(__GNU__)|| defined(__GLIBC__) \ - || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ - || defined(BSDI) || defined(UNIXWARE) \ - || defined(DARWIN) || defined(SYMBIAN) -#define PT_NO_SIGTIMEDWAIT -#endif - -#if defined(OSF1) -#define PT_PRIO_MIN PRI_OTHER_MIN -#define PT_PRIO_MAX PRI_OTHER_MAX -#elif defined(IRIX) -#include -#define PT_PRIO_MIN PX_PRIO_MIN -#define PT_PRIO_MAX PX_PRIO_MAX -#elif defined(AIX) -#include -#include -#ifndef PTHREAD_CREATE_JOINABLE -#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED -#endif -#define PT_PRIO_MIN DEFAULT_PRIO -#define PT_PRIO_MAX DEFAULT_PRIO -#elif defined(HPUX) - -#if defined(_PR_DCETHREADS) -#define PT_PRIO_MIN PRI_OTHER_MIN -#define PT_PRIO_MAX PRI_OTHER_MAX -#else /* defined(_PR_DCETHREADS) */ -#include -#define PT_PRIO_MIN sched_get_priority_min(SCHED_OTHER) -#define PT_PRIO_MAX sched_get_priority_max(SCHED_OTHER) -#endif /* defined(_PR_DCETHREADS) */ - -#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ - || defined(FREEBSD) || defined(SYMBIAN) -#define PT_PRIO_MIN sched_get_priority_min(SCHED_OTHER) -#define PT_PRIO_MAX sched_get_priority_max(SCHED_OTHER) -#elif defined(NTO) -/* - * Neutrino has functions that return the priority range but - * they return invalid numbers, so I just hard coded these here - * for now. Jerry.Kirk@Nexarecorp.com - */ -#define PT_PRIO_MIN 0 -#define PT_PRIO_MAX 30 -#elif defined(SOLARIS) -/* - * Solaris doesn't seem to have macros for the min/max priorities. - * The range of 0-127 is mentioned in the pthread_setschedparam(3T) - * man pages, and pthread_setschedparam indeed allows 0-127. However, - * pthread_attr_setschedparam does not allow 0; it allows 1-127. - */ -#define PT_PRIO_MIN 1 -#define PT_PRIO_MAX 127 -#elif defined(OPENBSD) -#define PT_PRIO_MIN 0 -#define PT_PRIO_MAX 31 -#elif defined(NETBSD) \ - || defined(BSDI) || defined(DARWIN) || defined(UNIXWARE) \ - || defined(RISCOS) /* XXX */ -#define PT_PRIO_MIN 0 -#define PT_PRIO_MAX 126 -#else -#error "pthreads is not supported for this architecture" -#endif - -/* - * The _PT_PTHREAD_YIELD function is called from a signal handler. - * Needed for garbage collection -- Look at PR_Suspend/PR_Resume - * implementation. - */ -#if defined(_PR_DCETHREADS) -#define _PT_PTHREAD_YIELD() pthread_yield() -#elif defined(OSF1) -/* - * sched_yield can't be called from a signal handler. Must use - * the _np version. - */ -#define _PT_PTHREAD_YIELD() pthread_yield_np() -#elif defined(AIX) -extern int (*_PT_aix_yield_fcn)(); -#define _PT_PTHREAD_YIELD() (*_PT_aix_yield_fcn)() -#elif defined(IRIX) -#include -#define _PT_PTHREAD_YIELD() \ - PR_BEGIN_MACRO \ - struct timespec onemillisec = {0}; \ - onemillisec.tv_nsec = 1000000L; \ - nanosleep(&onemillisec,NULL); \ - PR_END_MACRO -#elif defined(HPUX) || defined(SOLARIS) \ - || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ - || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ - || defined(BSDI) || defined(NTO) || defined(DARWIN) \ - || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) -#define _PT_PTHREAD_YIELD() sched_yield() -#else -#error "Need to define _PT_PTHREAD_YIELD for this platform" -#endif - -#endif /* nspr_pth_defs_h_ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_qnx.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_qnx.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_qnx.cfg 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_qnx.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef QNX -#define QNX -#endif - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#undef HAVE_LONG_LONG -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 1 -#define PR_ALIGN_OF_INT 1 -#define PR_ALIGN_OF_LONG 1 -#define PR_ALIGN_OF_INT64 1 -#define PR_ALIGN_OF_FLOAT 1 -#define PR_ALIGN_OF_DOUBLE 1 -#define PR_ALIGN_OF_POINTER 1 -#define PR_ALIGN_OF_WORD 1 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 -#define PR_WORDS_PER_DWORD_LOG2 1 - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_qnx.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_qnx.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_qnx.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_qnx.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,182 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_qnx_defs_h___ -#define nspr_qnx_defs_h___ - -/* -** Internal configuration macros -*/ -#define PR_LINKER_ARCH "qnx" -#define _PR_SI_SYSNAME "QNX" -#define _PR_SI_ARCHITECTURE "x86" -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#ifndef HAVE_WEAK_IO_SYMBOLS -#define HAVE_WEAK_IO_SYMBOLS -#endif - -#undef _PR_POLL_AVAILABLE -#undef _PR_USE_POLL -#define _PR_HAVE_SOCKADDR_LEN -#define HAVE_BSD_FLOCK -#define _PR_NO_LARGE_FILES -#define _PR_STAT_HAS_ONLY_ST_ATIME - -#include - -#undef HAVE_STACK_GROWING_UP -#undef HAVE_DLL -#undef USE_DLFCN -#define NEED_STRFTIME_LOCK -#define NEED_TIME_R -#define _PR_NEED_STRCASECMP - -#ifndef HAVE_STRERROR -#define HAVE_STRERROR -#endif - -#define USE_SETJMP - -#include - -#define _SETJMP setjmp -#define _LONGJMP longjmp -#define _PR_CONTEXT_TYPE jmp_buf -#define _PR_NUM_GCREGS _JBLEN -#define _MD_GET_SP(_t) (_t)->md.context[7] - -#define CONTEXT(_th) ((_th)->md.context) - -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ - _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!_SETJMP(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - _LONGJMP(CONTEXT(_thread), 1); \ -} - -/* -** Machine-dependent (MD) data structures. -*/ -struct _MDThread { - _PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* -** md-specific cpu structure field -*/ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_INTERVAL_USE_GTOD -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -/* -** We wrapped the select() call. _MD_SELECT refers to the built-in, -** unwrapped version. -*/ -#include -#include -#include -#define _MD_SELECT select - -#define SA_RESTART 0 - -#endif /* nspr_qnx_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_riscos.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_riscos.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_riscos.cfg 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_riscos.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef RISCOS -#define RISCOS -#endif - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 -#define PR_WORDS_PER_DWORD_LOG2 1 - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_riscos.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_riscos.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_riscos.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_riscos.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,176 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_riscos_defs_h___ -#define nspr_riscos_defs_h___ - -/* -** Internal configuration macros -*/ -#define PR_LINKER_ARCH "riscos" -#define _PR_SI_SYSNAME "RISCOS" -#define _PR_SI_ARCHITECTURE "arm" -#define PR_DLL_SUFFIX ".so" - -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_HAVE_SOCKADDR_LEN -#undef HAVE_BSD_FLOCK -#define _PR_NO_LARGE_FILES -#define _PR_STAT_HAS_ONLY_ST_ATIME -#define _PR_HAVE_POSIX_SEMAPHORES - -#include -#include -#include - - -#undef HAVE_STACK_GROWING_UP -#define HAVE_DLL -#define USE_DLFCN -#define NEED_STRFTIME_LOCK -#define NEED_TIME_R -#define PT_NO_SIGTIMEDWAIT - -#ifndef HAVE_STRERROR -#define HAVE_STRERROR -#endif - -#define USE_SETJMP - -#include - -#define _SETJMP setjmp -#define _LONGJMP longjmp -#define _PR_CONTEXT_TYPE jmp_buf -#define _PR_NUM_GCREGS _JBLEN -#define _MD_GET_SP(_t) (_t)->md.context[7] - -#define CONTEXT(_th) ((_th)->md.context) - - -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ - _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!_SETJMP(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - _LONGJMP(CONTEXT(_thread), 1); \ -} - -/* -** Machine-dependent (MD) data structures. -*/ -struct _MDThread { - _PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* -** md-specific cpu structure field -*/ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif -}; - -#define _PR_IOQ(_cpu) /* */ ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_INTERVAL_USE_GTOD -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -/* -** We wrapped the select() call. _MD_SELECT refers to the built-in, -** unwrapped version. -*/ -#include -#include -#include -#define _MD_SELECT select - -#endif /* nspr_riscos_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_scoos.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_scoos.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_scoos.cfg 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_scoos.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef SCO -#define SCO -#endif - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#undef HAVE_LONG_LONG -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#define _PR_POLL_BACKCOMPAT - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_scoos.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_scoos.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_scoos.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_scoos.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_scoos5_defs_h___ -#define nspr_scoos5_defs_h___ - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "scoos5" -#define PR_DLL_SUFFIX ".so" - -#define _PR_SI_SYSNAME "SCO" -#define _PR_SI_ARCHITECTURE "x86" -#define _PR_STACK_VMBASE 0x50000000 - -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#undef HAVE_STACK_GROWING_UP -#define HAVE_DLL -#define USE_DLFCN - -#if !defined (HAVE_STRERROR) -#define HAVE_STRERROR -#endif - -#ifndef HAVE_WEAK_IO_SYMBOLS -#define HAVE_WEAK_IO_SYMBOLS -#endif - -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_NO_LARGE_FILES -#define _PR_STAT_HAS_ONLY_ST_ATIME - -#define NEED_STRFTIME_LOCK -#define NEED_TIME_R -#define _PR_RECV_BROKEN /* recv doesn't work on Unix Domain Sockets */ - -#define USE_SETJMP - -#ifdef _PR_LOCAL_THREADS_ONLY -#include - -#define _MD_GET_SP(_t) (_t)->md.jb[4] -#define PR_NUM_GCREGS _SIGJBLEN -#define PR_CONTEXT_TYPE sigjmp_buf - -#define CONTEXT(_th) ((_th)->md.jb) - -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if (sigsetjmp(CONTEXT(_thread),1)) { \ - (*_main)(); \ - } \ - _MD_GET_SP(_thread) = (int) ((_sp) - 64); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!sigsetjmp(CONTEXT(_thread), 1)) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->osErrorCode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - siglongjmp(CONTEXT(_thread), 1); \ -} - -#endif /* _PR_LOCAL_THREADS_ONLY */ - -struct _MDThread { - jmp_buf jb; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -#define _MD_INTERVAL_USE_GTOD - -#define _MD_SELECT _select -#define _MD_POLL _poll - -#endif /* nspr_scoos5_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_solaris.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_solaris.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_solaris.cfg 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_solaris.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef SOLARIS -#define SOLARIS -#endif - -#define PR_AF_INET6 26 /* same as AF_INET6 */ - -#if defined(sparc) || defined(__sparc) -#undef IS_LITTLE_ENDIAN -#define IS_BIG_ENDIAN 1 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_DOUBLE 8 -#if defined(__sparcv9) -#define IS_64 -#endif -#elif defined(__x86_64) -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_DOUBLE 8 -#define IS_64 -#elif defined(i386) || defined(__i386) -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_DOUBLE 4 -#else -#error unknown processor -#endif - -#ifdef IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 8 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 64 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 6 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_POINTER 8 - -#else /* IS_64 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_POINTER 4 - -#endif /* IS_64 */ - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#define HAVE_ALIGNED_DOUBLES -#define HAVE_ALIGNED_LONGLONGS - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* ifndef nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_solaris.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_solaris.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_solaris.h 2012-10-25 14:54:24.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_solaris.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,493 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_solaris_defs_h___ -#define nspr_solaris_defs_h___ - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "solaris" -#define _PR_SI_SYSNAME "SOLARIS" -#ifdef sparc -#define _PR_SI_ARCHITECTURE "sparc" -#elif defined(__x86_64) -#define _PR_SI_ARCHITECTURE "x86-64" -#elif defined(i386) -#define _PR_SI_ARCHITECTURE "x86" -#else -#error unknown processor -#endif -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE (2*65536L) -#define _MD_MMAP_FLAGS MAP_SHARED - -#undef HAVE_STACK_GROWING_UP - -#ifndef HAVE_WEAK_IO_SYMBOLS -#define HAVE_WEAK_IO_SYMBOLS -#endif - -#undef HAVE_WEAK_MALLOC_SYMBOLS -#define HAVE_DLL -#define USE_DLFCN -#define NEED_STRFTIME_LOCK - -/* - * Intel x86 has atomic instructions. - * - * Sparc v8 does not have instructions to efficiently implement - * atomic increment/decrement operations. We use the default - * atomic routine implementation in pratom.c. - * - * 64-bit Solaris requires sparc v9, which has atomic instructions. - */ -#if defined(i386) || defined(IS_64) -#define _PR_HAVE_ATOMIC_OPS -#endif - -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_STAT_HAS_ST_ATIM -#ifdef SOLARIS2_5 -#define _PR_HAVE_SYSV_SEMAPHORES -#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY -#else -#define _PR_HAVE_POSIX_SEMAPHORES -#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY -#endif -#define _PR_HAVE_GETIPNODEBYNAME -#define _PR_HAVE_GETIPNODEBYADDR -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE -#define _PR_ACCEPT_INHERIT_NONBLOCK -#ifdef _PR_INET6 -#define _PR_HAVE_INET_NTOP -#else -#define AF_INET6 26 -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - char *ai_canonname; - struct sockaddr *ai_addr; - struct addrinfo *ai_next; -}; -#define AI_CANONNAME 0x0010 -#define AI_V4MAPPED 0x0001 -#define AI_ALL 0x0002 -#define AI_ADDRCONFIG 0x0004 -#define _PR_HAVE_MD_SOCKADDR_IN6 -/* isomorphic to struct in6_addr on Solaris 8 */ -struct _md_in6_addr { - union { - PRUint8 _S6_u8[16]; - PRUint32 _S6_u32[4]; - PRUint32 __S6_align; - } _S6_un; -}; -/* isomorphic to struct sockaddr_in6 on Solaris 8 */ -struct _md_sockaddr_in6 { - PRUint16 sin6_family; - PRUint16 sin6_port; - PRUint32 sin6_flowinfo; - struct _md_in6_addr sin6_addr; - PRUint32 sin6_scope_id; - PRUint32 __sin6_src_id; -}; -#endif -#if defined(_PR_PTHREADS) -#define _PR_HAVE_GETHOST_R -#define _PR_HAVE_GETHOST_R_POINTER -#endif - -#include "prinrval.h" -#define _MD_INTERVAL_INIT() -NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void); -#define _MD_GET_INTERVAL _MD_Solaris_GetInterval -NSPR_API(PRIntervalTime) _MD_Solaris_TicksPerSecond(void); -#define _MD_INTERVAL_PER_SEC _MD_Solaris_TicksPerSecond - -#if defined(_PR_HAVE_ATOMIC_OPS) -/* -** Atomic Operations -*/ -#define _MD_INIT_ATOMIC() - -NSPR_API(PRInt32) _MD_AtomicIncrement(PRInt32 *val); -#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement - -NSPR_API(PRInt32) _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val); -#define _MD_ATOMIC_ADD _MD_AtomicAdd - -NSPR_API(PRInt32) _MD_AtomicDecrement(PRInt32 *val); -#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement - -NSPR_API(PRInt32) _MD_AtomicSet(PRInt32 *val, PRInt32 newval); -#define _MD_ATOMIC_SET _MD_AtomicSet -#endif /* _PR_HAVE_ATOMIC_OPS */ - -#if defined(_PR_PTHREADS) - -NSPR_API(void) _MD_EarlyInit(void); - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit - -#else /* _PR_PTHREADS */ - -/* - * _PR_LOCAL_THREADS_ONLY implementation on Solaris - */ - -#include "prthread.h" - -#include -#include -#include -#include - -/* -** Initialization Related definitions -*/ - -NSPR_API(void) _MD_EarlyInit(void); -NSPR_API(void) _MD_SolarisInit(); -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _MD_SolarisInit -#define _MD_INIT_THREAD _MD_InitializeThread - -#ifdef USE_SETJMP - -#include - -#define _PR_CONTEXT_TYPE jmp_buf - -#ifdef sparc -#define _MD_GET_SP(_t) (_t)->md.context[2] -#else -#define _MD_GET_SP(_t) (_t)->md.context[4] -#endif - -#define PR_NUM_GCREGS _JBLEN -#define CONTEXT(_thread) (_thread)->md.context - -#else /* ! USE_SETJMP */ - -#ifdef sparc -#define _PR_CONTEXT_TYPE ucontext_t -#define _MD_GET_SP(_t) (_t)->md.context.uc_mcontext.gregs[REG_SP] -/* -** Sparc's use register windows. the _MD_GetRegisters for the sparc's -** doesn't actually store anything into the argument buffer; instead the -** register windows are homed to the stack. I assume that the stack -** always has room for the registers to spill to... -*/ -#define PR_NUM_GCREGS 0 -#else -#define _PR_CONTEXT_TYPE unsigned int edi; sigset_t oldMask, blockMask; ucontext_t -#define _MD_GET_SP(_t) (_t)->md.context.uc_mcontext.gregs[USP] -#define PR_NUM_GCREGS _JBLEN -#endif - -#define CONTEXT(_thread) (&(_thread)->md.context) - -#endif /* ! USE_SETJMP */ - -#include -/* - * Because clock_gettime() on Solaris/x86 always generates a - * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(), - * which is implemented using gettimeofday(). - */ -#ifdef i386 -#define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt)) -#else -#define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt)) -#endif /* i386 */ - -#define _MD_SAVE_ERRNO(_thread) (_thread)->md.errcode = errno; -#define _MD_RESTORE_ERRNO(_thread) errno = (_thread)->md.errcode; - -#ifdef sparc - -#ifdef USE_SETJMP -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - int *context = (_thread)->md.context; \ - *status = PR_TRUE; \ - (void) setjmp(context); \ - (_thread)->md.context[1] = (int) ((_sp) - 64); \ - (_thread)->md.context[2] = (int) _main; \ - (_thread)->md.context[3] = (int) _main + 4; \ - _thread->no_sched = 0; \ - PR_END_MACRO - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!setjmp(CONTEXT(_thread))) { \ - _MD_SAVE_ERRNO(_thread) \ - _MD_SET_LAST_THREAD(_thread); \ - _MD_SET_CURRENT_THREAD(_thread); \ - _PR_Schedule(); \ - } - -#define _MD_RESTORE_CONTEXT(_newThread) \ -{ \ - _MD_RESTORE_ERRNO(_newThread) \ - _MD_SET_CURRENT_THREAD(_newThread); \ - longjmp(CONTEXT(_newThread), 1); \ -} - -#else -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - ucontext_t *uc = CONTEXT(_thread); \ - *status = PR_TRUE; \ - getcontext(uc); \ - uc->uc_stack.ss_sp = (char *) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8); \ - uc->uc_stack.ss_size = _thread->stack->stackSize; \ - uc->uc_stack.ss_flags = 0; /* ? */ \ - uc->uc_mcontext.gregs[REG_SP] = (unsigned int) uc->uc_stack.ss_sp; \ - uc->uc_mcontext.gregs[REG_PC] = (unsigned int) _main; \ - uc->uc_mcontext.gregs[REG_nPC] = (unsigned int) ((char*)_main)+4; \ - uc->uc_flags = UC_ALL; \ - _thread->no_sched = 0; \ - PR_END_MACRO - -/* -** Switch away from the current thread context by saving its state and -** calling the thread scheduler. Reload cpu when we come back from the -** context switch because it might have changed. -*/ -#define _MD_SWITCH_CONTEXT(_thread) \ - PR_BEGIN_MACRO \ - if (!getcontext(CONTEXT(_thread))) { \ - _MD_SAVE_ERRNO(_thread); \ - _MD_SET_LAST_THREAD(_thread); \ - _PR_Schedule(); \ - } \ - PR_END_MACRO - -/* -** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or -** initialized by _MD_INIT_CONTEXT. -*/ -#define _MD_RESTORE_CONTEXT(_newThread) \ - PR_BEGIN_MACRO \ - ucontext_t *uc = CONTEXT(_newThread); \ - uc->uc_mcontext.gregs[11] = 1; \ - _MD_RESTORE_ERRNO(_newThread); \ - _MD_SET_CURRENT_THREAD(_newThread); \ - setcontext(uc); \ - PR_END_MACRO -#endif - -#else /* x86 solaris */ - -#ifdef USE_SETJMP - -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - *status = PR_TRUE; \ - if (setjmp(CONTEXT(_thread))) _main(); \ - _MD_GET_SP(_thread) = (int) ((_sp) - 64); \ - PR_END_MACRO - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!setjmp(CONTEXT(_thread))) { \ - _MD_SAVE_ERRNO(_thread) \ - _PR_Schedule(); \ - } - -#define _MD_RESTORE_CONTEXT(_newThread) \ -{ \ - _MD_RESTORE_ERRNO(_newThread) \ - _MD_SET_CURRENT_THREAD(_newThread); \ - longjmp(CONTEXT(_newThread), 1); \ -} - -#else /* USE_SETJMP */ - -#define WINDOWSIZE 0 - -int getedi(void); -void setedi(int); - -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - ucontext_t *uc = CONTEXT(_thread); \ - *status = PR_TRUE; \ - getcontext(uc); \ - /* Force sp to be double aligned! */ \ - uc->uc_mcontext.gregs[USP] = (int) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8); \ - uc->uc_mcontext.gregs[PC] = (int) _main; \ - (_thread)->no_sched = 0; \ - PR_END_MACRO - -/* getcontext() may return 1, contrary to what the man page says */ -#define _MD_SWITCH_CONTEXT(_thread) \ - PR_BEGIN_MACRO \ - ucontext_t *uc = CONTEXT(_thread); \ - PR_ASSERT(_thread->no_sched); \ - sigfillset(&((_thread)->md.blockMask)); \ - sigprocmask(SIG_BLOCK, &((_thread)->md.blockMask), \ - &((_thread)->md.oldMask)); \ - (_thread)->md.edi = getedi(); \ - if (! getcontext(uc)) { \ - sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \ - uc->uc_mcontext.gregs[EDI] = (_thread)->md.edi; \ - _MD_SAVE_ERRNO(_thread) \ - _MD_SET_LAST_THREAD(_thread); \ - _PR_Schedule(); \ - } else { \ - sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \ - setedi((_thread)->md.edi); \ - PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \ - _MD_LAST_THREAD()->no_sched = 0; \ - } \ - PR_END_MACRO - -/* -** Restore a thread context, saved by _PR_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_newthread) \ - PR_BEGIN_MACRO \ - ucontext_t *uc = CONTEXT(_newthread); \ - uc->uc_mcontext.gregs[EAX] = 1; \ - _MD_RESTORE_ERRNO(_newthread) \ - _MD_SET_CURRENT_THREAD(_newthread); \ - (_newthread)->no_sched = 1; \ - setcontext(uc); \ - PR_END_MACRO -#endif /* USE_SETJMP */ - -#endif /* sparc */ - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDThread { - _PR_CONTEXT_TYPE context; - int errcode; - int id; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -extern PRStatus _MD_WAIT(struct PRThread *, PRIntervalTime timeout); -extern PRStatus _MD_WAKEUP_WAITER(struct PRThread *); -extern void _MD_YIELD(void); -extern PRStatus _MD_InitializeThread(PRThread *thread); -extern void _MD_SET_PRIORITY(struct _MDThread *thread, - PRThreadPriority newPri); -extern PRStatus _MD_CREATE_THREAD(PRThread *thread, void (*start) (void *), - PRThreadPriority priority, PRThreadScope scope, PRThreadState state, - PRUint32 stackSize); - -/* The following defines the unwrapped versions of select() and poll(). */ -extern int _select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout); -#define _MD_SELECT _select - -#include -#include -#define _MD_POLL _poll -extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); - -PR_BEGIN_EXTERN_C - -/* -** Missing function prototypes -*/ -extern int gethostname (char *name, int namelen); - -PR_END_EXTERN_C - -#endif /* _PR_PTHREADS */ - -extern void _MD_solaris_map_sendfile_error(int err); - -#endif /* nspr_solaris_defs_h___ */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_symbian.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_symbian.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_symbian.cfg 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_symbian.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,170 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef SYMBIAN -#define SYMBIAN -#endif - -#define PR_AF_INET6 0x0806 /* same as AF_INET6 */ - -#ifdef __arm__ - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_DOUBLE 8 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(__WINS__) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_POINTER 4 -#define PR_ALIGN_OF_WORD 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_DOUBLE 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#else - -#error "Unknown CPU architecture" - -#endif - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#if PR_ALIGN_OF_DOUBLE == 8 -#define HAVE_ALIGNED_DOUBLES -#endif -#if PR_ALIGN_OF_INT64 == 8 -#define HAVE_ALIGNED_LONGLONGS -#endif - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_symbian.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_symbian.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_symbian.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_symbian.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_symbian_defs_h___ -#define nspr_symbian_defs_h___ - -#include "prthread.h" - -/* - * Internal configuration macros - */ - -#define _PR_SI_SYSNAME "SYMBIAN" -#if defined(__WINS__) -#define _PR_SI_ARCHITECTURE "i386" -#elif defined(__arm__) -#define _PR_SI_ARCHITECTURE "arm" -#else -#error "Unknown CPU architecture" -#endif -#define PR_DLL_SUFFIX ".dll" - -#undef HAVE_STACK_GROWING_UP - -#ifdef DYNAMIC_LIBRARY -#define HAVE_DLL -#define USE_DLFCN -#endif - -#define _PR_STAT_HAS_ONLY_ST_ATIME -#define _PR_NO_LARGE_FILES -#define _PR_HAVE_SYSV_SEMAPHORES -#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY - -#ifndef _PR_PTHREADS -#error "Classic NSPR is not implemented" -#endif - -extern void _MD_EarlyInit(void); - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INTERVAL_USE_GTOD - -/* For writev() */ -#include - -#endif /* nspr_symbian_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unix_errors.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unix_errors.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unix_errors.h 2012-03-06 13:13:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unix_errors.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prunixerrors_h___ -#define prunixerrors_h___ - -#include -#include - -PR_BEGIN_EXTERN_C - -extern void _MD_unix_map_default_error(int err); -#define _PR_MD_MAP_DEFAULT_ERROR _MD_unix_map_default_error - -extern void _MD_unix_map_opendir_error(int err); -#define _PR_MD_MAP_OPENDIR_ERROR _MD_unix_map_opendir_error - -extern void _MD_unix_map_closedir_error(int err); -#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_unix_map_closedir_error - -extern void _MD_unix_readdir_error(int err); -#define _PR_MD_MAP_READDIR_ERROR _MD_unix_readdir_error - -extern void _MD_unix_map_unlink_error(int err); -#define _PR_MD_MAP_UNLINK_ERROR _MD_unix_map_unlink_error - -extern void _MD_unix_map_stat_error(int err); -#define _PR_MD_MAP_STAT_ERROR _MD_unix_map_stat_error - -extern void _MD_unix_map_fstat_error(int err); -#define _PR_MD_MAP_FSTAT_ERROR _MD_unix_map_fstat_error - -extern void _MD_unix_map_rename_error(int err); -#define _PR_MD_MAP_RENAME_ERROR _MD_unix_map_rename_error - -extern void _MD_unix_map_access_error(int err); -#define _PR_MD_MAP_ACCESS_ERROR _MD_unix_map_access_error - -extern void _MD_unix_map_mkdir_error(int err); -#define _PR_MD_MAP_MKDIR_ERROR _MD_unix_map_mkdir_error - -extern void _MD_unix_map_rmdir_error(int err); -#define _PR_MD_MAP_RMDIR_ERROR _MD_unix_map_rmdir_error - -extern void _MD_unix_map_read_error(int err); -#define _PR_MD_MAP_READ_ERROR _MD_unix_map_read_error - -extern void _MD_unix_map_write_error(int err); -#define _PR_MD_MAP_WRITE_ERROR _MD_unix_map_write_error - -extern void _MD_unix_map_lseek_error(int err); -#define _PR_MD_MAP_LSEEK_ERROR _MD_unix_map_lseek_error - -extern void _MD_unix_map_fsync_error(int err); -#define _PR_MD_MAP_FSYNC_ERROR _MD_unix_map_fsync_error - -extern void _MD_unix_map_close_error(int err); -#define _PR_MD_MAP_CLOSE_ERROR _MD_unix_map_close_error - -extern void _MD_unix_map_socket_error(int err); -#define _PR_MD_MAP_SOCKET_ERROR _MD_unix_map_socket_error - -extern void _MD_unix_map_socketavailable_error(int err); -#define _PR_MD_MAP_SOCKETAVAILABLE_ERROR _MD_unix_map_socketavailable_error - -extern void _MD_unix_map_recv_error(int err); -#define _PR_MD_MAP_RECV_ERROR _MD_unix_map_recv_error - -extern void _MD_unix_map_recvfrom_error(int err); -#define _PR_MD_MAP_RECVFROM_ERROR _MD_unix_map_recvfrom_error - -extern void _MD_unix_map_send_error(int err); -#define _PR_MD_MAP_SEND_ERROR _MD_unix_map_send_error - -extern void _MD_unix_map_sendto_error(int err); -#define _PR_MD_MAP_SENDTO_ERROR _MD_unix_map_sendto_error - -extern void _MD_unix_map_writev_error(int err); -#define _PR_MD_MAP_WRITEV_ERROR _MD_unix_map_writev_error - -extern void _MD_unix_map_accept_error(int err); -#define _PR_MD_MAP_ACCEPT_ERROR _MD_unix_map_accept_error - -extern void _MD_unix_map_connect_error(int err); -#define _PR_MD_MAP_CONNECT_ERROR _MD_unix_map_connect_error - -extern void _MD_unix_map_bind_error(int err); -#define _PR_MD_MAP_BIND_ERROR _MD_unix_map_bind_error - -extern void _MD_unix_map_listen_error(int err); -#define _PR_MD_MAP_LISTEN_ERROR _MD_unix_map_listen_error - -extern void _MD_unix_map_shutdown_error(int err); -#define _PR_MD_MAP_SHUTDOWN_ERROR _MD_unix_map_shutdown_error - -extern void _MD_unix_map_socketpair_error(int err); -#define _PR_MD_MAP_SOCKETPAIR_ERROR _MD_unix_map_socketpair_error - -extern void _MD_unix_map_getsockname_error(int err); -#define _PR_MD_MAP_GETSOCKNAME_ERROR _MD_unix_map_getsockname_error - -extern void _MD_unix_map_getpeername_error(int err); -#define _PR_MD_MAP_GETPEERNAME_ERROR _MD_unix_map_getpeername_error - -extern void _MD_unix_map_getsockopt_error(int err); -#define _PR_MD_MAP_GETSOCKOPT_ERROR _MD_unix_map_getsockopt_error - -extern void _MD_unix_map_setsockopt_error(int err); -#define _PR_MD_MAP_SETSOCKOPT_ERROR _MD_unix_map_setsockopt_error - -extern void _MD_unix_map_open_error(int err); -#define _PR_MD_MAP_OPEN_ERROR _MD_unix_map_open_error - -extern void _MD_unix_map_mmap_error(int err); -#define _PR_MD_MAP_MMAP_ERROR _MD_unix_map_mmap_error - -extern void _MD_unix_map_gethostname_error(int err); -#define _PR_MD_MAP_GETHOSTNAME_ERROR _MD_unix_map_gethostname_error - -extern void _MD_unix_map_select_error(int err); -#define _PR_MD_MAP_SELECT_ERROR _MD_unix_map_select_error - -extern void _MD_unix_map_poll_error(int err); -#define _PR_MD_MAP_POLL_ERROR _MD_unix_map_poll_error - -extern void _MD_unix_map_poll_revents_error(int err); -#define _PR_MD_MAP_POLL_REVENTS_ERROR _MD_unix_map_poll_revents_error - -extern void _MD_unix_map_flock_error(int err); -#define _PR_MD_MAP_FLOCK_ERROR _MD_unix_map_flock_error - -extern void _MD_unix_map_lockf_error(int err); -#define _PR_MD_MAP_LOCKF_ERROR _MD_unix_map_lockf_error - -PR_END_EXTERN_C - -#endif /* prunixerrors_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unixos.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unixos.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unixos.h 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unixos.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,618 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prunixos_h___ -#define prunixos_h___ - -/* - * If FD_SETSIZE is not defined on the command line, set the default value - * before include select.h - */ -/* - * Linux: FD_SETSIZE is defined in /usr/include/sys/select.h and should - * not be redefined. - */ -#if !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__) \ - && !defined(DARWIN) -#ifndef FD_SETSIZE -#define FD_SETSIZE 4096 -#endif -#endif - -#include -#include -#include -#include -#include - -#include "prio.h" -#include "prmem.h" -#include "prclist.h" - -/* - * For select(), fd_set, and struct timeval. - * - * In The Single UNIX(R) Specification, Version 2, - * the header file for select() is . - * In Version 3, the header file for select() is - * changed to . - * - * fd_set is defined in . Usually - * includes , but on some - * older systems does not include - * , so we include it explicitly. - */ -#include -#include -#if defined(AIX) || defined(SYMBIAN) -#include -#endif - -#ifndef SYMBIAN -#define HAVE_NETINET_TCP_H -#endif - -#define _PR_HAVE_O_APPEND - -#define PR_DIRECTORY_SEPARATOR '/' -#define PR_DIRECTORY_SEPARATOR_STR "/" -#define PR_PATH_SEPARATOR ':' -#define PR_PATH_SEPARATOR_STR ":" -typedef int (*FARPROC)(); - -/* - * intervals at which GLOBAL threads wakeup to check for pending interrupt - */ -#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 -extern PRIntervalTime intr_timeout_ticks; - -/* - * The bit flags for the in_flags and out_flags fields - * of _PR_UnixPollDesc - */ -#ifdef _PR_USE_POLL -#define _PR_UNIX_POLL_READ POLLIN -#define _PR_UNIX_POLL_WRITE POLLOUT -#define _PR_UNIX_POLL_EXCEPT POLLPRI -#define _PR_UNIX_POLL_ERR POLLERR -#define _PR_UNIX_POLL_NVAL POLLNVAL -#define _PR_UNIX_POLL_HUP POLLHUP -#else /* _PR_USE_POLL */ -#define _PR_UNIX_POLL_READ 0x1 -#define _PR_UNIX_POLL_WRITE 0x2 -#define _PR_UNIX_POLL_EXCEPT 0x4 -#define _PR_UNIX_POLL_ERR 0x8 -#define _PR_UNIX_POLL_NVAL 0x10 -#define _PR_UNIX_POLL_HUP 0x20 -#endif /* _PR_USE_POLL */ - -typedef struct _PRUnixPollDesc { - PRInt32 osfd; - PRInt16 in_flags; - PRInt16 out_flags; -} _PRUnixPollDesc; - -typedef struct PRPollQueue { - PRCList links; /* for linking PRPollQueue's together */ - _PRUnixPollDesc *pds; /* array of poll descriptors */ - PRUintn npds; /* length of the array */ - PRPackedBool on_ioq; /* is this on the async i/o work q? */ - PRIntervalTime timeout; /* timeout, in ticks */ - struct PRThread *thr; -} PRPollQueue; - -#define _PR_POLLQUEUE_PTR(_qp) \ - ((PRPollQueue*) ((char*) (_qp) - offsetof(PRPollQueue,links))) - - -extern PRInt32 _PR_WaitForMultipleFDs( - _PRUnixPollDesc *unixpds, - PRInt32 pdcnt, - PRIntervalTime timeout); -extern void _PR_Unblock_IO_Wait(struct PRThread *thr); - -#if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY) -#define _MD_CHECK_FOR_EXIT() -#endif - -extern fd_set _pr_md_read_set, _pr_md_write_set, _pr_md_exception_set; -extern PRInt16 _pr_md_read_cnt[], _pr_md_write_cnt[], _pr_md_exception_cnt[]; -extern PRInt32 _pr_md_ioq_max_osfd; -extern PRUint32 _pr_md_ioq_timeout; - -struct _MDFileDesc { - int osfd; -#if defined(LINUX) && defined(_PR_PTHREADS) - int tcp_nodelay; /* used by pt_LinuxSendFile */ -#endif -}; - -struct _MDDir { - DIR *d; -}; - -struct _PRCPU; -extern void _MD_unix_init_running_cpu(struct _PRCPU *cpu); - -/* -** Make a redzone at both ends of the stack segment. Disallow access -** to those pages of memory. It's ok if the mprotect call's don't -** work - it just means that we don't really have a functional -** redzone. -*/ -#include -#ifndef PROT_NONE -#define PROT_NONE 0x0 -#endif - -#if defined(DEBUG) && !defined(DARWIN) -#if !defined(SOLARIS) -#include /* for memset() */ -#define _MD_INIT_STACK(ts,REDZONE) \ - PR_BEGIN_MACRO \ - (void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE); \ - (void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\ - REDZONE, PROT_NONE); \ - /* \ - ** Fill stack memory with something that turns into an illegal \ - ** pointer value. This will sometimes find runtime references to \ - ** uninitialized pointers. We don't do this for solaris because we \ - ** can use purify instead. \ - */ \ - if (_pr_debugStacks) { \ - memset(ts->allocBase + REDZONE, 0xf7, ts->stackSize); \ - } \ - PR_END_MACRO -#else /* !SOLARIS */ -#define _MD_INIT_STACK(ts,REDZONE) \ - PR_BEGIN_MACRO \ - (void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE); \ - (void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\ - REDZONE, PROT_NONE); \ - PR_END_MACRO -#endif /* !SOLARIS */ - -/* - * _MD_CLEAR_STACK - * Allow access to the redzone pages; the access was turned off in - * _MD_INIT_STACK. - */ -#define _MD_CLEAR_STACK(ts) \ - PR_BEGIN_MACRO \ - (void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_READ|PROT_WRITE);\ - (void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\ - REDZONE, PROT_READ|PROT_WRITE); \ - PR_END_MACRO - -#else /* DEBUG */ - -#define _MD_INIT_STACK(ts,REDZONE) -#define _MD_CLEAR_STACK(ts) - -#endif /* DEBUG */ - -#if !defined(SOLARIS) - -#define PR_SET_INTSOFF(newval) - -#endif - -/************************************************************************/ - -extern void _PR_UnixInit(void); - -extern void _PR_UnixCleanup(void); -#define _MD_EARLY_CLEANUP _PR_UnixCleanup - -/************************************************************************/ - -struct _MDProcess { - pid_t pid; -}; - -struct PRProcess; -struct PRProcessAttr; - -/* Create a new process (fork() + exec()) */ -#define _MD_CREATE_PROCESS _MD_CreateUnixProcess -extern struct PRProcess * _MD_CreateUnixProcess( - const char *path, - char *const *argv, - char *const *envp, - const struct PRProcessAttr *attr -); - -#define _MD_DETACH_PROCESS _MD_DetachUnixProcess -extern PRStatus _MD_DetachUnixProcess(struct PRProcess *process); - -/* Wait for a child process to terminate */ -#define _MD_WAIT_PROCESS _MD_WaitUnixProcess -extern PRStatus _MD_WaitUnixProcess(struct PRProcess *process, - PRInt32 *exitCode); - -#define _MD_KILL_PROCESS _MD_KillUnixProcess -extern PRStatus _MD_KillUnixProcess(struct PRProcess *process); - -/************************************************************************/ - -extern void _MD_EnableClockInterrupts(void); -extern void _MD_DisableClockInterrupts(void); - -#define _MD_START_INTERRUPTS _MD_StartInterrupts -#define _MD_STOP_INTERRUPTS _MD_StopInterrupts -#define _MD_DISABLE_CLOCK_INTERRUPTS _MD_DisableClockInterrupts -#define _MD_ENABLE_CLOCK_INTERRUPTS _MD_EnableClockInterrupts -#define _MD_BLOCK_CLOCK_INTERRUPTS _MD_BlockClockInterrupts -#define _MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UnblockClockInterrupts - -/************************************************************************/ - -extern void _MD_InitCPUS(void); -#define _MD_INIT_CPUS _MD_InitCPUS - -extern void _MD_Wakeup_CPUs(void); -#define _MD_WAKEUP_CPUS _MD_Wakeup_CPUs - -#define _MD_PAUSE_CPU _MD_PauseCPU - -#if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY) -#define _MD_CLEANUP_BEFORE_EXIT() -#endif - -#ifndef IRIX -#define _MD_EXIT(status) _exit(status) -#endif - -/************************************************************************/ - -#define _MD_GET_ENV getenv -#define _MD_PUT_ENV putenv - -/************************************************************************/ - -#define _MD_INIT_FILEDESC(fd) - -extern void _MD_MakeNonblock(PRFileDesc *fd); -#define _MD_MAKE_NONBLOCK _MD_MakeNonblock - -/************************************************************************/ - -#if !defined(_PR_PTHREADS) - -extern void _MD_InitSegs(void); -extern PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, - void *vaddr); -extern void _MD_FreeSegment(PRSegment *seg); - -#define _MD_INIT_SEGS _MD_InitSegs -#define _MD_ALLOC_SEGMENT _MD_AllocSegment -#define _MD_FREE_SEGMENT _MD_FreeSegment - -#endif /* !defined(_PR_PTHREADS) */ - -/************************************************************************/ - -#ifdef _MD_INTERVAL_USE_GTOD -extern PRIntervalTime _PR_UNIX_GetInterval(void); -extern PRIntervalTime _PR_UNIX_TicksPerSecond(void); -#define _MD_INTERVAL_INIT() -#define _MD_GET_INTERVAL _PR_UNIX_GetInterval -#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond -#endif - -#ifdef HAVE_CLOCK_MONOTONIC -extern PRIntervalTime _PR_UNIX_GetInterval2(void); -extern PRIntervalTime _PR_UNIX_TicksPerSecond2(void); -#define _MD_INTERVAL_INIT() -#define _MD_GET_INTERVAL _PR_UNIX_GetInterval2 -#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond2 -#endif - -#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) -#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) - -/************************************************************************/ - -#define _MD_ERRNO() (errno) -#define _MD_GET_SOCKET_ERROR() (errno) - -/************************************************************************/ - -extern PRInt32 _MD_AvailableSocket(PRInt32 osfd); - -extern void _MD_StartInterrupts(void); -extern void _MD_StopInterrupts(void); -extern void _MD_DisableClockInterrupts(void); -extern void _MD_BlockClockInterrupts(void); -extern void _MD_UnblockClockInterrupts(void); -extern void _MD_PauseCPU(PRIntervalTime timeout); - -extern PRStatus _MD_open_dir(struct _MDDir *, const char *); -extern PRInt32 _MD_close_dir(struct _MDDir *); -extern char * _MD_read_dir(struct _MDDir *, PRIntn); -extern PRInt32 _MD_open(const char *name, PRIntn osflags, PRIntn mode); -extern PRInt32 _MD_delete(const char *name); -extern PRInt32 _MD_getfileinfo(const char *fn, PRFileInfo *info); -extern PRInt32 _MD_getfileinfo64(const char *fn, PRFileInfo64 *info); -extern PRInt32 _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info); -extern PRInt32 _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info); -extern PRInt32 _MD_rename(const char *from, const char *to); -extern PRInt32 _MD_access(const char *name, PRAccessHow how); -extern PRInt32 _MD_mkdir(const char *name, PRIntn mode); -extern PRInt32 _MD_rmdir(const char *name); -extern PRInt32 _MD_accept_read(PRInt32 sock, PRInt32 *newSock, - PRNetAddr **raddr, void *buf, PRInt32 amount); -extern PRInt32 _PR_UnixSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout); - -extern PRStatus _MD_LockFile(PRInt32 osfd); -extern PRStatus _MD_TLockFile(PRInt32 osfd); -extern PRStatus _MD_UnlockFile(PRInt32 osfd); - -#define _MD_OPEN_DIR(dir, name) _MD_open_dir(dir, name) -#define _MD_CLOSE_DIR(dir) _MD_close_dir(dir) -#define _MD_READ_DIR(dir, flags) _MD_read_dir(dir, flags) -#define _MD_OPEN(name, osflags, mode) _MD_open(name, osflags, mode) -#define _MD_OPEN_FILE(name, osflags, mode) _MD_open(name, osflags, mode) -extern PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount); -#define _MD_READ(fd,buf,amount) _MD_read(fd,buf,amount) -extern PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount); -#define _MD_WRITE(fd,buf,amount) _MD_write(fd,buf,amount) -#define _MD_DELETE(name) _MD_delete(name) -#define _MD_GETFILEINFO(fn, info) _MD_getfileinfo(fn, info) -#define _MD_GETFILEINFO64(fn, info) _MD_getfileinfo64(fn, info) -#define _MD_GETOPENFILEINFO(fd, info) _MD_getopenfileinfo(fd, info) -#define _MD_GETOPENFILEINFO64(fd, info) _MD_getopenfileinfo64(fd, info) -#define _MD_RENAME(from, to) _MD_rename(from, to) -#define _MD_ACCESS(name, how) _MD_access(name, how) -#define _MD_MKDIR(name, mode) _MD_mkdir(name, mode) -#define _MD_MAKE_DIR(name, mode) _MD_mkdir(name, mode) -#define _MD_RMDIR(name) _MD_rmdir(name) -#define _MD_ACCEPT_READ(sock, newSock, raddr, buf, amount) _MD_accept_read(sock, newSock, raddr, buf, amount) - -#define _MD_LOCKFILE _MD_LockFile -#define _MD_TLOCKFILE _MD_TLockFile -#define _MD_UNLOCKFILE _MD_UnlockFile - - -extern PRInt32 _MD_socket(int af, int type, int flags); -#define _MD_SOCKET _MD_socket -extern PRInt32 _MD_connect(PRFileDesc *fd, const PRNetAddr *addr, - PRUint32 addrlen, PRIntervalTime timeout); -#define _MD_CONNECT _MD_connect -extern PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, - PRIntervalTime timeout); -#define _MD_ACCEPT _MD_accept -extern PRInt32 _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen); -#define _MD_BIND _MD_bind -extern PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog); -#define _MD_LISTEN _MD_listen -extern PRInt32 _MD_shutdown(PRFileDesc *fd, PRIntn how); -#define _MD_SHUTDOWN _MD_shutdown - -extern PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout); -#define _MD_RECV _MD_recv -extern PRInt32 _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout); -#define _MD_SEND _MD_send -extern PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, - PRIntervalTime timeout); -#define _MD_RECVFROM _MD_recvfrom -extern PRInt32 _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen, - PRIntervalTime timeout); -#define _MD_SENDTO _MD_sendto -extern PRInt32 _MD_writev(PRFileDesc *fd, const struct PRIOVec *iov, - PRInt32 iov_size, PRIntervalTime timeout); -#define _MD_WRITEV _MD_writev - -extern PRInt32 _MD_socketavailable(PRFileDesc *fd); -#define _MD_SOCKETAVAILABLE _MD_socketavailable -extern PRInt64 _MD_socketavailable64(PRFileDesc *fd); -#define _MD_SOCKETAVAILABLE64 _MD_socketavailable64 - -#define _MD_PIPEAVAILABLE _MD_socketavailable - -extern PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, - PRIntervalTime timeout); -#define _MD_PR_POLL _MD_pr_poll - -extern PRInt32 _MD_close(PRInt32 osfd); -#define _MD_CLOSE_FILE _MD_close -extern PRInt32 _MD_lseek(PRFileDesc*, PRInt32, PRSeekWhence); -#define _MD_LSEEK _MD_lseek -extern PRInt64 _MD_lseek64(PRFileDesc*, PRInt64, PRSeekWhence); -#define _MD_LSEEK64 _MD_lseek64 -extern PRInt32 _MD_fsync(PRFileDesc *fd); -#define _MD_FSYNC _MD_fsync - -extern PRInt32 _MD_socketpair(int af, int type, int flags, PRInt32 *osfd); -#define _MD_SOCKETPAIR _MD_socketpair - -#define _MD_CLOSE_SOCKET _MD_close - -#ifndef NO_NSPR_10_SUPPORT -#define _MD_STAT stat -#endif - -extern PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, - PRUint32 *addrlen); -#define _MD_GETPEERNAME _MD_getpeername -extern PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, - PRUint32 *addrlen); -#define _MD_GETSOCKNAME _MD_getsockname - -extern PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, - PRInt32 optname, char* optval, PRInt32* optlen); -#define _MD_GETSOCKOPT _MD_getsockopt -extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, - PRInt32 optname, const char* optval, PRInt32 optlen); -#define _MD_SETSOCKOPT _MD_setsockopt - -extern PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable); -#define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable - -extern void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported); -#define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable - -extern void _MD_query_fd_inheritable(PRFileDesc *fd); -#define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable - -extern PRStatus _MD_gethostname(char *name, PRUint32 namelen); -#define _MD_GETHOSTNAME _MD_gethostname - -extern PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen); -#define _MD_GETSYSINFO _MD_getsysinfo - -extern int _MD_unix_get_nonblocking_connect_error(int osfd); - -/* Memory-mapped files */ - -struct _MDFileMap { - PRIntn prot; - PRIntn flags; - PRBool isAnonFM; /* when true, PR_CloseFileMap() must close the related fd */ -}; - -extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); -#define _MD_CREATE_FILE_MAP _MD_CreateFileMap - -#define _MD_GET_MEM_MAP_ALIGNMENT() PR_GetPageSize() - -extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, - PRUint32 len); -#define _MD_MEM_MAP _MD_MemMap - -extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); -#define _MD_MEM_UNMAP _MD_MemUnmap - -extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); -#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap - -/* - * The standard (XPG4) gettimeofday() (from BSD) takes two arguments. - * On some SVR4 derivatives, gettimeofday() takes only one argument. - * The GETTIMEOFDAY macro is intended to hide this difference. - */ -#ifdef HAVE_SVID_GETTOD -#define GETTIMEOFDAY(tp) gettimeofday(tp) -#else -#define GETTIMEOFDAY(tp) gettimeofday((tp), NULL) -#endif - -#if defined(_PR_PTHREADS) && !defined(_PR_POLL_AVAILABLE) -#define _PR_NEED_FAKE_POLL -#endif - -#if defined(_PR_NEED_FAKE_POLL) - -/* - * Some platforms don't have poll(), but our pthreads code calls poll(). - * As a temporary measure, I implemented a fake poll() using select(). - * Here are the struct and macro definitions copied from sys/poll.h - * on Solaris 2.5. - */ - -struct pollfd { - int fd; - short events; - short revents; -}; - -/* poll events */ - -#define POLLIN 0x0001 /* fd is readable */ -#define POLLPRI 0x0002 /* high priority info at fd */ -#define POLLOUT 0x0004 /* fd is writeable (won't block) */ -#define POLLRDNORM 0x0040 /* normal data is readable */ -#define POLLWRNORM POLLOUT -#define POLLRDBAND 0x0080 /* out-of-band data is readable */ -#define POLLWRBAND 0x0100 /* out-of-band data is writeable */ - -#define POLLNORM POLLRDNORM - -#define POLLERR 0x0008 /* fd has error condition */ -#define POLLHUP 0x0010 /* fd has been hung up on */ -#define POLLNVAL 0x0020 /* invalid pollfd entry */ - -extern int poll(struct pollfd *, unsigned long, int); - -#endif /* _PR_NEED_FAKE_POLL */ - -/* -** A vector of the UNIX I/O calls we use. These are here to smooth over -** the rough edges needed for large files. All of NSPR's implmentaions -** go through this vector using syntax of the form -** result = _md_iovector.xxx64(args); -*/ - -#if defined(SOLARIS2_5) -/* -** Special case: Solaris 2.5.1 -** Solaris starts to have 64-bit file I/O in 2.6. We build on Solaris -** 2.5.1 so that we can use the same binaries on both Solaris 2.5.1 and -** 2.6. At run time, we detect whether 64-bit file I/O is available by -** looking up the 64-bit file function symbols in libc. At build time, -** we need to define the 64-bit file I/O datatypes that are compatible -** with their definitions on Solaris 2.6. -*/ -typedef PRInt64 off64_t; -typedef PRUint64 ino64_t; -typedef PRInt64 blkcnt64_t; -struct stat64 { - dev_t st_dev; - long st_pad1[3]; - ino64_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - long t_pad2[2]; - off64_t st_size; - timestruc_t st_atim; - timestruc_t st_mtim; - timestruc_t st_ctim; - long st_blksize; - blkcnt64_t st_blocks; - char st_fstype[_ST_FSTYPSZ]; - long st_pad4[8]; -}; -typedef struct stat64 _MDStat64; -typedef off64_t _MDOff64_t; - -#elif defined(_PR_HAVE_OFF64_T) -typedef struct stat64 _MDStat64; -typedef off64_t _MDOff64_t; -#elif defined(_PR_HAVE_LARGE_OFF_T) -typedef struct stat _MDStat64; -typedef off_t _MDOff64_t; -#elif defined(_PR_NO_LARGE_FILES) -typedef struct stat _MDStat64; -typedef PRInt64 _MDOff64_t; -#else -#error "I don't know yet" -#endif - -typedef PRIntn (*_MD_Fstat64)(PRIntn osfd, _MDStat64 *buf); -typedef PRIntn (*_MD_Open64)(const char *path, int oflag, ...); -typedef PRIntn (*_MD_Stat64)(const char *path, _MDStat64 *buf); -typedef _MDOff64_t (*_MD_Lseek64)(PRIntn osfd, _MDOff64_t, PRIntn whence); -typedef void* (*_MD_Mmap64)( - void *addr, PRSize len, PRIntn prot, PRIntn flags, - PRIntn fildes, _MDOff64_t offset); -struct _MD_IOVector -{ - _MD_Open64 _open64; - _MD_Mmap64 _mmap64; - _MD_Stat64 _stat64; - _MD_Fstat64 _fstat64; - _MD_Lseek64 _lseek64; -}; -extern struct _MD_IOVector _md_iovector; - -#endif /* prunixos_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unixware7.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unixware7.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unixware7.cfg 2012-03-06 13:13:54.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unixware7.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef UNIXWARE -#define UNIXWARE -#endif - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_AF_INET6 27 /* same as AF_INET6 */ - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#define _PR_POLL_BACKCOMPAT - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unixware.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unixware.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unixware.cfg 2012-03-06 13:13:54.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unixware.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_UNIX -#define XP_UNIX -#endif - -#ifndef UNIXWARE -#define UNIXWARE -#endif - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#undef HAVE_LONG_LONG -#undef HAVE_ALIGNED_DOUBLES -#undef HAVE_ALIGNED_LONGLONGS - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_DOUBLE 8 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_DOUBLE 64 -#define PR_BITS_PER_WORD 32 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_DOUBLE_LOG2 6 -#define PR_BITS_PER_WORD_LOG2 5 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 4 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#define _PR_POLL_BACKCOMPAT - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unixware.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unixware.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_unixware.h 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_unixware.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,186 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_unixware_defs_h___ -#define nspr_unixware_defs_h___ - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "unixware" -#define _PR_SI_SYSNAME "UnixWare" -#define _PR_SI_ARCHITECTURE "x86" -#define PR_DLL_SUFFIX ".so" - -#define _PR_VMBASE 0x30000000 -#define _PR_STACK_VMBASE 0x50000000 -#define _MD_DEFAULT_STACK_SIZE 65536L -#define _MD_MMAP_FLAGS MAP_PRIVATE - -#ifndef HAVE_WEAK_IO_SYMBOLS -#define HAVE_WEAK_IO_SYMBOLS -#endif -#define _PR_POLL_AVAILABLE -#define _PR_USE_POLL -#define _PR_STAT_HAS_ST_ATIM_UNION - -#undef HAVE_STACK_GROWING_UP -#define HAVE_NETCONFIG -#define HAVE_DLL -#define USE_DLFCN -#define HAVE_STRERROR -#define NEED_STRFTIME_LOCK -#define NEED_TIME_R -#define _PR_NEED_STRCASECMP - -#define USE_SETJMP - -#include - -#define _SETJMP setjmp -#define _LONGJMP longjmp -#define _PR_CONTEXT_TYPE jmp_buf -#define _MD_GET_SP(_t) (_t)->md.context[4] -#define _PR_NUM_GCREGS _JBLEN - -#define CONTEXT(_th) ((_th)->md.context) - -/* -** Initialize the thread context preparing it to execute _main. -*/ -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ -{ \ - *status = PR_TRUE; \ - if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ - _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ -} - -#define _MD_SWITCH_CONTEXT(_thread) \ - if (!_SETJMP(CONTEXT(_thread))) { \ - (_thread)->md.errcode = errno; \ - _PR_Schedule(); \ - } - -/* -** Restore a thread context, saved by _MD_SWITCH_CONTEXT -*/ -#define _MD_RESTORE_CONTEXT(_thread) \ -{ \ - errno = (_thread)->md.errcode; \ - _MD_SET_CURRENT_THREAD(_thread); \ - _LONGJMP(CONTEXT(_thread), 1); \ -} - -/* Machine-dependent (MD) data structures. - * Don't use SVR4 native threads (yet). - */ - -struct _MDThread { - _PR_CONTEXT_TYPE context; - int id; - int errcode; -}; - -struct _MDThreadStack { - PRInt8 notused; -}; - -struct _MDLock { - PRInt8 notused; -}; - -struct _MDSemaphore { - PRInt8 notused; -}; - -struct _MDCVar { - PRInt8 notused; -}; - -struct _MDSegment { - PRInt8 notused; -}; - -/* - * md-specific cpu structure field - */ -#define _PR_MD_MAX_OSFD FD_SETSIZE - -struct _MDCPU_Unix { - PRCList ioQ; - PRUint32 ioq_timeout; - PRInt32 ioq_max_osfd; - PRInt32 ioq_osfd_cnt; -#ifndef _PR_USE_POLL - fd_set fd_read_set, fd_write_set, fd_exception_set; - PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], - fd_exception_cnt[_PR_MD_MAX_OSFD]; -#else - struct pollfd *ioq_pollfds; - int ioq_pollfds_size; -#endif /* _PR_USE_POLL */ -}; - -#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) -#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) -#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) -#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) -#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) -#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) -#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) -#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) -#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) -#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) -#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) -#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) -#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) - -#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 - -struct _MDCPU { - struct _MDCPU_Unix md_unix; -}; - -#define _MD_INIT_LOCKS() -#define _MD_NEW_LOCK(lock) PR_SUCCESS -#define _MD_FREE_LOCK(lock) -#define _MD_LOCK(lock) -#define _MD_UNLOCK(lock) -#define _MD_INIT_IO() -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - -/* - * The following are copied from _sunos.h, _aix.h. This means - * some of them should probably be moved into _unixos.h. But - * _irix.h seems to be quite different in regard to these macros. - */ -#define _MD_INTERVAL_USE_GTOD - -#define _MD_EARLY_INIT _MD_EarlyInit -#define _MD_FINAL_INIT _PR_UnixInit -#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) -#define _MD_INIT_THREAD _MD_InitializeThread -#define _MD_EXIT_THREAD(thread) -#define _MD_SUSPEND_THREAD(thread) -#define _MD_RESUME_THREAD(thread) -#define _MD_CLEAN_THREAD(_thread) - -/* - * We wrapped the select() call. _MD_SELECT refers to the built-in, - * unwrapped version. - */ -#include -#include -#include -extern int _select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *execptfds, struct timeval *timeout); -#define _MD_SELECT _select - -#define _MD_POLL _poll -extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); - -#endif /* nspr_unixware_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_win32_errors.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_win32_errors.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_win32_errors.h 2012-03-06 13:13:54.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_win32_errors.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_win32_errors_h___ -#define nspr_win32_errors_h___ - -#include -#include -#include - - -extern void _MD_win32_map_default_error(PRInt32 err); -#define _PR_MD_MAP_DEFAULT_ERROR _MD_win32_map_default_error - -extern void _MD_win32_map_opendir_error(PRInt32 err); -#define _PR_MD_MAP_OPENDIR_ERROR _MD_win32_map_opendir_error - -extern void _MD_win32_map_closedir_error(PRInt32 err); -#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_win32_map_closedir_error - -extern void _MD_unix_readdir_error(PRInt32 err); -#define _PR_MD_MAP_READDIR_ERROR _MD_unix_readdir_error - -extern void _MD_win32_map_delete_error(PRInt32 err); -#define _PR_MD_MAP_DELETE_ERROR _MD_win32_map_delete_error - -extern void _MD_win32_map_stat_error(PRInt32 err); -#define _PR_MD_MAP_STAT_ERROR _MD_win32_map_stat_error - -extern void _MD_win32_map_fstat_error(PRInt32 err); -#define _PR_MD_MAP_FSTAT_ERROR _MD_win32_map_fstat_error - -extern void _MD_win32_map_rename_error(PRInt32 err); -#define _PR_MD_MAP_RENAME_ERROR _MD_win32_map_rename_error - -extern void _MD_win32_map_access_error(PRInt32 err); -#define _PR_MD_MAP_ACCESS_ERROR _MD_win32_map_access_error - -extern void _MD_win32_map_mkdir_error(PRInt32 err); -#define _PR_MD_MAP_MKDIR_ERROR _MD_win32_map_mkdir_error - -extern void _MD_win32_map_rmdir_error(PRInt32 err); -#define _PR_MD_MAP_RMDIR_ERROR _MD_win32_map_rmdir_error - -extern void _MD_win32_map_read_error(PRInt32 err); -#define _PR_MD_MAP_READ_ERROR _MD_win32_map_read_error - -extern void _MD_win32_map_transmitfile_error(PRInt32 err); -#define _PR_MD_MAP_TRANSMITFILE_ERROR _MD_win32_map_transmitfile_error - -extern void _MD_win32_map_write_error(PRInt32 err); -#define _PR_MD_MAP_WRITE_ERROR _MD_win32_map_write_error - -extern void _MD_win32_map_lseek_error(PRInt32 err); -#define _PR_MD_MAP_LSEEK_ERROR _MD_win32_map_lseek_error - -extern void _MD_win32_map_fsync_error(PRInt32 err); -#define _PR_MD_MAP_FSYNC_ERROR _MD_win32_map_fsync_error - -extern void _MD_win32_map_close_error(PRInt32 err); -#define _PR_MD_MAP_CLOSE_ERROR _MD_win32_map_close_error - -extern void _MD_win32_map_socket_error(PRInt32 err); -#define _PR_MD_MAP_SOCKET_ERROR _MD_win32_map_socket_error - -extern void _MD_win32_map_recv_error(PRInt32 err); -#define _PR_MD_MAP_RECV_ERROR _MD_win32_map_recv_error - -extern void _MD_win32_map_recvfrom_error(PRInt32 err); -#define _PR_MD_MAP_RECVFROM_ERROR _MD_win32_map_recvfrom_error - -extern void _MD_win32_map_send_error(PRInt32 err); -#define _PR_MD_MAP_SEND_ERROR _MD_win32_map_send_error - -extern void _MD_win32_map_sendto_error(PRInt32 err); -#define _PR_MD_MAP_SENDTO_ERROR _MD_win32_map_sendto_error - -extern void _MD_win32_map_accept_error(PRInt32 err); -#define _PR_MD_MAP_ACCEPT_ERROR _MD_win32_map_accept_error - -extern void _MD_win32_map_acceptex_error(PRInt32 err); -#define _PR_MD_MAP_ACCEPTEX_ERROR _MD_win32_map_acceptex_error - -extern PRInt32 _MD_win32_map_connect_error(PRInt32 err); -#define _PR_MD_MAP_CONNECT_ERROR _MD_win32_map_connect_error - -extern void _MD_win32_map_bind_error(PRInt32 err); -#define _PR_MD_MAP_BIND_ERROR _MD_win32_map_bind_error - -extern void _MD_win32_map_listen_error(PRInt32 err); -#define _PR_MD_MAP_LISTEN_ERROR _MD_win32_map_listen_error - -extern void _MD_win32_map_shutdown_error(PRInt32 err); -#define _PR_MD_MAP_SHUTDOWN_ERROR _MD_win32_map_shutdown_error - -extern void _MD_win32_map_getsockname_error(PRInt32 err); -#define _PR_MD_MAP_GETSOCKNAME_ERROR _MD_win32_map_getsockname_error - -extern void _MD_win32_map_getpeername_error(PRInt32 err); -#define _PR_MD_MAP_GETPEERNAME_ERROR _MD_win32_map_getpeername_error - -extern void _MD_win32_map_getsockopt_error(PRInt32 err); -#define _PR_MD_MAP_GETSOCKOPT_ERROR _MD_win32_map_getsockopt_error - -extern void _MD_win32_map_setsockopt_error(PRInt32 err); -#define _PR_MD_MAP_SETSOCKOPT_ERROR _MD_win32_map_setsockopt_error - -extern void _MD_win32_map_open_error(PRInt32 err); -#define _PR_MD_MAP_OPEN_ERROR _MD_win32_map_open_error - -extern void _MD_win32_map_gethostname_error(PRInt32 err); -#define _PR_MD_MAP_GETHOSTNAME_ERROR _MD_win32_map_gethostname_error - -extern void _MD_win32_map_select_error(PRInt32 err); -#define _PR_MD_MAP_SELECT_ERROR _MD_win32_map_select_error - -extern void _MD_win32_map_lockf_error(int err); -#define _PR_MD_MAP_LOCKF_ERROR _MD_win32_map_lockf_error - -#endif /* nspr_win32_errors_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_win95.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_win95.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_win95.cfg 2012-03-06 13:13:54.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_win95.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,278 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_PC -#define XP_PC -#endif - -#ifndef WIN32 -#define WIN32 -#endif - -#ifdef _WIN32_WCE -#ifndef WINCE -#define WINCE -#endif -#else -#ifndef WIN95 -#define WIN95 -#endif -#endif - -#define PR_AF_INET6 23 /* same as AF_INET6 */ - -#if defined(_M_IX86) || defined(_X86_) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_DOUBLE 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_WORD 32 -#define PR_BITS_PER_DWORD 64 -#define PR_BITS_PER_DOUBLE 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_WORD_LOG2 5 -#define PR_BITS_PER_DWORD_LOG2 6 -#define PR_BITS_PER_DOUBLE_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_WORD 4 -#define PR_ALIGN_OF_DWORD 8 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_DOUBLE 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_WORD 64 -#define PR_BITS_PER_DWORD 64 -#define PR_BITS_PER_DOUBLE 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_WORD_LOG2 6 -#define PR_BITS_PER_DWORD_LOG2 6 -#define PR_BITS_PER_DOUBLE_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_WORD 8 -#define PR_ALIGN_OF_DWORD 8 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(_M_IA64) || defined(_IA64_) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_DOUBLE 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_WORD 64 -#define PR_BITS_PER_DWORD 64 -#define PR_BITS_PER_DOUBLE 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_WORD_LOG2 6 -#define PR_BITS_PER_DWORD_LOG2 6 -#define PR_BITS_PER_DOUBLE_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_WORD 8 -#define PR_ALIGN_OF_DWORD 8 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(_M_ARM) || defined(_ARM_) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_DOUBLE 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_WORD 32 -#define PR_BITS_PER_DWORD 64 -#define PR_BITS_PER_DOUBLE 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_WORD_LOG2 5 -#define PR_BITS_PER_DWORD_LOG2 6 -#define PR_BITS_PER_DOUBLE_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_WORD 4 -#define PR_ALIGN_OF_DWORD 8 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#else /* defined(_M_IX86) || defined(_X86_) */ - -#error unknown processor architecture - -#endif /* defined(_M_IX86) || defined(_X86_) */ - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_win95.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_win95.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_win95.h 2012-05-26 00:15:23.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_win95.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,539 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_win95_defs_h___ -#define nspr_win95_defs_h___ - -#include "prio.h" - -#include -#include -#include - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "win32" -#define _PR_SI_SYSNAME "WIN95" -#if defined(_M_IX86) || defined(_X86_) -#define _PR_SI_ARCHITECTURE "x86" -#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) -#define _PR_SI_ARCHITECTURE "x86-64" -#elif defined(_M_IA64) || defined(_IA64_) -#define _PR_SI_ARCHITECTURE "ia64" -#elif defined(_M_ARM) || defined(_ARM_) -#define _PR_SI_ARCHITECTURE "arm" -#else -#error unknown processor architecture -#endif - -#define HAVE_DLL -#undef HAVE_THREAD_AFFINITY -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE -#ifndef _PR_INET6 -#define AF_INET6 23 -/* newer ws2tcpip.h provides these */ -#ifndef AI_CANONNAME -#define AI_CANONNAME 0x2 -#define AI_NUMERICHOST 0x4 -#define NI_NUMERICHOST 0x02 -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - char *ai_canonname; - struct sockaddr *ai_addr; - struct addrinfo *ai_next; -}; -#endif -#define _PR_HAVE_MD_SOCKADDR_IN6 -/* isomorphic to struct in6_addr on Windows */ -struct _md_in6_addr { - union { - PRUint8 _S6_u8[16]; - PRUint16 _S6_u16[8]; - } _S6_un; -}; -/* isomorphic to struct sockaddr_in6 on Windows */ -struct _md_sockaddr_in6 { - PRInt16 sin6_family; - PRUint16 sin6_port; - PRUint32 sin6_flowinfo; - struct _md_in6_addr sin6_addr; - PRUint32 sin6_scope_id; -}; -#endif -#define _PR_HAVE_THREADSAFE_GETHOST -#define _PR_HAVE_ATOMIC_OPS -#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY - -/* --- Common User-Thread/Native-Thread Definitions --------------------- */ - -/* --- Globals --- */ -extern struct PRLock *_pr_schedLock; - -/* --- Typedefs --- */ -typedef void (*FiberFunc)(void *); - -#define PR_NUM_GCREGS 8 -typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS]; -#define GC_VMBASE 0x40000000 -#define GC_VMLIMIT 0x00FFFFFF - -#define _MD_MAGIC_THREAD 0x22222222 -#define _MD_MAGIC_THREADSTACK 0x33333333 -#define _MD_MAGIC_SEGMENT 0x44444444 -#define _MD_MAGIC_DIR 0x55555555 -#define _MD_MAGIC_CV 0x66666666 - -struct _MDCPU { - int unused; -}; - -struct _MDThread { - HANDLE blocked_sema; /* Threads block on this when waiting - * for IO or CondVar. - */ - PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the - * wait queue of some cond var. - * PR_FALSE otherwise. */ - HANDLE handle; /* Win32 thread handle */ - PRUint32 id; - void *sp; /* only valid when suspended */ - PRUint32 magic; /* for debugging */ - PR_CONTEXT_TYPE gcContext; /* Thread context for GC */ - struct PRThread *prev, *next; /* used by the cvar wait queue to - * chain the PRThread structures - * together */ - void (*start)(void *); /* used by _PR_MD_CREATE_THREAD to - * pass its 'start' argument to - * pr_root. */ -}; - -struct _MDThreadStack { - PRUint32 magic; /* for debugging */ -}; - -struct _MDSegment { - PRUint32 magic; /* for debugging */ -}; - -#undef PROFILE_LOCKS - -struct _MDDir { - HANDLE d_hdl; - WIN32_FIND_DATAA d_entry; - PRBool firstEntry; /* Is this the entry returned - * by FindFirstFile()? */ - PRUint32 magic; /* for debugging */ -}; - -#ifdef MOZ_UNICODE -struct _MDDirUTF16 { - HANDLE d_hdl; - WIN32_FIND_DATAW d_entry; - PRBool firstEntry; /* Is this the entry returned - * by FindFirstFileW()? */ - PRUint32 magic; /* for debugging */ -}; -#endif /* MOZ_UNICODE */ - -struct _MDCVar { - PRUint32 magic; - struct PRThread *waitHead, *waitTail; /* the wait queue: a doubly- - * linked list of threads - * waiting on this condition - * variable */ - PRIntn nwait; /* number of threads in the - * wait queue */ -}; - -#define _MD_CV_NOTIFIED_LENGTH 6 -typedef struct _MDNotified _MDNotified; -struct _MDNotified { - PRIntn length; /* # of used entries in this - * structure */ - struct { - struct _MDCVar *cv; /* the condition variable notified */ - PRIntn times; /* and the number of times notified */ - struct PRThread *notifyHead; /* list of threads to wake up */ - } cv[_MD_CV_NOTIFIED_LENGTH]; - _MDNotified *link; /* link to another of these, or NULL */ -}; - -struct _MDLock { - CRITICAL_SECTION mutex; /* this is recursive on NT */ - - /* - * When notifying cvars, there is no point in actually - * waking up the threads waiting on the cvars until we've - * released the lock. So, we temporarily record the cvars. - * When doing an unlock, we'll then wake up the waiting threads. - */ - struct _MDNotified notified; /* array of conditions notified */ -#ifdef PROFILE_LOCKS - PRInt32 hitcount; - PRInt32 misscount; -#endif -}; - -struct _MDSemaphore { - HANDLE sem; -}; - -struct _MDFileDesc { - PROsfd osfd; /* The osfd can come from one of three spaces: - * - For stdin, stdout, and stderr, we are using - * the libc file handle (0, 1, 2), which is an int. - * - For files and pipes, we are using Win32 HANDLE, - * which is a void*. - * - For sockets, we are using Winsock SOCKET, which - * is a u_int. - */ -}; - -struct _MDProcess { - HANDLE handle; - DWORD id; -}; - -/* --- Misc stuff --- */ -#define _MD_GET_SP(thread) (thread)->md.gcContext[6] - -/* --- NT security stuff --- */ - -extern void _PR_NT_InitSids(void); -extern void _PR_NT_FreeSids(void); -extern PRStatus _PR_NT_MakeSecurityDescriptorACL( - PRIntn mode, - DWORD accessTable[], - PSECURITY_DESCRIPTOR *resultSD, - PACL *resultACL -); -extern void _PR_NT_FreeSecurityDescriptorACL( - PSECURITY_DESCRIPTOR pSD, PACL pACL); - -/* --- IO stuff --- */ - -#define _MD_OPEN _PR_MD_OPEN -#define _MD_OPEN_FILE _PR_MD_OPEN_FILE -#define _MD_READ _PR_MD_READ -#define _MD_WRITE _PR_MD_WRITE -#define _MD_WRITEV _PR_MD_WRITEV -#define _MD_LSEEK _PR_MD_LSEEK -#define _MD_LSEEK64 _PR_MD_LSEEK64 -extern PRInt32 _MD_CloseFile(PROsfd osfd); -#define _MD_CLOSE_FILE _MD_CloseFile -#define _MD_GETFILEINFO _PR_MD_GETFILEINFO -#define _MD_GETFILEINFO64 _PR_MD_GETFILEINFO64 -#define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO -#define _MD_GETOPENFILEINFO64 _PR_MD_GETOPENFILEINFO64 -#define _MD_STAT _PR_MD_STAT -#define _MD_RENAME _PR_MD_RENAME -#define _MD_ACCESS _PR_MD_ACCESS -#define _MD_DELETE _PR_MD_DELETE -#define _MD_MKDIR _PR_MD_MKDIR -#define _MD_MAKE_DIR _PR_MD_MAKE_DIR -#define _MD_RMDIR _PR_MD_RMDIR -#define _MD_LOCKFILE _PR_MD_LOCKFILE -#define _MD_TLOCKFILE _PR_MD_TLOCKFILE -#define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE - -/* --- UTF16 IO stuff --- */ -extern PRBool _pr_useUnicode; -#ifdef MOZ_UNICODE -#define _MD_OPEN_FILE_UTF16 _PR_MD_OPEN_FILE_UTF16 -#define _MD_OPEN_DIR_UTF16 _PR_MD_OPEN_DIR_UTF16 -#define _MD_READ_DIR_UTF16 _PR_MD_READ_DIR_UTF16 -#define _MD_CLOSE_DIR_UTF16 _PR_MD_CLOSE_DIR_UTF16 -#define _MD_GETFILEINFO64_UTF16 _PR_MD_GETFILEINFO64_UTF16 -#endif /* MOZ_UNICODE */ - -/* --- Socket IO stuff --- */ -extern void _PR_MD_InitSockets(void); -extern void _PR_MD_CleanupSockets(void); -#define _MD_EACCES WSAEACCES -#define _MD_EADDRINUSE WSAEADDRINUSE -#define _MD_EADDRNOTAVAIL WSAEADDRNOTAVAIL -#define _MD_EAFNOSUPPORT WSAEAFNOSUPPORT -#define _MD_EAGAIN WSAEWOULDBLOCK -#define _MD_EALREADY WSAEALREADY -#define _MD_EBADF WSAEBADF -#define _MD_ECONNREFUSED WSAECONNREFUSED -#define _MD_ECONNRESET WSAECONNRESET -#define _MD_EFAULT WSAEFAULT -#define _MD_EINPROGRESS WSAEINPROGRESS -#define _MD_EINTR WSAEINTR -#define _MD_EINVAL EINVAL -#define _MD_EISCONN WSAEISCONN -#define _MD_ENETUNREACH WSAENETUNREACH -#define _MD_ENOENT ENOENT -#define _MD_ENOTCONN WSAENOTCONN -#define _MD_ENOTSOCK WSAENOTSOCK -#define _MD_EOPNOTSUPP WSAEOPNOTSUPP -#define _MD_EWOULDBLOCK WSAEWOULDBLOCK -#define _MD_GET_SOCKET_ERROR() WSAGetLastError() -#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err) - -#define _MD_INIT_FILEDESC(fd) -extern void _MD_MakeNonblock(PRFileDesc *f); -#define _MD_MAKE_NONBLOCK _MD_MakeNonblock -#define _MD_INIT_FD_INHERITABLE _PR_MD_INIT_FD_INHERITABLE -#define _MD_QUERY_FD_INHERITABLE _PR_MD_QUERY_FD_INHERITABLE -#define _MD_SHUTDOWN _PR_MD_SHUTDOWN -#define _MD_LISTEN _PR_MD_LISTEN -extern PRInt32 _MD_CloseSocket(PROsfd osfd); -#define _MD_CLOSE_SOCKET _MD_CloseSocket -#define _MD_SENDTO _PR_MD_SENDTO -#define _MD_RECVFROM _PR_MD_RECVFROM -#define _MD_SOCKETPAIR(s, type, proto, sv) -1 -#define _MD_GETSOCKNAME _PR_MD_GETSOCKNAME -#define _MD_GETPEERNAME _PR_MD_GETPEERNAME -#define _MD_GETSOCKOPT _PR_MD_GETSOCKOPT -#define _MD_SETSOCKOPT _PR_MD_SETSOCKOPT -#define _MD_SET_FD_INHERITABLE _PR_MD_SET_FD_INHERITABLE -#define _MD_SELECT select -#define _MD_FSYNC _PR_MD_FSYNC -#define READ_FD 1 -#define WRITE_FD 2 - -#define _MD_INIT_ATOMIC() -#if defined(_M_IX86) || defined(_X86_) -#define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT -#define _MD_ATOMIC_ADD _PR_MD_ATOMIC_ADD -#define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT -#else /* non-x86 processors */ -#define _MD_ATOMIC_INCREMENT(x) InterlockedIncrement((PLONG)x) -#define _MD_ATOMIC_ADD(ptr,val) (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val) -#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x) -#endif /* x86 */ -#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y) - -#define _MD_INIT_IO _PR_MD_INIT_IO - - -/* win95 doesn't have async IO */ -#define _MD_SOCKET _PR_MD_SOCKET -extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd); -#define _MD_SOCKETAVAILABLE _MD_SocketAvailable -#define _MD_PIPEAVAILABLE _PR_MD_PIPEAVAILABLE -#define _MD_CONNECT _PR_MD_CONNECT -extern PROsfd _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, - PRIntervalTime timeout); -#define _MD_ACCEPT _MD_Accept -#define _MD_BIND _PR_MD_BIND -#define _MD_RECV _PR_MD_RECV -#define _MD_SEND _PR_MD_SEND -#define _MD_PR_POLL _PR_MD_PR_POLL - -/* --- Scheduler stuff --- */ -// #define _MD_PAUSE_CPU _PR_MD_PAUSE_CPU -#define _MD_PAUSE_CPU - -/* --- DIR stuff --- */ -#define PR_DIRECTORY_SEPARATOR '\\' -#define PR_DIRECTORY_SEPARATOR_STR "\\" -#define PR_PATH_SEPARATOR ';' -#define PR_PATH_SEPARATOR_STR ";" -#define _MD_ERRNO() GetLastError() -#define _MD_OPEN_DIR _PR_MD_OPEN_DIR -#define _MD_CLOSE_DIR _PR_MD_CLOSE_DIR -#define _MD_READ_DIR _PR_MD_READ_DIR - -/* --- Segment stuff --- */ -#define _MD_INIT_SEGS() -#define _MD_ALLOC_SEGMENT(seg, size, vaddr) 0 -#define _MD_FREE_SEGMENT(seg) - -/* --- Environment Stuff --- */ -#define _MD_GET_ENV _PR_MD_GET_ENV -#define _MD_PUT_ENV _PR_MD_PUT_ENV - -/* --- Threading Stuff --- */ -#define _MD_DEFAULT_STACK_SIZE 0 -#define _MD_INIT_THREAD _PR_MD_INIT_THREAD -#define _MD_INIT_ATTACHED_THREAD _PR_MD_INIT_THREAD -#define _MD_CREATE_THREAD _PR_MD_CREATE_THREAD -#define _MD_YIELD _PR_MD_YIELD -#define _MD_SET_PRIORITY _PR_MD_SET_PRIORITY -#define _MD_SET_CURRENT_THREAD_NAME _PR_MD_SET_CURRENT_THREAD_NAME -#define _MD_CLEAN_THREAD _PR_MD_CLEAN_THREAD -#define _MD_SETTHREADAFFINITYMASK _PR_MD_SETTHREADAFFINITYMASK -#define _MD_GETTHREADAFFINITYMASK _PR_MD_GETTHREADAFFINITYMASK -#define _MD_EXIT_THREAD _PR_MD_EXIT_THREAD -#define _MD_EXIT _PR_MD_EXIT -#define _MD_SUSPEND_THREAD _PR_MD_SUSPEND_THREAD -#define _MD_RESUME_THREAD _PR_MD_RESUME_THREAD -#define _MD_SUSPEND_CPU _PR_MD_SUSPEND_CPU -#define _MD_RESUME_CPU _PR_MD_RESUME_CPU -#define _MD_BEGIN_SUSPEND_ALL() -#define _MD_BEGIN_RESUME_ALL() -#define _MD_END_SUSPEND_ALL() -#define _MD_END_RESUME_ALL() - -/* --- Lock stuff --- */ -#define _PR_LOCK _MD_LOCK -#define _PR_UNLOCK _MD_UNLOCK - -#define _MD_NEW_LOCK(lock) (InitializeCriticalSection(&((lock)->mutex)),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS) -#define _MD_FREE_LOCK(lock) DeleteCriticalSection(&((lock)->mutex)) -#define _MD_LOCK(lock) EnterCriticalSection(&((lock)->mutex)) -#define _MD_TEST_AND_LOCK(lock) (EnterCriticalSection(&((lock)->mutex)),0) -#define _MD_UNLOCK _PR_MD_UNLOCK - -/* --- lock and cv waiting --- */ -#define _MD_WAIT _PR_MD_WAIT -#define _MD_WAKEUP_WAITER _PR_MD_WAKEUP_WAITER - -/* --- CVar ------------------- */ -#define _MD_WAIT_CV _PR_MD_WAIT_CV -#define _MD_NEW_CV _PR_MD_NEW_CV -#define _MD_FREE_CV _PR_MD_FREE_CV -#define _MD_NOTIFY_CV _PR_MD_NOTIFY_CV -#define _MD_NOTIFYALL_CV _PR_MD_NOTIFYALL_CV - - /* XXXMB- the IOQ stuff is certainly not working correctly yet. */ -// extern struct _MDLock _pr_ioq_lock; -#define _MD_IOQ_LOCK() -#define _MD_IOQ_UNLOCK() - - -/* --- Initialization stuff --- */ -#define _MD_START_INTERRUPTS() -#define _MD_STOP_INTERRUPTS() -#define _MD_DISABLE_CLOCK_INTERRUPTS() -#define _MD_ENABLE_CLOCK_INTERRUPTS() -#define _MD_BLOCK_CLOCK_INTERRUPTS() -#define _MD_UNBLOCK_CLOCK_INTERRUPTS() -#define _MD_EARLY_INIT _PR_MD_EARLY_INIT -#define _MD_FINAL_INIT() -#define _MD_EARLY_CLEANUP() -#define _MD_INIT_CPUS() -#define _MD_INIT_RUNNING_CPU(cpu) - -struct PRProcess; -struct PRProcessAttr; - -#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess -extern struct PRProcess * _PR_CreateWindowsProcess( - const char *path, - char *const *argv, - char *const *envp, - const struct PRProcessAttr *attr -); - -#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess -extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process); - -/* --- Wait for a child process to terminate --- */ -#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess -extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, - PRInt32 *exitCode); - -#define _MD_KILL_PROCESS _PR_KillWindowsProcess -extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process); - -#define _MD_CLEANUP_BEFORE_EXIT _PR_MD_CLEANUP_BEFORE_EXIT -#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ - PR_BEGIN_MACRO \ - *status = PR_TRUE; \ - PR_END_MACRO -#define _MD_SWITCH_CONTEXT -#define _MD_RESTORE_CONTEXT - -/* --- Intervals --- */ -#define _MD_INTERVAL_INIT _PR_MD_INTERVAL_INIT -#define _MD_GET_INTERVAL _PR_MD_GET_INTERVAL -#define _MD_INTERVAL_PER_SEC _PR_MD_INTERVAL_PER_SEC -#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) -#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) - -/* --- Time --- */ -extern void _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm); - -#ifdef WINCE -extern void _MD_InitTime(void); -extern void _MD_CleanupTime(void); -#endif - -/* --- Native-Thread Specific Definitions ------------------------------- */ - -extern struct PRThread * _MD_CURRENT_THREAD(void); - -#ifdef _PR_USE_STATIC_TLS -extern __declspec(thread) struct PRThread *_pr_currentThread; -#define _MD_GET_ATTACHED_THREAD() _pr_currentThread -#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread)) - -extern __declspec(thread) struct PRThread *_pr_thread_last_run; -#define _MD_LAST_THREAD() _pr_thread_last_run -#define _MD_SET_LAST_THREAD(_thread) (_pr_thread_last_run = 0) - -extern __declspec(thread) struct _PRCPU *_pr_currentCPU; -#define _MD_CURRENT_CPU() _pr_currentCPU -#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = 0) -#else /* _PR_USE_STATIC_TLS */ -extern DWORD _pr_currentThreadIndex; -#define _MD_GET_ATTACHED_THREAD() ((PRThread *) TlsGetValue(_pr_currentThreadIndex)) -#define _MD_SET_CURRENT_THREAD(_thread) TlsSetValue(_pr_currentThreadIndex, (_thread)) - -extern DWORD _pr_lastThreadIndex; -#define _MD_LAST_THREAD() ((PRThread *) TlsGetValue(_pr_lastThreadIndex)) -#define _MD_SET_LAST_THREAD(_thread) TlsSetValue(_pr_lastThreadIndex, 0) - -extern DWORD _pr_currentCPUIndex; -#define _MD_CURRENT_CPU() ((struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex)) -#define _MD_SET_CURRENT_CPU(_cpu) TlsSetValue(_pr_currentCPUIndex, 0) -#endif /* _PR_USE_STATIC_TLS */ - -/* --- Scheduler stuff --- */ -#define LOCK_SCHEDULER() 0 -#define UNLOCK_SCHEDULER() 0 -#define _PR_LockSched() 0 -#define _PR_UnlockSched() 0 - -/* --- Initialization stuff --- */ -#define _MD_INIT_LOCKS() - -/* --- Stack stuff --- */ -#define _MD_INIT_STACK(stack, redzone) -#define _MD_CLEAR_STACK(stack) - -/* --- Memory-mapped files stuff --- */ - -struct _MDFileMap { - HANDLE hFileMap; - DWORD dwAccess; -}; - -extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); -#define _MD_CREATE_FILE_MAP _MD_CreateFileMap - -extern PRInt32 _MD_GetMemMapAlignment(void); -#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment - -extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, - PRUint32 len); -#define _MD_MEM_MAP _MD_MemMap - -extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); -#define _MD_MEM_UNMAP _MD_MemUnmap - -extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); -#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap - -/* --- Named semaphores stuff --- */ -#define _PR_HAVE_NAMED_SEMAPHORES -#define _MD_OPEN_SEMAPHORE _PR_MD_OPEN_SEMAPHORE -#define _MD_WAIT_SEMAPHORE _PR_MD_WAIT_SEMAPHORE -#define _MD_POST_SEMAPHORE _PR_MD_POST_SEMAPHORE -#define _MD_CLOSE_SEMAPHORE _PR_MD_CLOSE_SEMAPHORE -#define _MD_DELETE_SEMAPHORE(name) PR_SUCCESS /* no op */ - -#endif /* nspr_win32_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_winnt.cfg nspr-4.10.7/mozilla/nsprpub/pr/include/md/_winnt.cfg --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_winnt.cfg 2012-03-06 13:13:55.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_winnt.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef nspr_cpucfg___ -#define nspr_cpucfg___ - -#ifndef XP_PC -#define XP_PC -#endif - -#ifndef WIN32 -#define WIN32 -#endif - -#ifndef WINNT -#define WINNT -#endif - -#define PR_AF_INET6 23 /* same as AF_INET6 */ - -#if defined(_M_IX86) || defined(_X86_) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_WORD 4 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_DOUBLE 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_WORD 32 -#define PR_BITS_PER_DWORD 64 -#define PR_BITS_PER_DOUBLE 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_WORD_LOG2 5 -#define PR_BITS_PER_DWORD_LOG2 6 -#define PR_BITS_PER_DOUBLE_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_WORD 4 -#define PR_ALIGN_OF_DWORD 8 -#define PR_ALIGN_OF_DOUBLE 4 -#define PR_ALIGN_OF_POINTER 4 - -#define PR_BYTES_PER_WORD_LOG2 2 -#define PR_BYTES_PER_DWORD_LOG2 2 - -#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_DOUBLE 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_WORD 64 -#define PR_BITS_PER_DWORD 64 -#define PR_BITS_PER_DOUBLE 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_WORD_LOG2 6 -#define PR_BITS_PER_DWORD_LOG2 6 -#define PR_BITS_PER_DOUBLE_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_WORD 8 -#define PR_ALIGN_OF_DWORD 8 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#elif defined(_M_IA64) || defined(_IA64_) - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN -#define IS_64 - -#define PR_BYTES_PER_BYTE 1 -#define PR_BYTES_PER_SHORT 2 -#define PR_BYTES_PER_INT 4 -#define PR_BYTES_PER_INT64 8 -#define PR_BYTES_PER_LONG 4 -#define PR_BYTES_PER_FLOAT 4 -#define PR_BYTES_PER_WORD 8 -#define PR_BYTES_PER_DWORD 8 -#define PR_BYTES_PER_DOUBLE 8 - -#define PR_BITS_PER_BYTE 8 -#define PR_BITS_PER_SHORT 16 -#define PR_BITS_PER_INT 32 -#define PR_BITS_PER_INT64 64 -#define PR_BITS_PER_LONG 32 -#define PR_BITS_PER_FLOAT 32 -#define PR_BITS_PER_WORD 64 -#define PR_BITS_PER_DWORD 64 -#define PR_BITS_PER_DOUBLE 64 - -#define PR_BITS_PER_BYTE_LOG2 3 -#define PR_BITS_PER_SHORT_LOG2 4 -#define PR_BITS_PER_INT_LOG2 5 -#define PR_BITS_PER_INT64_LOG2 6 -#define PR_BITS_PER_LONG_LOG2 5 -#define PR_BITS_PER_FLOAT_LOG2 5 -#define PR_BITS_PER_WORD_LOG2 6 -#define PR_BITS_PER_DWORD_LOG2 6 -#define PR_BITS_PER_DOUBLE_LOG2 6 - -#define PR_ALIGN_OF_SHORT 2 -#define PR_ALIGN_OF_INT 4 -#define PR_ALIGN_OF_LONG 4 -#define PR_ALIGN_OF_INT64 8 -#define PR_ALIGN_OF_FLOAT 4 -#define PR_ALIGN_OF_WORD 8 -#define PR_ALIGN_OF_DWORD 8 -#define PR_ALIGN_OF_DOUBLE 8 -#define PR_ALIGN_OF_POINTER 8 - -#define PR_BYTES_PER_WORD_LOG2 3 -#define PR_BYTES_PER_DWORD_LOG2 3 - -#else /* defined(_M_IX86) || defined(_X86_) */ - -#error unknown processor architecture - -#endif /* defined(_M_IX86) || defined(_X86_) */ - -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG -#endif - -#ifndef NO_NSPR_10_SUPPORT - -#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -#define BYTES_PER_INT PR_BYTES_PER_INT -#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -#define BYTES_PER_LONG PR_BYTES_PER_LONG -#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -#define BYTES_PER_WORD PR_BYTES_PER_WORD -#define BYTES_PER_DWORD PR_BYTES_PER_DWORD - -#define BITS_PER_BYTE PR_BITS_PER_BYTE -#define BITS_PER_SHORT PR_BITS_PER_SHORT -#define BITS_PER_INT PR_BITS_PER_INT -#define BITS_PER_INT64 PR_BITS_PER_INT64 -#define BITS_PER_LONG PR_BITS_PER_LONG -#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -#define BITS_PER_WORD PR_BITS_PER_WORD - -#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 - -#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -#define ALIGN_OF_INT PR_ALIGN_OF_INT -#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -#define ALIGN_OF_WORD PR_ALIGN_OF_WORD - -#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 - -#endif /* NO_NSPR_10_SUPPORT */ - -#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/md/_winnt.h nspr-4.10.7/mozilla/nsprpub/pr/include/md/_winnt.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/md/_winnt.h 2012-05-26 00:15:23.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/md/_winnt.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,593 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_win32_defs_h___ -#define nspr_win32_defs_h___ - -/* Need to force service-pack 3 extensions to be defined by -** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h. -*/ -#ifndef _WIN32_WINNT - #define _WIN32_WINNT 0x0400 -#elif (_WIN32_WINNT < 0x0400) - #undef _WIN32_WINNT - #define _WIN32_WINNT 0x0400 -#endif /* _WIN32_WINNT */ - -#include -#include -#ifdef __MINGW32__ -#include -#endif -#include - -#include "prio.h" -#include "prclist.h" - -/* - * Internal configuration macros - */ - -#define PR_LINKER_ARCH "win32" -#define _PR_SI_SYSNAME "WINNT" -#if defined(_M_IX86) || defined(_X86_) -#define _PR_SI_ARCHITECTURE "x86" -#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) -#define _PR_SI_ARCHITECTURE "x86-64" -#elif defined(_M_IA64) || defined(_IA64_) -#define _PR_SI_ARCHITECTURE "ia64" -#else -#error unknown processor architecture -#endif - -#define HAVE_DLL -#define HAVE_CUSTOM_USER_THREADS -#define HAVE_THREAD_AFFINITY -#define _PR_HAVE_GETADDRINFO -#define _PR_INET6_PROBE -#ifndef _PR_INET6 -#define AF_INET6 23 -/* newer ws2tcpip.h provides these */ -#ifndef AI_CANONNAME -#define AI_CANONNAME 0x2 -#define AI_NUMERICHOST 0x4 -#define NI_NUMERICHOST 0x02 -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - char *ai_canonname; - struct sockaddr *ai_addr; - struct addrinfo *ai_next; -}; -#endif -#define _PR_HAVE_MD_SOCKADDR_IN6 -/* isomorphic to struct in6_addr on Windows */ -struct _md_in6_addr { - union { - PRUint8 _S6_u8[16]; - PRUint16 _S6_u16[8]; - } _S6_un; -}; -/* isomorphic to struct sockaddr_in6 on Windows */ -struct _md_sockaddr_in6 { - PRInt16 sin6_family; - PRUint16 sin6_port; - PRUint32 sin6_flowinfo; - struct _md_in6_addr sin6_addr; - PRUint32 sin6_scope_id; -}; -#endif -#define _PR_HAVE_THREADSAFE_GETHOST -#define _PR_HAVE_ATOMIC_OPS -#if defined(_M_IX86) || defined(_X86_) -#define _PR_HAVE_ATOMIC_CAS -#endif -#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY -#define _PR_HAVE_PEEK_BUFFER -#define _PR_PEEK_BUFFER_MAX (32 * 1024) -#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) \ - (!(fd)->secret->nonblocking && (fd)->secret->inheritable != _PR_TRI_TRUE) -#define _PR_NEED_SECRET_AF - -/* --- Common User-Thread/Native-Thread Definitions --------------------- */ - -/* --- Globals --- */ -extern struct PRLock *_pr_schedLock; - -/* --- Typedefs --- */ -typedef void (*FiberFunc)(void *); - -#define PR_NUM_GCREGS 8 -typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS]; -#define GC_VMBASE 0x40000000 -#define GC_VMLIMIT 0x00FFFFFF - -#define _MD_MAGIC_THREAD 0x22222222 -#define _MD_MAGIC_THREADSTACK 0x33333333 -#define _MD_MAGIC_SEGMENT 0x44444444 -#define _MD_MAGIC_DIR 0x55555555 - -struct _MDCPU { - int unused; -}; - -enum _MDIOModel { - _MD_BlockingIO = 0x38, - _MD_MultiWaitIO = 0x49 -}; - -typedef struct _MDOverlapped { - OVERLAPPED overlapped; /* Used for async I/O */ - - enum _MDIOModel ioModel; /* The I/O model to implement - * using overlapped I/O. - */ - union { - struct _MDThread *mdThread; /* For blocking I/O, this structure - * is embedded in the _MDThread - * structure. - */ - struct { - PRCList links; /* for group->io_ready list */ - struct PRRecvWait *desc; /* For multiwait I/O, this structure - * is associated with a PRRecvWait - * structure. - */ - struct PRWaitGroup *group; - struct TimerEvent *timer; - DWORD error; - } mw; - } data; -} _MDOverlapped; - -struct _MDThread { - /* The overlapped structure must be first! */ - struct _MDOverlapped overlapped; /* Used for async IO for this thread */ - void *acceptex_buf; /* Used for AcceptEx() */ - TRANSMIT_FILE_BUFFERS *xmit_bufs; /* Used for TransmitFile() */ - HANDLE blocked_sema; /* Threads block on this when waiting - * for IO or CondVar. - */ - PRInt32 blocked_io_status; /* Status of the completed IO */ - PRInt32 blocked_io_bytes; /* Bytes transferred for completed IO */ - PRInt32 blocked_io_error; /* Save error if status is FALSE */ - HANDLE handle; - PRUint32 id; - void *sp; /* only valid when suspended */ - PRUint32 magic; /* for debugging */ - PR_CONTEXT_TYPE gcContext; /* Thread context for GC */ - struct _PRCPU *thr_bound_cpu; /* thread bound to cpu */ - PRBool interrupt_disabled;/* thread cannot be interrupted */ - HANDLE thr_event; /* For native-threads-only support, - thread blocks on this event */ - - /* The following are used only if this is a fiber */ - void *fiber_id; /* flag whether or not this is a fiber*/ - FiberFunc fiber_fn; /* main fiber routine */ - void *fiber_arg; /* arg to main fiber routine */ - PRUint32 fiber_stacksize; /* stacksize for fiber */ - PRInt32 fiber_last_error; /* last error for the fiber */ - void (*start)(void *); /* used by _PR_MD_CREATE_THREAD to - * pass its 'start' argument to - * pr_root. */ -}; - -struct _MDThreadStack { - PRUint32 magic; /* for debugging */ -}; - -struct _MDSegment { - PRUint32 magic; /* for debugging */ -}; - -#undef PROFILE_LOCKS - -struct _MDLock { - CRITICAL_SECTION mutex; /* this is recursive on NT */ -#ifdef PROFILE_LOCKS - PRInt32 hitcount; - PRInt32 misscount; -#endif -}; - -struct _MDDir { - HANDLE d_hdl; - WIN32_FIND_DATA d_entry; - PRBool firstEntry; /* Is this the entry returned - * by FindFirstFile()? */ - PRUint32 magic; /* for debugging */ -}; - -struct _MDCVar { - PRUint32 unused; -}; - -struct _MDSemaphore { - HANDLE sem; -}; - -struct _MDFileDesc { - PROsfd osfd; /* The osfd can come from one of three spaces: - * - For stdin, stdout, and stderr, we are using - * the libc file handle (0, 1, 2), which is an int. - * - For files and pipes, we are using Win32 HANDLE, - * which is a void*. - * - For sockets, we are using Winsock SOCKET, which - * is a u_int. - */ - PRBool io_model_committed; /* The io model (blocking or nonblocking) - * for this osfd has been committed and - * cannot be changed. The osfd has been - * either associated with the io - * completion port or made nonblocking. */ - PRBool sync_file_io; /* Use synchronous file I/O on the osfd - * (a file handle) */ - PRBool accepted_socket; /* Is this an accepted socket (on the - * server side)? */ - PRNetAddr peer_addr; /* If this is an accepted socket, cache - * the peer's address returned by - * AcceptEx(). This is to work around - * the bug that getpeername() on an - * socket accepted by AcceptEx() returns - * an all-zero net address. */ -}; - -struct _MDProcess { - HANDLE handle; - DWORD id; -}; - - -/* --- Misc stuff --- */ -#define _MD_GET_SP(thread) (thread)->md.gcContext[6] - -/* --- NT security stuff --- */ - -extern void _PR_NT_InitSids(void); -extern void _PR_NT_FreeSids(void); -extern PRStatus _PR_NT_MakeSecurityDescriptorACL( - PRIntn mode, - DWORD accessTable[], - PSECURITY_DESCRIPTOR *resultSD, - PACL *resultACL -); -extern void _PR_NT_FreeSecurityDescriptorACL( - PSECURITY_DESCRIPTOR pSD, PACL pACL); - -/* --- IO stuff --- */ - -extern PRInt32 _md_Associate(HANDLE); -extern PRInt32 _PR_MD_CLOSE(PROsfd osfd, PRBool socket); - -#define _MD_OPEN _PR_MD_OPEN -#define _MD_OPEN_FILE _PR_MD_OPEN_FILE -#define _MD_READ _PR_MD_READ -#define _MD_WRITE _PR_MD_WRITE -#define _MD_WRITEV _PR_MD_WRITEV -#define _MD_LSEEK _PR_MD_LSEEK -#define _MD_LSEEK64 _PR_MD_LSEEK64 -#define _MD_CLOSE_FILE(f) _PR_MD_CLOSE(f, PR_FALSE) -#define _MD_GETFILEINFO _PR_MD_GETFILEINFO -#define _MD_GETFILEINFO64 _PR_MD_GETFILEINFO64 -#define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO -#define _MD_GETOPENFILEINFO64 _PR_MD_GETOPENFILEINFO64 -#define _MD_STAT _PR_MD_STAT -#define _MD_RENAME _PR_MD_RENAME -#define _MD_ACCESS _PR_MD_ACCESS -#define _MD_DELETE _PR_MD_DELETE -#define _MD_MKDIR _PR_MD_MKDIR -#define _MD_MAKE_DIR _PR_MD_MAKE_DIR -#define _MD_RMDIR _PR_MD_RMDIR -#define _MD_LOCKFILE _PR_MD_LOCKFILE -#define _MD_TLOCKFILE _PR_MD_TLOCKFILE -#define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE - -/* --- Socket IO stuff --- */ -#define _MD_GET_SOCKET_ERROR() WSAGetLastError() -#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err) - -#define _MD_INIT_FILEDESC(fd) -#define _MD_MAKE_NONBLOCK _PR_MD_MAKE_NONBLOCK -#define _MD_INIT_FD_INHERITABLE _PR_MD_INIT_FD_INHERITABLE -#define _MD_QUERY_FD_INHERITABLE _PR_MD_QUERY_FD_INHERITABLE -#define _MD_SHUTDOWN _PR_MD_SHUTDOWN -#define _MD_LISTEN _PR_MD_LISTEN -#define _MD_CLOSE_SOCKET(s) _PR_MD_CLOSE(s, PR_TRUE) -#define _MD_SENDTO _PR_MD_SENDTO -#define _MD_RECVFROM _PR_MD_RECVFROM -#define _MD_SOCKETPAIR(s, type, proto, sv) -1 -#define _MD_GETSOCKNAME _PR_MD_GETSOCKNAME -#define _MD_GETPEERNAME _PR_MD_GETPEERNAME -#define _MD_GETSOCKOPT _PR_MD_GETSOCKOPT -#define _MD_SETSOCKOPT _PR_MD_SETSOCKOPT -#define _MD_SELECT select -extern int _PR_NTFiberSafeSelect(int, fd_set *, fd_set *, fd_set *, - const struct timeval *); -#define _MD_FSYNC _PR_MD_FSYNC -#define _MD_SOCKETAVAILABLE _PR_MD_SOCKETAVAILABLE -#define _MD_PIPEAVAILABLE _PR_MD_PIPEAVAILABLE -#define _MD_SET_FD_INHERITABLE _PR_MD_SET_FD_INHERITABLE - -#define _MD_INIT_ATOMIC() -#if defined(_M_IX86) || defined(_X86_) -#define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT -#define _MD_ATOMIC_ADD _PR_MD_ATOMIC_ADD -#define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT -#else /* non-x86 processors */ -#define _MD_ATOMIC_INCREMENT(x) InterlockedIncrement((PLONG)x) -#define _MD_ATOMIC_ADD(ptr,val) (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val) -#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x) -#endif /* x86 */ -#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y) - -#define _MD_INIT_IO _PR_MD_INIT_IO -#define _MD_SOCKET _PR_MD_SOCKET -#define _MD_CONNECT _PR_MD_CONNECT - -#define _MD_ACCEPT(s, a, l, to) \ - _MD_FAST_ACCEPT(s, a, l, to, PR_FALSE, NULL, NULL) -#define _MD_FAST_ACCEPT(s, a, l, to, fast, cb, cba) \ - _PR_MD_FAST_ACCEPT(s, a, l, to, fast, cb, cba) -#define _MD_ACCEPT_READ(s, ns, ra, buf, l, t) \ - _MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, PR_FALSE, NULL, NULL) -#define _MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, fast, cb, cba) \ - _PR_MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, fast, cb, cba) -#define _MD_UPDATE_ACCEPT_CONTEXT _PR_MD_UPDATE_ACCEPT_CONTEXT - -#define _MD_BIND _PR_MD_BIND -#define _MD_RECV _PR_MD_RECV -#define _MD_SEND _PR_MD_SEND -#define _MD_SENDFILE _PR_MD_SENDFILE -#define _MD_PR_POLL _PR_MD_PR_POLL - -/* --- Scheduler stuff --- */ -#define _MD_PAUSE_CPU _PR_MD_PAUSE_CPU - -/* --- DIR stuff --- */ -#define PR_DIRECTORY_SEPARATOR '\\' -#define PR_DIRECTORY_SEPARATOR_STR "\\" -#define PR_PATH_SEPARATOR ';' -#define PR_PATH_SEPARATOR_STR ";" -#define _MD_ERRNO() GetLastError() -#define _MD_OPEN_DIR _PR_MD_OPEN_DIR -#define _MD_CLOSE_DIR _PR_MD_CLOSE_DIR -#define _MD_READ_DIR _PR_MD_READ_DIR - -/* --- Segment stuff --- */ -#define _MD_INIT_SEGS() -#define _MD_ALLOC_SEGMENT(seg, size, vaddr) 0 -#define _MD_FREE_SEGMENT(seg) - -/* --- Environment Stuff --- */ -#define _MD_GET_ENV _PR_MD_GET_ENV -#define _MD_PUT_ENV _PR_MD_PUT_ENV - -/* --- Threading Stuff --- */ -#define _MD_DEFAULT_STACK_SIZE 0 -#define _MD_INIT_THREAD _PR_MD_INIT_THREAD -#define _MD_INIT_ATTACHED_THREAD _PR_MD_INIT_THREAD -#define _MD_CREATE_THREAD _PR_MD_CREATE_THREAD -#define _MD_JOIN_THREAD _PR_MD_JOIN_THREAD -#define _MD_END_THREAD _PR_MD_END_THREAD -#define _MD_YIELD _PR_MD_YIELD -#define _MD_SET_PRIORITY _PR_MD_SET_PRIORITY -#define _MD_SET_CURRENT_THREAD_NAME _PR_MD_SET_CURRENT_THREAD_NAME -#define _MD_CLEAN_THREAD _PR_MD_CLEAN_THREAD -#define _MD_SETTHREADAFFINITYMASK _PR_MD_SETTHREADAFFINITYMASK -#define _MD_GETTHREADAFFINITYMASK _PR_MD_GETTHREADAFFINITYMASK -#define _MD_EXIT_THREAD _PR_MD_EXIT_THREAD -#define _MD_SUSPEND_THREAD _PR_MD_SUSPEND_THREAD -#define _MD_RESUME_THREAD _PR_MD_RESUME_THREAD -#define _MD_SUSPEND_CPU _PR_MD_SUSPEND_CPU -#define _MD_RESUME_CPU _PR_MD_RESUME_CPU -#define _MD_BEGIN_SUSPEND_ALL() -#define _MD_BEGIN_RESUME_ALL() -#define _MD_END_SUSPEND_ALL() -#define _MD_END_RESUME_ALL() - -extern void _PR_Unblock_IO_Wait(PRThread *thr); - -/* --- Lock stuff --- */ -#define _MD_NEW_LOCK(lock) (InitializeCriticalSection(&((lock)->mutex)),PR_SUCCESS) -#define _MD_FREE_LOCK(lock) DeleteCriticalSection(&((lock)->mutex)) -#ifndef PROFILE_LOCKS -#define _MD_LOCK(lock) EnterCriticalSection(&((lock)->mutex)) -#define _MD_TEST_AND_LOCK(lock) (TryEnterCriticalSection(&((lock)->mutex))== FALSE) -#define _MD_UNLOCK(lock) LeaveCriticalSection(&((lock)->mutex)) -#else -#define _MD_LOCK(lock) \ - PR_BEGIN_MACRO \ - BOOL rv = TryEnterCriticalSection(&((lock)->mutex)); \ - if (rv == TRUE) { \ - InterlockedIncrement(&((lock)->hitcount)); \ - } else { \ - InterlockedIncrement(&((lock)->misscount)); \ - EnterCriticalSection(&((lock)->mutex)); \ - } \ - PR_END_MACRO -#define _MD_TEST_AND_LOCK(lock) 0 /* XXXMB */ -#define _MD_UNLOCK(lock) LeaveCriticalSection(&((lock)->mutex)) -#endif -#define _PR_LOCK _MD_LOCK -#define _PR_UNLOCK _MD_UNLOCK - -/* --- lock and cv waiting --- */ -#define _MD_WAIT _PR_MD_WAIT -#define _MD_WAKEUP_WAITER _PR_MD_WAKEUP_WAITER - - /* XXXMB- the IOQ stuff is certainly not working correctly yet. */ -extern struct _MDLock _pr_ioq_lock; -#define _MD_IOQ_LOCK() _MD_LOCK(&_pr_ioq_lock) -#define _MD_IOQ_UNLOCK() _MD_UNLOCK(&_pr_ioq_lock) - - -/* --- Initialization stuff --- */ -#define _MD_START_INTERRUPTS() -#define _MD_STOP_INTERRUPTS() -#define _MD_DISABLE_CLOCK_INTERRUPTS() -#define _MD_ENABLE_CLOCK_INTERRUPTS() -#define _MD_BLOCK_CLOCK_INTERRUPTS() -#define _MD_UNBLOCK_CLOCK_INTERRUPTS() -#define _MD_EARLY_INIT _PR_MD_EARLY_INIT -#define _MD_FINAL_INIT() -#define _MD_EARLY_CLEANUP() -#define _MD_INIT_CPUS() -#define _MD_INIT_RUNNING_CPU(cpu) - -struct PRProcess; -struct PRProcessAttr; - -/* --- Create a new process --- */ -#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess -extern struct PRProcess * _PR_CreateWindowsProcess( - const char *path, - char *const *argv, - char *const *envp, - const struct PRProcessAttr *attr -); - -#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess -extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process); - -/* --- Wait for a child process to terminate --- */ -#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess -extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, - PRInt32 *exitCode); - -#define _MD_KILL_PROCESS _PR_KillWindowsProcess -extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process); - -/* --- User Threading stuff --- */ -#define HAVE_FIBERS -#define _MD_CREATE_USER_THREAD _PR_MD_CREATE_USER_THREAD -#define _MD_CREATE_PRIMORDIAL_USER_THREAD _PR_MD_CREATE_PRIMORDIAL_USER_THREAD -#define _MD_CLEANUP_BEFORE_EXIT _PR_MD_CLEANUP_BEFORE_EXIT -#define _MD_EXIT _PR_MD_EXIT -#define _MD_INIT_CONTEXT _PR_MD_INIT_CONTEXT -#define _MD_SWITCH_CONTEXT _PR_MD_SWITCH_CONTEXT -#define _MD_RESTORE_CONTEXT _PR_MD_RESTORE_CONTEXT - -/* --- Intervals --- */ -#define _MD_INTERVAL_INIT _PR_MD_INTERVAL_INIT -#define _MD_GET_INTERVAL _PR_MD_GET_INTERVAL -#define _MD_INTERVAL_PER_SEC _PR_MD_INTERVAL_PER_SEC -#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) -#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) - -/* --- Time --- */ -extern void _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm); - -/* --- Native-Thread Specific Definitions ------------------------------- */ - -extern BOOL _pr_use_static_tls; - -extern __declspec(thread) struct PRThread *_pr_current_fiber; -extern DWORD _pr_currentFiberIndex; - -#define _MD_GET_ATTACHED_THREAD() \ - (_pr_use_static_tls ? _pr_current_fiber \ - : (PRThread *) TlsGetValue(_pr_currentFiberIndex)) - -extern struct PRThread * _MD_CURRENT_THREAD(void); - -#define _MD_SET_CURRENT_THREAD(_thread) \ - PR_BEGIN_MACRO \ - if (_pr_use_static_tls) { \ - _pr_current_fiber = (_thread); \ - } else { \ - TlsSetValue(_pr_currentFiberIndex, (_thread)); \ - } \ - PR_END_MACRO - -extern __declspec(thread) struct PRThread *_pr_fiber_last_run; -extern DWORD _pr_lastFiberIndex; - -#define _MD_LAST_THREAD() \ - (_pr_use_static_tls ? _pr_fiber_last_run \ - : (PRThread *) TlsGetValue(_pr_lastFiberIndex)) - -#define _MD_SET_LAST_THREAD(_thread) \ - PR_BEGIN_MACRO \ - if (_pr_use_static_tls) { \ - _pr_fiber_last_run = (_thread); \ - } else { \ - TlsSetValue(_pr_lastFiberIndex, (_thread)); \ - } \ - PR_END_MACRO - -extern __declspec(thread) struct _PRCPU *_pr_current_cpu; -extern DWORD _pr_currentCPUIndex; - -#define _MD_CURRENT_CPU() \ - (_pr_use_static_tls ? _pr_current_cpu \ - : (struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex)) - -#define _MD_SET_CURRENT_CPU(_cpu) \ - PR_BEGIN_MACRO \ - if (_pr_use_static_tls) { \ - _pr_current_cpu = (_cpu); \ - } else { \ - TlsSetValue(_pr_currentCPUIndex, (_cpu)); \ - } \ - PR_END_MACRO - -extern __declspec(thread) PRUintn _pr_ints_off; -extern DWORD _pr_intsOffIndex; - -#define _MD_GET_INTSOFF() \ - (_pr_use_static_tls ? _pr_ints_off \ - : (PRUintn) TlsGetValue(_pr_intsOffIndex)) - -#define _MD_SET_INTSOFF(_val) \ - PR_BEGIN_MACRO \ - if (_pr_use_static_tls) { \ - _pr_ints_off = (_val); \ - } else { \ - TlsSetValue(_pr_intsOffIndex, (LPVOID) (_val)); \ - } \ - PR_END_MACRO - -/* --- Initialization stuff --- */ -#define _MD_INIT_LOCKS() - -/* --- Stack stuff --- */ -#define _MD_INIT_STACK(stack, redzone) -#define _MD_CLEAR_STACK(stack) - -/* --- Memory-mapped files stuff --- */ - -struct _MDFileMap { - HANDLE hFileMap; - DWORD dwAccess; -}; - -extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); -#define _MD_CREATE_FILE_MAP _MD_CreateFileMap - -extern PRInt32 _MD_GetMemMapAlignment(void); -#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment - -extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, - PRUint32 len); -#define _MD_MEM_MAP _MD_MemMap - -extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); -#define _MD_MEM_UNMAP _MD_MemUnmap - -extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); -#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap - -/* --- Named semaphores stuff --- */ -#define _PR_HAVE_NAMED_SEMAPHORES -#define _MD_OPEN_SEMAPHORE _PR_MD_OPEN_SEMAPHORE -#define _MD_WAIT_SEMAPHORE _PR_MD_WAIT_SEMAPHORE -#define _MD_POST_SEMAPHORE _PR_MD_POST_SEMAPHORE -#define _MD_CLOSE_SEMAPHORE _PR_MD_CLOSE_SEMAPHORE -#define _MD_DELETE_SEMAPHORE(name) PR_SUCCESS /* no op */ - -#endif /* nspr_win32_defs_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/nspr.h nspr-4.10.7/mozilla/nsprpub/pr/include/nspr.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/nspr.h 2012-03-06 13:13:42.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/nspr.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nspr_h___ -#define nspr_h___ - -#include "pratom.h" -#include "prbit.h" -#include "prclist.h" -#include "prcmon.h" -#include "prcvar.h" -#include "prdtoa.h" -#include "prenv.h" -#include "prerror.h" -#include "prinet.h" -#include "prinit.h" -#include "prinrval.h" -#include "prio.h" -#include "pripcsem.h" -#include "prlink.h" -#include "prlock.h" -#include "prlog.h" -#include "prlong.h" -#include "prmem.h" -#include "prmon.h" -#include "prmwait.h" -#include "prnetdb.h" -#include "prprf.h" -#include "prproces.h" -#include "prrng.h" -#include "prrwlock.h" -#include "prshm.h" -#include "prshma.h" -#include "prsystem.h" -#include "prthread.h" -#include "prtime.h" -#include "prtpool.h" -#include "prtrace.h" -#include "prtypes.h" - -#endif /* nspr_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/.cvsignore 2001-05-12 01:58:29.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/Makefile.in 2012-03-06 13:13:55.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -HEADERS = $(wildcard $(srcdir)/*.h) - -RELEASE_HEADERS = $(HEADERS) -RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)/obsolete - -include_subdir = obsolete - -include $(topsrcdir)/config/rules.mk - -export:: $(RELEASE_HEADERS) - $(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)/obsolete diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/pralarm.h nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/pralarm.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/pralarm.h 2012-03-06 13:13:55.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/pralarm.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,162 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: pralarm.h -** Description: API to periodic alarms. -** -** -** Alarms are defined to invoke some client specified function at -** a time in the future. The notification may be a one time event -** or repeated at a fixed interval. The interval at which the next -** notification takes place may be modified by the client code only -** during the respective notification. -** -** The notification is delivered on a thread that is part of the -** alarm context (PRAlarm). The thread will inherit the priority -** of the Alarm creator. -** -** Any number of periodic alarms (PRAlarmID) may be created within -** the context of a single alarm (PRAlarm). The notifications will be -** scheduled as close to the desired time as possible. -** -** Repeating periodic notifies are expected to run at a fixed rate. -** That rate is expressed as some number of notifies per period where -** the period is much larger than a PRIntervalTime (see prinrval.h). -*/ - -#if !defined(pralarm_h) -#define pralarm_h - -#include "prtypes.h" -#include "prinrval.h" - - -PR_BEGIN_EXTERN_C - -/**********************************************************************/ -/************************* TYPES AND CONSTANTS ************************/ -/**********************************************************************/ - -typedef struct PRAlarm PRAlarm; -typedef struct PRAlarmID PRAlarmID; - -typedef PRBool (PR_CALLBACK *PRPeriodicAlarmFn)( - PRAlarmID *id, void *clientData, PRUint32 late); - -/**********************************************************************/ -/****************************** FUNCTIONS *****************************/ -/**********************************************************************/ - -/*********************************************************************** -** FUNCTION: PR_CreateAlarm -** DESCRIPTION: -** Create an alarm context. -** INPUTS: void -** OUTPUTS: None -** RETURN: PRAlarm* -** -** SIDE EFFECTS: -** This creates an alarm context, which is an object used for subsequent -** notification creations. It also creates a thread that will be used to -** deliver the notifications that are expected to be defined. The client -** is resposible for destroying the context when appropriate. -** RESTRICTIONS: -** None. -** MEMORY: The object (PRAlarm) and a thread to support notifications. -** ALGORITHM: N/A -***********************************************************************/ -NSPR_API(PRAlarm*) PR_CreateAlarm(void); - -/*********************************************************************** -** FUNCTION: PR_DestroyAlarm -** DESCRIPTION: -** Destroys the context created by PR_CreateAlarm(). -** INPUTS: PRAlarm* -** OUTPUTS: None -** RETURN: PRStatus -** -** SIDE EFFECTS: -** This destroys the context that was created by PR_CreateAlarm(). -** If there are any active alarms (PRAlarmID), they will be cancelled. -** Once that is done, the thread that was used to deliver the alarms -** will be joined. -** RESTRICTIONS: -** None. -** MEMORY: N/A -** ALGORITHM: N/A -***********************************************************************/ -NSPR_API(PRStatus) PR_DestroyAlarm(PRAlarm *alarm); - -/*********************************************************************** -** FUNCTION: PR_SetAlarm -** DESCRIPTION: -** Creates a periodic notifier that is to be delivered to a specified -** function at some fixed interval. -** INPUTS: PRAlarm *alarm Parent alarm context -** PRIntervalTime period Interval over which the notifies -** are delivered. -** PRUint32 rate The rate within the interval that -** the notifies will be delivered. -** PRPeriodicAlarmFn function Entry point where the notifies -** will be delivered. -** OUTPUTS: None -** RETURN: PRAlarmID* Handle to the notifier just created -** or NULL if the request failed. -** -** SIDE EFFECTS: -** A periodic notifier is created. The notifications will be delivered -** by the alarm's internal thread at a fixed interval whose rate is the -** number of interrupts per interval specified. The first notification -** will be delivered as soon as possible, and they will continue until -** the notifier routine indicates that they should cease of the alarm -** context is destroyed (PR_DestroyAlarm). -** RESTRICTIONS: -** None. -** MEMORY: Memory for the notifier object. -** ALGORITHM: The rate at which notifications are delivered are stated -** to be "'rate' notifies per 'interval'". The exact time of -** the notification is computed based on a epoch established -** when the notifier was set. Each notification is delivered -** not ealier than the epoch plus the fixed rate times the -** notification sequence number. Such notifications have the -** potential to be late by not more than 'interval'/'rate'. -** The amount of lateness of one notification is taken into -** account on the next in an attempt to avoid long term slew. -***********************************************************************/ -NSPR_API(PRAlarmID*) PR_SetAlarm( - PRAlarm *alarm, PRIntervalTime period, PRUint32 rate, - PRPeriodicAlarmFn function, void *clientData); - -/*********************************************************************** -** FUNCTION: PR_ResetAlarm -** DESCRIPTION: -** Resets an existing alarm. -** INPUTS: PRAlarmID *id Identify of the notifier. -** PRIntervalTime period Interval over which the notifies -** are delivered. -** PRUint32 rate The rate within the interval that -** the notifies will be delivered. -** OUTPUTS: None -** RETURN: PRStatus Indication of completion. -** -** SIDE EFFECTS: -** An existing alarm may have its period and rate redefined. The -** additional side effect is that the notifier's epoch is recomputed. -** The first notification delivered by the newly refreshed alarm is -** defined to be 'interval'/'rate' from the time of the reset. -** RESTRICTIONS: -** This function may only be called in the notifier for that alarm. -** MEMORY: N/A. -** ALGORITHM: See PR_SetAlarm(). -***********************************************************************/ -NSPR_API(PRStatus) PR_ResetAlarm( - PRAlarmID *id, PRIntervalTime period, PRUint32 rate); - -PR_END_EXTERN_C - -#endif /* !defined(pralarm_h) */ - -/* prinrval.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/probslet.h nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/probslet.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/probslet.h 2012-03-06 13:13:55.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/probslet.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,149 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** A collection of things thought to be obsolete -*/ - -#if defined(PROBSLET_H) -#else -#define PROBSLET_H - -#include "prio.h" -#include "private/pprio.h" /* for PROsfd */ - -PR_BEGIN_EXTERN_C - -/* -** Yield the current thread. The proper function to use in place of -** PR_Yield() is PR_Sleep() with an argument of PR_INTERVAL_NO_WAIT. -*/ -NSPR_API(PRStatus) PR_Yield(void); - -/************************************************************************/ -/************* The following definitions are for select *****************/ -/************************************************************************/ - -/* -** The following is obsolete and will be deleted in the next release! -** These are provided for compatibility, but are GUARANTEED to be slow. -** -** Override PR_MAX_SELECT_DESC if you need more space in the select set. -*/ -#ifndef PR_MAX_SELECT_DESC -#define PR_MAX_SELECT_DESC 1024 -#endif -typedef struct PR_fd_set { - PRUint32 hsize; - PRFileDesc *harray[PR_MAX_SELECT_DESC]; - PRUint32 nsize; - PROsfd narray[PR_MAX_SELECT_DESC]; -} PR_fd_set; - -/* -************************************************************************* -** FUNCTION: PR_Select -** DESCRIPTION: -** -** The call returns as soon as I/O is ready on one or more of the underlying -** file/socket descriptors or an exceptional condition is pending. A count of the -** number of ready descriptors is returned unless a timeout occurs in which case -** zero is returned. On return, PR_Select replaces the given descriptor sets with -** subsets consisting of those descriptors that are ready for the requested condition. -** The total number of ready descriptors in all the sets is the return value. -** -** INPUTS: -** PRInt32 num -** This argument is unused but is provided for select(unix) interface -** compatability. All input PR_fd_set arguments are self-describing -** with its own maximum number of elements in the set. -** -** PR_fd_set *readfds -** A set describing the io descriptors for which ready for reading -** condition is of interest. -** -** PR_fd_set *writefds -** A set describing the io descriptors for which ready for writing -** condition is of interest. -** -** PR_fd_set *exceptfds -** A set describing the io descriptors for which exception pending -** condition is of interest. -** -** Any of the above readfds, writefds or exceptfds may be given as NULL -** pointers if no descriptors are of interest for that particular condition. -** -** PRIntervalTime timeout -** Amount of time the call will block waiting for I/O to become ready. -** If this time expires without any I/O becoming ready, the result will -** be zero. -** -** OUTPUTS: -** PR_fd_set *readfds -** A set describing the io descriptors which are ready for reading. -** -** PR_fd_set *writefds -** A set describing the io descriptors which are ready for writing. -** -** PR_fd_set *exceptfds -** A set describing the io descriptors which have pending exception. -** -** RETURN:PRInt32 -** Number of io descriptors with asked for conditions or zero if the function -** timed out or -1 on failure. The reason for the failure is obtained by -** calling PR_GetError(). -** XXX can we implement this on windoze and mac? -************************************************************************** -*/ -NSPR_API(PRInt32) PR_Select( - PRInt32 num, PR_fd_set *readfds, PR_fd_set *writefds, - PR_fd_set *exceptfds, PRIntervalTime timeout); - -/* -** The following are not thread safe for two threads operating on them at the -** same time. -** -** The following routines are provided for manipulating io descriptor sets. -** PR_FD_ZERO(&fdset) initializes a descriptor set fdset to the null set. -** PR_FD_SET(fd, &fdset) includes a particular file descriptor fd in fdset. -** PR_FD_CLR(fd, &fdset) removes a file descriptor fd from fdset. -** PR_FD_ISSET(fd, &fdset) is nonzero if file descriptor fd is a member of -** fdset, zero otherwise. -** -** PR_FD_NSET(osfd, &fdset) includes a particular native file descriptor osfd -** in fdset. -** PR_FD_NCLR(osfd, &fdset) removes a native file descriptor osfd from fdset. -** PR_FD_NISSET(osfd, &fdset) is nonzero if native file descriptor osfd is a member of -** fdset, zero otherwise. -*/ - -NSPR_API(void) PR_FD_ZERO(PR_fd_set *set); -NSPR_API(void) PR_FD_SET(PRFileDesc *fd, PR_fd_set *set); -NSPR_API(void) PR_FD_CLR(PRFileDesc *fd, PR_fd_set *set); -NSPR_API(PRInt32) PR_FD_ISSET(PRFileDesc *fd, PR_fd_set *set); -NSPR_API(void) PR_FD_NSET(PROsfd osfd, PR_fd_set *set); -NSPR_API(void) PR_FD_NCLR(PROsfd osfd, PR_fd_set *set); -NSPR_API(PRInt32) PR_FD_NISSET(PROsfd osfd, PR_fd_set *set); - -/* -** The next two entry points should not be in the API, but they are -** declared here for historical reasons. -*/ - -NSPR_API(PRInt32) PR_GetSysfdTableMax(void); - -NSPR_API(PRInt32) PR_SetSysfdTableSize(PRIntn table_size); - -#ifndef NO_NSPR_10_SUPPORT -#include - -NSPR_API(PRInt32) PR_Stat(const char *path, struct stat *buf); -#endif /* NO_NSPR_10_SUPPORT */ - -PR_END_EXTERN_C - -#endif /* defined(PROBSLET_H) */ - -/* probslet.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/protypes.h nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/protypes.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/protypes.h 2012-03-06 13:13:55.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/protypes.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,199 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This header typedefs the old 'native' types to the new PRs. - * These definitions are scheduled to be eliminated at the earliest - * possible time. The NSPR API is implemented and documented using - * the new definitions. - */ - -#if !defined(PROTYPES_H) -#define PROTYPES_H - -typedef PRUintn uintn; -#ifndef _XP_Core_ -typedef PRIntn intn; -#endif - -/* - * It is trickier to define uint, int8, uint8, int16, uint16, - * int32, uint32, int64, and uint64 because some of these int - * types are defined by standard header files on some platforms. - * Our strategy here is to include all such standard headers - * first, and then define these int types only if they are not - * defined by those standard headers. - */ - -/* - * BeOS defines all the int types below in its standard header - * file SupportDefs.h. - */ -#ifdef XP_BEOS -#include -#endif - -/* - * SVR4 typedef of uint is commonly found on UNIX machines. - * - * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h) - * defines the types int8, int16, int32, and int64. - * - * On OS/2, sys/types.h defines uint. - */ -#if defined(XP_UNIX) || defined(XP_OS2) -#include -#endif - -/* model.h on HP-UX defines int8, int16, and int32. */ -#ifdef HPUX -#include -#endif - -/* - * uint - */ - -#if !defined(XP_BEOS) && !defined(XP_OS2) && !defined(XP_UNIX) || defined(NTO) -typedef PRUintn uint; -#endif - -/* - * uint64 - */ - -#if !defined(XP_BEOS) -typedef PRUint64 uint64; -#endif - -/* - * uint32 - */ - -#if !defined(XP_BEOS) -#if !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO) -typedef PRUint32 uint32; -#else -typedef unsigned long uint32; -#endif -#endif - -/* - * uint16 - */ - -#if !defined(XP_BEOS) -typedef PRUint16 uint16; -#endif - -/* - * uint8 - */ - -#if !defined(XP_BEOS) -typedef PRUint8 uint8; -#endif - -/* - * int64 - */ - -#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) -typedef PRInt64 int64; -#endif - -/* - * int32 - */ - -#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ - && !defined(HPUX) -#if !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO) -typedef PRInt32 int32; -#else -typedef long int32; -#endif -#endif - -/* - * int16 - */ - -#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ - && !defined(HPUX) -typedef PRInt16 int16; -#endif - -/* - * int8 - */ - -#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ - && !defined(HPUX) -typedef PRInt8 int8; -#endif - -typedef PRFloat64 float64; -typedef PRUptrdiff uptrdiff_t; -typedef PRUword uprword_t; -typedef PRWord prword_t; - - -/* Re: prbit.h */ -#define TEST_BIT PR_TEST_BIT -#define SET_BIT PR_SET_BIT -#define CLEAR_BIT PR_CLEAR_BIT - -/* Re: prarena.h->plarena.h */ -#define PRArena PLArena -#define PRArenaPool PLArenaPool -#define PRArenaStats PLArenaStats -#define PR_ARENA_ALIGN PL_ARENA_ALIGN -#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL -#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE -#define PR_ARENA_GROW PL_ARENA_GROW -#define PR_ARENA_MARK PL_ARENA_MARK -#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED -#define PR_CLEAR_ARENA PL_CLEAR_ARENA -#define PR_ARENA_RELEASE PL_ARENA_RELEASE -#define PR_COUNT_ARENA PL_COUNT_ARENA -#define PR_ARENA_DESTROY PL_ARENA_DESTROY -#define PR_InitArenaPool PL_InitArenaPool -#define PR_FreeArenaPool PL_FreeArenaPool -#define PR_FinishArenaPool PL_FinishArenaPool -#define PR_CompactArenaPool PL_CompactArenaPool -#define PR_ArenaFinish PL_ArenaFinish -#define PR_ArenaAllocate PL_ArenaAllocate -#define PR_ArenaGrow PL_ArenaGrow -#define PR_ArenaRelease PL_ArenaRelease -#define PR_ArenaCountAllocation PL_ArenaCountAllocation -#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth -#define PR_ArenaCountGrowth PL_ArenaCountGrowth -#define PR_ArenaCountRelease PL_ArenaCountRelease -#define PR_ArenaCountRetract PL_ArenaCountRetract - -/* Re: prhash.h->plhash.h */ -#define PRHashEntry PLHashEntry -#define PRHashTable PLHashTable -#define PRHashNumber PLHashNumber -#define PRHashFunction PLHashFunction -#define PRHashComparator PLHashComparator -#define PRHashEnumerator PLHashEnumerator -#define PRHashAllocOps PLHashAllocOps -#define PR_NewHashTable PL_NewHashTable -#define PR_HashTableDestroy PL_HashTableDestroy -#define PR_HashTableRawLookup PL_HashTableRawLookup -#define PR_HashTableRawAdd PL_HashTableRawAdd -#define PR_HashTableRawRemove PL_HashTableRawRemove -#define PR_HashTableAdd PL_HashTableAdd -#define PR_HashTableRemove PL_HashTableRemove -#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries -#define PR_HashTableLookup PL_HashTableLookup -#define PR_HashTableDump PL_HashTableDump -#define PR_HashString PL_HashString -#define PR_CompareStrings PL_CompareStrings -#define PR_CompareValues PL_CompareValues - -#endif /* !defined(PROTYPES_H) */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/prsem.h nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/prsem.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/obsolete/prsem.h 2012-03-06 13:13:56.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/obsolete/prsem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prsem_h___ -#define prsem_h___ - -/* -** API for counting semaphores. Semaphores are counting synchronizing -** variables based on a lock and a condition variable. They are lightweight -** contention control for a given count of resources. -*/ -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -typedef struct PRSemaphore PRSemaphore; - -/* -** Create a new semaphore object. -*/ -NSPR_API(PRSemaphore*) PR_NewSem(PRUintn value); - -/* -** Destroy the given semaphore object. -** -*/ -NSPR_API(void) PR_DestroySem(PRSemaphore *sem); - -/* -** Wait on a Semaphore. -** -** This routine allows a calling thread to wait or proceed depending upon the -** state of the semahore sem. The thread can proceed only if the counter value -** of the semaphore sem is currently greater than 0. If the value of semaphore -** sem is positive, it is decremented by one and the routine returns immediately -** allowing the calling thread to continue. If the value of semaphore sem is 0, -** the calling thread blocks awaiting the semaphore to be released by another -** thread. -** -** This routine can return PR_PENDING_INTERRUPT if the waiting thread -** has been interrupted. -*/ -NSPR_API(PRStatus) PR_WaitSem(PRSemaphore *sem); - -/* -** This routine increments the counter value of the semaphore. If other threads -** are blocked for the semaphore, then the scheduler will determine which ONE -** thread will be unblocked. -*/ -NSPR_API(void) PR_PostSem(PRSemaphore *sem); - -/* -** Returns the value of the semaphore referenced by sem without affecting -** the state of the semaphore. The value represents the semaphore vaule -F** at the time of the call, but may not be the actual value when the -** caller inspects it. -*/ -NSPR_API(PRUintn) PR_GetValueSem(PRSemaphore *sem); - -PR_END_EXTERN_C - -#endif /* prsem_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/pratom.h nspr-4.10.7/mozilla/nsprpub/pr/include/pratom.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/pratom.h 2012-03-06 13:13:42.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/pratom.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,199 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* GLOBAL FUNCTIONS: -** DESCRIPTION: -** PR Atomic operations -*/ - -#ifndef pratom_h___ -#define pratom_h___ - -#include "prtypes.h" -#include "prlock.h" - -PR_BEGIN_EXTERN_C - -/* -** FUNCTION: PR_AtomicIncrement -** DESCRIPTION: -** Atomically increment a 32 bit value. -** INPUTS: -** val: a pointer to the value to increment -** RETURN: -** the returned value is the result of the increment -*/ -NSPR_API(PRInt32) PR_AtomicIncrement(PRInt32 *val); - -/* -** FUNCTION: PR_AtomicDecrement -** DESCRIPTION: -** Atomically decrement a 32 bit value. -** INPUTS: -** val: a pointer to the value to decrement -** RETURN: -** the returned value is the result of the decrement -*/ -NSPR_API(PRInt32) PR_AtomicDecrement(PRInt32 *val); - -/* -** FUNCTION: PR_AtomicSet -** DESCRIPTION: -** Atomically set a 32 bit value. -** INPUTS: -** val: A pointer to a 32 bit value to be set -** newval: The newvalue to assign to val -** RETURN: -** Returns the prior value -*/ -NSPR_API(PRInt32) PR_AtomicSet(PRInt32 *val, PRInt32 newval); - -/* -** FUNCTION: PR_AtomicAdd -** DESCRIPTION: -** Atomically add a 32 bit value. -** INPUTS: -** ptr: a pointer to the value to increment -** val: value to be added -** RETURN: -** the returned value is the result of the addition -*/ -NSPR_API(PRInt32) PR_AtomicAdd(PRInt32 *ptr, PRInt32 val); - -/* -** MACRO: PR_ATOMIC_INCREMENT -** MACRO: PR_ATOMIC_DECREMENT -** MACRO: PR_ATOMIC_SET -** MACRO: PR_ATOMIC_ADD -** DESCRIPTION: -** Macro versions of the atomic operations. They may be implemented -** as compiler intrinsics. -** -** IMPORTANT NOTE TO NSPR MAINTAINERS: -** Implement these macros with compiler intrinsics only on platforms -** where the PR_AtomicXXX functions are truly atomic (i.e., where the -** configuration macro _PR_HAVE_ATOMIC_OPS is defined). Otherwise, -** the macros and functions won't be compatible and can't be used -** interchangeably. -*/ -#if defined(_WIN32) && !defined(_WIN32_WCE) && \ - (!defined(_MSC_VER) || (_MSC_VER >= 1310)) - -long __cdecl _InterlockedIncrement(long volatile *Addend); -long __cdecl _InterlockedDecrement(long volatile *Addend); -long __cdecl _InterlockedExchange(long volatile *Target, long Value); -long __cdecl _InterlockedExchangeAdd(long volatile *Addend, long Value); - -#ifdef _MSC_VER -#pragma intrinsic(_InterlockedIncrement) -#pragma intrinsic(_InterlockedDecrement) -#pragma intrinsic(_InterlockedExchange) -#pragma intrinsic(_InterlockedExchangeAdd) -#endif - -#define PR_ATOMIC_INCREMENT(val) _InterlockedIncrement((long volatile *)(val)) -#define PR_ATOMIC_DECREMENT(val) _InterlockedDecrement((long volatile *)(val)) -#define PR_ATOMIC_SET(val, newval) \ - _InterlockedExchange((long volatile *)(val), (long)(newval)) -#define PR_ATOMIC_ADD(ptr, val) \ - (_InterlockedExchangeAdd((long volatile *)(ptr), (long)(val)) + (val)) - -#elif ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && \ - ((defined(__APPLE__) && \ - (defined(__ppc__) || defined(__i386__) || defined(__x86_64__))) || \ - (defined(__linux__) && \ - ((defined(__i386__) && \ - defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \ - defined(__ia64__) || defined(__x86_64__) || \ - (defined(__powerpc__) && !defined(__powerpc64__)) || \ - (defined(__arm__) && \ - defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \ - defined(__alpha)))) - -/* - * Because the GCC manual warns that some processors may support - * reduced functionality of __sync_lock_test_and_set, we test for the - * processors that we believe support a full atomic exchange operation. - */ - -#define PR_ATOMIC_INCREMENT(val) __sync_add_and_fetch(val, 1) -#define PR_ATOMIC_DECREMENT(val) __sync_sub_and_fetch(val, 1) -#define PR_ATOMIC_SET(val, newval) __sync_lock_test_and_set(val, newval) -#define PR_ATOMIC_ADD(ptr, val) __sync_add_and_fetch(ptr, val) - -#else - -#define PR_ATOMIC_INCREMENT(val) PR_AtomicIncrement(val) -#define PR_ATOMIC_DECREMENT(val) PR_AtomicDecrement(val) -#define PR_ATOMIC_SET(val, newval) PR_AtomicSet(val, newval) -#define PR_ATOMIC_ADD(ptr, val) PR_AtomicAdd(ptr, val) - -#endif - -/* -** LIFO linked-list (stack) -*/ -typedef struct PRStackElemStr PRStackElem; - -struct PRStackElemStr { - PRStackElem *prstk_elem_next; /* next pointer MUST be at offset 0; - assembly language code relies on this */ -}; - -typedef struct PRStackStr PRStack; - -/* -** FUNCTION: PR_CreateStack -** DESCRIPTION: -** Create a stack, a LIFO linked list -** INPUTS: -** stack_name: a pointer to string containing the name of the stack -** RETURN: -** A pointer to the created stack, if successful, else NULL. -*/ -NSPR_API(PRStack *) PR_CreateStack(const char *stack_name); - -/* -** FUNCTION: PR_StackPush -** DESCRIPTION: -** Push an element on the top of the stack -** INPUTS: -** stack: pointer to the stack -** stack_elem: pointer to the stack element -** RETURN: -** None -*/ -NSPR_API(void) PR_StackPush(PRStack *stack, PRStackElem *stack_elem); - -/* -** FUNCTION: PR_StackPop -** DESCRIPTION: -** Remove the element on the top of the stack -** INPUTS: -** stack: pointer to the stack -** RETURN: -** A pointer to the stack element removed from the top of the stack, -** if non-empty, -** else NULL -*/ -NSPR_API(PRStackElem *) PR_StackPop(PRStack *stack); - -/* -** FUNCTION: PR_DestroyStack -** DESCRIPTION: -** Destroy the stack -** INPUTS: -** stack: pointer to the stack -** RETURN: -** PR_SUCCESS - if successfully deleted -** PR_FAILURE - if the stack is not empty -** PR_GetError will return -** PR_INVALID_STATE_ERROR - stack is not empty -*/ -NSPR_API(PRStatus) PR_DestroyStack(PRStack *stack); - -PR_END_EXTERN_C - -#endif /* pratom_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prbit.h nspr-4.10.7/mozilla/nsprpub/pr/include/prbit.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prbit.h 2012-03-06 13:13:42.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prbit.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prbit_h___ -#define prbit_h___ - -#include "prtypes.h" -PR_BEGIN_EXTERN_C - -/* replace compare/jump/add/shift sequence with x86 BSF/BSR instruction */ -#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64)) - unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask); - unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask); -# pragma intrinsic(_BitScanForward,_BitScanReverse) - __forceinline static int __prBitScanForward32(unsigned int val) - { - unsigned long idx; - _BitScanForward(&idx, (unsigned long)val); - return( (int)idx ); - } - __forceinline static int __prBitScanReverse32(unsigned int val) - { - unsigned long idx; - _BitScanReverse(&idx, (unsigned long)val); - return( (int)(31-idx) ); - } -# define pr_bitscan_ctz32(val) __prBitScanForward32(val) -# define pr_bitscan_clz32(val) __prBitScanReverse32(val) -# define PR_HAVE_BUILTIN_BITSCAN32 -#elif ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && \ - (defined(__i386__) || defined(__x86_64__) || defined(__arm__)) -# define pr_bitscan_ctz32(val) __builtin_ctz(val) -# define pr_bitscan_clz32(val) __builtin_clz(val) -# define PR_HAVE_BUILTIN_BITSCAN32 -#endif /* MSVC || GCC */ - -/* -** A prbitmap_t is a long integer that can be used for bitmaps -*/ -typedef unsigned long prbitmap_t; - -#define PR_TEST_BIT(_map,_bit) \ - ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] & (1L << ((_bit) & (PR_BITS_PER_LONG-1)))) -#define PR_SET_BIT(_map,_bit) \ - ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] |= (1L << ((_bit) & (PR_BITS_PER_LONG-1)))) -#define PR_CLEAR_BIT(_map,_bit) \ - ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] &= ~(1L << ((_bit) & (PR_BITS_PER_LONG-1)))) - -/* -** Compute the log of the least power of 2 greater than or equal to n -*/ -NSPR_API(PRIntn) PR_CeilingLog2(PRUint32 i); - -/* -** Compute the log of the greatest power of 2 less than or equal to n -*/ -NSPR_API(PRIntn) PR_FloorLog2(PRUint32 i); - -/* -** Macro version of PR_CeilingLog2: Compute the log of the least power of -** 2 greater than or equal to _n. The result is returned in _log2. -*/ -#ifdef PR_HAVE_BUILTIN_BITSCAN32 -#define PR_CEILING_LOG2(_log2,_n) \ - PR_BEGIN_MACRO \ - PRUint32 j_ = (PRUint32)(_n); \ - (_log2) = (j_ <= 1 ? 0 : 32 - pr_bitscan_clz32(j_ - 1)); \ - PR_END_MACRO -#else -#define PR_CEILING_LOG2(_log2,_n) \ - PR_BEGIN_MACRO \ - PRUint32 j_ = (PRUint32)(_n); \ - (_log2) = 0; \ - if ((j_) & ((j_)-1)) \ - (_log2) += 1; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - PR_END_MACRO -#endif /* PR_HAVE_BUILTIN_BITSCAN32 */ - -/* -** Macro version of PR_FloorLog2: Compute the log of the greatest power of -** 2 less than or equal to _n. The result is returned in _log2. -** -** This is equivalent to finding the highest set bit in the word. -*/ -#ifdef PR_HAVE_BUILTIN_BITSCAN32 -#define PR_FLOOR_LOG2(_log2,_n) \ - PR_BEGIN_MACRO \ - PRUint32 j_ = (PRUint32)(_n); \ - (_log2) = 31 - pr_bitscan_clz32((j_) | 1); \ - PR_END_MACRO -#else -#define PR_FLOOR_LOG2(_log2,_n) \ - PR_BEGIN_MACRO \ - PRUint32 j_ = (PRUint32)(_n); \ - (_log2) = 0; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - PR_END_MACRO -#endif /* PR_HAVE_BUILTIN_BITSCAN32 */ - -/* -** Macros for rotate left and right. The argument 'a' must be an unsigned -** 32-bit integer type such as PRUint32. -** -** There is no rotate operation in the C Language, so the construct -** (a << 4) | (a >> 28) is frequently used instead. Most compilers convert -** this to a rotate instruction, but MSVC doesn't without a little help. -** To get MSVC to generate a rotate instruction, we have to use the _rotl -** or _rotr intrinsic and use a pragma to make it inline. -** -** Note: MSVC in VS2005 will do an inline rotate instruction on the above -** construct. -*/ - -#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \ - defined(_M_X64)) -#include -#pragma intrinsic(_rotl, _rotr) -#define PR_ROTATE_LEFT32(a, bits) _rotl(a, bits) -#define PR_ROTATE_RIGHT32(a, bits) _rotr(a, bits) -#else -#define PR_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits)))) -#define PR_ROTATE_RIGHT32(a, bits) (((a) >> (bits)) | ((a) << (32 - (bits)))) -#endif - -PR_END_EXTERN_C -#endif /* prbit_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prclist.h nspr-4.10.7/mozilla/nsprpub/pr/include/prclist.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prclist.h 2012-03-06 13:13:42.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prclist.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prclist_h___ -#define prclist_h___ - -#include "prtypes.h" - -typedef struct PRCListStr PRCList; - -/* -** Circular linked list -*/ -struct PRCListStr { - PRCList *next; - PRCList *prev; -}; - -/* -** Insert element "_e" into the list, before "_l". -*/ -#define PR_INSERT_BEFORE(_e,_l) \ - PR_BEGIN_MACRO \ - (_e)->next = (_l); \ - (_e)->prev = (_l)->prev; \ - (_l)->prev->next = (_e); \ - (_l)->prev = (_e); \ - PR_END_MACRO - -/* -** Insert element "_e" into the list, after "_l". -*/ -#define PR_INSERT_AFTER(_e,_l) \ - PR_BEGIN_MACRO \ - (_e)->next = (_l)->next; \ - (_e)->prev = (_l); \ - (_l)->next->prev = (_e); \ - (_l)->next = (_e); \ - PR_END_MACRO - -/* -** Return the element following element "_e" -*/ -#define PR_NEXT_LINK(_e) \ - ((_e)->next) -/* -** Return the element preceding element "_e" -*/ -#define PR_PREV_LINK(_e) \ - ((_e)->prev) - -/* -** Append an element "_e" to the end of the list "_l" -*/ -#define PR_APPEND_LINK(_e,_l) PR_INSERT_BEFORE(_e,_l) - -/* -** Insert an element "_e" at the head of the list "_l" -*/ -#define PR_INSERT_LINK(_e,_l) PR_INSERT_AFTER(_e,_l) - -/* Return the head/tail of the list */ -#define PR_LIST_HEAD(_l) (_l)->next -#define PR_LIST_TAIL(_l) (_l)->prev - -/* -** Remove the element "_e" from it's circular list. -*/ -#define PR_REMOVE_LINK(_e) \ - PR_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - PR_END_MACRO - -/* -** Remove the element "_e" from it's circular list. Also initializes the -** linkage. -*/ -#define PR_REMOVE_AND_INIT_LINK(_e) \ - PR_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - (_e)->next = (_e); \ - (_e)->prev = (_e); \ - PR_END_MACRO - -/* -** Return non-zero if the given circular list "_l" is empty, zero if the -** circular list is not empty -*/ -#define PR_CLIST_IS_EMPTY(_l) \ - ((_l)->next == (_l)) - -/* -** Initialize a circular list -*/ -#define PR_INIT_CLIST(_l) \ - PR_BEGIN_MACRO \ - (_l)->next = (_l); \ - (_l)->prev = (_l); \ - PR_END_MACRO - -#define PR_INIT_STATIC_CLIST(_l) \ - {(_l), (_l)} - -#endif /* prclist_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prcmon.h nspr-4.10.7/mozilla/nsprpub/pr/include/prcmon.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prcmon.h 2012-03-06 13:13:43.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prcmon.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prcmon_h___ -#define prcmon_h___ - -/* -** Interface to cached monitors. Cached monitors use an address to find a -** given PR monitor. In this way a monitor can be associated with another -** object without preallocating a monitor for all objects. -** -** A hash table is used to quickly map addresses to individual monitors -** and the system automatically grows the hash table as needed. -** -** Cache monitors are about 5 times slower to use than uncached monitors. -*/ -#include "prmon.h" -#include "prinrval.h" - -PR_BEGIN_EXTERN_C - -/** -** Like PR_EnterMonitor except use the "address" to find a monitor in the -** monitor cache. If successful, returns the PRMonitor now associated -** with "address". Note that you must PR_CExitMonitor the address to -** release the monitor cache entry (otherwise the monitor cache will fill -** up). This call will return NULL if the monitor cache needs to be -** expanded and the system is out of memory. -*/ -NSPR_API(PRMonitor*) PR_CEnterMonitor(void *address); - -/* -** Like PR_ExitMonitor except use the "address" to find a monitor in the -** monitor cache. -*/ -NSPR_API(PRStatus) PR_CExitMonitor(void *address); - -/* -** Like PR_Wait except use the "address" to find a monitor in the -** monitor cache. -*/ -NSPR_API(PRStatus) PR_CWait(void *address, PRIntervalTime timeout); - -/* -** Like PR_Notify except use the "address" to find a monitor in the -** monitor cache. -*/ -NSPR_API(PRStatus) PR_CNotify(void *address); - -/* -** Like PR_NotifyAll except use the "address" to find a monitor in the -** monitor cache. -*/ -NSPR_API(PRStatus) PR_CNotifyAll(void *address); - -/* -** Set a callback to be invoked each time a monitor is recycled from the cache -** freelist, with the monitor's cache-key passed in address. -*/ -NSPR_API(void) PR_CSetOnMonitorRecycle(void (PR_CALLBACK *callback)(void *address)); - -PR_END_EXTERN_C - -#endif /* prcmon_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prcountr.h nspr-4.10.7/mozilla/nsprpub/pr/include/prcountr.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prcountr.h 2012-03-06 13:13:43.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prcountr.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,525 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prcountr_h___ -#define prcountr_h___ - -/*---------------------------------------------------------------------------- -** prcountr.h -- NSPR Instrumentation counters -** -** The NSPR Counter Feature provides a means to "count -** something." Counters can be dynamically defined, incremented, -** decremented, set, and deleted under application program -** control. -** -** The Counter Feature is intended to be used as instrumentation, -** not as operational data. If you need a counter for operational -** data, use native integral types. -** -** Counters are 32bit unsigned intergers. On overflow, a counter -** will wrap. No exception is recognized or reported. -** -** A counter can be dynamically created using a two level naming -** convention. A "handle" is returned when the counter is -** created. The counter can subsequently be addressed by its -** handle. An API is provided to get an existing counter's handle -** given the names with which it was originally created. -** Similarly, a counter's name can be retrieved given its handle. -** -** The counter naming convention is a two-level hierarchy. The -** QName is the higher level of the hierarchy; RName is the -** lower level. RNames can be thought of as existing within a -** QName. The same RName can exist within multiple QNames. QNames -** are unique. The NSPR Counter is not a near-zero overhead -** feature. Application designers should be aware of -** serialization issues when using the Counter API. Creating a -** counter locks a large asset, potentially causing a stall. This -** suggest that applications should create counters at component -** initialization, for example, and not create and destroy them -** willy-nilly. ... You have been warned. -** -** Incrementing and Adding to counters uses atomic operations. -** The performance of these operations will vary from platform -** to platform. On platforms where atomic operations are not -** supported the overhead may be substantial. -** -** When traversing the counter database with FindNext functions, -** the instantaneous values of any given counter is that at the -** moment of extraction. The state of the entire counter database -** may not be viewed as atomic. -** -** The counter interface may be disabled (No-Op'd) at compile -** time. When DEBUG is defined at compile time, the Counter -** Feature is compiled into NSPR and applications invoking it. -** When DEBUG is not defined, the counter macros compile to -** nothing. To force the Counter Feature to be compiled into an -** optimized build, define FORCE_NSPR_COUNTERS at compile time -** for both NSPR and the application intending to use it. -** -** Application designers should use the macro form of the Counter -** Feature methods to minimize performance impact in optimized -** builds. The macros normally compile to nothing on optimized -** builds. -** -** Application designers should be aware of the effects of -** debug and optimized build differences when using result of the -** Counter Feature macros in expressions. -** -** The Counter Feature is thread-safe and SMP safe. -** -** /lth. 09-Jun-1998. -*/ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* -** Opaque counter handle type. -** ... don't even think of looking in here. -** -*/ -typedef void * PRCounterHandle; - -#define PRCOUNTER_NAME_MAX 31 -#define PRCOUNTER_DESC_MAX 255 - - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_DEFINE_COUNTER() -- Define a PRCounterHandle -** -** DESCRIPTION: PR_DEFINE_COUNTER() is used to define a counter -** handle. -** -*/ -#define PR_DEFINE_COUNTER(name) PRCounterHandle name - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_INIT_COUNTER_HANDLE() -- Set the value of a PRCounterHandle -** -** DESCRIPTION: -** PR_INIT_COUNTER_HANDLE() sets the value of a PRCounterHandle -** to value. -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_INIT_COUNTER_HANDLE(handle,value)\ - (handle) = (PRCounterHandle)(value) -#else -#define PR_INIT_COUNTER_HANDLE(handle,value) -#endif - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_CreateCounter() -- Create a counter -** -** DESCRIPTION: PR_CreateCounter() creates a counter object and -** initializes it to zero. -** -** The macro form takes as its first argument the name of the -** PRCounterHandle to receive the handle returned from -** PR_CreateCounter(). -** -** INPUTS: -** qName: The QName for the counter object. The maximum length -** of qName is defined by PRCOUNTER_NAME_MAX -** -** rName: The RName for the counter object. The maximum length -** of qName is defined by PRCOUNTER_NAME_MAX -** -** descrioption: The description of the counter object. The -** maximum length of description is defined by -** PRCOUNTER_DESC_MAX. -** -** OUTPUTS: -** -** RETURNS: -** PRCounterHandle. -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_CREATE_COUNTER(handle,qName,rName,description)\ - (handle) = PR_CreateCounter((qName),(rName),(description)) -#else -#define PR_CREATE_COUNTER(handle,qName,rName,description) -#endif - -NSPR_API(PRCounterHandle) - PR_CreateCounter( - const char *qName, - const char *rName, - const char *description -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_DestroyCounter() -- Destroy a counter object. -** -** DESCRIPTION: PR_DestroyCounter() removes a counter and -** unregisters its handle from the counter database. -** -** INPUTS: -** handle: the PRCounterHandle of the counter to be destroyed. -** -** OUTPUTS: -** The counter is destroyed. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_DESTROY_COUNTER(handle) PR_DestroyCounter((handle)) -#else -#define PR_DESTROY_COUNTER(handle) -#endif - -NSPR_API(void) - PR_DestroyCounter( - PRCounterHandle handle -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_GetCounterHandleFromName() -- Retreive a -** counter's handle give its name. -** -** DESCRIPTION: PR_GetCounterHandleFromName() retreives a -** counter's handle from the counter database, given the name -** the counter was originally created with. -** -** INPUTS: -** qName: Counter's original QName. -** rName: Counter's original RName. -** -** OUTPUTS: -** -** RETURNS: -** PRCounterHandle or PRCounterError. -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)\ - (handle) = PR_GetCounterHandleFromName((qName),(rName)) -#else -#define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName) -#endif - -NSPR_API(PRCounterHandle) - PR_GetCounterHandleFromName( - const char *qName, - const char *rName -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_GetCounterNameFromHandle() -- Retreive a -** counter's name, given its handle. -** -** DESCRIPTION: PR_GetCounterNameFromHandle() retreives a -** counter's name given its handle. -** -** INPUTS: -** qName: Where to store a pointer to qName. -** rName: Where to store a pointer to rName. -** description: Where to store a pointer to description. -** -** OUTPUTS: Pointers to the Counter Feature's copies of the names -** used when the counters were created. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description)\ - PR_GetCounterNameFromHandle((handle),(qName),(rName),(description)) -#else -#define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description ) -#endif - -NSPR_API(void) - PR_GetCounterNameFromHandle( - PRCounterHandle handle, - const char **qName, - const char **rName, - const char **description -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_IncrementCounter() -- Add one to the referenced -** counter. -** -** DESCRIPTION: Add one to the referenced counter. -** -** INPUTS: -** handle: The PRCounterHandle of the counter to be incremented -** -** OUTPUTS: The counter is incrementd. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_INCREMENT_COUNTER(handle) PR_IncrementCounter(handle) -#else -#define PR_INCREMENT_COUNTER(handle) -#endif - -NSPR_API(void) - PR_IncrementCounter( - PRCounterHandle handle -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_DecrementCounter() -- Subtract one from the -** referenced counter -** -** DESCRIPTION: Subtract one from the referenced counter. -** -** INPUTS: -** handle: The PRCounterHandle of the coutner to be -** decremented. -** -** OUTPUTS: the counter is decremented. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_DECREMENT_COUNTER(handle) PR_DecrementCounter(handle) -#else -#define PR_DECREMENT_COUNTER(handle) -#endif - -NSPR_API(void) - PR_DecrementCounter( - PRCounterHandle handle -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_AddToCounter() -- Add a value to a counter. -** -** DESCRIPTION: Add value to the counter referenced by handle. -** -** INPUTS: -** handle: the PRCounterHandle of the counter to be added to. -** -** value: the value to be added to the counter. -** -** OUTPUTS: new value for counter. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_ADD_TO_COUNTER(handle,value)\ - PR_AddToCounter((handle),(value)) -#else -#define PR_ADD_TO_COUNTER(handle,value) -#endif - -NSPR_API(void) - PR_AddToCounter( - PRCounterHandle handle, - PRUint32 value -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_SubtractFromCounter() -- A value is subtracted -** from a counter. -** -** DESCRIPTION: -** Subtract a value from a counter. -** -** INPUTS: -** handle: the PRCounterHandle of the counter to be subtracted -** from. -** -** value: the value to be subtracted from the counter. -** -** OUTPUTS: new value for counter -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_SUBTRACT_FROM_COUNTER(handle,value)\ - PR_SubtractFromCounter((handle),(value)) -#else -#define PR_SUBTRACT_FROM_COUNTER(handle,value) -#endif - -NSPR_API(void) - PR_SubtractFromCounter( - PRCounterHandle handle, - PRUint32 value -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_GetCounter() -- Retreive the value of a counter -** -** DESCRIPTION: -** Retreive the value of a counter. -** -** INPUTS: -** handle: the PR_CounterHandle of the counter to be retreived -** -** OUTPUTS: -** -** RETURNS: The value of the referenced counter -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_GET_COUNTER(counter,handle)\ - (counter) = PR_GetCounter((handle)) -#else -#define PR_GET_COUNTER(counter,handle) 0 -#endif - -NSPR_API(PRUint32) - PR_GetCounter( - PRCounterHandle handle -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_SetCounter() -- Replace the content of counter -** with value. -** -** DESCRIPTION: The contents of the referenced counter are -** replaced by value. -** -** INPUTS: -** handle: the PRCounterHandle of the counter whose contents -** are to be replaced. -** -** value: the new value of the counter. -** -** OUTPUTS: -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_SET_COUNTER(handle,value) PR_SetCounter((handle),(value)) -#else -#define PR_SET_COUNTER(handle,value) -#endif - -NSPR_API(void) - PR_SetCounter( - PRCounterHandle handle, - PRUint32 value -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_FindNextCounterQname() -- Retreive the next QName counter -** handle iterator -** -** DESCRIPTION: -** PR_FindNextCounterQname() retreives the first or next Qname -** the counter data base, depending on the value of handle. When -** handle is NULL, the function attempts to retreive the first -** QName handle in the database. When handle is a handle previosly -** retreived QName handle, then the function attempts to retreive -** the next QName handle. -** -** INPUTS: -** handle: PRCounterHandle or NULL. -** -** OUTPUTS: returned -** -** RETURNS: PRCounterHandle or NULL when no more QName counter -** handles are present. -** -** RESTRICTIONS: -** A concurrent PR_CreateCounter() or PR_DestroyCounter() may -** cause unpredictable results. -** -** A PRCounterHandle returned from this function may only be used -** in another PR_FindNextCounterQname() function call; other -** operations may cause unpredictable results. -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_FIND_NEXT_COUNTER_QNAME(next,handle)\ - (next) = PR_FindNextCounterQname((handle)) -#else -#define PR_FIND_NEXT_COUNTER_QNAME(next,handle) NULL -#endif - -NSPR_API(PRCounterHandle) - PR_FindNextCounterQname( - PRCounterHandle handle -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_FindNextCounterRname() -- Retreive the next RName counter -** handle iterator -** -** DESCRIPTION: -** PR_FindNextCounterRname() retreives the first or next RNname -** handle from the counter data base, depending on the -** value of handle. When handle is NULL, the function attempts to -** retreive the first RName handle in the database. When handle is -** a handle previosly retreived RName handle, then the function -** attempts to retreive the next RName handle. -** -** INPUTS: -** handle: PRCounterHandle or NULL. -** qhandle: PRCounterHandle of a previously aquired via -** PR_FIND_NEXT_QNAME_HANDLE() -** -** OUTPUTS: returned -** -** RETURNS: PRCounterHandle or NULL when no more RName counter -** handles are present. -** -** RESTRICTIONS: -** A concurrent PR_CreateCounter() or PR_DestroyCounter() may -** cause unpredictable results. -** -** A PRCounterHandle returned from this function may only be used -** in another PR_FindNextCounterRname() function call; other -** operations may cause unpredictable results. -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) -#define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)\ - (next) = PR_FindNextCounterRname((rhandle),(qhandle)) -#else -#define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle) -#endif - -NSPR_API(PRCounterHandle) - PR_FindNextCounterRname( - PRCounterHandle rhandle, - PRCounterHandle qhandle -); - -PR_END_EXTERN_C - -#endif /* prcountr_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prcvar.h nspr-4.10.7/mozilla/nsprpub/pr/include/prcvar.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prcvar.h 2012-03-06 13:13:43.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prcvar.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prcvar_h___ -#define prcvar_h___ - -#include "prlock.h" -#include "prinrval.h" - -PR_BEGIN_EXTERN_C - -typedef struct PRCondVar PRCondVar; - -/* -** Create a new condition variable. -** -** "lock" is the lock used to protect the condition variable. -** -** Condition variables are synchronization objects that threads can use -** to wait for some condition to occur. -** -** This may fail if memory is tight or if some operating system resource -** is low. In such cases, a NULL will be returned. -*/ -NSPR_API(PRCondVar*) PR_NewCondVar(PRLock *lock); - -/* -** Destroy a condition variable. There must be no thread -** waiting on the condvar. The caller is responsible for guaranteeing -** that the condvar is no longer in use. -** -*/ -NSPR_API(void) PR_DestroyCondVar(PRCondVar *cvar); - -/* -** The thread that waits on a condition is blocked in a "waiting on -** condition" state until another thread notifies the condition or a -** caller specified amount of time expires. The lock associated with -** the condition variable will be released, which must have be held -** prior to the call to wait. -** -** Logically a notified thread is moved from the "waiting on condition" -** state and made "ready." When scheduled, it will attempt to reacquire -** the lock that it held when wait was called. -** -** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and -** PR_INTERVAL_NO_WAIT. The former value requires that a condition be -** notified (or the thread interrupted) before it will resume from the -** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect -** is to release the lock, possibly causing a rescheduling within the -** runtime, then immediately attempting to reacquire the lock and resume. -** -** Any other value for timeout will cause the thread to be rescheduled -** either due to explicit notification or an expired interval. The latter -** must be determined by treating time as one part of the monitored data -** being protected by the lock and tested explicitly for an expired -** interval. -** -** Returns PR_FAILURE if the caller has not locked the lock associated -** with the condition variable or the thread was interrupted (PR_Interrupt()). -** The particular reason can be extracted with PR_GetError(). -*/ -NSPR_API(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout); - -/* -** Notify ONE thread that is currently waiting on 'cvar'. Which thread is -** dependent on the implementation of the runtime. Common sense would dictate -** that all threads waiting on a single condition have identical semantics, -** therefore which one gets notified is not significant. -** -** The calling thead must hold the lock that protects the condition, as -** well as the invariants that are tightly bound to the condition, when -** notify is called. -** -** Returns PR_FAILURE if the caller has not locked the lock associated -** with the condition variable. -*/ -NSPR_API(PRStatus) PR_NotifyCondVar(PRCondVar *cvar); - -/* -** Notify all of the threads waiting on the condition variable. The order -** that the threads are notified is indeterminant. The lock that protects -** the condition must be held. -** -** Returns PR_FAILURE if the caller has not locked the lock associated -** with the condition variable. -*/ -NSPR_API(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar); - -PR_END_EXTERN_C - -#endif /* prcvar_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prdtoa.h nspr-4.10.7/mozilla/nsprpub/pr/include/prdtoa.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prdtoa.h 2012-03-06 13:13:43.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prdtoa.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prdtoa_h___ -#define prdtoa_h___ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* -** PR_strtod() returns as a double-precision floating-point number -** the value represented by the character string pointed to by -** s00. The string is scanned up to the first unrecognized -** character. -**a -** If the value of se is not (char **)NULL, a pointer to -** the character terminating the scan is returned in the location pointed -** to by se. If no number can be formed, se is set to s00, and -** zero is returned. -*/ -NSPR_API(PRFloat64) -PR_strtod(const char *s00, char **se); - -/* -** PR_cnvtf() -** conversion routines for floating point -** prcsn - number of digits of precision to generate floating -** point value. -*/ -NSPR_API(void) PR_cnvtf(char *buf, PRIntn bufsz, PRIntn prcsn, PRFloat64 fval); - -/* -** PR_dtoa() converts double to a string. -** -** ARGUMENTS: -** If rve is not null, *rve is set to point to the end of the return value. -** If d is +-Infinity or NaN, then *decpt is set to 9999. -** -** mode: -** 0 ==> shortest string that yields d when read in -** and rounded to nearest. -*/ -NSPR_API(PRStatus) PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits, - PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize); - -PR_END_EXTERN_C - -#endif /* prdtoa_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prenv.h nspr-4.10.7/mozilla/nsprpub/pr/include/prenv.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prenv.h 2012-03-06 13:13:43.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prenv.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prenv_h___ -#define prenv_h___ - -#include "prtypes.h" - -/*******************************************************************************/ -/*******************************************************************************/ -/****************** THESE FUNCTIONS MAY NOT BE THREAD SAFE *********************/ -/*******************************************************************************/ -/*******************************************************************************/ - -PR_BEGIN_EXTERN_C - -/* -** PR_GetEnv() -- Retrieve value of environment variable -** -** Description: -** PR_GetEnv() is modeled on Unix getenv(). -** -** -** Inputs: -** var -- The name of the environment variable -** -** Returns: -** The value of the environment variable 'var' or NULL if -** the variable is undefined. -** -** Restrictions: -** You'd think that a POSIX getenv(), putenv() would be -** consistently implemented everywhere. Surprise! It is not. On -** some platforms, a putenv() where the argument is of -** the form "name" causes the named environment variable to -** be un-set; that is: a subsequent getenv() returns NULL. On -** other platforms, the putenv() fails, on others, it is a -** no-op. Similarly, a putenv() where the argument is of the -** form "name=" causes the named environment variable to be -** un-set; a subsequent call to getenv() returns NULL. On -** other platforms, a subsequent call to getenv() returns a -** pointer to a null-string (a byte of zero). -** -** PR_GetEnv(), PR_SetEnv() provide a consistent behavior -** across all supported platforms. There are, however, some -** restrictions and some practices you must use to achieve -** consistent results everywhere. -** -** When manipulating the environment there is no way to un-set -** an environment variable across all platforms. We suggest -** you interpret the return of a pointer to null-string to -** mean the same as a return of NULL from PR_GetEnv(). -** -** A call to PR_SetEnv() where the parameter is of the form -** "name" will return PR_FAILURE; the environment remains -** unchanged. A call to PR_SetEnv() where the parameter is -** of the form "name=" may un-set the envrionment variable on -** some platforms; on others it may set the value of the -** environment variable to the null-string. -** -** For example, to test for NULL return or return of the -** null-string from PR_GetEnv(), use the following code -** fragment: -** -** char *val = PR_GetEnv("foo"); -** if ((NULL == val) || ('\0' == *val)) { -** ... interpret this as un-set ... -** } -** -** The caller must ensure that the string passed -** to PR_SetEnv() is persistent. That is: The string should -** not be on the stack, where it can be overwritten -** on return from the function calling PR_SetEnv(). -** Similarly, the string passed to PR_SetEnv() must not be -** overwritten by other actions of the process. ... Some -** platforms use the string by reference rather than copying -** it into the environment space. ... You have been warned! -** -** Use of platform-native functions that manipulate the -** environment (getenv(), putenv(), -** SetEnvironmentVariable(), etc.) must not be used with -** NSPR's similar functions. The platform-native functions -** may not be thread safe and/or may operate on different -** conceptual environment space than that operated upon by -** NSPR's functions or other environment manipulating -** functions on the same platform. (!) -** -*/ -NSPR_API(char*) PR_GetEnv(const char *var); - -/* -** PR_SetEnv() -- set, unset or change an environment variable -** -** Description: -** PR_SetEnv() is modeled on the Unix putenv() function. -** -** Inputs: -** string -- pointer to a caller supplied -** constant, persistent string of the form name=value. Where -** name is the name of the environment variable to be set or -** changed; value is the value assigned to the variable. -** -** Returns: -** PRStatus. -** -** Restrictions: -** See the Restrictions documented in the description of -** PR_GetEnv() in this header file. -** -** -*/ -NSPR_API(PRStatus) PR_SetEnv(const char *string); - -PR_END_EXTERN_C - -#endif /* prenv_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prerr.h nspr-4.10.7/mozilla/nsprpub/pr/include/prerr.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prerr.h 2012-03-06 13:13:43.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prerr.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,249 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prerr_h___ -#define prerr_h___ - -/* - * - * prerr.h - * This file is automatically generated; please do not edit it. - */ - -/* Memory allocation attempt failed */ -#define PR_OUT_OF_MEMORY_ERROR (-6000L) - -/* Invalid file descriptor */ -#define PR_BAD_DESCRIPTOR_ERROR (-5999L) - -/* The operation would have blocked */ -#define PR_WOULD_BLOCK_ERROR (-5998L) - -/* Invalid memory address argument */ -#define PR_ACCESS_FAULT_ERROR (-5997L) - -/* Invalid function for file type */ -#define PR_INVALID_METHOD_ERROR (-5996L) - -/* Invalid memory address argument */ -#define PR_ILLEGAL_ACCESS_ERROR (-5995L) - -/* Some unknown error has occurred */ -#define PR_UNKNOWN_ERROR (-5994L) - -/* Operation interrupted by another thread */ -#define PR_PENDING_INTERRUPT_ERROR (-5993L) - -/* function not implemented */ -#define PR_NOT_IMPLEMENTED_ERROR (-5992L) - -/* I/O function error */ -#define PR_IO_ERROR (-5991L) - -/* I/O operation timed out */ -#define PR_IO_TIMEOUT_ERROR (-5990L) - -/* I/O operation on busy file descriptor */ -#define PR_IO_PENDING_ERROR (-5989L) - -/* The directory could not be opened */ -#define PR_DIRECTORY_OPEN_ERROR (-5988L) - -/* Invalid function argument */ -#define PR_INVALID_ARGUMENT_ERROR (-5987L) - -/* Network address not available (in use?) */ -#define PR_ADDRESS_NOT_AVAILABLE_ERROR (-5986L) - -/* Network address type not supported */ -#define PR_ADDRESS_NOT_SUPPORTED_ERROR (-5985L) - -/* Already connected */ -#define PR_IS_CONNECTED_ERROR (-5984L) - -/* Network address is invalid */ -#define PR_BAD_ADDRESS_ERROR (-5983L) - -/* Local Network address is in use */ -#define PR_ADDRESS_IN_USE_ERROR (-5982L) - -/* Connection refused by peer */ -#define PR_CONNECT_REFUSED_ERROR (-5981L) - -/* Network address is presently unreachable */ -#define PR_NETWORK_UNREACHABLE_ERROR (-5980L) - -/* Connection attempt timed out */ -#define PR_CONNECT_TIMEOUT_ERROR (-5979L) - -/* Network file descriptor is not connected */ -#define PR_NOT_CONNECTED_ERROR (-5978L) - -/* Failure to load dynamic library */ -#define PR_LOAD_LIBRARY_ERROR (-5977L) - -/* Failure to unload dynamic library */ -#define PR_UNLOAD_LIBRARY_ERROR (-5976L) - -/* Symbol not found in any of the loaded dynamic libraries */ -#define PR_FIND_SYMBOL_ERROR (-5975L) - -/* Insufficient system resources */ -#define PR_INSUFFICIENT_RESOURCES_ERROR (-5974L) - -/* A directory lookup on a network address has failed */ -#define PR_DIRECTORY_LOOKUP_ERROR (-5973L) - -/* Attempt to access a TPD key that is out of range */ -#define PR_TPD_RANGE_ERROR (-5972L) - -/* Process open FD table is full */ -#define PR_PROC_DESC_TABLE_FULL_ERROR (-5971L) - -/* System open FD table is full */ -#define PR_SYS_DESC_TABLE_FULL_ERROR (-5970L) - -/* Network operation attempted on non-network file descriptor */ -#define PR_NOT_SOCKET_ERROR (-5969L) - -/* TCP-specific function attempted on a non-TCP file descriptor */ -#define PR_NOT_TCP_SOCKET_ERROR (-5968L) - -/* TCP file descriptor is already bound */ -#define PR_SOCKET_ADDRESS_IS_BOUND_ERROR (-5967L) - -/* Access Denied */ -#define PR_NO_ACCESS_RIGHTS_ERROR (-5966L) - -/* The requested operation is not supported by the platform */ -#define PR_OPERATION_NOT_SUPPORTED_ERROR (-5965L) - -/* The host operating system does not support the protocol requested */ -#define PR_PROTOCOL_NOT_SUPPORTED_ERROR (-5964L) - -/* Access to the remote file has been severed */ -#define PR_REMOTE_FILE_ERROR (-5963L) - -/* The value requested is too large to be stored in the data buffer provided */ -#define PR_BUFFER_OVERFLOW_ERROR (-5962L) - -/* TCP connection reset by peer */ -#define PR_CONNECT_RESET_ERROR (-5961L) - -/* Unused */ -#define PR_RANGE_ERROR (-5960L) - -/* The operation would have deadlocked */ -#define PR_DEADLOCK_ERROR (-5959L) - -/* The file is already locked */ -#define PR_FILE_IS_LOCKED_ERROR (-5958L) - -/* Write would result in file larger than the system allows */ -#define PR_FILE_TOO_BIG_ERROR (-5957L) - -/* The device for storing the file is full */ -#define PR_NO_DEVICE_SPACE_ERROR (-5956L) - -/* Unused */ -#define PR_PIPE_ERROR (-5955L) - -/* Unused */ -#define PR_NO_SEEK_DEVICE_ERROR (-5954L) - -/* Cannot perform a normal file operation on a directory */ -#define PR_IS_DIRECTORY_ERROR (-5953L) - -/* Symbolic link loop */ -#define PR_LOOP_ERROR (-5952L) - -/* File name is too long */ -#define PR_NAME_TOO_LONG_ERROR (-5951L) - -/* File not found */ -#define PR_FILE_NOT_FOUND_ERROR (-5950L) - -/* Cannot perform directory operation on a normal file */ -#define PR_NOT_DIRECTORY_ERROR (-5949L) - -/* Cannot write to a read-only file system */ -#define PR_READ_ONLY_FILESYSTEM_ERROR (-5948L) - -/* Cannot delete a directory that is not empty */ -#define PR_DIRECTORY_NOT_EMPTY_ERROR (-5947L) - -/* Cannot delete or rename a file object while the file system is busy */ -#define PR_FILESYSTEM_MOUNTED_ERROR (-5946L) - -/* Cannot rename a file to a file system on another device */ -#define PR_NOT_SAME_DEVICE_ERROR (-5945L) - -/* The directory object in the file system is corrupted */ -#define PR_DIRECTORY_CORRUPTED_ERROR (-5944L) - -/* Cannot create or rename a filename that already exists */ -#define PR_FILE_EXISTS_ERROR (-5943L) - -/* Directory is full. No additional filenames may be added */ -#define PR_MAX_DIRECTORY_ENTRIES_ERROR (-5942L) - -/* The required device was in an invalid state */ -#define PR_INVALID_DEVICE_STATE_ERROR (-5941L) - -/* The device is locked */ -#define PR_DEVICE_IS_LOCKED_ERROR (-5940L) - -/* No more entries in the directory */ -#define PR_NO_MORE_FILES_ERROR (-5939L) - -/* Encountered end of file */ -#define PR_END_OF_FILE_ERROR (-5938L) - -/* Seek error */ -#define PR_FILE_SEEK_ERROR (-5937L) - -/* The file is busy */ -#define PR_FILE_IS_BUSY_ERROR (-5936L) - -/* The I/O operation was aborted */ -#define PR_OPERATION_ABORTED_ERROR (-5935L) - -/* Operation is still in progress (probably a non-blocking connect) */ -#define PR_IN_PROGRESS_ERROR (-5934L) - -/* Operation has already been initiated (probably a non-blocking connect) */ -#define PR_ALREADY_INITIATED_ERROR (-5933L) - -/* The wait group is empty */ -#define PR_GROUP_EMPTY_ERROR (-5932L) - -/* Object state improper for request */ -#define PR_INVALID_STATE_ERROR (-5931L) - -/* Network is down */ -#define PR_NETWORK_DOWN_ERROR (-5930L) - -/* Socket shutdown */ -#define PR_SOCKET_SHUTDOWN_ERROR (-5929L) - -/* Connection aborted */ -#define PR_CONNECT_ABORTED_ERROR (-5928L) - -/* Host is unreachable */ -#define PR_HOST_UNREACHABLE_ERROR (-5927L) - -/* The library is not loaded */ -#define PR_LIBRARY_NOT_LOADED_ERROR (-5926L) - -/* The one-time function was previously called and failed. Its error code is no longer available */ -#define PR_CALL_ONCE_ERROR (-5925L) - -/* Placeholder for the end of the list */ -#define PR_MAX_ERROR (-5924L) - -extern void nspr_InitializePRErrorTable(void); -#define ERROR_TABLE_BASE_nspr (-6000L) - -#endif /* prerr_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prerror.h nspr-4.10.7/mozilla/nsprpub/pr/include/prerror.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prerror.h 2012-03-06 13:13:44.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prerror.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,294 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prerror_h___ -#define prerror_h___ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -typedef PRInt32 PRErrorCode; - -#define PR_NSPR_ERROR_BASE -6000 - -#include "prerr.h" - -/* -** Set error will preserve an error condition within a thread context. -** The values stored are the NSPR (platform independent) translation of -** the error. Also, if available, the platform specific oserror is stored. -** If there is no appropriate OS error number, a zero my be supplied. -*/ -NSPR_API(void) PR_SetError(PRErrorCode errorCode, PRInt32 oserr); - -/* -** The text value specified may be NULL. If it is not NULL and the text length -** is zero, the string is assumed to be a null terminated C string. Otherwise -** the text is assumed to be the length specified and possibly include NULL -** characters (e.g., a multi-national string). -** -** The text will be copied into to thread structure and remain there -** until the next call to PR_SetError. -*/ -NSPR_API(void) PR_SetErrorText( - PRIntn textLength, const char *text); - -/* -** Return the current threads last set error code. -*/ -NSPR_API(PRErrorCode) PR_GetError(void); - -/* -** Return the current threads last set os error code. This is used for -** machine specific code that desires the underlying os error. -*/ -NSPR_API(PRInt32) PR_GetOSError(void); - -/* -** Get the length of the error text. If a zero is returned, then there -** is no text. Otherwise, the value returned is sufficient to contain -** the error text currently available. -*/ -NSPR_API(PRInt32) PR_GetErrorTextLength(void); - -/* -** Copy the current threads current error text. Then actual number of bytes -** copied is returned as the result. If the result is zero, the 'text' area -** is unaffected. -*/ -NSPR_API(PRInt32) PR_GetErrorText(char *text); - - -/* -Copyright (C) 1987, 1988 Student Information Processing Board of the -Massachusetts Institute of Technology. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be -used in advertising or publicity pertaining to distribution of the software -without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B. -make no representations about the suitability of this software for any -purpose. It is provided "as is" without express or implied warranty. -*/ - - -/* - * NOTE: - * The interfaces for error-code-translation described in the rest of - * this file are preliminary in the 3.1 release of nspr and are subject - * to change in future releases. - */ - -/* -** Description: Localizable error code to string function. -** -** -** NSPR provides a mechanism for converting an error code to a -** descriptive string, in a caller-specified language. -** -** Error codes themselves are 32 bit (signed) integers. Typically, -** the high order 24 bits are an identifier of which error table the -** error code is from, and the low order 8 bits are a sequential error -** number within the table. NSPR supports error tables whose first -** error code is not a multiple of 256, such error code assignments -** should be avoided when possible. -** -** Error table 0 is defined to match the UNIX system call error table -** (sys_errlist); this allows errno values to be used directly in the -** library. Other error table numbers are typically formed by -** compacting together the first four characters of the error table -** name. The mapping between characters in the name and numeric -** values in the error code are defined in a system-independent -** fashion, so that two systems that can pass integral values between -** them can reliably pass error codes without loss of meaning; this -** should work even if the character sets used are not the -** same. (However, if this is to be done, error table 0 should be -** avoided, since the local system call error tables may differ.) -** -** Libraries defining error codes need only provide a table mapping -** error code numbers to names and default English descriptions, -** calling a routine to install the table, making it ``known'' to NSPR -** library. Once installed, a table may not be removed. Any error -** code the library generates can be converted to the corresponding -** error message. There is also a default format for error codes -** accidentally returned before making the table known, which is of -** the form "unknown code foo 32", where "foo" would be the name of -** the table. -** -** Normally, the error code conversion routine only supports the -** languages "i-default" and "en", returning the error-table-provided -** English description for both languages. The application may -** provide a localization plugin, allowing support for additional -** languages. -** -**/ - -/**********************************************************************/ -/************************* TYPES AND CONSTANTS ************************/ -/**********************************************************************/ - -/* - * PRLanguageCode -- - * - * NSPR represents a language code as a non-negative integer. - * Languages 0 is always "i-default" the language you get without - * explicit negotiation. Language 1 is always "en", English - * which has been explicitly negotiated. Additional language - * codes are defined by an application-provided localization plugin. - */ -typedef PRUint32 PRLanguageCode; -#define PR_LANGUAGE_I_DEFAULT 0 /* i-default, the default language */ -#define PR_LANGUAGE_EN 1 /* English, explicitly negotiated */ - -/* - * struct PRErrorMessage -- - * - * An error message in an error table. - */ -struct PRErrorMessage { - const char * name; /* Macro name for error */ - const char * en_text; /* Default English text */ -}; - -/* - * struct PRErrorTable -- - * - * An error table, provided by a library. - */ -struct PRErrorTable { - const struct PRErrorMessage * msgs; /* Array of error information */ - const char *name; /* Name of error table source */ - PRErrorCode base; /* Error code for first error in table */ - int n_msgs; /* Number of codes in table */ -}; - -/* - * struct PRErrorCallbackPrivate -- - * - * A private structure for the localization plugin - */ -struct PRErrorCallbackPrivate; - -/* - * struct PRErrorCallbackTablePrivate -- - * - * A data structure under which the localization plugin may store information, - * associated with an error table, that is private to itself. - */ -struct PRErrorCallbackTablePrivate; - -/* - * PRErrorCallbackLookupFn -- - * - * A function of PRErrorCallbackLookupFn type is a localization - * plugin callback which converts an error code into a description - * in the requested language. The callback is provided the - * appropriate error table, private data for the plugin and the table. - * The callback returns the appropriate UTF-8 encoded description, or NULL - * if no description can be found. - */ -typedef const char * -PRErrorCallbackLookupFn(PRErrorCode code, PRLanguageCode language, - const struct PRErrorTable *table, - struct PRErrorCallbackPrivate *cb_private, - struct PRErrorCallbackTablePrivate *table_private); - -/* - * PRErrorCallbackNewTableFn -- - * - * A function PRErrorCallbackNewTableFn type is a localization plugin - * callback which is called once with each error table registered - * with NSPR. The callback is provided with the error table and - * the plugin's private structure. The callback returns any table private - * data it wishes to associate with the error table. Does not need to be thread - * safe. - */ -typedef struct PRErrorCallbackTablePrivate * -PRErrorCallbackNewTableFn(const struct PRErrorTable *table, - struct PRErrorCallbackPrivate *cb_private); - -/**********************************************************************/ -/****************************** FUNCTIONS *****************************/ -/**********************************************************************/ - -/*********************************************************************** -** FUNCTION: PR_ErrorToString -** DESCRIPTION: -** Returns the UTF-8 message for an error code in -** the requested language. May return the message -** in the default language if a translation in the requested -** language is not available. The returned string is -** valid for the duration of the process. Never returns NULL. -** -***********************************************************************/ -NSPR_API(const char *) PR_ErrorToString(PRErrorCode code, - PRLanguageCode language); - - -/*********************************************************************** -** FUNCTION: PR_ErrorToName -** DESCRIPTION: -** Returns the macro name for an error code, or NULL -** if the error code is not known. The returned string is -** valid for the duration of the process. -** -** Does not work for error table 0, the system error codes. -** -***********************************************************************/ -NSPR_API(const char *) PR_ErrorToName(PRErrorCode code); - - -/*********************************************************************** -** FUNCTION: PR_ErrorLanguages -** DESCRIPTION: -** Returns the RFC 1766 language tags for the language -** codes PR_ErrorToString() supports. The returned array is valid -** for the duration of the process. Never returns NULL. The first -** item in the returned array is the language tag for PRLanguageCode 0, -** the second is for PRLanguageCode 1, and so on. The array is terminated -** with a null pointer. -** -***********************************************************************/ -NSPR_API(const char * const *) PR_ErrorLanguages(void); - - -/*********************************************************************** -** FUNCTION: PR_ErrorInstallTable -** DESCRIPTION: -** Registers an error table with NSPR. Must be done exactly once per -** table. Memory pointed to by `table' must remain valid for the life -** of the process. -** -** NOT THREAD SAFE! -** -***********************************************************************/ -NSPR_API(PRErrorCode) PR_ErrorInstallTable(const struct PRErrorTable *table); - - -/*********************************************************************** -** FUNCTION: PR_ErrorInstallCallback -** DESCRIPTION: -** Registers an error localization plugin with NSPR. May be called -** at most one time. `languages' contains the language codes supported -** by this plugin. Languages 0 and 1 must be "i-default" and "en" -** respectively. `lookup' and `newtable' contain pointers to -** the plugin callback functions. `cb_private' contains any information -** private to the plugin functions. -** -** NOT THREAD SAFE! -** -***********************************************************************/ -NSPR_API(void) PR_ErrorInstallCallback(const char * const * languages, - PRErrorCallbackLookupFn *lookup, - PRErrorCallbackNewTableFn *newtable, - struct PRErrorCallbackPrivate *cb_private); - -PR_END_EXTERN_C - -#endif /* prerror_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prinet.h nspr-4.10.7/mozilla/nsprpub/pr/include/prinet.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prinet.h 2012-03-06 13:13:44.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prinet.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: prinet.h - * Description: - * Header file used to find the system header files for socket support[1]. - * This file serves the following purposes: - * - A cross-platform, "get-everything" socket header file. On - * Unix, socket support is scattered in several header files, - * while Windows has a "get-everything" socket header file[2]. - * - NSPR needs the following macro definitions and function - * prototype declarations from these header files: - * AF_INET - * INADDR_ANY, INADDR_LOOPBACK, INADDR_BROADCAST - * ntohl(), ntohs(), htonl(), ntons(). - * NSPR does not define its own versions of these macros and - * functions. It simply uses the native versions, which have - * the same names on all supported platforms. - * This file is intended to be included by NSPR public header - * files, such as prio.h. One should not include this file directly. - * - * Notes: - * 1. This file should have been an internal header. Please do not - * depend on it to pull in the system header files you need. - * 2. WARNING: This file is no longer cross-platform as it is a no-op - * for WIN32! See the comment in the WIN32 section for details. - */ - -#ifndef prinet_h__ -#define prinet_h__ - -#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) -#include -#include /* AF_INET */ -#include /* INADDR_ANY, ..., ntohl(), ... */ -#ifdef XP_OS2 -#include -#endif -#ifdef XP_UNIX -#ifdef AIX -/* - * On AIX 4.3, the header refers to struct - * ether_addr and struct sockaddr_dl that are not declared. - * The following struct declarations eliminate the compiler - * warnings. - */ -struct ether_addr; -struct sockaddr_dl; -#endif /* AIX */ -#include -#endif /* XP_UNIX */ -#include - -#if defined(FREEBSD) || defined(BSDI) || defined(QNX) -#include /* the only place that defines INADDR_LOOPBACK */ -#endif - -/* - * OS/2 hack. For some reason INADDR_LOOPBACK is not defined in the - * socket headers. - */ -#if defined(OS2) && !defined(INADDR_LOOPBACK) -#define INADDR_LOOPBACK 0x7f000001 -#endif - -/* - * Prototypes of ntohl() etc. are declared in - * on these platforms. - */ -#if defined(BSDI) || defined(OSF1) -#include -#endif - -/* On Android, ntohl() etc. are declared in . */ -#ifdef __ANDROID__ -#include -#endif - -#elif defined(WIN32) - -/* - * Do not include any system header files. - * - * Originally we were including . It slowed down the - * compilation of files that included NSPR headers, so we removed - * the inclusion at customer's request, which created - * an unfortunate inconsistency with other platforms. - */ - -#else - -#error Unknown platform - -#endif - -#endif /* prinet_h__ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prinit.h nspr-4.10.7/mozilla/nsprpub/pr/include/prinit.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prinit.h 2013-01-31 01:03:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prinit.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,215 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prinit_h___ -#define prinit_h___ - -#include "prthread.h" -#include "prtypes.h" -#include "prwin16.h" -#include - -PR_BEGIN_EXTERN_C - -/************************************************************************/ -/**************************IDENTITY AND VERSIONING***********************/ -/************************************************************************/ - -/* -** NSPR's name, this should persist until at least the turn of the -** century. -*/ -#define PR_NAME "NSPR" - -/* -** NSPR's version is used to determine the likelihood that the version you -** used to build your component is anywhere close to being compatible with -** what is in the underlying library. -** -** The format of the version string is -** ".[.] []" -*/ -#define PR_VERSION "4.9.5" -#define PR_VMAJOR 4 -#define PR_VMINOR 9 -#define PR_VPATCH 5 -#define PR_BETA PR_FALSE - -/* -** PRVersionCheck -** -** The basic signature of the function that is called to provide version -** checking. The result will be a boolean that indicates the likelihood -** that the underling library will perform as the caller expects. -** -** The only argument is a string, which should be the verson identifier -** of the library in question. That string will be compared against an -** equivalent string that represents the actual build version of the -** exporting library. -** -** The result will be the logical union of the directly called library -** and all dependent libraries. -*/ - -typedef PRBool (*PRVersionCheck)(const char*); - -/* -** PR_VersionCheck -** -** NSPR's existance proof of the version check function. -** -** Note that NSPR has no cooperating dependencies. -*/ - -NSPR_API(PRBool) PR_VersionCheck(const char *importedVersion); - -/* - * Returns a const string of the NSPR library version. - */ -NSPR_API(const char*) PR_GetVersion(void); - - -/************************************************************************/ -/*******************************INITIALIZATION***************************/ -/************************************************************************/ - -/* -** Initialize the runtime. Attach a thread object to the currently -** executing native thread of type "type". -** -** The specificaiton of 'maxPTDs' is ignored. -*/ -NSPR_API(void) PR_Init( - PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs); - -/* -** And alternate form of initialization, one that may become the default if -** not the only mechanism, provides a method to get the NSPR runtime init- -** ialized and place NSPR between the caller and the runtime library. This -** allows main() to be treated as any other thread root function, signalling -** its compeletion by returning and allowing the runtime to coordinate the -** completion of the other threads of the runtime. -** -** The priority of the main (or primordial) thread will be PR_PRIORITY_NORMAL. -** The thread may adjust its own priority by using PR_SetPriority(), though -** at this time the support for priorities is somewhat weak. -** -** The specificaiton of 'maxPTDs' is ignored. -** -** The value returned by PR_Initialize is the value returned from the root -** function, 'prmain'. -*/ - -typedef PRIntn (PR_CALLBACK *PRPrimordialFn)(PRIntn argc, char **argv); - -NSPR_API(PRIntn) PR_Initialize( - PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs); - -/* -** Return PR_TRUE if PR_Init has already been called. -*/ -NSPR_API(PRBool) PR_Initialized(void); - -/* - * Perform a graceful shutdown of NSPR. PR_Cleanup() may be called by - * the primordial thread near the end of the main() function. - * - * PR_Cleanup() attempts to synchronize the natural termination of - * process. It does that by blocking the caller, if and only if it is - * the primordial thread, until the number of user threads has dropped - * to zero. When the primordial thread returns from main(), the process - * will immediately and silently exit. That is, it will (if necessary) - * forcibly terminate any existing threads and exit without significant - * blocking and there will be no error messages or core files. - * - * PR_Cleanup() returns PR_SUCCESS if NSPR is successfully shutdown, - * or PR_FAILURE if the calling thread of this function is not the - * primordial thread. - */ -NSPR_API(PRStatus) PR_Cleanup(void); - -/* -** Disable Interrupts -** Disables timer signals used for pre-emptive scheduling. -*/ -NSPR_API(void) PR_DisableClockInterrupts(void); - -/* -** Enables Interrupts -** Enables timer signals used for pre-emptive scheduling. -*/ -NSPR_API(void) PR_EnableClockInterrupts(void); - -/* -** Block Interrupts -** Blocks the timer signal used for pre-emptive scheduling -*/ -NSPR_API(void) PR_BlockClockInterrupts(void); - -/* -** Unblock Interrupts -** Unblocks the timer signal used for pre-emptive scheduling -*/ -NSPR_API(void) PR_UnblockClockInterrupts(void); - -/* -** Create extra virtual processor threads. Generally used with MP systems. -*/ -NSPR_API(void) PR_SetConcurrency(PRUintn numCPUs); - -/* -** Control the method and size of the file descriptor (PRFileDesc*) -** cache used by the runtime. Setting 'high' to zero is for performance, -** any other value probably for debugging (see memo on FD caching). -*/ -NSPR_API(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high); - -/* - * Cause an immediate, nongraceful, forced termination of the process. - * It takes a PRIntn argument, which is the exit status code of the - * process. - */ -NSPR_API(void) PR_ProcessExit(PRIntn status); - -/* -** Abort the process in a non-graceful manner. This will cause a core file, -** call to the debugger or other moral equivalent as well as causing the -** entire process to stop. -*/ -NSPR_API(void) PR_Abort(void); - -/* - **************************************************************** - * - * Module initialization: - * - **************************************************************** - */ - -typedef struct PRCallOnceType { - PRIntn initialized; - PRInt32 inProgress; - PRStatus status; -} PRCallOnceType; - -typedef PRStatus (PR_CALLBACK *PRCallOnceFN)(void); - -typedef PRStatus (PR_CALLBACK *PRCallOnceWithArgFN)(void *arg); - -NSPR_API(PRStatus) PR_CallOnce( - PRCallOnceType *once, - PRCallOnceFN func -); - -NSPR_API(PRStatus) PR_CallOnceWithArg( - PRCallOnceType *once, - PRCallOnceWithArgFN func, - void *arg -); - - -PR_END_EXTERN_C - -#endif /* prinit_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prinrval.h nspr-4.10.7/mozilla/nsprpub/pr/include/prinrval.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prinrval.h 2012-03-06 13:13:44.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prinrval.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prinrval.h -** Description: API to interval timing functions of NSPR. -** -** -** NSPR provides interval times that are independent of network time -** of day values. Interval times are (in theory) accurate regardless -** of host processing requirements and also very cheap to acquire. It -** is expected that getting an interval time while in a synchronized -** function (holding one's lock). -**/ - -#if !defined(prinrval_h) -#define prinrval_h - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/**********************************************************************/ -/************************* TYPES AND CONSTANTS ************************/ -/**********************************************************************/ - -typedef PRUint32 PRIntervalTime; - -/*********************************************************************** -** DEFINES: PR_INTERVAL_MIN -** PR_INTERVAL_MAX -** DESCRIPTION: -** These two constants define the range (in ticks / second) of the -** platform dependent type, PRIntervalTime. These constants bound both -** the period and the resolution of a PRIntervalTime. -***********************************************************************/ -#define PR_INTERVAL_MIN 1000UL -#define PR_INTERVAL_MAX 100000UL - -/*********************************************************************** -** DEFINES: PR_INTERVAL_NO_WAIT -** PR_INTERVAL_NO_TIMEOUT -** DESCRIPTION: -** Two reserved constants are defined in the PRIntervalTime namespace. -** They are used to indicate that the process should wait no time (return -** immediately) or wait forever (never time out), respectively. -** Note: PR_INTERVAL_NO_TIMEOUT passed as input to PR_Connect is -** interpreted as use the OS's connect timeout. -** -***********************************************************************/ -#define PR_INTERVAL_NO_WAIT 0UL -#define PR_INTERVAL_NO_TIMEOUT 0xffffffffUL - -/**********************************************************************/ -/****************************** FUNCTIONS *****************************/ -/**********************************************************************/ - -/*********************************************************************** -** FUNCTION: PR_IntervalNow -** DESCRIPTION: -** Return the value of NSPR's free running interval timer. That timer -** can be used to establish epochs and determine intervals (be computing -** the difference between two times). -** INPUTS: void -** OUTPUTS: void -** RETURN: PRIntervalTime -** -** SIDE EFFECTS: -** None -** RESTRICTIONS: -** The units of PRIntervalTime are platform dependent. They are chosen -** such that they are appropriate for the host OS, yet provide sufficient -** resolution and period to be useful to clients. -** MEMORY: N/A -** ALGORITHM: Platform dependent -***********************************************************************/ -NSPR_API(PRIntervalTime) PR_IntervalNow(void); - -/*********************************************************************** -** FUNCTION: PR_TicksPerSecond -** DESCRIPTION: -** Return the number of ticks per second for PR_IntervalNow's clock. -** The value will be in the range [PR_INTERVAL_MIN..PR_INTERVAL_MAX]. -** INPUTS: void -** OUTPUTS: void -** RETURN: PRUint32 -** -** SIDE EFFECTS: -** None -** RESTRICTIONS: -** None -** MEMORY: N/A -** ALGORITHM: N/A -***********************************************************************/ -NSPR_API(PRUint32) PR_TicksPerSecond(void); - -/*********************************************************************** -** FUNCTION: PR_SecondsToInterval -** PR_MillisecondsToInterval -** PR_MicrosecondsToInterval -** DESCRIPTION: -** Convert standard clock units to platform dependent intervals. -** INPUTS: PRUint32 -** OUTPUTS: void -** RETURN: PRIntervalTime -** -** SIDE EFFECTS: -** None -** RESTRICTIONS: -** Conversion may cause overflow, which is not reported. -** MEMORY: N/A -** ALGORITHM: N/A -***********************************************************************/ -NSPR_API(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds); -NSPR_API(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli); -NSPR_API(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro); - -/*********************************************************************** -** FUNCTION: PR_IntervalToSeconds -** PR_IntervalToMilliseconds -** PR_IntervalToMicroseconds -** DESCRIPTION: -** Convert platform dependent intervals to standard clock units. -** INPUTS: PRIntervalTime -** OUTPUTS: void -** RETURN: PRUint32 -** -** SIDE EFFECTS: -** None -** RESTRICTIONS: -** Conversion may cause overflow, which is not reported. -** MEMORY: N/A -** ALGORITHM: N/A -***********************************************************************/ -NSPR_API(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks); -NSPR_API(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks); -NSPR_API(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks); - -PR_END_EXTERN_C - - -#endif /* !defined(prinrval_h) */ - -/* prinrval.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prio.h nspr-4.10.7/mozilla/nsprpub/pr/include/prio.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prio.h 2012-03-06 13:13:44.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prio.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,2005 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: prio.h - * - * Description: PR i/o related stuff, such as file system access, file - * i/o, socket i/o, etc. - */ - -#ifndef prio_h___ -#define prio_h___ - -#include "prlong.h" -#include "prtime.h" -#include "prinrval.h" -#include "prinet.h" - -PR_BEGIN_EXTERN_C - -/* Typedefs */ -typedef struct PRDir PRDir; -typedef struct PRDirEntry PRDirEntry; -#ifdef MOZ_UNICODE -typedef struct PRDirUTF16 PRDirUTF16; -typedef struct PRDirEntryUTF16 PRDirEntryUTF16; -#endif /* MOZ_UNICODE */ -typedef struct PRFileDesc PRFileDesc; -typedef struct PRFileInfo PRFileInfo; -typedef struct PRFileInfo64 PRFileInfo64; -typedef union PRNetAddr PRNetAddr; -typedef struct PRIOMethods PRIOMethods; -typedef struct PRPollDesc PRPollDesc; -typedef struct PRFilePrivate PRFilePrivate; -typedef struct PRSendFileData PRSendFileData; - -/* -*************************************************************************** -** The file descriptor. -** This is the primary structure to represent any active open socket, -** whether it be a normal file or a network connection. Such objects -** are stackable (or layerable). Each layer may have its own set of -** method pointers and context private to that layer. All each layer -** knows about its neighbors is how to get to their method table. -*************************************************************************** -*/ - -typedef PRIntn PRDescIdentity; /* see: Layering file descriptors */ - -struct PRFileDesc { - const PRIOMethods *methods; /* the I/O methods table */ - PRFilePrivate *secret; /* layer dependent data */ - PRFileDesc *lower, *higher; /* pointers to adjacent layers */ - void (PR_CALLBACK *dtor)(PRFileDesc *fd); - /* A destructor function for layer */ - PRDescIdentity identity; /* Identity of this particular layer */ -}; - -/* -*************************************************************************** -** PRTransmitFileFlags -** -** Flags for PR_TransmitFile. Pass PR_TRANSMITFILE_CLOSE_SOCKET to -** PR_TransmitFile if the connection should be closed after the file -** is transmitted. -*************************************************************************** -*/ -typedef enum PRTransmitFileFlags { - PR_TRANSMITFILE_KEEP_OPEN = 0, /* socket is left open after file - * is transmitted. */ - PR_TRANSMITFILE_CLOSE_SOCKET = 1 /* socket is closed after file - * is transmitted. */ -} PRTransmitFileFlags; - -/* -************************************************************************** -** Macros for PRNetAddr -** -** Address families: PR_AF_INET, PR_AF_INET6, PR_AF_LOCAL -** IP addresses: PR_INADDR_ANY, PR_INADDR_LOOPBACK, PR_INADDR_BROADCAST -************************************************************************** -*/ - -#ifdef WIN32 - -#define PR_AF_INET 2 -#define PR_AF_LOCAL 1 -#define PR_INADDR_ANY (unsigned long)0x00000000 -#define PR_INADDR_LOOPBACK 0x7f000001 -#define PR_INADDR_BROADCAST (unsigned long)0xffffffff - -#else /* WIN32 */ - -#define PR_AF_INET AF_INET -#define PR_AF_LOCAL AF_UNIX -#define PR_INADDR_ANY INADDR_ANY -#define PR_INADDR_LOOPBACK INADDR_LOOPBACK -#define PR_INADDR_BROADCAST INADDR_BROADCAST - -#endif /* WIN32 */ - -/* -** Define PR_AF_INET6 in prcpucfg.h with the same -** value as AF_INET6 on platforms with IPv6 support. -** Otherwise define it here. -*/ -#ifndef PR_AF_INET6 -#define PR_AF_INET6 100 -#endif - -#define PR_AF_INET_SDP 101 -#define PR_AF_INET6_SDP 102 - -#ifndef PR_AF_UNSPEC -#define PR_AF_UNSPEC 0 -#endif - -/* -************************************************************************** -** A network address -** -** Only Internet Protocol (IPv4 and IPv6) addresses are supported. -** The address family must always represent IPv4 (AF_INET, probably == 2) -** or IPv6 (AF_INET6). -************************************************************************** -*************************************************************************/ - -struct PRIPv6Addr { - union { - PRUint8 _S6_u8[16]; - PRUint16 _S6_u16[8]; - PRUint32 _S6_u32[4]; - PRUint64 _S6_u64[2]; - } _S6_un; -}; -#define pr_s6_addr _S6_un._S6_u8 -#define pr_s6_addr16 _S6_un._S6_u16 -#define pr_s6_addr32 _S6_un._S6_u32 -#define pr_s6_addr64 _S6_un._S6_u64 - -typedef struct PRIPv6Addr PRIPv6Addr; - -union PRNetAddr { - struct { - PRUint16 family; /* address family (0x00ff maskable) */ -#ifdef XP_BEOS - char data[10]; /* Be has a smaller structure */ -#else - char data[14]; /* raw address data */ -#endif - } raw; - struct { - PRUint16 family; /* address family (AF_INET) */ - PRUint16 port; /* port number */ - PRUint32 ip; /* The actual 32 bits of address */ -#ifdef XP_BEOS - char pad[4]; /* Be has a smaller structure */ -#else - char pad[8]; -#endif - } inet; - struct { - PRUint16 family; /* address family (AF_INET6) */ - PRUint16 port; /* port number */ - PRUint32 flowinfo; /* routing information */ - PRIPv6Addr ip; /* the actual 128 bits of address */ - PRUint32 scope_id; /* set of interfaces for a scope */ - } ipv6; -#if defined(XP_UNIX) || defined(XP_OS2) - struct { /* Unix domain socket address */ - PRUint16 family; /* address family (AF_UNIX) */ -#ifdef XP_OS2 - char path[108]; /* null-terminated pathname */ - /* bind fails if size is not 108. */ -#else - char path[104]; /* null-terminated pathname */ -#endif - } local; -#endif -}; - -/* -*************************************************************************** -** PRSockOption -** -** The file descriptors can have predefined options set after they file -** descriptor is created to change their behavior. Only the options in -** the following enumeration are supported. -*************************************************************************** -*/ -typedef enum PRSockOption -{ - PR_SockOpt_Nonblocking, /* nonblocking io */ - PR_SockOpt_Linger, /* linger on close if data present */ - PR_SockOpt_Reuseaddr, /* allow local address reuse */ - PR_SockOpt_Keepalive, /* keep connections alive */ - PR_SockOpt_RecvBufferSize, /* send buffer size */ - PR_SockOpt_SendBufferSize, /* receive buffer size */ - - PR_SockOpt_IpTimeToLive, /* time to live */ - PR_SockOpt_IpTypeOfService, /* type of service and precedence */ - - PR_SockOpt_AddMember, /* add an IP group membership */ - PR_SockOpt_DropMember, /* drop an IP group membership */ - PR_SockOpt_McastInterface, /* multicast interface address */ - PR_SockOpt_McastTimeToLive, /* multicast timetolive */ - PR_SockOpt_McastLoopback, /* multicast loopback */ - - PR_SockOpt_NoDelay, /* don't delay send to coalesce packets */ - PR_SockOpt_MaxSegment, /* maximum segment size */ - PR_SockOpt_Broadcast, /* enable broadcast */ - PR_SockOpt_Last -} PRSockOption; - -typedef struct PRLinger { - PRBool polarity; /* Polarity of the option's setting */ - PRIntervalTime linger; /* Time to linger before closing */ -} PRLinger; - -typedef struct PRMcastRequest { - PRNetAddr mcaddr; /* IP multicast address of group */ - PRNetAddr ifaddr; /* local IP address of interface */ -} PRMcastRequest; - -typedef struct PRSocketOptionData -{ - PRSockOption option; - union - { - PRUintn ip_ttl; /* IP time to live */ - PRUintn mcast_ttl; /* IP multicast time to live */ - PRUintn tos; /* IP type of service and precedence */ - PRBool non_blocking; /* Non-blocking (network) I/O */ - PRBool reuse_addr; /* Allow local address reuse */ - PRBool keep_alive; /* Keep connections alive */ - PRBool mcast_loopback; /* IP multicast loopback */ - PRBool no_delay; /* Don't delay send to coalesce packets */ - PRBool broadcast; /* Enable broadcast */ - PRSize max_segment; /* Maximum segment size */ - PRSize recv_buffer_size; /* Receive buffer size */ - PRSize send_buffer_size; /* Send buffer size */ - PRLinger linger; /* Time to linger on close if data present */ - PRMcastRequest add_member; /* add an IP group membership */ - PRMcastRequest drop_member; /* Drop an IP group membership */ - PRNetAddr mcast_if; /* multicast interface address */ - } value; -} PRSocketOptionData; - -/* -*************************************************************************** -** PRIOVec -** -** The I/O vector is used by the write vector method to describe the areas -** that are affected by the ouput operation. -*************************************************************************** -*/ -typedef struct PRIOVec { - char *iov_base; - int iov_len; -} PRIOVec; - -/* -*************************************************************************** -** Discover what type of socket is being described by the file descriptor. -*************************************************************************** -*/ -typedef enum PRDescType -{ - PR_DESC_FILE = 1, - PR_DESC_SOCKET_TCP = 2, - PR_DESC_SOCKET_UDP = 3, - PR_DESC_LAYERED = 4, - PR_DESC_PIPE = 5 -} PRDescType; - -typedef enum PRSeekWhence { - PR_SEEK_SET = 0, - PR_SEEK_CUR = 1, - PR_SEEK_END = 2 -} PRSeekWhence; - -NSPR_API(PRDescType) PR_GetDescType(PRFileDesc *file); - -/* -*************************************************************************** -** PRIOMethods -** -** The I/O methods table provides procedural access to the functions of -** the file descriptor. It is the responsibility of a layer implementor -** to provide suitable functions at every entry point. If a layer provides -** no functionality, it should call the next lower(higher) function of the -** same name (e.g., return fd->lower->method->close(fd->lower)); -** -** Not all functions are implemented for all types of files. In cases where -** that is true, the function will return a error indication with an error -** code of PR_INVALID_METHOD_ERROR. -*************************************************************************** -*/ - -typedef PRStatus (PR_CALLBACK *PRCloseFN)(PRFileDesc *fd); -typedef PRInt32 (PR_CALLBACK *PRReadFN)(PRFileDesc *fd, void *buf, PRInt32 amount); -typedef PRInt32 (PR_CALLBACK *PRWriteFN)(PRFileDesc *fd, const void *buf, PRInt32 amount); -typedef PRInt32 (PR_CALLBACK *PRAvailableFN)(PRFileDesc *fd); -typedef PRInt64 (PR_CALLBACK *PRAvailable64FN)(PRFileDesc *fd); -typedef PRStatus (PR_CALLBACK *PRFsyncFN)(PRFileDesc *fd); -typedef PROffset32 (PR_CALLBACK *PRSeekFN)(PRFileDesc *fd, PROffset32 offset, PRSeekWhence how); -typedef PROffset64 (PR_CALLBACK *PRSeek64FN)(PRFileDesc *fd, PROffset64 offset, PRSeekWhence how); -typedef PRStatus (PR_CALLBACK *PRFileInfoFN)(PRFileDesc *fd, PRFileInfo *info); -typedef PRStatus (PR_CALLBACK *PRFileInfo64FN)(PRFileDesc *fd, PRFileInfo64 *info); -typedef PRInt32 (PR_CALLBACK *PRWritevFN)( - PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, - PRIntervalTime timeout); -typedef PRStatus (PR_CALLBACK *PRConnectFN)( - PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout); -typedef PRFileDesc* (PR_CALLBACK *PRAcceptFN) ( - PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout); -typedef PRStatus (PR_CALLBACK *PRBindFN)(PRFileDesc *fd, const PRNetAddr *addr); -typedef PRStatus (PR_CALLBACK *PRListenFN)(PRFileDesc *fd, PRIntn backlog); -typedef PRStatus (PR_CALLBACK *PRShutdownFN)(PRFileDesc *fd, PRIntn how); -typedef PRInt32 (PR_CALLBACK *PRRecvFN)( - PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout); -typedef PRInt32 (PR_CALLBACK *PRSendFN) ( - PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout); -typedef PRInt32 (PR_CALLBACK *PRRecvfromFN)( - PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout); -typedef PRInt32 (PR_CALLBACK *PRSendtoFN)( - PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout); -typedef PRInt16 (PR_CALLBACK *PRPollFN)( - PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags); -typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)( - PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, - void *buf, PRInt32 amount, PRIntervalTime t); -typedef PRInt32 (PR_CALLBACK *PRTransmitfileFN)( - PRFileDesc *sd, PRFileDesc *fd, const void *headers, - PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime t); -typedef PRStatus (PR_CALLBACK *PRGetsocknameFN)(PRFileDesc *fd, PRNetAddr *addr); -typedef PRStatus (PR_CALLBACK *PRGetpeernameFN)(PRFileDesc *fd, PRNetAddr *addr); -typedef PRStatus (PR_CALLBACK *PRGetsocketoptionFN)( - PRFileDesc *fd, PRSocketOptionData *data); -typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)( - PRFileDesc *fd, const PRSocketOptionData *data); -typedef PRInt32 (PR_CALLBACK *PRSendfileFN)( - PRFileDesc *networkSocket, PRSendFileData *sendData, - PRTransmitFileFlags flags, PRIntervalTime timeout); -typedef PRStatus (PR_CALLBACK *PRConnectcontinueFN)( - PRFileDesc *fd, PRInt16 out_flags); -typedef PRIntn (PR_CALLBACK *PRReservedFN)(PRFileDesc *fd); - -struct PRIOMethods { - PRDescType file_type; /* Type of file represented (tos) */ - PRCloseFN close; /* close file and destroy descriptor */ - PRReadFN read; /* read up to specified bytes into buffer */ - PRWriteFN write; /* write specified bytes from buffer */ - PRAvailableFN available; /* determine number of bytes available */ - PRAvailable64FN available64; /* ditto, 64 bit */ - PRFsyncFN fsync; /* flush all buffers to permanent store */ - PRSeekFN seek; /* position the file to the desired place */ - PRSeek64FN seek64; /* ditto, 64 bit */ - PRFileInfoFN fileInfo; /* Get information about an open file */ - PRFileInfo64FN fileInfo64; /* ditto, 64 bit */ - PRWritevFN writev; /* Write segments as described by iovector */ - PRConnectFN connect; /* Connect to the specified (net) address */ - PRAcceptFN accept; /* Accept a connection for a (net) peer */ - PRBindFN bind; /* Associate a (net) address with the fd */ - PRListenFN listen; /* Prepare to listen for (net) connections */ - PRShutdownFN shutdown; /* Shutdown a (net) connection */ - PRRecvFN recv; /* Solicit up the the specified bytes */ - PRSendFN send; /* Send all the bytes specified */ - PRRecvfromFN recvfrom; /* Solicit (net) bytes and report source */ - PRSendtoFN sendto; /* Send bytes to (net) address specified */ - PRPollFN poll; /* Test the fd to see if it is ready */ - PRAcceptreadFN acceptread; /* Accept and read on a new (net) fd */ - PRTransmitfileFN transmitfile; /* Transmit at entire file */ - PRGetsocknameFN getsockname; /* Get (net) address associated with fd */ - PRGetpeernameFN getpeername; /* Get peer's (net) address */ - PRReservedFN reserved_fn_6; /* reserved for future use */ - PRReservedFN reserved_fn_5; /* reserved for future use */ - PRGetsocketoptionFN getsocketoption; - /* Get current setting of specified option */ - PRSetsocketoptionFN setsocketoption; - /* Set value of specified option */ - PRSendfileFN sendfile; /* Send a (partial) file with header/trailer*/ - PRConnectcontinueFN connectcontinue; - /* Continue a nonblocking connect */ - PRReservedFN reserved_fn_3; /* reserved for future use */ - PRReservedFN reserved_fn_2; /* reserved for future use */ - PRReservedFN reserved_fn_1; /* reserved for future use */ - PRReservedFN reserved_fn_0; /* reserved for future use */ -}; - -/* - ************************************************************************** - * FUNCTION: PR_GetSpecialFD - * DESCRIPTION: Get the file descriptor that represents the standard input, - * output, or error stream. - * INPUTS: - * PRSpecialFD id - * A value indicating the type of stream desired: - * PR_StandardInput: standard input - * PR_StandardOuput: standard output - * PR_StandardError: standard error - * OUTPUTS: none - * RETURNS: PRFileDesc * - * If the argument is valid, PR_GetSpecialFD returns a file descriptor - * that represents the corresponding standard I/O stream. Otherwise, - * PR_GetSpecialFD returns NULL and sets error PR_INVALID_ARGUMENT_ERROR. - ************************************************************************** - */ - -typedef enum PRSpecialFD -{ - PR_StandardInput, /* standard input */ - PR_StandardOutput, /* standard output */ - PR_StandardError /* standard error */ -} PRSpecialFD; - -NSPR_API(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD id); - -#define PR_STDIN PR_GetSpecialFD(PR_StandardInput) -#define PR_STDOUT PR_GetSpecialFD(PR_StandardOutput) -#define PR_STDERR PR_GetSpecialFD(PR_StandardError) - -/* - ************************************************************************** - * Layering file descriptors - * - * File descriptors may be layered. Each layer has it's own identity. - * Identities are allocated by the runtime and are to be associated - * (by the layer implementor) with all layers that are of that type. - * It is then possible to scan the chain of layers and find a layer - * that one recongizes and therefore predict that it will implement - * a desired protocol. - * - * There are three well-known identities: - * PR_INVALID_IO_LAYER => an invalid layer identity, for error return - * PR_TOP_IO_LAYER => the identity of the top of the stack - * PR_NSPR_IO_LAYER => the identity used by NSPR proper - * PR_TOP_IO_LAYER may be used as a shorthand for identifying the topmost - * layer of an existing stack. Ie., the following two constructs are - * equivalent. - * - * rv = PR_PushIOLayer(stack, PR_TOP_IO_LAYER, my_layer); - * rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), my_layer) - * - * A string may be associated with the creation of the identity. It - * will be copied by the runtime. If queried the runtime will return - * a reference to that copied string (not yet another copy). There - * is no facility for deleting an identity. - ************************************************************************** - */ - -#define PR_IO_LAYER_HEAD (PRDescIdentity)-3 -#define PR_INVALID_IO_LAYER (PRDescIdentity)-1 -#define PR_TOP_IO_LAYER (PRDescIdentity)-2 -#define PR_NSPR_IO_LAYER (PRDescIdentity)0 - -NSPR_API(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name); -NSPR_API(const char*) PR_GetNameForIdentity(PRDescIdentity ident); -NSPR_API(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd); -NSPR_API(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd_stack, PRDescIdentity id); - -/* - ************************************************************************** - * PR_GetDefaultIOMethods: Accessing the default methods table. - * You may get a pointer to the default methods table by calling this function. - * You may then select any elements from that table with which to build your - * layer's methods table. You may NOT modify the table directly. - ************************************************************************** - */ -NSPR_API(const PRIOMethods *) PR_GetDefaultIOMethods(void); - -/* - ************************************************************************** - * Creating a layer - * - * A new layer may be allocated by calling PR_CreateIOLayerStub(). The - * file descriptor returned will contain the pointer to the methods table - * provided. The runtime will not modify the table nor test its correctness. - ************************************************************************** - */ -NSPR_API(PRFileDesc*) PR_CreateIOLayerStub( - PRDescIdentity ident, const PRIOMethods *methods); - -/* - ************************************************************************** - * Creating a layer - * - * A new stack may be created by calling PR_CreateIOLayer(). The - * file descriptor returned will point to the top of the stack, which has - * the layer 'fd' as the topmost layer. - * - * NOTE: This function creates a new style stack, which has a fixed, dummy - * header. The old style stack, created by a call to PR_PushIOLayer, - * results in modifying contents of the top layer of the stack, when - * pushing and popping layers of the stack. - ************************************************************************** - */ -NSPR_API(PRFileDesc*) PR_CreateIOLayer(PRFileDesc* fd); - -/* - ************************************************************************** - * Pushing a layer - * - * A file descriptor (perhaps allocated using PR_CreateIOLayerStub()) may - * be pushed into an existing stack of file descriptors at any point the - * caller deems appropriate. The new layer will be inserted into the stack - * just above the layer with the indicated identity. - * - * Note: Even if the identity parameter indicates the top-most layer of - * the stack, the value of the file descriptor describing the original - * stack will not change. - ************************************************************************** - */ -NSPR_API(PRStatus) PR_PushIOLayer( - PRFileDesc *fd_stack, PRDescIdentity id, PRFileDesc *layer); - -/* - ************************************************************************** - * Popping a layer - * - * A layer may be popped from a stack by indicating the identity of the - * layer to be removed. If found, a pointer to the removed object will - * be returned to the caller. The object then becomes the responsibility - * of the caller. - * - * Note: Even if the identity indicates the top layer of the stack, the - * reference returned will not be the file descriptor for the stack and - * that file descriptor will remain valid. - ************************************************************************** - */ -NSPR_API(PRFileDesc*) PR_PopIOLayer(PRFileDesc *fd_stack, PRDescIdentity id); - -/* - ************************************************************************** - * FUNCTION: PR_Open - * DESCRIPTION: Open a file for reading, writing, or both. - * INPUTS: - * const char *name - * The path name of the file to be opened - * PRIntn flags - * The file status flags. - * It is a bitwise OR of the following bit flags (only one of - * the first three flags below may be used): - * PR_RDONLY Open for reading only. - * PR_WRONLY Open for writing only. - * PR_RDWR Open for reading and writing. - * PR_CREATE_FILE If the file does not exist, the file is created - * If the file exists, this flag has no effect. - * PR_SYNC If set, each write will wait for both the file data - * and file status to be physically updated. - * PR_APPEND The file pointer is set to the end of - * the file prior to each write. - * PR_TRUNCATE If the file exists, its length is truncated to 0. - * PR_EXCL With PR_CREATE_FILE, if the file does not exist, - * the file is created. If the file already - * exists, no action and NULL is returned - * - * PRIntn mode - * The access permission bits of the file mode, if the file is - * created when PR_CREATE_FILE is on. - * OUTPUTS: None - * RETURNS: PRFileDesc * - * If the file is successfully opened, - * returns a pointer to the PRFileDesc - * created for the newly opened file. - * Returns a NULL pointer if the open - * failed. - * SIDE EFFECTS: - * RESTRICTIONS: - * MEMORY: - * The return value, if not NULL, points to a dynamically allocated - * PRFileDesc object. - * ALGORITHM: - ************************************************************************** - */ - -/* Open flags */ -#define PR_RDONLY 0x01 -#define PR_WRONLY 0x02 -#define PR_RDWR 0x04 -#define PR_CREATE_FILE 0x08 -#define PR_APPEND 0x10 -#define PR_TRUNCATE 0x20 -#define PR_SYNC 0x40 -#define PR_EXCL 0x80 - -/* -** File modes .... -** -** CAVEAT: 'mode' is currently only applicable on UNIX platforms. -** The 'mode' argument may be ignored by PR_Open on other platforms. -** -** 00400 Read by owner. -** 00200 Write by owner. -** 00100 Execute (search if a directory) by owner. -** 00040 Read by group. -** 00020 Write by group. -** 00010 Execute by group. -** 00004 Read by others. -** 00002 Write by others -** 00001 Execute by others. -** -*/ - -NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode); - -/* - ************************************************************************** - * FUNCTION: PR_OpenFile - * DESCRIPTION: - * Open a file for reading, writing, or both. - * PR_OpenFile has the same prototype as PR_Open but implements - * the specified file mode where possible. - ************************************************************************** - */ - -/* File mode bits */ -#define PR_IRWXU 00700 /* read, write, execute/search by owner */ -#define PR_IRUSR 00400 /* read permission, owner */ -#define PR_IWUSR 00200 /* write permission, owner */ -#define PR_IXUSR 00100 /* execute/search permission, owner */ -#define PR_IRWXG 00070 /* read, write, execute/search by group */ -#define PR_IRGRP 00040 /* read permission, group */ -#define PR_IWGRP 00020 /* write permission, group */ -#define PR_IXGRP 00010 /* execute/search permission, group */ -#define PR_IRWXO 00007 /* read, write, execute/search by others */ -#define PR_IROTH 00004 /* read permission, others */ -#define PR_IWOTH 00002 /* write permission, others */ -#define PR_IXOTH 00001 /* execute/search permission, others */ - -NSPR_API(PRFileDesc*) PR_OpenFile( - const char *name, PRIntn flags, PRIntn mode); - -#ifdef MOZ_UNICODE -/* - * EXPERIMENTAL: This function may be removed in a future release. - */ -NSPR_API(PRFileDesc*) PR_OpenFileUTF16( - const PRUnichar *name, PRIntn flags, PRIntn mode); -#endif /* MOZ_UNICODE */ - -/* - ************************************************************************** - * FUNCTION: PR_Close - * DESCRIPTION: - * Close a file or socket. - * INPUTS: - * PRFileDesc *fd - * a pointer to a PRFileDesc. - * OUTPUTS: - * None. - * RETURN: - * PRStatus - * SIDE EFFECTS: - * RESTRICTIONS: - * None. - * MEMORY: - * The dynamic memory pointed to by the argument fd is freed. - ************************************************************************** - */ - -NSPR_API(PRStatus) PR_Close(PRFileDesc *fd); - -/* - ************************************************************************** - * FUNCTION: PR_Read - * DESCRIPTION: - * Read bytes from a file or socket. - * The operation will block until either an end of stream indication is - * encountered, some positive number of bytes are transferred, or there - * is an error. No more than 'amount' bytes will be transferred. - * INPUTS: - * PRFileDesc *fd - * pointer to the PRFileDesc object for the file or socket - * void *buf - * pointer to a buffer to hold the data read in. - * PRInt32 amount - * the size of 'buf' (in bytes) - * OUTPUTS: - * RETURN: - * PRInt32 - * a positive number indicates the number of bytes actually read in. - * 0 means end of file is reached or the network connection is closed. - * -1 indicates a failure. The reason for the failure is obtained - * by calling PR_GetError(). - * SIDE EFFECTS: - * data is written into the buffer pointed to by 'buf'. - * RESTRICTIONS: - * None. - * MEMORY: - * N/A - * ALGORITHM: - * N/A - ************************************************************************** - */ - -NSPR_API(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount); - -/* - *************************************************************************** - * FUNCTION: PR_Write - * DESCRIPTION: - * Write a specified number of bytes to a file or socket. The thread - * invoking this function blocks until all the data is written. - * INPUTS: - * PRFileDesc *fd - * pointer to a PRFileDesc object that refers to a file or socket - * const void *buf - * pointer to the buffer holding the data - * PRInt32 amount - * amount of data in bytes to be written from the buffer - * OUTPUTS: - * None. - * RETURN: PRInt32 - * A positive number indicates the number of bytes successfully written. - * A -1 is an indication that the operation failed. The reason - * for the failure is obtained by calling PR_GetError(). - *************************************************************************** - */ - -NSPR_API(PRInt32) PR_Write(PRFileDesc *fd,const void *buf,PRInt32 amount); - -/* - *************************************************************************** - * FUNCTION: PR_Writev - * DESCRIPTION: - * Write data to a socket. The data is organized in a PRIOVec array. The - * operation will block until all the data is written or the operation - * fails. - * INPUTS: - * PRFileDesc *fd - * Pointer that points to a PRFileDesc object for a socket. - * const PRIOVec *iov - * An array of PRIOVec. PRIOVec is a struct with the following - * two fields: - * char *iov_base; - * int iov_len; - * PRInt32 iov_size - * Number of elements in the iov array. The value of this - * argument must not be greater than PR_MAX_IOVECTOR_SIZE. - * If it is, the method will fail (PR_BUFFER_OVERFLOW_ERROR). - * PRIntervalTime timeout - * Time limit for completion of the entire write operation. - * OUTPUTS: - * None - * RETURN: - * A positive number indicates the number of bytes successfully written. - * A -1 is an indication that the operation failed. The reason - * for the failure is obtained by calling PR_GetError(). - *************************************************************************** - */ - -#define PR_MAX_IOVECTOR_SIZE 16 /* 'iov_size' must be <= */ - -NSPR_API(PRInt32) PR_Writev( - PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, - PRIntervalTime timeout); - -/* - *************************************************************************** - * FUNCTION: PR_Delete - * DESCRIPTION: - * Delete a file from the filesystem. The operation may fail if the - * file is open. - * INPUTS: - * const char *name - * Path name of the file to be deleted. - * OUTPUTS: - * None. - * RETURN: PRStatus - * The function returns PR_SUCCESS if the file is successfully - * deleted, otherwise it returns PR_FAILURE. - *************************************************************************** - */ - -NSPR_API(PRStatus) PR_Delete(const char *name); - -/**************************************************************************/ - -typedef enum PRFileType -{ - PR_FILE_FILE = 1, - PR_FILE_DIRECTORY = 2, - PR_FILE_OTHER = 3 -} PRFileType; - -struct PRFileInfo { - PRFileType type; /* Type of file */ - PROffset32 size; /* Size, in bytes, of file's contents */ - PRTime creationTime; /* Creation time per definition of PRTime */ - PRTime modifyTime; /* Last modification time per definition of PRTime */ -}; - -struct PRFileInfo64 { - PRFileType type; /* Type of file */ - PROffset64 size; /* Size, in bytes, of file's contents */ - PRTime creationTime; /* Creation time per definition of PRTime */ - PRTime modifyTime; /* Last modification time per definition of PRTime */ -}; - -/**************************************************************************** - * FUNCTION: PR_GetFileInfo, PR_GetFileInfo64 - * DESCRIPTION: - * Get the information about the file with the given path name. This is - * applicable only to NSFileDesc describing 'file' types (see - * INPUTS: - * const char *fn - * path name of the file - * OUTPUTS: - * PRFileInfo *info - * Information about the given file is written into the file - * information object pointer to by 'info'. - * RETURN: PRStatus - * PR_GetFileInfo returns PR_SUCCESS if file information is successfully - * obtained, otherwise it returns PR_FAILURE. - *************************************************************************** - */ - -NSPR_API(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info); -NSPR_API(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info); - -#ifdef MOZ_UNICODE -/* - * EXPERIMENTAL: This function may be removed in a future release. - */ -NSPR_API(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info); -#endif /* MOZ_UNICODE */ - -/* - ************************************************************************** - * FUNCTION: PR_GetOpenFileInfo, PR_GetOpenFileInfo64 - * DESCRIPTION: - * Get information about an open file referred to by the - * given PRFileDesc object. - * INPUTS: - * const PRFileDesc *fd - * A reference to a valid, open file. - * OUTPUTS: - * Same as PR_GetFileInfo, PR_GetFileInfo64 - * RETURN: PRStatus - * PR_GetFileInfo returns PR_SUCCESS if file information is successfully - * obtained, otherwise it returns PR_FAILURE. - *************************************************************************** - */ - -NSPR_API(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info); -NSPR_API(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info); - -/* - ************************************************************************** - * FUNCTION: PR_Rename - * DESCRIPTION: - * Rename a file from the old name 'from' to the new name 'to'. - * INPUTS: - * const char *from - * The old name of the file to be renamed. - * const char *to - * The new name of the file. - * OUTPUTS: - * None. - * RETURN: PRStatus - ************************************************************************** - */ - -NSPR_API(PRStatus) PR_Rename(const char *from, const char *to); - -/* - ************************************************************************* - * FUNCTION: PR_Access - * DESCRIPTION: - * Determine accessibility of a file. - * INPUTS: - * const char *name - * path name of the file - * PRAccessHow how - * specifies which access permission to check for. - * It can be one of the following values: - * PR_ACCESS_READ_OK Test for read permission - * PR_ACCESS_WRITE_OK Test for write permission - * PR_ACCESS_EXISTS Check existence of file - * OUTPUTS: - * None. - * RETURN: PRStatus - * PR_SUCCESS is returned if the requested access is permitted. - * Otherwise, PR_FAILURE is returned. Additional information - * regarding the reason for the failure may be retrieved from - * PR_GetError(). - ************************************************************************* - */ - -typedef enum PRAccessHow { - PR_ACCESS_EXISTS = 1, - PR_ACCESS_WRITE_OK = 2, - PR_ACCESS_READ_OK = 3 -} PRAccessHow; - -NSPR_API(PRStatus) PR_Access(const char *name, PRAccessHow how); - -/* - ************************************************************************* - * FUNCTION: PR_Seek, PR_Seek64 - * DESCRIPTION: - * Moves read-write file offset - * INPUTS: - * PRFileDesc *fd - * Pointer to a PRFileDesc object. - * PROffset32, PROffset64 offset - * Specifies a value, in bytes, that is used in conjunction - * with the 'whence' parameter to set the file pointer. A - * negative value causes seeking in the reverse direction. - * PRSeekWhence whence - * Specifies how to interpret the 'offset' parameter in setting - * the file pointer associated with the 'fd' parameter. - * Values for the 'whence' parameter are: - * PR_SEEK_SET Sets the file pointer to the value of the - * 'offset' parameter - * PR_SEEK_CUR Sets the file pointer to its current location - * plus the value of the offset parameter. - * PR_SEEK_END Sets the file pointer to the size of the - * file plus the value of the offset parameter. - * OUTPUTS: - * None. - * RETURN: PROffset32, PROffset64 - * Upon successful completion, the resulting pointer location, - * measured in bytes from the beginning of the file, is returned. - * If the PR_Seek() function fails, the file offset remains - * unchanged, and the returned value is -1. The error code can - * then be retrieved via PR_GetError(). - ************************************************************************* - */ - -NSPR_API(PROffset32) PR_Seek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence); -NSPR_API(PROffset64) PR_Seek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence); - -/* - ************************************************************************ - * FUNCTION: PR_Available - * DESCRIPTION: - * Determine the amount of data in bytes available for reading - * in the given file or socket. - * INPUTS: - * PRFileDesc *fd - * Pointer to a PRFileDesc object that refers to a file or - * socket. - * OUTPUTS: - * None - * RETURN: PRInt32, PRInt64 - * Upon successful completion, PR_Available returns the number of - * bytes beyond the current read pointer that is available for - * reading. Otherwise, it returns a -1 and the reason for the - * failure can be retrieved via PR_GetError(). - ************************************************************************ - */ - -NSPR_API(PRInt32) PR_Available(PRFileDesc *fd); -NSPR_API(PRInt64) PR_Available64(PRFileDesc *fd); - -/* - ************************************************************************ - * FUNCTION: PR_Sync - * DESCRIPTION: - * Sync any buffered data for a fd to its backing device (disk). - * INPUTS: - * PRFileDesc *fd - * Pointer to a PRFileDesc object that refers to a file or - * socket - * OUTPUTS: - * None - * RETURN: PRStatus - * PR_SUCCESS is returned if the requested access is permitted. - * Otherwise, PR_FAILURE is returned. - ************************************************************************ - */ - -NSPR_API(PRStatus) PR_Sync(PRFileDesc *fd); - -/************************************************************************/ - -struct PRDirEntry { - const char *name; /* name of entry, relative to directory name */ -}; - -#ifdef MOZ_UNICODE -struct PRDirEntryUTF16 { - const PRUnichar *name; /* name of entry in UTF16, relative to - * directory name */ -}; -#endif /* MOZ_UNICODE */ - -#if !defined(NO_NSPR_10_SUPPORT) -#define PR_DirName(dirEntry) (dirEntry->name) -#endif - -/* - ************************************************************************* - * FUNCTION: PR_OpenDir - * DESCRIPTION: - * Open the directory by the given name - * INPUTS: - * const char *name - * path name of the directory to be opened - * OUTPUTS: - * None - * RETURN: PRDir * - * If the directory is sucessfully opened, a PRDir object is - * dynamically allocated and a pointer to it is returned. - * If the directory cannot be opened, a NULL pointer is returned. - * MEMORY: - * Upon successful completion, the return value points to - * dynamically allocated memory. - ************************************************************************* - */ - -NSPR_API(PRDir*) PR_OpenDir(const char *name); - -#ifdef MOZ_UNICODE -/* - * EXPERIMENTAL: This function may be removed in a future release. - */ -NSPR_API(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name); -#endif /* MOZ_UNICODE */ - -/* - ************************************************************************* - * FUNCTION: PR_ReadDir - * DESCRIPTION: - * INPUTS: - * PRDir *dir - * pointer to a PRDir object that designates an open directory - * PRDirFlags flags - * PR_SKIP_NONE Do not skip any files - * PR_SKIP_DOT Skip the directory entry "." that - * represents the current directory - * PR_SKIP_DOT_DOT Skip the directory entry ".." that - * represents the parent directory. - * PR_SKIP_BOTH Skip both '.' and '..' - * PR_SKIP_HIDDEN Skip hidden files - * OUTPUTS: - * RETURN: PRDirEntry* - * Returns a pointer to the next entry in the directory. Returns - * a NULL pointer upon reaching the end of the directory or when an - * error occurs. The actual reason can be retrieved via PR_GetError(). - ************************************************************************* - */ - -typedef enum PRDirFlags { - PR_SKIP_NONE = 0x0, - PR_SKIP_DOT = 0x1, - PR_SKIP_DOT_DOT = 0x2, - PR_SKIP_BOTH = 0x3, - PR_SKIP_HIDDEN = 0x4 -} PRDirFlags; - -NSPR_API(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags); - -#ifdef MOZ_UNICODE -/* - * EXPERIMENTAL: This function may be removed in a future release. - */ -NSPR_API(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags); -#endif /* MOZ_UNICODE */ - -/* - ************************************************************************* - * FUNCTION: PR_CloseDir - * DESCRIPTION: - * Close the specified directory. - * INPUTS: - * PRDir *dir - * The directory to be closed. - * OUTPUTS: - * None - * RETURN: PRStatus - * If successful, will return a status of PR_SUCCESS. Otherwise - * a value of PR_FAILURE. The reason for the failure may be re- - * trieved using PR_GetError(). - ************************************************************************* - */ - -NSPR_API(PRStatus) PR_CloseDir(PRDir *dir); - -#ifdef MOZ_UNICODE -/* - * EXPERIMENTAL: This function may be removed in a future release. - */ -NSPR_API(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir); -#endif /* MOZ_UNICODE */ - -/* - ************************************************************************* - * FUNCTION: PR_MkDir - * DESCRIPTION: - * Create a new directory with the given name and access mode. - * INPUTS: - * const char *name - * The name of the directory to be created. All the path components - * up to but not including the leaf component must already exist. - * PRIntn mode - * See 'mode' definiton in PR_Open(). - * OUTPUTS: - * None - * RETURN: PRStatus - * If successful, will return a status of PR_SUCCESS. Otherwise - * a value of PR_FAILURE. The reason for the failure may be re- - * trieved using PR_GetError(). - ************************************************************************* - */ - -NSPR_API(PRStatus) PR_MkDir(const char *name, PRIntn mode); - -/* - ************************************************************************* - * FUNCTION: PR_MakeDir - * DESCRIPTION: - * Create a new directory with the given name and access mode. - * PR_MakeDir has the same prototype as PR_MkDir but implements - * the specified access mode where possible. - ************************************************************************* - */ - -NSPR_API(PRStatus) PR_MakeDir(const char *name, PRIntn mode); - -/* - ************************************************************************* - * FUNCTION: PR_RmDir - * DESCRIPTION: - * Remove a directory by the given name. - * INPUTS: - * const char *name - * The name of the directory to be removed. All the path components - * must already exist. Only the leaf component will be removed. - * OUTPUTS: - * None - * RETURN: PRStatus - * If successful, will return a status of PR_SUCCESS. Otherwise - * a value of PR_FAILURE. The reason for the failure may be re- - * trieved using PR_GetError(). - ************************************************************************** - */ - -NSPR_API(PRStatus) PR_RmDir(const char *name); - -/* - ************************************************************************* - * FUNCTION: PR_NewUDPSocket - * DESCRIPTION: - * Create a new UDP socket. - * INPUTS: - * None - * OUTPUTS: - * None - * RETURN: PRFileDesc* - * Upon successful completion, PR_NewUDPSocket returns a pointer - * to the PRFileDesc created for the newly opened UDP socket. - * Returns a NULL pointer if the creation of a new UDP socket failed. - * - ************************************************************************** - */ - -NSPR_API(PRFileDesc*) PR_NewUDPSocket(void); - -/* - ************************************************************************* - * FUNCTION: PR_NewTCPSocket - * DESCRIPTION: - * Create a new TCP socket. - * INPUTS: - * None - * OUTPUTS: - * None - * RETURN: PRFileDesc* - * Upon successful completion, PR_NewTCPSocket returns a pointer - * to the PRFileDesc created for the newly opened TCP socket. - * Returns a NULL pointer if the creation of a new TCP socket failed. - * - ************************************************************************** - */ - -NSPR_API(PRFileDesc*) PR_NewTCPSocket(void); - -/* - ************************************************************************* - * FUNCTION: PR_OpenUDPSocket - * DESCRIPTION: - * Create a new UDP socket of the specified address family. - * INPUTS: - * PRIntn af - * Address family - * OUTPUTS: - * None - * RETURN: PRFileDesc* - * Upon successful completion, PR_OpenUDPSocket returns a pointer - * to the PRFileDesc created for the newly opened UDP socket. - * Returns a NULL pointer if the creation of a new UDP socket failed. - * - ************************************************************************** - */ - -NSPR_API(PRFileDesc*) PR_OpenUDPSocket(PRIntn af); - -/* - ************************************************************************* - * FUNCTION: PR_OpenTCPSocket - * DESCRIPTION: - * Create a new TCP socket of the specified address family. - * INPUTS: - * PRIntn af - * Address family - * OUTPUTS: - * None - * RETURN: PRFileDesc* - * Upon successful completion, PR_NewTCPSocket returns a pointer - * to the PRFileDesc created for the newly opened TCP socket. - * Returns a NULL pointer if the creation of a new TCP socket failed. - * - ************************************************************************** - */ - -NSPR_API(PRFileDesc*) PR_OpenTCPSocket(PRIntn af); - -/* - ************************************************************************* - * FUNCTION: PR_Connect - * DESCRIPTION: - * Initiate a connection on a socket. - * INPUTS: - * PRFileDesc *fd - * Points to a PRFileDesc object representing a socket - * PRNetAddr *addr - * Specifies the address of the socket in its own communication - * space. - * PRIntervalTime timeout - * The function uses the lesser of the provided timeout and - * the OS's connect timeout. In particular, if you specify - * PR_INTERVAL_NO_TIMEOUT as the timeout, the OS's connection - * time limit will be used. - * - * OUTPUTS: - * None - * RETURN: PRStatus - * Upon successful completion of connection initiation, PR_Connect - * returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further - * failure information can be obtained by calling PR_GetError(). - ************************************************************************** - */ - -NSPR_API(PRStatus) PR_Connect( - PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout); - -/* - ************************************************************************* - * FUNCTION: PR_ConnectContinue - * DESCRIPTION: - * Continue a nonblocking connect. After a nonblocking connect - * is initiated with PR_Connect() (which fails with - * PR_IN_PROGRESS_ERROR), one should call PR_Poll() on the socket, - * with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT. When - * PR_Poll() returns, one calls PR_ConnectContinue() on the - * socket to determine whether the nonblocking connect has - * completed or is still in progress. Repeat the PR_Poll(), - * PR_ConnectContinue() sequence until the nonblocking connect - * has completed. - * INPUTS: - * PRFileDesc *fd - * the file descriptor representing a socket - * PRInt16 out_flags - * the out_flags field of the poll descriptor returned by - * PR_Poll() - * RETURN: PRStatus - * If the nonblocking connect has successfully completed, - * PR_ConnectContinue returns PR_SUCCESS. If PR_ConnectContinue() - * returns PR_FAILURE, call PR_GetError(): - * - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in - * progress and has not completed yet. The caller should poll - * on the file descriptor for the in_flags - * PR_POLL_WRITE|PR_POLL_EXCEPT and retry PR_ConnectContinue - * later when PR_Poll() returns. - * - Other errors: the nonblocking connect has failed with this - * error code. - */ - -NSPR_API(PRStatus) PR_ConnectContinue(PRFileDesc *fd, PRInt16 out_flags); - -/* - ************************************************************************* - * THIS FUNCTION IS DEPRECATED. USE PR_ConnectContinue INSTEAD. - * - * FUNCTION: PR_GetConnectStatus - * DESCRIPTION: - * Get the completion status of a nonblocking connect. After - * a nonblocking connect is initiated with PR_Connect() (which - * fails with PR_IN_PROGRESS_ERROR), one should call PR_Poll() - * on the socket, with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT. - * When PR_Poll() returns, one calls PR_GetConnectStatus on the - * PRPollDesc structure to determine whether the nonblocking - * connect has succeeded or failed. - * INPUTS: - * const PRPollDesc *pd - * Pointer to a PRPollDesc whose fd member is the socket, - * and in_flags must contain PR_POLL_WRITE and PR_POLL_EXCEPT. - * PR_Poll() should have been called and set the out_flags. - * RETURN: PRStatus - * If the nonblocking connect has successfully completed, - * PR_GetConnectStatus returns PR_SUCCESS. If PR_GetConnectStatus() - * returns PR_FAILURE, call PR_GetError(): - * - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in - * progress and has not completed yet. - * - Other errors: the nonblocking connect has failed with this - * error code. - */ - -NSPR_API(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd); - -/* - ************************************************************************* - * FUNCTION: PR_Accept - * DESCRIPTION: - * Accept a connection on a socket. - * INPUTS: - * PRFileDesc *fd - * Points to a PRFileDesc object representing the rendezvous socket - * on which the caller is willing to accept new connections. - * PRIntervalTime timeout - * Time limit for completion of the accept operation. - * OUTPUTS: - * PRNetAddr *addr - * Returns the address of the connecting entity in its own - * communication space. It may be NULL. - * RETURN: PRFileDesc* - * Upon successful acceptance of a connection, PR_Accept - * returns a valid file descriptor. Otherwise, it returns NULL. - * Further failure information can be obtained by calling PR_GetError(). - ************************************************************************** - */ - -NSPR_API(PRFileDesc*) PR_Accept( - PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout); - -/* - ************************************************************************* - * FUNCTION: PR_Bind - * DESCRIPTION: - * Bind an address to a socket. - * INPUTS: - * PRFileDesc *fd - * Points to a PRFileDesc object representing a socket. - * PRNetAddr *addr - * Specifies the address to which the socket will be bound. - * OUTPUTS: - * None - * RETURN: PRStatus - * Upon successful binding of an address to a socket, PR_Bind - * returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further - * failure information can be obtained by calling PR_GetError(). - ************************************************************************** - */ - -NSPR_API(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr); - -/* - ************************************************************************* - * FUNCTION: PR_Listen - * DESCRIPTION: - * Listen for connections on a socket. - * INPUTS: - * PRFileDesc *fd - * Points to a PRFileDesc object representing a socket that will be - * used to listen for new connections. - * PRIntn backlog - * Specifies the maximum length of the queue of pending connections. - * OUTPUTS: - * None - * RETURN: PRStatus - * Upon successful completion of listen request, PR_Listen - * returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further - * failure information can be obtained by calling PR_GetError(). - ************************************************************************** - */ - -NSPR_API(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog); - -/* - ************************************************************************* - * FUNCTION: PR_Shutdown - * DESCRIPTION: - * Shut down part of a full-duplex connection on a socket. - * INPUTS: - * PRFileDesc *fd - * Points to a PRFileDesc object representing a connected socket. - * PRIntn how - * Specifies the kind of disallowed operations on the socket. - * PR_SHUTDOWN_RCV - Further receives will be disallowed - * PR_SHUTDOWN_SEND - Further sends will be disallowed - * PR_SHUTDOWN_BOTH - Further sends and receives will be disallowed - * OUTPUTS: - * None - * RETURN: PRStatus - * Upon successful completion of shutdown request, PR_Shutdown - * returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further - * failure information can be obtained by calling PR_GetError(). - ************************************************************************** - */ - -typedef enum PRShutdownHow -{ - PR_SHUTDOWN_RCV = 0, /* disallow further receives */ - PR_SHUTDOWN_SEND = 1, /* disallow further sends */ - PR_SHUTDOWN_BOTH = 2 /* disallow further receives and sends */ -} PRShutdownHow; - -NSPR_API(PRStatus) PR_Shutdown(PRFileDesc *fd, PRShutdownHow how); - -/* - ************************************************************************* - * FUNCTION: PR_Recv - * DESCRIPTION: - * Receive a specified number of bytes from a connected socket. - * The operation will block until some positive number of bytes are - * transferred, a time out has occurred, or there is an error. - * No more than 'amount' bytes will be transferred. - * INPUTS: - * PRFileDesc *fd - * points to a PRFileDesc object representing a socket. - * void *buf - * pointer to a buffer to hold the data received. - * PRInt32 amount - * the size of 'buf' (in bytes) - * PRIntn flags - * must be zero or PR_MSG_PEEK. - * PRIntervalTime timeout - * Time limit for completion of the receive operation. - * OUTPUTS: - * None - * RETURN: PRInt32 - * a positive number indicates the number of bytes actually received. - * 0 means the network connection is closed. - * -1 indicates a failure. The reason for the failure is obtained - * by calling PR_GetError(). - ************************************************************************** - */ - -#define PR_MSG_PEEK 0x2 - -NSPR_API(PRInt32) PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout); - -/* - ************************************************************************* - * FUNCTION: PR_Send - * DESCRIPTION: - * Send a specified number of bytes from a connected socket. - * The operation will block until all bytes are - * processed, a time out has occurred, or there is an error. - * INPUTS: - * PRFileDesc *fd - * points to a PRFileDesc object representing a socket. - * void *buf - * pointer to a buffer from where the data is sent. - * PRInt32 amount - * the size of 'buf' (in bytes) - * PRIntn flags - * (OBSOLETE - must always be zero) - * PRIntervalTime timeout - * Time limit for completion of the send operation. - * OUTPUTS: - * None - * RETURN: PRInt32 - * A positive number indicates the number of bytes successfully processed. - * This number must always equal 'amount'. A -1 is an indication that the - * operation failed. The reason for the failure is obtained by calling - * PR_GetError(). - ************************************************************************** - */ - -NSPR_API(PRInt32) PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout); - -/* - ************************************************************************* - * FUNCTION: PR_RecvFrom - * DESCRIPTION: - * Receive up to a specified number of bytes from socket which may - * or may not be connected. - * The operation will block until one or more bytes are - * transferred, a time out has occurred, or there is an error. - * No more than 'amount' bytes will be transferred. - * INPUTS: - * PRFileDesc *fd - * points to a PRFileDesc object representing a socket. - * void *buf - * pointer to a buffer to hold the data received. - * PRInt32 amount - * the size of 'buf' (in bytes) - * PRIntn flags - * (OBSOLETE - must always be zero) - * PRNetAddr *addr - * Specifies the address of the sending peer. It may be NULL. - * PRIntervalTime timeout - * Time limit for completion of the receive operation. - * OUTPUTS: - * None - * RETURN: PRInt32 - * a positive number indicates the number of bytes actually received. - * 0 means the network connection is closed. - * -1 indicates a failure. The reason for the failure is obtained - * by calling PR_GetError(). - ************************************************************************** - */ - -NSPR_API(PRInt32) PR_RecvFrom( - PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRNetAddr *addr, PRIntervalTime timeout); - -/* - ************************************************************************* - * FUNCTION: PR_SendTo - * DESCRIPTION: - * Send a specified number of bytes from an unconnected socket. - * The operation will block until all bytes are - * sent, a time out has occurred, or there is an error. - * INPUTS: - * PRFileDesc *fd - * points to a PRFileDesc object representing an unconnected socket. - * void *buf - * pointer to a buffer from where the data is sent. - * PRInt32 amount - * the size of 'buf' (in bytes) - * PRIntn flags - * (OBSOLETE - must always be zero) - * PRNetAddr *addr - * Specifies the address of the peer. -.* PRIntervalTime timeout - * Time limit for completion of the send operation. - * OUTPUTS: - * None - * RETURN: PRInt32 - * A positive number indicates the number of bytes successfully sent. - * -1 indicates a failure. The reason for the failure is obtained - * by calling PR_GetError(). - ************************************************************************** - */ - -NSPR_API(PRInt32) PR_SendTo( - PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRIntervalTime timeout); - -/* -************************************************************************* -** FUNCTION: PR_TransmitFile -** DESCRIPTION: -** Transmitfile sends a complete file (sourceFile) across a socket -** (networkSocket). If headers is non-NULL, the headers will be sent across -** the socket prior to sending the file. -** -** Optionally, the PR_TRANSMITFILE_CLOSE_SOCKET flag may be passed to -** transmitfile. This flag specifies that transmitfile should close the -** socket after sending the data. -** -** INPUTS: -** PRFileDesc *networkSocket -** The socket to send data over -** PRFileDesc *sourceFile -** The file to send -** const void *headers -** A pointer to headers to be sent before sending data -** PRInt32 hlen -** length of header buffers in bytes. -** PRTransmitFileFlags flags -** If the flags indicate that the connection should be closed, -** it will be done immediately after transferring the file, unless -** the operation is unsuccessful. -.* PRIntervalTime timeout - * Time limit for completion of the transmit operation. -** -** RETURNS: -** Returns the number of bytes written or -1 if the operation failed. -** If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_ -** SOCKET flag is ignored. The reason for the failure is obtained -** by calling PR_GetError(). -************************************************************************** -*/ - -NSPR_API(PRInt32) PR_TransmitFile( - PRFileDesc *networkSocket, PRFileDesc *sourceFile, - const void *headers, PRInt32 hlen, PRTransmitFileFlags flags, - PRIntervalTime timeout); - -/* -************************************************************************* -** FUNCTION: PR_SendFile -** DESCRIPTION: -** PR_SendFile sends data from a file (sendData->fd) across a socket -** (networkSocket). If specified, a header and/or trailer buffer are sent -** before and after the file, respectively. The file offset, number of bytes -** of file data to send, the header and trailer buffers are specified in the -** sendData argument. -** -** Optionally, if the PR_TRANSMITFILE_CLOSE_SOCKET flag is passed, the -** socket is closed after successfully sending the data. -** -** INPUTS: -** PRFileDesc *networkSocket -** The socket to send data over -** PRSendFileData *sendData -** Contains the FD, file offset and length, header and trailer -** buffer specifications. -** PRTransmitFileFlags flags -** If the flags indicate that the connection should be closed, -** it will be done immediately after transferring the file, unless -** the operation is unsuccessful. -.* PRIntervalTime timeout - * Time limit for completion of the send operation. -** -** RETURNS: -** Returns the number of bytes written or -1 if the operation failed. -** If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_ -** SOCKET flag is ignored. The reason for the failure is obtained -** by calling PR_GetError(). -************************************************************************** -*/ - -struct PRSendFileData { - PRFileDesc *fd; /* file to send */ - PRUint32 file_offset; /* file offset */ - PRSize file_nbytes; /* number of bytes of file data to send */ - /* if 0, send data from file_offset to */ - /* end-of-file. */ - const void *header; /* header buffer */ - PRInt32 hlen; /* header len */ - const void *trailer; /* trailer buffer */ - PRInt32 tlen; /* trailer len */ -}; - - -NSPR_API(PRInt32) PR_SendFile( - PRFileDesc *networkSocket, PRSendFileData *sendData, - PRTransmitFileFlags flags, PRIntervalTime timeout); - -/* -************************************************************************* -** FUNCTION: PR_AcceptRead -** DESCRIPTION: -** AcceptRead accepts a new connection, returns the newly created -** socket's descriptor and also returns the connecting peer's address. -** AcceptRead, as its name suggests, also receives the first block of data -** sent by the peer. -** -** INPUTS: -** PRFileDesc *listenSock -** A socket descriptor that has been called with the PR_Listen() -** function, also known as the rendezvous socket. -** void *buf -** A pointer to a buffer to receive data sent by the client. This -** buffer must be large enough to receive bytes of data -** and two PRNetAddr structures, plus an extra 32 bytes. See: -** PR_ACCEPT_READ_BUF_OVERHEAD. -** PRInt32 amount -** The number of bytes of client data to receive. Does not include -** the size of the PRNetAddr structures. If 0, no data will be read -** from the client. -** PRIntervalTime timeout -** The timeout interval only applies to the read portion of the -** operation. PR_AcceptRead will block indefinitely until the -** connection is accepted; the read will timeout after the timeout -** interval elapses. -** OUTPUTS: -** PRFileDesc **acceptedSock -** The file descriptor for the newly connected socket. This parameter -** will only be valid if the function return does not indicate failure. -** PRNetAddr **peerAddr, -** The address of the remote socket. This parameter will only be -** valid if the function return does not indicate failure. The -** returned address is not guaranteed to be properly aligned. -** -** RETURNS: -** The number of bytes read from the client or -1 on failure. The reason -** for the failure is obtained by calling PR_GetError(). -************************************************************************** -**/ -/* define buffer overhead constant. Add this value to the user's -** data length when allocating a buffer to accept data. -** Example: -** #define USER_DATA_SIZE 10 -** char buf[USER_DATA_SIZE + PR_ACCEPT_READ_BUF_OVERHEAD]; -** bytesRead = PR_AcceptRead( s, fd, &a, &p, USER_DATA_SIZE, ...); -*/ -#define PR_ACCEPT_READ_BUF_OVERHEAD (32+(2*sizeof(PRNetAddr))) - -NSPR_API(PRInt32) PR_AcceptRead( - PRFileDesc *listenSock, PRFileDesc **acceptedSock, - PRNetAddr **peerAddr, void *buf, PRInt32 amount, PRIntervalTime timeout); - -/* -************************************************************************* -** FUNCTION: PR_NewTCPSocketPair -** DESCRIPTION: -** Create a new TCP socket pair. The returned descriptors can be used -** interchangeably; they are interconnected full-duplex descriptors: data -** written to one can be read from the other and vice-versa. -** -** INPUTS: -** None -** OUTPUTS: -** PRFileDesc *fds[2] -** The file descriptor pair for the newly created TCP sockets. -** RETURN: PRStatus -** Upon successful completion of TCP socket pair, PR_NewTCPSocketPair -** returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further -** failure information can be obtained by calling PR_GetError(). -** XXX can we implement this on windoze and mac? -************************************************************************** -**/ -NSPR_API(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]); - -/* -************************************************************************* -** FUNCTION: PR_GetSockName -** DESCRIPTION: -** Get socket name. Return the network address for this socket. -** -** INPUTS: -** PRFileDesc *fd -** Points to a PRFileDesc object representing the socket. -** OUTPUTS: -** PRNetAddr *addr -** Returns the address of the socket in its own communication space. -** RETURN: PRStatus -** Upon successful completion, PR_GetSockName returns PR_SUCCESS. -** Otherwise, it returns PR_FAILURE. Further failure information can -** be obtained by calling PR_GetError(). -************************************************************************** -**/ -NSPR_API(PRStatus) PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr); - -/* -************************************************************************* -** FUNCTION: PR_GetPeerName -** DESCRIPTION: -** Get name of the connected peer. Return the network address for the -** connected peer socket. -** -** INPUTS: -** PRFileDesc *fd -** Points to a PRFileDesc object representing the connected peer. -** OUTPUTS: -** PRNetAddr *addr -** Returns the address of the connected peer in its own communication -** space. -** RETURN: PRStatus -** Upon successful completion, PR_GetPeerName returns PR_SUCCESS. -** Otherwise, it returns PR_FAILURE. Further failure information can -** be obtained by calling PR_GetError(). -************************************************************************** -**/ -NSPR_API(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr); - -NSPR_API(PRStatus) PR_GetSocketOption( - PRFileDesc *fd, PRSocketOptionData *data); - -NSPR_API(PRStatus) PR_SetSocketOption( - PRFileDesc *fd, const PRSocketOptionData *data); - -/* - ********************************************************************* - * - * File descriptor inheritance - * - ********************************************************************* - */ - -/* - ************************************************************************ - * FUNCTION: PR_SetFDInheritable - * DESCRIPTION: - * Set the inheritance attribute of a file descriptor. - * - * INPUTS: - * PRFileDesc *fd - * Points to a PRFileDesc object. - * PRBool inheritable - * If PR_TRUE, the file descriptor fd is set to be inheritable - * by a child process. If PR_FALSE, the file descriptor is set - * to be not inheritable by a child process. - * RETURN: PRStatus - * Upon successful completion, PR_SetFDInheritable returns PR_SUCCESS. - * Otherwise, it returns PR_FAILURE. Further failure information can - * be obtained by calling PR_GetError(). - ************************************************************************* - */ -NSPR_API(PRStatus) PR_SetFDInheritable( - PRFileDesc *fd, - PRBool inheritable); - -/* - ************************************************************************ - * FUNCTION: PR_GetInheritedFD - * DESCRIPTION: - * Get an inherited file descriptor with the specified name. - * - * INPUTS: - * const char *name - * The name of the inherited file descriptor. - * RETURN: PRFileDesc * - * Upon successful completion, PR_GetInheritedFD returns the - * inherited file descriptor with the specified name. Otherwise, - * it returns NULL. Further failure information can be obtained - * by calling PR_GetError(). - ************************************************************************* - */ -NSPR_API(PRFileDesc *) PR_GetInheritedFD(const char *name); - -/* - ********************************************************************* - * - * Memory-mapped files - * - ********************************************************************* - */ - -typedef struct PRFileMap PRFileMap; - -/* - * protection options for read and write accesses of a file mapping - */ -typedef enum PRFileMapProtect { - PR_PROT_READONLY, /* read only */ - PR_PROT_READWRITE, /* readable, and write is shared */ - PR_PROT_WRITECOPY /* readable, and write is private (copy-on-write) */ -} PRFileMapProtect; - -NSPR_API(PRFileMap *) PR_CreateFileMap( - PRFileDesc *fd, - PRInt64 size, - PRFileMapProtect prot); - -/* - * return the alignment (in bytes) of the offset argument to PR_MemMap - */ -NSPR_API(PRInt32) PR_GetMemMapAlignment(void); - -NSPR_API(void *) PR_MemMap( - PRFileMap *fmap, - PROffset64 offset, /* must be aligned and sized according to the - * return value of PR_GetMemMapAlignment() */ - PRUint32 len); - -NSPR_API(PRStatus) PR_MemUnmap(void *addr, PRUint32 len); - -NSPR_API(PRStatus) PR_CloseFileMap(PRFileMap *fmap); - -/* - ****************************************************************** - * - * Interprocess communication - * - ****************************************************************** - */ - -/* - * Creates an anonymous pipe and returns file descriptors for the - * read and write ends of the pipe. - */ - -NSPR_API(PRStatus) PR_CreatePipe( - PRFileDesc **readPipe, - PRFileDesc **writePipe -); - -/************************************************************************/ -/************** The following definitions are for poll ******************/ -/************************************************************************/ - -struct PRPollDesc { - PRFileDesc* fd; - PRInt16 in_flags; - PRInt16 out_flags; -}; - -/* -** Bit values for PRPollDesc.in_flags or PRPollDesc.out_flags. Binary-or -** these together to produce the desired poll request. -*/ - -#if defined(_PR_POLL_BACKCOMPAT) - -#include -#define PR_POLL_READ POLLIN -#define PR_POLL_WRITE POLLOUT -#define PR_POLL_EXCEPT POLLPRI -#define PR_POLL_ERR POLLERR /* only in out_flags */ -#define PR_POLL_NVAL POLLNVAL /* only in out_flags when fd is bad */ -#define PR_POLL_HUP POLLHUP /* only in out_flags */ - -#else /* _PR_POLL_BACKCOMPAT */ - -#define PR_POLL_READ 0x1 -#define PR_POLL_WRITE 0x2 -#define PR_POLL_EXCEPT 0x4 -#define PR_POLL_ERR 0x8 /* only in out_flags */ -#define PR_POLL_NVAL 0x10 /* only in out_flags when fd is bad */ -#define PR_POLL_HUP 0x20 /* only in out_flags */ - -#endif /* _PR_POLL_BACKCOMPAT */ - -/* -************************************************************************* -** FUNCTION: PR_Poll -** DESCRIPTION: -** -** The call returns as soon as I/O is ready on one or more of the underlying -** socket objects. A count of the number of ready descriptors is -** returned unless a timeout occurs in which case zero is returned. -** -** PRPollDesc.fd should be set to a pointer to a PRFileDesc object -** representing a socket. This field can be set to NULL to indicate to -** PR_Poll that this PRFileDesc object should be ignored. -** PRPollDesc.in_flags should be set to the desired request -** (read/write/except or some combination). Upon successful return from -** this call PRPollDesc.out_flags will be set to indicate what kind of -** i/o can be performed on the respective descriptor. PR_Poll() uses the -** out_flags fields as scratch variables during the call. If PR_Poll() -** returns 0 or -1, the out_flags fields do not contain meaningful values -** and must not be used. -** -** INPUTS: -** PRPollDesc *pds A pointer to an array of PRPollDesc -** -** PRIntn npds The number of elements in the array -** If this argument is zero PR_Poll is -** equivalent to a PR_Sleep(timeout). -** -** PRIntervalTime timeout Amount of time the call will block waiting -** for I/O to become ready. If this time expires -** w/o any I/O becoming ready, the result will -** be zero. -** -** OUTPUTS: None -** RETURN: -** PRInt32 Number of PRPollDesc's with events or zero -** if the function timed out or -1 on failure. -** The reason for the failure is obtained by -** calling PR_GetError(). -************************************************************************** -*/ -NSPR_API(PRInt32) PR_Poll( - PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout); - -/* -************************************************************************** -** -** Pollable events -** -** A pollable event is a special kind of file descriptor. -** The only I/O operation you can perform on a pollable event -** is to poll it with the PR_POLL_READ flag. You can't -** read from or write to a pollable event. -** -** The purpose of a pollable event is to combine event waiting -** with I/O waiting in a single PR_Poll call. Pollable events -** are implemented using a pipe or a pair of TCP sockets -** connected via the loopback address, therefore setting and -** waiting for pollable events are expensive operating system -** calls. Do not use pollable events for general thread -** synchronization. Use condition variables instead. -** -** A pollable event has two states: set and unset. Events -** are not queued, so there is no notion of an event count. -** A pollable event is either set or unset. -** -** A new pollable event is created by a PR_NewPollableEvent -** call and is initially in the unset state. -** -** PR_WaitForPollableEvent blocks the calling thread until -** the pollable event is set, and then it atomically unsets -** the pollable event before it returns. -** -** To set a pollable event, call PR_SetPollableEvent. -** -** One can call PR_Poll with the PR_POLL_READ flag on a pollable -** event. When the pollable event is set, PR_Poll returns with -** the PR_POLL_READ flag set in the out_flags. -** -** To close a pollable event, call PR_DestroyPollableEvent -** (not PR_Close). -** -************************************************************************** -*/ - -NSPR_API(PRFileDesc *) PR_NewPollableEvent(void); - -NSPR_API(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event); - -NSPR_API(PRStatus) PR_SetPollableEvent(PRFileDesc *event); - -NSPR_API(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event); - -PR_END_EXTERN_C - -#endif /* prio_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/pripcsem.h nspr-4.10.7/mozilla/nsprpub/pr/include/pripcsem.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/pripcsem.h 2012-03-06 13:13:45.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/pripcsem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: pripcsem.h - * - * Description: named semaphores for interprocess - * synchronization - * - * Unrelated processes obtain access to a shared semaphore - * by specifying its name. - * - * Our goal is to support named semaphores on at least - * Unix and Win32 platforms. The implementation will use - * one of the three native semaphore APIs: POSIX, System V, - * and Win32. - * - * Because POSIX named semaphores have kernel persistence, - * we are forced to have a delete function in this API. - */ - -#ifndef pripcsem_h___ -#define pripcsem_h___ - -#include "prtypes.h" -#include "prio.h" - -PR_BEGIN_EXTERN_C - -/* - * PRSem is an opaque structure that represents a named - * semaphore. - */ -typedef struct PRSem PRSem; - -/* - * PR_OpenSemaphore -- - * - * Create or open a named semaphore with the specified name. - * A handle to the semaphore is returned. - * - * If the named semaphore doesn't exist and the PR_SEM_CREATE - * flag is specified, the named semaphore is created. The - * created semaphore needs to be removed from the system with - * a PR_DeleteSemaphore call. - * - * If PR_SEM_CREATE is specified, the third argument is the - * access permission bits of the new semaphore (same - * interpretation as the mode argument to PR_Open) and the - * fourth argument is the initial value of the new semaphore. - * If PR_SEM_CREATE is not specified, the third and fourth - * arguments are ignored. - */ - -#define PR_SEM_CREATE 0x1 /* create if not exist */ -#define PR_SEM_EXCL 0x2 /* fail if already exists */ - -NSPR_API(PRSem *) PR_OpenSemaphore( - const char *name, PRIntn flags, PRIntn mode, PRUintn value); - -/* - * PR_WaitSemaphore -- - * - * If the value of the semaphore is > 0, decrement the value and return. - * If the value is 0, sleep until the value becomes > 0, then decrement - * the value and return. - * - * The "test and decrement" operation is performed atomically. - */ - -NSPR_API(PRStatus) PR_WaitSemaphore(PRSem *sem); - -/* - * PR_PostSemaphore -- - * - * Increment the value of the named semaphore by 1. - */ - -NSPR_API(PRStatus) PR_PostSemaphore(PRSem *sem); - -/* - * PR_CloseSemaphore -- - * - * Close a named semaphore handle. - */ - -NSPR_API(PRStatus) PR_CloseSemaphore(PRSem *sem); - -/* - * PR_DeleteSemaphore -- - * - * Remove a named semaphore from the system. - */ - -NSPR_API(PRStatus) PR_DeleteSemaphore(const char *name); - -PR_END_EXTERN_C - -#endif /* pripcsem_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/private/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/include/private/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/include/private/.cvsignore 2001-05-12 02:03:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/private/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/private/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/include/private/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/include/private/Makefile.in 2012-03-06 13:13:56.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/private/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -RELEASE_HEADERS = pprio.h pprthred.h prpriv.h -RELEASE_HEADERS := $(addprefix $(srcdir)/, $(RELEASE_HEADERS)) -RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)/private - -HEADERS = $(RELEASE_HEADERS) $(srcdir)/pprmwait.h $(srcdir)/primpl.h - -include_subdir = private - -include $(topsrcdir)/config/rules.mk - -export:: $(RELEASE_HEADERS) - $(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)/private diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/private/pprio.h nspr-4.10.7/mozilla/nsprpub/pr/include/private/pprio.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/private/pprio.h 2012-03-06 13:13:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/private/pprio.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,242 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: pprio.h -** -** Description: Private definitions for I/O related structures -*/ - -#ifndef pprio_h___ -#define pprio_h___ - -#include "prtypes.h" -#include "prio.h" - -PR_BEGIN_EXTERN_C - -/************************************************************************/ -/************************************************************************/ - -#ifdef _WIN64 -typedef __int64 PROsfd; -#else -typedef PRInt32 PROsfd; -#endif - -/* Return the method tables for files, tcp sockets and udp sockets */ -NSPR_API(const PRIOMethods*) PR_GetFileMethods(void); -NSPR_API(const PRIOMethods*) PR_GetTCPMethods(void); -NSPR_API(const PRIOMethods*) PR_GetUDPMethods(void); -NSPR_API(const PRIOMethods*) PR_GetPipeMethods(void); - -/* -** Convert a NSPR socket handle to a native socket handle. -** -** Using this function makes your code depend on the properties of the -** current NSPR implementation, which may change (although extremely -** unlikely because of NSPR's backward compatibility requirement). Avoid -** using it if you can. -** -** If you use this function, you need to understand what NSPR does to -** the native handle. For example, NSPR puts native socket handles in -** non-blocking mode or associates them with an I/O completion port (the -** WINNT build configuration only). Your use of the native handle should -** not interfere with NSPR's use of the native handle. If your code -** changes the configuration of the native handle, (e.g., changes it to -** blocking or closes it), NSPR will not work correctly. -*/ -NSPR_API(PROsfd) PR_FileDesc2NativeHandle(PRFileDesc *); -NSPR_API(void) PR_ChangeFileDescNativeHandle(PRFileDesc *, PROsfd); -NSPR_API(PRFileDesc*) PR_AllocFileDesc(PROsfd osfd, - const PRIOMethods *methods); -NSPR_API(void) PR_FreeFileDesc(PRFileDesc *fd); -/* -** Import an existing OS file to NSPR. -*/ -NSPR_API(PRFileDesc*) PR_ImportFile(PROsfd osfd); -NSPR_API(PRFileDesc*) PR_ImportPipe(PROsfd osfd); -NSPR_API(PRFileDesc*) PR_ImportTCPSocket(PROsfd osfd); -NSPR_API(PRFileDesc*) PR_ImportUDPSocket(PROsfd osfd); - - -/* - ************************************************************************* - * FUNCTION: PR_CreateSocketPollFd - * DESCRIPTION: - * Create a PRFileDesc wrapper for a native socket handle, for use with - * PR_Poll only - * INPUTS: - * None - * OUTPUTS: - * None - * RETURN: PRFileDesc* - * Upon successful completion, PR_CreateSocketPollFd returns a pointer - * to the PRFileDesc created for the native socket handle - * Returns a NULL pointer if the create of a new PRFileDesc failed - * - ************************************************************************** - */ - -NSPR_API(PRFileDesc*) PR_CreateSocketPollFd(PROsfd osfd); - -/* - ************************************************************************* - * FUNCTION: PR_DestroySocketPollFd - * DESCRIPTION: - * Destroy the PRFileDesc wrapper created by PR_CreateSocketPollFd - * INPUTS: - * None - * OUTPUTS: - * None - * RETURN: PRFileDesc* - * Upon successful completion, PR_DestroySocketPollFd returns - * PR_SUCCESS, else PR_FAILURE - * - ************************************************************************** - */ - -NSPR_API(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd); - - -/* -** Macros for PR_Socket -** -** Socket types: PR_SOCK_STREAM, PR_SOCK_DGRAM -*/ - -#ifdef WIN32 - -#define PR_SOCK_STREAM 1 -#define PR_SOCK_DGRAM 2 - -#else /* WIN32 */ - -#define PR_SOCK_STREAM SOCK_STREAM -#define PR_SOCK_DGRAM SOCK_DGRAM - -#endif /* WIN32 */ - -/* -** Create a new Socket; this function is obsolete. -*/ -NSPR_API(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto); - -/* FUNCTION: PR_LockFile -** DESCRIPTION: -** Lock a file for exclusive access. -** RETURNS: -** PR_SUCCESS when the lock is held -** PR_FAILURE otherwise -*/ -NSPR_API(PRStatus) PR_LockFile(PRFileDesc *fd); - -/* FUNCTION: PR_TLockFile -** DESCRIPTION: -** Test and Lock a file for exclusive access. Do not block if the -** file cannot be locked immediately. -** RETURNS: -** PR_SUCCESS when the lock is held -** PR_FAILURE otherwise -*/ -NSPR_API(PRStatus) PR_TLockFile(PRFileDesc *fd); - -/* FUNCTION: PR_UnlockFile -** DESCRIPTION: -** Unlock a file which has been previously locked successfully by this -** process. -** RETURNS: -** PR_SUCCESS when the lock is released -** PR_FAILURE otherwise -*/ -NSPR_API(PRStatus) PR_UnlockFile(PRFileDesc *fd); - -/* -** Emulate acceptread by accept and recv. -*/ -NSPR_API(PRInt32) PR_EmulateAcceptRead(PRFileDesc *sd, PRFileDesc **nd, - PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout); - -/* -** Emulate sendfile by reading from the file and writing to the socket. -** The file is memory-mapped if memory-mapped files are supported. -*/ -NSPR_API(PRInt32) PR_EmulateSendFile( - PRFileDesc *networkSocket, PRSendFileData *sendData, - PRTransmitFileFlags flags, PRIntervalTime timeout); - -#ifdef WIN32 -/* FUNCTION: PR_NTFast_AcceptRead -** DESCRIPTION: -** NT has the notion of an "accept context", which is only needed in -** order to make certain calls. By default, a socket connected via -** AcceptEx can only do a limited number of things without updating -** the acceptcontext. The generic version of PR_AcceptRead always -** updates the accept context. This version does not. -**/ -NSPR_API(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, - PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime t); - -typedef void (*_PR_AcceptTimeoutCallback)(void *); - -/* FUNCTION: PR_NTFast_AcceptRead_WithTimeoutCallback -** DESCRIPTION: -** The AcceptEx call combines the accept with the read function. However, -** our daemon threads need to be able to wakeup and reliably flush their -** log buffers if the Accept times out. However, with the current blocking -** interface to AcceptRead, there is no way for us to timeout the Accept; -** this is because when we timeout the Read, we can close the newly -** socket and continue; but when we timeout the accept itself, there is no -** new socket to timeout. So instead, this version of the function is -** provided. After the initial timeout period elapses on the accept() -** portion of the function, it will call the callback routine and then -** continue the accept. If the timeout occurs on the read, it will -** close the connection and return error. -*/ -NSPR_API(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback( - PRFileDesc *sd, - PRFileDesc **nd, - PRNetAddr **raddr, - void *buf, - PRInt32 amount, - PRIntervalTime t, - _PR_AcceptTimeoutCallback callback, - void *callback_arg); - -/* FUNCTION: PR_NTFast_Accept -** DESCRIPTION: -** NT has the notion of an "accept context", which is only needed in -** order to make certain calls. By default, a socket connected via -** AcceptEx can only do a limited number of things without updating -** the acceptcontext. The generic version of PR_Accept always -** updates the accept context. This version does not. -**/ -NSPR_API(PRFileDesc*) PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr, - PRIntervalTime timeout); - -/* FUNCTION: PR_NTFast_Update -** DESCRIPTION: -** For sockets accepted with PR_NTFast_Accept or PR_NTFastAcceptRead, -** this function will update the accept context for those sockets, -** so that the socket can make general purpose socket calls. -** Without calling this, the only operations supported on the socket -** Are PR_Read, PR_Write, PR_Transmitfile, and PR_Close. -*/ -NSPR_API(void) PR_NTFast_UpdateAcceptContext(PRFileDesc *acceptSock, - PRFileDesc *listenSock); - - -/* FUNCTION: PR_NT_CancelIo -** DESCRIPTION: -** Cancel IO operations on fd. -*/ -NSPR_API(PRStatus) PR_NT_CancelIo(PRFileDesc *fd); - - -#endif /* WIN32 */ - -PR_END_EXTERN_C - -#endif /* pprio_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/private/pprmwait.h nspr-4.10.7/mozilla/nsprpub/pr/include/private/pprmwait.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/private/pprmwait.h 2012-03-06 13:13:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/private/pprmwait.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#if defined(_PPRMWAIT_H) -#else -#define _PPRMWAIT_H - -#include "prlock.h" -#include "prcvar.h" -#include "prclist.h" -#include "prthread.h" - -#define MAX_POLLING_INTERVAL 100 -#define _PR_POLL_COUNT_FUDGE 64 -#define _PR_DEFAULT_HASH_LENGTH 59 - -/* - * Our hash table resolves collisions by open addressing with - * double hashing. See Cormen, Leiserson, and Rivest, - * Introduction to Algorithms, p. 232, The MIT Press, 1990. - */ - -#define _MW_HASH(a, m) ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m)) -#define _MW_HASH2(a, m) (1 + ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m - 2))) -#define _MW_ABORTED(_rv) \ - ((PR_FAILURE == (_rv)) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) - -typedef enum {_prmw_success, _prmw_rehash, _prmw_error} _PR_HashStory; - -typedef struct _PRWaiterHash -{ - PRUint16 count; /* current number in hash table */ - PRUint16 length; /* current size of the hash table */ - PRRecvWait *recv_wait; /* hash table of receive wait objects */ -} _PRWaiterHash; - -typedef enum {_prmw_running, _prmw_stopping, _prmw_stopped} PRMWGroupState; - -struct PRWaitGroup -{ - PRCList group_link; /* all groups are linked to each other */ - PRCList io_ready; /* list of I/O requests that are ready */ - PRMWGroupState state; /* state of this group (so we can shut down) */ - - PRLock *ml; /* lock for synchronizing this wait group */ - PRCondVar *io_taken; /* calling threads notify when they take I/O */ - PRCondVar *io_complete; /* calling threads wait here for completions */ - PRCondVar *new_business; /* polling thread waits here more work */ - PRCondVar *mw_manage; /* used to manage group lists */ - PRThread* poller; /* thread that's actually doing the poll() */ - PRUint16 waiting_threads; /* number of threads waiting for recv */ - PRUint16 polling_count; /* number of elements in the polling list */ - PRUint32 p_timestamp; /* pseudo-time group had element removed */ - PRPollDesc *polling_list; /* list poller builds for polling */ - PRIntervalTime last_poll; /* last time we polled */ - _PRWaiterHash *waiter; /* pointer to hash table of wait receive objects */ - -#ifdef WINNT - /* - * On NT, idle threads are responsible for getting completed i/o. - * They need to add completed i/o to the io_ready list. Since - * idle threads cannot use nspr locks, we have to use an md lock - * to protect the io_ready list. - */ - _MDLock mdlock; /* protect io_ready, waiter, and wait_list */ - PRCList wait_list; /* used in place of io_complete. reuse - * waitQLinks in the PRThread structure. */ -#endif /* WINNT */ -}; - -/********************************************************************** -*********************************************************************** -******************** Wait group enumerations ************************** -*********************************************************************** -**********************************************************************/ -typedef struct _PRGlobalState -{ - PRCList group_list; /* master of the group list */ - PRWaitGroup *group; /* the default (NULL) group */ -} _PRGlobalState; - -#ifdef WINNT -extern PRStatus NT_HashRemoveInternal(PRWaitGroup *group, PRFileDesc *fd); -#endif - -typedef enum {_PR_ENUM_UNSEALED=0, _PR_ENUM_SEALED=0x0eadface} _PREnumSeal; - -struct PRMWaitEnumerator -{ - PRWaitGroup *group; /* group this enumerator is bound to */ - PRThread *thread; /* thread in midst of an enumeration */ - _PREnumSeal seal; /* trying to detect deleted objects */ - PRUint32 p_timestamp; /* when enumeration was (re)started */ - PRRecvWait **waiter; /* pointer into hash table */ - PRUintn index; /* position in hash table */ - void *pad[4]; /* some room to grow */ -}; - -#endif /* defined(_PPRMWAIT_H) */ - -/* pprmwait.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/private/pprthred.h nspr-4.10.7/mozilla/nsprpub/pr/include/private/pprthred.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/private/pprthred.h 2012-03-06 13:13:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/private/pprthred.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,331 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef pprthred_h___ -#define pprthred_h___ - -/* -** API for PR private functions. These calls are to be used by internal -** developers only. -*/ -#include "nspr.h" - -#if defined(XP_OS2) -#define INCL_DOS -#define INCL_DOSERRORS -#define INCL_WIN -#include -#endif - -PR_BEGIN_EXTERN_C - -/*--------------------------------------------------------------------------- -** THREAD PRIVATE FUNCTIONS ----------------------------------------------------------------------------*/ - -/* -** Associate a thread object with an existing native thread. -** "type" is the type of thread object to attach -** "priority" is the priority to assign to the thread -** "stack" defines the shape of the threads stack -** -** This can return NULL if some kind of error occurs, or if memory is -** tight. This call invokes "start(obj,arg)" and returns when the -** function returns. The thread object is automatically destroyed. -** -** This call is not normally needed unless you create your own native -** thread. PR_Init does this automatically for the primordial thread. -*/ -NSPR_API(PRThread*) PR_AttachThread(PRThreadType type, - PRThreadPriority priority, - PRThreadStack *stack); - -/* -** Detach the nspr thread from the currently executing native thread. -** The thread object will be destroyed and all related data attached -** to it. The exit procs will be invoked. -** -** This call is not normally needed unless you create your own native -** thread. PR_Exit will automatially detach the nspr thread object -** created by PR_Init for the primordial thread. -** -** This call returns after the nspr thread object is destroyed. -*/ -NSPR_API(void) PR_DetachThread(void); - -/* -** Get the id of the named thread. Each thread is assigned a unique id -** when it is created or attached. -*/ -NSPR_API(PRUint32) PR_GetThreadID(PRThread *thread); - -/* -** Set the procedure that is called when a thread is dumped. The procedure -** will be applied to the argument, arg, when called. Setting the procedure -** to NULL effectively removes it. -*/ -typedef void (*PRThreadDumpProc)(PRFileDesc *fd, PRThread *t, void *arg); -NSPR_API(void) PR_SetThreadDumpProc( - PRThread* thread, PRThreadDumpProc dump, void *arg); - -/* -** Get this thread's affinity mask. The affinity mask is a 32 bit quantity -** marking a bit for each processor this process is allowed to run on. -** The processor mask is returned in the mask argument. -** The least-significant-bit represents processor 0. -** -** Returns 0 on success, -1 on failure. -*/ -NSPR_API(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask); - -/* -** Set this thread's affinity mask. -** -** Returns 0 on success, -1 on failure. -*/ -NSPR_API(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask ); - -/* -** Set the default CPU Affinity mask. -** -*/ -NSPR_API(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask); - -/* -** Show status of all threads to standard error output. -*/ -NSPR_API(void) PR_ShowStatus(void); - -/* -** Set thread recycle mode to on (1) or off (0) -*/ -NSPR_API(void) PR_SetThreadRecycleMode(PRUint32 flag); - - -/*--------------------------------------------------------------------------- -** THREAD PRIVATE FUNCTIONS FOR GARBAGE COLLECTIBLE THREADS ----------------------------------------------------------------------------*/ - -/* -** Only Garbage collectible threads participate in resume all, suspend all and -** enumeration operations. They are also different during creation when -** platform specific action may be needed (For example, all Solaris GC able -** threads are bound threads). -*/ - -/* -** Same as PR_CreateThread except that the thread is marked as garbage -** collectible. -*/ -NSPR_API(PRThread*) PR_CreateThreadGCAble(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize); - -/* -** Same as PR_AttachThread except that the thread being attached is marked as -** garbage collectible. -*/ -NSPR_API(PRThread*) PR_AttachThreadGCAble(PRThreadType type, - PRThreadPriority priority, - PRThreadStack *stack); - -/* -** Mark the thread as garbage collectible. -*/ -NSPR_API(void) PR_SetThreadGCAble(void); - -/* -** Unmark the thread as garbage collectible. -*/ -NSPR_API(void) PR_ClearThreadGCAble(void); - -/* -** This routine prevents all other GC able threads from running. This call is needed by -** the garbage collector. -*/ -NSPR_API(void) PR_SuspendAll(void); - -/* -** This routine unblocks all other GC able threads that were suspended from running by -** PR_SuspendAll(). This call is needed by the garbage collector. -*/ -NSPR_API(void) PR_ResumeAll(void); - -/* -** Return the thread stack pointer of the given thread. -** Needed by the garbage collector. -*/ -NSPR_API(void *) PR_GetSP(PRThread *thread); - -/* -** Save the registers that the GC would find interesting into the thread -** "t". isCurrent will be non-zero if the thread state that is being -** saved is the currently executing thread. Return the address of the -** first register to be scanned as well as the number of registers to -** scan in "np". -** -** If "isCurrent" is non-zero then it is allowed for the thread context -** area to be used as scratch storage to hold just the registers -** necessary for scanning. -** -** This function simply calls the internal function _MD_HomeGCRegisters(). -*/ -NSPR_API(PRWord *) PR_GetGCRegisters(PRThread *t, int isCurrent, int *np); - -/* -** (Get|Set)ExecutionEnvironent -** -** Used by Java to associate it's execution environment so garbage collector -** can find it. If return is NULL, then it's probably not a collectable thread. -** -** There's no locking required around these calls. -*/ -NSPR_API(void*) GetExecutionEnvironment(PRThread *thread); -NSPR_API(void) SetExecutionEnvironment(PRThread* thread, void *environment); - -/* -** Enumeration function that applies "func(thread,i,arg)" to each active -** thread in the process. The enumerator returns PR_SUCCESS if the enumeration -** should continue, any other value is considered failure, and enumeration -** stops, returning the failure value from PR_EnumerateThreads. -** Needed by the garbage collector. -*/ -typedef PRStatus (PR_CALLBACK *PREnumerator)(PRThread *t, int i, void *arg); -NSPR_API(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg); - -/* -** Signature of a thread stack scanning function. It is applied to every -** contiguous group of potential pointers within a thread. Count denotes the -** number of pointers. -*/ -typedef PRStatus -(PR_CALLBACK *PRScanStackFun)(PRThread* t, - void** baseAddr, PRUword count, void* closure); - -/* -** Applies scanFun to all contiguous groups of potential pointers -** within a thread. This includes the stack, registers, and thread-local -** data. If scanFun returns a status value other than PR_SUCCESS the scan -** is aborted, and the status value is returned. -*/ -NSPR_API(PRStatus) -PR_ThreadScanStackPointers(PRThread* t, - PRScanStackFun scanFun, void* scanClosure); - -/* -** Calls PR_ThreadScanStackPointers for every thread. -*/ -NSPR_API(PRStatus) -PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure); - -/* -** Returns a conservative estimate on the amount of stack space left -** on a thread in bytes, sufficient for making decisions about whether -** to continue recursing or not. -*/ -NSPR_API(PRUword) -PR_GetStackSpaceLeft(PRThread* t); - -/*--------------------------------------------------------------------------- -** THREAD CPU PRIVATE FUNCTIONS ----------------------------------------------------------------------------*/ - -/* -** Get a pointer to the primordial CPU. -*/ -NSPR_API(struct _PRCPU *) _PR_GetPrimordialCPU(void); - -/*--------------------------------------------------------------------------- -** THREAD SYNCHRONIZATION PRIVATE FUNCTIONS ----------------------------------------------------------------------------*/ - -/* -** Create a new named monitor (named for debugging purposes). -** Monitors are re-entrant locks with a built-in condition variable. -** -** This may fail if memory is tight or if some operating system resource -** is low. -*/ -NSPR_API(PRMonitor*) PR_NewNamedMonitor(const char* name); - -/* -** Test and then lock the lock if it's not already locked by some other -** thread. Return PR_FALSE if some other thread owned the lock at the -** time of the call. -*/ -NSPR_API(PRBool) PR_TestAndLock(PRLock *lock); - -/* -** Test and then enter the mutex associated with the monitor if it's not -** already entered by some other thread. Return PR_FALSE if some other -** thread owned the mutex at the time of the call. -*/ -NSPR_API(PRBool) PR_TestAndEnterMonitor(PRMonitor *mon); - -/* -** Return the number of times that the current thread has entered the -** mutex. Returns zero if the current thread has not entered the mutex. -*/ -NSPR_API(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon); - -/* -** Just like PR_CEnterMonitor except that if the monitor is owned by -** another thread NULL is returned. -*/ -NSPR_API(PRMonitor*) PR_CTestAndEnterMonitor(void *address); - -/*--------------------------------------------------------------------------- -** PLATFORM-SPECIFIC INITIALIZATION FUNCTIONS ----------------------------------------------------------------------------*/ -#if defined(IRIX) -/* -** Irix specific initialization funtion to be called before PR_Init -** is called by the application. Sets the CONF_INITUSERS and CONF_INITSIZE -** attributes of the shared arena set up by nspr. -** -** The environment variables _NSPR_IRIX_INITUSERS and _NSPR_IRIX_INITSIZE -** can also be used to set these arena attributes. If _NSPR_IRIX_INITUSERS -** is set, but not _NSPR_IRIX_INITSIZE, the value of the CONF_INITSIZE -** attribute of the nspr arena is scaled as a function of the -** _NSPR_IRIX_INITUSERS value. -** -** If the _PR_Irix_Set_Arena_Params() is called in addition to setting the -** environment variables, the values of the environment variables are used. -** -*/ -NSPR_API(void) _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize); - -#endif /* IRIX */ - -#if defined(XP_OS2) -/* -** These functions need to be called at the start and end of a thread. -** An EXCEPTIONREGISTRATIONRECORD must be declared on the stack and its -** address passed to the two functions. -*/ -NSPR_API(void) PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* e); -NSPR_API(void) PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* e); -#endif /* XP_OS2 */ - -/* I think PR_GetMonitorEntryCount is useless. All you really want is this... */ -#define PR_InMonitor(m) (PR_GetMonitorEntryCount(m) > 0) - -/*--------------------------------------------------------------------------- -** Special X-Lock hack for client ----------------------------------------------------------------------------*/ - -#ifdef XP_UNIX -extern void PR_XLock(void); -extern void PR_XUnlock(void); -extern PRBool PR_XIsLocked(void); -#endif /* XP_UNIX */ - -PR_END_EXTERN_C - -#endif /* pprthred_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/private/primpl.h nspr-4.10.7/mozilla/nsprpub/pr/include/private/primpl.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/private/primpl.h 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/private/primpl.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,2099 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef primpl_h___ -#define primpl_h___ - -/* - * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which - * has: - * #define sigaction _sigaction_sys - * This macro causes chaos if signal.h gets included before pthread.h. - * To be safe, we include pthread.h first. - */ - -#if defined(_PR_PTHREADS) -#include -#endif - -#if defined(_PR_BTHREADS) -#include -#endif - -#ifdef WIN32 -/* - * Allow use of functions and symbols first defined in Win2k. - */ -#if !defined(WINVER) || (WINVER < 0x0500) -#undef WINVER -#define WINVER 0x0500 -#endif -#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 -#endif -#endif /* WIN32 */ - -#include "nspr.h" -#include "prpriv.h" - -typedef struct PRSegment PRSegment; - -#include "md/prosdep.h" -#include "obsolete/probslet.h" - -#ifdef _PR_HAVE_POSIX_SEMAPHORES -#include -#elif defined(_PR_HAVE_SYSV_SEMAPHORES) -#include -#endif - -/************************************************************************* -***** A Word about Model Dependent Function Naming Convention *********** -*************************************************************************/ - -/* -NSPR 2.0 must implement its function across a range of platforms -including: MAC, Windows/16, Windows/95, Windows/NT, and several -variants of Unix. Each implementation shares common code as well -as having platform dependent portions. This standard describes how -the model dependent portions are to be implemented. - -In header file pr/include/primpl.h, each publicly declared -platform dependent function is declared as: - -NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 ); -#define _PR_MD_FUNCTION _MD_FUNCTION - -In header file pr/include/md//_.h, -each #define'd macro is redefined as one of: - -#define _MD_FUNCTION -#define _MD_FUNCTION -#define _MD_FUNCTION -#define _MD_FUNCTION <_MD_Function> - -Where: - - is no definition at all. In this case, the function is not implemented -and is never called for this platform. -For example: -#define _MD_INIT_CPUS() - - is a C language macro expansion. -For example: -#define _MD_CLEAN_THREAD(_thread) \ - PR_BEGIN_MACRO \ - PR_DestroyCondVar(_thread->md.asyncIOCVar); \ - PR_DestroyLock(_thread->md.asyncIOLock); \ - PR_END_MACRO - - is some function implemented by the host operating system. -For example: -#define _MD_EXIT exit - -<_MD_function> is the name of a function implemented for this platform in -pr/src/md//.c file. -For example: -#define _MD_GETFILEINFO _MD_GetFileInfo - -In .c, the implementation is: -PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info); -*/ - -PR_BEGIN_EXTERN_C - -typedef struct _MDLock _MDLock; -typedef struct _MDCVar _MDCVar; -typedef struct _MDSegment _MDSegment; -typedef struct _MDThread _MDThread; -typedef struct _MDThreadStack _MDThreadStack; -typedef struct _MDSemaphore _MDSemaphore; -typedef struct _MDDir _MDDir; -#ifdef MOZ_UNICODE -typedef struct _MDDirUTF16 _MDDirUTF16; -#endif /* MOZ_UNICODE */ -typedef struct _MDFileDesc _MDFileDesc; -typedef struct _MDProcess _MDProcess; -typedef struct _MDFileMap _MDFileMap; - -#if defined(_PR_PTHREADS) - -/* -** The following definitions are unique to implementing NSPR using pthreads. -** Since pthreads defines most of the thread and thread synchronization -** stuff, this is a pretty small set. -*/ - -#define PT_CV_NOTIFIED_LENGTH 6 -typedef struct _PT_Notified _PT_Notified; -struct _PT_Notified -{ - PRIntn length; /* # of used entries in this structure */ - struct - { - PRCondVar *cv; /* the condition variable notified */ - PRIntn times; /* and the number of times notified */ - } cv[PT_CV_NOTIFIED_LENGTH]; - _PT_Notified *link; /* link to another of these | NULL */ -}; - -/* - * bits defined for pthreads 'state' field - */ -#define PT_THREAD_DETACHED 0x01 /* thread can't be joined */ -#define PT_THREAD_GLOBAL 0x02 /* a global thread (unlikely) */ -#define PT_THREAD_SYSTEM 0x04 /* system (not user) thread */ -#define PT_THREAD_PRIMORD 0x08 /* this is the primordial thread */ -#define PT_THREAD_ABORTED 0x10 /* thread has been interrupted */ -#define PT_THREAD_GCABLE 0x20 /* thread is garbage collectible */ -#define PT_THREAD_SUSPENDED 0x40 /* thread has been suspended */ -#define PT_THREAD_FOREIGN 0x80 /* thread is not one of ours */ -#define PT_THREAD_BOUND 0x100 /* a bound-global thread */ - -#define _PT_THREAD_INTERRUPTED(thr) \ - (!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED)) -#define _PT_THREAD_BLOCK_INTERRUPT(thr) \ - (thr->interrupt_blocked = 1) -#define _PT_THREAD_UNBLOCK_INTERRUPT(thr) \ - (thr->interrupt_blocked = 0) - -#define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE) - -/* -** Possible values for thread's suspend field -** Note that the first two can be the same as they are really mutually exclusive, -** i.e. both cannot be happening at the same time. We have two symbolic names -** just as a mnemonic. -**/ -#define PT_THREAD_RESUMED 0x80 /* thread has been resumed */ -#define PT_THREAD_SETGCABLE 0x100 /* set the GCAble flag */ - -#if defined(DEBUG) - -typedef struct PTDebug -{ - PRTime timeStarted; - PRUintn locks_created, locks_destroyed; - PRUintn locks_acquired, locks_released; - PRUintn cvars_created, cvars_destroyed; - PRUintn cvars_notified, delayed_cv_deletes; -} PTDebug; - -#endif /* defined(DEBUG) */ - -NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg); - -#else /* defined(_PR_PTHREADS) */ - -NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg); - -/* -** This section is contains those parts needed to implement NSPR on -** platforms in general. One would assume that the pthreads implementation -** included lots of the same types, at least conceptually. -*/ - -/* - * Local threads only. No multiple CPU support and hence all the - * following routines are no-op. - */ -#ifdef _PR_LOCAL_THREADS_ONLY - -#define _PR_MD_SUSPEND_THREAD(thread) -#define _PR_MD_RESUME_THREAD(thread) -#define _PR_MD_SUSPEND_CPU(cpu) -#define _PR_MD_RESUME_CPU(cpu) -#define _PR_MD_BEGIN_SUSPEND_ALL() -#define _PR_MD_END_SUSPEND_ALL() -#define _PR_MD_BEGIN_RESUME_ALL() -#define _PR_MD_END_RESUME_ALL() -#define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE - -#endif - -typedef struct _PRCPUQueue _PRCPUQueue; -typedef struct _PRCPU _PRCPU; -typedef struct _MDCPU _MDCPU; - -struct _PRCPUQueue { - _MDLock runQLock; /* lock for the run + wait queues */ - _MDLock sleepQLock; /* lock for the run + wait queues */ - _MDLock miscQLock; /* lock for the run + wait queues */ - - PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */ - PRUint32 runQReadyMask; - PRCList sleepQ; - PRIntervalTime sleepQmax; - PRCList pauseQ; - PRCList suspendQ; - PRCList waitingToJoinQ; - - PRUintn numCPUs; /* number of CPUs using this Q */ -}; - -struct _PRCPU { - PRCList links; /* link list of CPUs */ - PRUint32 id; /* id for this CPU */ - - union { - PRInt32 bits; - PRUint8 missed[4]; - } u; - PRIntn where; /* index into u.missed */ - PRPackedBool paused; /* cpu is paused */ - PRPackedBool exit; /* cpu should exit */ - - PRThread *thread; /* native thread for this CPUThread */ - PRThread *idle_thread; /* user-level idle thread for this CPUThread */ - - PRIntervalTime last_clock; /* the last time we went into - * _PR_ClockInterrupt() on this CPU - */ - - _PRCPUQueue *queue; - - _MDCPU md; -}; - -typedef struct _PRInterruptTable { - const char *name; - PRUintn missed_bit; - void (*handler)(void); -} _PRInterruptTable; - -#define _PR_CPU_PTR(_qp) \ - ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links))) - -#if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \ - && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)) -#define _MD_GET_ATTACHED_THREAD() (_PR_MD_CURRENT_THREAD()) -#endif - -#ifdef _PR_LOCAL_THREADS_ONLY - -NSPR_API(struct _PRCPU *) _pr_currentCPU; -NSPR_API(PRThread *) _pr_currentThread; -NSPR_API(PRThread *) _pr_lastThread; -NSPR_API(PRInt32) _pr_intsOff; - -#define _MD_CURRENT_CPU() (_pr_currentCPU) -#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (_cpu)) -#define _MD_CURRENT_THREAD() (_pr_currentThread) -#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread)) -#define _MD_LAST_THREAD() (_pr_lastThread) -#define _MD_SET_LAST_THREAD(t) (_pr_lastThread = t) - -#define _MD_GET_INTSOFF() (_pr_intsOff) -#define _MD_SET_INTSOFF(_val) (_pr_intsOff = _val) - - -/* The unbalanced curly braces in these two macros are intentional */ -#define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is); -#define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); } - -#endif /* _PR_LOCAL_THREADS_ONLY */ - -extern PRInt32 _native_threads_only; - -#if defined(_PR_GLOBAL_THREADS_ONLY) - -#define _MD_GET_INTSOFF() 0 -#define _MD_SET_INTSOFF(_val) -#define _PR_INTSOFF(_is) -#define _PR_FAST_INTSON(_is) -#define _PR_INTSON(_is) -#define _PR_THREAD_LOCK(_thread) -#define _PR_THREAD_UNLOCK(_thread) -#define _PR_RUNQ_LOCK(cpu) -#define _PR_RUNQ_UNLOCK(cpu) -#define _PR_SLEEPQ_LOCK(thread) -#define _PR_SLEEPQ_UNLOCK(thread) -#define _PR_MISCQ_LOCK(thread) -#define _PR_MISCQ_UNLOCK(thread) -#define _PR_CPU_LIST_LOCK() -#define _PR_CPU_LIST_UNLOCK() - -#define _PR_ADD_RUNQ(_thread, _cpu, _pri) -#define _PR_DEL_RUNQ(_thread) -#define _PR_ADD_SLEEPQ(_thread, _timeout) -#define _PR_DEL_SLEEPQ(_thread, _propogate) -#define _PR_ADD_JOINQ(_thread, _cpu) -#define _PR_DEL_JOINQ(_thread) -#define _PR_ADD_SUSPENDQ(_thread, _cpu) -#define _PR_DEL_SUSPENDQ(_thread) - -#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) - -#define _PR_IS_NATIVE_THREAD(thread) 1 -#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1 - -#else - -#define _PR_INTSOFF(_is) \ - PR_BEGIN_MACRO \ - (_is) = _PR_MD_GET_INTSOFF(); \ - _PR_MD_SET_INTSOFF(1); \ - PR_END_MACRO - -#define _PR_FAST_INTSON(_is) \ - PR_BEGIN_MACRO \ - _PR_MD_SET_INTSOFF(_is); \ - PR_END_MACRO - -#define _PR_INTSON(_is) \ - PR_BEGIN_MACRO \ - if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \ - _PR_IntsOn((_PR_MD_CURRENT_CPU())); \ - _PR_MD_SET_INTSOFF(_is); \ - PR_END_MACRO - -#ifdef _PR_LOCAL_THREADS_ONLY - -#define _PR_IS_NATIVE_THREAD(thread) 0 -#define _PR_THREAD_LOCK(_thread) -#define _PR_THREAD_UNLOCK(_thread) -#define _PR_RUNQ_LOCK(cpu) -#define _PR_RUNQ_UNLOCK(cpu) -#define _PR_SLEEPQ_LOCK(thread) -#define _PR_SLEEPQ_UNLOCK(thread) -#define _PR_MISCQ_LOCK(thread) -#define _PR_MISCQ_UNLOCK(thread) -#define _PR_CPU_LIST_LOCK() -#define _PR_CPU_LIST_UNLOCK() - -#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \ - PR_BEGIN_MACRO \ - PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \ - _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \ - PR_END_MACRO - -#define _PR_DEL_RUNQ(_thread) \ - PR_BEGIN_MACRO \ - _PRCPU *_cpu = _thread->cpu; \ - PRInt32 _pri = _thread->priority; \ - PR_REMOVE_LINK(&(_thread)->links); \ - if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \ - _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \ - PR_END_MACRO - -#define _PR_ADD_SLEEPQ(_thread, _timeout) \ - _PR_AddSleepQ(_thread, _timeout); - -#define _PR_DEL_SLEEPQ(_thread, _propogate) \ - _PR_DelSleepQ(_thread, _propogate); - -#define _PR_ADD_JOINQ(_thread, _cpu) \ - PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu)); - -#define _PR_DEL_JOINQ(_thread) \ - PR_REMOVE_LINK(&(_thread)->links); - -#define _PR_ADD_SUSPENDQ(_thread, _cpu) \ - PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu)); - -#define _PR_DEL_SUSPENDQ(_thread) \ - PR_REMOVE_LINK(&(_thread)->links); - -#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) - -#define _PR_IS_NATIVE_THREAD_SUPPORTED() 0 - -#else /* _PR_LOCAL_THREADS_ONLY */ - -/* These are for the "combined" thread model */ - -#define _PR_THREAD_LOCK(_thread) \ - _PR_MD_LOCK(&(_thread)->threadLock); - -#define _PR_THREAD_UNLOCK(_thread) \ - _PR_MD_UNLOCK(&(_thread)->threadLock); - -#define _PR_RUNQ_LOCK(_cpu) \ - PR_BEGIN_MACRO \ - _PR_MD_LOCK(&(_cpu)->queue->runQLock );\ - PR_END_MACRO - -#define _PR_RUNQ_UNLOCK(_cpu) \ - PR_BEGIN_MACRO \ - _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\ - PR_END_MACRO - -#define _PR_SLEEPQ_LOCK(_cpu) \ - _PR_MD_LOCK(&(_cpu)->queue->sleepQLock ); - -#define _PR_SLEEPQ_UNLOCK(_cpu) \ - _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock ); - -#define _PR_MISCQ_LOCK(_cpu) \ - _PR_MD_LOCK(&(_cpu)->queue->miscQLock ); - -#define _PR_MISCQ_UNLOCK(_cpu) \ - _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock ); - -#define _PR_CPU_LIST_LOCK() _PR_MD_LOCK(&_pr_cpuLock) -#define _PR_CPU_LIST_UNLOCK() _PR_MD_UNLOCK(&_pr_cpuLock) - -#define QUEUE_RUN 0x1 -#define QUEUE_SLEEP 0x2 -#define QUEUE_JOIN 0x4 -#define QUEUE_SUSPEND 0x8 -#define QUEUE_LOCK 0x10 - -#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \ - PR_BEGIN_MACRO \ - PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \ - _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \ - PR_ASSERT((_thread)->queueCount == 0); \ - (_thread)->queueCount = QUEUE_RUN; \ - PR_END_MACRO - -#define _PR_DEL_RUNQ(_thread) \ - PR_BEGIN_MACRO \ - _PRCPU *_cpu = _thread->cpu; \ - PRInt32 _pri = _thread->priority; \ - PR_REMOVE_LINK(&(_thread)->links); \ - if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \ - _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \ - PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\ - (_thread)->queueCount = 0; \ - PR_END_MACRO - -#define _PR_ADD_SLEEPQ(_thread, _timeout) \ - PR_ASSERT((_thread)->queueCount == 0); \ - (_thread)->queueCount = QUEUE_SLEEP; \ - _PR_AddSleepQ(_thread, _timeout); - -#define _PR_DEL_SLEEPQ(_thread, _propogate) \ - PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\ - (_thread)->queueCount = 0; \ - _PR_DelSleepQ(_thread, _propogate); - -#define _PR_ADD_JOINQ(_thread, _cpu) \ - PR_ASSERT((_thread)->queueCount == 0); \ - (_thread)->queueCount = QUEUE_JOIN; \ - PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu)); - -#define _PR_DEL_JOINQ(_thread) \ - PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\ - (_thread)->queueCount = 0; \ - PR_REMOVE_LINK(&(_thread)->links); - -#define _PR_ADD_SUSPENDQ(_thread, _cpu) \ - PR_ASSERT((_thread)->queueCount == 0); \ - (_thread)->queueCount = QUEUE_SUSPEND; \ - PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu)); - -#define _PR_DEL_SUSPENDQ(_thread) \ - PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\ - (_thread)->queueCount = 0; \ - PR_REMOVE_LINK(&(_thread)->links); - -#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \ - (_thread)->cpu = (_newCPU); - -#define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE) -#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1 - -#endif /* _PR_LOCAL_THREADS_ONLY */ - -#endif /* _PR_GLOBAL_THREADS_ONLY */ - -#define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1 -#define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0 - -extern _PRInterruptTable _pr_interruptTable[]; - -/* Bits for _pr_interruptState.u.missed[0,1] */ -#define _PR_MISSED_CLOCK 0x1 -#define _PR_MISSED_IO 0x2 -#define _PR_MISSED_CHILD 0x4 - -extern void _PR_IntsOn(_PRCPU *cpu); - -NSPR_API(void) _PR_WakeupCPU(void); -NSPR_API(void) _PR_PauseCPU(void); - -/************************************************************************/ - -#define _PR_LOCK_LOCK(_lock) \ - _PR_MD_LOCK(&(_lock)->ilock); -#define _PR_LOCK_UNLOCK(_lock) \ - _PR_MD_UNLOCK(&(_lock)->ilock); - -extern void _PR_UnblockLockWaiter(PRLock *lock); - -#define _PR_LOCK_PTR(_qp) \ - ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links))) - -/************************************************************************/ - -#define _PR_CVAR_LOCK(_cvar) \ - _PR_MD_LOCK(&(_cvar)->ilock); -#define _PR_CVAR_UNLOCK(_cvar) \ - _PR_MD_UNLOCK(&(_cvar)->ilock); - -extern PRStatus _PR_WaitCondVar( - PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout); -extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen); - -NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky); - -/* PRThread.flags */ -#define _PR_SYSTEM 0x01 -#define _PR_INTERRUPT 0x02 -#define _PR_ATTACHED 0x04 /* created via PR_AttachThread */ -#define _PR_PRIMORDIAL 0x08 /* the thread that called PR_Init */ -#define _PR_ON_SLEEPQ 0x10 /* thread is on the sleepQ */ -#define _PR_ON_PAUSEQ 0x20 /* thread is on the pauseQ */ -#define _PR_SUSPENDING 0x40 /* thread wants to suspend */ -#define _PR_GLOBAL_SCOPE 0x80 /* thread is global scope */ -#define _PR_IDLE_THREAD 0x200 /* this is an idle thread */ -#define _PR_GCABLE_THREAD 0x400 /* this is a collectable thread */ -#define _PR_BOUND_THREAD 0x800 /* a bound thread */ -#define _PR_INTERRUPT_BLOCKED 0x1000 /* interrupts blocked */ - -/* PRThread.state */ -#define _PR_UNBORN 0 -#define _PR_RUNNABLE 1 -#define _PR_RUNNING 2 -#define _PR_LOCK_WAIT 3 -#define _PR_COND_WAIT 4 -#define _PR_JOIN_WAIT 5 -#define _PR_IO_WAIT 6 -#define _PR_SUSPENDED 7 -#define _PR_DEAD_STATE 8 /* for debugging */ - -/* PRThreadStack.flags */ -#define _PR_STACK_VM 0x1 /* using vm instead of malloc */ -#define _PR_STACK_MAPPED 0x2 /* vm is mapped */ -#define _PR_STACK_PRIMORDIAL 0x4 /* stack for primordial thread */ - -/* -** If the default stcksize from the client is zero, we need to pick a machine -** dependent value. This is only for standard user threads. For custom threads, -** 0 has a special meaning. -** Adjust stackSize. Round up to a page boundary. -*/ - -#ifndef _MD_MINIMUM_STACK_SIZE -#define _MD_MINIMUM_STACK_SIZE 0 -#endif - -#if (!defined(HAVE_CUSTOM_USER_THREADS)) -#define _PR_ADJUST_STACKSIZE(stackSize) \ - PR_BEGIN_MACRO \ - if (stackSize == 0) \ - stackSize = _MD_DEFAULT_STACK_SIZE; \ - if (stackSize < _MD_MINIMUM_STACK_SIZE) \ - stackSize = _MD_MINIMUM_STACK_SIZE; \ - stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \ - stackSize <<= _pr_pageShift; \ - PR_END_MACRO -#else -#define _PR_ADJUST_STACKSIZE(stackSize) -#endif - -#define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD) - -#define _PR_PENDING_INTERRUPT(thr) \ - (!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT)) -#define _PR_THREAD_BLOCK_INTERRUPT(thr) \ - (thr->flags |= _PR_INTERRUPT_BLOCKED) -#define _PR_THREAD_UNBLOCK_INTERRUPT(thr) \ - (thr->flags &= ~_PR_INTERRUPT_BLOCKED) - -#define _PR_THREAD_PTR(_qp) \ - ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links))) - -#define _PR_ACTIVE_THREAD_PTR(_qp) \ - ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active))) - -#define _PR_THREAD_CONDQ_PTR(_qp) \ - ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks))) - -#define _PR_THREAD_MD_TO_PTR(_md) \ - ((PRThread*) ((char*) (_md) - offsetof(PRThread,md))) - -#define _PR_THREAD_STACK_TO_PTR(_stack) \ - ((PRThread*) (_stack->thr)) - -extern PRCList _pr_active_local_threadQ; -extern PRCList _pr_active_global_threadQ; -extern PRCList _pr_cpuQ; -extern _MDLock _pr_cpuLock; -extern PRInt32 _pr_md_idle_cpus; - -#define _PR_ACTIVE_LOCAL_THREADQ() _pr_active_local_threadQ -#define _PR_ACTIVE_GLOBAL_THREADQ() _pr_active_global_threadQ -#define _PR_CPUQ() _pr_cpuQ -#define _PR_RUNQ(_cpu) ((_cpu)->queue->runQ) -#define _PR_RUNQREADYMASK(_cpu) ((_cpu)->queue->runQReadyMask) -#define _PR_SLEEPQ(_cpu) ((_cpu)->queue->sleepQ) -#define _PR_SLEEPQMAX(_cpu) ((_cpu)->queue->sleepQmax) -#define _PR_PAUSEQ(_cpu) ((_cpu)->queue->pauseQ) -#define _PR_SUSPENDQ(_cpu) ((_cpu)->queue->suspendQ) -#define _PR_WAITINGTOJOINQ(_cpu) ((_cpu)->queue->waitingToJoinQ) - -extern PRUint32 _pr_recycleThreads; /* Flag for behavior on thread cleanup */ -extern PRLock *_pr_deadQLock; -extern PRUint32 _pr_numNativeDead; -extern PRUint32 _pr_numUserDead; -extern PRCList _pr_deadNativeQ; -extern PRCList _pr_deadUserQ; -#define _PR_DEADNATIVEQ _pr_deadNativeQ -#define _PR_DEADUSERQ _pr_deadUserQ -#define _PR_DEADQ_LOCK PR_Lock(_pr_deadQLock); -#define _PR_DEADQ_UNLOCK PR_Unlock(_pr_deadQLock); -#define _PR_INC_DEADNATIVE (_pr_numNativeDead++) -#define _PR_DEC_DEADNATIVE (_pr_numNativeDead--) -#define _PR_NUM_DEADNATIVE (_pr_numNativeDead) -#define _PR_INC_DEADUSER (_pr_numUserDead++) -#define _PR_DEC_DEADUSER (_pr_numUserDead--) -#define _PR_NUM_DEADUSER (_pr_numUserDead) - -extern PRUint32 _pr_utid; - -extern struct _PRCPU *_pr_primordialCPU; - -extern PRLock *_pr_activeLock; /* lock for userActive and systemActive */ -extern PRInt32 _pr_userActive; /* number of active user threads */ -extern PRInt32 _pr_systemActive; /* number of active system threads */ -extern PRInt32 _pr_primordialExitCount; /* number of user threads left - * before the primordial thread - * can exit. */ -extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for - * notifying the primordial thread - * when all other user threads - * have terminated. */ - -extern PRUintn _pr_maxPTDs; - -extern PRLock *_pr_terminationCVLock; - -/************************************************************************* -* Internal routines either called by PR itself or from machine-dependent * -* code. * -*************************************************************************/ - -extern void _PR_ClockInterrupt(void); - -extern void _PR_Schedule(void); -extern void _PR_SetThreadPriority( - PRThread* thread, PRThreadPriority priority); - -/*********************************************************************** -** FUNCTION: _PR_NewSegment() -** DESCRIPTION: -** Allocate a memory segment. The "size" value is rounded up to the -** native system page size and a page aligned portion of memory is -** returned. This memory is not part of the malloc heap. If "vaddr" is -** not NULL then PR tries to allocate the segment at the desired virtual -** address. -** INPUTS: size: size of the desired memory segment -** vaddr: address at which the newly aquired segment is to be -** mapped into memory. -** OUTPUTS: a memory segment is allocated, a PRSegment is allocated -** RETURN: pointer to PRSegment -***********************************************************************/ -extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr); - -/*********************************************************************** -** FUNCTION: _PR_DestroySegment() -** DESCRIPTION: -** The memory segment and the PRSegment are freed -** INPUTS: seg: pointer to PRSegment to be freed -** OUTPUTS: the the PRSegment and its associated memory segment are freed -** RETURN: void -***********************************************************************/ -extern void _PR_DestroySegment(PRSegment *seg); - -extern PRThreadStack * _PR_NewStack(PRUint32 stackSize); -extern void _PR_FreeStack(PRThreadStack *stack); -extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me); -extern void _PR_NotifyLockedThread (PRThread *thread); - -NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout); -NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time); - -extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread); - -NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize, - PRUint32 flags); - -extern void _PR_NativeDestroyThread(PRThread *thread); -extern void _PR_UserDestroyThread(PRThread *thread); - -extern PRThread* _PRI_AttachThread( - PRThreadType type, PRThreadPriority priority, - PRThreadStack *stack, PRUint32 flags); - -extern void _PRI_DetachThread(void); - - -#define _PR_IO_PENDING(_thread) ((_thread)->io_pending) - -NSPR_API(void) _PR_MD_INIT_CPUS(); -#define _PR_MD_INIT_CPUS _MD_INIT_CPUS - -NSPR_API(void) _PR_MD_WAKEUP_CPUS(); -#define _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS - -/* Interrupts related */ - -NSPR_API(void) _PR_MD_START_INTERRUPTS(void); -#define _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS - -NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void); -#define _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS - -NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void); -#define _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS - -NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void); -#define _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS - -NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void); -#define _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS - -NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void); -#define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS - -/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and - * awaken a thread which is waiting on a lock or cvar. - */ -extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout); -#define _PR_MD_WAIT _MD_WAIT - -extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *); -#define _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER - -#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ -NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void); -#define _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT -#endif - -/* Stack debugging */ -NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone); -#define _PR_MD_INIT_STACK _MD_INIT_STACK - -NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts); -#define _PR_MD_CLEAR_STACK _MD_CLEAR_STACK - -/* CPU related */ -NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void); -#define _PR_MD_GET_INTSOFF _MD_GET_INTSOFF - -NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val); -#define _PR_MD_SET_INTSOFF _MD_SET_INTSOFF - -NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void); -#define _PR_MD_CURRENT_CPU _MD_CURRENT_CPU - -NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu); -#define _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU - -NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu); -#define _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU - -/* - * Returns the number of threads awoken or 0 if a timeout occurred; - */ -extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout); -#define _PR_MD_PAUSE_CPU _MD_PAUSE_CPU - -extern void _PR_MD_CLEANUP_BEFORE_EXIT(void); -#define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT - -extern void _PR_MD_EXIT(PRIntn status); -#define _PR_MD_EXIT _MD_EXIT - -/* Locks related */ - -NSPR_API(void) _PR_MD_INIT_LOCKS(void); -#define _PR_MD_INIT_LOCKS _MD_INIT_LOCKS - -NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md); -#define _PR_MD_NEW_LOCK _MD_NEW_LOCK - -NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md); -#define _PR_MD_FREE_LOCK _MD_FREE_LOCK - -NSPR_API(void) _PR_MD_LOCK(_MDLock *md); -#define _PR_MD_LOCK _MD_LOCK - -/* Return 0 on success, a nonzero value on failure. */ -NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md); -#define _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK - -NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md); -#define _PR_MD_UNLOCK _MD_UNLOCK - -NSPR_API(void) _PR_MD_IOQ_LOCK(void); -#define _PR_MD_IOQ_LOCK _MD_IOQ_LOCK - -NSPR_API(void) _PR_MD_IOQ_UNLOCK(void); -#define _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK - -#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ -/* Semaphore related -- only for native threads */ -#ifdef HAVE_CVAR_BUILT_ON_SEM -NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value); -#define _PR_MD_NEW_SEM _MD_NEW_SEM - -NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md); -#define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM - -NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM( - _MDSemaphore *md, PRIntervalTime timeout); -#define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM - -NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md); -#define _PR_MD_WAIT_SEM _MD_WAIT_SEM - -NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md); -#define _PR_MD_POST_SEM _MD_POST_SEM -#endif /* HAVE_CVAR_BUILT_ON_SEM */ - -#endif - -/* Condition Variables related -- only for native threads */ - -#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ -NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md); -#define _PR_MD_NEW_CV _MD_NEW_CV - -NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md); -#define _PR_MD_FREE_CV _MD_FREE_CV - -NSPR_API(void) _PR_MD_WAIT_CV( - _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout); -#define _PR_MD_WAIT_CV _MD_WAIT_CV - -NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock); -#define _PR_MD_NOTIFY_CV _MD_NOTIFY_CV - -NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock); -#define _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV -#endif /* _PR_LOCAL_THREADS_ONLY */ - -/* Threads related */ -NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void); -#define _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD - -NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void); -#define _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD - -NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void); -#define _PR_MD_LAST_THREAD _MD_LAST_THREAD - -NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread); -#define _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD - -NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread); -#define _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD - -extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread); -#define _PR_MD_INIT_THREAD _MD_INIT_THREAD - -extern void _PR_MD_EXIT_THREAD(PRThread *thread); -#define _PR_MD_EXIT_THREAD _MD_EXIT_THREAD - -#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ - -NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread); -#define _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD - -extern void _PR_MD_SUSPEND_THREAD(PRThread *thread); -#define _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD - -extern void _PR_MD_RESUME_THREAD(PRThread *thread); -#define _PR_MD_RESUME_THREAD _MD_RESUME_THREAD - -extern void _PR_MD_SUSPEND_CPU(_PRCPU *cpu); -#define _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU - -extern void _PR_MD_RESUME_CPU(_PRCPU *cpu); -#define _PR_MD_RESUME_CPU _MD_RESUME_CPU - -extern void _PR_MD_BEGIN_SUSPEND_ALL(void); -#define _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL - -extern void _PR_MD_END_SUSPEND_ALL(void); -#define _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL - -extern void _PR_MD_BEGIN_RESUME_ALL(void); -#define _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL - -extern void _PR_MD_END_RESUME_ALL(void); -#define _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL - -#if defined(IRIX) -NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void); -#endif /* IRIX */ - -#endif /* !_PR_LOCAL_THREADS_ONLY */ - -extern void _PR_MD_CLEAN_THREAD(PRThread *thread); -#define _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD - -#ifdef HAVE_CUSTOM_USER_THREADS -extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *); -#define _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD - -extern PRThread* _PR_MD_CREATE_USER_THREAD( - PRUint32 stacksize, - void (*start)(void *), - void *arg); -#define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD -#endif - -extern PRStatus _PR_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize); -#define _PR_MD_CREATE_THREAD _MD_CREATE_THREAD - -extern void _PR_MD_JOIN_THREAD(_MDThread *md); -#define _PR_MD_JOIN_THREAD _MD_JOIN_THREAD - -extern void _PR_MD_END_THREAD(void); -#define _PR_MD_END_THREAD _MD_END_THREAD - -extern void _PR_MD_YIELD(void); -#define _PR_MD_YIELD _MD_YIELD - -extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri); -#define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY - -extern void _PR_MD_SET_CURRENT_THREAD_NAME(const char *name); -#define _PR_MD_SET_CURRENT_THREAD_NAME _MD_SET_CURRENT_THREAD_NAME - -NSPR_API(void) _PR_MD_SUSPENDALL(void); -#define _PR_MD_SUSPENDALL _MD_SUSPENDALL - -NSPR_API(void) _PR_MD_RESUMEALL(void); -#define _PR_MD_RESUMEALL _MD_RESUMEALL - -extern void _PR_MD_INIT_CONTEXT( - PRThread *thread, char *top, void (*start) (void), PRBool *status); -#define _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT - -extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread); -#define _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT - -extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread); -#define _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT - -/* Segment related */ -extern void _PR_MD_INIT_SEGS(void); -#define _PR_MD_INIT_SEGS _MD_INIT_SEGS - -extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr); -#define _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT - -extern void _PR_MD_FREE_SEGMENT(PRSegment *seg); -#define _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT - -/* Directory enumeration related */ -extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name); -#define _PR_MD_OPEN_DIR _MD_OPEN_DIR - -extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags); -#define _PR_MD_READ_DIR _MD_READ_DIR - -extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md); -#define _PR_MD_CLOSE_DIR _MD_CLOSE_DIR - -/* Named semaphores related */ -extern PRSem * _PR_MD_OPEN_SEMAPHORE( - const char *osname, PRIntn flags, PRIntn mode, PRUintn value); -#define _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE - -extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem); -#define _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE - -extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem); -#define _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE - -extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem); -#define _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE - -extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname); -#define _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE - -/* I/O related */ -extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd); -#define _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC - -extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd); -#define _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK - -/* File I/O related */ -extern PROsfd _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode); -#define _PR_MD_OPEN _MD_OPEN - -extern PROsfd _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode); -#define _PR_MD_OPEN_FILE _MD_OPEN_FILE - -extern PRInt32 _PR_MD_CLOSE_FILE(PROsfd osfd); -#define _PR_MD_CLOSE_FILE _MD_CLOSE_FILE - -extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount); -#define _PR_MD_READ _MD_READ - -extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount); -#define _PR_MD_WRITE _MD_WRITE - -extern PRInt32 _PR_MD_WRITEV( - PRFileDesc *fd, const struct PRIOVec *iov, - PRInt32 iov_size, PRIntervalTime timeout); -#define _PR_MD_WRITEV _MD_WRITEV - -extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd); -#define _PR_MD_FSYNC _MD_FSYNC - -extern PRInt32 _PR_MD_DELETE(const char *name); -#define _PR_MD_DELETE _MD_DELETE - -extern PRInt32 _PR_MD_RENAME(const char *from, const char *to); -#define _PR_MD_RENAME _MD_RENAME - -extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how); -#define _PR_MD_ACCESS _MD_ACCESS - -extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf); -#define _PR_MD_STAT _MD_STAT - -extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode); -#define _PR_MD_MKDIR _MD_MKDIR - -extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode); -#define _PR_MD_MAKE_DIR _MD_MAKE_DIR - -extern PRInt32 _PR_MD_RMDIR(const char *name); -#define _PR_MD_RMDIR _MD_RMDIR - -#ifdef MOZ_UNICODE -/* UTF16 File I/O related */ -extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name); -#define _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16 - -extern PROsfd _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode); -#define _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16 - -extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags); -#define _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16 - -extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md); -#define _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16 - -extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info); -#define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16 -#endif /* MOZ_UNICODE */ - -/* Socket I/O related */ -extern void _PR_MD_INIT_IO(void); -#define _PR_MD_INIT_IO _MD_INIT_IO - -extern PRInt32 _PR_MD_CLOSE_SOCKET(PROsfd osfd); -#define _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET - -extern PRInt32 _PR_MD_CONNECT( - PRFileDesc *fd, const PRNetAddr *addr, - PRUint32 addrlen, PRIntervalTime timeout); -#define _PR_MD_CONNECT _MD_CONNECT - -extern PROsfd _PR_MD_ACCEPT( - PRFileDesc *fd, PRNetAddr *addr, - PRUint32 *addrlen, PRIntervalTime timeout); -#define _PR_MD_ACCEPT _MD_ACCEPT - -extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen); -#define _PR_MD_BIND _MD_BIND - -extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog); -#define _PR_MD_LISTEN _MD_LISTEN - -extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how); -#define _PR_MD_SHUTDOWN _MD_SHUTDOWN - -extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout); -#define _PR_MD_RECV _MD_RECV - -extern PRInt32 _PR_MD_SEND( - PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - PRIntervalTime timeout); -#define _PR_MD_SEND _MD_SEND - -extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, - PRNetAddr **raddr, void *buf, PRInt32 amount, - PRIntervalTime timeout); -#define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ - -#ifdef WIN32 -extern PROsfd _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, - PRUint32 *addrlen, PRIntervalTime timeout, - PRBool fast, - _PR_AcceptTimeoutCallback callback, - void *callbackArg); - -extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, - PRNetAddr **raddr, void *buf, PRInt32 amount, - PRIntervalTime timeout, PRBool fast, - _PR_AcceptTimeoutCallback callback, - void *callbackArg); - -extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls); -#define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT -/* - * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME. - * We store the value in a PRTime variable for convenience. - * This constant is used by _PR_FileTimeToPRTime(). - * This is defined in ntmisc.c - */ -extern const PRTime _pr_filetime_offset; -#endif /* WIN32 */ - -extern PRInt32 _PR_MD_SENDFILE( - PRFileDesc *sock, PRSendFileData *sfd, - PRInt32 flags, PRIntervalTime timeout); -#define _PR_MD_SENDFILE _MD_SENDFILE - -extern PRStatus _PR_MD_GETSOCKNAME( - PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); -#define _PR_MD_GETSOCKNAME _MD_GETSOCKNAME - -extern PRStatus _PR_MD_GETPEERNAME( - PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); -#define _PR_MD_GETPEERNAME _MD_GETPEERNAME - -extern PRStatus _PR_MD_GETSOCKOPT( - PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen); -#define _PR_MD_GETSOCKOPT _MD_GETSOCKOPT - -extern PRStatus _PR_MD_SETSOCKOPT( - PRFileDesc *fd, PRInt32 level, PRInt32 optname, - const char* optval, PRInt32 optlen); -#define _PR_MD_SETSOCKOPT _MD_SETSOCKOPT - -extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption( - PRFileDesc *fd, PRSocketOptionData *data); - -extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption( - PRFileDesc *fd, const PRSocketOptionData *data); - -extern PRInt32 _PR_MD_RECVFROM( - PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout); -#define _PR_MD_RECVFROM _MD_RECVFROM - -extern PRInt32 _PR_MD_SENDTO( - PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); -#define _PR_MD_SENDTO _MD_SENDTO - -extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd); -#define _PR_MD_SOCKETPAIR _MD_SOCKETPAIR - -extern PROsfd _PR_MD_SOCKET(int af, int type, int flags); -#define _PR_MD_SOCKET _MD_SOCKET - -extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd); -#define _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE - -extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd); -#define _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE - -extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, - PRIntervalTime timeout); -#define _PR_MD_PR_POLL _MD_PR_POLL - -/* - * Initialize fd->secret->inheritable for a newly created fd. - * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd) - * was created by NSPR and hence has the OS-dependent default - * inheritable attribute. If 'imported' is true, the osfd was - * not created by NSPR and hence a system call is required to - * query its inheritable attribute. Since we may never need to - * know the inheritable attribute of a fd, a platform may choose - * to initialize fd->secret->inheritable of an imported fd to - * _PR_TRI_UNKNOWN and only pay the cost of the system call - * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary. - */ -extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported); -#define _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE - -extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable); -#define _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE - - -#define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \ - if (_PR_PENDING_INTERRUPT(me)) { \ - me->flags &= ~_PR_INTERRUPT; \ - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \ - } else { \ - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \ - } - -extern void *_PR_MD_GET_SP(PRThread *thread); -#define _PR_MD_GET_SP _MD_GET_SP - -#endif /* defined(_PR_PTHREADS) */ - -/************************************************************************/ -/************************************************************************* -** The remainder of the definitions are shared by pthreads and the classic -** NSPR code. These too may be conditionalized. -*************************************************************************/ -/************************************************************************/ - -extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence); -#define _PR_MD_LSEEK _MD_LSEEK - -extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence); -#define _PR_MD_LSEEK64 _MD_LSEEK64 - -extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info); -#define _PR_MD_GETFILEINFO _MD_GETFILEINFO - -extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info); -#define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64 - -extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info); -#define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO - -extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info); -#define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64 - - -/*****************************************************************************/ -/************************** File descriptor caching **************************/ -/*****************************************************************************/ -extern void _PR_InitFdCache(void); -extern void _PR_CleanupFdCache(void); -extern PRFileDesc *_PR_Getfd(void); -extern void _PR_Putfd(PRFileDesc *fd); - -/* - * These flags are used by NSPR temporarily in the poll - * descriptor's out_flags field to record the mapping of - * NSPR's poll flags to the system poll flags. - * - * If _PR_POLL_READ_SYS_WRITE bit is set, it means the - * PR_POLL_READ flag specified by the topmost layer is - * mapped to the WRITE flag at the system layer. Similarly - * for the other three _PR_POLL_XXX_SYS_YYY flags. It is - * assumed that the PR_POLL_EXCEPT flag doesn't get mapped - * to other flags. - */ -#define _PR_POLL_READ_SYS_READ 0x1 -#define _PR_POLL_READ_SYS_WRITE 0x2 -#define _PR_POLL_WRITE_SYS_READ 0x4 -#define _PR_POLL_WRITE_SYS_WRITE 0x8 - -/* -** These methods are coerced into file descriptor methods table -** when the intended service is inappropriate for the particular -** type of file descriptor. -*/ -extern PRIntn _PR_InvalidInt(void); -extern PRInt16 _PR_InvalidInt16(void); -extern PRInt64 _PR_InvalidInt64(void); -extern PRStatus _PR_InvalidStatus(void); -extern PRFileDesc *_PR_InvalidDesc(void); - -extern PRIOMethods _pr_faulty_methods; - -/* -** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union -** whose 'family' field is set. It returns the size of the union -** member corresponding to the specified address family. -*/ - -extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr); - -#if defined(_PR_INET6) - -#define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr) - -#elif defined(_PR_HAVE_MD_SOCKADDR_IN6) - -/* -** Under the following conditions: -** 1. _PR_INET6 is not defined; -** 2. _PR_INET6_PROBE is defined; -** 3. struct sockaddr_in6 has nonstandard fields at the end -** (e.g., on Solaris 8), -** (_addr)->ipv6 is smaller than struct sockaddr_in6, and -** hence we can't pass sizeof((_addr)->ipv6) to socket -** functions such as connect because they would fail with -** EINVAL. -** -** To pass the correct socket address length to socket -** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and -** define struct _md_sockaddr_in6 to be isomorphic to -** struct sockaddr_in6. -*/ - -#if defined(XP_UNIX) || defined(XP_OS2) -#define PR_NETADDR_SIZE(_addr) \ - ((_addr)->raw.family == PR_AF_INET \ - ? sizeof((_addr)->inet) \ - : ((_addr)->raw.family == PR_AF_INET6 \ - ? sizeof(struct _md_sockaddr_in6) \ - : sizeof((_addr)->local))) -#else -#define PR_NETADDR_SIZE(_addr) \ - ((_addr)->raw.family == PR_AF_INET \ - ? sizeof((_addr)->inet) \ - : sizeof(struct _md_sockaddr_in6)) -#endif /* defined(XP_UNIX) */ - -#else - -#if defined(XP_UNIX) || defined(XP_OS2) -#define PR_NETADDR_SIZE(_addr) \ - ((_addr)->raw.family == PR_AF_INET \ - ? sizeof((_addr)->inet) \ - : ((_addr)->raw.family == PR_AF_INET6 \ - ? sizeof((_addr)->ipv6) \ - : sizeof((_addr)->local))) -#else -#define PR_NETADDR_SIZE(_addr) \ - ((_addr)->raw.family == PR_AF_INET \ - ? sizeof((_addr)->inet) \ - : sizeof((_addr)->ipv6)) -#endif /* defined(XP_UNIX) */ - -#endif /* defined(_PR_INET6) */ - -extern PRStatus _PR_MapOptionName( - PRSockOption optname, PRInt32 *level, PRInt32 *name); -extern void _PR_InitThreads( - PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs); - -struct PRLock { -#if defined(_PR_PTHREADS) - pthread_mutex_t mutex; /* the underlying lock */ - _PT_Notified notified; /* array of conditions notified */ - PRBool locked; /* whether the mutex is locked */ - pthread_t owner; /* if locked, current lock owner */ -#elif defined(_PR_BTHREADS) - sem_id semaphoreID; /* the underlying lock */ - int32 benaphoreCount; /* number of people in lock */ - thread_id owner; /* current lock owner */ -#else /* not pthreads or Be threads */ - PRCList links; /* linkage for PRThread.lockList */ - struct PRThread *owner; /* current lock owner */ - PRCList waitQ; /* list of threads waiting for lock */ - PRThreadPriority priority; /* priority of lock */ - PRThreadPriority boostPriority; /* boosted priority of lock owner */ - _MDLock ilock; /* Internal Lock to protect user-level fields */ -#endif -}; - -extern void _PR_InitLocks(void); - -struct PRCondVar { - PRLock *lock; /* associated lock that protects the condition */ -#if defined(_PR_PTHREADS) - pthread_cond_t cv; /* underlying pthreads condition */ - PRInt32 notify_pending; /* CV has destroy pending notification */ -#elif defined(_PR_BTHREADS) - sem_id sem; /* the underlying lock */ - sem_id handshakeSem; /* the lock for 'notify'-threads waiting for confirmation */ - sem_id signalSem; /* the lock for threads waiting for someone to notify */ - volatile int32 nw; /* the number waiting */ - volatile int32 ns; /* the number signalling */ - long signalBenCount; /* the number waiting on the underlying sem */ -#else /* not pthreads or Be threads */ - PRCList condQ; /* Condition variable wait Q */ - _MDLock ilock; /* Internal Lock to protect condQ */ - _MDCVar md; -#endif -}; - -/************************************************************************/ - -struct PRMonitor { - const char* name; /* monitor name for debugging */ -#if defined(_PR_PTHREADS) - PRLock lock; /* the lock structure */ - pthread_t owner; /* the owner of the lock or invalid */ - PRCondVar *cvar; /* condition variable queue */ -#else /* defined(_PR_PTHREADS) */ - PRCondVar *cvar; /* associated lock and condition variable queue */ -#endif /* defined(_PR_PTHREADS) */ - PRUint32 entryCount; /* # of times re-entered */ -}; - -/************************************************************************/ - -struct PRSemaphore { -#if defined(_PR_BTHREADS) - sem_id sem; - int32 benaphoreCount; -#else - PRCondVar *cvar; /* associated lock and condition variable queue */ - PRUintn count; /* the value of the counting semaphore */ - PRUint32 waiters; /* threads waiting on the semaphore */ -#if defined(_PR_PTHREADS) -#else /* defined(_PR_PTHREADS) */ - _MDSemaphore md; -#endif /* defined(_PR_PTHREADS) */ -#endif /* defined(_PR_BTHREADS) */ -}; - -NSPR_API(void) _PR_InitSem(void); - -/*************************************************************************/ - -struct PRSem { -#ifdef _PR_HAVE_POSIX_SEMAPHORES - sem_t *sem; -#elif defined(_PR_HAVE_SYSV_SEMAPHORES) - int semid; -#elif defined(WIN32) - HANDLE sem; -#else - PRInt8 notused; -#endif -}; - -/*************************************************************************/ - -struct PRStackStr { - /* head MUST be at offset 0; assembly language code relies on this */ -#if defined(AIX) - volatile PRStackElem prstk_head; -#else - PRStackElem prstk_head; -#endif - - PRLock *prstk_lock; - char *prstk_name; -}; - -/************************************************************************/ - -/* XXX this needs to be exported (sigh) */ -struct PRThreadStack { - PRCList links; - PRUintn flags; - - char *allocBase; /* base of stack's allocated memory */ - PRUint32 allocSize; /* size of stack's allocated memory */ - char *stackBottom; /* bottom of stack from C's point of view */ - char *stackTop; /* top of stack from C's point of view */ - PRUint32 stackSize; /* size of usable portion of the stack */ - - PRSegment *seg; - PRThread* thr; /* back pointer to thread owning this stack */ - -#if defined(_PR_PTHREADS) -#else /* defined(_PR_PTHREADS) */ - _MDThreadStack md; -#endif /* defined(_PR_PTHREADS) */ -}; - -extern void _PR_DestroyThreadPrivate(PRThread*); - -typedef void (PR_CALLBACK *_PRStartFn)(void *); - -struct PRThread { - PRUint32 state; /* thread's creation state */ - PRThreadPriority priority; /* apparent priority, loosly defined */ - - void *arg; /* argument to the client's entry point */ - _PRStartFn startFunc; /* the root of the client's thread */ - - PRThreadStack *stack; /* info about thread's stack (for GC) */ - void *environment; /* pointer to execution environment */ - - PRThreadDumpProc dump; /* dump thread info out */ - void *dumpArg; /* argument for the dump function */ - - /* - ** Per thread private data - */ - PRUint32 tpdLength; /* thread's current vector length */ - void **privateData; /* private data vector or NULL */ - PRErrorCode errorCode; /* current NSPR error code | zero */ - PRInt32 osErrorCode; /* mapping of errorCode | zero */ - PRIntn errorStringLength; /* textLength from last call to PR_SetErrorText() */ - PRInt32 errorStringSize; /* malloc()'d size of buffer | zero */ - char *errorString; /* current error string | NULL */ - char *name; /* thread's name */ - -#if defined(_PR_PTHREADS) - pthread_t id; /* pthread identifier for the thread */ - PRBool okToDelete; /* ok to delete the PRThread struct? */ - PRCondVar *waiting; /* where the thread is waiting | NULL */ - void *sp; /* recorded sp for garbage collection */ - PRThread *next, *prev; /* simple linked list of all threads */ - PRUint32 suspend; /* used to store suspend and resume flags */ -#ifdef PT_NO_SIGTIMEDWAIT - pthread_mutex_t suspendResumeMutex; - pthread_cond_t suspendResumeCV; -#endif - PRUint32 interrupt_blocked; /* interrupt blocked */ - struct pollfd *syspoll_list; /* Unix polling list used by PR_Poll */ - PRUint32 syspoll_count; /* number of elements in syspoll_list */ -#if defined(_PR_POLL_WITH_SELECT) - int *selectfd_list; /* Unix fd's that PR_Poll selects on */ - PRUint32 selectfd_count; /* number of elements in selectfd_list */ -#endif -#elif defined(_PR_BTHREADS) - PRUint32 flags; - _MDThread md; - PRBool io_pending; - PRInt32 io_fd; - PRBool io_suspended; -#else /* not pthreads or Be threads */ - _MDLock threadLock; /* Lock to protect thread state variables. - * Protects the following fields: - * state - * priority - * links - * wait - * cpu - */ - PRUint32 queueCount; - PRUint32 waitCount; - - PRCList active; /* on list of all active threads */ - PRCList links; - PRCList waitQLinks; /* when thread is PR_Wait'ing */ - PRCList lockList; /* list of locks currently holding */ - PRIntervalTime sleep; /* sleep time when thread is sleeping */ - struct _wait { - struct PRLock *lock; - struct PRCondVar *cvar; - } wait; - - PRUint32 id; - PRUint32 flags; - PRUint32 no_sched; /* Don't schedule the thread to run. - * This flag has relevance only when - * multiple NSPR CPUs are created. - * When a thread is de-scheduled, there - * is a narrow window of time in which - * the thread is put on the run queue - * but the scheduler is actually using - * the stack of this thread. It is safe - * to run this thread on a different CPU - * only when its stack is not in use on - * any other CPU. The no_sched flag is - * set during this interval to prevent - * the thread from being scheduled on a - * different CPU. - */ - - /* thread termination condition variable for join */ - PRCondVar *term; - - _PRCPU *cpu; /* cpu to which this thread is bound */ - PRUint32 threadAllocatedOnStack;/* boolean */ - - /* When an async IO is in progress and a second async IO cannot be - * initiated, the io_pending flag is set to true. Some platforms will - * not use the io_pending flag. If the io_pending flag is true, then - * io_fd is the OS-file descriptor on which IO is pending. - */ - PRBool io_pending; - PRInt32 io_fd; - - /* If a timeout occurs or if an outstanding IO is interrupted and the - * OS doesn't support a real cancellation (NT or MAC), then the - * io_suspended flag will be set to true. The thread will be resumed - * but may run into trouble issuing additional IOs until the io_pending - * flag can be cleared - */ - PRBool io_suspended; - - _MDThread md; -#endif -}; - -struct PRProcessAttr { - PRFileDesc *stdinFd; - PRFileDesc *stdoutFd; - PRFileDesc *stderrFd; - char *currentDirectory; - char *fdInheritBuffer; - PRSize fdInheritBufferSize; - PRSize fdInheritBufferUsed; -}; - -struct PRProcess { - _MDProcess md; -}; - -struct PRFileMap { - PRFileDesc *fd; - PRFileMapProtect prot; - _MDFileMap md; -}; - -/************************************************************************/ - -/* -** File descriptors of the NSPR layer can be in one of the -** following states (stored in the 'state' field of struct -** PRFilePrivate): -** - _PR_FILEDESC_OPEN: The OS fd is open. -** - _PR_FILEDESC_CLOSED: The OS fd is closed. The PRFileDesc -** is still open but is unusable. The only operation allowed -** on the PRFileDesc is PR_Close(). -** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc -** structure is freed. -*/ - -#define _PR_FILEDESC_OPEN 0xaaaaaaaa /* 1010101... */ -#define _PR_FILEDESC_CLOSED 0x55555555 /* 0101010... */ -#define _PR_FILEDESC_FREED 0x11111111 - -/* -** A boolean type with an additional "unknown" state -*/ - -typedef enum { - _PR_TRI_TRUE = 1, - _PR_TRI_FALSE = 0, - _PR_TRI_UNKNOWN = -1 -} _PRTriStateBool; - -struct PRFilePrivate { - PRInt32 state; - PRBool nonblocking; - _PRTriStateBool inheritable; - PRFileDesc *next; - PRIntn lockCount; /* 0: not locked - * -1: a native lockfile call is in progress - * > 0: # times the file is locked */ -#ifdef _PR_HAVE_PEEK_BUFFER - char *peekBuffer; - PRInt32 peekBufSize; - PRInt32 peekBytes; -#endif -#if !defined(_PR_HAVE_O_APPEND) - PRBool appendMode; /* Some platforms don't have O_APPEND or its - * equivalent, so they have to seek to end of - * file on write if the file was opened in - * append mode. See Bugzilla 4090, 276330. */ -#endif - _MDFileDesc md; -#ifdef _PR_NEED_SECRET_AF - PRUint16 af; /* If the platform's implementation of accept() - * requires knowing the address family of the - * socket, we save the address family here. */ -#endif -}; - -#ifdef _WIN64 -#define PR_PRIdOSFD "lld" /* for printing PROsfd */ -#define PR_PRIxOSFD "llx" -#define PR_SCNdOSFD "lld" /* for scanning PROsfd */ -#define PR_SCNxOSFD "llx" -#else -#define PR_PRIdOSFD "ld" /* for printing PROsfd */ -#define PR_PRIxOSFD "lx" -#define PR_SCNdOSFD "ld" /* for scanning PROsfd */ -#define PR_SCNxOSFD "lx" -#endif - -struct PRDir { - PRDirEntry d; - _MDDir md; -}; - -#ifdef MOZ_UNICODE -struct PRDirUTF16 { - PRDirEntry d; - _MDDirUTF16 md; -}; -#endif /* MOZ_UNICODE */ - -extern void _PR_InitSegs(void); -extern void _PR_InitStacks(void); -extern void _PR_InitTPD(void); -extern void _PR_InitMem(void); -extern void _PR_InitEnv(void); -extern void _PR_InitCMon(void); -extern void _PR_InitIO(void); -extern void _PR_InitLog(void); -extern void _PR_InitNet(void); -extern void _PR_InitClock(void); -extern void _PR_InitLinker(void); -extern void _PR_InitAtomic(void); -extern void _PR_InitCPUs(void); -extern void _PR_InitDtoa(void); -extern void _PR_InitTime(void); -extern void _PR_InitMW(void); -extern void _PR_InitRWLocks(void); -extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me); -extern void _PR_CleanupThread(PRThread *thread); -extern void _PR_CleanupCallOnce(void); -extern void _PR_CleanupMW(void); -extern void _PR_CleanupTime(void); -extern void _PR_CleanupDtoa(void); -extern void _PR_ShutdownLinker(void); -extern void _PR_CleanupEnv(void); -extern void _PR_CleanupIO(void); -extern void _PR_CleanupCMon(void); -extern void _PR_CleanupNet(void); -extern void _PR_CleanupLayerCache(void); -extern void _PR_CleanupStacks(void); -#ifdef WINNT -extern void _PR_CleanupCPUs(void); -#endif -extern void _PR_CleanupThreads(void); -extern void _PR_CleanupTPD(void); -extern void _PR_Cleanup(void); -extern void _PR_LogCleanup(void); -extern void _PR_InitLayerCache(void); - -extern PRBool _pr_initialized; -extern void _PR_ImplicitInitialization(void); -extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred); - -/************************************************************************/ - -struct PRSegment { - void *vaddr; - PRUint32 size; - PRUintn flags; -#if defined(_PR_PTHREADS) -#else /* defined(_PR_PTHREADS) */ - _MDSegment md; -#endif /* defined(_PR_PTHREADS) */ -}; - -/* PRSegment.flags */ -#define _PR_SEG_VM 0x1 - -/************************************************************************/ - -extern PRInt32 _pr_pageSize; -extern PRInt32 _pr_pageShift; - -extern PRLogModuleInfo *_pr_clock_lm; -extern PRLogModuleInfo *_pr_cmon_lm; -extern PRLogModuleInfo *_pr_io_lm; -extern PRLogModuleInfo *_pr_cvar_lm; -extern PRLogModuleInfo *_pr_mon_lm; -extern PRLogModuleInfo *_pr_linker_lm; -extern PRLogModuleInfo *_pr_sched_lm; -extern PRLogModuleInfo *_pr_thread_lm; -extern PRLogModuleInfo *_pr_gc_lm; - -extern PRFileDesc *_pr_stdin; -extern PRFileDesc *_pr_stdout; -extern PRFileDesc *_pr_stderr; - -/* Zone allocator */ -/* -** The zone allocator code has hardcoded pthread types and -** functions, so it can only be used in the pthreads version. -** This can be fixed by replacing the hardcoded pthread types -** and functions with macros that expand to the native thread -** types and functions on each platform. -*/ -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) -#define _PR_ZONE_ALLOCATOR -#endif - -#ifdef _PR_ZONE_ALLOCATOR -extern void _PR_InitZones(void); -extern void _PR_DestroyZones(void); -#endif - -/* Overriding malloc, free, etc. */ -#if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \ - && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \ - && !defined(PURIFY) \ - && !defined(DARWIN) \ - && !defined(QNX) \ - && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS)) -#define _PR_OVERRIDE_MALLOC -#endif - -/************************************************************************* -* External machine-dependent code provided by each OS. * * -*************************************************************************/ - -/* Initialization related */ -extern void _PR_MD_EARLY_INIT(void); -#define _PR_MD_EARLY_INIT _MD_EARLY_INIT - -extern void _PR_MD_INTERVAL_INIT(void); -#define _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT - -NSPR_API(void) _PR_MD_FINAL_INIT(void); -#define _PR_MD_FINAL_INIT _MD_FINAL_INIT - -extern void _PR_MD_EARLY_CLEANUP(void); -#define _PR_MD_EARLY_CLEANUP _MD_EARLY_CLEANUP - -/* Process control */ - -extern PRProcess * _PR_MD_CREATE_PROCESS( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr); -#define _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS - -extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process); -#define _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS - -extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode); -#define _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS - -extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process); -#define _PR_MD_KILL_PROCESS _MD_KILL_PROCESS - -/* Current Time */ -NSPR_API(PRTime) _PR_MD_NOW(void); -#define _PR_MD_NOW _MD_NOW - -/* Environment related */ -extern char* _PR_MD_GET_ENV(const char *name); -#define _PR_MD_GET_ENV _MD_GET_ENV - -extern PRIntn _PR_MD_PUT_ENV(const char *name); -#define _PR_MD_PUT_ENV _MD_PUT_ENV - -/* Atomic operations */ - -extern void _PR_MD_INIT_ATOMIC(void); -#define _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC - -extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *); -#define _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT - -extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32); -#define _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD - -extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *); -#define _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT - -extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32); -#define _PR_MD_ATOMIC_SET _MD_ATOMIC_SET - -/* Garbage collection */ - -/* -** Save the registers that the GC would find interesting into the thread -** "t". isCurrent will be non-zero if the thread state that is being -** saved is the currently executing thread. Return the address of the -** first register to be scanned as well as the number of registers to -** scan in "np". -** -** If "isCurrent" is non-zero then it is allowed for the thread context -** area to be used as scratch storage to hold just the registers -** necessary for scanning. -*/ -extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np); - -/* Time intervals */ - -extern PRIntervalTime _PR_MD_GET_INTERVAL(void); -#define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL - -extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void); -#define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC - -/* Affinity masks */ - -extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ); -#define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK - -extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask); -#define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK - -/* File locking */ - -extern PRStatus _PR_MD_LOCKFILE(PROsfd osfd); -#define _PR_MD_LOCKFILE _MD_LOCKFILE - -extern PRStatus _PR_MD_TLOCKFILE(PROsfd osfd); -#define _PR_MD_TLOCKFILE _MD_TLOCKFILE - -extern PRStatus _PR_MD_UNLOCKFILE(PROsfd osfd); -#define _PR_MD_UNLOCKFILE _MD_UNLOCKFILE - -/* Memory-mapped files */ - -extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size); -#define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP - -extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void); -#define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT - -extern void * _PR_MD_MEM_MAP( - PRFileMap *fmap, - PROffset64 offset, - PRUint32 len); -#define _PR_MD_MEM_MAP _MD_MEM_MAP - -extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size); -#define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP - -extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap); -#define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP - -/* Named Shared Memory */ - -/* -** Declare PRSharedMemory. -*/ -struct PRSharedMemory -{ - char *ipcname; /* after conversion to native */ - PRSize size; /* from open */ - PRIntn mode; /* from open */ - PRIntn flags; /* from open */ -#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY) - int id; -#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY) - int id; -#elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY) - HANDLE handle; -#else - PRUint32 nothing; /* placeholder, nothing behind here */ -#endif - PRUint32 ident; /* guard word at end of struct */ -#define _PR_SHM_IDENT 0xdeadbad -}; - -extern PRSharedMemory * _MD_OpenSharedMemory( - const char *name, - PRSize size, - PRIntn flags, - PRIntn mode -); -#define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory - -extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ); -#define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory - -extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ); -#define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory - -extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ); -#define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory - -extern PRStatus _MD_DeleteSharedMemory( const char *name ); -#define _PR_MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory - -extern PRFileMap* _md_OpenAnonFileMap( - const char *dirName, - PRSize size, - PRFileMapProtect prot -); -#define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap - -extern PRStatus _md_ExportFileMapAsString( - PRFileMap *fm, - PRSize bufSize, - char *buf -); -#define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString - -extern PRFileMap * _md_ImportFileMapFromString( - const char *fmstring -); -#define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString - - - -/* Interprocess communications (IPC) */ - -/* - * The maximum length of an NSPR IPC name, including the - * terminating null byte. - */ -#define PR_IPC_NAME_SIZE 1024 - -/* - * Types of NSPR IPC objects - */ -typedef enum { - _PRIPCSem, /* semaphores */ - _PRIPCShm /* shared memory segments */ -} _PRIPCType; - -/* - * Make a native IPC name from an NSPR IPC name. - */ -extern PRStatus _PR_MakeNativeIPCName( - const char *name, /* NSPR IPC name */ - char *result, /* result buffer */ - PRIntn size, /* size of result buffer */ - _PRIPCType type /* type of IPC object */ -); - -/* Socket call error code */ - -NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void); -#define _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR - -/* Get name of current host */ -extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen); -#define _PR_MD_GETHOSTNAME _MD_GETHOSTNAME - -extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen); -#define _PR_MD_GETSYSINFO _MD_GETSYSINFO - -/* File descriptor inheritance */ - -/* - * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to - * know the inheritable attribute of the fd, call this function - * to find that out. This typically requires a system call. - */ -extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd); -#define _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE - -/* --- PR_GetRandomNoise() related things --- */ - -extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ); -#define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size)) -extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srclen ); - -/* end PR_GetRandomNoise() related */ - -#ifdef XP_BEOS - -extern PRLock *_connectLock; - -typedef struct _ConnectListNode { - PRInt32 osfd; - PRNetAddr addr; - PRUint32 addrlen; - PRIntervalTime timeout; -} ConnectListNode; - -extern ConnectListNode connectList[64]; - -extern PRUint32 connectCount; - -#endif /* XP_BEOS */ - -PR_END_EXTERN_C - -#endif /* primpl_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/private/prpriv.h nspr-4.10.7/mozilla/nsprpub/pr/include/private/prpriv.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/private/prpriv.h 2012-03-06 13:13:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/private/prpriv.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prpriv_h___ -#define prpriv_h___ - -/* - * NSPR 2.0 Private API - */ - -#include "private/pprio.h" -#include "private/pprthred.h" - -#endif /* prpriv_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prlink.h nspr-4.10.7/mozilla/nsprpub/pr/include/prlink.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prlink.h 2012-03-06 13:13:46.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prlink.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prlink_h___ -#define prlink_h___ - -/* -** API to static and dynamic linking. -*/ -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -typedef struct PRLibrary PRLibrary; - -typedef struct PRStaticLinkTable { - const char *name; - void (*fp)(void); -} PRStaticLinkTable; - -/* -** Change the default library path to the given string. The string is -** copied. This call will fail if it runs out of memory. -** -** The string provided as 'path' is copied. The caller can do whatever is -** convenient with the argument when the function is complete. -*/ -NSPR_API(PRStatus) PR_SetLibraryPath(const char *path); - -/* -** Return a character string which contains the path used to search for -** dynamically loadable libraries. -** -** The returned value is basically a copy of a PR_SetLibraryPath(). -** The storage is allocated by the runtime and becomes the responsibilty -** of the caller. -*/ -NSPR_API(char*) PR_GetLibraryPath(void); - -/* -** Given a directory name "dir" and a library name "lib" construct a full -** path name that will refer to the actual dynamically loaded -** library. This does not test for existance of said file, it just -** constructs the full filename. The name constructed is system dependent -** and prepared for PR_LoadLibrary. The result must be free'd when the -** caller is done with it. -** -** The storage for the result is allocated by the runtime and becomes the -** responsibility of the caller. -*/ -NSPR_API(char*) PR_GetLibraryName(const char *dir, const char *lib); - -/* -** -** Free the memory allocated, for the caller, by PR_GetLibraryName -*/ -NSPR_API(void) PR_FreeLibraryName(char *mem); - -/* -** Given a library "name" try to load the library. The argument "name" -** is a machine-dependent name for the library, such as the full pathname -** returned by PR_GetLibraryName. If the library is already loaded, -** this function will avoid loading the library twice. -** -** If the library is loaded successfully, then a pointer to the PRLibrary -** structure representing the library is returned. Otherwise, NULL is -** returned. -** -** This increments the reference count of the library. -*/ -NSPR_API(PRLibrary*) PR_LoadLibrary(const char *name); - -/* -** Each operating system has its preferred way of specifying -** a file in the file system. Most operating systems use -** a pathname. Mac OS Classic, on the other hand, uses the FSSpec -** structure to specify a file. PRLibSpec allows NSPR clients -** to use the type of file specification that is most efficient -** for a particular platform. -** -** On some operating systems such as Mac OS Classic, a shared library -** may contain code fragments that can be individually loaded. -** PRLibSpec also allows NSPR clients to identify a code fragment -** in a library, if code fragments are supported by the OS. -** A code fragment can be specified by name or by an integer index. -** -** Right now PRLibSpec supports four types of library specification: -** a pathname in the native character encoding, a Mac code fragment -** by name, a Mac code fragment by index, and a UTF-16 pathname. -*/ - -typedef enum PRLibSpecType { - PR_LibSpec_Pathname, - PR_LibSpec_MacNamedFragment, /* obsolete (for Mac OS Classic) */ - PR_LibSpec_MacIndexedFragment, /* obsolete (for Mac OS Classic) */ - PR_LibSpec_PathnameU /* supported only on Win32 */ -} PRLibSpecType; - -struct FSSpec; /* Mac OS Classic FSSpec */ - -typedef struct PRLibSpec { - PRLibSpecType type; - union { - /* if type is PR_LibSpec_Pathname */ - const char *pathname; - - /* if type is PR_LibSpec_MacNamedFragment */ - struct { - const struct FSSpec *fsspec; - const char *name; - } mac_named_fragment; /* obsolete (for Mac OS Classic) */ - - /* if type is PR_LibSpec_MacIndexedFragment */ - struct { - const struct FSSpec *fsspec; - PRUint32 index; - } mac_indexed_fragment; /* obsolete (for Mac OS Classic) */ - - /* if type is PR_LibSpec_PathnameU */ - const PRUnichar *pathname_u; /* supported only on Win32 */ - } value; -} PRLibSpec; - -/* -** The following bit flags may be or'd together and passed -** as the 'flags' argument to PR_LoadLibraryWithFlags. -** Flags not supported by the underlying OS are ignored. -*/ - -#define PR_LD_LAZY 0x1 /* equivalent to RTLD_LAZY on Unix */ -#define PR_LD_NOW 0x2 /* equivalent to RTLD_NOW on Unix */ -#define PR_LD_GLOBAL 0x4 /* equivalent to RTLD_GLOBAL on Unix */ -#define PR_LD_LOCAL 0x8 /* equivalent to RTLD_LOCAL on Unix */ -/* The following is equivalent to LOAD_WITH_ALTERED_SEARCH_PATH on Windows */ -#define PR_LD_ALT_SEARCH_PATH 0x10 -/* 0x8000 reserved for NSPR internal use */ - -/* -** Load the specified library, in the manner specified by 'flags'. -*/ - -NSPR_API(PRLibrary *) -PR_LoadLibraryWithFlags( - PRLibSpec libSpec, /* the shared library */ - PRIntn flags /* flags that affect the loading */ -); - -/* -** Unload a previously loaded library. If the library was a static -** library then the static link table will no longer be referenced. The -** associated PRLibrary object is freed. -** -** PR_FAILURE is returned if the library cannot be unloaded. -** -** This function decrements the reference count of the library. -*/ -NSPR_API(PRStatus) PR_UnloadLibrary(PRLibrary *lib); - -/* -** Given the name of a procedure, return the address of the function that -** implements the procedure, or NULL if no such function can be -** found. This does not find symbols in the main program (the ".exe"); -** use PR_LoadStaticLibrary to register symbols in the main program. -** -** This function does not modify the reference count of the library. -*/ -NSPR_API(void*) PR_FindSymbol(PRLibrary *lib, const char *name); - -/* -** Similar to PR_FindSymbol, except that the return value is a pointer to -** a function, and not a pointer to void. Casting between a data pointer -** and a function pointer is not portable according to the C standard. -** Any function pointer can be cast to any other function pointer. -** -** This function does not modify the reference count of the library. -*/ -typedef void (*PRFuncPtr)(void); -NSPR_API(PRFuncPtr) PR_FindFunctionSymbol(PRLibrary *lib, const char *name); - -/* -** Finds a symbol in one of the currently loaded libraries. Given the -** name of a procedure, return the address of the function that -** implements the procedure, and return the library that contains that -** symbol, or NULL if no such function can be found. This does not find -** symbols in the main program (the ".exe"); use PR_AddStaticLibrary to -** register symbols in the main program. -** -** This increments the reference count of the library. -*/ -NSPR_API(void*) PR_FindSymbolAndLibrary(const char *name, - PRLibrary* *lib); - -/* -** Similar to PR_FindSymbolAndLibrary, except that the return value is -** a pointer to a function, and not a pointer to void. Casting between a -** data pointer and a function pointer is not portable according to the C -** standard. Any function pointer can be cast to any other function pointer. -** -** This increments the reference count of the library. -*/ -NSPR_API(PRFuncPtr) PR_FindFunctionSymbolAndLibrary(const char *name, - PRLibrary* *lib); - -/* -** Register a static link table with the runtime under the name -** "name". The symbols present in the static link table will be made -** available to PR_FindSymbol. If "name" is null then the symbols will be -** made available to the library which represents the executable. The -** tables are not copied. -** -** Returns the library object if successful, null otherwise. -** -** This increments the reference count of the library. -*/ -NSPR_API(PRLibrary*) PR_LoadStaticLibrary( - const char *name, const PRStaticLinkTable *table); - -/* -** Return the pathname of the file that the library "name" was loaded -** from. "addr" is the address of a function defined in the library. -** -** The caller is responsible for freeing the result with PR_Free. -*/ -NSPR_API(char *) PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr); - -PR_END_EXTERN_C - -#endif /* prlink_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prlock.h nspr-4.10.7/mozilla/nsprpub/pr/include/prlock.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prlock.h 2012-03-06 13:13:46.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prlock.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prlock.h -** Description: API to basic locking functions of NSPR. -** -** -** NSPR provides basic locking mechanisms for thread synchronization. Locks -** are lightweight resource contention controls that prevent multiple threads -** from accessing something (code/data) simultaneously. -**/ - -#ifndef prlock_h___ -#define prlock_h___ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/**********************************************************************/ -/************************* TYPES AND CONSTANTS ************************/ -/**********************************************************************/ - -/* - * PRLock -- - * - * NSPR represents the lock as an opaque entity to the client of the - * API. All routines operate on a pointer to this opaque entity. - */ - -typedef struct PRLock PRLock; - -/**********************************************************************/ -/****************************** FUNCTIONS *****************************/ -/**********************************************************************/ - -/*********************************************************************** -** FUNCTION: PR_NewLock -** DESCRIPTION: -** Returns a pointer to a newly created opaque lock object. -** INPUTS: void -** OUTPUTS: void -** RETURN: PRLock* -** If the lock can not be created because of resource constraints, NULL -** is returned. -** -***********************************************************************/ -NSPR_API(PRLock*) PR_NewLock(void); - -/*********************************************************************** -** FUNCTION: PR_DestroyLock -** DESCRIPTION: -** Destroys a given opaque lock object. -** INPUTS: PRLock *lock -** Lock to be freed. -** OUTPUTS: void -** RETURN: None -***********************************************************************/ -NSPR_API(void) PR_DestroyLock(PRLock *lock); - -/*********************************************************************** -** FUNCTION: PR_Lock -** DESCRIPTION: -** Lock a lock. -** INPUTS: PRLock *lock -** Lock to locked. -** OUTPUTS: void -** RETURN: None -***********************************************************************/ -NSPR_API(void) PR_Lock(PRLock *lock); - -/*********************************************************************** -** FUNCTION: PR_Unlock -** DESCRIPTION: -** Unlock a lock. Unlocking an unlocked lock has undefined results. -** INPUTS: PRLock *lock -** Lock to unlocked. -** OUTPUTS: void -** RETURN: PR_STATUS -** Returns PR_FAILURE if the caller does not own the lock. -***********************************************************************/ -NSPR_API(PRStatus) PR_Unlock(PRLock *lock); - -/*********************************************************************** -** MACRO: PR_ASSERT_CURRENT_THREAD_OWNS_LOCK -** DESCRIPTION: -** If the current thread owns |lock|, this assertion is guaranteed to -** succeed. Otherwise, the behavior of this function is undefined. -** INPUTS: PRLock *lock -** Lock to assert ownership of. -** OUTPUTS: void -** RETURN: None -***********************************************************************/ -#if defined(DEBUG) || defined(FORCE_PR_ASSERT) -#define PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(/* PrLock* */ lock) \ - PR_AssertCurrentThreadOwnsLock(lock) -#else -#define PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(/* PrLock* */ lock) -#endif - -/* Don't call this function directly. */ -NSPR_API(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock); - -PR_END_EXTERN_C - -#endif /* prlock_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prlog.h nspr-4.10.7/mozilla/nsprpub/pr/include/prlog.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prlog.h 2012-03-06 13:13:46.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prlog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prlog_h___ -#define prlog_h___ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* -** prlog.h -- Declare interfaces to NSPR's Logging service -** -** NSPR provides a logging service that is used by NSPR itself and is -** available to client programs. -** -** To use the service from a client program, you should create a -** PRLogModuleInfo structure by calling PR_NewLogModule(). After -** creating the LogModule, you can write to the log using the PR_LOG() -** macro. -** -** Initialization of the log service is handled by NSPR initialization. -** -** At execution time, you must enable the log service. To enable the -** log service, set the environment variable: NSPR_LOG_MODULES -** variable. -** -** NSPR_LOG_MODULES variable has the form: -** -** :[, :]* -** -** Where: -** is the name passed to PR_NewLogModule(). -** is a numeric constant, e.g. 5. This value is the maximum -** value of a log event, enumerated by PRLogModuleLevel, that you want -** written to the log. -** -** For example: to record all events of greater value than or equal to -** PR_LOG_ERROR for a LogModule names "gizmo", say: -** -** set NSPR_LOG_MODULES=gizmo:2 -** -** Note that you must specify the numeric value of PR_LOG_ERROR. -** -** Special LogModule names are provided for controlling NSPR's log -** service at execution time. These controls should be set in the -** NSPR_LOG_MODULES environment variable at execution time to affect -** NSPR's log service for your application. -** -** The special LogModule "all" enables all LogModules. To enable all -** LogModule calls to PR_LOG(), say: -** -** set NSPR_LOG_MODULES=all:5 -** -** The special LogModule name "sync" tells the NSPR log service to do -** unbuffered logging. -** -** The special LogModule name "bufsize:" tells NSPR to set the -** log buffer to . -** -** The environment variable NSPR_LOG_FILE specifies the log file to use -** unless the default of "stderr" is acceptable. For MS Windows -** systems, NSPR_LOG_FILE can be set to a special value: "WinDebug" -** (case sensitive). This value causes PR_LOG() output to be written -** using the Windows API OutputDebugString(). OutputDebugString() -** writes to the debugger window; some people find this helpful. -** -** -** To put log messages in your programs, use the PR_LOG macro: -** -** PR_LOG(, , (, *)); -** -** Where is the address of a PRLogModuleInfo structure, and -** is one of the levels defined by the enumeration: -** PRLogModuleLevel. is a printf() style of argument list. That -** is: (fmtstring, ...). -** -** Example: -** -** main() { -** PRIntn one = 1; -** PRLogModuleInfo * myLm = PR_NewLogModule("gizmo"); -** PR_LOG( myLm, PR_LOG_ALWAYS, ("Log this! %d\n", one)); -** return; -** } -** -** Note the use of printf() style arguments as the third agrument(s) to -** PR_LOG(). -** -** After compiling and linking you application, set the environment: -** -** set NSPR_LOG_MODULES=gizmo:5 -** set NSPR_LOG_FILE=logfile.txt -** -** When you execute your application, the string "Log this! 1" will be -** written to the file "logfile.txt". -** -** Note to NSPR engineers: a number of PRLogModuleInfo structures are -** defined and initialized in prinit.c. See this module for ideas on -** what to log where. -** -*/ - -typedef enum PRLogModuleLevel { - PR_LOG_NONE = 0, /* nothing */ - PR_LOG_ALWAYS = 1, /* always printed */ - PR_LOG_ERROR = 2, /* error messages */ - PR_LOG_WARNING = 3, /* warning messages */ - PR_LOG_DEBUG = 4, /* debug messages */ - - PR_LOG_NOTICE = PR_LOG_DEBUG, /* notice messages */ - PR_LOG_WARN = PR_LOG_WARNING, /* warning messages */ - PR_LOG_MIN = PR_LOG_DEBUG, /* minimal debugging messages */ - PR_LOG_MAX = PR_LOG_DEBUG /* maximal debugging messages */ -} PRLogModuleLevel; - -/* -** One of these structures is created for each module that uses logging. -** "name" is the name of the module -** "level" is the debugging level selected for that module -*/ -typedef struct PRLogModuleInfo { - const char *name; - PRLogModuleLevel level; - struct PRLogModuleInfo *next; -} PRLogModuleInfo; - -/* -** Create a new log module. -*/ -NSPR_API(PRLogModuleInfo*) PR_NewLogModule(const char *name); - -/* -** Set the file to use for logging. Returns PR_FALSE if the file cannot -** be created -*/ -NSPR_API(PRBool) PR_SetLogFile(const char *name); - -/* -** Set the size of the logging buffer. If "buffer_size" is zero then the -** logging becomes "synchronous" (or unbuffered). -*/ -NSPR_API(void) PR_SetLogBuffering(PRIntn buffer_size); - -/* -** Print a string to the log. "fmt" is a PR_snprintf format type. All -** messages printed to the log are preceeded by the name of the thread -** and a time stamp. Also, the routine provides a missing newline if one -** is not provided. -*/ -NSPR_API(void) PR_LogPrint(const char *fmt, ...); - -/* -** Flush the log to its file. -*/ -NSPR_API(void) PR_LogFlush(void); - -NSPR_API(void) PR_Assert(const char *s, const char *file, PRIntn ln); - -#if defined(DEBUG) || defined(FORCE_PR_LOG) -#define PR_LOGGING 1 - -#define PR_LOG_TEST(_module,_level) \ - ((_module)->level >= (_level)) - -/* -** Log something. -** "module" is the address of a PRLogModuleInfo structure -** "level" is the desired logging level -** "args" is a variable length list of arguments to print, in the following -** format: ("printf style format string", ...) -*/ -#define PR_LOG(_module,_level,_args) \ - PR_BEGIN_MACRO \ - if (PR_LOG_TEST(_module,_level)) { \ - PR_LogPrint _args; \ - } \ - PR_END_MACRO - -#else /* defined(DEBUG) || defined(FORCE_PR_LOG) */ - -#undef PR_LOGGING -#define PR_LOG_TEST(module,level) 0 -#define PR_LOG(module,level,args) - -#endif /* defined(DEBUG) || defined(FORCE_PR_LOG) */ - -#ifndef NO_NSPR_10_SUPPORT - -#ifdef PR_LOGGING -#define PR_LOG_BEGIN PR_LOG -#define PR_LOG_END PR_LOG -#define PR_LOG_DEFINE PR_NewLogModule -#else -#define PR_LOG_BEGIN(module,level,args) -#define PR_LOG_END(module,level,args) -#define PR_LOG_DEFINE(_name) NULL -#endif /* PR_LOGGING */ - -#endif /* NO_NSPR_10_SUPPORT */ - -#if defined(DEBUG) || defined(FORCE_PR_ASSERT) - -#define PR_ASSERT(_expr) \ - ((_expr)?((void)0):PR_Assert(# _expr,__FILE__,__LINE__)) - -#define PR_NOT_REACHED(_reasonStr) \ - PR_Assert(_reasonStr,__FILE__,__LINE__) - -#else - -#define PR_ASSERT(expr) ((void) 0) -#define PR_NOT_REACHED(reasonStr) - -#endif /* defined(DEBUG) || defined(FORCE_PR_ASSERT) */ - -PR_END_EXTERN_C - -#endif /* prlog_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prlong.h nspr-4.10.7/mozilla/nsprpub/pr/include/prlong.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prlong.h 2012-12-07 21:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prlong.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,403 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prlong.h -** Description: Portable access to 64 bit numerics -** -** Long-long (64-bit signed integer type) support. Some C compilers -** don't support 64 bit integers yet, so we use these macros to -** support both machines that do and don't. -**/ -#ifndef prlong_h___ -#define prlong_h___ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/*********************************************************************** -** DEFINES: LL_MaxInt -** LL_MinInt -** LL_Zero -** LL_MaxUint -** DESCRIPTION: -** Various interesting constants and static variable -** initializer -***********************************************************************/ -NSPR_API(PRInt64) LL_MaxInt(void); -NSPR_API(PRInt64) LL_MinInt(void); -NSPR_API(PRInt64) LL_Zero(void); -NSPR_API(PRUint64) LL_MaxUint(void); - -#if defined(HAVE_LONG_LONG) - -/* Keep this in sync with prtypes.h. */ -#if PR_BYTES_PER_LONG == 8 && !defined(PR_ALTERNATE_INT64_TYPEDEF) -#define LL_MAXINT 9223372036854775807L -#define LL_MININT (-LL_MAXINT - 1L) -#define LL_ZERO 0L -#define LL_MAXUINT 18446744073709551615UL -#define LL_INIT(hi, lo) ((hi ## L << 32) + lo ## L) -#elif defined(WIN32) && !defined(__GNUC__) -#define LL_MAXINT 9223372036854775807i64 -#define LL_MININT (-LL_MAXINT - 1i64) -#define LL_ZERO 0i64 -#define LL_MAXUINT 18446744073709551615ui64 -#define LL_INIT(hi, lo) ((hi ## i64 << 32) + lo ## i64) -#else -#define LL_MAXINT 9223372036854775807LL -#define LL_MININT (-LL_MAXINT - 1LL) -#define LL_ZERO 0LL -#define LL_MAXUINT 18446744073709551615ULL -#define LL_INIT(hi, lo) ((hi ## LL << 32) + lo ## LL) -#endif - -/*********************************************************************** -** MACROS: LL_* -** DESCRIPTION: -** The following macros define portable access to the 64 bit -** math facilities. -** -***********************************************************************/ - -/*********************************************************************** -** MACROS: LL_ -** -** LL_IS_ZERO Test for zero -** LL_EQ Test for equality -** LL_NE Test for inequality -** LL_GE_ZERO Test for zero or positive -** LL_CMP Compare two values -***********************************************************************/ -#define LL_IS_ZERO(a) ((a) == 0) -#define LL_EQ(a, b) ((a) == (b)) -#define LL_NE(a, b) ((a) != (b)) -#define LL_GE_ZERO(a) ((a) >= 0) -#define LL_CMP(a, op, b) ((PRInt64)(a) op (PRInt64)(b)) -#define LL_UCMP(a, op, b) ((PRUint64)(a) op (PRUint64)(b)) - -/*********************************************************************** -** MACROS: LL_ -** -** LL_AND Logical and -** LL_OR Logical or -** LL_XOR Logical exclusion -** LL_OR2 A disgusting deviation -** LL_NOT Negation (one's complement) -***********************************************************************/ -#define LL_AND(r, a, b) ((r) = (a) & (b)) -#define LL_OR(r, a, b) ((r) = (a) | (b)) -#define LL_XOR(r, a, b) ((r) = (a) ^ (b)) -#define LL_OR2(r, a) ((r) = (r) | (a)) -#define LL_NOT(r, a) ((r) = ~(a)) - -/*********************************************************************** -** MACROS: LL_ -** -** LL_NEG Negation (two's complement) -** LL_ADD Summation (two's complement) -** LL_SUB Difference (two's complement) -***********************************************************************/ -#define LL_NEG(r, a) ((r) = -(a)) -#define LL_ADD(r, a, b) ((r) = (a) + (b)) -#define LL_SUB(r, a, b) ((r) = (a) - (b)) - -/*********************************************************************** -** MACROS: LL_ -** -** LL_MUL Product (two's complement) -** LL_DIV Quotient (two's complement) -** LL_MOD Modulus (two's complement) -***********************************************************************/ -#define LL_MUL(r, a, b) ((r) = (a) * (b)) -#define LL_DIV(r, a, b) ((r) = (a) / (b)) -#define LL_MOD(r, a, b) ((r) = (a) % (b)) - -/*********************************************************************** -** MACROS: LL_ -** -** LL_SHL Shift left [0..64] bits -** LL_SHR Shift right [0..64] bits with sign extension -** LL_USHR Unsigned shift right [0..64] bits -** LL_ISHL Signed shift left [0..64] bits -***********************************************************************/ -#define LL_SHL(r, a, b) ((r) = (PRInt64)(a) << (b)) -#define LL_SHR(r, a, b) ((r) = (PRInt64)(a) >> (b)) -#define LL_USHR(r, a, b) ((r) = (PRUint64)(a) >> (b)) -#define LL_ISHL(r, a, b) ((r) = (PRInt64)(a) << (b)) - -/*********************************************************************** -** MACROS: LL_ -** -** LL_L2I Convert to signed 32 bit -** LL_L2UI Convert to unsigned 32 bit -** LL_L2F Convert to floating point -** LL_L2D Convert to floating point -** LL_I2L Convert signed to 64 bit -** LL_UI2L Convert unsigned to 64 bit -** LL_F2L Convert float to 64 bit -** LL_D2L Convert float to 64 bit -***********************************************************************/ -#define LL_L2I(i, l) ((i) = (PRInt32)(l)) -#define LL_L2UI(ui, l) ((ui) = (PRUint32)(l)) -#define LL_L2F(f, l) ((f) = (PRFloat64)(l)) -#define LL_L2D(d, l) ((d) = (PRFloat64)(l)) - -#define LL_I2L(l, i) ((l) = (PRInt64)(i)) -#define LL_UI2L(l, ui) ((l) = (PRInt64)(ui)) -#define LL_F2L(l, f) ((l) = (PRInt64)(f)) -#define LL_D2L(l, d) ((l) = (PRInt64)(d)) - -/*********************************************************************** -** MACROS: LL_UDIVMOD -** DESCRIPTION: -** Produce both a quotient and a remainder given an unsigned -** INPUTS: PRUint64 a: The dividend of the operation -** PRUint64 b: The quotient of the operation -** OUTPUTS: PRUint64 *qp: pointer to quotient -** PRUint64 *rp: pointer to remainder -***********************************************************************/ -#define LL_UDIVMOD(qp, rp, a, b) \ - (*(qp) = ((PRUint64)(a) / (b)), \ - *(rp) = ((PRUint64)(a) % (b))) - -#else /* !HAVE_LONG_LONG */ - -#define LL_MAXINT LL_MaxInt() -#define LL_MININT LL_MinInt() -#define LL_ZERO LL_Zero() -#define LL_MAXUINT LL_MaxUint() - -#ifdef IS_LITTLE_ENDIAN -#define LL_INIT(hi, lo) {PR_UINT32(lo), PR_UINT32(hi)} -#else -#define LL_INIT(hi, lo) {PR_UINT32(hi), PR_UINT32(lo)} -#endif - -#define LL_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0)) -#define LL_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo)) -#define LL_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo)) -#define LL_GE_ZERO(a) (((a).hi >> 31) == 0) - -#define LL_CMP(a, op, b) (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \ - ((PRInt32)(a).hi op (PRInt32)(b).hi)) -#define LL_UCMP(a, op, b) (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \ - ((a).hi op (b).hi)) - -#define LL_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \ - (r).hi = (a).hi & (b).hi) -#define LL_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \ - (r).hi = (a).hi | (b).hi) -#define LL_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \ - (r).hi = (a).hi ^ (b).hi) -#define LL_OR2(r, a) ((r).lo = (r).lo | (a).lo, \ - (r).hi = (r).hi | (a).hi) -#define LL_NOT(r, a) ((r).lo = ~(a).lo, \ - (r).hi = ~(a).hi) - -#define LL_NEG(r, a) ((r).lo = -(PRInt32)(a).lo, \ - (r).hi = -(PRInt32)(a).hi - ((r).lo != 0)) -#define LL_ADD(r, a, b) { \ - PRInt64 _a, _b; \ - _a = a; _b = b; \ - (r).lo = _a.lo + _b.lo; \ - (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \ -} - -#define LL_SUB(r, a, b) { \ - PRInt64 _a, _b; \ - _a = a; _b = b; \ - (r).lo = _a.lo - _b.lo; \ - (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \ -} - -#define LL_MUL(r, a, b) { \ - PRInt64 _a, _b; \ - _a = a; _b = b; \ - LL_MUL32(r, _a.lo, _b.lo); \ - (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \ -} - -#define _lo16(a) ((a) & PR_BITMASK(16)) -#define _hi16(a) ((a) >> 16) - -#define LL_MUL32(r, a, b) { \ - PRUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \ - _a1 = _hi16(a), _a0 = _lo16(a); \ - _b1 = _hi16(b), _b0 = _lo16(b); \ - _y0 = _a0 * _b0; \ - _y1 = _a0 * _b1; \ - _y2 = _a1 * _b0; \ - _y3 = _a1 * _b1; \ - _y1 += _hi16(_y0); /* can't carry */ \ - _y1 += _y2; /* might carry */ \ - if (_y1 < _y2) \ - _y3 += (PRUint32)(PR_BIT(16)); /* propagate */ \ - (r).lo = (_lo16(_y1) << 16) + _lo16(_y0); \ - (r).hi = _y3 + _hi16(_y1); \ -} - -#define LL_UDIVMOD(qp, rp, a, b) ll_udivmod(qp, rp, a, b) - -NSPR_API(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b); - -#define LL_DIV(r, a, b) { \ - PRInt64 _a, _b; \ - PRUint32 _negative = (PRInt32)(a).hi < 0; \ - if (_negative) { \ - LL_NEG(_a, a); \ - } else { \ - _a = a; \ - } \ - if ((PRInt32)(b).hi < 0) { \ - _negative ^= 1; \ - LL_NEG(_b, b); \ - } else { \ - _b = b; \ - } \ - LL_UDIVMOD(&(r), 0, _a, _b); \ - if (_negative) \ - LL_NEG(r, r); \ -} - -#define LL_MOD(r, a, b) { \ - PRInt64 _a, _b; \ - PRUint32 _negative = (PRInt32)(a).hi < 0; \ - if (_negative) { \ - LL_NEG(_a, a); \ - } else { \ - _a = a; \ - } \ - if ((PRInt32)(b).hi < 0) { \ - LL_NEG(_b, b); \ - } else { \ - _b = b; \ - } \ - LL_UDIVMOD(0, &(r), _a, _b); \ - if (_negative) \ - LL_NEG(r, r); \ -} - -#define LL_SHL(r, a, b) { \ - if (b) { \ - PRInt64 _a; \ - _a = a; \ - if ((b) < 32) { \ - (r).lo = _a.lo << ((b) & 31); \ - (r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \ - } else { \ - (r).lo = 0; \ - (r).hi = _a.lo << ((b) & 31); \ - } \ - } else { \ - (r) = (a); \ - } \ -} - -/* a is an PRInt32, b is PRInt32, r is PRInt64 */ -#define LL_ISHL(r, a, b) { \ - if (b) { \ - PRInt64 _a; \ - _a.lo = (a); \ - _a.hi = 0; \ - if ((b) < 32) { \ - (r).lo = (a) << ((b) & 31); \ - (r).hi = ((a) >> (32 - (b))); \ - } else { \ - (r).lo = 0; \ - (r).hi = (a) << ((b) & 31); \ - } \ - } else { \ - (r).lo = (a); \ - (r).hi = 0; \ - } \ -} - -#define LL_SHR(r, a, b) { \ - if (b) { \ - PRInt64 _a; \ - _a = a; \ - if ((b) < 32) { \ - (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \ - (r).hi = (PRInt32)_a.hi >> ((b) & 31); \ - } else { \ - (r).lo = (PRInt32)_a.hi >> ((b) & 31); \ - (r).hi = (PRInt32)_a.hi >> 31; \ - } \ - } else { \ - (r) = (a); \ - } \ -} - -#define LL_USHR(r, a, b) { \ - if (b) { \ - PRInt64 _a; \ - _a = a; \ - if ((b) < 32) { \ - (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \ - (r).hi = _a.hi >> ((b) & 31); \ - } else { \ - (r).lo = _a.hi >> ((b) & 31); \ - (r).hi = 0; \ - } \ - } else { \ - (r) = (a); \ - } \ -} - -#define LL_L2I(i, l) ((i) = (l).lo) -#define LL_L2UI(ui, l) ((ui) = (l).lo) -#define LL_L2F(f, l) { double _d; LL_L2D(_d, l); (f) = (PRFloat64)_d; } - -#define LL_L2D(d, l) { \ - int _negative; \ - PRInt64 _absval; \ - \ - _negative = (l).hi >> 31; \ - if (_negative) { \ - LL_NEG(_absval, l); \ - } else { \ - _absval = l; \ - } \ - (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \ - if (_negative) \ - (d) = -(d); \ -} - -#define LL_I2L(l, i) { PRInt32 _i = ((PRInt32)(i)) >> 31; (l).lo = (i); (l).hi = _i; } -#define LL_UI2L(l, ui) ((l).lo = (ui), (l).hi = 0) -#define LL_F2L(l, f) { double _d = (double)f; LL_D2L(l, _d); } - -#define LL_D2L(l, d) { \ - int _negative; \ - double _absval, _d_hi; \ - PRInt64 _lo_d; \ - \ - _negative = ((d) < 0); \ - _absval = _negative ? -(d) : (d); \ - \ - (l).hi = _absval / 4.294967296e9; \ - (l).lo = 0; \ - LL_L2D(_d_hi, l); \ - _absval -= _d_hi; \ - _lo_d.hi = 0; \ - if (_absval < 0) { \ - _lo_d.lo = -_absval; \ - LL_SUB(l, l, _lo_d); \ - } else { \ - _lo_d.lo = _absval; \ - LL_ADD(l, l, _lo_d); \ - } \ - \ - if (_negative) \ - LL_NEG(l, l); \ -} - -#endif /* !HAVE_LONG_LONG */ - -PR_END_EXTERN_C - -#endif /* prlong_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prmem.h nspr-4.10.7/mozilla/nsprpub/pr/include/prmem.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prmem.h 2012-03-06 13:13:47.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prmem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prmem.h -** Description: API to NSPR memory management functions -** -*/ -#ifndef prmem_h___ -#define prmem_h___ - -#include "prtypes.h" -#include - -PR_BEGIN_EXTERN_C - -/* -** Thread safe memory allocation. -** -** NOTE: pr wraps up malloc, free, calloc, realloc so they are already -** thread safe (and are not declared here - look in stdlib.h). -*/ - -/* -** PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free have the same signatures -** as their libc equivalent malloc, calloc, realloc, and free, and have -** the same semantics. (Note that the argument type size_t is replaced -** by PRUint32.) Memory allocated by PR_Malloc, PR_Calloc, or PR_Realloc -** must be freed by PR_Free. -*/ - -NSPR_API(void *) PR_Malloc(PRUint32 size); - -NSPR_API(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize); - -NSPR_API(void *) PR_Realloc(void *ptr, PRUint32 size); - -NSPR_API(void) PR_Free(void *ptr); - -/* -** The following are some convenience macros defined in terms of -** PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free. -*/ - -/*********************************************************************** -** FUNCTION: PR_MALLOC() -** DESCRIPTION: -** PR_NEW() allocates an untyped item of size _size from the heap. -** INPUTS: _size: size in bytes of item to be allocated -** OUTPUTS: untyped pointer to the node allocated -** RETURN: pointer to node or error returned from malloc(). -***********************************************************************/ -#define PR_MALLOC(_bytes) (PR_Malloc((_bytes))) - -/*********************************************************************** -** FUNCTION: PR_NEW() -** DESCRIPTION: -** PR_NEW() allocates an item of type _struct from the heap. -** INPUTS: _struct: a data type -** OUTPUTS: pointer to _struct -** RETURN: pointer to _struct or error returns from malloc(). -***********************************************************************/ -#define PR_NEW(_struct) ((_struct *) PR_MALLOC(sizeof(_struct))) - -/*********************************************************************** -** FUNCTION: PR_REALLOC() -** DESCRIPTION: -** PR_REALLOC() re-allocates _ptr bytes from the heap as a _size -** untyped item. -** INPUTS: _ptr: pointer to node to reallocate -** _size: size of node to allocate -** OUTPUTS: pointer to node allocated -** RETURN: pointer to node allocated -***********************************************************************/ -#define PR_REALLOC(_ptr, _size) (PR_Realloc((_ptr), (_size))) - -/*********************************************************************** -** FUNCTION: PR_CALLOC() -** DESCRIPTION: -** PR_CALLOC() allocates a _size bytes untyped item from the heap -** and sets the allocated memory to all 0x00. -** INPUTS: _size: size of node to allocate -** OUTPUTS: pointer to node allocated -** RETURN: pointer to node allocated -***********************************************************************/ -#define PR_CALLOC(_size) (PR_Calloc(1, (_size))) - -/*********************************************************************** -** FUNCTION: PR_NEWZAP() -** DESCRIPTION: -** PR_NEWZAP() allocates an item of type _struct from the heap -** and sets the allocated memory to all 0x00. -** INPUTS: _struct: a data type -** OUTPUTS: pointer to _struct -** RETURN: pointer to _struct -***********************************************************************/ -#define PR_NEWZAP(_struct) ((_struct*)PR_Calloc(1, sizeof(_struct))) - -/*********************************************************************** -** FUNCTION: PR_DELETE() -** DESCRIPTION: -** PR_DELETE() unallocates an object previosly allocated via PR_NEW() -** or PR_NEWZAP() to the heap. -** INPUTS: pointer to previously allocated object -** OUTPUTS: the referenced object is returned to the heap -** RETURN: void -***********************************************************************/ -#define PR_DELETE(_ptr) { PR_Free(_ptr); (_ptr) = NULL; } - -/*********************************************************************** -** FUNCTION: PR_FREEIF() -** DESCRIPTION: -** PR_FREEIF() conditionally unallocates an object previously allocated -** vial PR_NEW() or PR_NEWZAP(). If the pointer to the object is -** equal to zero (0), the object is not released. -** INPUTS: pointer to previously allocated object -** OUTPUTS: the referenced object is conditionally returned to the heap -** RETURN: void -***********************************************************************/ -#define PR_FREEIF(_ptr) if (_ptr) PR_DELETE(_ptr) - -PR_END_EXTERN_C - -#endif /* prmem_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prmon.h nspr-4.10.7/mozilla/nsprpub/pr/include/prmon.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prmon.h 2012-03-06 13:13:47.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prmon.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prmon_h___ -#define prmon_h___ - -#include "prtypes.h" -#include "prinrval.h" - -PR_BEGIN_EXTERN_C - -typedef struct PRMonitor PRMonitor; - -/* -** Create a new monitor. Monitors are re-entrant locks with a single built-in -** condition variable. -** -** This may fail if memory is tight or if some operating system resource -** is low. -*/ -NSPR_API(PRMonitor*) PR_NewMonitor(void); - -/* -** Destroy a monitor. The caller is responsible for guaranteeing that the -** monitor is no longer in use. There must be no thread waiting on the monitor's -** condition variable and that the lock is not held. -** -*/ -NSPR_API(void) PR_DestroyMonitor(PRMonitor *mon); - -/* -** Enter the lock associated with the monitor. If the calling thread currently -** is in the monitor, the call to enter will silently succeed. In either case, -** it will increment the entry count by one. -*/ -NSPR_API(void) PR_EnterMonitor(PRMonitor *mon); - -/* -** Decrement the entry count associated with the monitor. If the decremented -** entry count is zero, the monitor is exited. Returns PR_FAILURE if the -** calling thread has not entered the monitor. -*/ -NSPR_API(PRStatus) PR_ExitMonitor(PRMonitor *mon); - -/* -** Wait for a notify on the monitor's condition variable. Sleep for "ticks" -** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is -** indefinite). -** -** While the thread is waiting it exits the monitor (as if it called -** PR_ExitMonitor as many times as it had called PR_EnterMonitor). When -** the wait has finished the thread regains control of the monitors lock -** with the same entry count as before the wait began. -** -** The thread waiting on the monitor will be resumed when the monitor is -** notified (assuming the thread is the next in line to receive the -** notify) or when the "ticks" timeout elapses. -** -** Returns PR_FAILURE if the caller has not entered the monitor. -*/ -NSPR_API(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks); - -/* -** Notify a thread waiting on the monitor's condition variable. If a thread -** is waiting on the condition variable (using PR_Wait) then it is awakened -** and attempts to reenter the monitor. -*/ -NSPR_API(PRStatus) PR_Notify(PRMonitor *mon); - -/* -** Notify all of the threads waiting on the monitor's condition variable. -** All of threads waiting on the condition are scheduled to reenter the -** monitor. -*/ -NSPR_API(PRStatus) PR_NotifyAll(PRMonitor *mon); - -/* -** PR_ASSERT_CURRENT_THREAD_IN_MONITOR -** If the current thread is in |mon|, this assertion is guaranteed to -** succeed. Otherwise, the behavior of this function is undefined. -*/ -#if defined(DEBUG) || defined(FORCE_PR_ASSERT) -#define PR_ASSERT_CURRENT_THREAD_IN_MONITOR(/* PRMonitor* */ mon) \ - PR_AssertCurrentThreadInMonitor(mon) -#else -#define PR_ASSERT_CURRENT_THREAD_IN_MONITOR(/* PRMonitor* */ mon) -#endif - -/* Don't call this function directly. */ -NSPR_API(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon); - -PR_END_EXTERN_C - -#endif /* prmon_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prmwait.h nspr-4.10.7/mozilla/nsprpub/pr/include/prmwait.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prmwait.h 2012-03-06 13:13:47.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prmwait.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,380 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#if defined(_PRMWAIT_H) -#else -#define _PRMWAIT_H - -#include "prio.h" -#include "prtypes.h" -#include "prclist.h" - -PR_BEGIN_EXTERN_C - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/****************************** WARNING ****************************/ -/********************************************************************************/ -/**************************** This is work in progress. *************************/ -/************************** Do not make any assumptions *************************/ -/************************** about the stability of this *************************/ -/************************** API or the underlying imple- ************************/ -/************************** mentation. ************************/ -/********************************************************************************/ -/********************************************************************************/ - -/* -** STRUCTURE: PRWaitGroup -** DESCRIPTION: -** The client may define several wait groups in order to semantically -** tie a collection of file descriptors for a single purpose. This allows -** easier dispatching of threads that returned with active file descriptors -** from the wait function. -*/ -typedef struct PRWaitGroup PRWaitGroup; - -/* -** ENUMERATION: PRMWStatus -** DESCRIPTION: -** This enumeration is used to indicate the completion status of -** a receive wait object. Generally stated, a positive value indicates -** that the operation is not yet complete. A zero value indicates -** success (similar to PR_SUCCESS) and any negative value is an -** indication of failure. The reason for the failure can be retrieved -** by calling PR_GetError(). -** -** PR_MW_PENDING The operation is still pending. None of the other -** fields of the object are currently valid. -** PR_MW_SUCCESS The operation is complete and it was successful. -** PR_MW_FAILURE The operation failed. The reason for the failure -** can be retrieved by calling PR_GetError(). -** PR_MW_TIMEOUT The amount of time allowed for by the object's -** 'timeout' field has expired w/o the operation -** otherwise coming to closure. -** PR_MW_INTERRUPT The operation was cancelled, either by the client -** calling PR_CancelWaitFileDesc() or destroying the -** entire wait group (PR_DestroyWaitGroup()). -*/ -typedef enum PRMWStatus -{ - PR_MW_PENDING = 1, - PR_MW_SUCCESS = 0, - PR_MW_FAILURE = -1, - PR_MW_TIMEOUT = -2, - PR_MW_INTERRUPT = -3 -} PRMWStatus; - -/* -** STRUCTURE: PRMemoryDescriptor -** DESCRIPTION: -** THis is a descriptor for an interval of memory. It contains a -** pointer to the first byte of that memory and the length (in -** bytes) of the interval. -*/ -typedef struct PRMemoryDescriptor -{ - void *start; /* pointer to first byte of memory */ - PRSize length; /* length (in bytes) of memory interval */ -} PRMemoryDescriptor; - -/* -** STRUCTURE: PRMWaitClientData -** DESCRIPTION: -** An opague stucture for which a client MAY give provide a concrete -** definition and associate with a receive descriptor. The NSPR runtime -** does not manage this field. It is completely up to the client. -*/ -typedef struct PRMWaitClientData PRMWaitClientData; - -/* -** STRUCTURE: PRRecvWait -** DESCRIPTION: -** A receive wait object contains the file descriptor that is subject -** to the wait and the amount of time (beginning epoch established -** when the object is presented to the runtime) the the channel should -** block before abandoning the process. -** -** The success of the wait operation will be noted in the object's -** 'outcome' field. The fields are not valid when the NSPR runtime -** is in possession of the object. -** -** The memory descriptor describes an interval of writable memory -** in the caller's address space where data from an initial read -** can be placed. The description may indicate a null interval. -*/ -typedef struct PRRecvWait -{ - PRCList internal; /* internal runtime linkages */ - - PRFileDesc *fd; /* file descriptor associated w/ object */ - PRMWStatus outcome; /* outcome of the current/last operation */ - PRIntervalTime timeout; /* time allowed for entire operation */ - - PRInt32 bytesRecv; /* number of bytes transferred into buffer */ - PRMemoryDescriptor buffer; /* where to store first segment of input data */ - PRMWaitClientData *client; /* pointer to arbitrary client defined data */ -} PRRecvWait; - -/* -** STRUCTURE: PRMWaitEnumerator -** DESCRIPTION: -** An enumeration object is used to store the state of an existing -** enumeration over a wait group. The opaque object must be allocated -** by the client and the reference presented on each call to the -** pseudo-stateless enumerator. The enumeration objects are sharable -** only in serial fashion. -*/ -typedef struct PRMWaitEnumerator PRMWaitEnumerator; - - -/* -** FUNCTION: PR_AddWaitFileDesc -** DESCRIPTION: -** This function will effectively add a file descriptor to the -** list of those waiting for network receive. The new descriptor -** will be semantically tied to the wait group specified. -** -** The ownership for the storage pointed to by 'desc' is temporarily -** passed over the the NSPR runtime. It will be handed back by the -** function PR_WaitRecvReady(). -** -** INPUTS -** group A reference to a PRWaitGroup or NULL. Wait groups are -** created by calling PR_CreateWaitGroup() and are used -** to semantically group various file descriptors by the -** client's application. -** desc A reference to a valid PRRecvWait. The object of the -** reference must be preserved and not be modified -** until its ownership is returned to the client. -** RETURN -** PRStatus An indication of success. If equal to PR_FAILUE details -** of the failure are avaiable via PR_GetError(). -** -** ERRORS -** PR_INVALID_ARGUMENT_ERROR -** Invalid 'group' identifier or duplicate 'desc' object. -** PR_OUT_OF_MEMORY_ERROR -** Insuffient memory for internal data structures. -** PR_INVALID_STATE_ERROR -** The group is being destroyed. -*/ -NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc); - -/* -** FUNCTION: PR_WaitRecvReady -** DESCRIPTION: -** PR_WaitRecvReady will block the calling thread until one of the -** file descriptors that have been added via PR_AddWaitFileDesc is -** available for input I/O. -** INPUT -** group A pointer to a valid PRWaitGroup or NULL (the null -** group. The function will block the caller until a -** channel from the wait group becomes ready for receive -** or there is some sort of error. -** RETURN -** PRReciveWait -** When the caller is resumed it is either returned a -** valid pointer to a previously added receive wait or -** a NULL. If the latter, the function has terminated -** for a reason that can be determined by calling -** PR_GetError(). -** If a valid pointer is returned, the reference is to the -** file descriptor contained in the receive wait object. -** The outcome of the wait operation may still fail, and -** if it has, that fact will be noted in the object's -** outcome field. Details can be retrieved from PR_GetError(). -** -** ERRORS -** PR_INVALID_ARGUMENT_ERROR -** The 'group' is not known by the runtime. -** PR_PENDING_INTERRUPT_ERROR - The thread was interrupted. -** PR_INVALID_STATE_ERROR -** The group is being destroyed. -*/ -NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group); - -/* -** FUNCTION: PR_CancelWaitFileDesc -** DESCRIPTION: -** PR_CancelWaitFileDesc is provided as a means for cancelling operations -** on objects previously submitted by use of PR_AddWaitFileDesc(). If -** the runtime knows of the object, it will be marked as having failed -** because it was interrupted (similar to PR_Interrupt()). The first -** available thread waiting on the group will be made to return the -** PRRecvWait object with the outcome noted. -** -** INPUTS -** group The wait group under which the wait receive object was -** added. -** desc A pointer to the wait receive object that is to be -** cancelled. -** RETURN -** PRStatus If the wait receive object was located and associated -** with the specified wait group, the status returned will -** be PR_SUCCESS. There is still a race condition that would -** permit the offected object to complete normally, but it -** is assured that it will complete in the near future. -** If the receive object or wait group are invalid, the -** function will return with a status of PR_FAILURE. -** -** ERRORS -** PR_INVALID_ARGUMENT_ERROR -** The 'group' argument is not recognized as a valid group. -** PR_COLLECTION_EMPTY_ERROR -** There are no more receive wait objects in the group's -** collection. -** PR_INVALID_STATE_ERROR -** The group is being destroyed. -*/ -NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc); - -/* -** FUNCTION: PR_CancelWaitGroup -** DESCRIPTION: -** PR_CancelWaitGroup is provided as a means for cancelling operations -** on objects previously submitted by use of PR_AddWaitFileDesc(). Each -** successive call will return a pointer to a PRRecvWait object that -** was previously registered via PR_AddWaitFileDesc(). If no wait -** objects are associated with the wait group, a NULL will be returned. -** This function should be called in a loop until a NULL is returned -** to reclaim all the wait objects prior to calling PR_DestroyWaitGroup(). -** -** INPUTS -** group The wait group under which the wait receive object was -** added. -** RETURN -** PRRecvWait* If the wait group is valid and at least one receive wait -** object is present in the group, that object will be -** marked as PR_MW_INTERRUPT'd and removed from the group's -** queues. Otherwise a NULL will be returned and the reason -** for the NULL may be retrieved by calling PR_GetError(). -** -** ERRORS -** PR_INVALID_ARGUMENT_ERROR -** PR_GROUP_EMPTY_ERROR -*/ -NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group); - -/* -** FUNCTION: PR_CreateWaitGroup -** DESCRIPTION: -** A wait group is an opaque object that a client may create in order -** to semantically group various wait requests. Each wait group is -** unique, including the default wait group (NULL). A wait request -** that was added under a wait group will only be serviced by a caller -** that specified the same wait group. -** -** INPUT -** size The size of the hash table to be used to contain the -** receive wait objects. This is just the initial size. -** It will grow as it needs to, but to avoid that hassle -** one can suggest a suitable size initially. It should -** be ~30% larger than the maximum number of receive wait -** objects expected. -** RETURN -** PRWaitGroup If successful, the function will return a pointer to an -** object that was allocated by and owned by the runtime. -** The reference remains valid until it is explicitly destroyed -** by calling PR_DestroyWaitGroup(). -** -** ERRORS -** PR_OUT_OF_MEMORY_ERROR -*/ -NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size); - -/* -** FUNCTION: PR_DestroyWaitGroup -** DESCRIPTION: -** Undo the effects of PR_CreateWaitGroup(). Any receive wait operations -** on the group will be treated as if the each had been the target of a -** PR_CancelWaitFileDesc(). -** -** INPUT -** group Reference to a wait group previously allocated using -** PR_CreateWaitGroup(). -** RETURN -** PRStatus Will be PR_SUCCESS if the wait group was valid and there -** are no receive wait objects in that group. Otherwise -** will indicate PR_FAILURE. -** -** ERRORS -** PR_INVALID_ARGUMENT_ERROR -** The 'group' argument does not reference a known object. -** PR_INVALID_STATE_ERROR -** The group still contains receive wait objects. -*/ -NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group); - -/* -** FUNCTION: PR_CreateMWaitEnumerator -** DESCRIPTION: -** The PR_CreateMWaitEnumerator() function returns a reference to an -** opaque PRMWaitEnumerator object. The enumerator object is required -** as an argument for each successive call in the stateless enumeration -** of the indicated wait group. -** -** group The wait group that the enumeration is intended to -** process. It may be be the default wait group (NULL). -** RETURN -** PRMWaitEnumerator* group -** A reference to an object that will be used to store -** intermediate state of enumerations. -** ERRORS -** Errors are indicated by the function returning a NULL. -** PR_INVALID_ARGUMENT_ERROR -** The 'group' argument does not reference a known object. -** PR_OUT_OF_MEMORY_ERROR -*/ -NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group); - -/* -** FUNCTION: PR_DestroyMWaitEnumerator -** DESCRIPTION: -** Destroys the object created by PR_CreateMWaitEnumerator(). The reference -** used as an argument becomes invalid. -** -** INPUT -** PRMWaitEnumerator* enumerator -** The PRMWaitEnumerator object to destroy. -** RETURN -** PRStatus -** PR_SUCCESS if successful, PR_FAILURE otherwise. -** ERRORS -** PR_INVALID_ARGUMENT_ERROR -** The enumerator is invalid. -*/ -NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator); - -/* -** FUNCTION: PR_EnumerateWaitGroup -** DESCRIPTION: -** PR_EnumerateWaitGroup is a thread safe enumerator over a wait group. -** Each call to the enumerator must present a valid PRMWaitEnumerator -** rererence and a pointer to the "previous" element returned from the -** enumeration process or a NULL. -** -** An enumeration is started by passing a NULL as the "previous" value. -** Subsequent calls to the enumerator must pass in the result of the -** previous call. The enumeration end is signaled by the runtime returning -** a NULL as the result. -** -** Modifications to the content of the wait group are allowed during -** an enumeration. The effect is that the enumeration may have to be -** "reset" and that may result in duplicates being returned from the -** enumeration. -** -** An enumeration may be abandoned at any time. The runtime is not -** keeping any state, so there are no issues in that regard. -*/ -NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup( - PRMWaitEnumerator *enumerator, const PRRecvWait *previous); - -PR_END_EXTERN_C - -#endif /* defined(_PRMWAIT_H) */ - -/* prmwait.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prnetdb.h nspr-4.10.7/mozilla/nsprpub/pr/include/prnetdb.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prnetdb.h 2012-03-06 13:13:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prnetdb.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,467 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prnetdb_h___ -#define prnetdb_h___ - -#include "prtypes.h" -#include "prio.h" - -PR_BEGIN_EXTERN_C - - -/* - ********************************************************************* - * Translate an Internet address to/from a character string - ********************************************************************* - */ -NSPR_API(PRStatus) PR_StringToNetAddr( - const char *string, PRNetAddr *addr); - -NSPR_API(PRStatus) PR_NetAddrToString( - const PRNetAddr *addr, char *string, PRUint32 size); - -/* -** Structures returned by network data base library. All addresses are -** supplied in host order, and returned in network order (suitable for -** use in system calls). -*/ -/* -** Beware that WINSOCK.H defines h_addrtype and h_length as short. -** Client code does direct struct copies of hostent to PRHostEnt and -** hence the ifdef. -*/ -typedef struct PRHostEnt { - char *h_name; /* official name of host */ - char **h_aliases; /* alias list */ -#ifdef WIN32 - PRInt16 h_addrtype; /* host address type */ - PRInt16 h_length; /* length of address */ -#else - PRInt32 h_addrtype; /* host address type */ - PRInt32 h_length; /* length of address */ -#endif - char **h_addr_list; /* list of addresses from name server */ -} PRHostEnt; - -/* A safe size to use that will mostly work... */ -#if (defined(AIX) && defined(_THREAD_SAFE)) || defined(OSF1) -#define PR_NETDB_BUF_SIZE sizeof(struct protoent_data) -#else -#define PR_NETDB_BUF_SIZE 1024 -#endif - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_GetHostByName() -** Lookup a host by name. -** -** INPUTS: -** char *hostname Character string defining the host name of interest -** char *buf A scratch buffer for the runtime to return result. -** This buffer is allocated by the caller. -** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to -** use is PR_NETDB_BUF_SIZE. -** OUTPUTS: -** PRHostEnt *hostentry -** This structure is filled in by the runtime if -** the function returns PR_SUCCESS. This structure -** is allocated by the caller. -** RETURN: -** PRStatus PR_SUCCESS if the lookup succeeds. If it fails -** the result will be PR_FAILURE and the reason -** for the failure can be retrieved by PR_GetError(). -***********************************************************************/ -NSPR_API(PRStatus) PR_GetHostByName( - const char *hostname, char *buf, PRIntn bufsize, PRHostEnt *hostentry); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_GetIPNodeByName() -** Lookup a host by name. Equivalent to getipnodebyname(AI_DEFAULT) -** of RFC 2553. -** -** INPUTS: -** char *hostname Character string defining the host name of interest -** PRUint16 af Address family (either PR_AF_INET or PR_AF_INET6) -** PRIntn flags Specifies the types of addresses that are searched -** for and the types of addresses that are returned. -** The only supported flag is PR_AI_DEFAULT. -** char *buf A scratch buffer for the runtime to return result. -** This buffer is allocated by the caller. -** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to -** use is PR_NETDB_BUF_SIZE. -** OUTPUTS: -** PRHostEnt *hostentry -** This structure is filled in by the runtime if -** the function returns PR_SUCCESS. This structure -** is allocated by the caller. -** RETURN: -** PRStatus PR_SUCCESS if the lookup succeeds. If it fails -** the result will be PR_FAILURE and the reason -** for the failure can be retrieved by PR_GetError(). -***********************************************************************/ - - -#define PR_AI_ALL 0x08 -#define PR_AI_V4MAPPED 0x10 -#define PR_AI_ADDRCONFIG 0x20 -#define PR_AI_NOCANONNAME 0x8000 -#define PR_AI_DEFAULT (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG) - -NSPR_API(PRStatus) PR_GetIPNodeByName( - const char *hostname, - PRUint16 af, - PRIntn flags, - char *buf, - PRIntn bufsize, - PRHostEnt *hostentry); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_GetHostByAddr() -** Lookup a host entry by its network address. -** -** INPUTS: -** char *hostaddr IP address of host in question -** char *buf A scratch buffer for the runtime to return result. -** This buffer is allocated by the caller. -** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to -** use is PR_NETDB_BUF_SIZE. -** OUTPUTS: -** PRHostEnt *hostentry -** This structure is filled in by the runtime if -** the function returns PR_SUCCESS. This structure -** is allocated by the caller. -** RETURN: -** PRStatus PR_SUCCESS if the lookup succeeds. If it fails -** the result will be PR_FAILURE and the reason -** for the failure can be retrieved by PR_GetError(). -***********************************************************************/ -NSPR_API(PRStatus) PR_GetHostByAddr( - const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry); - -/*********************************************************************** -** FUNCTION: PR_EnumerateHostEnt() -** DESCRIPTION: -** A stateless enumerator over a PRHostEnt structure acquired from -** PR_GetHostByName() PR_GetHostByAddr() to evaluate the possible -** network addresses. -** -** INPUTS: -** PRIntn enumIndex Index of the enumeration. The enumeration starts -** and ends with a value of zero. -** -** PRHostEnt *hostEnt A pointer to a host entry struct that was -** previously returned by PR_GetHostByName() or -** PR_GetHostByAddr(). -** -** PRUint16 port The port number to be assigned as part of the -** PRNetAddr. -** -** OUTPUTS: -** PRNetAddr *address A pointer to an address structure that will be -** filled in by the call to the enumeration if the -** result of the call is greater than zero. -** -** RETURN: -** PRIntn The value that should be used for the next call -** of the enumerator ('enumIndex'). The enumeration -** is ended if this value is returned zero. -** If a value of -1 is returned, the enumeration -** has failed. The reason for the failure can be -** retrieved by calling PR_GetError(). -***********************************************************************/ -NSPR_API(PRIntn) PR_EnumerateHostEnt( - PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address); - -/*********************************************************************** -** FUNCTION: PR_InitializeNetAddr(), -** DESCRIPTION: -** Initialize the fields of a PRNetAddr, assigning well known values as -** appropriate. -** -** INPUTS -** PRNetAddrValue val The value to be assigned to the IP Address portion -** of the network address. This can only specify the -** special well known values that are equivalent to -** INADDR_ANY and INADDR_LOOPBACK. -** -** PRUint16 port The port number to be assigned in the structure. -** -** OUTPUTS: -** PRNetAddr *addr The address to be manipulated. -** -** RETURN: -** PRStatus To indicate success or failure. If the latter, the -** reason for the failure can be retrieved by calling -** PR_GetError(); -***********************************************************************/ -typedef enum PRNetAddrValue -{ - PR_IpAddrNull, /* do NOT overwrite the IP address */ - PR_IpAddrAny, /* assign logical INADDR_ANY to IP address */ - PR_IpAddrLoopback, /* assign logical INADDR_LOOPBACK */ - PR_IpAddrV4Mapped /* IPv4 mapped address */ -} PRNetAddrValue; - -NSPR_API(PRStatus) PR_InitializeNetAddr( - PRNetAddrValue val, PRUint16 port, PRNetAddr *addr); - -/*********************************************************************** -** FUNCTION: PR_SetNetAddr(), -** DESCRIPTION: -** Set the fields of a PRNetAddr, assigning well known values as -** appropriate. This function is similar to PR_InitializeNetAddr -** but differs in that the address family is specified. -** -** INPUTS -** PRNetAddrValue val The value to be assigned to the IP Address portion -** of the network address. This can only specify the -** special well known values that are equivalent to -** INADDR_ANY and INADDR_LOOPBACK. -** -** PRUint16 af The address family (either PR_AF_INET or PR_AF_INET6) -** -** PRUint16 port The port number to be assigned in the structure. -** -** OUTPUTS: -** PRNetAddr *addr The address to be manipulated. -** -** RETURN: -** PRStatus To indicate success or failure. If the latter, the -** reason for the failure can be retrieved by calling -** PR_GetError(); -***********************************************************************/ -NSPR_API(PRStatus) PR_SetNetAddr( - PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_IsNetAddrType() -** Determine if the network address is of the specified type. -** -** INPUTS: -** const PRNetAddr *addr A network address. -** PRNetAddrValue The type of network address -** -** RETURN: -** PRBool PR_TRUE if the network address is of the -** specified type, else PR_FALSE. -***********************************************************************/ -NSPR_API(PRBool) PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_ConvertIPv4AddrToIPv6() -** Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr -** -** INPUTS: -** PRUint32 v4addr IPv4 address -** -** OUTPUTS: -** PRIPv6Addr *v6addr The converted IPv6 address -** -** RETURN: -** void -** -***********************************************************************/ -NSPR_API(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr); - -/*********************************************************************** -** MACRO: -** DESCRIPTION: PR_NetAddrFamily() -** Get the 'family' field of a PRNetAddr union. -** -** INPUTS: -** const PRNetAddr *addr A network address. -** -** RETURN: -** PRUint16 The 'family' field of 'addr'. -***********************************************************************/ -#define PR_NetAddrFamily(addr) ((addr)->raw.family) - -/*********************************************************************** -** MACRO: -** DESCRIPTION: PR_NetAddrInetPort() -** Get the 'port' field of a PRNetAddr union. -** -** INPUTS: -** const PRNetAddr *addr A network address. -** -** RETURN: -** PRUint16 The 'port' field of 'addr'. -***********************************************************************/ -#define PR_NetAddrInetPort(addr) \ - ((addr)->raw.family == PR_AF_INET6 ? (addr)->ipv6.port : (addr)->inet.port) - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_GetProtoByName() -** Lookup a protocol entry based on protocol's name -** -** INPUTS: -** char *protocolname Character string of the protocol's name. -** char *buf A scratch buffer for the runtime to return result. -** This buffer is allocated by the caller. -** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to -** use is PR_NETDB_BUF_SIZE. -** OUTPUTS: -** PRHostEnt *PRProtoEnt -** This structure is filled in by the runtime if -** the function returns PR_SUCCESS. This structure -** is allocated by the caller. -** RETURN: -** PRStatus PR_SUCCESS if the lookup succeeds. If it fails -** the result will be PR_FAILURE and the reason -** for the failure can be retrieved by PR_GetError(). -***********************************************************************/ - -typedef struct PRProtoEnt { - char *p_name; /* official protocol name */ - char **p_aliases; /* alias list */ -#ifdef WIN32 - PRInt16 p_num; /* protocol # */ -#else - PRInt32 p_num; /* protocol # */ -#endif -} PRProtoEnt; - -NSPR_API(PRStatus) PR_GetProtoByName( - const char* protocolname, char* buffer, PRInt32 bufsize, PRProtoEnt* result); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_GetProtoByNumber() -** Lookup a protocol entry based on protocol's number -** -** INPUTS: -** PRInt32 protocolnumber -** Number assigned to the protocol. -** char *buf A scratch buffer for the runtime to return result. -** This buffer is allocated by the caller. -** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to -** use is PR_NETDB_BUF_SIZE. -** OUTPUTS: -** PRHostEnt *PRProtoEnt -** This structure is filled in by the runtime if -** the function returns PR_SUCCESS. This structure -** is allocated by the caller. -** RETURN: -** PRStatus PR_SUCCESS if the lookup succeeds. If it fails -** the result will be PR_FAILURE and the reason -** for the failure can be retrieved by PR_GetError(). -***********************************************************************/ -NSPR_API(PRStatus) PR_GetProtoByNumber( - PRInt32 protocolnumber, char* buffer, PRInt32 bufsize, PRProtoEnt* result); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_GetAddrInfoByName() -** Look up a host by name. Equivalent to getaddrinfo(host, NULL, ...) of -** RFC 3493. -** -** INPUTS: -** char *hostname Character string defining the host name of interest -** PRUint16 af May be PR_AF_UNSPEC or PR_AF_INET. -** PRIntn flags May be either PR_AI_ADDRCONFIG or -** PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME. Include -** PR_AI_NOCANONNAME to suppress the determination of -** the canonical name corresponding to hostname. -** RETURN: -** PRAddrInfo* Handle to a data structure containing the results -** of the host lookup. Use PR_EnumerateAddrInfo to -** inspect the PRNetAddr values stored in this object. -** When no longer needed, this handle must be destroyed -** with a call to PR_FreeAddrInfo. If a lookup error -** occurs, then NULL will be returned. -***********************************************************************/ -typedef struct PRAddrInfo PRAddrInfo; - -NSPR_API(PRAddrInfo*) PR_GetAddrInfoByName( - const char *hostname, PRUint16 af, PRIntn flags); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_FreeAddrInfo() -** Destroy the PRAddrInfo handle allocated by PR_GetAddrInfoByName(). -** -** INPUTS: -** PRAddrInfo *addrInfo -** The handle resulting from a successful call to -** PR_GetAddrInfoByName(). -** RETURN: -** void -***********************************************************************/ -NSPR_API(void) PR_FreeAddrInfo(PRAddrInfo *addrInfo); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_EnumerateAddrInfo() -** A stateless enumerator over a PRAddrInfo handle acquired from -** PR_GetAddrInfoByName() to inspect the possible network addresses. -** -** INPUTS: -** void *enumPtr Index pointer of the enumeration. The enumeration -** starts and ends with a value of NULL. -** const PRAddrInfo *addrInfo -** The PRAddrInfo handle returned by a successful -** call to PR_GetAddrInfoByName(). -** PRUint16 port The port number to be assigned as part of the -** PRNetAddr. -** OUTPUTS: -** PRNetAddr *result A pointer to an address structure that will be -** filled in by the call to the enumeration if the -** result of the call is not NULL. -** RETURN: -** void* The value that should be used for the next call -** of the enumerator ('enumPtr'). The enumeration -** is ended if this value is NULL. -***********************************************************************/ -NSPR_API(void *) PR_EnumerateAddrInfo( - void *enumPtr, const PRAddrInfo *addrInfo, PRUint16 port, PRNetAddr *result); - -/*********************************************************************** -** FUNCTION: -** DESCRIPTION: PR_GetCanonNameFromAddrInfo() -** Extracts the canonical name of the hostname passed to -** PR_GetAddrInfoByName(). -** -** INPUTS: -** const PRAddrInfo *addrInfo -** The PRAddrInfo handle returned by a successful -** call to PR_GetAddrInfoByName(). -** RETURN: -** const char * A const pointer to the canonical hostname stored -** in the given PRAddrInfo handle. This pointer is -** invalidated once the PRAddrInfo handle is destroyed -** by a call to PR_FreeAddrInfo(). -***********************************************************************/ -NSPR_API(const char *) PR_GetCanonNameFromAddrInfo( - const PRAddrInfo *addrInfo); - -/*********************************************************************** -** FUNCTIONS: PR_ntohs, PR_ntohl, PR_ntohll, PR_htons, PR_htonl, PR_htonll -** -** DESCRIPTION: API entries for the common byte ordering routines. -** -** PR_ntohs 16 bit conversion from network to host -** PR_ntohl 32 bit conversion from network to host -** PR_ntohll 64 bit conversion from network to host -** PR_htons 16 bit conversion from host to network -** PR_htonl 32 bit conversion from host to network -** PR_ntonll 64 bit conversion from host to network -** -***********************************************************************/ -NSPR_API(PRUint16) PR_ntohs(PRUint16); -NSPR_API(PRUint32) PR_ntohl(PRUint32); -NSPR_API(PRUint64) PR_ntohll(PRUint64); -NSPR_API(PRUint16) PR_htons(PRUint16); -NSPR_API(PRUint32) PR_htonl(PRUint32); -NSPR_API(PRUint64) PR_htonll(PRUint64); - -PR_END_EXTERN_C - -#endif /* prnetdb_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prolock.h nspr-4.10.7/mozilla/nsprpub/pr/include/prolock.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prolock.h 2012-03-06 13:13:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prolock.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prolock_h___ -#define prolock_h___ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* -** A locking mechanism, built on the existing PRLock definiion, -** is provided that will permit applications to define a Lock -** Hierarchy (or Lock Ordering) schema. An application designed -** using the Ordered Lock functions will terminate with a -** diagnostic message when a lock inversion condition is -** detected. -** -** The lock ordering detection is complile-time enabled only. in -** optimized builds of NSPR, the Ordered Lock functions map -** directly to PRLock functions, providing no lock order -** detection. -** -** The Ordered Lock Facility is compiled in when DEBUG is defined at -** compile time. Ordered Lock can be forced on in optimized builds by -** defining FORCE_NSPR_ORDERED_LOCK at compile time. Both the -** application using Ordered Lock and NSPR must be compiled with the -** facility enabled to achieve the desired results. -** -** Application designers should use the macro interfaces to the Ordered -** Lock facility to ensure that it is compiled out in optimized builds. -** -** Application designers are responsible for defining their own -** lock hierarchy. -** -** Ordered Lock is thread-safe and SMP safe. -** -** See Also: prlock.h -** -** /lth. 10-Jun-1998. -** -*/ - -/* -** Opaque type for ordered lock. -** ... Don't even think of looking in here. -** -*/ - -#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) -typedef void * PROrderedLock; -#else -/* -** Map PROrderedLock and methods onto PRLock when ordered locking -** is not compiled in. -** -*/ -#include "prlock.h" - -typedef PRLock PROrderedLock; -#endif - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_CreateOrderedLock() -- Create an Ordered Lock -** -** DESCRIPTION: PR_CreateOrderedLock() creates an ordered lock. -** -** INPUTS: -** order: user defined order of this lock. -** name: name of the lock. For debugging purposes. -** -** OUTPUTS: returned -** -** RETURNS: PR_OrderedLock pointer -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) -#define PR_CREATE_ORDERED_LOCK(order,name)\ - PR_CreateOrderedLock((order),(name)) -#else -#define PR_CREATE_ORDERED_LOCK(order) PR_NewLock() -#endif - -NSPR_API(PROrderedLock *) - PR_CreateOrderedLock( - PRInt32 order, - const char *name -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_DestroyOrderedLock() -- Destroy an Ordered Lock -** -** DESCRIPTION: PR_DestroyOrderedLock() destroys the ordered lock -** referenced by lock. -** -** INPUTS: lock: pointer to a PROrderedLock -** -** OUTPUTS: the lock is destroyed -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) -#define PR_DESTROY_ORDERED_LOCK(lock) PR_DestroyOrderedLock((lock)) -#else -#define PR_DESTROY_ORDERED_LOCK(lock) PR_DestroyLock((lock)) -#endif - -NSPR_API(void) - PR_DestroyOrderedLock( - PROrderedLock *lock -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_LockOrderedLock() -- Lock an ordered lock -** -** DESCRIPTION: PR_LockOrderedLock() locks the ordered lock -** referenced by lock. If the order of lock is less than or equal -** to the order of the highest lock held by the locking thread, -** the function asserts. -** -** INPUTS: lock: a pointer to a PROrderedLock -** -** OUTPUTS: The lock is held or the function asserts. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) -#define PR_LOCK_ORDERED_LOCK(lock) PR_LockOrderedLock((lock)) -#else -#define PR_LOCK_ORDERED_LOCK(lock) PR_Lock((lock)) -#endif - -NSPR_API(void) - PR_LockOrderedLock( - PROrderedLock *lock -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_UnlockOrderedLock() -- unlock and Ordered Lock -** -** DESCRIPTION: PR_UnlockOrderedLock() unlocks the lock referenced -** by lock. -** -** INPUTS: lock: a pointer to a PROrderedLock -** -** OUTPUTS: the lock is unlocked -** -** RETURNS: -** PR_SUCCESS -** PR_FAILURE -** -** RESTRICTIONS: -** -*/ -#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) -#define PR_UNLOCK_ORDERED_LOCK(lock) PR_UnlockOrderedLock((lock)) -#else -#define PR_UNLOCK_ORDERED_LOCK(lock) PR_Unlock((lock)) -#endif - -NSPR_API(PRStatus) - PR_UnlockOrderedLock( - PROrderedLock *lock -); - -PR_END_EXTERN_C - -#endif /* prolock_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prpdce.h nspr-4.10.7/mozilla/nsprpub/pr/include/prpdce.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prpdce.h 2012-03-06 13:13:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prpdce.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: prpdce.h - * Description: This file is the API defined to allow for DCE (aka POSIX) - * thread emulation in an NSPR environment. It is not the - * intent that this be a fully supported API. - */ - -#if !defined(PRPDCE_H) -#define PRPDCE_H - -#include "prlock.h" -#include "prcvar.h" -#include "prtypes.h" -#include "prinrval.h" - -PR_BEGIN_EXTERN_C - -#define _PR_NAKED_CV_LOCK (PRLock*)0xdce1dce1 - -/* -** Test and acquire a lock. -** -** If the lock is acquired by the calling thread, the -** return value will be PR_SUCCESS. If the lock is -** already held, by another thread or this thread, the -** result will be PR_FAILURE. -*/ -NSPR_API(PRStatus) PRP_TryLock(PRLock *lock); - -/* -** Create a naked condition variable -** -** A "naked" condition variable is one that is not created bound -** to a lock. The CV created with this function is the only type -** that may be used in the subsequent "naked" condition variable -** operations (see PRP_NakedWait, PRP_NakedNotify, PRP_NakedBroadcast); -*/ -NSPR_API(PRCondVar*) PRP_NewNakedCondVar(void); - -/* -** Destroy a naked condition variable -** -** Destroy the condition variable created by PR_NewNakedCondVar. -*/ -NSPR_API(void) PRP_DestroyNakedCondVar(PRCondVar *cvar); - -/* -** Wait on a condition -** -** Wait on the condition variable 'cvar'. It is asserted that -** the lock protecting the condition 'lock' is held by the -** calling thread. If more time expires than that declared in -** 'timeout' the condition will be notified. Waits can be -** interrupted by another thread. -** -** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar. -*/ -NSPR_API(PRStatus) PRP_NakedWait( - PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout); - -/* -** Notify a thread waiting on a condition -** -** Notify the condition specified 'cvar'. -** -** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar. -*/ -NSPR_API(PRStatus) PRP_NakedNotify(PRCondVar *cvar); - -/* -** Notify all threads waiting on a condition -** -** Notify the condition specified 'cvar'. -** -** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar. -*/ -NSPR_API(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar); - -PR_END_EXTERN_C - -#endif /* PRPDCE_H */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prprf.h nspr-4.10.7/mozilla/nsprpub/pr/include/prprf.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prprf.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prprf.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prprf_h___ -#define prprf_h___ - -/* -** API for PR printf like routines. Supports the following formats -** %d - decimal -** %u - unsigned decimal -** %x - unsigned hex -** %X - unsigned uppercase hex -** %o - unsigned octal -** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above -** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above -** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above -** %s - string -** %c - character -** %p - pointer (deals with machine dependent pointer size) -** %f - float -** %g - float -*/ -#include "prtypes.h" -#include "prio.h" -#include -#include - -PR_BEGIN_EXTERN_C - -/* -** sprintf into a fixed size buffer. Guarantees that a NUL is at the end -** of the buffer. Returns the length of the written output, NOT including -** the NUL, or (PRUint32)-1 if an error occurs. -*/ -NSPR_API(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...); - -/* -** sprintf into a PR_MALLOC'd buffer. Return a pointer to the malloc'd -** buffer on success, NULL on failure. Call "PR_smprintf_free" to release -** the memory returned. -*/ -NSPR_API(char*) PR_smprintf(const char *fmt, ...); - -/* -** Free the memory allocated, for the caller, by PR_smprintf -*/ -NSPR_API(void) PR_smprintf_free(char *mem); - -/* -** "append" sprintf into a PR_MALLOC'd buffer. "last" is the last value of -** the PR_MALLOC'd buffer. sprintf will append data to the end of last, -** growing it as necessary using realloc. If last is NULL, PR_sprintf_append -** will allocate the initial string. The return value is the new value of -** last for subsequent calls, or NULL if there is a malloc failure. -*/ -NSPR_API(char*) PR_sprintf_append(char *last, const char *fmt, ...); - -/* -** sprintf into a function. The function "f" is called with a string to -** place into the output. "arg" is an opaque pointer used by the stuff -** function to hold any state needed to do the storage of the output -** data. The return value is a count of the number of characters fed to -** the stuff function, or (PRUint32)-1 if an error occurs. -*/ -typedef PRIntn (*PRStuffFunc)(void *arg, const char *s, PRUint32 slen); - -NSPR_API(PRUint32) PR_sxprintf(PRStuffFunc f, void *arg, const char *fmt, ...); - -/* -** fprintf to a PRFileDesc -*/ -NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...); - -/* -** va_list forms of the above. -*/ -NSPR_API(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen, const char *fmt, va_list ap); -NSPR_API(char*) PR_vsmprintf(const char *fmt, va_list ap); -NSPR_API(char*) PR_vsprintf_append(char *last, const char *fmt, va_list ap); -NSPR_API(PRUint32) PR_vsxprintf(PRStuffFunc f, void *arg, const char *fmt, va_list ap); -NSPR_API(PRUint32) PR_vfprintf(struct PRFileDesc* fd, const char *fmt, va_list ap); - -/* -*************************************************************************** -** FUNCTION: PR_sscanf -** DESCRIPTION: -** PR_sscanf() scans the input character string, performs data -** conversions, and stores the converted values in the data objects -** pointed to by its arguments according to the format control -** string. -** -** PR_sscanf() behaves the same way as the sscanf() function in the -** Standard C Library (stdio.h), with the following exceptions: -** - PR_sscanf() handles the NSPR integer and floating point types, -** such as PRInt16, PRInt32, PRInt64, and PRFloat64, whereas -** sscanf() handles the standard C types like short, int, long, -** and double. -** - PR_sscanf() has no multibyte character support, while sscanf() -** does. -** INPUTS: -** const char *buf -** a character string holding the input to scan -** const char *fmt -** the format control string for the conversions -** ... -** variable number of arguments, each of them is a pointer to -** a data object in which the converted value will be stored -** OUTPUTS: none -** RETURNS: PRInt32 -** The number of values converted and stored. -** RESTRICTIONS: -** Multibyte characters in 'buf' or 'fmt' are not allowed. -*************************************************************************** -*/ - -NSPR_API(PRInt32) PR_sscanf(const char *buf, const char *fmt, ...); - -PR_END_EXTERN_C - -#endif /* prprf_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prproces.h nspr-4.10.7/mozilla/nsprpub/pr/include/prproces.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prproces.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prproces.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prproces_h___ -#define prproces_h___ - -#include "prtypes.h" -#include "prio.h" - -PR_BEGIN_EXTERN_C - -/************************************************************************/ -/*****************************PROCESS OPERATIONS*************************/ -/************************************************************************/ - -typedef struct PRProcess PRProcess; -typedef struct PRProcessAttr PRProcessAttr; - -NSPR_API(PRProcessAttr *) PR_NewProcessAttr(void); - -NSPR_API(void) PR_ResetProcessAttr(PRProcessAttr *attr); - -NSPR_API(void) PR_DestroyProcessAttr(PRProcessAttr *attr); - -NSPR_API(void) PR_ProcessAttrSetStdioRedirect( - PRProcessAttr *attr, - PRSpecialFD stdioFd, - PRFileDesc *redirectFd -); - -/* - * OBSOLETE -- use PR_ProcessAttrSetStdioRedirect instead. - */ -NSPR_API(void) PR_SetStdioRedirect( - PRProcessAttr *attr, - PRSpecialFD stdioFd, - PRFileDesc *redirectFd -); - -NSPR_API(PRStatus) PR_ProcessAttrSetCurrentDirectory( - PRProcessAttr *attr, - const char *dir -); - -NSPR_API(PRStatus) PR_ProcessAttrSetInheritableFD( - PRProcessAttr *attr, - PRFileDesc *fd, - const char *name -); - -/* -** Create a new process -** -** Create a new process executing the file specified as 'path' and with -** the supplied arguments and environment. -** -** This function may fail because of illegal access (permissions), -** invalid arguments or insufficient resources. -** -** A process may be created such that the creator can later synchronize its -** termination using PR_WaitProcess(). -*/ - -NSPR_API(PRProcess*) PR_CreateProcess( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr); - -NSPR_API(PRStatus) PR_CreateProcessDetached( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr); - -NSPR_API(PRStatus) PR_DetachProcess(PRProcess *process); - -NSPR_API(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode); - -NSPR_API(PRStatus) PR_KillProcess(PRProcess *process); - -PR_END_EXTERN_C - -#endif /* prproces_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prrng.h nspr-4.10.7/mozilla/nsprpub/pr/include/prrng.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prrng.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prrng.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -/* -** prrng.h -- NSPR Random Number Generator -** -** -** lth. 29-Oct-1999. -*/ - -#ifndef prrng_h___ -#define prrng_h___ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* -** PR_GetRandomNoise() -- Get random noise from the host platform -** -** Description: -** PR_GetRandomNoise() provides, depending on platform, a random value. -** The length of the random value is dependent on platform and the -** platform's ability to provide a random value at that moment. -** -** The intent of PR_GetRandomNoise() is to provide a "seed" value for a -** another random number generator that may be suitable for -** cryptographic operations. This implies that the random value -** provided may not be, by itself, cryptographically secure. The value -** generated by PR_GetRandomNoise() is at best, extremely difficult to -** predict and is as non-deterministic as the underlying platfrom can -** provide. -** -** Inputs: -** buf -- pointer to a caller supplied buffer to contain the -** generated random number. buf must be at least as large as -** is specified in the 'size' argument. -** -** size -- the requested size of the generated random number -** -** Outputs: -** a random number provided in 'buf'. -** -** Returns: -** PRSize value equal to the size of the random number actually -** generated, or zero. The generated size may be less than the size -** requested. A return value of zero means that PR_GetRandomNoise() is -** not implemented on this platform, or there is no available noise -** available to be returned at the time of the call. -** -** Restrictions: -** Calls to PR_GetRandomNoise() may use a lot of CPU on some platforms. -** Some platforms may block for up to a few seconds while they -** accumulate some noise. Busy machines generate lots of noise, but -** care is advised when using PR_GetRandomNoise() frequently in your -** application. -** -** History: -** Parts of the model dependent implementation for PR_GetRandomNoise() -** were taken in whole or part from code previously in Netscape's NSS -** component. -** -*/ -NSPR_API(PRSize) PR_GetRandomNoise( - void *buf, - PRSize size -); - -PR_END_EXTERN_C - -#endif /* prrng_h___ */ -/* end prrng.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prrwlock.h nspr-4.10.7/mozilla/nsprpub/pr/include/prrwlock.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prrwlock.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prrwlock.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prrwlock.h -** Description: API to basic reader-writer lock functions of NSPR. -** -**/ - -#ifndef prrwlock_h___ -#define prrwlock_h___ - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* - * PRRWLock -- - * - * The reader writer lock, PRRWLock, is an opaque object to the clients - * of NSPR. All routines operate on a pointer to this opaque entity. - */ - - -typedef struct PRRWLock PRRWLock; - -#define PR_RWLOCK_RANK_NONE 0 - - -/*********************************************************************** -** FUNCTION: PR_NewRWLock -** DESCRIPTION: -** Returns a pointer to a newly created reader-writer lock object. -** INPUTS: Lock rank -** Lock name -** OUTPUTS: void -** RETURN: PRRWLock* -** If the lock cannot be created because of resource constraints, NULL -** is returned. -** -***********************************************************************/ -NSPR_API(PRRWLock*) PR_NewRWLock(PRUint32 lock_rank, const char *lock_name); - -/*********************************************************************** -** FUNCTION: PR_DestroyRWLock -** DESCRIPTION: -** Destroys a given RW lock object. -** INPUTS: PRRWLock *lock - Lock to be freed. -** OUTPUTS: void -** RETURN: None -***********************************************************************/ -NSPR_API(void) PR_DestroyRWLock(PRRWLock *lock); - -/*********************************************************************** -** FUNCTION: PR_RWLock_Rlock -** DESCRIPTION: -** Apply a read lock (non-exclusive) on a RWLock -** INPUTS: PRRWLock *lock - Lock to be read-locked. -** OUTPUTS: void -** RETURN: None -***********************************************************************/ -NSPR_API(void) PR_RWLock_Rlock(PRRWLock *lock); - -/*********************************************************************** -** FUNCTION: PR_RWLock_Wlock -** DESCRIPTION: -** Apply a write lock (exclusive) on a RWLock -** INPUTS: PRRWLock *lock - Lock to write-locked. -** OUTPUTS: void -** RETURN: None -***********************************************************************/ -NSPR_API(void) PR_RWLock_Wlock(PRRWLock *lock); - -/*********************************************************************** -** FUNCTION: PR_RWLock_Unlock -** DESCRIPTION: -** Release a RW lock. Unlocking an unlocked lock has undefined results. -** INPUTS: PRRWLock *lock - Lock to unlocked. -** OUTPUTS: void -** RETURN: void -***********************************************************************/ -NSPR_API(void) PR_RWLock_Unlock(PRRWLock *lock); - -PR_END_EXTERN_C - -#endif /* prrwlock_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prshma.h nspr-4.10.7/mozilla/nsprpub/pr/include/prshma.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prshma.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prshma.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,239 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** prshma.h -- NSPR Anonymous Shared Memory -** -** NSPR provides an anonymous shared memory based on NSPR's PRFileMap -** type. The anonymous file-mapped shared memory provides an inheritable -** shared memory, as in: the child process inherits the shared memory. -** Compare the file-mapped anonymous shared memory to to a named shared -** memory described in prshm.h. The intent is to provide a shared -** memory that is accessable only by parent and child processes. ... -** It's a security thing. -** -** Depending on the underlying platform, the file-mapped shared memory -** may be backed by a file. ... surprise! ... On some platforms, no -** real file backs the shared memory. On platforms where the shared -** memory is backed by a file, the file's name in the filesystem is -** visible to other processes for only the duration of the creation of -** the file, hopefully a very short time. This restricts processess -** that do not inherit the shared memory from opening the file and -** reading or writing its contents. Further, when all processes -** using an anonymous shared memory terminate, the backing file is -** deleted. ... If you are not paranoid, you're not paying attention. -** -** The file-mapped shared memory requires a protocol for the parent -** process and child process to share the memory. NSPR provides two -** protocols. Use one or the other; don't mix and match. -** -** In the first protocol, the job of passing the inheritable shared -** memory is done via helper-functions with PR_CreateProcess(). In the -** second protocol, the parent process is responsible for creating the -** child process; the parent and child are mutually responsible for -** passing a FileMap string. NSPR provides helper functions for -** extracting data from the PRFileMap object. ... See the examples -** below. -** -** Both sides should adhere strictly to the protocol for proper -** operation. The pseudo-code below shows the use of a file-mapped -** shared memory by a parent and child processes. In the examples, the -** server creates the file-mapped shared memory, the client attaches to -** it. -** -** First protocol. -** Server: -** -** fm = PR_OpenAnonFileMap(dirName, size, FilemapProt); -** addr = PR_MemMap(fm); -** attr = PR_NewProcessAttr(); -** PR_ProcessAttrSetInheritableFileMap( attr, fm, shmname ); -** PR_CreateProcess(Client); -** PR_DestroyProcessAttr(attr); -** ... yadda ... -** PR_MemUnmap( addr ); -** PR_CloseFileMap(fm); -** -** -** Client: -** ... started by server via PR_CreateProcess() -** fm = PR_GetInheritedFileMap( shmname ); -** addr = PR_MemMap(fm); -** ... yadda ... -** PR_MemUnmap(addr); -** PR_CloseFileMap(fm); -** -** -** Second Protocol: -** Server: -** -** fm = PR_OpenAnonFileMap(dirName, size, FilemapProt); -** fmstring = PR_ExportFileMapAsString( fm ); -** addr = PR_MemMap(fm); -** ... application specific technique to pass fmstring to child -** ... yadda ... Server uses his own magic to create child -** PR_MemUnmap( addr ); -** PR_CloseFileMap(fm); -** -** -** Client: -** ... started by server via his own magic -** ... application specific technique to find fmstring from parent -** fm = PR_ImportFileMapFromString( fmstring ) -** addr = PR_MemMap(fm); -** ... yadda ... -** PR_MemUnmap(addr); -** PR_CloseFileMap(fm); -** -** -** lth. 2-Jul-1999. -** -** Note: The second protocol was requested by NelsonB (7/1999); this is -** to accomodate servers which already create their own child processes -** using platform native methods. -** -*/ - -#ifndef prshma_h___ -#define prshma_h___ - -#include "prtypes.h" -#include "prio.h" -#include "prproces.h" - -PR_BEGIN_EXTERN_C - -/* -** PR_OpenAnonFileMap() -- Creates an anonymous file-mapped shared memory -** -** Description: -** PR_OpenAnonFileMap() creates an anonymous shared memory. If the -** shared memory already exists, a handle is returned to that shared -** memory object. -** -** On Unix platforms, PR_OpenAnonFileMap() uses 'dirName' as a -** directory name, without the trailing '/', to contain the anonymous -** file. A filename is generated for the name. -** -** On Windows platforms, dirName is ignored. -** -** Inputs: -** dirName -- A directory name to contain the anonymous file. -** size -- The size of the shared memory -** prot -- How the shared memory is mapped. See prio.h -** -** Outputs: -** PRFileMap * -** -** Returns: -** Pointer to PRFileMap or NULL on error. -** -*/ -NSPR_API( PRFileMap *) -PR_OpenAnonFileMap( - const char *dirName, - PRSize size, - PRFileMapProtect prot -); - -/* -** PR_ProcessAttrSetInheritableFileMap() -- Prepare FileMap for export -** to my children processes via PR_CreateProcess() -** -** Description: -** PR_ProcessAttrSetInheritableFileMap() connects the PRFileMap to -** PRProcessAttr with shmname. A subsequent call to PR_CreateProcess() -** makes the PRFileMap importable by the child process. -** -** Inputs: -** attr -- PRProcessAttr, used to pass data to PR_CreateProcess() -** fm -- PRFileMap structure to be passed to the child process -** shmname -- The name for the PRFileMap; used by child. -** -** Outputs: -** PRFileMap * -** -** Returns: -** PRStatus -** -*/ -NSPR_API(PRStatus) -PR_ProcessAttrSetInheritableFileMap( - PRProcessAttr *attr, - PRFileMap *fm, - const char *shmname -); - -/* -** PR_GetInheritedFileMap() -- Import a PRFileMap previously exported -** by my parent process via PR_CreateProcess() -** -** Description: -** PR_GetInheritedFileMap() retrieves a PRFileMap object exported from -** its parent process via PR_CreateProcess(). -** -** Inputs: -** shmname -- The name provided to PR_ProcessAttrSetInheritableFileMap() -** -** Outputs: -** PRFileMap * -** -** Returns: -** PRFileMap pointer or NULL. -** -*/ -NSPR_API( PRFileMap *) -PR_GetInheritedFileMap( - const char *shmname -); - -/* -** PR_ExportFileMapAsString() -- Creates a string identifying a PRFileMap -** -** Description: -** Creates an identifier, as a string, from a PRFileMap object -** previously created with PR_OpenAnonFileMap(). -** -** Inputs: -** fm -- PRFileMap pointer to be represented as a string. -** bufsize -- sizeof(buf) -** buf -- a buffer of length PR_FILEMAP_STRING_BUFSIZE -** -** Outputs: -** buf contains the stringized PRFileMap identifier -** -** Returns: -** PRStatus -** -*/ -NSPR_API( PRStatus ) -PR_ExportFileMapAsString( - PRFileMap *fm, - PRSize bufsize, - char *buf -); -#define PR_FILEMAP_STRING_BUFSIZE 128 - -/* -** PR_ImportFileMapFromString() -- Creates a PRFileMap from the identifying string -** -** Description: -** PR_ImportFileMapFromString() creates a PRFileMap object from a -** string previously created by PR_ExportFileMapAsString(). -** -** Inputs: -** fmstring -- string created by PR_ExportFileMapAsString() -** -** Returns: -** PRFileMap pointer or NULL. -** -*/ -NSPR_API( PRFileMap * ) -PR_ImportFileMapFromString( - const char *fmstring -); - -PR_END_EXTERN_C -#endif /* prshma_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prshm.h nspr-4.10.7/mozilla/nsprpub/pr/include/prshm.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prshm.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prshm.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,257 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** prshm.h -- NSPR Shared Memory -** -** NSPR Named Shared Memory API provides a cross-platform named -** shared-memory interface. NSPR Named Shared Memory is modeled on -** similar constructs in Unix and Windows operating systems. Shared -** memory allows multiple processes to access one or more common shared -** memory regions, using it as an inter-process communication channel. -** -** Notes on Platform Independence: -** NSPR Named Shared Memory is built on the native services offered -** by most platforms. The NSPR Named Shared Memory API tries to -** provide a least common denominator interface so that it works -** across all supported platforms. To ensure that it works everywhere, -** some platform considerations must be accomodated and the protocol -** for using NSPR Shared Memory API must be observed. -** -** Protocol: -** Multiple shared memories can be created using NSPR's Shared Memory -** feature. For each named shared memory, as defined by the name -** given in the PR_OpenSharedMemory() call, a protocol for using the -** shared memory API is required to ensure desired behavior. Failing -** to follow the protocol may yield unpredictable results. -** -** PR_OpenSharedMemory() will create the shared memory segment, if it -** does not already exist, or open a connection that the existing -** shared memory segment if it already exists. -** -** PR_AttachSharedMemory() should be called following -** PR_OpenSharedMemory() to map the memory segment to an address in -** the application's address space. -** -** PR_AttachSharedMemory() may be called to re-map a shared memory -** segment after detaching the same PRSharedMemory object. Be -** sure to detach it when done. -** -** PR_DetachSharedMemory() should be called to un-map the shared -** memory segment from the application's address space. -** -** PR_CloseSharedMemory() should be called when no further use of the -** PRSharedMemory object is required within a process. Following a -** call to PR_CloseSharedMemory() the PRSharedMemory object is -** invalid and cannot be reused. -** -** PR_DeleteSharedMemory() should be called before process -** termination. After calling PR_DeleteSharedMemory() any further use -** of the shared memory associated with the name may cause -** unpredictable results. -** -** Files: -** The name passed to PR_OpenSharedMemory() should be a valid filename -** for a unix platform. PR_OpenSharedMemory() creates file using the -** name passed in. Some platforms may mangle the name before creating -** the file and the shared memory. -** -** The unix implementation may use SysV IPC shared memory, Posix -** shared memory, or memory mapped files; the filename may used to -** define the namespace. On Windows, the name is significant, but -** there is no file associated with name. -** -** No assumptions about the persistence of data in the named file -** should be made. Depending on platform, the shared memory may be -** mapped onto system paging space and be discarded at process -** termination. -** -** All names provided to PR_OpenSharedMemory() should be valid -** filename syntax or name syntax for shared memory for the target -** platform. Referenced directories should have permissions -** appropriate for writing. -** -** Limits: -** Different platforms have limits on both the number and size of -** shared memory resources. The default system limits on some -** platforms may be smaller than your requirements. These limits may -** be adjusted on some platforms either via boot-time options or by -** setting the size of the system paging space to accomodate more -** and/or larger shared memory segment(s). -** -** Security: -** On unix platforms, depending on implementation, contents of the -** backing store for the shared memory can be exposed via the file -** system. Set permissions and or access controls at create and attach -** time to ensure you get the desired security. -** -** On windows platforms, no special security measures are provided. -** -** Example: -** The test case pr/tests/nameshm1.c provides an example of use as -** well as testing the operation of NSPR's Named Shared Memory. -** -** lth. 18-Aug-1999. -*/ - -#ifndef prshm_h___ -#define prshm_h___ - -#include "prtypes.h" -#include "prio.h" - -PR_BEGIN_EXTERN_C - -/* -** Declare opaque type PRSharedMemory. -*/ -typedef struct PRSharedMemory PRSharedMemory; - -/* -** FUNCTION: PR_OpenSharedMemory() -** -** DESCRIPTION: -** PR_OpenSharedMemory() creates a new shared-memory segment or -** associates a previously created memory segment with name. -** -** When parameter create is (PR_SHM_EXCL | PR_SHM_CREATE) and the -** shared memory already exists, the function returns NULL with the -** error set to PR_FILE_EXISTS_ERROR. -** -** When parameter create is PR_SHM_CREATE and the shared memory -** already exists, a handle to that memory segment is returned. If -** the segment does not exist, it is created and a pointer to the -** related PRSharedMemory structure is returned. -** -** When parameter create is 0, and the shared memory exists, a -** pointer to a PRSharedMemory is returned. If the shared memory does -** not exist, NULL is returned with the error set to -** PR_FILE_NOT_FOUND_ERROR. -** -** INPUTS: -** name -- the name the shared-memory segment is known as. -** size -- the size of the shared memory segment. -** flags -- Options for creating the shared memory -** mode -- Same as is passed to PR_Open() -** -** OUTPUTS: -** The shared memory is allocated. -** -** RETURNS: Pointer to opaque structure PRSharedMemory or NULL. -** NULL is returned on error. The reason for the error can be -** retrieved via PR_GetError() and PR_GetOSError(); -** -*/ -NSPR_API( PRSharedMemory * ) - PR_OpenSharedMemory( - const char *name, - PRSize size, - PRIntn flags, - PRIntn mode -); -/* Define values for PR_OpenShareMemory(...,create) */ -#define PR_SHM_CREATE 0x1 /* create if not exist */ -#define PR_SHM_EXCL 0x2 /* fail if already exists */ - -/* -** FUNCTION: PR_AttachSharedMemory() -** -** DESCRIPTION: -** PR_AttachSharedMemory() maps the shared-memory described by -** shm to the current process. -** -** INPUTS: -** shm -- The handle returned from PR_OpenSharedMemory(). -** flags -- options for mapping the shared memory. -** PR_SHM_READONLY causes the memory to be attached -** read-only. -** -** OUTPUTS: -** On success, the shared memory segment represented by shm is mapped -** into the process' address space. -** -** RETURNS: Address where shared memory is mapped, or NULL. -** NULL is returned on error. The reason for the error can be -** retrieved via PR_GetError() and PR_GetOSError(); -** -** -*/ -NSPR_API( void * ) - PR_AttachSharedMemory( - PRSharedMemory *shm, - PRIntn flags -); -/* Define values for PR_AttachSharedMemory(...,flags) */ -#define PR_SHM_READONLY 0x01 - -/* -** FUNCTION: PR_DetachSharedMemory() -** -** DESCRIPTION: -** PR_DetachSharedMemory() detaches the shared-memory described -** by shm. -** -** INPUTS: -** shm -- The handle returned from PR_OpenSharedMemory(). -** addr -- The address at which the memory was attached. -** -** OUTPUTS: -** The shared memory mapped to an address via a previous call to -** PR_AttachSharedMemory() is unmapped. -** -** RETURNS: PRStatus -** -*/ -NSPR_API( PRStatus ) - PR_DetachSharedMemory( - PRSharedMemory *shm, - void *addr -); - -/* -** FUNCTION: PR_CloseSharedMemory() -** -** DESCRIPTION: -** PR_CloseSharedMemory() closes the shared-memory described by -** shm. -** -** INPUTS: -** shm -- The handle returned from PR_OpenSharedMemory(). -** -** OUTPUTS: -** the shared memory represented by shm is closed -** -** RETURNS: PRStatus -** -*/ -NSPR_API( PRStatus ) - PR_CloseSharedMemory( - PRSharedMemory *shm -); - -/* -** FUNCTION: PR_DeleteSharedMemory() -** -** DESCRIPTION: -** The shared memory resource represented by name is released. -** -** INPUTS: -** name -- the name the shared-memory segment -** -** OUTPUTS: -** depending on platform, resources may be returned to the underlying -** operating system. -** -** RETURNS: PRStatus -** -*/ -NSPR_API( PRStatus ) - PR_DeleteSharedMemory( - const char *name -); - -PR_END_EXTERN_C - -#endif /* prshm_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prsystem.h nspr-4.10.7/mozilla/nsprpub/pr/include/prsystem.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prsystem.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prsystem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prsystem_h___ -#define prsystem_h___ - -/* -** API to NSPR functions returning system info. -*/ -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* -** Get the host' directory separator. -** Pathnames are then assumed to be of the form: -** []*() -*/ - -NSPR_API(char) PR_GetDirectorySeparator(void); - -/* -** OBSOLETE -- the function name is misspelled. -** Use PR_GetDirectorySeparator instead. -*/ - -NSPR_API(char) PR_GetDirectorySepartor(void); - -/* -** Get the host' path separator. -** Paths are assumed to be of the form: -** []* -*/ - -NSPR_API(char) PR_GetPathSeparator(void); - -/* Types of information available via PR_GetSystemInfo(...) */ -typedef enum { - PR_SI_HOSTNAME, /* the hostname with the domain name (if any) - * removed */ - PR_SI_SYSNAME, - PR_SI_RELEASE, - PR_SI_ARCHITECTURE, - PR_SI_HOSTNAME_UNTRUNCATED /* the hostname exactly as configured - * on the system */ -} PRSysInfo; - - -/* -** If successful returns a null termintated string in 'buf' for -** the information indicated in 'cmd'. If unseccussful the reason for -** the failure can be retrieved from PR_GetError(). -** -** The buffer is allocated by the caller and should be at least -** SYS_INFO_BUFFER_LENGTH bytes in length. -*/ - -#define SYS_INFO_BUFFER_LENGTH 256 - -NSPR_API(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen); - -/* -** Return the number of bytes in a page -*/ -NSPR_API(PRInt32) PR_GetPageSize(void); - -/* -** Return log2 of the size of a page -*/ -NSPR_API(PRInt32) PR_GetPageShift(void); - -/* -** PR_GetNumberOfProcessors() -- returns the number of CPUs -** -** Description: -** PR_GetNumberOfProcessors() extracts the number of processors -** (CPUs available in an SMP system) and returns the number. -** -** Parameters: -** none -** -** Returns: -** The number of available processors or -1 on error -** -*/ -NSPR_API(PRInt32) PR_GetNumberOfProcessors( void ); - -/* -** PR_GetPhysicalMemorySize() -- returns the amount of system RAM -** -** Description: -** PR_GetPhysicalMemorySize() determines the amount of physical RAM -** in the system and returns the size in bytes. -** -** Parameters: -** none -** -** Returns: -** The amount of system RAM, or 0 on failure. -** -*/ -NSPR_API(PRUint64) PR_GetPhysicalMemorySize(void); - -PR_END_EXTERN_C - -#endif /* prsystem_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prthread.h nspr-4.10.7/mozilla/nsprpub/pr/include/prthread.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prthread.h 2012-06-06 23:22:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prthread.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,265 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prthread_h___ -#define prthread_h___ - -/* -** API for NSPR threads. On some architectures (Mac OS Classic -** notably) pre-emptibility is not guaranteed. Hard priority scheduling -** is not guaranteed, so programming using priority based synchronization -** is a no-no. -** -** NSPR threads are scheduled based loosely on their client set priority. -** In general, a thread of a higher priority has a statistically better -** chance of running relative to threads of lower priority. However, -** NSPR uses multiple strategies to provide execution vehicles for thread -** abstraction of various host platforms. As it turns out, there is little -** NSPR can do to affect the scheduling attributes of "GLOBAL" threads. -** However, a semblance of GLOBAL threads is used to implement "LOCAL" -** threads. An arbitrary number of such LOCAL threads can be assigned to -** a single GLOBAL thread. -** -** For scheduling, NSPR will attempt to run the highest priority LOCAL -** thread associated with a given GLOBAL thread. It is further assumed -** that the host OS will apply some form of "fair" scheduling on the -** GLOBAL threads. -** -** Threads have a "system flag" which when set indicates the thread -** doesn't count for determining when the process should exit (the -** process exits when the last user thread exits). -** -** Threads also have a "scope flag" which controls whether the threads -** are scheduled in the local scope or scheduled by the OS globally. This -** indicates whether a thread is permanently bound to a native OS thread. -** An unbound thread competes for scheduling resources in the same process. -** -** Another flag is "state flag" which control whether the thread is joinable. -** It allows other threads to wait for the created thread to reach completion. -** -** Threads can have "per-thread-data" attached to them. Each thread has a -** per-thread error number and error string which are updated when NSPR -** operations fail. -*/ -#include "prtypes.h" -#include "prinrval.h" - -PR_BEGIN_EXTERN_C - -typedef struct PRThread PRThread; -typedef struct PRThreadStack PRThreadStack; - -typedef enum PRThreadType { - PR_USER_THREAD, - PR_SYSTEM_THREAD -} PRThreadType; - -typedef enum PRThreadScope { - PR_LOCAL_THREAD, - PR_GLOBAL_THREAD, - PR_GLOBAL_BOUND_THREAD -} PRThreadScope; - -typedef enum PRThreadState { - PR_JOINABLE_THREAD, - PR_UNJOINABLE_THREAD -} PRThreadState; - -typedef enum PRThreadPriority -{ - PR_PRIORITY_FIRST = 0, /* just a placeholder */ - PR_PRIORITY_LOW = 0, /* the lowest possible priority */ - PR_PRIORITY_NORMAL = 1, /* most common expected priority */ - PR_PRIORITY_HIGH = 2, /* slightly more aggressive scheduling */ - PR_PRIORITY_URGENT = 3, /* it does little good to have more than one */ - PR_PRIORITY_LAST = 3 /* this is just a placeholder */ -} PRThreadPriority; - -/* -** Create a new thread: -** "type" is the type of thread to create -** "start(arg)" will be invoked as the threads "main" -** "priority" will be created thread's priority -** "scope" will specify whether the thread is local or global -** "state" will specify whether the thread is joinable or not -** "stackSize" the size of the stack, in bytes. The value can be zero -** and then a machine specific stack size will be chosen. -** -** This can return NULL if some kind of error occurs, such as if memory is -** tight. -** -** If you want the thread to start up waiting for the creator to do -** something, enter a lock before creating the thread and then have the -** threads start routine enter and exit the same lock. When you are ready -** for the thread to run, exit the lock. -** -** If you want to detect the completion of the created thread, the thread -** should be created joinable. Then, use PR_JoinThread to synchrnoize the -** termination of another thread. -** -** When the start function returns the thread exits. If it is the last -** PR_USER_THREAD to exit then the process exits. -*/ -NSPR_API(PRThread*) PR_CreateThread(PRThreadType type, - void (PR_CALLBACK *start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize); - -/* -** Wait for thread termination: -** "thread" is the target thread -** -** This can return PR_FAILURE if no joinable thread could be found -** corresponding to the specified target thread. -** -** The calling thread is blocked until the target thread completes. -** Several threads cannot wait for the same thread to complete; one thread -** will operate successfully and others will terminate with an error PR_FAILURE. -** The calling thread will not be blocked if the target thread has already -** terminated. -*/ -NSPR_API(PRStatus) PR_JoinThread(PRThread *thread); - -/* -** Return the current thread object for the currently running code. -** Never returns NULL. -*/ -NSPR_API(PRThread*) PR_GetCurrentThread(void); -#ifndef NO_NSPR_10_SUPPORT -#define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */ -#endif /* NO_NSPR_10_SUPPORT */ - -/* -** Get the priority of "thread". -*/ -NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread); - -/* -** Change the priority of the "thread" to "priority". -*/ -NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority); - -/* -** Set the name of the current thread, which will be visible in a debugger -** and accessible via a call to PR_GetThreadName(). -*/ -NSPR_API(PRStatus) PR_SetCurrentThreadName(const char *name); - -/* -** Return the name of "thread", if set. Otherwise return NULL. -*/ -NSPR_API(const char *) PR_GetThreadName(const PRThread *thread); - -/* -** This routine returns a new index for per-thread-private data table. -** The index is visible to all threads within a process. This index can -** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines -** to save and retrieve data associated with the index for a thread. -** -** Each index is associationed with a destructor function ('dtor'). The function -** may be specified as NULL when the index is created. If it is not NULL, the -** function will be called when: -** - the thread exits and the private data for the associated index -** is not NULL, -** - new thread private data is set and the current private data is -** not NULL. -** -** The index independently maintains specific values for each binding thread. -** A thread can only get access to its own thread-specific-data. -** -** Upon a new index return the value associated with the index for all threads -** is NULL, and upon thread creation the value associated with all indices for -** that thread is NULL. -** -** Returns PR_FAILURE if the total number of indices will exceed the maximun -** allowed. -*/ -typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv); - -NSPR_API(PRStatus) PR_NewThreadPrivateIndex( - PRUintn *newIndex, PRThreadPrivateDTOR destructor); - -/* -** Define some per-thread-private data. -** "tpdIndex" is an index into the per-thread private data table -** "priv" is the per-thread-private data -** -** If the per-thread private data table has a previously registered -** destructor function and a non-NULL per-thread-private data value, -** the destructor function is invoked. -** -** This can return PR_FAILURE if the index is invalid. -*/ -NSPR_API(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv); - -/* -** Recover the per-thread-private data for the current thread. "tpdIndex" is -** the index into the per-thread private data table. -** -** The returned value may be NULL which is indistinguishable from an error -** condition. -** -** A thread can only get access to its own thread-specific-data. -*/ -NSPR_API(void*) PR_GetThreadPrivate(PRUintn tpdIndex); - -/* -** This routine sets the interrupt request for a target thread. The interrupt -** request remains in the thread's state until it is delivered exactly once -** or explicitly canceled. -** -** A thread that has been interrupted will fail all NSPR blocking operations -** that return a PRStatus (I/O, waiting on a condition, etc). -** -** PR_Interrupt may itself fail if the target thread is invalid. -*/ -NSPR_API(PRStatus) PR_Interrupt(PRThread *thread); - -/* -** Clear the interrupt request for the calling thread. If no such request -** is pending, this operation is a noop. -*/ -NSPR_API(void) PR_ClearInterrupt(void); - -/* -** Block the interrupt for the calling thread. -*/ -NSPR_API(void) PR_BlockInterrupt(void); - -/* -** Unblock the interrupt for the calling thread. -*/ -NSPR_API(void) PR_UnblockInterrupt(void); - -/* -** Make the current thread sleep until "ticks" time amount of time -** has expired. If "ticks" is PR_INTERVAL_NO_WAIT then the call is -** equivalent to calling PR_Yield. Calling PR_Sleep with an argument -** equivalent to PR_INTERVAL_NO_TIMEOUT is an error and will result -** in a PR_FAILURE error return. -*/ -NSPR_API(PRStatus) PR_Sleep(PRIntervalTime ticks); - -/* -** Get the scoping of this thread. -*/ -NSPR_API(PRThreadScope) PR_GetThreadScope(const PRThread *thread); - -/* -** Get the type of this thread. -*/ -NSPR_API(PRThreadType) PR_GetThreadType(const PRThread *thread); - -/* -** Get the join state of this thread. -*/ -NSPR_API(PRThreadState) PR_GetThreadState(const PRThread *thread); - -PR_END_EXTERN_C - -#endif /* prthread_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prtime.h nspr-4.10.7/mozilla/nsprpub/pr/include/prtime.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prtime.h 2012-10-23 23:35:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prtime.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,262 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - *---------------------------------------------------------------------- - * - * prtime.h -- - * - * NSPR date and time functions - * - *----------------------------------------------------------------------- - */ - -#ifndef prtime_h___ -#define prtime_h___ - -#include "prlong.h" - -PR_BEGIN_EXTERN_C - -/**********************************************************************/ -/************************* TYPES AND CONSTANTS ************************/ -/**********************************************************************/ - -#define PR_MSEC_PER_SEC 1000L -#define PR_USEC_PER_SEC 1000000L -#define PR_NSEC_PER_SEC 1000000000L -#define PR_USEC_PER_MSEC 1000L -#define PR_NSEC_PER_MSEC 1000000L - -/* - * PRTime -- - * - * NSPR represents basic time as 64-bit signed integers relative - * to midnight (00:00:00), January 1, 1970 Greenwich Mean Time (GMT). - * (GMT is also known as Coordinated Universal Time, UTC.) - * The units of time are in microseconds. Negative times are allowed - * to represent times prior to the January 1970 epoch. Such values are - * intended to be exported to other systems or converted to human - * readable form. - * - * Notes on porting: PRTime corresponds to time_t in ANSI C. NSPR 1.0 - * simply uses PRInt64. - */ - -typedef PRInt64 PRTime; - -/* - * Time zone and daylight saving time corrections applied to GMT to - * obtain the local time of some geographic location - */ - -typedef struct PRTimeParameters { - PRInt32 tp_gmt_offset; /* the offset from GMT in seconds */ - PRInt32 tp_dst_offset; /* contribution of DST in seconds */ -} PRTimeParameters; - -/* - * PRExplodedTime -- - * - * Time broken down into human-readable components such as year, month, - * day, hour, minute, second, and microsecond. Time zone and daylight - * saving time corrections may be applied. If they are applied, the - * offsets from the GMT must be saved in the 'tm_params' field so that - * all the information is available to reconstruct GMT. - * - * Notes on porting: PRExplodedTime corrresponds to struct tm in - * ANSI C, with the following differences: - * - an additional field tm_usec; - * - replacing tm_isdst by tm_params; - * - the month field is spelled tm_month, not tm_mon; - * - we use absolute year, AD, not the year since 1900. - * The corresponding type in NSPR 1.0 is called PRTime. Below is - * a table of date/time type correspondence in the three APIs: - * API time since epoch time in components - * ANSI C time_t struct tm - * NSPR 1.0 PRInt64 PRTime - * NSPR 2.0 PRTime PRExplodedTime - */ - -typedef struct PRExplodedTime { - PRInt32 tm_usec; /* microseconds past tm_sec (0-99999) */ - PRInt32 tm_sec; /* seconds past tm_min (0-61, accomodating - up to two leap seconds) */ - PRInt32 tm_min; /* minutes past tm_hour (0-59) */ - PRInt32 tm_hour; /* hours past tm_day (0-23) */ - PRInt32 tm_mday; /* days past tm_mon (1-31, note that it - starts from 1) */ - PRInt32 tm_month; /* months past tm_year (0-11, Jan = 0) */ - PRInt16 tm_year; /* absolute year, AD (note that we do not - count from 1900) */ - - PRInt8 tm_wday; /* calculated day of the week - (0-6, Sun = 0) */ - PRInt16 tm_yday; /* calculated day of the year - (0-365, Jan 1 = 0) */ - - PRTimeParameters tm_params; /* time parameters used by conversion */ -} PRExplodedTime; - -/* - * PRTimeParamFn -- - * - * A function of PRTimeParamFn type returns the time zone and - * daylight saving time corrections for some geographic location, - * given the current time in GMT. The input argument gmt should - * point to a PRExplodedTime that is in GMT, i.e., whose - * tm_params contains all 0's. - * - * For any time zone other than GMT, the computation is intended to - * consist of two steps: - * - Figure out the time zone correction, tp_gmt_offset. This number - * usually depends on the geographic location only. But it may - * also depend on the current time. For example, all of China - * is one time zone right now. But this situation may change - * in the future. - * - Figure out the daylight saving time correction, tp_dst_offset. - * This number depends on both the geographic location and the - * current time. Most of the DST rules are expressed in local - * current time. If so, one should apply the time zone correction - * to GMT before applying the DST rules. - */ - -typedef PRTimeParameters (PR_CALLBACK *PRTimeParamFn)(const PRExplodedTime *gmt); - -/**********************************************************************/ -/****************************** FUNCTIONS *****************************/ -/**********************************************************************/ - -/* - * The PR_Now routine returns the current time relative to the - * epoch, midnight, January 1, 1970 UTC. The units of the returned - * value are microseconds since the epoch. - * - * The values returned are not guaranteed to advance in a linear fashion - * due to the application of time correction protocols which synchronize - * computer clocks to some external time source. Consequently it should - * not be depended on for interval timing. - * - * The implementation is machine dependent. - * Cf. time_t time(time_t *tp) in ANSI C. - */ -NSPR_API(PRTime) -PR_Now(void); - -/* - * Expand time binding it to time parameters provided by PRTimeParamFn. - * The calculation is envisoned to proceed in the following steps: - * - From given PRTime, calculate PRExplodedTime in GMT - * - Apply the given PRTimeParamFn to the GMT that we just calculated - * to obtain PRTimeParameters. - * - Add the PRTimeParameters offsets to GMT to get the local time - * as PRExplodedTime. - */ - -NSPR_API(void) PR_ExplodeTime( - PRTime usecs, PRTimeParamFn params, PRExplodedTime *exploded); - -/* Reverse operation of PR_ExplodeTime */ -NSPR_API(PRTime) -PR_ImplodeTime(const PRExplodedTime *exploded); - -/* - * Adjust exploded time to normalize field overflows after manipulation. - * Note that the following fields of PRExplodedTime should not be - * manipulated: - * - tm_month and tm_year: because the number of days in a month and - * number of days in a year are not constant, it is ambiguous to - * manipulate the month and year fields, although one may be tempted - * to. For example, what does "a month from January 31st" mean? - * - tm_wday and tm_yday: these fields are calculated by NSPR. Users - * should treat them as "read-only". - */ - -NSPR_API(void) PR_NormalizeTime( - PRExplodedTime *exploded, PRTimeParamFn params); - -/**********************************************************************/ -/*********************** TIME PARAMETER FUNCTIONS *********************/ -/**********************************************************************/ - -/* Time parameters that suit current host machine */ -NSPR_API(PRTimeParameters) PR_LocalTimeParameters(const PRExplodedTime *gmt); - -/* Time parameters that represent Greenwich Mean Time */ -NSPR_API(PRTimeParameters) PR_GMTParameters(const PRExplodedTime *gmt); - -/* - * Time parameters that represent the US Pacific Time Zone, with the - * current daylight saving time rules (for testing only) - */ -NSPR_API(PRTimeParameters) PR_USPacificTimeParameters(const PRExplodedTime *gmt); - -/* - * This parses a time/date string into a PRExplodedTime - * struct. It populates all fields but it can't split - * the offset from UTC into tp_gmt_offset and tp_dst_offset in - * most cases (exceptions: PST/PDT, MST/MDT, CST/CDT, EST/EDT, GMT/BST). - * In those cases tp_gmt_offset will be the sum of these two and - * tp_dst_offset will be 0. - * It returns PR_SUCCESS on success, and PR_FAILURE - * if the time/date string can't be parsed. - * - * Many formats are handled, including: - * - * 14 Apr 89 03:20:12 - * 14 Apr 89 03:20 GMT - * Fri, 17 Mar 89 4:01:33 - * Fri, 17 Mar 89 4:01 GMT - * Mon Jan 16 16:12 PDT 1989 - * Mon Jan 16 16:12 +0130 1989 - * 6 May 1992 16:41-JST (Wednesday) - * 22-AUG-1993 10:59:12.82 - * 22-AUG-1993 10:59pm - * 22-AUG-1993 12:59am - * 22-AUG-1993 12:59 PM - * Friday, August 04, 1995 3:54 PM - * 06/21/95 04:24:34 PM - * 20/06/95 21:07 - * 95-06-08 19:32:48 EDT - * - * If the input string doesn't contain a description of the timezone, - * we consult the `default_to_gmt' to decide whether the string should - * be interpreted relative to the local time zone (PR_FALSE) or GMT (PR_TRUE). - * The correct value for this argument depends on what standard specified - * the time string which you are parsing. - */ - -NSPR_API(PRStatus) PR_ParseTimeStringToExplodedTime ( - const char *string, - PRBool default_to_gmt, - PRExplodedTime *result); - -/* - * This uses PR_ParseTimeStringToExplodedTime to parse - * a time/date string and PR_ImplodeTime to transform it into - * a PRTime (microseconds after "1-Jan-1970 00:00:00 GMT"). - * It returns PR_SUCCESS on success, and PR_FAILURE - * if the time/date string can't be parsed. - */ - -NSPR_API(PRStatus) PR_ParseTimeString ( - const char *string, - PRBool default_to_gmt, - PRTime *result); - -/* Format a time value into a buffer. Same semantics as strftime() */ -NSPR_API(PRUint32) PR_FormatTime(char *buf, int buflen, const char *fmt, - const PRExplodedTime *tm); - -/* Format a time value into a buffer. Time is always in US English format, regardless - * of locale setting. - */ -NSPR_API(PRUint32) -PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize, - const char* format, const PRExplodedTime* tm ); - -PR_END_EXTERN_C - -#endif /* prtime_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prtpool.h nspr-4.10.7/mozilla/nsprpub/pr/include/prtpool.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prtpool.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prtpool.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prtpool_h___ -#define prtpool_h___ - -#include "prtypes.h" -#include "prthread.h" -#include "prio.h" -#include "prerror.h" - -/* - * NOTE: - * THIS API IS A PRELIMINARY VERSION IN NSPR 4.0 AND IS SUBJECT TO - * CHANGE - */ - -PR_BEGIN_EXTERN_C - -typedef struct PRJobIoDesc { - PRFileDesc *socket; - PRErrorCode error; - PRIntervalTime timeout; -} PRJobIoDesc; - -typedef struct PRThreadPool PRThreadPool; -typedef struct PRJob PRJob; -typedef void (PR_CALLBACK *PRJobFn) (void *arg); - -/* Create thread pool */ -NSPR_API(PRThreadPool *) -PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads, - PRUint32 stacksize); - -/* queue a job */ -NSPR_API(PRJob *) -PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable); - -/* queue a job, when a socket is readable */ -NSPR_API(PRJob *) -PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, - PRJobFn fn, void * arg, PRBool joinable); - -/* queue a job, when a socket is writeable */ -NSPR_API(PRJob *) -PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, - PRJobFn fn, void * arg, PRBool joinable); - -/* queue a job, when a socket has a pending connection */ -NSPR_API(PRJob *) -PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, - PRJobFn fn, void * arg, PRBool joinable); - -/* queue a job, when the socket connection to addr succeeds or fails */ -NSPR_API(PRJob *) -PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod, - const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable); - -/* queue a job, when a timer exipres */ -NSPR_API(PRJob *) -PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout, - PRJobFn fn, void * arg, PRBool joinable); -/* cancel a job */ -NSPR_API(PRStatus) -PR_CancelJob(PRJob *job); - -/* join a job */ -NSPR_API(PRStatus) -PR_JoinJob(PRJob *job); - -/* shutdown pool */ -NSPR_API(PRStatus) -PR_ShutdownThreadPool(PRThreadPool *tpool); - -/* join pool, wait for exit of all threads */ -NSPR_API(PRStatus) -PR_JoinThreadPool(PRThreadPool *tpool); - -PR_END_EXTERN_C - -#endif /* prtpool_h___ */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prtrace.h nspr-4.10.7/mozilla/nsprpub/pr/include/prtrace.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prtrace.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prtrace.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,646 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prtrace_h___ -#define prtrace_h___ -/* -** prtrace.h -- NSPR's Trace Facility. -** -** The Trace Facility provides a means to trace application -** program events within a process. When implementing an -** application program an engineer may insert a "Trace" function -** call, passing arguments to be traced. The "Trace" function -** combines the user trace data with identifying data and -** writes this data in time ordered sequence into a circular -** in-memory buffer; when the buffer fills, it wraps. -** -** Functions are provided to set and/or re-configure the size of -** the trace buffer, control what events are recorded in the -** buffer, enable and disable tracing based on specific user -** supplied data and other control functions. Methods are provided -** to record the trace entries in the in-memory trace buffer to -** a file. -** -** Tracing may cause a performance degredation to the application -** depending on the number and placement of calls to the tracing -** facility. When tracing is compiled in and all tracing is -** disabled via the runtime controls, the overhead should be -** minimal. ... Famous last words, eh? -** -** When DEBUG is defined at compile time, the Trace Facility is -** compiled as part of NSPR and any application using NSPR's -** header files will have tracing compiled in. When DEBUG is not -** defined, the Trace Facility is not compiled into NSPR nor -** exported in its header files. If the Trace Facility is -** desired in a non-debug build, then FORCE_NSPR_TRACE may be -** defined at compile time for both the optimized build of NSPR -** and the application. NSPR and any application using NSPR's -** Trace Facility must be compiled with the same level of trace -** conditioning or unresolved references may be realized at link -** time. -** -** For any of the Trace Facility methods that requires a trace -** handle as an input argument, the caller must ensure that the -** trace handle argument is valid. An invalid trace handle -** argument may cause unpredictable results. -** -** Trace Facility methods are thread-safe and SMP safe. -** -** Users of the Trace Facility should use the defined macros to -** invoke trace methods, not the function calls directly. e.g. -** PR_TRACE( h1,0,1,2, ...); not PR_Trace(h1,0,1,2, ...); -** -** Application designers should be aware of the effects of -** debug and optimized build differences when using result of the -** Trace Facility macros in expressions. -** -** See Also: prcountr.h -** -** /lth. 08-Jun-1998. -*/ - -#include "prtypes.h" -#include "prthread.h" -#include "prtime.h" - -PR_BEGIN_EXTERN_C - -/* -** Opaque type for the trace handle -** ... Don't even think about looking in here. -** -*/ -typedef void * PRTraceHandle; - -/* -** PRTraceEntry -- A trace entry in the in-memory trace buffer -** looks like this. -** -*/ -typedef struct PRTraceEntry -{ - PRThread *thread; /* The thread creating the trace entry */ - PRTraceHandle handle; /* PRTraceHandle creating the trace entry */ - PRTime time; /* Value of PR_Now() at time of trace entry */ - PRUint32 userData[8]; /* user supplied trace data */ -} PRTraceEntry; - -/* -** PRTraceOption -- command operands to -** PR_[Set|Get]TraceOption(). See descriptive meanings there. -** -*/ -typedef enum PRTraceOption -{ - PRTraceBufSize, - PRTraceEnable, - PRTraceDisable, - PRTraceSuspend, - PRTraceResume, - PRTraceSuspendRecording, - PRTraceResumeRecording, - PRTraceLockHandles, - PRTraceUnLockHandles, - PRTraceStopRecording -} PRTraceOption; - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_DEFINE_TRACE() -- Define a PRTraceHandle -** -** DESCRIPTION: PR_DEFINE_TRACE() is used to define a trace -** handle. -** -*/ -#define PR_DEFINE_TRACE(name) PRTraceHandle name - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_INIT_TRACE_HANDLE() -- Set the value of a PRTraceHandle -** -** DESCRIPTION: -** PR_INIT_TRACE_HANDLE() sets the value of a PRTraceHandle -** to value. e.g. PR_INIT_TRACE_HANDLE( myHandle, NULL ); -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_INIT_TRACE_HANDLE(handle,value)\ - (handle) = (PRCounterHandle)(value) -#else -#define PR_INIT_TRACE_HANDLE(handle,value) -#endif - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_CreateTrace() -- Create a trace handle -** -** DESCRIPTION: -** PR_CreateTrace() creates a new trace handle. Tracing is -** enabled for this handle when it is created. The trace handle -** is intended for use in other Trace Facility calls. -** -** PR_CreateTrace() registers the QName, RName and description -** data so that this data can be retrieved later. -** -** INPUTS: -** qName: pointer to string. QName for this trace handle. -** -** rName: pointer to string. RName for this trace handle. -** -** description: pointer to string. Descriptive data about this -** trace handle. -** -** OUTPUTS: -** Creates the trace handle. -** Registers the QName and RName with the trace facility. -** -** RETURNS: -** PRTraceHandle -** -** RESTRICTIONS: -** qName is limited to 31 characters. -** rName is limited to 31 characters. -** description is limited to 255 characters. -** -*/ -#define PRTRACE_NAME_MAX 31 -#define PRTRACE_DESC_MAX 255 - -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_CREATE_TRACE(handle,qName,rName,description)\ - (handle) = PR_CreateTrace((qName),(rName),(description)) -#else -#define PR_CREATE_TRACE(handle,qName,rName,description) -#endif - -NSPR_API(PRTraceHandle) - PR_CreateTrace( - const char *qName, /* QName for this trace handle */ - const char *rName, /* RName for this trace handle */ - const char *description /* description for this trace handle */ -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_DestroyTrace() -- Destroy a trace handle -** -** DESCRIPTION: -** PR_DestroyTrace() removes the referenced trace handle and -** associated QName, RName and description data from the Trace -** Facility. -** -** INPUTS: handle. A PRTraceHandle -** -** OUTPUTS: -** The trace handle is unregistered. -** The QName, RName and description are removed. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_DESTROY_TRACE(handle)\ - PR_DestroyTrace((handle)) -#else -#define PR_DESTROY_TRACE(handle) -#endif - -NSPR_API(void) - PR_DestroyTrace( - PRTraceHandle handle /* Handle to be destroyed */ -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_Trace() -- Make a trace entry in the in-memory trace -** -** DESCRIPTION: -** PR_Trace() makes an entry in the in-memory trace buffer for -** the referenced trace handle. The next logically available -** PRTraceEntry is used; when the next trace entry would overflow -** the trace table, the table wraps. -** -** PR_Trace() for a specific trace handle may be disabled by -** calling PR_SetTraceOption() specifying PRTraceDisable for the -** trace handle to be disabled. -** -** INPUTS: -** handle: PRTraceHandle. The trace handle for this trace. -** -** userData[0..7]: unsigned 32bit integers. user supplied data -** that is copied into the PRTraceEntry -** -** OUTPUTS: -** A PRTraceEntry is (conditionally) formatted in the in-memory -** trace buffer. -** -** RETURNS: void. -** -** RESTRICTIONS: -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_TRACE(handle,ud0,ud1,ud2,ud3,ud4,ud5,ud6,ud7)\ - PR_Trace((handle),(ud0),(ud1),(ud2),(ud3),(ud4),(ud5),(ud6),(ud7)) -#else -#define PR_TRACE(handle,ud0,ud1,ud2,ud3,ud4,ud5,ud6,ud7) -#endif - -NSPR_API(void) - PR_Trace( - PRTraceHandle handle, /* use this trace handle */ - PRUint32 userData0, /* User supplied data word 0 */ - PRUint32 userData1, /* User supplied data word 1 */ - PRUint32 userData2, /* User supplied data word 2 */ - PRUint32 userData3, /* User supplied data word 3 */ - PRUint32 userData4, /* User supplied data word 4 */ - PRUint32 userData5, /* User supplied data word 5 */ - PRUint32 userData6, /* User supplied data word 6 */ - PRUint32 userData7 /* User supplied data word 7 */ -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_SetTraceOption() -- Control the Trace Facility -** -** DESCRIPTION: -** PR_SetTraceOption() controls the Trace Facility. Depending on -** command and value, attributes of the Trace Facility may be -** changed. -** -** INPUTS: -** command: An enumerated value in the set of PRTraceOption. -** value: pointer to the data to be set. Type of the data is -** dependent on command; for each value of command, the type -** and meaning of dereferenced value is shown. -** -** PRTraceBufSize: unsigned long: the size of the trace buffer, -** in bytes. -** -** PRTraceEnable: PRTraceHandle. The trace handle to be -** enabled. -** -** PRTraceDisable: PRTraceHandle. The trace handle to be -** disabled. -** -** PRTraceSuspend: void. value must be NULL. All tracing is -** suspended. -** -** PRTraceResume: void. value must be NULL. Tracing for all -** previously enabled, prior to a PRTraceSuspend, is resumed. -** -** PRTraceStopRecording: void. value must be NULL. If recording -** (see: ** PR_RecordTraceEntries()) is being done, -** PRTraceStopRecording causes PR_RecordTraceEntries() to return -** to its caller. If recording is not being done, this function -** has no effect. -** -** PRTraceSuspendRecording: void. Must be NULL. If recording is -** being done, PRTraceSuspendRecording causes further writes to -** the trace file to be suspended. Data in the in-memory -** trace buffer that would ordinarily be written to the -** trace file will not be written. Trace entries will continue -** to be entered in the in-memory buffer. If the Trace Facility -** recording is already in a suspended state, the call has no -** effect. -** -** PRTraceResumeRecording: void. value must be NULL. If -** recording for the Trace Facility has been previously been -** suspended, this causes recording to resume. Recording resumes -** with the next in-memory buffer segment that would be written -** if trace recording had not been suspended. If recording is -** not currently suspended, the call has no effect. -** -** PRTraceLockHandles: void. value must be NULL. Locks the -** trace handle lock. While the trace handle lock is held, -** calls to PR_CreateTrace() will block until the lock is -** released. -** -** PRTraceUnlockHandles: void. value must be NULL. Unlocks the -** trace handle lock. -** -** OUTPUTS: -** The operation of the Trace Facility may be changed. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_SET_TRACE_OPTION(command,value)\ - PR_SetTraceOption((command),(value)) -#else -#define PR_SET_TRACE_OPTION(command,value) -#endif - -NSPR_API(void) - PR_SetTraceOption( - PRTraceOption command, /* One of the enumerated values */ - void *value /* command value or NULL */ -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_GetTraceOption() -- Retrieve settings from the Trace Facility -** -** DESCRIPTION: -** PR_GetTraceOption() retrieves the current setting of the -** Trace Facility control depending on command. -** -** -** PRTraceBufSize: unsigned long: the size of the trace buffer, -** in bytes. -** -** -** INPUTS: -** command: one of the enumerated values in PRTraceOptions -** valid for PR_GetTraceOption(). -** -** OUTPUTS: -** dependent on command. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_GET_TRACE_OPTION(command,value)\ - PR_GetTraceOption((command),(value)) -#else -#define PR_GET_TRACE_OPTION(command,value) -#endif - -NSPR_API(void) - PR_GetTraceOption( - PRTraceOption command, /* One of the enumerated values */ - void *value /* command value or NULL */ -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_GetTraceHandleFromName() -- Retrieve an existing -** handle by name. -** -** DESCRIPTION: -** PR_GetTraceHandleFromName() retreives an existing tracehandle -** using the name specified by qName and rName. -** -** INPUTS: -** qName: pointer to string. QName for this trace handle. -** -** rName: pointer to string. RName for this trace handle. -** -** -** OUTPUTS: returned. -** -** RETURNS: -** PRTraceHandle associated with qName and rName or NULL when -** there is no match. -** -** RESTRICTIONS: -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_GET_TRACE_HANDLE_FROM_NAME(handle,qName,rName)\ - (handle) = PR_GetTraceHandleFromName((qName),(rName)) -#else -#define PR_GET_TRACE_HANDLE_FROM_NAME(handle,qName,rName) -#endif - -NSPR_API(PRTraceHandle) - PR_GetTraceHandleFromName( - const char *qName, /* QName search argument */ - const char *rName /* RName search argument */ -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_GetTraceNameFromHandle() -- Retreive trace name -** by bandle. -** -** DESCRIPTION: -** PR_GetTraceNameFromHandle() retreives the existing qName, -** rName, and description for the referenced trace handle. -** -** INPUTS: handle: PRTraceHandle. -** -** OUTPUTS: pointers to the Trace Facility's copy of qName, -** rName and description. ... Don't mess with these values. -** They're mine. -** -** RETURNS: void -** -** RESTRICTIONS: -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_GET_TRACE_NAME_FROM_HANDLE(handle,qName,rName,description)\ - PR_GetTraceNameFromHandle((handle),(qName),(rName),(description)) -#else -#define PR_GET_TRACE_NAME_FROM_HANDLE(handle,qName,rName,description) -#endif - -NSPR_API(void) - PR_GetTraceNameFromHandle( - PRTraceHandle handle, /* handle as search argument */ - const char **qName, /* pointer to associated QName */ - const char **rName, /* pointer to associated RName */ - const char **description /* pointer to associated description */ -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_FindNextTraceQname() -- Retrieive a QName handle -** iterator. -** -** DESCRIPTION: -** PR_FindNextTraceQname() retreives the first or next trace -** QName handle, depending on the value of handle, from the trace -** database. The PRTraceHandle returned can be used as an -** iterator to traverse the QName handles in the Trace database. -** -** INPUTS: -** handle: When NULL, PR_FindNextQname() returns the first QName -** handle. When a handle is a valid PRTraceHandle previously -** retreived using PR_FindNextQname() the next QName handle is -** retreived. -** -** OUTPUTS: returned. -** -** RETURNS: -** PRTraceHandle or NULL when there are no trace handles. -** -** RESTRICTIONS: -** Iterating thru the trace handles via FindFirst/FindNext -** should be done under protection of the trace handle lock. -** See: PR_SetTraceOption( PRLockTraceHandles ). -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_FIND_NEXT_TRACE_QNAME(next,handle)\ - (next) = PR_FindNextTraceQname((handle)) -#else -#define PR_FIND_NEXT_TRACE_QNAME(next,handle) -#endif - -NSPR_API(PRTraceHandle) - PR_FindNextTraceQname( - PRTraceHandle handle -); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_FindNextTraceRname() -- Retrieive an RName handle -** iterator. -** -** DESCRIPTION: -** PR_FindNextTraceRname() retreives the first or next trace -** RName handle, depending on the value of handle, from the trace -** database. The PRTraceHandle returned can be used as an -** iterator to traverse the RName handles in the Trace database. -** -** INPUTS: -** rhandle: When NULL, PR_FindNextRname() returns the first -** RName handle. When a handle is a valid PRTraceHandle -** previously retreived using PR_FindNextRname() the next RName -** handle is retreived. -** qhandle: A valid PRTraceHandle retruned from a previous call -** to PR_FIND_NEXT_TRACE_QNAME(). -** -** OUTPUTS: returned. -** -** RETURNS: -** PRTraceHandle or NULL when there are no trace handles. -** -** RESTRICTIONS: -** Iterating thru the trace handles via FindNext should be done -** under protection of the trace handle lock. See: ( -** PR_SetTraceOption( PRLockTraceHandles ). -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_FIND_NEXT_TRACE_RNAME(next,rhandle,qhandle)\ - (next) = PR_FindNextTraceRname((rhandle),(qhandle)) -#else -#define PR_FIND_NEXT_TRACE_RNAME(next,rhandle,qhandle) -#endif - -NSPR_API(PRTraceHandle) - PR_FindNextTraceRname( - PRTraceHandle rhandle, - PRTraceHandle qhandle -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_RecordTraceEntries() -- Write trace entries to external media -** -** DESCRIPTION: -** PR_RecordTraceEntries() causes entries in the in-memory trace -** buffer to be written to external media. -** -** When PR_RecordTraceEntries() is called from an application -** thread, the function appears to block until another thread -** calls PR_SetTraceOption() with the PRTraceStopRecording -** option. This suggests that PR_RecordTraceEntries() should be -** called from a user supplied thread whose only job is to -** record trace entries. -** -** The environment variable NSPR_TRACE_LOG controls the operation -** of this function. When NSPR_TRACE_LOG is not defined in the -** environment, no recording of trace entries occurs. When -** NSPR_TRACE_LOG is defined, the value of its definition must be -** the filename of the file to receive the trace entry buffer. -** -** PR_RecordTraceEntries() attempts to record the in-memory -** buffer to a file, subject to the setting of the environment -** variable NSPR_TRACE_LOG. It is possible because of system -** load, the thread priority of the recording thread, number of -** active trace records being written over time, and other -** variables that some trace records can be lost. ... In other -** words: don't bet the farm on getting everything. -** -** INPUTS: none -** -** OUTPUTS: none -** -** RETURNS: PR_STATUS -** PR_SUCCESS no errors were found. -** PR_FAILURE errors were found. -** -** RESTRICTIONS: -** Only one thread can call PR_RecordTraceEntries() within a -** process. -** -** On error, PR_RecordTraceEntries() may return prematurely. -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_RECORD_TRACE_ENTRIES()\ - PR_RecordTraceEntries() -#else -#define PR_RECORD_TRACE_ENTRIES() -#endif - -NSPR_API(void) - PR_RecordTraceEntries( - void -); - -/* ----------------------------------------------------------------------- -** FUNCTION: PR_GetTraceEntries() -- Retreive trace entries from -** the Trace Facility -** -** DESCRIPTION: -** PR_GetTraceEntries() retreives trace entries from the Trace -** Facility. Up to count trace entries are copied from the Trace -** Facility into buffer. Only those trace entries that have not -** been copied via a previous call to PR_GetTraceEntries() are -** copied. The actual number copied is placed in the PRInt32 -** variable pointed to by found. -** -** If more than count trace entries have entered the Trace -** Facility since the last call to PR_GetTraceEntries() -** a lost data condition is returned. In this case, the most -** recent count trace entries are copied into buffer and found is -** set to count. -** -** INPUTS: -** count. The number of trace entries to be copied into buffer. -** -** -** OUTPUTS: -** buffer. An array of PRTraceEntries. The buffer is supplied -** by the caller. -** -** found: 32bit signed integer. The number of PRTraceEntries -** actually copied. found is always less than or equal to count. -** -** RETURNS: -** zero when there is no lost data. -** non-zero when some PRTraceEntries have been lost. -** -** RESTRICTIONS: -** This is a real performance pig. The copy out operation is bad -** enough, but depending on then frequency of calls to the -** function, serious performance impact to the operating -** application may be realized. ... YMMV. -** -*/ -#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) -#define PR_GET_TRACE_ENTRIES(buffer,count,found)\ - PR_GetTraceEntries((buffer),(count),(found)) -#else -#define PR_GET_TRACE_ENTRIES(buffer,count,found) -#endif - -NSPR_API(PRIntn) - PR_GetTraceEntries( - PRTraceEntry *buffer, /* where to write output */ - PRInt32 count, /* number to get */ - PRInt32 *found /* number you got */ -); - -PR_END_EXTERN_C - -#endif /* prtrace_h___ */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prtypes.h nspr-4.10.7/mozilla/nsprpub/pr/include/prtypes.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prtypes.h 2012-12-07 21:13:41.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prtypes.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,565 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prtypes.h -** Description: Definitions of NSPR's basic types -** -** Prototypes and macros used to make up for deficiencies that we have found -** in ANSI environments. -** -** Since we do not wrap and all the other standard headers, authors -** of portable code will not know in general that they need these definitions. -** Instead of requiring these authors to find the dependent uses in their code -** and take the following steps only in those C files, we take steps once here -** for all C files. -**/ - -#ifndef prtypes_h___ -#define prtypes_h___ - -#ifdef MDCPUCFG -#include MDCPUCFG -#else -#include "prcpucfg.h" -#endif - -#include - -/*********************************************************************** -** MACROS: PR_EXTERN -** PR_IMPLEMENT -** DESCRIPTION: -** These are only for externally visible routines and globals. For -** internal routines, just use "extern" for type checking and that -** will not export internal cross-file or forward-declared symbols. -** Define a macro for declaring procedures return types. We use this to -** deal with windoze specific type hackery for DLL definitions. Use -** PR_EXTERN when the prototype for the method is declared. Use -** PR_IMPLEMENT for the implementation of the method. -** -** Example: -** in dowhim.h -** PR_EXTERN( void ) DoWhatIMean( void ); -** in dowhim.c -** PR_IMPLEMENT( void ) DoWhatIMean( void ) { return; } -** -** -***********************************************************************/ -#if defined(WIN32) - -#define PR_EXPORT(__type) extern __declspec(dllexport) __type -#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type -#define PR_IMPORT(__type) __declspec(dllimport) __type -#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type - -#define PR_EXTERN(__type) extern __declspec(dllexport) __type -#define PR_IMPLEMENT(__type) __declspec(dllexport) __type -#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type -#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type - -#define PR_CALLBACK -#define PR_CALLBACK_DECL -#define PR_STATIC_CALLBACK(__x) static __x - -#elif defined(XP_BEOS) - -#define PR_EXPORT(__type) extern __declspec(dllexport) __type -#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type -#define PR_IMPORT(__type) extern __declspec(dllexport) __type -#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type - -#define PR_EXTERN(__type) extern __declspec(dllexport) __type -#define PR_IMPLEMENT(__type) __declspec(dllexport) __type -#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type -#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type - -#define PR_CALLBACK -#define PR_CALLBACK_DECL -#define PR_STATIC_CALLBACK(__x) static __x - -#elif defined(XP_OS2) && defined(__declspec) - -#define PR_EXPORT(__type) extern __declspec(dllexport) __type -#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type -#define PR_IMPORT(__type) extern __declspec(dllimport) __type -#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type - -#define PR_EXTERN(__type) extern __declspec(dllexport) __type -#define PR_IMPLEMENT(__type) __declspec(dllexport) __type -#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type -#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type - -#define PR_CALLBACK -#define PR_CALLBACK_DECL -#define PR_STATIC_CALLBACK(__x) static __x - -#elif defined(SYMBIAN) - -#define PR_EXPORT(__type) extern __declspec(dllexport) __type -#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type -#ifdef __WINS__ -#define PR_IMPORT(__type) extern __declspec(dllexport) __type -#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type -#else -#define PR_IMPORT(__type) extern __declspec(dllimport) __type -#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type -#endif - -#define PR_EXTERN(__type) extern __type -#define PR_IMPLEMENT(__type) __type -#define PR_EXTERN_DATA(__type) extern __type -#define PR_IMPLEMENT_DATA(__type) __type - -#define PR_CALLBACK -#define PR_CALLBACK_DECL -#define PR_STATIC_CALLBACK(__x) static __x - -#else /* Unix */ - -/* GCC 3.3 and later support the visibility attribute. */ -#if (__GNUC__ >= 4) || \ - (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) -#define PR_VISIBILITY_DEFAULT __attribute__((visibility("default"))) -#else -#define PR_VISIBILITY_DEFAULT -#endif - -#define PR_EXPORT(__type) extern PR_VISIBILITY_DEFAULT __type -#define PR_EXPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type -#define PR_IMPORT(__type) extern PR_VISIBILITY_DEFAULT __type -#define PR_IMPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type - -#define PR_EXTERN(__type) extern PR_VISIBILITY_DEFAULT __type -#define PR_IMPLEMENT(__type) PR_VISIBILITY_DEFAULT __type -#define PR_EXTERN_DATA(__type) extern PR_VISIBILITY_DEFAULT __type -#define PR_IMPLEMENT_DATA(__type) PR_VISIBILITY_DEFAULT __type -#define PR_CALLBACK -#define PR_CALLBACK_DECL -#define PR_STATIC_CALLBACK(__x) static __x - -#endif - -#if defined(_NSPR_BUILD_) -#define NSPR_API(__type) PR_EXPORT(__type) -#define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type) -#else -#define NSPR_API(__type) PR_IMPORT(__type) -#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type) -#endif - -/*********************************************************************** -** MACROS: PR_BEGIN_MACRO -** PR_END_MACRO -** DESCRIPTION: -** Macro body brackets so that macros with compound statement definitions -** behave syntactically more like functions when called. -***********************************************************************/ -#define PR_BEGIN_MACRO do { -#define PR_END_MACRO } while (0) - -/*********************************************************************** -** MACROS: PR_BEGIN_EXTERN_C -** PR_END_EXTERN_C -** DESCRIPTION: -** Macro shorthands for conditional C++ extern block delimiters. -***********************************************************************/ -#ifdef __cplusplus -#define PR_BEGIN_EXTERN_C extern "C" { -#define PR_END_EXTERN_C } -#else -#define PR_BEGIN_EXTERN_C -#define PR_END_EXTERN_C -#endif - -/*********************************************************************** -** MACROS: PR_BIT -** PR_BITMASK -** DESCRIPTION: -** Bit masking macros. XXX n must be <= 31 to be portable -***********************************************************************/ -#define PR_BIT(n) ((PRUint32)1 << (n)) -#define PR_BITMASK(n) (PR_BIT(n) - 1) - -/*********************************************************************** -** MACROS: PR_ROUNDUP -** PR_MIN -** PR_MAX -** PR_ABS -** DESCRIPTION: -** Commonly used macros for operations on compatible types. -***********************************************************************/ -#define PR_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y)) -#define PR_MIN(x,y) ((x)<(y)?(x):(y)) -#define PR_MAX(x,y) ((x)>(y)?(x):(y)) -#define PR_ABS(x) ((x)<0?-(x):(x)) - -/*********************************************************************** -** MACROS: PR_ARRAY_SIZE -** DESCRIPTION: -** The number of elements in an array. -***********************************************************************/ -#define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) - -PR_BEGIN_EXTERN_C - -/* -** Starting in NSPR 4.9.5, NSPR's exact-width integer types should match -** the exact-width integer types defined in . This allows sloppy -** code to use PRInt{N} and int{N}_t interchangeably. -** -** The 8-bit and 16-bit integer types can only be defined using char and -** short. All platforms define the 32-bit integer types using int. So only -** the 64-bit integer types could be defined differently. -** -** NSPR's original strategy was to use the "shortest" 64-bit integer type: -** if long is 64-bit, then prefer it over long long. This strategy is also -** used by Linux/glibc, FreeBSD, and NetBSD. -** -** Other platforms use a different strategy: simply define the 64-bit -** integer types using long long. We define the PR_ALTERNATE_INT64_TYPEDEF -** macro on these platforms. Note that PR_ALTERNATE_INT64_TYPEDEF is for -** internal use by NSPR headers only. Do not define or test this macro in -** your code. -** -** NOTE: NSPR can't use because C99 requires C++ code to define -** __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS to make all the macros -** defined in available. This strange requirement is gone in -** C11. When most platforms ignore this C99 requirement, NSPR will be able -** to use . A patch to do that is in NSPR bug 634793. -*/ - -#if defined(__APPLE__) || defined(__ANDROID__) || defined(__OpenBSD__) -#define PR_ALTERNATE_INT64_TYPEDEF -#endif - -/************************************************************************ -** TYPES: PRUint8 -** PRInt8 -** DESCRIPTION: -** The int8 types are known to be 8 bits each. There is no type that -** is equivalent to a plain "char". -************************************************************************/ -#if PR_BYTES_PER_BYTE == 1 -typedef unsigned char PRUint8; -/* -** Some cfront-based C++ compilers do not like 'signed char' and -** issue the warning message: -** warning: "signed" not implemented (ignored) -** For these compilers, we have to define PRInt8 as plain 'char'. -** Make sure that plain 'char' is indeed signed under these compilers. -*/ -#if (defined(HPUX) && defined(__cplusplus) \ - && !defined(__GNUC__) && __cplusplus < 199707L) \ - || (defined(SCO) && defined(__cplusplus) \ - && !defined(__GNUC__) && __cplusplus == 1L) -typedef char PRInt8; -#else -typedef signed char PRInt8; -#endif -#else -#error No suitable type for PRInt8/PRUint8 -#endif - -/************************************************************************ - * MACROS: PR_INT8_MAX - * PR_INT8_MIN - * PR_UINT8_MAX - * DESCRIPTION: - * The maximum and minimum values of a PRInt8 or PRUint8. -************************************************************************/ - -#define PR_INT8_MAX 127 -#define PR_INT8_MIN (-128) -#define PR_UINT8_MAX 255U - -/************************************************************************ -** TYPES: PRUint16 -** PRInt16 -** DESCRIPTION: -** The int16 types are known to be 16 bits each. -************************************************************************/ -#if PR_BYTES_PER_SHORT == 2 -typedef unsigned short PRUint16; -typedef short PRInt16; -#else -#error No suitable type for PRInt16/PRUint16 -#endif - -/************************************************************************ - * MACROS: PR_INT16_MAX - * PR_INT16_MIN - * PR_UINT16_MAX - * DESCRIPTION: - * The maximum and minimum values of a PRInt16 or PRUint16. -************************************************************************/ - -#define PR_INT16_MAX 32767 -#define PR_INT16_MIN (-32768) -#define PR_UINT16_MAX 65535U - -/************************************************************************ -** TYPES: PRUint32 -** PRInt32 -** DESCRIPTION: -** The int32 types are known to be 32 bits each. -************************************************************************/ -#if PR_BYTES_PER_INT == 4 -typedef unsigned int PRUint32; -typedef int PRInt32; -#define PR_INT32(x) x -#define PR_UINT32(x) x ## U -#elif PR_BYTES_PER_LONG == 4 -typedef unsigned long PRUint32; -typedef long PRInt32; -#define PR_INT32(x) x ## L -#define PR_UINT32(x) x ## UL -#else -#error No suitable type for PRInt32/PRUint32 -#endif - -/************************************************************************ - * MACROS: PR_INT32_MAX - * PR_INT32_MIN - * PR_UINT32_MAX - * DESCRIPTION: - * The maximum and minimum values of a PRInt32 or PRUint32. -************************************************************************/ - -#define PR_INT32_MAX PR_INT32(2147483647) -#define PR_INT32_MIN (-PR_INT32_MAX - 1) -#define PR_UINT32_MAX PR_UINT32(4294967295) - -/************************************************************************ -** TYPES: PRUint64 -** PRInt64 -** DESCRIPTION: -** The int64 types are known to be 64 bits each. Care must be used when -** declaring variables of type PRUint64 or PRInt64. Different hardware -** architectures and even different compilers have varying support for -** 64 bit values. The only guaranteed portability requires the use of -** the LL_ macros (see prlong.h). -** -** MACROS: PR_INT64 -** PR_UINT64 -** DESCRIPTION: -** The PR_INT64 and PR_UINT64 macros provide a portable way for -** specifying 64-bit integer constants. They can only be used if -** PRInt64 and PRUint64 are defined as compiler-supported 64-bit -** integer types (i.e., if HAVE_LONG_LONG is defined, which is true -** for all the supported compilers topday). If PRInt64 and PRUint64 -** are defined as structs, the LL_INIT macro defined in prlong.h has -** to be used. -** -** MACROS: PR_INT64_MAX -** PR_INT64_MIN -** PR_UINT64_MAX -** DESCRIPTION: -** The maximum and minimum values of a PRInt64 or PRUint64. -************************************************************************/ -#ifdef HAVE_LONG_LONG -/* Keep this in sync with prlong.h. */ -#if PR_BYTES_PER_LONG == 8 && !defined(PR_ALTERNATE_INT64_TYPEDEF) -typedef long PRInt64; -typedef unsigned long PRUint64; -#define PR_INT64(x) x ## L -#define PR_UINT64(x) x ## UL -#elif defined(WIN32) && !defined(__GNUC__) -typedef __int64 PRInt64; -typedef unsigned __int64 PRUint64; -#define PR_INT64(x) x ## i64 -#define PR_UINT64(x) x ## ui64 -#else -typedef long long PRInt64; -typedef unsigned long long PRUint64; -#define PR_INT64(x) x ## LL -#define PR_UINT64(x) x ## ULL -#endif /* PR_BYTES_PER_LONG == 8 */ - -#define PR_INT64_MAX PR_INT64(0x7fffffffffffffff) -#define PR_INT64_MIN (-PR_INT64_MAX - 1) -#define PR_UINT64_MAX PR_UINT64(-1) -#else /* !HAVE_LONG_LONG */ -typedef struct { -#ifdef IS_LITTLE_ENDIAN - PRUint32 lo, hi; -#else - PRUint32 hi, lo; -#endif -} PRInt64; -typedef PRInt64 PRUint64; - -#define PR_INT64_MAX (PRInt64){0x7fffffff, 0xffffffff} -#define PR_INT64_MIN (PRInt64){0xffffffff, 0xffffffff} -#define PR_UINT64_MAX (PRUint64){0xffffffff, 0xffffffff} - -#endif /* !HAVE_LONG_LONG */ - -/************************************************************************ -** TYPES: PRUintn -** PRIntn -** DESCRIPTION: -** The PRIntn types are most appropriate for automatic variables. They are -** guaranteed to be at least 16 bits, though various architectures may -** define them to be wider (e.g., 32 or even 64 bits). These types are -** never valid for fields of a structure. -************************************************************************/ -#if PR_BYTES_PER_INT >= 2 -typedef int PRIntn; -typedef unsigned int PRUintn; -#else -#error 'sizeof(int)' not sufficient for platform use -#endif - -/************************************************************************ -** TYPES: PRFloat64 -** DESCRIPTION: -** NSPR's floating point type is always 64 bits. -************************************************************************/ -typedef double PRFloat64; - -/************************************************************************ -** TYPES: PRSize -** DESCRIPTION: -** A type for representing the size of objects. -************************************************************************/ -typedef size_t PRSize; - - -/************************************************************************ -** TYPES: PROffset32, PROffset64 -** DESCRIPTION: -** A type for representing byte offsets from some location. -************************************************************************/ -typedef PRInt32 PROffset32; -typedef PRInt64 PROffset64; - -/************************************************************************ -** TYPES: PRPtrDiff -** DESCRIPTION: -** A type for pointer difference. Variables of this type are suitable -** for storing a pointer or pointer subtraction. -************************************************************************/ -typedef ptrdiff_t PRPtrdiff; - -/************************************************************************ -** TYPES: PRUptrdiff -** DESCRIPTION: -** A type for pointer difference. Variables of this type are suitable -** for storing a pointer or pointer sutraction. -************************************************************************/ -#ifdef _WIN64 -typedef PRUint64 PRUptrdiff; -#else -typedef unsigned long PRUptrdiff; -#endif - -/************************************************************************ -** TYPES: PRBool -** DESCRIPTION: -** Use PRBool for variables and parameter types. Use PR_FALSE and PR_TRUE -** for clarity of target type in assignments and actual arguments. Use -** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans -** just as you would C int-valued conditions. -************************************************************************/ -typedef PRIntn PRBool; -#define PR_TRUE 1 -#define PR_FALSE 0 - -/************************************************************************ -** TYPES: PRPackedBool -** DESCRIPTION: -** Use PRPackedBool within structs where bitfields are not desirable -** but minimum and consistant overhead matters. -************************************************************************/ -typedef PRUint8 PRPackedBool; - -/* -** Status code used by some routines that have a single point of failure or -** special status return. -*/ -typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus; - -#ifndef __PRUNICHAR__ -#define __PRUNICHAR__ -#ifdef WIN32 -typedef wchar_t PRUnichar; -#else -typedef PRUint16 PRUnichar; -#endif -#endif - -/* -** WARNING: The undocumented data types PRWord and PRUword are -** only used in the garbage collection and arena code. Do not -** use PRWord and PRUword in new code. -** -** A PRWord is an integer that is the same size as a void*. -** It implements the notion of a "word" in the Java Virtual -** Machine. (See Sec. 3.4 "Words", The Java Virtual Machine -** Specification, Addison-Wesley, September 1996. -** http://java.sun.com/docs/books/vmspec/index.html.) -*/ -#ifdef _WIN64 -typedef PRInt64 PRWord; -typedef PRUint64 PRUword; -#else -typedef long PRWord; -typedef unsigned long PRUword; -#endif - -#if defined(NO_NSPR_10_SUPPORT) -#else -/********* ???????????????? FIX ME ??????????????????????????? *****/ -/********************** Some old definitions until pr=>ds transition is done ***/ -/********************** Also, we are still using NSPR 1.0. GC ******************/ -/* -** Fundamental NSPR macros, used nearly everywhere. -*/ - -#define PR_PUBLIC_API PR_IMPLEMENT - -/* -** Macro body brackets so that macros with compound statement definitions -** behave syntactically more like functions when called. -*/ -#define NSPR_BEGIN_MACRO do { -#define NSPR_END_MACRO } while (0) - -/* -** Macro shorthands for conditional C++ extern block delimiters. -*/ -#ifdef NSPR_BEGIN_EXTERN_C -#undef NSPR_BEGIN_EXTERN_C -#endif -#ifdef NSPR_END_EXTERN_C -#undef NSPR_END_EXTERN_C -#endif - -#ifdef __cplusplus -#define NSPR_BEGIN_EXTERN_C extern "C" { -#define NSPR_END_EXTERN_C } -#else -#define NSPR_BEGIN_EXTERN_C -#define NSPR_END_EXTERN_C -#endif - -#include "obsolete/protypes.h" - -/********* ????????????? End Fix me ?????????????????????????????? *****/ -#endif /* NO_NSPR_10_SUPPORT */ - -/* -** Compile-time assert. "condition" must be a constant expression. -** The macro can be used only in places where an "extern" declaration is -** allowed. -*/ -#define PR_STATIC_ASSERT(condition) \ - extern void pr_static_assert(int arg[(condition) ? 1 : -1]) - -PR_END_EXTERN_C - -#endif /* prtypes_h___ */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prvrsion.h nspr-4.10.7/mozilla/nsprpub/pr/include/prvrsion.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prvrsion.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prvrsion.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -/* author: jstewart */ - -#if defined(_PRVERSION_H) -#else -#define _PRVERSION_H - -#include "prtypes.h" - -PR_BEGIN_EXTERN_C - -/* All components participating in the PR version protocol must expose - * a structure and a function. The structure is defined below and named - * according to the naming conventions outlined further below. The function - * is called libVersionPoint and returns a pointer to this structure. - */ - -/* on NT, always pack the structure the same. */ -#ifdef _WIN32 -#pragma pack(push, 8) -#endif - -typedef struct { - /* - * The first field defines which version of this structure is in use. - * At this time, only version 2 is specified. If this value is not - * 2, you must read no further into the structure. - */ - PRInt32 version; - - /* for Version 2, this is the body format. */ - PRInt64 buildTime; /* 64 bits - usecs since midnight, 1/1/1970 */ - char * buildTimeString;/* a human readable version of the time */ - - PRUint8 vMajor; /* Major version of this component */ - PRUint8 vMinor; /* Minor version of this component */ - PRUint8 vPatch; /* Patch level of this component */ - - PRBool beta; /* true if this is a beta component */ - PRBool debug; /* true if this is a debug component */ - PRBool special; /* true if this component is a special build */ - - char * filename; /* The original filename */ - char * description; /* description of this component */ - char * security; /* level of security in this component */ - char * copyright; /* The copyright for this file */ - char * comment; /* free form field for misc usage */ - char * specialString; /* the special variant for this build */ -} PRVersionDescription; - -/* on NT, restore the previous packing */ -#ifdef _WIN32 -#pragma pack(pop) -#endif - -/* - * All components must define an entrypoint named libVersionPoint which - * is of type versionEntryPointType. - * - * For example, for a library named libfoo, we would have: - * - * PRVersionDescription prVersionDescription_libfoo = - * { - * ... - * }; - * - * PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void) - * { - * return &prVersionDescription_libfoo; - * } - */ -typedef const PRVersionDescription *(*versionEntryPointType)(void); - -/* - * Where you declare your libVersionPoint, do it like this: - * PR_IMPLEMENT(const PRVersionDescription *) libVersionPoint(void) { - * fill it in... - * } - */ - -/* - * NAMING CONVENTION FOR struct - * - * all components should also expose a static PRVersionDescription - * The name of the struct should be calculated as follows: - * Take the value of filename. (If filename is not specified, calculate - * a short, unique string.) Convert all non-alphanumeric characters - * to '_'. To this, prepend "PRVersionDescription_". Thus for libfoo.so, - * the symbol name is "PRVersionDescription_libfoo_so". - * so the file should have - * PRVersionDescription PRVersionDescription_libfoo_so { fill it in }; - * on NT, this file should be declspec export. - */ - -PR_END_EXTERN_C - -#endif /* defined(_PRVERSION_H) */ - -/* prvrsion.h */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/include/prwin16.h nspr-4.10.7/mozilla/nsprpub/pr/include/prwin16.h --- nspr-4.9.5/mozilla/nsprpub/pr/include/prwin16.h 2012-03-06 13:13:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/include/prwin16.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,164 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef prwin16_h___ -#define prwin16_h___ - -/* -** Condition use of this header on platform. -*/ -#if (defined(XP_PC) && !defined(_WIN32) && !defined(XP_OS2) && defined(MOZILLA_CLIENT)) || defined(WIN16) -#include - -PR_BEGIN_EXTERN_C -/* -** Win16 stdio special case. -** To get stdio to work for Win16, all calls to printf() and related -** things must be called from the environment of the .EXE; calls to -** printf() from the .DLL send output to the bit-bucket. -** -** To make sure that PR_fprintf(), and related functions, work correctly, -** the actual stream I/O to stdout, stderr, stdin must be done in the -** .EXE. To do this, a hack is placed in _MD_Write() such that the -** fd for stdio handles results in a call to the .EXE. -** -** file w16stdio.c contains the functions that get called from NSPR -** to do the actual I/O. w16stdio.o must be statically linked with -** any application needing stdio for Win16. -** -** The address of these functions must be made available to the .DLL -** so he can call back to the .EXE. To do this, function -** PR_MD_RegisterW16StdioCallbacks() is called from the .EXE. -** The arguments are the functions defined in w16stdio.c -** At runtime, MD_Write() calls the registered functions, if any -** were registered. -** -** prinit.h contains a macro PR_STDIO_INIT() that calls the registration -** function for Win16; For other platforms, the macro is a No-Op. -** -** Note that stdio is not operational at all on Win16 GUI applications. -** This special case exists to provide stdio capability from the NSPR -** .DLL for command line applications only. NSPR's test cases are -** almost exclusively command line applications. -** -** See also: w16io.c, w16stdio.c -*/ -typedef PRInt32 (PR_CALLBACK *PRStdinRead)( void *buf, PRInt32 amount); -typedef PRInt32 (PR_CALLBACK *PRStdoutWrite)( void *buf, PRInt32 amount); -typedef PRInt32 (PR_CALLBACK *PRStderrWrite)( void *buf, PRInt32 amount); - -NSPR_API(PRStatus) -PR_MD_RegisterW16StdioCallbacks( - PRStdinRead inReadf, /* i: function pointer for stdin read */ - PRStdoutWrite outWritef, /* i: function pointer for stdout write */ - PRStderrWrite errWritef /* i: function pointer for stderr write */ - ); - -NSPR_API(PRInt32) -_PL_W16StdioWrite( void *buf, PRInt32 amount ); - -NSPR_API(PRInt32) -_PL_W16StdioRead( void *buf, PRInt32 amount ); - -#define PR_STDIO_INIT() PR_MD_RegisterW16StdioCallbacks( \ - _PL_W16StdioRead, _PL_W16StdioWrite, _PL_W16StdioWrite ); \ - PR_INIT_CALLBACKS(); - -/* -** Win16 hackery. -** -*/ -struct PRMethodCallbackStr { - int (PR_CALLBACK *auxOutput)(const char *outputString); - size_t (PR_CALLBACK *strftime)(char *s, size_t len, const char *fmt, const struct tm *p); - void * (PR_CALLBACK *malloc)( size_t size ); - void * (PR_CALLBACK *calloc)(size_t n, size_t size ); - void * (PR_CALLBACK *realloc)( void* old_blk, size_t size ); - void (PR_CALLBACK *free)( void *ptr ); - void * (PR_CALLBACK *getenv)( const char *name); - int (PR_CALLBACK *putenv)( const char *assoc); -/* void * (PR_CALLBACK *perror)( const char *prefix ); */ -}; - -NSPR_API(void) PR_MDRegisterCallbacks(struct PRMethodCallbackStr *); - -int PR_CALLBACK _PL_W16CallBackPuts( const char *outputString ); -size_t PR_CALLBACK _PL_W16CallBackStrftime( - char *s, - size_t len, - const char *fmt, - const struct tm *p ); -void * PR_CALLBACK _PL_W16CallBackMalloc( size_t size ); -void * PR_CALLBACK _PL_W16CallBackCalloc( size_t n, size_t size ); -void * PR_CALLBACK _PL_W16CallBackRealloc( - void *old_blk, - size_t size ); -void PR_CALLBACK _PL_W16CallBackFree( void *ptr ); -void * PR_CALLBACK _PL_W16CallBackGetenv( const char *name ); -int PR_CALLBACK _PL_W16CallBackPutenv( const char *assoc ); - -/* -** Hackery! -** -** These functions are provided as static link points. -** This is to satisfy the quick port of Gromit to NSPR 2.0 -** ... Don't do this! ... alas, It may never go away. -** -*/ -NSPR_API(int) PR_MD_printf(const char *, ...); -NSPR_API(void) PR_MD_exit(int); -NSPR_API(size_t) PR_MD_strftime(char *, size_t, const char *, const struct tm *); -NSPR_API(int) PR_MD_sscanf(const char *, const char *, ...); -NSPR_API(void*) PR_MD_malloc( size_t size ); -NSPR_API(void*) PR_MD_calloc( size_t n, size_t size ); -NSPR_API(void*) PR_MD_realloc( void* old_blk, size_t size ); -NSPR_API(void) PR_MD_free( void *ptr ); -NSPR_API(char*) PR_MD_getenv( const char *name ); -NSPR_API(int) PR_MD_putenv( const char *assoc ); -NSPR_API(int) PR_MD_fprintf(FILE *fPtr, const char *fmt, ...); - -#define PR_INIT_CALLBACKS() \ - { \ - static struct PRMethodCallbackStr cbf = { \ - _PL_W16CallBackPuts, \ - _PL_W16CallBackStrftime, \ - _PL_W16CallBackMalloc, \ - _PL_W16CallBackCalloc, \ - _PL_W16CallBackRealloc, \ - _PL_W16CallBackFree, \ - _PL_W16CallBackGetenv, \ - _PL_W16CallBackPutenv, \ - }; \ - PR_MDRegisterCallbacks( &cbf ); \ - } - - -/* -** Get the exception context for Win16 MFC applications threads -*/ -NSPR_API(void *) PR_W16GetExceptionContext(void); -/* -** Set the exception context for Win16 MFC applications threads -*/ -NSPR_API(void) PR_W16SetExceptionContext(void *context); - -PR_END_EXTERN_C -#else -/* -** For platforms other than Win16, define -** PR_STDIO_INIT() as a No-Op. -*/ -#define PR_STDIO_INIT() -#endif /* WIN16 || MOZILLA_CLIENT */ - -#endif /* prwin16_h___ */ - - - - - - - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/Makefile.in 2012-03-06 13:13:42.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = .. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -DIRS = include src - -include $(topsrcdir)/config/rules.mk diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/bsrcs.mk nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/bsrcs.mk --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/bsrcs.mk 2012-03-06 13:14:01.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/bsrcs.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# this file lists the source files to be compiled (used in Makefile) and -# then enumerated as object files (in objs.mk) for inclusion in the NSPR -# shared library - -BTCSRCS = \ - btthread.c \ - btlocks.c \ - btcvar.c \ - btmon.c \ - btsem.c \ - btmisc.c \ - $(NULL) diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btcvar.c nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btcvar.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btcvar.c 2012-03-06 13:14:02.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btcvar.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,244 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "primpl.h" - -/* -** Create a new condition variable. -** -** "lock" is the lock used to protect the condition variable. -** -** Condition variables are synchronization objects that threads can use -** to wait for some condition to occur. -** -** This may fail if memory is tight or if some operating system resource -** is low. In such cases, a NULL will be returned. -*/ -PR_IMPLEMENT(PRCondVar*) - PR_NewCondVar (PRLock *lock) -{ - PRCondVar *cv = PR_NEW( PRCondVar ); - PR_ASSERT( NULL != lock ); - if( NULL != cv ) - { - cv->lock = lock; - cv->sem = create_sem(0, "CVSem"); - cv->handshakeSem = create_sem(0, "CVHandshake"); - cv->signalSem = create_sem( 0, "CVSignal"); - cv->signalBenCount = 0; - cv->ns = cv->nw = 0; - PR_ASSERT( cv->sem >= B_NO_ERROR ); - PR_ASSERT( cv->handshakeSem >= B_NO_ERROR ); - PR_ASSERT( cv->signalSem >= B_NO_ERROR ); - } - return cv; -} /* PR_NewCondVar */ - -/* -** Destroy a condition variable. There must be no thread -** waiting on the condvar. The caller is responsible for guaranteeing -** that the condvar is no longer in use. -** -*/ -PR_IMPLEMENT(void) - PR_DestroyCondVar (PRCondVar *cvar) -{ - status_t result = delete_sem( cvar->sem ); - PR_ASSERT( result == B_NO_ERROR ); - - result = delete_sem( cvar->handshakeSem ); - PR_ASSERT( result == B_NO_ERROR ); - - result = delete_sem( cvar->signalSem ); - PR_ASSERT( result == B_NO_ERROR ); - - PR_DELETE( cvar ); -} - -/* -** The thread that waits on a condition is blocked in a "waiting on -** condition" state until another thread notifies the condition or a -** caller specified amount of time expires. The lock associated with -** the condition variable will be released, which must have be held -** prior to the call to wait. -** -** Logically a notified thread is moved from the "waiting on condition" -** state and made "ready." When scheduled, it will attempt to reacquire -** the lock that it held when wait was called. -** -** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and -** PR_INTERVAL_NO_WAIT. The former value requires that a condition be -** notified (or the thread interrupted) before it will resume from the -** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect -** is to release the lock, possibly causing a rescheduling within the -** runtime, then immediately attempting to reacquire the lock and resume. -** -** Any other value for timeout will cause the thread to be rescheduled -** either due to explicit notification or an expired interval. The latter -** must be determined by treating time as one part of the monitored data -** being protected by the lock and tested explicitly for an expired -** interval. -** -** Returns PR_FAILURE if the caller has not locked the lock associated -** with the condition variable or the thread was interrupted (PR_Interrupt()). -** The particular reason can be extracted with PR_GetError(). -*/ -PR_IMPLEMENT(PRStatus) - PR_WaitCondVar (PRCondVar *cvar, PRIntervalTime timeout) -{ - status_t err; - if( timeout == PR_INTERVAL_NO_WAIT ) - { - PR_Unlock( cvar->lock ); - PR_Lock( cvar->lock ); - return PR_SUCCESS; - } - - if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) - { - if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) - { - atomic_add( &cvar->signalBenCount, -1 ); - return PR_FAILURE; - } - } - cvar->nw += 1; - if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) - { - release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); - } - - PR_Unlock( cvar->lock ); - if( timeout==PR_INTERVAL_NO_TIMEOUT ) - { - err = acquire_sem(cvar->sem); - } - else - { - err = acquire_sem_etc(cvar->sem, 1, B_RELATIVE_TIMEOUT, PR_IntervalToMicroseconds(timeout) ); - } - - if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) - { - while (acquire_sem(cvar->signalSem) == B_INTERRUPTED); - } - - if (cvar->ns > 0) - { - release_sem_etc(cvar->handshakeSem, 1, B_DO_NOT_RESCHEDULE); - cvar->ns -= 1; - } - cvar->nw -= 1; - if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) - { - release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); - } - - PR_Lock( cvar->lock ); - if(err!=B_NO_ERROR) - { - return PR_FAILURE; - } - return PR_SUCCESS; -} - -/* -** Notify ONE thread that is currently waiting on 'cvar'. Which thread is -** dependent on the implementation of the runtime. Common sense would dictate -** that all threads waiting on a single condition have identical semantics, -** therefore which one gets notified is not significant. -** -** The calling thead must hold the lock that protects the condition, as -** well as the invariants that are tightly bound to the condition, when -** notify is called. -** -** Returns PR_FAILURE if the caller has not locked the lock associated -** with the condition variable. -*/ -PR_IMPLEMENT(PRStatus) - PR_NotifyCondVar (PRCondVar *cvar) -{ - status_t err ; - if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) - { - if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) - { - atomic_add( &cvar->signalBenCount, -1 ); - return PR_FAILURE; - } - } - if (cvar->nw > cvar->ns) - { - cvar->ns += 1; - release_sem_etc(cvar->sem, 1, B_DO_NOT_RESCHEDULE); - if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) - { - release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); - } - - while (acquire_sem(cvar->handshakeSem) == B_INTERRUPTED) - { - err = B_INTERRUPTED; - } - } - else - { - if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) - { - release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); - } - } - return PR_SUCCESS; -} - -/* -** Notify all of the threads waiting on the condition variable. The order -** that the threads are notified is indeterminant. The lock that protects -** the condition must be held. -** -** Returns PR_FAILURE if the caller has not locked the lock associated -** with the condition variable. -*/ -PR_IMPLEMENT(PRStatus) - PR_NotifyAllCondVar (PRCondVar *cvar) -{ - int32 handshakes; - status_t err = B_OK; - - if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) - { - if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) - { - atomic_add( &cvar->signalBenCount, -1 ); - return PR_FAILURE; - } - } - - if (cvar->nw > cvar->ns) - { - handshakes = cvar->nw - cvar->ns; - cvar->ns = cvar->nw; - release_sem_etc(cvar->sem, handshakes, B_DO_NOT_RESCHEDULE); - if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) - { - release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); - } - - while (acquire_sem_etc(cvar->handshakeSem, handshakes, 0, 0) == B_INTERRUPTED) - { - err = B_INTERRUPTED; - } - } - else - { - if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) - { - release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); - } - } - return PR_SUCCESS; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btlocks.c nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btlocks.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btlocks.c 2012-03-06 13:14:02.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btlocks.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: btlocks.c -** Description: Implemenation for thread locks using bthreads -** Exports: prlock.h -*/ - -#include "primpl.h" - -#include -#include - -void -_PR_InitLocks (void) -{ -} - -PR_IMPLEMENT(PRLock*) - PR_NewLock (void) -{ - PRLock *lock; - status_t semresult; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - lock = PR_NEWZAP(PRLock); - if (lock != NULL) { - - lock->benaphoreCount = 0; - lock->semaphoreID = create_sem( 0, "nsprLockSem" ); - if( lock->semaphoreID < B_NO_ERROR ) { - - PR_DELETE( lock ); - lock = NULL; - } - } - - return lock; -} - -PR_IMPLEMENT(void) - PR_DestroyLock (PRLock* lock) -{ - status_t result; - - PR_ASSERT(NULL != lock); - result = delete_sem(lock->semaphoreID); - PR_ASSERT(result == B_NO_ERROR); - PR_DELETE(lock); -} - -PR_IMPLEMENT(void) - PR_Lock (PRLock* lock) -{ - PR_ASSERT(lock != NULL); - - if( atomic_add( &lock->benaphoreCount, 1 ) > 0 ) { - - if( acquire_sem(lock->semaphoreID ) != B_NO_ERROR ) { - - atomic_add( &lock->benaphoreCount, -1 ); - return; - } - } - - lock->owner = find_thread( NULL ); -} - -PR_IMPLEMENT(PRStatus) - PR_Unlock (PRLock* lock) -{ - PR_ASSERT(lock != NULL); - lock->owner = NULL; - if( atomic_add( &lock->benaphoreCount, -1 ) > 1 ) { - - release_sem_etc( lock->semaphoreID, 1, B_DO_NOT_RESCHEDULE ); - } - - return PR_SUCCESS; -} - -PR_IMPLEMENT(void) - PR_AssertCurrentThreadOwnsLock(PRLock *lock) -{ - PR_ASSERT(lock != NULL); - PR_ASSERT(lock->owner == find_thread( NULL )); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btmisc.c nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btmisc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btmisc.c 2012-03-06 13:14:02.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btmisc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include - -// void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")} -// void _MD_StartInterrupts(void) {PT_LOG("_MD_StartInterrupts")} - -/* this is a total hack.. */ - -struct protoent* getprotobyname(const char* name) -{ - return 0; -} - -struct protoent* getprotobynumber(int number) -{ - return 0; -} - -/* this is needed by prinit for some reason */ -void -_PR_InitStacks (void) -{ -} - -/* this is needed by prinit for some reason */ -void -_PR_InitTPD (void) -{ -} - -/* -** Create extra virtual processor threads. Generally used with MP systems. -*/ -PR_IMPLEMENT(void) - PR_SetConcurrency (PRUintn numCPUs) -{ -} - -/* -** Set thread recycle mode to on (1) or off (0) -*/ -PR_IMPLEMENT(void) - PR_SetThreadRecycleMode (PRUint32 flag) -{ -} - -/* -** Get context registers, return with error for now. -*/ - -PR_IMPLEMENT(PRWord *) -_MD_HomeGCRegisters( PRThread *t, int isCurrent, int *np ) -{ - return 0; -} - -PR_IMPLEMENT(void *) -PR_GetSP( PRThread *t ) -{ - return 0; -} - -PR_IMPLEMENT(PRStatus) -PR_EnumerateThreads( PREnumerator func, void *arg ) -{ - return PR_FAILURE; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btmon.c nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btmon.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btmon.c 2012-03-06 13:14:02.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btmon.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "primpl.h" - -/* -** Create a new monitor. Monitors are re-entrant locks with a single built-in -** condition variable. -** -** This may fail if memory is tight or if some operating system resource -** is low. -*/ -PR_IMPLEMENT(PRMonitor*) - PR_NewMonitor (void) -{ - PRMonitor *mon; - PRCondVar *cvar; - PRLock *lock; - - mon = PR_NEWZAP( PRMonitor ); - if( mon ) - { - lock = PR_NewLock(); - if( !lock ) - { - PR_DELETE( mon ); - return( 0 ); - } - - cvar = PR_NewCondVar( lock ); - if( !cvar ) - { - PR_DestroyLock( lock ); - PR_DELETE( mon ); - return( 0 ); - } - - mon->cvar = cvar; - mon->name = NULL; - } - - return( mon ); -} - -PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name) -{ - PRMonitor* mon = PR_NewMonitor(); - if( mon ) - { - mon->name = name; - } - return mon; -} - -/* -** Destroy a monitor. The caller is responsible for guaranteeing that the -** monitor is no longer in use. There must be no thread waiting on the -** monitor's condition variable and that the lock is not held. -** -*/ -PR_IMPLEMENT(void) - PR_DestroyMonitor (PRMonitor *mon) -{ - PR_DestroyLock( mon->cvar->lock ); - PR_DestroyCondVar( mon->cvar ); - PR_DELETE( mon ); -} - -/* -** Enter the lock associated with the monitor. If the calling thread currently -** is in the monitor, the call to enter will silently succeed. In either case, -** it will increment the entry count by one. -*/ -PR_IMPLEMENT(void) - PR_EnterMonitor (PRMonitor *mon) -{ - if( mon->cvar->lock->owner == find_thread( NULL ) ) - { - mon->entryCount++; - - } else - { - PR_Lock( mon->cvar->lock ); - mon->entryCount = 1; - } -} - -/* -** Decrement the entry count associated with the monitor. If the decremented -** entry count is zero, the monitor is exited. Returns PR_FAILURE if the -** calling thread has not entered the monitor. -*/ -PR_IMPLEMENT(PRStatus) - PR_ExitMonitor (PRMonitor *mon) -{ - if( mon->cvar->lock->owner != find_thread( NULL ) ) - { - return( PR_FAILURE ); - } - if( --mon->entryCount == 0 ) - { - return( PR_Unlock( mon->cvar->lock ) ); - } - return( PR_SUCCESS ); -} - -/* -** Wait for a notify on the monitor's condition variable. Sleep for "ticks" -** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is -** indefinite). -** -** While the thread is waiting it exits the monitor (as if it called -** PR_ExitMonitor as many times as it had called PR_EnterMonitor). When -** the wait has finished the thread regains control of the monitors lock -** with the same entry count as before the wait began. -** -** The thread waiting on the monitor will be resumed when the monitor is -** notified (assuming the thread is the next in line to receive the -** notify) or when the "ticks" timeout elapses. -** -** Returns PR_FAILURE if the caller has not entered the monitor. -*/ -PR_IMPLEMENT(PRStatus) - PR_Wait (PRMonitor *mon, PRIntervalTime ticks) -{ - PRUint32 entryCount; - PRUintn status; - PRThread *meThread; - thread_id me = find_thread( NULL ); - meThread = PR_GetCurrentThread(); - - if( mon->cvar->lock->owner != me ) return( PR_FAILURE ); - - entryCount = mon->entryCount; - mon->entryCount = 0; - - status = PR_WaitCondVar( mon->cvar, ticks ); - - mon->entryCount = entryCount; - - return( status ); -} - -/* -** Notify a thread waiting on the monitor's condition variable. If a thread -** is waiting on the condition variable (using PR_Wait) then it is awakened -** and attempts to reenter the monitor. -*/ -PR_IMPLEMENT(PRStatus) - PR_Notify (PRMonitor *mon) -{ - if( mon->cvar->lock->owner != find_thread( NULL ) ) - { - return( PR_FAILURE ); - } - - PR_NotifyCondVar( mon->cvar ); - return( PR_SUCCESS ); -} - -/* -** Notify all of the threads waiting on the monitor's condition variable. -** All of threads waiting on the condition are scheduled to reenter the -** monitor. -*/ -PR_IMPLEMENT(PRStatus) - PR_NotifyAll (PRMonitor *mon) -{ - if( mon->cvar->lock->owner != find_thread( NULL ) ) - { - return( PR_FAILURE ); - } - - PR_NotifyAllCondVar( mon->cvar ); - return( PR_SUCCESS ); -} - -/* -** Return the number of times that the current thread has entered the -** lock. Returns zero if the current thread has not entered the lock. -*/ -PR_IMPLEMENT(PRIntn) - PR_GetMonitorEntryCount(PRMonitor *mon) -{ - return( (mon->cvar->lock->owner == find_thread( NULL )) ? - mon->entryCount : 0 ); -} - -/* -** If the current thread is in |mon|, this assertion is guaranteed to -** succeed. Otherwise, the behavior of this function is undefined. -*/ -PR_IMPLEMENT(void) - PR_AssertCurrentThreadInMonitor(PRMonitor *mon) -{ - PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mon->cvar->lock); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btsem.c nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btsem.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btsem.c 2012-03-06 13:14:02.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btsem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "primpl.h" - -/* -** Create a new semaphore object. -*/ -PR_IMPLEMENT(PRSemaphore*) - PR_NewSem (PRUintn value) -{ - PRSemaphore *semaphore; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - semaphore = PR_NEWZAP(PRSemaphore); - if (NULL != semaphore) { - if ((semaphore->sem = create_sem(value, "nspr_sem")) < B_NO_ERROR) - return NULL; - else - return semaphore; - } - return NULL; -} - -/* -** Destroy the given semaphore object. -** -*/ -PR_IMPLEMENT(void) - PR_DestroySem (PRSemaphore *sem) -{ - status_t result; - - PR_ASSERT(sem != NULL); - result = delete_sem(sem->sem); - PR_ASSERT(result == B_NO_ERROR); - PR_DELETE(sem); -} - -/* -** Wait on a Semaphore. -** -** This routine allows a calling thread to wait or proceed depending upon -** the state of the semahore sem. The thread can proceed only if the -** counter value of the semaphore sem is currently greater than 0. If the -** value of semaphore sem is positive, it is decremented by one and the -** routine returns immediately allowing the calling thread to continue. If -** the value of semaphore sem is 0, the calling thread blocks awaiting the -** semaphore to be released by another thread. -** -** This routine can return PR_PENDING_INTERRUPT if the waiting thread -** has been interrupted. -*/ -PR_IMPLEMENT(PRStatus) - PR_WaitSem (PRSemaphore *sem) -{ - PR_ASSERT(sem != NULL); - if (acquire_sem(sem->sem) == B_NO_ERROR) - return PR_SUCCESS; - else - return PR_FAILURE; -} - -/* -** This routine increments the counter value of the semaphore. If other -** threads are blocked for the semaphore, then the scheduler will -** determine which ONE thread will be unblocked. -*/ -PR_IMPLEMENT(void) - PR_PostSem (PRSemaphore *sem) -{ - status_t result; - - PR_ASSERT(sem != NULL); - result = release_sem_etc(sem->sem, 1, B_DO_NOT_RESCHEDULE); - PR_ASSERT(result == B_NO_ERROR); -} - -/* -** Returns the value of the semaphore referenced by sem without affecting -** the state of the semaphore. The value represents the semaphore value -** at the time of the call, but may not be the actual value when the -** caller inspects it. -*/ -PR_IMPLEMENT(PRUintn) - PR_GetValueSem (PRSemaphore *sem) -{ - sem_info info; - - PR_ASSERT(sem != NULL); - get_sem_info(sem->sem, &info); - return info.count; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btthread.c nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btthread.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/btthread.c 2012-03-06 13:14:02.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/btthread.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,662 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include - -#include "prlog.h" -#include "primpl.h" -#include "prcvar.h" -#include "prpdce.h" - -#include -#include -#include - -/* values for PRThread.state */ -#define BT_THREAD_PRIMORD 0x01 /* this is the primordial thread */ -#define BT_THREAD_SYSTEM 0x02 /* this is a system thread */ -#define BT_THREAD_JOINABLE 0x04 /* this is a joinable thread */ - -struct _BT_Bookeeping -{ - PRLock *ml; /* a lock to protect ourselves */ - sem_id cleanUpSem; /* the primoridal thread will block on this - sem while waiting for the user threads */ - PRInt32 threadCount; /* user thred count */ - -} bt_book = { NULL, B_ERROR, 0 }; - - -#define BT_TPD_LIMIT 128 /* number of TPD slots we'll provide (arbitrary) */ - -/* these will be used to map an index returned by PR_NewThreadPrivateIndex() - to the corresponding beos native TLS slot number, and to the destructor - for that slot - note that, because it is allocated globally, this data - will be automatically zeroed for us when the program begins */ -static int32 tpd_beosTLSSlots[BT_TPD_LIMIT]; -static PRThreadPrivateDTOR tpd_dtors[BT_TPD_LIMIT]; - -static vint32 tpd_slotsUsed=0; /* number of currently-allocated TPD slots */ -static int32 tls_prThreadSlot; /* TLS slot in which PRThread will be stored */ - -/* this mutex will be used to synchronize access to every - PRThread.md.joinSem and PRThread.md.is_joining (we could - actually allocate one per thread, but that seems a bit excessive, - especially considering that there will probably be little - contention, PR_JoinThread() is allowed to block anyway, and the code - protected by the mutex is short/fast) */ -static PRLock *joinSemLock; - -static PRUint32 _bt_MapNSPRToNativePriority( PRThreadPriority priority ); -static PRThreadPriority _bt_MapNativeToNSPRPriority( PRUint32 priority ); -static void _bt_CleanupThread(void *arg); -static PRThread *_bt_AttachThread(); - -void -_PR_InitThreads (PRThreadType type, PRThreadPriority priority, - PRUintn maxPTDs) -{ - PRThread *primordialThread; - PRUint32 beThreadPriority; - - /* allocate joinSem mutex */ - joinSemLock = PR_NewLock(); - if (joinSemLock == NULL) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return; - } - - /* - ** Create and initialize NSPR structure for our primordial thread. - */ - - primordialThread = PR_NEWZAP(PRThread); - if( NULL == primordialThread ) - { - PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 ); - return; - } - - primordialThread->md.joinSem = B_ERROR; - - /* - ** Set the priority to the desired level. - */ - - beThreadPriority = _bt_MapNSPRToNativePriority( priority ); - - set_thread_priority( find_thread( NULL ), beThreadPriority ); - - primordialThread->priority = priority; - - - /* set the thread's state - note that the thread is not joinable */ - primordialThread->state |= BT_THREAD_PRIMORD; - if (type == PR_SYSTEM_THREAD) - primordialThread->state |= BT_THREAD_SYSTEM; - - /* - ** Allocate a TLS slot for the PRThread structure (just using - ** native TLS, as opposed to NSPR TPD, will make PR_GetCurrentThread() - ** somewhat faster, and will leave one more TPD slot for our client) - */ - - tls_prThreadSlot = tls_allocate(); - - /* - ** Stuff our new PRThread structure into our thread specific - ** slot. - */ - - tls_set(tls_prThreadSlot, primordialThread); - - /* allocate lock for bt_book */ - bt_book.ml = PR_NewLock(); - if( NULL == bt_book.ml ) - { - PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 ); - return; - } -} - -PRUint32 -_bt_MapNSPRToNativePriority( PRThreadPriority priority ) - { - switch( priority ) - { - case PR_PRIORITY_LOW: return( B_LOW_PRIORITY ); - case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY ); - case PR_PRIORITY_HIGH: return( B_DISPLAY_PRIORITY ); - case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY ); - default: return( B_NORMAL_PRIORITY ); - } -} - -PRThreadPriority -_bt_MapNativeToNSPRPriority(PRUint32 priority) - { - if (priority < B_NORMAL_PRIORITY) - return PR_PRIORITY_LOW; - if (priority < B_DISPLAY_PRIORITY) - return PR_PRIORITY_NORMAL; - if (priority < B_URGENT_DISPLAY_PRIORITY) - return PR_PRIORITY_HIGH; - return PR_PRIORITY_URGENT; -} - -PRUint32 -_bt_mapNativeToNSPRPriority( int32 priority ) -{ - switch( priority ) - { - case PR_PRIORITY_LOW: return( B_LOW_PRIORITY ); - case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY ); - case PR_PRIORITY_HIGH: return( B_DISPLAY_PRIORITY ); - case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY ); - default: return( B_NORMAL_PRIORITY ); - } -} - -/* This method is called by all NSPR threads as they exit */ -void _bt_CleanupThread(void *arg) -{ - PRThread *me = PR_GetCurrentThread(); - int32 i; - - /* first, clean up all thread-private data */ - for (i = 0; i < tpd_slotsUsed; i++) - { - void *oldValue = tls_get(tpd_beosTLSSlots[i]); - if ( oldValue != NULL && tpd_dtors[i] != NULL ) - (*tpd_dtors[i])(oldValue); - } - - /* if this thread is joinable, wait for someone to join it */ - if (me->state & BT_THREAD_JOINABLE) - { - /* protect access to our joinSem */ - PR_Lock(joinSemLock); - - if (me->md.is_joining) - { - /* someone is already waiting to join us (they've - allocated a joinSem for us) - let them know we're - ready */ - delete_sem(me->md.joinSem); - - PR_Unlock(joinSemLock); - - } - else - { - /* noone is currently waiting for our demise - it - is our responsibility to allocate the joinSem - and block on it */ - me->md.joinSem = create_sem(0, "join sem"); - - /* we're done accessing our joinSem */ - PR_Unlock(joinSemLock); - - /* wait for someone to join us */ - while (acquire_sem(me->md.joinSem) == B_INTERRUPTED); - } - } - - /* if this is a user thread, we must update our books */ - if ((me->state & BT_THREAD_SYSTEM) == 0) - { - /* synchronize access to bt_book */ - PR_Lock( bt_book.ml ); - - /* decrement the number of currently-alive user threads */ - bt_book.threadCount--; - - if (bt_book.threadCount == 0 && bt_book.cleanUpSem != B_ERROR) { - /* we are the last user thread, and the primordial thread is - blocked in PR_Cleanup() waiting for us to finish - notify - it */ - delete_sem(bt_book.cleanUpSem); - } - - PR_Unlock( bt_book.ml ); - } - - /* finally, delete this thread's PRThread */ - PR_DELETE(me); -} - -/** - * This is a wrapper that all threads invoke that allows us to set some - * things up prior to a thread's invocation and clean up after a thread has - * exited. - */ -static void* -_bt_root (void* arg) - { - PRThread *thred = (PRThread*)arg; - PRIntn rv; - void *privData; - status_t result; - int i; - - /* save our PRThread object into our TLS */ - tls_set(tls_prThreadSlot, thred); - - thred->startFunc(thred->arg); /* run the dang thing */ - - /* clean up */ - _bt_CleanupThread(NULL); - - return 0; -} - -PR_IMPLEMENT(PRThread*) - PR_CreateThread (PRThreadType type, void (*start)(void* arg), void* arg, - PRThreadPriority priority, PRThreadScope scope, - PRThreadState state, PRUint32 stackSize) -{ - PRUint32 bePriority; - - PRThread* thred; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - thred = PR_NEWZAP(PRThread); - if (thred == NULL) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - thred->md.joinSem = B_ERROR; - - thred->arg = arg; - thred->startFunc = start; - thred->priority = priority; - - if( state == PR_JOINABLE_THREAD ) - { - thred->state |= BT_THREAD_JOINABLE; - } - - /* keep some books */ - - PR_Lock( bt_book.ml ); - - if (type == PR_USER_THREAD) - { - bt_book.threadCount++; - } - - PR_Unlock( bt_book.ml ); - - bePriority = _bt_MapNSPRToNativePriority( priority ); - - thred->md.tid = spawn_thread((thread_func)_bt_root, "moz-thread", - bePriority, thred); - if (thred->md.tid < B_OK) { - PR_SetError(PR_UNKNOWN_ERROR, thred->md.tid); - PR_DELETE(thred); - return NULL; - } - - if (resume_thread(thred->md.tid) < B_OK) { - PR_SetError(PR_UNKNOWN_ERROR, 0); - PR_DELETE(thred); - return NULL; - } - - return thred; - } - -PR_IMPLEMENT(PRThread*) - PR_AttachThread(PRThreadType type, PRThreadPriority priority, - PRThreadStack *stack) -{ - /* PR_GetCurrentThread() will attach a thread if necessary */ - return PR_GetCurrentThread(); -} - -PR_IMPLEMENT(void) - PR_DetachThread() -{ - /* we don't support detaching */ -} - -PR_IMPLEMENT(PRStatus) - PR_JoinThread (PRThread* thred) -{ - status_t eval, status; - - PR_ASSERT(thred != NULL); - - if ((thred->state & BT_THREAD_JOINABLE) == 0) - { - PR_SetError( PR_INVALID_ARGUMENT_ERROR, 0 ); - return( PR_FAILURE ); - } - - /* synchronize access to the thread's joinSem */ - PR_Lock(joinSemLock); - - if (thred->md.is_joining) - { - /* another thread is already waiting to join the specified - thread - we must fail */ - PR_Unlock(joinSemLock); - return PR_FAILURE; - } - - /* let others know we are waiting to join */ - thred->md.is_joining = PR_TRUE; - - if (thred->md.joinSem == B_ERROR) - { - /* the thread hasn't finished yet - it is our responsibility to - allocate a joinSem and wait on it */ - thred->md.joinSem = create_sem(0, "join sem"); - - /* we're done changing the joinSem now */ - PR_Unlock(joinSemLock); - - /* wait for the thread to finish */ - while (acquire_sem(thred->md.joinSem) == B_INTERRUPTED); - - } - else - { - /* the thread has already finished, and has allocated the - joinSem itself - let it know it can finally die */ - delete_sem(thred->md.joinSem); - - PR_Unlock(joinSemLock); - } - - /* make sure the thread is dead */ - wait_for_thread(thred->md.tid, &eval); - - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRThread*) - PR_GetCurrentThread () -{ - PRThread* thred; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - thred = (PRThread *)tls_get( tls_prThreadSlot); - if (thred == NULL) - { - /* this thread doesn't have a PRThread structure (it must be - a native thread not created by the NSPR) - assimilate it */ - thred = _bt_AttachThread(); - } - PR_ASSERT(NULL != thred); - - return thred; -} - -PR_IMPLEMENT(PRThreadScope) - PR_GetThreadScope (const PRThread* thred) -{ - PR_ASSERT(thred != NULL); - return PR_GLOBAL_THREAD; -} - -PR_IMPLEMENT(PRThreadType) - PR_GetThreadType (const PRThread* thred) -{ - PR_ASSERT(thred != NULL); - return (thred->state & BT_THREAD_SYSTEM) ? - PR_SYSTEM_THREAD : PR_USER_THREAD; -} - -PR_IMPLEMENT(PRThreadState) - PR_GetThreadState (const PRThread* thred) -{ - PR_ASSERT(thred != NULL); - return (thred->state & BT_THREAD_JOINABLE)? - PR_JOINABLE_THREAD: PR_UNJOINABLE_THREAD; -} - -PR_IMPLEMENT(PRThreadPriority) - PR_GetThreadPriority (const PRThread* thred) -{ - PR_ASSERT(thred != NULL); - return thred->priority; -} /* PR_GetThreadPriority */ - -PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred, - PRThreadPriority newPri) -{ - PRUint32 bePriority; - - PR_ASSERT( thred != NULL ); - - thred->priority = newPri; - bePriority = _bt_MapNSPRToNativePriority( newPri ); - set_thread_priority( thred->md.tid, bePriority ); -} - -PR_IMPLEMENT(PRStatus) - PR_NewThreadPrivateIndex (PRUintn* newIndex, - PRThreadPrivateDTOR destructor) -{ - int32 index; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - /* reserve the next available tpd slot */ - index = atomic_add( &tpd_slotsUsed, 1 ); - if (index >= BT_TPD_LIMIT) - { - /* no slots left - decrement value, then fail */ - atomic_add( &tpd_slotsUsed, -1 ); - PR_SetError( PR_TPD_RANGE_ERROR, 0 ); - return( PR_FAILURE ); - } - - /* allocate a beos-native TLS slot for this index (the new slot - automatically contains NULL) */ - tpd_beosTLSSlots[index] = tls_allocate(); - - /* remember the destructor */ - tpd_dtors[index] = destructor; - - *newIndex = (PRUintn)index; - - return( PR_SUCCESS ); -} - -PR_IMPLEMENT(PRStatus) - PR_SetThreadPrivate (PRUintn index, void* priv) -{ - void *oldValue; - - /* - ** Sanity checking - */ - - if(index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT) - { - PR_SetError( PR_TPD_RANGE_ERROR, 0 ); - return( PR_FAILURE ); - } - - /* if the old value isn't NULL, and the dtor for this slot isn't - NULL, we must destroy the data */ - oldValue = tls_get(tpd_beosTLSSlots[index]); - if (oldValue != NULL && tpd_dtors[index] != NULL) - (*tpd_dtors[index])(oldValue); - - /* save new value */ - tls_set(tpd_beosTLSSlots[index], priv); - - return( PR_SUCCESS ); - } - -PR_IMPLEMENT(void*) - PR_GetThreadPrivate (PRUintn index) -{ - /* make sure the index is valid */ - if (index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT) - { - PR_SetError( PR_TPD_RANGE_ERROR, 0 ); - return NULL; - } - - /* return the value */ - return tls_get( tpd_beosTLSSlots[index] ); - } - - -PR_IMPLEMENT(PRStatus) - PR_Interrupt (PRThread* thred) -{ - PRIntn rv; - - PR_ASSERT(thred != NULL); - - /* - ** there seems to be a bug in beos R5 in which calling - ** resume_thread() on a blocked thread returns B_OK instead - ** of B_BAD_THREAD_STATE (beos bug #20000422-19095). as such, - ** to interrupt a thread, we will simply suspend then resume it - ** (no longer call resume_thread(), check for B_BAD_THREAD_STATE, - ** the suspend/resume to wake up a blocked thread). this wakes - ** up blocked threads properly, and doesn't hurt unblocked threads - ** (they simply get stopped then re-started immediately) - */ - - rv = suspend_thread( thred->md.tid ); - if( rv != B_NO_ERROR ) - { - /* this doesn't appear to be a valid thread_id */ - PR_SetError( PR_UNKNOWN_ERROR, rv ); - return PR_FAILURE; - } - - rv = resume_thread( thred->md.tid ); - if( rv != B_NO_ERROR ) - { - PR_SetError( PR_UNKNOWN_ERROR, rv ); - return PR_FAILURE; - } - - return PR_SUCCESS; -} - -PR_IMPLEMENT(void) - PR_ClearInterrupt () -{ -} - -PR_IMPLEMENT(PRStatus) - PR_Yield () -{ - /* we just sleep for long enough to cause a reschedule (100 - microseconds) */ - snooze(100); -} - -#define BT_MILLION 1000000UL - -PR_IMPLEMENT(PRStatus) - PR_Sleep (PRIntervalTime ticks) -{ - bigtime_t tps; - status_t status; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - tps = PR_IntervalToMicroseconds( ticks ); - - status = snooze(tps); - if (status == B_NO_ERROR) return PR_SUCCESS; - - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, status); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) - PR_Cleanup () -{ - PRThread *me = PR_GetCurrentThread(); - - PR_ASSERT(me->state & BT_THREAD_PRIMORD); - if ((me->state & BT_THREAD_PRIMORD) == 0) { - return PR_FAILURE; - } - - PR_Lock( bt_book.ml ); - - if (bt_book.threadCount != 0) - { - /* we'll have to wait for some threads to finish - create a - sem to block on */ - bt_book.cleanUpSem = create_sem(0, "cleanup sem"); - } - - PR_Unlock( bt_book.ml ); - - /* note that, if all the user threads were already dead, we - wouldn't have created a sem above, so this acquire_sem() - will fail immediately */ - while (acquire_sem(bt_book.cleanUpSem) == B_INTERRUPTED); - - return PR_SUCCESS; -} - -PR_IMPLEMENT(void) - PR_ProcessExit (PRIntn status) -{ - exit(status); -} - -PRThread *_bt_AttachThread() -{ - PRThread *thread; - thread_info tInfo; - - /* make sure this thread doesn't already have a PRThread structure */ - PR_ASSERT(tls_get(tls_prThreadSlot) == NULL); - - /* allocate a PRThread structure for this thread */ - thread = PR_NEWZAP(PRThread); - if (thread == NULL) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - /* get the native thread's current state */ - get_thread_info(find_thread(NULL), &tInfo); - - /* initialize new PRThread */ - thread->md.tid = tInfo.thread; - thread->md.joinSem = B_ERROR; - thread->priority = _bt_MapNativeToNSPRPriority(tInfo.priority); - - /* attached threads are always non-joinable user threads */ - thread->state = 0; - - /* increment user thread count */ - PR_Lock(bt_book.ml); - bt_book.threadCount++; - PR_Unlock(bt_book.ml); - - /* store this thread's PRThread */ - tls_set(tls_prThreadSlot, thread); - - /* the thread must call _bt_CleanupThread() before it dies, in order - to clean up its PRThread, synchronize with the primordial thread, - etc. */ - on_exit_thread(_bt_CleanupThread, NULL); - - return thread; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/.cvsignore 2001-05-12 06:00:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/Makefile.in 2012-03-06 13:14:01.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -include $(srcdir)/bsrcs.mk -CSRCS += $(BTCSRCS) - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -include $(topsrcdir)/config/rules.mk - -DEFINES += -D_NSPR_BUILD_ - -export:: $(TARGETS) - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/objs.mk nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/objs.mk --- nspr-4.9.5/mozilla/nsprpub/pr/src/bthreads/objs.mk 2012-03-06 13:14:02.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/bthreads/objs.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This makefile appends to the variable OBJS the bthread object modules -# that will be part of the nspr20 library. - -include $(srcdir)/bthreads/bsrcs.mk - -OBJS += $(BTCSRCS:%.c=bthreads/$(OBJDIR)/%.$(OBJ_SUFFIX)) diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/.cvsignore 2001-05-12 06:01:46.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/Makefile.in 2012-03-06 13:14:03.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CXXSRCS = \ - rcbase.cpp \ - rccv.cpp \ - rcfileio.cpp \ - rcinrval.cpp \ - rcio.cpp \ - rclock.cpp \ - rcnetdb.cpp \ - rcnetio.cpp \ - rcthread.cpp \ - rctime.cpp \ - $(NULL) - -OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX))) - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -HEADERS = $(wildcard $(srcdir)/*.h) - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcascii.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcascii.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcascii.h 2012-03-06 13:14:03.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcascii.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,143 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Class definitions to format ASCII data. -*/ - -#if defined(_RCASCII_H) -#else -#define _RCASCII_H - -/* -** RCFormatStuff -** This class maintains no state - that is the responsibility of -** the class' client. For each call to Sx_printf(), the StuffFunction -** will be called for each embedded "%" in the 'fmt' string and once -** for each interveaning literal. -*/ -class PR_IMPLEMENT(RCFormatStuff) -{ -public: - RCFormatStuff(); - virtual ~RCFormatStuff(); - - /* - ** Process the arbitrary argument list using as indicated by - ** the 'fmt' string. Each segment of the processing the stuff - ** function is called with the relavent translation. - */ - virtual PRInt32 Sx_printf(void *state, const char *fmt, ...); - - /* - ** The 'state' argument is not processed by the runtime. It - ** is merely passed from the Sx_printf() call. It is intended - ** to be used by the client to figure out what to do with the - ** new string. - ** - ** The new string ('stuff') is ASCII translation driven by the - ** Sx_printf()'s 'fmt' string. It is not guaranteed to be a null - ** terminated string. - ** - ** The return value is the number of bytes copied from the 'stuff' - ** string. It is accumulated for each of the calls to the stuff - ** function and returned from the original caller of Sx_printf(). - */ - virtual PRSize StuffFunction( - void *state, const char *stuff, PRSize stufflen) = 0; -}; /* RCFormatStuff */ - - -/* -** RCFormatBuffer -** The caller is supplying the buffer, the runtime is doing all -** the conversion. The object contains no state, so is reusable -** and reentrant. -*/ -class PR_IMPLEMENT(RCFormatBuffer): public RCFormatStuff -{ -public: - RCFormatBuffer(); - virtual ~RCFormatBuffer(); - - /* - ** Format the trailing arguments as indicated by the 'fmt' - ** string. Put the result in 'buffer'. Return the number - ** of bytes moved into 'buffer'. 'buffer' will always be - ** a properly terminated string even if the convresion fails. - */ - virtual PRSize Sn_printf( - char *buffer, PRSize length, const char *fmt, ...); - - virtual char *Sm_append(char *buffer, const char *fmt, ...); - -private: - /* - ** This class overrides the stuff function, does not preserve - ** its virtual-ness and no longer allows the clients to call - ** it in the clear. In other words, it is now the implementation - ** for this class. - */ - PRSize StuffFunction(void*, const char*, PRSize); - -}; /* RCFormatBuffer */ - -/* -** RCFormat -** The runtime is supplying the buffer. The object has state - the -** buffer. Each operation must run to completion before the object -** can be reused. When it is, the buffer is reset (whatever that -** means). The result of a conversion is available via the extractor. -** After extracted, the memory still belongs to the class - if the -** caller wants to retain or modify, it must first be copied. -*/ -class PR_IMPLEMENT(RCFormat): pubic RCFormatBuffer -{ -public: - RCFormat(); - virtual ~RCFormat(); - - /* - ** Translate the trailing arguments according to the 'fmt' - ** string and store the results in the object. - */ - virtual PRSize Sm_printf(const char *fmt, ...); - - /* - ** Extract the latest translation. - ** The object does not surrender the memory occupied by - ** the string. If the caller wishes to modify the data, - ** it must first be copied. - */ - const char*(); - -private: - char *buffer; - - RCFormat(const RCFormat&); - RCFormat& operator=(const RCFormat&); -}; /* RCFormat */ - -/* -** RCPrint -** The output is formatted and then written to an associated file -** descriptor. The client can provide a suitable file descriptor -** or can indicate that the output should be directed to one of -** the well-known "console" devices. -*/ -class PR_IMPLEMENT(RCPrint): public RCFormat -{ - virtual ~RCPrint(); - RCPrint(RCIO* output); - RCPrint(RCFileIO::SpecialFile output); - - virtual PRSize Printf(const char *fmt, ...); -private: - RCPrint(); -}; /* RCPrint */ - -#endif /* defined(_RCASCII_H) */ - -/* RCAscii.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcbase.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcbase.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcbase.cpp 2012-03-06 13:14:04.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** RCBase.cpp - Mixin class for NSPR C++ wrappers -*/ - -#include "rcbase.h" - -RCBase::~RCBase() { } - -PRSize RCBase::GetErrorTextLength() { return PR_GetErrorTextLength(); } -PRSize RCBase::CopyErrorText(char *text) { return PR_GetErrorText(text); } - -void RCBase::SetError(PRErrorCode error, PRInt32 oserror) - { PR_SetError(error, oserror); } - -void RCBase::SetErrorText(PRSize text_length, const char *text) - { PR_SetErrorText(text_length, text); } - -/* rcbase.cpp */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcbase.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcbase.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcbase.h 2012-03-06 13:14:05.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** RCBase.h - Mixin class for NSPR C++ wrappers -*/ - -#if defined(_RCRUNTIME_H) -#else -#define _RCRUNTIME_H - -#include - -/* -** Class: RCBase (mixin) -** -** Generally mixed into every base class. The functions in this class are all -** static. Therefore this entire class is just syntatic sugar. It gives the -** illusion that errors (in particular) are retrieved via the same object -** that just reported a failure. It also (unfortunately) might lead one to -** believe that the errors are persistent in that object. They're not. -*/ - -class PR_IMPLEMENT(RCBase) -{ -public: - virtual ~RCBase(); - - static void AbortSelf(); - - static PRErrorCode GetError(); - static PRInt32 GetOSError(); - - static PRSize GetErrorTextLength(); - static PRSize CopyErrorText(char *text); - - static void SetError(PRErrorCode error, PRInt32 oserror); - static void SetErrorText(PRSize textLength, const char *text); - -protected: - RCBase() { } -}; /* RCObject */ - -inline PRErrorCode RCBase::GetError() { return PR_GetError(); } -inline PRInt32 RCBase::GetOSError() { return PR_GetOSError(); } - -#endif /* defined(_RCRUNTIME_H) */ - -/* rcbase.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rccv.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rccv.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rccv.cpp 2012-03-06 13:14:05.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rccv.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** RCCondition - C++ wrapper around NSPR's PRCondVar -*/ - -#include "rccv.h" - -#include -#include -#include - -RCCondition::RCCondition(class RCLock *lock): RCBase() -{ - cv = PR_NewCondVar(lock->lock); - PR_ASSERT(NULL != cv); - timeout = PR_INTERVAL_NO_TIMEOUT; -} /* RCCondition::RCCondition */ - -RCCondition::~RCCondition() -{ - if (NULL != cv) PR_DestroyCondVar(cv); -} /* RCCondition::~RCCondition */ - -PRStatus RCCondition::Wait() -{ - PRStatus rv; - PR_ASSERT(NULL != cv); - if (NULL == cv) - { - SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; - } - else - rv = PR_WaitCondVar(cv, timeout.interval); - return rv; -} /* RCCondition::Wait */ - -PRStatus RCCondition::Notify() -{ - return PR_NotifyCondVar(cv); -} /* RCCondition::Notify */ - -PRStatus RCCondition::Broadcast() -{ - return PR_NotifyAllCondVar(cv); -} /* RCCondition::Broadcast */ - -PRStatus RCCondition::SetTimeout(const RCInterval& tmo) -{ - if (NULL == cv) - { - SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - timeout = tmo; - return PR_SUCCESS; -} /* RCCondition::SetTimeout */ - -RCInterval RCCondition::GetTimeout() const { return timeout; } - -/* rccv.cpp */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rccv.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rccv.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rccv.h 2012-03-06 13:14:05.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rccv.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** RCCondition - C++ wrapper around NSPR's PRCondVar -** -** Conditions have a notion of timeouts. A thread that waits on a condition -** will resume execution when the condition is notified OR when a specified -** interval of time has expired. -** -** Most applications don't adjust the timeouts on conditions. The literature -** would argue that all threads waiting on a single condition must have the -** same semantics. But if an application wishes to modify the timeout with -** (perhaps) each wait call, that modification should be done consistantly -** and under protection of the condition's associated lock. -** -** The default timeout is infinity. -*/ - -#if defined(_RCCOND_H) -#else -#define _RCCOND_H - -#include "rclock.h" -#include "rcbase.h" -#include "rcinrval.h" - -struct PRCondVar; - -class PR_IMPLEMENT(RCCondition): public RCBase -{ -public: - RCCondition(RCLock*); /* associates CV with a lock and infinite tmo */ - virtual ~RCCondition(); - - virtual PRStatus Wait(); /* applies object's current timeout */ - - virtual PRStatus Notify(); /* perhaps ready one thread */ - virtual PRStatus Broadcast(); /* perhaps ready many threads */ - - virtual PRStatus SetTimeout(const RCInterval&); - /* set object's current timeout value */ - -private: - PRCondVar *cv; - RCInterval timeout; - - RCCondition(); - RCCondition(const RCCondition&); - void operator=(const RCCondition&); - -public: - RCInterval GetTimeout() const; -}; /* RCCondition */ - -inline RCCondition::RCCondition(): RCBase() { } -inline RCCondition::RCCondition(const RCCondition&): RCBase() { } -inline void RCCondition::operator=(const RCCondition&) { } - -#endif /* defined(_RCCOND_H) */ - -/* RCCond.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcfileio.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcfileio.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcfileio.cpp 2012-03-06 13:14:05.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcfileio.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,167 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Class implementation for normal and special file I/O (ref: prio.h) -*/ - -#include "rcfileio.h" - -#include - -RCFileIO::RCFileIO(): RCIO(RCIO::file) { } - -RCFileIO::~RCFileIO() { if (NULL != fd) (void)Close(); } - -PRInt64 RCFileIO::Available() - { return fd->methods->available(fd); } - -PRStatus RCFileIO::Close() - { PRStatus rv = fd->methods->close(fd); fd = NULL; return rv; } - -PRStatus RCFileIO::Delete(const char* filename) { return PR_Delete(filename); } - -PRStatus RCFileIO::FileInfo(RCFileInfo* info) const - { return fd->methods->fileInfo64(fd, &info->info); } - -PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo* info) - { return PR_GetFileInfo64(name, &info->info); } - -PRStatus RCFileIO::Fsync() - { return fd->methods->fsync(fd); } - -PRStatus RCFileIO::Open(const char *filename, PRIntn flags, PRIntn mode) -{ - fd = PR_Open(filename, flags, mode); - return (NULL == fd) ? PR_FAILURE : PR_SUCCESS; -} /* RCFileIO::Open */ - -PRInt32 RCFileIO::Read(void *buf, PRSize amount) - { return fd->methods->read(fd, buf, amount); } - -PRInt64 RCFileIO::Seek(PRInt64 offset, RCIO::Whence how) -{ - PRSeekWhence whence; - switch (how) - { - case RCFileIO::set: whence = PR_SEEK_SET; break; - case RCFileIO::current: whence = PR_SEEK_CUR; break; - case RCFileIO::end: whence = PR_SEEK_END; break; - default: whence = (PRSeekWhence)-1; - } - return fd->methods->seek64(fd, offset, whence); -} /* RCFileIO::Seek */ - -PRInt32 RCFileIO::Write(const void *buf, PRSize amount) - { return fd->methods->write(fd, buf, amount); } - -PRInt32 RCFileIO::Writev( - const PRIOVec *iov, PRSize size, const RCInterval& timeout) - { return fd->methods->writev(fd, iov, size, timeout); } - -RCIO *RCFileIO::GetSpecialFile(RCFileIO::SpecialFile special) -{ - PRFileDesc* fd; - PRSpecialFD which; - RCFileIO* spec = NULL; - - switch (special) - { - case RCFileIO::input: which = PR_StandardInput; break; - case RCFileIO::output: which = PR_StandardOutput; break; - case RCFileIO::error: which = PR_StandardError; break; - default: which = (PRSpecialFD)-1; - } - fd = PR_GetSpecialFD(which); - if (NULL != fd) - { - spec = new RCFileIO(); - if (NULL != spec) spec->fd = fd; - } - return spec; -} /* RCFileIO::GetSpecialFile */ - - -/* -** The following methods have been made non-virtual and private. These -** default implementations are intended to NEVER be called. They -** are not valid for this type of I/O class (normal and special file). -*/ -PRStatus RCFileIO::Connect(const RCNetAddr&, const RCInterval&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRStatus RCFileIO::GetLocalName(RCNetAddr*) const -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRStatus RCFileIO::GetPeerName(RCNetAddr*) const -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRStatus RCFileIO::GetSocketOption(PRSocketOptionData*) const -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRStatus RCFileIO::Listen(PRIntn) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRInt16 RCFileIO::Poll(PRInt16, PRInt16*) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return 0; } - -PRInt32 RCFileIO::Recv(void*, PRSize, PRIntn, const RCInterval&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } - -PRInt32 RCFileIO::Recvfrom(void*, PRSize, PRIntn, RCNetAddr*, const RCInterval&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } - -PRInt32 RCFileIO::Send( - const void*, PRSize, PRIntn, const RCInterval&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } - -PRInt32 RCFileIO::Sendto( - const void*, PRSize, PRIntn, const RCNetAddr&, const RCInterval&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } - -RCIO* RCFileIO::Accept(RCNetAddr*, const RCInterval&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return NULL; } - -PRStatus RCFileIO::Bind(const RCNetAddr&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRInt32 RCFileIO::AcceptRead( - RCIO**, RCNetAddr**, void*, PRSize, const RCInterval&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } - -PRStatus RCFileIO::SetSocketOption(const PRSocketOptionData*) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRStatus RCFileIO::Shutdown(RCIO::ShutdownHow) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRInt32 RCFileIO::TransmitFile( - RCIO*, const void*, PRSize, RCIO::FileDisposition, const RCInterval&) -{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } - -/* -** Class implementation for file information object (ref: prio.h) -*/ - -RCFileInfo::~RCFileInfo() { } - -RCFileInfo::RCFileInfo(const RCFileInfo& her): RCBase() - { info = her.info; } /* RCFileInfo::RCFileInfo */ - -RCTime RCFileInfo::CreationTime() const { return RCTime(info.creationTime); } - -RCTime RCFileInfo::ModifyTime() const { return RCTime(info.modifyTime); } - -RCFileInfo::FileType RCFileInfo::Type() const -{ - RCFileInfo::FileType type; - switch (info.type) - { - case PR_FILE_FILE: type = RCFileInfo::file; break; - case PR_FILE_DIRECTORY: type = RCFileInfo::directory; break; - default: type = RCFileInfo::other; - } - return type; -} /* RCFileInfo::Type */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcfileio.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcfileio.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcfileio.h 2012-03-06 13:14:06.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcfileio.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Class definitions for normal and special file I/O (ref: prio.h) -*/ - -#if defined(_RCFILEIO_H) -#else -#define _RCFILEIO_H - -#include "rcio.h" -#include "rctime.h" - -/* -** One would normally create a concrete class, such as RCFileIO, but then -** pass around more generic references, ie., RCIO. -** -** This subclass of RCIO hides (makes private) the methods that are not -** applicable to normal files. -*/ - -class RCFileInfo; - -class PR_IMPLEMENT(RCFileIO): public RCIO -{ -public: - RCFileIO(); - virtual ~RCFileIO(); - - virtual PRInt64 Available(); - virtual PRStatus Close(); - static PRStatus Delete(const char *name); - virtual PRStatus FileInfo(RCFileInfo* info) const; - static PRStatus FileInfo(const char *name, RCFileInfo* info); - virtual PRStatus Fsync(); - virtual PRStatus Open(const char *name, PRIntn flags, PRIntn mode); - virtual PRInt32 Read(void *buf, PRSize amount); - virtual PRInt64 Seek(PRInt64 offset, RCIO::Whence how); - virtual PRInt32 Write(const void *buf, PRSize amount); - virtual PRInt32 Writev( - const PRIOVec *iov, PRSize size, - const RCInterval& timeout); - -private: - - /* These methods made private are unavailable for this object */ - RCFileIO(const RCFileIO&); - void operator=(const RCFileIO&); - - RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout); - PRInt32 AcceptRead( - RCIO **newfd, RCNetAddr **address, void *buffer, - PRSize amount, const RCInterval& timeout); - PRStatus Bind(const RCNetAddr& addr); - PRStatus Connect(const RCNetAddr& addr, const RCInterval& timeout); - PRStatus GetLocalName(RCNetAddr *addr) const; - PRStatus GetPeerName(RCNetAddr *addr) const; - PRStatus GetSocketOption(PRSocketOptionData *data) const; - PRStatus Listen(PRIntn backlog); - PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags); - PRInt32 Recv( - void *buf, PRSize amount, PRIntn flags, - const RCInterval& timeout); - PRInt32 Recvfrom( - void *buf, PRSize amount, PRIntn flags, - RCNetAddr* addr, const RCInterval& timeout); - PRInt32 Send( - const void *buf, PRSize amount, PRIntn flags, - const RCInterval& timeout); - PRInt32 Sendto( - const void *buf, PRSize amount, PRIntn flags, - const RCNetAddr& addr, - const RCInterval& timeout); - PRStatus SetSocketOption(const PRSocketOptionData *data); - PRStatus Shutdown(RCIO::ShutdownHow how); - PRInt32 TransmitFile( - RCIO *source, const void *headers, - PRSize hlen, RCIO::FileDisposition flags, - const RCInterval& timeout); -public: - - /* - ** The following function return a valid normal file object, - ** Such objects can be used for scanned input and console output. - */ - typedef enum { - input = PR_StandardInput, - output = PR_StandardOutput, - error = PR_StandardError - } SpecialFile; - - static RCIO *GetSpecialFile(RCFileIO::SpecialFile special); - -}; /* RCFileIO */ - -class PR_IMPLEMENT(RCFileInfo): public RCBase -{ -public: - typedef enum { - file = PR_FILE_FILE, - directory = PR_FILE_DIRECTORY, - other = PR_FILE_OTHER - } FileType; - -public: - RCFileInfo(); - RCFileInfo(const RCFileInfo&); - - virtual ~RCFileInfo(); - - PRInt64 Size() const; - RCTime CreationTime() const; - RCTime ModifyTime() const; - RCFileInfo::FileType Type() const; - -friend PRStatus RCFileIO::FileInfo(RCFileInfo*) const; -friend PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo*); - -private: - PRFileInfo64 info; -}; /* RCFileInfo */ - -inline RCFileInfo::RCFileInfo(): RCBase() { } -inline PRInt64 RCFileInfo::Size() const { return info.size; } - -#endif /* defined(_RCFILEIO_H) */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcinrval.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcinrval.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcinrval.cpp 2012-03-06 13:14:06.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcinrval.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** C++ interval times (ref: prinrval.h) -** -** An interval is a period of time. The start of the interval (epoch) -** must be defined by the application. The unit of time of an interval -** is platform dependent, therefore so is the maximum interval that is -** representable. However, that interval is never less that ~12 hours. -*/ - -#include "rcinrval.h" - -RCInterval::~RCInterval() { } - -RCInterval::RCInterval(RCInterval::RCReservedInterval special): RCBase() -{ - switch (special) - { - case RCInterval::now: - interval = PR_IntervalNow(); - break; - case RCInterval::no_timeout: - interval = PR_INTERVAL_NO_TIMEOUT; - break; - case RCInterval::no_wait: - interval = PR_INTERVAL_NO_WAIT; - break; - default: - break; - } -} /* RCInterval::RCInterval */ - -/* rcinrval.cpp */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcinrval.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcinrval.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcinrval.h 2012-03-06 13:14:07.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcinrval.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** C++ interval times (ref: prinrval.h) -** -** An interval is a period of time. The start of the interval (epoch) -** must be defined by the application. The unit of time of an interval -** is platform dependent, therefore so is the maximum interval that is -** representable. However, that interval is never less than ~6 hours. -*/ -#if defined(_RCINTERVAL_H) -#else -#define _RCINTERVAL_H - -#include "rcbase.h" -#include - -class PR_IMPLEMENT(RCInterval): public RCBase -{ -public: - typedef enum {now, no_timeout, no_wait} RCReservedInterval; - - virtual ~RCInterval(); - - RCInterval(); - - RCInterval(PRIntervalTime interval); - RCInterval(const RCInterval& copy); - RCInterval(RCReservedInterval special); - - void SetToNow(); - - void operator=(const RCInterval&); - void operator=(PRIntervalTime interval); - - PRBool operator<(const RCInterval&); - PRBool operator>(const RCInterval&); - PRBool operator==(const RCInterval&); - PRBool operator>=(const RCInterval&); - PRBool operator<=(const RCInterval&); - - RCInterval operator+(const RCInterval&); - RCInterval operator-(const RCInterval&); - RCInterval& operator+=(const RCInterval&); - RCInterval& operator-=(const RCInterval&); - - RCInterval operator/(PRUint32); - RCInterval operator*(PRUint32); - RCInterval& operator/=(PRUint32); - RCInterval& operator*=(PRUint32); - - - PRUint32 ToSeconds() const; - PRUint32 ToMilliseconds() const; - PRUint32 ToMicroseconds() const; - operator PRIntervalTime() const; - - static PRIntervalTime FromSeconds(PRUint32 seconds); - static PRIntervalTime FromMilliseconds(PRUint32 milli); - static PRIntervalTime FromMicroseconds(PRUint32 micro); - - friend class RCCondition; - -private: - PRIntervalTime interval; - -}; /* RCInterval */ - - -inline RCInterval::RCInterval(): RCBase() { } - -inline RCInterval::RCInterval(const RCInterval& his): RCBase() - { interval = his.interval; } - -inline RCInterval::RCInterval(PRIntervalTime ticks): RCBase() - { interval = ticks; } - -inline void RCInterval::SetToNow() { interval = PR_IntervalNow(); } - -inline void RCInterval::operator=(const RCInterval& his) - { interval = his.interval; } - -inline void RCInterval::operator=(PRIntervalTime his) - { interval = his; } - -inline PRBool RCInterval::operator==(const RCInterval& his) - { return (interval == his.interval) ? PR_TRUE : PR_FALSE; } -inline PRBool RCInterval::operator<(const RCInterval& his) - { return (interval < his.interval)? PR_TRUE : PR_FALSE; } -inline PRBool RCInterval::operator>(const RCInterval& his) - { return (interval > his.interval) ? PR_TRUE : PR_FALSE; } -inline PRBool RCInterval::operator<=(const RCInterval& his) - { return (interval <= his.interval) ? PR_TRUE : PR_FALSE; } -inline PRBool RCInterval::operator>=(const RCInterval& his) - { return (interval <= his.interval) ? PR_TRUE : PR_FALSE; } - -inline RCInterval RCInterval::operator+(const RCInterval& his) - { return RCInterval((PRIntervalTime)(interval + his.interval)); } -inline RCInterval RCInterval::operator-(const RCInterval& his) - { return RCInterval((PRIntervalTime)(interval - his.interval)); } -inline RCInterval& RCInterval::operator+=(const RCInterval& his) - { interval += his.interval; return *this; } -inline RCInterval& RCInterval::operator-=(const RCInterval& his) - { interval -= his.interval; return *this; } - -inline RCInterval RCInterval::operator/(PRUint32 him) - { return RCInterval((PRIntervalTime)(interval / him)); } -inline RCInterval RCInterval::operator*(PRUint32 him) - { return RCInterval((PRIntervalTime)(interval * him)); } - -inline RCInterval& RCInterval::operator/=(PRUint32 him) - { interval /= him; return *this; } - -inline RCInterval& RCInterval::operator*=(PRUint32 him) - { interval *= him; return *this; } - -inline PRUint32 RCInterval::ToSeconds() const - { return PR_IntervalToSeconds(interval); } -inline PRUint32 RCInterval::ToMilliseconds() const - { return PR_IntervalToMilliseconds(interval); } -inline PRUint32 RCInterval::ToMicroseconds() const - { return PR_IntervalToMicroseconds(interval); } -inline RCInterval::operator PRIntervalTime() const { return interval; } - -inline PRIntervalTime RCInterval::FromSeconds(PRUint32 seconds) - { return PR_SecondsToInterval(seconds); } -inline PRIntervalTime RCInterval::FromMilliseconds(PRUint32 milli) - { return PR_MillisecondsToInterval(milli); } -inline PRIntervalTime RCInterval::FromMicroseconds(PRUint32 micro) - { return PR_MicrosecondsToInterval(micro); } - -#endif /* defined(_RCINTERVAL_H) */ - -/* RCInterval.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcio.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcio.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcio.cpp 2012-03-06 13:14:07.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcio.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Base class implmenation for I/O (ref: prio.h) -*/ - -#include "rcio.h" - -RCIO::~RCIO() { } - -RCIO::RCIO(RCIO::RCIOType): RCBase() { } diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcio.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcio.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcio.h 2012-03-06 13:14:07.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcio.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Base class definitions for I/O (ref: prio.h) -** -** This class is a virtual base class. Construction must be done by a -** subclass, but the I/O operations can be done on a RCIO object reference. -*/ - -#if defined(_RCIO_H) -#else -#define _RCIO_H - -#include "rcbase.h" -#include "rcnetdb.h" -#include "rcinrval.h" - -#include "prio.h" - -class RCFileInfo; - -class PR_IMPLEMENT(RCIO): public RCBase -{ -public: - typedef enum { - open = PR_TRANSMITFILE_KEEP_OPEN, /* socket is left open after file - * is transmitted. */ - close = PR_TRANSMITFILE_CLOSE_SOCKET/* socket is closed after file - * is transmitted. */ - } FileDisposition; - - typedef enum { - set = PR_SEEK_SET, /* Set to value specified */ - current = PR_SEEK_CUR, /* Seek relative to current position */ - end = PR_SEEK_END /* seek past end of current eof */ - } Whence; - - typedef enum { - recv = PR_SHUTDOWN_RCV, /* receives will be disallowed */ - send = PR_SHUTDOWN_SEND, /* sends will be disallowed */ - both = PR_SHUTDOWN_BOTH /* sends & receives will be disallowed */ - } ShutdownHow; - -public: - virtual ~RCIO(); - - virtual RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout) = 0; - virtual PRInt32 AcceptRead( - RCIO **nd, RCNetAddr **raddr, void *buf, - PRSize amount, const RCInterval& timeout) = 0; - virtual PRInt64 Available() = 0; - virtual PRStatus Bind(const RCNetAddr& addr) = 0; - virtual PRStatus Close() = 0; - virtual PRStatus Connect( - const RCNetAddr& addr, - const RCInterval& timeout) = 0; - virtual PRStatus FileInfo(RCFileInfo *info) const = 0; - virtual PRStatus Fsync() = 0; - virtual PRStatus GetLocalName(RCNetAddr *addr) const = 0; - virtual PRStatus GetPeerName(RCNetAddr *addr) const = 0; - virtual PRStatus GetSocketOption(PRSocketOptionData *data) const = 0; - virtual PRStatus Listen(PRIntn backlog) = 0; - virtual PRStatus Open(const char *name, PRIntn flags, PRIntn mode) = 0; - virtual PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags) = 0; - virtual PRInt32 Read(void *buf, PRSize amount) = 0; - virtual PRInt32 Recv( - void *buf, PRSize amount, PRIntn flags, - const RCInterval& timeout) = 0; - virtual PRInt32 Recvfrom( - void *buf, PRSize amount, PRIntn flags, - RCNetAddr* addr, const RCInterval& timeout) = 0; - virtual PRInt64 Seek(PRInt64 offset, Whence how) = 0; - virtual PRInt32 Send( - const void *buf, PRSize amount, PRIntn flags, - const RCInterval& timeout) = 0; - virtual PRInt32 Sendto( - const void *buf, PRSize amount, PRIntn flags, - const RCNetAddr& addr, - const RCInterval& timeout) = 0; - virtual PRStatus SetSocketOption(const PRSocketOptionData *data) = 0; - virtual PRStatus Shutdown(ShutdownHow how) = 0; - virtual PRInt32 TransmitFile( - RCIO *source, const void *headers, - PRSize hlen, RCIO::FileDisposition flags, - const RCInterval& timeout) = 0; - virtual PRInt32 Write(const void *buf, PRSize amount) = 0; - virtual PRInt32 Writev( - const PRIOVec *iov, PRSize size, - const RCInterval& timeout) = 0; - -protected: - typedef enum { - file = PR_DESC_FILE, - tcp = PR_DESC_SOCKET_TCP, - udp = PR_DESC_SOCKET_UDP, - layered = PR_DESC_LAYERED} RCIOType; - - RCIO(RCIOType); - - PRFileDesc *fd; /* where the real code hides */ - -private: - /* no default construction and no copies allowed */ - RCIO(); - RCIO(const RCIO&); - -}; /* RCIO */ - -#endif /* defined(_RCIO_H) */ - -/* RCIO.h */ - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rclock.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rclock.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rclock.cpp 2012-03-06 13:14:07.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rclock.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* -** C++ access to NSPR locks (PRLock) -*/ - -#include "rclock.h" -#include - -RCLock::RCLock() -{ - lock = PR_NewLock(); /* it might be NULL */ - PR_ASSERT(NULL != lock); -} /* RCLock::RCLock */ - -RCLock::~RCLock() -{ - if (NULL != lock) PR_DestroyLock(lock); - lock = NULL; -} /* RCLock::~RCLock */ - -void RCLock::Acquire() -{ - PR_ASSERT(NULL != lock); - PR_Lock(lock); -} /* RCLock::Acquire */ - -void RCLock::Release() -{ - PRStatus rv; - PR_ASSERT(NULL != lock); - rv = PR_Unlock(lock); - PR_ASSERT(PR_SUCCESS == rv); -} /* RCLock::Release */ - -/* RCLock.cpp */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rclock.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rclock.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rclock.h 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rclock.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** C++ access to NSPR locks (PRLock) -*/ - -#if defined(_RCLOCK_H) -#else -#define _RCLOCK_H - -#include "rcbase.h" - -#include - -class PR_IMPLEMENT(RCLock): public RCBase -{ -public: - RCLock(); - virtual ~RCLock(); - - void Acquire(); /* non-reentrant */ - void Release(); /* should be by owning thread */ - - friend class RCCondition; - -private: - RCLock(const RCLock&); /* can't do that */ - void operator=(const RCLock&); /* nor that */ - - PRLock *lock; -}; /* RCLock */ - -/* -** Class: RCEnter -** -** In scope locks. You can only allocate them on the stack. The language -** will insure that they get released (by calling the destructor) when -** the thread leaves scope, even if via an exception. -*/ -class PR_IMPLEMENT(RCEnter) -{ -public: - ~RCEnter(); /* releases the lock */ - RCEnter(RCLock*); /* acquires the lock */ - -private: - RCLock *lock; - - RCEnter(); - RCEnter(const RCEnter&); - void operator=(const RCEnter&); - - void *operator new(PRSize) { return NULL; } - void operator delete(void*) { } -}; /* RCEnter */ - - -inline RCEnter::RCEnter(RCLock* ml) { lock = ml; lock->Acquire(); } -inline RCEnter::~RCEnter() { lock->Release(); lock = NULL; } - -#endif /* defined(_RCLOCK_H) */ - -/* RCLock.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcmon.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcmon.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcmon.h 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcmon.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Class: RCMonitor (ref prmonitor.h) -** -** RCMonitor.h - C++ wrapper around NSPR's monitors -*/ -#if defined(_RCMONITOR_H) -#else -#define _RCMONITOR_H - -#include "rcbase.h" -#include "rcinrval.h" - -struct PRMonitor; - -class PR_IMPLEMENT(RCMonitor): public RCBase -{ -public: - RCMonitor(); /* timeout is infinity */ - virtual ~RCMonitor(); - - virtual void Enter(); /* reentrant entry */ - virtual void Exit(); - - virtual void Notify(); /* possibly enable one thread */ - virtual void NotifyAll(); /* enable all waiters */ - - virtual void Wait(); /* applies object's timeout */ - - virtual void SetTimeout(const RCInterval& timeout); - -private: - PRMonitor *monitor; - RCInterval timeout; - -public: - RCInterval GetTimeout() const; /* get the current value */ - -}; /* RCMonitor */ - -#endif /* defined(_RCMONITOR_H) */ - -/* RCMonitor.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcnetdb.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcnetdb.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcnetdb.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcnetdb.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,200 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Base class implementation for network access functions (ref: prnetdb.h) -*/ - -#include "rclock.h" -#include "rcnetdb.h" - -#include -#include -#include - -RCNetAddr::RCNetAddr(const RCNetAddr& his): RCBase() - { address = his.address; } - -RCNetAddr::RCNetAddr(const RCNetAddr& his, PRUint16 port): RCBase() -{ - address = his.address; - switch (address.raw.family) - { - case PR_AF_INET: address.inet.port = port; break; - case PR_AF_INET6: address.ipv6.port = port; break; - default: break; - } -} /* RCNetAddr::RCNetAddr */ - -RCNetAddr::RCNetAddr(RCNetAddr::HostValue host, PRUint16 port): RCBase() -{ - PRNetAddrValue how; - switch (host) - { - case RCNetAddr::any: how = PR_IpAddrAny; break; - case RCNetAddr::loopback: how = PR_IpAddrLoopback; break; - default: PR_ASSERT(!"This can't happen -- and did!"); - } - (void)PR_InitializeNetAddr(how, port, &address); -} /* RCNetAddr::RCNetAddr */ - -RCNetAddr::~RCNetAddr() { } - -void RCNetAddr::operator=(const RCNetAddr& his) { address = his.address; } - -PRStatus RCNetAddr::FromString(const char* string) - { return PR_StringToNetAddr(string, &address); } - -void RCNetAddr::operator=(const PRNetAddr* addr) { address = *addr; } - -PRBool RCNetAddr::operator==(const RCNetAddr& his) const -{ - PRBool rv = EqualHost(his); - if (rv) - { - switch (address.raw.family) - { - case PR_AF_INET: - rv = (address.inet.port == his.address.inet.port); break; - case PR_AF_INET6: - rv = (address.ipv6.port == his.address.ipv6.port); break; - case PR_AF_LOCAL: - default: break; - } - } - return rv; -} /* RCNetAddr::operator== */ - -PRBool RCNetAddr::EqualHost(const RCNetAddr& his) const -{ - PRBool rv; - switch (address.raw.family) - { - case PR_AF_INET: - rv = (address.inet.ip == his.address.inet.ip); break; - case PR_AF_INET6: - rv = (0 == memcmp( - &address.ipv6.ip, &his.address.ipv6.ip, - sizeof(address.ipv6.ip))); - break; -#if defined(XP_UNIX) - case PR_AF_LOCAL: - rv = (0 == strncmp( - address.local.path, his.address.local.path, - sizeof(address.local.path))); - break; -#endif - default: break; - } - return rv; -} /* RCNetAddr::operator== */ - -PRStatus RCNetAddr::ToString(char *string, PRSize size) const - { return PR_NetAddrToString(&address, string, size); } - -/* -** RCHostLookup -*/ - -RCHostLookup::~RCHostLookup() -{ - if (NULL != address) delete [] address; -} /* RCHostLookup::~RCHostLookup */ - -RCHostLookup::RCHostLookup(): RCBase() -{ - address = NULL; - max_index = 0; -} /* RCHostLookup::RCHostLookup */ - -PRStatus RCHostLookup::ByName(const char* name) -{ - PRStatus rv; - PRNetAddr addr; - PRHostEnt hostentry; - PRIntn index = 0, max; - RCNetAddr* vector = NULL; - RCNetAddr* old_vector = NULL; - void* buffer = PR_Malloc(PR_NETDB_BUF_SIZE); - if (NULL == buffer) return PR_FAILURE; - rv = PR_GetHostByName(name, (char*)buffer, PR_NETDB_BUF_SIZE, &hostentry); - if (PR_SUCCESS == rv) - { - for (max = 0, index = 0;; ++max) - { - index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); - if (0 == index) break; - } - if (max > 0) - { - vector = new RCNetAddr[max]; - while (--max > 0) - { - index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); - if (0 == index) break; - vector[index] = &addr; - } - { - RCEnter entry(&ml); - old_vector = address; - address = vector; - max_index = max; - } - if (NULL != old_vector) delete [] old_vector; - } - } - if (NULL != buffer) PR_DELETE(buffer); - return PR_SUCCESS; -} /* RCHostLookup::ByName */ - -PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr) -{ - PRStatus rv; - PRNetAddr addr; - PRHostEnt hostentry; - PRIntn index = 0, max; - RCNetAddr* vector = NULL; - RCNetAddr* old_vector = NULL; - char *buffer = (char*)PR_Malloc(PR_NETDB_BUF_SIZE); - if (NULL == buffer) return PR_FAILURE; - rv = PR_GetHostByAddr(host_addr, buffer, PR_NETDB_BUF_SIZE, &hostentry); - if (PR_SUCCESS == rv) - { - for (max = 0, index = 0;; ++max) - { - index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); - if (0 == index) break; - } - if (max > 0) - { - vector = new RCNetAddr[max]; - while (--max > 0) - { - index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); - if (0 == index) break; - vector[index] = &addr; - } - { - RCEnter entry(&ml); - old_vector = address; - address = vector; - max_index = max; - } - if (NULL != old_vector) delete [] old_vector; - } - } - if (NULL != buffer) PR_DELETE(buffer); - return PR_SUCCESS; -} /* RCHostLookup::ByAddress */ - -const RCNetAddr* RCHostLookup::operator[](PRUintn which) -{ - RCNetAddr* addr = NULL; - if (which < max_index) - addr = &address[which]; - return addr; -} /* RCHostLookup::operator[] */ - -/* RCNetdb.cpp */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcnetdb.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcnetdb.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcnetdb.h 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcnetdb.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Base class definitions for network access functions (ref: prnetdb.h) -*/ - -#if defined(_RCNETDB_H) -#else -#define _RCNETDB_H - -#include "rclock.h" -#include "rcbase.h" - -#include - -class PR_IMPLEMENT(RCNetAddr): public RCBase -{ -public: - typedef enum { - any = PR_IpAddrAny, /* assign logical INADDR_ANY */ - loopback = PR_IpAddrLoopback /* assign logical INADDR_LOOPBACK */ - } HostValue; - - RCNetAddr(); /* default constructor is unit'd object */ - RCNetAddr(const RCNetAddr&); /* copy constructor */ - RCNetAddr(HostValue, PRUint16 port);/* init'd w/ 'special' assignments */ - RCNetAddr(const RCNetAddr&, PRUint16 port); - /* copy w/ port reassigment */ - - virtual ~RCNetAddr(); - - void operator=(const RCNetAddr&); - - virtual PRBool operator==(const RCNetAddr&) const; - /* compare of all relavent fields */ - virtual PRBool EqualHost(const RCNetAddr&) const; - /* compare of just host field */ - - -public: - - void operator=(const PRNetAddr*); /* construction from more primitive data */ - operator const PRNetAddr*() const; /* extraction of underlying representation */ - virtual PRStatus FromString(const char* string); - /* initialization from an ASCII string */ - virtual PRStatus ToString(char *string, PRSize size) const; - /* convert internal fromat to a string */ - -private: - - PRNetAddr address; - -}; /* RCNetAddr */ - -/* -** Class: RCHostLookup -** -** Abstractions to look up host names and addresses. -** -** This is a stateful class. One looks up the host by name or by -** address, then enumerates over a possibly empty array of network -** addresses. The storage for the addresses is owned by the class. -*/ - -class RCHostLookup: public RCBase -{ -public: - virtual ~RCHostLookup(); - - RCHostLookup(); - - virtual PRStatus ByName(const char* name); - virtual PRStatus ByAddress(const RCNetAddr&); - - virtual const RCNetAddr* operator[](PRUintn); - -private: - RCLock ml; - PRIntn max_index; - RCNetAddr* address; - - RCHostLookup(const RCHostLookup&); - RCHostLookup& operator=(const RCHostLookup&); -}; - -inline RCNetAddr::RCNetAddr(): RCBase() { } -inline RCNetAddr::operator const PRNetAddr*() const { return &address; } - - -#endif /* defined(_RCNETDB_H) */ - -/* RCNetdb.h */ - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcnetio.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcnetio.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcnetio.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcnetio.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,163 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Subclass implementation for streamed network I/O (ref: prio.h) -*/ - -#include "rcnetio.h" - -#include - -RCNetStreamIO::~RCNetStreamIO() - { PRStatus rv = (fd->methods->close)(fd); fd = NULL; } - -RCNetStreamIO::RCNetStreamIO(): RCIO(RCIO::tcp) - { fd = PR_NewTCPSocket(); } - -RCNetStreamIO::RCNetStreamIO(PRIntn protocol): RCIO(RCIO::tcp) - { fd = PR_Socket(PR_AF_INET, PR_SOCK_STREAM, protocol); } - -RCIO* RCNetStreamIO::Accept(RCNetAddr* addr, const RCInterval& timeout) -{ - PRNetAddr peer; - RCNetStreamIO* rcio = NULL; - PRFileDesc* newfd = fd->methods->accept(fd, &peer, timeout); - if (NULL != newfd) - { - rcio = new RCNetStreamIO(); - if (NULL != rcio) - { - *addr = &peer; - rcio->fd = newfd; - } - else - (void)(newfd->methods->close)(newfd); - } - return rcio; -} /* RCNetStreamIO::Accept */ - -PRInt32 RCNetStreamIO::AcceptRead( - RCIO **nd, RCNetAddr **raddr, void *buf, - PRSize amount, const RCInterval& timeout) -{ - PRNetAddr *from; - PRFileDesc *accepted; - PRInt32 rv = (fd->methods->acceptread)( - fd, &accepted, &from, buf, amount, timeout); - if (rv >= 0) - { - RCNetStreamIO *ns = new RCNetStreamIO(); - if (NULL != *nd) ns->fd = accepted; - else {PR_Close(accepted); rv = -1; } - *nd = ns; - } - return rv; -} /* RCNetStreamIO::AcceptRead */ - -PRInt64 RCNetStreamIO::Available() - { return (fd->methods->available64)(fd); } - -PRStatus RCNetStreamIO::Bind(const RCNetAddr& addr) - { return (fd->methods->bind)(fd, addr); } - -PRStatus RCNetStreamIO::Connect(const RCNetAddr& addr, const RCInterval& timeout) - { return (fd->methods->connect)(fd, addr, timeout); } - -PRStatus RCNetStreamIO::GetLocalName(RCNetAddr *addr) const -{ - PRNetAddr local; - PRStatus rv = (fd->methods->getsockname)(fd, &local); - if (PR_SUCCESS == rv) *addr = &local; - return rv; -} /* RCNetStreamIO::GetLocalName */ - -PRStatus RCNetStreamIO::GetPeerName(RCNetAddr *addr) const -{ - PRNetAddr peer; - PRStatus rv = (fd->methods->getpeername)(fd, &peer); - if (PR_SUCCESS == rv) *addr = &peer; - return rv; -} /* RCNetStreamIO::GetPeerName */ - -PRStatus RCNetStreamIO::GetSocketOption(PRSocketOptionData *data) const - { return (fd->methods->getsocketoption)(fd, data); } - -PRStatus RCNetStreamIO::Listen(PRIntn backlog) - { return (fd->methods->listen)(fd, backlog); } - -PRInt16 RCNetStreamIO::Poll(PRInt16 in_flags, PRInt16 *out_flags) - { return (fd->methods->poll)(fd, in_flags, out_flags); } - -PRInt32 RCNetStreamIO::Read(void *buf, PRSize amount) - { return (fd->methods->read)(fd, buf, amount); } - -PRInt32 RCNetStreamIO::Recv( - void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout) - { return (fd->methods->recv)(fd, buf, amount, flags, timeout); } - -PRInt32 RCNetStreamIO::Recvfrom( - void *buf, PRSize amount, PRIntn flags, - RCNetAddr* addr, const RCInterval& timeout) -{ - PRNetAddr peer; - PRInt32 rv = (fd->methods->recvfrom)( - fd, buf, amount, flags, &peer, timeout); - if (-1 != rv) *addr = &peer; - return rv; -} /* RCNetStreamIO::Recvfrom */ - -PRInt32 RCNetStreamIO::Send( - const void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout) - { return (fd->methods->send)(fd, buf, amount, flags, timeout); } - -PRInt32 RCNetStreamIO::Sendto( - const void *buf, PRSize amount, PRIntn flags, - const RCNetAddr& addr, const RCInterval& timeout) - { return (fd->methods->sendto)(fd, buf, amount, flags, addr, timeout); } - -PRStatus RCNetStreamIO::SetSocketOption(const PRSocketOptionData *data) - { return (fd->methods->setsocketoption)(fd, data); } - -PRStatus RCNetStreamIO::Shutdown(RCIO::ShutdownHow how) - { return (fd->methods->shutdown)(fd, (PRIntn)how); } - -PRInt32 RCNetStreamIO::TransmitFile( - RCIO *source, const void *headers, PRSize hlen, - RCIO::FileDisposition flags, const RCInterval& timeout) -{ - RCNetStreamIO *src = (RCNetStreamIO*)source; - return (fd->methods->transmitfile)( - fd, src->fd, headers, hlen, (PRTransmitFileFlags)flags, timeout); } - -PRInt32 RCNetStreamIO::Write(const void *buf, PRSize amount) - { return (fd->methods->write)(fd, buf, amount); } - -PRInt32 RCNetStreamIO::Writev( - const PRIOVec *iov, PRSize size, const RCInterval& timeout) - { return (fd->methods->writev)(fd, iov, size, timeout); } - -/* -** Invalid functions -*/ - -PRStatus RCNetStreamIO::Close() - { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRStatus RCNetStreamIO::FileInfo(RCFileInfo*) const - { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRStatus RCNetStreamIO::Fsync() - { return (fd->methods->fsync)(fd); } - -PRStatus RCNetStreamIO::Open(const char*, PRIntn, PRIntn) - { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -PRInt64 RCNetStreamIO::Seek(PRInt64, RCIO::Whence) - { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } - -/* RCNetStreamIO.cpp */ - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcnetio.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcnetio.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcnetio.h 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcnetio.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Subclass definitions for network I/O (ref: prio.h) -*/ - -#if defined(_RCNETIO_H) -#else -#define _RCNETIO_H - -#include "rcbase.h" -#include "rcinrval.h" -#include "rcio.h" -#include "rcnetdb.h" - -#include "prio.h" - -class RCFileInfo; - -/* -** Class: RCNetStreamIO (ref prio.h) -** -** Streamed (reliable) network I/O (e.g., TCP). -** This class hides (makes private) the functions that are not applicable -** to network I/O (i.e., those for file I/O). -*/ - -class PR_IMPLEMENT(RCNetStreamIO): public RCIO -{ - -public: - RCNetStreamIO(); - virtual ~RCNetStreamIO(); - - virtual RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout); - virtual PRInt32 AcceptRead( - RCIO **nd, RCNetAddr **raddr, void *buf, - PRSize amount, const RCInterval& timeout); - virtual PRInt64 Available(); - virtual PRStatus Bind(const RCNetAddr& addr); - virtual PRStatus Connect( - const RCNetAddr& addr, const RCInterval& timeout); - virtual PRStatus GetLocalName(RCNetAddr *addr) const; - virtual PRStatus GetPeerName(RCNetAddr *addr) const; - virtual PRStatus GetSocketOption(PRSocketOptionData *data) const; - virtual PRStatus Listen(PRIntn backlog); - virtual PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags); - virtual PRInt32 Read(void *buf, PRSize amount); - virtual PRInt32 Recv( - void *buf, PRSize amount, PRIntn flags, - const RCInterval& timeout); - virtual PRInt32 Recvfrom( - void *buf, PRSize amount, PRIntn flags, - RCNetAddr* addr, const RCInterval& timeout); - virtual PRInt32 Send( - const void *buf, PRSize amount, PRIntn flags, - const RCInterval& timeout); - virtual PRInt32 Sendto( - const void *buf, PRSize amount, PRIntn flags, - const RCNetAddr& addr, - const RCInterval& timeout); - virtual PRStatus SetSocketOption(const PRSocketOptionData *data); - virtual PRStatus Shutdown(ShutdownHow how); - virtual PRInt32 TransmitFile( - RCIO *source, const void *headers, - PRSize hlen, RCIO::FileDisposition flags, - const RCInterval& timeout); - virtual PRInt32 Write(const void *buf, PRSize amount); - virtual PRInt32 Writev( - const PRIOVec *iov, PRSize size, - const RCInterval& timeout); - -private: - /* functions unavailable to this clients of this class */ - RCNetStreamIO(const RCNetStreamIO&); - - PRStatus Close(); - PRStatus Open(const char *name, PRIntn flags, PRIntn mode); - PRStatus FileInfo(RCFileInfo *info) const; - PRStatus Fsync(); - PRInt64 Seek(PRInt64 offset, RCIO::Whence how); - -public: - RCNetStreamIO(PRIntn protocol); -}; /* RCNetIO */ - -#endif /* defined(_RCNETIO_H) */ - -/* RCNetStreamIO.h */ - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcthread.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcthread.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcthread.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcthread.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,188 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* RCThread.cpp - C++ wrapper on NSPR */ - -#include "rcthread.h" -#include "rcinrval.h" - -#include -#include -#include -#include - -static RCPrimordialThread *primordial = NULL; - -void nas_Root(void *arg) -{ - RCThread *him = (RCThread*)arg; - while (RCThread::ex_unstarted == him->execution) - (void)PR_Sleep(PR_INTERVAL_NO_TIMEOUT); /* wait for Start() */ - him->RootFunction(); /* he gets a self reference */ - if (PR_UNJOINABLE_THREAD == PR_GetThreadState(him->identity)) - delete him; -} /* nas_Root */ - -RCThread::~RCThread() { } - -RCThread::RCThread(): RCBase() { } - -RCThread::RCThread(const RCThread&): RCBase() -{ - PR_NOT_REACHED("Cannot call thread copy constructor"); -} /* RCThread::RCThread */ - -RCThread::RCThread( - RCThread::Scope scope, RCThread::State join, PRUint32 stackSize): - RCBase() -{ - execution = ex_unstarted; - identity = PR_CreateThread( - PR_USER_THREAD, nas_Root, this, - PR_GetThreadPriority(PR_GetCurrentThread()), - (PRThreadScope)scope, (PRThreadState)join, stackSize); -} /* RCThread::RCThread */ - -void RCThread::operator=(const RCThread&) -{ - PR_NOT_REACHED("Cannot call thread assignment operator"); -} /* RCThread::operator= */ - - -PRStatus RCThread::Start() -{ - PRStatus rv; - /* This is an unsafe check, but not too critical */ - if (RCThread::ex_unstarted == execution) - { - execution = RCThread::ex_started; - rv = PR_Interrupt(identity); - PR_ASSERT(PR_SUCCESS == rv); - } - else - { - rv = PR_FAILURE; - PR_SetError(PR_INVALID_STATE_ERROR, 0); - } - return rv; -} /* RCThread::Start */ - -PRStatus RCThread::Join() -{ - PRStatus rv; - if (RCThread::ex_unstarted == execution) - { - rv = PR_FAILURE; - PR_SetError(PR_INVALID_STATE_ERROR, 0); - } - else rv = PR_JoinThread(identity); - if (PR_SUCCESS == rv) delete this; - return rv; -} /* RCThread::Join */ - -PRStatus RCThread::Interrupt() -{ - PRStatus rv; - if (RCThread::ex_unstarted == execution) - { - rv = PR_FAILURE; - PR_SetError(PR_INVALID_STATE_ERROR, 0); - } - else rv = PR_Interrupt(identity); - return rv; -} /* RCThread::Interrupt */ - -void RCThread::ClearInterrupt() { PR_ClearInterrupt(); } - -void RCThread::SetPriority(RCThread::Priority new_priority) - { PR_SetThreadPriority(identity, (PRThreadPriority)new_priority); } - -PRThread *RCThread::Self() - { return PR_GetCurrentThread(); } - -RCThread::Scope RCThread::GetScope() const - { return (RCThread::Scope)PR_GetThreadScope(identity); } - -RCThread::State RCThread::GetState() const - { return (RCThread::State)PR_GetThreadState(identity); } - -RCThread::Priority RCThread::GetPriority() const - { return (RCThread::Priority)PR_GetThreadPriority(identity); } - -static void _rc_PDDestructor(RCThreadPrivateData* privateData) -{ - PR_ASSERT(NULL != privateData); - privateData->Release(); -} - -static PRThreadPrivateDTOR _tpd_dtor = (PRThreadPrivateDTOR)_rc_PDDestructor; - -PRStatus RCThread::NewPrivateIndex(PRUintn* index) - { return PR_NewThreadPrivateIndex(index, _tpd_dtor); } - -PRStatus RCThread::SetPrivateData(PRUintn index) - { return PR_SetThreadPrivate(index, NULL); } - -PRStatus RCThread::SetPrivateData(PRUintn index, RCThreadPrivateData* data) -{ - return PR_SetThreadPrivate(index, data); -} - -RCThreadPrivateData* RCThread::GetPrivateData(PRUintn index) - { return (RCThreadPrivateData*)PR_GetThreadPrivate(index); } - -PRStatus RCThread::Sleep(const RCInterval& ticks) - { PRIntervalTime tmo = ticks; return PR_Sleep(tmo); } - -RCPrimordialThread *RCThread::WrapPrimordialThread() -{ - /* - ** This needs to take more care in insuring that the thread - ** being wrapped is really the primordial thread. This code - ** is assuming that the caller is the primordial thread, and - ** there's nothing to insure that. - */ - if (NULL == primordial) - { - /* it doesn't have to be perfect */ - RCPrimordialThread *me = new RCPrimordialThread(); - PR_ASSERT(NULL != me); - if (NULL == primordial) - { - primordial = me; - me->execution = RCThread::ex_started; - me->identity = PR_GetCurrentThread(); - } - else delete me; /* somebody beat us to it */ - } - return primordial; -} /* RCThread::WrapPrimordialThread */ - -RCPrimordialThread::RCPrimordialThread(): RCThread() { } - -RCPrimordialThread::~RCPrimordialThread() { } - -void RCPrimordialThread::RootFunction() -{ - PR_NOT_REACHED("Primordial thread calling root function"); -} /* RCPrimordialThread::RootFunction */ - -PRStatus RCPrimordialThread::Cleanup() { return PR_Cleanup(); } - -PRStatus RCPrimordialThread::SetVirtualProcessors(PRIntn count) -{ - PR_SetConcurrency(count); - return PR_SUCCESS; -} /* SetVirutalProcessors */ - -RCThreadPrivateData::RCThreadPrivateData() { } - -RCThreadPrivateData::RCThreadPrivateData( - const RCThreadPrivateData& him) { } - -RCThreadPrivateData::~RCThreadPrivateData() { } - -/* RCThread.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcthread.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcthread.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rcthread.h 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rcthread.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* RCThread.h */ - -#if defined(_RCTHREAD_H) -#else -#define _RCTHREAD_H - -#include "rcbase.h" - -#include - -class RCInterval; - -class PR_IMPLEMENT(RCThreadPrivateData) -{ -public: - RCThreadPrivateData(); - RCThreadPrivateData(const RCThreadPrivateData&); - - virtual ~RCThreadPrivateData(); - - virtual void Release() = 0; - -}; /* RCThreadPrivateData */ - -class PR_IMPLEMENT(RCThread): public RCBase -{ -public: - - typedef enum - { - local = PR_LOCAL_THREAD, global = PR_GLOBAL_THREAD - } Scope; - - typedef enum - { - joinable = PR_JOINABLE_THREAD, unjoinable = PR_UNJOINABLE_THREAD - } State; - - typedef enum - { - first = PR_PRIORITY_FIRST, - low = PR_PRIORITY_LOW, - normal = PR_PRIORITY_NORMAL, - high = PR_PRIORITY_HIGH, - urgent = PR_PRIORITY_URGENT, - last = PR_PRIORITY_LAST - } Priority; - - /* - * Create a new thread, providing scope and joinability state. - */ - RCThread(Scope scope, State state, PRUint32 stackSize=0); - - /* - * New threads are created in a suspended state. It must be 'started" - * before it begins execution in the class' defined 'RootFunction()'. - */ - virtual PRStatus Start(); - - /* - * If a thread is created joinable, then the thread's object exists - * until join is called. The thread that calls join will block until - * the target thread returns from it's root function. - */ - virtual PRStatus Join(); - - /* - * The priority of a newly created thread is the same as the creator. - * The priority may be changed either by the new thread itself, by - * the creator or any other arbitrary thread. - */ - virtual void SetPriority(Priority newPriority); - - - /* - * Interrupt another thread, causing it to stop what it - * is doing and return with a well known error code. - */ - virtual PRStatus Interrupt(); - - /* - * And in case a thread was interrupted and didn't get a chance - * to have the notification delivered, a way to cancel the pending - * status. - */ - static void ClearInterrupt(); - - /* - * Methods to discover the attributes of an existing thread. - */ - static PRThread *Self(); - Scope GetScope() const; - State GetState() const; - Priority GetPriority() const; - - /* - * Thread private data - */ - static PRStatus NewPrivateIndex(PRUintn* index); - - /* - * Getting it - if you want to modify, make a copy - */ - static RCThreadPrivateData* GetPrivateData(PRUintn index); - - /* - * Setting it to - deletes existing data - */ - static PRStatus SetPrivateData(PRUintn index); - - /* - * Setting it - runtime will make a copy, freeing old iff necessary - */ - static PRStatus SetPrivateData(PRUintn index, RCThreadPrivateData* data); - - /* - * Scheduling control - */ - static PRStatus Sleep(const RCInterval& ticks); - - friend void nas_Root(void*); - friend class RCPrimordialThread; -protected: - - /* - * The instantiator of a class must not call the destructor. The base - * implementation of Join will, and if the thread is created unjoinable, - * then the code that called the RootFunction will call the desctructor. - */ - virtual ~RCThread(); - -private: - - /* - * This is where a newly created thread begins execution. Returning - * from this function is equivalent to terminating the thread. - */ - virtual void RootFunction() = 0; - - PRThread *identity; - - /* Threads are unstarted until started - pretty startling */ - enum {ex_unstarted, ex_started} execution; - - /* There is no public default constructor or copy constructor */ - RCThread(); - RCThread(const RCThread&); - - /* And there is no assignment operator */ - void operator=(const RCThread&); - -public: - static RCPrimordialThread *WrapPrimordialThread(); - - }; - -/* -** class RCPrimordialThread -*/ -class PR_IMPLEMENT(RCPrimordialThread): public RCThread -{ -public: - /* - ** The primordial thread can (optionally) wait for all created - ** threads to terminate before allowing the process to exit. - ** Not calling Cleanup() before returning from main() will cause - ** the immediate termination of the entire process, including - ** any running threads. - */ - static PRStatus Cleanup(); - - /* - ** Only the primordial thread is allowed to adjust the number of - ** virtual processors of the runtime. It's a lame security thing. - */ - static PRStatus SetVirtualProcessors(PRIntn count=10); - -friend class RCThread; -private: - /* - ** None other than the runtime can create of destruct - ** a primordial thread. It is fabricated by the runtime - ** to wrap the thread that initiated the application. - */ - RCPrimordialThread(); - ~RCPrimordialThread(); - void RootFunction(); -}; /* RCPrimordialThread */ - - #endif /* defined(_RCTHREAD_H) */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rctime.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rctime.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rctime.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rctime.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Class implementation for calendar time routines (ref: prtime.h) -*/ - -#include "rctime.h" - -RCTime::~RCTime() { } - -RCTime::RCTime(PRTime time): RCBase() { gmt = time; } -RCTime::RCTime(const RCTime& his): RCBase() { gmt = his.gmt; } -RCTime::RCTime(RCTime::Current): RCBase() { gmt = PR_Now(); } -RCTime::RCTime(const PRExplodedTime& time): RCBase() -{ gmt = PR_ImplodeTime(&time); } - -void RCTime::operator=(const PRExplodedTime& time) -{ gmt = PR_ImplodeTime(&time); } - -RCTime RCTime::operator+(const RCTime& his) -{ RCTime sum(gmt + his.gmt); return sum; } - -RCTime RCTime::operator-(const RCTime& his) -{ RCTime difference(gmt - his.gmt); return difference; } - -RCTime RCTime::operator/(PRUint64 his) -{ RCTime quotient(gmt / gmt); return quotient; } - -RCTime RCTime::operator*(PRUint64 his) -{ RCTime product(gmt * his); return product; } - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rctime.h nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rctime.h --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/rctime.h 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/rctime.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Class definitions for calendar time routines (ref: prtime.h) -*/ - -#if defined(_RCTIME_H) -#else -#define _RCTIME_H - -#include "rcbase.h" - -#include - -/* -** Class: RCTime (ref: prtime.h) -** -** RCTimes are objects that are intended to be used to represent calendar -** times. They maintain units internally as microseconds since the defined -** epoch (midnight, January 1, 1970, GMT). Conversions to and from external -** formats (PRExplodedTime) are available. -** -** In general, NCTimes possess normal algebretic capabilities. -*/ - -class PR_IMPLEMENT(RCTime): public RCBase -{ -public: - typedef enum {now} Current; - - RCTime(); /* leaves the object unitialized */ - RCTime(Current); /* initializes to current system time */ - RCTime(const RCTime&); /* copy constructor */ - RCTime(const PRExplodedTime&); /* construction from exploded representation */ - - virtual ~RCTime(); - - /* assignment operators */ - void operator=(const RCTime&); - void operator=(const PRExplodedTime&); - - /* comparitive operators */ - PRBool operator<(const RCTime&); - PRBool operator>(const RCTime&); - PRBool operator<=(const RCTime&); - PRBool operator>=(const RCTime&); - PRBool operator==(const RCTime&); - - /* associative operators */ - RCTime operator+(const RCTime&); - RCTime operator-(const RCTime&); - RCTime& operator+=(const RCTime&); - RCTime& operator-=(const RCTime&); - - /* multiply and divide operators */ - RCTime operator/(PRUint64); - RCTime operator*(PRUint64); - RCTime& operator/=(PRUint64); - RCTime& operator*=(PRUint64); - - void Now(); /* assign current time to object */ - -private: - PRTime gmt; - -public: - - RCTime(PRTime); /* construct from raw PRTime */ - void operator=(PRTime); /* assign from raw PRTime */ - operator PRTime() const; /* extract internal representation */ -}; /* RCTime */ - -inline RCTime::RCTime(): RCBase() { } - -inline void RCTime::Now() { gmt = PR_Now(); } -inline RCTime::operator PRTime() const { return gmt; } - -inline void RCTime::operator=(PRTime his) { gmt = his; } -inline void RCTime::operator=(const RCTime& his) { gmt = his.gmt; } - -inline PRBool RCTime::operator<(const RCTime& his) - { return (gmt < his.gmt) ? PR_TRUE : PR_FALSE; } -inline PRBool RCTime::operator>(const RCTime& his) - { return (gmt > his.gmt) ? PR_TRUE : PR_FALSE; } -inline PRBool RCTime::operator<=(const RCTime& his) - { return (gmt <= his.gmt) ? PR_TRUE : PR_FALSE; } -inline PRBool RCTime::operator>=(const RCTime& his) - { return (gmt >= his.gmt) ? PR_TRUE : PR_FALSE; } -inline PRBool RCTime::operator==(const RCTime& his) - { return (gmt == his.gmt) ? PR_TRUE : PR_FALSE; } - -inline RCTime& RCTime::operator+=(const RCTime& his) - { gmt += his.gmt; return *this; } -inline RCTime& RCTime::operator-=(const RCTime& his) - { gmt -= his.gmt; return *this; } -inline RCTime& RCTime::operator/=(PRUint64 his) - { gmt /= his; return *this; } -inline RCTime& RCTime::operator*=(PRUint64 his) - { gmt *= his; return *this; } - -#endif /* defined(_RCTIME_H) */ - -/* RCTime.h */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/.cvsignore 2001-05-12 06:06:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/fileio.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/fileio.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/fileio.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/fileio.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* fileio.cpp - a test program */ - -#include "rcfileio.h" - -#include -#include - -#define DEFAULT_ITERATIONS 100 - -PRIntn main(PRIntn argc, char **argv) -{ - PRStatus rv; - RCFileIO fd; - RCFileInfo info; - rv = fd.Open("filio.dat", PR_CREATE_FILE, 0666); - PR_ASSERT(PR_SUCCESS == rv); - rv = fd.FileInfo(&info); - PR_ASSERT(PR_SUCCESS == rv); - rv = fd.Delete("filio.dat"); - PR_ASSERT(PR_SUCCESS == rv); - fd.Close(); - PR_ASSERT(PR_SUCCESS == rv); - - return 0; -} /* main */ - -/* interval.cpp */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/interval.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/interval.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/interval.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/interval.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* interval.cpp - a test program */ - -#include "rclock.h" -#include "rcthread.h" -#include "rcinrval.h" -#include "rccv.h" - -#include -#include -#include - -#define DEFAULT_ITERATIONS 100 - -PRIntn main(PRIntn argc, char **argv) -{ - RCLock ml; - PRStatus rv; - RCCondition cv(&ml); - - RCInterval now, timeout, epoch, elapsed; - PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput); - PRIntn msecs, seconds, loops, iterations = DEFAULT_ITERATIONS; - - /* slow, agonizing waits */ - for (seconds = 0; seconds < 10; ++seconds) - { - timeout = RCInterval::FromSeconds(seconds); - cv.SetTimeout(timeout); - { - RCEnter lock(&ml); - - epoch.SetToNow(); - - rv = cv.Wait(); - PR_ASSERT(PR_SUCCESS == rv); - - now = RCInterval(RCInterval::now); - elapsed = now - epoch; - } - - PR_fprintf( - output, "Waiting %u seconds took %s%u milliseconds\n", - seconds, ((elapsed < timeout)? "**" : ""), - elapsed.ToMilliseconds()); - } - - /* more slow, agonizing sleeps */ - for (seconds = 0; seconds < 10; ++seconds) - { - timeout = RCInterval::FromSeconds(seconds); - { - epoch.SetToNow(); - - rv = RCThread::Sleep(timeout); - PR_ASSERT(PR_SUCCESS == rv); - - now = RCInterval(RCInterval::now); - elapsed = now - epoch; - } - - PR_fprintf( - output, "Sleeping %u seconds took %s%u milliseconds\n", - seconds, ((elapsed < timeout)? "**" : ""), - elapsed.ToMilliseconds()); - } - - /* fast, spritely little devils */ - for (msecs = 10; msecs < 100; msecs += 10) - { - timeout = RCInterval::FromMilliseconds(msecs); - cv.SetTimeout(timeout); - { - RCEnter lock(&ml); - - epoch.SetToNow(); - - for (loops = 0; loops < iterations; ++loops) - { - rv = cv.Wait(); - PR_ASSERT(PR_SUCCESS == rv); - } - - now = RCInterval(RCInterval::now); - elapsed = now - epoch; - } - elapsed /= iterations; - - PR_fprintf( - output, "Waiting %u msecs took %s%u milliseconds average\n", - msecs, ((elapsed < timeout)? "**" : ""), elapsed.ToMilliseconds()); - } - return 0; -} /* main */ - -/* interval.cpp */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/Makefile.in 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -ifeq ($(OS_TARGET), WIN16) -OS_CFLAGS = $(OS_EXE_CFLAGS) -endif - -CXXSRCS = \ - ranfile.cpp \ - thread.cpp \ - interval.cpp \ - time.cpp \ - fileio.cpp \ - switch.cpp \ - tpd.cpp \ - $(NULL) - -OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX))) - -ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) -PROG_SUFFIX = .exe -else -PROG_SUFFIX = -endif - -PROGS = $(addprefix $(OBJDIR)/, $(CXXSRCS:.cpp=$(PROG_SUFFIX))) - -TARGETS = $(PROGS) $(OBJS) - -INCLUDES = -I.. -I$(dist_includedir) - -# Setting the variables LDOPTS and LIBPR. We first initialize -# them to the default values, then adjust them for some platforms. -LDOPTS = -L$(dist_libdir) -LIBPR = -lnspr$(MOD_MAJOR_VERSION) -LIBPL = -lplc$(MOD_MAJOR_VERSION) - -ifeq ($(OS_ARCH), IRIX) - LDOPTS += -rpath $(PWD)/$(dist_libdir) -rdata_shared - # For 6.x machines, include this flag - ifeq ($(basename $(OS_RELEASE)),6) - ifeq ($(USE_N32),1) - LDOPTS += -n32 - else - LDOPTS += -32 - endif - - ifeq ($(USE_PTHREADS), 1) - ifeq ($(OS_RELEASE), 6.2) - LDOPTS += -Wl,-woff,85 - endif - endif - endif -endif - -# Solaris -ifeq ($(OS_ARCH), SunOS) - ifdef NS_USE_GCC - LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir) - else - LDOPTS += -R $(PWD)/$(dist_libdir) - endif - -# SunOS 5.5 needs to link with -lpthread, even though we already -# linked with this system library when we built libnspr.so. - ifeq ($(OS_RELEASE), 5.5) - ifdef USE_PTHREADS - EXTRA_LIBS = -lpthread - endif - endif -endif # SunOS - -ifeq ($(OS_ARCH), WINNT) -ifeq ($(OS_TARGET), WIN16) - LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib - LIBPL = $(dist_libdir)/plc$(MOD_MAJOR_VERSION).lib -else - LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO - LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) - LIBPL = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) -endif -endif - -ifeq ($(OS_ARCH),OS2) -LDOPTS += -Zomf -Zlinker /PM:VIO -lstdcpp -endif - -ifneq ($(OS_ARCH), WINNT) -PWD = $(shell pwd) -endif - -ifeq ($(OS_ARCH), OSF1) -LDOPTS += -rpath $(PWD)/$(dist_libdir) -endif - -ifeq ($(OS_ARCH), HP-UX) - LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir) -endif - -# AIX -ifeq ($(OS_ARCH),AIX) - LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib - ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1) - LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr - LIBPLC = -lplc$(MOD_MAJOR_VERSION)_shr - else - LDOPTS += -brtl - EXTRA_LIBS = -ldl - endif -endif - -ifeq ($(OS_ARCH), Linux) - ifeq ($(OS_RELEASE), 1.2) - EXTRA_LIBS = -ldl - else - LDOPTS += -Xlinker -rpath $(PWD)/$(dist_libdir) - ifeq ($(USE_PTHREADS),1) - EXTRA_LIBS = -lpthread - endif - endif -endif - -ifeq ($(OS_ARCH), SCO_SV) -# SCO Unix needs to link against -lsocket again even though we -# already linked with these system libraries when we built libnspr.so. -EXTRA_LIBS = -lsocket -# This hardcodes in the executable programs the directory to find -# libnspr.so etc. at program startup. Equivalent to the -R or -rpath -# option for ld on other platforms. -export LD_RUN_PATH = $(PWD)/$(dist_libdir) -endif - -ifeq ($(OS_ARCH), UNIXWARE) -export LD_RUN_PATH = $(PWD)/$(dist_libdir) -endif - -##################################################### -# -# The rules -# -##################################################### - -include $(topsrcdir)/config/rules.mk - -AIX_PRE_4_2 = 0 -ifeq ($(OS_ARCH),AIX) -ifneq ($(OS_RELEASE),4.2) -ifneq ($(USE_PTHREADS), 1) -#AIX_PRE_4_2 = 1 -endif -endif -endif - -ifeq ($(AIX_PRE_4_2),1) - -# AIX releases prior to 4.2 need a special two-step linking hack -# in order to both override the system select() and be able to -# get at the original system select(). -# -# We use a pattern rule in ns/nspr20/config/rules.mk to generate -# the .$(OBJ_SUFFIX) file from the .c source file, then do the -# two-step linking hack below. - -$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) - rm -f $@ $(AIX_TMP) - $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a - $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) - rm -f $(AIX_TMP) - -else - -# All platforms that are not AIX pre-4.2. - -$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) -ifeq ($(OS_ARCH), WINNT) -ifeq ($(OS_TARGET),WIN16) - echo system windows >w16link - echo option map >>w16link - echo option stack=10K >>w16link - echo option heapsize=32K >>w16link - echo debug $(DEBUGTYPE) all >>w16link - echo name $@ >>w16link - echo file >>w16link - echo $< >>w16link - echo library >>w16link - echo $(LIBPR), >>w16link - echo $(LIBPL), >>w16link - echo winsock.lib >>w16link - wlink @w16link. -else - link $(LDOPTS) $< $(LIBPR) $(LIBPL) wsock32.lib -out:$@ -endif -else -ifeq ($(OS_ARCH),OS2) - $(LINK) $(LDOPTS) $< $(LIBGC) $(LIBPLC) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS) -o $@ -else - $(CCC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPL) $(EXTRA_LIBS) -o $@ -endif -endif -endif - -export:: $(TARGETS) -clean:: - rm -f $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/ranfile.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/ranfile.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/ranfile.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/ranfile.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,400 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Contact: AOF -** -** Name: ranfile.c -** -** Description: Test to hammer on various components of NSPR -** Modification History: -** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include -#include -#include - -#include "rccv.h" -#include "rcthread.h" -#include "rcfileio.h" -#include "rclock.h" - -#include -#include -#include - -static PRFileDesc *output; -static PRIntn debug_mode = 0; -static PRIntn failed_already = 0; - -class HammerData -{ -public: - typedef enum { - sg_go, sg_stop, sg_done} Action; - typedef enum { - sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem; - - virtual ~HammerData(); - HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip); - virtual PRUint32 Random(); - - Action action; - Problem problem; - PRUint32 writes; - RCInterval timein; -friend class Hammer; -private: - RCLock *ml; - RCCondition *cv; - PRUint32 limit; - - PRFloat64 seed; -}; /* HammerData */ - -class Hammer: public HammerData, public RCThread -{ -public: - virtual ~Hammer(); - Hammer(RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip); - -private: - void RootFunction(); - -}; - -static PRInt32 pageSize = 1024; -static const char* baseName = "./"; -static const char *programName = "Random File"; - -/*********************************************************************** -** PRIVATE FUNCTION: Random -** DESCRIPTION: -** Generate a pseudo-random number -** INPUTS: None -** OUTPUTS: None -** RETURN: A pseudo-random unsigned number, 32-bits wide -** SIDE EFFECTS: -** Updates random seed (a static) -** RESTRICTIONS: -** None -** MEMORY: NA -** ALGORITHM: -** Uses the current interval timer value, promoted to a 64 bit -** float as a multiplier for a static residue (which begins -** as an uninitialized variable). The result is bits [16..48) -** of the product. Seed is then updated with the return value -** promoted to a float-64. -***********************************************************************/ -PRUint32 HammerData::Random() -{ - PRUint32 rv; - PRUint64 shift; - RCInterval now = RCInterval(RCInterval::now); - PRFloat64 random = seed * (PRFloat64)((PRIntervalTime)now); - LL_USHR(shift, *((PRUint64*)&random), 16); - LL_L2UI(rv, shift); - seed = (PRFloat64)rv; - return rv; -} /* HammerData::Random */ - -Hammer::~Hammer() { } - -Hammer::Hammer( - RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip): - HammerData(lock, cond, clip), RCThread(scope, RCThread::joinable, 0) { } - -HammerData::~HammerData() { } - -HammerData::HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip) -{ - ml = lock; - cv = cond; - writes = 0; - limit = clip; - seed = 0x58a9382; - action = HammerData::sg_go; - problem = HammerData::sg_okay; - timein = RCInterval(RCInterval::now); -} /* HammerData::HammerData */ - - -/*********************************************************************** -** PRIVATE FUNCTION: Hammer::RootFunction -** DESCRIPTION: -** Hammer on the file I/O system -** INPUTS: A pointer to the thread's private data -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** Creates, accesses and deletes a file -** RESTRICTIONS: -** (Currently) must have file create permission in "/usr/tmp". -** MEMORY: NA -** ALGORITHM: -** This function is a root of a thread -** 1) Creates a (hopefully) unique file in /usr/tmp/ -** 2) Writes a zero to a random number of sequential pages -** 3) Closes the file -** 4) Reopens the file -** 5) Seeks to a random page within the file -** 6) Writes a one byte on that page -** 7) Repeat steps [5..6] for each page in the file -** 8) Close and delete the file -** 9) Repeat steps [1..8] until told to stop -** 10) Notify complete and return -***********************************************************************/ -void Hammer::RootFunction() -{ - PRUint32 index; - RCFileIO file; - char filename[30]; - const char zero = 0; - PRStatus rv = PR_SUCCESS; - - limit = (Random() % limit) + 1; - - (void)sprintf(filename, "%ssg%04p.dat", baseName, this); - - if (debug_mode) PR_fprintf(output, "Starting work on %s\n", filename); - - while (PR_TRUE) - { - PRUint64 bytes; - PRUint32 minor = (Random() % limit) + 1; - PRUint32 random = (Random() % limit) + 1; - PRUint32 pages = (Random() % limit) + 10; - while (minor-- > 0) - { - problem = sg_okay; - if (action != sg_go) goto finished; - problem = sg_open; - rv = file.Open(filename, PR_RDWR|PR_CREATE_FILE, 0666); - if (PR_FAILURE == rv) goto finished; - for (index = 0; index < pages; index++) - { - problem = sg_okay; - if (action != sg_go) goto close; - problem = sg_seek; - bytes = file.Seek(pageSize * index, RCFileIO::set); - if (bytes != pageSize * index) goto close; - problem = sg_write; - bytes = file.Write(&zero, sizeof(zero)); - if (bytes <= 0) goto close; - writes += 1; - } - problem = sg_close; - rv = file.Close(); - if (rv != PR_SUCCESS) goto purge; - - problem = sg_okay; - if (action != sg_go) goto purge; - - problem = sg_open; - rv = file.Open(filename, PR_RDWR, 0666); - if (PR_FAILURE == rv) goto finished; - for (index = 0; index < pages; index++) - { - problem = sg_okay; - if (action != sg_go) goto close; - problem = sg_seek; - bytes = file.Seek(pageSize * index, RCFileIO::set); - if (bytes != pageSize * index) goto close; - problem = sg_write; - bytes = file.Write(&zero, sizeof(zero)); - if (bytes <= 0) goto close; - writes += 1; - random = (random + 511) % pages; - } - problem = sg_close; - rv = file.Close(); - if (rv != PR_SUCCESS) goto purge; - problem = sg_delete; - rv = file.Delete(filename); - if (rv != PR_SUCCESS) goto finished; - } - } - -close: - (void)file.Close(); -purge: - (void)file.Delete(filename); -finished: - RCEnter scope(ml); - action = HammerData::sg_done; - cv->Notify(); - - if (debug_mode) PR_fprintf(output, "Ending work on %s\n", filename); - - return; -} /* Hammer::RootFunction */ - -static Hammer* hammer[100]; -/*********************************************************************** -** PRIVATE FUNCTION: main -** DESCRIPTION: -** Hammer on the file I/O system -** INPUTS: The usual argc and argv -** argv[0] - program name (not used) -** argv[1] - the number of virtual_procs to execute the major loop -** argv[2] - the number of threads to toss into the batch -** argv[3] - the clipping number applied to randoms -** default values: max_virtual_procs = 2, threads = 10, limit = 57 -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** Creates, accesses and deletes lots of files -** RESTRICTIONS: -** (Currently) must have file create permission in "/usr/tmp". -** MEMORY: NA -** ALGORITHM: -** 1) Fork a "Thread()" -** 2) Wait for 'interleave' seconds -** 3) For [0..'threads') repeat [1..2] -** 4) Mark all objects to stop -** 5) Collect the threads, accumulating the results -** 6) For [0..'max_virtual_procs') repeat [1..5] -** 7) Print accumulated results and exit -** -** Characteristic output (from IRIX) -** Random File: Using max_virtual_procs = 2, threads = 10, limit = 57 -** Random File: [min [avg] max] writes/sec average -***********************************************************************/ -PRIntn main (PRIntn argc, char *argv[]) -{ - RCLock ml; - PLOptStatus os; - RCCondition cv(&ml); - PRUint32 writesMax = 0, durationTot = 0; - RCThread::Scope thread_scope = RCThread::local; - PRUint32 writes, writesMin = 0x7fffffff, writesTot = 0; - PRIntn active, poll, limit = 0, max_virtual_procs = 0, threads = 0, virtual_procs; - RCInterval interleave(RCInterval::FromMilliseconds(10000)), duration(0); - - const char *where[] = {"okay", "open", "close", "delete", "write", "seek"}; - - PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: - baseName = opt->value; - break; - case 'G': /* global threads */ - thread_scope = RCThread::global; - break; - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'l': /* limiting number */ - limit = atoi(opt->value); - break; - case 't': /* number of threads */ - threads = atoi(opt->value); - break; - case 'i': /* iteration counter */ - max_virtual_procs = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - output = PR_GetSpecialFD(PR_StandardOutput); - - /* main test */ - - cv.SetTimeout(interleave); - - if (max_virtual_procs == 0) max_virtual_procs = 2; - if (limit == 0) limit = 57; - if (threads == 0) threads = 10; - - if (debug_mode) PR_fprintf(output, - "%s: Using %d virtual processors, %d threads, limit = %d and %s threads\n", - programName, max_virtual_procs, threads, limit, - (thread_scope == RCThread::local) ? "LOCAL" : "GLOBAL"); - - for (virtual_procs = 0; virtual_procs < max_virtual_procs; ++virtual_procs) - { - if (debug_mode) - PR_fprintf(output, - "%s: Setting number of virtual processors to %d\n", - programName, virtual_procs + 1); - RCPrimordialThread::SetVirtualProcessors(virtual_procs + 1); - for (active = 0; active < threads; active++) - { - hammer[active] = new Hammer(thread_scope, &ml, &cv, limit); - hammer[active]->Start(); /* then make it roll */ - RCThread::Sleep(interleave); /* start them slowly */ - } - - /* - * The last thread started has had the opportunity to run for - * 'interleave' seconds. Now gather them all back in. - */ - { - RCEnter scope(&ml); - for (poll = 0; poll < threads; poll++) - { - if (hammer[poll]->action == HammerData::sg_go) /* don't overwrite done */ - hammer[poll]->action = HammerData::sg_stop; /* ask him to stop */ - } - } - - while (active > 0) - { - for (poll = 0; poll < threads; poll++) - { - ml.Acquire(); - while (hammer[poll]->action < HammerData::sg_done) cv.Wait(); - ml.Release(); - - if (hammer[poll]->problem == HammerData::sg_okay) - { - duration = RCInterval(RCInterval::now) - hammer[poll]->timein; - writes = hammer[poll]->writes * 1000 / duration; - if (writes < writesMin) writesMin = writes; - if (writes > writesMax) writesMax = writes; - writesTot += hammer[poll]->writes; - durationTot += duration; - } - else - { - if (debug_mode) PR_fprintf(output, - "%s: test failed %s after %ld seconds\n", - programName, where[hammer[poll]->problem], duration); - else failed_already=1; - } - active -= 1; /* this is another one down */ - (void)hammer[poll]->Join(); - hammer[poll] = NULL; - } - } - if (debug_mode) PR_fprintf(output, - "%s: [%ld [%ld] %ld] writes/sec average\n", - programName, writesMin, - writesTot * 1000 / durationTot, writesMax); - } - - failed_already |= (PR_FAILURE == RCPrimordialThread::Cleanup()); - PR_fprintf(output, "%s\n", (failed_already) ? "FAIL\n" : "PASS\n"); - return failed_already; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/switch.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/switch.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/switch.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/switch.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,234 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: switch.cpp -** Description: trying to time context switches -*/ - -#include "rccv.h" -#include "rcinrval.h" -#include "rclock.h" -#include "rcthread.h" - -#include -#include -#include -#include -#include - -#include - -#define INNER_LOOPS 100 -#define DEFAULT_LOOPS 100 -#define DEFAULT_THREADS 10 - -static PRFileDesc *debug_out = NULL; -static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE; - -class Home: public RCCondition -{ -public: - virtual ~Home(); - Home(Home *link, RCLock* ml); - -public: - Home *next; - RCLock* ml; - PRBool twiddle; -}; /* Home */ - -Home::~Home() { } - -Home::Home(Home *link, RCLock* lock): RCCondition(lock) -{ - ml = lock; - next = link; - twiddle = PR_FALSE; -} /* Home::Home */ - -class Shared: public Home, public RCThread -{ -public: - Shared(RCThread::Scope scope, Home* link, RCLock* ml); - -private: - ~Shared(); - void RootFunction(); -}; /* Shared */ - -Shared::Shared(RCThread::Scope scope, Home* link, RCLock* lock): - Home(link, lock), RCThread(scope, RCThread::joinable) { } - -Shared::~Shared() { } - -void Shared::RootFunction() -{ - PRStatus status = PR_SUCCESS; - while (PR_SUCCESS == status) - { - RCEnter entry(ml); - while (twiddle && (PR_SUCCESS == status)) status = Wait(); - if (verbosity) PR_fprintf(debug_out, "+"); - twiddle = PR_TRUE; - next->twiddle = PR_FALSE; - next->Notify(); - } -} /* Shared::RootFunction */ - -static void Help(void) -{ - debug_out = PR_STDOUT; - - PR_fprintf( - debug_out, "Usage: >./switch [-d] [-c n] [-t n] [-T n] [-G]\n"); - PR_fprintf( - debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS); - PR_fprintf( - debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS); - PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n"); - PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n"); - PR_fprintf(debug_out, "-G n\tglobal threads only (default: FALSE)\n"); - PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n"); -} /* Help */ - -PRIntn main(PRIntn argc, char **argv) -{ - PLOptStatus os; - PRStatus status; - PRBool help = PR_FALSE; - PRUintn concurrency = 1; - RCThread::Scope thread_scope = RCThread::local; - PRUintn thread_count, inner_count, loop_count, average; - PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS; - PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'v': /* verbose mode */ - verbosity = PR_TRUE; - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'c': /* loop counter */ - loop_limit = atoi(opt->value); - break; - case 't': /* thread limit */ - thread_limit = atoi(opt->value); - break; - case 'C': /* Concurrency limit */ - concurrency = atoi(opt->value); - break; - case 'G': /* global threads only */ - thread_scope = RCThread::global; - break; - case 'h': /* help message */ - Help(); - help = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (help) return -1; - - if (PR_TRUE == debug_mode) - { - debug_out = PR_STDOUT; - PR_fprintf(debug_out, "Test parameters\n"); - PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit); - PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit); - PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency); - PR_fprintf( - debug_out, "\tThread type: %s\n", - (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); - } - - /* - ** The interesting part starts here - */ - RCLock lock; - Shared* shared; - Home home(NULL, &lock); - Home* link = &home; - RCInterval timein, timeout = 0; - - /* Build up the string of objects */ - for (thread_count = 1; thread_count <= thread_limit; ++thread_count) - { - shared = new Shared(thread_scope, link, &lock); - shared->Start(); /* make it run */ - link = (Home*)shared; - } - - /* Pass the message around the horn a few times */ - for (loop_count = 1; loop_count <= loop_limit; ++loop_count) - { - timein.SetToNow(); - for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count) - { - RCEnter entry(&lock); - home.twiddle = PR_TRUE; - shared->twiddle = PR_FALSE; - shared->Notify(); - while (home.twiddle) - { - failed = (PR_FAILURE == home.Wait()) ? PR_TRUE : PR_FALSE; - } - } - timeout += (RCInterval(RCInterval::now) - timein); - } - - /* Figure out how well we did */ - if (debug_mode) - { - average = timeout.ToMicroseconds() - / (INNER_LOOPS * loop_limit * thread_count); - PR_fprintf( - debug_out, "Average switch times %d usecs for %d threads\n", - average, thread_limit); - } - - /* Start reclamation process */ - link = shared; - for (thread_count = 1; thread_count <= thread_limit; ++thread_count) - { - if (&home == link) break; - status = ((Shared*)link)->Interrupt(); - if (PR_SUCCESS != status) - { - failed = PR_TRUE; - if (debug_mode) - PL_FPrintError(debug_out, "Failed to interrupt"); - } - link = link->next; - } - - for (thread_count = 1; thread_count <= thread_limit; ++thread_count) - { - link = shared->next; - status = shared->Join(); - if (PR_SUCCESS != status) - { - failed = PR_TRUE; - if (debug_mode) - PL_FPrintError(debug_out, "Failed to join"); - } - if (&home == link) break; - shared = (Shared*)link; - } - - PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n")); - - failed |= (PR_SUCCESS == RCPrimordialThread::Cleanup()); - - return ((failed) ? 1 : 0); -} /* main */ - -/* switch.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/thread.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/thread.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/thread.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/thread.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* thread.cpp - a test program */ - -#include "rcthread.h" - -#include - -#include - -class TestThread: public RCThread -{ -public: - TestThread(RCThread::State state, PRIntn count); - - virtual void RootFunction(); - -protected: - virtual ~TestThread(); - -private: - PRUint32 mydata; -}; - -TestThread::~TestThread() { } - -TestThread::TestThread(RCThread::State state, PRIntn count): - RCThread(RCThread::global, state, 0) { mydata = count; } - -void TestThread::RootFunction() -{ - SetPriority(RCThread::high); - printf("TestThread::RootFunction %d did it\n", mydata); -} /* TestThread::RootFunction */ - -class Foo1 -{ -public: - Foo1(); - virtual ~Foo1(); - - TestThread *thread; - PRIntn data; -}; - -Foo1::Foo1() -{ - data = 0xafaf; - thread = new TestThread(RCThread::joinable, 0xafaf); - thread->Start(); -} - -Foo1::~Foo1() -{ - PRStatus rv = thread->Join(); - PR_ASSERT(PR_SUCCESS == rv); -} /* Foo1::~Foo1 */ - -PRIntn main(PRIntn argc, char **agrv) -{ - PRStatus status; - PRIntn count = 100; - RCThread *thread[10]; - while (--count > 0) - { - TestThread *thread = new TestThread(RCThread::joinable, count); - status = thread->Start(); /* have to remember to start it */ - PR_ASSERT(PR_SUCCESS == status); - status = thread->Join(); /* this should work */ - PR_ASSERT(PR_SUCCESS == status); - } - while (++count < 100) - { - TestThread *thread = new TestThread(RCThread::unjoinable, count); - status = thread->Start(); /* have to remember to start it */ - PR_ASSERT(PR_SUCCESS == status); - } - - { - Foo1 *foo1 = new Foo1(); - PR_ASSERT(NULL != foo1); - delete foo1; - } - - { - for (count = 0; count < 10; ++count) - { - thread[count] = new TestThread( RCThread::joinable, count); - status = thread[count]->Start(); /* have to remember to start it */ - PR_ASSERT(PR_SUCCESS == status); - } - for (count = 0; count < 10; ++count) - { - PRStatus rv = thread[count]->Join(); - PR_ASSERT(PR_SUCCESS == rv); - } - } - - (void)RCPrimordialThread::Cleanup(); - - return 0; -} /* main */ - -/* thread.cpp */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/time.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/time.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/time.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/time.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* time.cpp - a test program */ - -#include "rctime.h" - -#include -#include - -#define DEFAULT_ITERATIONS 100 - -PRIntn main(PRIntn argc, char **argv) -{ - RCTime unitialized; - RCTime now(PR_Now()); - RCTime current(RCTime::now); - PRTime time = current; - - unitialized = now; - now.Now(); - - return 0; -} /* main */ - -/* time.cpp */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/tpd.cpp nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/tpd.cpp --- nspr-4.9.5/mozilla/nsprpub/pr/src/cplus/tests/tpd.cpp 2012-03-06 13:14:08.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/cplus/tests/tpd.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,336 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: tpd.cpp -** Description: Exercising the thread private data bailywick. -*/ - -#include "prlog.h" -#include "prprf.h" -#include "rcthread.h" - -#include - -#include "plgetopt.h" - -/* -** class MyThread -*/ -class MyThread: public RCThread -{ -public: - MyThread(); - -private: - ~MyThread(); - void RootFunction(); -}; /* MyThread */ - -/* -** class MyPrivateData -*/ -class MyPrivateData: public RCThreadPrivateData -{ -public: - virtual ~MyPrivateData(); - - MyPrivateData(); - MyPrivateData(char*); - MyPrivateData(const MyPrivateData&); - - void Release(); - -private: - char *string; -}; /* MyPrivateData */ - -static PRUintn key[128]; -static PRIntn debug = 0; -static PRBool failed = PR_FALSE; -static PRBool should = PR_TRUE; -static PRBool did = PR_TRUE; -static PRFileDesc *fout = NULL; - -static void PrintProgress(PRIntn line) -{ - failed = failed || (should && !did); - failed = failed || (!should && did); - if (debug > 0) - { - PR_fprintf( - fout, "@ line %d destructor should %shave been called and was%s\n", - line, ((should) ? "" : "NOT "), ((did) ? "" : " NOT")); - } -} /* PrintProgress */ - -static void MyAssert(const char *expr, const char *file, PRIntn line) -{ - if (debug > 0) - (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line); -} /* MyAssert */ - -#define MY_ASSERT(_expr) \ - ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__)) - -int main(PRIntn argc, char *argv[]) -{ - PRStatus rv; - PRUintn keys; - MyThread *thread; - const RCThreadPrivateData *pd; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d"); - RCThread *primordial = RCThread::WrapPrimordialThread(); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - fout = PR_STDOUT; - - MyPrivateData extension = MyPrivateData("EXTENSION"); - MyPrivateData key_string[] = { - "Key #0", "Key #1", "Key #2", "Key #3", - "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; - - - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = RCThread::NewPrivateIndex(&key[keys]); - key[keys + 4] = key[keys] + 4; - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - /* the first four should be bu null, the last four undefined and null */ - did = should = PR_FALSE; - for (keys = 0; keys < 8; ++keys) - { - pd = RCThread::GetPrivateData(key[keys]); - MY_ASSERT(NULL == pd); - } - PrintProgress(__LINE__); - - /* initially set private data for new keys */ - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = RCThread::SetPrivateData(key[keys], &key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - /* re-assign the private data, albeit the same content */ - did = PR_FALSE; should = PR_TRUE; - for (keys = 0; keys < 4; ++keys) - { - pd = RCThread::GetPrivateData(key[keys]); - PR_ASSERT(NULL != pd); - rv = RCThread::SetPrivateData(key[keys], &key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - /* set private to */ - did = PR_FALSE; should = PR_TRUE; - for (keys = 0; keys < 4; ++keys) - { - rv = RCThread::SetPrivateData(key[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - /* should all be null now */ - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - pd = RCThread::GetPrivateData(key[keys]); - PR_ASSERT(NULL == pd); - } - PrintProgress(__LINE__); - - /* allocate another batch of keys and assign data to them */ - did = should = PR_FALSE; - for (keys = 8; keys < 127; ++keys) - { - rv = RCThread::NewPrivateIndex(&key[keys]); - MY_ASSERT(PR_SUCCESS == rv); - rv = RCThread::SetPrivateData(key[keys], &extension); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - /* set all the extended slots to */ - did = PR_FALSE; should = PR_TRUE; - for (keys = 8; keys < 127; ++keys) - { - rv = RCThread::SetPrivateData(key[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - /* set all the extended slots to again (noop) */ - did = should = PR_FALSE; - for (keys = 8; keys < 127; ++keys) - { - rv = RCThread::SetPrivateData(key[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - - if (debug) PR_fprintf(fout, "Creating thread\n"); - thread = new MyThread(); - if (debug) PR_fprintf(fout, "Starting thread\n"); - thread->Start(); - if (debug) PR_fprintf(fout, "Joining thread\n"); - (void)thread->Join(); - if (debug) PR_fprintf(fout, "Joined thread\n"); - - failed |= (PR_FAILURE == RCPrimordialThread::Cleanup()); - - (void)PR_fprintf( - fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); - - return (failed) ? 1 : 0; - -} /* main */ - -/* -** class MyPrivateData -*/ -MyPrivateData::~MyPrivateData() -{ - PR_fprintf( - fout, "MyPrivateData::~MyPrivateData[%s]\n", - (NULL != string) ? string : "NULL"); -} /* MyPrivateData::~MyPrivateData */ - -MyPrivateData::MyPrivateData(): RCThreadPrivateData() -{ - PR_fprintf(fout, "MyPrivateData::MyPrivateData()\n"); - string = NULL; -} /* MyPrivateData::MyPrivateData */ - -MyPrivateData::MyPrivateData(char* data): RCThreadPrivateData() -{ - PR_fprintf(fout, "MyPrivateData::MyPrivateData(char* data)\n"); - string = data; -} /* MyPrivateData:: MyPrivateData */ - -MyPrivateData::MyPrivateData(const MyPrivateData& him): RCThreadPrivateData(him) -{ - PR_fprintf(fout, "MyPrivateData::MyPrivateData(const MyPrivateData& him)\n"); - string = him.string; -} /* MyPrivateData:: MyPrivateData */ - -void MyPrivateData::Release() -{ - if (should) did = PR_TRUE; - else failed = PR_TRUE; -} /* MyPrivateData::operator= */ - -/* -** class MyThread -*/ -MyThread::~MyThread() { } -MyThread::MyThread(): RCThread(RCThread::global, RCThread::joinable) { } - - -void MyThread::RootFunction() -{ - PRStatus rv; - PRUintn keys; - const RCThreadPrivateData *pd; - - MyPrivateData extension = MyPrivateData("EXTENSION"); - MyPrivateData key_string[] = { - "Key #0", "Key #1", "Key #2", "Key #3", - "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; - - did = should = PR_FALSE; - for (keys = 0; keys < 8; ++keys) - { - pd = GetPrivateData(key[keys]); - MY_ASSERT(NULL == pd); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = SetPrivateData(keys, &key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - -#if !defined(DEBUG) - did = should = PR_FALSE; - for (keys = 4; keys < 8; ++keys) - { - rv = SetPrivateData(keys, &key_string[keys]); - MY_ASSERT(PR_FAILURE == rv); - } - PrintProgress(__LINE__); -#endif - - did = PR_FALSE; should = PR_TRUE; - for (keys = 0; keys < 4; ++keys) - { - rv = SetPrivateData(key[keys], &key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = PR_FALSE; should = PR_TRUE; - for (keys = 0; keys < 4; ++keys) - { - rv = SetPrivateData(key[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = SetPrivateData(key[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 8; keys < 127; ++keys) - { - rv = SetPrivateData(key[keys], &extension); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = PR_FALSE; should = PR_TRUE; - for (keys = 8; keys < 127; ++keys) - { - rv = SetPrivateData(key[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 8; keys < 127; ++keys) - { - rv = SetPrivateData(key[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } -} /* MyThread::RootFunction */ - -/* tpd.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/.cvsignore 2001-05-14 22:10:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Makefile -_pr_bld.h diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/io/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/.cvsignore 2001-05-12 04:14:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/io/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/Makefile.in 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CSRCS = \ - prfdcach.c \ - prmwait.c \ - priometh.c \ - pripv6.c \ - prmapopt.c \ - prlayer.c \ - prlog.c \ - prmmap.c \ - prpolevt.c \ - prprf.c \ - prscanf.c \ - prstdio.c \ - $(NULL) - -ifndef USE_PTHREADS - CSRCS += \ - prdir.c \ - prfile.c \ - prio.c \ - prsocket.c \ - $(NULL) -endif - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prdir.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prdir.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prdir.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prdir.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name) -{ - PRDir *dir; - PRStatus sts; - - dir = PR_NEW(PRDir); - if (dir) { - sts = _PR_MD_OPEN_DIR(&dir->md,name); - if (sts != PR_SUCCESS) { - PR_DELETE(dir); - return NULL; - } - } else { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - } - return dir; -} - -PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags) -{ - /* _MD_READ_DIR return a char* to the name; allocation in machine-dependent code */ - char* name = _PR_MD_READ_DIR(&dir->md, flags); - dir->d.name = name; - return name ? &dir->d : NULL; -} - -PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir) -{ -PRInt32 rv; - - if (dir) { - rv = _PR_MD_CLOSE_DIR(&dir->md); - PR_DELETE(dir); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode) -{ -PRInt32 rv; - - rv = _PR_MD_MKDIR(name, mode); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode) -{ -PRInt32 rv; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - rv = _PR_MD_MAKE_DIR(name, mode); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name) -{ -PRInt32 rv; - - rv = _PR_MD_RMDIR(name); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; -} - -#ifdef MOZ_UNICODE -/* - * UTF16 Interface - */ -PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name) -{ - PRDirUTF16 *dir; - PRStatus sts; - - dir = PR_NEW(PRDirUTF16); - if (dir) { - sts = _PR_MD_OPEN_DIR_UTF16(&dir->md,name); - if (sts != PR_SUCCESS) { - PR_DELETE(dir); - return NULL; - } - } else { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - } - return dir; -} - -PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags) -{ - /* - * _MD_READ_DIR_UTF16 return a PRUnichar* to the name; allocation in - * machine-dependent code - */ - PRUnichar* name = _PR_MD_READ_DIR_UTF16(&dir->md, flags); - dir->d.name = name; - return name ? &dir->d : NULL; -} - -PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir) -{ - PRInt32 rv; - - if (dir) { - rv = _PR_MD_CLOSE_DIR_UTF16(&dir->md); - PR_DELETE(dir); - if (rv < 0) - return PR_FAILURE; - else - return PR_SUCCESS; - } - return PR_SUCCESS; -} - -#endif /* MOZ_UNICODE */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prfdcach.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prfdcach.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prfdcach.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prfdcach.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,292 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -/*****************************************************************************/ -/*****************************************************************************/ -/************************** File descriptor caching **************************/ -/*****************************************************************************/ -/*****************************************************************************/ - -/* -** This code is built into debuggable versions of NSPR to assist in -** finding misused file descriptors. Since file descritors (PRFileDesc) -** are identified by a pointer to their structure, they can be the -** target of dangling references. Furthermore, NSPR caches and tries -** to aggressively reuse file descriptors, leading to more ambiguity. -** The following code will allow a debugging client to set environment -** variables and control the number of file descriptors that will be -** preserved before they are recycled. The environment variables are -** NSPR_FD_CACHE_SIZE_LOW and NSPR_FD_CACHE_SIZE_HIGH. The former sets -** the number of descriptors NSPR will allocate before beginning to -** recycle. The latter is the maximum number permitted in the cache -** (exclusive of those in use) at a time. -*/ -typedef struct _PR_Fd_Cache -{ - PRLock *ml; - PRIntn count; - PRStack *stack; - PRFileDesc *head, *tail; - PRIntn limit_low, limit_high; -} _PR_Fd_Cache; - -static _PR_Fd_Cache _pr_fd_cache; -static PRFileDesc **stack2fd = &(((PRFileDesc*)NULL)->higher); - - -/* -** Get a FileDescriptor from the cache if one exists. If not allocate -** a new one from the heap. -*/ -PRFileDesc *_PR_Getfd(void) -{ - PRFileDesc *fd; - /* - ** $$$ - ** This may look a little wasteful. We'll see. Right now I want to - ** be able to toggle between caching and not at runtime to measure - ** the differences. If it isn't too annoying, I'll leave it in. - ** $$$$ - ** - ** The test is against _pr_fd_cache.limit_high. If that's zero, - ** we're not doing the extended cache but going for performance. - */ - if (0 == _pr_fd_cache.limit_high) - { - PRStackElem *pop; - PR_ASSERT(NULL != _pr_fd_cache.stack); - pop = PR_StackPop(_pr_fd_cache.stack); - if (NULL == pop) goto allocate; - fd = (PRFileDesc*)((PRPtrdiff)pop - (PRPtrdiff)stack2fd); - } - else - { - do - { - if (NULL == _pr_fd_cache.head) goto allocate; /* nothing there */ - if (_pr_fd_cache.count < _pr_fd_cache.limit_low) goto allocate; - - /* we "should" be able to extract an fd from the cache */ - PR_Lock(_pr_fd_cache.ml); /* need the lock to do this safely */ - fd = _pr_fd_cache.head; /* protected extraction */ - if (NULL == fd) /* unexpected, but not fatal */ - { - PR_ASSERT(0 == _pr_fd_cache.count); - PR_ASSERT(NULL == _pr_fd_cache.tail); - } - else - { - _pr_fd_cache.count -= 1; - _pr_fd_cache.head = fd->higher; - if (NULL == _pr_fd_cache.head) - { - PR_ASSERT(0 == _pr_fd_cache.count); - _pr_fd_cache.tail = NULL; - } - PR_ASSERT(&_pr_faulty_methods == fd->methods); - PR_ASSERT(PR_INVALID_IO_LAYER == fd->identity); - PR_ASSERT(_PR_FILEDESC_FREED == fd->secret->state); - } - PR_Unlock(_pr_fd_cache.ml); - - } while (NULL == fd); /* then go around and allocate a new one */ - } - -finished: - fd->dtor = NULL; - fd->lower = fd->higher = NULL; - fd->identity = PR_NSPR_IO_LAYER; - memset(fd->secret, 0, sizeof(PRFilePrivate)); - return fd; - -allocate: - fd = PR_NEW(PRFileDesc); - if (NULL != fd) - { - fd->secret = PR_NEW(PRFilePrivate); - if (NULL == fd->secret) PR_DELETE(fd); - } - if (NULL != fd) goto finished; - else return NULL; - -} /* _PR_Getfd */ - -/* -** Return a file descriptor to the cache unless there are too many in -** there already. If put in cache, clear the fields first. -*/ -void _PR_Putfd(PRFileDesc *fd) -{ - PR_ASSERT(PR_NSPR_IO_LAYER == fd->identity); - fd->methods = &_pr_faulty_methods; - fd->identity = PR_INVALID_IO_LAYER; - fd->secret->state = _PR_FILEDESC_FREED; - - if (0 == _pr_fd_cache.limit_high) - { - PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher)); - } - else - { - if (_pr_fd_cache.count > _pr_fd_cache.limit_high) - { - PR_Free(fd->secret); - PR_Free(fd); - } - else - { - PR_Lock(_pr_fd_cache.ml); - if (NULL == _pr_fd_cache.tail) - { - PR_ASSERT(0 == _pr_fd_cache.count); - PR_ASSERT(NULL == _pr_fd_cache.head); - _pr_fd_cache.head = _pr_fd_cache.tail = fd; - } - else - { - PR_ASSERT(NULL == _pr_fd_cache.tail->higher); - _pr_fd_cache.tail->higher = fd; - _pr_fd_cache.tail = fd; /* new value */ - } - fd->higher = NULL; /* always so */ - _pr_fd_cache.count += 1; /* count the new entry */ - PR_Unlock(_pr_fd_cache.ml); - } - } -} /* _PR_Putfd */ - -PR_IMPLEMENT(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high) -{ - /* - ** This can be called at any time, may adjust the cache sizes, - ** turn the caches off, or turn them on. It is not dependent - ** on the compilation setting of DEBUG. - */ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (low > high) low = high; /* sanity check the params */ - - PR_Lock(_pr_fd_cache.ml); - if (0 == high) /* shutting down or staying down */ - { - if (0 != _pr_fd_cache.limit_high) /* shutting down */ - { - _pr_fd_cache.limit_high = 0; /* stop use */ - /* - ** Hold the lock throughout - nobody's going to want it - ** other than another caller to this routine. Just don't - ** let that happen. - ** - ** Put all the cached fds onto the new cache. - */ - while (NULL != _pr_fd_cache.head) - { - PRFileDesc *fd = _pr_fd_cache.head; - _pr_fd_cache.head = fd->higher; - PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher)); - } - _pr_fd_cache.limit_low = 0; - _pr_fd_cache.tail = NULL; - _pr_fd_cache.count = 0; - } - } - else /* starting up or just adjusting parameters */ - { - PRBool was_using_stack = (0 == _pr_fd_cache.limit_high); - _pr_fd_cache.limit_low = low; - _pr_fd_cache.limit_high = high; - if (was_using_stack) /* was using stack - feed into cache */ - { - PRStackElem *pop; - while (NULL != (pop = PR_StackPop(_pr_fd_cache.stack))) - { - PRFileDesc *fd = (PRFileDesc*) - ((PRPtrdiff)pop - (PRPtrdiff)stack2fd); - if (NULL == _pr_fd_cache.tail) _pr_fd_cache.tail = fd; - fd->higher = _pr_fd_cache.head; - _pr_fd_cache.head = fd; - _pr_fd_cache.count += 1; - } - } - } - PR_Unlock(_pr_fd_cache.ml); - return PR_SUCCESS; -} /* PR_SetFDCacheSize */ - -void _PR_InitFdCache(void) -{ - /* - ** The fd caching is enabled by default for DEBUG builds, - ** disabled by default for OPT builds. That default can - ** be overridden at runtime using environment variables - ** or a super-wiz-bang API. - */ - const char *low = PR_GetEnv("NSPR_FD_CACHE_SIZE_LOW"); - const char *high = PR_GetEnv("NSPR_FD_CACHE_SIZE_HIGH"); - - /* - ** _low is allowed to be zero, _high is not. - ** If _high is zero, we're not doing the caching. - */ - - _pr_fd_cache.limit_low = 0; -#if defined(DEBUG) - _pr_fd_cache.limit_high = FD_SETSIZE; -#else - _pr_fd_cache.limit_high = 0; -#endif /* defined(DEBUG) */ - - if (NULL != low) _pr_fd_cache.limit_low = atoi(low); - if (NULL != high) _pr_fd_cache.limit_high = atoi(high); - - if (_pr_fd_cache.limit_low < 0) - _pr_fd_cache.limit_low = 0; - if (_pr_fd_cache.limit_low > FD_SETSIZE) - _pr_fd_cache.limit_low = FD_SETSIZE; - - if (_pr_fd_cache.limit_high > FD_SETSIZE) - _pr_fd_cache.limit_high = FD_SETSIZE; - - if (_pr_fd_cache.limit_high < _pr_fd_cache.limit_low) - _pr_fd_cache.limit_high = _pr_fd_cache.limit_low; - - _pr_fd_cache.ml = PR_NewLock(); - PR_ASSERT(NULL != _pr_fd_cache.ml); - _pr_fd_cache.stack = PR_CreateStack("FD"); - PR_ASSERT(NULL != _pr_fd_cache.stack); - -} /* _PR_InitFdCache */ - -void _PR_CleanupFdCache(void) -{ - PRFileDesc *fd, *next; - PRStackElem *pop; - - for (fd = _pr_fd_cache.head; fd != NULL; fd = next) - { - next = fd->higher; - PR_DELETE(fd->secret); - PR_DELETE(fd); - } - _pr_fd_cache.head = NULL; - _pr_fd_cache.tail = NULL; - _pr_fd_cache.count = 0; - PR_DestroyLock(_pr_fd_cache.ml); - _pr_fd_cache.ml = NULL; - while ((pop = PR_StackPop(_pr_fd_cache.stack)) != NULL) - { - fd = (PRFileDesc*)((PRPtrdiff)pop - (PRPtrdiff)stack2fd); - PR_DELETE(fd->secret); - PR_DELETE(fd); - } - PR_DestroyStack(_pr_fd_cache.stack); - _pr_fd_cache.stack = NULL; -} /* _PR_CleanupFdCache */ - -/* prfdcach.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prfile.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prfile.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prfile.c 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prfile.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,783 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include - -#ifdef XP_UNIX -#if defined(AIX) || defined(QNX) -/* To pick up sysconf */ -#include -#else -/* To pick up getrlimit, setrlimit */ -#include -#include -#endif -#endif /* XP_UNIX */ - -extern PRLock *_pr_flock_lock; -extern PRCondVar *_pr_flock_cv; - -static PRInt32 PR_CALLBACK FileRead(PRFileDesc *fd, void *buf, PRInt32 amount) -{ - PRInt32 rv = 0; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - rv = -1; - } - if (rv == -1) - return rv; - - rv = _PR_MD_READ(fd, buf, amount); - if (rv < 0) { - PR_ASSERT(rv == -1); - } - PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv)); - return rv; -} - -static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 amount) -{ - PRInt32 rv = 0; - PRInt32 temp, count; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - rv = -1; - } - if (rv != 0) - return rv; - - count = 0; -#if !defined(_PR_HAVE_O_APPEND) /* Bugzilla: 4090, 276330 */ - if (fd->secret->appendMode) { - if (PR_Seek64(fd, 0, PR_SEEK_END) == -1) { - return -1; - } - } /* if (fd->secret->appendMode...) */ -#endif /* _PR_HAVE_O_APPEND */ - while (amount > 0) { - temp = _PR_MD_WRITE(fd, buf, amount); - if (temp < 0) { - count = -1; - break; - } - count += temp; - if (fd->secret->nonblocking) { - break; - } - buf = (const void*) ((const char*)buf + temp); - amount -= temp; - } - PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count)); - return count; -} - -static PROffset32 PR_CALLBACK FileSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) -{ - PROffset32 result; - - result = _PR_MD_LSEEK(fd, offset, whence); - return result; -} - -static PROffset64 PR_CALLBACK FileSeek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) -{ - PROffset64 result; - - result = _PR_MD_LSEEK64(fd, offset, whence); - return result; -} - -static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc *fd) -{ - PRInt32 result, cur, end; - - cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR); - - if (cur >= 0) - end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END); - - if ((cur < 0) || (end < 0)) { - return -1; - } - - result = end - cur; - _PR_MD_LSEEK(fd, cur, PR_SEEK_SET); - - return result; -} - -static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd) -{ - PRInt64 result, cur, end; - PRInt64 minus_one; - - LL_I2L(minus_one, -1); - cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR); - - if (LL_GE_ZERO(cur)) - end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END); - - if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one; - - LL_SUB(result, end, cur); - (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET); - - return result; -} - -static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd) -{ - PRInt32 rv; - rv = _PR_MD_PIPEAVAILABLE(fd); - return rv; -} - -static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd) -{ - PRInt64 rv; - LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd)); - return rv; -} - -static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd) -{ - return PR_SUCCESS; -} - -static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info) -{ - PRInt32 rv; - - rv = _PR_MD_GETOPENFILEINFO(fd, info); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; -} - -static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info) -{ - /* $$$$ NOT YET IMPLEMENTED */ - PRInt32 rv; - - rv = _PR_MD_GETOPENFILEINFO64(fd, info); - if (rv < 0) return PR_FAILURE; - else return PR_SUCCESS; -} - -static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd) -{ - PRInt32 result; - result = _PR_MD_FSYNC(fd); - if (result < 0) { - return PR_FAILURE; - } - return PR_SUCCESS; -} - -static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd) -{ - if (!fd || !fd->secret - || (fd->secret->state != _PR_FILEDESC_OPEN - && fd->secret->state != _PR_FILEDESC_CLOSED)) { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - return PR_FAILURE; - } - - if (fd->secret->state == _PR_FILEDESC_OPEN) { - if (_PR_MD_CLOSE_FILE(fd->secret->md.osfd) < 0) { - return PR_FAILURE; - } - fd->secret->state = _PR_FILEDESC_CLOSED; - } - PR_FreeFileDesc(fd); - return PR_SUCCESS; -} - -static PRInt16 PR_CALLBACK FilePoll( - PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) -{ - *out_flags = 0; - return in_flags; -} /* FilePoll */ - -static PRIOMethods _pr_fileMethods = { - PR_DESC_FILE, - FileClose, - FileRead, - FileWrite, - FileAvailable, - FileAvailable64, - FileSync, - FileSeek, - FileSeek64, - FileGetInfo, - FileGetInfo64, - (PRWritevFN)_PR_InvalidInt, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt, - (PRSendFN)_PR_InvalidInt, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - FilePoll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - (PRGetsocknameFN)_PR_InvalidStatus, - (PRGetpeernameFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void) -{ - return &_pr_fileMethods; -} - -static PRIOMethods _pr_pipeMethods = { - PR_DESC_PIPE, - FileClose, - FileRead, - FileWrite, - PipeAvailable, - PipeAvailable64, - PipeSync, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - (PRWritevFN)_PR_InvalidInt, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt, - (PRSendFN)_PR_InvalidInt, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - FilePoll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - (PRGetsocknameFN)_PR_InvalidStatus, - (PRGetpeernameFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void) -{ - return &_pr_pipeMethods; -} - -PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode) -{ - PROsfd osfd; - PRFileDesc *fd = 0; -#if !defined(_PR_HAVE_O_APPEND) - PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - /* Map pr open flags and mode to os specific flags */ - - osfd = _PR_MD_OPEN(name, flags, mode); - if (osfd != -1) { - fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); - if (!fd) { - (void) _PR_MD_CLOSE_FILE(osfd); - } else { -#if !defined(_PR_HAVE_O_APPEND) - fd->secret->appendMode = appendMode; -#endif - _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); - } - } - return fd; -} - -PR_IMPLEMENT(PRFileDesc*) PR_OpenFile( - const char *name, PRIntn flags, PRIntn mode) -{ - PROsfd osfd; - PRFileDesc *fd = 0; -#if !defined(_PR_HAVE_O_APPEND) - PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - /* Map pr open flags and mode to os specific flags */ - - osfd = _PR_MD_OPEN_FILE(name, flags, mode); - if (osfd != -1) { - fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); - if (!fd) { - (void) _PR_MD_CLOSE_FILE(osfd); - } else { -#if !defined(_PR_HAVE_O_APPEND) - fd->secret->appendMode = appendMode; -#endif - _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); - } - } - return fd; -} - -PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void) -{ -#if defined(XP_UNIX) && !defined(AIX) && !defined(QNX) - struct rlimit rlim; - - if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) { - /* XXX need to call PR_SetError() */ - return -1; - } - - return rlim.rlim_max; -#elif defined(AIX) || defined(QNX) - return sysconf(_SC_OPEN_MAX); -#elif defined(WIN32) - /* - * There is a systemwide limit of 65536 user handles. - */ - return 16384; -#elif defined (WIN16) - return FOPEN_MAX; -#elif defined(XP_OS2) - ULONG ulReqCount = 0; - ULONG ulCurMaxFH = 0; - DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH); - return ulCurMaxFH; -#elif defined(XP_BEOS) - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; -#else - write me; -#endif -} - -PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size) -{ -#if defined(XP_UNIX) && !defined(AIX) && !defined(QNX) - struct rlimit rlim; - PRInt32 tableMax = PR_GetSysfdTableMax(); - - if (tableMax < 0) - return -1; - - if (tableMax > FD_SETSIZE) - tableMax = FD_SETSIZE; - - rlim.rlim_max = tableMax; - - /* Grow as much as we can; even if too big */ - if ( rlim.rlim_max < table_size ) - rlim.rlim_cur = rlim.rlim_max; - else - rlim.rlim_cur = table_size; - - if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) { - /* XXX need to call PR_SetError() */ - return -1; - } - - return rlim.rlim_cur; -#elif defined(XP_OS2) - PRInt32 tableMax = PR_GetSysfdTableMax(); - if (table_size > tableMax) { - APIRET rc = NO_ERROR; - rc = DosSetMaxFH(table_size); - if (rc == NO_ERROR) - return table_size; - else - return -1; - } - return tableMax; -#elif defined(AIX) || defined(QNX) \ - || defined(WIN32) || defined(WIN16) || defined(XP_BEOS) - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; -#else - write me; -#endif -} - -PR_IMPLEMENT(PRStatus) PR_Delete(const char *name) -{ - PRInt32 rv; - - rv = _PR_MD_DELETE(name); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info) -{ - PRInt32 rv; - - rv = _PR_MD_GETFILEINFO(fn, info); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info) -{ - PRInt32 rv; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - rv = _PR_MD_GETFILEINFO64(fn, info); - if (rv < 0) { - return PR_FAILURE; - } else { - return PR_SUCCESS; - } -} - -PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to) -{ - PRInt32 rv; - - rv = _PR_MD_RENAME(from, to); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how) -{ -PRInt32 rv; - - rv = _PR_MD_ACCESS(name, how); - if (rv < 0) { - return PR_FAILURE; - } else - return PR_SUCCESS; -} - -/* -** Import an existing OS file to NSPR -*/ -PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd) -{ - PRFileDesc *fd = NULL; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); - if( !fd ) { - (void) _PR_MD_CLOSE_FILE(osfd); - } else { - _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); - } - - return fd; -} - -/* -** Import an existing OS pipe to NSPR -*/ -PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd) -{ - PRFileDesc *fd = NULL; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - fd = PR_AllocFileDesc(osfd, &_pr_pipeMethods); - if( !fd ) { - (void) _PR_MD_CLOSE_FILE(osfd); - } else { - _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); -#ifdef WINNT - fd->secret->md.sync_file_io = PR_TRUE; -#endif - } - - return fd; -} - -#ifndef NO_NSPR_10_SUPPORT -/* -** PR_Stat() for Win16 is defined in w16io.c -** it is a hack to circumvent problems in Gromit and Java -** See also: BugSplat: 98516. -*/ -#if !defined(WIN16) -/* - * This function is supposed to be for backward compatibility with - * nspr 1.0. Therefore, it still uses the nspr 1.0 error-reporting - * mechanism -- returns a PRInt32, which is the error code when the call - * fails. - * - * If we need this function in nspr 2.0, it should be changed to - * return PRStatus, as follows: - * - * PR_IMPLEMENT(PRStatus) PR_Stat(const char *name, struct stat *buf) - * { - * PRInt32 rv; - * - * rv = _PR_MD_STAT(name, buf); - * if (rv < 0) - * return PR_FAILURE; - * else - * return PR_SUCCESS; - * } - * - * -- wtc, 2/14/97. - */ -PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf) -{ - PRInt32 rv; - - rv = _PR_MD_STAT(name, buf); - return rv; -} - -#endif /* !defined(WIN16) */ -#endif /* ! NO_NSPR_10_SUPPORT */ - -PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd) -{ - PRStatus status = PR_SUCCESS; - -#ifdef WINNT - if (!fd->secret->md.io_model_committed) { - PRInt32 rv; - rv = _md_Associate((HANDLE)fd->secret->md.osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } -#endif - - PR_Lock(_pr_flock_lock); - while (fd->secret->lockCount == -1) - PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT); - if (fd->secret->lockCount == 0) { - fd->secret->lockCount = -1; - PR_Unlock(_pr_flock_lock); - status = _PR_MD_LOCKFILE(fd->secret->md.osfd); - PR_Lock(_pr_flock_lock); - fd->secret->lockCount = (status == PR_SUCCESS) ? 1 : 0; - PR_NotifyAllCondVar(_pr_flock_cv); - } else { - fd->secret->lockCount++; - } - PR_Unlock(_pr_flock_lock); - - return status; -} - -PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd) -{ - PRStatus status = PR_SUCCESS; - -#ifdef WINNT - if (!fd->secret->md.io_model_committed) { - PRInt32 rv; - rv = _md_Associate((HANDLE)fd->secret->md.osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } -#endif - - PR_Lock(_pr_flock_lock); - if (fd->secret->lockCount == 0) { - status = _PR_MD_TLOCKFILE(fd->secret->md.osfd); - PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0); - if (status == PR_SUCCESS) - fd->secret->lockCount = 1; - } else { - fd->secret->lockCount++; - } - PR_Unlock(_pr_flock_lock); - - return status; -} - -PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd) -{ - PRStatus rv = PR_SUCCESS; - - PR_Lock(_pr_flock_lock); - if (fd->secret->lockCount == 1) { - rv = _PR_MD_UNLOCKFILE(fd->secret->md.osfd); - if (rv == PR_SUCCESS) - fd->secret->lockCount = 0; - } else { - fd->secret->lockCount--; - } - PR_Unlock(_pr_flock_lock); - - return rv; -} - -PR_IMPLEMENT(PRStatus) PR_CreatePipe( - PRFileDesc **readPipe, - PRFileDesc **writePipe -) -{ -#if defined(WIN32) && !defined(WINCE) - HANDLE readEnd, writeEnd; - SECURITY_ATTRIBUTES pipeAttributes; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - ZeroMemory(&pipeAttributes, sizeof(pipeAttributes)); - pipeAttributes.nLength = sizeof(pipeAttributes); - pipeAttributes.bInheritHandle = TRUE; - if (CreatePipe(&readEnd, &writeEnd, &pipeAttributes, 0) == 0) { - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - return PR_FAILURE; - } - *readPipe = PR_AllocFileDesc((PROsfd)readEnd, &_pr_pipeMethods); - if (NULL == *readPipe) { - CloseHandle(readEnd); - CloseHandle(writeEnd); - return PR_FAILURE; - } - *writePipe = PR_AllocFileDesc((PROsfd)writeEnd, &_pr_pipeMethods); - if (NULL == *writePipe) { - PR_Close(*readPipe); - CloseHandle(writeEnd); - return PR_FAILURE; - } -#ifdef WINNT - (*readPipe)->secret->md.sync_file_io = PR_TRUE; - (*writePipe)->secret->md.sync_file_io = PR_TRUE; -#endif - (*readPipe)->secret->inheritable = _PR_TRI_TRUE; - (*writePipe)->secret->inheritable = _PR_TRI_TRUE; - return PR_SUCCESS; -#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) -#ifdef XP_OS2 - HFILE pipefd[2]; -#else - int pipefd[2]; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - -#ifdef XP_OS2 - if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) { -#else - if (pipe(pipefd) == -1) { -#endif - /* XXX map pipe error */ - PR_SetError(PR_UNKNOWN_ERROR, errno); - return PR_FAILURE; - } - *readPipe = PR_AllocFileDesc(pipefd[0], &_pr_pipeMethods); - if (NULL == *readPipe) { - close(pipefd[0]); - close(pipefd[1]); - return PR_FAILURE; - } - *writePipe = PR_AllocFileDesc(pipefd[1], &_pr_pipeMethods); - if (NULL == *writePipe) { - PR_Close(*readPipe); - close(pipefd[1]); - return PR_FAILURE; - } -#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */ - _PR_MD_MAKE_NONBLOCK(*readPipe); -#endif - _PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE); -#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */ - _PR_MD_MAKE_NONBLOCK(*writePipe); -#endif - _PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE); - return PR_SUCCESS; -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -#endif -} - -#ifdef MOZ_UNICODE -/* ================ UTF16 Interfaces ================================ */ -PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16( - const PRUnichar *name, PRIntn flags, PRIntn mode) -{ - PROsfd osfd; - PRFileDesc *fd = 0; -#if !defined(_PR_HAVE_O_APPEND) - PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - /* Map pr open flags and mode to os specific flags */ - osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode); - if (osfd != -1) { - fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); - if (!fd) { - (void) _PR_MD_CLOSE_FILE(osfd); - } else { -#if !defined(_PR_HAVE_O_APPEND) - fd->secret->appendMode = appendMode; -#endif - _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); - } - } - return fd; -} - -PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info) -{ - PRInt32 rv; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - rv = _PR_MD_GETFILEINFO64_UTF16(fn, info); - if (rv < 0) { - return PR_FAILURE; - } else { - return PR_SUCCESS; - } -} - -/* ================ UTF16 Interfaces ================================ */ -#endif /* MOZ_UNICODE */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prio.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prio.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prio.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prio.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include /* for memset() */ - - -/************************************************************************/ - -PRLock *_pr_flock_lock; -PRCondVar *_pr_flock_cv; - -#ifdef WINCE -/* - * There are no stdin, stdout, stderr in Windows CE. INVALID_HANDLE_VALUE - * should cause all I/O functions on the handle to fail. - */ -#define STD_INPUT_HANDLE ((DWORD)-10) -#define STD_OUTPUT_HANDLE ((DWORD)-11) -#define STD_ERROR_HANDLE ((DWORD)-12) - -static HANDLE GetStdHandle(DWORD nStdHandle) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return INVALID_HANDLE_VALUE; -} -#endif - -void _PR_InitIO(void) -{ - const PRIOMethods *methods = PR_GetFileMethods(); - - _PR_InitFdCache(); - - _pr_flock_lock = PR_NewLock(); - _pr_flock_cv = PR_NewCondVar(_pr_flock_lock); - -#ifdef WIN32 - _pr_stdin = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_INPUT_HANDLE), - methods); - _pr_stdout = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_OUTPUT_HANDLE), - methods); - _pr_stderr = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_ERROR_HANDLE), - methods); -#ifdef WINNT - _pr_stdin->secret->md.sync_file_io = PR_TRUE; - _pr_stdout->secret->md.sync_file_io = PR_TRUE; - _pr_stderr->secret->md.sync_file_io = PR_TRUE; -#endif -#else - _pr_stdin = PR_AllocFileDesc(0, methods); - _pr_stdout = PR_AllocFileDesc(1, methods); - _pr_stderr = PR_AllocFileDesc(2, methods); -#endif - _PR_MD_INIT_FD_INHERITABLE(_pr_stdin, PR_TRUE); - _PR_MD_INIT_FD_INHERITABLE(_pr_stdout, PR_TRUE); - _PR_MD_INIT_FD_INHERITABLE(_pr_stderr, PR_TRUE); - - _PR_MD_INIT_IO(); -} - -void _PR_CleanupIO(void) -{ - PR_FreeFileDesc(_pr_stdin); - _pr_stdin = NULL; - PR_FreeFileDesc(_pr_stdout); - _pr_stdout = NULL; - PR_FreeFileDesc(_pr_stderr); - _pr_stderr = NULL; - - if (_pr_flock_cv) { - PR_DestroyCondVar(_pr_flock_cv); - _pr_flock_cv = NULL; - } - if (_pr_flock_lock) { - PR_DestroyLock(_pr_flock_lock); - _pr_flock_lock = NULL; - } - - _PR_CleanupFdCache(); -} - -PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd) -{ - PRFileDesc *result = NULL; - PR_ASSERT((int) osfd >= PR_StandardInput && osfd <= PR_StandardError); - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - switch (osfd) - { - case PR_StandardInput: result = _pr_stdin; break; - case PR_StandardOutput: result = _pr_stdout; break; - case PR_StandardError: result = _pr_stderr; break; - default: - (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - } - return result; -} - -PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc( - PROsfd osfd, const PRIOMethods *methods) -{ - PRFileDesc *fd; - -#ifdef XP_UNIX - /* - * Assert that the file descriptor is small enough to fit in the - * fd_set passed to select - */ - PR_ASSERT(osfd < FD_SETSIZE); -#endif - fd = _PR_Getfd(); - if (fd) { - /* Initialize the members of PRFileDesc and PRFilePrivate */ - fd->methods = methods; - fd->secret->state = _PR_FILEDESC_OPEN; - fd->secret->md.osfd = osfd; - _PR_MD_INIT_FILEDESC(fd); - } else { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - } - - return fd; -} - -PR_IMPLEMENT(void) PR_FreeFileDesc(PRFileDesc *fd) -{ - PR_ASSERT(fd); - _PR_Putfd(fd); -} - -/* -** Wait for some i/o to finish on one or more more poll descriptors. -*/ -PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - return(_PR_MD_PR_POLL(pds, npds, timeout)); -} - -/* -** Set the inheritance attribute of a file descriptor. -*/ -PR_IMPLEMENT(PRStatus) PR_SetFDInheritable( - PRFileDesc *fd, - PRBool inheritable) -{ -#if defined(XP_UNIX) || defined(WIN32) || defined(XP_OS2) || defined(XP_BEOS) - /* - * Only a non-layered, NSPR file descriptor can be inherited - * by a child process. - */ - if (fd->identity != PR_NSPR_IO_LAYER) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - if (fd->secret->inheritable != inheritable) { - if (_PR_MD_SET_FD_INHERITABLE(fd, inheritable) == PR_FAILURE) { - return PR_FAILURE; - } - fd->secret->inheritable = inheritable; - } - return PR_SUCCESS; -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -#endif -} - -/* -** This function only has a useful implementation in the debug build of -** the pthreads version. -*/ -PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) -{ - /* do nothing */ -} /* PT_FPrintStats */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/priometh.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/priometh.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/priometh.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/priometh.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,596 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "primpl.h" - -#include - -/*****************************************************************************/ -/************************** Invalid I/O method object ************************/ -/*****************************************************************************/ -PRIOMethods _pr_faulty_methods = { - (PRDescType)0, - (PRCloseFN)_PR_InvalidStatus, - (PRReadFN)_PR_InvalidInt, - (PRWriteFN)_PR_InvalidInt, - (PRAvailableFN)_PR_InvalidInt, - (PRAvailable64FN)_PR_InvalidInt64, - (PRFsyncFN)_PR_InvalidStatus, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - (PRWritevFN)_PR_InvalidInt, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt, - (PRSendFN)_PR_InvalidInt, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - (PRPollFN)_PR_InvalidInt16, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - (PRGetsocknameFN)_PR_InvalidStatus, - (PRGetpeernameFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -PRIntn _PR_InvalidInt(void) -{ - PR_ASSERT(!"I/O method is invalid"); - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} /* _PR_InvalidInt */ - -PRInt16 _PR_InvalidInt16(void) -{ - PR_ASSERT(!"I/O method is invalid"); - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return -1; -} /* _PR_InvalidInt */ - -PRInt64 _PR_InvalidInt64(void) -{ - PRInt64 rv; - LL_I2L(rv, -1); - PR_ASSERT(!"I/O method is invalid"); - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return rv; -} /* _PR_InvalidInt */ - -/* - * An invalid method that returns PRStatus - */ - -PRStatus _PR_InvalidStatus(void) -{ - PR_ASSERT(!"I/O method is invalid"); - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return PR_FAILURE; -} /* _PR_InvalidDesc */ - -/* - * An invalid method that returns a pointer - */ - -PRFileDesc *_PR_InvalidDesc(void) -{ - PR_ASSERT(!"I/O method is invalid"); - PR_SetError(PR_INVALID_METHOD_ERROR, 0); - return NULL; -} /* _PR_InvalidDesc */ - -PR_IMPLEMENT(PRDescType) PR_GetDescType(PRFileDesc *file) -{ - return file->methods->file_type; -} - -PR_IMPLEMENT(PRStatus) PR_Close(PRFileDesc *fd) -{ - return (fd->methods->close)(fd); -} - -PR_IMPLEMENT(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount) -{ - return((fd->methods->read)(fd,buf,amount)); -} - -PR_IMPLEMENT(PRInt32) PR_Write(PRFileDesc *fd, const void *buf, PRInt32 amount) -{ - return((fd->methods->write)(fd,buf,amount)); -} - -PR_IMPLEMENT(PRInt32) PR_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence) -{ - return((fd->methods->seek)(fd, offset, whence)); -} - -PR_IMPLEMENT(PRInt64) PR_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence) -{ - return((fd->methods->seek64)(fd, offset, whence)); -} - -PR_IMPLEMENT(PRInt32) PR_Available(PRFileDesc *fd) -{ - return((fd->methods->available)(fd)); -} - -PR_IMPLEMENT(PRInt64) PR_Available64(PRFileDesc *fd) -{ - return((fd->methods->available64)(fd)); -} - -PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info) -{ - return((fd->methods->fileInfo)(fd, info)); -} - -PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info) -{ - return((fd->methods->fileInfo64)(fd, info)); -} - -PR_IMPLEMENT(PRStatus) PR_Sync(PRFileDesc *fd) -{ - return((fd->methods->fsync)(fd)); -} - -PR_IMPLEMENT(PRStatus) PR_Connect( - PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) -{ - return((fd->methods->connect)(fd,addr,timeout)); -} - -PR_IMPLEMENT(PRStatus) PR_ConnectContinue( - PRFileDesc *fd, PRInt16 out_flags) -{ - return((fd->methods->connectcontinue)(fd,out_flags)); -} - -PR_IMPLEMENT(PRFileDesc*) PR_Accept(PRFileDesc *fd, PRNetAddr *addr, -PRIntervalTime timeout) -{ - return((fd->methods->accept)(fd,addr,timeout)); -} - -PR_IMPLEMENT(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr) -{ - return((fd->methods->bind)(fd,addr)); -} - -PR_IMPLEMENT(PRStatus) PR_Shutdown(PRFileDesc *fd, PRShutdownHow how) -{ - return((fd->methods->shutdown)(fd,how)); -} - -PR_IMPLEMENT(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog) -{ - return((fd->methods->listen)(fd,backlog)); -} - -PR_IMPLEMENT(PRInt32) PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount, -PRIntn flags, PRIntervalTime timeout) -{ - return((fd->methods->recv)(fd,buf,amount,flags,timeout)); -} - -PR_IMPLEMENT(PRInt32) PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount, -PRIntn flags, PRIntervalTime timeout) -{ - return((fd->methods->send)(fd,buf,amount,flags,timeout)); -} - -PR_IMPLEMENT(PRInt32) PR_Writev(PRFileDesc *fd, const PRIOVec *iov, -PRInt32 iov_size, PRIntervalTime timeout) -{ - if (iov_size > PR_MAX_IOVECTOR_SIZE) - { - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); - return -1; - } - return((fd->methods->writev)(fd,iov,iov_size,timeout)); -} - -PR_IMPLEMENT(PRInt32) PR_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, -PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) -{ - return((fd->methods->recvfrom)(fd,buf,amount,flags,addr,timeout)); -} - -PR_IMPLEMENT(PRInt32) PR_SendTo( - PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout) -{ - return((fd->methods->sendto)(fd,buf,amount,flags,addr,timeout)); -} - -PR_IMPLEMENT(PRInt32) PR_TransmitFile( - PRFileDesc *sd, PRFileDesc *fd, const void *hdr, PRInt32 hlen, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - return((sd->methods->transmitfile)(sd,fd,hdr,hlen,flags,timeout)); -} - -PR_IMPLEMENT(PRInt32) PR_AcceptRead( - PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, - void *buf, PRInt32 amount, PRIntervalTime timeout) -{ - return((sd->methods->acceptread)(sd, nd, raddr, buf, amount,timeout)); -} - -PR_IMPLEMENT(PRStatus) PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr) -{ - return((fd->methods->getsockname)(fd,addr)); -} - -PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) -{ - return((fd->methods->getpeername)(fd,addr)); -} - -PR_IMPLEMENT(PRStatus) PR_GetSocketOption( - PRFileDesc *fd, PRSocketOptionData *data) -{ - return((fd->methods->getsocketoption)(fd, data)); -} - -PR_IMPLEMENT(PRStatus) PR_SetSocketOption( - PRFileDesc *fd, const PRSocketOptionData *data) -{ - return((fd->methods->setsocketoption)(fd, data)); -} - -PR_IMPLEMENT(PRInt32) PR_SendFile( - PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - return((sd->methods->sendfile)(sd,sfd,flags,timeout)); -} - -PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead( - PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, - void *buf, PRInt32 amount, PRIntervalTime timeout) -{ - PRInt32 rv = -1; - PRNetAddr remote; - PRFileDesc *accepted = NULL; - - /* - ** The timeout does not apply to the accept portion of the - ** operation - it waits indefinitely. - */ - accepted = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT); - if (NULL == accepted) return rv; - - rv = PR_Recv(accepted, buf, amount, 0, timeout); - if (rv >= 0) - { - /* copy the new info out where caller can see it */ -#define AMASK ((PRPtrdiff)7) /* mask for alignment of PRNetAddr */ - PRPtrdiff aligned = (PRPtrdiff)buf + amount + AMASK; - *raddr = (PRNetAddr*)(aligned & ~AMASK); - memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote)); - *nd = accepted; - return rv; - } - - PR_Close(accepted); - return rv; -} - -/* - * PR_EmulateSendFile - * - * Send file sfd->fd across socket sd. If header/trailer are specified - * they are sent before and after the file, respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ - -#if defined(XP_UNIX) || defined(WIN32) - -/* - * An implementation based on memory-mapped files - */ - -#define SENDFILE_MMAP_CHUNK (256 * 1024) - -PR_IMPLEMENT(PRInt32) PR_EmulateSendFile( - PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - PRInt32 rv, count = 0; - PRInt32 len, file_bytes, index = 0; - PRFileInfo info; - PRIOVec iov[3]; - PRFileMap *mapHandle = NULL; - void *addr = (void*)0; /* initialized to some arbitrary value. Keeps compiler warnings down. */ - PRUint32 file_mmap_offset, alignment; - PRInt64 zero64; - PROffset64 file_mmap_offset64; - PRUint32 addr_offset, mmap_len; - - /* Get file size */ - if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) { - count = -1; - goto done; - } - if (sfd->file_nbytes && - (info.size < (sfd->file_offset + sfd->file_nbytes))) { - /* - * there are fewer bytes in file to send than specified - */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - count = -1; - goto done; - } - if (sfd->file_nbytes) - file_bytes = sfd->file_nbytes; - else - file_bytes = info.size - sfd->file_offset; - - alignment = PR_GetMemMapAlignment(); - - /* number of initial bytes to skip in mmap'd segment */ - addr_offset = sfd->file_offset % alignment; - - /* find previous mmap alignment boundary */ - file_mmap_offset = sfd->file_offset - addr_offset; - - /* - * If the file is large, mmap and send the file in chunks so as - * to not consume too much virtual address space - */ - mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK); - len = mmap_len - addr_offset; - - /* - * Map in (part of) file. Take care of zero-length files. - */ - if (len) { - LL_I2L(zero64, 0); - mapHandle = PR_CreateFileMap(sfd->fd, zero64, PR_PROT_READONLY); - if (!mapHandle) { - count = -1; - goto done; - } - LL_I2L(file_mmap_offset64, file_mmap_offset); - addr = PR_MemMap(mapHandle, file_mmap_offset64, mmap_len); - if (!addr) { - count = -1; - goto done; - } - } - /* - * send headers first, followed by the file - */ - if (sfd->hlen) { - iov[index].iov_base = (char *) sfd->header; - iov[index].iov_len = sfd->hlen; - index++; - } - if (len) { - iov[index].iov_base = (char*)addr + addr_offset; - iov[index].iov_len = len; - index++; - } - if ((file_bytes == len) && (sfd->tlen)) { - /* - * all file data is mapped in; send the trailer too - */ - iov[index].iov_base = (char *) sfd->trailer; - iov[index].iov_len = sfd->tlen; - index++; - } - rv = PR_Writev(sd, iov, index, timeout); - if (len) - PR_MemUnmap(addr, mmap_len); - if (rv < 0) { - count = -1; - goto done; - } - - PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0)); - - file_bytes -= len; - count += rv; - if (!file_bytes) /* header, file and trailer are sent */ - goto done; - - /* - * send remaining bytes of the file, if any - */ - len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); - while (len > 0) { - /* - * Map in (part of) file - */ - file_mmap_offset = sfd->file_offset + count - sfd->hlen; - PR_ASSERT((file_mmap_offset % alignment) == 0); - - LL_I2L(file_mmap_offset64, file_mmap_offset); - addr = PR_MemMap(mapHandle, file_mmap_offset64, len); - if (!addr) { - count = -1; - goto done; - } - rv = PR_Send(sd, addr, len, 0, timeout); - PR_MemUnmap(addr, len); - if (rv < 0) { - count = -1; - goto done; - } - - PR_ASSERT(rv == len); - file_bytes -= rv; - count += rv; - len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); - } - PR_ASSERT(0 == file_bytes); - if (sfd->tlen) { - rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout); - if (rv >= 0) { - PR_ASSERT(rv == sfd->tlen); - count += rv; - } else - count = -1; - } -done: - if (mapHandle) - PR_CloseFileMap(mapHandle); - if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) - PR_Close(sd); - return count; -} - -#else - -PR_IMPLEMENT(PRInt32) PR_EmulateSendFile( - PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - PRInt32 rv, count = 0; - PRInt32 rlen; - const void * buffer; - PRInt32 buflen; - PRInt32 sendbytes, readbytes; - char *buf; - -#define _SENDFILE_BUFSIZE (16 * 1024) - - buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE); - if (buf == NULL) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - - /* - * send header first - */ - buflen = sfd->hlen; - buffer = sfd->header; - while (buflen) { - rv = PR_Send(sd, buffer, buflen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - buffer = (const void*) ((const char*)buffer + rv); - buflen -= rv; - } - } - - /* - * send file next - */ - if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) { - rv = -1; - goto done; - } - sendbytes = sfd->file_nbytes; - if (sendbytes == 0) { - /* send entire file */ - while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) { - while (rlen) { - char *bufptr = buf; - - rv = PR_Send(sd, bufptr, rlen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - bufptr = ((char*)bufptr + rv); - rlen -= rv; - } - } - } - if (rlen < 0) { - /* PR_Read() has invoked PR_SetError(). */ - rv = -1; - goto done; - } - } else { - readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); - while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) { - while (rlen) { - char *bufptr = buf; - - rv = PR_Send(sd, bufptr, rlen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - sendbytes -= rv; - bufptr = ((char*)bufptr + rv); - rlen -= rv; - } - } - readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); - } - if (rlen < 0) { - /* PR_Read() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else if (sendbytes != 0) { - /* - * there are fewer bytes in file to send than specified - */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = -1; - goto done; - } - } - - /* - * send trailer last - */ - buflen = sfd->tlen; - buffer = sfd->trailer; - while (buflen) { - rv = PR_Send(sd, buffer, buflen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - buffer = (const void*) ((const char*)buffer + rv); - buflen -= rv; - } - } - rv = count; - -done: - if (buf) - PR_DELETE(buf); - if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) - PR_Close(sd); - return rv; -} - -#endif - -/* priometh.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/pripv6.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/pripv6.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/pripv6.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/pripv6.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,364 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: pripv6.c -** Description: Support for various functions unique to IPv6 -*/ -#include "primpl.h" -#include - -#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE) - -static PRIOMethods ipv6_to_v4_tcpMethods; -static PRIOMethods ipv6_to_v4_udpMethods; -static PRDescIdentity _pr_ipv6_to_ipv4_id; -extern PRBool IsValidNetAddr(const PRNetAddr *addr); -extern PRIPv6Addr _pr_in6addr_any; -extern PRIPv6Addr _pr_in6addr_loopback; - -/* - * convert an IPv4-mapped IPv6 addr to an IPv4 addr - */ -static void _PR_ConvertToIpv4NetAddr(const PRNetAddr *src_v6addr, - PRNetAddr *dst_v4addr) -{ -const PRUint8 *srcp; - - PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family); - - if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) { - srcp = src_v6addr->ipv6.ip.pr_s6_addr; - memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4); - } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrAny)) { - dst_v4addr->inet.ip = htonl(INADDR_ANY); - } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback)) { - dst_v4addr->inet.ip = htonl(INADDR_LOOPBACK); - } - dst_v4addr->inet.family = PR_AF_INET; - dst_v4addr->inet.port = src_v6addr->ipv6.port; -} - -/* - * convert an IPv4 addr to an IPv4-mapped IPv6 addr - */ -static void _PR_ConvertToIpv6NetAddr(const PRNetAddr *src_v4addr, - PRNetAddr *dst_v6addr) -{ -PRUint8 *dstp; - - PR_ASSERT(PR_AF_INET == src_v4addr->inet.family); - dst_v6addr->ipv6.family = PR_AF_INET6; - dst_v6addr->ipv6.port = src_v4addr->inet.port; - - if (htonl(INADDR_ANY) == src_v4addr->inet.ip) { - dst_v6addr->ipv6.ip = _pr_in6addr_any; - } else { - dstp = dst_v6addr->ipv6.ip.pr_s6_addr; - memset(dstp, 0, 10); - memset(dstp + 10, 0xff, 2); - memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4); - } -} - -static PRStatus PR_CALLBACK Ipv6ToIpv4SocketBind(PRFileDesc *fd, - const PRNetAddr *addr) -{ - PRNetAddr tmp_ipv4addr; - const PRNetAddr *tmp_addrp; - PRFileDesc *lo = fd->lower; - - if (PR_AF_INET6 != addr->raw.family) { - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return PR_FAILURE; - } - if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || - PR_IsNetAddrType(addr, PR_IpAddrAny)) { - _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); - tmp_addrp = &tmp_ipv4addr; - } else { - PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); - return PR_FAILURE; - } - return((lo->methods->bind)(lo,tmp_addrp)); -} - -static PRStatus PR_CALLBACK Ipv6ToIpv4SocketConnect( - PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) -{ - PRNetAddr tmp_ipv4addr; - const PRNetAddr *tmp_addrp; - - if (PR_AF_INET6 != addr->raw.family) { - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return PR_FAILURE; - } - if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || - PR_IsNetAddrType(addr, PR_IpAddrLoopback)) { - _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); - tmp_addrp = &tmp_ipv4addr; - } else { - PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); - return PR_FAILURE; - } - return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout); -} - -static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketSendTo( - PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout) -{ - PRNetAddr tmp_ipv4addr; - const PRNetAddr *tmp_addrp; - - if (PR_AF_INET6 != addr->raw.family) { - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return PR_FAILURE; - } - if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || - PR_IsNetAddrType(addr, PR_IpAddrLoopback)) { - _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); - tmp_addrp = &tmp_ipv4addr; - } else { - PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); - return PR_FAILURE; - } - return (fd->lower->methods->sendto)( - fd->lower, buf, amount, flags, tmp_addrp, timeout); -} - -static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept ( - PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout) -{ - PRStatus rv; - PRFileDesc *newfd; - PRFileDesc *newstack; - PRNetAddr tmp_ipv4addr; - PRNetAddr *addrlower = NULL; - - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - newstack = PR_NEW(PRFileDesc); - if (NULL == newstack) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - *newstack = *fd; /* make a copy of the accepting layer */ - - if (addr) - addrlower = &tmp_ipv4addr; - newfd = (fd->lower->methods->accept)(fd->lower, addrlower, timeout); - if (NULL == newfd) - { - PR_DELETE(newstack); - return NULL; - } - if (addr) - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, addr); - - rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); - PR_ASSERT(PR_SUCCESS == rv); - return newfd; /* that's it */ -} - -static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd, - PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount, - PRIntervalTime timeout) -{ - PRInt32 nbytes; - PRStatus rv; - PRNetAddr tmp_ipv4addr; - PRFileDesc *newstack; - - PR_ASSERT(sd != NULL); - PR_ASSERT(sd->lower != NULL); - - newstack = PR_NEW(PRFileDesc); - if (NULL == newstack) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - *newstack = *sd; /* make a copy of the accepting layer */ - - nbytes = sd->lower->methods->acceptread( - sd->lower, nd, ipv6_raddr, buf, amount, timeout); - if (-1 == nbytes) - { - PR_DELETE(newstack); - return nbytes; - } - tmp_ipv4addr = **ipv6_raddr; /* copy */ - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr); - - /* this PR_PushIOLayer call cannot fail */ - rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack); - PR_ASSERT(PR_SUCCESS == rv); - return nbytes; -} - -static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetName(PRFileDesc *fd, - PRNetAddr *ipv6addr) -{ - PRStatus result; - PRNetAddr tmp_ipv4addr; - - result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr); - if (PR_SUCCESS == result) { - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); - PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); - } - return result; -} - -static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetPeerName(PRFileDesc *fd, - PRNetAddr *ipv6addr) -{ - PRStatus result; - PRNetAddr tmp_ipv4addr; - - result = (fd->lower->methods->getpeername)(fd->lower, &tmp_ipv4addr); - if (PR_SUCCESS == result) { - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); - PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); - } - return result; -} - -static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf, - PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr, - PRIntervalTime timeout) -{ - PRNetAddr tmp_ipv4addr; - PRInt32 result; - - result = (fd->lower->methods->recvfrom)( - fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout); - if (-1 != result) { - _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); - PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); - } - return result; -} - -#if defined(_PR_INET6_PROBE) -static PRBool ipv6_is_present; -extern PRBool _pr_test_ipv6_socket(void); - -#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) -extern PRStatus _pr_find_getipnodebyname(void); -#endif - -#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO) -extern PRStatus _pr_find_getaddrinfo(void); -#endif - -static PRBool -_pr_probe_ipv6_presence(void) -{ -#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) - if (_pr_find_getipnodebyname() != PR_SUCCESS) - return PR_FALSE; -#endif - -#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO) - if (_pr_find_getaddrinfo() != PR_SUCCESS) - return PR_FALSE; -#endif - - return _pr_test_ipv6_socket(); -} -#endif /* _PR_INET6_PROBE */ - -static PRCallOnceType _pr_init_ipv6_once; - -static PRStatus PR_CALLBACK _pr_init_ipv6(void) -{ - const PRIOMethods *stubMethods; - -#if defined(_PR_INET6_PROBE) - ipv6_is_present = _pr_probe_ipv6_presence(); - if (ipv6_is_present) - return PR_SUCCESS; -#endif - - _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer"); - PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id); - - stubMethods = PR_GetDefaultIOMethods(); - - ipv6_to_v4_tcpMethods = *stubMethods; /* first get the entire batch */ - /* then override the ones we care about */ - ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect; - ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind; - ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept; - ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead; - ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName; - ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName; -/* - ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption; - ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption; -*/ - ipv6_to_v4_udpMethods = *stubMethods; /* first get the entire batch */ - /* then override the ones we care about */ - ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect; - ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind; - ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo; - ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom; - ipv6_to_v4_udpMethods.getsockname = Ipv6ToIpv4SocketGetName; - ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName; -/* - ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption; - ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption; -*/ - return PR_SUCCESS; -} - -#if defined(_PR_INET6_PROBE) -PRBool _pr_ipv6_is_present(void) -{ - if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) - return PR_FALSE; - return ipv6_is_present; -} -#endif - -PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd) -{ - PRFileDesc *ipv6_fd = NULL; - - if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) - return PR_FAILURE; - - /* - * For platforms with no support for IPv6 - * create layered socket for IPv4-mapped IPv6 addresses - */ - if (fd->methods->file_type == PR_DESC_SOCKET_TCP) - ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id, - &ipv6_to_v4_tcpMethods); - else - ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id, - &ipv6_to_v4_udpMethods); - if (NULL == ipv6_fd) { - goto errorExit; - } - ipv6_fd->secret = NULL; - - if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) { - goto errorExit; - } - - return PR_SUCCESS; -errorExit: - - if (ipv6_fd) - ipv6_fd->dtor(ipv6_fd); - return PR_FAILURE; -} - -#endif /* !defined(_PR_INET6) || defined(_PR_INET6_PROBE) */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prlayer.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prlayer.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prlayer.c 2012-09-28 14:21:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prlayer.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,752 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prlayer.c -** Description: Routines for handling pushable protocol modules on sockets. -*/ - -#include "primpl.h" -#include "prerror.h" -#include "prmem.h" -#include "prlock.h" -#include "prlog.h" -#include "prio.h" - -#include /* for memset() */ -static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack); - -void PR_CALLBACK pl_FDDestructor(PRFileDesc *fd) -{ - PR_ASSERT(fd != NULL); - if (NULL != fd->lower) fd->lower->higher = fd->higher; - if (NULL != fd->higher) fd->higher->lower = fd->lower; - PR_DELETE(fd); -} - -/* -** Default methods that just call down to the next fd. -*/ -static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd) -{ - PRFileDesc *top, *lower; - PRStatus rv; - - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - PR_ASSERT(fd->secret == NULL); - PR_ASSERT(fd->methods->file_type == PR_DESC_LAYERED); - - if (PR_IO_LAYER_HEAD == fd->identity) { - /* - * new style stack; close all the layers, before deleting the - * stack head - */ - rv = fd->lower->methods->close(fd->lower); - _PR_DestroyIOLayer(fd); - return rv; - } else if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) { - /* - * lower layers of new style stack - */ - lower = fd->lower; - /* - * pop and cleanup current layer - */ - top = PR_PopIOLayer(fd->higher, PR_TOP_IO_LAYER); - top->dtor(top); - /* - * then call lower layer - */ - return (lower->methods->close(lower)); - } else { - /* old style stack */ - top = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); - top->dtor(top); - return (fd->methods->close)(fd); - } -} - -static PRInt32 PR_CALLBACK pl_DefRead (PRFileDesc *fd, void *buf, PRInt32 amount) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->read)(fd->lower, buf, amount); -} - -static PRInt32 PR_CALLBACK pl_DefWrite ( - PRFileDesc *fd, const void *buf, PRInt32 amount) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->write)(fd->lower, buf, amount); -} - -static PRInt32 PR_CALLBACK pl_DefAvailable (PRFileDesc *fd) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->available)(fd->lower); -} - -static PRInt64 PR_CALLBACK pl_DefAvailable64 (PRFileDesc *fd) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->available64)(fd->lower); -} - -static PRStatus PR_CALLBACK pl_DefFsync (PRFileDesc *fd) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->fsync)(fd->lower); -} - -static PRInt32 PR_CALLBACK pl_DefSeek ( - PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->seek)(fd->lower, offset, how); -} - -static PRInt64 PR_CALLBACK pl_DefSeek64 ( - PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->seek64)(fd->lower, offset, how); -} - -static PRStatus PR_CALLBACK pl_DefFileInfo (PRFileDesc *fd, PRFileInfo *info) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->fileInfo)(fd->lower, info); -} - -static PRStatus PR_CALLBACK pl_DefFileInfo64 (PRFileDesc *fd, PRFileInfo64 *info) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->fileInfo64)(fd->lower, info); -} - -static PRInt32 PR_CALLBACK pl_DefWritev (PRFileDesc *fd, const PRIOVec *iov, - PRInt32 size, PRIntervalTime timeout) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->writev)(fd->lower, iov, size, timeout); -} - -static PRStatus PR_CALLBACK pl_DefConnect ( - PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->connect)(fd->lower, addr, timeout); -} - -static PRStatus PR_CALLBACK pl_DefConnectcontinue ( - PRFileDesc *fd, PRInt16 out_flags) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->connectcontinue)(fd->lower, out_flags); -} - -static PRFileDesc* PR_CALLBACK pl_TopAccept ( - PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout) -{ - PRStatus rv; - PRFileDesc *newfd, *layer = fd; - PRFileDesc *newstack; - PRBool newstyle_stack = PR_FALSE; - - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - /* test for new style stack */ - while (NULL != layer->higher) - layer = layer->higher; - newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE; - newstack = PR_NEW(PRFileDesc); - if (NULL == newstack) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - *newstack = *fd; /* make a copy of the accepting layer */ - - newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout); - if (NULL == newfd) - { - PR_DELETE(newstack); - return NULL; - } - - if (newstyle_stack) { - newstack->lower = newfd; - newfd->higher = newstack; - return newstack; - } else { - /* this PR_PushIOLayer call cannot fail */ - rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); - PR_ASSERT(PR_SUCCESS == rv); - return newfd; /* that's it */ - } -} - -static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->bind)(fd->lower, addr); -} - -static PRStatus PR_CALLBACK pl_DefListen (PRFileDesc *fd, PRIntn backlog) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->listen)(fd->lower, backlog); -} - -static PRStatus PR_CALLBACK pl_DefShutdown (PRFileDesc *fd, PRIntn how) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->shutdown)(fd->lower, how); -} - -static PRInt32 PR_CALLBACK pl_DefRecv ( - PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->recv)( - fd->lower, buf, amount, flags, timeout); -} - -static PRInt32 PR_CALLBACK pl_DefSend ( - PRFileDesc *fd, const void *buf, - PRInt32 amount, PRIntn flags, PRIntervalTime timeout) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->send)(fd->lower, buf, amount, flags, timeout); -} - -static PRInt32 PR_CALLBACK pl_DefRecvfrom ( - PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->recvfrom)( - fd->lower, buf, amount, flags, addr, timeout); -} - -static PRInt32 PR_CALLBACK pl_DefSendto ( - PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRIntervalTime timeout) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->sendto)( - fd->lower, buf, amount, flags, addr, timeout); -} - -static PRInt16 PR_CALLBACK pl_DefPoll ( - PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags); -} - -static PRInt32 PR_CALLBACK pl_DefAcceptread ( - PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf, - PRInt32 amount, PRIntervalTime t) -{ - PRInt32 nbytes; - PRStatus rv; - PRFileDesc *newstack; - PRFileDesc *layer = sd; - PRBool newstyle_stack = PR_FALSE; - - PR_ASSERT(sd != NULL); - PR_ASSERT(sd->lower != NULL); - - /* test for new style stack */ - while (NULL != layer->higher) - layer = layer->higher; - newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE; - newstack = PR_NEW(PRFileDesc); - if (NULL == newstack) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - *newstack = *sd; /* make a copy of the accepting layer */ - - nbytes = sd->lower->methods->acceptread( - sd->lower, nd, raddr, buf, amount, t); - if (-1 == nbytes) - { - PR_DELETE(newstack); - return nbytes; - } - if (newstyle_stack) { - newstack->lower = *nd; - (*nd)->higher = newstack; - *nd = newstack; - return nbytes; - } else { - /* this PR_PushIOLayer call cannot fail */ - rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack); - PR_ASSERT(PR_SUCCESS == rv); - return nbytes; - } -} - -static PRInt32 PR_CALLBACK pl_DefTransmitfile ( - PRFileDesc *sd, PRFileDesc *fd, const void *headers, PRInt32 hlen, - PRTransmitFileFlags flags, PRIntervalTime t) -{ - PR_ASSERT(sd != NULL); - PR_ASSERT(sd->lower != NULL); - - return sd->lower->methods->transmitfile( - sd->lower, fd, headers, hlen, flags, t); -} - -static PRStatus PR_CALLBACK pl_DefGetsockname (PRFileDesc *fd, PRNetAddr *addr) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->getsockname)(fd->lower, addr); -} - -static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->getpeername)(fd->lower, addr); -} - -static PRStatus PR_CALLBACK pl_DefGetsocketoption ( - PRFileDesc *fd, PRSocketOptionData *data) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->getsocketoption)(fd->lower, data); -} - -static PRStatus PR_CALLBACK pl_DefSetsocketoption ( - PRFileDesc *fd, const PRSocketOptionData *data) -{ - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - return (fd->lower->methods->setsocketoption)(fd->lower, data); -} - -static PRInt32 PR_CALLBACK pl_DefSendfile ( - PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - PR_ASSERT(sd != NULL); - PR_ASSERT(sd->lower != NULL); - - return sd->lower->methods->sendfile( - sd->lower, sfd, flags, timeout); -} - -/* Methods for the top of the stack. Just call down to the next fd. */ -static PRIOMethods pl_methods = { - PR_DESC_LAYERED, - pl_TopClose, - pl_DefRead, - pl_DefWrite, - pl_DefAvailable, - pl_DefAvailable64, - pl_DefFsync, - pl_DefSeek, - pl_DefSeek64, - pl_DefFileInfo, - pl_DefFileInfo64, - pl_DefWritev, - pl_DefConnect, - pl_TopAccept, - pl_DefBind, - pl_DefListen, - pl_DefShutdown, - pl_DefRecv, - pl_DefSend, - pl_DefRecvfrom, - pl_DefSendto, - pl_DefPoll, - pl_DefAcceptread, - pl_DefTransmitfile, - pl_DefGetsockname, - pl_DefGetpeername, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - pl_DefGetsocketoption, - pl_DefSetsocketoption, - pl_DefSendfile, - pl_DefConnectcontinue, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods(void) -{ - return &pl_methods; -} /* PR_GetDefaultIOMethods */ - -PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub( - PRDescIdentity ident, const PRIOMethods *methods) -{ - PRFileDesc *fd = NULL; - PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident)); - if ((PR_NSPR_IO_LAYER == ident) || (PR_TOP_IO_LAYER == ident)) - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - else - { - fd = PR_NEWZAP(PRFileDesc); - if (NULL == fd) - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - else - { - fd->methods = methods; - fd->dtor = pl_FDDestructor; - fd->identity = ident; - } - } - return fd; -} /* PR_CreateIOLayerStub */ - -/* - * PR_CreateIOLayer - * Create a new style stack, where the stack top is a dummy header. - * Unlike the old style stacks, the contents of the stack head - * are not modified when a layer is pushed onto or popped from a new - * style stack. - */ - -PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayer(PRFileDesc *top) -{ - PRFileDesc *fd = NULL; - - fd = PR_NEWZAP(PRFileDesc); - if (NULL == fd) - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - else - { - fd->methods = &pl_methods; - fd->dtor = pl_FDDestructor; - fd->identity = PR_IO_LAYER_HEAD; - fd->higher = NULL; - fd->lower = top; - top->higher = fd; - top->lower = NULL; - } - return fd; -} /* PR_CreateIOLayer */ - -/* - * _PR_DestroyIOLayer - * Delete the stack head of a new style stack. - */ - -static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack) -{ - if (NULL == stack) - return PR_FAILURE; - else { - PR_DELETE(stack); - return PR_SUCCESS; - } -} /* _PR_DestroyIOLayer */ - -PR_IMPLEMENT(PRStatus) PR_PushIOLayer( - PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd) -{ - PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id); - - PR_ASSERT(fd != NULL); - PR_ASSERT(stack != NULL); - PR_ASSERT(insert != NULL); - PR_ASSERT(PR_IO_LAYER_HEAD != id); - if ((NULL == stack) || (NULL == fd) || (NULL == insert)) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - - if (stack == insert) - { - /* going on top of the stack */ - /* old-style stack */ - PRFileDesc copy = *stack; - *stack = *fd; - *fd = copy; - fd->higher = stack; - if (fd->lower) - { - PR_ASSERT(fd->lower->higher == stack); - fd->lower->higher = fd; - } - stack->lower = fd; - stack->higher = NULL; - } else { - /* - * going somewhere in the middle of the stack for both old and new - * style stacks, or going on top of stack for new style stack - */ - fd->lower = insert; - fd->higher = insert->higher; - - insert->higher->lower = fd; - insert->higher = fd; - } - - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id) -{ - PRFileDesc *extract = PR_GetIdentitiesLayer(stack, id); - - PR_ASSERT(0 != id); - PR_ASSERT(NULL != stack); - PR_ASSERT(NULL != extract); - if ((NULL == stack) || (0 == id) || (NULL == extract)) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } - - if (extract == stack) { - /* popping top layer of the stack */ - /* old style stack */ - PRFileDesc copy = *stack; - extract = stack->lower; - *stack = *extract; - *extract = copy; - stack->higher = NULL; - if (stack->lower) { - PR_ASSERT(stack->lower->higher == extract); - stack->lower->higher = stack; - } - } else if ((PR_IO_LAYER_HEAD == stack->identity) && - (extract == stack->lower) && (extract->lower == NULL)) { - /* - * new style stack - * popping the only layer in the stack; delete the stack too - */ - stack->lower = NULL; - _PR_DestroyIOLayer(stack); - } else { - /* for both kinds of stacks */ - extract->lower->higher = extract->higher; - extract->higher->lower = extract->lower; - } - extract->higher = extract->lower = NULL; - return extract; -} /* PR_PopIOLayer */ - -#define ID_CACHE_INCREMENT 16 -typedef struct _PRIdentity_cache -{ - PRLock *ml; - char **name; - PRIntn length; - PRDescIdentity ident; -} _PRIdentity_cache; - -static _PRIdentity_cache identity_cache; - -PR_IMPLEMENT(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name) -{ - PRDescIdentity identity, length; - char **names = NULL, *name = NULL, **old = NULL; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - PR_ASSERT((PRDescIdentity)0x7fff > identity_cache.ident); - - if (NULL != layer_name) - { - name = (char*)PR_Malloc(strlen(layer_name) + 1); - if (NULL == name) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return PR_INVALID_IO_LAYER; - } - strcpy(name, layer_name); - } - - /* this initial code runs unsafe */ -retry: - PR_ASSERT(NULL == names); - /* - * In the initial round, both identity_cache.ident and - * identity_cache.length are 0, so (identity_cache.ident + 1) is greater - * than length. In later rounds, identity_cache.ident is always less - * than length, so (identity_cache.ident + 1) can be equal to but cannot - * be greater than length. - */ - length = identity_cache.length; - if ((identity_cache.ident + 1) >= length) - { - length += ID_CACHE_INCREMENT; - names = (char**)PR_CALLOC(length * sizeof(char*)); - if (NULL == names) - { - if (NULL != name) PR_DELETE(name); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return PR_INVALID_IO_LAYER; - } - } - - /* now we get serious about thread safety */ - PR_Lock(identity_cache.ml); - PR_ASSERT(identity_cache.length == 0 || - identity_cache.ident < identity_cache.length); - identity = identity_cache.ident + 1; - if (identity >= identity_cache.length) /* there's no room */ - { - /* we have to do something - hopefully it's already done */ - if ((NULL != names) && (identity < length)) - { - /* what we did is still okay */ - memcpy( - names, identity_cache.name, - identity_cache.length * sizeof(char*)); - old = identity_cache.name; - identity_cache.name = names; - identity_cache.length = length; - names = NULL; - } - else - { - PR_Unlock(identity_cache.ml); - if (NULL != names) PR_DELETE(names); - goto retry; - } - } - if (NULL != name) /* there's a name to be stored */ - { - identity_cache.name[identity] = name; - } - identity_cache.ident = identity; - PR_ASSERT(identity_cache.ident < identity_cache.length); - PR_Unlock(identity_cache.ml); - - if (NULL != old) PR_DELETE(old); - if (NULL != names) PR_DELETE(names); - - return identity; -} /* PR_GetUniqueIdentity */ - -PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (PR_TOP_IO_LAYER == ident) return NULL; - - PR_ASSERT(ident <= identity_cache.ident); - return (ident > identity_cache.ident) ? NULL : identity_cache.name[ident]; -} /* PR_GetNameForIdentity */ - -PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd) -{ - PR_ASSERT(NULL != fd); - if (PR_IO_LAYER_HEAD == fd->identity) { - PR_ASSERT(NULL != fd->lower); - return fd->lower->identity; - } else - return fd->identity; -} /* PR_GetLayersIdentity */ - -PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id) -{ - PRFileDesc *layer = fd; - - if (PR_TOP_IO_LAYER == id) { - if (PR_IO_LAYER_HEAD == fd->identity) - return fd->lower; - else - return fd; - } - - for (layer = fd; layer != NULL; layer = layer->lower) - { - if (id == layer->identity) return layer; - } - for (layer = fd; layer != NULL; layer = layer->higher) - { - if (id == layer->identity) return layer; - } - return NULL; -} /* PR_GetIdentitiesLayer */ - -void _PR_InitLayerCache(void) -{ - memset(&identity_cache, 0, sizeof(identity_cache)); - identity_cache.ml = PR_NewLock(); - PR_ASSERT(NULL != identity_cache.ml); -} /* _PR_InitLayerCache */ - -void _PR_CleanupLayerCache(void) -{ - if (identity_cache.ml) - { - PR_DestroyLock(identity_cache.ml); - identity_cache.ml = NULL; - } - - if (identity_cache.name) - { - PRDescIdentity ident; - - for (ident = 0; ident <= identity_cache.ident; ident++) - PR_DELETE(identity_cache.name[ident]); - - PR_DELETE(identity_cache.name); - } -} /* _PR_CleanupLayerCache */ - -/* prlayer.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prlog.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prlog.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prlog.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prlog.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,555 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include "prenv.h" -#include "prprf.h" -#include -#ifdef ANDROID -#include -#endif - -/* - * Lock used to lock the log. - * - * We can't define _PR_LOCK_LOG simply as PR_Lock because PR_Lock may - * contain assertions. We have to avoid assertions in _PR_LOCK_LOG - * because PR_ASSERT calls PR_LogPrint, which in turn calls _PR_LOCK_LOG. - * This can lead to infinite recursion. - */ -static PRLock *_pr_logLock; -#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) -#define _PR_LOCK_LOG() PR_Lock(_pr_logLock); -#define _PR_UNLOCK_LOG() PR_Unlock(_pr_logLock); -#elif defined(_PR_GLOBAL_THREADS_ONLY) -#define _PR_LOCK_LOG() { _PR_LOCK_LOCK(_pr_logLock) -#define _PR_UNLOCK_LOG() _PR_LOCK_UNLOCK(_pr_logLock); } -#else - -#define _PR_LOCK_LOG() \ -{ \ - PRIntn _is; \ - PRThread *_me = _PR_MD_CURRENT_THREAD(); \ - if (!_PR_IS_NATIVE_THREAD(_me)) \ - _PR_INTSOFF(_is); \ - _PR_LOCK_LOCK(_pr_logLock) - -#define _PR_UNLOCK_LOG() \ - _PR_LOCK_UNLOCK(_pr_logLock); \ - PR_ASSERT(_me == _PR_MD_CURRENT_THREAD()); \ - if (!_PR_IS_NATIVE_THREAD(_me)) \ - _PR_INTSON(_is); \ -} - -#endif - -#if defined(XP_PC) -#define strcasecmp stricmp -#endif - -/* - * On NT, we can't define _PUT_LOG as PR_Write or _PR_MD_WRITE, - * because every asynchronous file io operation leads to a fiber context - * switch. So we define _PUT_LOG as fputs (from stdio.h). A side - * benefit is that fputs handles the LF->CRLF translation. This - * code can also be used on other platforms with file stream io. - */ -#if defined(WIN32) || defined(XP_OS2) -#define _PR_USE_STDIO_FOR_LOGGING -#endif - -/* -** Coerce Win32 log output to use OutputDebugString() when -** NSPR_LOG_FILE is set to "WinDebug". -*/ -#if defined(XP_PC) -#define WIN32_DEBUG_FILE (FILE*)-2 -#endif - -#ifdef WINCE -static void OutputDebugStringA(const char* msg) { - int len = MultiByteToWideChar(CP_ACP, 0, msg, -1, 0, 0); - WCHAR *wMsg = (WCHAR *)PR_Malloc(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, msg, -1, wMsg, len); - OutputDebugStringW(wMsg); - PR_Free(wMsg); -} -#endif - -/* Macros used to reduce #ifdef pollution */ - -#if defined(_PR_USE_STDIO_FOR_LOGGING) && defined(XP_PC) -#define _PUT_LOG(fd, buf, nb) \ - PR_BEGIN_MACRO \ - if (logFile == WIN32_DEBUG_FILE) { \ - char savebyte = buf[nb]; \ - buf[nb] = '\0'; \ - OutputDebugStringA(buf); \ - buf[nb] = savebyte; \ - } else { \ - fwrite(buf, 1, nb, fd); \ - fflush(fd); \ - } \ - PR_END_MACRO -#elif defined(_PR_USE_STDIO_FOR_LOGGING) -#define _PUT_LOG(fd, buf, nb) {fwrite(buf, 1, nb, fd); fflush(fd);} -#elif defined(ANDROID) -#define _PUT_LOG(fd, buf, nb) \ - PR_BEGIN_MACRO \ - if (fd == _pr_stderr) { \ - char savebyte = buf[nb]; \ - buf[nb] = '\0'; \ - __android_log_write(ANDROID_LOG_INFO, "PRLog", buf); \ - buf[nb] = savebyte; \ - } else { \ - PR_Write(fd, buf, nb); \ - } \ - PR_END_MACRO -#elif defined(_PR_PTHREADS) -#define _PUT_LOG(fd, buf, nb) PR_Write(fd, buf, nb) -#else -#define _PUT_LOG(fd, buf, nb) _PR_MD_WRITE(fd, buf, nb) -#endif - -/************************************************************************/ - -static PRLogModuleInfo *logModules; - -static char *logBuf = NULL; -static char *logp; -static char *logEndp; -#ifdef _PR_USE_STDIO_FOR_LOGGING -static FILE *logFile = NULL; -#else -static PRFileDesc *logFile = 0; -#endif -static PRBool outputTimeStamp = PR_FALSE; -static PRBool appendToLog = PR_FALSE; - -#define LINE_BUF_SIZE 512 -#define DEFAULT_BUF_SIZE 16384 - -#ifdef _PR_NEED_STRCASECMP - -/* - * strcasecmp is defined in /usr/ucblib/libucb.a on some platforms - * such as NCR and Unixware. Linking with both libc and libucb - * may cause some problem, so I just provide our own implementation - * of strcasecmp here. - */ - -static const unsigned char uc[] = -{ - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - ' ', '!', '"', '#', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', - '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '{', '|', '}', '~', '\177' -}; - -PRIntn strcasecmp(const char *a, const char *b) -{ - const unsigned char *ua = (const unsigned char *)a; - const unsigned char *ub = (const unsigned char *)b; - - if( ((const char *)0 == a) || (const char *)0 == b ) - return (PRIntn)(a-b); - - while( (uc[*ua] == uc[*ub]) && ('\0' != *a) ) - { - a++; - ua++; - ub++; - } - - return (PRIntn)(uc[*ua] - uc[*ub]); -} - -#endif /* _PR_NEED_STRCASECMP */ - -void _PR_InitLog(void) -{ - char *ev; - - _pr_logLock = PR_NewLock(); - - ev = PR_GetEnv("NSPR_LOG_MODULES"); - if (ev && ev[0]) { - char module[64]; /* Security-Critical: If you change this - * size, you must also change the sscanf - * format string to be size-1. - */ - PRBool isSync = PR_FALSE; - PRIntn evlen = strlen(ev), pos = 0; - PRInt32 bufSize = DEFAULT_BUF_SIZE; - while (pos < evlen) { - PRIntn level = 1, count = 0, delta = 0; - count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n", - module, &delta, &level, &delta); - pos += delta; - if (count == 0) break; - - /* - ** If count == 2, then we got module and level. If count - ** == 1, then level defaults to 1 (module enabled). - */ - if (strcasecmp(module, "sync") == 0) { - isSync = PR_TRUE; - } else if (strcasecmp(module, "bufsize") == 0) { - if (level >= LINE_BUF_SIZE) { - bufSize = level; - } - } else if (strcasecmp(module, "timestamp") == 0) { - outputTimeStamp = PR_TRUE; - } else if (strcasecmp(module, "append") == 0) { - appendToLog = PR_TRUE; - } else { - PRLogModuleInfo *lm = logModules; - PRBool skip_modcheck = - (0 == strcasecmp (module, "all")) ? PR_TRUE : PR_FALSE; - - while (lm != NULL) { - if (skip_modcheck) lm -> level = (PRLogModuleLevel)level; - else if (strcasecmp(module, lm->name) == 0) { - lm->level = (PRLogModuleLevel)level; - break; - } - lm = lm->next; - } - } - /*found:*/ - count = sscanf(&ev[pos], " , %n", &delta); - pos += delta; - if (count == EOF) break; - } - PR_SetLogBuffering(isSync ? 0 : bufSize); - -#ifdef XP_UNIX - if ((getuid() != geteuid()) || (getgid() != getegid())) { - return; - } -#endif /* XP_UNIX */ - - ev = PR_GetEnv("NSPR_LOG_FILE"); - if (ev && ev[0]) { - if (!PR_SetLogFile(ev)) { -#ifdef XP_PC - char* str = PR_smprintf("Unable to create nspr log file '%s'\n", ev); - if (str) { - OutputDebugStringA(str); - PR_smprintf_free(str); - } -#else - fprintf(stderr, "Unable to create nspr log file '%s'\n", ev); -#endif - } - } else { -#ifdef _PR_USE_STDIO_FOR_LOGGING - logFile = stderr; -#else - logFile = _pr_stderr; -#endif - } - } -} - -void _PR_LogCleanup(void) -{ - PRLogModuleInfo *lm = logModules; - - PR_LogFlush(); - -#ifdef _PR_USE_STDIO_FOR_LOGGING - if (logFile - && logFile != stdout - && logFile != stderr -#ifdef XP_PC - && logFile != WIN32_DEBUG_FILE -#endif - ) { - fclose(logFile); - } -#else - if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) { - PR_Close(logFile); - } -#endif - logFile = NULL; - - if (logBuf) - PR_DELETE(logBuf); - - while (lm != NULL) { - PRLogModuleInfo *next = lm->next; - free((/*const*/ char *)lm->name); - PR_Free(lm); - lm = next; - } - logModules = NULL; - - if (_pr_logLock) { - PR_DestroyLock(_pr_logLock); - _pr_logLock = NULL; - } -} - -static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm ) -{ - char *ev; - - ev = PR_GetEnv("NSPR_LOG_MODULES"); - if (ev && ev[0]) { - char module[64]; /* Security-Critical: If you change this - * size, you must also change the sscanf - * format string to be size-1. - */ - PRIntn evlen = strlen(ev), pos = 0; - while (pos < evlen) { - PRIntn level = 1, count = 0, delta = 0; - - count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n", - module, &delta, &level, &delta); - pos += delta; - if (count == 0) break; - - /* - ** If count == 2, then we got module and level. If count - ** == 1, then level defaults to 1 (module enabled). - */ - if (lm != NULL) - { - if ((strcasecmp(module, "all") == 0) - || (strcasecmp(module, lm->name) == 0)) - { - lm->level = (PRLogModuleLevel)level; - } - } - count = sscanf(&ev[pos], " , %n", &delta); - pos += delta; - if (count == EOF) break; - } - } -} /* end _PR_SetLogModuleLevel() */ - -PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name) -{ - PRLogModuleInfo *lm; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - lm = PR_NEWZAP(PRLogModuleInfo); - if (lm) { - lm->name = strdup(name); - lm->level = PR_LOG_NONE; - lm->next = logModules; - logModules = lm; - _PR_SetLogModuleLevel(lm); - } - return lm; -} - -PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file) -{ -#ifdef _PR_USE_STDIO_FOR_LOGGING - FILE *newLogFile; - -#ifdef XP_PC - if ( strcmp( file, "WinDebug") == 0) - { - newLogFile = WIN32_DEBUG_FILE; - } - else -#endif - { - const char *mode = appendToLog ? "a" : "w"; - newLogFile = fopen(file, mode); - if (!newLogFile) - return PR_FALSE; - -#ifndef WINCE /* _IONBF does not exist in the Windows Mobile 6 SDK. */ - /* We do buffering ourselves. */ - setvbuf(newLogFile, NULL, _IONBF, 0); -#endif - } - if (logFile - && logFile != stdout - && logFile != stderr -#ifdef XP_PC - && logFile != WIN32_DEBUG_FILE -#endif - ) { - fclose(logFile); - } - logFile = newLogFile; - return PR_TRUE; -#else - PRFileDesc *newLogFile; - PRIntn flags = PR_WRONLY|PR_CREATE_FILE; - if (appendToLog) { - flags |= PR_APPEND; - } else { - flags |= PR_TRUNCATE; - } - - newLogFile = PR_Open(file, flags, 0666); - if (newLogFile) { - if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) { - PR_Close(logFile); - } - logFile = newLogFile; - } - return (PRBool) (newLogFile != 0); -#endif /* _PR_USE_STDIO_FOR_LOGGING */ -} - -PR_IMPLEMENT(void) PR_SetLogBuffering(PRIntn buffer_size) -{ - PR_LogFlush(); - - if (logBuf) - PR_DELETE(logBuf); - - if (buffer_size >= LINE_BUF_SIZE) { - logp = logBuf = (char*) PR_MALLOC(buffer_size); - logEndp = logp + buffer_size; - } -} - -PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...) -{ - va_list ap; - char line[LINE_BUF_SIZE]; - char *line_long = NULL; - PRUint32 nb_tid = 0, nb; - PRThread *me; - PRExplodedTime now; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (!logFile) { - return; - } - - if (outputTimeStamp) { - PR_ExplodeTime(PR_Now(), PR_GMTParameters, &now); - nb_tid = PR_snprintf(line, sizeof(line)-1, - "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC - ", - now.tm_year, now.tm_month + 1, now.tm_mday, - now.tm_hour, now.tm_min, now.tm_sec, - now.tm_usec); - } - - me = PR_GetCurrentThread(); - nb_tid += PR_snprintf(line+nb_tid, sizeof(line)-nb_tid-1, "%ld[%p]: ", -#if defined(_PR_BTHREADS) - me, me); -#else - me ? me->id : 0L, me); -#endif - - va_start(ap, fmt); - nb = nb_tid + PR_vsnprintf(line+nb_tid, sizeof(line)-nb_tid-1, fmt, ap); - va_end(ap); - - /* - * Check if we might have run out of buffer space (in case we have a - * long line), and malloc a buffer just this once. - */ - if (nb == sizeof(line)-2) { - va_start(ap, fmt); - line_long = PR_vsmprintf(fmt, ap); - va_end(ap); - /* If this failed, we'll fall back to writing the truncated line. */ - } - - if (line_long) { - nb = strlen(line_long); - _PR_LOCK_LOG(); - if (logBuf != 0) { - _PUT_LOG(logFile, logBuf, logp - logBuf); - logp = logBuf; - } - /* - * Write out the thread id (with an optional timestamp) and the - * malloc'ed buffer. - */ - _PUT_LOG(logFile, line, nb_tid); - _PUT_LOG(logFile, line_long, nb); - /* Ensure there is a trailing newline. */ - if (!nb || (line_long[nb-1] != '\n')) { - char eol[2]; - eol[0] = '\n'; - eol[1] = '\0'; - _PUT_LOG(logFile, eol, 1); - } - _PR_UNLOCK_LOG(); - PR_smprintf_free(line_long); - } else { - /* Ensure there is a trailing newline. */ - if (nb && (line[nb-1] != '\n')) { - line[nb++] = '\n'; - line[nb] = '\0'; - } - _PR_LOCK_LOG(); - if (logBuf == 0) { - _PUT_LOG(logFile, line, nb); - } else { - /* If nb can't fit into logBuf, write out logBuf first. */ - if (logp + nb > logEndp) { - _PUT_LOG(logFile, logBuf, logp - logBuf); - logp = logBuf; - } - /* nb is guaranteed to fit into logBuf. */ - memcpy(logp, line, nb); - logp += nb; - } - _PR_UNLOCK_LOG(); - } - PR_LogFlush(); -} - -PR_IMPLEMENT(void) PR_LogFlush(void) -{ - if (logBuf && logFile) { - _PR_LOCK_LOG(); - if (logp > logBuf) { - _PUT_LOG(logFile, logBuf, logp - logBuf); - logp = logBuf; - } - _PR_UNLOCK_LOG(); - } -} - -PR_IMPLEMENT(void) PR_Abort(void) -{ - PR_LogPrint("Aborting"); - abort(); -} - -PR_IMPLEMENT(void) PR_Assert(const char *s, const char *file, PRIntn ln) -{ - PR_LogPrint("Assertion failure: %s, at %s:%d\n", s, file, ln); - fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); - fflush(stderr); -#ifdef WIN32 - DebugBreak(); -#endif -#ifdef XP_OS2 - asm("int $3"); -#endif - abort(); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prmapopt.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prmapopt.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prmapopt.c 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prmapopt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,452 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This file defines _PR_MapOptionName(). The purpose of putting - * _PR_MapOptionName() in a separate file is to work around a Winsock - * header file problem on Windows NT. - * - * On Windows NT, if we define _WIN32_WINNT to be 0x0400 (in order - * to use Service Pack 3 extensions), windows.h includes winsock2.h - * (instead of winsock.h), which doesn't define many socket options - * defined in winsock.h. - * - * We need the socket options defined in winsock.h. So this file - * includes winsock.h, with _WIN32_WINNT undefined. - */ - -#if defined(WINNT) || defined(__MINGW32__) -#include -#endif - -/* MinGW doesn't define these in its winsock.h. */ -#ifdef __MINGW32__ -#ifndef IP_TTL -#define IP_TTL 7 -#endif -#ifndef IP_TOS -#define IP_TOS 8 -#endif -#endif - -#include "primpl.h" - -#ifdef HAVE_NETINET_TCP_H -#include /* TCP_NODELAY, TCP_MAXSEG */ -#endif - -#ifndef _PR_PTHREADS - -PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data) -{ - PRStatus rv; - PRInt32 length; - PRInt32 level, name; - - /* - * PR_SockOpt_Nonblocking is a special case that does not - * translate to a getsockopt() call - */ - if (PR_SockOpt_Nonblocking == data->option) - { - data->value.non_blocking = fd->secret->nonblocking; - return PR_SUCCESS; - } - - rv = _PR_MapOptionName(data->option, &level, &name); - if (PR_SUCCESS == rv) - { - switch (data->option) - { - case PR_SockOpt_Linger: - { -#if !defined(XP_BEOS) || defined(BONE_VERSION) - struct linger linger; - length = sizeof(linger); - rv = _PR_MD_GETSOCKOPT( - fd, level, name, (char *) &linger, &length); - if (PR_SUCCESS == rv) - { - PR_ASSERT(sizeof(linger) == length); - data->value.linger.polarity = - (linger.l_onoff) ? PR_TRUE : PR_FALSE; - data->value.linger.linger = - PR_SecondsToInterval(linger.l_linger); - } - break; -#else - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return PR_FAILURE; -#endif - } - case PR_SockOpt_Reuseaddr: - case PR_SockOpt_Keepalive: - case PR_SockOpt_NoDelay: - case PR_SockOpt_Broadcast: - { -#ifdef WIN32 /* Winsock */ - BOOL value; -#else - PRIntn value; -#endif - length = sizeof(value); - rv = _PR_MD_GETSOCKOPT( - fd, level, name, (char*)&value, &length); - if (PR_SUCCESS == rv) - data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE; - break; - } - case PR_SockOpt_McastLoopback: - { -#ifdef WIN32 /* Winsock */ - BOOL bool; -#else - PRUint8 bool; -#endif - length = sizeof(bool); - rv = _PR_MD_GETSOCKOPT( - fd, level, name, (char*)&bool, &length); - if (PR_SUCCESS == rv) - data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE; - break; - } - case PR_SockOpt_RecvBufferSize: - case PR_SockOpt_SendBufferSize: - case PR_SockOpt_MaxSegment: - { - PRIntn value; - length = sizeof(value); - rv = _PR_MD_GETSOCKOPT( - fd, level, name, (char*)&value, &length); - if (PR_SUCCESS == rv) - data->value.recv_buffer_size = value; - break; - } - case PR_SockOpt_IpTimeToLive: - case PR_SockOpt_IpTypeOfService: - { - /* These options should really be an int (or PRIntn). */ - length = sizeof(PRUintn); - rv = _PR_MD_GETSOCKOPT( - fd, level, name, (char*)&data->value.ip_ttl, &length); - break; - } - case PR_SockOpt_McastTimeToLive: - { -#ifdef WIN32 /* Winsock */ - int ttl; -#else - PRUint8 ttl; -#endif - length = sizeof(ttl); - rv = _PR_MD_GETSOCKOPT( - fd, level, name, (char*)&ttl, &length); - if (PR_SUCCESS == rv) - data->value.mcast_ttl = ttl; - break; - } -#ifdef IP_ADD_MEMBERSHIP - case PR_SockOpt_AddMember: - case PR_SockOpt_DropMember: - { - struct ip_mreq mreq; - length = sizeof(mreq); - rv = _PR_MD_GETSOCKOPT( - fd, level, name, (char*)&mreq, &length); - if (PR_SUCCESS == rv) - { - data->value.add_member.mcaddr.inet.ip = - mreq.imr_multiaddr.s_addr; - data->value.add_member.ifaddr.inet.ip = - mreq.imr_interface.s_addr; - } - break; - } -#endif /* IP_ADD_MEMBERSHIP */ - case PR_SockOpt_McastInterface: - { - /* This option is a struct in_addr. */ - length = sizeof(data->value.mcast_if.inet.ip); - rv = _PR_MD_GETSOCKOPT( - fd, level, name, - (char*)&data->value.mcast_if.inet.ip, &length); - break; - } - default: - PR_NOT_REACHED("Unknown socket option"); - break; - } - } - return rv; -} /* _PR_SocketGetSocketOption */ - -PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data) -{ - PRStatus rv; - PRInt32 level, name; - - /* - * PR_SockOpt_Nonblocking is a special case that does not - * translate to a setsockopt call. - */ - if (PR_SockOpt_Nonblocking == data->option) - { -#ifdef WINNT - PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE) - || (fd->secret->nonblocking == data->value.non_blocking)); - if (fd->secret->md.io_model_committed - && (fd->secret->nonblocking != data->value.non_blocking)) - { - /* - * On NT, once we have associated a socket with the io - * completion port, we can't disassociate it. So we - * can't change the nonblocking option of the socket - * afterwards. - */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } -#endif - fd->secret->nonblocking = data->value.non_blocking; - return PR_SUCCESS; - } - - rv = _PR_MapOptionName(data->option, &level, &name); - if (PR_SUCCESS == rv) - { - switch (data->option) - { - case PR_SockOpt_Linger: - { -#if !defined(XP_BEOS) || defined(BONE_VERSION) - struct linger linger; - linger.l_onoff = data->value.linger.polarity; - linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger); - rv = _PR_MD_SETSOCKOPT( - fd, level, name, (char*)&linger, sizeof(linger)); - break; -#else - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return PR_FAILURE; -#endif - } - case PR_SockOpt_Reuseaddr: - case PR_SockOpt_Keepalive: - case PR_SockOpt_NoDelay: - case PR_SockOpt_Broadcast: - { -#ifdef WIN32 /* Winsock */ - BOOL value; -#else - PRIntn value; -#endif - value = (data->value.reuse_addr) ? 1 : 0; - rv = _PR_MD_SETSOCKOPT( - fd, level, name, (char*)&value, sizeof(value)); - break; - } - case PR_SockOpt_McastLoopback: - { -#ifdef WIN32 /* Winsock */ - BOOL bool; -#else - PRUint8 bool; -#endif - bool = data->value.mcast_loopback ? 1 : 0; - rv = _PR_MD_SETSOCKOPT( - fd, level, name, (char*)&bool, sizeof(bool)); - break; - } - case PR_SockOpt_RecvBufferSize: - case PR_SockOpt_SendBufferSize: - case PR_SockOpt_MaxSegment: - { - PRIntn value = data->value.recv_buffer_size; - rv = _PR_MD_SETSOCKOPT( - fd, level, name, (char*)&value, sizeof(value)); - break; - } - case PR_SockOpt_IpTimeToLive: - case PR_SockOpt_IpTypeOfService: - { - /* These options should really be an int (or PRIntn). */ - rv = _PR_MD_SETSOCKOPT( - fd, level, name, (char*)&data->value.ip_ttl, sizeof(PRUintn)); - break; - } - case PR_SockOpt_McastTimeToLive: - { -#ifdef WIN32 /* Winsock */ - int ttl; -#else - PRUint8 ttl; -#endif - ttl = data->value.mcast_ttl; - rv = _PR_MD_SETSOCKOPT( - fd, level, name, (char*)&ttl, sizeof(ttl)); - break; - } -#ifdef IP_ADD_MEMBERSHIP - case PR_SockOpt_AddMember: - case PR_SockOpt_DropMember: - { - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = - data->value.add_member.mcaddr.inet.ip; - mreq.imr_interface.s_addr = - data->value.add_member.ifaddr.inet.ip; - rv = _PR_MD_SETSOCKOPT( - fd, level, name, (char*)&mreq, sizeof(mreq)); - break; - } -#endif /* IP_ADD_MEMBERSHIP */ - case PR_SockOpt_McastInterface: - { - /* This option is a struct in_addr. */ - rv = _PR_MD_SETSOCKOPT( - fd, level, name, (char*)&data->value.mcast_if.inet.ip, - sizeof(data->value.mcast_if.inet.ip)); - break; - } - default: - PR_NOT_REACHED("Unknown socket option"); - break; - } - } - return rv; -} /* _PR_SocketSetSocketOption */ - -#endif /* ! _PR_PTHREADS */ - -/* - ********************************************************************* - ********************************************************************* - ** - ** Make sure that the following is at the end of this file, - ** because we will be playing with macro redefines. - ** - ********************************************************************* - ********************************************************************* - */ - -/* - * Not every platform has all the socket options we want to - * support. Some older operating systems such as SunOS 4.1.3 - * don't have the IP multicast socket options. Win32 doesn't - * have TCP_MAXSEG. - * - * To deal with this problem, we define the missing socket - * options as _PR_NO_SUCH_SOCKOPT. _PR_MapOptionName() fails with - * PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not - * available on the platform is requested. - */ - -/* - * Sanity check. SO_LINGER and TCP_NODELAY should be available - * on all platforms. Just to make sure we have included the - * appropriate header files. Then any undefined socket options - * are really missing. - */ - -#if !defined(SO_LINGER) -#error "SO_LINGER is not defined" -#endif - -#if !defined(TCP_NODELAY) -#error "TCP_NODELAY is not defined" -#endif - -/* - * Make sure the value of _PR_NO_SUCH_SOCKOPT is not - * a valid socket option. - */ -#define _PR_NO_SUCH_SOCKOPT -1 - -#ifndef SO_KEEPALIVE -#define SO_KEEPALIVE _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef SO_SNDBUF -#define SO_SNDBUF _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef SO_RCVBUF -#define SO_RCVBUF _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef IP_MULTICAST_IF /* set/get IP multicast interface */ -#define IP_MULTICAST_IF _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef IP_MULTICAST_TTL /* set/get IP multicast timetolive */ -#define IP_MULTICAST_TTL _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef IP_MULTICAST_LOOP /* set/get IP multicast loopback */ -#define IP_MULTICAST_LOOP _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef IP_ADD_MEMBERSHIP /* add an IP group membership */ -#define IP_ADD_MEMBERSHIP _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef IP_DROP_MEMBERSHIP /* drop an IP group membership */ -#define IP_DROP_MEMBERSHIP _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef IP_TTL /* set/get IP Time To Live */ -#define IP_TTL _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef IP_TOS /* set/get IP Type Of Service */ -#define IP_TOS _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef TCP_NODELAY /* don't delay to coalesce data */ -#define TCP_NODELAY _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef TCP_MAXSEG /* maxumum segment size for tcp */ -#define TCP_MAXSEG _PR_NO_SUCH_SOCKOPT -#endif - -#ifndef SO_BROADCAST /* enable broadcast on udp sockets */ -#define SO_BROADCAST _PR_NO_SUCH_SOCKOPT -#endif - -PRStatus _PR_MapOptionName( - PRSockOption optname, PRInt32 *level, PRInt32 *name) -{ - static PRInt32 socketOptions[PR_SockOpt_Last] = - { - 0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF, - IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, - IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP, - TCP_NODELAY, TCP_MAXSEG, SO_BROADCAST - }; - static PRInt32 socketLevels[PR_SockOpt_Last] = - { - 0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, - IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, - IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, - IPPROTO_TCP, IPPROTO_TCP, SOL_SOCKET - }; - - if ((optname < PR_SockOpt_Linger) - || (optname >= PR_SockOpt_Last)) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - - if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT) - { - PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0); - return PR_FAILURE; - } - *name = socketOptions[optname]; - *level = socketLevels[optname]; - return PR_SUCCESS; -} /* _PR_MapOptionName */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prmmap.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prmmap.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prmmap.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prmmap.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - ********************************************************************* - * - * Memory-mapped files - * - ********************************************************************* - */ - -#include "primpl.h" - -PR_IMPLEMENT(PRFileMap *) PR_CreateFileMap( - PRFileDesc *fd, - PRInt64 size, - PRFileMapProtect prot) -{ - PRFileMap *fmap; - - PR_ASSERT(prot == PR_PROT_READONLY || prot == PR_PROT_READWRITE - || prot == PR_PROT_WRITECOPY); - fmap = PR_NEWZAP(PRFileMap); - if (NULL == fmap) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - fmap->fd = fd; - fmap->prot = prot; - if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) { - return fmap; - } else { - PR_DELETE(fmap); - return NULL; - } -} - -PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void) -{ - return _PR_MD_GET_MEM_MAP_ALIGNMENT(); -} - -PR_IMPLEMENT(void *) PR_MemMap( - PRFileMap *fmap, - PROffset64 offset, - PRUint32 len) -{ - return _PR_MD_MEM_MAP(fmap, offset, len); -} - -PR_IMPLEMENT(PRStatus) PR_MemUnmap(void *addr, PRUint32 len) -{ - return _PR_MD_MEM_UNMAP(addr, len); -} - -PR_IMPLEMENT(PRStatus) PR_CloseFileMap(PRFileMap *fmap) -{ - return _PR_MD_CLOSE_FILE_MAP(fmap); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prmwait.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prmwait.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prmwait.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prmwait.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1456 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include "pprmwait.h" - -#define _MW_REHASH_MAX 11 - -static PRLock *mw_lock = NULL; -static _PRGlobalState *mw_state = NULL; - -static PRIntervalTime max_polling_interval; - -#ifdef WINNT - -typedef struct TimerEvent { - PRIntervalTime absolute; - void (*func)(void *); - void *arg; - LONG ref_count; - PRCList links; -} TimerEvent; - -#define TIMER_EVENT_PTR(_qp) \ - ((TimerEvent *) ((char *) (_qp) - offsetof(TimerEvent, links))) - -struct { - PRLock *ml; - PRCondVar *new_timer; - PRCondVar *cancel_timer; - PRThread *manager_thread; - PRCList timer_queue; -} tm_vars; - -static PRStatus TimerInit(void); -static void TimerManager(void *arg); -static TimerEvent *CreateTimer(PRIntervalTime timeout, - void (*func)(void *), void *arg); -static PRBool CancelTimer(TimerEvent *timer); - -static void TimerManager(void *arg) -{ - PRIntervalTime now; - PRIntervalTime timeout; - PRCList *head; - TimerEvent *timer; - - PR_Lock(tm_vars.ml); - while (1) - { - if (PR_CLIST_IS_EMPTY(&tm_vars.timer_queue)) - { - PR_WaitCondVar(tm_vars.new_timer, PR_INTERVAL_NO_TIMEOUT); - } - else - { - now = PR_IntervalNow(); - head = PR_LIST_HEAD(&tm_vars.timer_queue); - timer = TIMER_EVENT_PTR(head); - if ((PRInt32) (now - timer->absolute) >= 0) - { - PR_REMOVE_LINK(head); - /* - * make its prev and next point to itself so that - * it's obvious that it's not on the timer_queue. - */ - PR_INIT_CLIST(head); - PR_ASSERT(2 == timer->ref_count); - PR_Unlock(tm_vars.ml); - timer->func(timer->arg); - PR_Lock(tm_vars.ml); - timer->ref_count -= 1; - if (0 == timer->ref_count) - { - PR_NotifyAllCondVar(tm_vars.cancel_timer); - } - } - else - { - timeout = (PRIntervalTime)(timer->absolute - now); - PR_WaitCondVar(tm_vars.new_timer, timeout); - } - } - } - PR_Unlock(tm_vars.ml); -} - -static TimerEvent *CreateTimer( - PRIntervalTime timeout, - void (*func)(void *), - void *arg) -{ - TimerEvent *timer; - PRCList *links, *tail; - TimerEvent *elem; - - timer = PR_NEW(TimerEvent); - if (NULL == timer) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return timer; - } - timer->absolute = PR_IntervalNow() + timeout; - timer->func = func; - timer->arg = arg; - timer->ref_count = 2; - PR_Lock(tm_vars.ml); - tail = links = PR_LIST_TAIL(&tm_vars.timer_queue); - while (links->prev != tail) - { - elem = TIMER_EVENT_PTR(links); - if ((PRInt32)(timer->absolute - elem->absolute) >= 0) - { - break; - } - links = links->prev; - } - PR_INSERT_AFTER(&timer->links, links); - PR_NotifyCondVar(tm_vars.new_timer); - PR_Unlock(tm_vars.ml); - return timer; -} - -static PRBool CancelTimer(TimerEvent *timer) -{ - PRBool canceled = PR_FALSE; - - PR_Lock(tm_vars.ml); - timer->ref_count -= 1; - if (timer->links.prev == &timer->links) - { - while (timer->ref_count == 1) - { - PR_WaitCondVar(tm_vars.cancel_timer, PR_INTERVAL_NO_TIMEOUT); - } - } - else - { - PR_REMOVE_LINK(&timer->links); - canceled = PR_TRUE; - } - PR_Unlock(tm_vars.ml); - PR_DELETE(timer); - return canceled; -} - -static PRStatus TimerInit(void) -{ - tm_vars.ml = PR_NewLock(); - if (NULL == tm_vars.ml) - { - goto failed; - } - tm_vars.new_timer = PR_NewCondVar(tm_vars.ml); - if (NULL == tm_vars.new_timer) - { - goto failed; - } - tm_vars.cancel_timer = PR_NewCondVar(tm_vars.ml); - if (NULL == tm_vars.cancel_timer) - { - goto failed; - } - PR_INIT_CLIST(&tm_vars.timer_queue); - tm_vars.manager_thread = PR_CreateThread( - PR_SYSTEM_THREAD, TimerManager, NULL, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); - if (NULL == tm_vars.manager_thread) - { - goto failed; - } - return PR_SUCCESS; - -failed: - if (NULL != tm_vars.cancel_timer) - { - PR_DestroyCondVar(tm_vars.cancel_timer); - } - if (NULL != tm_vars.new_timer) - { - PR_DestroyCondVar(tm_vars.new_timer); - } - if (NULL != tm_vars.ml) - { - PR_DestroyLock(tm_vars.ml); - } - return PR_FAILURE; -} - -#endif /* WINNT */ - -/******************************************************************/ -/******************************************************************/ -/************************ The private portion *********************/ -/******************************************************************/ -/******************************************************************/ -void _PR_InitMW(void) -{ -#ifdef WINNT - /* - * We use NT 4's InterlockedCompareExchange() to operate - * on PRMWStatus variables. - */ - PR_ASSERT(sizeof(LONG) == sizeof(PRMWStatus)); - TimerInit(); -#endif - mw_lock = PR_NewLock(); - PR_ASSERT(NULL != mw_lock); - mw_state = PR_NEWZAP(_PRGlobalState); - PR_ASSERT(NULL != mw_state); - PR_INIT_CLIST(&mw_state->group_list); - max_polling_interval = PR_MillisecondsToInterval(MAX_POLLING_INTERVAL); -} /* _PR_InitMW */ - -void _PR_CleanupMW(void) -{ - PR_DestroyLock(mw_lock); - mw_lock = NULL; - if (mw_state->group) { - PR_DestroyWaitGroup(mw_state->group); - /* mw_state->group is set to NULL as a side effect. */ - } - PR_DELETE(mw_state); -} /* _PR_CleanupMW */ - -static PRWaitGroup *MW_Init2(void) -{ - PRWaitGroup *group = mw_state->group; /* it's the null group */ - if (NULL == group) /* there is this special case */ - { - group = PR_CreateWaitGroup(_PR_DEFAULT_HASH_LENGTH); - if (NULL == group) goto failed_alloc; - PR_Lock(mw_lock); - if (NULL == mw_state->group) - { - mw_state->group = group; - group = NULL; - } - PR_Unlock(mw_lock); - if (group != NULL) (void)PR_DestroyWaitGroup(group); - group = mw_state->group; /* somebody beat us to it */ - } -failed_alloc: - return group; /* whatever */ -} /* MW_Init2 */ - -static _PR_HashStory MW_AddHashInternal(PRRecvWait *desc, _PRWaiterHash *hash) -{ - /* - ** The entries are put in the table using the fd (PRFileDesc*) of - ** the receive descriptor as the key. This allows us to locate - ** the appropriate entry aqain when the poll operation finishes. - ** - ** The pointer to the file descriptor object is first divided by - ** the natural alignment of a pointer in the belief that object - ** will have at least that many zeros in the low order bits. - ** This may not be a good assuption. - ** - ** We try to put the entry in by rehashing _MW_REHASH_MAX times. After - ** that we declare defeat and force the table to be reconstructed. - ** Since some fds might be added more than once, won't that cause - ** collisions even in an empty table? - */ - PRIntn rehash = _MW_REHASH_MAX; - PRRecvWait **waiter; - PRUintn hidx = _MW_HASH(desc->fd, hash->length); - PRUintn hoffset = 0; - - while (rehash-- > 0) - { - waiter = &hash->recv_wait; - if (NULL == waiter[hidx]) - { - waiter[hidx] = desc; - hash->count += 1; -#if 0 - printf("Adding 0x%x->0x%x ", desc, desc->fd); - printf( - "table[%u:%u:*%u]: 0x%x->0x%x\n", - hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd); -#endif - return _prmw_success; - } - if (desc == waiter[hidx]) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); /* desc already in table */ - return _prmw_error; - } -#if 0 - printf("Failing 0x%x->0x%x ", desc, desc->fd); - printf( - "table[*%u:%u:%u]: 0x%x->0x%x\n", - hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd); -#endif - if (0 == hoffset) - { - hoffset = _MW_HASH2(desc->fd, hash->length); - PR_ASSERT(0 != hoffset); - } - hidx = (hidx + hoffset) % (hash->length); - } - return _prmw_rehash; -} /* MW_AddHashInternal */ - -static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group) -{ - PRRecvWait **desc; - PRUint32 pidx, length; - _PRWaiterHash *newHash, *oldHash = group->waiter; - PRBool retry; - _PR_HashStory hrv; - - static const PRInt32 prime_number[] = { - _PR_DEFAULT_HASH_LENGTH, 179, 521, 907, 1427, - 2711, 3917, 5021, 8219, 11549, 18911, 26711, 33749, 44771}; - PRUintn primes = (sizeof(prime_number) / sizeof(PRInt32)); - - /* look up the next size we'd like to use for the hash table */ - for (pidx = 0; pidx < primes; ++pidx) - { - if (prime_number[pidx] == oldHash->length) - { - break; - } - } - /* table size must be one of the prime numbers */ - PR_ASSERT(pidx < primes); - - /* if pidx == primes - 1, we can't expand the table any more */ - while (pidx < primes - 1) - { - /* next size */ - ++pidx; - length = prime_number[pidx]; - - /* allocate the new hash table and fill it in with the old */ - newHash = (_PRWaiterHash*)PR_CALLOC( - sizeof(_PRWaiterHash) + (length * sizeof(PRRecvWait*))); - if (NULL == newHash) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return _prmw_error; - } - - newHash->length = length; - retry = PR_FALSE; - for (desc = &oldHash->recv_wait; - newHash->count < oldHash->count; ++desc) - { - PR_ASSERT(desc < &oldHash->recv_wait + oldHash->length); - if (NULL != *desc) - { - hrv = MW_AddHashInternal(*desc, newHash); - PR_ASSERT(_prmw_error != hrv); - if (_prmw_success != hrv) - { - PR_DELETE(newHash); - retry = PR_TRUE; - break; - } - } - } - if (retry) continue; - - PR_DELETE(group->waiter); - group->waiter = newHash; - group->p_timestamp += 1; - return _prmw_success; - } - - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return _prmw_error; /* we're hosed */ -} /* MW_ExpandHashInternal */ - -#ifndef WINNT -static void _MW_DoneInternal( - PRWaitGroup *group, PRRecvWait **waiter, PRMWStatus outcome) -{ - /* - ** Add this receive wait object to the list of finished I/O - ** operations for this particular group. If there are other - ** threads waiting on the group, notify one. If not, arrange - ** for this thread to return. - */ - -#if 0 - printf("Removing 0x%x->0x%x\n", *waiter, (*waiter)->fd); -#endif - (*waiter)->outcome = outcome; - PR_APPEND_LINK(&((*waiter)->internal), &group->io_ready); - PR_NotifyCondVar(group->io_complete); - PR_ASSERT(0 != group->waiter->count); - group->waiter->count -= 1; - *waiter = NULL; -} /* _MW_DoneInternal */ -#endif /* WINNT */ - -static PRRecvWait **_MW_LookupInternal(PRWaitGroup *group, PRFileDesc *fd) -{ - /* - ** Find the receive wait object corresponding to the file descriptor. - ** Only search the wait group specified. - */ - PRRecvWait **desc; - PRIntn rehash = _MW_REHASH_MAX; - _PRWaiterHash *hash = group->waiter; - PRUintn hidx = _MW_HASH(fd, hash->length); - PRUintn hoffset = 0; - - while (rehash-- > 0) - { - desc = (&hash->recv_wait) + hidx; - if ((*desc != NULL) && ((*desc)->fd == fd)) return desc; - if (0 == hoffset) - { - hoffset = _MW_HASH2(fd, hash->length); - PR_ASSERT(0 != hoffset); - } - hidx = (hidx + hoffset) % (hash->length); - } - return NULL; -} /* _MW_LookupInternal */ - -#ifndef WINNT -static PRStatus _MW_PollInternal(PRWaitGroup *group) -{ - PRRecvWait **waiter; - PRStatus rv = PR_FAILURE; - PRInt32 count, count_ready; - PRIntervalTime polling_interval; - - group->poller = PR_GetCurrentThread(); - - while (PR_TRUE) - { - PRIntervalTime now, since_last_poll; - PRPollDesc *poll_list; - - while (0 == group->waiter->count) - { - PRStatus st; - st = PR_WaitCondVar(group->new_business, PR_INTERVAL_NO_TIMEOUT); - if (_prmw_running != group->state) - { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - goto aborted; - } - if (_MW_ABORTED(st)) goto aborted; - } - - /* - ** There's something to do. See if our existing polling list - ** is large enough for what we have to do? - */ - - while (group->polling_count < group->waiter->count) - { - PRUint32 old_count = group->waiter->count; - PRUint32 new_count = PR_ROUNDUP(old_count, _PR_POLL_COUNT_FUDGE); - PRSize new_size = sizeof(PRPollDesc) * new_count; - PRPollDesc *old_polling_list = group->polling_list; - - PR_Unlock(group->ml); - poll_list = (PRPollDesc*)PR_CALLOC(new_size); - if (NULL == poll_list) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - PR_Lock(group->ml); - goto failed_alloc; - } - if (NULL != old_polling_list) - PR_DELETE(old_polling_list); - PR_Lock(group->ml); - if (_prmw_running != group->state) - { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - goto aborted; - } - group->polling_list = poll_list; - group->polling_count = new_count; - } - - now = PR_IntervalNow(); - polling_interval = max_polling_interval; - since_last_poll = now - group->last_poll; - - waiter = &group->waiter->recv_wait; - poll_list = group->polling_list; - for (count = 0; count < group->waiter->count; ++waiter) - { - PR_ASSERT(waiter < &group->waiter->recv_wait - + group->waiter->length); - if (NULL != *waiter) /* a live one! */ - { - if ((PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout) - && (since_last_poll >= (*waiter)->timeout)) - _MW_DoneInternal(group, waiter, PR_MW_TIMEOUT); - else - { - if (PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout) - { - (*waiter)->timeout -= since_last_poll; - if ((*waiter)->timeout < polling_interval) - polling_interval = (*waiter)->timeout; - } - PR_ASSERT(poll_list < group->polling_list - + group->polling_count); - poll_list->fd = (*waiter)->fd; - poll_list->in_flags = PR_POLL_READ; - poll_list->out_flags = 0; -#if 0 - printf( - "Polling 0x%x[%d]: [fd: 0x%x, tmo: %u]\n", - poll_list, count, poll_list->fd, (*waiter)->timeout); -#endif - poll_list += 1; - count += 1; - } - } - } - - PR_ASSERT(count == group->waiter->count); - - /* - ** If there are no more threads waiting for completion, - ** we need to return. - */ - if ((!PR_CLIST_IS_EMPTY(&group->io_ready)) - && (1 == group->waiting_threads)) break; - - if (0 == count) continue; /* wait for new business */ - - group->last_poll = now; - - PR_Unlock(group->ml); - - count_ready = PR_Poll(group->polling_list, count, polling_interval); - - PR_Lock(group->ml); - - if (_prmw_running != group->state) - { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - goto aborted; - } - if (-1 == count_ready) - { - goto failed_poll; /* that's a shame */ - } - else if (0 < count_ready) - { - for (poll_list = group->polling_list; count > 0; - poll_list++, count--) - { - PR_ASSERT( - poll_list < group->polling_list + group->polling_count); - if (poll_list->out_flags != 0) - { - waiter = _MW_LookupInternal(group, poll_list->fd); - /* - ** If 'waiter' is NULL, that means the wait receive - ** descriptor has been canceled. - */ - if (NULL != waiter) - _MW_DoneInternal(group, waiter, PR_MW_SUCCESS); - } - } - } - /* - ** If there are no more threads waiting for completion, - ** we need to return. - ** This thread was "borrowed" to do the polling, but it really - ** belongs to the client. - */ - if ((!PR_CLIST_IS_EMPTY(&group->io_ready)) - && (1 == group->waiting_threads)) break; - } - - rv = PR_SUCCESS; - -aborted: -failed_poll: -failed_alloc: - group->poller = NULL; /* we were that, not we ain't */ - if ((_prmw_running == group->state) && (group->waiting_threads > 1)) - { - /* Wake up one thread to become the new poller. */ - PR_NotifyCondVar(group->io_complete); - } - return rv; /* we return with the lock held */ -} /* _MW_PollInternal */ -#endif /* !WINNT */ - -static PRMWGroupState MW_TestForShutdownInternal(PRWaitGroup *group) -{ - PRMWGroupState rv = group->state; - /* - ** Looking at the group's fields is safe because - ** once the group's state is no longer running, it - ** cannot revert and there is a safe check on entry - ** to make sure no more threads are made to wait. - */ - if ((_prmw_stopping == rv) - && (0 == group->waiting_threads)) - { - rv = group->state = _prmw_stopped; - PR_NotifyCondVar(group->mw_manage); - } - return rv; -} /* MW_TestForShutdownInternal */ - -#ifndef WINNT -static void _MW_InitialRecv(PRCList *io_ready) -{ - PRRecvWait *desc = (PRRecvWait*)io_ready; - if ((NULL == desc->buffer.start) - || (0 == desc->buffer.length)) - desc->bytesRecv = 0; - else - { - desc->bytesRecv = (desc->fd->methods->recv)( - desc->fd, desc->buffer.start, - desc->buffer.length, 0, desc->timeout); - if (desc->bytesRecv < 0) /* SetError should already be there */ - desc->outcome = PR_MW_FAILURE; - } -} /* _MW_InitialRecv */ -#endif - -#ifdef WINNT -static void NT_TimeProc(void *arg) -{ - _MDOverlapped *overlapped = (_MDOverlapped *)arg; - PRRecvWait *desc = overlapped->data.mw.desc; - PRFileDesc *bottom; - - if (InterlockedCompareExchange((LONG *)&desc->outcome, - (LONG)PR_MW_TIMEOUT, (LONG)PR_MW_PENDING) != (LONG)PR_MW_PENDING) - { - /* This wait recv descriptor has already completed. */ - return; - } - - /* close the osfd to abort the outstanding async io request */ - /* $$$$ - ** Little late to be checking if NSPR's on the bottom of stack, - ** but if we don't check, we can't assert that the private data - ** is what we think it is. - ** $$$$ - */ - bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); - if (NULL != bottom) /* now what!?!?! */ - { - bottom->secret->state = _PR_FILEDESC_CLOSED; - if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR) - { - fprintf(stderr, "closesocket failed: %d\n", WSAGetLastError()); - PR_ASSERT(!"What shall I do?"); - } - } - return; -} /* NT_TimeProc */ - -static PRStatus NT_HashRemove(PRWaitGroup *group, PRFileDesc *fd) -{ - PRRecvWait **waiter; - - _PR_MD_LOCK(&group->mdlock); - waiter = _MW_LookupInternal(group, fd); - if (NULL != waiter) - { - group->waiter->count -= 1; - *waiter = NULL; - } - _PR_MD_UNLOCK(&group->mdlock); - return (NULL != waiter) ? PR_SUCCESS : PR_FAILURE; -} - -PRStatus NT_HashRemoveInternal(PRWaitGroup *group, PRFileDesc *fd) -{ - PRRecvWait **waiter; - - waiter = _MW_LookupInternal(group, fd); - if (NULL != waiter) - { - group->waiter->count -= 1; - *waiter = NULL; - } - return (NULL != waiter) ? PR_SUCCESS : PR_FAILURE; -} -#endif /* WINNT */ - -/******************************************************************/ -/******************************************************************/ -/********************** The public API portion ********************/ -/******************************************************************/ -/******************************************************************/ -PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc( - PRWaitGroup *group, PRRecvWait *desc) -{ - _PR_HashStory hrv; - PRStatus rv = PR_FAILURE; -#ifdef WINNT - _MDOverlapped *overlapped; - HANDLE hFile; - BOOL bResult; - DWORD dwError; - PRFileDesc *bottom; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - if ((NULL == group) && (NULL == (group = MW_Init2()))) - { - return rv; - } - - PR_ASSERT(NULL != desc->fd); - - desc->outcome = PR_MW_PENDING; /* nice, well known value */ - desc->bytesRecv = 0; /* likewise, though this value is ambiguious */ - - PR_Lock(group->ml); - - if (_prmw_running != group->state) - { - /* Not allowed to add after cancelling the group */ - desc->outcome = PR_MW_INTERRUPT; - PR_SetError(PR_INVALID_STATE_ERROR, 0); - PR_Unlock(group->ml); - return rv; - } - -#ifdef WINNT - _PR_MD_LOCK(&group->mdlock); -#endif - - /* - ** If the waiter count is zero at this point, there's no telling - ** how long we've been idle. Therefore, initialize the beginning - ** of the timing interval. As long as the list doesn't go empty, - ** it will maintain itself. - */ - if (0 == group->waiter->count) - group->last_poll = PR_IntervalNow(); - - do - { - hrv = MW_AddHashInternal(desc, group->waiter); - if (_prmw_rehash != hrv) break; - hrv = MW_ExpandHashInternal(group); /* gruesome */ - if (_prmw_success != hrv) break; - } while (PR_TRUE); - -#ifdef WINNT - _PR_MD_UNLOCK(&group->mdlock); -#endif - - PR_NotifyCondVar(group->new_business); /* tell the world */ - rv = (_prmw_success == hrv) ? PR_SUCCESS : PR_FAILURE; - PR_Unlock(group->ml); - -#ifdef WINNT - overlapped = PR_NEWZAP(_MDOverlapped); - if (NULL == overlapped) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - NT_HashRemove(group, desc->fd); - return rv; - } - overlapped->ioModel = _MD_MultiWaitIO; - overlapped->data.mw.desc = desc; - overlapped->data.mw.group = group; - if (desc->timeout != PR_INTERVAL_NO_TIMEOUT) - { - overlapped->data.mw.timer = CreateTimer( - desc->timeout, - NT_TimeProc, - overlapped); - if (0 == overlapped->data.mw.timer) - { - NT_HashRemove(group, desc->fd); - PR_DELETE(overlapped); - /* - * XXX It appears that a maximum of 16 timer events can - * be outstanding. GetLastError() returns 0 when I try it. - */ - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, GetLastError()); - return PR_FAILURE; - } - } - - /* Reach to the bottom layer to get the OS fd */ - bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); - if (NULL == bottom) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - hFile = (HANDLE)bottom->secret->md.osfd; - if (!bottom->secret->md.io_model_committed) - { - PRInt32 st; - st = _md_Associate(hFile); - PR_ASSERT(0 != st); - bottom->secret->md.io_model_committed = PR_TRUE; - } - bResult = ReadFile(hFile, - desc->buffer.start, - (DWORD)desc->buffer.length, - NULL, - &overlapped->overlapped); - if (FALSE == bResult && (dwError = GetLastError()) != ERROR_IO_PENDING) - { - if (desc->timeout != PR_INTERVAL_NO_TIMEOUT) - { - if (InterlockedCompareExchange((LONG *)&desc->outcome, - (LONG)PR_MW_FAILURE, (LONG)PR_MW_PENDING) - == (LONG)PR_MW_PENDING) - { - CancelTimer(overlapped->data.mw.timer); - } - NT_HashRemove(group, desc->fd); - PR_DELETE(overlapped); - } - _PR_MD_MAP_READ_ERROR(dwError); - rv = PR_FAILURE; - } -#endif - - return rv; -} /* PR_AddWaitFileDesc */ - -PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group) -{ - PRCList *io_ready = NULL; -#ifdef WINNT - PRThread *me = _PR_MD_CURRENT_THREAD(); - _MDOverlapped *overlapped; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - if ((NULL == group) && (NULL == (group = MW_Init2()))) goto failed_init; - - PR_Lock(group->ml); - - if (_prmw_running != group->state) - { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - goto invalid_state; - } - - group->waiting_threads += 1; /* the polling thread is counted */ - -#ifdef WINNT - _PR_MD_LOCK(&group->mdlock); - while (PR_CLIST_IS_EMPTY(&group->io_ready)) - { - _PR_THREAD_LOCK(me); - me->state = _PR_IO_WAIT; - PR_APPEND_LINK(&me->waitQLinks, &group->wait_list); - if (!_PR_IS_NATIVE_THREAD(me)) - { - _PR_SLEEPQ_LOCK(me->cpu); - _PR_ADD_SLEEPQ(me, PR_INTERVAL_NO_TIMEOUT); - _PR_SLEEPQ_UNLOCK(me->cpu); - } - _PR_THREAD_UNLOCK(me); - _PR_MD_UNLOCK(&group->mdlock); - PR_Unlock(group->ml); - _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT); - me->state = _PR_RUNNING; - PR_Lock(group->ml); - _PR_MD_LOCK(&group->mdlock); - if (_PR_PENDING_INTERRUPT(me)) { - PR_REMOVE_LINK(&me->waitQLinks); - _PR_MD_UNLOCK(&group->mdlock); - me->flags &= ~_PR_INTERRUPT; - me->io_suspended = PR_FALSE; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - goto aborted; - } - } - io_ready = PR_LIST_HEAD(&group->io_ready); - PR_ASSERT(io_ready != NULL); - PR_REMOVE_LINK(io_ready); - _PR_MD_UNLOCK(&group->mdlock); - overlapped = (_MDOverlapped *) - ((char *)io_ready - offsetof(_MDOverlapped, data)); - io_ready = &overlapped->data.mw.desc->internal; -#else - do - { - /* - ** If the I/O ready list isn't empty, have this thread - ** return with the first receive wait object that's available. - */ - if (PR_CLIST_IS_EMPTY(&group->io_ready)) - { - /* - ** Is there a polling thread yet? If not, grab this thread - ** and use it. - */ - if (NULL == group->poller) - { - /* - ** This thread will stay do polling until it becomes the only one - ** left to service a completion. Then it will return and there will - ** be none left to actually poll or to run completions. - ** - ** The polling function should only return w/ failure or - ** with some I/O ready. - */ - if (PR_FAILURE == _MW_PollInternal(group)) goto failed_poll; - } - else - { - /* - ** There are four reasons a thread can be awakened from - ** a wait on the io_complete condition variable. - ** 1. Some I/O has completed, i.e., the io_ready list - ** is nonempty. - ** 2. The wait group is canceled. - ** 3. The thread is interrupted. - ** 4. The current polling thread has to leave and needs - ** a replacement. - ** The logic to find a new polling thread is made more - ** complicated by all the other possible events. - ** I tried my best to write the logic clearly, but - ** it is still full of if's with continue and goto. - */ - PRStatus st; - do - { - st = PR_WaitCondVar(group->io_complete, PR_INTERVAL_NO_TIMEOUT); - if (_prmw_running != group->state) - { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - goto aborted; - } - if (_MW_ABORTED(st) || (NULL == group->poller)) break; - } while (PR_CLIST_IS_EMPTY(&group->io_ready)); - - /* - ** The thread is interrupted and has to leave. It might - ** have also been awakened to process ready i/o or be the - ** new poller. To be safe, if either condition is true, - ** we awaken another thread to take its place. - */ - if (_MW_ABORTED(st)) - { - if ((NULL == group->poller - || !PR_CLIST_IS_EMPTY(&group->io_ready)) - && group->waiting_threads > 1) - PR_NotifyCondVar(group->io_complete); - goto aborted; - } - - /* - ** A new poller is needed, but can I be the new poller? - ** If there is no i/o ready, sure. But if there is any - ** i/o ready, it has a higher priority. I want to - ** process the ready i/o first and wake up another - ** thread to be the new poller. - */ - if (NULL == group->poller) - { - if (PR_CLIST_IS_EMPTY(&group->io_ready)) - continue; - if (group->waiting_threads > 1) - PR_NotifyCondVar(group->io_complete); - } - } - PR_ASSERT(!PR_CLIST_IS_EMPTY(&group->io_ready)); - } - io_ready = PR_LIST_HEAD(&group->io_ready); - PR_NotifyCondVar(group->io_taken); - PR_ASSERT(io_ready != NULL); - PR_REMOVE_LINK(io_ready); - } while (NULL == io_ready); - -failed_poll: - -#endif - -aborted: - - group->waiting_threads -= 1; -invalid_state: - (void)MW_TestForShutdownInternal(group); - PR_Unlock(group->ml); - -failed_init: - if (NULL != io_ready) - { - /* If the operation failed, record the reason why */ - switch (((PRRecvWait*)io_ready)->outcome) - { - case PR_MW_PENDING: - PR_ASSERT(0); - break; - case PR_MW_SUCCESS: -#ifndef WINNT - _MW_InitialRecv(io_ready); -#endif - break; -#ifdef WINNT - case PR_MW_FAILURE: - _PR_MD_MAP_READ_ERROR(overlapped->data.mw.error); - break; -#endif - case PR_MW_TIMEOUT: - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - break; - case PR_MW_INTERRUPT: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - break; - default: break; - } -#ifdef WINNT - if (NULL != overlapped->data.mw.timer) - { - PR_ASSERT(PR_INTERVAL_NO_TIMEOUT - != overlapped->data.mw.desc->timeout); - CancelTimer(overlapped->data.mw.timer); - } - else - { - PR_ASSERT(PR_INTERVAL_NO_TIMEOUT - == overlapped->data.mw.desc->timeout); - } - PR_DELETE(overlapped); -#endif - } - return (PRRecvWait*)io_ready; -} /* PR_WaitRecvReady */ - -PR_IMPLEMENT(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc) -{ -#if !defined(WINNT) - PRRecvWait **recv_wait; -#endif - PRStatus rv = PR_SUCCESS; - if (NULL == group) group = mw_state->group; - PR_ASSERT(NULL != group); - if (NULL == group) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - - PR_Lock(group->ml); - - if (_prmw_running != group->state) - { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - rv = PR_FAILURE; - goto unlock; - } - -#ifdef WINNT - if (InterlockedCompareExchange((LONG *)&desc->outcome, - (LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING) == (LONG)PR_MW_PENDING) - { - PRFileDesc *bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); - if (NULL == bottom) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - goto unlock; - } - bottom->secret->state = _PR_FILEDESC_CLOSED; -#if 0 - fprintf(stderr, "cancel wait recv: closing socket\n"); -#endif - if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR) - { - fprintf(stderr, "closesocket failed: %d\n", WSAGetLastError()); - exit(1); - } - } -#else - if (NULL != (recv_wait = _MW_LookupInternal(group, desc->fd))) - { - /* it was in the wait table */ - _MW_DoneInternal(group, recv_wait, PR_MW_INTERRUPT); - goto unlock; - } - if (!PR_CLIST_IS_EMPTY(&group->io_ready)) - { - /* is it already complete? */ - PRCList *head = PR_LIST_HEAD(&group->io_ready); - do - { - PRRecvWait *done = (PRRecvWait*)head; - if (done == desc) goto unlock; - head = PR_NEXT_LINK(head); - } while (head != &group->io_ready); - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; - -#endif -unlock: - PR_Unlock(group->ml); - return rv; -} /* PR_CancelWaitFileDesc */ - -PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group) -{ - PRRecvWait **desc; - PRRecvWait *recv_wait = NULL; -#ifdef WINNT - _MDOverlapped *overlapped; - PRRecvWait **end; - PRThread *me = _PR_MD_CURRENT_THREAD(); -#endif - - if (NULL == group) group = mw_state->group; - PR_ASSERT(NULL != group); - if (NULL == group) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } - - PR_Lock(group->ml); - if (_prmw_stopped != group->state) - { - if (_prmw_running == group->state) - group->state = _prmw_stopping; /* so nothing new comes in */ - if (0 == group->waiting_threads) /* is there anybody else? */ - group->state = _prmw_stopped; /* we can stop right now */ - else - { - PR_NotifyAllCondVar(group->new_business); - PR_NotifyAllCondVar(group->io_complete); - } - while (_prmw_stopped != group->state) - (void)PR_WaitCondVar(group->mw_manage, PR_INTERVAL_NO_TIMEOUT); - } - -#ifdef WINNT - _PR_MD_LOCK(&group->mdlock); -#endif - /* make all the existing descriptors look done/interrupted */ -#ifdef WINNT - end = &group->waiter->recv_wait + group->waiter->length; - for (desc = &group->waiter->recv_wait; desc < end; ++desc) - { - if (NULL != *desc) - { - if (InterlockedCompareExchange((LONG *)&(*desc)->outcome, - (LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING) - == (LONG)PR_MW_PENDING) - { - PRFileDesc *bottom = PR_GetIdentitiesLayer( - (*desc)->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); - if (NULL == bottom) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - goto invalid_arg; - } - bottom->secret->state = _PR_FILEDESC_CLOSED; -#if 0 - fprintf(stderr, "cancel wait group: closing socket\n"); -#endif - if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR) - { - fprintf(stderr, "closesocket failed: %d\n", - WSAGetLastError()); - exit(1); - } - } - } - } - while (group->waiter->count > 0) - { - _PR_THREAD_LOCK(me); - me->state = _PR_IO_WAIT; - PR_APPEND_LINK(&me->waitQLinks, &group->wait_list); - if (!_PR_IS_NATIVE_THREAD(me)) - { - _PR_SLEEPQ_LOCK(me->cpu); - _PR_ADD_SLEEPQ(me, PR_INTERVAL_NO_TIMEOUT); - _PR_SLEEPQ_UNLOCK(me->cpu); - } - _PR_THREAD_UNLOCK(me); - _PR_MD_UNLOCK(&group->mdlock); - PR_Unlock(group->ml); - _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT); - me->state = _PR_RUNNING; - PR_Lock(group->ml); - _PR_MD_LOCK(&group->mdlock); - } -#else - for (desc = &group->waiter->recv_wait; group->waiter->count > 0; ++desc) - { - PR_ASSERT(desc < &group->waiter->recv_wait + group->waiter->length); - if (NULL != *desc) - _MW_DoneInternal(group, desc, PR_MW_INTERRUPT); - } -#endif - - /* take first element of finished list and return it or NULL */ - if (PR_CLIST_IS_EMPTY(&group->io_ready)) - PR_SetError(PR_GROUP_EMPTY_ERROR, 0); - else - { - PRCList *head = PR_LIST_HEAD(&group->io_ready); - PR_REMOVE_AND_INIT_LINK(head); -#ifdef WINNT - overlapped = (_MDOverlapped *) - ((char *)head - offsetof(_MDOverlapped, data)); - head = &overlapped->data.mw.desc->internal; - if (NULL != overlapped->data.mw.timer) - { - PR_ASSERT(PR_INTERVAL_NO_TIMEOUT - != overlapped->data.mw.desc->timeout); - CancelTimer(overlapped->data.mw.timer); - } - else - { - PR_ASSERT(PR_INTERVAL_NO_TIMEOUT - == overlapped->data.mw.desc->timeout); - } - PR_DELETE(overlapped); -#endif - recv_wait = (PRRecvWait*)head; - } -#ifdef WINNT -invalid_arg: - _PR_MD_UNLOCK(&group->mdlock); -#endif - PR_Unlock(group->ml); - - return recv_wait; -} /* PR_CancelWaitGroup */ - -PR_IMPLEMENT(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size /* ignored */) -{ - PRWaitGroup *wg; - - if (NULL == (wg = PR_NEWZAP(PRWaitGroup))) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto failed; - } - /* the wait group itself */ - wg->ml = PR_NewLock(); - if (NULL == wg->ml) goto failed_lock; - wg->io_taken = PR_NewCondVar(wg->ml); - if (NULL == wg->io_taken) goto failed_cvar0; - wg->io_complete = PR_NewCondVar(wg->ml); - if (NULL == wg->io_complete) goto failed_cvar1; - wg->new_business = PR_NewCondVar(wg->ml); - if (NULL == wg->new_business) goto failed_cvar2; - wg->mw_manage = PR_NewCondVar(wg->ml); - if (NULL == wg->mw_manage) goto failed_cvar3; - - PR_INIT_CLIST(&wg->group_link); - PR_INIT_CLIST(&wg->io_ready); - - /* the waiters sequence */ - wg->waiter = (_PRWaiterHash*)PR_CALLOC( - sizeof(_PRWaiterHash) + - (_PR_DEFAULT_HASH_LENGTH * sizeof(PRRecvWait*))); - if (NULL == wg->waiter) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto failed_waiter; - } - wg->waiter->count = 0; - wg->waiter->length = _PR_DEFAULT_HASH_LENGTH; - -#ifdef WINNT - _PR_MD_NEW_LOCK(&wg->mdlock); - PR_INIT_CLIST(&wg->wait_list); -#endif /* WINNT */ - - PR_Lock(mw_lock); - PR_APPEND_LINK(&wg->group_link, &mw_state->group_list); - PR_Unlock(mw_lock); - return wg; - -failed_waiter: - PR_DestroyCondVar(wg->mw_manage); -failed_cvar3: - PR_DestroyCondVar(wg->new_business); -failed_cvar2: - PR_DestroyCondVar(wg->io_complete); -failed_cvar1: - PR_DestroyCondVar(wg->io_taken); -failed_cvar0: - PR_DestroyLock(wg->ml); -failed_lock: - PR_DELETE(wg); - wg = NULL; - -failed: - return wg; -} /* MW_CreateWaitGroup */ - -PR_IMPLEMENT(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group) -{ - PRStatus rv = PR_SUCCESS; - if (NULL == group) group = mw_state->group; - PR_ASSERT(NULL != group); - if (NULL != group) - { - PR_Lock(group->ml); - if ((group->waiting_threads == 0) - && (group->waiter->count == 0) - && PR_CLIST_IS_EMPTY(&group->io_ready)) - { - group->state = _prmw_stopped; - } - else - { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - rv = PR_FAILURE; - } - PR_Unlock(group->ml); - if (PR_FAILURE == rv) return rv; - - PR_Lock(mw_lock); - PR_REMOVE_LINK(&group->group_link); - PR_Unlock(mw_lock); - -#ifdef WINNT - /* - * XXX make sure wait_list is empty and waiter is empty. - * These must be checked while holding mdlock. - */ - _PR_MD_FREE_LOCK(&group->mdlock); -#endif - - PR_DELETE(group->waiter); - PR_DELETE(group->polling_list); - PR_DestroyCondVar(group->mw_manage); - PR_DestroyCondVar(group->new_business); - PR_DestroyCondVar(group->io_complete); - PR_DestroyCondVar(group->io_taken); - PR_DestroyLock(group->ml); - if (group == mw_state->group) mw_state->group = NULL; - PR_DELETE(group); - } - else - { - /* The default wait group is not created yet. */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; - } - return rv; -} /* PR_DestroyWaitGroup */ - -/********************************************************************** -*********************************************************************** -******************** Wait group enumerations ************************** -*********************************************************************** -**********************************************************************/ - -PR_IMPLEMENT(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group) -{ - PRMWaitEnumerator *enumerator = PR_NEWZAP(PRMWaitEnumerator); - if (NULL == enumerator) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - else - { - enumerator->group = group; - enumerator->seal = _PR_ENUM_SEALED; - } - return enumerator; -} /* PR_CreateMWaitEnumerator */ - -PR_IMPLEMENT(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator) -{ - PR_ASSERT(NULL != enumerator); - PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal); - if ((NULL == enumerator) || (_PR_ENUM_SEALED != enumerator->seal)) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - enumerator->seal = _PR_ENUM_UNSEALED; - PR_Free(enumerator); - return PR_SUCCESS; -} /* PR_DestroyMWaitEnumerator */ - -PR_IMPLEMENT(PRRecvWait*) PR_EnumerateWaitGroup( - PRMWaitEnumerator *enumerator, const PRRecvWait *previous) -{ - PRRecvWait *result = NULL; - - /* entry point sanity checking */ - PR_ASSERT(NULL != enumerator); - PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal); - if ((NULL == enumerator) - || (_PR_ENUM_SEALED != enumerator->seal)) goto bad_argument; - - /* beginning of enumeration */ - if (NULL == previous) - { - if (NULL == enumerator->group) - { - enumerator->group = mw_state->group; - if (NULL == enumerator->group) - { - PR_SetError(PR_GROUP_EMPTY_ERROR, 0); - return NULL; - } - } - enumerator->waiter = &enumerator->group->waiter->recv_wait; - enumerator->p_timestamp = enumerator->group->p_timestamp; - enumerator->thread = PR_GetCurrentThread(); - enumerator->index = 0; - } - /* continuing an enumeration */ - else - { - PRThread *me = PR_GetCurrentThread(); - PR_ASSERT(me == enumerator->thread); - if (me != enumerator->thread) goto bad_argument; - - /* need to restart the enumeration */ - if (enumerator->p_timestamp != enumerator->group->p_timestamp) - return PR_EnumerateWaitGroup(enumerator, NULL); - } - - /* actually progress the enumeration */ -#if defined(WINNT) - _PR_MD_LOCK(&enumerator->group->mdlock); -#else - PR_Lock(enumerator->group->ml); -#endif - while (enumerator->index++ < enumerator->group->waiter->length) - { - if (NULL != (result = *(enumerator->waiter)++)) break; - } -#if defined(WINNT) - _PR_MD_UNLOCK(&enumerator->group->mdlock); -#else - PR_Unlock(enumerator->group->ml); -#endif - - return result; /* what we live for */ - -bad_argument: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; /* probably ambiguous */ -} /* PR_EnumerateWaitGroup */ - -/* prmwait.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prpolevt.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prpolevt.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prpolevt.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prpolevt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - ********************************************************************* - * - * Pollable events - * - * Pollable events are implemented using layered I/O. The only - * I/O methods that are implemented for pollable events are poll - * and close. No other methods can be invoked on a pollable - * event. - * - * A pipe or socket pair is created and the pollable event layer - * is pushed onto the read end. A pointer to the write end is - * saved in the PRFilePrivate structure of the pollable event. - * - ********************************************************************* - */ - -#include "prinit.h" -#include "prio.h" -#include "prmem.h" -#include "prerror.h" -#include "prlog.h" - -/* - * These internal functions are declared in primpl.h, - * but we can't include primpl.h because the definition - * of struct PRFilePrivate in this file (for the pollable - * event layer) will conflict with the definition of - * struct PRFilePrivate in primpl.h (for the NSPR layer). - */ -extern PRIntn _PR_InvalidInt(void); -extern PRInt64 _PR_InvalidInt64(void); -extern PRStatus _PR_InvalidStatus(void); -extern PRFileDesc *_PR_InvalidDesc(void); - -/* - * PRFilePrivate structure for the NSPR pollable events layer - */ -struct PRFilePrivate { - PRFileDesc *writeEnd; /* the write end of the pipe/socketpair */ -}; - -static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd); - -static PRInt16 PR_CALLBACK _pr_PolEvtPoll( - PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags); - -static PRIOMethods _pr_polevt_methods = { - PR_DESC_LAYERED, - _pr_PolEvtClose, - (PRReadFN)_PR_InvalidInt, - (PRWriteFN)_PR_InvalidInt, - (PRAvailableFN)_PR_InvalidInt, - (PRAvailable64FN)_PR_InvalidInt64, - (PRFsyncFN)_PR_InvalidStatus, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - (PRWritevFN)_PR_InvalidInt, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt, - (PRSendFN)_PR_InvalidInt, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - _pr_PolEvtPoll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - (PRGetsocknameFN)_PR_InvalidStatus, - (PRGetpeernameFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -static PRDescIdentity _pr_polevt_id; -static PRCallOnceType _pr_polevt_once_control; -static PRStatus PR_CALLBACK _pr_PolEvtInit(void); - -static PRInt16 PR_CALLBACK _pr_PolEvtPoll( - PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) -{ - return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags); -} - -static PRStatus PR_CALLBACK _pr_PolEvtInit(void) -{ - _pr_polevt_id = PR_GetUniqueIdentity("NSPR pollable events"); - if (PR_INVALID_IO_LAYER == _pr_polevt_id) { - return PR_FAILURE; - } - return PR_SUCCESS; -} - -#if !defined(XP_UNIX) -#define USE_TCP_SOCKETPAIR -#endif - -PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void) -{ - PRFileDesc *event; - PRFileDesc *fd[2]; /* fd[0] is the read end; fd[1] is the write end */ -#ifdef USE_TCP_SOCKETPAIR - PRSocketOptionData socket_opt; - PRStatus rv; -#endif - - fd[0] = fd[1] = NULL; - - if (PR_CallOnce(&_pr_polevt_once_control, _pr_PolEvtInit) == PR_FAILURE) { - return NULL; - } - - event = PR_CreateIOLayerStub(_pr_polevt_id, &_pr_polevt_methods); - if (NULL == event) { - goto errorExit; - } - event->secret = PR_NEW(PRFilePrivate); - if (event->secret == NULL) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto errorExit; - } - -#ifndef USE_TCP_SOCKETPAIR - if (PR_CreatePipe(&fd[0], &fd[1]) == PR_FAILURE) { - fd[0] = fd[1] = NULL; - goto errorExit; - } -#else - if (PR_NewTCPSocketPair(fd) == PR_FAILURE) { - fd[0] = fd[1] = NULL; - goto errorExit; - } - /* - * set the TCP_NODELAY option to reduce notification latency - */ - socket_opt.option = PR_SockOpt_NoDelay; - socket_opt.value.no_delay = PR_TRUE; - rv = PR_SetSocketOption(fd[1], &socket_opt); - PR_ASSERT(PR_SUCCESS == rv); -#endif - - event->secret->writeEnd = fd[1]; - if (PR_PushIOLayer(fd[0], PR_TOP_IO_LAYER, event) == PR_FAILURE) { - goto errorExit; - } - - return fd[0]; - -errorExit: - if (fd[0]) { - PR_Close(fd[0]); - PR_Close(fd[1]); - } - if (event) { - PR_DELETE(event->secret); - event->dtor(event); - } - return NULL; -} - -static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd) -{ - PRFileDesc *event; - - event = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); - PR_ASSERT(NULL == event->higher && NULL == event->lower); - PR_Close(fd); - PR_Close(event->secret->writeEnd); - PR_DELETE(event->secret); - event->dtor(event); - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event) -{ - return PR_Close(event); -} - -static const char magicChar = '\x38'; - -PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event) -{ - if (PR_Write(event->secret->writeEnd, &magicChar, 1) != 1) { - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event) -{ - char buf[1024]; - PRInt32 nBytes; -#ifdef DEBUG - PRIntn i; -#endif - - nBytes = PR_Read(event->lower, buf, sizeof(buf)); - if (nBytes == -1) { - return PR_FAILURE; - } - -#ifdef DEBUG - /* - * Make sure people do not write to the pollable event fd - * directly. - */ - for (i = 0; i < nBytes; i++) { - PR_ASSERT(buf[i] == magicChar); - } -#endif - - return PR_SUCCESS; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prprf.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prprf.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prprf.c 2012-05-08 22:55:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prprf.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1248 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Portable safe sprintf code. -** -** Author: Kipp E.B. Hickman -*/ -#include -#include -#include -#include -#include "primpl.h" -#include "prprf.h" -#include "prlong.h" -#include "prlog.h" -#include "prmem.h" - -/* -** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it) -*/ - -/* -** XXX This needs to be internationalized! -*/ - -typedef struct SprintfStateStr SprintfState; - -struct SprintfStateStr { - int (*stuff)(SprintfState *ss, const char *sp, PRUint32 len); - - char *base; - char *cur; - PRUint32 maxlen; - - int (*func)(void *arg, const char *sp, PRUint32 len); - void *arg; -}; - -/* -** Numbered Argument -*/ -struct NumArg { - int type; /* type of the numbered argument */ - union { /* the numbered argument */ - int i; - unsigned int ui; - PRInt32 i32; - PRUint32 ui32; - PRInt64 ll; - PRUint64 ull; - double d; - const char *s; - int *ip; -#ifdef WIN32 - const WCHAR *ws; -#endif - } u; -}; - -#define NAS_DEFAULT_NUM 20 /* default number of NumberedArgument array */ - - -#define TYPE_INT16 0 -#define TYPE_UINT16 1 -#define TYPE_INTN 2 -#define TYPE_UINTN 3 -#define TYPE_INT32 4 -#define TYPE_UINT32 5 -#define TYPE_INT64 6 -#define TYPE_UINT64 7 -#define TYPE_STRING 8 -#define TYPE_DOUBLE 9 -#define TYPE_INTSTR 10 -#ifdef WIN32 -#define TYPE_WSTRING 11 -#endif -#define TYPE_UNKNOWN 20 - -#define FLAG_LEFT 0x1 -#define FLAG_SIGNED 0x2 -#define FLAG_SPACED 0x4 -#define FLAG_ZEROS 0x8 -#define FLAG_NEG 0x10 - -/* -** Fill into the buffer using the data in src -*/ -static int fill2(SprintfState *ss, const char *src, int srclen, int width, - int flags) -{ - char space = ' '; - int rv; - - width -= srclen; - if ((width > 0) && ((flags & FLAG_LEFT) == 0)) { /* Right adjusting */ - if (flags & FLAG_ZEROS) { - space = '0'; - } - while (--width >= 0) { - rv = (*ss->stuff)(ss, &space, 1); - if (rv < 0) { - return rv; - } - } - } - - /* Copy out the source data */ - rv = (*ss->stuff)(ss, src, srclen); - if (rv < 0) { - return rv; - } - - if ((width > 0) && ((flags & FLAG_LEFT) != 0)) { /* Left adjusting */ - while (--width >= 0) { - rv = (*ss->stuff)(ss, &space, 1); - if (rv < 0) { - return rv; - } - } - } - return 0; -} - -/* -** Fill a number. The order is: optional-sign zero-filling conversion-digits -*/ -static int fill_n(SprintfState *ss, const char *src, int srclen, int width, - int prec, int type, int flags) -{ - int zerowidth = 0; - int precwidth = 0; - int signwidth = 0; - int leftspaces = 0; - int rightspaces = 0; - int cvtwidth; - int rv; - char sign; - - if ((type & 1) == 0) { - if (flags & FLAG_NEG) { - sign = '-'; - signwidth = 1; - } else if (flags & FLAG_SIGNED) { - sign = '+'; - signwidth = 1; - } else if (flags & FLAG_SPACED) { - sign = ' '; - signwidth = 1; - } - } - cvtwidth = signwidth + srclen; - - if (prec > 0) { - if (prec > srclen) { - precwidth = prec - srclen; /* Need zero filling */ - cvtwidth += precwidth; - } - } - - if ((flags & FLAG_ZEROS) && (prec < 0)) { - if (width > cvtwidth) { - zerowidth = width - cvtwidth; /* Zero filling */ - cvtwidth += zerowidth; - } - } - - if (flags & FLAG_LEFT) { - if (width > cvtwidth) { - /* Space filling on the right (i.e. left adjusting) */ - rightspaces = width - cvtwidth; - } - } else { - if (width > cvtwidth) { - /* Space filling on the left (i.e. right adjusting) */ - leftspaces = width - cvtwidth; - } - } - while (--leftspaces >= 0) { - rv = (*ss->stuff)(ss, " ", 1); - if (rv < 0) { - return rv; - } - } - if (signwidth) { - rv = (*ss->stuff)(ss, &sign, 1); - if (rv < 0) { - return rv; - } - } - while (--precwidth >= 0) { - rv = (*ss->stuff)(ss, "0", 1); - if (rv < 0) { - return rv; - } - } - while (--zerowidth >= 0) { - rv = (*ss->stuff)(ss, "0", 1); - if (rv < 0) { - return rv; - } - } - rv = (*ss->stuff)(ss, src, srclen); - if (rv < 0) { - return rv; - } - while (--rightspaces >= 0) { - rv = (*ss->stuff)(ss, " ", 1); - if (rv < 0) { - return rv; - } - } - return 0; -} - -/* -** Convert a long into its printable form -*/ -static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, - int type, int flags, const char *hexp) -{ - char cvtbuf[100]; - char *cvt; - int digits; - - /* according to the man page this needs to happen */ - if ((prec == 0) && (num == 0)) { - return 0; - } - - /* - ** Converting decimal is a little tricky. In the unsigned case we - ** need to stop when we hit 10 digits. In the signed case, we can - ** stop when the number is zero. - */ - cvt = cvtbuf + sizeof(cvtbuf); - digits = 0; - while (num) { - int digit = (((unsigned long)num) % radix) & 0xF; - *--cvt = hexp[digit]; - digits++; - num = (long)(((unsigned long)num) / radix); - } - if (digits == 0) { - *--cvt = '0'; - digits++; - } - - /* - ** Now that we have the number converted without its sign, deal with - ** the sign and zero padding. - */ - return fill_n(ss, cvt, digits, width, prec, type, flags); -} - -/* -** Convert a 64-bit integer into its printable form -*/ -static int cvt_ll(SprintfState *ss, PRInt64 num, int width, int prec, int radix, - int type, int flags, const char *hexp) -{ - char cvtbuf[100]; - char *cvt; - int digits; - PRInt64 rad; - - /* according to the man page this needs to happen */ - if ((prec == 0) && (LL_IS_ZERO(num))) { - return 0; - } - - /* - ** Converting decimal is a little tricky. In the unsigned case we - ** need to stop when we hit 10 digits. In the signed case, we can - ** stop when the number is zero. - */ - LL_I2L(rad, radix); - cvt = cvtbuf + sizeof(cvtbuf); - digits = 0; - while (!LL_IS_ZERO(num)) { - PRInt32 digit; - PRInt64 quot, rem; - LL_UDIVMOD(", &rem, num, rad); - LL_L2I(digit, rem); - *--cvt = hexp[digit & 0xf]; - digits++; - num = quot; - } - if (digits == 0) { - *--cvt = '0'; - digits++; - } - - /* - ** Now that we have the number converted without its sign, deal with - ** the sign and zero padding. - */ - return fill_n(ss, cvt, digits, width, prec, type, flags); -} - -/* -** Convert a double precision floating point number into its printable -** form. -** -** XXX stop using sprintf to convert floating point -*/ -static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) -{ - char fin[20]; - char fout[300]; - int amount = fmt1 - fmt0; - - PR_ASSERT((amount > 0) && (amount < sizeof(fin))); - if (amount >= sizeof(fin)) { - /* Totally bogus % command to sprintf. Just ignore it */ - return 0; - } - memcpy(fin, fmt0, amount); - fin[amount] = 0; - - /* Convert floating point using the native sprintf code */ -#ifdef DEBUG - { - const char *p = fin; - while (*p) { - PR_ASSERT(*p != 'L'); - p++; - } - } -#endif - sprintf(fout, fin, d); - - /* - ** This assert will catch overflow's of fout, when building with - ** debugging on. At least this way we can track down the evil piece - ** of calling code and fix it! - */ - PR_ASSERT(strlen(fout) < sizeof(fout)); - - return (*ss->stuff)(ss, fout, strlen(fout)); -} - -/* -** Convert a string into its printable form. "width" is the output -** width. "prec" is the maximum number of characters of "s" to output, -** where -1 means until NUL. -*/ -static int cvt_s(SprintfState *ss, const char *str, int width, int prec, - int flags) -{ - int slen; - - if (prec == 0) - return 0; - - /* Limit string length by precision value */ - if (!str) { - str = "(null)"; - } - if (prec > 0) { - /* this is: slen = strnlen(str, prec); */ - register const char *s; - - for(s = str; prec && *s; s++, prec-- ) - ; - slen = s - str; - } else { - slen = strlen(str); - } - - /* and away we go */ - return fill2(ss, str, slen, width, flags); -} - -/* -** BuildArgArray stands for Numbered Argument list Sprintf -** for example, -** fmp = "%4$i, %2$d, %3s, %1d"; -** the number must start from 1, and no gap among them -*/ - -static struct NumArg* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArg* nasArray ) -{ - int number = 0, cn = 0, i; - const char* p; - char c; - struct NumArg* nas; - - - /* - ** first pass: - ** determine how many legal % I have got, then allocate space - */ - - p = fmt; - *rv = 0; - i = 0; - while( ( c = *p++ ) != 0 ){ - if( c != '%' ) - continue; - if( ( c = *p++ ) == '%' ) /* skip %% case */ - continue; - - while( c != 0 ){ - if( c > '9' || c < '0' ){ - if( c == '$' ){ /* numbered argument case */ - if( i > 0 ){ - *rv = -1; - return NULL; - } - number++; - } else{ /* non-numbered argument case */ - if( number > 0 ){ - *rv = -1; - return NULL; - } - i = 1; - } - break; - } - - c = *p++; - } - } - - if( number == 0 ){ - return NULL; - } - - - if( number > NAS_DEFAULT_NUM ){ - nas = (struct NumArg*)PR_MALLOC( number * sizeof( struct NumArg ) ); - if( !nas ){ - *rv = -1; - return NULL; - } - } else { - nas = nasArray; - } - - for( i = 0; i < number; i++ ){ - nas[i].type = TYPE_UNKNOWN; - } - - - /* - ** second pass: - ** set nas[].type - */ - - p = fmt; - while( ( c = *p++ ) != 0 ){ - if( c != '%' ) continue; - c = *p++; - if( c == '%' ) continue; - - cn = 0; - while( c && c != '$' ){ /* should imporve error check later */ - cn = cn*10 + c - '0'; - c = *p++; - } - - if( !c || cn < 1 || cn > number ){ - *rv = -1; - break; - } - - /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */ - cn--; - if( nas[cn].type != TYPE_UNKNOWN ) - continue; - - c = *p++; - - /* width */ - if (c == '*') { - /* not supported feature, for the argument is not numbered */ - *rv = -1; - break; - } - - while ((c >= '0') && (c <= '9')) { - c = *p++; - } - - /* precision */ - if (c == '.') { - c = *p++; - if (c == '*') { - /* not supported feature, for the argument is not numbered */ - *rv = -1; - break; - } - - while ((c >= '0') && (c <= '9')) { - c = *p++; - } - } - - /* size */ - nas[cn].type = TYPE_INTN; - if (c == 'h') { - nas[cn].type = TYPE_INT16; - c = *p++; - } else if (c == 'L') { - /* XXX not quite sure here */ - nas[cn].type = TYPE_INT64; - c = *p++; - } else if (c == 'l') { - nas[cn].type = TYPE_INT32; - c = *p++; - if (c == 'l') { - nas[cn].type = TYPE_INT64; - c = *p++; - } - } - - /* format */ - switch (c) { - case 'd': - case 'c': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - break; - - case 'e': - case 'f': - case 'g': - nas[ cn ].type = TYPE_DOUBLE; - break; - - case 'p': - /* XXX should use cpp */ - if (sizeof(void *) == sizeof(PRInt32)) { - nas[ cn ].type = TYPE_UINT32; - } else if (sizeof(void *) == sizeof(PRInt64)) { - nas[ cn ].type = TYPE_UINT64; - } else if (sizeof(void *) == sizeof(PRIntn)) { - nas[ cn ].type = TYPE_UINTN; - } else { - nas[ cn ].type = TYPE_UNKNOWN; - } - break; - - case 'S': -#ifdef WIN32 - nas[ cn ].type = TYPE_WSTRING; - break; -#endif - case 'C': - case 'E': - case 'G': - /* XXX not supported I suppose */ - PR_ASSERT(0); - nas[ cn ].type = TYPE_UNKNOWN; - break; - - case 's': - nas[ cn ].type = TYPE_STRING; - break; - - case 'n': - nas[ cn ].type = TYPE_INTSTR; - break; - - default: - PR_ASSERT(0); - nas[ cn ].type = TYPE_UNKNOWN; - break; - } - - /* get a legal para. */ - if( nas[ cn ].type == TYPE_UNKNOWN ){ - *rv = -1; - break; - } - } - - - /* - ** third pass - ** fill the nas[cn].ap - */ - - if( *rv < 0 ){ - if( nas != nasArray ) - PR_DELETE( nas ); - return NULL; - } - - cn = 0; - while( cn < number ){ - if( nas[cn].type == TYPE_UNKNOWN ){ - cn++; - continue; - } - - switch( nas[cn].type ){ - case TYPE_INT16: - case TYPE_UINT16: - case TYPE_INTN: - nas[cn].u.i = va_arg( ap, int ); - break; - - case TYPE_UINTN: - nas[cn].u.ui = va_arg( ap, unsigned int ); - break; - - case TYPE_INT32: - nas[cn].u.i32 = va_arg( ap, PRInt32 ); - break; - - case TYPE_UINT32: - nas[cn].u.ui32 = va_arg( ap, PRUint32 ); - break; - - case TYPE_INT64: - nas[cn].u.ll = va_arg( ap, PRInt64 ); - break; - - case TYPE_UINT64: - nas[cn].u.ull = va_arg( ap, PRUint64 ); - break; - - case TYPE_STRING: - nas[cn].u.s = va_arg( ap, char* ); - break; - -#ifdef WIN32 - case TYPE_WSTRING: - nas[cn].u.ws = va_arg( ap, WCHAR* ); - break; -#endif - - case TYPE_INTSTR: - nas[cn].u.ip = va_arg( ap, int* ); - break; - - case TYPE_DOUBLE: - nas[cn].u.d = va_arg( ap, double ); - break; - - default: - if( nas != nasArray ) - PR_DELETE( nas ); - *rv = -1; - return NULL; - } - - cn++; - } - - - return nas; -} - -/* -** The workhorse sprintf code. -*/ -static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) -{ - char c; - int flags, width, prec, radix, type; - union { - char ch; - int i; - long l; - PRInt64 ll; - double d; - const char *s; - int *ip; -#ifdef WIN32 - const WCHAR *ws; -#endif - } u; - const char *fmt0; - static char *hex = "0123456789abcdef"; - static char *HEX = "0123456789ABCDEF"; - char *hexp; - int rv, i; - struct NumArg* nas = NULL; - struct NumArg* nap; - struct NumArg nasArray[ NAS_DEFAULT_NUM ]; - char pattern[20]; - const char* dolPt = NULL; /* in "%4$.2f", dolPt will point to . */ -#ifdef WIN32 - char *pBuf = NULL; -#endif - - /* - ** build an argument array, IF the fmt is numbered argument - ** list style, to contain the Numbered Argument list pointers - */ - - nas = BuildArgArray( fmt, ap, &rv, nasArray ); - if( rv < 0 ){ - /* the fmt contains error Numbered Argument format, jliu@netscape.com */ - PR_ASSERT(0); - return rv; - } - - while ((c = *fmt++) != 0) { - if (c != '%') { - rv = (*ss->stuff)(ss, fmt - 1, 1); - if (rv < 0) { - return rv; - } - continue; - } - fmt0 = fmt - 1; - - /* - ** Gobble up the % format string. Hopefully we have handled all - ** of the strange cases! - */ - flags = 0; - c = *fmt++; - if (c == '%') { - /* quoting a % with %% */ - rv = (*ss->stuff)(ss, fmt - 1, 1); - if (rv < 0) { - return rv; - } - continue; - } - - if( nas != NULL ){ - /* the fmt contains the Numbered Arguments feature */ - i = 0; - while( c && c != '$' ){ /* should imporve error check later */ - i = ( i * 10 ) + ( c - '0' ); - c = *fmt++; - } - - if( nas[i-1].type == TYPE_UNKNOWN ){ - if( nas && ( nas != nasArray ) ) - PR_DELETE( nas ); - return -1; - } - - nap = &nas[i-1]; - dolPt = fmt; - c = *fmt++; - } - - /* - * Examine optional flags. Note that we do not implement the - * '#' flag of sprintf(). The ANSI C spec. of the '#' flag is - * somewhat ambiguous and not ideal, which is perhaps why - * the various sprintf() implementations are inconsistent - * on this feature. - */ - while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) { - if (c == '-') flags |= FLAG_LEFT; - if (c == '+') flags |= FLAG_SIGNED; - if (c == ' ') flags |= FLAG_SPACED; - if (c == '0') flags |= FLAG_ZEROS; - c = *fmt++; - } - if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED; - if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS; - - /* width */ - if (c == '*') { - c = *fmt++; - width = va_arg(ap, int); - } else { - width = 0; - while ((c >= '0') && (c <= '9')) { - width = (width * 10) + (c - '0'); - c = *fmt++; - } - } - - /* precision */ - prec = -1; - if (c == '.') { - c = *fmt++; - if (c == '*') { - c = *fmt++; - prec = va_arg(ap, int); - } else { - prec = 0; - while ((c >= '0') && (c <= '9')) { - prec = (prec * 10) + (c - '0'); - c = *fmt++; - } - } - } - - /* size */ - type = TYPE_INTN; - if (c == 'h') { - type = TYPE_INT16; - c = *fmt++; - } else if (c == 'L') { - /* XXX not quite sure here */ - type = TYPE_INT64; - c = *fmt++; - } else if (c == 'l') { - type = TYPE_INT32; - c = *fmt++; - if (c == 'l') { - type = TYPE_INT64; - c = *fmt++; - } - } - - /* format */ - hexp = hex; - switch (c) { - case 'd': case 'i': /* decimal/integer */ - radix = 10; - goto fetch_and_convert; - - case 'o': /* octal */ - radix = 8; - type |= 1; - goto fetch_and_convert; - - case 'u': /* unsigned decimal */ - radix = 10; - type |= 1; - goto fetch_and_convert; - - case 'x': /* unsigned hex */ - radix = 16; - type |= 1; - goto fetch_and_convert; - - case 'X': /* unsigned HEX */ - radix = 16; - hexp = HEX; - type |= 1; - goto fetch_and_convert; - - fetch_and_convert: - switch (type) { - case TYPE_INT16: - u.l = nas ? nap->u.i : va_arg(ap, int); - if (u.l < 0) { - u.l = -u.l; - flags |= FLAG_NEG; - } - goto do_long; - case TYPE_UINT16: - u.l = (nas ? nap->u.i : va_arg(ap, int)) & 0xffff; - goto do_long; - case TYPE_INTN: - u.l = nas ? nap->u.i : va_arg(ap, int); - if (u.l < 0) { - u.l = -u.l; - flags |= FLAG_NEG; - } - goto do_long; - case TYPE_UINTN: - u.l = (long)(nas ? nap->u.ui : va_arg(ap, unsigned int)); - goto do_long; - - case TYPE_INT32: - u.l = nas ? nap->u.i32 : va_arg(ap, PRInt32); - if (u.l < 0) { - u.l = -u.l; - flags |= FLAG_NEG; - } - goto do_long; - case TYPE_UINT32: - u.l = (long)(nas ? nap->u.ui32 : va_arg(ap, PRUint32)); - do_long: - rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp); - if (rv < 0) { - return rv; - } - break; - - case TYPE_INT64: - u.ll = nas ? nap->u.ll : va_arg(ap, PRInt64); - if (!LL_GE_ZERO(u.ll)) { - LL_NEG(u.ll, u.ll); - flags |= FLAG_NEG; - } - goto do_longlong; - case TYPE_UINT64: - u.ll = nas ? nap->u.ull : va_arg(ap, PRUint64); - do_longlong: - rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp); - if (rv < 0) { - return rv; - } - break; - } - break; - - case 'e': - case 'E': - case 'f': - case 'g': - u.d = nas ? nap->u.d : va_arg(ap, double); - if( nas != NULL ){ - i = fmt - dolPt; - if( i < sizeof( pattern ) ){ - pattern[0] = '%'; - memcpy( &pattern[1], dolPt, i ); - rv = cvt_f(ss, u.d, pattern, &pattern[i+1] ); - } - } else - rv = cvt_f(ss, u.d, fmt0, fmt); - - if (rv < 0) { - return rv; - } - break; - - case 'c': - u.ch = nas ? nap->u.i : va_arg(ap, int); - if ((flags & FLAG_LEFT) == 0) { - while (width-- > 1) { - rv = (*ss->stuff)(ss, " ", 1); - if (rv < 0) { - return rv; - } - } - } - rv = (*ss->stuff)(ss, &u.ch, 1); - if (rv < 0) { - return rv; - } - if (flags & FLAG_LEFT) { - while (width-- > 1) { - rv = (*ss->stuff)(ss, " ", 1); - if (rv < 0) { - return rv; - } - } - } - break; - - case 'p': - if (sizeof(void *) == sizeof(PRInt32)) { - type = TYPE_UINT32; - } else if (sizeof(void *) == sizeof(PRInt64)) { - type = TYPE_UINT64; - } else if (sizeof(void *) == sizeof(int)) { - type = TYPE_UINTN; - } else { - PR_ASSERT(0); - break; - } - radix = 16; - goto fetch_and_convert; - -#ifndef WIN32 - case 'S': - /* XXX not supported I suppose */ - PR_ASSERT(0); - break; -#endif - -#if 0 - case 'C': - case 'E': - case 'G': - /* XXX not supported I suppose */ - PR_ASSERT(0); - break; -#endif - -#ifdef WIN32 - case 'S': - u.ws = nas ? nap->u.ws : va_arg(ap, const WCHAR*); - - /* Get the required size in rv */ - rv = WideCharToMultiByte(CP_ACP, 0, u.ws, -1, NULL, 0, NULL, NULL); - if (rv == 0) - rv = 1; - pBuf = PR_MALLOC(rv); - WideCharToMultiByte(CP_ACP, 0, u.ws, -1, pBuf, (int)rv, NULL, NULL); - pBuf[rv-1] = '\0'; - - rv = cvt_s(ss, pBuf, width, prec, flags); - - /* We don't need the allocated buffer anymore */ - PR_Free(pBuf); - if (rv < 0) { - return rv; - } - break; - -#endif - - case 's': - u.s = nas ? nap->u.s : va_arg(ap, const char*); - rv = cvt_s(ss, u.s, width, prec, flags); - if (rv < 0) { - return rv; - } - break; - - case 'n': - u.ip = nas ? nap->u.ip : va_arg(ap, int*); - if (u.ip) { - *u.ip = ss->cur - ss->base; - } - break; - - default: - /* Not a % token after all... skip it */ -#if 0 - PR_ASSERT(0); -#endif - rv = (*ss->stuff)(ss, "%", 1); - if (rv < 0) { - return rv; - } - rv = (*ss->stuff)(ss, fmt - 1, 1); - if (rv < 0) { - return rv; - } - } - } - - /* Stuff trailing NUL */ - rv = (*ss->stuff)(ss, "\0", 1); - - if( nas && ( nas != nasArray ) ){ - PR_DELETE( nas ); - } - - return rv; -} - -/************************************************************************/ - -static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len) -{ - int rv; - - rv = (*ss->func)(ss->arg, sp, len); - if (rv < 0) { - return rv; - } - ss->maxlen += len; - return 0; -} - -PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, - const char *fmt, ...) -{ - va_list ap; - PRUint32 rv; - - va_start(ap, fmt); - rv = PR_vsxprintf(func, arg, fmt, ap); - va_end(ap); - return rv; -} - -PR_IMPLEMENT(PRUint32) PR_vsxprintf(PRStuffFunc func, void *arg, - const char *fmt, va_list ap) -{ - SprintfState ss; - int rv; - - ss.stuff = FuncStuff; - ss.func = func; - ss.arg = arg; - ss.maxlen = 0; - rv = dosprintf(&ss, fmt, ap); - return (rv < 0) ? (PRUint32)-1 : ss.maxlen; -} - -/* -** Stuff routine that automatically grows the malloc'd output buffer -** before it overflows. -*/ -static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len) -{ - ptrdiff_t off; - char *newbase; - PRUint32 newlen; - - off = ss->cur - ss->base; - if (off + len >= ss->maxlen) { - /* Grow the buffer */ - newlen = ss->maxlen + ((len > 32) ? len : 32); - if (ss->base) { - newbase = (char*) PR_REALLOC(ss->base, newlen); - } else { - newbase = (char*) PR_MALLOC(newlen); - } - if (!newbase) { - /* Ran out of memory */ - return -1; - } - ss->base = newbase; - ss->maxlen = newlen; - ss->cur = ss->base + off; - } - - /* Copy data */ - while (len) { - --len; - *ss->cur++ = *sp++; - } - PR_ASSERT((PRUint32)(ss->cur - ss->base) <= ss->maxlen); - return 0; -} - -/* -** sprintf into a malloc'd buffer -*/ -PR_IMPLEMENT(char *) PR_smprintf(const char *fmt, ...) -{ - va_list ap; - char *rv; - - va_start(ap, fmt); - rv = PR_vsmprintf(fmt, ap); - va_end(ap); - return rv; -} - -/* -** Free memory allocated, for the caller, by PR_smprintf -*/ -PR_IMPLEMENT(void) PR_smprintf_free(char *mem) -{ - PR_DELETE(mem); -} - -PR_IMPLEMENT(char *) PR_vsmprintf(const char *fmt, va_list ap) -{ - SprintfState ss; - int rv; - - ss.stuff = GrowStuff; - ss.base = 0; - ss.cur = 0; - ss.maxlen = 0; - rv = dosprintf(&ss, fmt, ap); - if (rv < 0) { - if (ss.base) { - PR_DELETE(ss.base); - } - return 0; - } - return ss.base; -} - -/* -** Stuff routine that discards overflow data -*/ -static int LimitStuff(SprintfState *ss, const char *sp, PRUint32 len) -{ - PRUint32 limit = ss->maxlen - (ss->cur - ss->base); - - if (len > limit) { - len = limit; - } - while (len) { - --len; - *ss->cur++ = *sp++; - } - return 0; -} - -/* -** sprintf into a fixed size buffer. Make sure there is a NUL at the end -** when finished. -*/ -PR_IMPLEMENT(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...) -{ - va_list ap; - PRUint32 rv; - - va_start(ap, fmt); - rv = PR_vsnprintf(out, outlen, fmt, ap); - va_end(ap); - return rv; -} - -PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt, - va_list ap) -{ - SprintfState ss; - PRUint32 n; - - PR_ASSERT((PRInt32)outlen > 0); - if ((PRInt32)outlen <= 0) { - return 0; - } - - ss.stuff = LimitStuff; - ss.base = out; - ss.cur = out; - ss.maxlen = outlen; - (void) dosprintf(&ss, fmt, ap); - - /* If we added chars, and we didn't append a null, do it now. */ - if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') ) - *(ss.cur - 1) = '\0'; - - n = ss.cur - ss.base; - return n ? n - 1 : n; -} - -PR_IMPLEMENT(char *) PR_sprintf_append(char *last, const char *fmt, ...) -{ - va_list ap; - char *rv; - - va_start(ap, fmt); - rv = PR_vsprintf_append(last, fmt, ap); - va_end(ap); - return rv; -} - -PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap) -{ - SprintfState ss; - int rv; - - ss.stuff = GrowStuff; - if (last) { - int lastlen = strlen(last); - ss.base = last; - ss.cur = last + lastlen; - ss.maxlen = lastlen; - } else { - ss.base = 0; - ss.cur = 0; - ss.maxlen = 0; - } - rv = dosprintf(&ss, fmt, ap); - if (rv < 0) { - if (ss.base) { - PR_DELETE(ss.base); - } - return 0; - } - return ss.base; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prscanf.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prscanf.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prscanf.c 2012-10-24 22:19:10.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prscanf.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,634 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Scan functions for NSPR types - * - * Author: Wan-Teh Chang - * - * Acknowledgment: The implementation is inspired by the source code - * in P.J. Plauger's "The Standard C Library," Prentice-Hall, 1992. - */ - -#include -#include -#include -#include -#include "prprf.h" -#include "prdtoa.h" -#include "prlog.h" -#include "prerror.h" - -/* - * A function that reads a character from 'stream'. - * Returns the character read, or EOF if end of stream is reached. - */ -typedef int (*_PRGetCharFN)(void *stream); - -/* - * A function that pushes the character 'ch' back to 'stream'. - */ -typedef void (*_PRUngetCharFN)(void *stream, int ch); - -/* - * The size specifier for the integer and floating point number - * conversions in format control strings. - */ -typedef enum { - _PR_size_none, /* No size specifier is given */ - _PR_size_h, /* The 'h' specifier, suggesting "short" */ - _PR_size_l, /* The 'l' specifier, suggesting "long" */ - _PR_size_L, /* The 'L' specifier, meaning a 'long double' */ - _PR_size_ll /* The 'll' specifier, suggesting "long long" */ -} _PRSizeSpec; - -/* - * The collection of data that is passed between the scan function - * and its subordinate functions. The fields of this structure - * serve as the input or output arguments for these functions. - */ -typedef struct { - _PRGetCharFN get; /* get a character from input stream */ - _PRUngetCharFN unget; /* unget (push back) a character */ - void *stream; /* argument for get and unget */ - va_list ap; /* the variable argument list */ - int nChar; /* number of characters read from 'stream' */ - - PRBool assign; /* assign, or suppress assignment? */ - int width; /* field width */ - _PRSizeSpec sizeSpec; /* 'h', 'l', 'L', or 'll' */ - - PRBool converted; /* is the value actually converted? */ -} ScanfState; - -#define GET(state) ((state)->nChar++, (state)->get((state)->stream)) -#define UNGET(state, ch) \ - ((state)->nChar--, (state)->unget((state)->stream, ch)) - -/* - * The following two macros, GET_IF_WITHIN_WIDTH and WITHIN_WIDTH, - * are always used together. - * - * GET_IF_WITHIN_WIDTH calls the GET macro and assigns its return - * value to 'ch' only if we have not exceeded the field width of - * 'state'. Therefore, after GET_IF_WITHIN_WIDTH, the value of - * 'ch' is valid only if the macro WITHIN_WIDTH evaluates to true. - */ - -#define GET_IF_WITHIN_WIDTH(state, ch) \ - if (--(state)->width >= 0) { \ - (ch) = GET(state); \ - } -#define WITHIN_WIDTH(state) ((state)->width >= 0) - -/* - * _pr_strtoull: - * Convert a string to an unsigned 64-bit integer. The string - * 'str' is assumed to be a representation of the integer in - * base 'base'. - * - * Warning: - * - Only handle base 8, 10, and 16. - * - No overflow checking. - */ - -static PRUint64 -_pr_strtoull(const char *str, char **endptr, int base) -{ - static const int BASE_MAX = 16; - static const char digits[] = "0123456789abcdef"; - char *digitPtr; - PRUint64 x; /* return value */ - PRInt64 base64; - const char *cPtr; - PRBool negative; - const char *digitStart; - - PR_ASSERT(base == 0 || base == 8 || base == 10 || base == 16); - if (base < 0 || base == 1 || base > BASE_MAX) { - if (endptr) { - *endptr = (char *) str; - return LL_ZERO; - } - } - - cPtr = str; - while (isspace(*cPtr)) { - ++cPtr; - } - - negative = PR_FALSE; - if (*cPtr == '-') { - negative = PR_TRUE; - cPtr++; - } else if (*cPtr == '+') { - cPtr++; - } - - if (base == 16) { - if (*cPtr == '0' && (cPtr[1] == 'x' || cPtr[1] == 'X')) { - cPtr += 2; - } - } else if (base == 0) { - if (*cPtr != '0') { - base = 10; - } else if (cPtr[1] == 'x' || cPtr[1] == 'X') { - base = 16; - cPtr += 2; - } else { - base = 8; - } - } - PR_ASSERT(base != 0); - LL_I2L(base64, base); - digitStart = cPtr; - - /* Skip leading zeros */ - while (*cPtr == '0') { - cPtr++; - } - - LL_I2L(x, 0); - while ((digitPtr = (char*)memchr(digits, tolower(*cPtr), base)) != NULL) { - PRUint64 d; - - LL_I2L(d, (digitPtr - digits)); - LL_MUL(x, x, base64); - LL_ADD(x, x, d); - cPtr++; - } - - if (cPtr == digitStart) { - if (endptr) { - *endptr = (char *) str; - } - return LL_ZERO; - } - - if (negative) { -#ifdef HAVE_LONG_LONG - /* The cast to a signed type is to avoid a compiler warning */ - x = -(PRInt64)x; -#else - LL_NEG(x, x); -#endif - } - - if (endptr) { - *endptr = (char *) cPtr; - } - return x; -} - -/* - * The maximum field width (in number of characters) that is enough - * (may be more than necessary) to represent a 64-bit integer or - * floating point number. - */ -#define FMAX 31 -#define DECIMAL_POINT '.' - -static PRStatus -GetInt(ScanfState *state, int code) -{ - char buf[FMAX + 1], *p; - int ch; - static const char digits[] = "0123456789abcdefABCDEF"; - PRBool seenDigit = PR_FALSE; - int base; - int dlen; - - switch (code) { - case 'd': case 'u': - base = 10; - break; - case 'i': - base = 0; - break; - case 'x': case 'X': case 'p': - base = 16; - break; - case 'o': - base = 8; - break; - default: - return PR_FAILURE; - } - if (state->width == 0 || state->width > FMAX) { - state->width = FMAX; - } - p = buf; - GET_IF_WITHIN_WIDTH(state, ch); - if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - } - if (WITHIN_WIDTH(state) && ch == '0') { - seenDigit = PR_TRUE; - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - if (WITHIN_WIDTH(state) - && (ch == 'x' || ch == 'X') - && (base == 0 || base == 16)) { - base = 16; - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - } else if (base == 0) { - base = 8; - } - } - if (base == 0 || base == 10) { - dlen = 10; - } else if (base == 8) { - dlen = 8; - } else { - PR_ASSERT(base == 16); - dlen = 16 + 6; /* 16 digits, plus 6 in uppercase */ - } - while (WITHIN_WIDTH(state) && memchr(digits, ch, dlen)) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - seenDigit = PR_TRUE; - } - if (WITHIN_WIDTH(state)) { - UNGET(state, ch); - } - if (!seenDigit) { - return PR_FAILURE; - } - *p = '\0'; - if (state->assign) { - if (code == 'd' || code == 'i') { - if (state->sizeSpec == _PR_size_ll) { - PRInt64 llval = _pr_strtoull(buf, NULL, base); - *va_arg(state->ap, PRInt64 *) = llval; - } else { - long lval = strtol(buf, NULL, base); - - if (state->sizeSpec == _PR_size_none) { - *va_arg(state->ap, PRIntn *) = lval; - } else if (state->sizeSpec == _PR_size_h) { - *va_arg(state->ap, PRInt16 *) = (PRInt16)lval; - } else if (state->sizeSpec == _PR_size_l) { - *va_arg(state->ap, PRInt32 *) = lval; - } else { - return PR_FAILURE; - } - } - } else { - if (state->sizeSpec == _PR_size_ll) { - PRUint64 llval = _pr_strtoull(buf, NULL, base); - *va_arg(state->ap, PRUint64 *) = llval; - } else { - unsigned long lval = strtoul(buf, NULL, base); - - if (state->sizeSpec == _PR_size_none) { - *va_arg(state->ap, PRUintn *) = lval; - } else if (state->sizeSpec == _PR_size_h) { - *va_arg(state->ap, PRUint16 *) = (PRUint16)lval; - } else if (state->sizeSpec == _PR_size_l) { - *va_arg(state->ap, PRUint32 *) = lval; - } else { - return PR_FAILURE; - } - } - } - state->converted = PR_TRUE; - } - return PR_SUCCESS; -} - -static PRStatus -GetFloat(ScanfState *state) -{ - char buf[FMAX + 1], *p; - int ch; - PRBool seenDigit = PR_FALSE; - - if (state->width == 0 || state->width > FMAX) { - state->width = FMAX; - } - p = buf; - GET_IF_WITHIN_WIDTH(state, ch); - if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - } - while (WITHIN_WIDTH(state) && isdigit(ch)) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - seenDigit = PR_TRUE; - } - if (WITHIN_WIDTH(state) && ch == DECIMAL_POINT) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - while (WITHIN_WIDTH(state) && isdigit(ch)) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - seenDigit = PR_TRUE; - } - } - - /* - * This is not robust. For example, "1.2e+" would confuse - * the code below to read 'e' and '+', only to realize that - * it should have stopped at "1.2". But we can't push back - * more than one character, so there is nothing I can do. - */ - - /* Parse exponent */ - if (WITHIN_WIDTH(state) && (ch == 'e' || ch == 'E') && seenDigit) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - } - while (WITHIN_WIDTH(state) && isdigit(ch)) { - *p++ = ch; - GET_IF_WITHIN_WIDTH(state, ch); - } - } - if (WITHIN_WIDTH(state)) { - UNGET(state, ch); - } - if (!seenDigit) { - return PR_FAILURE; - } - *p = '\0'; - if (state->assign) { - PRFloat64 dval = PR_strtod(buf, NULL); - - state->converted = PR_TRUE; - if (state->sizeSpec == _PR_size_l) { - *va_arg(state->ap, PRFloat64 *) = dval; - } else if (state->sizeSpec == _PR_size_L) { -#if defined(OSF1) || defined(IRIX) - *va_arg(state->ap, double *) = dval; -#else - *va_arg(state->ap, long double *) = dval; -#endif - } else { - *va_arg(state->ap, float *) = (float) dval; - } - } - return PR_SUCCESS; -} - -/* - * Convert, and return the end of the conversion spec. - * Return NULL on error. - */ - -static const char * -Convert(ScanfState *state, const char *fmt) -{ - const char *cPtr; - int ch; - char *cArg = NULL; - - state->converted = PR_FALSE; - cPtr = fmt; - if (*cPtr != 'c' && *cPtr != 'n' && *cPtr != '[') { - do { - ch = GET(state); - } while (isspace(ch)); - UNGET(state, ch); - } - switch (*cPtr) { - case 'c': - if (state->assign) { - cArg = va_arg(state->ap, char *); - } - if (state->width == 0) { - state->width = 1; - } - for (; state->width > 0; state->width--) { - ch = GET(state); - if (ch == EOF) { - return NULL; - } else if (state->assign) { - *cArg++ = ch; - } - } - if (state->assign) { - state->converted = PR_TRUE; - } - break; - case 'p': - case 'd': case 'i': case 'o': - case 'u': case 'x': case 'X': - if (GetInt(state, *cPtr) == PR_FAILURE) { - return NULL; - } - break; - case 'e': case 'E': case 'f': - case 'g': case 'G': - if (GetFloat(state) == PR_FAILURE) { - return NULL; - } - break; - case 'n': - /* do not consume any input */ - if (state->assign) { - switch (state->sizeSpec) { - case _PR_size_none: - *va_arg(state->ap, PRIntn *) = state->nChar; - break; - case _PR_size_h: - *va_arg(state->ap, PRInt16 *) = state->nChar; - break; - case _PR_size_l: - *va_arg(state->ap, PRInt32 *) = state->nChar; - break; - case _PR_size_ll: - LL_I2L(*va_arg(state->ap, PRInt64 *), state->nChar); - break; - default: - PR_ASSERT(0); - } - } - break; - case 's': - if (state->width == 0) { - state->width = INT_MAX; - } - if (state->assign) { - cArg = va_arg(state->ap, char *); - } - for (; state->width > 0; state->width--) { - ch = GET(state); - if ((ch == EOF) || isspace(ch)) { - UNGET(state, ch); - break; - } - if (state->assign) { - *cArg++ = ch; - } - } - if (state->assign) { - *cArg = '\0'; - state->converted = PR_TRUE; - } - break; - case '%': - ch = GET(state); - if (ch != '%') { - UNGET(state, ch); - return NULL; - } - break; - case '[': - { - PRBool complement = PR_FALSE; - const char *closeBracket; - size_t n; - - if (*++cPtr == '^') { - complement = PR_TRUE; - cPtr++; - } - closeBracket = strchr(*cPtr == ']' ? cPtr + 1 : cPtr, ']'); - if (closeBracket == NULL) { - return NULL; - } - n = closeBracket - cPtr; - if (state->width == 0) { - state->width = INT_MAX; - } - if (state->assign) { - cArg = va_arg(state->ap, char *); - } - for (; state->width > 0; state->width--) { - ch = GET(state); - if ((ch == EOF) - || (!complement && !memchr(cPtr, ch, n)) - || (complement && memchr(cPtr, ch, n))) { - UNGET(state, ch); - break; - } - if (state->assign) { - *cArg++ = ch; - } - } - if (state->assign) { - *cArg = '\0'; - state->converted = PR_TRUE; - } - cPtr = closeBracket; - } - break; - default: - return NULL; - } - return cPtr; -} - -static PRInt32 -DoScanf(ScanfState *state, const char *fmt) -{ - PRInt32 nConverted = 0; - const char *cPtr; - int ch; - - state->nChar = 0; - cPtr = fmt; - while (1) { - if (isspace(*cPtr)) { - /* white space: skip */ - do { - cPtr++; - } while (isspace(*cPtr)); - do { - ch = GET(state); - } while (isspace(ch)); - UNGET(state, ch); - } else if (*cPtr == '%') { - /* format spec: convert */ - cPtr++; - state->assign = PR_TRUE; - if (*cPtr == '*') { - cPtr++; - state->assign = PR_FALSE; - } - for (state->width = 0; isdigit(*cPtr); cPtr++) { - state->width = state->width * 10 + *cPtr - '0'; - } - state->sizeSpec = _PR_size_none; - if (*cPtr == 'h') { - cPtr++; - state->sizeSpec = _PR_size_h; - } else if (*cPtr == 'l') { - cPtr++; - if (*cPtr == 'l') { - cPtr++; - state->sizeSpec = _PR_size_ll; - } else { - state->sizeSpec = _PR_size_l; - } - } else if (*cPtr == 'L') { - cPtr++; - state->sizeSpec = _PR_size_L; - } - cPtr = Convert(state, cPtr); - if (cPtr == NULL) { - return (nConverted > 0 ? nConverted : EOF); - } - if (state->converted) { - nConverted++; - } - cPtr++; - } else { - /* others: must match */ - if (*cPtr == '\0') { - return nConverted; - } - ch = GET(state); - if (ch != *cPtr) { - UNGET(state, ch); - return nConverted; - } - cPtr++; - } - } -} - -static int -StringGetChar(void *stream) -{ - char *cPtr = *((char **) stream); - - if (*cPtr == '\0') { - return EOF; - } else { - *((char **) stream) = cPtr + 1; - return (unsigned char) *cPtr; - } -} - -static void -StringUngetChar(void *stream, int ch) -{ - char *cPtr = *((char **) stream); - - if (ch != EOF) { - *((char **) stream) = cPtr - 1; - } -} - -PR_IMPLEMENT(PRInt32) -PR_sscanf(const char *buf, const char *fmt, ...) -{ - PRInt32 rv; - ScanfState state; - - state.get = &StringGetChar; - state.unget = &StringUngetChar; - state.stream = (void *) &buf; - va_start(state.ap, fmt); - rv = DoScanf(&state, fmt); - va_end(state.ap); - return rv; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prsocket.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prsocket.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prsocket.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prsocket.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1802 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -/************************************************************************/ - -/* These two functions are only used in assertions. */ -#if defined(DEBUG) - -PRBool IsValidNetAddr(const PRNetAddr *addr) -{ - if ((addr != NULL) -#if defined(XP_UNIX) || defined(XP_OS2) - && (addr->raw.family != PR_AF_LOCAL) -#endif - && (addr->raw.family != PR_AF_INET6) - && (addr->raw.family != PR_AF_INET)) { - return PR_FALSE; - } - return PR_TRUE; -} - -static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len) -{ - /* - * The definition of the length of a Unix domain socket address - * is not uniform, so we don't check it. - */ - if ((addr != NULL) -#if defined(XP_UNIX) || defined(XP_OS2) - && (addr->raw.family != AF_UNIX) -#endif - && (PR_NETADDR_SIZE(addr) != addr_len)) { -#if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1 - /* - * In glibc 2.1, struct sockaddr_in6 is 24 bytes. In glibc 2.2 - * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id - * field and is 28 bytes. It is possible for socket functions - * to return an addr_len greater than sizeof(struct sockaddr_in6). - * We need to allow that. (Bugzilla bug #77264) - */ - if ((PR_AF_INET6 == addr->raw.family) - && (sizeof(addr->ipv6) == addr_len)) { - return PR_TRUE; - } -#endif - /* - * The accept(), getsockname(), etc. calls on some platforms - * do not set the actual socket address length on return. - * In this case, we verifiy addr_len is still the value we - * passed in (i.e., sizeof(PRNetAddr)). - */ -#if defined(QNX) - if (sizeof(PRNetAddr) == addr_len) { - return PR_TRUE; - } -#endif - return PR_FALSE; - } - return PR_TRUE; -} - -#endif /* DEBUG */ - -static PRInt32 PR_CALLBACK SocketWritev(PRFileDesc *fd, const PRIOVec *iov, -PRInt32 iov_size, PRIntervalTime timeout) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - int w = 0; - const PRIOVec *tmp_iov; -#define LOCAL_MAXIOV 8 - PRIOVec local_iov[LOCAL_MAXIOV]; - PRIOVec *iov_copy = NULL; - int tmp_out; - int index, iov_cnt; - int count=0, sz = 0; /* 'count' is the return value. */ - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - - /* - * Assume the first writev will succeed. Copy iov's only on - * failure. - */ - tmp_iov = iov; - for (index = 0; index < iov_size; index++) - sz += iov[index].iov_len; - - iov_cnt = iov_size; - - while (sz > 0) { - - w = _PR_MD_WRITEV(fd, tmp_iov, iov_cnt, timeout); - if (w < 0) { - count = -1; - break; - } - count += w; - if (fd->secret->nonblocking) { - break; - } - sz -= w; - - if (sz > 0) { - /* find the next unwritten vector */ - for ( index = 0, tmp_out = count; - tmp_out >= iov[index].iov_len; - tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */ - - if (tmp_iov == iov) { - /* - * The first writev failed so we - * must copy iov's around. - * Avoid calloc/free if there - * are few enough iov's. - */ - if (iov_size - index <= LOCAL_MAXIOV) - iov_copy = local_iov; - else if ((iov_copy = (PRIOVec *) PR_CALLOC((iov_size - index) * - sizeof *iov_copy)) == NULL) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - tmp_iov = iov_copy; - } - - PR_ASSERT(tmp_iov == iov_copy); - - /* fill in the first partial read */ - iov_copy[0].iov_base = &(((char *)iov[index].iov_base)[tmp_out]); - iov_copy[0].iov_len = iov[index].iov_len - tmp_out; - index++; - - /* copy the remaining vectors */ - for (iov_cnt=1; indexsecret->af = AF_INET; -#endif - } else - _PR_MD_CLOSE_SOCKET(osfd); - return(fd); -} - -PR_IMPLEMENT(PRFileDesc *) PR_ImportUDPSocket(PROsfd osfd) -{ -PRFileDesc *fd; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods()); - if (fd != NULL) { - _PR_MD_MAKE_NONBLOCK(fd); - _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); - } else - _PR_MD_CLOSE_SOCKET(osfd); - return(fd); -} - - -static const PRIOMethods* PR_GetSocketPollFdMethods(void); - -PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PROsfd osfd) -{ - PRFileDesc *fd; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - fd = _PR_Getfd(); - - if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - else - { - fd->secret->md.osfd = osfd; - fd->secret->inheritable = _PR_TRI_FALSE; - fd->secret->state = _PR_FILEDESC_OPEN; - fd->methods = PR_GetSocketPollFdMethods(); - } - - return fd; -} /* PR_CreateSocketPollFD */ - -PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd) -{ - if (NULL == fd) - { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - return PR_FAILURE; - } - fd->secret->state = _PR_FILEDESC_CLOSED; - _PR_Putfd(fd); - return PR_SUCCESS; -} /* PR_DestroySocketPollFd */ - -static PRStatus PR_CALLBACK SocketConnect( - PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) -{ - PRInt32 rv; /* Return value of _PR_MD_CONNECT */ - const PRNetAddr *addrp = addr; -#if defined(_PR_INET6) - PRNetAddr addrCopy; -#endif - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return PR_FAILURE; - } -#if defined(_PR_INET6) - if (addr->raw.family == PR_AF_INET6) { - addrCopy = *addr; - addrCopy.raw.family = AF_INET6; - addrp = &addrCopy; - } -#endif - - rv = _PR_MD_CONNECT(fd, addrp, PR_NETADDR_SIZE(addr), timeout); - PR_LOG(_pr_io_lm, PR_LOG_MAX, ("connect -> %d", rv)); - if (rv == 0) - return PR_SUCCESS; - else - return PR_FAILURE; -} - -static PRStatus PR_CALLBACK SocketConnectContinue( - PRFileDesc *fd, PRInt16 out_flags) -{ - PROsfd osfd; - int err; - - if (out_flags & PR_POLL_NVAL) { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - return PR_FAILURE; - } - if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) { - PR_ASSERT(out_flags == 0); - PR_SetError(PR_IN_PROGRESS_ERROR, 0); - return PR_FAILURE; - } - - osfd = fd->secret->md.osfd; - -#if defined(XP_UNIX) - - err = _MD_unix_get_nonblocking_connect_error(osfd); - if (err != 0) { - _PR_MD_MAP_CONNECT_ERROR(err); - return PR_FAILURE; - } - return PR_SUCCESS; - -#elif defined(WIN32) || defined(WIN16) - -#if defined(WIN32) - /* - * The sleep circumvents a bug in Win32 WinSock. - * See Microsoft Knowledge Base article ID: Q165989. - */ - Sleep(0); -#endif /* WIN32 */ - - if (out_flags & PR_POLL_EXCEPT) { - int len = sizeof(err); - if (getsockopt(osfd, (int)SOL_SOCKET, SO_ERROR, (char *) &err, &len) - == SOCKET_ERROR) { - _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); - return PR_FAILURE; - } - if (err != 0) { - _PR_MD_MAP_CONNECT_ERROR(err); - } else { - PR_SetError(PR_UNKNOWN_ERROR, 0); - } - return PR_FAILURE; - } - - PR_ASSERT(out_flags & PR_POLL_WRITE); - return PR_SUCCESS; - -#elif defined(XP_OS2) - - err = _MD_os2_get_nonblocking_connect_error(osfd); - if (err != 0) { - _PR_MD_MAP_CONNECT_ERROR(err); - return PR_FAILURE; - } - return PR_SUCCESS; - -#elif defined(XP_BEOS) - -#ifdef BONE_VERSION /* bug 122364 */ - /* temporary workaround until getsockopt(SO_ERROR) works in BONE */ - if (out_flags & PR_POLL_EXCEPT) { - PR_SetError(PR_CONNECT_REFUSED_ERROR, 0); - return PR_FAILURE; - } - PR_ASSERT(out_flags & PR_POLL_WRITE); - return PR_SUCCESS; -#else - err = _MD_beos_get_nonblocking_connect_error(fd); - if( err != 0 ) { - _PR_MD_MAP_CONNECT_ERROR(err); - return PR_FAILURE; - } - else - return PR_SUCCESS; -#endif /* BONE_VERSION */ - -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -#endif -} - -PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd) -{ - /* Find the NSPR layer and invoke its connectcontinue method */ - PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - - if (NULL == bottom) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - return SocketConnectContinue(bottom, pd->out_flags); -} - -static PRFileDesc* PR_CALLBACK SocketAccept(PRFileDesc *fd, PRNetAddr *addr, -PRIntervalTime timeout) -{ - PROsfd osfd; - PRFileDesc *fd2; - PRUint32 al; - PRThread *me = _PR_MD_CURRENT_THREAD(); -#ifdef WINNT - PRNetAddr addrCopy; -#endif - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return 0; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return 0; - } - -#ifdef WINNT - if (addr == NULL) { - addr = &addrCopy; - } -#endif - al = sizeof(PRNetAddr); - osfd = _PR_MD_ACCEPT(fd, addr, &al, timeout); - if (osfd == -1) - return 0; - - fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods()); - if (!fd2) { - _PR_MD_CLOSE_SOCKET(osfd); - return NULL; - } - - fd2->secret->nonblocking = fd->secret->nonblocking; - fd2->secret->inheritable = fd->secret->inheritable; -#ifdef WINNT - if (!fd2->secret->nonblocking && fd2->secret->inheritable != _PR_TRI_TRUE) { - /* - * The new socket has been associated with an I/O - * completion port. There is no going back. - */ - fd2->secret->md.io_model_committed = PR_TRUE; - } - PR_ASSERT(al == PR_NETADDR_SIZE(addr)); - fd2->secret->md.accepted_socket = PR_TRUE; - memcpy(&fd2->secret->md.peer_addr, addr, al); -#endif - - /* - * On some platforms, the new socket created by accept() - * inherits the nonblocking (or overlapped io) attribute - * of the listening socket. As an optimization, these - * platforms can skip the following _PR_MD_MAKE_NONBLOCK - * call. - */ -#if !defined(SOLARIS) && !defined(IRIX) && !defined(WINNT) - _PR_MD_MAKE_NONBLOCK(fd2); -#endif - -#ifdef _PR_INET6 - if (addr && (AF_INET6 == addr->raw.family)) - addr->raw.family = PR_AF_INET6; -#endif - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE); - - return fd2; -} - -#ifdef WINNT -PR_IMPLEMENT(PRFileDesc*) PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr, -PRIntervalTime timeout) -{ - PROsfd osfd; - PRFileDesc *fd2; - PRIntn al; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRNetAddr addrCopy; - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return 0; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return 0; - } - - if (addr == NULL) { - addr = &addrCopy; - } - al = PR_NETADDR_SIZE(addr); - osfd = _PR_MD_FAST_ACCEPT(fd, addr, &al, timeout, PR_TRUE, NULL, NULL); - if (osfd == -1) { - return 0; - } - - fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods()); - if (!fd2) { - _PR_MD_CLOSE_SOCKET(osfd); - } else { - fd2->secret->nonblocking = fd->secret->nonblocking; - fd2->secret->md.io_model_committed = PR_TRUE; - PR_ASSERT(al == PR_NETADDR_SIZE(addr)); - fd2->secret->md.accepted_socket = PR_TRUE; - memcpy(&fd2->secret->md.peer_addr, addr, al); -#ifdef _PR_INET6 - if (AF_INET6 == addr->raw.family) - addr->raw.family = PR_AF_INET6; -#endif -#ifdef _PR_NEED_SECRET_AF - fd2->secret->af = fd->secret->af; -#endif - } - return fd2; -} -#endif /* WINNT */ - - -static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr) -{ - PRInt32 result; - const PRNetAddr *addrp = addr; -#if defined(_PR_INET6) - PRNetAddr addrCopy; -#endif - - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - -#ifdef XP_UNIX - if (addr->raw.family == AF_UNIX) { - /* Disallow relative pathnames */ - if (addr->local.path[0] != '/') { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - } -#endif /* XP_UNIX */ - -#if defined(_PR_INET6) - if (addr->raw.family == PR_AF_INET6) { - addrCopy = *addr; - addrCopy.raw.family = AF_INET6; - addrp = &addrCopy; - } -#endif - result = _PR_MD_BIND(fd, addrp, PR_NETADDR_SIZE(addr)); - if (result < 0) { - return PR_FAILURE; - } - return PR_SUCCESS; -} - -static PRStatus PR_CALLBACK SocketListen(PRFileDesc *fd, PRIntn backlog) -{ - PRInt32 result; - - result = _PR_MD_LISTEN(fd, backlog); - if (result < 0) { - return PR_FAILURE; - } - return PR_SUCCESS; -} - -static PRStatus PR_CALLBACK SocketShutdown(PRFileDesc *fd, PRIntn how) -{ - PRInt32 result; - - result = _PR_MD_SHUTDOWN(fd, how); - if (result < 0) { - return PR_FAILURE; - } - return PR_SUCCESS; -} - -static PRInt32 PR_CALLBACK SocketRecv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, -PRIntervalTime timeout) -{ - PRInt32 rv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if ((flags != 0) && (flags != PR_MSG_PEEK)) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - - PR_LOG(_pr_io_lm, PR_LOG_MAX, - ("recv: fd=%p osfd=%" PR_PRIdOSFD " buf=%p amount=%d flags=%d", - fd, fd->secret->md.osfd, buf, amount, flags)); - -#ifdef _PR_HAVE_PEEK_BUFFER - if (fd->secret->peekBytes != 0) { - rv = (amount < fd->secret->peekBytes) ? - amount : fd->secret->peekBytes; - memcpy(buf, fd->secret->peekBuffer, rv); - if (flags == 0) { - /* consume the bytes in the peek buffer */ - fd->secret->peekBytes -= rv; - if (fd->secret->peekBytes != 0) { - memmove(fd->secret->peekBuffer, - fd->secret->peekBuffer + rv, - fd->secret->peekBytes); - } - } - return rv; - } - - /* allocate peek buffer, if necessary */ - if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) { - PR_ASSERT(0 == fd->secret->peekBytes); - /* impose a max size on the peek buffer */ - if (amount > _PR_PEEK_BUFFER_MAX) { - amount = _PR_PEEK_BUFFER_MAX; - } - if (fd->secret->peekBufSize < amount) { - if (fd->secret->peekBuffer) { - PR_Free(fd->secret->peekBuffer); - } - fd->secret->peekBufSize = amount; - fd->secret->peekBuffer = PR_Malloc(amount); - if (NULL == fd->secret->peekBuffer) { - fd->secret->peekBufSize = 0; - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - } - } -#endif - - rv = _PR_MD_RECV(fd, buf, amount, flags, timeout); - PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv -> %d, error = %d, os error = %d", - rv, PR_GetError(), PR_GetOSError())); - -#ifdef _PR_HAVE_PEEK_BUFFER - if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) { - if (rv > 0) { - memcpy(fd->secret->peekBuffer, buf, rv); - fd->secret->peekBytes = rv; - } - } -#endif - - return rv; -} - -static PRInt32 PR_CALLBACK SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount) -{ - return SocketRecv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); -} - -static PRInt32 PR_CALLBACK SocketSend(PRFileDesc *fd, const void *buf, PRInt32 amount, -PRIntn flags, PRIntervalTime timeout) -{ - PRInt32 temp, count; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - - count = 0; - while (amount > 0) { - PR_LOG(_pr_io_lm, PR_LOG_MAX, - ("send: fd=%p osfd=%" PR_PRIdOSFD " buf=%p amount=%d", - fd, fd->secret->md.osfd, buf, amount)); - temp = _PR_MD_SEND(fd, buf, amount, flags, timeout); - if (temp < 0) { - count = -1; - break; - } - - count += temp; - if (fd->secret->nonblocking) { - break; - } - buf = (const void*) ((const char*)buf + temp); - - amount -= temp; - } - PR_LOG(_pr_io_lm, PR_LOG_MAX, ("send -> %d", count)); - return count; -} - -static PRInt32 PR_CALLBACK SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount) -{ - return SocketSend(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); -} - -static PRStatus PR_CALLBACK SocketClose(PRFileDesc *fd) -{ - if (!fd || !fd->secret - || (fd->secret->state != _PR_FILEDESC_OPEN - && fd->secret->state != _PR_FILEDESC_CLOSED)) { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - return PR_FAILURE; - } - - if (fd->secret->state == _PR_FILEDESC_OPEN) { - if (_PR_MD_CLOSE_SOCKET(fd->secret->md.osfd) < 0) { - return PR_FAILURE; - } - fd->secret->state = _PR_FILEDESC_CLOSED; - } - -#ifdef _PR_HAVE_PEEK_BUFFER - if (fd->secret->peekBuffer) { - PR_ASSERT(fd->secret->peekBufSize > 0); - PR_DELETE(fd->secret->peekBuffer); - fd->secret->peekBufSize = 0; - fd->secret->peekBytes = 0; - } -#endif - - PR_FreeFileDesc(fd); - return PR_SUCCESS; -} - -static PRInt32 PR_CALLBACK SocketAvailable(PRFileDesc *fd) -{ - PRInt32 rv; -#ifdef _PR_HAVE_PEEK_BUFFER - if (fd->secret->peekBytes != 0) { - return fd->secret->peekBytes; - } -#endif - rv = _PR_MD_SOCKETAVAILABLE(fd); - return rv; -} - -static PRInt64 PR_CALLBACK SocketAvailable64(PRFileDesc *fd) -{ - PRInt64 rv; -#ifdef _PR_HAVE_PEEK_BUFFER - if (fd->secret->peekBytes != 0) { - LL_I2L(rv, fd->secret->peekBytes); - return rv; - } -#endif - LL_I2L(rv, _PR_MD_SOCKETAVAILABLE(fd)); - return rv; -} - -static PRStatus PR_CALLBACK SocketSync(PRFileDesc *fd) -{ - return PR_SUCCESS; -} - -static PRInt32 PR_CALLBACK SocketSendTo( - PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout) -{ - PRInt32 temp, count; - const PRNetAddr *addrp = addr; -#if defined(_PR_INET6) - PRNetAddr addrCopy; -#endif - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); -#if defined(_PR_INET6) - if (addr->raw.family == PR_AF_INET6) { - addrCopy = *addr; - addrCopy.raw.family = AF_INET6; - addrp = &addrCopy; - } -#endif - - count = 0; - while (amount > 0) { - temp = _PR_MD_SENDTO(fd, buf, amount, flags, - addrp, PR_NETADDR_SIZE(addr), timeout); - if (temp < 0) { - count = -1; - break; - } - count += temp; - if (fd->secret->nonblocking) { - break; - } - buf = (const void*) ((const char*)buf + temp); - amount -= temp; - } - return count; -} - -static PRInt32 PR_CALLBACK SocketRecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, -PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) -{ - PRInt32 rv; - PRUint32 al; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - - al = sizeof(PRNetAddr); - rv = _PR_MD_RECVFROM(fd, buf, amount, flags, addr, &al, timeout); -#ifdef _PR_INET6 - if (addr && (AF_INET6 == addr->raw.family)) - addr->raw.family = PR_AF_INET6; -#endif - return rv; -} - -static PRInt32 PR_CALLBACK SocketAcceptRead(PRFileDesc *sd, PRFileDesc **nd, -PRNetAddr **raddr, void *buf, PRInt32 amount, -PRIntervalTime timeout) -{ - PRInt32 rv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - /* The socket must be in blocking mode. */ - if (sd->secret->nonblocking) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - *nd = NULL; - -#if defined(WINNT) - { - PROsfd newSock; - PRNetAddr *raddrCopy; - - if (raddr == NULL) { - raddr = &raddrCopy; - } - rv = _PR_MD_ACCEPT_READ(sd, &newSock, raddr, buf, amount, timeout); - if (rv < 0) { - rv = -1; - } else { - /* Successfully accepted and read; create the new PRFileDesc */ - *nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods()); - if (*nd == 0) { - _PR_MD_CLOSE_SOCKET(newSock); - /* PR_AllocFileDesc() has invoked PR_SetError(). */ - rv = -1; - } else { - (*nd)->secret->md.io_model_committed = PR_TRUE; - (*nd)->secret->md.accepted_socket = PR_TRUE; - memcpy(&(*nd)->secret->md.peer_addr, *raddr, - PR_NETADDR_SIZE(*raddr)); -#ifdef _PR_INET6 - if (AF_INET6 == *raddr->raw.family) - *raddr->raw.family = PR_AF_INET6; -#endif - } - } - } -#else - rv = PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout); -#endif - return rv; -} - -#ifdef WINNT -PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, -PRNetAddr **raddr, void *buf, PRInt32 amount, -PRIntervalTime timeout) -{ - PRInt32 rv; - PROsfd newSock; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRNetAddr *raddrCopy; - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - *nd = NULL; - - if (raddr == NULL) { - raddr = &raddrCopy; - } - rv = _PR_MD_FAST_ACCEPT_READ(sd, &newSock, raddr, buf, amount, - timeout, PR_TRUE, NULL, NULL); - if (rv < 0) { - rv = -1; - } else { - /* Successfully accepted and read; create the new PRFileDesc */ - *nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods()); - if (*nd == 0) { - _PR_MD_CLOSE_SOCKET(newSock); - /* PR_AllocFileDesc() has invoked PR_SetError(). */ - rv = -1; - } else { - (*nd)->secret->md.io_model_committed = PR_TRUE; - (*nd)->secret->md.accepted_socket = PR_TRUE; - memcpy(&(*nd)->secret->md.peer_addr, *raddr, - PR_NETADDR_SIZE(*raddr)); -#ifdef _PR_INET6 - if (AF_INET6 == *raddr->raw.family) - *raddr->raw.family = PR_AF_INET6; -#endif -#ifdef _PR_NEED_SECRET_AF - (*nd)->secret->af = sd->secret->af; -#endif - } - } - return rv; -} - -PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback( -PRFileDesc *sd, PRFileDesc **nd, -PRNetAddr **raddr, void *buf, PRInt32 amount, -PRIntervalTime timeout, -_PR_AcceptTimeoutCallback callback, -void *callbackArg) -{ - PRInt32 rv; - PROsfd newSock; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRNetAddr *raddrCopy; - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - *nd = NULL; - - if (raddr == NULL) { - raddr = &raddrCopy; - } - rv = _PR_MD_FAST_ACCEPT_READ(sd, &newSock, raddr, buf, amount, - timeout, PR_TRUE, callback, callbackArg); - if (rv < 0) { - rv = -1; - } else { - /* Successfully accepted and read; create the new PRFileDesc */ - *nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods()); - if (*nd == 0) { - _PR_MD_CLOSE_SOCKET(newSock); - /* PR_AllocFileDesc() has invoked PR_SetError(). */ - rv = -1; - } else { - (*nd)->secret->md.io_model_committed = PR_TRUE; - (*nd)->secret->md.accepted_socket = PR_TRUE; - memcpy(&(*nd)->secret->md.peer_addr, *raddr, - PR_NETADDR_SIZE(*raddr)); -#ifdef _PR_INET6 - if (AF_INET6 == *raddr->raw.family) - *raddr->raw.family = PR_AF_INET6; -#endif -#ifdef _PR_NEED_SECRET_AF - (*nd)->secret->af = sd->secret->af; -#endif - } - } - return rv; -} -#endif /* WINNT */ - -#ifdef WINNT -PR_IMPLEMENT(void) -PR_NTFast_UpdateAcceptContext(PRFileDesc *socket, PRFileDesc *acceptSocket) -{ - _PR_MD_UPDATE_ACCEPT_CONTEXT( - socket->secret->md.osfd, acceptSocket->secret->md.osfd); -} -#endif /* WINNT */ - -static PRInt32 PR_CALLBACK SocketSendFile( - PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - PRInt32 rv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (_PR_IO_PENDING(me)) { - PR_SetError(PR_IO_PENDING_ERROR, 0); - return -1; - } - /* The socket must be in blocking mode. */ - if (sd->secret->nonblocking) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } -#if defined(WINNT) - rv = _PR_MD_SENDFILE(sd, sfd, flags, timeout); - if ((rv >= 0) && (flags == PR_TRANSMITFILE_CLOSE_SOCKET)) { - /* - * This should be kept the same as SocketClose, except - * that _PR_MD_CLOSE_SOCKET(sd->secret->md.osfd) should - * not be called because the socket will be recycled. - */ - PR_FreeFileDesc(sd); - } -#else - rv = PR_EmulateSendFile(sd, sfd, flags, timeout); -#endif /* WINNT */ - - return rv; -} - -static PRInt32 PR_CALLBACK SocketTransmitFile(PRFileDesc *sd, PRFileDesc *fd, -const void *headers, PRInt32 hlen, PRTransmitFileFlags flags, -PRIntervalTime timeout) -{ - PRSendFileData sfd; - - sfd.fd = fd; - sfd.file_offset = 0; - sfd.file_nbytes = 0; - sfd.header = headers; - sfd.hlen = hlen; - sfd.trailer = NULL; - sfd.tlen = 0; - - return(SocketSendFile(sd, &sfd, flags, timeout)); -} - -static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr) -{ - PRInt32 result; - PRUint32 addrlen; - - addrlen = sizeof(PRNetAddr); - result = _PR_MD_GETSOCKNAME(fd, addr, &addrlen); - if (result < 0) { - return PR_FAILURE; - } -#ifdef _PR_INET6 - if (AF_INET6 == addr->raw.family) - addr->raw.family = PR_AF_INET6; -#endif - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE); - return PR_SUCCESS; -} - -static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr) -{ - PRInt32 result; - PRUint32 addrlen; - - addrlen = sizeof(PRNetAddr); - result = _PR_MD_GETPEERNAME(fd, addr, &addrlen); - if (result < 0) { - return PR_FAILURE; - } -#ifdef _PR_INET6 - if (AF_INET6 == addr->raw.family) - addr->raw.family = PR_AF_INET6; -#endif - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE); - return PR_SUCCESS; -} - -static PRInt16 PR_CALLBACK SocketPoll( - PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) -{ - *out_flags = 0; - return in_flags; -} /* SocketPoll */ - -static PRIOMethods tcpMethods = { - PR_DESC_SOCKET_TCP, - SocketClose, - SocketRead, - SocketWrite, - SocketAvailable, - SocketAvailable64, - SocketSync, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - SocketWritev, - SocketConnect, - SocketAccept, - SocketBind, - SocketListen, - SocketShutdown, - SocketRecv, - SocketSend, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - SocketPoll, - SocketAcceptRead, - SocketTransmitFile, - SocketGetName, - SocketGetPeerName, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - _PR_SocketGetSocketOption, - _PR_SocketSetSocketOption, - SocketSendFile, - SocketConnectContinue, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -static PRIOMethods udpMethods = { - PR_DESC_SOCKET_UDP, - SocketClose, - SocketRead, - SocketWrite, - SocketAvailable, - SocketAvailable64, - SocketSync, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - SocketWritev, - SocketConnect, - (PRAcceptFN)_PR_InvalidDesc, - SocketBind, - SocketListen, - SocketShutdown, - SocketRecv, - SocketSend, - SocketRecvFrom, - SocketSendTo, - SocketPoll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - SocketGetName, - SocketGetPeerName, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - _PR_SocketGetSocketOption, - _PR_SocketSetSocketOption, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - - -static PRIOMethods socketpollfdMethods = { - (PRDescType) 0, - (PRCloseFN)_PR_InvalidStatus, - (PRReadFN)_PR_InvalidInt, - (PRWriteFN)_PR_InvalidInt, - (PRAvailableFN)_PR_InvalidInt, - (PRAvailable64FN)_PR_InvalidInt64, - (PRFsyncFN)_PR_InvalidStatus, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - (PRWritevFN)_PR_InvalidInt, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt, - (PRSendFN)_PR_InvalidInt, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - SocketPoll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - (PRGetsocknameFN)_PR_InvalidStatus, - (PRGetpeernameFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods() -{ - return &tcpMethods; -} - -PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods() -{ - return &udpMethods; -} - -static const PRIOMethods* PR_GetSocketPollFdMethods() -{ - return &socketpollfdMethods; -} /* PR_GetSocketPollFdMethods */ - -#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE) -PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd); - -#if defined(_PR_INET6_PROBE) - -extern PRBool _pr_ipv6_is_present(void); - -PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket() -{ - PROsfd osfd; - - osfd = _PR_MD_SOCKET(AF_INET6, SOCK_STREAM, 0); - if (osfd != -1) { - _PR_MD_CLOSE_SOCKET(osfd); - return PR_TRUE; - } - return PR_FALSE; -} -#endif /* _PR_INET6_PROBE */ - -#endif - -PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto) -{ - PROsfd osfd; - PRFileDesc *fd; - PRInt32 tmp_domain = domain; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - if (PR_AF_INET != domain - && PR_AF_INET6 != domain -#if defined(XP_UNIX) || defined(XP_OS2) - && PR_AF_LOCAL != domain -#endif - ) { - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return NULL; - } - -#if defined(_PR_INET6_PROBE) - if (PR_AF_INET6 == domain) - domain = _pr_ipv6_is_present() ? AF_INET6 : AF_INET; -#elif defined(_PR_INET6) - if (PR_AF_INET6 == domain) - domain = AF_INET6; -#else - if (PR_AF_INET6 == domain) - domain = AF_INET; -#endif /* _PR_INET6 */ - osfd = _PR_MD_SOCKET(domain, type, proto); - if (osfd == -1) { - return 0; - } - if (type == SOCK_STREAM) - fd = PR_AllocFileDesc(osfd, PR_GetTCPMethods()); - else - fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods()); - /* - * Make the sockets non-blocking - */ - if (fd != NULL) { - _PR_MD_MAKE_NONBLOCK(fd); - _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); -#ifdef _PR_NEED_SECRET_AF - fd->secret->af = domain; -#endif -#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6) - /* - * For platforms with no support for IPv6 - * create layered socket for IPv4-mapped IPv6 addresses - */ - if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) { - if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) { - PR_Close(fd); - fd = NULL; - } - } -#endif - } else - _PR_MD_CLOSE_SOCKET(osfd); - - return fd; -} - -PR_IMPLEMENT(PRFileDesc *) PR_NewTCPSocket(void) -{ - PRInt32 domain = AF_INET; - - return PR_Socket(domain, SOCK_STREAM, 0); -} - -PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void) -{ - PRInt32 domain = AF_INET; - - return PR_Socket(domain, SOCK_DGRAM, 0); -} - -PR_IMPLEMENT(PRFileDesc *) PR_OpenTCPSocket(PRIntn af) -{ - return PR_Socket(af, SOCK_STREAM, 0); -} - -PR_IMPLEMENT(PRFileDesc*) PR_OpenUDPSocket(PRIntn af) -{ - return PR_Socket(af, SOCK_DGRAM, 0); -} - -PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[]) -{ -#ifdef XP_UNIX - PRInt32 rv, osfd[2]; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - rv = _PR_MD_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, osfd); - if (rv == -1) { - return PR_FAILURE; - } - - f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods()); - if (!f[0]) { - _PR_MD_CLOSE_SOCKET(osfd[0]); - _PR_MD_CLOSE_SOCKET(osfd[1]); - /* PR_AllocFileDesc() has invoked PR_SetError(). */ - return PR_FAILURE; - } - f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods()); - if (!f[1]) { - PR_Close(f[0]); - _PR_MD_CLOSE_SOCKET(osfd[1]); - /* PR_AllocFileDesc() has invoked PR_SetError(). */ - return PR_FAILURE; - } - _PR_MD_MAKE_NONBLOCK(f[0]); - _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE); - _PR_MD_MAKE_NONBLOCK(f[1]); - _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE); - return PR_SUCCESS; -#elif defined(WINNT) - /* - * A socket pair is often used for interprocess communication, - * so we need to make sure neither socket is associated with - * the I/O completion port; otherwise it can't be used by a - * child process. - * - * The default implementation below cannot be used for NT - * because PR_Accept would have associated the I/O completion - * port with the listening and accepted sockets. - */ - SOCKET listenSock; - SOCKET osfd[2]; - struct sockaddr_in selfAddr, peerAddr; - int addrLen; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - osfd[0] = osfd[1] = INVALID_SOCKET; - listenSock = socket(AF_INET, SOCK_STREAM, 0); - if (listenSock == INVALID_SOCKET) { - goto failed; - } - selfAddr.sin_family = AF_INET; - selfAddr.sin_port = 0; - selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* BugZilla: 35408 */ - addrLen = sizeof(selfAddr); - if (bind(listenSock, (struct sockaddr *) &selfAddr, - addrLen) == SOCKET_ERROR) { - goto failed; - } - if (getsockname(listenSock, (struct sockaddr *) &selfAddr, - &addrLen) == SOCKET_ERROR) { - goto failed; - } - if (listen(listenSock, 5) == SOCKET_ERROR) { - goto failed; - } - osfd[0] = socket(AF_INET, SOCK_STREAM, 0); - if (osfd[0] == INVALID_SOCKET) { - goto failed; - } - selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - /* - * Only a thread is used to do the connect and accept. - * I am relying on the fact that connect returns - * successfully as soon as the connect request is put - * into the listen queue (but before accept is called). - * This is the behavior of the BSD socket code. If - * connect does not return until accept is called, we - * will need to create another thread to call connect. - */ - if (connect(osfd[0], (struct sockaddr *) &selfAddr, - addrLen) == SOCKET_ERROR) { - goto failed; - } - /* - * A malicious local process may connect to the listening - * socket, so we need to verify that the accepted connection - * is made from our own socket osfd[0]. - */ - if (getsockname(osfd[0], (struct sockaddr *) &selfAddr, - &addrLen) == SOCKET_ERROR) { - goto failed; - } - osfd[1] = accept(listenSock, (struct sockaddr *) &peerAddr, &addrLen); - if (osfd[1] == INVALID_SOCKET) { - goto failed; - } - if (peerAddr.sin_port != selfAddr.sin_port) { - /* the connection we accepted is not from osfd[0] */ - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - goto failed; - } - closesocket(listenSock); - - f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods()); - if (!f[0]) { - closesocket(osfd[0]); - closesocket(osfd[1]); - /* PR_AllocFileDesc() has invoked PR_SetError(). */ - return PR_FAILURE; - } - f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods()); - if (!f[1]) { - PR_Close(f[0]); - closesocket(osfd[1]); - /* PR_AllocFileDesc() has invoked PR_SetError(). */ - return PR_FAILURE; - } - _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE); - _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE); - return PR_SUCCESS; - -failed: - if (listenSock != INVALID_SOCKET) { - closesocket(listenSock); - } - if (osfd[0] != INVALID_SOCKET) { - closesocket(osfd[0]); - } - if (osfd[1] != INVALID_SOCKET) { - closesocket(osfd[1]); - } - return PR_FAILURE; -#else /* not Unix or NT */ - /* - * default implementation - */ - PRFileDesc *listenSock; - PRNetAddr selfAddr, peerAddr; - PRUint16 port; - - f[0] = f[1] = NULL; - listenSock = PR_NewTCPSocket(); - if (listenSock == NULL) { - goto failed; - } - PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */ - if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) { - goto failed; - } - if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) { - goto failed; - } - port = ntohs(selfAddr.inet.port); - if (PR_Listen(listenSock, 5) == PR_FAILURE) { - goto failed; - } - f[0] = PR_NewTCPSocket(); - if (f[0] == NULL) { - goto failed; - } -#ifdef _PR_CONNECT_DOES_NOT_BIND - /* - * If connect does not implicitly bind the socket (e.g., on - * BeOS), we have to bind the socket so that we can get its - * port with getsockname later. - */ - PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); - if (PR_Bind(f[0], &selfAddr) == PR_FAILURE) { - goto failed; - } -#endif - PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr); - - /* - * Only a thread is used to do the connect and accept. - * I am relying on the fact that PR_Connect returns - * successfully as soon as the connect request is put - * into the listen queue (but before PR_Accept is called). - * This is the behavior of the BSD socket code. If - * connect does not return until accept is called, we - * will need to create another thread to call connect. - */ - if (PR_Connect(f[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT) - == PR_FAILURE) { - goto failed; - } - /* - * A malicious local process may connect to the listening - * socket, so we need to verify that the accepted connection - * is made from our own socket f[0]. - */ - if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) { - goto failed; - } - f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT); - if (f[1] == NULL) { - goto failed; - } - if (peerAddr.inet.port != selfAddr.inet.port) { - /* the connection we accepted is not from f[0] */ - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - goto failed; - } - PR_Close(listenSock); - return PR_SUCCESS; - -failed: - if (listenSock) { - PR_Close(listenSock); - } - if (f[0]) { - PR_Close(f[0]); - } - if (f[1]) { - PR_Close(f[1]); - } - return PR_FAILURE; -#endif -} - -PR_IMPLEMENT(PROsfd) -PR_FileDesc2NativeHandle(PRFileDesc *fd) -{ - if (fd) { - fd = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER); - } - if (!fd) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - return fd->secret->md.osfd; -} - -PR_IMPLEMENT(void) -PR_ChangeFileDescNativeHandle(PRFileDesc *fd, PROsfd handle) -{ - if (fd) - fd->secret->md.osfd = handle; -} - -/* -** Select compatibility -** -*/ - -PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set) -{ - memset(set, 0, sizeof(PR_fd_set)); -} - -PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set) -{ - PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC ); - - set->harray[set->hsize++] = fh; -} - -PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set) -{ - PRUint32 index, index2; - - for (index = 0; indexhsize; index++) - if (set->harray[index] == fh) { - for (index2=index; index2 < (set->hsize-1); index2++) { - set->harray[index2] = set->harray[index2+1]; - } - set->hsize--; - break; - } -} - -PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set) -{ - PRUint32 index; - for (index = 0; indexhsize; index++) - if (set->harray[index] == fh) { - return 1; - } - return 0; -} - -PR_IMPLEMENT(void) PR_FD_NSET(PROsfd fd, PR_fd_set *set) -{ - PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC ); - - set->narray[set->nsize++] = fd; -} - -PR_IMPLEMENT(void) PR_FD_NCLR(PROsfd fd, PR_fd_set *set) -{ - PRUint32 index, index2; - - for (index = 0; indexnsize; index++) - if (set->narray[index] == fd) { - for (index2=index; index2 < (set->nsize-1); index2++) { - set->narray[index2] = set->narray[index2+1]; - } - set->nsize--; - break; - } -} - -PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PROsfd fd, PR_fd_set *set) -{ - PRUint32 index; - for (index = 0; indexnsize; index++) - if (set->narray[index] == fd) { - return 1; - } - return 0; -} - - -#if !defined(NEED_SELECT) -#include "obsolete/probslet.h" - -#define PD_INCR 20 - -static PRPollDesc *_pr_setfd( - PR_fd_set *set, PRInt16 flags, PRPollDesc *polldesc) -{ - PRUintn fsidx, pdidx; - PRPollDesc *poll = polldesc; - - if (NULL == set) return poll; - - /* First set the pr file handle osfds */ - for (fsidx = 0; fsidx < set->hsize; fsidx++) - { - for (pdidx = 0; 1; pdidx++) - { - if ((PRFileDesc*)-1 == poll[pdidx].fd) - { - /* our vector is full - extend and condition it */ - poll = (PRPollDesc*)PR_Realloc( - poll, (pdidx + 1 + PD_INCR) * sizeof(PRPollDesc)); - if (NULL == poll) goto out_of_memory; - memset( - poll + pdidx * sizeof(PRPollDesc), - 0, PD_INCR * sizeof(PRPollDesc)); - poll[pdidx + PD_INCR].fd = (PRFileDesc*)-1; - } - if ((NULL == poll[pdidx].fd) - || (poll[pdidx].fd == set->harray[fsidx])) - { - /* PR_ASSERT(0 == (poll[pdidx].in_flags & flags)); */ - /* either empty or prevously defined */ - poll[pdidx].fd = set->harray[fsidx]; /* possibly redundant */ - poll[pdidx].in_flags |= flags; /* possibly redundant */ - break; - } - } - } - -#if 0 - /* Second set the native osfds */ - for (fsidx = 0; fsidx < set->nsize; fsidx++) - { - for (pdidx = 0; ((PRFileDesc*)-1 != poll[pdidx].fd); pdidx++) - { - if ((PRFileDesc*)-1 == poll[pdidx].fd) - { - /* our vector is full - extend and condition it */ - poll = PR_Realloc( - poll, (pdidx + PD_INCR) * sizeof(PRPollDesc)); - if (NULL == poll) goto out_of_memory; - memset( - poll + pdidx * sizeof(PRPollDesc), - 0, PD_INCR * sizeof(PRPollDesc)); - poll[(pdidx + PD_INCR)].fd = (PRFileDesc*)-1; - } - if ((NULL == poll[pdidx].fd) - || (poll[pdidx].fd == set->narray[fsidx])) - { - /* either empty or prevously defined */ - poll[pdidx].fd = set->narray[fsidx]; - PR_ASSERT(0 == (poll[pdidx].in_flags & flags)); - poll[pdidx].in_flags |= flags; - break; - } - } - } -#endif /* 0 */ - - return poll; - -out_of_memory: - if (NULL != polldesc) PR_DELETE(polldesc); - return NULL; -} /* _pr_setfd */ - -#endif /* !defined(NEED_SELECT) */ - -PR_IMPLEMENT(PRInt32) PR_Select( - PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, - PR_fd_set *pr_ex, PRIntervalTime timeout) -{ - -#if !defined(NEED_SELECT) - PRInt32 npds = 0; - /* - ** Find out how many fds are represented in the three lists. - ** Then allocate a polling descriptor for the logical union - ** (there can't be any overlapping) and call PR_Poll(). - */ - - PRPollDesc *copy, *poll; - - static PRBool warning = PR_TRUE; - if (warning) warning = _PR_Obsolete( "PR_Select()", "PR_Poll()"); - - /* try to get an initial guesss at how much space we need */ - npds = 0; - if ((NULL != pr_rd) && ((pr_rd->hsize + pr_rd->nsize - npds) > 0)) - npds = pr_rd->hsize + pr_rd->nsize; - if ((NULL != pr_wr) && ((pr_wr->hsize + pr_wr->nsize - npds) > 0)) - npds = pr_wr->hsize + pr_wr->nsize; - if ((NULL != pr_ex) && ((pr_ex->hsize + pr_ex->nsize - npds) > 0)) - npds = pr_ex->hsize + pr_ex->nsize; - - if (0 == npds) - { - PR_Sleep(timeout); - return 0; - } - - copy = poll = (PRPollDesc*)PR_Calloc(npds + PD_INCR, sizeof(PRPollDesc)); - if (NULL == poll) goto out_of_memory; - poll[npds + PD_INCR - 1].fd = (PRFileDesc*)-1; - - poll = _pr_setfd(pr_rd, PR_POLL_READ, poll); - if (NULL == poll) goto out_of_memory; - poll = _pr_setfd(pr_wr, PR_POLL_WRITE, poll); - if (NULL == poll) goto out_of_memory; - poll = _pr_setfd(pr_ex, PR_POLL_EXCEPT, poll); - if (NULL == poll) goto out_of_memory; - unused = 0; - while (NULL != poll[unused].fd && (PRFileDesc*)-1 != poll[unused].fd) - { - ++unused; - } - - PR_ASSERT(unused > 0); - npds = PR_Poll(poll, unused, timeout); - - if (npds > 0) - { - /* Copy the results back into the fd sets */ - if (NULL != pr_rd) pr_rd->nsize = pr_rd->hsize = 0; - if (NULL != pr_wr) pr_wr->nsize = pr_wr->hsize = 0; - if (NULL != pr_ex) pr_ex->nsize = pr_ex->hsize = 0; - for (copy = &poll[unused - 1]; copy >= poll; --copy) - { - if (copy->out_flags & PR_POLL_NVAL) - { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - npds = -1; - break; - } - if (copy->out_flags & PR_POLL_READ) - if (NULL != pr_rd) pr_rd->harray[pr_rd->hsize++] = copy->fd; - if (copy->out_flags & PR_POLL_WRITE) - if (NULL != pr_wr) pr_wr->harray[pr_wr->hsize++] = copy->fd; - if (copy->out_flags & PR_POLL_EXCEPT) - if (NULL != pr_ex) pr_ex->harray[pr_ex->hsize++] = copy->fd; - } - } - PR_DELETE(poll); - - return npds; -out_of_memory: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - -#endif /* !defined(NEED_SELECT) */ - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/io/prstdio.c nspr-4.10.7/mozilla/nsprpub/pr/src/io/prstdio.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/io/prstdio.c 2012-03-06 13:14:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/io/prstdio.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -/* -** fprintf to a PRFileDesc -*/ -PR_IMPLEMENT(PRUint32) PR_fprintf(PRFileDesc* fd, const char *fmt, ...) -{ - va_list ap; - PRUint32 rv; - - va_start(ap, fmt); - rv = PR_vfprintf(fd, fmt, ap); - va_end(ap); - return rv; -} - -PR_IMPLEMENT(PRUint32) PR_vfprintf(PRFileDesc* fd, const char *fmt, va_list ap) -{ - /* XXX this could be better */ - PRUint32 rv, len; - char* msg = PR_vsmprintf(fmt, ap); - if (NULL == msg) { - return -1; - } - len = strlen(msg); -#ifdef XP_OS2 - /* - * OS/2 really needs a \r for every \n. - * In the future we should try to use scatter-gather instead of a - * succession of PR_Write. - */ - if (isatty(PR_FileDesc2NativeHandle(fd))) { - PRUint32 last = 0, idx; - PRInt32 tmp; - rv = 0; - for (idx = 0; idx < len+1; idx++) { - if ((idx - last > 0) && (('\n' == msg[idx]) || (idx == len))) { - tmp = PR_Write(fd, msg + last, idx - last); - if (tmp >= 0) { - rv += tmp; - } - last = idx; - } - /* - * if current character is \n, and - * previous character isn't \r, and - * next character isn't \r - */ - if (('\n' == msg[idx]) && - ((0 == idx) || ('\r' != msg[idx-1])) && - ('\r' != msg[idx+1])) { - /* add extra \r */ - tmp = PR_Write(fd, "\r", 1); - if (tmp >= 0) { - rv += tmp; - } - } - } - } else { - rv = PR_Write(fd, msg, len); - } -#else - rv = PR_Write(fd, msg, len); -#endif - PR_DELETE(msg); - return rv; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/linking/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/linking/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/linking/.cvsignore 2001-05-12 04:20:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/linking/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/linking/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/linking/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/linking/Makefile.in 2012-11-13 23:17:58.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/linking/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CSRCS = \ - prlink.c \ - $(NULL) - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/linking/prlink.c nspr-4.10.7/mozilla/nsprpub/pr/src/linking/prlink.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/linking/prlink.c 2013-01-29 22:06:49.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/linking/prlink.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1608 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -#ifdef XP_BEOS -#include -#endif - -#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) -#include -#include -#endif - -#ifdef XP_UNIX -#ifdef USE_DLFCN -#include -/* Define these on systems that don't have them. */ -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif -#ifndef RTLD_LAZY -#define RTLD_LAZY RTLD_NOW -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif -#ifndef RTLD_LOCAL -#define RTLD_LOCAL 0 -#endif -#ifdef AIX -#include -#ifndef L_IGNOREUNLOAD /* AIX 4.3.3 does not have L_IGNOREUNLOAD. */ -#define L_IGNOREUNLOAD 0x10000000 -#endif -#endif -#ifdef OSF1 -#include -#include -#endif -#elif defined(USE_HPSHL) -#include -#elif defined(USE_MACH_DYLD) -#include -#endif -#endif /* XP_UNIX */ - -#define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY - -/* - * On these platforms, symbols have a leading '_'. - */ -#if (defined(DARWIN) && defined(USE_MACH_DYLD)) \ - || defined(XP_OS2) \ - || ((defined(OPENBSD) || defined(NETBSD)) && !defined(__ELF__)) -#define NEED_LEADING_UNDERSCORE -#endif - -#define PR_LD_PATHW 0x8000 /* for PR_LibSpec_PathnameU */ - -/************************************************************************/ - -struct PRLibrary { - char* name; /* Our own copy of the name string */ - PRLibrary* next; - int refCount; - const PRStaticLinkTable* staticTable; - -#ifdef XP_PC -#ifdef XP_OS2 - HMODULE dlh; -#else - HINSTANCE dlh; -#endif -#endif - -#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) - CFragConnectionID connection; - CFBundleRef bundle; - Ptr main; - CFMutableDictionaryRef wrappers; - const struct mach_header* image; -#endif - -#ifdef XP_UNIX -#if defined(USE_HPSHL) - shl_t dlh; -#elif defined(USE_MACH_DYLD) - NSModule dlh; -#else - void* dlh; -#endif -#endif - -#ifdef XP_BEOS - void* dlh; - void* stub_dlh; -#endif -}; - -static PRLibrary *pr_loadmap; -static PRLibrary *pr_exe_loadmap; -static PRMonitor *pr_linker_lock; -static char* _pr_currentLibPath = NULL; - -static PRLibrary *pr_LoadLibraryByPathname(const char *name, PRIntn flags); - -/************************************************************************/ - -#if !defined(USE_DLFCN) && !defined(HAVE_STRERROR) -#define ERR_STR_BUF_LENGTH 20 -#endif - -static void DLLErrorInternal(PRIntn oserr) -/* -** This whole function, and most of the code in this file, are run -** with a big hairy lock wrapped around it. Not the best of situations, -** but will eventually come up with the right answer. -*/ -{ - const char *error = NULL; -#ifdef USE_DLFCN - error = dlerror(); /* $$$ That'll be wrong some of the time - AOF */ -#elif defined(HAVE_STRERROR) - error = strerror(oserr); /* this should be okay */ -#else - char errStrBuf[ERR_STR_BUF_LENGTH]; - PR_snprintf(errStrBuf, sizeof(errStrBuf), "error %d", oserr); - error = errStrBuf; -#endif - if (NULL != error) - PR_SetErrorText(strlen(error), error); -} /* DLLErrorInternal */ - -void _PR_InitLinker(void) -{ - PRLibrary *lm = NULL; -#if defined(XP_UNIX) - void *h; -#endif - - if (!pr_linker_lock) { - pr_linker_lock = PR_NewNamedMonitor("linker-lock"); - } - PR_EnterMonitor(pr_linker_lock); - -#if defined(XP_PC) - lm = PR_NEWZAP(PRLibrary); - lm->name = strdup("Executable"); -#if defined(XP_OS2) - lm->dlh = NULLHANDLE; -#else - /* A module handle for the executable. */ - lm->dlh = GetModuleHandle(NULL); -#endif /* ! XP_OS2 */ - - lm->refCount = 1; - lm->staticTable = NULL; - pr_exe_loadmap = lm; - pr_loadmap = lm; - -#elif defined(XP_UNIX) -#ifdef HAVE_DLL -#if defined(USE_DLFCN) && !defined(NO_DLOPEN_NULL) - h = dlopen(0, RTLD_LAZY); - if (!h) { - char *error; - - DLLErrorInternal(_MD_ERRNO()); - error = (char*)PR_MALLOC(PR_GetErrorTextLength()); - (void) PR_GetErrorText(error); - fprintf(stderr, "failed to initialize shared libraries [%s]\n", - error); - PR_DELETE(error); - abort();/* XXX */ - } -#elif defined(USE_HPSHL) - h = NULL; - /* don't abort with this NULL */ -#elif defined(USE_MACH_DYLD) || defined(NO_DLOPEN_NULL) - h = NULL; /* XXXX toshok */ /* XXXX vlad */ -#else -#error no dll strategy -#endif /* USE_DLFCN */ - - lm = PR_NEWZAP(PRLibrary); - if (lm) { - lm->name = strdup("a.out"); - lm->refCount = 1; - lm->dlh = h; - lm->staticTable = NULL; - } - pr_exe_loadmap = lm; - pr_loadmap = lm; -#endif /* HAVE_DLL */ -#endif /* XP_UNIX */ - - if (lm) { - PR_LOG(_pr_linker_lm, PR_LOG_MIN, - ("Loaded library %s (init)", lm->name)); - } - - PR_ExitMonitor(pr_linker_lock); -} - -/* - * _PR_ShutdownLinker does not unload the dlls loaded by the application - * via calls to PR_LoadLibrary. Any dlls that still remain on the - * pr_loadmap list when NSPR shuts down are application programming errors. - * The only exception is pr_exe_loadmap, which was added to the list by - * NSPR and hence should be cleaned up by NSPR. - */ -void _PR_ShutdownLinker(void) -{ - /* FIXME: pr_exe_loadmap should be destroyed. */ - - PR_DestroyMonitor(pr_linker_lock); - pr_linker_lock = NULL; - - if (_pr_currentLibPath) { - free(_pr_currentLibPath); - _pr_currentLibPath = NULL; - } -} - -/******************************************************************************/ - -PR_IMPLEMENT(PRStatus) PR_SetLibraryPath(const char *path) -{ - PRStatus rv = PR_SUCCESS; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - PR_EnterMonitor(pr_linker_lock); - if (_pr_currentLibPath) { - free(_pr_currentLibPath); - } - if (path) { - _pr_currentLibPath = strdup(path); - if (!_pr_currentLibPath) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - rv = PR_FAILURE; - } - } else { - _pr_currentLibPath = 0; - } - PR_ExitMonitor(pr_linker_lock); - return rv; -} - -/* -** Return the library path for finding shared libraries. -*/ -PR_IMPLEMENT(char *) -PR_GetLibraryPath(void) -{ - char *ev; - char *copy = NULL; /* a copy of _pr_currentLibPath */ - - if (!_pr_initialized) _PR_ImplicitInitialization(); - PR_EnterMonitor(pr_linker_lock); - if (_pr_currentLibPath != NULL) { - goto exit; - } - - /* initialize pr_currentLibPath */ - -#ifdef XP_PC - ev = getenv("LD_LIBRARY_PATH"); - if (!ev) { - ev = ".;\\lib"; - } - ev = strdup(ev); -#endif - -#if defined(XP_UNIX) || defined(XP_BEOS) -#if defined(USE_DLFCN) || defined(USE_MACH_DYLD) || defined(XP_BEOS) - { - char *p=NULL; - int len; - -#ifdef XP_BEOS - ev = getenv("LIBRARY_PATH"); - if (!ev) { - ev = "%A/lib:/boot/home/config/lib:/boot/beos/system/lib"; - } -#else - ev = getenv("LD_LIBRARY_PATH"); - if (!ev) { - ev = "/usr/lib:/lib"; - } -#endif - len = strlen(ev) + 1; /* +1 for the null */ - - p = (char*) malloc(len); - if (p) { - strcpy(p, ev); - } /* if (p) */ - ev = p; - PR_LOG(_pr_io_lm, PR_LOG_NOTICE, ("linker path '%s'", ev)); - - } -#else - /* AFAIK there isn't a library path with the HP SHL interface --Rob */ - ev = strdup(""); -#endif -#endif - - /* - * If ev is NULL, we have run out of memory - */ - _pr_currentLibPath = ev; - - exit: - if (_pr_currentLibPath) { - copy = strdup(_pr_currentLibPath); - } - PR_ExitMonitor(pr_linker_lock); - if (!copy) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - } - return copy; -} - -/* -** Build library name from path, lib and extensions -*/ -PR_IMPLEMENT(char*) -PR_GetLibraryName(const char *path, const char *lib) -{ - char *fullname; - -#ifdef XP_PC - if (strstr(lib, PR_DLL_SUFFIX) == NULL) - { - if (path) { - fullname = PR_smprintf("%s\\%s%s", path, lib, PR_DLL_SUFFIX); - } else { - fullname = PR_smprintf("%s%s", lib, PR_DLL_SUFFIX); - } - } else { - if (path) { - fullname = PR_smprintf("%s\\%s", path, lib); - } else { - fullname = PR_smprintf("%s", lib); - } - } -#endif /* XP_PC */ -#if defined(XP_UNIX) || defined(XP_BEOS) - if (strstr(lib, PR_DLL_SUFFIX) == NULL) - { - if (path) { - fullname = PR_smprintf("%s/lib%s%s", path, lib, PR_DLL_SUFFIX); - } else { - fullname = PR_smprintf("lib%s%s", lib, PR_DLL_SUFFIX); - } - } else { - if (path) { - fullname = PR_smprintf("%s/%s", path, lib); - } else { - fullname = PR_smprintf("%s", lib); - } - } -#endif /* XP_UNIX || XP_BEOS */ - return fullname; -} - -/* -** Free the memory allocated, for the caller, by PR_GetLibraryName -*/ -PR_IMPLEMENT(void) -PR_FreeLibraryName(char *mem) -{ - PR_smprintf_free(mem); -} - -static PRLibrary* -pr_UnlockedFindLibrary(const char *name) -{ - PRLibrary* lm = pr_loadmap; - const char* np = strrchr(name, PR_DIRECTORY_SEPARATOR); - np = np ? np + 1 : name; - while (lm) { - const char* cp = strrchr(lm->name, PR_DIRECTORY_SEPARATOR); - cp = cp ? cp + 1 : lm->name; -#ifdef WIN32 - /* Windows DLL names are case insensitive... */ - if (strcmpi(np, cp) == 0) -#elif defined(XP_OS2) - if (stricmp(np, cp) == 0) -#else - if (strcmp(np, cp) == 0) -#endif - { - /* found */ - lm->refCount++; - PR_LOG(_pr_linker_lm, PR_LOG_MIN, - ("%s incr => %d (find lib)", - lm->name, lm->refCount)); - return lm; - } - lm = lm->next; - } - return NULL; -} - -PR_IMPLEMENT(PRLibrary*) -PR_LoadLibraryWithFlags(PRLibSpec libSpec, PRIntn flags) -{ - if (flags == 0) { - flags = _PR_DEFAULT_LD_FLAGS; - } - switch (libSpec.type) { - case PR_LibSpec_Pathname: - return pr_LoadLibraryByPathname(libSpec.value.pathname, flags); -#ifdef WIN32 - case PR_LibSpec_PathnameU: - /* - * cast to |char *| and set PR_LD_PATHW flag so that - * it can be cast back to PRUnichar* in the callee. - */ - return pr_LoadLibraryByPathname((const char*) - libSpec.value.pathname_u, - flags | PR_LD_PATHW); -#endif - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } -} - -PR_IMPLEMENT(PRLibrary*) -PR_LoadLibrary(const char *name) -{ - PRLibSpec libSpec; - - libSpec.type = PR_LibSpec_Pathname; - libSpec.value.pathname = name; - return PR_LoadLibraryWithFlags(libSpec, 0); -} - -#if defined(USE_MACH_DYLD) -static NSModule -pr_LoadMachDyldModule(const char *name) -{ - NSObjectFileImage ofi; - NSModule h = NULL; - if (NSCreateObjectFileImageFromFile(name, &ofi) - == NSObjectFileImageSuccess) { - h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE - | NSLINKMODULE_OPTION_RETURN_ON_ERROR); - if (h == NULL) { - NSLinkEditErrors linkEditError; - int errorNum; - const char *fileName; - const char *errorString; - NSLinkEditError(&linkEditError, &errorNum, &fileName, &errorString); - PR_LOG(_pr_linker_lm, PR_LOG_MIN, - ("LoadMachDyldModule error %d:%d for file %s:\n%s", - linkEditError, errorNum, fileName, errorString)); - } - if (NSDestroyObjectFileImage(ofi) == FALSE) { - if (h) { - (void)NSUnLinkModule(h, NSUNLINKMODULE_OPTION_NONE); - h = NULL; - } - } - } - return h; -} -#endif - -#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) - -/* -** macLibraryLoadProc is a function definition for a Mac shared library -** loading method. The "name" param is the same full or partial pathname -** that was passed to pr_LoadLibraryByPathName. The function must fill -** in the fields of "lm" which apply to its library type. Returns -** PR_SUCCESS if successful. -*/ - -typedef PRStatus (*macLibraryLoadProc)(const char *name, PRLibrary *lm); - -#ifdef __ppc__ - -/* -** CFM and its TVectors only exist on PowerPC. Other OS X architectures -** only use Mach-O as a native binary format. -*/ - -static void* TV2FP(CFMutableDictionaryRef dict, const char* name, void *tvp) -{ - static uint32 glue[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 }; - uint32* newGlue = NULL; - - if (tvp != NULL) { - CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII); - if (nameRef) { - CFMutableDataRef glueData = (CFMutableDataRef) CFDictionaryGetValue(dict, nameRef); - if (glueData == NULL) { - glueData = CFDataCreateMutable(NULL, sizeof(glue)); - if (glueData != NULL) { - newGlue = (uint32*) CFDataGetMutableBytePtr(glueData); - memcpy(newGlue, glue, sizeof(glue)); - newGlue[0] |= ((UInt32)tvp >> 16); - newGlue[1] |= ((UInt32)tvp & 0xFFFF); - MakeDataExecutable(newGlue, sizeof(glue)); - CFDictionaryAddValue(dict, nameRef, glueData); - CFRelease(glueData); - - PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: created wrapper for CFM function %s().", name)); - } - } else { - PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: found wrapper for CFM function %s().", name)); - - newGlue = (uint32*) CFDataGetMutableBytePtr(glueData); - } - CFRelease(nameRef); - } - } - - return newGlue; -} - -static PRStatus -pr_LoadViaCFM(const char *name, PRLibrary *lm) -{ - OSErr err; - Str255 errName; - FSRef ref; - FSSpec fileSpec; - Boolean tempUnusedBool; - - /* - * Make an FSSpec from the path name and call GetDiskFragment. - */ - - /* Use direct conversion of POSIX path to FSRef to FSSpec. */ - err = FSPathMakeRef((const UInt8*)name, &ref, NULL); - if (err != noErr) - return PR_FAILURE; - err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, - &fileSpec, NULL); - if (err != noErr) - return PR_FAILURE; - - /* Resolve an alias if this was one */ - err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool, - &tempUnusedBool); - if (err != noErr) - return PR_FAILURE; - - /* Finally, try to load the library */ - err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, fileSpec.name, - kLoadCFrag, &lm->connection, &lm->main, errName); - - if (err == noErr && lm->connection) { - /* - * if we're a mach-o binary, need to wrap all CFM function - * pointers. need a hash-table of already seen function - * pointers, etc. - */ - lm->wrappers = CFDictionaryCreateMutable(NULL, 16, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - if (lm->wrappers) { - lm->main = TV2FP(lm->wrappers, "main", lm->main); - } else - err = memFullErr; - } - return (err == noErr) ? PR_SUCCESS : PR_FAILURE; -} -#endif /* __ppc__ */ - -/* -** Creates a CFBundleRef if the pathname refers to a Mac OS X bundle -** directory. The caller is responsible for calling CFRelease() to -** deallocate. -*/ - -static PRStatus -pr_LoadCFBundle(const char *name, PRLibrary *lm) -{ - CFURLRef bundleURL; - CFBundleRef bundle = NULL; - char pathBuf[PATH_MAX]; - const char *resolvedPath; - CFStringRef pathRef; - - /* Takes care of relative paths and symlinks */ - resolvedPath = realpath(name, pathBuf); - if (!resolvedPath) - return PR_FAILURE; - - pathRef = CFStringCreateWithCString(NULL, pathBuf, kCFStringEncodingUTF8); - if (pathRef) { - bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef, - kCFURLPOSIXPathStyle, true); - if (bundleURL) { - bundle = CFBundleCreate(NULL, bundleURL); - CFRelease(bundleURL); - } - CFRelease(pathRef); - } - - lm->bundle = bundle; - return (bundle != NULL) ? PR_SUCCESS : PR_FAILURE; -} - -static PRStatus -pr_LoadViaDyld(const char *name, PRLibrary *lm) -{ - lm->dlh = pr_LoadMachDyldModule(name); - if (lm->dlh == NULL) { - lm->image = NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ON_ERROR - | NSADDIMAGE_OPTION_WITH_SEARCHING); - if (lm->image == NULL) { - NSLinkEditErrors linkEditError; - int errorNum; - const char *fileName; - const char *errorString; - NSLinkEditError(&linkEditError, &errorNum, &fileName, &errorString); - PR_LOG(_pr_linker_lm, PR_LOG_MIN, - ("LoadMachDyldModule error %d:%d for file %s:\n%s", - linkEditError, errorNum, fileName, errorString)); - } - } - return (lm->dlh != NULL || lm->image != NULL) ? PR_SUCCESS : PR_FAILURE; -} - -#endif /* XP_MACOSX && USE_MACH_DYLD */ - -/* -** Dynamically load a library. Only load libraries once, so scan the load -** map first. -*/ -static PRLibrary* -pr_LoadLibraryByPathname(const char *name, PRIntn flags) -{ - PRLibrary *lm; - PRLibrary* result = NULL; - PRInt32 oserr; -#ifdef WIN32 - char utf8name_stack[MAX_PATH]; - char *utf8name_malloc = NULL; - char *utf8name = utf8name_stack; - PRUnichar wname_stack[MAX_PATH]; - PRUnichar *wname_malloc = NULL; - PRUnichar *wname = wname_stack; - int len; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - /* See if library is already loaded */ - PR_EnterMonitor(pr_linker_lock); - -#ifdef WIN32 - if (flags & PR_LD_PATHW) { - /* cast back what's cast to |char *| for the argument passing. */ - wname = (LPWSTR) name; - } else { - int wlen = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0); - if (wlen > MAX_PATH) - wname = wname_malloc = PR_Malloc(wlen * sizeof(PRUnichar)); - if (wname == NULL || - !MultiByteToWideChar(CP_ACP, 0, name, -1, wname, wlen)) { - oserr = _MD_ERRNO(); - goto unlock; - } - } - len = WideCharToMultiByte(CP_UTF8, 0, wname, -1, NULL, 0, NULL, NULL); - if (len > MAX_PATH) - utf8name = utf8name_malloc = PR_Malloc(len); - if (utf8name == NULL || - !WideCharToMultiByte(CP_UTF8, 0, wname, -1, - utf8name, len, NULL, NULL)) { - oserr = _MD_ERRNO(); - goto unlock; - } - /* the list of loaded library names are always kept in UTF-8 - * on Win32 platforms */ - result = pr_UnlockedFindLibrary(utf8name); -#else - result = pr_UnlockedFindLibrary(name); -#endif - - if (result != NULL) goto unlock; - - lm = PR_NEWZAP(PRLibrary); - if (lm == NULL) { - oserr = _MD_ERRNO(); - goto unlock; - } - lm->staticTable = NULL; - -#ifdef XP_OS2 /* Why isn't all this stuff in MD code?! */ - { - HMODULE h; - UCHAR pszError[_MAX_PATH]; - ULONG ulRc = NO_ERROR; - - ulRc = DosLoadModule(pszError, _MAX_PATH, (PSZ) name, &h); - if (ulRc != NO_ERROR) { - oserr = ulRc; - PR_DELETE(lm); - goto unlock; - } - lm->name = strdup(name); - lm->dlh = h; - lm->next = pr_loadmap; - pr_loadmap = lm; - } -#endif /* XP_OS2 */ - -#ifdef WIN32 - { - HINSTANCE h; - - h = LoadLibraryExW(wname, NULL, - (flags & PR_LD_ALT_SEARCH_PATH) ? - LOAD_WITH_ALTERED_SEARCH_PATH : 0); - if (h == NULL) { - oserr = _MD_ERRNO(); - PR_DELETE(lm); - goto unlock; - } - lm->name = strdup(utf8name); - lm->dlh = h; - lm->next = pr_loadmap; - pr_loadmap = lm; - } -#endif /* WIN32 */ - -#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) - { - int i; - PRStatus status; - - static const macLibraryLoadProc loadProcs[] = { -#ifdef __ppc__ - pr_LoadViaDyld, pr_LoadCFBundle, pr_LoadViaCFM -#else /* __ppc__ */ - pr_LoadViaDyld, pr_LoadCFBundle -#endif /* __ppc__ */ - }; - - for (i = 0; i < sizeof(loadProcs) / sizeof(loadProcs[0]); i++) { - if ((status = loadProcs[i](name, lm)) == PR_SUCCESS) - break; - } - if (status != PR_SUCCESS) { - oserr = cfragNoLibraryErr; - PR_DELETE(lm); - goto unlock; - } - lm->name = strdup(name); - lm->next = pr_loadmap; - pr_loadmap = lm; - } -#endif - -#if defined(XP_UNIX) && !(defined(XP_MACOSX) && defined(USE_MACH_DYLD)) -#ifdef HAVE_DLL - { -#if defined(USE_DLFCN) -#ifdef NTO - /* Neutrino needs RTLD_GROUP to load Netscape plugins. (bug 71179) */ - int dl_flags = RTLD_GROUP; -#elif defined(AIX) - /* AIX needs RTLD_MEMBER to load an archive member. (bug 228899) */ - int dl_flags = RTLD_MEMBER; -#else - int dl_flags = 0; -#endif - void *h = NULL; - - if (flags & PR_LD_LAZY) { - dl_flags |= RTLD_LAZY; - } - if (flags & PR_LD_NOW) { - dl_flags |= RTLD_NOW; - } - if (flags & PR_LD_GLOBAL) { - dl_flags |= RTLD_GLOBAL; - } - if (flags & PR_LD_LOCAL) { - dl_flags |= RTLD_LOCAL; - } -#if defined(DARWIN) - /* ensure the file exists if it contains a slash character i.e. path */ - /* DARWIN's dlopen ignores the provided path and checks for the */ - /* plain filename in DYLD_LIBRARY_PATH */ - if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL || - PR_Access(name, PR_ACCESS_EXISTS) == PR_SUCCESS) { - h = dlopen(name, dl_flags); - } -#else - h = dlopen(name, dl_flags); -#endif -#elif defined(USE_HPSHL) - int shl_flags = 0; - shl_t h; - - /* - * Use the DYNAMIC_PATH flag only if 'name' is a plain file - * name (containing no directory) to match the behavior of - * dlopen(). - */ - if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) { - shl_flags |= DYNAMIC_PATH; - } - if (flags & PR_LD_LAZY) { - shl_flags |= BIND_DEFERRED; - } - if (flags & PR_LD_NOW) { - shl_flags |= BIND_IMMEDIATE; - } - /* No equivalent of PR_LD_GLOBAL and PR_LD_LOCAL. */ - h = shl_load(name, shl_flags, 0L); -#elif defined(USE_MACH_DYLD) - NSModule h = pr_LoadMachDyldModule(name); -#else -#error Configuration error -#endif - if (!h) { - oserr = _MD_ERRNO(); - PR_DELETE(lm); - goto unlock; - } - lm->name = strdup(name); - lm->dlh = h; - lm->next = pr_loadmap; - pr_loadmap = lm; - } -#endif /* HAVE_DLL */ -#endif /* XP_UNIX && !(XP_MACOSX && USE_MACH_DYLD) */ - - lm->refCount = 1; - -#ifdef XP_BEOS - { - image_info info; - int32 cookie = 0; - image_id imageid = B_ERROR; - image_id stubid = B_ERROR; - PRLibrary *p; - - for (p = pr_loadmap; p != NULL; p = p->next) { - /* hopefully, our caller will always use the same string - to refer to the same library */ - if (strcmp(name, p->name) == 0) { - /* we've already loaded this library */ - imageid = info.id; - lm->refCount++; - break; - } - } - - if(imageid == B_ERROR) { - /* it appears the library isn't yet loaded - load it now */ - char stubName [B_PATH_NAME_LENGTH + 1]; - - /* the following is a work-around to a "bug" in the beos - - the beos system loader allows only 32M (system-wide) - to be used by code loaded as "add-ons" (code loaded - through the 'load_add_on()' system call, which includes - mozilla components), but allows 256M to be used by - shared libraries. - - unfortunately, mozilla is too large to fit into the - "add-on" space, so we must trick the loader into - loading some of the components as shared libraries. this - is accomplished by creating a "stub" add-on (an empty - shared object), and linking it with the component - (the actual .so file generated by the build process, - without any modifications). when this stub is loaded - by load_add_on(), the loader will automatically load the - component into the shared library space. - */ - - strcpy(stubName, name); - strcat(stubName, ".stub"); - - /* first, attempt to load the stub (thereby loading the - component as a shared library */ - if ((stubid = load_add_on(stubName)) > B_ERROR) { - /* the stub was loaded successfully. */ - imageid = B_FILE_NOT_FOUND; - - cookie = 0; - while (get_next_image_info(0, &cookie, &info) == B_OK) { - const char *endOfSystemName = strrchr(info.name, '/'); - const char *endOfPassedName = strrchr(name, '/'); - if( 0 == endOfSystemName ) - endOfSystemName = info.name; - else - endOfSystemName++; - if( 0 == endOfPassedName ) - endOfPassedName = name; - else - endOfPassedName++; - if (strcmp(endOfSystemName, endOfPassedName) == 0) { - /* this is the actual component - remember it */ - imageid = info.id; - break; - } - } - - } else { - /* we failed to load the "stub" - try to load the - component directly as an add-on */ - stubid = B_ERROR; - imageid = load_add_on(name); - } - } - - if (imageid <= B_ERROR) { - oserr = imageid; - PR_DELETE( lm ); - goto unlock; - } - lm->name = strdup(name); - lm->dlh = (void*)imageid; - lm->stub_dlh = (void*)stubid; - lm->next = pr_loadmap; - pr_loadmap = lm; - } -#endif - - result = lm; /* success */ - PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", lm->name)); - - unlock: - if (result == NULL) { - PR_SetError(PR_LOAD_LIBRARY_ERROR, oserr); - DLLErrorInternal(oserr); /* sets error text */ - } -#ifdef WIN32 - if (utf8name_malloc) - PR_Free(utf8name_malloc); - if (wname_malloc) - PR_Free(wname_malloc); -#endif - PR_ExitMonitor(pr_linker_lock); - return result; -} - -/* -** Unload a shared library which was loaded via PR_LoadLibrary -*/ -PR_IMPLEMENT(PRStatus) -PR_UnloadLibrary(PRLibrary *lib) -{ - int result = 0; - PRStatus status = PR_SUCCESS; - - if (lib == 0) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - - PR_EnterMonitor(pr_linker_lock); - - if (lib->refCount <= 0) { - PR_ExitMonitor(pr_linker_lock); - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - - if (--lib->refCount > 0) { - PR_LOG(_pr_linker_lm, PR_LOG_MIN, - ("%s decr => %d", - lib->name, lib->refCount)); - goto done; - } - -#ifdef XP_BEOS - if(((image_id)lib->stub_dlh) == B_ERROR) - unload_add_on( (image_id) lib->dlh ); - else - unload_add_on( (image_id) lib->stub_dlh); -#endif - -#ifdef XP_UNIX -#ifdef HAVE_DLL -#ifdef USE_DLFCN - result = dlclose(lib->dlh); -#elif defined(USE_HPSHL) - result = shl_unload(lib->dlh); -#elif defined(USE_MACH_DYLD) - if (lib->dlh) - result = NSUnLinkModule(lib->dlh, NSUNLINKMODULE_OPTION_NONE) ? 0 : -1; -#else -#error Configuration error -#endif -#endif /* HAVE_DLL */ -#endif /* XP_UNIX */ -#ifdef XP_PC - if (lib->dlh) { - FreeLibrary((HINSTANCE)(lib->dlh)); - lib->dlh = (HINSTANCE)NULL; - } -#endif /* XP_PC */ - -#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) - /* Close the connection */ - if (lib->connection) - CloseConnection(&(lib->connection)); - if (lib->bundle) - CFRelease(lib->bundle); - if (lib->wrappers) - CFRelease(lib->wrappers); - /* No way to unload an image (lib->image) */ -#endif - - /* unlink from library search list */ - if (pr_loadmap == lib) - pr_loadmap = pr_loadmap->next; - else if (pr_loadmap != NULL) { - PRLibrary* prev = pr_loadmap; - PRLibrary* next = pr_loadmap->next; - while (next != NULL) { - if (next == lib) { - prev->next = next->next; - goto freeLib; - } - prev = next; - next = next->next; - } - /* - * fail (the library is not on the _pr_loadmap list), - * but don't wipe out an error from dlclose/shl_unload. - */ - PR_ASSERT(!"_pr_loadmap and lib->refCount inconsistent"); - if (result == 0) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - status = PR_FAILURE; - } - } - /* - * We free the PRLibrary structure whether dlclose/shl_unload - * succeeds or not. - */ - - freeLib: - PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Unloaded library %s", lib->name)); - free(lib->name); - lib->name = NULL; - PR_DELETE(lib); - if (result != 0) { - PR_SetError(PR_UNLOAD_LIBRARY_ERROR, _MD_ERRNO()); - DLLErrorInternal(_MD_ERRNO()); - status = PR_FAILURE; - } - -done: - PR_ExitMonitor(pr_linker_lock); - return status; -} - -static void* -pr_FindSymbolInLib(PRLibrary *lm, const char *name) -{ - void *f = NULL; -#ifdef XP_OS2 - int rc; -#endif - - if (lm->staticTable != NULL) { - const PRStaticLinkTable* tp; - for (tp = lm->staticTable; tp->name; tp++) { - if (strcmp(name, tp->name) == 0) { - return (void*) tp->fp; - } - } - /* - ** If the symbol was not found in the static table then check if - ** the symbol was exported in the DLL... Win16 only!! - */ -#if !defined(WIN16) && !defined(XP_BEOS) - PR_SetError(PR_FIND_SYMBOL_ERROR, 0); - return (void*)NULL; -#endif - } - -#ifdef XP_OS2 - rc = DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f); -#if defined(NEED_LEADING_UNDERSCORE) - /* - * Older plugins (not built using GCC) will have symbols that are not - * underscore prefixed. We check for that here. - */ - if (rc != NO_ERROR) { - name++; - DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f); - } -#endif -#endif /* XP_OS2 */ - -#ifdef WIN32 - f = GetProcAddress(lm->dlh, name); -#endif /* WIN32 */ - -#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) -/* add this offset to skip the leading underscore in name */ -#define SYM_OFFSET 1 - if (lm->bundle) { - CFStringRef nameRef = CFStringCreateWithCString(NULL, name + SYM_OFFSET, kCFStringEncodingASCII); - if (nameRef) { - f = CFBundleGetFunctionPointerForName(lm->bundle, nameRef); - CFRelease(nameRef); - } - } - if (lm->connection) { - Ptr symAddr; - CFragSymbolClass symClass; - Str255 pName; - - PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Looking up symbol: %s", name + SYM_OFFSET)); - - c2pstrcpy(pName, name + SYM_OFFSET); - - f = (FindSymbol(lm->connection, pName, &symAddr, &symClass) == noErr) ? symAddr : NULL; - -#ifdef __ppc__ - /* callers expect mach-o function pointers, so must wrap tvectors with glue. */ - if (f && symClass == kTVectorCFragSymbol) { - f = TV2FP(lm->wrappers, name + SYM_OFFSET, f); - } -#endif /* __ppc__ */ - - if (f == NULL && strcmp(name + SYM_OFFSET, "main") == 0) f = lm->main; - } - if (lm->image) { - NSSymbol symbol; - symbol = NSLookupSymbolInImage(lm->image, name, - NSLOOKUPSYMBOLINIMAGE_OPTION_BIND - | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); - if (symbol != NULL) - f = NSAddressOfSymbol(symbol); - else - f = NULL; - } -#undef SYM_OFFSET -#endif /* XP_MACOSX && USE_MACH_DYLD */ - -#ifdef XP_BEOS - if( B_NO_ERROR != get_image_symbol( (image_id)lm->dlh, name, B_SYMBOL_TYPE_TEXT, &f ) ) { - f = NULL; - } -#endif - -#ifdef XP_UNIX -#ifdef HAVE_DLL -#ifdef USE_DLFCN - f = dlsym(lm->dlh, name); -#elif defined(USE_HPSHL) - if (shl_findsym(&lm->dlh, name, TYPE_PROCEDURE, &f) == -1) { - f = NULL; - } -#elif defined(USE_MACH_DYLD) - if (lm->dlh) { - NSSymbol symbol; - symbol = NSLookupSymbolInModule(lm->dlh, name); - if (symbol != NULL) - f = NSAddressOfSymbol(symbol); - else - f = NULL; - } -#endif -#endif /* HAVE_DLL */ -#endif /* XP_UNIX */ - if (f == NULL) { - PR_SetError(PR_FIND_SYMBOL_ERROR, _MD_ERRNO()); - DLLErrorInternal(_MD_ERRNO()); - } - return f; -} - -/* -** Called by class loader to resolve missing native's -*/ -PR_IMPLEMENT(void*) -PR_FindSymbol(PRLibrary *lib, const char *raw_name) -{ - void *f = NULL; -#if defined(NEED_LEADING_UNDERSCORE) - char *name; -#else - const char *name; -#endif - /* - ** Mangle the raw symbol name in any way that is platform specific. - */ -#if defined(NEED_LEADING_UNDERSCORE) - /* Need a leading _ */ - name = PR_smprintf("_%s", raw_name); -#elif defined(AIX) - /* - ** AIX with the normal linker put's a "." in front of the symbol - ** name. When use "svcc" and "svld" then the "." disappears. Go - ** figure. - */ - name = raw_name; -#else - name = raw_name; -#endif - - PR_EnterMonitor(pr_linker_lock); - PR_ASSERT(lib != NULL); - f = pr_FindSymbolInLib(lib, name); - -#if defined(NEED_LEADING_UNDERSCORE) - PR_smprintf_free(name); -#endif - - PR_ExitMonitor(pr_linker_lock); - return f; -} - -/* -** Return the address of the function 'raw_name' in the library 'lib' -*/ -PR_IMPLEMENT(PRFuncPtr) -PR_FindFunctionSymbol(PRLibrary *lib, const char *raw_name) -{ - return ((PRFuncPtr) PR_FindSymbol(lib, raw_name)); -} - -PR_IMPLEMENT(void*) -PR_FindSymbolAndLibrary(const char *raw_name, PRLibrary* *lib) -{ - void *f = NULL; -#if defined(NEED_LEADING_UNDERSCORE) - char *name; -#else - const char *name; -#endif - PRLibrary* lm; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - /* - ** Mangle the raw symbol name in any way that is platform specific. - */ -#if defined(NEED_LEADING_UNDERSCORE) - /* Need a leading _ */ - name = PR_smprintf("_%s", raw_name); -#elif defined(AIX) - /* - ** AIX with the normal linker put's a "." in front of the symbol - ** name. When use "svcc" and "svld" then the "." disappears. Go - ** figure. - */ - name = raw_name; -#else - name = raw_name; -#endif - - PR_EnterMonitor(pr_linker_lock); - - /* search all libraries */ - for (lm = pr_loadmap; lm != NULL; lm = lm->next) { - f = pr_FindSymbolInLib(lm, name); - if (f != NULL) { - *lib = lm; - lm->refCount++; - PR_LOG(_pr_linker_lm, PR_LOG_MIN, - ("%s incr => %d (for %s)", - lm->name, lm->refCount, name)); - break; - } - } -#if defined(NEED_LEADING_UNDERSCORE) - PR_smprintf_free(name); -#endif - - PR_ExitMonitor(pr_linker_lock); - return f; -} - -PR_IMPLEMENT(PRFuncPtr) -PR_FindFunctionSymbolAndLibrary(const char *raw_name, PRLibrary* *lib) -{ - return ((PRFuncPtr) PR_FindSymbolAndLibrary(raw_name, lib)); -} - -/* -** Add a static library to the list of loaded libraries. If LoadLibrary -** is called with the name then we will pretend it was already loaded -*/ -PR_IMPLEMENT(PRLibrary*) -PR_LoadStaticLibrary(const char *name, const PRStaticLinkTable *slt) -{ - PRLibrary *lm=NULL; - PRLibrary* result = NULL; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - /* See if library is already loaded */ - PR_EnterMonitor(pr_linker_lock); - - /* If the lbrary is already loaded, then add the static table information... */ - result = pr_UnlockedFindLibrary(name); - if (result != NULL) { - PR_ASSERT( (result->staticTable == NULL) || (result->staticTable == slt) ); - result->staticTable = slt; - goto unlock; - } - - /* Add library to list...Mark it static */ - lm = PR_NEWZAP(PRLibrary); - if (lm == NULL) goto unlock; - - lm->name = strdup(name); - lm->refCount = 1; - lm->dlh = pr_exe_loadmap ? pr_exe_loadmap->dlh : 0; - lm->staticTable = slt; - lm->next = pr_loadmap; - pr_loadmap = lm; - - result = lm; /* success */ - PR_ASSERT(lm->refCount == 1); - PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (static lib)", lm->name)); - unlock: - PR_ExitMonitor(pr_linker_lock); - return result; -} - -PR_IMPLEMENT(char *) -PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr) -{ -#if defined(USE_DLFCN) && defined(HAVE_DLADDR) - Dl_info dli; - char *result; - - if (dladdr((void *)addr, &dli) == 0) { - PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO()); - DLLErrorInternal(_MD_ERRNO()); - return NULL; - } - result = PR_Malloc(strlen(dli.dli_fname)+1); - if (result != NULL) { - strcpy(result, dli.dli_fname); - } - return result; -#elif defined(USE_MACH_DYLD) - char *result; - const char *image_name; - int i, count = _dyld_image_count(); - - for (i = 0; i < count; i++) { - image_name = _dyld_get_image_name(i); - if (strstr(image_name, name) != NULL) { - result = PR_Malloc(strlen(image_name)+1); - if (result != NULL) { - strcpy(result, image_name); - } - return result; - } - } - PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); - return NULL; -#elif defined(AIX) - char *result; -#define LD_INFO_INCREMENT 64 - struct ld_info *info; - unsigned int info_length = LD_INFO_INCREMENT * sizeof(struct ld_info); - struct ld_info *infop; - int loadflags = L_GETINFO | L_IGNOREUNLOAD; - - for (;;) { - info = PR_Malloc(info_length); - if (info == NULL) { - return NULL; - } - /* If buffer is too small, loadquery fails with ENOMEM. */ - if (loadquery(loadflags, info, info_length) != -1) { - break; - } - /* - * Calling loadquery when compiled for 64-bit with the - * L_IGNOREUNLOAD flag can cause an invalid argument error - * on AIX 5.1. Detect this error the first time that - * loadquery is called, and try calling it again without - * this flag set. - */ - if (errno == EINVAL && (loadflags & L_IGNOREUNLOAD)) { - loadflags &= ~L_IGNOREUNLOAD; - if (loadquery(loadflags, info, info_length) != -1) { - break; - } - } - PR_Free(info); - if (errno != ENOMEM) { - /* should not happen */ - _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); - return NULL; - } - /* retry with a larger buffer */ - info_length += LD_INFO_INCREMENT * sizeof(struct ld_info); - } - - for (infop = info; - ; - infop = (struct ld_info *)((char *)infop + infop->ldinfo_next)) { - unsigned long start = (unsigned long)infop->ldinfo_dataorg; - unsigned long end = start + infop->ldinfo_datasize; - if (start <= (unsigned long)addr && end > (unsigned long)addr) { - result = PR_Malloc(strlen(infop->ldinfo_filename)+1); - if (result != NULL) { - strcpy(result, infop->ldinfo_filename); - } - break; - } - if (!infop->ldinfo_next) { - PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); - result = NULL; - break; - } - } - PR_Free(info); - return result; -#elif defined(OSF1) - /* Contributed by Steve Streeter of HP */ - ldr_process_t process, ldr_my_process(); - ldr_module_t mod_id; - ldr_module_info_t info; - ldr_region_t regno; - ldr_region_info_t reginfo; - size_t retsize; - int rv; - char *result; - - /* Get process for which dynamic modules will be listed */ - - process = ldr_my_process(); - - /* Attach to process */ - - rv = ldr_xattach(process); - if (rv) { - /* should not happen */ - _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); - return NULL; - } - - /* Print information for list of modules */ - - mod_id = LDR_NULL_MODULE; - - for (;;) { - - /* Get information for the next module in the module list. */ - - ldr_next_module(process, &mod_id); - if (ldr_inq_module(process, mod_id, &info, sizeof(info), - &retsize) != 0) { - /* No more modules */ - break; - } - if (retsize < sizeof(info)) { - continue; - } - - /* - * Get information for each region in the module and check if any - * contain the address of this function. - */ - - for (regno = 0; ; regno++) { - if (ldr_inq_region(process, mod_id, regno, ®info, - sizeof(reginfo), &retsize) != 0) { - /* No more regions */ - break; - } - if (((unsigned long)reginfo.lri_mapaddr <= - (unsigned long)addr) && - (((unsigned long)reginfo.lri_mapaddr + reginfo.lri_size) > - (unsigned long)addr)) { - /* Found it. */ - result = PR_Malloc(strlen(info.lmi_name)+1); - if (result != NULL) { - strcpy(result, info.lmi_name); - } - return result; - } - } - } - PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); - return NULL; -#elif defined(HPUX) && defined(USE_HPSHL) - int index; - struct shl_descriptor desc; - char *result; - - for (index = 0; shl_get_r(index, &desc) == 0; index++) { - if (strstr(desc.filename, name) != NULL) { - result = PR_Malloc(strlen(desc.filename)+1); - if (result != NULL) { - strcpy(result, desc.filename); - } - return result; - } - } - /* - * Since the index value of a library is decremented if - * a library preceding it in the shared library search - * list was unloaded, it is possible that we missed some - * libraries as we went up the list. So we should go - * down the list to be sure that we not miss anything. - */ - for (index--; index >= 0; index--) { - if ((shl_get_r(index, &desc) == 0) - && (strstr(desc.filename, name) != NULL)) { - result = PR_Malloc(strlen(desc.filename)+1); - if (result != NULL) { - strcpy(result, desc.filename); - } - return result; - } - } - PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); - return NULL; -#elif defined(HPUX) && defined(USE_DLFCN) - struct load_module_desc desc; - char *result; - const char *module_name; - - if (dlmodinfo((unsigned long)addr, &desc, sizeof desc, NULL, 0, 0) == 0) { - PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO()); - DLLErrorInternal(_MD_ERRNO()); - return NULL; - } - module_name = dlgetname(&desc, sizeof desc, NULL, 0, 0); - if (module_name == NULL) { - /* should not happen */ - _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); - DLLErrorInternal(_MD_ERRNO()); - return NULL; - } - result = PR_Malloc(strlen(module_name)+1); - if (result != NULL) { - strcpy(result, module_name); - } - return result; -#elif defined(WIN32) - PRUnichar wname[MAX_PATH]; - HMODULE handle = NULL; - PRUnichar module_name[MAX_PATH]; - int len; - char *result; - - if (MultiByteToWideChar(CP_ACP, 0, name, -1, wname, MAX_PATH)) { - handle = GetModuleHandleW(wname); - } - if (handle == NULL) { - PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO()); - DLLErrorInternal(_MD_ERRNO()); - return NULL; - } - if (GetModuleFileNameW(handle, module_name, MAX_PATH) == 0) { - /* should not happen */ - _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); - return NULL; - } - len = WideCharToMultiByte(CP_ACP, 0, module_name, -1, - NULL, 0, NULL, NULL); - if (len == 0) { - _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); - return NULL; - } - result = PR_Malloc(len * sizeof(PRUnichar)); - if (result != NULL) { - WideCharToMultiByte(CP_ACP, 0, module_name, -1, - result, len, NULL, NULL); - } - return result; -#elif defined(XP_OS2) - HMODULE module = NULL; - char module_name[_MAX_PATH]; - char *result; - APIRET ulrc = DosQueryModFromEIP(&module, NULL, 0, NULL, NULL, (ULONG) addr); - if ((NO_ERROR != ulrc) || (NULL == module) ) { - PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO()); - DLLErrorInternal(_MD_ERRNO()); - return NULL; - } - ulrc = DosQueryModuleName(module, sizeof module_name, module_name); - if (NO_ERROR != ulrc) { - /* should not happen */ - _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); - return NULL; - } - result = PR_Malloc(strlen(module_name)+1); - if (result != NULL) { - strcpy(result, module_name); - } - return result; -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -#endif -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/Makefile.in 2013-01-03 14:49:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,379 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -DIRS = io linking malloc md memory misc threads - -ifeq ($(USE_PTHREADS), 1) - DIRS += pthreads -endif - -ifeq ($(USE_BTHREADS), 1) - DIRS += bthreads -endif - -ifeq ($(USE_CPLUS), 1) - DIRS += cplus -endif - -# -# Define platform-dependent OS_LIBS -# - -ifeq ($(OS_ARCH),SunOS) -MAPFILE = $(OBJDIR)/nsprmap.sun -GARBAGE += $(MAPFILE) -ifdef NS_USE_GCC -ifdef GCC_USE_GNU_LD -MKSHLIB += -Wl,--version-script,$(MAPFILE) -else -MKSHLIB += -Wl,-M,$(MAPFILE) -endif -else -MKSHLIB += -M $(MAPFILE) -endif -# -# In Solaris 2.6 or earlier, -lrt is called -lposix4. -# -LIBRT_TEST=$(firstword $(sort 5.7 $(OS_RELEASE))) -ifeq (5.7, $(LIBRT_TEST)) -LIBRT=-lrt -else -LIBRT=-lposix4 -endif - -ifdef USE_PTHREADS -OS_LIBS = -lpthread ${LIBRT} -lsocket -lnsl -ldl -lc -else -OS_LIBS = -lsocket -lnsl -ldl -lc -endif # USE_PTHREADS -ifeq ($(CPU_ARCH),sparc) -ifndef USE_64 -DSO_LDOPTS += -Wl,-f,\$$ORIGIN/cpu/\$$ISALIST/lib$(ULTRASPARC_LIBRARY)$(LIBRARY_VERSION).so -endif -endif # sparc -endif # SunOS - -ifeq ($(OS_ARCH), IRIX) -ifeq ($(USE_PTHREADS), 1) -OS_LIBS = -lpthread -endif -OS_LIBS += -lc -endif - -ifeq ($(OS_ARCH),AIX) -DSO_LDOPTS += -binitfini::_PR_Fini -OS_LIBS = -lodm -lcfg -ifeq ($(CLASSIC_NSPR),1) -ifeq ($(OS_RELEASE),4.1) -OS_LIBS += -lsvld -lc -else -OS_LIBS += -ldl -lc -endif -else -ifeq ($(OS_RELEASE),4.1) -OS_LIBS += -lpthreads -lsvld -lC_r -lC -lc_r -lm /usr/lib/libc.a -else -OS_LIBS += -lpthreads -ldl -lC_r -lC -lc_r -lm /usr/lib/libc.a -endif -endif -endif - -# On AIX, we override malloc in non-pthread versions. On AIX 4.2 or -# above, this requires that we use the rtl-enabled version of libc.a. -ifeq ($(OS_ARCH),AIX) -ifneq (,$(filter-out 3.2 4.1,$(OS_RELEASE))) -ifneq ($(USE_PTHREADS),1) -BUILD_AIX_RTL_LIBC = 1 -AIX_RTL_LIBC = $(OBJDIR)/libc.a -endif -endif -endif - -ifeq ($(OS_ARCH),OS2) -MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def -ADD_TO_DEF_FILE = cat $(srcdir)/os2extra.def >> $(MAPFILE) -GARBAGE += $(MAPFILE) -MKSHLIB += $(MAPFILE) -endif - -ifeq ($(OS_ARCH),OSF1) -ifeq ($(USE_PTHREADS), 1) -OS_LIBS = -lpthread -lrt -endif -ifneq ($(OS_RELEASE),V2.0) -OS_LIBS += -lc_r -endif -endif - -# Linux, GNU/Hurd, and GNU/kFreeBSD systems -ifneq (,$(filter Linux GNU%,$(OS_ARCH))) -ifeq ($(USE_PTHREADS), 1) -ifeq ($(OS_TARGET),Android) -# Android has no libpthread.so in NDK -OS_LIBS = -ldl -else -OS_LIBS = -lpthread -ldl -endif -else -OS_LIBS = -ldl -endif -ifneq ($(OS_TARGET),Android) -# Android has no librt - realtime functions are in libc -OS_LIBS += -lrt -endif -endif - -ifeq ($(OS_ARCH),HP-UX) -ifeq ($(USE_PTHREADS), 1) -ifeq (,$(filter-out B.10.10 B.10.20,$(OS_RELEASE))) -OS_LIBS = -ldce -else -OS_LIBS = -lpthread -lrt -endif -endif -ifeq ($(PTHREADS_USER), 1) -OS_LIBS = -lpthread -endif -ifeq ($(basename $(OS_RELEASE)),A.09) -OS_LIBS += -ldld -L/lib/pa1.1 -lm -else -OS_LIBS += -ldld -lm -lc -endif -ifneq ($(OS_TEST),ia64) -ifndef USE_64 -DSO_LDOPTS += +I PR_HPUX10xInit -endif -endif -endif - -ifeq ($(OS_ARCH),UNIXWARE) -OS_LIBS = -lsocket -lc -endif - -ifeq ($(OS_ARCH),WINNT) -ifdef NS_USE_GCC -OS_LIBS = -ladvapi32 -lwsock32 -lwinmm -else -OS_LIBS = advapi32.lib wsock32.lib winmm.lib -endif -endif - -ifeq ($(OS_ARCH),WINCE) -OS_LIBS = ws2.lib -endif - -ifeq ($(OS_TARGET),Android) -OS_LIBS += -llog -endif - -ifeq ($(OS_TARGET),MacOSX) -OS_LIBS = -framework CoreServices -framework CoreFoundation -endif - -EXTRA_LIBS += $(OS_LIBS) - -# -# Define platform-dependent OBJS -# - -OBJS = \ - $(OBJDIR)/prvrsion.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prfdcach.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prmwait.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prmapopt.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/priometh.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prlayer.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prlog.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prmmap.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prpolevt.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prprf.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prscanf.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prstdio.$(OBJ_SUFFIX) \ - threads/$(OBJDIR)/prcmon.$(OBJ_SUFFIX) \ - threads/$(OBJDIR)/prrwlock.$(OBJ_SUFFIX) \ - threads/$(OBJDIR)/prtpd.$(OBJ_SUFFIX) \ - linking/$(OBJDIR)/prlink.$(OBJ_SUFFIX) \ - malloc/$(OBJDIR)/prmalloc.$(OBJ_SUFFIX) \ - malloc/$(OBJDIR)/prmem.$(OBJ_SUFFIX) \ - md/$(OBJDIR)/prosdep.$(OBJ_SUFFIX) \ - memory/$(OBJDIR)/prshm.$(OBJ_SUFFIX) \ - memory/$(OBJDIR)/prshma.$(OBJ_SUFFIX) \ - memory/$(OBJDIR)/prseg.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/pralarm.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/pratom.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prcountr.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prdtoa.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prenv.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prerr.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prerror.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prerrortable.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prinit.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prinrval.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/pripc.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prlog2.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prlong.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prnetdb.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/praton.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prolock.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prrng.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prsystem.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prthinfo.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prtpool.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prtrace.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/prtime.$(OBJ_SUFFIX) - -ifdef USE_PTHREADS -OBJS += \ - pthreads/$(OBJDIR)/ptsynch.$(OBJ_SUFFIX) \ - pthreads/$(OBJDIR)/ptio.$(OBJ_SUFFIX) \ - pthreads/$(OBJDIR)/ptthread.$(OBJ_SUFFIX) \ - pthreads/$(OBJDIR)/ptmisc.$(OBJ_SUFFIX) -else -OBJS += \ - io/$(OBJDIR)/prdir.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prfile.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prio.$(OBJ_SUFFIX) \ - io/$(OBJDIR)/prsocket.$(OBJ_SUFFIX) \ - misc/$(OBJDIR)/pripcsem.$(OBJ_SUFFIX) - -ifndef USE_BTHREADS -OBJS += \ - threads/$(OBJDIR)/prcthr.$(OBJ_SUFFIX) \ - threads/$(OBJDIR)/prdump.$(OBJ_SUFFIX) \ - threads/$(OBJDIR)/prmon.$(OBJ_SUFFIX) \ - threads/$(OBJDIR)/prsem.$(OBJ_SUFFIX) \ - threads/combined/$(OBJDIR)/prucpu.$(OBJ_SUFFIX) \ - threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \ - threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \ - threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \ - threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX) -endif - -endif - -ifeq ($(USE_CPLUS), 1) -OBJS += \ - cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rccv.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rcfileio.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rcinrval.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rcio.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rclock.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rcnetdb.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rcnetio.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rcthread.$(OBJ_SUFFIX) \ - cplus/$(OBJDIR)/rctime.$(OBJ_SUFFIX) -endif - -ifeq ($(OS_ARCH), WINNT) -RES=$(OBJDIR)/nspr.res -RESNAME=nspr.rc -endif # WINNT - -include $(srcdir)/md/$(PR_MD_ARCH_DIR)/objs.mk -ifdef USE_BTHREADS -include $(srcdir)/bthreads/objs.mk -endif - -LIBRARY_NAME = nspr -LIBRARY_VERSION = $(MOD_MAJOR_VERSION) - -RELEASE_LIBS = $(TARGETS) - -include $(topsrcdir)/config/rules.mk - -ifeq ($(BUILD_AIX_RTL_LIBC),1) -TARGETS += $(AIX_RTL_LIBC) -# XXX is this a shared library? -endif - -# -# Version information generation (begin) -# -ECHO = echo -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private -TINC = $(OBJDIR)/_pr_bld.h - -ifeq ($(OS_TARGET),OS2) -PROD = nspr$(MOD_MAJOR_VERSION).$(DLL_SUFFIX) -else -PROD = $(notdir $(SHARED_LIBRARY)) -endif - -NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now -SH_DATE = $(shell date "+%Y-%m-%d %T") -SH_NOW = $(shell $(NOW)) - -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - SUF = i64 -else - SUF = LL -endif - -DEFINES += -D_NSPR_BUILD_ - -GARBAGE += $(TINC) - -$(TINC): - @$(MAKE_OBJDIR) - @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC) - @if test ! -z "$(SH_NOW)"; then \ - $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \ - else \ - true; \ - fi - @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) - - -$(OBJDIR)/prvrsion.$(OBJ_SUFFIX): prvrsion.c $(TINC) -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $< -else - $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< -endif -# -# Version information generation (end) -# - - -# We use a 'build' target here to ensure that we build $(TARGETS) after -# looping over $(DIRS) to create the object files in a parallel build. -# Recipe commands are executed sequentially in a parallel build while -# target dependencies are executed in parallel. -export:: - $(MAKE) build - -# -# The Client build wants the shared libraries in $(dist_bindir) -# so we also install them there. -# - -build:: $(TARGETS) - $(INSTALL) -m 444 $(TARGETS) $(dist_libdir) -ifdef SHARED_LIBRARY -ifeq ($(OS_ARCH),HP-UX) - $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir) - $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir) -else - $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir) -endif -endif - -ifeq ($(BUILD_AIX_RTL_LIBC),1) -$(AIX_RTL_LIBC): /usr/ccs/lib/libc.a - rtl_enable -o $@ $< -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/malloc/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/malloc/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/malloc/.cvsignore 2001-05-12 04:22:54.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/malloc/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/malloc/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/malloc/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/malloc/Makefile.in 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/malloc/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -CSRCS = prmalloc.c prmem.c - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/malloc/prmalloc.c nspr-4.10.7/mozilla/nsprpub/pr/src/malloc/prmalloc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/malloc/prmalloc.c 2012-03-06 13:14:11.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/malloc/prmalloc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1142 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -/* -** We override malloc etc. on any platform which has preemption + -** nspr20 user level threads. When we're debugging, we can make our -** version of malloc fail occasionally. -*/ -#ifdef _PR_OVERRIDE_MALLOC - -/* -** Thread safe version of malloc, calloc, realloc, free -*/ -#include - -#ifdef DEBUG -#define SANITY -#define EXTRA_SANITY -#else -#undef SANITY -#undef EXTRA_SANITY -#endif - -/* Forward decls */ -void *_PR_UnlockedMalloc(size_t size); -void _PR_UnlockedFree(void *ptr); -void *_PR_UnlockedRealloc(void *ptr, size_t size); -void *_PR_UnlockedCalloc(size_t n, size_t elsize); - -/************************************************************************/ - -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - */ - -/* - * Defining SANITY will enable some checks which will tell you if the users - * program did botch something - */ - -/* - * Defining EXTRA_SANITY will enable some checks which are mostly related - * to internal conditions in malloc.c - */ - -/* - * Very verbose progress on stdout... - */ -#if 0 -# define TRACE(foo) printf foo -static int malloc_event; -#else -# define TRACE(foo) -#endif - -/* XXX Pick a number, any number */ -# define malloc_pagesize 4096UL -# define malloc_pageshift 12UL - -#ifdef XP_UNIX -#include -#include -#include -#include -#include -#include -#include -#endif - -/* - * This structure describes a page's worth of chunks. - */ - -struct pginfo { - struct pginfo *next; /* next on the free list */ - char *page; /* Pointer to the page */ - u_short size; /* size of this page's chunks */ - u_short shift; /* How far to shift for this size chunks */ - u_short free; /* How many free chunks */ - u_short total; /* How many chunk */ - u_long bits[1]; /* Which chunks are free */ -}; - -struct pgfree { - struct pgfree *next; /* next run of free pages */ - struct pgfree *prev; /* prev run of free pages */ - char *page; /* pointer to free pages */ - char *end; /* pointer to end of free pages */ - u_long size; /* number of bytes free */ -}; - -/* - * How many bits per u_long in the bitmap. - * Change only if not 8 bits/byte - */ -#define MALLOC_BITS (8*sizeof(u_long)) - -/* - * Magic values to put in the page_directory - */ -#define MALLOC_NOT_MINE ((struct pginfo*) 0) -#define MALLOC_FREE ((struct pginfo*) 1) -#define MALLOC_FIRST ((struct pginfo*) 2) -#define MALLOC_FOLLOW ((struct pginfo*) 3) -#define MALLOC_MAGIC ((struct pginfo*) 4) - -/* - * Set to one when malloc_init has been called - */ -static unsigned initialized; - -/* - * The size of a page. - * Must be a integral multiplum of the granularity of mmap(2). - * Your toes will curl if it isn't a power of two - */ -#define malloc_pagemask ((malloc_pagesize)-1) - -/* - * The size of the largest chunk. - * Half a page. - */ -#define malloc_maxsize ((malloc_pagesize)>>1) - -/* - * malloc_pagesize == 1 << malloc_pageshift - */ -#ifndef malloc_pageshift -static unsigned malloc_pageshift; -#endif /* malloc_pageshift */ - -/* - * The smallest allocation we bother about. - * Must be power of two - */ -#ifndef malloc_minsize -static unsigned malloc_minsize; -#endif /* malloc_minsize */ - -/* - * The largest chunk we care about. - * Must be smaller than pagesize - * Must be power of two - */ -#ifndef malloc_maxsize -static unsigned malloc_maxsize; -#endif /* malloc_maxsize */ - -#ifndef malloc_cache -static unsigned malloc_cache; -#endif /* malloc_cache */ - -/* - * The offset from pagenumber to index into the page directory - */ -static u_long malloc_origo; - -/* - * The last index in the page directory we care about - */ -static u_long last_index; - -/* - * Pointer to page directory. - * Allocated "as if with" malloc - */ -static struct pginfo **page_dir; - -/* - * How many slots in the page directory - */ -static unsigned malloc_ninfo; - -/* - * Free pages line up here - */ -static struct pgfree free_list; - -/* - * Abort() if we fail to get VM ? - */ -static int malloc_abort; - -#ifdef SANITY -/* - * Are we trying to die ? - */ -static int suicide; -#endif - -/* - * dump statistics - */ -static int malloc_stats; - -/* - * always realloc ? - */ -static int malloc_realloc; - -/* - * my last break. - */ -static void *malloc_brk; - -/* - * one location cache for free-list holders - */ -static struct pgfree *px; - -static int set_pgdir(void *ptr, struct pginfo *info); -static int extend_page_directory(u_long index); - -#ifdef SANITY -void -malloc_dump(FILE *fd) -{ - struct pginfo **pd; - struct pgfree *pf; - int j; - - pd = page_dir; - - /* print out all the pages */ - for(j=0;j<=last_index;j++) { - fprintf(fd,"%08lx %5d ",(j+malloc_origo) << malloc_pageshift,j); - if (pd[j] == MALLOC_NOT_MINE) { - for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++) - ; - j--; - fprintf(fd,".. %5d not mine\n", j); - } else if (pd[j] == MALLOC_FREE) { - for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++) - ; - j--; - fprintf(fd,".. %5d free\n", j); - } else if (pd[j] == MALLOC_FIRST) { - for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++) - ; - j--; - fprintf(fd,".. %5d in use\n", j); - } else if (pd[j] < MALLOC_MAGIC) { - fprintf(fd,"(%p)\n", pd[j]); - } else { - fprintf(fd,"%p %d (of %d) x %d @ %p --> %p\n", - pd[j],pd[j]->free, pd[j]->total, - pd[j]->size, pd[j]->page, pd[j]->next); - } - } - - for(pf=free_list.next; pf; pf=pf->next) { - fprintf(fd,"Free: @%p [%p...%p[ %ld ->%p <-%p\n", - pf,pf->page,pf->end,pf->size,pf->prev,pf->next); - if (pf == pf->next) { - fprintf(fd,"Free_list loops.\n"); - break; - } - } - - /* print out various info */ - fprintf(fd,"Minsize\t%d\n",malloc_minsize); - fprintf(fd,"Maxsize\t%ld\n",malloc_maxsize); - fprintf(fd,"Pagesize\t%ld\n",malloc_pagesize); - fprintf(fd,"Pageshift\t%ld\n",malloc_pageshift); - fprintf(fd,"FirstPage\t%ld\n",malloc_origo); - fprintf(fd,"LastPage\t%ld %lx\n",last_index+malloc_pageshift, - (last_index + malloc_pageshift) << malloc_pageshift); - fprintf(fd,"Break\t%ld\n",(u_long)sbrk(0) >> malloc_pageshift); -} - -static void wrterror(char *fmt, ...) -{ - char *q = "malloc() error: "; - char buf[100]; - va_list ap; - - suicide = 1; - - va_start(ap, fmt); - PR_vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - fputs(q, stderr); - fputs(buf, stderr); - - malloc_dump(stderr); - PR_Abort(); -} - -static void wrtwarning(char *fmt, ...) -{ - char *q = "malloc() warning: "; - char buf[100]; - va_list ap; - - va_start(ap, fmt); - PR_vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - fputs(q, stderr); - fputs(buf, stderr); -} -#endif /* SANITY */ - - -/* - * Allocate a number of pages from the OS - */ -static caddr_t -map_pages(int pages, int update) -{ - caddr_t result,tail; - - result = ((caddr_t)sbrk(0)) + malloc_pagemask - 1; - result = (caddr_t) ((u_long)result & ~malloc_pagemask); - tail = result + (pages << malloc_pageshift); - if (!brk(tail)) { - last_index = ((u_long)tail >> malloc_pageshift) - malloc_origo -1; - malloc_brk = tail; - TRACE(("%6d S %p .. %p\n",malloc_event++, result, tail)); - if (!update || last_index < malloc_ninfo || - extend_page_directory(last_index)) - return result; - } - TRACE(("%6d s %d %p %d\n",malloc_event++,pages,sbrk(0),errno)); -#ifdef EXTRA_SANITY - wrterror("map_pages fails\n"); -#endif - return 0; -} - -#define set_bit(_pi,_bit) \ - (_pi)->bits[(_bit)/MALLOC_BITS] |= 1L<<((_bit)%MALLOC_BITS) - -#define clr_bit(_pi,_bit) \ - (_pi)->bits[(_bit)/MALLOC_BITS] &= ~(1L<<((_bit)%MALLOC_BITS)); - -#define tst_bit(_pi,_bit) \ - ((_pi)->bits[(_bit)/MALLOC_BITS] & (1L<<((_bit)%MALLOC_BITS))) - -/* - * Extend page directory - */ -static int -extend_page_directory(u_long index) -{ - struct pginfo **young, **old; - int i; - - TRACE(("%6d E %lu\n",malloc_event++,index)); - - /* Make it this many pages */ - i = index * sizeof *page_dir; - i /= malloc_pagesize; - i += 2; - - /* Get new pages, if you used this much mem you don't care :-) */ - young = (struct pginfo**) map_pages(i,0); - if (!young) - return 0; - - /* Copy the old stuff */ - memset(young, 0, i * malloc_pagesize); - memcpy(young, page_dir, - malloc_ninfo * sizeof *page_dir); - - /* register the new size */ - malloc_ninfo = i * malloc_pagesize / sizeof *page_dir; - - /* swap the pointers */ - old = page_dir; - page_dir = young; - - /* Mark the pages */ - index = ((u_long)young >> malloc_pageshift) - malloc_origo; - page_dir[index] = MALLOC_FIRST; - while (--i) { - page_dir[++index] = MALLOC_FOLLOW; - } - - /* Now free the old stuff */ - _PR_UnlockedFree(old); - return 1; -} - -/* - * Set entry in page directory. - * Extend page directory if need be. - */ -static int -set_pgdir(void *ptr, struct pginfo *info) -{ - u_long index = ((u_long)ptr >> malloc_pageshift) - malloc_origo; - - if (index >= malloc_ninfo && !extend_page_directory(index)) - return 0; - page_dir[index] = info; - return 1; -} - -/* - * Initialize the world - */ -static void -malloc_init (void) -{ - int i; - char *p; - - TRACE(("%6d I\n",malloc_event++)); -#ifdef DEBUG - for (p=getenv("MALLOC_OPTIONS"); p && *p; p++) { - switch (*p) { - case 'a': malloc_abort = 0; break; - case 'A': malloc_abort = 1; break; - case 'd': malloc_stats = 0; break; - case 'D': malloc_stats = 1; break; - case 'r': malloc_realloc = 0; break; - case 'R': malloc_realloc = 1; break; - default: - wrtwarning("Unknown chars in MALLOC_OPTIONS\n"); - break; - } - } -#endif - -#ifndef malloc_pagesize - /* determine our pagesize */ - malloc_pagesize = getpagesize(); -#endif /* malloc_pagesize */ - -#ifndef malloc_pageshift - /* determine how much we shift by to get there */ - for (i = malloc_pagesize; i > 1; i >>= 1) - malloc_pageshift++; -#endif /* malloc_pageshift */ - -#ifndef malloc_cache - malloc_cache = 50 << malloc_pageshift; -#endif /* malloc_cache */ - -#ifndef malloc_minsize - /* - * find the smallest size allocation we will bother about. - * this is determined as the smallest allocation that can hold - * it's own pginfo; - */ - i = 2; - for(;;) { - int j; - - /* Figure out the size of the bits */ - j = malloc_pagesize/i; - j /= 8; - if (j < sizeof(u_long)) - j = sizeof (u_long); - if (sizeof(struct pginfo) + j - sizeof (u_long) <= i) - break; - i += i; - } - malloc_minsize = i; -#endif /* malloc_minsize */ - - - /* Allocate one page for the page directory */ - page_dir = (struct pginfo **) map_pages(1,0); -#ifdef SANITY - if (!page_dir) - wrterror("fatal: my first mmap failed. (check limits ?)\n"); -#endif - - /* - * We need a maximum of malloc_pageshift buckets, steal these from the - * front of the page_directory; - */ - malloc_origo = (u_long) page_dir >> malloc_pageshift; - malloc_origo -= malloc_pageshift; - - /* Clear it */ - memset(page_dir,0,malloc_pagesize); - - /* Find out how much it tells us */ - malloc_ninfo = malloc_pagesize / sizeof *page_dir; - - /* Plug the page directory into itself */ - i = set_pgdir(page_dir,MALLOC_FIRST); -#ifdef SANITY - if (!i) - wrterror("fatal: couldn't set myself in the page directory\n"); -#endif - - /* Been here, done that */ - initialized++; -} - -/* - * Allocate a number of complete pages - */ -static void *malloc_pages(size_t size) -{ - void *p,*delay_free = 0; - int i; - struct pgfree *pf; - u_long index; - - /* How many pages ? */ - size += (malloc_pagesize-1); - size &= ~malloc_pagemask; - - p = 0; - /* Look for free pages before asking for more */ - for(pf = free_list.next; pf; pf = pf->next) { -#ifdef EXTRA_SANITY - if (pf->page == pf->end) - wrterror("zero entry on free_list\n"); - if (pf->page > pf->end) { - TRACE(("%6d !s %p %p %p <%d>\n",malloc_event++, - pf,pf->page,pf->end,__LINE__)); - wrterror("sick entry on free_list\n"); - } - if ((void*)pf->page >= (void*)sbrk(0)) - wrterror("entry on free_list past brk\n"); - if (page_dir[((u_long)pf->page >> malloc_pageshift) - malloc_origo] - != MALLOC_FREE) { - TRACE(("%6d !f %p %p %p <%d>\n",malloc_event++, - pf,pf->page,pf->end,__LINE__)); - wrterror("non-free first page on free-list\n"); - } - if (page_dir[((u_long)pf->end >> malloc_pageshift) - 1 - malloc_origo] - != MALLOC_FREE) - wrterror("non-free last page on free-list\n"); -#endif /* EXTRA_SANITY */ - if (pf->size < size) - continue; - else if (pf->size == size) { - p = pf->page; - if (pf->next) - pf->next->prev = pf->prev; - pf->prev->next = pf->next; - delay_free = pf; - break; - } else { - p = pf->page; - pf->page += size; - pf->size -= size; - break; - } - } -#ifdef EXTRA_SANITY - if (p && page_dir[((u_long)p >> malloc_pageshift) - malloc_origo] - != MALLOC_FREE) { - wrterror("allocated non-free page on free-list\n"); - } -#endif /* EXTRA_SANITY */ - - size >>= malloc_pageshift; - - /* Map new pages */ - if (!p) - p = map_pages(size,1); - - if (p) { - /* Mark the pages in the directory */ - index = ((u_long)p >> malloc_pageshift) - malloc_origo; - page_dir[index] = MALLOC_FIRST; - for (i=1;i> bits)+MALLOC_BITS-1) / MALLOC_BITS); - if ((1<<(bits)) <= l+l) { - bp = (struct pginfo *)pp; - } else { - bp = (struct pginfo *)_PR_UnlockedMalloc(l); - } - if (!bp) - return 0; - bp->size = (1<shift = bits; - bp->total = bp->free = malloc_pagesize >> bits; - bp->next = page_dir[bits]; - bp->page = (char*)pp; - i = set_pgdir(pp,bp); - if (!i) - return 0; - - /* We can safely assume that there is nobody in this chain */ - page_dir[bits] = bp; - - /* set all valid bits in the bits */ - k = bp->total; - i = 0; -/* - for(;k-i >= MALLOC_BITS; i += MALLOC_BITS) - bp->bits[i / MALLOC_BITS] = ~0; -*/ - for(; i < k; i++) - set_bit(bp,i); - - if (bp != pp) - return 1; - - /* We may have used the first ones already */ - for(i=0;l > 0;i++) { - clr_bit(bp,i); - bp->free--; - bp->total--; - l -= (1 << bits); - } - return 1; -} - -/* - * Allocate a fragment - */ -static void *malloc_bytes(size_t size) -{ - size_t s; - int j; - struct pginfo *bp; - int k; - u_long *lp, bf; - - /* Don't bother with anything less than this */ - if (size < malloc_minsize) { - size = malloc_minsize; - } - - /* Find the right bucket */ - j = 1; - s = size - 1; - while (s >>= 1) { - j++; - } - - /* If it's empty, make a page more of that size chunks */ - if (!page_dir[j] && !malloc_make_chunks(j)) - return 0; - - /* Find first word of bitmap which isn't empty */ - bp = page_dir[j]; - for (lp = bp->bits; !*lp; lp++) - ; - - /* Find that bit */ - bf = *lp; - k = 0; - while ((bf & 1) == 0) { - bf >>= 1; - k++; - } - - *lp ^= 1L<free--; - if (!bp->free) { - page_dir[j] = bp->next; - bp->next = 0; - } - k += (lp - bp->bits)*MALLOC_BITS; - return bp->page + (k << bp->shift); -} - -void *_PR_UnlockedMalloc(size_t size) -{ - void *result; - - /* Round up to a multiple of 8 bytes */ - if (size & 7) { - size = size + 8 - (size & 7); - } - - if (!initialized) - malloc_init(); - -#ifdef SANITY - if (suicide) - PR_Abort(); -#endif - - if (size <= malloc_maxsize) - result = malloc_bytes(size); - else - result = malloc_pages(size); -#ifdef SANITY - if (malloc_abort && !result) - wrterror("malloc() returns NULL\n"); -#endif - TRACE(("%6d M %p %d\n",malloc_event++,result,size)); - - return result; -} - -void *_PR_UnlockedMemalign(size_t alignment, size_t size) -{ - void *result; - - /* - * alignment has to be a power of 2 - */ - - if ((size <= alignment) && (alignment <= malloc_maxsize)) - size = alignment; - else - size += alignment - 1; - - /* Round up to a multiple of 8 bytes */ - if (size & 7) { - size = size + 8 - (size & 7); - } - - if (!initialized) - malloc_init(); - -#ifdef SANITY - if (suicide) - abort(); -#endif - - if (size <= malloc_maxsize) - result = malloc_bytes(size); - else - result = malloc_pages(size); -#ifdef SANITY - if (malloc_abort && !result) - wrterror("malloc() returns NULL\n"); -#endif - TRACE(("%6d A %p %d\n",malloc_event++,result,size)); - - if ((u_long)result & (alignment - 1)) - return ((void *)(((u_long)result + alignment) & ~(alignment - 1))); - else - return result; -} - -void *_PR_UnlockedCalloc(size_t n, size_t nelem) -{ - void *p; - - /* Compute total size and then round up to a double word amount */ - n *= nelem; - if (n & 7) { - n = n + 8 - (n & 7); - } - - /* Get the memory */ - p = _PR_UnlockedMalloc(n); - if (p) { - /* Zero it */ - memset(p, 0, n); - } - return p; -} - -/* - * Change an allocation's size - */ -void *_PR_UnlockedRealloc(void *ptr, size_t size) -{ - void *p; - u_long osize,page,index,tmp_index; - struct pginfo **mp; - - if (!initialized) - malloc_init(); - -#ifdef SANITY - if (suicide) - PR_Abort(); -#endif - - /* used as free() */ - TRACE(("%6d R %p %d\n",malloc_event++, ptr, size)); - if (ptr && !size) { - _PR_UnlockedFree(ptr); - return _PR_UnlockedMalloc (1); - } - - /* used as malloc() */ - if (!ptr) { - p = _PR_UnlockedMalloc(size); - return p; - } - - /* Find the page directory entry for the page in question */ - page = (u_long)ptr >> malloc_pageshift; - index = page - malloc_origo; - - /* - * check if memory was allocated by memalign - */ - tmp_index = index; - while (page_dir[tmp_index] == MALLOC_FOLLOW) - tmp_index--; - if (tmp_index != index) { - /* - * memalign-allocated memory - */ - index = tmp_index; - page = index + malloc_origo; - ptr = (void *) (page << malloc_pageshift); - } - TRACE(("%6d R2 %p %d\n",malloc_event++, ptr, size)); - - /* make sure it makes sense in some fashion */ - if (index < malloc_pageshift || index > last_index) { -#ifdef SANITY - wrtwarning("junk pointer passed to realloc()\n"); -#endif - return 0; - } - - /* find the size of that allocation, and see if we need to relocate */ - mp = &page_dir[index]; - if (*mp == MALLOC_FIRST) { - osize = malloc_pagesize; - while (mp[1] == MALLOC_FOLLOW) { - osize += malloc_pagesize; - mp++; - } - if (!malloc_realloc && - size < osize && - size > malloc_maxsize && - size > (osize - malloc_pagesize)) { - return ptr; - } - } else if (*mp >= MALLOC_MAGIC) { - osize = (*mp)->size; - if (!malloc_realloc && - size < osize && - (size > (*mp)->size/2 || (*mp)->size == malloc_minsize)) { - return ptr; - } - } else { -#ifdef SANITY - wrterror("realloc() of wrong page.\n"); -#endif - } - - /* try to reallocate */ - p = _PR_UnlockedMalloc(size); - - if (p) { - /* copy the lesser of the two sizes */ - if (osize < size) - memcpy(p,ptr,osize); - else - memcpy(p,ptr,size); - _PR_UnlockedFree(ptr); - } -#ifdef DEBUG - else if (malloc_abort) - wrterror("realloc() returns NULL\n"); -#endif - - return p; -} - -/* - * Free a sequence of pages - */ - -static void -free_pages(char *ptr, u_long page, int index, struct pginfo *info) -{ - int i; - struct pgfree *pf,*pt; - u_long l; - char *tail; - - TRACE(("%6d FP %p %d\n",malloc_event++, ptr, page)); - /* Is it free already ? */ - if (info == MALLOC_FREE) { -#ifdef SANITY - wrtwarning("freeing free page at %p.\n", ptr); -#endif - return; - } - -#ifdef SANITY - /* Is it not the right place to begin ? */ - if (info != MALLOC_FIRST) - wrterror("freeing wrong page.\n"); - - /* Is this really a pointer to a page ? */ - if ((u_long)ptr & malloc_pagemask) - wrterror("freeing messed up page pointer.\n"); -#endif - - /* Count how many pages it is anyway */ - page_dir[index] = MALLOC_FREE; - for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++) - page_dir[index + i] = MALLOC_FREE; - - l = i << malloc_pageshift; - - tail = ptr+l; - - /* add to free-list */ - if (!px) - px = (struct pgfree*)_PR_UnlockedMalloc(sizeof *pt); - /* XXX check success */ - px->page = ptr; - px->end = tail; - px->size = l; - if (!free_list.next) { - px->next = free_list.next; - px->prev = &free_list; - free_list.next = px; - pf = px; - px = 0; - } else { - tail = ptr+l; - for(pf = free_list.next; pf->next && pf->end < ptr; pf = pf->next) - ; - for(; pf; pf = pf->next) { - if (pf->end == ptr ) { - /* append to entry */ - pf->end += l; - pf->size += l; - if (pf->next && pf->end == pf->next->page ) { - pt = pf->next; - pf->end = pt->end; - pf->size += pt->size; - pf->next = pt->next; - if (pf->next) - pf->next->prev = pf; - _PR_UnlockedFree(pt); - } - } else if (pf->page == tail) { - /* prepend to entry */ - pf->size += l; - pf->page = ptr; - } else if (pf->page > ptr) { - px->next = pf; - px->prev = pf->prev; - pf->prev = px; - px->prev->next = px; - pf = px; - px = 0; - } else if (!pf->next) { - px->next = 0; - px->prev = pf; - pf->next = px; - pf = px; - px = 0; - } else { - continue; - } - break; - } - } - if (!pf->next && - pf->size > malloc_cache && - pf->end == malloc_brk && - malloc_brk == (void*)sbrk(0)) { - pf->end = pf->page + malloc_cache; - pf->size = malloc_cache; - TRACE(("%6d U %p %d\n",malloc_event++,pf->end,pf->end - pf->page)); - brk(pf->end); - malloc_brk = pf->end; - /* Find the page directory entry for the page in question */ - page = (u_long)pf->end >> malloc_pageshift; - index = page - malloc_origo; - /* Now update the directory */ - for(i=index;i <= last_index;) - page_dir[i++] = MALLOC_NOT_MINE; - last_index = index - 1; - } -} - -/* - * Free a chunk, and possibly the page it's on, if the page becomes empty. - */ - -static void -free_bytes(void *ptr, u_long page, int index, struct pginfo *info) -{ - int i; - struct pginfo **mp; - void *vp; - - /* Make sure that pointer is multiplum of chunk-size */ -#ifdef SANITY - if ((u_long)ptr & (info->size - 1)) - wrterror("freeing messed up chunk pointer\n"); -#endif - - /* Find the chunk number on the page */ - i = ((u_long)ptr & malloc_pagemask) >> info->shift; - - /* See if it's free already */ - if (tst_bit(info,i)) { -#ifdef SANITY - wrtwarning("freeing free chunk at %p\n", ptr); -#endif - return; - } - - /* Mark it free */ - set_bit(info,i); - info->free++; - - /* If the page was full before, we need to put it on the queue now */ - if (info->free == 1) { - mp = page_dir + info->shift; - while (*mp && (*mp)->next && (*mp)->next->page < info->page) - mp = &(*mp)->next; - info->next = *mp; - *mp = info; - return; - } - - /* If this page isn't empty, don't do anything. */ - if (info->free != info->total) - return; - - /* We may want to keep at least one page of each size chunks around. */ - mp = page_dir + info->shift; - if (0 && (*mp == info) && !info->next) - return; - - /* Find & remove this page in the queue */ - while (*mp != info) { - mp = &((*mp)->next); -#ifdef EXTRA_SANITY - if (!*mp) { - TRACE(("%6d !q %p\n",malloc_event++,info)); - wrterror("Not on queue\n"); - } -#endif - } - *mp = info->next; - - /* Free the page & the info structure if need be */ - set_pgdir(info->page,MALLOC_FIRST); - if((void*)info->page == (void*)info) { - _PR_UnlockedFree(info->page); - } else { - vp = info->page; - _PR_UnlockedFree(info); - _PR_UnlockedFree(vp); - } -} - -void _PR_UnlockedFree(void *ptr) -{ - u_long page; - struct pginfo *info; - int index, tmp_index; - - TRACE(("%6d F %p\n",malloc_event++,ptr)); - /* This is legal */ - if (!ptr) - return; - -#ifdef SANITY - /* There wouldn't be anything to free */ - if (!initialized) { - wrtwarning("free() called before malloc() ever got called\n"); - return; - } -#endif - -#ifdef SANITY - if (suicide) - PR_Abort(); -#endif - - /* Find the page directory entry for the page in question */ - page = (u_long)ptr >> malloc_pageshift; - index = page - malloc_origo; - - /* - * check if memory was allocated by memalign - */ - tmp_index = index; - while (page_dir[tmp_index] == MALLOC_FOLLOW) - tmp_index--; - if (tmp_index != index) { - /* - * memalign-allocated memory - */ - index = tmp_index; - page = index + malloc_origo; - ptr = (void *) (page << malloc_pageshift); - } - /* make sure it makes sense in some fashion */ - if (index < malloc_pageshift) { -#ifdef SANITY - wrtwarning("junk pointer %p (low) passed to free()\n", ptr); -#endif - return; - } - if (index > last_index) { -#ifdef SANITY - wrtwarning("junk pointer %p (high) passed to free()\n", ptr); -#endif - return; - } - - /* handle as page-allocation or chunk allocation */ - info = page_dir[index]; - if (info < MALLOC_MAGIC) - free_pages((char*)ptr, page, index, info); - else - free_bytes(ptr,page,index,info); - return; -} -#endif /* _PR_OVERRIDE_MALLOC */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/malloc/prmem.c nspr-4.10.7/mozilla/nsprpub/pr/src/malloc/prmem.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/malloc/prmem.c 2012-03-06 13:14:11.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/malloc/prmem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,694 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Thread safe versions of malloc, free, realloc, calloc and cfree. -*/ - -#include "primpl.h" - -#ifdef _PR_ZONE_ALLOCATOR - -/* -** The zone allocator code must use native mutexes and cannot -** use PRLocks because PR_NewLock calls PR_Calloc, resulting -** in cyclic dependency of initialization. -*/ - -#include - -union memBlkHdrUn; - -typedef struct MemoryZoneStr { - union memBlkHdrUn *head; /* free list */ - pthread_mutex_t lock; - size_t blockSize; /* size of blocks on this free list */ - PRUint32 locked; /* current state of lock */ - PRUint32 contention; /* counter: had to wait for lock */ - PRUint32 hits; /* allocated from free list */ - PRUint32 misses; /* had to call malloc */ - PRUint32 elements; /* on free list */ -} MemoryZone; - -typedef union memBlkHdrUn { - unsigned char filler[48]; /* fix the size of this beast */ - struct memBlkHdrStr { - union memBlkHdrUn *next; - MemoryZone *zone; - size_t blockSize; - size_t requestedSize; - PRUint32 magic; - } s; -} MemBlockHdr; - -#define MEM_ZONES 7 -#define THREAD_POOLS 11 /* prime number for modulus */ -#define ZONE_MAGIC 0x0BADC0DE - -static MemoryZone zones[MEM_ZONES][THREAD_POOLS]; - -static PRBool use_zone_allocator = PR_FALSE; - -static void pr_ZoneFree(void *ptr); - -void -_PR_DestroyZones(void) -{ - int i, j; - - if (!use_zone_allocator) - return; - - for (j = 0; j < THREAD_POOLS; j++) { - for (i = 0; i < MEM_ZONES; i++) { - MemoryZone *mz = &zones[i][j]; - pthread_mutex_destroy(&mz->lock); - while (mz->head) { - MemBlockHdr *hdr = mz->head; - mz->head = hdr->s.next; /* unlink it */ - free(hdr); - mz->elements--; - } - } - } - use_zone_allocator = PR_FALSE; -} - -/* -** pr_FindSymbolInProg -** -** Find the specified data symbol in the program and return -** its address. -*/ - -#ifdef HAVE_DLL - -#if defined(USE_DLFCN) && !defined(NO_DLOPEN_NULL) - -#include - -static void * -pr_FindSymbolInProg(const char *name) -{ - void *h; - void *sym; - - h = dlopen(0, RTLD_LAZY); - if (h == NULL) - return NULL; - sym = dlsym(h, name); - (void)dlclose(h); - return sym; -} - -#elif defined(USE_HPSHL) - -#include - -static void * -pr_FindSymbolInProg(const char *name) -{ - shl_t h = NULL; - void *sym; - - if (shl_findsym(&h, name, TYPE_DATA, &sym) == -1) - return NULL; - return sym; -} - -#elif defined(USE_MACH_DYLD) || defined(NO_DLOPEN_NULL) - -static void * -pr_FindSymbolInProg(const char *name) -{ - /* FIXME: not implemented */ - return NULL; -} - -#else - -#error "The zone allocator is not supported on this platform" - -#endif - -#else /* !defined(HAVE_DLL) */ - -static void * -pr_FindSymbolInProg(const char *name) -{ - /* can't be implemented */ - return NULL; -} - -#endif /* HAVE_DLL */ - -void -_PR_InitZones(void) -{ - int i, j; - char *envp; - PRBool *sym; - - if ((sym = (PRBool *)pr_FindSymbolInProg("nspr_use_zone_allocator")) != NULL) { - use_zone_allocator = *sym; - } else if ((envp = getenv("NSPR_USE_ZONE_ALLOCATOR")) != NULL) { - use_zone_allocator = (atoi(envp) == 1); - } - - if (!use_zone_allocator) - return; - - for (j = 0; j < THREAD_POOLS; j++) { - for (i = 0; i < MEM_ZONES; i++) { - MemoryZone *mz = &zones[i][j]; - int rv = pthread_mutex_init(&mz->lock, NULL); - PR_ASSERT(0 == rv); - if (rv != 0) { - goto loser; - } - mz->blockSize = 16 << ( 2 * i); - } - } - return; - -loser: - _PR_DestroyZones(); - return; -} - -PR_IMPLEMENT(void) -PR_FPrintZoneStats(PRFileDesc *debug_out) -{ - int i, j; - - for (j = 0; j < THREAD_POOLS; j++) { - for (i = 0; i < MEM_ZONES; i++) { - MemoryZone *mz = &zones[i][j]; - MemoryZone zone = *mz; - if (zone.elements || zone.misses || zone.hits) { - PR_fprintf(debug_out, -"pool: %d, zone: %d, size: %d, free: %d, hit: %d, miss: %d, contend: %d\n", - j, i, zone.blockSize, zone.elements, - zone.hits, zone.misses, zone.contention); - } - } - } -} - -static void * -pr_ZoneMalloc(PRUint32 size) -{ - void *rv; - unsigned int zone; - size_t blockSize; - MemBlockHdr *mb, *mt; - MemoryZone *mz; - - /* Always allocate a non-zero amount of bytes */ - if (size < 1) { - size = 1; - } - for (zone = 0, blockSize = 16; zone < MEM_ZONES; ++zone, blockSize <<= 2) { - if (size <= blockSize) { - break; - } - } - if (zone < MEM_ZONES) { - pthread_t me = pthread_self(); - unsigned int pool = (PRUptrdiff)me % THREAD_POOLS; - PRUint32 wasLocked; - mz = &zones[zone][pool]; - wasLocked = mz->locked; - pthread_mutex_lock(&mz->lock); - mz->locked = 1; - if (wasLocked) - mz->contention++; - if (mz->head) { - mb = mz->head; - PR_ASSERT(mb->s.magic == ZONE_MAGIC); - PR_ASSERT(mb->s.zone == mz); - PR_ASSERT(mb->s.blockSize == blockSize); - PR_ASSERT(mz->blockSize == blockSize); - - mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); - PR_ASSERT(mt->s.magic == ZONE_MAGIC); - PR_ASSERT(mt->s.zone == mz); - PR_ASSERT(mt->s.blockSize == blockSize); - - mz->hits++; - mz->elements--; - mz->head = mb->s.next; /* take off free list */ - mz->locked = 0; - pthread_mutex_unlock(&mz->lock); - - mt->s.next = mb->s.next = NULL; - mt->s.requestedSize = mb->s.requestedSize = size; - - rv = (void *)(mb + 1); - return rv; - } - - mz->misses++; - mz->locked = 0; - pthread_mutex_unlock(&mz->lock); - - mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb)); - if (!mb) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - mb->s.next = NULL; - mb->s.zone = mz; - mb->s.magic = ZONE_MAGIC; - mb->s.blockSize = blockSize; - mb->s.requestedSize = size; - - mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); - memcpy(mt, mb, sizeof *mb); - - rv = (void *)(mb + 1); - return rv; - } - - /* size was too big. Create a block with no zone */ - blockSize = (size & 15) ? size + 16 - (size & 15) : size; - mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb)); - if (!mb) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - mb->s.next = NULL; - mb->s.zone = NULL; - mb->s.magic = ZONE_MAGIC; - mb->s.blockSize = blockSize; - mb->s.requestedSize = size; - - mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); - memcpy(mt, mb, sizeof *mb); - - rv = (void *)(mb + 1); - return rv; -} - - -static void * -pr_ZoneCalloc(PRUint32 nelem, PRUint32 elsize) -{ - PRUint32 size = nelem * elsize; - void *p = pr_ZoneMalloc(size); - if (p) { - memset(p, 0, size); - } - return p; -} - -static void * -pr_ZoneRealloc(void *oldptr, PRUint32 bytes) -{ - void *rv; - MemBlockHdr *mb; - int ours; - MemBlockHdr phony; - - if (!oldptr) - return pr_ZoneMalloc(bytes); - mb = (MemBlockHdr *)((char *)oldptr - (sizeof *mb)); - if (mb->s.magic != ZONE_MAGIC) { - /* Maybe this just came from ordinary malloc */ -#ifdef DEBUG - fprintf(stderr, - "Warning: reallocing memory block %p from ordinary malloc\n", - oldptr); -#endif - /* - * We are going to realloc oldptr. If realloc succeeds, the - * original value of oldptr will point to freed memory. So this - * function must not fail after a successfull realloc call. We - * must perform any operation that may fail before the realloc - * call. - */ - rv = pr_ZoneMalloc(bytes); /* this may fail */ - if (!rv) { - return rv; - } - - /* We don't know how big it is. But we can fix that. */ - oldptr = realloc(oldptr, bytes); - /* - * If realloc returns NULL, this function loses the original - * value of oldptr. This isn't a leak because the caller of - * this function still has the original value of oldptr. - */ - if (!oldptr) { - if (bytes) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - pr_ZoneFree(rv); - return oldptr; - } - } - phony.s.requestedSize = bytes; - mb = &phony; - ours = 0; - } else { - size_t blockSize = mb->s.blockSize; - MemBlockHdr *mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); - - PR_ASSERT(mt->s.magic == ZONE_MAGIC); - PR_ASSERT(mt->s.zone == mb->s.zone); - PR_ASSERT(mt->s.blockSize == blockSize); - - if (bytes <= blockSize) { - /* The block is already big enough. */ - mt->s.requestedSize = mb->s.requestedSize = bytes; - return oldptr; - } - ours = 1; - rv = pr_ZoneMalloc(bytes); - if (!rv) { - return rv; - } - } - - if (oldptr && mb->s.requestedSize) - memcpy(rv, oldptr, mb->s.requestedSize); - if (ours) - pr_ZoneFree(oldptr); - else if (oldptr) - free(oldptr); - return rv; -} - -static void -pr_ZoneFree(void *ptr) -{ - MemBlockHdr *mb, *mt; - MemoryZone *mz; - size_t blockSize; - PRUint32 wasLocked; - - if (!ptr) - return; - - mb = (MemBlockHdr *)((char *)ptr - (sizeof *mb)); - - if (mb->s.magic != ZONE_MAGIC) { - /* maybe this came from ordinary malloc */ -#ifdef DEBUG - fprintf(stderr, - "Warning: freeing memory block %p from ordinary malloc\n", ptr); -#endif - free(ptr); - return; - } - - blockSize = mb->s.blockSize; - mz = mb->s.zone; - mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); - PR_ASSERT(mt->s.magic == ZONE_MAGIC); - PR_ASSERT(mt->s.zone == mz); - PR_ASSERT(mt->s.blockSize == blockSize); - if (!mz) { - PR_ASSERT(blockSize > 65536); - /* This block was not in any zone. Just free it. */ - free(mb); - return; - } - PR_ASSERT(mz->blockSize == blockSize); - wasLocked = mz->locked; - pthread_mutex_lock(&mz->lock); - mz->locked = 1; - if (wasLocked) - mz->contention++; - mt->s.next = mb->s.next = mz->head; /* put on head of list */ - mz->head = mb; - mz->elements++; - mz->locked = 0; - pthread_mutex_unlock(&mz->lock); -} - -PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - return use_zone_allocator ? pr_ZoneMalloc(size) : malloc(size); -} - -PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - return use_zone_allocator ? - pr_ZoneCalloc(nelem, elsize) : calloc(nelem, elsize); -} - -PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - return use_zone_allocator ? pr_ZoneRealloc(ptr, size) : realloc(ptr, size); -} - -PR_IMPLEMENT(void) PR_Free(void *ptr) -{ - if (use_zone_allocator) - pr_ZoneFree(ptr); - else - free(ptr); -} - -#else /* !defined(_PR_ZONE_ALLOCATOR) */ - -/* -** The PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free functions simply -** call their libc equivalents now. This may seem redundant, but it -** ensures that we are calling into the same runtime library. On -** Win32, it is possible to have multiple runtime libraries (e.g., -** objects compiled with /MD and /MDd) in the same process, and -** they maintain separate heaps, which cannot be mixed. -*/ -PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size) -{ -#if defined (WIN16) - return PR_MD_malloc( (size_t) size); -#else - return malloc(size); -#endif -} - -PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize) -{ -#if defined (WIN16) - return PR_MD_calloc( (size_t)nelem, (size_t)elsize ); - -#else - return calloc(nelem, elsize); -#endif -} - -PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size) -{ -#if defined (WIN16) - return PR_MD_realloc( ptr, (size_t) size); -#else - return realloc(ptr, size); -#endif -} - -PR_IMPLEMENT(void) PR_Free(void *ptr) -{ -#if defined (WIN16) - PR_MD_free( ptr ); -#else - free(ptr); -#endif -} - -#endif /* _PR_ZONE_ALLOCATOR */ - -/* -** Complexity alert! -** -** If malloc/calloc/free (etc.) were implemented to use pr lock's then -** the entry points could block when called if some other thread had the -** lock. -** -** Most of the time this isn't a problem. However, in the case that we -** are using the thread safe malloc code after PR_Init but before -** PR_AttachThread has been called (on a native thread that nspr has yet -** to be told about) we could get royally screwed if the lock was busy -** and we tried to context switch the thread away. In this scenario -** PR_CURRENT_THREAD() == NULL -** -** To avoid this unfortunate case, we use the low level locking -** facilities for malloc protection instead of the slightly higher level -** locking. This makes malloc somewhat faster so maybe it's a good thing -** anyway. -*/ -#ifdef _PR_OVERRIDE_MALLOC - -/* Imports */ -extern void *_PR_UnlockedMalloc(size_t size); -extern void *_PR_UnlockedMemalign(size_t alignment, size_t size); -extern void _PR_UnlockedFree(void *ptr); -extern void *_PR_UnlockedRealloc(void *ptr, size_t size); -extern void *_PR_UnlockedCalloc(size_t n, size_t elsize); - -static PRBool _PR_malloc_initialised = PR_FALSE; - -#ifdef _PR_PTHREADS -static pthread_mutex_t _PR_MD_malloc_crustylock; - -#define _PR_Lock_Malloc() { \ - if(PR_TRUE == _PR_malloc_initialised) { \ - PRStatus rv; \ - rv = pthread_mutex_lock(&_PR_MD_malloc_crustylock); \ - PR_ASSERT(0 == rv); \ - } - -#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ - PRStatus rv; \ - rv = pthread_mutex_unlock(&_PR_MD_malloc_crustylock); \ - PR_ASSERT(0 == rv); \ - } \ - } -#else /* _PR_PTHREADS */ -static _MDLock _PR_MD_malloc_crustylock; - -#ifdef IRIX -#define _PR_Lock_Malloc() { \ - PRIntn _is; \ - if(PR_TRUE == _PR_malloc_initialised) { \ - if (_PR_MD_GET_ATTACHED_THREAD() && \ - !_PR_IS_NATIVE_THREAD( \ - _PR_MD_GET_ATTACHED_THREAD())) \ - _PR_INTSOFF(_is); \ - _PR_MD_LOCK(&_PR_MD_malloc_crustylock); \ - } - -#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ - _PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \ - if (_PR_MD_GET_ATTACHED_THREAD() && \ - !_PR_IS_NATIVE_THREAD( \ - _PR_MD_GET_ATTACHED_THREAD())) \ - _PR_INTSON(_is); \ - } \ - } -#else /* IRIX */ -#define _PR_Lock_Malloc() { \ - PRIntn _is; \ - if(PR_TRUE == _PR_malloc_initialised) { \ - if (_PR_MD_CURRENT_THREAD() && \ - !_PR_IS_NATIVE_THREAD( \ - _PR_MD_CURRENT_THREAD())) \ - _PR_INTSOFF(_is); \ - _PR_MD_LOCK(&_PR_MD_malloc_crustylock); \ - } - -#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ - _PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \ - if (_PR_MD_CURRENT_THREAD() && \ - !_PR_IS_NATIVE_THREAD( \ - _PR_MD_CURRENT_THREAD())) \ - _PR_INTSON(_is); \ - } \ - } -#endif /* IRIX */ -#endif /* _PR_PTHREADS */ - -PR_IMPLEMENT(PRStatus) _PR_MallocInit(void) -{ - PRStatus rv = PR_SUCCESS; - - if( PR_TRUE == _PR_malloc_initialised ) return PR_SUCCESS; - -#ifdef _PR_PTHREADS - { - int status; - pthread_mutexattr_t mattr; - - status = _PT_PTHREAD_MUTEXATTR_INIT(&mattr); - PR_ASSERT(0 == status); - status = _PT_PTHREAD_MUTEX_INIT(_PR_MD_malloc_crustylock, mattr); - PR_ASSERT(0 == status); - status = _PT_PTHREAD_MUTEXATTR_DESTROY(&mattr); - PR_ASSERT(0 == status); - } -#else /* _PR_PTHREADS */ - _MD_NEW_LOCK(&_PR_MD_malloc_crustylock); -#endif /* _PR_PTHREADS */ - - if( PR_SUCCESS == rv ) - { - _PR_malloc_initialised = PR_TRUE; - } - - return rv; -} - -void *malloc(size_t size) -{ - void *p; - _PR_Lock_Malloc(); - p = _PR_UnlockedMalloc(size); - _PR_Unlock_Malloc(); - return p; -} - -#if defined(IRIX) -void *memalign(size_t alignment, size_t size) -{ - void *p; - _PR_Lock_Malloc(); - p = _PR_UnlockedMemalign(alignment, size); - _PR_Unlock_Malloc(); - return p; -} - -void *valloc(size_t size) -{ - return(memalign(sysconf(_SC_PAGESIZE),size)); -} -#endif /* IRIX */ - -void free(void *ptr) -{ - _PR_Lock_Malloc(); - _PR_UnlockedFree(ptr); - _PR_Unlock_Malloc(); -} - -void *realloc(void *ptr, size_t size) -{ - void *p; - _PR_Lock_Malloc(); - p = _PR_UnlockedRealloc(ptr, size); - _PR_Unlock_Malloc(); - return p; -} - -void *calloc(size_t n, size_t elsize) -{ - void *p; - _PR_Lock_Malloc(); - p = _PR_UnlockedCalloc(n, elsize); - _PR_Unlock_Malloc(); - return p; -} - -void cfree(void *p) -{ - _PR_Lock_Malloc(); - _PR_UnlockedFree(p); - _PR_Unlock_Malloc(); -} - -void _PR_InitMem(void) -{ - PRStatus rv; - rv = _PR_MallocInit(); - PR_ASSERT(PR_SUCCESS == rv); -} - -#endif /* _PR_OVERRIDE_MALLOC */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bcpu.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bcpu.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bcpu.c 2012-03-06 13:14:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bcpu.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -PR_EXTERN(void) _PR_MD_INIT_CPUS(); -PR_EXTERN(void) _PR_MD_WAKEUP_CPUS(); -PR_EXTERN(void) _PR_MD_START_INTERRUPTS(void); -PR_EXTERN(void) _PR_MD_STOP_INTERRUPTS(void); -PR_EXTERN(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void); -PR_EXTERN(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void); -PR_EXTERN(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void); -PR_EXTERN(void) _PR_MD_CLOCK_INTERRUPT(void); -PR_EXTERN(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone); -PR_EXTERN(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts); -PR_EXTERN(PRInt32) _PR_MD_GET_INTSOFF(void); -PR_EXTERN(void) _PR_MD_SET_INTSOFF(PRInt32 _val); -PR_EXTERN(_PRCPU*) _PR_MD_CURRENT_CPU(void); -PR_EXTERN(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu); -PR_EXTERN(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu); -PR_EXTERN(PRInt32) _PR_MD_PAUSE_CPU(PRIntervalTime timeout); diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/beos.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/beos.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/beos.c 2012-03-06 13:14:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/beos.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or - * PRInt32* pointer to a _PRSockLen_t* pointer. - */ -#define _PRSockLen_t int - -/* -** Global lock variable used to bracket calls into rusty libraries that -** aren't thread safe (like libc, libX, etc). -*/ -static PRLock *_pr_rename_lock = NULL; -static PRMonitor *_pr_Xfe_mon = NULL; - -/* - * Variables used by the GC code, initialized in _MD_InitSegs(). - * _pr_zero_fd should be a static variable. Unfortunately, there is - * still some Unix-specific code left in function PR_GrowSegment() - * in file memory/prseg.c that references it, so it needs - * to be a global variable for now. - */ -PRInt32 _pr_zero_fd = -1; -static PRLock *_pr_md_lock = NULL; - -sigset_t timer_set; - -void _PR_UnixInit() -{ - struct sigaction sigact; - int rv; - - sigemptyset(&timer_set); - - sigact.sa_handler = SIG_IGN; - sigemptyset(&sigact.sa_mask); - sigact.sa_flags = 0; - rv = sigaction(SIGPIPE, &sigact, 0); - PR_ASSERT(0 == rv); - - _pr_rename_lock = PR_NewLock(); - PR_ASSERT(NULL != _pr_rename_lock); - _pr_Xfe_mon = PR_NewMonitor(); - PR_ASSERT(NULL != _pr_Xfe_mon); -} - -/* - *----------------------------------------------------------------------- - * - * PR_Now -- - * - * Returns the current time in microseconds since the epoch. - * The epoch is midnight January 1, 1970 GMT. - * The implementation is machine dependent. This is the Unix - * implementation. - * Cf. time_t time(time_t *tp) - * - *----------------------------------------------------------------------- - */ - -PR_IMPLEMENT(PRTime) -PR_Now(void) -{ - struct timeval tv; - PRInt64 s, us, s2us; - - GETTIMEOFDAY(&tv); - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(s, tv.tv_sec); - LL_I2L(us, tv.tv_usec); - LL_MUL(s, s, s2us); - LL_ADD(s, s, us); - return s; -} - -PRIntervalTime -_PR_UNIX_GetInterval() -{ - struct timeval time; - PRIntervalTime ticks; - - (void)GETTIMEOFDAY(&time); /* fallicy of course */ - ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; /* that's in milliseconds */ - ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC; /* so's that */ - return ticks; -} /* _PR_SUNOS_GetInterval */ - -PRIntervalTime _PR_UNIX_TicksPerSecond() -{ - return 1000; /* this needs some work :) */ -} - -/************************************************************************/ - -/* -** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread -** safe. Unfortunately, neither is mozilla. To make these programs work -** in a pre-emptive threaded environment, we need to use a lock. -*/ - -void PR_XLock() -{ - PR_EnterMonitor(_pr_Xfe_mon); -} - -void PR_XUnlock() -{ - PR_ExitMonitor(_pr_Xfe_mon); -} - -PRBool PR_XIsLocked() -{ - return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE; -} - -void PR_XWait(int ms) -{ - PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms)); -} - -void PR_XNotify(void) -{ - PR_Notify(_pr_Xfe_mon); -} - -void PR_XNotifyAll(void) -{ - PR_NotifyAll(_pr_Xfe_mon); -} - -#if !defined(BEOS) -#ifdef HAVE_BSD_FLOCK - -#include - -PR_IMPLEMENT(PRStatus) -_MD_LOCKFILE (PRInt32 f) -{ - PRInt32 rv; - rv = flock(f, LOCK_EX); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) -_MD_TLOCKFILE (PRInt32 f) -{ - PRInt32 rv; - rv = flock(f, LOCK_EX|LOCK_NB); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) -_MD_UNLOCKFILE (PRInt32 f) -{ - PRInt32 rv; - rv = flock(f, LOCK_UN); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} -#else - -PR_IMPLEMENT(PRStatus) -_MD_LOCKFILE (PRInt32 f) -{ - PRInt32 rv; - rv = lockf(f, F_LOCK, 0); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) -_MD_TLOCKFILE (PRInt32 f) -{ - PRInt32 rv; - rv = lockf(f, F_TLOCK, 0); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) -_MD_UNLOCKFILE (PRInt32 f) -{ - PRInt32 rv; - rv = lockf(f, F_ULOCK, 0); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} -#endif - -PR_IMPLEMENT(PRStatus) - _MD_GETHOSTNAME (char *name, PRUint32 namelen) -{ - PRIntn rv; - - rv = gethostname(name, namelen); - if (0 == rv) { - return PR_SUCCESS; - } - _PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -#endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/beos_errors.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/beos_errors.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/beos_errors.c 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/beos_errors.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1494 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prtypes.h" -#include "md/_unix_errors.h" -#include "prerror.h" -#include - -void _MD_unix_map_opendir_error(int err) -{ - switch (err) { - case ENOTDIR: - PR_SetError(PR_NOT_DIRECTORY_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EMFILE: - PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); - break; - case ENFILE: - PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ELOOP: - PR_SetError(PR_LOOP_ERROR, err); - break; - case ENAMETOOLONG: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_closedir_error(int err) -{ - switch (err) { - case EINVAL: - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_readdir_error(int err) -{ - - switch (err) { - case 0: - case ENOENT: - PR_SetError(PR_NO_MORE_FILES_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#ifdef IRIX -#ifdef IRIX5_3 -#else - case EDIRCORRUPTED: - PR_SetError(PR_DIRECTORY_CORRUPTED_ERROR, err); - break; -#endif -#endif -#ifdef EOVERFLOW - case EOVERFLOW: - PR_SetError(PR_IO_ERROR, err); - break; -#endif - case EINVAL: - PR_SetError(PR_IO_ERROR, err); - break; -#ifdef EBADMSG - case EBADMSG: - PR_SetError(PR_IO_ERROR, err); - break; -#endif - case EDEADLK: - PR_SetError(PR_DEADLOCK_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - case ENOLCK: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; -#ifdef ENOLINK - case ENOLINK: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; -#endif - case ENXIO: - PR_SetError(PR_IO_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_unlink_error(int err) -{ - switch (err) { - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EBUSY: - PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case ELOOP: - PR_SetError(PR_LOOP_ERROR, err); - break; - case ENAMETOOLONG: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ENOTDIR: - PR_SetError(PR_NOT_DIRECTORY_ERROR, err); - break; - case EPERM: - PR_SetError(PR_IS_DIRECTORY_ERROR, err); - break; - case EROFS: - PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_stat_error(int err) -{ - switch (err) { - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case ETIMEDOUT: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; - case ELOOP: - PR_SetError(PR_LOOP_ERROR, err); - break; - case ENAMETOOLONG: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ENOTDIR: - PR_SetError(PR_NOT_DIRECTORY_ERROR, err); - break; -#ifdef EOVERFLOW - case EOVERFLOW: - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_fstat_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case ETIMEDOUT: -#ifdef ENOLINK - case ENOLINK: -#endif - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; -#ifdef EOVERFLOW - case EOVERFLOW: - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_rename_error(int err) -{ - switch (err) { - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EBUSY: - PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err); - break; -#ifdef EDQUOT - case EDQUOT: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; -#endif - case EEXIST: - PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - case EISDIR: - PR_SetError(PR_IS_DIRECTORY_ERROR, err); - break; - case ELOOP: - PR_SetError(PR_LOOP_ERROR, err); - break; - case ENAMETOOLONG: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ENOSPC: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; - case ENOTDIR: - PR_SetError(PR_NOT_DIRECTORY_ERROR, err); - break; - case EROFS: - PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); - break; - case EXDEV: - PR_SetError(PR_NOT_SAME_DEVICE_ERROR, err); - break; - case EMLINK: - PR_SetError(PR_MAX_DIRECTORY_ENTRIES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_access_error(int err) -{ - switch (err) { - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ELOOP: - PR_SetError(PR_LOOP_ERROR, err); - break; - case ETIMEDOUT: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; - case ENAMETOOLONG: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ENOTDIR: - PR_SetError(PR_NOT_DIRECTORY_ERROR, err); - break; - case EROFS: - PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_mkdir_error(int err) -{ - switch (err) { - case ENOTDIR: - PR_SetError(PR_NOT_DIRECTORY_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ENAMETOOLONG: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EEXIST: - PR_SetError(PR_FILE_EXISTS_ERROR, err); - break; - case EROFS: - PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ELOOP: - PR_SetError(PR_LOOP_ERROR, err); - break; - case EMLINK: - PR_SetError(PR_MAX_DIRECTORY_ENTRIES_ERROR, err); - break; - case ENOSPC: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; -#ifdef EDQUOT - case EDQUOT: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; -#endif - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_rmdir_error(int err) -{ - - switch (err) { - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EBUSY: - PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err); - break; - case EEXIST: - PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - case ELOOP: - PR_SetError(PR_LOOP_ERROR, err); - break; - case ETIMEDOUT: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; - case ENAMETOOLONG: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ENOTDIR: - PR_SetError(PR_NOT_DIRECTORY_ERROR, err); - break; - case EROFS: - PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_read_error(int err) -{ - switch (err) { - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#ifdef EBADMSG - case EBADMSG: - PR_SetError(PR_IO_ERROR, err); - break; -#endif - case EDEADLK: - PR_SetError(PR_DEADLOCK_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_METHOD_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - case ENOLCK: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ENXIO: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case EISDIR: - PR_SetError(PR_IS_DIRECTORY_ERROR, err); - break; - case ECONNRESET: - case EPIPE: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; -#ifdef ENOLINK - case ENOLINK: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_write_error(int err) -{ - switch (err) { - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EDEADLK: - PR_SetError(PR_DEADLOCK_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EFBIG: - PR_SetError(PR_FILE_TOO_BIG_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_METHOD_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - case ENOLCK: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - case ENOSPC: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; - case ENXIO: - PR_SetError(PR_INVALID_METHOD_ERROR, err); - break; - case ERANGE: - PR_SetError(PR_INVALID_METHOD_ERROR, err); - break; - case ETIMEDOUT: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; - case ECONNRESET: - case EPIPE: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; -#ifdef EDQUOT - case EDQUOT: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; -#endif -#ifdef ENOLINK - case ENOLINK: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_lseek_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ESPIPE: - PR_SetError(PR_INVALID_METHOD_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_fsync_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#ifdef ENOLINK - case ENOLINK: -#endif - case ETIMEDOUT: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_METHOD_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_close_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; -#ifdef ENOLINK - case ENOLINK: -#endif - case ETIMEDOUT: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_socket_error(int err) -{ - switch (err) { - case EPROTONOSUPPORT: - PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err); - break; - case EMFILE: - PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); - break; - case ENFILE: - PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; -#if !defined(SCO) - case ENOBUFS: -#endif /* !defined(SCO) */ - case ENOMEM: -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_socketavailable_error(int err) -{ - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); -} - -void _MD_unix_map_recv_error(int err) -{ - switch (err) { - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ENOMEM: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); - break; - case ECONNRESET: - case EPIPE: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_recvfrom_error(int err) -{ - switch (err) { - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ENOMEM: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - case ECONNRESET: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_send_error(int err) -{ - switch (err) { - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif -#if !defined(BEOS) - case EMSGSIZE: -#endif - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; -#if !defined(SCO) - case ENOBUFS: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif /* !defined(SCO) */ - case ECONNREFUSED: - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); - break; - case EISCONN: - PR_SetError(PR_IS_CONNECTED_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case ENOMEM: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - case ECONNRESET: - case EPIPE: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_sendto_error(int err) -{ - switch (err) { - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif -#if !defined(BEOS) - case EMSGSIZE: -#endif - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; -#if !defined(SCO) - case ENOBUFS: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif /* !defined(SCO) */ - case ECONNREFUSED: - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); - break; - case EISCONN: - PR_SetError(PR_IS_CONNECTED_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case ENOMEM: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - case ECONNRESET: - case EPIPE: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_writev_error(int err) -{ - switch (err) { - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ECONNRESET: - case EPIPE: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_accept_error(int err) -{ - switch (err) { - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif -#if !defined(BEOS) - case EOPNOTSUPP: -#endif - case ENODEV: - PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EMFILE: - PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); - break; - case ENFILE: - PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case ENOMEM: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif -#ifdef EPROTO - case EPROTO: - PR_SetError(PR_IO_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_connect_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EADDRNOTAVAIL: - PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); - break; - case EINPROGRESS: - PR_SetError(PR_IN_PROGRESS_ERROR, err); - break; - case EALREADY: - PR_SetError(PR_ALREADY_INITIATED_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case EAFNOSUPPORT: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - case EISCONN: - PR_SetError(PR_IS_CONNECTED_ERROR, err); - break; - case ETIMEDOUT: - PR_SetError(PR_IO_TIMEOUT_ERROR, err); - break; - case ECONNREFUSED: - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); - break; - case ENETUNREACH: - PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err); - break; - case EADDRINUSE: - PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - /* - * UNIX domain sockets are not supported in NSPR - */ - case EACCES: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case EIO: -#if defined(UNIXWARE) - /* - * On some platforms, if we connect to a port on - * the local host (the loopback address) that no - * process is listening on, we get EIO instead - * of ECONNREFUSED. - */ - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); -#else - PR_SetError(PR_IO_ERROR, err); -#endif - break; - case ELOOP: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - case ENOENT: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - case ENXIO: - PR_SetError(PR_IO_ERROR, err); - break; - case EPROTOTYPE: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_bind_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EADDRNOTAVAIL: - PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); - break; - case EADDRINUSE: - PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_SOCKET_ADDRESS_IS_BOUND_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - /* - * UNIX domain sockets are not supported in NSPR - */ - case EIO: - case EISDIR: - case ELOOP: - case ENOENT: - case ENOTDIR: - case EROFS: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_listen_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif -#if !defined(BEOS) - case EOPNOTSUPP: - PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_shutdown_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case ENOTCONN: - PR_SetError(PR_NOT_CONNECTED_ERROR, err); - break; - case ENOMEM: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_socketpair_error(int err) -{ - switch (err) { - case EMFILE: - PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ENOMEM: -#ifdef ENOSR - case ENOSR: -#endif - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case EAFNOSUPPORT: - case EPROTONOSUPPORT: -#if !defined(BEOS) - case EOPNOTSUPP: -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_getsockname_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#if !defined(SCO) - case ENOBUFS: -#endif /* !defined(SCO) */ - case ENOMEM: -#ifdef ENOSR - case ENOSR: -#endif - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_getpeername_error(int err) -{ - - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case ENOTCONN: - PR_SetError(PR_NOT_CONNECTED_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#if !defined(SCO) - case ENOBUFS: -#endif /* !defined(SCO) */ - case ENOMEM: -#ifdef ENOSR - case ENOSR: -#endif - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_getsockopt_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case ENOPROTOOPT: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); - break; - case ENOMEM: -#ifdef ENOSR - case ENOSR: -#endif - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_setsockopt_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; -#if !defined(BEOS) - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#endif - case ENOPROTOOPT: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); - break; - case ENOMEM: -#ifdef ENOSR - case ENOSR: -#endif - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_open_error(int err) -{ - switch (err) { - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EAGAIN: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case EBUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case EEXIST: - PR_SetError(PR_FILE_EXISTS_ERROR, err); - break; - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case EIO: - PR_SetError(PR_IO_ERROR, err); - break; - case EISDIR: - PR_SetError(PR_IS_DIRECTORY_ERROR, err); - break; - case ELOOP: - PR_SetError(PR_LOOP_ERROR, err); - break; - case EMFILE: - PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); - break; - case ENAMETOOLONG: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ENFILE: - PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); - break; - case ENODEV: - case ENOENT: - case ENXIO: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ENOMEM: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ENOSPC: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; -#ifdef ENOSR - case ENOSR: -#endif - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ENOTDIR: - PR_SetError(PR_NOT_DIRECTORY_ERROR, err); - break; - case EPERM: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ETIMEDOUT: - PR_SetError(PR_REMOTE_FILE_ERROR, err); - break; - case EROFS: - PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_mmap_error(int err) -{ - - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EAGAIN: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ENOMEM: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_gethostname_error(int err) -{ - switch (err) { - case EFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_select_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_poll_error(int err) -{ - PRErrorCode prerror; - switch (err) { - case EAGAIN: - prerror = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case EINVAL: - prerror = PR_INVALID_ARGUMENT_ERROR; - break; - case EFAULT: - prerror = PR_ACCESS_FAULT_ERROR; - break; - default: - prerror = PR_UNKNOWN_ERROR; - break; - } - PR_SetError(prerror, err); -} - -void _MD_unix_map_flock_error(int err) -{ - switch (err) { - case EBADF: - case EINVAL: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EWOULDBLOCK: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_unix_map_lockf_error(int err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EACCES: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case EDEADLK: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -#ifdef HPUX11 -void _MD_hpux_map_sendfile_error(int oserror) -{ - PRErrorCode prerror; - - switch (oserror) { - case ENOTSOCK: - prerror = PR_NOT_SOCKET_ERROR; - break; - case EFAULT: - prerror = PR_ACCESS_FAULT_ERROR; - break; - case ENOBUFS: - prerror = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case EINVAL: - prerror = PR_INVALID_ARGUMENT_ERROR; - break; - case ENOTCONN: - prerror = PR_NOT_CONNECTED_ERROR; - break; - case EPIPE: - prerror = PR_CONNECT_RESET_ERROR; - break; - case ENOMEM: - prerror = PR_OUT_OF_MEMORY_ERROR; - break; - case EOPNOTSUPP: - prerror = PR_NOT_TCP_SOCKET_ERROR; - break; - default: - prerror = PR_UNKNOWN_ERROR; - } - PR_SetError(prerror, oserror); -} -#endif /* HPUX11 */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bfile.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bfile.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bfile.c 2012-03-06 13:14:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bfile.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,873 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -/* -** Global lock variable used to bracket calls into rusty libraries that -** aren't thread safe (like libc, libX, etc). -*/ -static PRLock *_pr_rename_lock = NULL; - -void -_MD_InitIO (void) -{ -} - -PRStatus -_MD_open_dir (_MDDir *md,const char *name) -{ -int err; - - md->d = opendir(name); - if (!md->d) { - err = _MD_ERRNO(); - _PR_MD_MAP_OPENDIR_ERROR(err); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -char* -_MD_read_dir (_MDDir *md, PRIntn flags) -{ -struct dirent *de; -int err; - - for (;;) { - /* - * XXX: readdir() is not MT-safe - */ - _MD_ERRNO() = 0; - de = readdir(md->d); - - if (!de) { - err = _MD_ERRNO(); - _PR_MD_MAP_READDIR_ERROR(err); - return 0; - } - - if ((flags & PR_SKIP_DOT) && - (de->d_name[0] == '.') && (de->d_name[1] == 0)) - continue; - - if ((flags & PR_SKIP_DOT_DOT) && - (de->d_name[0] == '.') && (de->d_name[1] == '.') && - (de->d_name[2] == 0)) - continue; - - if ((flags & PR_SKIP_HIDDEN) && (de->d_name[1] == '.')) - continue; - - break; - } - return de->d_name; -} - - -PRInt32 -_MD_close_dir (_MDDir *md) -{ -int rv = 0, err; - - if (md->d) { - rv = closedir(md->d); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_CLOSEDIR_ERROR(err); - } - } - return(rv); -} - -void -_MD_make_nonblock (PRFileDesc *fd) -{ - int blocking = 1; - setsockopt(fd->secret->md.osfd, SOL_SOCKET, SO_NONBLOCK, &blocking, sizeof(blocking)); - -} - -PRStatus -_MD_set_fd_inheritable (PRFileDesc *fd, PRBool inheritable) -{ - int rv; - - rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC); - if (-1 == rv) { - PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -void -_MD_init_fd_inheritable (PRFileDesc *fd, PRBool imported) -{ - if (imported) { - fd->secret->inheritable = _PR_TRI_UNKNOWN; - } else { - int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0); - if (flags == -1) { - PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); - return; - } - fd->secret->inheritable = (flags & FD_CLOEXEC) ? - _PR_TRI_TRUE : _PR_TRI_FALSE; - } -} - -void -_MD_query_fd_inheritable (PRFileDesc *fd) -{ - int flags; - - PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); - flags = fcntl(fd->secret->md.osfd, F_GETFD, 0); - PR_ASSERT(-1 != flags); - fd->secret->inheritable = (flags & FD_CLOEXEC) ? - _PR_TRI_FALSE : _PR_TRI_TRUE; -} - -PRInt32 -_MD_open (const char *name, PRIntn flags, PRIntn mode) -{ - PRInt32 osflags; - PRInt32 rv, err; - - if (flags & PR_RDWR) { - osflags = O_RDWR; - } else if (flags & PR_WRONLY) { - osflags = O_WRONLY; - } else { - osflags = O_RDONLY; - } - - if (flags & PR_EXCL) - osflags |= O_EXCL; - if (flags & PR_APPEND) - osflags |= O_APPEND; - if (flags & PR_TRUNCATE) - osflags |= O_TRUNC; - if (flags & PR_SYNC) { -/* Ummmm. BeOS doesn't appear to - support sync in any way shape or - form. */ - return PR_NOT_IMPLEMENTED_ERROR; - } - - /* - ** On creations we hold the 'create' lock in order to enforce - ** the semantics of PR_Rename. (see the latter for more details) - */ - if (flags & PR_CREATE_FILE) - { - osflags |= O_CREAT ; - if (NULL !=_pr_rename_lock) - PR_Lock(_pr_rename_lock); - } - - rv = open(name, osflags, mode); - - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_OPEN_ERROR(err); - } - - if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock)) - PR_Unlock(_pr_rename_lock); - return rv; -} - -PRInt32 -_MD_close_file (PRInt32 osfd) -{ -PRInt32 rv, err; - - rv = close(osfd); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_CLOSE_ERROR(err); - } - return(rv); -} - -PRInt32 -_MD_read (PRFileDesc *fd, void *buf, PRInt32 amount) -{ - PRInt32 rv, err; - PRInt32 osfd = fd->secret->md.osfd; - - rv = read( osfd, buf, amount ); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_READ_ERROR(err); - } - return(rv); -} - -PRInt32 -_MD_write (PRFileDesc *fd, const void *buf, PRInt32 amount) -{ - PRInt32 rv, err; - PRInt32 osfd = fd->secret->md.osfd; - - rv = write( osfd, buf, amount ); - - if( rv < 0 ) { - - err = _MD_ERRNO(); - _PR_MD_MAP_WRITE_ERROR(err); - } - return( rv ); -} - -#ifndef BONE_VERSION /* Writev moves to bnet.c with BONE */ -PRInt32 -_MD_writev (PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, - PRIntervalTime timeout) -{ - return PR_NOT_IMPLEMENTED_ERROR; -} -#endif - -PRInt32 -_MD_lseek (PRFileDesc *fd, PRInt32 offset, int whence) -{ -PRInt32 rv, err; - - rv = lseek (fd->secret->md.osfd, offset, whence); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_LSEEK_ERROR(err); - } - return( rv ); -} - -PRInt64 -_MD_lseek64 (PRFileDesc *fd, PRInt64 offset, int whence) -{ -PRInt32 rv, err; - -/* According to the BeOS headers, lseek accepts a - * variable of type off_t for the offset, and off_t - * is defined to be a 64-bit value. So no special - * cracking needs to be done on "offset". - */ - - rv = lseek (fd->secret->md.osfd, offset, whence); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_LSEEK_ERROR(err); - } - return( rv ); -} - -PRInt32 -_MD_fsync (PRFileDesc *fd) -{ -PRInt32 rv, err; - - rv = fsync(fd->secret->md.osfd); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_FSYNC_ERROR(err); - } - return(rv); -} - -PRInt32 -_MD_delete (const char *name) -{ -PRInt32 rv, err; - - rv = unlink(name); - if (rv == -1) - { - err = _MD_ERRNO(); - _PR_MD_MAP_UNLINK_ERROR(err); - } - return (rv); -} - -PRInt32 -_MD_getfileinfo (const char *fn, PRFileInfo *info) -{ -struct stat sb; -PRInt32 rv, err; -PRInt64 s, s2us; - - rv = stat(fn, &sb); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_STAT_ERROR(err); - } else if (info) { - if (S_IFREG & sb.st_mode) - info->type = PR_FILE_FILE; - else if (S_IFDIR & sb.st_mode) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_OTHER; - - /* Must truncate file size for the 32 bit - version */ - info->size = (sb.st_size & 0xffffffff); - LL_I2L(s, sb.st_mtime); - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_MUL(s, s, s2us); - info->modifyTime = s; - LL_I2L(s, sb.st_ctime); - LL_MUL(s, s, s2us); - info->creationTime = s; - } - return rv; -} - -PRInt32 -_MD_getfileinfo64 (const char *fn, PRFileInfo64 *info) -{ -struct stat sb; -PRInt32 rv, err; -PRInt64 s, s2us; - - rv = stat(fn, &sb); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_STAT_ERROR(err); - } else if (info) { - if (S_IFREG & sb.st_mode) - info->type = PR_FILE_FILE; - else if (S_IFDIR & sb.st_mode) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_OTHER; - - /* For the 64 bit version we can use - * the native st_size without modification - */ - info->size = sb.st_size; - LL_I2L(s, sb.st_mtime); - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_MUL(s, s, s2us); - info->modifyTime = s; - LL_I2L(s, sb.st_ctime); - LL_MUL(s, s, s2us); - info->creationTime = s; - } - return rv; -} - -PRInt32 -_MD_getopenfileinfo (const PRFileDesc *fd, PRFileInfo *info) -{ - struct stat sb; - PRInt64 s, s2us; - PRInt32 rv, err; - - rv = fstat(fd->secret->md.osfd, &sb); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_FSTAT_ERROR(err); - } else if (info) { - if (info) { - if (S_IFREG & sb.st_mode) - info->type = PR_FILE_FILE ; - else if (S_IFDIR & sb.st_mode) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_OTHER; - /* Use lower 32 bits of file size */ - info->size = ( sb.st_size & 0xffffffff); - LL_I2L(s, sb.st_mtime); - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_MUL(s, s, s2us); - info->modifyTime = s; - LL_I2L(s, sb.st_ctime); - LL_MUL(s, s, s2us); - info->creationTime = s; - } - } - return rv; -} - -PRInt32 -_MD_getopenfileinfo64 (const PRFileDesc *fd, PRFileInfo64 *info) -{ - struct stat sb; - PRInt64 s, s2us; - PRInt32 rv, err; - - rv = fstat(fd->secret->md.osfd, &sb); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_FSTAT_ERROR(err); - } else if (info) { - if (info) { - if (S_IFREG & sb.st_mode) - info->type = PR_FILE_FILE ; - else if (S_IFDIR & sb.st_mode) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_OTHER; - info->size = sb.st_size; - LL_I2L(s, sb.st_mtime); - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_MUL(s, s, s2us); - info->modifyTime = s; - LL_I2L(s, sb.st_ctime); - LL_MUL(s, s, s2us); - info->creationTime = s; - } - } - return rv; -} - -PRInt32 -_MD_rename (const char *from, const char *to) -{ - PRInt32 rv = -1, err; - - /* - ** This is trying to enforce the semantics of WINDOZE' rename - ** operation. That means one is not allowed to rename over top - ** of an existing file. Holding a lock across these two function - ** and the open function is known to be a bad idea, but .... - */ - if (NULL != _pr_rename_lock) - PR_Lock(_pr_rename_lock); - if (0 == access(to, F_OK)) - PR_SetError(PR_FILE_EXISTS_ERROR, 0); - else - { - rv = rename(from, to); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_RENAME_ERROR(err); - } - } - if (NULL != _pr_rename_lock) - PR_Unlock(_pr_rename_lock); - return rv; -} - -PRInt32 -_MD_access (const char *name, PRIntn how) -{ -PRInt32 rv, err; -int checkFlags; -struct stat buf; - - switch (how) { - case PR_ACCESS_WRITE_OK: - checkFlags = S_IWUSR | S_IWGRP | S_IWOTH; - break; - - case PR_ACCESS_READ_OK: - checkFlags = S_IRUSR | S_IRGRP | S_IROTH; - break; - - case PR_ACCESS_EXISTS: - /* we don't need to examine st_mode. */ - break; - - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - - rv = stat(name, &buf); - if (rv == 0 && how != PR_ACCESS_EXISTS && (!(buf.st_mode & checkFlags))) { - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0); - return -1; - } - - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_STAT_ERROR(err); - } - - return(rv); -} - -PRInt32 -_MD_stat (const char *name, struct stat *buf) -{ - return PR_NOT_IMPLEMENTED_ERROR; -} - -PRInt32 -_MD_mkdir (const char *name, PRIntn mode) -{ - status_t rv; - int err; - - /* - ** This lock is used to enforce rename semantics as described - ** in PR_Rename. Look there for more fun details. - */ - if (NULL !=_pr_rename_lock) - PR_Lock(_pr_rename_lock); - - rv = mkdir(name, mode); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_MKDIR_ERROR(err); - } - if (NULL !=_pr_rename_lock) - PR_Unlock(_pr_rename_lock); - return rv; -} - -PRInt32 -_MD_rmdir (const char *name) -{ -int rv, err; - - rv = rmdir(name); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_RMDIR_ERROR(err); - } - return rv; -} - -PRInt32 -_MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - PRInt32 rv = 0; - PRThread *me = _PR_MD_CURRENT_THREAD(); - /* - * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL(). - */ - fd_set rd, wt, ex; - PRFileDesc *bottom; - PRPollDesc *pd, *epd; - PRInt32 maxfd = -1, ready, err; - PRIntervalTime remaining, elapsed, start; - - struct timeval tv, *tvp = NULL; - - if (_PR_PENDING_INTERRUPT(me)) - { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - - if (0 == npds) { - PR_Sleep(timeout); - return rv; - } - - FD_ZERO(&rd); - FD_ZERO(&wt); - FD_ZERO(&ex); - - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - if (pd->in_flags & PR_POLL_READ) - { - in_flags_read = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); - } - if (pd->in_flags & PR_POLL_WRITE) - { - in_flags_write = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); - } - if ((0 != (in_flags_read & out_flags_read)) - || (0 != (in_flags_write & out_flags_write))) - { - /* this one's ready right now */ - if (0 == ready) - { - /* - * We will have to return without calling the - * system poll/select function. So zero the - * out_flags fields of all the poll descriptors - * before this one. - */ - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; - pd->out_flags = out_flags_read | out_flags_write; - } - else - { - pd->out_flags = 0; /* pre-condition */ - - /* make sure this is an NSPR supported stack */ - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); /* what to do about that? */ - if ((NULL != bottom) - && (_PR_FILEDESC_OPEN == bottom->secret->state)) - { - if (0 == ready) - { - PRInt32 osfd = bottom->secret->md.osfd; - if (osfd > maxfd) maxfd = osfd; - if (in_flags_read & PR_POLL_READ) - { - pd->out_flags |= _PR_POLL_READ_SYS_READ; - FD_SET(osfd, &rd); - } - if (in_flags_read & PR_POLL_WRITE) - { - pd->out_flags |= _PR_POLL_READ_SYS_WRITE; - FD_SET(osfd, &wt); - } - if (in_flags_write & PR_POLL_READ) - { - pd->out_flags |= _PR_POLL_WRITE_SYS_READ; - FD_SET(osfd, &rd); - } - if (in_flags_write & PR_POLL_WRITE) - { - pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; - FD_SET(osfd, &wt); - } - if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex); - } - } - else - { - if (0 == ready) - { - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; /* this will cause an abrupt return */ - pd->out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - else - { - pd->out_flags = 0; - } - } - - if (0 != ready) return ready; /* no need to block */ - - remaining = timeout; - start = PR_IntervalNow(); - - retry: - if (timeout != PR_INTERVAL_NO_TIMEOUT) - { - PRInt32 ticksPerSecond = PR_TicksPerSecond(); - tv.tv_sec = remaining / ticksPerSecond; - tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); - tvp = &tv; - } - - ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp); - - if (ready == -1 && errno == EINTR) - { - if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; - else - { - elapsed = (PRIntervalTime) (PR_IntervalNow() - start); - if (elapsed > timeout) ready = 0; /* timed out */ - else - { - remaining = timeout - elapsed; - goto retry; - } - } - } - - /* - ** Now to unravel the select sets back into the client's poll - ** descriptor list. Is this possibly an area for pissing away - ** a few cycles or what? - */ - if (ready > 0) - { - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRInt16 out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - PRInt32 osfd; - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); - - osfd = bottom->secret->md.osfd; - - if (FD_ISSET(osfd, &rd)) - { - if (pd->out_flags & _PR_POLL_READ_SYS_READ) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) - out_flags |= PR_POLL_WRITE; - } - if (FD_ISSET(osfd, &wt)) - { - if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) - out_flags |= PR_POLL_WRITE; - } - if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; - -/* Workaround for nonblocking connects under net_server */ -#ifndef BONE_VERSION - if (out_flags) - { - /* check if it is a pending connect */ - int i = 0, j = 0; - PR_Lock( _connectLock ); - for( i = 0; i < connectCount; i++ ) - { - if(connectList[i].osfd == osfd) - { - int connectError; - int connectResult; - - connectResult = connect(connectList[i].osfd, - &connectList[i].addr, - connectList[i].addrlen); - connectError = errno; - - if(connectResult < 0 ) - { - if(connectError == EINTR || connectError == EWOULDBLOCK || - connectError == EINPROGRESS || connectError == EALREADY) - { - break; - } - } - - if(i == (connectCount - 1)) - { - connectList[i].osfd = -1; - } else { - for(j = i; j < connectCount; j++ ) - { - memcpy( &connectList[j], &connectList[j+1], - sizeof(connectList[j])); - } - } - connectCount--; - - bottom->secret->md.connectReturnValue = connectResult; - bottom->secret->md.connectReturnError = connectError; - bottom->secret->md.connectValueValid = PR_TRUE; - break; - } - } - PR_Unlock( _connectLock ); - } -#endif - } - pd->out_flags = out_flags; - if (out_flags) ready++; - } - PR_ASSERT(ready > 0); - } - else if (ready < 0) - { - err = _MD_ERRNO(); - if (err == EBADF) - { - /* Find the bad fds */ - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - pd->out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1) - { - pd->out_flags = PR_POLL_NVAL; - ready++; - } - } - } - PR_ASSERT(ready > 0); - } - else _PR_MD_MAP_SELECT_ERROR(err); - } - - return ready; -} /* _MD_pr_poll */ - -/* - * File locking. - */ - -PRStatus -_MD_lockfile (PRInt32 osfd) -{ - PRInt32 rv; - struct flock linfo; - - linfo.l_type = - linfo.l_whence = SEEK_SET; - linfo.l_start = 0; - linfo.l_len = 0; - - rv = fcntl(osfd, F_SETLKW, &linfo); - if (rv == 0) - return PR_SUCCESS; - - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus -_MD_tlockfile (PRInt32 osfd) -{ - PRInt32 rv; - struct flock linfo; - - linfo.l_type = - linfo.l_whence = SEEK_SET; - linfo.l_start = 0; - linfo.l_len = 0; - - rv = fcntl(osfd, F_SETLK, &linfo); - if (rv == 0) - return PR_SUCCESS; - - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus -_MD_unlockfile (PRInt32 osfd) -{ - PRInt32 rv; - struct flock linfo; - - linfo.l_type = - linfo.l_whence = SEEK_SET; - linfo.l_start = 0; - linfo.l_len = 0; - - rv = fcntl(osfd, F_UNLCK, &linfo); - - if (rv == 0) - return PR_SUCCESS; - - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bmemory.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bmemory.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bmemory.c 2012-03-06 13:14:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bmemory.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -PR_EXTERN(void) _PR_MD_INIT_SEGS(void); -PR_EXTERN(PRStatus) _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr); -PR_EXTERN(void) _PR_MD_FREE_SEGMENT(PRSegment *seg); diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bmisc.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bmisc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bmisc.c 2012-03-06 13:14:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bmisc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -PRLock *_connectLock = NULL; - -#ifndef BONE_VERSION -/* Workaround for nonblocking connects under net_server */ -PRUint32 connectCount = 0; -ConnectListNode connectList[64]; -#endif - -void -_MD_cleanup_before_exit (void) -{ -} - -void -_MD_exit (PRIntn status) -{ - exit(status); -} - -void -_MD_early_init (void) -{ -} - -static PRLock *monitor = NULL; - -void -_MD_final_init (void) -{ - _connectLock = PR_NewLock(); - PR_ASSERT(NULL != _connectLock); -#ifndef BONE_VERSION - /* Workaround for nonblocking connects under net_server */ - connectCount = 0; -#endif -} - -void -_MD_AtomicInit (void) -{ - if (monitor == NULL) { - monitor = PR_NewLock(); - } -} - -/* -** This is exceedingly messy. atomic_add returns the last value, NSPR expects the new value. -** We just add or subtract 1 from the result. The actual memory update is atomic. -*/ - -PRInt32 -_MD_AtomicAdd( PRInt32 *ptr, PRInt32 val ) -{ - return( ( atomic_add( (long *)ptr, val ) ) + val ); -} - -PRInt32 -_MD_AtomicIncrement( PRInt32 *val ) -{ - return( ( atomic_add( (long *)val, 1 ) ) + 1 ); -} - -PRInt32 -_MD_AtomicDecrement( PRInt32 *val ) -{ - return( ( atomic_add( (long *)val, -1 ) ) - 1 ); -} - -PRInt32 -_MD_AtomicSet( PRInt32 *val, PRInt32 newval ) -{ - PRInt32 rv; - - if (!_pr_initialized) { - _PR_ImplicitInitialization(); - } - PR_Lock(monitor); - rv = *val; - *val = newval; - PR_Unlock(monitor); - return rv; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bmmap.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bmmap.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bmmap.c 2012-03-06 13:14:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bmmap.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -PR_EXTERN(PRStatus) -_PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size) -{ - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return PR_FAILURE; -} - -PR_EXTERN(PRInt32) -_PR_MD_GET_MEM_MAP_ALIGNMENT(void) -{ - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return -1; -} - -PR_EXTERN(void *) -_PR_MD_MEM_MAP(PRFileMap *fmap, PRInt64 offset, PRUint32 len) -{ - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return 0; -} - -PR_EXTERN(PRStatus) -_PR_MD_MEM_UNMAP(void *addr, PRUint32 size) -{ - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return PR_FAILURE; -} - -PR_EXTERN(PRStatus) -_PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap) -{ - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return PR_FAILURE; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bnet.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bnet.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bnet.c 2012-03-06 13:14:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bnet.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,911 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or - * PRInt32* pointer to a _PRSockLen_t* pointer. - */ -#define _PRSockLen_t int - - -/* -** Global lock variable used to bracket calls into rusty libraries that -** aren't thread safe (like libc, libX, etc). -*/ -static PRLock *_pr_rename_lock = NULL; -static PRMonitor *_pr_Xfe_mon = NULL; - -#define READ_FD 1 -#define WRITE_FD 2 - -/* -** This is a support routine to handle "deferred" i/o on sockets. -** It uses "select", so it is subject to all of the BeOS limitations -** (only READ notification, only sockets) -*/ - -/* - * socket_io_wait -- - * - * wait for socket i/o, periodically checking for interrupt - * - */ - -static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type, - PRIntervalTime timeout) -{ - PRInt32 rv = -1; - struct timeval tv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRIntervalTime epoch, now, elapsed, remaining; - PRBool wait_for_remaining; - PRInt32 syserror; - fd_set rd_wr; - - switch (timeout) { - case PR_INTERVAL_NO_WAIT: - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - break; - case PR_INTERVAL_NO_TIMEOUT: - /* - * This is a special case of the 'default' case below. - * Please see the comments there. - */ - tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; - tv.tv_usec = 0; - FD_ZERO(&rd_wr); - do { - FD_SET(osfd, &rd_wr); - if (fd_type == READ_FD) - rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv); - else - rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv); - if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { -#ifdef BONE_VERSION - _PR_MD_MAP_SELECT_ERROR(syserror); -#else - if (syserror == EBADF) { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF); - } else { - PR_SetError(PR_UNKNOWN_ERROR, syserror); - } -#endif - break; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - } while (rv == 0 || (rv == -1 && syserror == EINTR)); - break; - default: - now = epoch = PR_IntervalNow(); - remaining = timeout; - FD_ZERO(&rd_wr); - do { - /* - * We block in _MD_SELECT for at most - * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, - * so that there is an upper limit on the delay - * before the interrupt bit is checked. - */ - wait_for_remaining = PR_TRUE; - tv.tv_sec = PR_IntervalToSeconds(remaining); - if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { - wait_for_remaining = PR_FALSE; - tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; - tv.tv_usec = 0; - } else { - tv.tv_usec = PR_IntervalToMicroseconds( - remaining - - PR_SecondsToInterval(tv.tv_sec)); - } - FD_SET(osfd, &rd_wr); - if (fd_type == READ_FD) - rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv); - else - rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv); - /* - * we don't consider EINTR a real error - */ - if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { -#ifdef BONE_VERSION - _PR_MD_MAP_SELECT_ERROR(syserror); -#else - if (syserror == EBADF) { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF); - } else { - PR_SetError(PR_UNKNOWN_ERROR, syserror); - } -#endif - break; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - /* - * We loop again if _MD_SELECT timed out or got interrupted - * by a signal, and the timeout deadline has not passed yet. - */ - if (rv == 0 || (rv == -1 && syserror == EINTR)) { - /* - * If _MD_SELECT timed out, we know how much time - * we spent in blocking, so we can avoid a - * PR_IntervalNow() call. - */ - if (rv == 0) { - if (wait_for_remaining) { - now += remaining; - } else { - now += PR_SecondsToInterval(tv.tv_sec) - + PR_MicrosecondsToInterval(tv.tv_usec); - } - } else { - now = PR_IntervalNow(); - } - elapsed = (PRIntervalTime) (now - epoch); - if (elapsed >= timeout) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - rv = -1; - break; - } else { - remaining = timeout - elapsed; - } - } - } while (rv == 0 || (rv == -1 && syserror == EINTR)); - break; - } - return(rv); -} - -PRInt32 -_MD_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRInt32 flags, - PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - -#ifndef BONE_VERSION - if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_READ) { - _PR_MD_MAP_RECV_ERROR(EPIPE); - return -1; - } -#endif - -#ifdef BONE_VERSION - /* - ** Gah, stupid hack. If reading a zero amount, instantly return success. - ** BONE beta 6 returns EINVAL for reads of zero bytes, which parts of - ** mozilla use to check for socket availability. - */ - - if( 0 == amount ) return(0); -#endif - - while ((rv = recv(osfd, buf, amount, flags)) == -1) { - err = _MD_ERRNO(); - - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - /* If socket was supposed to be blocking, - wait a while for the condition to be - satisfied. */ - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - - } else - break; - } - - if (rv < 0) { - _PR_MD_MAP_RECV_ERROR(err); - } - -done: - return(rv); -} - -PRInt32 -_MD_recvfrom (PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - while ((*addrlen = PR_NETADDR_SIZE(addr)), - ((rv = recvfrom(osfd, buf, amount, flags, - (struct sockaddr *) addr, - (_PRSockLen_t *)addrlen)) == -1)) { - err = _MD_ERRNO(); - - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) { - continue; - } else { - break; - } - } - - if (rv < 0) { - _PR_MD_MAP_RECVFROM_ERROR(err); - } - -done: -#ifdef _PR_HAVE_SOCKADDR_LEN - if (rv != -1) { - /* ignore the sa_len field of struct sockaddr */ - if (addr) { - addr->raw.family = ((struct sockaddr *) addr)->sa_family; - } - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ - return(rv); -} - -PRInt32 -_MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags, - PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - -#ifndef BONE_VERSION - if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_WRITE) - { - _PR_MD_MAP_SEND_ERROR(EPIPE); - return -1; - } -#endif - - while ((rv = send(osfd, buf, amount, flags)) == -1) { - err = _MD_ERRNO(); - - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - -#ifndef BONE_VERSION - if( _PR_PENDING_INTERRUPT(me)) { - - me->flags &= ~_PR_INTERRUPT; - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - - /* in UNIX implementations, you could do a socket_io_wait here. - * but since BeOS doesn't yet support WRITE notification in select, - * you're spanked. - */ - snooze( 10000L ); - continue; -#else /* BONE_VERSION */ - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0) - goto done; -#endif - - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) { - continue; - - } else { - break; - } - } - -#ifdef BONE_VERSION - /* - * optimization; if bytes sent is less than "amount" call - * select before returning. This is because it is likely that - * the next writev() call will return EWOULDBLOCK. - */ - if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) - && (timeout != PR_INTERVAL_NO_WAIT)) { - if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { - rv = -1; - goto done; - } - } -#endif /* BONE_VERSION */ - - if (rv < 0) { - _PR_MD_MAP_SEND_ERROR(err); - } - -#ifdef BONE_VERSION -done: -#endif - return(rv); -} - -PRInt32 -_MD_sendto (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); -#ifdef _PR_HAVE_SOCKADDR_LEN - PRNetAddr addrCopy; - - addrCopy = *addr; - ((struct sockaddr *) &addrCopy)->sa_len = addrlen; - ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; - - while ((rv = sendto(osfd, buf, amount, flags, - (struct sockaddr *) &addrCopy, addrlen)) == -1) { -#else - while ((rv = sendto(osfd, buf, amount, flags, - (struct sockaddr *) addr, addrlen)) == -1) { -#endif - err = _MD_ERRNO(); - - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - -#ifdef BONE_VERSION - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0) - goto done; -#endif - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) { - continue; - - } else { - break; - } - } - - if (rv < 0) { - _PR_MD_MAP_SENDTO_ERROR(err); - } - -#ifdef BONE_VERSION -done: -#endif - return(rv); -} - -#ifdef BONE_VERSION - -PRInt32 _MD_writev( - PRFileDesc *fd, const PRIOVec *iov, - PRInt32 iov_size, PRIntervalTime timeout) -{ - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 index, amount = 0; - PRInt32 osfd = fd->secret->md.osfd; - struct iovec osiov[PR_MAX_IOVECTOR_SIZE]; - - /* Ensured by PR_Writev */ - PR_ASSERT(iov_size <= PR_MAX_IOVECTOR_SIZE); - - /* - * We can't pass iov to writev because PRIOVec and struct iovec - * may not be binary compatible. Make osiov a copy of iov and - * pass osiov to writev. - */ - for (index = 0; index < iov_size; index++) { - osiov[index].iov_base = iov[index].iov_base; - osiov[index].iov_len = iov[index].iov_len; - } - - /* - * Calculate the total number of bytes to be sent; needed for - * optimization later. - * We could avoid this if this number was passed in; but it is - * probably not a big deal because iov_size is usually small (less than - * 3) - */ - if (!fd->secret->nonblocking) { - for (index=0; indexsecret->nonblocking) { - break; - } - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0) - goto done; - - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - - /* - * optimization; if bytes sent is less than "amount" call - * select before returning. This is because it is likely that - * the next writev() call will return EWOULDBLOCK. - */ - if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) - && (timeout != PR_INTERVAL_NO_WAIT)) { - if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { - rv = -1; - goto done; - } - } - - - if (rv < 0) { - _PR_MD_MAP_WRITEV_ERROR(err); - } -done: - return(rv); -} - -#endif /* BONE_VERSION */ - -PRInt32 -_MD_accept (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, - PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - while ((rv = accept(osfd, (struct sockaddr *) addr, - (_PRSockLen_t *)addrlen)) == -1) { - err = _MD_ERRNO(); - - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - /* If it's SUPPOSED to be a blocking thread, wait - * a while to see if the triggering condition gets - * satisfied. - */ - /* Assume that we're always using a native thread */ - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) { - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_ACCEPT_ERROR(err); - } else if (addr != NULL) { - /* bug 134099 */ - err = getpeername(rv, (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); - } -done: -#ifdef _PR_HAVE_SOCKADDR_LEN - if (rv != -1) { - /* Mask off the first byte of struct sockaddr (the length field) */ - if (addr) { - addr->raw.family = ((struct sockaddr *) addr)->sa_family; - } - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ - return(rv); -} - -PRInt32 -_MD_connect (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, - PRIntervalTime timeout) -{ - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 osfd = fd->secret->md.osfd; - -#ifndef BONE_VERSION - fd->secret->md.connectValueValid = PR_FALSE; -#endif -#ifdef _PR_HAVE_SOCKADDR_LEN - PRNetAddr addrCopy; - - addrCopy = *addr; - ((struct sockaddr *) &addrCopy)->sa_len = addrlen; - ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; -#endif - - /* (Copied from unix.c) - * We initiate the connection setup by making a nonblocking connect() - * call. If the connect() call fails, there are two cases we handle - * specially: - * 1. The connect() call was interrupted by a signal. In this case - * we simply retry connect(). - * 2. The NSPR socket is nonblocking and connect() fails with - * EINPROGRESS. We first wait until the socket becomes writable. - * Then we try to find out whether the connection setup succeeded - * or failed. - */ - -retry: -#ifdef _PR_HAVE_SOCKADDR_LEN - if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) { -#else - if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) { -#endif - err = _MD_ERRNO(); -#ifndef BONE_VERSION - fd->secret->md.connectReturnValue = rv; - fd->secret->md.connectReturnError = err; - fd->secret->md.connectValueValid = PR_TRUE; -#endif - if( err == EINTR ) { - - if( _PR_PENDING_INTERRUPT(me)) { - - me->flags &= ~_PR_INTERRUPT; - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } -#ifndef BONE_VERSION - snooze( 100000L ); -#endif - goto retry; - } - -#ifndef BONE_VERSION - if(!fd->secret->nonblocking && ((err == EINPROGRESS) || (err==EAGAIN) || (err==EALREADY))) { - - /* - ** There's no timeout on this connect, but that's not - ** a big deal, since the connect times out anyways - ** after 30 seconds. Just sleep for 1/10th of a second - ** and retry until we go through or die. - */ - - if( _PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - - goto retry; - } - - if( fd->secret->nonblocking && ((err == EAGAIN) || (err == EINPROGRESS))) { - PR_Lock(_connectLock); - if (connectCount < sizeof(connectList)/sizeof(connectList[0])) { - connectList[connectCount].osfd = osfd; - memcpy(&connectList[connectCount].addr, addr, addrlen); - connectList[connectCount].addrlen = addrlen; - connectList[connectCount].timeout = timeout; - connectCount++; - PR_Unlock(_connectLock); - _PR_MD_MAP_CONNECT_ERROR(err); - } else { - PR_Unlock(_connectLock); - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } - return rv; - } -#else /* BONE_VERSION */ - if(!fd->secret->nonblocking && (err == EINTR)) { - - rv = socket_io_wait(osfd, WRITE_FD, timeout); - if (rv == -1) { - return -1; - } - - PR_ASSERT(rv == 1); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - err = _MD_beos_get_nonblocking_connect_error(osfd); - if (err != 0) { - _PR_MD_MAP_CONNECT_ERROR(err); - return -1; - } - return 0; - } -#endif - - _PR_MD_MAP_CONNECT_ERROR(err); - } - - return rv; -} - -PRInt32 -_MD_bind (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) -{ - PRInt32 rv, err; -#ifdef _PR_HAVE_SOCKADDR_LEN - PRNetAddr addrCopy; - - addrCopy = *addr; - ((struct sockaddr *) &addrCopy)->sa_len = addrlen; - ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; - rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen); -#else - rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen); -#endif - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_BIND_ERROR(err); - } - - return(rv); -} - -PRInt32 -_MD_listen (PRFileDesc *fd, PRIntn backlog) -{ - PRInt32 rv, err; - -#ifndef BONE_VERSION - /* Bug workaround! Setting listen to 0 on Be accepts no connections. - ** On most UN*Xes this sets the default. - */ - - if( backlog == 0 ) backlog = 5; -#endif - - rv = listen(fd->secret->md.osfd, backlog); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_LISTEN_ERROR(err); - } - - return(rv); -} - -PRInt32 -_MD_shutdown (PRFileDesc *fd, PRIntn how) -{ - PRInt32 rv, err; - -#ifndef BONE_VERSION - if (how == PR_SHUTDOWN_SEND) - fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_WRITE; - else if (how == PR_SHUTDOWN_RCV) - fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_READ; - else if (how == PR_SHUTDOWN_BOTH) { - fd->secret->md.sock_state = (BE_SOCK_SHUTDOWN_WRITE | BE_SOCK_SHUTDOWN_READ); - } - - return 0; -#else /* BONE_VERSION */ - rv = shutdown(fd->secret->md.osfd, how); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_SHUTDOWN_ERROR(err); - } - return(rv); -#endif -} - -PRInt32 -_MD_socketpair (int af, int type, int flags, PRInt32 *osfd) -{ - return PR_NOT_IMPLEMENTED_ERROR; -} - -PRInt32 -_MD_close_socket (PRInt32 osfd) -{ -#ifdef BONE_VERSION - close( osfd ); -#else - closesocket( osfd ); -#endif -} - -PRStatus -_MD_getsockname (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) -{ - PRInt32 rv, err; - - rv = getsockname(fd->secret->md.osfd, - (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); -#ifdef _PR_HAVE_SOCKADDR_LEN - if (rv == 0) { - /* ignore the sa_len field of struct sockaddr */ - if (addr) { - addr->raw.family = ((struct sockaddr *) addr)->sa_family; - } - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_GETSOCKNAME_ERROR(err); - } - - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus -_MD_getpeername (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) -{ - PRInt32 rv, err; - - rv = getpeername(fd->secret->md.osfd, - (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); - -#ifdef _PR_HAVE_SOCKADDR_LEN - if (rv == 0) { - /* ignore the sa_len field of struct sockaddr */ - if (addr) { - addr->raw.family = ((struct sockaddr *) addr)->sa_family; - } - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ - - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_GETPEERNAME_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus -_MD_getsockopt (PRFileDesc *fd, PRInt32 level, - PRInt32 optname, char* optval, PRInt32* optlen) -{ - PRInt32 rv, err; - - rv = getsockopt(fd->secret->md.osfd, level, optname, - optval, (_PRSockLen_t *)optlen); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_GETSOCKOPT_ERROR(err); - } - - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus -_MD_setsockopt (PRFileDesc *fd, PRInt32 level, - PRInt32 optname, const char* optval, PRInt32 optlen) -{ - PRInt32 rv, err; - - rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_SETSOCKOPT_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRInt32 -_MD_accept_read (PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, - void *buf, PRInt32 amount, PRIntervalTime timeout) -{ - return PR_NOT_IMPLEMENTED_ERROR; -} - -#ifndef BONE_VERSION -PRInt32 -_MD_socket (int af, int type, int flags) -{ - PRInt32 osfd, err; - - osfd = socket( af, type, 0 ); - - if( -1 == osfd ) { - - err = _MD_ERRNO(); - _PR_MD_MAP_SOCKET_ERROR( err ); - } - - return( osfd ); -} -#else -PRInt32 -_MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto) -{ - PRInt32 osfd, err; - - osfd = socket(domain, type, proto); - - if (osfd == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_SOCKET_ERROR(err); - } - - return(osfd); -} -#endif - -PRInt32 -_MD_socketavailable (PRFileDesc *fd) -{ -#ifdef BONE_VERSION - PRInt32 result; - - if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) { - _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO()); - return -1; - } - return result; -#else - return PR_NOT_IMPLEMENTED_ERROR; -#endif -} - -PRInt32 -_MD_get_socket_error (void) -{ - return PR_NOT_IMPLEMENTED_ERROR; -} - -PRStatus -_MD_gethostname (char *name, PRUint32 namelen) -{ - PRInt32 rv, err; - - rv = gethostname(name, namelen); - if (rv == 0) - { - err = _MD_ERRNO(); - _PR_MD_MAP_GETHOSTNAME_ERROR(err); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -#ifndef BONE_VERSION -PRInt32 -_MD_beos_get_nonblocking_connect_error(PRFileDesc *fd) -{ - int rv; - int flags = 0; - - rv = recv(fd->secret->md.osfd, NULL, 0, flags); - PR_ASSERT(-1 == rv || 0 == rv); - if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) { - return errno; - } - return 0; /* no error */ -} -#else -PRInt32 -_MD_beos_get_nonblocking_connect_error(int osfd) -{ - return PR_NOT_IMPLEMENTED_ERROR; - // int err; - // _PRSockLen_t optlen = sizeof(err); - // if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) { - // return errno; - // } else { - // return err; - // } -} -#endif /* BONE_VERSION */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bproc.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bproc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bproc.c 2012-03-06 13:14:13.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bproc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,212 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include -#include - -#define _PR_SIGNALED_EXITSTATUS 256 - -PRProcess* -_MD_create_process (const char *path, char *const *argv, - char *const *envp, const PRProcessAttr *attr) -{ - PRProcess *process; - int nEnv, idx; - char *const *childEnvp; - char **newEnvp = NULL; - int flags; - PRBool found = PR_FALSE; - - process = PR_NEW(PRProcess); - if (!process) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - childEnvp = envp; - if (attr && attr->fdInheritBuffer) { - if (NULL == childEnvp) { - childEnvp = environ; - } - for (nEnv = 0; childEnvp[nEnv]; nEnv++) { - } - newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *)); - if (NULL == newEnvp) { - PR_DELETE(process); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - for (idx = 0; idx < nEnv; idx++) { - newEnvp[idx] = childEnvp[idx]; - if (!found && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) { - newEnvp[idx] = attr->fdInheritBuffer; - found = PR_TRUE; - } - } - if (!found) { - newEnvp[idx++] = attr->fdInheritBuffer; - } - newEnvp[idx] = NULL; - childEnvp = newEnvp; - } - - process->md.pid = fork(); - - if ((pid_t) -1 == process->md.pid) { - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno); - PR_DELETE(process); - if (newEnvp) { - PR_DELETE(newEnvp); - } - return NULL; - } else if (0 == process->md.pid) { /* the child process */ - /* - * If the child process needs to exit, it must call _exit(). - * Do not call exit(), because exit() will flush and close - * the standard I/O file descriptors, and hence corrupt - * the parent process's standard I/O data structures. - */ - - if (attr) { - /* the osfd's to redirect stdin, stdout, and stderr to */ - int in_osfd = -1, out_osfd = -1, err_osfd = -1; - - if (attr->stdinFd - && attr->stdinFd->secret->md.osfd != 0) { - in_osfd = attr->stdinFd->secret->md.osfd; - if (dup2(in_osfd, 0) != 0) { - _exit(1); /* failed */ - } - flags = fcntl(0, F_GETFL, 0); - if (flags & O_NONBLOCK) { - fcntl(0, F_SETFL, flags & ~O_NONBLOCK); - } - } - if (attr->stdoutFd - && attr->stdoutFd->secret->md.osfd != 1) { - out_osfd = attr->stdoutFd->secret->md.osfd; - if (dup2(out_osfd, 1) != 1) { - _exit(1); /* failed */ - } - flags = fcntl(1, F_GETFL, 0); - if (flags & O_NONBLOCK) { - fcntl(1, F_SETFL, flags & ~O_NONBLOCK); - } - } - if (attr->stderrFd - && attr->stderrFd->secret->md.osfd != 2) { - err_osfd = attr->stderrFd->secret->md.osfd; - if (dup2(err_osfd, 2) != 2) { - _exit(1); /* failed */ - } - flags = fcntl(2, F_GETFL, 0); - if (flags & O_NONBLOCK) { - fcntl(2, F_SETFL, flags & ~O_NONBLOCK); - } - } - if (in_osfd != -1) { - close(in_osfd); - } - if (out_osfd != -1 && out_osfd != in_osfd) { - close(out_osfd); - } - if (err_osfd != -1 && err_osfd != in_osfd - && err_osfd != out_osfd) { - close(err_osfd); - } - if (attr->currentDirectory) { - if (chdir(attr->currentDirectory) < 0) { - _exit(1); /* failed */ - } - } - } - - if (childEnvp) { - (void)execve(path, argv, childEnvp); - } else { - /* Inherit the environment of the parent. */ - (void)execv(path, argv); - } - /* Whoops! It returned. That's a bad sign. */ - _exit(1); - } - - if (newEnvp) { - PR_DELETE(newEnvp); - } - - return process; -} - -PRStatus -_MD_detach_process (PRProcess *process) -{ - /* If we kept a process table like unix does, - * we'd remove the entry here. - * Since we dont', just delete the process variable - */ - PR_DELETE(process); - return PR_SUCCESS; -} - -PRStatus -_MD_wait_process (PRProcess *process, PRInt32 *exitCode) -{ - PRStatus retVal = PR_SUCCESS; - int ret, status; - - /* Ignore interruptions */ - do { - ret = waitpid(process->md.pid, &status, 0); - } while (ret == -1 && errno == EINTR); - - /* - * waitpid() cannot return 0 because we did not invoke it - * with the WNOHANG option. - */ - PR_ASSERT(0 != ret); - - if (ret < 0) { - PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } - - /* If child process exited normally, return child exit code */ - if (WIFEXITED(status)) { - *exitCode = WEXITSTATUS(status); - } else { - PR_ASSERT(WIFSIGNALED(status)); - *exitCode = _PR_SIGNALED_EXITSTATUS; - } - - PR_DELETE(process); - return PR_SUCCESS; -} - -PRStatus -_MD_kill_process (PRProcess *process) -{ - PRErrorCode prerror; - PRInt32 oserror; - - if (kill(process->md.pid, SIGKILL) == 0) { - return PR_SUCCESS; - } - oserror = errno; - switch (oserror) { - case EPERM: - prerror = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case ESRCH: - prerror = PR_INVALID_ARGUMENT_ERROR; - break; - default: - prerror = PR_UNKNOWN_ERROR; - break; - } - PR_SetError(prerror, oserror); - return PR_FAILURE; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/brng.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/brng.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/brng.c 2012-03-06 13:14:13.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/brng.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "primpl.h" - -extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ) -{ - struct timeval tv; - int n = 0; - int s; - - GETTIMEOFDAY(&tv); - - if ( size > 0 ) { - s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec)); - size -= s; - n += s; - } - if ( size > 0 ) { - s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec)); - size -= s; - n += s; - } - - return n; -} /* end _PR_MD_GetRandomNoise() */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bseg.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bseg.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bseg.c 2012-03-06 13:14:13.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bseg.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -PR_IMPLEMENT(void) - _MD_init_segs (void) -{ -} - -PR_IMPLEMENT(PRStatus) - _MD_alloc_segment (PRSegment *seg, PRUint32 size, void *vaddr) -{ - return PR_NOT_IMPLEMENTED_ERROR; -} - -PR_IMPLEMENT(void) - _MD_free_segment (PRSegment *seg) -{ -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bsrcs.mk nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bsrcs.mk --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/bsrcs.mk 2012-03-06 13:14:13.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/bsrcs.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -# this file lists the source files to be compiled (used in Makefile) and -# then enumerated as object files (in objs.mk) for inclusion in the NSPR -# shared library - -MDCSRCS = \ - beos.c \ - beos_errors.c \ - bfile.c \ - bmisc.c \ - bnet.c \ - bproc.c \ - brng.c \ - bseg.c \ - btime.c \ - bmmap.c \ - $(NULL) diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/btime.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/btime.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/btime.c 2012-03-06 13:14:13.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/btime.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include - -static bigtime_t start; - -PRTime -_MD_now (void) -{ - return (PRTime)real_time_clock_usecs(); -} - -void -_MD_interval_init (void) -{ - /* grab the base interval time */ - start = real_time_clock_usecs(); -} - -PRIntervalTime -_MD_get_interval (void) -{ - return( (PRIntervalTime) real_time_clock_usecs() / 10 ); - -#if 0 - /* return the number of tens of microseconds that have elapsed since - we were initialized */ - bigtime_t now = real_time_clock_usecs(); - now -= start; - now /= 10; - return (PRIntervalTime)now; -#endif -} - -PRIntervalTime -_MD_interval_per_sec (void) -{ - return 100000L; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/.cvsignore 2001-05-12 06:08:09.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/Makefile.in 2012-03-06 13:14:12.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -MOD_DEPTH = ../../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -include $(srcdir)/bsrcs.mk -CSRCS += $(MDCSRCS) - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/objs.mk nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/objs.mk --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/beos/objs.mk 2012-03-06 13:14:13.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/beos/objs.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This makefile appends to the variable OBJS the platform-dependent -# object modules that will be part of the nspr20 library. - -include $(srcdir)/md/beos/bsrcs.mk - -OBJS += $(MDCSRCS:%.c=md/beos/$(OBJDIR)/%.$(OBJ_SUFFIX)) diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/md/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/.cvsignore 2001-05-12 04:24:53.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/md/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/Makefile.in 2012-03-06 13:14:11.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -DIRS = $(PR_MD_ARCH_DIR) - -CSRCS = \ - prosdep.c \ - $(NULL) - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/.cvsignore 2001-05-12 06:11:46.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/Makefile.in 2012-03-06 13:14:13.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -ifeq ($(OS_TARGET), OS2) -CSRCS = \ - os2misc.c \ - os2sem.c \ - os2inrval.c \ - os2gc.c \ - os2thred.c \ - os2io.c \ - os2cv.c \ - os2sock.c \ - os2_errors.c \ - os2poll.c \ - os2rng.c \ - $(NULL) -endif - -ASFILES = os2emx.s os2vaclegacy.s - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - - - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/objs.mk nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/objs.mk --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/objs.mk 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/objs.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This makefile appends to the variable OBJS the platform-dependent -# object modules that will be part of the nspr20 library. - -CSRCS = \ - os2io.c \ - os2sock.c \ - os2thred.c \ - os2cv.c \ - os2gc.c \ - os2misc.c \ - os2inrval.c \ - os2sem.c \ - os2_errors.c \ - os2poll.c \ - os2rng.c \ - $(NULL) - -ASFILES = os2emx.s os2vaclegacy.s - -OBJS += $(addprefix md/os2/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \ - $(addprefix md/os2/$(OBJDIR)/,$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2cv.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2cv.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2cv.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2cv.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,330 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * os2cv.c -- OS/2 Machine-Dependent Code for Condition Variables - * - * We implement our own condition variable wait queue. Each thread - * has a semaphore object (thread->md.blocked_sema) to block on while - * waiting on a condition variable. - * - * We use a deferred condition notify algorithm. When PR_NotifyCondVar - * or PR_NotifyAllCondVar is called, the condition notifies are simply - * recorded in the _MDLock structure. We defer the condition notifies - * until right after we unlock the lock. This way the awakened threads - * have a better chance to reaquire the lock. - */ - -#include "primpl.h" - -/* - * AddThreadToCVWaitQueueInternal -- - * - * Add the thread to the end of the condition variable's wait queue. - * The CV's lock must be locked when this function is called. - */ - -static void -AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv) -{ - PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL) - || (cv->waitTail == NULL && cv->waitHead == NULL)); - cv->nwait += 1; - thred->md.inCVWaitQueue = PR_TRUE; - thred->md.next = NULL; - thred->md.prev = cv->waitTail; - if (cv->waitHead == NULL) { - cv->waitHead = thred; - } else { - cv->waitTail->md.next = thred; - } - cv->waitTail = thred; -} - -/* - * md_UnlockAndPostNotifies -- - * - * Unlock the lock, and then do the deferred condition notifies. - * If waitThred and waitCV are not NULL, waitThred is added to - * the wait queue of waitCV before the lock is unlocked. - * - * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK, - * the two places where a lock is unlocked. - */ -void -md_UnlockAndPostNotifies( - _MDLock *lock, - PRThread *waitThred, - _MDCVar *waitCV) -{ - PRIntn index; - _MDNotified post; - _MDNotified *notified, *prev = NULL; - - /* - * Time to actually notify any conditions that were affected - * while the lock was held. Get a copy of the list that's in - * the lock structure and then zero the original. If it's - * linked to other such structures, we own that storage. - */ - post = lock->notified; /* a safe copy; we own the lock */ - -#if defined(DEBUG) - memset(&lock->notified, 0, sizeof(_MDNotified)); /* reset */ -#else - lock->notified.length = 0; /* these are really sufficient */ - lock->notified.link = NULL; -#endif - - /* - * Figure out how many threads we need to wake up. - */ - notified = &post; /* this is where we start */ - do { - for (index = 0; index < notified->length; ++index) { - _MDCVar *cv = notified->cv[index].cv; - PRThread *thred; - int i; - - /* Fast special case: no waiting threads */ - if (cv->waitHead == NULL) { - notified->cv[index].notifyHead = NULL; - continue; - } - - /* General case */ - if (-1 == notified->cv[index].times) { - /* broadcast */ - thred = cv->waitHead; - while (thred != NULL) { - thred->md.inCVWaitQueue = PR_FALSE; - thred = thred->md.next; - } - notified->cv[index].notifyHead = cv->waitHead; - cv->waitHead = cv->waitTail = NULL; - cv->nwait = 0; - } else { - thred = cv->waitHead; - i = notified->cv[index].times; - while (thred != NULL && i > 0) { - thred->md.inCVWaitQueue = PR_FALSE; - thred = thred->md.next; - i--; - } - notified->cv[index].notifyHead = cv->waitHead; - cv->waitHead = thred; - if (cv->waitHead == NULL) { - cv->waitTail = NULL; - } else { - if (cv->waitHead->md.prev != NULL) { - cv->waitHead->md.prev->md.next = NULL; - cv->waitHead->md.prev = NULL; - } - } - cv->nwait -= notified->cv[index].times - i; - } - } - notified = notified->link; - } while (NULL != notified); - - if (waitThred) { - AddThreadToCVWaitQueueInternal(waitThred, waitCV); - } - - /* Release the lock before notifying */ - DosReleaseMutexSem(lock->mutex); - - notified = &post; /* this is where we start */ - do { - for (index = 0; index < notified->length; ++index) { - PRThread *thred; - PRThread *next; - - thred = notified->cv[index].notifyHead; - while (thred != NULL) { - BOOL rv; - - next = thred->md.next; - thred->md.prev = thred->md.next = NULL; - rv = DosPostEventSem(thred->md.blocked_sema); - PR_ASSERT(rv == NO_ERROR); - thred = next; - } - } - prev = notified; - notified = notified->link; - if (&post != prev) PR_DELETE(prev); - } while (NULL != notified); -} - -/* - * Notifies just get posted to the protecting mutex. The - * actual notification is done when the lock is released so that - * MP systems don't contend for a lock that they can't have. - */ -static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock, - PRBool broadcast) -{ - PRIntn index = 0; - _MDNotified *notified = &lock->notified; - - while (1) { - for (index = 0; index < notified->length; ++index) { - if (notified->cv[index].cv == cvar) { - if (broadcast) { - notified->cv[index].times = -1; - } else if (-1 != notified->cv[index].times) { - notified->cv[index].times += 1; - } - return; - } - } - /* if not full, enter new CV in this array */ - if (notified->length < _MD_CV_NOTIFIED_LENGTH) break; - - /* if there's no link, create an empty array and link it */ - if (NULL == notified->link) { - notified->link = PR_NEWZAP(_MDNotified); - } - - notified = notified->link; - } - - /* A brand new entry in the array */ - notified->cv[index].times = (broadcast) ? -1 : 1; - notified->cv[index].cv = cvar; - notified->length += 1; -} - -/* - * _PR_MD_NEW_CV() -- Creating new condition variable - * ... Solaris uses cond_init() in similar function. - * - * returns: -1 on failure - * 0 when it succeeds. - * - */ -PRInt32 -_PR_MD_NEW_CV(_MDCVar *cv) -{ - cv->magic = _MD_MAGIC_CV; - /* - * The waitHead, waitTail, and nwait fields are zeroed - * when the PRCondVar structure is created. - */ - return 0; -} - -void _PR_MD_FREE_CV(_MDCVar *cv) -{ - cv->magic = (PRUint32)-1; - return; -} - -/* - * _PR_MD_WAIT_CV() -- Wait on condition variable - */ -void -_PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout ) -{ - PRThread *thred = _PR_MD_CURRENT_THREAD(); - ULONG rv, count; - ULONG msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ? - SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(timeout); - - /* - * If we have pending notifies, post them now. - */ - if (0 != lock->notified.length) { - md_UnlockAndPostNotifies(lock, thred, cv); - } else { - AddThreadToCVWaitQueueInternal(thred, cv); - DosReleaseMutexSem(lock->mutex); - } - - /* Wait for notification or timeout; don't really care which */ - rv = DosWaitEventSem(thred->md.blocked_sema, msecs); - if (rv == NO_ERROR) { - DosResetEventSem(thred->md.blocked_sema, &count); - } - - DosRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT); - - PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT); - - if(rv == ERROR_TIMEOUT) - { - if (thred->md.inCVWaitQueue) { - PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL) - || (cv->waitTail == NULL && cv->waitHead == NULL)); - cv->nwait -= 1; - thred->md.inCVWaitQueue = PR_FALSE; - if (cv->waitHead == thred) { - cv->waitHead = thred->md.next; - if (cv->waitHead == NULL) { - cv->waitTail = NULL; - } else { - cv->waitHead->md.prev = NULL; - } - } else { - PR_ASSERT(thred->md.prev != NULL); - thred->md.prev->md.next = thred->md.next; - if (thred->md.next != NULL) { - thred->md.next->md.prev = thred->md.prev; - } else { - PR_ASSERT(cv->waitTail == thred); - cv->waitTail = thred->md.prev; - } - } - thred->md.next = thred->md.prev = NULL; - } else { - /* - * This thread must have been notified, but the - * SemRelease call happens after SemRequest - * times out. Wait on the semaphore again to make it - * non-signaled. We assume this wait won't take long. - */ - rv = DosWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT); - if (rv == NO_ERROR) { - DosResetEventSem(thred->md.blocked_sema, &count); - } - PR_ASSERT(rv == NO_ERROR); - } - } - PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE); - return; -} /* --- end _PR_MD_WAIT_CV() --- */ - -void -_PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock) -{ - md_PostNotifyToCvar(cv, lock, PR_FALSE); - return; -} - -PRStatus -_PR_MD_NEW_LOCK(_MDLock *lock) -{ - DosCreateMutexSem(0, &(lock->mutex), 0, 0); - (lock)->notified.length=0; - (lock)->notified.link=NULL; - return PR_SUCCESS; -} - -void -_PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock) -{ - md_PostNotifyToCvar(cv, lock, PR_TRUE); - return; -} - -void _PR_MD_UNLOCK(_MDLock *lock) -{ - if (0 != lock->notified.length) { - md_UnlockAndPostNotifies(lock, NULL, NULL); - } else { - DosReleaseMutexSem(lock->mutex); - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2emx.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2emx.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2emx.s 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2emx.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -/ -/ This Source Code Form is subject to the terms of the Mozilla Public -/ License, v. 2.0. If a copy of the MPL was not distributed with this -/ file, You can obtain one at http://mozilla.org/MPL/2.0/. - -/ PRInt32 __PR_MD_ATOMIC_INCREMENT(PRInt32 *val) -/ -/ Atomically increment the integer pointed to by 'val' and return -/ the result of the increment. -/ - .text - .globl __PR_MD_ATOMIC_INCREMENT - .align 4 -__PR_MD_ATOMIC_INCREMENT: - movl 4(%esp), %ecx - movl $1, %eax - lock - xaddl %eax, (%ecx) - incl %eax - ret - -/ PRInt32 __PR_MD_ATOMIC_DECREMENT(PRInt32 *val) -/ -/ Atomically decrement the integer pointed to by 'val' and return -/ the result of the decrement. -/ - .text - .globl __PR_MD_ATOMIC_DECREMENT - .align 4 -__PR_MD_ATOMIC_DECREMENT: - movl 4(%esp), %ecx - movl $-1, %eax - lock - xaddl %eax, (%ecx) - decl %eax - ret - -/ PRInt32 __PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) -/ -/ Atomically set the integer pointed to by 'val' to the new -/ value 'newval' and return the old value. -/ -/ An alternative implementation: -/ .text -/ .globl __PR_MD_ATOMIC_SET -/ .align 4 -/__PR_MD_ATOMIC_SET: -/ movl 4(%esp), %ecx -/ movl 8(%esp), %edx -/ movl (%ecx), %eax -/retry: -/ lock -/ cmpxchgl %edx, (%ecx) -/ jne retry -/ ret -/ - .text - .globl __PR_MD_ATOMIC_SET - .align 4 -__PR_MD_ATOMIC_SET: - movl 4(%esp), %ecx - movl 8(%esp), %eax - xchgl %eax, (%ecx) - ret - -/ PRInt32 __PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) -/ -/ Atomically add 'val' to the integer pointed to by 'ptr' -/ and return the result of the addition. -/ - .text - .globl __PR_MD_ATOMIC_ADD - .align 4 -__PR_MD_ATOMIC_ADD: - movl 4(%esp), %ecx - movl 8(%esp), %eax - movl %eax, %edx - lock - xaddl %eax, (%ecx) - addl %edx, %eax - ret diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2_errors.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2_errors.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2_errors.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2_errors.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1095 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prerror.h" -#include "primpl.h" - -void _MD_os2_map_default_error(PRInt32 err) -{ - switch (err) { - case EWOULDBLOCK: - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case EMSGSIZE: - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ENOBUFS: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ECONNREFUSED: - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); - break; - case EISCONN: - PR_SetError(PR_IS_CONNECTED_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case ERROR_NETNAME_DELETED: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} -void _MD_os2_map_opendir_error(PRInt32 err) -{ - switch (err) { - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - case ERROR_INVALID_ACCESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_INVALID_NAME: - case ERROR_INVALID_PARAMETER: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ERROR_TOO_MANY_OPEN_FILES: - case ERROR_NOT_DOS_DISK: - case ERROR_NOT_READY: - case ERROR_OPEN_FAILED: - case ERROR_PATH_BUSY: - case ERROR_CANNOT_MAKE: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - case ERROR_DEVICE_IN_USE: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_FILENAME_EXCED_RANGE: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_SHARING_BUFFER_EXCEEDED: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_closedir_error(PRInt32 err) -{ - switch (err) { - case ERROR_FILE_NOT_FOUND: - case ERROR_ACCESS_DENIED: - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_readdir_error(PRInt32 err) -{ - - switch (err) { - case ERROR_NO_MORE_FILES: - PR_SetError(PR_NO_MORE_FILES_ERROR, err); - break; - case ERROR_FILE_NOT_FOUND: - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_NOT_DOS_DISK: - case ERROR_LOCK_VIOLATION: - case ERROR_BROKEN_PIPE: - case ERROR_NOT_READY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_delete_error(PRInt32 err) -{ - switch (err) { - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_ACCESS_DENIED: - case ERROR_WRITE_PROTECT: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - case ERROR_LOCKED: - case ERROR_SHARING_VIOLATION: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -/* The error code for stat() is in errno. */ -void _MD_os2_map_stat_error(PRInt32 err) -{ - switch (err) { - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - } -} - -void _MD_os2_map_fstat_error(PRInt32 err) -{ - switch (err) { - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - case ERROR_LOCKED: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_rename_error(PRInt32 err) -{ - switch (err) { - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_INVALID_NAME: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_FILENAME_EXCED_RANGE: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ERROR_ALREADY_EXISTS: - case ERROR_FILE_EXISTS: - PR_SetError(PR_FILE_EXISTS_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -/* The error code for access() is in errno. */ -void _MD_os2_map_access_error(PRInt32 err) -{ - switch (err) { - case ENOENT: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - } -} - -void _MD_os2_map_mkdir_error(PRInt32 err) -{ - switch (err) { - case ERROR_ALREADY_EXISTS: - case ERROR_FILE_EXISTS: - PR_SetError(PR_FILE_EXISTS_ERROR, err); - break; - case ERROR_FILE_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_INVALID_NAME: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_FILENAME_EXCED_RANGE: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ERROR_TOO_MANY_OPEN_FILES: - PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); - break; - case ERROR_PATH_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ERROR_DISK_FULL: - case ERROR_HANDLE_DISK_FULL: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; - case ERROR_WRITE_PROTECT: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_rmdir_error(PRInt32 err) -{ - - switch (err) { - case ERROR_FILE_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_INVALID_NAME: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_FILENAME_EXCED_RANGE: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ERROR_TOO_MANY_OPEN_FILES: - PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); - break; - case ERROR_PATH_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ERROR_WRITE_PROTECT: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_read_error(PRInt32 err) -{ - switch (err) { - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - case ERROR_LOCKED: - case ERROR_SHARING_VIOLATION: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_NETNAME_DELETED: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_transmitfile_error(PRInt32 err) -{ - switch (err) { - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - case ERROR_LOCKED: - case ERROR_SHARING_VIOLATION: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_FILENAME_EXCED_RANGE: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ERROR_TOO_MANY_OPEN_FILES: - PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); - break; - case ERROR_PATH_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_write_error(PRInt32 err) -{ - switch (err) { - case ERROR_ACCESS_DENIED: - case ERROR_WRITE_PROTECT: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - case ERROR_LOCKED: - case ERROR_SHARING_VIOLATION: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - case ERROR_DISK_FULL: - case ERROR_HANDLE_DISK_FULL: - case ENOSPC: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; - case ERROR_NETNAME_DELETED: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case EMSGSIZE: - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ENOBUFS: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ECONNREFUSED: - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); - break; - case EISCONN: - PR_SetError(PR_IS_CONNECTED_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_lseek_error(PRInt32 err) -{ - switch (err) { - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_SEEK_ON_DEVICE: - PR_SetError(PR_IO_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_fsync_error(PRInt32 err) -{ - switch (err) { - case ERROR_ACCESS_DENIED: - case ERROR_WRITE_PROTECT: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ERROR_DISK_FULL: - case ERROR_HANDLE_DISK_FULL: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_close_error(PRInt32 err) -{ - switch (err) { - case ERROR_INVALID_HANDLE: - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_socket_error(PRInt32 err) -{ - switch (err) { - case EPROTONOSUPPORT: - PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - case ENOBUFS: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_recv_error(PRInt32 err) -{ - switch (err) { - case EWOULDBLOCK: - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case ERROR_NETNAME_DELETED: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_recvfrom_error(PRInt32 err) -{ - switch (err) { - case EWOULDBLOCK: - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case ERROR_NETNAME_DELETED: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_send_error(PRInt32 err) -{ - switch (err) { - case EWOULDBLOCK: - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case EMSGSIZE: - case EINVAL: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ENOBUFS: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ECONNREFUSED: - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); - break; - case EISCONN: - PR_SetError(PR_IS_CONNECTED_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case ERROR_NETNAME_DELETED: - PR_SetError(PR_CONNECT_RESET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_sendto_error(PRInt32 err) -{ - _MD_os2_map_default_error(err); -} - -void _MD_os2_map_writev_error(int err) -{ - _MD_os2_map_default_error(err); -} - -void _MD_os2_map_accept_error(PRInt32 err) -{ - _MD_os2_map_default_error(err); -} - -void _MD_os2_map_acceptex_error(PRInt32 err) -{ - switch (err) { - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -/* - * An error code of 0 means that the nonblocking connect succeeded. - */ - -int _MD_os2_get_nonblocking_connect_error(int osfd) -{ - int err; - int len = sizeof(err); - if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == -1) { - return sock_errno(); - } else { - return err; - } -} - -void _MD_os2_map_connect_error(PRInt32 err) -{ - switch (err) { - case EWOULDBLOCK: - PR_SetError(PR_WOULD_BLOCK_ERROR, err); - break; - case EINPROGRESS: - PR_SetError(PR_IN_PROGRESS_ERROR, err); - break; - case EALREADY: - case EINVAL: - PR_SetError(PR_ALREADY_INITIATED_ERROR, err); - break; - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case EADDRNOTAVAIL: - PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case EAFNOSUPPORT: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - case ETIMEDOUT: - PR_SetError(PR_IO_TIMEOUT_ERROR, err); - break; - case ECONNREFUSED: - PR_SetError(PR_CONNECT_REFUSED_ERROR, err); - break; - case ENETUNREACH: - PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err); - break; - case EADDRINUSE: - PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); - break; - case EISCONN: - PR_SetError(PR_IS_CONNECTED_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_bind_error(PRInt32 err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case EADDRNOTAVAIL: - PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); - break; - case EADDRINUSE: - PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); - break; - case EACCES: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case EINVAL: - PR_SetError(PR_SOCKET_ADDRESS_IS_BOUND_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_listen_error(PRInt32 err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case EOPNOTSUPP: - PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_shutdown_error(PRInt32 err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case ENOTCONN: - PR_SetError(PR_NOT_CONNECTED_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_socketpair_error(PRInt32 err) -{ - switch (err) { - case ENOMEM: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case EAFNOSUPPORT: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - case EPROTONOSUPPORT: - PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err); - break; - case EOPNOTSUPP: - PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err); - break; - case EPROTOTYPE: - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); - break; - default: - _MD_os2_map_default_error(err); - return; - } -} - -void _MD_os2_map_getsockname_error(PRInt32 err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case ENOBUFS: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_getpeername_error(PRInt32 err) -{ - - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case ENOTCONN: - PR_SetError(PR_NOT_CONNECTED_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case ENOBUFS: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_getsockopt_error(PRInt32 err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case ENOPROTOOPT: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case EINVAL: - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_setsockopt_error(PRInt32 err) -{ - switch (err) { - case EBADF: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ENOTSOCK: - PR_SetError(PR_NOT_SOCKET_ERROR, err); - break; - case ENOPROTOOPT: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case EINVAL: - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_open_error(PRInt32 err) -{ - switch (err) { - case ERROR_ALREADY_EXISTS: - case ERROR_FILE_EXISTS: - PR_SetError(PR_FILE_EXISTS_ERROR, err); - break; - case ERROR_FILE_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_INVALID_NAME: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); - break; - case ERROR_NOT_READY: - case ERROR_OPEN_FAILED: - case ERROR_PATH_BUSY: - PR_SetError(PR_IO_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_FILENAME_EXCED_RANGE: - PR_SetError(PR_NAME_TOO_LONG_ERROR, err); - break; - case ERROR_TOO_MANY_OPEN_FILES: - PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); - break; - case ERROR_PATH_NOT_FOUND: - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - case ERROR_DISK_FULL: - case ERROR_HANDLE_DISK_FULL: - PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); - break; - case ERROR_WRITE_PROTECT: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_gethostname_error(PRInt32 err) -{ - switch (err) { -#ifdef SOCEFAULT - case SOCEFAULT: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; -#endif - case ENETDOWN: - case EINPROGRESS: - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} - -void _MD_os2_map_select_error(PRInt32 err) -{ - PRErrorCode prerror; - - switch (err) { - /* - * OS/2 select() only works on sockets. So in this - * context, ENOTSOCK is equivalent to EBADF on Unix. - */ - case ENOTSOCK: - prerror = PR_BAD_DESCRIPTOR_ERROR; - break; - case EINVAL: - prerror = PR_INVALID_ARGUMENT_ERROR; - break; -#ifdef SOCEFAULT - case SOCEFAULT: - prerror = PR_ACCESS_FAULT_ERROR; - break; -#endif - default: - prerror = PR_UNKNOWN_ERROR; - } - PR_SetError(prerror, err); -} - -void _MD_os2_map_lockf_error(PRInt32 err) -{ - switch (err) { - case ERROR_ACCESS_DENIED: - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); - break; - case ERROR_INVALID_HANDLE: - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); - break; - case ERROR_INVALID_ADDRESS: - PR_SetError(PR_ACCESS_FAULT_ERROR, err); - break; - case ERROR_DRIVE_LOCKED: - case ERROR_LOCKED: - case ERROR_SHARING_VIOLATION: - PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_MORE_DATA: - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); - break; - default: - PR_SetError(PR_UNKNOWN_ERROR, err); - break; - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2gc.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2gc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2gc.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2gc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * GC related routines - * - */ -#include "primpl.h" - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - CONTEXTRECORD context; - context.ContextFlags = CONTEXT_INTEGER; - - if (_PR_IS_NATIVE_THREAD(t)) { - context.ContextFlags |= CONTEXT_CONTROL; - if (QueryThreadContext(t->md.handle, CONTEXT_CONTROL, &context)) { - t->md.gcContext[0] = context.ctx_RegEax; - t->md.gcContext[1] = context.ctx_RegEbx; - t->md.gcContext[2] = context.ctx_RegEcx; - t->md.gcContext[3] = context.ctx_RegEdx; - t->md.gcContext[4] = context.ctx_RegEsi; - t->md.gcContext[5] = context.ctx_RegEdi; - t->md.gcContext[6] = context.ctx_RegEsp; - t->md.gcContext[7] = context.ctx_RegEbp; - *np = PR_NUM_GCREGS; - } else { - PR_ASSERT(0);/* XXX */ - } - } - return (PRWord *)&t->md.gcContext; -} - -/* This function is not used right now, but is left as a reference. - * If you ever need to get the fiberID from the currently running fiber, - * this is it. - */ -void * -GetMyFiberID() -{ - void *fiberData = 0; - - /* A pointer to our tib entry is found at FS:[18] - * At offset 10h is the fiberData pointer. The context of the - * fiber is stored in there. - */ -#ifdef HAVE_ASM - __asm { - mov EDX, FS:[18h] - mov EAX, DWORD PTR [EDX+10h] - mov [fiberData], EAX - } -#endif - - return fiberData; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2inrval.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2inrval.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2inrval.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2inrval.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * OS/2 interval timers - * - */ - -#include "primpl.h" - -static PRBool useHighResTimer = PR_FALSE; -PRIntervalTime _os2_ticksPerSec = -1; -PRIntn _os2_bitShift = 0; -PRInt32 _os2_highMask = 0; - -void -_PR_MD_INTERVAL_INIT() -{ - char *envp; - ULONG timerFreq; - APIRET rc; - - if ((envp = getenv("NSPR_OS2_NO_HIRES_TIMER")) != NULL) { - if (atoi(envp) == 1) - return; - } - - timerFreq = 0; /* OS/2 high-resolution timer frequency in Hz */ - rc = DosTmrQueryFreq(&timerFreq); - if (NO_ERROR == rc) { - useHighResTimer = PR_TRUE; - PR_ASSERT(timerFreq != 0); - while (timerFreq > PR_INTERVAL_MAX) { - timerFreq >>= 1; - _os2_bitShift++; - _os2_highMask = (_os2_highMask << 1)+1; - } - - _os2_ticksPerSec = timerFreq; - PR_ASSERT(_os2_ticksPerSec > PR_INTERVAL_MIN); - } -} - -PRIntervalTime -_PR_MD_GET_INTERVAL() -{ - if (useHighResTimer) { - QWORD timestamp; - PRInt32 top; - APIRET rc = DosTmrQueryTime(×tamp); - if (NO_ERROR != rc) { - return -1; - } - /* Sadly, nspr requires the interval to range from 1000 ticks per - * second to only 100000 ticks per second. DosTmrQueryTime is too - * high resolution... - */ - top = timestamp.ulHi & _os2_highMask; - top = top << (32 - _os2_bitShift); - timestamp.ulLo = timestamp.ulLo >> _os2_bitShift; - timestamp.ulLo = timestamp.ulLo + top; - return (PRUint32)timestamp.ulLo; - } else { - ULONG msCount = -1; - DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msCount, sizeof(msCount)); - return msCount; - } -} - -PRIntervalTime -_PR_MD_INTERVAL_PER_SEC() -{ - if (useHighResTimer) { - return _os2_ticksPerSec; - } else { - return 1000; - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2io.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2io.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2io.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2io.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,942 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* OS2 IO module - * - * Assumes synchronous I/O. - * - */ - -#include "primpl.h" -#include "prio.h" -#include -#include -#include -#include -#include -#include - -struct _MDLock _pr_ioq_lock; - -static PRBool isWSEB = PR_FALSE; /* whether we are using an OS/2 kernel that supports large files */ - -typedef APIRET (*DosOpenLType)(PSZ pszFileName, PHFILE pHf, PULONG pulAction, - LONGLONG cbFile, ULONG ulAttribute, - ULONG fsOpenFlags, ULONG fsOpenMode, - PEAOP2 peaop2); - -typedef APIRET (*DosSetFileLocksLType)(HFILE hFile, PFILELOCKL pflUnlock, - PFILELOCKL pflLock, ULONG timeout, - ULONG flags); - -typedef APIRET (*DosSetFilePtrLType)(HFILE hFile, LONGLONG ib, ULONG method, - PLONGLONG ibActual); - -DosOpenLType myDosOpenL; -DosSetFileLocksLType myDosSetFileLocksL; -DosSetFilePtrLType myDosSetFilePtrL; - -void -_PR_MD_INIT_IO() -{ - APIRET rc; - HMODULE module; - - sock_init(); - - rc = DosLoadModule(NULL, 0, "DOSCALL1", &module); - if (rc != NO_ERROR) - { - return; - } - rc = DosQueryProcAddr(module, 981, NULL, (PFN*) &myDosOpenL); - if (rc != NO_ERROR) - { - return; - } - rc = DosQueryProcAddr(module, 986, NULL, (PFN*) &myDosSetFileLocksL); - if (rc != NO_ERROR) - { - return; - } - rc = DosQueryProcAddr(module, 988, NULL, (PFN*) &myDosSetFilePtrL); - if (rc != NO_ERROR) - { - return; - } - isWSEB = PR_TRUE; -} - -PRStatus -_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PRInt32 rv; - ULONG count; - - PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? - SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks); - rv = DosWaitEventSem(thread->md.blocked_sema, msecs); - DosResetEventSem(thread->md.blocked_sema, &count); - switch(rv) - { - case NO_ERROR: - return PR_SUCCESS; - break; - case ERROR_TIMEOUT: - _PR_THREAD_LOCK(thread); - if (thread->state == _PR_IO_WAIT) { - ; - } else { - if (thread->wait.cvar != NULL) { - thread->wait.cvar = NULL; - _PR_THREAD_UNLOCK(thread); - } else { - /* The CVAR was notified just as the timeout - * occurred. This led to us being notified twice. - * call SemRequest() to clear the semaphore. - */ - _PR_THREAD_UNLOCK(thread); - rv = DosWaitEventSem(thread->md.blocked_sema, 0); - DosResetEventSem(thread->md.blocked_sema, &count); - PR_ASSERT(rv == NO_ERROR); - } - } - return PR_SUCCESS; - break; - default: - break; - } - return PR_FAILURE; -} -PRStatus -_PR_MD_WAKEUP_WAITER(PRThread *thread) -{ - if ( _PR_IS_NATIVE_THREAD(thread) ) - { - if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR) - return PR_FAILURE; - else - return PR_SUCCESS; - } -} - - -/* --- FILE IO ----------------------------------------------------------- */ -/* - * _PR_MD_OPEN() -- Open a file - * - * returns: a fileHandle - * - * The NSPR open flags (osflags) are translated into flags for OS/2 - * - * Mode seems to be passed in as a unix style file permissions argument - * as in 0666, in the case of opening the logFile. - * - */ -PRInt32 -_PR_MD_OPEN(const char *name, PRIntn osflags, int mode) -{ - HFILE file; - PRInt32 access = OPEN_SHARE_DENYNONE; - PRInt32 flags = 0L; - APIRET rc = 0; - PRUword actionTaken; - -#ifdef MOZ_OS2_HIGH_MEMORY - /* - * All the pointer arguments (&file, &actionTaken and name) have to be in - * low memory for DosOpen to use them. - * The following moves name to low memory. - */ - if ((ULONG)name >= 0x20000000) - { - size_t len = strlen(name) + 1; - char *copy = (char *)alloca(len); - memcpy(copy, name, len); - name = copy; - } -#endif - - if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH; - - if (osflags & PR_RDONLY) - access |= OPEN_ACCESS_READONLY; - else if (osflags & PR_WRONLY) - access |= OPEN_ACCESS_WRITEONLY; - else if(osflags & PR_RDWR) - access |= OPEN_ACCESS_READWRITE; - - if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) - { - flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; - } - else if (osflags & PR_CREATE_FILE) - { - if (osflags & PR_TRUNCATE) - flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; - else - flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; - } - else - { - if (osflags & PR_TRUNCATE) - flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; - else - flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; - } - - do { - if (isWSEB) - { - rc = myDosOpenL((char*)name, - &file, /* file handle if successful */ - &actionTaken, /* reason for failure */ - 0, /* initial size of new file */ - FILE_NORMAL, /* file system attributes */ - flags, /* Open flags */ - access, /* Open mode and rights */ - 0); /* OS/2 Extended Attributes */ - } - else - { - rc = DosOpen((char*)name, - &file, /* file handle if successful */ - &actionTaken, /* reason for failure */ - 0, /* initial size of new file */ - FILE_NORMAL, /* file system attributes */ - flags, /* Open flags */ - access, /* Open mode and rights */ - 0); /* OS/2 Extended Attributes */ - }; - if (rc == ERROR_TOO_MANY_OPEN_FILES) { - ULONG CurMaxFH = 0; - LONG ReqCount = 20; - APIRET rc2; - rc2 = DosSetRelMaxFH(&ReqCount, &CurMaxFH); - if (rc2 != NO_ERROR) { - break; - } - } - } while (rc == ERROR_TOO_MANY_OPEN_FILES); - - if (rc != NO_ERROR) { - _PR_MD_MAP_OPEN_ERROR(rc); - return -1; - } - - return (PRInt32)file; -} - -PRInt32 -_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len) -{ - ULONG bytes; - int rv; - - rv = DosRead((HFILE)fd->secret->md.osfd, - (PVOID)buf, - len, - &bytes); - - if (rv != NO_ERROR) - { - /* ERROR_HANDLE_EOF can only be returned by async io */ - PR_ASSERT(rv != ERROR_HANDLE_EOF); - if (rv == ERROR_BROKEN_PIPE) - return 0; - else { - _PR_MD_MAP_READ_ERROR(rv); - return -1; - } - } - return (PRInt32)bytes; -} - -PRInt32 -_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len) -{ - PRInt32 bytes; - int rv; - - rv = DosWrite((HFILE)fd->secret->md.osfd, - (PVOID)buf, - len, - (PULONG)&bytes); - - if (rv != NO_ERROR) - { - _PR_MD_MAP_WRITE_ERROR(rv); - return -1; - } - - if (len != bytes) { - rv = ERROR_DISK_FULL; - _PR_MD_MAP_WRITE_ERROR(rv); - return -1; - } - - return bytes; -} /* --- end _PR_MD_WRITE() --- */ - -PRInt32 -_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence) -{ - PRInt32 rv; - PRUword newLocation; - - rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation); - - if (rv != NO_ERROR) { - _PR_MD_MAP_LSEEK_ERROR(rv); - return -1; - } else - return newLocation; -} - -PRInt64 -_PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence) -{ -#ifdef NO_LONG_LONG - PRInt64 result; - PRInt32 rv, low = offset.lo, hi = offset.hi; - PRUword newLocation; - - rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation); - rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation); - - if (rv != NO_ERROR) { - _PR_MD_MAP_LSEEK_ERROR(rv); - hi = newLocation = -1; - } - - result.lo = newLocation; - result.hi = hi; - return result; - -#else - PRInt32 where, rc, lo = (PRInt32)offset, hi = (PRInt32)(offset >> 32); - PRUint64 rv; - PRUint32 newLocation, uhi; - PRUint64 newLocationL; - - switch (whence) - { - case PR_SEEK_SET: - where = FILE_BEGIN; - break; - case PR_SEEK_CUR: - where = FILE_CURRENT; - break; - case PR_SEEK_END: - where = FILE_END; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - if (isWSEB) - { - rc = myDosSetFilePtrL((HFILE)fd->secret->md.osfd, offset, where, (PLONGLONG)&newLocationL); - } - else - { - rc = DosSetFilePtr((HFILE)fd->secret->md.osfd, lo, where, (PULONG)&newLocation); - } - - if (rc != NO_ERROR) { - _PR_MD_MAP_LSEEK_ERROR(rc); - return -1; - } - - if (isWSEB) - { - return newLocationL; - } - - uhi = (PRUint32)hi; - PR_ASSERT((PRInt32)uhi >= 0); - rv = uhi; - PR_ASSERT((PRInt64)rv >= 0); - rv = (rv << 32); - PR_ASSERT((PRInt64)rv >= 0); - rv += newLocation; - PR_ASSERT((PRInt64)rv >= 0); - return (PRInt64)rv; -#endif -} - -PRInt32 -_PR_MD_FSYNC(PRFileDesc *fd) -{ - PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd); - - if (rc != NO_ERROR) { - if (rc != ERROR_ACCESS_DENIED) { - _PR_MD_MAP_FSYNC_ERROR(rc); - return -1; - } - } - return 0; -} - -PRInt32 -_MD_CloseFile(PRInt32 osfd) -{ - PRInt32 rv; - - rv = DosClose((HFILE)osfd); - if (rv != NO_ERROR) - _PR_MD_MAP_CLOSE_ERROR(rv); - return rv; -} - - -/* --- DIR IO ------------------------------------------------------------ */ -#define GetFileFromDIR(d) (isWSEB?(d)->d_entry.large.achName:(d)->d_entry.small.achName) -#define GetFileAttr(d) (isWSEB?(d)->d_entry.large.attrFile:(d)->d_entry.small.attrFile) - -void FlipSlashes(char *cp, int len) -{ - while (--len >= 0) { - if (cp[0] == '/') { - cp[0] = PR_DIRECTORY_SEPARATOR; - } - cp++; - } -} - -/* -** -** Local implementations of standard Unix RTL functions which are not provided -** by the VAC RTL. -** -*/ - -PRInt32 -_PR_MD_CLOSE_DIR(_MDDir *d) -{ - PRInt32 rc; - - if ( d ) { - rc = DosFindClose(d->d_hdl); - if(rc == NO_ERROR){ - d->magic = (PRUint32)-1; - return PR_SUCCESS; - } else { - _PR_MD_MAP_CLOSEDIR_ERROR(rc); - return PR_FAILURE; - } - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; -} - - -PRStatus -_PR_MD_OPEN_DIR(_MDDir *d, const char *name) -{ - char filename[ CCHMAXPATH ]; - PRUword numEntries, rc; - - numEntries = 1; - - PR_snprintf(filename, CCHMAXPATH, "%s%s%s", - name, PR_DIRECTORY_SEPARATOR_STR, "*.*"); - FlipSlashes( filename, strlen(filename) ); - - d->d_hdl = HDIR_CREATE; - - if (isWSEB) - { - rc = DosFindFirst( filename, - &d->d_hdl, - FILE_DIRECTORY | FILE_HIDDEN, - &(d->d_entry.large), - sizeof(d->d_entry.large), - &numEntries, - FIL_STANDARDL); - } - else - { - rc = DosFindFirst( filename, - &d->d_hdl, - FILE_DIRECTORY | FILE_HIDDEN, - &(d->d_entry.small), - sizeof(d->d_entry.small), - &numEntries, - FIL_STANDARD); - } - if ( rc != NO_ERROR ) { - _PR_MD_MAP_OPENDIR_ERROR(rc); - return PR_FAILURE; - } - d->firstEntry = PR_TRUE; - d->magic = _MD_MAGIC_DIR; - return PR_SUCCESS; -} - -char * -_PR_MD_READ_DIR(_MDDir *d, PRIntn flags) -{ - PRUword numFiles = 1; - BOOL rv; - char *fileName; - USHORT fileAttr; - - if ( d ) { - while (1) { - if (d->firstEntry) { - d->firstEntry = PR_FALSE; - rv = NO_ERROR; - } else { - rv = DosFindNext(d->d_hdl, - &(d->d_entry), - sizeof(d->d_entry), - &numFiles); - } - if (rv != NO_ERROR) { - break; - } - fileName = GetFileFromDIR(d); - fileAttr = GetFileAttr(d); - if ( (flags & PR_SKIP_DOT) && - (fileName[0] == '.') && (fileName[1] == '\0')) - continue; - if ( (flags & PR_SKIP_DOT_DOT) && - (fileName[0] == '.') && (fileName[1] == '.') && - (fileName[2] == '\0')) - continue; - /* - * XXX - * Is this the correct definition of a hidden file on OS/2? - */ - if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN)) - return fileName; - else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN)) - continue; - return fileName; - } - PR_ASSERT(NO_ERROR != rv); - _PR_MD_MAP_READDIR_ERROR(rv); - return NULL; - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; -} - -PRInt32 -_PR_MD_DELETE(const char *name) -{ - PRInt32 rc = DosDelete((char*)name); - if(rc == NO_ERROR) { - return 0; - } else { - _PR_MD_MAP_DELETE_ERROR(rc); - return -1; - } -} - -PRInt32 -_PR_MD_STAT(const char *fn, struct stat *info) -{ - PRInt32 rv; - char filename[CCHMAXPATH]; - - PR_snprintf(filename, CCHMAXPATH, "%s", fn); - FlipSlashes(filename, strlen(filename)); - - rv = _stat((char*)filename, info); - if (-1 == rv) { - /* - * Check for MSVC runtime library _stat() bug. - * (It's really a bug in FindFirstFile().) - * If a pathname ends in a backslash or slash, - * e.g., c:\temp\ or c:/temp/, _stat() will fail. - * Note: a pathname ending in a slash (e.g., c:/temp/) - * can be handled by _stat() on NT but not on Win95. - * - * We remove the backslash or slash at the end and - * try again. - * - * Not sure if this happens on OS/2 or not, - * but it doesn't hurt to be careful. - */ - - int len = strlen(fn); - if (len > 0 && len <= _MAX_PATH - && (fn[len - 1] == '\\' || fn[len - 1] == '/')) { - char newfn[_MAX_PATH + 1]; - - strcpy(newfn, fn); - newfn[len - 1] = '\0'; - rv = _stat(newfn, info); - } - } - - if (-1 == rv) { - _PR_MD_MAP_STAT_ERROR(errno); - } - return rv; -} - -PRInt32 -_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info) -{ - struct stat sb; - PRInt32 rv; - PRInt64 s, s2us; - - if ( (rv = _PR_MD_STAT(fn, &sb)) == 0 ) { - if (info) { - if (S_IFREG & sb.st_mode) - info->type = PR_FILE_FILE ; - else if (S_IFDIR & sb.st_mode) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_OTHER; - info->size = sb.st_size; - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(s, sb.st_mtime); - LL_MUL(s, s, s2us); - info->modifyTime = s; - LL_I2L(s, sb.st_ctime); - LL_MUL(s, s, s2us); - info->creationTime = s; - } - } - return rv; -} - -PRInt32 -_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) -{ - PRFileInfo info32; - PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32); - if (rv != 0) - { - return rv; - } - info->type = info32.type; - LL_UI2L(info->size,info32.size); - info->modifyTime = info32.modifyTime; - info->creationTime = info32.creationTime; - - if (isWSEB) - { - APIRET rc ; - FILESTATUS3L fstatus; - - rc = DosQueryPathInfo(fn, FIL_STANDARDL, &fstatus, sizeof(fstatus)); - - if (NO_ERROR != rc) - { - _PR_MD_MAP_OPEN_ERROR(rc); - return -1; - } - - if (! (fstatus.attrFile & FILE_DIRECTORY)) - { - info->size = fstatus.cbFile; - } - } - - return rv; -} - -PRInt32 -_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) -{ - /* For once, the VAC compiler/library did a nice thing. - * The file handle used by the C runtime is the same one - * returned by the OS when you call DosOpen(). This means - * that you can take an OS HFILE and use it with C file - * functions. The only caveat is that you have to call - * _setmode() first to initialize some junk. This is - * immensely useful because I did not have a clue how to - * implement this function otherwise. The windows folks - * took the source from the Microsoft C library source, but - * IBM wasn't kind enough to ship the source with VAC. - * On second thought, the needed function could probably - * be gotten from the OS/2 GNU library source, but the - * point is now moot. - */ - struct stat hinfo; - PRInt64 s, s2us; - - _setmode(fd->secret->md.osfd, O_BINARY); - if(fstat((int)fd->secret->md.osfd, &hinfo) != NO_ERROR) { - _PR_MD_MAP_FSTAT_ERROR(errno); - return -1; - } - - if (hinfo.st_mode & S_IFDIR) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_FILE; - - info->size = hinfo.st_size; - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(s, hinfo.st_mtime); - LL_MUL(s, s, s2us); - info->modifyTime = s; - LL_I2L(s, hinfo.st_ctime); - LL_MUL(s, s, s2us); - info->creationTime = s; - - return 0; -} - -PRInt32 -_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info) -{ - PRFileInfo info32; - PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32); - if (0 == rv) - { - info->type = info32.type; - LL_UI2L(info->size,info32.size); - - info->modifyTime = info32.modifyTime; - info->creationTime = info32.creationTime; - } - - if (isWSEB) - { - APIRET rc ; - FILESTATUS3L fstatus; - - rc = DosQueryFileInfo(fd->secret->md.osfd, FIL_STANDARDL, &fstatus, sizeof(fstatus)); - - if (NO_ERROR != rc) - { - _PR_MD_MAP_OPEN_ERROR(rc); - return -1; - } - - if (! (fstatus.attrFile & FILE_DIRECTORY)) - { - info->size = fstatus.cbFile; - } - } - - return rv; -} - - -PRInt32 -_PR_MD_RENAME(const char *from, const char *to) -{ - PRInt32 rc; - /* Does this work with dot-relative pathnames? */ - if ( (rc = DosMove((char *)from, (char *)to)) == NO_ERROR) { - return 0; - } else { - _PR_MD_MAP_RENAME_ERROR(rc); - return -1; - } -} - -PRInt32 -_PR_MD_ACCESS(const char *name, PRAccessHow how) -{ - PRInt32 rv; - switch (how) { - case PR_ACCESS_WRITE_OK: - rv = access(name, 02); - break; - case PR_ACCESS_READ_OK: - rv = access(name, 04); - break; - case PR_ACCESS_EXISTS: - return access(name, 00); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - if (rv < 0) - _PR_MD_MAP_ACCESS_ERROR(errno); - return rv; -} - -PRInt32 -_PR_MD_MKDIR(const char *name, PRIntn mode) -{ - PRInt32 rc; - /* XXXMB - how to translate the "mode"??? */ - if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) { - return 0; - } else { - _PR_MD_MAP_MKDIR_ERROR(rc); - return -1; - } -} - -PRInt32 -_PR_MD_RMDIR(const char *name) -{ - PRInt32 rc; - if ( (rc = DosDeleteDir((char *)name)) == NO_ERROR) { - return 0; - } else { - _PR_MD_MAP_RMDIR_ERROR(rc); - return -1; - } -} - -PRStatus -_PR_MD_LOCKFILE(PRInt32 f) -{ - PRInt32 rv; - FILELOCK lock, unlock; - FILELOCKL lockL, unlockL; - - lock.lOffset = 0; - lockL.lOffset = 0; - lock.lRange = 0xffffffff; - lockL.lRange = 0xffffffffffffffff; - unlock.lOffset = 0; - unlock.lRange = 0; - unlockL.lOffset = 0; - unlockL.lRange = 0; - - /* - * loop trying to DosSetFileLocks(), - * pause for a few miliseconds when can't get the lock - * and try again - */ - for( rv = FALSE; rv == FALSE; /* do nothing */ ) - { - if (isWSEB) - { - rv = myDosSetFileLocksL( (HFILE) f, - &unlockL, &lockL, - 0, 0); - } - else - { - rv = DosSetFileLocks( (HFILE) f, - &unlock, &lock, - 0, 0); - } - if ( rv != NO_ERROR ) - { - DosSleep( 50 ); /* Sleep() a few milisecs and try again. */ - } - } /* end for() */ - return PR_SUCCESS; -} /* end _PR_MD_LOCKFILE() */ - -PRStatus -_PR_MD_TLOCKFILE(PRInt32 f) -{ - return _PR_MD_LOCKFILE(f); -} /* end _PR_MD_TLOCKFILE() */ - - -PRStatus -_PR_MD_UNLOCKFILE(PRInt32 f) -{ - PRInt32 rv; - FILELOCK lock, unlock; - FILELOCKL lockL, unlockL; - - lock.lOffset = 0; - lockL.lOffset = 0; - lock.lRange = 0; - lockL.lRange = 0; - unlock.lOffset = 0; - unlockL.lOffset = 0; - unlock.lRange = 0xffffffff; - unlockL.lRange = 0xffffffffffffffff; - - if (isWSEB) - { - rv = myDosSetFileLocksL( (HFILE) f, - &unlockL, &lockL, - 0, 0); - } - else - { - rv = DosSetFileLocks( (HFILE) f, - &unlock, &lock, - 0, 0); - } - - if ( rv != NO_ERROR ) - { - return PR_SUCCESS; - } - else - { - return PR_FAILURE; - } -} /* end _PR_MD_UNLOCKFILE() */ - -PRStatus -_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) -{ - APIRET rc = 0; - ULONG flags; - switch (fd->methods->file_type) - { - case PR_DESC_PIPE: - case PR_DESC_FILE: - rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags); - if (rc != NO_ERROR) { - PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } - - if (inheritable) - flags &= ~OPEN_FLAGS_NOINHERIT; - else - flags |= OPEN_FLAGS_NOINHERIT; - - /* Mask off flags DosSetFHState don't want. */ - flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT); - rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags); - if (rc != NO_ERROR) { - PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } - break; - - case PR_DESC_LAYERED: - /* what to do here? */ - PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/); - return PR_FAILURE; - - case PR_DESC_SOCKET_TCP: - case PR_DESC_SOCKET_UDP: - /* These are global on OS/2. */ - break; - } - - return PR_SUCCESS; -} - -void -_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported) -{ - /* XXX this function needs to be implemented */ - fd->secret->inheritable = _PR_TRI_UNKNOWN; -} - -void -_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd) -{ - /* XXX this function needs to be reviewed */ - ULONG flags; - - PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); - if (DosQueryFHState((HFILE)fd->secret->md.osfd, &flags) == 0) { - if (flags & OPEN_FLAGS_NOINHERIT) { - fd->secret->inheritable = _PR_TRI_FALSE; - } else { - fd->secret->inheritable = _PR_TRI_TRUE; - } - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2misc.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2misc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2misc.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2misc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,619 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * os2misc.c - * - */ - -#ifdef MOZ_OS2_HIGH_MEMORY -/* os2safe.h has to be included before os2.h, needed for high mem */ -#include -#endif - -#include -#include "primpl.h" - -extern int _CRT_init(void); -extern void _CRT_term(void); -extern void __ctordtorInit(int flag); -extern void __ctordtorTerm(int flag); - -char * -_PR_MD_GET_ENV(const char *name) -{ - return getenv(name); -} - -PRIntn -_PR_MD_PUT_ENV(const char *name) -{ - return putenv(name); -} - - -/* - ************************************************************************** - ************************************************************************** - ** - ** Date and time routines - ** - ************************************************************************** - ************************************************************************** - */ - -#include -/* - *----------------------------------------------------------------------- - * - * PR_Now -- - * - * Returns the current time in microseconds since the epoch. - * The epoch is midnight January 1, 1970 GMT. - * The implementation is machine dependent. This is the - * implementation for OS/2. - * Cf. time_t time(time_t *tp) - * - *----------------------------------------------------------------------- - */ - -PR_IMPLEMENT(PRTime) -PR_Now(void) -{ - PRInt64 s, ms, ms2us, s2us; - struct timeb b; - - ftime(&b); - LL_I2L(ms2us, PR_USEC_PER_MSEC); - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(s, b.time); - LL_I2L(ms, b.millitm); - LL_MUL(ms, ms, ms2us); - LL_MUL(s, s, s2us); - LL_ADD(s, s, ms); - return s; -} - - -/* - *********************************************************************** - *********************************************************************** - * - * Process creation routines - * - *********************************************************************** - *********************************************************************** - */ - -/* - * Assemble the command line by concatenating the argv array. - * Special characters intentionally do not get escaped, and it is - * expected that the caller wraps arguments in quotes if needed - * (e.g. for filename with spaces). - * - * On success, this function returns 0 and the resulting command - * line is returned in *cmdLine. On failure, it returns -1. - */ -static int assembleCmdLine(char *const *argv, char **cmdLine) -{ - char *const *arg; - int cmdLineSize; - - /* - * Find out how large the command line buffer should be. - */ - cmdLineSize = 1; /* final null */ - for (arg = argv+1; *arg; arg++) { - cmdLineSize += strlen(*arg) + 1; /* space in between */ - } - *cmdLine = PR_MALLOC(cmdLineSize); - if (*cmdLine == NULL) { - return -1; - } - - (*cmdLine)[0] = '\0'; - - for (arg = argv+1; *arg; arg++) { - if (arg > argv +1) { - strcat(*cmdLine, " "); - } - strcat(*cmdLine, *arg); - } - return 0; -} - -/* - * Assemble the environment block by concatenating the envp array - * (preserving the terminating null byte in each array element) - * and adding a null byte at the end. - * - * Returns 0 on success. The resulting environment block is returned - * in *envBlock. Note that if envp is NULL, a NULL pointer is returned - * in *envBlock. Returns -1 on failure. - */ -static int assembleEnvBlock(char **envp, char **envBlock) -{ - char *p; - char *q; - char **env; - char *curEnv; - char *cwdStart, *cwdEnd; - int envBlockSize; - - PPIB ppib = NULL; - PTIB ptib = NULL; - - if (envp == NULL) { - *envBlock = NULL; - return 0; - } - - if(DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR) - return -1; - - curEnv = ppib->pib_pchenv; - - cwdStart = curEnv; - while (*cwdStart) { - if (cwdStart[0] == '=' && cwdStart[1] != '\0' - && cwdStart[2] == ':' && cwdStart[3] == '=') { - break; - } - cwdStart += strlen(cwdStart) + 1; - } - cwdEnd = cwdStart; - if (*cwdEnd) { - cwdEnd += strlen(cwdEnd) + 1; - while (*cwdEnd) { - if (cwdEnd[0] != '=' || cwdEnd[1] == '\0' - || cwdEnd[2] != ':' || cwdEnd[3] != '=') { - break; - } - cwdEnd += strlen(cwdEnd) + 1; - } - } - envBlockSize = cwdEnd - cwdStart; - - for (env = envp; *env; env++) { - envBlockSize += strlen(*env) + 1; - } - envBlockSize++; - - p = *envBlock = PR_MALLOC(envBlockSize); - if (p == NULL) { - return -1; - } - - q = cwdStart; - while (q < cwdEnd) { - *p++ = *q++; - } - - for (env = envp; *env; env++) { - q = *env; - while (*q) { - *p++ = *q++; - } - *p++ = '\0'; - } - *p = '\0'; - return 0; -} - -/* - * For qsort. We sort (case-insensitive) the environment strings - * before generating the environment block. - */ -static int compare(const void *arg1, const void *arg2) -{ - return stricmp(* (char**)arg1, * (char**)arg2); -} - -PRProcess * _PR_CreateOS2Process( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr) -{ - PRProcess *proc = NULL; - char *cmdLine = NULL; - char **newEnvp = NULL; - char *envBlock = NULL; - - STARTDATA startData = {0}; - APIRET rc; - ULONG ulAppType = 0; - PID pid = 0; - char *pszComSpec; - char pszEXEName[CCHMAXPATH] = ""; - char pszFormatString[CCHMAXPATH]; - char pszObjectBuffer[CCHMAXPATH]; - char *pszFormatResult = NULL; - - /* - * Variables for DosExecPgm - */ - char szFailed[CCHMAXPATH]; - char *pszCmdLine = NULL; - RESULTCODES procInfo; - HFILE hStdIn = 0, - hStdOut = 0, - hStdErr = 0; - HFILE hStdInSave = -1, - hStdOutSave = -1, - hStdErrSave = -1; - - proc = PR_NEW(PRProcess); - if (!proc) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto errorExit; - } - - if (assembleCmdLine(argv, &cmdLine) == -1) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto errorExit; - } - -#ifdef MOZ_OS2_HIGH_MEMORY - /* - * DosQueryAppType() fails if path (the char* in the first argument) is in - * high memory. If that is the case, the following moves it to low memory. - */ - if ((ULONG)path >= 0x20000000) { - size_t len = strlen(path) + 1; - char *copy = (char *)alloca(len); - memcpy(copy, path, len); - path = copy; - } -#endif - - if (envp == NULL) { - newEnvp = NULL; - } else { - int i; - int numEnv = 0; - while (envp[numEnv]) { - numEnv++; - } - newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *)); - for (i = 0; i <= numEnv; i++) { - newEnvp[i] = envp[i]; - } - qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare); - } - if (assembleEnvBlock(newEnvp, &envBlock) == -1) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto errorExit; - } - - rc = DosQueryAppType(path, &ulAppType); - if (rc != NO_ERROR) { - char *pszDot = strrchr(path, '.'); - if (pszDot) { - /* If it is a CMD file, launch the users command processor */ - if (!stricmp(pszDot, ".cmd")) { - rc = DosScanEnv("COMSPEC", (PSZ *)&pszComSpec); - if (!rc) { - strcpy(pszFormatString, "/C %s %s"); - strcpy(pszEXEName, pszComSpec); - ulAppType = FAPPTYP_WINDOWCOMPAT; - } - } - } - } - if (ulAppType == 0) { - PR_SetError(PR_UNKNOWN_ERROR, 0); - goto errorExit; - } - - if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) { - startData.SessionType = SSF_TYPE_PM; - } - else if (ulAppType & FAPPTYP_WINDOWCOMPAT) { - startData.SessionType = SSF_TYPE_WINDOWABLEVIO; - } - else { - startData.SessionType = SSF_TYPE_DEFAULT; - } - - if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL)) - { - strcpy(pszEXEName, "WINOS2.COM"); - startData.SessionType = PROG_31_STDSEAMLESSVDM; - strcpy(pszFormatString, "/3 %s %s"); - } - - startData.InheritOpt = SSF_INHERTOPT_SHELL; - - if (pszEXEName[0]) { - pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine)); - sprintf(pszFormatResult, pszFormatString, path, cmdLine); - startData.PgmInputs = pszFormatResult; - } else { - strcpy(pszEXEName, path); - startData.PgmInputs = cmdLine; - } - startData.PgmName = pszEXEName; - - startData.Length = sizeof(startData); - startData.Related = SSF_RELATED_INDEPENDENT; - startData.ObjectBuffer = pszObjectBuffer; - startData.ObjectBuffLen = CCHMAXPATH; - startData.Environment = envBlock; - - if (attr) { - /* On OS/2, there is really no way to pass file handles for stdin, - * stdout, and stderr to a new process. Instead, we can make it - * a child process and make the given file handles a copy of our - * stdin, stdout, and stderr. The child process then inherits - * ours, and we set ours back. Twisted and gross I know. If you - * know a better way, please use it. - */ - if (attr->stdinFd) { - hStdIn = 0; - DosDupHandle(hStdIn, &hStdInSave); - DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn); - } - - if (attr->stdoutFd) { - hStdOut = 1; - DosDupHandle(hStdOut, &hStdOutSave); - DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut); - } - - if (attr->stderrFd) { - hStdErr = 2; - DosDupHandle(hStdErr, &hStdErrSave); - DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr); - } - /* - * Build up the Command Line for DosExecPgm - */ - pszCmdLine = PR_MALLOC(strlen(pszEXEName) + - strlen(startData.PgmInputs) + 3); - sprintf(pszCmdLine, "%s%c%s%c", pszEXEName, '\0', - startData.PgmInputs, '\0'); - rc = DosExecPgm(szFailed, - CCHMAXPATH, - EXEC_ASYNCRESULT, - pszCmdLine, - envBlock, - &procInfo, - pszEXEName); - PR_DELETE(pszCmdLine); - - /* Restore our old values. Hope this works */ - if (hStdInSave != -1) { - DosDupHandle(hStdInSave, &hStdIn); - DosClose(hStdInSave); - } - - if (hStdOutSave != -1) { - DosDupHandle(hStdOutSave, &hStdOut); - DosClose(hStdOutSave); - } - - if (hStdErrSave != -1) { - DosDupHandle(hStdErrSave, &hStdErr); - DosClose(hStdErrSave); - } - - if (rc != NO_ERROR) { - /* XXX what error code? */ - PR_SetError(PR_UNKNOWN_ERROR, rc); - goto errorExit; - } - - proc->md.pid = procInfo.codeTerminate; - } else { - /* - * If no STDIN/STDOUT redirection is not needed, use DosStartSession - * to create a new, independent session - */ - rc = DosStartSession(&startData, &ulAppType, &pid); - - if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) { - PR_SetError(PR_UNKNOWN_ERROR, rc); - goto errorExit; - } - - proc->md.pid = pid; - } - - if (pszFormatResult) { - PR_DELETE(pszFormatResult); - } - - PR_DELETE(cmdLine); - if (newEnvp) { - PR_DELETE(newEnvp); - } - if (envBlock) { - PR_DELETE(envBlock); - } - return proc; - -errorExit: - if (cmdLine) { - PR_DELETE(cmdLine); - } - if (newEnvp) { - PR_DELETE(newEnvp); - } - if (envBlock) { - PR_DELETE(envBlock); - } - if (proc) { - PR_DELETE(proc); - } - return NULL; -} /* _PR_CreateOS2Process */ - -PRStatus _PR_DetachOS2Process(PRProcess *process) -{ - /* On OS/2, a process is either created as a child or not. - * You can't 'detach' it later on. - */ - PR_DELETE(process); - return PR_SUCCESS; -} - -/* - * XXX: This will currently only work on a child process. - */ -PRStatus _PR_WaitOS2Process(PRProcess *process, - PRInt32 *exitCode) -{ - ULONG ulRetVal; - RESULTCODES results; - PID pidEnded = 0; - - ulRetVal = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, - &results, - &pidEnded, process->md.pid); - - if (ulRetVal != NO_ERROR) { - printf("\nDosWaitChild rc = %lu\n", ulRetVal); - PR_SetError(PR_UNKNOWN_ERROR, ulRetVal); - return PR_FAILURE; - } - PR_DELETE(process); - return PR_SUCCESS; -} - -PRStatus _PR_KillOS2Process(PRProcess *process) -{ - ULONG ulRetVal; - if ((ulRetVal = DosKillProcess(DKP_PROCESS, process->md.pid)) == NO_ERROR) { - return PR_SUCCESS; - } - PR_SetError(PR_UNKNOWN_ERROR, ulRetVal); - return PR_FAILURE; -} - -PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen) -{ - PRIntn rv; - - rv = gethostname(name, (PRInt32) namelen); - if (0 == rv) { - return PR_SUCCESS; - } - _PR_MD_MAP_GETHOSTNAME_ERROR(sock_errno()); - return PR_FAILURE; -} - -void -_PR_MD_WAKEUP_CPUS( void ) -{ - return; -} - -/* - ********************************************************************** - * - * Memory-mapped files - * - * A credible emulation of memory-mapped i/o on OS/2 would require - * an exception-handler on each thread that might access the mapped - * memory. In the Mozilla environment, that would be impractical. - * Instead, the following simulates those modes which don't modify - * the mapped file. It reads the entire mapped file segment at once - * when MemMap is called, and frees it on MemUnmap. CreateFileMap - * only does sanity-checks, while CloseFileMap does almost nothing. - * - ********************************************************************** - */ - -PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size) -{ - PRFileInfo64 info; - - /* assert on PR_PROT_READWRITE which modifies the underlying file */ - PR_ASSERT(fmap->prot == PR_PROT_READONLY || - fmap->prot == PR_PROT_WRITECOPY); - if (fmap->prot != PR_PROT_READONLY && - fmap->prot != PR_PROT_WRITECOPY) { - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; - } - if (PR_GetOpenFileInfo64(fmap->fd, &info) == PR_FAILURE) { - return PR_FAILURE; - } - /* reject zero-byte mappings & zero-byte files */ - if (!size || !info.size) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - /* file size rounded up to the next page boundary */ - fmap->md.maxExtent = (info.size + 0xfff) & ~(0xfff); - - return PR_SUCCESS; -} - -PRInt32 _MD_GetMemMapAlignment(void) -{ - /* OS/2 pages are 4k */ - return 0x1000; -} - -void * _MD_MemMap(PRFileMap *fmap, PROffset64 offset, PRUint32 len) -{ - PRUint32 rv; - void *addr; - - /* prevent mappings beyond EOF + remainder of page */ - if (offset + len > fmap->md.maxExtent) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } - if (PR_Seek64(fmap->fd, offset, PR_SEEK_SET) == -1) { - return NULL; - } - /* try for high memory, fall back to low memory if hi-mem fails */ - rv = DosAllocMem(&addr, len, OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE); - if (rv) { - rv = DosAllocMem(&addr, len, PAG_COMMIT | PAG_READ | PAG_WRITE); - if (rv) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, rv); - return NULL; - } - } - if (PR_Read(fmap->fd, addr, len) == -1) { - DosFreeMem(addr); - return NULL; - } - /* don't permit writes if readonly */ - if (fmap->prot == PR_PROT_READONLY) { - rv = DosSetMem(addr, len, PAG_READ); - if (rv) { - DosFreeMem(addr); - PR_SetError(PR_UNKNOWN_ERROR, rv); - return NULL; - } - } - return addr; -} - -PRStatus _MD_MemUnmap(void *addr, PRUint32 len) -{ - PRUint32 rv; - - /* we just have to trust that addr & len are those used by MemMap */ - rv = DosFreeMem(addr); - if (rv) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PRStatus _MD_CloseFileMap(PRFileMap *fmap) -{ - /* nothing to do except free the PRFileMap struct */ - PR_Free(fmap); - return PR_SUCCESS; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2poll.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2poll.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2poll.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2poll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,348 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This file implements _PR_MD_PR_POLL for OS/2. - */ - -#include /* For timeval. */ - -#include "primpl.h" - -#ifndef BSD_SELECT -/* Utility functions called when using OS/2 select */ - -PRBool IsSocketSet( PRInt32 osfd, int* socks, int start, int count ) -{ - int i; - PRBool isSet = PR_FALSE; - - for( i = start; i < start+count; i++ ) - { - if( socks[i] == osfd ) - isSet = PR_TRUE; - } - - return isSet; -} -#endif - -PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ -#ifdef BSD_SELECT - fd_set rd, wt, ex; -#else - int rd, wt, ex; - int* socks; - unsigned long msecs; - int i, j; -#endif - PRFileDesc *bottom; - PRPollDesc *pd, *epd; - PRInt32 maxfd = -1, ready, err; - PRIntervalTime remaining, elapsed, start; - -#ifdef BSD_SELECT - struct timeval tv, *tvp = NULL; - - FD_ZERO(&rd); - FD_ZERO(&wt); - FD_ZERO(&ex); -#else - rd = 0; - wt = 0; - ex = 0; - socks = (int) PR_MALLOC( npds * 3 * sizeof(int) ); - - if (!socks) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } -#endif - - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - if (pd->in_flags & PR_POLL_READ) - { - in_flags_read = (pd->fd->methods->poll)( - pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); - } - if (pd->in_flags & PR_POLL_WRITE) - { - in_flags_write = (pd->fd->methods->poll)( - pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); - } - if ((0 != (in_flags_read & out_flags_read)) || - (0 != (in_flags_write & out_flags_write))) - { - /* this one's ready right now */ - if (0 == ready) - { - /* - * We will have to return without calling the - * system poll/select function. So zero the - * out_flags fields of all the poll descriptors - * before this one. - */ - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; - pd->out_flags = out_flags_read | out_flags_write; - } - else - { - pd->out_flags = 0; /* pre-condition */ - - /* make sure this is an NSPR supported stack */ - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); /* what to do about that? */ - if ((NULL != bottom) && - (_PR_FILEDESC_OPEN == bottom->secret->state)) - { - if (0 == ready) - { - PRInt32 osfd = bottom->secret->md.osfd; - if (osfd > maxfd) - maxfd = osfd; - if (in_flags_read & PR_POLL_READ) - { - pd->out_flags |= _PR_POLL_READ_SYS_READ; -#ifdef BSD_SELECT - FD_SET(osfd, &rd); -#else - socks[rd] = osfd; - rd++; -#endif - } - if (in_flags_read & PR_POLL_WRITE) - { - pd->out_flags |= _PR_POLL_READ_SYS_WRITE; -#ifdef BSD_SELECT - FD_SET(osfd, &wt); -#else - socks[npds+wt] = osfd; - wt++; -#endif - } - if (in_flags_write & PR_POLL_READ) - { - pd->out_flags |= _PR_POLL_WRITE_SYS_READ; -#ifdef BSD_SELECT - FD_SET(osfd, &rd); -#else - socks[rd] = osfd; - rd++; -#endif - } - if (in_flags_write & PR_POLL_WRITE) - { - pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; -#ifdef BSD_SELECT - FD_SET(osfd, &wt); -#else - socks[npds+wt] = osfd; - wt++; -#endif - } - if (pd->in_flags & PR_POLL_EXCEPT) - { -#ifdef BSD_SELECT - FD_SET(osfd, &ex); -#else - socks[npds*2+ex] = osfd; - ex++; -#endif - } - } - } - else - { - if (0 == ready) - { - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; /* this will cause an abrupt return */ - pd->out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - else - { - pd->out_flags = 0; - } - } - - if (0 != ready) - { -#ifndef BSD_SELECT - PR_Free(socks); -#endif - return ready; /* no need to block */ - } - - remaining = timeout; - start = PR_IntervalNow(); - -retry: -#ifdef BSD_SELECT - if (timeout != PR_INTERVAL_NO_TIMEOUT) - { - PRInt32 ticksPerSecond = PR_TicksPerSecond(); - tv.tv_sec = remaining / ticksPerSecond; - tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); - tvp = &tv; - } - - ready = bsdselect(maxfd + 1, &rd, &wt, &ex, tvp); -#else - switch (timeout) - { - case PR_INTERVAL_NO_WAIT: - msecs = 0; - break; - case PR_INTERVAL_NO_TIMEOUT: - msecs = -1; - break; - default: - msecs = PR_IntervalToMilliseconds(remaining); - } - - /* compact array */ - for( i = rd, j = npds; j < npds+wt; i++,j++ ) - socks[i] = socks[j]; - for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ ) - socks[i] = socks[j]; - - ready = os2_select(socks, rd, wt, ex, msecs); -#endif - - if (ready == -1 && errno == EINTR) - { - if (timeout == PR_INTERVAL_NO_TIMEOUT) - goto retry; - else - { - elapsed = (PRIntervalTime) (PR_IntervalNow() - start); - if (elapsed > timeout) - ready = 0; /* timed out */ - else - { - remaining = timeout - elapsed; - goto retry; - } - } - } - - /* - ** Now to unravel the select sets back into the client's poll - ** descriptor list. Is this possibly an area for pissing away - ** a few cycles or what? - */ - if (ready > 0) - { - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRInt16 out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - PRInt32 osfd; - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); - - osfd = bottom->secret->md.osfd; - -#ifdef BSD_SELECT - if (FD_ISSET(osfd, &rd)) -#else - if( IsSocketSet(osfd, socks, 0, rd) ) -#endif - { - if (pd->out_flags & _PR_POLL_READ_SYS_READ) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) - out_flags |= PR_POLL_WRITE; - } - -#ifdef BSD_SELECT - if (FD_ISSET(osfd, &wt)) -#else - if( IsSocketSet(osfd, socks, rd, wt) ) -#endif - { - if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) - out_flags |= PR_POLL_WRITE; - } - -#ifdef BSD_SELECT - if (FD_ISSET(osfd, &ex)) -#else - if( IsSocketSet(osfd, socks, rd+wt, ex) ) -#endif - { - out_flags |= PR_POLL_EXCEPT; - } - } - pd->out_flags = out_flags; - if (out_flags) ready++; - } - PR_ASSERT(ready > 0); - } - else if (ready < 0) - { - err = _MD_ERRNO(); - if (err == EBADF) - { - /* Find the bad fds */ - int optval; - int optlen = sizeof(optval); - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - pd->out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET, - SO_TYPE, (char *) &optval, &optlen) == -1) - { - PR_ASSERT(sock_errno() == ENOTSOCK); - if (sock_errno() == ENOTSOCK) - { - pd->out_flags = PR_POLL_NVAL; - ready++; - } - } - } - } - PR_ASSERT(ready > 0); - } - else - _PR_MD_MAP_SELECT_ERROR(err); - } - -#ifndef BSD_SELECT - PR_Free(socks); -#endif - return ready; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2rng.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2rng.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2rng.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2rng.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -#define INCL_DOS -#define INCL_DOSERRORS -#include -#include -#include -#include "primpl.h" - -static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow) -{ - APIRET rc = NO_ERROR; - QWORD qword = {0,0}; - - rc = DosTmrQueryTime(&qword); - if (rc != NO_ERROR) - return FALSE; - - *phigh = qword.ulHi; - *plow = qword.ulLo; - - return TRUE; -} - -extern PRSize _PR_MD_GetRandomNoise(void *buf, PRSize size ) -{ - unsigned long high = 0; - unsigned long low = 0; - clock_t val = 0; - int n = 0; - int nBytes = 0; - time_t sTime; - - if (size <= 0) - return 0; - - clockTickTime(&high, &low); - - /* get the maximally changing bits first */ - nBytes = sizeof(low) > size ? size : sizeof(low); - memcpy(buf, &low, nBytes); - n += nBytes; - size -= nBytes; - - if (size <= 0) - return n; - - nBytes = sizeof(high) > size ? size : sizeof(high); - memcpy(((char *)buf) + n, &high, nBytes); - n += nBytes; - size -= nBytes; - - if (size <= 0) - return n; - - /* get the number of milliseconds that have elapsed since application started */ - val = clock(); - - nBytes = sizeof(val) > size ? size : sizeof(val); - memcpy(((char *)buf) + n, &val, nBytes); - n += nBytes; - size -= nBytes; - - if (size <= 0) - return n; - - /* get the time in seconds since midnight Jan 1, 1970 */ - time(&sTime); - nBytes = sizeof(sTime) > size ? size : sizeof(sTime); - memcpy(((char *)buf) + n, &sTime, nBytes); - n += nBytes; - - return n; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2sem.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2sem.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2sem.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2sem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * OS/2-specific semaphore handling code. - * - */ - -#include "primpl.h" - - -void -_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value) -{ - int rv; - - /* Our Sems don't support a value > 1 */ - PR_ASSERT(value <= 1); - - rv = DosCreateEventSem(NULL, &md->sem, 0, 0); - PR_ASSERT(rv == NO_ERROR); -} - -void -_PR_MD_DESTROY_SEM(_MDSemaphore *md) -{ - int rv; - rv = DosCloseEventSem(md->sem); - PR_ASSERT(rv == NO_ERROR); - -} - -PRStatus -_PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks) -{ - int rv; - rv = DosWaitEventSem(md->sem, PR_IntervalToMilliseconds(ticks)); - - if (rv == NO_ERROR) - return PR_SUCCESS; - else - return PR_FAILURE; -} - -PRStatus -_PR_MD_WAIT_SEM(_MDSemaphore *md) -{ - return _PR_MD_TIMED_WAIT_SEM(md, PR_INTERVAL_NO_TIMEOUT); -} - -void -_PR_MD_POST_SEM(_MDSemaphore *md) -{ - int rv; - rv = DosPostEventSem(md->sem); - PR_ASSERT(rv == NO_ERROR); -} - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2sock.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2sock.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2sock.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2sock.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,654 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* OS/2 Sockets module - * - */ - -/*Note from DSR111297 - it should be noted that there are two flavors of select() on OS/2 */ -/*There is standard BSD (which is kind of slow) and a new flavor of select() that takes */ -/*an integer list of sockets, the number of read sockets, write sockets, except sockets, and */ -/*a millisecond count for timeout. In the interest of performance I have choosen the OS/2 */ -/*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info. */ - -#include "primpl.h" - -#include /* For timeval. */ - -#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 -#define READ_FD 1 -#define WRITE_FD 2 - -/* --- SOCKET IO --------------------------------------------------------- */ - - -PRInt32 -_PR_MD_SOCKET(int domain, int type, int flags) -{ - PRInt32 osfd, err; - - osfd = socket(domain, type, flags); - - if (osfd == -1) - { - err = sock_errno(); - _PR_MD_MAP_SOCKET_ERROR(err); - } - - return(osfd); -} - -/* -** _MD_CloseSocket() -- Close a socket -** -*/ -PRInt32 -_MD_CloseSocket(PRInt32 osfd) -{ - PRInt32 rv, err; - - rv = soclose(osfd); - if (rv == -1) { - err = sock_errno(); - _PR_MD_MAP_CLOSE_ERROR(err); - } - return rv; -} - -PRInt32 -_MD_SocketAvailable(PRFileDesc *fd) -{ - PRInt32 result; - - if (so_ioctl(fd->secret->md.osfd, FIONREAD, (char *) &result, sizeof(result)) < 0) { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, sock_errno()); - return -1; - } - return result; -} - -static PRInt32 -socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout ) -{ - PRInt32 rv = -1; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRIntervalTime epoch, now, elapsed, remaining; - PRBool wait_for_remaining; - PRInt32 syserror; -#ifdef BSD_SELECT - struct timeval tv; - fd_set rd_wr; -#else - int socks[1]; - long lTimeout; -#endif - - switch (timeout) { - case PR_INTERVAL_NO_WAIT: - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - break; - case PR_INTERVAL_NO_TIMEOUT: - /* - * This is a special case of the 'default' case below. - * Please see the comments there. - */ -#ifdef BSD_SELECT - tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; - tv.tv_usec = 0; - FD_ZERO(&rd_wr); - do { - FD_SET(osfd, &rd_wr); - if (fd_type == READ_FD) - rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv); - else - rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv); -#else - lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; - do { - socks[0] = osfd; - if (fd_type == READ_FD) - rv = os2_select(socks, 1, 0, 0, lTimeout); - else - rv = os2_select(socks, 0, 1, 0, lTimeout); -#endif - if (rv == -1 && (syserror = sock_errno()) != EINTR) { - _PR_MD_MAP_SELECT_ERROR(syserror); - break; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - } while (rv == 0 || (rv == -1 && syserror == EINTR)); - break; - default: - now = epoch = PR_IntervalNow(); - remaining = timeout; -#ifdef BSD_SELECT - FD_ZERO(&rd_wr); -#endif - do { - /* - * We block in select for at most - * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, - * so that there is an upper limit on the delay - * before the interrupt bit is checked. - */ -#ifdef BSD_SELECT - wait_for_remaining = PR_TRUE; - tv.tv_sec = PR_IntervalToSeconds(remaining); - if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { - wait_for_remaining = PR_FALSE; - tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; - tv.tv_usec = 0; - } else { - tv.tv_usec = PR_IntervalToMicroseconds( - remaining - - PR_SecondsToInterval(tv.tv_sec)); - } - FD_SET(osfd, &rd_wr); - if (fd_type == READ_FD) - rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv); - else - rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv); -#else - wait_for_remaining = PR_TRUE; - lTimeout = PR_IntervalToMilliseconds(remaining); - if (lTimeout > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) { - wait_for_remaining = PR_FALSE; - lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; - } - socks[0] = osfd; - if (fd_type == READ_FD) - rv = os2_select(socks, 1, 0, 0, lTimeout); - else - rv = os2_select(socks, 0, 1, 0, lTimeout); -#endif - /* - * we don't consider EINTR a real error - */ - if (rv == -1 && (syserror = sock_errno()) != EINTR) { - _PR_MD_MAP_SELECT_ERROR(syserror); - break; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - /* - * We loop again if select timed out or got interrupted - * by a signal, and the timeout deadline has not passed yet. - */ - if (rv == 0 || (rv == -1 && syserror == EINTR)) { - /* - * If select timed out, we know how much time - * we spent in blocking, so we can avoid a - * PR_IntervalNow() call. - */ - if (rv == 0) { - if (wait_for_remaining) { - now += remaining; - } else { -#ifdef BSD_SELECT - now += PR_SecondsToInterval(tv.tv_sec) - + PR_MicrosecondsToInterval(tv.tv_usec); -#else - now += PR_MillisecondsToInterval(lTimeout); -#endif - } - } else { - now = PR_IntervalNow(); - } - elapsed = (PRIntervalTime) (now - epoch); - if (elapsed >= timeout) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - rv = -1; - break; - } else { - remaining = timeout - elapsed; - } - } - } while (rv == 0 || (rv == -1 && syserror == EINTR)); - break; - } - return(rv); -} - -PRInt32 -_MD_Accept(PRFileDesc *fd, PRNetAddr *addr, - PRUint32 *addrlen, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - while ((rv = accept(osfd, (struct sockaddr*) addr, (int*)addrlen)) == -1) - { - err = sock_errno(); - if ((err == EWOULDBLOCK) || (err == ECONNABORTED)) - { - if (fd->secret->nonblocking) { - break; - } - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_ACCEPT_ERROR(err); - } -done: - return(rv); -} - -PRInt32 -_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, - PRIntervalTime timeout) -{ - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 osfd = fd->secret->md.osfd; - PRNetAddr addrCopy = *addr; /* Work around a bug in OS/2 where connect - * modifies the sockaddr structure. - * See Bugzilla bug 100776. */ - - /* - * We initiate the connection setup by making a nonblocking connect() - * call. If the connect() call fails, there are two cases we handle - * specially: - * 1. The connect() call was interrupted by a signal. In this case - * we simply retry connect(). - * 2. The NSPR socket is nonblocking and connect() fails with - * EINPROGRESS. We first wait until the socket becomes writable. - * Then we try to find out whether the connection setup succeeded - * or failed. - */ - -retry: - if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) - { - err = sock_errno(); - - if (err == EINTR) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - goto retry; - } - - if (!fd->secret->nonblocking && (err == EINPROGRESS)) - { - /* - * socket_io_wait() may return -1 or 1. - */ - - rv = socket_io_wait(osfd, WRITE_FD, timeout); - if (rv == -1) { - return -1; - } - - PR_ASSERT(rv == 1); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - err = _MD_os2_get_nonblocking_connect_error(osfd); - if (err != 0) { - _PR_MD_MAP_CONNECT_ERROR(err); - return -1; - } - return 0; - } - - _PR_MD_MAP_CONNECT_ERROR(err); - } - - return rv; -} /* _MD_connect */ - -PRInt32 -_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) -{ - PRInt32 rv, err; - rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen); - if (rv < 0) { - err = sock_errno(); - _PR_MD_MAP_BIND_ERROR(err); - } - return(rv); -} - - -PRInt32 -_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog) -{ - PRInt32 rv, err; - rv = listen(fd->secret->md.osfd, backlog); - if (rv < 0) { - err = sock_errno(); - _PR_MD_MAP_DEFAULT_ERROR(err); - } - return(rv); -} - - -PRInt32 -_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - while ((rv = recv(osfd,buf,amount,flags)) == -1) - { - err = sock_errno(); - if ((err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_RECV_ERROR(err); - } -done: - return(rv); -} - -PRInt32 -_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - while ((rv = send(osfd,buf,amount,flags)) == -1) - { - err = sock_errno(); - if ((err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0) - goto done; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - - /* - * optimization; if bytes sent is less than "amount" call - * select before returning. This is because it is likely that - * the next send() call will return EWOULDBLOCK. - */ - if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) - && (timeout != PR_INTERVAL_NO_WAIT)) - { - if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) { - rv = -1; - goto done; - } - } - if (rv < 0) { - _PR_MD_MAP_SEND_ERROR(err); - } -done: - return(rv); -} - -PRInt32 -_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - while ((rv = sendto(osfd, buf, amount, flags, - (struct sockaddr *) addr, addrlen)) == -1) - { - err = sock_errno(); - if ((err == EWOULDBLOCK)) - { - if (fd->secret->nonblocking) { - break; - } - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0) - goto done; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_SENDTO_ERROR(err); - } -done: - return(rv); -} - -PRInt32 -_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - while( (*addrlen = PR_NETADDR_SIZE(addr)), - ((rv = recvfrom(osfd, buf, amount, flags, - (struct sockaddr *) addr, (int *)addrlen)) == -1)) - { - err = sock_errno(); - if ((err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_RECVFROM_ERROR(err); - } -done: - return(rv); -} - -PRInt32 -_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, - PRIntervalTime timeout) -{ - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 index, amount = 0; - PRInt32 osfd = fd->secret->md.osfd; - struct iovec osiov[PR_MAX_IOVECTOR_SIZE]; - - /* Ensured by PR_Writev */ - PR_ASSERT(iov_size <= PR_MAX_IOVECTOR_SIZE); - - /* - * We can't pass iov to so_writev because PRIOVec and struct iovec - * may not be binary compatible. Make osiov a copy of iov and - * pass osiov to so_writev . - */ - for (index = 0; index < iov_size; index++) { - osiov[index].iov_base = iov[index].iov_base; - osiov[index].iov_len = iov[index].iov_len; - } - - /* - * Calculate the total number of bytes to be sent; needed for - * optimization later. - * We could avoid this if this number was passed in; but it is - * probably not a big deal because iov_size is usually small (less than - * 3) - */ - if (!fd->secret->nonblocking) { - for (index=0; indexsecret->nonblocking) { - break; - } - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0) - goto done; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - - /* - * optimization; if bytes sent is less than "amount" call - * select before returning. This is because it is likely that - * the next writev() call will return EWOULDBLOCK. - */ - if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) - && (timeout != PR_INTERVAL_NO_WAIT)) { - if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { - rv = -1; - goto done; - } - } - if (rv < 0) { - _PR_MD_MAP_WRITEV_ERROR(err); - } -done: - return(rv); -} - -PRInt32 -_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how) -{ - PRInt32 rv; - - rv = shutdown(fd->secret->md.osfd, how); - if (rv < 0) - _PR_MD_MAP_SHUTDOWN_ERROR(sock_errno()); - return rv; -} - -PRInt32 -_PR_MD_SOCKETPAIR(int af, int type, int flags, PRInt32 *osfd) -{ - PRInt32 rv, err; - - rv = socketpair(af, type, flags, osfd); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_SOCKETPAIR_ERROR(err); - } - return rv; -} - -PRStatus -_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) -{ - PRInt32 rv, err; - - rv = getsockname(fd->secret->md.osfd, - (struct sockaddr *) addr, (int *)addrlen); - if (rv < 0) { - err = sock_errno(); - _PR_MD_MAP_GETSOCKNAME_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus -_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) -{ - PRInt32 rv, err; - - rv = getpeername(fd->secret->md.osfd, - (struct sockaddr *) addr, (int *)addrlen); - if (rv < 0) { - err = sock_errno(); - _PR_MD_MAP_GETPEERNAME_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus -_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, - char* optval, PRInt32* optlen) -{ - PRInt32 rv, err; - - rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (int *)optlen); - if (rv < 0) { - err = sock_errno(); - _PR_MD_MAP_GETSOCKOPT_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus -_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, - const char* optval, PRInt32 optlen) -{ - PRInt32 rv, err; - - rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen); - if (rv < 0) { - err = sock_errno(); - _PR_MD_MAP_SETSOCKOPT_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -void -_MD_MakeNonblock(PRFileDesc *fd) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 err; - PRUint32 one = 1; - - if (osfd <= 2) { - /* Don't mess around with stdin, stdout or stderr */ - return; - } - - err = so_ioctl( osfd, FIONBIO, (char *) &one, sizeof(one)); - if ( err != 0 ) - { - err = sock_errno(); - _PR_MD_MAP_SOCKET_ERROR(err); - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2thred.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2thred.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2thred.c 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2thred.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,353 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include /* for _beginthread() */ -#include -#include - -/* --- globals ------------------------------------------------ */ -_NSPR_TLS* pThreadLocalStorage = 0; -_PRInterruptTable _pr_interruptTable[] = { { 0 } }; -APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD); - -void -_PR_MD_ENSURE_TLS(void) -{ - if(!pThreadLocalStorage) - { - /* Allocate thread local storage (TLS). Note, that only 32 bytes can - * be allocated at a time. - */ - int rc = DosAllocThreadLocalMemory(sizeof(_NSPR_TLS) / 4, (PULONG*)&pThreadLocalStorage); - PR_ASSERT(rc == NO_ERROR); - memset(pThreadLocalStorage, 0, sizeof(_NSPR_TLS)); - } -} - -void -_PR_MD_EARLY_INIT() -{ - HMODULE hmod; - - if (DosLoadModule(NULL, 0, "DOSCALL1", &hmod) == 0) - DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT", - (PFN *)&QueryThreadContext); -} - -static void -_pr_SetThreadMDHandle(PRThread *thread) -{ - PTIB ptib; - PPIB ppib; - PRUword rc; - - rc = DosGetInfoBlocks(&ptib, &ppib); - - thread->md.handle = ptib->tib_ptib2->tib2_ultid; -} - -/* On OS/2, some system function calls seem to change the FPU control word, - * such that we crash with a floating underflow exception. The FIX_FPU() call - * in jsnum.c does not always work, as sometimes FIX_FPU() is called BEFORE the - * OS/2 system call that horks the FPU control word. So, we set an exception - * handler that covers any floating point exceptions and resets the FPU CW to - * the required value. - */ -static ULONG -_System OS2_FloatExcpHandler(PEXCEPTIONREPORTRECORD p1, - PEXCEPTIONREGISTRATIONRECORD p2, - PCONTEXTRECORD p3, - PVOID pv) -{ -#ifdef DEBUG_pedemonte - printf("Entering exception handler; ExceptionNum = %x\n", p1->ExceptionNum); - switch(p1->ExceptionNum) { - case XCPT_FLOAT_DENORMAL_OPERAND: - printf("got XCPT_FLOAT_DENORMAL_OPERAND\n"); - break; - case XCPT_FLOAT_DIVIDE_BY_ZERO: - printf("got XCPT_FLOAT_DIVIDE_BY_ZERO\n"); - break; - case XCPT_FLOAT_INEXACT_RESULT: - printf("got XCPT_FLOAT_INEXACT_RESULT\n"); - break; - case XCPT_FLOAT_INVALID_OPERATION: - printf("got XCPT_FLOAT_INVALID_OPERATION\n"); - break; - case XCPT_FLOAT_OVERFLOW: - printf("got XCPT_FLOAT_OVERFLOW\n"); - break; - case XCPT_FLOAT_STACK_CHECK: - printf("got XCPT_FLOAT_STACK_CHECK\n"); - break; - case XCPT_FLOAT_UNDERFLOW: - printf("got XCPT_FLOAT_UNDERFLOW\n"); - break; - } -#endif - - switch(p1->ExceptionNum) { - case XCPT_FLOAT_DENORMAL_OPERAND: - case XCPT_FLOAT_DIVIDE_BY_ZERO: - case XCPT_FLOAT_INEXACT_RESULT: - case XCPT_FLOAT_INVALID_OPERATION: - case XCPT_FLOAT_OVERFLOW: - case XCPT_FLOAT_STACK_CHECK: - case XCPT_FLOAT_UNDERFLOW: - { - unsigned cw = p3->ctx_env[0]; - if ((cw & MCW_EM) != MCW_EM) { - /* Mask out all floating point exceptions */ - p3->ctx_env[0] |= MCW_EM; - /* Following two lines set precision to 53 bit mantissa. See jsnum.c */ - p3->ctx_env[0] &= ~MCW_PC; - p3->ctx_env[0] |= PC_53; - return XCPT_CONTINUE_EXECUTION; - } - } - } - return XCPT_CONTINUE_SEARCH; -} - -PR_IMPLEMENT(void) -PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg) -{ - /* setup the exception handler for the thread */ - APIRET rv; - excpreg->ExceptionHandler = OS2_FloatExcpHandler; - excpreg->prev_structure = NULL; - rv = DosSetExceptionHandler(excpreg); - PR_ASSERT(rv == NO_ERROR); -} - -PR_IMPLEMENT(void) -PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg) -{ - /* unset exception handler */ - APIRET rv = DosUnsetExceptionHandler(excpreg); - PR_ASSERT(rv == NO_ERROR); -} - -PRStatus -_PR_MD_INIT_THREAD(PRThread *thread) -{ - APIRET rv; - - if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { - _pr_SetThreadMDHandle(thread); - } - - /* Create the blocking IO semaphore */ - rv = DosCreateEventSem(NULL, &(thread->md.blocked_sema), 0, 0); - return (rv == NO_ERROR) ? PR_SUCCESS : PR_FAILURE; -} - -typedef struct param_store -{ - void (*start)(void *); - PRThread* thread; -} PARAMSTORE; - -/* This is a small intermediate function that sets/unsets the exception - handler before calling the initial thread function */ -static void -ExcpStartFunc(void* arg) -{ - EXCEPTIONREGISTRATIONRECORD excpreg; - PARAMSTORE params, *pParams = arg; - - PR_OS2_SetFloatExcpHandler(&excpreg); - - params = *pParams; - PR_Free(pParams); - params.start(params.thread); - - PR_OS2_UnsetFloatExcpHandler(&excpreg); -} - -PRStatus -_PR_MD_CREATE_THREAD(PRThread *thread, - void (*start)(void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PARAMSTORE* params = PR_Malloc(sizeof(PARAMSTORE)); - params->start = start; - params->thread = thread; - thread->md.handle = thread->id = (TID) _beginthread(ExcpStartFunc, - NULL, - thread->stack->stackSize, - params); - if(thread->md.handle == -1) { - return PR_FAILURE; - } - - /* - * On OS/2, a thread is created with a thread priority of - * THREAD_PRIORITY_NORMAL - */ - - if (priority != PR_PRIORITY_NORMAL) { - _PR_MD_SET_PRIORITY(&(thread->md), priority); - } - - return PR_SUCCESS; -} - -void -_PR_MD_YIELD(void) -{ - /* Isn't there some problem with DosSleep(0) on OS/2? */ - DosSleep(0); -} - -void -_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) -{ - int nativePri = PRTYC_NOCHANGE; - BOOL rv; - - if (newPri < PR_PRIORITY_FIRST) { - newPri = PR_PRIORITY_FIRST; - } else if (newPri > PR_PRIORITY_LAST) { - newPri = PR_PRIORITY_LAST; - } - switch (newPri) { - case PR_PRIORITY_LOW: - case PR_PRIORITY_NORMAL: - nativePri = PRTYC_REGULAR; - break; - case PR_PRIORITY_HIGH: - nativePri = PRTYC_FOREGROUNDSERVER; - break; - case PR_PRIORITY_URGENT: - nativePri = PRTYC_TIMECRITICAL; - } - rv = DosSetPriority(PRTYS_THREAD, nativePri, 0, thread->handle); - PR_ASSERT(rv == NO_ERROR); - if (rv != NO_ERROR) { - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("PR_SetThreadPriority: can't set thread priority\n")); - } - return; -} - -void -_PR_MD_CLEAN_THREAD(PRThread *thread) -{ - APIRET rv; - - if (thread->md.blocked_sema) { - rv = DosCloseEventSem(thread->md.blocked_sema); - PR_ASSERT(rv == NO_ERROR); - thread->md.blocked_sema = 0; - } - - if (thread->md.handle) { - thread->md.handle = 0; - } -} - -void -_PR_MD_EXIT_THREAD(PRThread *thread) -{ - _PR_MD_CLEAN_THREAD(thread); - _PR_MD_SET_CURRENT_THREAD(NULL); -} - - -void -_PR_MD_EXIT(PRIntn status) -{ - _exit(status); -} - -#ifdef HAVE_THREAD_AFFINITY -PR_EXTERN(PRInt32) -_PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ) -{ - /* Can we do this on OS/2? Only on SMP versions? */ - PR_ASSERT(!"Not implemented"); - return 0; - - /* This is what windows does: - int rv; - - rv = SetThreadAffinityMask(thread->md.handle, mask); - - return rv?0:-1; - */ -} - -PR_EXTERN(PRInt32) -_PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask) -{ - /* Can we do this on OS/2? Only on SMP versions? */ - PR_ASSERT(!"Not implemented"); - return 0; - - /* This is what windows does: - PRInt32 rv, system_mask; - - rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask); - - return rv?0:-1; - */ -} -#endif /* HAVE_THREAD_AFFINITY */ - -void -_PR_MD_SUSPEND_CPU(_PRCPU *cpu) -{ - _PR_MD_SUSPEND_THREAD(cpu->thread); -} - -void -_PR_MD_RESUME_CPU(_PRCPU *cpu) -{ - _PR_MD_RESUME_THREAD(cpu->thread); -} - -void -_PR_MD_SUSPEND_THREAD(PRThread *thread) -{ - if (_PR_IS_NATIVE_THREAD(thread)) { - APIRET rc; - - /* XXXMB - DosSuspendThread() is not a blocking call; how do we - * know when the thread is *REALLY* suspended? - */ - rc = DosSuspendThread(thread->md.handle); - PR_ASSERT(rc == NO_ERROR); - } -} - -void -_PR_MD_RESUME_THREAD(PRThread *thread) -{ - if (_PR_IS_NATIVE_THREAD(thread)) { - DosResumeThread(thread->md.handle); - } -} - - -PRThread* -_MD_CURRENT_THREAD(void) -{ - PRThread *thread; - - thread = _MD_GET_ATTACHED_THREAD(); - - if (NULL == thread) { - thread = _PRI_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); - } - - PR_ASSERT(thread != NULL); - return thread; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2vaclegacy.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2vaclegacy.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/os2/os2vaclegacy.s 2012-03-06 13:14:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/os2/os2vaclegacy.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -/ -/ This Source Code Form is subject to the terms of the Mozilla Public -/ License, v. 2.0. If a copy of the MPL was not distributed with this -/ file, You can obtain one at http://mozilla.org/MPL/2.0/. - - .text - .align 4 - .globl PR_NewMonitor -PR_NewMonitor: - jmp _PR_NewMonitor - - .align 4 - .globl PR_EnterMonitor -PR_EnterMonitor: - mov %eax, 4(%esp) - jmp _PR_EnterMonitor - - .align 4 - .globl PR_ExitMonitor -PR_ExitMonitor: - mov %eax, 4(%esp) - jmp _PR_ExitMonitor - - - - .align 4 - .globl PR_AttachThread -PR_AttachThread: - mov %eax, 4(%esp) - mov %edx, 8(%esp) - mov %ecx, 12(%esp) - jmp _PR_AttachThread - - .align 4 - .globl PR_DetachThread -PR_DetachThread: - jmp _PR_DetachThread - - .align 4 - .globl PR_GetCurrentThread -PR_GetCurrentThread: - jmp _PR_GetCurrentThread - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/prosdep.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/prosdep.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/prosdep.c 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/prosdep.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prbit.h" -#include "prsystem.h" - -#ifdef XP_UNIX -#include -#endif -#ifdef _WIN32 -#include -#endif -#ifdef XP_BEOS -#include -#endif - -PRInt32 _pr_pageShift; -PRInt32 _pr_pageSize; - -/* -** Get system page size -*/ -static void GetPageSize(void) -{ - PRInt32 pageSize; - - /* Get page size */ -#ifdef XP_UNIX -#if defined BSDI || defined AIX \ - || defined LINUX || defined __GNU__ || defined __GLIBC__ \ - || defined FREEBSD || defined NETBSD || defined OPENBSD \ - || defined DARWIN || defined SYMBIAN - _pr_pageSize = getpagesize(); -#elif defined(HPUX) - /* I have no idea. Don't get me started. --Rob */ - _pr_pageSize = sysconf(_SC_PAGE_SIZE); -#else - _pr_pageSize = sysconf(_SC_PAGESIZE); -#endif -#endif /* XP_UNIX */ - -#ifdef XP_BEOS - _pr_pageSize = B_PAGE_SIZE; -#endif - -#ifdef XP_PC -#ifdef _WIN32 - SYSTEM_INFO info; - GetSystemInfo(&info); - _pr_pageSize = info.dwPageSize; -#else - _pr_pageSize = 4096; -#endif -#endif /* XP_PC */ - - pageSize = _pr_pageSize; - PR_CEILING_LOG2(_pr_pageShift, pageSize); -} - -PR_IMPLEMENT(PRInt32) PR_GetPageShift(void) -{ - if (!_pr_pageSize) { - GetPageSize(); - } - return _pr_pageShift; -} - -PR_IMPLEMENT(PRInt32) PR_GetPageSize(void) -{ - if (!_pr_pageSize) { - GetPageSize(); - } - return _pr_pageSize; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/aix.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/aix.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/aix.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/aix.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,301 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#ifdef AIX_HAVE_ATOMIC_OP_H -#include - -PRInt32 _AIX_AtomicSet(PRInt32 *val, PRInt32 newval) -{ - PRIntn oldval; - boolean_t stored; - oldval = fetch_and_add((atomic_p)val, 0); - do - { - stored = compare_and_swap((atomic_p)val, &oldval, newval); - } while (!stored); - return oldval; -} /* _AIX_AtomicSet */ -#endif /* AIX_HAVE_ATOMIC_OP_H */ - -#if defined(AIX_TIMERS) - -#include - -static PRUint32 _aix_baseline_epoch; - -static void _MD_AixIntervalInit(void) -{ - timebasestruct_t real_time; - read_real_time(&real_time, TIMEBASE_SZ); - (void)time_base_to_time(&real_time, TIMEBASE_SZ); - _aix_baseline_epoch = real_time.tb_high; -} /* _MD_AixIntervalInit */ - -PRIntervalTime _MD_AixGetInterval(void) -{ - PRIntn rv; - PRUint64 temp; - timebasestruct_t real_time; - read_real_time(&real_time, TIMEBASE_SZ); - (void)time_base_to_time(&real_time, TIMEBASE_SZ); - /* tb_high is in seconds, tb_low in 10(-9)seconds */ - temp = 1000000000ULL * (PRUint64)(real_time.tb_high - _aix_baseline_epoch); - temp += (PRUint64)real_time.tb_low; /* everything's 10(-9) seconds */ - temp >>= 16; /* now it's something way different */ - return (PRIntervalTime)temp; -} /* _MD_AixGetInterval */ - -PRIntervalTime _MD_AixIntervalPerSec(void) -{ - return 1000000000ULL >> 16; /* that's 15258, I think */ -} /* _MD_AixIntervalPerSec */ - -#endif /* defined(AIX_TIMERS) */ - -#if !defined(PTHREADS_USER) - -#if defined(_PR_PTHREADS) - -/* - * AIX 4.3 has sched_yield(). AIX 4.2 has pthread_yield(). - * So we look up the appropriate function pointer at run time. - */ - -#include - -int (*_PT_aix_yield_fcn)() = NULL; -int _pr_aix_send_file_use_disabled = 0; - -void _MD_EarlyInit(void) -{ - void *main_app_handle; - char *evp; - - main_app_handle = dlopen(NULL, RTLD_NOW); - PR_ASSERT(NULL != main_app_handle); - - _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle, "sched_yield"); - if (!_PT_aix_yield_fcn) { - _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle,"pthread_yield"); - PR_ASSERT(NULL != _PT_aix_yield_fcn); - } - dlclose(main_app_handle); - - if (evp = getenv("NSPR_AIX_SEND_FILE_USE_DISABLED")) { - if (1 == atoi(evp)) - _pr_aix_send_file_use_disabled = 1; - } - -#if defined(AIX_TIMERS) - _MD_AixIntervalInit(); -#endif -} - -#else /* _PR_PTHREADS */ - -void _MD_EarlyInit(void) -{ -#if defined(AIX_TIMERS) - _MD_AixIntervalInit(); -#endif -} - -#endif /* _PR_PTHREADS */ - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifndef _PR_PTHREADS -PR_IMPLEMENT(void) -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PR_IMPLEMENT(PRStatus) -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for AIX */ -PR_IMPLEMENT(void) -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for AIX."); -} - -PR_IMPLEMENT(PRStatus) -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for AIX."); -} -#endif /* _PR_PTHREADS */ -#endif /* PTHREADS_USER */ - -/* - * NSPR 2.0 overrides the system select() and poll() functions. - * On AIX 4.2, we use dlopen("/unix", RTLD_NOW) and dlsym() to get - * at the original system select() and poll() functions. - */ - -#if !defined(AIX_RENAME_SELECT) - -#include -#include -#include - -static int (*aix_select_fcn)() = NULL; -static int (*aix_poll_fcn)() = NULL; - -int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) -{ - int rv; - - if (!aix_select_fcn) { - void *aix_handle; - - aix_handle = dlopen("/unix", RTLD_NOW); - if (!aix_handle) { - PR_SetError(PR_UNKNOWN_ERROR, 0); - return -1; - } - aix_select_fcn = (int(*)())dlsym(aix_handle,"select"); - dlclose(aix_handle); - if (!aix_select_fcn) { - PR_SetError(PR_UNKNOWN_ERROR, 0); - return -1; - } - } - rv = (*aix_select_fcn)(width, r, w, e, t); - return rv; -} - -int _MD_POLL(void *listptr, unsigned long nfds, long timeout) -{ - int rv; - - if (!aix_poll_fcn) { - void *aix_handle; - - aix_handle = dlopen("/unix", RTLD_NOW); - if (!aix_handle) { - PR_SetError(PR_UNKNOWN_ERROR, 0); - return -1; - } - aix_poll_fcn = (int(*)())dlsym(aix_handle,"poll"); - dlclose(aix_handle); - if (!aix_poll_fcn) { - PR_SetError(PR_UNKNOWN_ERROR, 0); - return -1; - } - } - rv = (*aix_poll_fcn)(listptr, nfds, timeout); - return rv; -} - -#else - -/* - * In AIX versions prior to 4.2, we use the two-step rename/link trick. - * The binary must contain at least one "poll" symbol for linker's rename - * to work. So we must have this dummy function that references poll(). - */ -#include -void _pr_aix_dummy() -{ - poll(0,0,0); -} - -#endif /* !defined(AIX_RENAME_SELECT) */ - -#ifdef _PR_HAVE_ATOMIC_CAS - -#include "pratom.h" - -#define _PR_AIX_ATOMIC_LOCK -1 - -PR_IMPLEMENT(void) -PR_StackPush(PRStack *stack, PRStackElem *stack_elem) -{ -PRStackElem *addr; -boolean_t locked = TRUE; - - /* Is it safe to cast a pointer to an int? */ - PR_ASSERT(sizeof(int) == sizeof(PRStackElem *)); - do { - while ((addr = stack->prstk_head.prstk_elem_next) == - (PRStackElem *)_PR_AIX_ATOMIC_LOCK) - ; - locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next, - (int) addr, _PR_AIX_ATOMIC_LOCK); - } while (locked == TRUE); - stack_elem->prstk_elem_next = addr; - _clear_lock((atomic_p)&stack->prstk_head.prstk_elem_next, (int)stack_elem); - return; -} - -PR_IMPLEMENT(PRStackElem *) -PR_StackPop(PRStack *stack) -{ -PRStackElem *element; -boolean_t locked = TRUE; - - /* Is it safe to cast a pointer to an int? */ - PR_ASSERT(sizeof(int) == sizeof(PRStackElem *)); - do { - while ((element = stack->prstk_head.prstk_elem_next) == - (PRStackElem *) _PR_AIX_ATOMIC_LOCK) - ; - locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next, - (int)element, _PR_AIX_ATOMIC_LOCK); - } while (locked == TRUE); - - if (element == NULL) { - _clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next, NULL); - } else { - _clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next, - (int) element->prstk_elem_next); - } - return element; -} - -#endif /* _PR_HAVE_ATOMIC_CAS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/aixwrap.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/aixwrap.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/aixwrap.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/aixwrap.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: aixwrap.c - * Description: - * This file contains a single function, _MD_SELECT(), which simply - * invokes the select() function. This file is used in an ugly - * hack to override the system select() function on AIX releases - * prior to 4.2. (On AIX 4.2, we use a different mechanism to - * override select().) - */ - -#ifndef AIX_RENAME_SELECT -#error aixwrap.c should only be used on AIX 3.2 or 4.1 -#else - -#include -#include - -int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) -{ - return select(width, r, w, e, t); -} - -int _MD_POLL(void *listptr, unsigned long nfds, long timeout) -{ - return poll(listptr, nfds, timeout); -} - -#endif /* AIX_RENAME_SELECT */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/bsdi.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/bsdi.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/bsdi.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/bsdi.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -void _MD_EarlyInit(void) -{ - /* - * Ignore FPE because coercion of a NaN to an int causes SIGFPE - * to be raised. - */ - struct sigaction act; - - act.sa_handler = SIG_IGN; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - sigaction(SIGFPE, &act, 0); -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifndef _PR_PTHREADS -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for BSDI */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for BSDI."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for BSDI."); - return PR_FAILURE; -} -#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/.cvsignore 2001-05-12 04:29:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/darwin.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/darwin.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/darwin.c 2012-11-10 11:48:55.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/darwin.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -void _MD_EarlyInit(void) -{ -} - -/* - * The multiplier (as a fraction) for converting the Mach absolute time - * unit to nanoseconds. - */ -static mach_timebase_info_data_t machTimebaseInfo; - -void _PR_Mach_IntervalInit(void) -{ - kern_return_t rv; - - rv = mach_timebase_info(&machTimebaseInfo); - PR_ASSERT(rv == KERN_SUCCESS); -} - -PRIntervalTime _PR_Mach_GetInterval(void) -{ - uint64_t time; - - /* - * mach_absolute_time returns the time in the Mach absolute time unit. - * Convert it to milliseconds. See Mac Technical Q&A QA1398. - */ - time = mach_absolute_time(); - time = time * machTimebaseInfo.numer / machTimebaseInfo.denom / - PR_NSEC_PER_MSEC; - return (PRIntervalTime)time; -} /* _PR_Mach_GetInterval */ - -PRIntervalTime _PR_Mach_TicksPerSecond(void) -{ - return 1000; -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#if !defined(_PR_PTHREADS) - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#if !defined(_PR_PTHREADS) -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for Darwin */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for Darwin."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Darwin."); - return PR_FAILURE; -} -#endif /* ! _PR_PTHREADS */ - -/* darwin.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/dgux.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/dgux.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/dgux.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/dgux.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -/* - * using only NSPR threads here - * - * Copied from the UnixWare implementation. Should be kept in sync - * with ../../../include/md/_dgux.h. - */ - -#include - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -} - -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for DG/UX */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for DG/UX."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for DG/UX."); -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/freebsd.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/freebsd.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/freebsd.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/freebsd.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -void _MD_EarlyInit(void) -{ - /* - * Ignore FPE because coercion of a NaN to an int causes SIGFPE - * to be raised. - */ - struct sigaction act; - - act.sa_handler = SIG_IGN; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - sigaction(SIGFPE, &act, 0); -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) sigsetjmp(CONTEXT(t), 1); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifndef _PR_PTHREADS -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for FreeBSD */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for FreeBSD."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for FreeBSD."); - return PR_FAILURE; -} -#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/hpux.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/hpux.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/hpux.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/hpux.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,229 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include - -#if defined(HPUX_LW_TIMER) - -#include -#include -#include -#include -#include - -int __lw_get_thread_times(int which, int64_t *sample, int64_t *time); - -static double msecond_per_itick; - -void _PR_HPUX_LW_IntervalInit(void) -{ - struct pst_processor psp; - int iticksperclktick, clk_tck; - int rv; - - rv = pstat_getprocessor(&psp, sizeof(psp), 1, 0); - PR_ASSERT(rv != -1); - - iticksperclktick = psp.psp_iticksperclktick; - clk_tck = sysconf(_SC_CLK_TCK); - msecond_per_itick = (1000.0)/(double)(iticksperclktick * clk_tck); -} - -PRIntervalTime _PR_HPUX_LW_GetInterval(void) -{ - int64_t time, sample; - - __lw_get_thread_times(1, &sample, &time); - /* - * Division is slower than float multiplication. - * return (time / iticks_per_msecond); - */ - return (time * msecond_per_itick); -} -#endif /* HPUX_LW_TIMER */ - -#if !defined(PTHREADS_USER) - -void _MD_EarlyInit(void) -{ -#ifndef _PR_PTHREADS - /* - * The following piece of code is taken from ns/nspr/src/md_HP-UX.c. - * In the comment for revision 1.6, dated 1995/09/11 23:33:34, - * robm says: - * This version has some problems which need to be addressed. - * First, intercept all system calls and prevent them from - * executing the library code which performs stack switches - * before normal system call invocation. In order for library - * calls which make system calls to work (like stdio), however, - * we must also allocate our own stack and switch the primordial - * stack to use it. This isn't so bad, except that I fudged the - * backtrace length when copying the old stack to the new one. - * - * This is the original comment of robm in the code: - * XXXrobm Horrific. To avoid a problem with HP's system call - * code, we allocate a new stack for the primordial thread and - * use it. However, we don't know how far back the original stack - * goes. We should create a routine that performs a backtrace and - * finds out just how much we need to copy. As a temporary measure, - * I just copy an arbitrary guess. - * - * In an email to servereng dated 2 Jan 1997, Mike Patnode (mikep) - * suggests that this only needs to be done for HP-UX 9. - */ -#ifdef HPUX9 -#define PIDOOMA_STACK_SIZE 524288 -#define BACKTRACE_SIZE 8192 - { - jmp_buf jb; - char *newstack; - char *oldstack; - - if(!setjmp(jb)) { - newstack = (char *) PR_MALLOC(PIDOOMA_STACK_SIZE); - oldstack = (char *) (*(((int *) jb) + 1) - BACKTRACE_SIZE); - memcpy(newstack, oldstack, BACKTRACE_SIZE); - *(((int *) jb) + 1) = (int) (newstack + BACKTRACE_SIZE); - longjmp(jb, 1); - } - } -#endif /* HPUX9 */ -#endif /* !_PR_PTHREADS */ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifndef _PR_PTHREADS -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for HP-UX */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for HP-UX."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for HP-UX."); -} -#endif /* _PR_PTHREADS */ - -void -_MD_suspend_thread(PRThread *thread) -{ -#ifdef _PR_PTHREADS -#endif -} - -void -_MD_resume_thread(PRThread *thread) -{ -#ifdef _PR_PTHREADS -#endif -} -#endif /* PTHREADS_USER */ - -/* - * The HP version of strchr is buggy. It looks past the end of the - * string and causes a segmentation fault when our (NSPR) version - * of malloc is used. - * - * A better solution might be to put a cushion in our malloc just in - * case HP's version of strchr somehow gets used instead of this one. - */ -char * -strchr(const char *s, int c) -{ - char ch; - - if (!s) { - return NULL; - } - - ch = (char) c; - - while ((*s) && ((*s) != ch)) { - s++; - } - - if ((*s) == ch) { - return (char *) s; - } - - return NULL; -} - -/* - * Implemementation of memcmp in HP-UX (verified on releases A.09.03, - * A.09.07, and B.10.10) dumps core if called with: - * 1. First operand with address = 1(mod 4). - * 2. Size = 1(mod 4) - * 3. Last byte of the second operand is the last byte of the page and - * next page is not accessible(not mapped or protected) - * Thus, using the following naive version (tons of optimizations are - * possible;^) - */ - -int memcmp(const void *s1, const void *s2, size_t n) -{ - register unsigned char *p1 = (unsigned char *) s1, - *p2 = (unsigned char *) s2; - - while (n-- > 0) { - register int r = ((int) ((unsigned int) *p1)) - - ((int) ((unsigned int) *p2)); - if (r) return r; - p1++; p2++; - } - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/irix.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/irix.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/irix.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/irix.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1648 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void _MD_IrixIntervalInit(void); - -#if defined(_PR_PTHREADS) -/* - * for compatibility with classic nspr - */ -void _PR_IRIX_CHILD_PROCESS() -{ -} -#else /* defined(_PR_PTHREADS) */ - -static void irix_detach_sproc(void); -char *_nspr_sproc_private; /* ptr. to private region in every sproc */ - -extern PRUintn _pr_numCPU; - -typedef struct nspr_arena { - PRCList links; - usptr_t *usarena; -} nspr_arena; - -#define ARENA_PTR(qp) \ - ((nspr_arena *) ((char*) (qp) - offsetof(nspr_arena , links))) - -static usptr_t *alloc_new_arena(void); - -PRCList arena_list = PR_INIT_STATIC_CLIST(&arena_list); -ulock_t arena_list_lock; -nspr_arena first_arena; -int _nspr_irix_arena_cnt = 1; - -PRCList sproc_list = PR_INIT_STATIC_CLIST(&sproc_list); -ulock_t sproc_list_lock; - -typedef struct sproc_data { - void (*entry) (void *, size_t); - unsigned inh; - void *arg; - caddr_t sp; - size_t len; - int *pid; - int creator_pid; -} sproc_data; - -typedef struct sproc_params { - PRCList links; - sproc_data sd; -} sproc_params; - -#define SPROC_PARAMS_PTR(qp) \ - ((sproc_params *) ((char*) (qp) - offsetof(sproc_params , links))) - -long _nspr_irix_lock_cnt = 0; -long _nspr_irix_sem_cnt = 0; -long _nspr_irix_pollsem_cnt = 0; - -usptr_t *_pr_usArena; -ulock_t _pr_heapLock; - -usema_t *_pr_irix_exit_sem; -PRInt32 _pr_irix_exit_now = 0; -PRInt32 _pr_irix_process_exit_code = 0; /* exit code for PR_ProcessExit */ -PRInt32 _pr_irix_process_exit = 0; /* process exiting due to call to - PR_ProcessExit */ - -int _pr_irix_primoridal_cpu_fd[2] = { -1, -1 }; -static void (*libc_exit)(int) = NULL; -static void *libc_handle = NULL; - -#define _NSPR_DEF_INITUSERS 100 /* default value of CONF_INITUSERS */ -#define _NSPR_DEF_INITSIZE (4 * 1024 * 1024) /* 4 MB */ - -int _irix_initusers = _NSPR_DEF_INITUSERS; -int _irix_initsize = _NSPR_DEF_INITSIZE; - -PRIntn _pr_io_in_progress, _pr_clock_in_progress; - -PRInt32 _pr_md_irix_sprocs_created, _pr_md_irix_sprocs_failed; -PRInt32 _pr_md_irix_sprocs = 1; -PRCList _pr_md_irix_sproc_list = -PR_INIT_STATIC_CLIST(&_pr_md_irix_sproc_list); - -sigset_t ints_off; -extern sigset_t timer_set; - -#if !defined(PR_SETABORTSIG) -#define PR_SETABORTSIG 18 -#endif -/* - * terminate the entire application if any sproc exits abnormally - */ -PRBool _nspr_terminate_on_error = PR_TRUE; - -/* - * exported interface to set the shared arena parameters - */ -void _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize) -{ - _irix_initusers = initusers; - _irix_initsize = initsize; -} - -static usptr_t *alloc_new_arena() -{ - return(usinit("/dev/zero")); -} - -static PRStatus new_poll_sem(struct _MDThread *mdthr, int val) -{ -PRIntn _is; -PRStatus rv = PR_SUCCESS; -usema_t *sem = NULL; -PRCList *qp; -nspr_arena *arena; -usptr_t *irix_arena; -PRThread *me = _MD_GET_ATTACHED_THREAD(); - - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(_is); - _PR_LOCK(arena_list_lock); - for (qp = arena_list.next; qp != &arena_list; qp = qp->next) { - arena = ARENA_PTR(qp); - sem = usnewpollsema(arena->usarena, val); - if (sem != NULL) { - mdthr->cvar_pollsem = sem; - mdthr->pollsem_arena = arena->usarena; - break; - } - } - if (sem == NULL) { - /* - * If no space left in the arena allocate a new one. - */ - if (errno == ENOMEM) { - arena = PR_NEWZAP(nspr_arena); - if (arena != NULL) { - irix_arena = alloc_new_arena(); - if (irix_arena) { - PR_APPEND_LINK(&arena->links, &arena_list); - _nspr_irix_arena_cnt++; - arena->usarena = irix_arena; - sem = usnewpollsema(arena->usarena, val); - if (sem != NULL) { - mdthr->cvar_pollsem = sem; - mdthr->pollsem_arena = arena->usarena; - } else - rv = PR_FAILURE; - } else { - PR_DELETE(arena); - rv = PR_FAILURE; - } - - } else - rv = PR_FAILURE; - } else - rv = PR_FAILURE; - } - _PR_UNLOCK(arena_list_lock); - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(_is); - if (rv == PR_SUCCESS) - _MD_ATOMIC_INCREMENT(&_nspr_irix_pollsem_cnt); - return rv; -} - -static void free_poll_sem(struct _MDThread *mdthr) -{ -PRIntn _is; -PRThread *me = _MD_GET_ATTACHED_THREAD(); - - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(_is); - usfreepollsema(mdthr->cvar_pollsem, mdthr->pollsem_arena); - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(_is); - _MD_ATOMIC_DECREMENT(&_nspr_irix_pollsem_cnt); -} - -static PRStatus new_lock(struct _MDLock *lockp) -{ -PRIntn _is; -PRStatus rv = PR_SUCCESS; -ulock_t lock = NULL; -PRCList *qp; -nspr_arena *arena; -usptr_t *irix_arena; -PRThread *me = _MD_GET_ATTACHED_THREAD(); - - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(_is); - _PR_LOCK(arena_list_lock); - for (qp = arena_list.next; qp != &arena_list; qp = qp->next) { - arena = ARENA_PTR(qp); - lock = usnewlock(arena->usarena); - if (lock != NULL) { - lockp->lock = lock; - lockp->arena = arena->usarena; - break; - } - } - if (lock == NULL) { - /* - * If no space left in the arena allocate a new one. - */ - if (errno == ENOMEM) { - arena = PR_NEWZAP(nspr_arena); - if (arena != NULL) { - irix_arena = alloc_new_arena(); - if (irix_arena) { - PR_APPEND_LINK(&arena->links, &arena_list); - _nspr_irix_arena_cnt++; - arena->usarena = irix_arena; - lock = usnewlock(irix_arena); - if (lock != NULL) { - lockp->lock = lock; - lockp->arena = arena->usarena; - } else - rv = PR_FAILURE; - } else { - PR_DELETE(arena); - rv = PR_FAILURE; - } - - } else - rv = PR_FAILURE; - } else - rv = PR_FAILURE; - } - _PR_UNLOCK(arena_list_lock); - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(_is); - if (rv == PR_SUCCESS) - _MD_ATOMIC_INCREMENT(&_nspr_irix_lock_cnt); - return rv; -} - -static void free_lock(struct _MDLock *lockp) -{ -PRIntn _is; -PRThread *me = _MD_GET_ATTACHED_THREAD(); - - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(_is); - usfreelock(lockp->lock, lockp->arena); - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(_is); - _MD_ATOMIC_DECREMENT(&_nspr_irix_lock_cnt); -} - -void _MD_FREE_LOCK(struct _MDLock *lockp) -{ - PRIntn _is; - PRThread *me = _MD_GET_ATTACHED_THREAD(); - - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(_is); - free_lock(lockp); - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(_is); -} - -/* - * _MD_get_attached_thread - * Return the thread pointer of the current thread if it is attached. - * - * This function is needed for Irix because the thread-local-storage is - * implemented by mmapin'g a page with the MAP_LOCAL flag. This causes the - * sproc-private page to inherit contents of the page of the caller of sproc(). - */ -PRThread *_MD_get_attached_thread(void) -{ - - if (_MD_GET_SPROC_PID() == get_pid()) - return _MD_THIS_THREAD(); - else - return 0; -} - -/* - * _MD_get_current_thread - * Return the thread pointer of the current thread (attaching it if - * necessary) - */ -PRThread *_MD_get_current_thread(void) -{ -PRThread *me; - - me = _MD_GET_ATTACHED_THREAD(); - if (NULL == me) { - me = _PRI_AttachThread( - PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); - } - PR_ASSERT(me != NULL); - return(me); -} - -/* - * irix_detach_sproc - * auto-detach a sproc when it exits - */ -void irix_detach_sproc(void) -{ -PRThread *me; - - me = _MD_GET_ATTACHED_THREAD(); - if ((me != NULL) && (me->flags & _PR_ATTACHED)) { - _PRI_DetachThread(); - } -} - - -PRStatus _MD_NEW_LOCK(struct _MDLock *lockp) -{ - PRStatus rv; - PRIntn is; - PRThread *me = _MD_GET_ATTACHED_THREAD(); - - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - rv = new_lock(lockp); - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return rv; -} - -static void -sigchld_handler(int sig) -{ - pid_t pid; - int status; - - /* - * If an sproc exited abnormally send a SIGKILL signal to all the - * sprocs in the process to terminate the application - */ - while ((pid = waitpid(0, &status, WNOHANG)) > 0) { - if (WIFSIGNALED(status) && ((WTERMSIG(status) == SIGSEGV) || - (WTERMSIG(status) == SIGBUS) || - (WTERMSIG(status) == SIGABRT) || - (WTERMSIG(status) == SIGILL))) { - - prctl(PR_SETEXITSIG, SIGKILL); - _exit(status); - } - } -} - -static void save_context_and_block(int sig) -{ -PRThread *me = _PR_MD_CURRENT_THREAD(); -_PRCPU *cpu = _PR_MD_CURRENT_CPU(); - - /* - * save context - */ - (void) setjmp(me->md.jb); - /* - * unblock the suspending thread - */ - if (me->cpu) { - /* - * I am a cpu thread, not a user-created GLOBAL thread - */ - unblockproc(cpu->md.suspending_id); - } else { - unblockproc(me->md.suspending_id); - } - /* - * now, block current thread - */ - blockproc(getpid()); -} - -/* -** The irix kernel has a bug in it which causes async connect's which are -** interrupted by a signal to fail terribly (EADDRINUSE is returned). -** We work around the bug by blocking signals during the async connect -** attempt. -*/ -PRInt32 _MD_irix_connect( - PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout) -{ - PRInt32 rv; - sigset_t oldset; - - sigprocmask(SIG_BLOCK, &ints_off, &oldset); - rv = connect(osfd, addr, addrlen); - sigprocmask(SIG_SETMASK, &oldset, 0); - - return(rv); -} - -#include "prprf.h" - -/********************************************************************/ -/********************************************************************/ -/*************** Various thread like things for IRIX ****************/ -/********************************************************************/ -/********************************************************************/ - -void *_MD_GetSP(PRThread *t) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - void *sp; - - if (me == t) - (void) setjmp(t->md.jb); - - sp = (void *)(t->md.jb[JB_SP]); - PR_ASSERT((sp >= (void *) t->stack->stackBottom) && - (sp <= (void *) (t->stack->stackBottom + t->stack->stackSize))); - return(sp); -} - -void _MD_InitLocks() -{ - char buf[200]; - char *init_users, *init_size; - - PR_snprintf(buf, sizeof(buf), "/dev/zero"); - - if (init_users = getenv("_NSPR_IRIX_INITUSERS")) - _irix_initusers = atoi(init_users); - - if (init_size = getenv("_NSPR_IRIX_INITSIZE")) - _irix_initsize = atoi(init_size); - - usconfig(CONF_INITUSERS, _irix_initusers); - usconfig(CONF_INITSIZE, _irix_initsize); - usconfig(CONF_AUTOGROW, 1); - usconfig(CONF_AUTORESV, 1); - if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) { - perror("PR_Init: unable to config mutex arena"); - exit(-1); - } - - _pr_usArena = usinit(buf); - if (!_pr_usArena) { - fprintf(stderr, - "PR_Init: Error - unable to create lock/monitor arena\n"); - exit(-1); - } - _pr_heapLock = usnewlock(_pr_usArena); - _nspr_irix_lock_cnt++; - - arena_list_lock = usnewlock(_pr_usArena); - _nspr_irix_lock_cnt++; - - sproc_list_lock = usnewlock(_pr_usArena); - _nspr_irix_lock_cnt++; - - _pr_irix_exit_sem = usnewsema(_pr_usArena, 0); - _nspr_irix_sem_cnt = 1; - - first_arena.usarena = _pr_usArena; - PR_INIT_CLIST(&first_arena.links); - PR_APPEND_LINK(&first_arena.links, &arena_list); -} - -/* _PR_IRIX_CHILD_PROCESS is a private API for Server group */ -void _PR_IRIX_CHILD_PROCESS() -{ -extern PRUint32 _pr_global_threads; - - PR_ASSERT(_PR_MD_CURRENT_CPU() == _pr_primordialCPU); - PR_ASSERT(_pr_numCPU == 1); - PR_ASSERT(_pr_global_threads == 0); - /* - * save the new pid - */ - _pr_primordialCPU->md.id = getpid(); - _MD_SET_SPROC_PID(getpid()); -} - -static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout) -{ - int rv; - -#ifdef _PR_USE_POLL - struct pollfd pfd; - int msecs; - - if (timeout == PR_INTERVAL_NO_TIMEOUT) - msecs = -1; - else - msecs = PR_IntervalToMilliseconds(timeout); -#else - struct timeval tv, *tvp; - fd_set rd; - - if(timeout == PR_INTERVAL_NO_TIMEOUT) - tvp = NULL; - else { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - } - FD_ZERO(&rd); - FD_SET(thread->md.cvar_pollsemfd, &rd); -#endif - - /* - * call uspsema only if a previous select call on this semaphore - * did not timeout - */ - if (!thread->md.cvar_pollsem_select) { - rv = _PR_WAIT_SEM(thread->md.cvar_pollsem); - PR_ASSERT(rv >= 0); - } else - rv = 0; -again: - if(!rv) { -#ifdef _PR_USE_POLL - pfd.events = POLLIN; - pfd.fd = thread->md.cvar_pollsemfd; - rv = _MD_POLL(&pfd, 1, msecs); -#else - rv = _MD_SELECT(thread->md.cvar_pollsemfd + 1, &rd, NULL,NULL,tvp); -#endif - if ((rv == -1) && (errno == EINTR)) { - rv = 0; - goto again; - } - PR_ASSERT(rv >= 0); - } - - if (rv > 0) { - /* - * acquired the semaphore, call uspsema next time - */ - thread->md.cvar_pollsem_select = 0; - return PR_SUCCESS; - } else { - /* - * select timed out; must call select, not uspsema, when trying - * to acquire the semaphore the next time - */ - thread->md.cvar_pollsem_select = 1; - return PR_FAILURE; - } -} - -PRStatus _MD_wait(PRThread *thread, PRIntervalTime ticks) -{ - if ( thread->flags & _PR_GLOBAL_SCOPE ) { - _MD_CHECK_FOR_EXIT(); - if (pr_cvar_wait_sem(thread, ticks) == PR_FAILURE) { - _MD_CHECK_FOR_EXIT(); - /* - * wait timed out - */ - _PR_THREAD_LOCK(thread); - if (thread->wait.cvar) { - /* - * The thread will remove itself from the waitQ - * of the cvar in _PR_WaitCondVar - */ - thread->wait.cvar = NULL; - thread->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(thread); - } else { - _PR_THREAD_UNLOCK(thread); - /* - * This thread was woken up by a notifying thread - * at the same time as a timeout; so, consume the - * extra post operation on the semaphore - */ - _MD_CHECK_FOR_EXIT(); - pr_cvar_wait_sem(thread, PR_INTERVAL_NO_TIMEOUT); - } - _MD_CHECK_FOR_EXIT(); - } - } else { - _PR_MD_SWITCH_CONTEXT(thread); - } - return PR_SUCCESS; -} - -PRStatus _MD_WakeupWaiter(PRThread *thread) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRIntn is; - - PR_ASSERT(_pr_md_idle_cpus >= 0); - if (thread == NULL) { - if (_pr_md_idle_cpus) - _MD_Wakeup_CPUs(); - } else if (!_PR_IS_NATIVE_THREAD(thread)) { - if (_pr_md_idle_cpus) - _MD_Wakeup_CPUs(); - } else { - PR_ASSERT(_PR_IS_NATIVE_THREAD(thread)); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - _MD_CVAR_POST_SEM(thread); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - } - return PR_SUCCESS; -} - -void create_sproc (void (*entry) (void *, size_t), unsigned inh, - void *arg, caddr_t sp, size_t len, int *pid) -{ -sproc_params sparams; -char data; -int rv; -PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) { - *pid = sprocsp(entry, /* startup func */ - inh, /* attribute flags */ - arg, /* thread param */ - sp, /* stack address */ - len); /* stack size */ - } else { - sparams.sd.entry = entry; - sparams.sd.inh = inh; - sparams.sd.arg = arg; - sparams.sd.sp = sp; - sparams.sd.len = len; - sparams.sd.pid = pid; - sparams.sd.creator_pid = getpid(); - _PR_LOCK(sproc_list_lock); - PR_APPEND_LINK(&sparams.links, &sproc_list); - rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1); - PR_ASSERT(rv == 1); - _PR_UNLOCK(sproc_list_lock); - blockproc(getpid()); - } -} - -/* - * _PR_MD_WAKEUP_PRIMORDIAL_CPU - * - * wakeup cpu 0 - */ - -void _PR_MD_WAKEUP_PRIMORDIAL_CPU() -{ -char data = '0'; -int rv; - - rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1); - PR_ASSERT(rv == 1); -} - -/* - * _PR_MD_primordial_cpu - * - * process events that need to executed by the primordial cpu on each - * iteration through the idle loop - */ - -void _PR_MD_primordial_cpu() -{ -PRCList *qp; -sproc_params *sp; -int pid; - - _PR_LOCK(sproc_list_lock); - while ((qp = sproc_list.next) != &sproc_list) { - sp = SPROC_PARAMS_PTR(qp); - PR_REMOVE_LINK(&sp->links); - pid = sp->sd.creator_pid; - (*(sp->sd.pid)) = sprocsp(sp->sd.entry, /* startup func */ - sp->sd.inh, /* attribute flags */ - sp->sd.arg, /* thread param */ - sp->sd.sp, /* stack address */ - sp->sd.len); /* stack size */ - unblockproc(pid); - } - _PR_UNLOCK(sproc_list_lock); -} - -PRStatus _MD_CreateThread(PRThread *thread, -void (*start)(void *), -PRThreadPriority priority, -PRThreadScope scope, -PRThreadState state, -PRUint32 stackSize) -{ - typedef void (*SprocEntry) (void *, size_t); - SprocEntry spentry = (SprocEntry)start; - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 pid; - PRStatus rv; - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - thread->md.cvar_pollsem_select = 0; - thread->flags |= _PR_GLOBAL_SCOPE; - - thread->md.cvar_pollsemfd = -1; - if (new_poll_sem(&thread->md,0) == PR_FAILURE) { - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return PR_FAILURE; - } - thread->md.cvar_pollsemfd = - _PR_OPEN_POLL_SEM(thread->md.cvar_pollsem); - if ((thread->md.cvar_pollsemfd < 0)) { - free_poll_sem(&thread->md); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return PR_FAILURE; - } - - create_sproc(spentry, /* startup func */ - PR_SALL, /* attribute flags */ - (void *)thread, /* thread param */ - NULL, /* stack address */ - stackSize, &pid); /* stack size */ - if (pid > 0) { - _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_created); - _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs); - rv = PR_SUCCESS; - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return rv; - } else { - close(thread->md.cvar_pollsemfd); - thread->md.cvar_pollsemfd = -1; - free_poll_sem(&thread->md); - thread->md.cvar_pollsem = NULL; - _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_failed); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return PR_FAILURE; - } -} - -void _MD_CleanThread(PRThread *thread) -{ - if (thread->flags & _PR_GLOBAL_SCOPE) { - close(thread->md.cvar_pollsemfd); - thread->md.cvar_pollsemfd = -1; - free_poll_sem(&thread->md); - thread->md.cvar_pollsem = NULL; - } -} - -void _MD_SetPriority(_MDThread *thread, PRThreadPriority newPri) -{ - return; -} - -extern void _MD_unix_terminate_waitpid_daemon(void); - -void -_MD_CleanupBeforeExit(void) -{ - extern PRInt32 _pr_cpus_exit; - - _MD_unix_terminate_waitpid_daemon(); - - _pr_irix_exit_now = 1; - if (_pr_numCPU > 1) { - /* - * Set a global flag, and wakeup all cpus which will notice the flag - * and exit. - */ - _pr_cpus_exit = getpid(); - _MD_Wakeup_CPUs(); - while(_pr_numCPU > 1) { - _PR_WAIT_SEM(_pr_irix_exit_sem); - _pr_numCPU--; - } - } - /* - * cause global threads on the recycle list to exit - */ - _PR_DEADQ_LOCK; - if (_PR_NUM_DEADNATIVE != 0) { - PRThread *thread; - PRCList *ptr; - - ptr = _PR_DEADNATIVEQ.next; - while( ptr != &_PR_DEADNATIVEQ ) { - thread = _PR_THREAD_PTR(ptr); - _MD_CVAR_POST_SEM(thread); - ptr = ptr->next; - } - } - _PR_DEADQ_UNLOCK; - while(_PR_NUM_DEADNATIVE > 1) { - _PR_WAIT_SEM(_pr_irix_exit_sem); - _PR_DEC_DEADNATIVE; - } -} - -#ifdef _PR_HAVE_SGI_PRDA_PROCMASK -extern void __sgi_prda_procmask(int); -#endif - -PRStatus -_MD_InitAttachedThread(PRThread *thread, PRBool wakeup_parent) -{ - PRStatus rv = PR_SUCCESS; - - if (thread->flags & _PR_GLOBAL_SCOPE) { - if (new_poll_sem(&thread->md,0) == PR_FAILURE) { - return PR_FAILURE; - } - thread->md.cvar_pollsemfd = - _PR_OPEN_POLL_SEM(thread->md.cvar_pollsem); - if ((thread->md.cvar_pollsemfd < 0)) { - free_poll_sem(&thread->md); - return PR_FAILURE; - } - if (_MD_InitThread(thread, PR_FALSE) == PR_FAILURE) { - close(thread->md.cvar_pollsemfd); - thread->md.cvar_pollsemfd = -1; - free_poll_sem(&thread->md); - thread->md.cvar_pollsem = NULL; - return PR_FAILURE; - } - } - return rv; -} - -PRStatus -_MD_InitThread(PRThread *thread, PRBool wakeup_parent) -{ - struct sigaction sigact; - PRStatus rv = PR_SUCCESS; - - if (thread->flags & _PR_GLOBAL_SCOPE) { - thread->md.id = getpid(); - setblockproccnt(thread->md.id, 0); - _MD_SET_SPROC_PID(getpid()); -#ifdef _PR_HAVE_SGI_PRDA_PROCMASK - /* - * enable user-level processing of sigprocmask(); this is an - * undocumented feature available in Irix 6.2, 6.3, 6.4 and 6.5 - */ - __sgi_prda_procmask(USER_LEVEL); -#endif - /* - * set up SIGUSR1 handler; this is used to save state - */ - sigact.sa_handler = save_context_and_block; - sigact.sa_flags = SA_RESTART; - /* - * Must mask clock interrupts - */ - sigact.sa_mask = timer_set; - sigaction(SIGUSR1, &sigact, 0); - - - /* - * PR_SETABORTSIG is a new command implemented in a patch to - * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all - * sprocs in the process when one of them terminates abnormally - * - */ - if (prctl(PR_SETABORTSIG, SIGKILL) < 0) { - /* - * if (errno == EINVAL) - * - * PR_SETABORTSIG not supported under this OS. - * You may want to get a recent kernel rollup patch that - * supports this feature. - */ - } - /* - * SIGCLD handler for detecting abormally-terminating - * sprocs and for reaping sprocs - */ - sigact.sa_handler = sigchld_handler; - sigact.sa_flags = SA_RESTART; - sigact.sa_mask = ints_off; - sigaction(SIGCLD, &sigact, NULL); - } - return rv; -} - -/* - * PR_Cleanup should be executed on the primordial sproc; migrate the thread - * to the primordial cpu - */ - -void _PR_MD_PRE_CLEANUP(PRThread *me) -{ -PRIntn is; -_PRCPU *cpu = _pr_primordialCPU; - - PR_ASSERT(cpu); - - me->flags |= _PR_BOUND_THREAD; - - if (me->cpu->id != 0) { - _PR_INTSOFF(is); - _PR_RUNQ_LOCK(cpu); - me->cpu = cpu; - me->state = _PR_RUNNABLE; - _PR_ADD_RUNQ(me, cpu, me->priority); - _PR_RUNQ_UNLOCK(cpu); - _MD_Wakeup_CPUs(); - - _PR_MD_SWITCH_CONTEXT(me); - - _PR_FAST_INTSON(is); - PR_ASSERT(me->cpu->id == 0); - } -} - -/* - * process exiting - */ -PR_EXTERN(void ) _MD_exit(PRIntn status) -{ -PRThread *me = _PR_MD_CURRENT_THREAD(); - - /* - * the exit code of the process is the exit code of the primordial - * sproc - */ - if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) { - /* - * primordial sproc case: call _exit directly - * Cause SIGKILL to be sent to other sprocs - */ - prctl(PR_SETEXITSIG, SIGKILL); - _exit(status); - } else { - int rv; - char data; - sigset_t set; - - /* - * non-primordial sproc case: cause the primordial sproc, cpu 0, - * to wakeup and call _exit - */ - _pr_irix_process_exit = 1; - _pr_irix_process_exit_code = status; - rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1); - PR_ASSERT(rv == 1); - /* - * block all signals and wait for SIGKILL to terminate this sproc - */ - sigfillset(&set); - sigsuspend(&set); - /* - * this code doesn't (shouldn't) execute - */ - prctl(PR_SETEXITSIG, SIGKILL); - _exit(status); - } -} - -/* - * Override the exit() function in libc to cause the process to exit - * when the primodial/main nspr thread calls exit. Calls to exit by any - * other thread simply result in a call to the exit function in libc. - * The exit code of the process is the exit code of the primordial - * sproc. - */ - -void exit(int status) -{ -PRThread *me, *thr; -PRCList *qp; - - if (!_pr_initialized) { - if (!libc_exit) { - - if (!libc_handle) - libc_handle = dlopen("libc.so",RTLD_NOW); - if (libc_handle) - libc_exit = (void (*)(int)) dlsym(libc_handle, "exit"); - } - if (libc_exit) - (*libc_exit)(status); - else - _exit(status); - } - - me = _PR_MD_CURRENT_THREAD(); - - if (me == NULL) /* detached thread */ - (*libc_exit)(status); - - PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || - (_PR_MD_CURRENT_CPU())->id == me->cpu->id); - - if (me->flags & _PR_PRIMORDIAL) { - - me->flags |= _PR_BOUND_THREAD; - - PR_ASSERT((_PR_MD_CURRENT_CPU())->id == me->cpu->id); - if (me->cpu->id != 0) { - _PRCPU *cpu = _pr_primordialCPU; - PRIntn is; - - _PR_INTSOFF(is); - _PR_RUNQ_LOCK(cpu); - me->cpu = cpu; - me->state = _PR_RUNNABLE; - _PR_ADD_RUNQ(me, cpu, me->priority); - _PR_RUNQ_UNLOCK(cpu); - _MD_Wakeup_CPUs(); - - _PR_MD_SWITCH_CONTEXT(me); - - _PR_FAST_INTSON(is); - } - - PR_ASSERT((_PR_MD_CURRENT_CPU())->id == 0); - - if (prctl(PR_GETNSHARE) > 1) { -#define SPROC_EXIT_WAIT_TIME 5 - int sleep_cnt = SPROC_EXIT_WAIT_TIME; - - /* - * sprocs still running; caue cpus and recycled global threads - * to exit - */ - _pr_irix_exit_now = 1; - if (_pr_numCPU > 1) { - _MD_Wakeup_CPUs(); - } - _PR_DEADQ_LOCK; - if (_PR_NUM_DEADNATIVE != 0) { - PRThread *thread; - PRCList *ptr; - - ptr = _PR_DEADNATIVEQ.next; - while( ptr != &_PR_DEADNATIVEQ ) { - thread = _PR_THREAD_PTR(ptr); - _MD_CVAR_POST_SEM(thread); - ptr = ptr->next; - } - } - - while (sleep_cnt-- > 0) { - if (waitpid(0, NULL, WNOHANG) >= 0) - sleep(1); - else - break; - } - prctl(PR_SETEXITSIG, SIGKILL); - } - (*libc_exit)(status); - } else { - /* - * non-primordial thread; simply call exit in libc. - */ - (*libc_exit)(status); - } -} - - -void -_MD_InitRunningCPU(_PRCPU *cpu) -{ - extern int _pr_md_pipefd[2]; - - _MD_unix_init_running_cpu(cpu); - cpu->md.id = getpid(); - _MD_SET_SPROC_PID(getpid()); - if (_pr_md_pipefd[0] >= 0) { - _PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0]; -#ifndef _PR_USE_POLL - FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu)); -#endif - } -} - -void -_MD_ExitThread(PRThread *thread) -{ - if (thread->flags & _PR_GLOBAL_SCOPE) { - _MD_ATOMIC_DECREMENT(&_pr_md_irix_sprocs); - _MD_CLEAN_THREAD(thread); - _MD_SET_CURRENT_THREAD(NULL); - } -} - -void -_MD_SuspendCPU(_PRCPU *cpu) -{ - PRInt32 rv; - - cpu->md.suspending_id = getpid(); - rv = kill(cpu->md.id, SIGUSR1); - PR_ASSERT(rv == 0); - /* - * now, block the current thread/cpu until woken up by the suspended - * thread from it's SIGUSR1 signal handler - */ - blockproc(getpid()); - -} - -void -_MD_ResumeCPU(_PRCPU *cpu) -{ - unblockproc(cpu->md.id); -} - -#if 0 -/* - * save the register context of a suspended sproc - */ -void get_context(PRThread *thr) -{ - int len, fd; - char pidstr[24]; - char path[24]; - - /* - * open the file corresponding to this process in procfs - */ - sprintf(path,"/proc/%s","00000"); - len = strlen(path); - sprintf(pidstr,"%d",thr->md.id); - len -= strlen(pidstr); - sprintf(path + len,"%s",pidstr); - fd = open(path,O_RDONLY); - if (fd >= 0) { - (void) ioctl(fd, PIOCGREG, thr->md.gregs); - close(fd); - } - return; -} -#endif /* 0 */ - -void -_MD_SuspendThread(PRThread *thread) -{ - PRInt32 rv; - - PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) && - _PR_IS_GCABLE_THREAD(thread)); - - thread->md.suspending_id = getpid(); - rv = kill(thread->md.id, SIGUSR1); - PR_ASSERT(rv == 0); - /* - * now, block the current thread/cpu until woken up by the suspended - * thread from it's SIGUSR1 signal handler - */ - blockproc(getpid()); -} - -void -_MD_ResumeThread(PRThread *thread) -{ - PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) && - _PR_IS_GCABLE_THREAD(thread)); - (void)unblockproc(thread->md.id); -} - -/* - * return the set of processors available for scheduling procs in the - * "mask" argument - */ -PRInt32 _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask) -{ - PRInt32 nprocs, rv; - struct pda_stat *pstat; -#define MAX_PROCESSORS 32 - - nprocs = sysmp(MP_NPROCS); - if (nprocs < 0) - return(-1); - pstat = (struct pda_stat*)PR_MALLOC(sizeof(struct pda_stat) * nprocs); - if (pstat == NULL) - return(-1); - rv = sysmp(MP_STAT, pstat); - if (rv < 0) { - PR_DELETE(pstat); - return(-1); - } - /* - * look at the first 32 cpus - */ - nprocs = (nprocs > MAX_PROCESSORS) ? MAX_PROCESSORS : nprocs; - *mask = 0; - while (nprocs) { - if ((pstat->p_flags & PDAF_ENABLED) && - !(pstat->p_flags & PDAF_ISOLATED)) { - *mask |= (1 << pstat->p_cpuid); - } - nprocs--; - pstat++; - } - return 0; -} - -static char *_thr_state[] = { - "UNBORN", - "RUNNABLE", - "RUNNING", - "LOCK_WAIT", - "COND_WAIT", - "JOIN_WAIT", - "IO_WAIT", - "SUSPENDED", - "DEAD" -}; - -void _PR_List_Threads() -{ - PRThread *thr; - void *handle; - struct _PRCPU *cpu; - PRCList *qp; - int len, fd; - char pidstr[24]; - char path[24]; - prpsinfo_t pinfo; - - - printf("\n%s %-s\n"," ","LOCAL Threads"); - printf("%s %-s\n"," ","----- -------"); - printf("%s %-14s %-10s %-12s %-3s %-10s %-10s %-12s\n\n"," ", - "Thread", "State", "Wait-Handle", - "Cpu","Stk-Base","Stk-Sz","SP"); - for (qp = _PR_ACTIVE_LOCAL_THREADQ().next; - qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) { - thr = _PR_ACTIVE_THREAD_PTR(qp); - printf("%s 0x%-12x %-10s "," ",thr,_thr_state[thr->state]); - if (thr->state == _PR_LOCK_WAIT) - handle = thr->wait.lock; - else if (thr->state == _PR_COND_WAIT) - handle = thr->wait.cvar; - else - handle = NULL; - if (handle) - printf("0x%-10x ",handle); - else - printf("%-12s "," "); - printf("%-3d ",thr->cpu->id); - printf("0x%-8x ",thr->stack->stackBottom); - printf("0x%-8x ",thr->stack->stackSize); - printf("0x%-10x\n",thr->md.jb[JB_SP]); - } - - printf("\n%s %-s\n"," ","GLOBAL Threads"); - printf("%s %-s\n"," ","------ -------"); - printf("%s %-14s %-6s %-12s %-12s %-12s %-12s\n\n"," ","Thread", - "Pid","State","Wait-Handle", - "Stk-Base","Stk-Sz"); - - for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next; - qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) { - thr = _PR_ACTIVE_THREAD_PTR(qp); - if (thr->cpu != NULL) - continue; /* it is a cpu thread */ - printf("%s 0x%-12x %-6d "," ",thr,thr->md.id); - /* - * check if the sproc is still running - * first call prctl(PR_GETSHMASK,pid) to check if - * the process is part of the share group (the pid - * could have been recycled by the OS) - */ - if (prctl(PR_GETSHMASK,thr->md.id) < 0) { - printf("%-12s\n","TERMINATED"); - continue; - } - /* - * Now, check if the sproc terminated and is in zombie - * state - */ - sprintf(path,"/proc/pinfo/%s","00000"); - len = strlen(path); - sprintf(pidstr,"%d",thr->md.id); - len -= strlen(pidstr); - sprintf(path + len,"%s",pidstr); - fd = open(path,O_RDONLY); - if (fd >= 0) { - if (ioctl(fd, PIOCPSINFO, &pinfo) < 0) - printf("%-12s ","TERMINATED"); - else if (pinfo.pr_zomb) - printf("%-12s ","TERMINATED"); - else - printf("%-12s ",_thr_state[thr->state]); - close(fd); - } else { - printf("%-12s ","TERMINATED"); - } - - if (thr->state == _PR_LOCK_WAIT) - handle = thr->wait.lock; - else if (thr->state == _PR_COND_WAIT) - handle = thr->wait.cvar; - else - handle = NULL; - if (handle) - printf("%-12x ",handle); - else - printf("%-12s "," "); - printf("0x%-10x ",thr->stack->stackBottom); - printf("0x%-10x\n",thr->stack->stackSize); - } - - printf("\n%s %-s\n"," ","CPUs"); - printf("%s %-s\n"," ","----"); - printf("%s %-14s %-6s %-12s \n\n"," ","Id","Pid","State"); - - - for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) { - cpu = _PR_CPU_PTR(qp); - printf("%s %-14d %-6d "," ",cpu->id,cpu->md.id); - /* - * check if the sproc is still running - * first call prctl(PR_GETSHMASK,pid) to check if - * the process is part of the share group (the pid - * could have been recycled by the OS) - */ - if (prctl(PR_GETSHMASK,cpu->md.id) < 0) { - printf("%-12s\n","TERMINATED"); - continue; - } - /* - * Now, check if the sproc terminated and is in zombie - * state - */ - sprintf(path,"/proc/pinfo/%s","00000"); - len = strlen(path); - sprintf(pidstr,"%d",cpu->md.id); - len -= strlen(pidstr); - sprintf(path + len,"%s",pidstr); - fd = open(path,O_RDONLY); - if (fd >= 0) { - if (ioctl(fd, PIOCPSINFO, &pinfo) < 0) - printf("%-12s\n","TERMINATED"); - else if (pinfo.pr_zomb) - printf("%-12s\n","TERMINATED"); - else - printf("%-12s\n","RUNNING"); - close(fd); - } else { - printf("%-12s\n","TERMINATED"); - } - - } - fflush(stdout); -} -#endif /* defined(_PR_PTHREADS) */ - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#if !defined(_PR_PTHREADS) - if (isCurrent) { - (void) setjmp(t->md.jb); - } - *np = sizeof(t->md.jb) / sizeof(PRWord); - return (PRWord *) (t->md.jb); -#else - *np = 0; - return NULL; -#endif -} - -void _MD_EarlyInit(void) -{ -#if !defined(_PR_PTHREADS) - char *eval; - int fd; - extern int __ateachexit(void (*func)(void)); - - sigemptyset(&ints_off); - sigaddset(&ints_off, SIGALRM); - sigaddset(&ints_off, SIGIO); - sigaddset(&ints_off, SIGCLD); - - if (eval = getenv("_NSPR_TERMINATE_ON_ERROR")) - _nspr_terminate_on_error = (0 == atoi(eval) == 0) ? PR_FALSE : PR_TRUE; - - fd = open("/dev/zero",O_RDWR , 0); - if (fd < 0) { - perror("open /dev/zero failed"); - exit(1); - } - /* - * Set up the sproc private data area. - * This region exists at the same address, _nspr_sproc_private, for - * every sproc, but each sproc gets a private copy of the region. - */ - _nspr_sproc_private = (char*)mmap(0, _pr_pageSize, PROT_READ | PROT_WRITE, - MAP_PRIVATE| MAP_LOCAL, fd, 0); - if (_nspr_sproc_private == (void*)-1) { - perror("mmap /dev/zero failed"); - exit(1); - } - _MD_SET_SPROC_PID(getpid()); - close(fd); - __ateachexit(irix_detach_sproc); -#endif - _MD_IrixIntervalInit(); -} /* _MD_EarlyInit */ - -void _MD_IrixInit(void) -{ -#if !defined(_PR_PTHREADS) - struct sigaction sigact; - PRThread *me = _PR_MD_CURRENT_THREAD(); - int rv; - -#ifdef _PR_HAVE_SGI_PRDA_PROCMASK - /* - * enable user-level processing of sigprocmask(); this is an undocumented - * feature available in Irix 6.2, 6.3, 6.4 and 6.5 - */ - __sgi_prda_procmask(USER_LEVEL); -#endif - - /* - * set up SIGUSR1 handler; this is used to save state - * during PR_SuspendAll - */ - sigact.sa_handler = save_context_and_block; - sigact.sa_flags = SA_RESTART; - sigact.sa_mask = ints_off; - sigaction(SIGUSR1, &sigact, 0); - - /* - * Change the name of the core file from core to core.pid, - * This is inherited by the sprocs created by this process - */ -#ifdef PR_COREPID - prctl(PR_COREPID, 0, 1); -#endif - /* - * Irix-specific terminate on error processing - */ - /* - * PR_SETABORTSIG is a new command implemented in a patch to - * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all - * sprocs in the process when one of them terminates abnormally - * - */ - if (prctl(PR_SETABORTSIG, SIGKILL) < 0) { - /* - * if (errno == EINVAL) - * - * PR_SETABORTSIG not supported under this OS. - * You may want to get a recent kernel rollup patch that - * supports this feature. - * - */ - } - /* - * PR_SETEXITSIG - send the SIGCLD signal to the parent - * sproc when any sproc terminates - * - * This is used to cause the entire application to - * terminate when any sproc terminates abnormally by - * receipt of a SIGSEGV, SIGBUS or SIGABRT signal. - * If this is not done, the application may seem - * "hung" to the user because the other sprocs may be - * waiting for resources held by the - * abnormally-terminating sproc. - */ - prctl(PR_SETEXITSIG, 0); - - sigact.sa_handler = sigchld_handler; - sigact.sa_flags = SA_RESTART; - sigact.sa_mask = ints_off; - sigaction(SIGCLD, &sigact, NULL); - - /* - * setup stack fields for the primordial thread - */ - me->stack->stackSize = prctl(PR_GETSTACKSIZE); - me->stack->stackBottom = me->stack->stackTop - me->stack->stackSize; - - rv = pipe(_pr_irix_primoridal_cpu_fd); - PR_ASSERT(rv == 0); -#ifndef _PR_USE_POLL - _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0]; - FD_SET(_pr_irix_primoridal_cpu_fd[0], &_PR_FD_READ_SET(me->cpu)); -#endif - - libc_handle = dlopen("libc.so",RTLD_NOW); - PR_ASSERT(libc_handle != NULL); - libc_exit = (void (*)(int)) dlsym(libc_handle, "exit"); - PR_ASSERT(libc_exit != NULL); - /* dlclose(libc_handle); */ - -#endif /* _PR_PTHREADS */ - - _PR_UnixInit(); -} - -/**************************************************************************/ -/************** code and such for NSPR 2.0's interval times ***************/ -/**************************************************************************/ - -#define PR_PSEC_PER_SEC 1000000000000ULL /* 10^12 */ - -#ifndef SGI_CYCLECNTR_SIZE -#define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */ -#endif - -static PRIntn mmem_fd = -1; -static PRIntn clock_width = 0; -static void *iotimer_addr = NULL; -static PRUint32 pr_clock_mask = 0; -static PRUint32 pr_clock_shift = 0; -static PRIntervalTime pr_ticks = 0; -static PRUint32 pr_clock_granularity = 1; -static PRUint32 pr_previous = 0, pr_residual = 0; -static PRUint32 pr_ticks_per_second = 0; - -extern PRIntervalTime _PR_UNIX_GetInterval(void); -extern PRIntervalTime _PR_UNIX_TicksPerSecond(void); - -static void _MD_IrixIntervalInit(void) -{ - /* - * As much as I would like, the service available through this - * interface on R3000's (aka, IP12) just isn't going to make it. - * The register is only 24 bits wide, and rolls over at a verocious - * rate. - */ - PRUint32 one_tick = 0; - struct utsname utsinfo; - uname(&utsinfo); - if ((strncmp("IP12", utsinfo.machine, 4) != 0) - && ((mmem_fd = open("/dev/mmem", O_RDONLY)) != -1)) - { - int poffmask = getpagesize() - 1; - __psunsigned_t phys_addr, raddr, cycleval; - - phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval); - raddr = phys_addr & ~poffmask; - iotimer_addr = mmap( - 0, poffmask, PROT_READ, MAP_PRIVATE, mmem_fd, (__psint_t)raddr); - - clock_width = syssgi(SGI_CYCLECNTR_SIZE); - if (clock_width < 0) - { - /* - * We must be executing on a 6.0 or earlier system, since the - * SGI_CYCLECNTR_SIZE call is not supported. - * - * The only pre-6.1 platforms with 64-bit counters are - * IP19 and IP21 (Challenge, PowerChallenge, Onyx). - */ - if (!strncmp(utsinfo.machine, "IP19", 4) || - !strncmp(utsinfo.machine, "IP21", 4)) - clock_width = 64; - else - clock_width = 32; - } - - /* - * 'cycleval' is picoseconds / increment of the counter. - * I'm pushing for a tick to be 100 microseconds, 10^(-4). - * That leaves 10^(-8) left over, or 10^8 / cycleval. - * Did I do that right? - */ - - one_tick = 100000000UL / cycleval ; /* 100 microseconds */ - - while (0 != one_tick) - { - pr_clock_shift += 1; - one_tick = one_tick >> 1; - pr_clock_granularity = pr_clock_granularity << 1; - } - pr_clock_mask = pr_clock_granularity - 1; /* to make a mask out of it */ - pr_ticks_per_second = PR_PSEC_PER_SEC - / ((PRUint64)pr_clock_granularity * (PRUint64)cycleval); - - iotimer_addr = (void*) - ((__psunsigned_t)iotimer_addr + (phys_addr & poffmask)); - } - else - { - pr_ticks_per_second = _PR_UNIX_TicksPerSecond(); - } -} /* _MD_IrixIntervalInit */ - -PRIntervalTime _MD_IrixIntervalPerSec(void) -{ - return pr_ticks_per_second; -} - -PRIntervalTime _MD_IrixGetInterval(void) -{ - if (mmem_fd != -1) - { - if (64 == clock_width) - { - PRUint64 temp = *(PRUint64*)iotimer_addr; - pr_ticks = (PRIntervalTime)(temp >> pr_clock_shift); - } - else - { - PRIntervalTime ticks = pr_ticks; - PRUint32 now = *(PRUint32*)iotimer_addr, temp; - PRUint32 residual = pr_residual, previous = pr_previous; - - temp = now - previous + residual; - residual = temp & pr_clock_mask; - ticks += temp >> pr_clock_shift; - - pr_previous = now; - pr_residual = residual; - pr_ticks = ticks; - } - } - else - { - /* - * No fast access. Use the time of day clock. This isn't the - * right answer since this clock can get set back, tick at odd - * rates, and it's expensive to acqurie. - */ - pr_ticks = _PR_UNIX_GetInterval(); - } - return pr_ticks; -} /* _MD_IrixGetInterval */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/linux.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/linux.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/linux.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/linux.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifdef _PR_PTHREADS - -extern void _MD_unix_terminate_waitpid_daemon(void); - -void _MD_CleanupBeforeExit(void) -{ - _MD_unix_terminate_waitpid_daemon(); -} - -#else /* ! _PR_PTHREADS */ - -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - /* - * set the pointers to the stack-pointer and frame-pointer words in the - * context structure; this is for debugging use. - */ - thread->md.sp = _MD_GET_SP_PTR(thread); - thread->md.fp = _MD_GET_FP_PTR(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for Linux */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for Linux."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Linux."); - return PR_FAILURE; -} -#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/Makefile.in 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -MOD_DEPTH = ../../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CSRCS = \ - unix.c \ - unix_errors.c \ - uxproces.c \ - uxrng.c \ - uxshm.c \ - uxwrap.c \ - $(NULL) - -ifneq ($(USE_PTHREADS),1) -CSRCS += uxpoll.c -endif - -ifeq ($(PTHREADS_USER),1) -CSRCS += pthreads_user.c -endif - -CSRCS += $(PR_MD_CSRCS) -ASFILES += $(PR_MD_ASFILES) - -TARGETS = $(OBJS) - -ifeq ($(OS_ARCH),SunOS) - ifeq ($(CPU_ARCH),sparc) - ifdef USE_64 - ULTRASPARC_ASFILES = os_SunOS_sparcv9.s - ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX))) - else - LIBRARY_NAME = $(ULTRASPARC_LIBRARY) - LIBRARY_VERSION = $(MOD_MAJOR_VERSION) - ULTRASPARC_ASFILES = os_SunOS_ultrasparc.s - ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX))) - TARGETS += $(ULTRASPARC_ASOBJS) $(SHARED_LIBRARY) - RELEASE_LIBS = $(SHARED_LIBRARY) - RELEASE_LIBS_DEST = $(RELEASE_LIB_DIR)/cpu/sparcv8plus - lib_subdir = cpu/sparcv8plus - endif - endif -endif - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - -ifeq ($(OS_ARCH),SunOS) -ifeq ($(CPU_ARCH),sparc) - -ifdef USE_64 -$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES) - /usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v9 $< -else -$(SHARED_LIBRARY): $(ULTRASPARC_ASOBJS) - $(LD) -G -z text -z endfiltee -o $@ $(ULTRASPARC_ASOBJS) - $(INSTALL) -m 444 $@ $(dist_libdir)/cpu/sparcv8plus - $(INSTALL) -m 444 $@ $(dist_bindir)/cpu/sparcv8plus -# -# The -f $(ORIGIN)/... linker flag uses the real file, after symbolic links -# are resolved, as the origin. If NSDISTMODE is not "copy", libnspr4.so -# will be installed as a symbolic link in $(dist_libdir), pointing to the -# real libnspr4.so file in pr/src. Therefore we need to install an -# additional copy of libnspr_flt4.so in pr/src/cpu/sparcv8plus. -# -ifneq ($(NSDISTMODE),copy) - $(INSTALL) -m 444 $@ ../../cpu/sparcv8plus -endif - -ifneq ($(NSDISTMODE),copy) -clobber realclean clobber_all distclean:: - rm -rf ../../cpu -endif - -$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES) - /usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v8plus $< - -clean:: - rm -rf $(ULTRASPARC_ASOBJS) -endif - -endif -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/netbsd.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/netbsd.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/netbsd.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/netbsd.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include -#include - -void _MD_EarlyInit(void) -{ - /* - * Ignore FPE because coercion of a NaN to an int causes SIGFPE - * to be raised. - */ - struct sigaction act; - - act.sa_handler = SIG_IGN; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - sigaction(SIGFPE, &act, 0); -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) sigsetjmp(CONTEXT(t), 1); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifndef _PR_PTHREADS -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for NetBSD */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for NetBSD."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NetBSD."); - return PR_FAILURE; -} -#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/nto.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/nto.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/nto.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/nto.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -/* Fake this out */ -int socketpair (int foo, int foo2, int foo3, int sv[2]) -{ - printf("error in socketpair\n"); - exit (-1); -} - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/objs.mk nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/objs.mk --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/objs.mk 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/objs.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This makefile appends to the variable OBJS the platform-dependent -# object modules that will be part of the nspr20 library. - -CSRCS = \ - unix.c \ - unix_errors.c \ - uxproces.c \ - uxrng.c \ - uxshm.c \ - uxwrap.c \ - $(NULL) - -ifneq ($(USE_PTHREADS),1) -CSRCS += uxpoll.c -endif - -ifeq ($(PTHREADS_USER),1) -CSRCS += pthreads_user.c -endif - -CSRCS += $(PR_MD_CSRCS) -ASFILES += $(PR_MD_ASFILES) - -OBJS += $(addprefix md/unix/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \ - $(addprefix md/unix/$(OBJDIR)/,$(ASFILES:.s=.$(OBJ_SUFFIX))) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/openbsd.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/openbsd.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/openbsd.c 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/openbsd.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include -#include - -void _MD_EarlyInit(void) -{ - /* - * Ignore FPE because coercion of a NaN to an int causes SIGFPE - * to be raised. - */ - struct sigaction act; - - act.sa_handler = SIG_IGN; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - sigaction(SIGFPE, &act, 0); -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) sigsetjmp(CONTEXT(t), 1); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifndef _PR_PTHREADS -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for OpenBSD */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for OpenBSD."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OpenBSD."); - return PR_FAILURE; -} -#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_AIX.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_AIX.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_AIX.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_AIX.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4 -.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 -.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 -.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 -.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 -.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 -.set r30,30; .set r31,31 - - - .rename H.10.NO_SYMBOL{PR},"" - .rename H.18.longjmp{TC},"longjmp" - - .lglobl H.10.NO_SYMBOL{PR} - .globl .longjmp - .globl longjmp{DS} - .extern .sigcleanup - .extern .jmprestfpr - -# .text section - - .csect H.10.NO_SYMBOL{PR} -.longjmp: - mr r13,r3 - mr r14,r4 - stu SP,-56(SP) - bl .sigcleanup - l RTOC,0x14(SP) - cal SP,0x38(SP) - mr r3,r13 - mr r4,r14 - l r5,0x8(r3) - l SP,0xc(r3) - l r7,0xf8(r3) - st r7,0x0(SP) - l RTOC,0x10(r3) - bl .jmprestfpr -# 1 == cr0 in disassembly - cmpi 1,r4,0x0 - mtlr r5 - lm r13,0x14(r3) - l r5,0x60(r3) - mtcrf 0x38,r5 - mr r3,r4 - bne __L1 - lil r3,0x1 -__L1: - br - -# traceback table - .long 0x00000000 - .byte 0x00 # VERSION=0 - .byte 0x00 # LANG=TB_C - .byte 0x20 # IS_GL=0,IS_EPROL=0,HAS_TBOFF=1 - # INT_PROC=0,HAS_CTL=0,TOCLESS=0 - # FP_PRESENT=0,LOG_ABORT=0 - .byte 0x40 # INT_HNDL=0,NAME_PRESENT=1 - # USES_ALLOCA=0,CL_DIS_INV=WALK_ONCOND - # SAVES_CR=0,SAVES_LR=0 - .byte 0x80 # STORES_BC=1,FPR_SAVED=0 - .byte 0x00 # GPR_SAVED=0 - .byte 0x02 # FIXEDPARMS=2 - .byte 0x01 # FLOATPARMS=0,PARMSONSTK=1 - .long 0x00000000 # - .long 0x00000014 # TB_OFFSET - .short 7 # NAME_LEN - .byte "longjmp" - .byte 0 # padding - .byte 0 # padding - .byte 0 # padding -# End of traceback table - .long 0x00000000 # "\0\0\0\0" - -# .data section - - .toc # 0x00000038 -T.18.longjmp: - .tc H.18.longjmp{TC},longjmp{DS} - - .csect longjmp{DS} - .long .longjmp # "\0\0\0\0" - .long TOC{TC0} # "\0\0\0008" - .long 0x00000000 # "\0\0\0\0" -# End csect longjmp{DS} - -# .bss section diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_BSD_386_2.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_BSD_386_2.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_BSD_386_2.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_BSD_386_2.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * os_BSD_386_2.s - * We need to define our own setjmp/longjmp on BSDI 2.x because libc's - * implementation does some sanity checking that defeats user level threads. - * This should no longer be necessary in BSDI 3.0. - */ - -.globl _setjmp -.align 2 -_setjmp: - movl 4(%esp),%eax - movl 0(%esp),%edx - movl %edx, 0(%eax) /* rta */ - movl %ebx, 4(%eax) - movl %esp, 8(%eax) - movl %ebp,12(%eax) - movl %esi,16(%eax) - movl %edi,20(%eax) - movl $0,%eax - ret - -.globl _longjmp -.align 2 -_longjmp: - movl 4(%esp),%edx - movl 8(%esp),%eax - movl 0(%edx),%ecx - movl 4(%edx),%ebx - movl 8(%edx),%esp - movl 12(%edx),%ebp - movl 16(%edx),%esi - movl 20(%edx),%edi - cmpl $0,%eax - jne 1f - movl $1,%eax -1: movl %ecx,0(%esp) - ret diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Darwin_ppc.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Darwin_ppc.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Darwin_ppc.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Darwin_ppc.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# -# Based on the programming examples in The PowerPC Architecture: -# A Specification for A New Family of RISC Processors, 2nd Ed., -# Book I, Section E.1, "Synchronization," pp. 249-256, May 1994. -# - -.text - -# -# PRInt32 __PR_DarwinPPC_AtomicIncrement(PRInt32 *val); -# - .align 2 - .globl __PR_DarwinPPC_AtomicIncrement - .private_extern __PR_DarwinPPC_AtomicIncrement -__PR_DarwinPPC_AtomicIncrement: - lwarx r4,0,r3 - addi r0,r4,1 - stwcx. r0,0,r3 - bne- __PR_DarwinPPC_AtomicIncrement - mr r3,r0 - blr - -# -# PRInt32 __PR_DarwinPPC_AtomicDecrement(PRInt32 *val); -# - .align 2 - .globl __PR_DarwinPPC_AtomicDecrement - .private_extern __PR_DarwinPPC_AtomicDecrement -__PR_DarwinPPC_AtomicDecrement: - lwarx r4,0,r3 - addi r0,r4,-1 - stwcx. r0,0,r3 - bne- __PR_DarwinPPC_AtomicDecrement - mr r3,r0 - blr - -# -# PRInt32 __PR_DarwinPPC_AtomicSet(PRInt32 *val, PRInt32 newval); -# - .align 2 - .globl __PR_DarwinPPC_AtomicSet - .private_extern __PR_DarwinPPC_AtomicSet -__PR_DarwinPPC_AtomicSet: - lwarx r5,0,r3 - stwcx. r4,0,r3 - bne- __PR_DarwinPPC_AtomicSet - mr r3,r5 - blr - -# -# PRInt32 __PR_DarwinPPC_AtomicAdd(PRInt32 *ptr, PRInt32 val); -# - .align 2 - .globl __PR_DarwinPPC_AtomicAdd - .private_extern __PR_DarwinPPC_AtomicAdd -__PR_DarwinPPC_AtomicAdd: - lwarx r5,0,r3 - add r0,r4,r5 - stwcx. r0,0,r3 - bne- __PR_DarwinPPC_AtomicAdd - mr r3,r0 - blr diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Darwin.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Darwin.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Darwin.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Darwin.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifdef __i386__ -#include "os_Darwin_x86.s" -#elif defined(__x86_64__) -#include "os_Darwin_x86_64.s" -#elif defined(__ppc__) -#include "os_Darwin_ppc.s" -#endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86_64.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86_64.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86_64.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86_64.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# PRInt32 __PR_Darwin_x86_64_AtomicIncrement(PRInt32 *val) -# -# Atomically increment the integer pointed to by 'val' and return -# the result of the increment. -# - .text - .globl __PR_Darwin_x86_64_AtomicIncrement - .private_extern __PR_Darwin_x86_64_AtomicIncrement - .align 4 -__PR_Darwin_x86_64_AtomicIncrement: - movl $1, %eax - lock - xaddl %eax, (%rdi) - incl %eax - ret - -# PRInt32 __PR_Darwin_x86_64_AtomicDecrement(PRInt32 *val) -# -# Atomically decrement the integer pointed to by 'val' and return -# the result of the decrement. -# - .text - .globl __PR_Darwin_x86_64_AtomicDecrement - .private_extern __PR_Darwin_x86_64_AtomicDecrement - .align 4 -__PR_Darwin_x86_64_AtomicDecrement: - movl $-1, %eax - lock - xaddl %eax, (%rdi) - decl %eax - ret - -# PRInt32 __PR_Darwin_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval) -# -# Atomically set the integer pointed to by 'val' to the new -# value 'newval' and return the old value. -# - .text - .globl __PR_Darwin_x86_64_AtomicSet - .private_extern __PR_Darwin_x86_64_AtomicSet - .align 4 -__PR_Darwin_x86_64_AtomicSet: - movl %esi, %eax - xchgl %eax, (%rdi) - ret - -# PRInt32 __PR_Darwin_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val) -# -# Atomically add 'val' to the integer pointed to by 'ptr' -# and return the result of the addition. -# - .text - .globl __PR_Darwin_x86_64_AtomicAdd - .private_extern __PR_Darwin_x86_64_AtomicAdd - .align 4 -__PR_Darwin_x86_64_AtomicAdd: - movl %esi, %eax - lock - xaddl %eax, (%rdi) - addl %esi, %eax - ret diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Darwin_x86.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# -# Based on os_Linux_x86.s -# - -# -# PRInt32 __PR_Darwin_x86_AtomicIncrement(PRInt32 *val); -# -# Atomically increment the integer pointed to by 'val' and return -# the result of the increment. -# - .text - .globl __PR_Darwin_x86_AtomicIncrement - .private_extern __PR_Darwin_x86_AtomicIncrement - .align 4 -__PR_Darwin_x86_AtomicIncrement: - movl 4(%esp), %ecx - movl $1, %eax - lock - xaddl %eax, (%ecx) - incl %eax - ret - -# -# PRInt32 __PR_Darwin_x86_AtomicDecrement(PRInt32 *val); -# -# Atomically decrement the integer pointed to by 'val' and return -# the result of the decrement. -# - .text - .globl __PR_Darwin_x86_AtomicDecrement - .private_extern __PR_Darwin_x86_AtomicDecrement - .align 4 -__PR_Darwin_x86_AtomicDecrement: - movl 4(%esp), %ecx - movl $-1, %eax - lock - xaddl %eax, (%ecx) - decl %eax - ret - -# -# PRInt32 __PR_Darwin_x86_AtomicSet(PRInt32 *val, PRInt32 newval); -# -# Atomically set the integer pointed to by 'val' to the new -# value 'newval' and return the old value. -# - .text - .globl __PR_Darwin_x86_AtomicSet - .private_extern __PR_Darwin_x86_AtomicSet - .align 4 -__PR_Darwin_x86_AtomicSet: - movl 4(%esp), %ecx - movl 8(%esp), %eax - xchgl %eax, (%ecx) - ret - -# -# PRInt32 __PR_Darwin_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val); -# -# Atomically add 'val' to the integer pointed to by 'ptr' -# and return the result of the addition. -# - .text - .globl __PR_Darwin_x86_AtomicAdd - .private_extern __PR_Darwin_x86_AtomicAdd - .align 4 -__PR_Darwin_x86_AtomicAdd: - movl 4(%esp), %ecx - movl 8(%esp), %eax - movl %eax, %edx - lock - xaddl %eax, (%ecx) - addl %edx, %eax - ret diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/osf1.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/osf1.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/osf1.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/osf1.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifndef _PR_PTHREADS -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for OSF1 */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for OSF1."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OSF1."); - return PR_FAILURE; -} -#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_HPUX_ia64.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_HPUX_ia64.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_HPUX_ia64.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_HPUX_ia64.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -.text - -// PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val) -// -// Atomically increment the integer pointed to by 'val' and return -// the result of the increment. -// - .align 16 - .global _PR_ia64_AtomicIncrement# - .proc _PR_ia64_AtomicIncrement# -_PR_ia64_AtomicIncrement: -#ifndef _LP64 - addp4 r32 = 0, r32 ;; -#endif - fetchadd4.acq r8 = [r32], 1 ;; - adds r8 = 1, r8 - br.ret.sptk.many b0 - .endp _PR_ia64_AtomicIncrement# - -// PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val) -// -// Atomically decrement the integer pointed to by 'val' and return -// the result of the decrement. -// - .align 16 - .global _PR_ia64_AtomicDecrement# - .proc _PR_ia64_AtomicDecrement# -_PR_ia64_AtomicDecrement: -#ifndef _LP64 - addp4 r32 = 0, r32 ;; -#endif - fetchadd4.rel r8 = [r32], -1 ;; - adds r8 = -1, r8 - br.ret.sptk.many b0 - .endp _PR_ia64_AtomicDecrement# - -// PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val) -// -// Atomically add 'val' to the integer pointed to by 'ptr' -// and return the result of the addition. -// - .align 16 - .global _PR_ia64_AtomicAdd# - .proc _PR_ia64_AtomicAdd# -_PR_ia64_AtomicAdd: -#ifndef _LP64 - addp4 r32 = 0, r32 ;; -#endif - ld4 r15 = [r32] ;; -.L3: - mov r14 = r15 - mov ar.ccv = r15 - add r8 = r15, r33 ;; - cmpxchg4.acq r15 = [r32], r8, ar.ccv ;; - cmp4.ne p6, p7 = r15, r14 - (p6) br.cond.dptk .L3 - br.ret.sptk.many b0 - .endp _PR_ia64_AtomicAdd# - -// PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval) -// -// Atomically set the integer pointed to by 'val' to the new -// value 'newval' and return the old value. -// - .align 16 - .global _PR_ia64_AtomicSet# - .proc _PR_ia64_AtomicSet# -_PR_ia64_AtomicSet: -#ifndef _LP64 - addp4 r32 = 0, r32 ;; -#endif - xchg4 r8 = [r32], r33 - br.ret.sptk.many b0 - .endp _PR_ia64_AtomicSet# diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_HPUX.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_HPUX.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_HPUX.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_HPUX.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -; -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifdef __LP64__ - .LEVEL 2.0W -#else - .LEVEL 1.1 -#endif - - .CODE ; equivalent to the following two lines -; .SPACE $TEXT$,SORT=8 -; .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24 - -ret_cr16 - .PROC - .CALLINFO FRAME=0, NO_CALLS - .EXPORT ret_cr16,ENTRY - .ENTRY - BV %r0(%rp) - .EXIT - MFCTL %cr16,%ret0 - .PROCEND - .END diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Irix.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Irix.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Irix.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Irix.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Atomically add a new element to the top of the stack - * - * usage : PR_StackPush(listp, elementp); - * ----------------------- - */ - -#include "md/_irix.h" -#ifdef _PR_HAVE_ATOMIC_CAS - -#include -#include - -LEAF(PR_StackPush) - -retry_push: -.set noreorder - lw v0,0(a0) - li t1,1 - beq v0,t1,retry_push - move t0,a1 - - ll v0,0(a0) - beq v0,t1,retry_push - nop - sc t1,0(a0) - beq t1,0,retry_push - nop - sw v0,0(a1) - sync - sw t0,0(a0) - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - jr ra - nop - -END(PR_StackPush) - -/* - * - * Atomically remove the element at the top of the stack - * - * usage : elemep = PR_StackPop(listp); - * - */ - -LEAF(PR_StackPop) -retry_pop: -.set noreorder - - - lw v0,0(a0) - li t1,1 - beq v0,0,done - nop - beq v0,t1,retry_pop - nop - - ll v0,0(a0) - beq v0,0,done - nop - beq v0,t1,retry_pop - nop - sc t1,0(a0) - beq t1,0,retry_pop - nop - lw t0,0(v0) - sw t0,0(a0) -done: - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - jr ra - nop - -END(PR_StackPop) - -#endif /* _PR_HAVE_ATOMIC_CAS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Linux_ia64.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Linux_ia64.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Linux_ia64.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Linux_ia64.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -.text - -// PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val) -// -// Atomically increment the integer pointed to by 'val' and return -// the result of the increment. -// - .align 16 - .global _PR_ia64_AtomicIncrement# - .proc _PR_ia64_AtomicIncrement# -_PR_ia64_AtomicIncrement: - fetchadd4.acq r8 = [r32], 1 ;; - adds r8 = 1, r8 - br.ret.sptk.many b0 - .endp _PR_ia64_AtomicIncrement# - -// PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val) -// -// Atomically decrement the integer pointed to by 'val' and return -// the result of the decrement. -// - .align 16 - .global _PR_ia64_AtomicDecrement# - .proc _PR_ia64_AtomicDecrement# -_PR_ia64_AtomicDecrement: - fetchadd4.rel r8 = [r32], -1 ;; - adds r8 = -1, r8 - br.ret.sptk.many b0 - .endp _PR_ia64_AtomicDecrement# - -// PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val) -// -// Atomically add 'val' to the integer pointed to by 'ptr' -// and return the result of the addition. -// - .align 16 - .global _PR_ia64_AtomicAdd# - .proc _PR_ia64_AtomicAdd# -_PR_ia64_AtomicAdd: - ld4 r15 = [r32] ;; -.L3: - mov r14 = r15 - mov ar.ccv = r15 - add r8 = r15, r33 ;; - cmpxchg4.acq r15 = [r32], r8, ar.ccv ;; - cmp4.ne p6, p7 = r15, r14 - (p6) br.cond.dptk .L3 - br.ret.sptk.many b0 - .endp _PR_ia64_AtomicAdd# - -// PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval) -// -// Atomically set the integer pointed to by 'val' to the new -// value 'newval' and return the old value. -// - .align 16 - .global _PR_ia64_AtomicSet# - .proc _PR_ia64_AtomicSet# -_PR_ia64_AtomicSet: - xchg4 r8 = [r32], r33 - br.ret.sptk.many b0 - .endp _PR_ia64_AtomicSet# - -// Magic indicating no need for an executable stack -.section .note.GNU-stack, "", @progbits ; .previous diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Linux_ppc.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Linux_ppc.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Linux_ppc.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Linux_ppc.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# -# Based on the programming examples in The PowerPC Architecture: -# A Specification for A New Family of RISC Processors, 2nd Ed., -# Book I, Section E.1, "Synchronization," pp. 249-256, May 1994. -# - - .section ".text" - -# -# PRInt32 _PR_ppc_AtomicIncrement(PRInt32 *val); -# - .align 2 - .globl _PR_ppc_AtomicIncrement - .type _PR_ppc_AtomicIncrement,@function -_PR_ppc_AtomicIncrement: -.Lfd1: lwarx 4,0,3 - addi 0,4,1 - stwcx. 0,0,3 - bne- .Lfd1 - mr 3,0 - blr -.Lfe1: .size _PR_ppc_AtomicIncrement,.Lfe1-_PR_ppc_AtomicIncrement - -# -# PRInt32 _PR_ppc_AtomicDecrement(PRInt32 *val); -# - .align 2 - .globl _PR_ppc_AtomicDecrement - .type _PR_ppc_AtomicDecrement,@function -_PR_ppc_AtomicDecrement: -.Lfd2: lwarx 4,0,3 - addi 0,4,-1 - stwcx. 0,0,3 - bne- .Lfd2 - mr 3,0 - blr -.Lfe2: .size _PR_ppc_AtomicDecrement,.Lfe2-_PR_ppc_AtomicDecrement - -# -# PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval); -# - .align 2 - .globl _PR_ppc_AtomicSet - .type _PR_ppc_AtomicSet,@function -_PR_ppc_AtomicSet: -.Lfd3: lwarx 5,0,3 - stwcx. 4,0,3 - bne- .Lfd3 - mr 3,5 - blr -.Lfe3: .size _PR_ppc_AtomicSet,.Lfe3-_PR_ppc_AtomicSet - -# -# PRInt32 _PR_ppc_AtomicAdd(PRInt32 *ptr, PRInt32 val); -# - .align 2 - .globl _PR_ppc_AtomicAdd - .type _PR_ppc_AtomicAdd,@function -_PR_ppc_AtomicAdd: -.Lfd4: lwarx 5,0,3 - add 0,4,5 - stwcx. 0,0,3 - bne- .Lfd4 - mr 3,0 - blr -.Lfe4: .size _PR_ppc_AtomicAdd,.Lfe4-_PR_ppc_AtomicAdd - -# Magic indicating no need for an executable stack -.section .note.GNU-stack, "", @progbits ; .previous diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86_64.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86_64.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86_64.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86_64.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val) -// -// Atomically increment the integer pointed to by 'val' and return -// the result of the increment. -// - .text - .globl _PR_x86_64_AtomicIncrement - .type _PR_x86_64_AtomicIncrement, @function - .align 4 -_PR_x86_64_AtomicIncrement: - movl $1, %eax - lock - xaddl %eax, (%rdi) - incl %eax - ret - .size _PR_x86_64_AtomicIncrement, .-_PR_x86_64_AtomicIncrement - -// PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val) -// -// Atomically decrement the integer pointed to by 'val' and return -// the result of the decrement. -// - .text - .globl _PR_x86_64_AtomicDecrement - .type _PR_x86_64_AtomicDecrement, @function - .align 4 -_PR_x86_64_AtomicDecrement: - movl $-1, %eax - lock - xaddl %eax, (%rdi) - decl %eax - ret - .size _PR_x86_64_AtomicDecrement, .-_PR_x86_64_AtomicDecrement - -// PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval) -// -// Atomically set the integer pointed to by 'val' to the new -// value 'newval' and return the old value. -// - .text - .globl _PR_x86_64_AtomicSet - .type _PR_x86_64_AtomicSet, @function - .align 4 -_PR_x86_64_AtomicSet: - movl %esi, %eax - xchgl %eax, (%rdi) - ret - .size _PR_x86_64_AtomicSet, .-_PR_x86_64_AtomicSet - -// PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val) -// -// Atomically add 'val' to the integer pointed to by 'ptr' -// and return the result of the addition. -// - .text - .globl _PR_x86_64_AtomicAdd - .type _PR_x86_64_AtomicAdd, @function - .align 4 -_PR_x86_64_AtomicAdd: - movl %esi, %eax - lock - xaddl %eax, (%rdi) - addl %esi, %eax - ret - .size _PR_x86_64_AtomicAdd, .-_PR_x86_64_AtomicAdd - -// Magic indicating no need for an executable stack -.section .note.GNU-stack, "", @progbits ; .previous diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s 2012-03-06 13:14:15.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val) -// -// Atomically increment the integer pointed to by 'val' and return -// the result of the increment. -// - .text - .globl _PR_x86_AtomicIncrement - .align 4 -_PR_x86_AtomicIncrement: - movl 4(%esp), %ecx - movl $1, %eax - lock - xaddl %eax, (%ecx) - incl %eax - ret - -// PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val) -// -// Atomically decrement the integer pointed to by 'val' and return -// the result of the decrement. -// - .text - .globl _PR_x86_AtomicDecrement - .align 4 -_PR_x86_AtomicDecrement: - movl 4(%esp), %ecx - movl $-1, %eax - lock - xaddl %eax, (%ecx) - decl %eax - ret - -// PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval) -// -// Atomically set the integer pointed to by 'val' to the new -// value 'newval' and return the old value. -// -// An alternative implementation: -// .text -// .globl _PR_x86_AtomicSet -// .align 4 -//_PR_x86_AtomicSet: -// movl 4(%esp), %ecx -// movl 8(%esp), %edx -// movl (%ecx), %eax -//retry: -// lock -// cmpxchgl %edx, (%ecx) -// jne retry -// ret -// - .text - .globl _PR_x86_AtomicSet - .align 4 -_PR_x86_AtomicSet: - movl 4(%esp), %ecx - movl 8(%esp), %eax - xchgl %eax, (%ecx) - ret - -// PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val) -// -// Atomically add 'val' to the integer pointed to by 'ptr' -// and return the result of the addition. -// - .text - .globl _PR_x86_AtomicAdd - .align 4 -_PR_x86_AtomicAdd: - movl 4(%esp), %ecx - movl 8(%esp), %eax - movl %eax, %edx - lock - xaddl %eax, (%ecx) - addl %edx, %eax - ret - -// Magic indicating no need for an executable stack -.section .note.GNU-stack, "", @progbits ; .previous diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -! -! This Source Code Form is subject to the terms of the Mozilla Public -! License, v. 2.0. If a copy of the MPL was not distributed with this -! file, You can obtain one at http://mozilla.org/MPL/2.0/. - -! -! atomic increment, decrement and swap routines for V8+ sparc (ultrasparc) -! using CAS (compare-and-swap) atomic instructions -! -! this MUST be compiled with an ultrasparc-aware assembler -! -! standard asm linkage macros; this module must be compiled -! with the -P option (use C preprocessor) - -#include - -! ====================================================================== -! -! Perform the sequence a = a + 1 atomically with respect to other -! fetch-and-adds to location a in a wait-free fashion. -! -! usage : val = PR_AtomicIncrement(address) -! return: current value (you'd think this would be old val) -! -! ----------------------- -! Note on REGISTER USAGE: -! as this is a LEAF procedure, a new stack frame is not created; -! we use the caller's stack frame so what would normally be %i (input) -! registers are actually %o (output registers). Also, we must not -! overwrite the contents of %l (local) registers as they are not -! assumed to be volatile during calls. -! -! So, the registers used are: -! %o0 [input] - the address of the value to increment -! %o1 [local] - work register -! %o2 [local] - work register -! %o3 [local] - work register -! ----------------------- - - ENTRY(_MD_AtomicIncrement) ! standard assembler/ELF prologue - -retryAI: - ld [%o0], %o2 ! set o2 to the current value - add %o2, 0x1, %o3 ! calc the new value - mov %o3, %o1 ! save the return value - cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed - cmp %o2, %o3 ! see if we set the value - bne retryAI ! if not, try again - nop ! empty out the branch pipeline - retl ! return back to the caller - mov %o1, %o0 ! set the return code to the new value - - SET_SIZE(_MD_AtomicIncrement) ! standard assembler/ELF epilogue - -! -! end -! -! ====================================================================== -! - -! ====================================================================== -! -! Perform the sequence a = a - 1 atomically with respect to other -! fetch-and-decs to location a in a wait-free fashion. -! -! usage : val = PR_AtomicDecrement(address) -! return: current value (you'd think this would be old val) -! -! ----------------------- -! Note on REGISTER USAGE: -! as this is a LEAF procedure, a new stack frame is not created; -! we use the caller's stack frame so what would normally be %i (input) -! registers are actually %o (output registers). Also, we must not -! overwrite the contents of %l (local) registers as they are not -! assumed to be volatile during calls. -! -! So, the registers used are: -! %o0 [input] - the address of the value to increment -! %o1 [local] - work register -! %o2 [local] - work register -! %o3 [local] - work register -! ----------------------- - - ENTRY(_MD_AtomicDecrement) ! standard assembler/ELF prologue - -retryAD: - ld [%o0], %o2 ! set o2 to the current value - sub %o2, 0x1, %o3 ! calc the new value - mov %o3, %o1 ! save the return value - cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed - cmp %o2, %o3 ! see if we set the value - bne retryAD ! if not, try again - nop ! empty out the branch pipeline - retl ! return back to the caller - mov %o1, %o0 ! set the return code to the new value - - SET_SIZE(_MD_AtomicDecrement) ! standard assembler/ELF epilogue - -! -! end -! -! ====================================================================== -! - -! ====================================================================== -! -! Perform the sequence a = b atomically with respect to other -! fetch-and-stores to location a in a wait-free fashion. -! -! usage : old_val = PR_AtomicSet(address, newval) -! -! ----------------------- -! Note on REGISTER USAGE: -! as this is a LEAF procedure, a new stack frame is not created; -! we use the caller's stack frame so what would normally be %i (input) -! registers are actually %o (output registers). Also, we must not -! overwrite the contents of %l (local) registers as they are not -! assumed to be volatile during calls. -! -! So, the registers used are: -! %o0 [input] - the address of the value to increment -! %o1 [input] - the new value to set for [%o0] -! %o2 [local] - work register -! %o3 [local] - work register -! ----------------------- - - ENTRY(_MD_AtomicSet) ! standard assembler/ELF prologue - -retryAS: - ld [%o0], %o2 ! set o2 to the current value - mov %o1, %o3 ! set up the new value - cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed - cmp %o2, %o3 ! see if we set the value - bne retryAS ! if not, try again - nop ! empty out the branch pipeline - retl ! return back to the caller - mov %o3, %o0 ! set the return code to the prev value - - SET_SIZE(_MD_AtomicSet) ! standard assembler/ELF epilogue - -! -! end -! -! ====================================================================== -! - -! ====================================================================== -! -! Perform the sequence a = a + b atomically with respect to other -! fetch-and-adds to location a in a wait-free fashion. -! -! usage : newval = PR_AtomicAdd(address, val) -! return: the value after addition -! - ENTRY(_MD_AtomicAdd) ! standard assembler/ELF prologue - -retryAA: - ld [%o0], %o2 ! set o2 to the current value - add %o2, %o1, %o3 ! calc the new value - mov %o3, %o4 ! save the return value - cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed - cmp %o2, %o3 ! see if we set the value - bne retryAA ! if not, try again - nop ! empty out the branch pipeline - retl ! return back to the caller - mov %o4, %o0 ! set the return code to the new value - - SET_SIZE(_MD_AtomicAdd) ! standard assembler/ELF epilogue - -! -! end -! diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -! -! This Source Code Form is subject to the terms of the Mozilla Public -! License, v. 2.0. If a copy of the MPL was not distributed with this -! file, You can obtain one at http://mozilla.org/MPL/2.0/. - -! -! atomic increment, decrement and swap routines for V8+ sparc (ultrasparc) -! using CAS (compare-and-swap) atomic instructions -! -! this MUST be compiled with an ultrasparc-aware assembler -! -! standard asm linkage macros; this module must be compiled -! with the -P option (use C preprocessor) - -#include - -! ====================================================================== -! -! Perform the sequence a = a + 1 atomically with respect to other -! fetch-and-adds to location a in a wait-free fashion. -! -! usage : val = PR_AtomicIncrement(address) -! return: current value (you'd think this would be old val) -! -! ----------------------- -! Note on REGISTER USAGE: -! as this is a LEAF procedure, a new stack frame is not created; -! we use the caller's stack frame so what would normally be %i (input) -! registers are actually %o (output registers). Also, we must not -! overwrite the contents of %l (local) registers as they are not -! assumed to be volatile during calls. -! -! So, the registers used are: -! %o0 [input] - the address of the value to increment -! %o1 [local] - work register -! %o2 [local] - work register -! %o3 [local] - work register -! ----------------------- - - ENTRY(PR_AtomicIncrement) ! standard assembler/ELF prologue - -retryAI: - ld [%o0], %o2 ! set o2 to the current value - add %o2, 0x1, %o3 ! calc the new value - mov %o3, %o1 ! save the return value - cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed - cmp %o2, %o3 ! see if we set the value - bne retryAI ! if not, try again - nop ! empty out the branch pipeline - retl ! return back to the caller - mov %o1, %o0 ! set the return code to the new value - - SET_SIZE(PR_AtomicIncrement) ! standard assembler/ELF epilogue - -! -! end -! -! ====================================================================== -! - -! ====================================================================== -! -! Perform the sequence a = a - 1 atomically with respect to other -! fetch-and-decs to location a in a wait-free fashion. -! -! usage : val = PR_AtomicDecrement(address) -! return: current value (you'd think this would be old val) -! -! ----------------------- -! Note on REGISTER USAGE: -! as this is a LEAF procedure, a new stack frame is not created; -! we use the caller's stack frame so what would normally be %i (input) -! registers are actually %o (output registers). Also, we must not -! overwrite the contents of %l (local) registers as they are not -! assumed to be volatile during calls. -! -! So, the registers used are: -! %o0 [input] - the address of the value to increment -! %o1 [local] - work register -! %o2 [local] - work register -! %o3 [local] - work register -! ----------------------- - - ENTRY(PR_AtomicDecrement) ! standard assembler/ELF prologue - -retryAD: - ld [%o0], %o2 ! set o2 to the current value - sub %o2, 0x1, %o3 ! calc the new value - mov %o3, %o1 ! save the return value - cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed - cmp %o2, %o3 ! see if we set the value - bne retryAD ! if not, try again - nop ! empty out the branch pipeline - retl ! return back to the caller - mov %o1, %o0 ! set the return code to the new value - - SET_SIZE(PR_AtomicDecrement) ! standard assembler/ELF epilogue - -! -! end -! -! ====================================================================== -! - -! ====================================================================== -! -! Perform the sequence a = b atomically with respect to other -! fetch-and-stores to location a in a wait-free fashion. -! -! usage : old_val = PR_AtomicSet(address, newval) -! -! ----------------------- -! Note on REGISTER USAGE: -! as this is a LEAF procedure, a new stack frame is not created; -! we use the caller's stack frame so what would normally be %i (input) -! registers are actually %o (output registers). Also, we must not -! overwrite the contents of %l (local) registers as they are not -! assumed to be volatile during calls. -! -! So, the registers used are: -! %o0 [input] - the address of the value to increment -! %o1 [input] - the new value to set for [%o0] -! %o2 [local] - work register -! %o3 [local] - work register -! ----------------------- - - ENTRY(PR_AtomicSet) ! standard assembler/ELF prologue - -retryAS: - ld [%o0], %o2 ! set o2 to the current value - mov %o1, %o3 ! set up the new value - cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed - cmp %o2, %o3 ! see if we set the value - bne retryAS ! if not, try again - nop ! empty out the branch pipeline - retl ! return back to the caller - mov %o3, %o0 ! set the return code to the prev value - - SET_SIZE(PR_AtomicSet) ! standard assembler/ELF epilogue - -! -! end -! -! ====================================================================== -! - -! ====================================================================== -! -! Perform the sequence a = a + b atomically with respect to other -! fetch-and-adds to location a in a wait-free fashion. -! -! usage : newval = PR_AtomicAdd(address, val) -! return: the value after addition -! - ENTRY(PR_AtomicAdd) ! standard assembler/ELF prologue - -retryAA: - ld [%o0], %o2 ! set o2 to the current value - add %o2, %o1, %o3 ! calc the new value - mov %o3, %o4 ! save the return value - cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed - cmp %o2, %o3 ! see if we set the value - bne retryAA ! if not, try again - nop ! empty out the branch pipeline - retl ! return back to the caller - mov %o4, %o0 ! set the return code to the new value - - SET_SIZE(PR_AtomicAdd) ! standard assembler/ELF epilogue - -! -! end -! diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// PRInt32 _MD_AtomicIncrement(PRInt32 *val) -// -// Atomically increment the integer pointed to by 'val' and return -// the result of the increment. -// - .text - .globl _MD_AtomicIncrement - .align 4 -_MD_AtomicIncrement: - movl $1, %eax - lock - xaddl %eax, (%rdi) - incl %eax - ret - -// PRInt32 _MD_AtomicDecrement(PRInt32 *val) -// -// Atomically decrement the integer pointed to by 'val' and return -// the result of the decrement. -// - .text - .globl _MD_AtomicDecrement - .align 4 -_MD_AtomicDecrement: - movl $-1, %eax - lock - xaddl %eax, (%rdi) - decl %eax - ret - -// PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval) -// -// Atomically set the integer pointed to by 'val' to the new -// value 'newval' and return the old value. -// - .text - .globl _MD_AtomicSet - .align 4 -_MD_AtomicSet: - movl %esi, %eax - xchgl %eax, (%rdi) - ret - -// PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val) -// -// Atomically add 'val' to the integer pointed to by 'ptr' -// and return the result of the addition. -// - .text - .globl _MD_AtomicAdd - .align 4 -_MD_AtomicAdd: - movl %esi, %eax - lock - xaddl %eax, (%rdi) - addl %esi, %eax - ret diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86.s nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86.s --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86.s 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/os_SunOS_x86.s 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - - .text - - .globl getedi -getedi: - movl %edi,%eax - ret - .type getedi,@function - .size getedi,.-getedi - - .globl setedi -setedi: - movl 4(%esp),%edi - ret - .type setedi,@function - .size setedi,.-setedi - - .globl __MD_FlushRegisterWindows - .globl _MD_FlushRegisterWindows - -__MD_FlushRegisterWindows: -_MD_FlushRegisterWindows: - - ret - -// -// sol_getsp() -// -// Return the current sp (for debugging) -// - .globl sol_getsp -sol_getsp: - movl %esp, %eax - ret - -// -// sol_curthread() -// -// Return a unique identifier for the currently active thread. -// - .globl sol_curthread -sol_curthread: - movl %ecx, %eax - ret - -// PRInt32 _MD_AtomicIncrement(PRInt32 *val) -// -// Atomically increment the integer pointed to by 'val' and return -// the result of the increment. -// - .text - .globl _MD_AtomicIncrement - .align 4 -_MD_AtomicIncrement: - movl 4(%esp), %ecx - movl $1, %eax - lock - xaddl %eax, (%ecx) - incl %eax - ret - -// PRInt32 _MD_AtomicDecrement(PRInt32 *val) -// -// Atomically decrement the integer pointed to by 'val' and return -// the result of the decrement. -// - .text - .globl _MD_AtomicDecrement - .align 4 -_MD_AtomicDecrement: - movl 4(%esp), %ecx - movl $-1, %eax - lock - xaddl %eax, (%ecx) - decl %eax - ret - -// PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval) -// -// Atomically set the integer pointed to by 'val' to the new -// value 'newval' and return the old value. -// -// An alternative implementation: -// .text -// .globl _MD_AtomicSet -// .align 4 -//_MD_AtomicSet: -// movl 4(%esp), %ecx -// movl 8(%esp), %edx -// movl (%ecx), %eax -//retry: -// lock -// cmpxchgl %edx, (%ecx) -// jne retry -// ret -// - .text - .globl _MD_AtomicSet - .align 4 -_MD_AtomicSet: - movl 4(%esp), %ecx - movl 8(%esp), %eax - xchgl %eax, (%ecx) - ret - -// PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val) -// -// Atomically add 'val' to the integer pointed to by 'ptr' -// and return the result of the addition. -// - .text - .globl _MD_AtomicAdd - .align 4 -_MD_AtomicAdd: - movl 4(%esp), %ecx - movl 8(%esp), %eax - movl %eax, %edx - lock - xaddl %eax, (%ecx) - addl %edx, %eax - ret diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/pthreads_user.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/pthreads_user.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/pthreads_user.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/pthreads_user.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,448 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include -#include -#include -#include - - -sigset_t ints_off; -pthread_mutex_t _pr_heapLock; -pthread_key_t current_thread_key; -pthread_key_t current_cpu_key; -pthread_key_t last_thread_key; -pthread_key_t intsoff_key; - - -PRInt32 _pr_md_pthreads_created, _pr_md_pthreads_failed; -PRInt32 _pr_md_pthreads = 1; - -void _MD_EarlyInit(void) -{ -extern PRInt32 _nspr_noclock; - - if (pthread_key_create(¤t_thread_key, NULL) != 0) { - perror("pthread_key_create failed"); - exit(1); - } - if (pthread_key_create(¤t_cpu_key, NULL) != 0) { - perror("pthread_key_create failed"); - exit(1); - } - if (pthread_key_create(&last_thread_key, NULL) != 0) { - perror("pthread_key_create failed"); - exit(1); - } - if (pthread_key_create(&intsoff_key, NULL) != 0) { - perror("pthread_key_create failed"); - exit(1); - } - - sigemptyset(&ints_off); - sigaddset(&ints_off, SIGALRM); - sigaddset(&ints_off, SIGIO); - sigaddset(&ints_off, SIGCLD); - - /* - * disable clock interrupts - */ - _nspr_noclock = 1; - -} - -void _MD_InitLocks() -{ - if (pthread_mutex_init(&_pr_heapLock, NULL) != 0) { - perror("pthread_mutex_init failed"); - exit(1); - } -} - -PR_IMPLEMENT(void) _MD_FREE_LOCK(struct _MDLock *lockp) -{ - PRIntn _is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(_is); - pthread_mutex_destroy(&lockp->mutex); - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(_is); -} - - - -PR_IMPLEMENT(PRStatus) _MD_NEW_LOCK(struct _MDLock *lockp) -{ - PRStatus rv; - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - rv = pthread_mutex_init(&lockp->mutex, NULL); - if (me && !_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return (rv == 0) ? PR_SUCCESS : PR_FAILURE; -} - - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -} - -PR_IMPLEMENT(void) -_MD_SetPriority(_MDThread *thread, PRThreadPriority newPri) -{ - /* - * XXX - to be implemented - */ - return; -} - -PR_IMPLEMENT(PRStatus) _MD_InitThread(struct PRThread *thread) -{ - struct sigaction sigact; - - if (thread->flags & _PR_GLOBAL_SCOPE) { - thread->md.pthread = pthread_self(); -#if 0 - /* - * set up SIGUSR1 handler; this is used to save state - * during PR_SuspendAll - */ - sigact.sa_handler = save_context_and_block; - sigact.sa_flags = SA_RESTART; - /* - * Must mask clock interrupts - */ - sigact.sa_mask = timer_set; - sigaction(SIGUSR1, &sigact, 0); -#endif - } - - return PR_SUCCESS; -} - -PR_IMPLEMENT(void) _MD_ExitThread(struct PRThread *thread) -{ - if (thread->flags & _PR_GLOBAL_SCOPE) { - _MD_CLEAN_THREAD(thread); - _MD_SET_CURRENT_THREAD(NULL); - } -} - -PR_IMPLEMENT(void) _MD_CleanThread(struct PRThread *thread) -{ - if (thread->flags & _PR_GLOBAL_SCOPE) { - pthread_mutex_destroy(&thread->md.pthread_mutex); - pthread_cond_destroy(&thread->md.pthread_cond); - } -} - -PR_IMPLEMENT(void) _MD_SuspendThread(struct PRThread *thread) -{ - PRInt32 rv; - - PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) && - _PR_IS_GCABLE_THREAD(thread)); -#if 0 - thread->md.suspending_id = getpid(); - rv = kill(thread->md.id, SIGUSR1); - PR_ASSERT(rv == 0); - /* - * now, block the current thread/cpu until woken up by the suspended - * thread from it's SIGUSR1 signal handler - */ - blockproc(getpid()); -#endif -} - -PR_IMPLEMENT(void) _MD_ResumeThread(struct PRThread *thread) -{ - PRInt32 rv; - - PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) && - _PR_IS_GCABLE_THREAD(thread)); -#if 0 - rv = unblockproc(thread->md.id); -#endif -} - -PR_IMPLEMENT(void) _MD_SuspendCPU(struct _PRCPU *thread) -{ - PRInt32 rv; - -#if 0 - cpu->md.suspending_id = getpid(); - rv = kill(cpu->md.id, SIGUSR1); - PR_ASSERT(rv == 0); - /* - * now, block the current thread/cpu until woken up by the suspended - * thread from it's SIGUSR1 signal handler - */ - blockproc(getpid()); -#endif -} - -PR_IMPLEMENT(void) _MD_ResumeCPU(struct _PRCPU *thread) -{ -#if 0 - unblockproc(cpu->md.id); -#endif -} - - -#define PT_NANOPERMICRO 1000UL -#define PT_BILLION 1000000000UL - -PR_IMPLEMENT(PRStatus) -_pt_wait(PRThread *thread, PRIntervalTime timeout) -{ -int rv; -struct timeval now; -struct timespec tmo; -PRUint32 ticks = PR_TicksPerSecond(); - - - if (timeout != PR_INTERVAL_NO_TIMEOUT) { - tmo.tv_sec = timeout / ticks; - tmo.tv_nsec = timeout - (tmo.tv_sec * ticks); - tmo.tv_nsec = PR_IntervalToMicroseconds(PT_NANOPERMICRO * - tmo.tv_nsec); - - /* pthreads wants this in absolute time, off we go ... */ - (void)GETTIMEOFDAY(&now); - /* that one's usecs, this one's nsecs - grrrr! */ - tmo.tv_sec += now.tv_sec; - tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec); - tmo.tv_sec += tmo.tv_nsec / PT_BILLION; - tmo.tv_nsec %= PT_BILLION; - } - - pthread_mutex_lock(&thread->md.pthread_mutex); - thread->md.wait--; - if (thread->md.wait < 0) { - if (timeout != PR_INTERVAL_NO_TIMEOUT) { - rv = pthread_cond_timedwait(&thread->md.pthread_cond, - &thread->md.pthread_mutex, &tmo); - } - else - rv = pthread_cond_wait(&thread->md.pthread_cond, - &thread->md.pthread_mutex); - if (rv != 0) { - thread->md.wait++; - } - } else - rv = 0; - pthread_mutex_unlock(&thread->md.pthread_mutex); - - return (rv == 0) ? PR_SUCCESS : PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) -_MD_wait(PRThread *thread, PRIntervalTime ticks) -{ - if ( thread->flags & _PR_GLOBAL_SCOPE ) { - _MD_CHECK_FOR_EXIT(); - if (_pt_wait(thread, ticks) == PR_FAILURE) { - _MD_CHECK_FOR_EXIT(); - /* - * wait timed out - */ - _PR_THREAD_LOCK(thread); - if (thread->wait.cvar) { - /* - * The thread will remove itself from the waitQ - * of the cvar in _PR_WaitCondVar - */ - thread->wait.cvar = NULL; - thread->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(thread); - } else { - _pt_wait(thread, PR_INTERVAL_NO_TIMEOUT); - _PR_THREAD_UNLOCK(thread); - } - } - } else { - _PR_MD_SWITCH_CONTEXT(thread); - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) -_MD_WakeupWaiter(PRThread *thread) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 pid, rv; - PRIntn is; - - PR_ASSERT(_pr_md_idle_cpus >= 0); - if (thread == NULL) { - if (_pr_md_idle_cpus) - _MD_Wakeup_CPUs(); - } else if (!_PR_IS_NATIVE_THREAD(thread)) { - /* - * If the thread is on my cpu's runq there is no need to - * wakeup any cpus - */ - if (!_PR_IS_NATIVE_THREAD(me)) { - if (me->cpu != thread->cpu) { - if (_pr_md_idle_cpus) - _MD_Wakeup_CPUs(); - } - } else { - if (_pr_md_idle_cpus) - _MD_Wakeup_CPUs(); - } - } else { - PR_ASSERT(_PR_IS_NATIVE_THREAD(thread)); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - - pthread_mutex_lock(&thread->md.pthread_mutex); - thread->md.wait++; - rv = pthread_cond_signal(&thread->md.pthread_cond); - PR_ASSERT(rv == 0); - pthread_mutex_unlock(&thread->md.pthread_mutex); - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - } - return PR_SUCCESS; -} - -/* These functions should not be called for AIX */ -PR_IMPLEMENT(void) -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for AIX."); -} - -PR_IMPLEMENT(PRStatus) -_MD_CreateThread( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PRIntn is; - int rv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - pthread_attr_t attr; - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - - if (pthread_mutex_init(&thread->md.pthread_mutex, NULL) != 0) { - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return PR_FAILURE; - } - - if (pthread_cond_init(&thread->md.pthread_cond, NULL) != 0) { - pthread_mutex_destroy(&thread->md.pthread_mutex); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return PR_FAILURE; - } - thread->flags |= _PR_GLOBAL_SCOPE; - - pthread_attr_init(&attr); /* initialize attr with default attributes */ - if (pthread_attr_setstacksize(&attr, (size_t) stackSize) != 0) { - pthread_mutex_destroy(&thread->md.pthread_mutex); - pthread_cond_destroy(&thread->md.pthread_cond); - pthread_attr_destroy(&attr); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return PR_FAILURE; - } - - thread->md.wait = 0; - rv = pthread_create(&thread->md.pthread, &attr, start, (void *)thread); - if (0 == rv) { - _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_created); - _MD_ATOMIC_INCREMENT(&_pr_md_pthreads); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return PR_SUCCESS; - } else { - pthread_mutex_destroy(&thread->md.pthread_mutex); - pthread_cond_destroy(&thread->md.pthread_cond); - pthread_attr_destroy(&attr); - _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_failed); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, rv); - return PR_FAILURE; - } -} - -PR_IMPLEMENT(void) -_MD_InitRunningCPU(struct _PRCPU *cpu) -{ - extern int _pr_md_pipefd[2]; - - _MD_unix_init_running_cpu(cpu); - cpu->md.pthread = pthread_self(); - if (_pr_md_pipefd[0] >= 0) { - _PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0]; -#ifndef _PR_USE_POLL - FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu)); -#endif - } -} - - -void -_MD_CleanupBeforeExit(void) -{ -#if 0 - extern PRInt32 _pr_cpus_exit; - - _pr_irix_exit_now = 1; - if (_pr_numCPU > 1) { - /* - * Set a global flag, and wakeup all cpus which will notice the flag - * and exit. - */ - _pr_cpus_exit = getpid(); - _MD_Wakeup_CPUs(); - while(_pr_numCPU > 1) { - _PR_WAIT_SEM(_pr_irix_exit_sem); - _pr_numCPU--; - } - } - /* - * cause global threads on the recycle list to exit - */ - _PR_DEADQ_LOCK; - if (_PR_NUM_DEADNATIVE != 0) { - PRThread *thread; - PRCList *ptr; - - ptr = _PR_DEADNATIVEQ.next; - while( ptr != &_PR_DEADNATIVEQ ) { - thread = _PR_THREAD_PTR(ptr); - _MD_CVAR_POST_SEM(thread); - ptr = ptr->next; - } - } - _PR_DEADQ_UNLOCK; - while(_PR_NUM_DEADNATIVE > 1) { - _PR_WAIT_SEM(_pr_irix_exit_sem); - _PR_DEC_DEADNATIVE; - } -#endif -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/qnx.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/qnx.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/qnx.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/qnx.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -} - -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for Unixware */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for Unixware."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRUintn priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware."); - return PR_FAILURE; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/riscos.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/riscos.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/riscos.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/riscos.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#ifndef _PR_PTHREADS - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -#else - *np = 0; - return NULL; -#endif -} - -#ifdef _PR_PTHREADS - -void _MD_CleanupBeforeExit(void) -{ -} - -#else /* ! _PR_PTHREADS */ - -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - /* - * set the pointers to the stack-pointer and frame-pointer words in the - * context structure; this is for debugging use. - */ - thread->md.sp = _MD_GET_SP_PTR(thread); - thread->md.fp = _MD_GET_FP_PTR(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for RISC OS */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for RISC OS."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for RISC OS."); - return PR_FAILURE; -} -#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/scoos.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/scoos.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/scoos.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/scoos.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,149 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * SCO ODT 5.0 - originally created by mikep - */ -#include "primpl.h" - -#include - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -} - -#ifdef ALARMS_BREAK_TCP /* I don't think they do */ - -PRInt32 _MD_connect(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen, - PRIntervalTime timeout) -{ - PRInt32 rv; - - _MD_BLOCK_CLOCK_INTERRUPTS(); - rv = _connect(osfd,addr,addrlen); - _MD_UNBLOCK_CLOCK_INTERRUPTS(); -} - -PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen, - PRIntervalTime timeout) -{ - PRInt32 rv; - - _MD_BLOCK_CLOCK_INTERRUPTS(); - rv = _accept(osfd,addr,addrlen); - _MD_UNBLOCK_CLOCK_INTERRUPTS(); - return(rv); -} -#endif - -/* - * These are also implemented in pratom.c using NSPR locks. Any reason - * this might be better or worse? If you like this better, define - * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h - */ -#ifdef _PR_HAVE_ATOMIC_OPS -/* Atomic operations */ -#include -static FILE *_uw_semf; - -void -_MD_INIT_ATOMIC(void) -{ - /* Sigh. Sure wish SYSV semaphores weren't such a pain to use */ - if ((_uw_semf = tmpfile()) == NULL) - PR_ASSERT(0); - - return; -} - -void -_MD_ATOMIC_INCREMENT(PRInt32 *val) -{ - flockfile(_uw_semf); - (*val)++; - unflockfile(_uw_semf); -} - -void -_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) -{ - flockfile(_uw_semf); - (*ptr) += val; - unflockfile(_uw_semf); -} - -void -_MD_ATOMIC_DECREMENT(PRInt32 *val) -{ - flockfile(_uw_semf); - (*val)--; - unflockfile(_uw_semf); -} - -void -_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) -{ - flockfile(_uw_semf); - *val = newval; - unflockfile(_uw_semf); -} -#endif - -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for SCO */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for SCO."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SCO."); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/solaris.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/solaris.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/solaris.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/solaris.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - - -extern PRBool suspendAllOn; -extern PRThread *suspendAllThread; - -extern void _MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri); - -PRIntervalTime _MD_Solaris_TicksPerSecond(void) -{ - /* - * Ticks have a 10-microsecond resolution. So there are - * 100000 ticks per second. - */ - return 100000UL; -} - -/* Interval timers, implemented using gethrtime() */ - -PRIntervalTime _MD_Solaris_GetInterval(void) -{ - union { - hrtime_t hrt; /* hrtime_t is a 64-bit (long long) integer */ - PRInt64 pr64; - } time; - PRInt64 resolution; - PRIntervalTime ticks; - - time.hrt = gethrtime(); /* in nanoseconds */ - /* - * Convert from nanoseconds to ticks. A tick's resolution is - * 10 microseconds, or 10000 nanoseconds. - */ - LL_I2L(resolution, 10000); - LL_DIV(time.pr64, time.pr64, resolution); - LL_L2UI(ticks, time.pr64); - return ticks; -} - -#ifdef _PR_PTHREADS -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np) -{ - *np = 0; - return NULL; -} -#endif /* _PR_PTHREADS */ - -#if defined(_PR_LOCAL_THREADS_ONLY) - -void _MD_EarlyInit(void) -{ -} - -void _MD_SolarisInit() -{ - _PR_UnixInit(); -} - -void -_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - PR_ASSERT((thread == NULL) || (!(thread->flags & _PR_GLOBAL_SCOPE))); - return PR_SUCCESS; -} - -/* These functions should not be called for Solaris */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for Solaris"); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Solaris"); - return(PR_FAILURE); -} - -#ifdef USE_SETJMP -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -} -#else -PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np) -{ - if (isCurrent) { - (void) getcontext(CONTEXT(t)); - } - *np = NGREG; - return (PRWord*) &t->md.context.uc_mcontext.gregs[0]; -} -#endif /* USE_SETJMP */ - -#endif /* _PR_LOCAL_THREADS_ONLY */ - -#ifndef _PR_PTHREADS -#if defined(i386) && defined(SOLARIS2_4) -/* - * Because clock_gettime() on Solaris/x86 2.4 always generates a - * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(), - * which is implemented using gettimeofday(). - */ - -int -_pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp) -{ - struct timeval tv; - - if (clock_id != CLOCK_REALTIME) { - errno = EINVAL; - return -1; - } - - gettimeofday(&tv, NULL); - tp->tv_sec = tv.tv_sec; - tp->tv_nsec = tv.tv_usec * 1000; - return 0; -} -#endif /* i386 && SOLARIS2_4 */ -#endif /* _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/symbian.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/symbian.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/symbian.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/symbian.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - *np = 0; - return NULL; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/unix.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/unix.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/unix.c 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/unix.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,3774 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _PR_POLL_AVAILABLE -#include -#endif - -/* To get FIONREAD */ -#if defined(UNIXWARE) -#include -#endif - -#if defined(NTO) -#include -#endif - -/* - * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or - * PRInt32* pointer to a _PRSockLen_t* pointer. - */ -#if defined(HAVE_SOCKLEN_T) \ - || (defined(__GLIBC__) && __GLIBC__ >= 2) -#define _PRSockLen_t socklen_t -#elif defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \ - || defined(AIX4_1) || defined(LINUX) \ - || defined(BSDI) || defined(SCO) \ - || defined(DARWIN) \ - || defined(QNX) -#define _PRSockLen_t int -#elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \ - || defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \ - || defined(DGUX) || defined(NTO) || defined(RISCOS) -#define _PRSockLen_t size_t -#else -#error "Cannot determine architecture" -#endif - -/* -** Global lock variable used to bracket calls into rusty libraries that -** aren't thread safe (like libc, libX, etc). -*/ -static PRLock *_pr_rename_lock = NULL; -static PRMonitor *_pr_Xfe_mon = NULL; - -static PRInt64 minus_one; - -sigset_t timer_set; - -#if !defined(_PR_PTHREADS) - -static sigset_t empty_set; - -#ifdef SOLARIS -#include -#include -#endif - -#ifndef PIPE_BUF -#define PIPE_BUF 512 -#endif - -/* - * _nspr_noclock - if set clock interrupts are disabled - */ -int _nspr_noclock = 1; - -#ifdef IRIX -extern PRInt32 _nspr_terminate_on_error; -#endif - -/* - * There is an assertion in this code that NSPR's definition of PRIOVec - * is bit compatible with UNIX' definition of a struct iovec. This is - * applicable to the 'writev()' operations where the types are casually - * cast to avoid warnings. - */ - -int _pr_md_pipefd[2] = { -1, -1 }; -static char _pr_md_pipebuf[PIPE_BUF]; -static PRInt32 local_io_wait(PRInt32 osfd, PRInt32 wait_flag, - PRIntervalTime timeout); - -_PRInterruptTable _pr_interruptTable[] = { - { - "clock", _PR_MISSED_CLOCK, _PR_ClockInterrupt, }, - { - 0 } -}; - -void _MD_unix_init_running_cpu(_PRCPU *cpu) -{ - PR_INIT_CLIST(&(cpu->md.md_unix.ioQ)); - cpu->md.md_unix.ioq_max_osfd = -1; - cpu->md.md_unix.ioq_timeout = PR_INTERVAL_NO_TIMEOUT; -} - -PRStatus _MD_open_dir(_MDDir *d, const char *name) -{ -int err; - - d->d = opendir(name); - if (!d->d) { - err = _MD_ERRNO(); - _PR_MD_MAP_OPENDIR_ERROR(err); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PRInt32 _MD_close_dir(_MDDir *d) -{ -int rv = 0, err; - - if (d->d) { - rv = closedir(d->d); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_CLOSEDIR_ERROR(err); - } - } - return rv; -} - -char * _MD_read_dir(_MDDir *d, PRIntn flags) -{ -struct dirent *de; -int err; - - for (;;) { - /* - * XXX: readdir() is not MT-safe. There is an MT-safe version - * readdir_r() on some systems. - */ - _MD_ERRNO() = 0; - de = readdir(d->d); - if (!de) { - err = _MD_ERRNO(); - _PR_MD_MAP_READDIR_ERROR(err); - return 0; - } - if ((flags & PR_SKIP_DOT) && - (de->d_name[0] == '.') && (de->d_name[1] == 0)) - continue; - if ((flags & PR_SKIP_DOT_DOT) && - (de->d_name[0] == '.') && (de->d_name[1] == '.') && - (de->d_name[2] == 0)) - continue; - if ((flags & PR_SKIP_HIDDEN) && (de->d_name[0] == '.')) - continue; - break; - } - return de->d_name; -} - -PRInt32 _MD_delete(const char *name) -{ -PRInt32 rv, err; -#ifdef UNIXWARE - sigset_t set, oset; -#endif - -#ifdef UNIXWARE - sigfillset(&set); - sigprocmask(SIG_SETMASK, &set, &oset); -#endif - rv = unlink(name); -#ifdef UNIXWARE - sigprocmask(SIG_SETMASK, &oset, NULL); -#endif - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_UNLINK_ERROR(err); - } - return(rv); -} - -PRInt32 _MD_rename(const char *from, const char *to) -{ - PRInt32 rv = -1, err; - - /* - ** This is trying to enforce the semantics of WINDOZE' rename - ** operation. That means one is not allowed to rename over top - ** of an existing file. Holding a lock across these two function - ** and the open function is known to be a bad idea, but .... - */ - if (NULL != _pr_rename_lock) - PR_Lock(_pr_rename_lock); - if (0 == access(to, F_OK)) - PR_SetError(PR_FILE_EXISTS_ERROR, 0); - else - { - rv = rename(from, to); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_RENAME_ERROR(err); - } - } - if (NULL != _pr_rename_lock) - PR_Unlock(_pr_rename_lock); - return rv; -} - -PRInt32 _MD_access(const char *name, PRAccessHow how) -{ -PRInt32 rv, err; -int amode; - - switch (how) { - case PR_ACCESS_WRITE_OK: - amode = W_OK; - break; - case PR_ACCESS_READ_OK: - amode = R_OK; - break; - case PR_ACCESS_EXISTS: - amode = F_OK; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = -1; - goto done; - } - rv = access(name, amode); - - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_ACCESS_ERROR(err); - } - -done: - return(rv); -} - -PRInt32 _MD_mkdir(const char *name, PRIntn mode) -{ -int rv, err; - - /* - ** This lock is used to enforce rename semantics as described - ** in PR_Rename. Look there for more fun details. - */ - if (NULL !=_pr_rename_lock) - PR_Lock(_pr_rename_lock); - rv = mkdir(name, mode); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_MKDIR_ERROR(err); - } - if (NULL !=_pr_rename_lock) - PR_Unlock(_pr_rename_lock); - return rv; -} - -PRInt32 _MD_rmdir(const char *name) -{ -int rv, err; - - rv = rmdir(name); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_RMDIR_ERROR(err); - } - return rv; -} - -PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount) -{ -PRThread *me = _PR_MD_CURRENT_THREAD(); -PRInt32 rv, err; -#ifndef _PR_USE_POLL -fd_set rd; -#else -struct pollfd pfd; -#endif /* _PR_USE_POLL */ -PRInt32 osfd = fd->secret->md.osfd; - -#ifndef _PR_USE_POLL - FD_ZERO(&rd); - FD_SET(osfd, &rd); -#else - pfd.fd = osfd; - pfd.events = POLLIN; -#endif /* _PR_USE_POLL */ - while ((rv = read(osfd,buf,amount)) == -1) { - err = _MD_ERRNO(); - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) { - if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, - PR_INTERVAL_NO_TIMEOUT)) < 0) - goto done; - } else { -#ifndef _PR_USE_POLL - while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL)) - == -1 && (err = _MD_ERRNO()) == EINTR) { - /* retry _MD_SELECT() if it is interrupted */ - } -#else /* _PR_USE_POLL */ - while ((rv = _MD_POLL(&pfd, 1, -1)) - == -1 && (err = _MD_ERRNO()) == EINTR) { - /* retry _MD_POLL() if it is interrupted */ - } -#endif /* _PR_USE_POLL */ - if (rv == -1) { - break; - } - } - if (_PR_PENDING_INTERRUPT(me)) - break; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - _PR_MD_MAP_READ_ERROR(err); - } - } -done: - return(rv); -} - -PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount) -{ -PRThread *me = _PR_MD_CURRENT_THREAD(); -PRInt32 rv, err; -#ifndef _PR_USE_POLL -fd_set wd; -#else -struct pollfd pfd; -#endif /* _PR_USE_POLL */ -PRInt32 osfd = fd->secret->md.osfd; - -#ifndef _PR_USE_POLL - FD_ZERO(&wd); - FD_SET(osfd, &wd); -#else - pfd.fd = osfd; - pfd.events = POLLOUT; -#endif /* _PR_USE_POLL */ - while ((rv = write(osfd,buf,amount)) == -1) { - err = _MD_ERRNO(); - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) { - if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, - PR_INTERVAL_NO_TIMEOUT)) < 0) - goto done; - } else { -#ifndef _PR_USE_POLL - while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL)) - == -1 && (err = _MD_ERRNO()) == EINTR) { - /* retry _MD_SELECT() if it is interrupted */ - } -#else /* _PR_USE_POLL */ - while ((rv = _MD_POLL(&pfd, 1, -1)) - == -1 && (err = _MD_ERRNO()) == EINTR) { - /* retry _MD_POLL() if it is interrupted */ - } -#endif /* _PR_USE_POLL */ - if (rv == -1) { - break; - } - } - if (_PR_PENDING_INTERRUPT(me)) - break; - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - _PR_MD_MAP_WRITE_ERROR(err); - } - } -done: - return(rv); -} - -PRInt32 _MD_fsync(PRFileDesc *fd) -{ -PRInt32 rv, err; - - rv = fsync(fd->secret->md.osfd); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_FSYNC_ERROR(err); - } - return(rv); -} - -PRInt32 _MD_close(PRInt32 osfd) -{ -PRInt32 rv, err; - - rv = close(osfd); - if (rv == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_CLOSE_ERROR(err); - } - return(rv); -} - -PRInt32 _MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto) -{ - PRInt32 osfd, err; - - osfd = socket(domain, type, proto); - - if (osfd == -1) { - err = _MD_ERRNO(); - _PR_MD_MAP_SOCKET_ERROR(err); - return(osfd); - } - - return(osfd); -} - -PRInt32 _MD_socketavailable(PRFileDesc *fd) -{ - PRInt32 result; - - if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) { - _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO()); - return -1; - } - return result; -} - -PRInt64 _MD_socketavailable64(PRFileDesc *fd) -{ - PRInt64 result; - LL_I2L(result, _MD_socketavailable(fd)); - return result; -} /* _MD_socketavailable64 */ - -#define READ_FD 1 -#define WRITE_FD 2 - -/* - * socket_io_wait -- - * - * wait for socket i/o, periodically checking for interrupt - * - * The first implementation uses select(), for platforms without - * poll(). The second (preferred) implementation uses poll(). - */ - -#ifndef _PR_USE_POLL - -static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type, - PRIntervalTime timeout) -{ - PRInt32 rv = -1; - struct timeval tv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRIntervalTime epoch, now, elapsed, remaining; - PRBool wait_for_remaining; - PRInt32 syserror; - fd_set rd_wr; - - switch (timeout) { - case PR_INTERVAL_NO_WAIT: - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - break; - case PR_INTERVAL_NO_TIMEOUT: - /* - * This is a special case of the 'default' case below. - * Please see the comments there. - */ - tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; - tv.tv_usec = 0; - FD_ZERO(&rd_wr); - do { - FD_SET(osfd, &rd_wr); - if (fd_type == READ_FD) - rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv); - else - rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv); - if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { - _PR_MD_MAP_SELECT_ERROR(syserror); - break; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - } while (rv == 0 || (rv == -1 && syserror == EINTR)); - break; - default: - now = epoch = PR_IntervalNow(); - remaining = timeout; - FD_ZERO(&rd_wr); - do { - /* - * We block in _MD_SELECT for at most - * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, - * so that there is an upper limit on the delay - * before the interrupt bit is checked. - */ - wait_for_remaining = PR_TRUE; - tv.tv_sec = PR_IntervalToSeconds(remaining); - if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { - wait_for_remaining = PR_FALSE; - tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; - tv.tv_usec = 0; - } else { - tv.tv_usec = PR_IntervalToMicroseconds( - remaining - - PR_SecondsToInterval(tv.tv_sec)); - } - FD_SET(osfd, &rd_wr); - if (fd_type == READ_FD) - rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv); - else - rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv); - /* - * we don't consider EINTR a real error - */ - if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { - _PR_MD_MAP_SELECT_ERROR(syserror); - break; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - /* - * We loop again if _MD_SELECT timed out or got interrupted - * by a signal, and the timeout deadline has not passed yet. - */ - if (rv == 0 || (rv == -1 && syserror == EINTR)) { - /* - * If _MD_SELECT timed out, we know how much time - * we spent in blocking, so we can avoid a - * PR_IntervalNow() call. - */ - if (rv == 0) { - if (wait_for_remaining) { - now += remaining; - } else { - now += PR_SecondsToInterval(tv.tv_sec) - + PR_MicrosecondsToInterval(tv.tv_usec); - } - } else { - now = PR_IntervalNow(); - } - elapsed = (PRIntervalTime) (now - epoch); - if (elapsed >= timeout) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - rv = -1; - break; - } else { - remaining = timeout - elapsed; - } - } - } while (rv == 0 || (rv == -1 && syserror == EINTR)); - break; - } - return(rv); -} - -#else /* _PR_USE_POLL */ - -static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type, - PRIntervalTime timeout) -{ - PRInt32 rv = -1; - int msecs; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRIntervalTime epoch, now, elapsed, remaining; - PRBool wait_for_remaining; - PRInt32 syserror; - struct pollfd pfd; - - switch (timeout) { - case PR_INTERVAL_NO_WAIT: - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - break; - case PR_INTERVAL_NO_TIMEOUT: - /* - * This is a special case of the 'default' case below. - * Please see the comments there. - */ - msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; - pfd.fd = osfd; - if (fd_type == READ_FD) { - pfd.events = POLLIN; - } else { - pfd.events = POLLOUT; - } - do { - rv = _MD_POLL(&pfd, 1, msecs); - if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { - _PR_MD_MAP_POLL_ERROR(syserror); - break; - } - /* - * If POLLERR is set, don't process it; retry the operation - */ - if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) { - rv = -1; - _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents); - break; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - } while (rv == 0 || (rv == -1 && syserror == EINTR)); - break; - default: - now = epoch = PR_IntervalNow(); - remaining = timeout; - pfd.fd = osfd; - if (fd_type == READ_FD) { - pfd.events = POLLIN; - } else { - pfd.events = POLLOUT; - } - do { - /* - * We block in _MD_POLL for at most - * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, - * so that there is an upper limit on the delay - * before the interrupt bit is checked. - */ - wait_for_remaining = PR_TRUE; - msecs = PR_IntervalToMilliseconds(remaining); - if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) { - wait_for_remaining = PR_FALSE; - msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; - } - rv = _MD_POLL(&pfd, 1, msecs); - /* - * we don't consider EINTR a real error - */ - if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { - _PR_MD_MAP_POLL_ERROR(syserror); - break; - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - /* - * If POLLERR is set, don't process it; retry the operation - */ - if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) { - rv = -1; - _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents); - break; - } - /* - * We loop again if _MD_POLL timed out or got interrupted - * by a signal, and the timeout deadline has not passed yet. - */ - if (rv == 0 || (rv == -1 && syserror == EINTR)) { - /* - * If _MD_POLL timed out, we know how much time - * we spent in blocking, so we can avoid a - * PR_IntervalNow() call. - */ - if (rv == 0) { - if (wait_for_remaining) { - now += remaining; - } else { - now += PR_MillisecondsToInterval(msecs); - } - } else { - now = PR_IntervalNow(); - } - elapsed = (PRIntervalTime) (now - epoch); - if (elapsed >= timeout) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - rv = -1; - break; - } else { - remaining = timeout - elapsed; - } - } - } while (rv == 0 || (rv == -1 && syserror == EINTR)); - break; - } - return(rv); -} - -#endif /* _PR_USE_POLL */ - -static PRInt32 local_io_wait( - PRInt32 osfd, - PRInt32 wait_flag, - PRIntervalTime timeout) -{ - _PRUnixPollDesc pd; - PRInt32 rv; - - PR_LOG(_pr_io_lm, PR_LOG_MIN, - ("waiting to %s on osfd=%d", - (wait_flag == _PR_UNIX_POLL_READ) ? "read" : "write", - osfd)); - - if (timeout == PR_INTERVAL_NO_WAIT) return 0; - - pd.osfd = osfd; - pd.in_flags = wait_flag; - pd.out_flags = 0; - - rv = _PR_WaitForMultipleFDs(&pd, 1, timeout); - - if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - rv = -1; - } - return rv; -} - - -PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, - PRInt32 flags, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - -/* - * Many OS's (Solaris, Unixware) have a broken recv which won't read - * from socketpairs. As long as we don't use flags on socketpairs, this - * is a decent fix. - mikep - */ -#if defined(UNIXWARE) || defined(SOLARIS) - while ((rv = read(osfd,buf,amount)) == -1) { -#else - while ((rv = recv(osfd,buf,amount,flags)) == -1) { -#endif - err = _MD_ERRNO(); - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) { - if ((rv = local_io_wait(osfd,_PR_UNIX_POLL_READ,timeout)) < 0) - goto done; - } else { - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - } - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_RECV_ERROR(err); - } -done: - return(rv); -} - -PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, - PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - while ((*addrlen = PR_NETADDR_SIZE(addr)), - ((rv = recvfrom(osfd, buf, amount, flags, - (struct sockaddr *) addr, (_PRSockLen_t *)addrlen)) == -1)) { - err = _MD_ERRNO(); - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) { - if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0) - goto done; - } else { - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - } - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_RECVFROM_ERROR(err); - } -done: -#ifdef _PR_HAVE_SOCKADDR_LEN - if (rv != -1) { - /* ignore the sa_len field of struct sockaddr */ - if (addr) { - addr->raw.family = ((struct sockaddr *) addr)->sa_family; - } - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ - return(rv); -} - -PRInt32 _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount, - PRInt32 flags, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); -#if defined(SOLARIS) - PRInt32 tmp_amount = amount; -#endif - - /* - * On pre-2.6 Solaris, send() is much slower than write(). - * On 2.6 and beyond, with in-kernel sockets, send() and - * write() are fairly equivalent in performance. - */ -#if defined(SOLARIS) - PR_ASSERT(0 == flags); - while ((rv = write(osfd,buf,tmp_amount)) == -1) { -#else - while ((rv = send(osfd,buf,amount,flags)) == -1) { -#endif - err = _MD_ERRNO(); - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) { - if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0) - goto done; - } else { - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0) - goto done; - } - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { -#if defined(SOLARIS) - /* - * The write system call has been reported to return the ERANGE - * error on occasion. Try to write in smaller chunks to workaround - * this bug. - */ - if (err == ERANGE) { - if (tmp_amount > 1) { - tmp_amount = tmp_amount/2; /* half the bytes */ - continue; - } - } -#endif - break; - } - } - /* - * optimization; if bytes sent is less than "amount" call - * select before returning. This is because it is likely that - * the next send() call will return EWOULDBLOCK. - */ - if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) - && (timeout != PR_INTERVAL_NO_WAIT)) { - if (_PR_IS_NATIVE_THREAD(me)) { - if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) { - rv = -1; - goto done; - } - } else { - if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) { - rv = -1; - goto done; - } - } - } - if (rv < 0) { - _PR_MD_MAP_SEND_ERROR(err); - } -done: - return(rv); -} - -PRInt32 _MD_sendto( - PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); -#ifdef _PR_HAVE_SOCKADDR_LEN - PRNetAddr addrCopy; - - addrCopy = *addr; - ((struct sockaddr *) &addrCopy)->sa_len = addrlen; - ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; - - while ((rv = sendto(osfd, buf, amount, flags, - (struct sockaddr *) &addrCopy, addrlen)) == -1) { -#else - while ((rv = sendto(osfd, buf, amount, flags, - (struct sockaddr *) addr, addrlen)) == -1) { -#endif - err = _MD_ERRNO(); - if ((err == EAGAIN) || (err == EWOULDBLOCK)) { - if (fd->secret->nonblocking) { - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) { - if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0) - goto done; - } else { - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0) - goto done; - } - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_SENDTO_ERROR(err); - } -done: - return(rv); -} - -PRInt32 _MD_writev( - PRFileDesc *fd, const PRIOVec *iov, - PRInt32 iov_size, PRIntervalTime timeout) -{ - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 index, amount = 0; - PRInt32 osfd = fd->secret->md.osfd; - - /* - * Calculate the total number of bytes to be sent; needed for - * optimization later. - * We could avoid this if this number was passed in; but it is - * probably not a big deal because iov_size is usually small (less than - * 3) - */ - if (!fd->secret->nonblocking) { - for (index=0; indexsecret->nonblocking) { - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) { - if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0) - goto done; - } else { - if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0) - goto done; - } - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - /* - * optimization; if bytes sent is less than "amount" call - * select before returning. This is because it is likely that - * the next writev() call will return EWOULDBLOCK. - */ - if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) - && (timeout != PR_INTERVAL_NO_WAIT)) { - if (_PR_IS_NATIVE_THREAD(me)) { - if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { - rv = -1; - goto done; - } - } else { - if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) { - rv = -1; - goto done; - } - } - } - if (rv < 0) { - _PR_MD_MAP_WRITEV_ERROR(err); - } -done: - return(rv); -} - -PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, - PRUint32 *addrlen, PRIntervalTime timeout) -{ - PRInt32 osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - while ((rv = accept(osfd, (struct sockaddr *) addr, - (_PRSockLen_t *)addrlen)) == -1) { - err = _MD_ERRNO(); - if ((err == EAGAIN) || (err == EWOULDBLOCK) || (err == ECONNABORTED)) { - if (fd->secret->nonblocking) { - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) { - if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0) - goto done; - } else { - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - goto done; - } - } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ - continue; - } else { - break; - } - } - if (rv < 0) { - _PR_MD_MAP_ACCEPT_ERROR(err); - } -done: -#ifdef _PR_HAVE_SOCKADDR_LEN - if (rv != -1) { - /* ignore the sa_len field of struct sockaddr */ - if (addr) { - addr->raw.family = ((struct sockaddr *) addr)->sa_family; - } - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ - return(rv); -} - -extern int _connect (int s, const struct sockaddr *name, int namelen); -PRInt32 _MD_connect( - PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) -{ - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 osfd = fd->secret->md.osfd; -#ifdef IRIX -extern PRInt32 _MD_irix_connect( - PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout); -#endif -#ifdef _PR_HAVE_SOCKADDR_LEN - PRNetAddr addrCopy; - - addrCopy = *addr; - ((struct sockaddr *) &addrCopy)->sa_len = addrlen; - ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; -#endif - - /* - * We initiate the connection setup by making a nonblocking connect() - * call. If the connect() call fails, there are two cases we handle - * specially: - * 1. The connect() call was interrupted by a signal. In this case - * we simply retry connect(). - * 2. The NSPR socket is nonblocking and connect() fails with - * EINPROGRESS. We first wait until the socket becomes writable. - * Then we try to find out whether the connection setup succeeded - * or failed. - */ - -retry: -#ifdef IRIX - if ((rv = _MD_irix_connect(osfd, addr, addrlen, timeout)) == -1) { -#else -#ifdef _PR_HAVE_SOCKADDR_LEN - if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) { -#else - if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) { -#endif -#endif - err = _MD_ERRNO(); - - if (err == EINTR) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - goto retry; - } - - if (!fd->secret->nonblocking && (err == EINPROGRESS)) { - if (!_PR_IS_NATIVE_THREAD(me)) { - - if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0) - return -1; - } else { - /* - * socket_io_wait() may return -1 or 1. - */ - - rv = socket_io_wait(osfd, WRITE_FD, timeout); - if (rv == -1) { - return -1; - } - } - - PR_ASSERT(rv == 1); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - err = _MD_unix_get_nonblocking_connect_error(osfd); - if (err != 0) { - _PR_MD_MAP_CONNECT_ERROR(err); - return -1; - } - return 0; - } - - _PR_MD_MAP_CONNECT_ERROR(err); - } - - return rv; -} /* _MD_connect */ - -PRInt32 _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) -{ - PRInt32 rv, err; -#ifdef _PR_HAVE_SOCKADDR_LEN - PRNetAddr addrCopy; - - addrCopy = *addr; - ((struct sockaddr *) &addrCopy)->sa_len = addrlen; - ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; - rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen); -#else - rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen); -#endif - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_BIND_ERROR(err); - } - return(rv); -} - -PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog) -{ - PRInt32 rv, err; - - rv = listen(fd->secret->md.osfd, backlog); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_LISTEN_ERROR(err); - } - return(rv); -} - -PRInt32 _MD_shutdown(PRFileDesc *fd, PRIntn how) -{ - PRInt32 rv, err; - - rv = shutdown(fd->secret->md.osfd, how); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_SHUTDOWN_ERROR(err); - } - return(rv); -} - -PRInt32 _MD_socketpair(int af, int type, int flags, - PRInt32 *osfd) -{ - PRInt32 rv, err; - - rv = socketpair(af, type, flags, osfd); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_SOCKETPAIR_ERROR(err); - } - return rv; -} - -PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, - PRUint32 *addrlen) -{ - PRInt32 rv, err; - - rv = getsockname(fd->secret->md.osfd, - (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); -#ifdef _PR_HAVE_SOCKADDR_LEN - if (rv == 0) { - /* ignore the sa_len field of struct sockaddr */ - if (addr) { - addr->raw.family = ((struct sockaddr *) addr)->sa_family; - } - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_GETSOCKNAME_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, - PRUint32 *addrlen) -{ - PRInt32 rv, err; - - rv = getpeername(fd->secret->md.osfd, - (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); -#ifdef _PR_HAVE_SOCKADDR_LEN - if (rv == 0) { - /* ignore the sa_len field of struct sockaddr */ - if (addr) { - addr->raw.family = ((struct sockaddr *) addr)->sa_family; - } - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_GETPEERNAME_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, - PRInt32 optname, char* optval, PRInt32* optlen) -{ - PRInt32 rv, err; - - rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (_PRSockLen_t *)optlen); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_GETSOCKOPT_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, - PRInt32 optname, const char* optval, PRInt32 optlen) -{ - PRInt32 rv, err; - - rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen); - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_SETSOCKOPT_ERROR(err); - } - return rv==0?PR_SUCCESS:PR_FAILURE; -} - -PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable) -{ - int rv; - - rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC); - if (-1 == rv) { - PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported) -{ - if (imported) { - fd->secret->inheritable = _PR_TRI_UNKNOWN; - } else { - /* By default, a Unix fd is not closed on exec. */ -#ifdef DEBUG - { - int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0); - PR_ASSERT(0 == flags); - } -#endif - fd->secret->inheritable = _PR_TRI_TRUE; - } -} - -/************************************************************************/ -#if !defined(_PR_USE_POLL) - -/* -** Scan through io queue and find any bad fd's that triggered the error -** from _MD_SELECT -*/ -static void FindBadFDs(void) -{ - PRCList *q; - PRThread *me = _MD_CURRENT_THREAD(); - - PR_ASSERT(!_PR_IS_NATIVE_THREAD(me)); - q = (_PR_IOQ(me->cpu)).next; - _PR_IOQ_MAX_OSFD(me->cpu) = -1; - _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT; - while (q != &_PR_IOQ(me->cpu)) { - PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); - PRBool notify = PR_FALSE; - _PRUnixPollDesc *pds = pq->pds; - _PRUnixPollDesc *epds = pds + pq->npds; - PRInt32 pq_max_osfd = -1; - - q = q->next; - for (; pds < epds; pds++) { - PRInt32 osfd = pds->osfd; - pds->out_flags = 0; - PR_ASSERT(osfd >= 0 || pds->in_flags == 0); - if (pds->in_flags == 0) { - continue; /* skip this fd */ - } - if (fcntl(osfd, F_GETFL, 0) == -1) { - /* Found a bad descriptor, remove it from the fd_sets. */ - PR_LOG(_pr_io_lm, PR_LOG_MAX, - ("file descriptor %d is bad", osfd)); - pds->out_flags = _PR_UNIX_POLL_NVAL; - notify = PR_TRUE; - } - if (osfd > pq_max_osfd) { - pq_max_osfd = osfd; - } - } - - if (notify) { - PRIntn pri; - PR_REMOVE_LINK(&pq->links); - pq->on_ioq = PR_FALSE; - - /* - * Decrement the count of descriptors for each desciptor/event - * because this I/O request is being removed from the - * ioq - */ - pds = pq->pds; - for (; pds < epds; pds++) { - PRInt32 osfd = pds->osfd; - PRInt16 in_flags = pds->in_flags; - PR_ASSERT(osfd >= 0 || in_flags == 0); - if (in_flags & _PR_UNIX_POLL_READ) { - if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); - } - if (in_flags & _PR_UNIX_POLL_WRITE) { - if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); - } - if (in_flags & _PR_UNIX_POLL_EXCEPT) { - if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); - } - } - - _PR_THREAD_LOCK(pq->thr); - if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { - _PRCPU *cpu = pq->thr->cpu; - _PR_SLEEPQ_LOCK(pq->thr->cpu); - _PR_DEL_SLEEPQ(pq->thr, PR_TRUE); - _PR_SLEEPQ_UNLOCK(pq->thr->cpu); - - if (pq->thr->flags & _PR_SUSPENDING) { - /* - * set thread state to SUSPENDED; - * a Resume operation on the thread - * will move it to the runQ - */ - pq->thr->state = _PR_SUSPENDED; - _PR_MISCQ_LOCK(pq->thr->cpu); - _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu); - _PR_MISCQ_UNLOCK(pq->thr->cpu); - } else { - pri = pq->thr->priority; - pq->thr->state = _PR_RUNNABLE; - - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(pq->thr, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - } - } - _PR_THREAD_UNLOCK(pq->thr); - } else { - if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu)) - _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout; - if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd) - _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd; - } - } - if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { - if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0]) - _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0]; - } -} -#endif /* !defined(_PR_USE_POLL) */ - -/************************************************************************/ - -/* -** Called by the scheduler when there is nothing to do. This means that -** all threads are blocked on some monitor somewhere. -** -** Note: this code doesn't release the scheduler lock. -*/ -/* -** Pause the current CPU. longjmp to the cpu's pause stack -** -** This must be called with the scheduler locked -*/ -void _MD_PauseCPU(PRIntervalTime ticks) -{ - PRThread *me = _MD_CURRENT_THREAD(); -#ifdef _PR_USE_POLL - int timeout; - struct pollfd *pollfds; /* an array of pollfd structures */ - struct pollfd *pollfdPtr; /* a pointer that steps through the array */ - unsigned long npollfds; /* number of pollfd structures in array */ - unsigned long pollfds_size; - int nfd; /* to hold the return value of poll() */ -#else - struct timeval timeout, *tvp; - fd_set r, w, e; - fd_set *rp, *wp, *ep; - PRInt32 max_osfd, nfd; -#endif /* _PR_USE_POLL */ - PRInt32 rv; - PRCList *q; - PRUint32 min_timeout; - sigset_t oldset; -#ifdef IRIX -extern sigset_t ints_off; -#endif - - PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); - - _PR_MD_IOQ_LOCK(); - -#ifdef _PR_USE_POLL - /* Build up the pollfd structure array to wait on */ - - /* Find out how many pollfd structures are needed */ - npollfds = _PR_IOQ_OSFD_CNT(me->cpu); - PR_ASSERT(npollfds >= 0); - - /* - * We use a pipe to wake up a native thread. An fd is needed - * for the pipe and we poll it for reading. - */ - if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { - npollfds++; -#ifdef IRIX - /* - * On Irix, a second pipe is used to cause the primordial cpu to - * wakeup and exit, when the process is exiting because of a call - * to exit/PR_ProcessExit. - */ - if (me->cpu->id == 0) { - npollfds++; - } -#endif - } - - /* - * if the cpu's pollfd array is not big enough, release it and allocate a new one - */ - if (npollfds > _PR_IOQ_POLLFDS_SIZE(me->cpu)) { - if (_PR_IOQ_POLLFDS(me->cpu) != NULL) - PR_DELETE(_PR_IOQ_POLLFDS(me->cpu)); - pollfds_size = PR_MAX(_PR_IOQ_MIN_POLLFDS_SIZE(me->cpu), npollfds); - pollfds = (struct pollfd *) PR_MALLOC(pollfds_size * sizeof(struct pollfd)); - _PR_IOQ_POLLFDS(me->cpu) = pollfds; - _PR_IOQ_POLLFDS_SIZE(me->cpu) = pollfds_size; - } else { - pollfds = _PR_IOQ_POLLFDS(me->cpu); - } - pollfdPtr = pollfds; - - /* - * If we need to poll the pipe for waking up a native thread, - * the pipe's fd is the first element in the pollfds array. - */ - if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { - pollfdPtr->fd = _pr_md_pipefd[0]; - pollfdPtr->events = POLLIN; - pollfdPtr++; -#ifdef IRIX - /* - * On Irix, the second element is the exit pipe - */ - if (me->cpu->id == 0) { - pollfdPtr->fd = _pr_irix_primoridal_cpu_fd[0]; - pollfdPtr->events = POLLIN; - pollfdPtr++; - } -#endif - } - - min_timeout = PR_INTERVAL_NO_TIMEOUT; - for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) { - PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); - _PRUnixPollDesc *pds = pq->pds; - _PRUnixPollDesc *epds = pds + pq->npds; - - if (pq->timeout < min_timeout) { - min_timeout = pq->timeout; - } - for (; pds < epds; pds++, pollfdPtr++) { - /* - * Assert that the pollfdPtr pointer does not go - * beyond the end of the pollfds array - */ - PR_ASSERT(pollfdPtr < pollfds + npollfds); - pollfdPtr->fd = pds->osfd; - /* direct copy of poll flags */ - pollfdPtr->events = pds->in_flags; - } - } - _PR_IOQ_TIMEOUT(me->cpu) = min_timeout; -#else - /* - * assigment of fd_sets - */ - r = _PR_FD_READ_SET(me->cpu); - w = _PR_FD_WRITE_SET(me->cpu); - e = _PR_FD_EXCEPTION_SET(me->cpu); - - rp = &r; - wp = &w; - ep = &e; - - max_osfd = _PR_IOQ_MAX_OSFD(me->cpu) + 1; - min_timeout = _PR_IOQ_TIMEOUT(me->cpu); -#endif /* _PR_USE_POLL */ - /* - ** Compute the minimum timeout value: make it the smaller of the - ** timeouts specified by the i/o pollers or the timeout of the first - ** sleeping thread. - */ - q = _PR_SLEEPQ(me->cpu).next; - - if (q != &_PR_SLEEPQ(me->cpu)) { - PRThread *t = _PR_THREAD_PTR(q); - - if (t->sleep < min_timeout) { - min_timeout = t->sleep; - } - } - if (min_timeout > ticks) { - min_timeout = ticks; - } - -#ifdef _PR_USE_POLL - if (min_timeout == PR_INTERVAL_NO_TIMEOUT) - timeout = -1; - else - timeout = PR_IntervalToMilliseconds(min_timeout); -#else - if (min_timeout == PR_INTERVAL_NO_TIMEOUT) { - tvp = NULL; - } else { - timeout.tv_sec = PR_IntervalToSeconds(min_timeout); - timeout.tv_usec = PR_IntervalToMicroseconds(min_timeout) - % PR_USEC_PER_SEC; - tvp = &timeout; - } -#endif /* _PR_USE_POLL */ - - _PR_MD_IOQ_UNLOCK(); - _MD_CHECK_FOR_EXIT(); - /* - * check for i/o operations - */ -#ifndef _PR_NO_CLOCK_TIMER - /* - * Disable the clock interrupts while we are in select, if clock interrupts - * are enabled. Otherwise, when the select/poll calls are interrupted, the - * timer value starts ticking from zero again when the system call is restarted. - */ -#ifdef IRIX - /* - * SIGCHLD signal is used on Irix to detect he termination of an - * sproc by SIGSEGV, SIGBUS or SIGABRT signals when - * _nspr_terminate_on_error is set. - */ - if ((!_nspr_noclock) || (_nspr_terminate_on_error)) -#else - if (!_nspr_noclock) -#endif /* IRIX */ -#ifdef IRIX - sigprocmask(SIG_BLOCK, &ints_off, &oldset); -#else - PR_ASSERT(sigismember(&timer_set, SIGALRM)); - sigprocmask(SIG_BLOCK, &timer_set, &oldset); -#endif /* IRIX */ -#endif /* !_PR_NO_CLOCK_TIMER */ - -#ifndef _PR_USE_POLL - PR_ASSERT(FD_ISSET(_pr_md_pipefd[0],rp)); - nfd = _MD_SELECT(max_osfd, rp, wp, ep, tvp); -#else - nfd = _MD_POLL(pollfds, npollfds, timeout); -#endif /* !_PR_USE_POLL */ - -#ifndef _PR_NO_CLOCK_TIMER -#ifdef IRIX - if ((!_nspr_noclock) || (_nspr_terminate_on_error)) -#else - if (!_nspr_noclock) -#endif /* IRIX */ - sigprocmask(SIG_SETMASK, &oldset, 0); -#endif /* !_PR_NO_CLOCK_TIMER */ - - _MD_CHECK_FOR_EXIT(); - -#ifdef IRIX - _PR_MD_primordial_cpu(); -#endif - - _PR_MD_IOQ_LOCK(); - /* - ** Notify monitors that are associated with the selected descriptors. - */ -#ifdef _PR_USE_POLL - if (nfd > 0) { - pollfdPtr = pollfds; - if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { - /* - * Assert that the pipe is the first element in the - * pollfds array. - */ - PR_ASSERT(pollfds[0].fd == _pr_md_pipefd[0]); - if ((pollfds[0].revents & POLLIN) && (nfd == 1)) { - /* - * woken up by another thread; read all the data - * in the pipe to empty the pipe - */ - while ((rv = read(_pr_md_pipefd[0], _pr_md_pipebuf, - PIPE_BUF)) == PIPE_BUF){ - } - PR_ASSERT((rv > 0) || ((rv == -1) && (errno == EAGAIN))); - } - pollfdPtr++; -#ifdef IRIX - /* - * On Irix, check to see if the primordial cpu needs to exit - * to cause the process to terminate - */ - if (me->cpu->id == 0) { - PR_ASSERT(pollfds[1].fd == _pr_irix_primoridal_cpu_fd[0]); - if (pollfdPtr->revents & POLLIN) { - if (_pr_irix_process_exit) { - /* - * process exit due to a call to PR_ProcessExit - */ - prctl(PR_SETEXITSIG, SIGKILL); - _exit(_pr_irix_process_exit_code); - } else { - while ((rv = read(_pr_irix_primoridal_cpu_fd[0], - _pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) { - } - PR_ASSERT(rv > 0); - } - } - pollfdPtr++; - } -#endif - } - for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) { - PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); - PRBool notify = PR_FALSE; - _PRUnixPollDesc *pds = pq->pds; - _PRUnixPollDesc *epds = pds + pq->npds; - - for (; pds < epds; pds++, pollfdPtr++) { - /* - * Assert that the pollfdPtr pointer does not go beyond - * the end of the pollfds array. - */ - PR_ASSERT(pollfdPtr < pollfds + npollfds); - /* - * Assert that the fd's in the pollfds array (stepped - * through by pollfdPtr) are in the same order as - * the fd's in _PR_IOQ() (stepped through by q and pds). - * This is how the pollfds array was created earlier. - */ - PR_ASSERT(pollfdPtr->fd == pds->osfd); - pds->out_flags = pollfdPtr->revents; - /* Negative fd's are ignored by poll() */ - if (pds->osfd >= 0 && pds->out_flags) { - notify = PR_TRUE; - } - } - if (notify) { - PRIntn pri; - PRThread *thred; - - PR_REMOVE_LINK(&pq->links); - pq->on_ioq = PR_FALSE; - - thred = pq->thr; - _PR_THREAD_LOCK(thred); - if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { - _PRCPU *cpu = pq->thr->cpu; - _PR_SLEEPQ_LOCK(pq->thr->cpu); - _PR_DEL_SLEEPQ(pq->thr, PR_TRUE); - _PR_SLEEPQ_UNLOCK(pq->thr->cpu); - - if (pq->thr->flags & _PR_SUSPENDING) { - /* - * set thread state to SUSPENDED; - * a Resume operation on the thread - * will move it to the runQ - */ - pq->thr->state = _PR_SUSPENDED; - _PR_MISCQ_LOCK(pq->thr->cpu); - _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu); - _PR_MISCQ_UNLOCK(pq->thr->cpu); - } else { - pri = pq->thr->priority; - pq->thr->state = _PR_RUNNABLE; - - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(pq->thr, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - if (_pr_md_idle_cpus > 1) - _PR_MD_WAKEUP_WAITER(thred); - } - } - _PR_THREAD_UNLOCK(thred); - _PR_IOQ_OSFD_CNT(me->cpu) -= pq->npds; - PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0); - } - } - } else if (nfd == -1) { - PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno)); - } - -#else - if (nfd > 0) { - q = _PR_IOQ(me->cpu).next; - _PR_IOQ_MAX_OSFD(me->cpu) = -1; - _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT; - while (q != &_PR_IOQ(me->cpu)) { - PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); - PRBool notify = PR_FALSE; - _PRUnixPollDesc *pds = pq->pds; - _PRUnixPollDesc *epds = pds + pq->npds; - PRInt32 pq_max_osfd = -1; - - q = q->next; - for (; pds < epds; pds++) { - PRInt32 osfd = pds->osfd; - PRInt16 in_flags = pds->in_flags; - PRInt16 out_flags = 0; - PR_ASSERT(osfd >= 0 || in_flags == 0); - if ((in_flags & _PR_UNIX_POLL_READ) && FD_ISSET(osfd, rp)) { - out_flags |= _PR_UNIX_POLL_READ; - } - if ((in_flags & _PR_UNIX_POLL_WRITE) && FD_ISSET(osfd, wp)) { - out_flags |= _PR_UNIX_POLL_WRITE; - } - if ((in_flags & _PR_UNIX_POLL_EXCEPT) && FD_ISSET(osfd, ep)) { - out_flags |= _PR_UNIX_POLL_EXCEPT; - } - pds->out_flags = out_flags; - if (out_flags) { - notify = PR_TRUE; - } - if (osfd > pq_max_osfd) { - pq_max_osfd = osfd; - } - } - if (notify == PR_TRUE) { - PRIntn pri; - PRThread *thred; - - PR_REMOVE_LINK(&pq->links); - pq->on_ioq = PR_FALSE; - - /* - * Decrement the count of descriptors for each desciptor/event - * because this I/O request is being removed from the - * ioq - */ - pds = pq->pds; - for (; pds < epds; pds++) { - PRInt32 osfd = pds->osfd; - PRInt16 in_flags = pds->in_flags; - PR_ASSERT(osfd >= 0 || in_flags == 0); - if (in_flags & _PR_UNIX_POLL_READ) { - if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); - } - if (in_flags & _PR_UNIX_POLL_WRITE) { - if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); - } - if (in_flags & _PR_UNIX_POLL_EXCEPT) { - if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); - } - } - - /* - * Because this thread can run on a different cpu right - * after being added to the run queue, do not dereference - * pq - */ - thred = pq->thr; - _PR_THREAD_LOCK(thred); - if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { - _PRCPU *cpu = thred->cpu; - _PR_SLEEPQ_LOCK(pq->thr->cpu); - _PR_DEL_SLEEPQ(pq->thr, PR_TRUE); - _PR_SLEEPQ_UNLOCK(pq->thr->cpu); - - if (pq->thr->flags & _PR_SUSPENDING) { - /* - * set thread state to SUSPENDED; - * a Resume operation on the thread - * will move it to the runQ - */ - pq->thr->state = _PR_SUSPENDED; - _PR_MISCQ_LOCK(pq->thr->cpu); - _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu); - _PR_MISCQ_UNLOCK(pq->thr->cpu); - } else { - pri = pq->thr->priority; - pq->thr->state = _PR_RUNNABLE; - - pq->thr->cpu = cpu; - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(pq->thr, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - if (_pr_md_idle_cpus > 1) - _PR_MD_WAKEUP_WAITER(thred); - } - } - _PR_THREAD_UNLOCK(thred); - } else { - if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu)) - _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout; - if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd) - _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd; - } - } - if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { - if ((FD_ISSET(_pr_md_pipefd[0], rp)) && (nfd == 1)) { - /* - * woken up by another thread; read all the data - * in the pipe to empty the pipe - */ - while ((rv = - read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF)) - == PIPE_BUF){ - } - PR_ASSERT((rv > 0) || - ((rv == -1) && (errno == EAGAIN))); - } - if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0]) - _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0]; -#ifdef IRIX - if ((me->cpu->id == 0) && - (FD_ISSET(_pr_irix_primoridal_cpu_fd[0], rp))) { - if (_pr_irix_process_exit) { - /* - * process exit due to a call to PR_ProcessExit - */ - prctl(PR_SETEXITSIG, SIGKILL); - _exit(_pr_irix_process_exit_code); - } else { - while ((rv = read(_pr_irix_primoridal_cpu_fd[0], - _pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) { - } - PR_ASSERT(rv > 0); - } - } - if (me->cpu->id == 0) { - if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_irix_primoridal_cpu_fd[0]) - _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0]; - } -#endif - } - } else if (nfd < 0) { - if (errno == EBADF) { - FindBadFDs(); - } else { - PR_LOG(_pr_io_lm, PR_LOG_MAX, ("select() failed with errno %d", - errno)); - } - } else { - PR_ASSERT(nfd == 0); - /* - * compute the new value of _PR_IOQ_TIMEOUT - */ - q = _PR_IOQ(me->cpu).next; - _PR_IOQ_MAX_OSFD(me->cpu) = -1; - _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT; - while (q != &_PR_IOQ(me->cpu)) { - PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); - _PRUnixPollDesc *pds = pq->pds; - _PRUnixPollDesc *epds = pds + pq->npds; - PRInt32 pq_max_osfd = -1; - - q = q->next; - for (; pds < epds; pds++) { - if (pds->osfd > pq_max_osfd) { - pq_max_osfd = pds->osfd; - } - } - if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu)) - _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout; - if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd) - _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd; - } - if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { - if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0]) - _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0]; - } - } -#endif /* _PR_USE_POLL */ - _PR_MD_IOQ_UNLOCK(); -} - -void _MD_Wakeup_CPUs() -{ - PRInt32 rv, data; - - data = 0; - rv = write(_pr_md_pipefd[1], &data, 1); - - while ((rv < 0) && (errno == EAGAIN)) { - /* - * pipe full, read all data in pipe to empty it - */ - while ((rv = - read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF)) - == PIPE_BUF) { - } - PR_ASSERT((rv > 0) || - ((rv == -1) && (errno == EAGAIN))); - rv = write(_pr_md_pipefd[1], &data, 1); - } -} - - -void _MD_InitCPUS() -{ - PRInt32 rv, flags; - PRThread *me = _MD_CURRENT_THREAD(); - - rv = pipe(_pr_md_pipefd); - PR_ASSERT(rv == 0); - _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0]; -#ifndef _PR_USE_POLL - FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu)); -#endif - - flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0); - fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK); - flags = fcntl(_pr_md_pipefd[1], F_GETFL, 0); - fcntl(_pr_md_pipefd[1], F_SETFL, flags | O_NONBLOCK); -} - -/* -** Unix SIGALRM (clock) signal handler -*/ -static void ClockInterruptHandler() -{ - int olderrno; - PRUintn pri; - _PRCPU *cpu = _PR_MD_CURRENT_CPU(); - PRThread *me = _MD_CURRENT_THREAD(); - -#ifdef SOLARIS - if (!me || _PR_IS_NATIVE_THREAD(me)) { - _pr_primordialCPU->u.missed[_pr_primordialCPU->where] |= _PR_MISSED_CLOCK; - return; - } -#endif - - if (_PR_MD_GET_INTSOFF() != 0) { - cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK; - return; - } - _PR_MD_SET_INTSOFF(1); - - olderrno = errno; - _PR_ClockInterrupt(); - errno = olderrno; - - /* - ** If the interrupt wants a resched or if some other thread at - ** the same priority needs the cpu, reschedule. - */ - pri = me->priority; - if ((cpu->u.missed[3] || (_PR_RUNQREADYMASK(me->cpu) >> pri))) { -#ifdef _PR_NO_PREEMPT - cpu->resched = PR_TRUE; - if (pr_interruptSwitchHook) { - (*pr_interruptSwitchHook)(pr_interruptSwitchHookArg); - } -#else /* _PR_NO_PREEMPT */ - /* - ** Re-enable unix interrupts (so that we can use - ** setjmp/longjmp for context switching without having to - ** worry about the signal state) - */ - sigprocmask(SIG_SETMASK, &empty_set, 0); - PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock caused context switch")); - - if(!(me->flags & _PR_IDLE_THREAD)) { - _PR_THREAD_LOCK(me); - me->state = _PR_RUNNABLE; - me->cpu = cpu; - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(me, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - _PR_THREAD_UNLOCK(me); - } else - me->state = _PR_RUNNABLE; - _MD_SWITCH_CONTEXT(me); - PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock back from context switch")); -#endif /* _PR_NO_PREEMPT */ - } - /* - * Because this thread could be running on a different cpu after - * a context switch the current cpu should be accessed and the - * value of the 'cpu' variable should not be used. - */ - _PR_MD_SET_INTSOFF(0); -} - -/* - * On HP-UX 9, we have to use the sigvector() interface to restart - * interrupted system calls, because sigaction() does not have the - * SA_RESTART flag. - */ - -#ifdef HPUX9 -static void HPUX9_ClockInterruptHandler( - int sig, - int code, - struct sigcontext *scp) -{ - ClockInterruptHandler(); - scp->sc_syscall_action = SIG_RESTART; -} -#endif /* HPUX9 */ - -/* # of milliseconds per clock tick that we will use */ -#define MSEC_PER_TICK 50 - - -void _MD_StartInterrupts() -{ - char *eval; - - if ((eval = getenv("NSPR_NOCLOCK")) != NULL) { - if (atoi(eval) == 0) - _nspr_noclock = 0; - else - _nspr_noclock = 1; - } - -#ifndef _PR_NO_CLOCK_TIMER - if (!_nspr_noclock) { - _MD_EnableClockInterrupts(); - } -#endif -} - -void _MD_StopInterrupts() -{ - sigprocmask(SIG_BLOCK, &timer_set, 0); -} - -void _MD_EnableClockInterrupts() -{ - struct itimerval itval; - extern PRUintn _pr_numCPU; -#ifdef HPUX9 - struct sigvec vec; - - vec.sv_handler = (void (*)()) HPUX9_ClockInterruptHandler; - vec.sv_mask = 0; - vec.sv_flags = 0; - sigvector(SIGALRM, &vec, 0); -#else - struct sigaction vtact; - - vtact.sa_handler = (void (*)()) ClockInterruptHandler; - sigemptyset(&vtact.sa_mask); - vtact.sa_flags = SA_RESTART; - sigaction(SIGALRM, &vtact, 0); -#endif /* HPUX9 */ - - PR_ASSERT(_pr_numCPU == 1); - itval.it_interval.tv_sec = 0; - itval.it_interval.tv_usec = MSEC_PER_TICK * PR_USEC_PER_MSEC; - itval.it_value = itval.it_interval; - setitimer(ITIMER_REAL, &itval, 0); -} - -void _MD_DisableClockInterrupts() -{ - struct itimerval itval; - extern PRUintn _pr_numCPU; - - PR_ASSERT(_pr_numCPU == 1); - itval.it_interval.tv_sec = 0; - itval.it_interval.tv_usec = 0; - itval.it_value = itval.it_interval; - setitimer(ITIMER_REAL, &itval, 0); -} - -void _MD_BlockClockInterrupts() -{ - sigprocmask(SIG_BLOCK, &timer_set, 0); -} - -void _MD_UnblockClockInterrupts() -{ - sigprocmask(SIG_UNBLOCK, &timer_set, 0); -} - -void _MD_MakeNonblock(PRFileDesc *fd) -{ - PRInt32 osfd = fd->secret->md.osfd; - int flags; - - if (osfd <= 2) { - /* Don't mess around with stdin, stdout or stderr */ - return; - } - flags = fcntl(osfd, F_GETFL, 0); - - /* - * Use O_NONBLOCK (POSIX-style non-blocking I/O) whenever possible. - * On SunOS 4, we must use FNDELAY (BSD-style non-blocking I/O), - * otherwise connect() still blocks and can be interrupted by SIGALRM. - */ - - fcntl(osfd, F_SETFL, flags | O_NONBLOCK); - } - -PRInt32 _MD_open(const char *name, PRIntn flags, PRIntn mode) -{ - PRInt32 osflags; - PRInt32 rv, err; - - if (flags & PR_RDWR) { - osflags = O_RDWR; - } else if (flags & PR_WRONLY) { - osflags = O_WRONLY; - } else { - osflags = O_RDONLY; - } - - if (flags & PR_EXCL) - osflags |= O_EXCL; - if (flags & PR_APPEND) - osflags |= O_APPEND; - if (flags & PR_TRUNCATE) - osflags |= O_TRUNC; - if (flags & PR_SYNC) { -#if defined(O_SYNC) - osflags |= O_SYNC; -#elif defined(O_FSYNC) - osflags |= O_FSYNC; -#else -#error "Neither O_SYNC nor O_FSYNC is defined on this platform" -#endif - } - - /* - ** On creations we hold the 'create' lock in order to enforce - ** the semantics of PR_Rename. (see the latter for more details) - */ - if (flags & PR_CREATE_FILE) - { - osflags |= O_CREAT; - if (NULL !=_pr_rename_lock) - PR_Lock(_pr_rename_lock); - } - -#if defined(ANDROID) - osflags |= O_LARGEFILE; -#endif - - rv = _md_iovector._open64(name, osflags, mode); - - if (rv < 0) { - err = _MD_ERRNO(); - _PR_MD_MAP_OPEN_ERROR(err); - } - - if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock)) - PR_Unlock(_pr_rename_lock); - return rv; -} - -PRIntervalTime intr_timeout_ticks; - -#if defined(SOLARIS) || defined(IRIX) -static void sigsegvhandler() { - fprintf(stderr,"Received SIGSEGV\n"); - fflush(stderr); - pause(); -} - -static void sigaborthandler() { - fprintf(stderr,"Received SIGABRT\n"); - fflush(stderr); - pause(); -} - -static void sigbushandler() { - fprintf(stderr,"Received SIGBUS\n"); - fflush(stderr); - pause(); -} -#endif /* SOLARIS, IRIX */ - -#endif /* !defined(_PR_PTHREADS) */ - -void _MD_query_fd_inheritable(PRFileDesc *fd) -{ - int flags; - - PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); - flags = fcntl(fd->secret->md.osfd, F_GETFD, 0); - PR_ASSERT(-1 != flags); - fd->secret->inheritable = (flags & FD_CLOEXEC) ? - _PR_TRI_FALSE : _PR_TRI_TRUE; -} - -PROffset32 _MD_lseek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) -{ - PROffset32 rv, where; - - switch (whence) { - case PR_SEEK_SET: - where = SEEK_SET; - break; - case PR_SEEK_CUR: - where = SEEK_CUR; - break; - case PR_SEEK_END: - where = SEEK_END; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = -1; - goto done; - } - rv = lseek(fd->secret->md.osfd,offset,where); - if (rv == -1) - { - PRInt32 syserr = _MD_ERRNO(); - _PR_MD_MAP_LSEEK_ERROR(syserr); - } -done: - return(rv); -} - -PROffset64 _MD_lseek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) -{ - PRInt32 where; - PROffset64 rv; - - switch (whence) - { - case PR_SEEK_SET: - where = SEEK_SET; - break; - case PR_SEEK_CUR: - where = SEEK_CUR; - break; - case PR_SEEK_END: - where = SEEK_END; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = minus_one; - goto done; - } - rv = _md_iovector._lseek64(fd->secret->md.osfd, offset, where); - if (LL_EQ(rv, minus_one)) - { - PRInt32 syserr = _MD_ERRNO(); - _PR_MD_MAP_LSEEK_ERROR(syserr); - } -done: - return rv; -} /* _MD_lseek64 */ - -/* -** _MD_set_fileinfo_times -- -** Set the modifyTime and creationTime of the PRFileInfo -** structure using the values in struct stat. -** -** _MD_set_fileinfo64_times -- -** Set the modifyTime and creationTime of the PRFileInfo64 -** structure using the values in _MDStat64. -*/ - -#if defined(_PR_STAT_HAS_ST_ATIM) -/* -** struct stat has st_atim, st_mtim, and st_ctim fields of -** type timestruc_t. -*/ -static void _MD_set_fileinfo_times( - const struct stat *sb, - PRFileInfo *info) -{ - PRInt64 us, s2us; - - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(info->modifyTime, sb->st_mtim.tv_sec); - LL_MUL(info->modifyTime, info->modifyTime, s2us); - LL_I2L(us, sb->st_mtim.tv_nsec / 1000); - LL_ADD(info->modifyTime, info->modifyTime, us); - LL_I2L(info->creationTime, sb->st_ctim.tv_sec); - LL_MUL(info->creationTime, info->creationTime, s2us); - LL_I2L(us, sb->st_ctim.tv_nsec / 1000); - LL_ADD(info->creationTime, info->creationTime, us); -} - -static void _MD_set_fileinfo64_times( - const _MDStat64 *sb, - PRFileInfo64 *info) -{ - PRInt64 us, s2us; - - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(info->modifyTime, sb->st_mtim.tv_sec); - LL_MUL(info->modifyTime, info->modifyTime, s2us); - LL_I2L(us, sb->st_mtim.tv_nsec / 1000); - LL_ADD(info->modifyTime, info->modifyTime, us); - LL_I2L(info->creationTime, sb->st_ctim.tv_sec); - LL_MUL(info->creationTime, info->creationTime, s2us); - LL_I2L(us, sb->st_ctim.tv_nsec / 1000); - LL_ADD(info->creationTime, info->creationTime, us); -} -#elif defined(_PR_STAT_HAS_ST_ATIM_UNION) -/* -** The st_atim, st_mtim, and st_ctim fields in struct stat are -** unions with a st__tim union member of type timestruc_t. -*/ -static void _MD_set_fileinfo_times( - const struct stat *sb, - PRFileInfo *info) -{ - PRInt64 us, s2us; - - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(info->modifyTime, sb->st_mtim.st__tim.tv_sec); - LL_MUL(info->modifyTime, info->modifyTime, s2us); - LL_I2L(us, sb->st_mtim.st__tim.tv_nsec / 1000); - LL_ADD(info->modifyTime, info->modifyTime, us); - LL_I2L(info->creationTime, sb->st_ctim.st__tim.tv_sec); - LL_MUL(info->creationTime, info->creationTime, s2us); - LL_I2L(us, sb->st_ctim.st__tim.tv_nsec / 1000); - LL_ADD(info->creationTime, info->creationTime, us); -} - -static void _MD_set_fileinfo64_times( - const _MDStat64 *sb, - PRFileInfo64 *info) -{ - PRInt64 us, s2us; - - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(info->modifyTime, sb->st_mtim.st__tim.tv_sec); - LL_MUL(info->modifyTime, info->modifyTime, s2us); - LL_I2L(us, sb->st_mtim.st__tim.tv_nsec / 1000); - LL_ADD(info->modifyTime, info->modifyTime, us); - LL_I2L(info->creationTime, sb->st_ctim.st__tim.tv_sec); - LL_MUL(info->creationTime, info->creationTime, s2us); - LL_I2L(us, sb->st_ctim.st__tim.tv_nsec / 1000); - LL_ADD(info->creationTime, info->creationTime, us); -} -#elif defined(_PR_STAT_HAS_ST_ATIMESPEC) -/* -** struct stat has st_atimespec, st_mtimespec, and st_ctimespec -** fields of type struct timespec. -*/ -#if defined(_PR_TIMESPEC_HAS_TS_SEC) -static void _MD_set_fileinfo_times( - const struct stat *sb, - PRFileInfo *info) -{ - PRInt64 us, s2us; - - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(info->modifyTime, sb->st_mtimespec.ts_sec); - LL_MUL(info->modifyTime, info->modifyTime, s2us); - LL_I2L(us, sb->st_mtimespec.ts_nsec / 1000); - LL_ADD(info->modifyTime, info->modifyTime, us); - LL_I2L(info->creationTime, sb->st_ctimespec.ts_sec); - LL_MUL(info->creationTime, info->creationTime, s2us); - LL_I2L(us, sb->st_ctimespec.ts_nsec / 1000); - LL_ADD(info->creationTime, info->creationTime, us); -} - -static void _MD_set_fileinfo64_times( - const _MDStat64 *sb, - PRFileInfo64 *info) -{ - PRInt64 us, s2us; - - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(info->modifyTime, sb->st_mtimespec.ts_sec); - LL_MUL(info->modifyTime, info->modifyTime, s2us); - LL_I2L(us, sb->st_mtimespec.ts_nsec / 1000); - LL_ADD(info->modifyTime, info->modifyTime, us); - LL_I2L(info->creationTime, sb->st_ctimespec.ts_sec); - LL_MUL(info->creationTime, info->creationTime, s2us); - LL_I2L(us, sb->st_ctimespec.ts_nsec / 1000); - LL_ADD(info->creationTime, info->creationTime, us); -} -#else /* _PR_TIMESPEC_HAS_TS_SEC */ -/* -** The POSIX timespec structure has tv_sec and tv_nsec. -*/ -static void _MD_set_fileinfo_times( - const struct stat *sb, - PRFileInfo *info) -{ - PRInt64 us, s2us; - - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(info->modifyTime, sb->st_mtimespec.tv_sec); - LL_MUL(info->modifyTime, info->modifyTime, s2us); - LL_I2L(us, sb->st_mtimespec.tv_nsec / 1000); - LL_ADD(info->modifyTime, info->modifyTime, us); - LL_I2L(info->creationTime, sb->st_ctimespec.tv_sec); - LL_MUL(info->creationTime, info->creationTime, s2us); - LL_I2L(us, sb->st_ctimespec.tv_nsec / 1000); - LL_ADD(info->creationTime, info->creationTime, us); -} - -static void _MD_set_fileinfo64_times( - const _MDStat64 *sb, - PRFileInfo64 *info) -{ - PRInt64 us, s2us; - - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(info->modifyTime, sb->st_mtimespec.tv_sec); - LL_MUL(info->modifyTime, info->modifyTime, s2us); - LL_I2L(us, sb->st_mtimespec.tv_nsec / 1000); - LL_ADD(info->modifyTime, info->modifyTime, us); - LL_I2L(info->creationTime, sb->st_ctimespec.tv_sec); - LL_MUL(info->creationTime, info->creationTime, s2us); - LL_I2L(us, sb->st_ctimespec.tv_nsec / 1000); - LL_ADD(info->creationTime, info->creationTime, us); -} -#endif /* _PR_TIMESPEC_HAS_TS_SEC */ -#elif defined(_PR_STAT_HAS_ONLY_ST_ATIME) -/* -** struct stat only has st_atime, st_mtime, and st_ctime fields -** of type time_t. -*/ -static void _MD_set_fileinfo_times( - const struct stat *sb, - PRFileInfo *info) -{ - PRInt64 s, s2us; - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(s, sb->st_mtime); - LL_MUL(s, s, s2us); - info->modifyTime = s; - LL_I2L(s, sb->st_ctime); - LL_MUL(s, s, s2us); - info->creationTime = s; -} - -static void _MD_set_fileinfo64_times( - const _MDStat64 *sb, - PRFileInfo64 *info) -{ - PRInt64 s, s2us; - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(s, sb->st_mtime); - LL_MUL(s, s, s2us); - info->modifyTime = s; - LL_I2L(s, sb->st_ctime); - LL_MUL(s, s, s2us); - info->creationTime = s; -} -#else -#error "I don't know yet" -#endif - -static int _MD_convert_stat_to_fileinfo( - const struct stat *sb, - PRFileInfo *info) -{ - if (S_IFREG & sb->st_mode) - info->type = PR_FILE_FILE; - else if (S_IFDIR & sb->st_mode) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_OTHER; - -#if defined(_PR_HAVE_LARGE_OFF_T) - if (0x7fffffffL < sb->st_size) - { - PR_SetError(PR_FILE_TOO_BIG_ERROR, 0); - return -1; - } -#endif /* defined(_PR_HAVE_LARGE_OFF_T) */ - info->size = sb->st_size; - - _MD_set_fileinfo_times(sb, info); - return 0; -} /* _MD_convert_stat_to_fileinfo */ - -static int _MD_convert_stat64_to_fileinfo64( - const _MDStat64 *sb, - PRFileInfo64 *info) -{ - if (S_IFREG & sb->st_mode) - info->type = PR_FILE_FILE; - else if (S_IFDIR & sb->st_mode) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_OTHER; - - LL_I2L(info->size, sb->st_size); - - _MD_set_fileinfo64_times(sb, info); - return 0; -} /* _MD_convert_stat64_to_fileinfo64 */ - -PRInt32 _MD_getfileinfo(const char *fn, PRFileInfo *info) -{ - PRInt32 rv; - struct stat sb; - - rv = stat(fn, &sb); - if (rv < 0) - _PR_MD_MAP_STAT_ERROR(_MD_ERRNO()); - else if (NULL != info) - rv = _MD_convert_stat_to_fileinfo(&sb, info); - return rv; -} - -PRInt32 _MD_getfileinfo64(const char *fn, PRFileInfo64 *info) -{ - _MDStat64 sb; - PRInt32 rv = _md_iovector._stat64(fn, &sb); - if (rv < 0) - _PR_MD_MAP_STAT_ERROR(_MD_ERRNO()); - else if (NULL != info) - rv = _MD_convert_stat64_to_fileinfo64(&sb, info); - return rv; -} - -PRInt32 _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info) -{ - struct stat sb; - PRInt32 rv = fstat(fd->secret->md.osfd, &sb); - if (rv < 0) - _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO()); - else if (NULL != info) - rv = _MD_convert_stat_to_fileinfo(&sb, info); - return rv; -} - -PRInt32 _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info) -{ - _MDStat64 sb; - PRInt32 rv = _md_iovector._fstat64(fd->secret->md.osfd, &sb); - if (rv < 0) - _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO()); - else if (NULL != info) - rv = _MD_convert_stat64_to_fileinfo64(&sb, info); - return rv; -} - -/* - * _md_iovector._open64 must be initialized to 'open' so that _PR_InitLog can - * open the log file during NSPR initialization, before _md_iovector is - * initialized by _PR_MD_FINAL_INIT. This means the log file cannot be a - * large file on some platforms. - */ -#ifdef SYMBIAN -struct _MD_IOVector _md_iovector; /* Will crash if NSPR_LOG_FILE is set. */ -#else -struct _MD_IOVector _md_iovector = { open }; -#endif - -/* -** These implementations are to emulate large file routines on systems that -** don't have them. Their goal is to check in case overflow occurs. Otherwise -** they will just operate as normal using 32-bit file routines. -** -** The checking might be pre- or post-op, depending on the semantics. -*/ - -#if defined(SOLARIS2_5) - -static PRIntn _MD_solaris25_fstat64(PRIntn osfd, _MDStat64 *buf) -{ - PRInt32 rv; - struct stat sb; - - rv = fstat(osfd, &sb); - if (rv >= 0) - { - /* - ** I'm only copying the fields that are immediately needed. - ** If somebody else calls this function, some of the fields - ** may not be defined. - */ - (void)memset(buf, 0, sizeof(_MDStat64)); - buf->st_mode = sb.st_mode; - buf->st_ctim = sb.st_ctim; - buf->st_mtim = sb.st_mtim; - buf->st_size = sb.st_size; - } - return rv; -} /* _MD_solaris25_fstat64 */ - -static PRIntn _MD_solaris25_stat64(const char *fn, _MDStat64 *buf) -{ - PRInt32 rv; - struct stat sb; - - rv = stat(fn, &sb); - if (rv >= 0) - { - /* - ** I'm only copying the fields that are immediately needed. - ** If somebody else calls this function, some of the fields - ** may not be defined. - */ - (void)memset(buf, 0, sizeof(_MDStat64)); - buf->st_mode = sb.st_mode; - buf->st_ctim = sb.st_ctim; - buf->st_mtim = sb.st_mtim; - buf->st_size = sb.st_size; - } - return rv; -} /* _MD_solaris25_stat64 */ -#endif /* defined(SOLARIS2_5) */ - -#if defined(_PR_NO_LARGE_FILES) || defined(SOLARIS2_5) - -static PROffset64 _MD_Unix_lseek64(PRIntn osfd, PROffset64 offset, PRIntn whence) -{ - PRUint64 maxoff; - PROffset64 rv = minus_one; - LL_I2L(maxoff, 0x7fffffff); - if (LL_CMP(offset, <=, maxoff)) - { - off_t off; - LL_L2I(off, offset); - LL_I2L(rv, lseek(osfd, off, whence)); - } - else errno = EFBIG; /* we can't go there */ - return rv; -} /* _MD_Unix_lseek64 */ - -static void* _MD_Unix_mmap64( - void *addr, PRSize len, PRIntn prot, PRIntn flags, - PRIntn fildes, PRInt64 offset) -{ - PR_SetError(PR_FILE_TOO_BIG_ERROR, 0); - return NULL; -} /* _MD_Unix_mmap64 */ -#endif /* defined(_PR_NO_LARGE_FILES) || defined(SOLARIS2_5) */ - -/* Android doesn't have mmap64. */ -#if defined(ANDROID) -extern void *__mmap2(void *, size_t, int, int, int, size_t); - -#define ANDROID_PAGE_SIZE 4096 - -static void * -mmap64(void *addr, size_t len, int prot, int flags, int fd, loff_t offset) -{ - if (offset & (ANDROID_PAGE_SIZE - 1)) { - errno = EINVAL; - return MAP_FAILED; - } - return __mmap2(addr, len, prot, flags, fd, offset / ANDROID_PAGE_SIZE); -} -#endif - -#if defined(OSF1) && defined(__GNUC__) - -/* - * On OSF1 V5.0A, defines stat and fstat as - * macros when compiled under gcc, so it is rather tricky to - * take the addresses of the real functions the macros expend - * to. A simple solution is to define forwarder functions - * and take the addresses of the forwarder functions instead. - */ - -static int stat_forwarder(const char *path, struct stat *buffer) -{ - return stat(path, buffer); -} - -static int fstat_forwarder(int filedes, struct stat *buffer) -{ - return fstat(filedes, buffer); -} - -#endif - -static void _PR_InitIOV(void) -{ -#if defined(SOLARIS2_5) - PRLibrary *lib; - void *open64_func; - - open64_func = PR_FindSymbolAndLibrary("open64", &lib); - if (NULL != open64_func) - { - PR_ASSERT(NULL != lib); - _md_iovector._open64 = (_MD_Open64)open64_func; - _md_iovector._mmap64 = (_MD_Mmap64)PR_FindSymbol(lib, "mmap64"); - _md_iovector._fstat64 = (_MD_Fstat64)PR_FindSymbol(lib, "fstat64"); - _md_iovector._stat64 = (_MD_Stat64)PR_FindSymbol(lib, "stat64"); - _md_iovector._lseek64 = (_MD_Lseek64)PR_FindSymbol(lib, "lseek64"); - (void)PR_UnloadLibrary(lib); - } - else - { - _md_iovector._open64 = open; - _md_iovector._mmap64 = _MD_Unix_mmap64; - _md_iovector._fstat64 = _MD_solaris25_fstat64; - _md_iovector._stat64 = _MD_solaris25_stat64; - _md_iovector._lseek64 = _MD_Unix_lseek64; - } -#elif defined(_PR_NO_LARGE_FILES) - _md_iovector._open64 = open; - _md_iovector._mmap64 = _MD_Unix_mmap64; - _md_iovector._fstat64 = fstat; - _md_iovector._stat64 = stat; - _md_iovector._lseek64 = _MD_Unix_lseek64; -#elif defined(_PR_HAVE_OFF64_T) -#if defined(IRIX5_3) || defined(ANDROID) - /* - * Android doesn't have open64. We pass the O_LARGEFILE flag to open - * in _MD_open. - */ - _md_iovector._open64 = open; -#else - _md_iovector._open64 = open64; -#endif - _md_iovector._mmap64 = mmap64; - _md_iovector._fstat64 = fstat64; - _md_iovector._stat64 = stat64; - _md_iovector._lseek64 = lseek64; -#elif defined(_PR_HAVE_LARGE_OFF_T) - _md_iovector._open64 = open; - _md_iovector._mmap64 = mmap; -#if defined(OSF1) && defined(__GNUC__) - _md_iovector._fstat64 = fstat_forwarder; - _md_iovector._stat64 = stat_forwarder; -#else - _md_iovector._fstat64 = fstat; - _md_iovector._stat64 = stat; -#endif - _md_iovector._lseek64 = lseek; -#else -#error "I don't know yet" -#endif - LL_I2L(minus_one, -1); -} /* _PR_InitIOV */ - -void _PR_UnixInit(void) -{ - struct sigaction sigact; - int rv; - - sigemptyset(&timer_set); - -#if !defined(_PR_PTHREADS) - - sigaddset(&timer_set, SIGALRM); - sigemptyset(&empty_set); - intr_timeout_ticks = - PR_SecondsToInterval(_PR_INTERRUPT_CHECK_INTERVAL_SECS); - -#if defined(SOLARIS) || defined(IRIX) - - if (getenv("NSPR_SIGSEGV_HANDLE")) { - sigact.sa_handler = sigsegvhandler; - sigact.sa_flags = 0; - sigact.sa_mask = timer_set; - sigaction(SIGSEGV, &sigact, 0); - } - - if (getenv("NSPR_SIGABRT_HANDLE")) { - sigact.sa_handler = sigaborthandler; - sigact.sa_flags = 0; - sigact.sa_mask = timer_set; - sigaction(SIGABRT, &sigact, 0); - } - - if (getenv("NSPR_SIGBUS_HANDLE")) { - sigact.sa_handler = sigbushandler; - sigact.sa_flags = 0; - sigact.sa_mask = timer_set; - sigaction(SIGBUS, &sigact, 0); - } - -#endif -#endif /* !defined(_PR_PTHREADS) */ - - /* - * Under HP-UX DCE threads, sigaction() installs a per-thread - * handler, so we use sigvector() to install a process-wide - * handler. - */ -#if defined(HPUX) && defined(_PR_DCETHREADS) - { - struct sigvec vec; - - vec.sv_handler = SIG_IGN; - vec.sv_mask = 0; - vec.sv_flags = 0; - rv = sigvector(SIGPIPE, &vec, NULL); - PR_ASSERT(0 == rv); - } -#else - sigact.sa_handler = SIG_IGN; - sigemptyset(&sigact.sa_mask); - sigact.sa_flags = 0; - rv = sigaction(SIGPIPE, &sigact, 0); - PR_ASSERT(0 == rv); -#endif /* HPUX && _PR_DCETHREADS */ - - _pr_rename_lock = PR_NewLock(); - PR_ASSERT(NULL != _pr_rename_lock); - _pr_Xfe_mon = PR_NewMonitor(); - PR_ASSERT(NULL != _pr_Xfe_mon); - - _PR_InitIOV(); /* one last hack */ -} - -void _PR_UnixCleanup(void) -{ - if (_pr_rename_lock) { - PR_DestroyLock(_pr_rename_lock); - _pr_rename_lock = NULL; - } - if (_pr_Xfe_mon) { - PR_DestroyMonitor(_pr_Xfe_mon); - _pr_Xfe_mon = NULL; - } -} - -#if !defined(_PR_PTHREADS) - -/* - * Variables used by the GC code, initialized in _MD_InitSegs(). - */ -static PRInt32 _pr_zero_fd = -1; -static PRLock *_pr_md_lock = NULL; - -/* - * _MD_InitSegs -- - * - * This is Unix's version of _PR_MD_INIT_SEGS(), which is - * called by _PR_InitSegs(), which in turn is called by - * PR_Init(). - */ -void _MD_InitSegs(void) -{ -#ifdef DEBUG - /* - ** Disable using mmap(2) if NSPR_NO_MMAP is set - */ - if (getenv("NSPR_NO_MMAP")) { - _pr_zero_fd = -2; - return; - } -#endif - _pr_zero_fd = open("/dev/zero",O_RDWR , 0); - /* Prevent the fd from being inherited by child processes */ - fcntl(_pr_zero_fd, F_SETFD, FD_CLOEXEC); - _pr_md_lock = PR_NewLock(); -} - -PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr) -{ - static char *lastaddr = (char*) _PR_STACK_VMBASE; - PRStatus retval = PR_SUCCESS; - int prot; - void *rv; - - PR_ASSERT(seg != 0); - PR_ASSERT(size != 0); - - PR_Lock(_pr_md_lock); - if (_pr_zero_fd < 0) { -from_heap: - seg->vaddr = PR_MALLOC(size); - if (!seg->vaddr) { - retval = PR_FAILURE; - } - else { - seg->size = size; - } - goto exit; - } - - prot = PROT_READ|PROT_WRITE; - /* - * On Alpha Linux, the user-level thread stack needs - * to be made executable because longjmp/signal seem - * to put machine instructions on the stack. - */ -#if defined(LINUX) && defined(__alpha) - prot |= PROT_EXEC; -#endif - rv = mmap((vaddr != 0) ? vaddr : lastaddr, size, prot, - _MD_MMAP_FLAGS, - _pr_zero_fd, 0); - if (rv == (void*)-1) { - goto from_heap; - } - lastaddr += size; - seg->vaddr = rv; - seg->size = size; - seg->flags = _PR_SEG_VM; - -exit: - PR_Unlock(_pr_md_lock); - return retval; -} - -void _MD_FreeSegment(PRSegment *seg) -{ - if (seg->flags & _PR_SEG_VM) - (void) munmap(seg->vaddr, seg->size); - else - PR_DELETE(seg->vaddr); -} - -#endif /* _PR_PTHREADS */ - -/* - *----------------------------------------------------------------------- - * - * PR_Now -- - * - * Returns the current time in microseconds since the epoch. - * The epoch is midnight January 1, 1970 GMT. - * The implementation is machine dependent. This is the Unix - * implementation. - * Cf. time_t time(time_t *tp) - * - *----------------------------------------------------------------------- - */ - -PR_IMPLEMENT(PRTime) -PR_Now(void) -{ - struct timeval tv; - PRInt64 s, us, s2us; - - GETTIMEOFDAY(&tv); - LL_I2L(s2us, PR_USEC_PER_SEC); - LL_I2L(s, tv.tv_sec); - LL_I2L(us, tv.tv_usec); - LL_MUL(s, s, s2us); - LL_ADD(s, s, us); - return s; -} - -#if defined(_MD_INTERVAL_USE_GTOD) -/* - * This version of interval times is based on the time of day - * capability offered by the system. This isn't valid for two reasons: - * 1) The time of day is neither linear nor montonically increasing - * 2) The units here are milliseconds. That's not appropriate for our use. - */ -PRIntervalTime _PR_UNIX_GetInterval() -{ - struct timeval time; - PRIntervalTime ticks; - - (void)GETTIMEOFDAY(&time); /* fallicy of course */ - ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; /* that's in milliseconds */ - ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC; /* so's that */ - return ticks; -} /* _PR_UNIX_GetInterval */ - -PRIntervalTime _PR_UNIX_TicksPerSecond() -{ - return 1000; /* this needs some work :) */ -} -#endif - -#if defined(HAVE_CLOCK_MONOTONIC) -PRIntervalTime _PR_UNIX_GetInterval2() -{ - struct timespec time; - PRIntervalTime ticks; - - if (clock_gettime(CLOCK_MONOTONIC, &time) != 0) { - fprintf(stderr, "clock_gettime failed: %d\n", errno); - abort(); - } - - ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; - ticks += (PRUint32)time.tv_nsec / PR_NSEC_PER_MSEC; - return ticks; -} - -PRIntervalTime _PR_UNIX_TicksPerSecond2() -{ - return 1000; -} -#endif - -#if !defined(_PR_PTHREADS) -/* - * Wait for I/O on multiple descriptors. - * - * Return 0 if timed out, return -1 if interrupted, - * else return the number of ready descriptors. - */ -PRInt32 _PR_WaitForMultipleFDs( - _PRUnixPollDesc *unixpds, - PRInt32 pdcnt, - PRIntervalTime timeout) -{ - PRPollQueue pq; - PRIntn is; - PRInt32 rv; - _PRCPU *io_cpu; - _PRUnixPollDesc *unixpd, *eunixpd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - - pq.pds = unixpds; - pq.npds = pdcnt; - - _PR_INTSOFF(is); - _PR_MD_IOQ_LOCK(); - _PR_THREAD_LOCK(me); - - pq.thr = me; - io_cpu = me->cpu; - pq.on_ioq = PR_TRUE; - pq.timeout = timeout; - _PR_ADD_TO_IOQ(pq, me->cpu); - -#if !defined(_PR_USE_POLL) - eunixpd = unixpds + pdcnt; - for (unixpd = unixpds; unixpd < eunixpd; unixpd++) { - PRInt32 osfd = unixpd->osfd; - if (unixpd->in_flags & _PR_UNIX_POLL_READ) { - FD_SET(osfd, &_PR_FD_READ_SET(me->cpu)); - _PR_FD_READ_CNT(me->cpu)[osfd]++; - } - if (unixpd->in_flags & _PR_UNIX_POLL_WRITE) { - FD_SET(osfd, &_PR_FD_WRITE_SET(me->cpu)); - (_PR_FD_WRITE_CNT(me->cpu))[osfd]++; - } - if (unixpd->in_flags & _PR_UNIX_POLL_EXCEPT) { - FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); - (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++; - } - if (osfd > _PR_IOQ_MAX_OSFD(me->cpu)) { - _PR_IOQ_MAX_OSFD(me->cpu) = osfd; - } - } -#endif /* !defined(_PR_USE_POLL) */ - - if (_PR_IOQ_TIMEOUT(me->cpu) > timeout) { - _PR_IOQ_TIMEOUT(me->cpu) = timeout; - } - - _PR_IOQ_OSFD_CNT(me->cpu) += pdcnt; - - _PR_SLEEPQ_LOCK(me->cpu); - _PR_ADD_SLEEPQ(me, timeout); - me->state = _PR_IO_WAIT; - me->io_pending = PR_TRUE; - me->io_suspended = PR_FALSE; - _PR_SLEEPQ_UNLOCK(me->cpu); - _PR_THREAD_UNLOCK(me); - _PR_MD_IOQ_UNLOCK(); - - _PR_MD_WAIT(me, timeout); - - me->io_pending = PR_FALSE; - me->io_suspended = PR_FALSE; - - /* - * This thread should run on the same cpu on which it was blocked; when - * the IO request times out the fd sets and fd counts for the - * cpu are updated below. - */ - PR_ASSERT(me->cpu == io_cpu); - - /* - ** If we timed out the pollq might still be on the ioq. Remove it - ** before continuing. - */ - if (pq.on_ioq) { - _PR_MD_IOQ_LOCK(); - /* - * Need to check pq.on_ioq again - */ - if (pq.on_ioq) { - PR_REMOVE_LINK(&pq.links); -#ifndef _PR_USE_POLL - eunixpd = unixpds + pdcnt; - for (unixpd = unixpds; unixpd < eunixpd; unixpd++) { - PRInt32 osfd = unixpd->osfd; - PRInt16 in_flags = unixpd->in_flags; - - if (in_flags & _PR_UNIX_POLL_READ) { - if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); - } - if (in_flags & _PR_UNIX_POLL_WRITE) { - if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); - } - if (in_flags & _PR_UNIX_POLL_EXCEPT) { - if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0) - FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); - } - } -#endif /* _PR_USE_POLL */ - PR_ASSERT(pq.npds == pdcnt); - _PR_IOQ_OSFD_CNT(me->cpu) -= pdcnt; - PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0); - } - _PR_MD_IOQ_UNLOCK(); - } - /* XXX Should we use _PR_FAST_INTSON or _PR_INTSON? */ - if (1 == pdcnt) { - _PR_FAST_INTSON(is); - } else { - _PR_INTSON(is); - } - - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - - rv = 0; - if (pq.on_ioq == PR_FALSE) { - /* Count the number of ready descriptors */ - while (--pdcnt >= 0) { - if (unixpds->out_flags != 0) { - rv++; - } - unixpds++; - } - } - - return rv; -} - -/* - * Unblock threads waiting for I/O - * used when interrupting threads - * - * NOTE: The thread lock should held when this function is called. - * On return, the thread lock is released. - */ -void _PR_Unblock_IO_Wait(PRThread *thr) -{ - int pri = thr->priority; - _PRCPU *cpu = thr->cpu; - - /* - * GLOBAL threads wakeup periodically to check for interrupt - */ - if (_PR_IS_NATIVE_THREAD(thr)) { - _PR_THREAD_UNLOCK(thr); - return; - } - - PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ)); - _PR_SLEEPQ_LOCK(cpu); - _PR_DEL_SLEEPQ(thr, PR_TRUE); - _PR_SLEEPQ_UNLOCK(cpu); - - PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD)); - thr->state = _PR_RUNNABLE; - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(thr, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - _PR_THREAD_UNLOCK(thr); - _PR_MD_WAKEUP_WAITER(thr); -} -#endif /* !defined(_PR_PTHREADS) */ - -/* - * When a nonblocking connect has completed, determine whether it - * succeeded or failed, and if it failed, what the error code is. - * - * The function returns the error code. An error code of 0 means - * that the nonblocking connect succeeded. - */ - -int _MD_unix_get_nonblocking_connect_error(int osfd) -{ -#if defined(NTO) - /* Neutrino does not support the SO_ERROR socket option */ - PRInt32 rv; - PRNetAddr addr; - _PRSockLen_t addrlen = sizeof(addr); - - /* Test to see if we are using the Tiny TCP/IP Stack or the Full one. */ - struct statvfs superblock; - rv = fstatvfs(osfd, &superblock); - if (rv == 0) { - if (strcmp(superblock.f_basetype, "ttcpip") == 0) { - /* Using the Tiny Stack! */ - rv = getpeername(osfd, (struct sockaddr *) &addr, - (_PRSockLen_t *) &addrlen); - if (rv == -1) { - int errno_copy = errno; /* make a copy so I don't - * accidentally reset */ - - if (errno_copy == ENOTCONN) { - struct stat StatInfo; - rv = fstat(osfd, &StatInfo); - if (rv == 0) { - time_t current_time = time(NULL); - - /* - * this is a real hack, can't explain why it - * works it just does - */ - if (abs(current_time - StatInfo.st_atime) < 5) { - return ECONNREFUSED; - } else { - return ETIMEDOUT; - } - } else { - return ECONNREFUSED; - } - } else { - return errno_copy; - } - } else { - /* No Error */ - return 0; - } - } else { - /* Have the FULL Stack which supports SO_ERROR */ - /* Hasn't been written yet, never been tested! */ - /* Jerry.Kirk@Nexwarecorp.com */ - - int err; - _PRSockLen_t optlen = sizeof(err); - - if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, - (char *) &err, &optlen) == -1) { - return errno; - } else { - return err; - } - } - } else { - return ECONNREFUSED; - } -#elif defined(UNIXWARE) - /* - * getsockopt() fails with EPIPE, so use getmsg() instead. - */ - - int rv; - int flags = 0; - rv = getmsg(osfd, NULL, NULL, &flags); - PR_ASSERT(-1 == rv || 0 == rv); - if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) { - return errno; - } - return 0; /* no error */ -#else - int err; - _PRSockLen_t optlen = sizeof(err); - if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) { - return errno; - } else { - return err; - } -#endif -} - -/************************************************************************/ - -/* -** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread -** safe. Unfortunately, neither is mozilla. To make these programs work -** in a pre-emptive threaded environment, we need to use a lock. -*/ - -void PR_XLock(void) -{ - PR_EnterMonitor(_pr_Xfe_mon); -} - -void PR_XUnlock(void) -{ - PR_ExitMonitor(_pr_Xfe_mon); -} - -PRBool PR_XIsLocked(void) -{ - return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE; -} - -void PR_XWait(int ms) -{ - PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms)); -} - -void PR_XNotify(void) -{ - PR_Notify(_pr_Xfe_mon); -} - -void PR_XNotifyAll(void) -{ - PR_NotifyAll(_pr_Xfe_mon); -} - -#if defined(HAVE_FCNTL_FILE_LOCKING) - -PRStatus -_MD_LockFile(PRInt32 f) -{ - PRInt32 rv; - struct flock arg; - - arg.l_type = F_WRLCK; - arg.l_whence = SEEK_SET; - arg.l_start = 0; - arg.l_len = 0; /* until EOF */ - rv = fcntl(f, F_SETLKW, &arg); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus -_MD_TLockFile(PRInt32 f) -{ - PRInt32 rv; - struct flock arg; - - arg.l_type = F_WRLCK; - arg.l_whence = SEEK_SET; - arg.l_start = 0; - arg.l_len = 0; /* until EOF */ - rv = fcntl(f, F_SETLK, &arg); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus -_MD_UnlockFile(PRInt32 f) -{ - PRInt32 rv; - struct flock arg; - - arg.l_type = F_UNLCK; - arg.l_whence = SEEK_SET; - arg.l_start = 0; - arg.l_len = 0; /* until EOF */ - rv = fcntl(f, F_SETLK, &arg); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -#elif defined(HAVE_BSD_FLOCK) - -#include - -PRStatus -_MD_LockFile(PRInt32 f) -{ - PRInt32 rv; - rv = flock(f, LOCK_EX); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus -_MD_TLockFile(PRInt32 f) -{ - PRInt32 rv; - rv = flock(f, LOCK_EX|LOCK_NB); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus -_MD_UnlockFile(PRInt32 f) -{ - PRInt32 rv; - rv = flock(f, LOCK_UN); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} -#else - -PRStatus -_MD_LockFile(PRInt32 f) -{ - PRInt32 rv; - rv = lockf(f, F_LOCK, 0); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus -_MD_TLockFile(PRInt32 f) -{ - PRInt32 rv; - rv = lockf(f, F_TLOCK, 0); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus -_MD_UnlockFile(PRInt32 f) -{ - PRInt32 rv; - rv = lockf(f, F_ULOCK, 0); - if (rv == 0) - return PR_SUCCESS; - _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} -#endif - -PRStatus _MD_gethostname(char *name, PRUint32 namelen) -{ - PRIntn rv; - - rv = gethostname(name, namelen); - if (0 == rv) { - return PR_SUCCESS; - } - _PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO()); - return PR_FAILURE; -} - -PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen) -{ - struct utsname info; - - PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE)); - - if (uname(&info) == -1) { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - if (PR_SI_SYSNAME == cmd) - (void)PR_snprintf(name, namelen, info.sysname); - else if (PR_SI_RELEASE == cmd) - (void)PR_snprintf(name, namelen, info.release); - else - return PR_FAILURE; - return PR_SUCCESS; -} - -/* - ******************************************************************* - * - * Memory-mapped files - * - ******************************************************************* - */ - -PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size) -{ - PRFileInfo info; - PRUint32 sz; - - LL_L2UI(sz, size); - if (sz) { - if (PR_GetOpenFileInfo(fmap->fd, &info) == PR_FAILURE) { - return PR_FAILURE; - } - if (sz > info.size) { - /* - * Need to extend the file - */ - if (fmap->prot != PR_PROT_READWRITE) { - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0); - return PR_FAILURE; - } - if (PR_Seek(fmap->fd, sz - 1, PR_SEEK_SET) == -1) { - return PR_FAILURE; - } - if (PR_Write(fmap->fd, "", 1) != 1) { - return PR_FAILURE; - } - } - } - if (fmap->prot == PR_PROT_READONLY) { - fmap->md.prot = PROT_READ; -#ifdef OSF1V4_MAP_PRIVATE_BUG - /* - * Use MAP_SHARED to work around a bug in OSF1 V4.0D - * (QAR 70220 in the OSF_QAR database) that results in - * corrupted data in the memory-mapped region. This - * bug is fixed in V5.0. - */ - fmap->md.flags = MAP_SHARED; -#else - fmap->md.flags = MAP_PRIVATE; -#endif - } else if (fmap->prot == PR_PROT_READWRITE) { - fmap->md.prot = PROT_READ | PROT_WRITE; - fmap->md.flags = MAP_SHARED; - } else { - PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY); - fmap->md.prot = PROT_READ | PROT_WRITE; - fmap->md.flags = MAP_PRIVATE; - } - return PR_SUCCESS; -} - -void * _MD_MemMap( - PRFileMap *fmap, - PRInt64 offset, - PRUint32 len) -{ - PRInt32 off; - void *addr; - - LL_L2I(off, offset); - if ((addr = mmap(0, len, fmap->md.prot, fmap->md.flags, - fmap->fd->secret->md.osfd, off)) == (void *) -1) { - _PR_MD_MAP_MMAP_ERROR(_MD_ERRNO()); - addr = NULL; - } - return addr; -} - -PRStatus _MD_MemUnmap(void *addr, PRUint32 len) -{ - if (munmap(addr, len) == 0) { - return PR_SUCCESS; - } else { - if (errno == EINVAL) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, errno); - } else { - PR_SetError(PR_UNKNOWN_ERROR, errno); - } - return PR_FAILURE; - } -} - -PRStatus _MD_CloseFileMap(PRFileMap *fmap) -{ - if ( PR_TRUE == fmap->md.isAnonFM ) { - PRStatus rc = PR_Close( fmap->fd ); - if ( PR_FAILURE == rc ) { - PR_LOG( _pr_io_lm, PR_LOG_DEBUG, - ("_MD_CloseFileMap(): error closing anonymnous file map osfd")); - return PR_FAILURE; - } - } - PR_DELETE(fmap); - return PR_SUCCESS; -} - -#if defined(_PR_NEED_FAKE_POLL) - -/* - * Some platforms don't have poll(). For easier porting of code - * that calls poll(), we emulate poll() using select(). - */ - -int poll(struct pollfd *filedes, unsigned long nfds, int timeout) -{ - int i; - int rv; - int maxfd; - fd_set rd, wr, ex; - struct timeval tv, *tvp; - - if (timeout < 0 && timeout != -1) { - errno = EINVAL; - return -1; - } - - if (timeout == -1) { - tvp = NULL; - } else { - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - tvp = &tv; - } - - maxfd = -1; - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); - - for (i = 0; i < nfds; i++) { - int osfd = filedes[i].fd; - int events = filedes[i].events; - PRBool fdHasEvent = PR_FALSE; - - if (osfd < 0) { - continue; /* Skip this osfd. */ - } - - /* - * Map the poll events to the select fd_sets. - * POLLIN, POLLRDNORM ===> readable - * POLLOUT, POLLWRNORM ===> writable - * POLLPRI, POLLRDBAND ===> exception - * POLLNORM, POLLWRBAND (and POLLMSG on some platforms) - * are ignored. - * - * The output events POLLERR and POLLHUP are never turned on. - * POLLNVAL may be turned on. - */ - - if (events & (POLLIN | POLLRDNORM)) { - FD_SET(osfd, &rd); - fdHasEvent = PR_TRUE; - } - if (events & (POLLOUT | POLLWRNORM)) { - FD_SET(osfd, &wr); - fdHasEvent = PR_TRUE; - } - if (events & (POLLPRI | POLLRDBAND)) { - FD_SET(osfd, &ex); - fdHasEvent = PR_TRUE; - } - if (fdHasEvent && osfd > maxfd) { - maxfd = osfd; - } - } - - rv = select(maxfd + 1, &rd, &wr, &ex, tvp); - - /* Compute poll results */ - if (rv > 0) { - rv = 0; - for (i = 0; i < nfds; i++) { - PRBool fdHasEvent = PR_FALSE; - - filedes[i].revents = 0; - if (filedes[i].fd < 0) { - continue; - } - if (FD_ISSET(filedes[i].fd, &rd)) { - if (filedes[i].events & POLLIN) { - filedes[i].revents |= POLLIN; - } - if (filedes[i].events & POLLRDNORM) { - filedes[i].revents |= POLLRDNORM; - } - fdHasEvent = PR_TRUE; - } - if (FD_ISSET(filedes[i].fd, &wr)) { - if (filedes[i].events & POLLOUT) { - filedes[i].revents |= POLLOUT; - } - if (filedes[i].events & POLLWRNORM) { - filedes[i].revents |= POLLWRNORM; - } - fdHasEvent = PR_TRUE; - } - if (FD_ISSET(filedes[i].fd, &ex)) { - if (filedes[i].events & POLLPRI) { - filedes[i].revents |= POLLPRI; - } - if (filedes[i].events & POLLRDBAND) { - filedes[i].revents |= POLLRDBAND; - } - fdHasEvent = PR_TRUE; - } - if (fdHasEvent) { - rv++; - } - } - PR_ASSERT(rv > 0); - } else if (rv == -1 && errno == EBADF) { - rv = 0; - for (i = 0; i < nfds; i++) { - filedes[i].revents = 0; - if (filedes[i].fd < 0) { - continue; - } - if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) { - filedes[i].revents = POLLNVAL; - rv++; - } - } - PR_ASSERT(rv > 0); - } - PR_ASSERT(-1 != timeout || rv != 0); - - return rv; -} -#endif /* _PR_NEED_FAKE_POLL */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/unix_errors.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/unix_errors.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/unix_errors.c 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/unix_errors.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,849 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#if defined(_PR_POLL_AVAILABLE) -#include -#endif -#include - -void _MD_unix_map_default_error(int err) -{ - PRErrorCode prError; - - switch (err ) { - case EACCES: - prError = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case EADDRINUSE: - prError = PR_ADDRESS_IN_USE_ERROR; - break; - case EADDRNOTAVAIL: - prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; - break; - case EAFNOSUPPORT: - prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; - break; - case EAGAIN: - prError = PR_WOULD_BLOCK_ERROR; - break; - /* - * On QNX and Neutrino, EALREADY is defined as EBUSY. - */ -#if EALREADY != EBUSY - case EALREADY: - prError = PR_ALREADY_INITIATED_ERROR; - break; -#endif - case EBADF: - prError = PR_BAD_DESCRIPTOR_ERROR; - break; -#ifdef EBADMSG - case EBADMSG: - prError = PR_IO_ERROR; - break; -#endif - case EBUSY: - prError = PR_FILESYSTEM_MOUNTED_ERROR; - break; - case ECONNABORTED: - prError = PR_CONNECT_ABORTED_ERROR; - break; - case ECONNREFUSED: - prError = PR_CONNECT_REFUSED_ERROR; - break; - case ECONNRESET: - prError = PR_CONNECT_RESET_ERROR; - break; - case EDEADLK: - prError = PR_DEADLOCK_ERROR; - break; -#ifdef EDIRCORRUPTED - case EDIRCORRUPTED: - prError = PR_DIRECTORY_CORRUPTED_ERROR; - break; -#endif -#ifdef EDQUOT - case EDQUOT: - prError = PR_NO_DEVICE_SPACE_ERROR; - break; -#endif - case EEXIST: - prError = PR_FILE_EXISTS_ERROR; - break; - case EFAULT: - prError = PR_ACCESS_FAULT_ERROR; - break; - case EFBIG: - prError = PR_FILE_TOO_BIG_ERROR; - break; - case EHOSTUNREACH: - case EHOSTDOWN: - prError = PR_HOST_UNREACHABLE_ERROR; - break; - case EINPROGRESS: - prError = PR_IN_PROGRESS_ERROR; - break; - case EINTR: - prError = PR_PENDING_INTERRUPT_ERROR; - break; - case EINVAL: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case EIO: - prError = PR_IO_ERROR; - break; - case EISCONN: - prError = PR_IS_CONNECTED_ERROR; - break; - case EISDIR: - prError = PR_IS_DIRECTORY_ERROR; - break; - case ELOOP: - prError = PR_LOOP_ERROR; - break; - case EMFILE: - prError = PR_PROC_DESC_TABLE_FULL_ERROR; - break; - case EMLINK: - prError = PR_MAX_DIRECTORY_ENTRIES_ERROR; - break; - case EMSGSIZE: - prError = PR_INVALID_ARGUMENT_ERROR; - break; -#ifdef EMULTIHOP - case EMULTIHOP: - prError = PR_REMOTE_FILE_ERROR; - break; -#endif - case ENAMETOOLONG: - prError = PR_NAME_TOO_LONG_ERROR; - break; - case ENETUNREACH: - prError = PR_NETWORK_UNREACHABLE_ERROR; - break; - case ENFILE: - prError = PR_SYS_DESC_TABLE_FULL_ERROR; - break; - /* - * On SCO OpenServer 5, ENOBUFS is defined as ENOSR. - */ -#if defined(ENOBUFS) && (ENOBUFS != ENOSR) - case ENOBUFS: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; -#endif - case ENODEV: - prError = PR_FILE_NOT_FOUND_ERROR; - break; - case ENOENT: - prError = PR_FILE_NOT_FOUND_ERROR; - break; - case ENOLCK: - prError = PR_FILE_IS_LOCKED_ERROR; - break; -#ifdef ENOLINK - case ENOLINK: - prError = PR_REMOTE_FILE_ERROR; - break; -#endif - case ENOMEM: - prError = PR_OUT_OF_MEMORY_ERROR; - break; - case ENOPROTOOPT: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case ENOSPC: - prError = PR_NO_DEVICE_SPACE_ERROR; - break; -#ifdef ENOSR - case ENOSR: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; -#endif - case ENOSYS: - prError = PR_NOT_IMPLEMENTED_ERROR; - break; - case ENOTCONN: - prError = PR_NOT_CONNECTED_ERROR; - break; - case ENOTDIR: - prError = PR_NOT_DIRECTORY_ERROR; - break; - case ENOTSOCK: - prError = PR_NOT_SOCKET_ERROR; - break; - case ENXIO: - prError = PR_FILE_NOT_FOUND_ERROR; - break; - case EOPNOTSUPP: - prError = PR_NOT_TCP_SOCKET_ERROR; - break; -#ifdef EOVERFLOW - case EOVERFLOW: - prError = PR_BUFFER_OVERFLOW_ERROR; - break; -#endif - case EPERM: - prError = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case EPIPE: - prError = PR_CONNECT_RESET_ERROR; - break; -#ifdef EPROTO - case EPROTO: - prError = PR_IO_ERROR; - break; -#endif - case EPROTONOSUPPORT: - prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; - break; - case EPROTOTYPE: - prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; - break; - case ERANGE: - prError = PR_INVALID_METHOD_ERROR; - break; - case EROFS: - prError = PR_READ_ONLY_FILESYSTEM_ERROR; - break; - case ESPIPE: - prError = PR_INVALID_METHOD_ERROR; - break; - case ETIMEDOUT: - prError = PR_IO_TIMEOUT_ERROR; - break; -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: - prError = PR_WOULD_BLOCK_ERROR; - break; -#endif - case EXDEV: - prError = PR_NOT_SAME_DEVICE_ERROR; - break; - default: - prError = PR_UNKNOWN_ERROR; - break; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_opendir_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_closedir_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EINVAL: - prError = PR_BAD_DESCRIPTOR_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_readdir_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case 0: - case ENOENT: - prError = PR_NO_MORE_FILES_ERROR; - break; -#ifdef EOVERFLOW - case EOVERFLOW: - prError = PR_IO_ERROR; - break; -#endif - case EINVAL: - prError = PR_IO_ERROR; - break; - case ENXIO: - prError = PR_IO_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_unlink_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EPERM: - prError = PR_IS_DIRECTORY_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_stat_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ETIMEDOUT: - prError = PR_REMOTE_FILE_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_fstat_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ETIMEDOUT: - prError = PR_REMOTE_FILE_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_rename_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EEXIST: - prError = PR_DIRECTORY_NOT_EMPTY_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_access_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ETIMEDOUT: - prError = PR_REMOTE_FILE_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_mkdir_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_rmdir_error(int err) -{ - PRErrorCode prError; - - switch (err) { - /* - * On AIX 4.3, ENOTEMPTY is defined as EEXIST. - */ -#if ENOTEMPTY != EEXIST - case ENOTEMPTY: - prError = PR_DIRECTORY_NOT_EMPTY_ERROR; - break; -#endif - case EEXIST: - prError = PR_DIRECTORY_NOT_EMPTY_ERROR; - break; - case EINVAL: - prError = PR_DIRECTORY_NOT_EMPTY_ERROR; - break; - case ETIMEDOUT: - prError = PR_REMOTE_FILE_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_read_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EINVAL: - prError = PR_INVALID_METHOD_ERROR; - break; - case ENXIO: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_write_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EINVAL: - prError = PR_INVALID_METHOD_ERROR; - break; - case ENXIO: - prError = PR_INVALID_METHOD_ERROR; - break; - case ETIMEDOUT: - prError = PR_REMOTE_FILE_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_lseek_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_fsync_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ETIMEDOUT: - prError = PR_REMOTE_FILE_ERROR; - break; - case EINVAL: - prError = PR_INVALID_METHOD_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_close_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ETIMEDOUT: - prError = PR_REMOTE_FILE_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_socket_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ENOMEM: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_socketavailable_error(int err) -{ - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); -} - -void _MD_unix_map_recv_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_recvfrom_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_send_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_sendto_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_writev_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_accept_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ENODEV: - prError = PR_NOT_TCP_SOCKET_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_connect_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EACCES: - prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; - break; -#if defined(UNIXWARE) - /* - * On some platforms, if we connect to a port on the local host - * (the loopback address) that no process is listening on, we get - * EIO instead of ECONNREFUSED. - */ - case EIO: - prError = PR_CONNECT_REFUSED_ERROR; - break; -#endif - case ELOOP: - prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; - break; - case ENOENT: - prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; - break; - case ENXIO: - prError = PR_IO_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_bind_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EINVAL: - prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; - break; - /* - * UNIX domain sockets are not supported in NSPR - */ - case EIO: - case EISDIR: - case ELOOP: - case ENOENT: - case ENOTDIR: - case EROFS: - prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_listen_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_shutdown_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_socketpair_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ENOMEM: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_getsockname_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ENOMEM: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_getpeername_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case ENOMEM: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_getsockopt_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EINVAL: - prError = PR_BUFFER_OVERFLOW_ERROR; - break; - case ENOMEM: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_setsockopt_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EINVAL: - prError = PR_BUFFER_OVERFLOW_ERROR; - break; - case ENOMEM: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_open_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EAGAIN: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case EBUSY: - prError = PR_IO_ERROR; - break; - case ENODEV: - prError = PR_FILE_NOT_FOUND_ERROR; - break; - case ENOMEM: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; -#ifdef EOVERFLOW - case EOVERFLOW: - prError = PR_FILE_TOO_BIG_ERROR; - break; -#endif - case ETIMEDOUT: - prError = PR_REMOTE_FILE_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_mmap_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EAGAIN: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case EMFILE: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case ENODEV: - prError = PR_OPERATION_NOT_SUPPORTED_ERROR; - break; - case ENXIO: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_gethostname_error(int err) -{ - _MD_unix_map_default_error(err); -} - -void _MD_unix_map_select_error(int err) -{ - _MD_unix_map_default_error(err); -} - -#if defined(_PR_POLL_AVAILABLE) || defined(_PR_NEED_FAKE_POLL) -void _MD_unix_map_poll_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EAGAIN: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_poll_revents_error(int err) -{ - if (err & POLLNVAL) - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF); - else if (err & POLLHUP) - PR_SetError(PR_CONNECT_RESET_ERROR, EPIPE); - else if (err & POLLERR) - PR_SetError(PR_IO_ERROR, EIO); - else - PR_SetError(PR_UNKNOWN_ERROR, err); -} -#endif /* _PR_POLL_AVAILABLE || _PR_NEED_FAKE_POLL */ - - -void _MD_unix_map_flock_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EINVAL: - prError = PR_BAD_DESCRIPTOR_ERROR; - break; - case EWOULDBLOCK: - prError = PR_FILE_IS_LOCKED_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_unix_map_lockf_error(int err) -{ - PRErrorCode prError; - - switch (err) { - case EACCES: - prError = PR_FILE_IS_LOCKED_ERROR; - break; - case EDEADLK: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - default: - _MD_unix_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -#ifdef AIX -void _MD_aix_map_sendfile_error(int err) -{ - _MD_unix_map_default_error(err); -} -#endif /* AIX */ - -#ifdef HPUX11 -void _MD_hpux_map_sendfile_error(int err) -{ - _MD_unix_map_default_error(err); -} -#endif /* HPUX11 */ - -#ifdef SOLARIS -void _MD_solaris_map_sendfile_error(int err) -{ - PRErrorCode prError; - - switch (err) { - /* - * Solaris defines a 0 return value for sendfile to mean end-of-file. - */ - case 0: - prError = PR_END_OF_FILE_ERROR; - break; - - default: - _MD_unix_map_default_error(err) ; - return; - } - PR_SetError(prError, err); -} -#endif /* SOLARIS */ - -#ifdef LINUX -void _MD_linux_map_sendfile_error(int err) -{ - _MD_unix_map_default_error(err) ; -} -#endif /* LINUX */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/unixware.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/unixware.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/unixware.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/unixware.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,551 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#if !defined (USE_SVR4_THREADS) - -/* - * using only NSPR threads here - */ - -#include - -void _MD_EarlyInit(void) -{ -} - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - if (isCurrent) { - (void) setjmp(CONTEXT(t)); - } - *np = sizeof(CONTEXT(t)) / sizeof(PRWord); - return (PRWord *) CONTEXT(t); -} - -#ifdef ALARMS_BREAK_TCP /* I don't think they do */ - -PRInt32 _MD_connect(PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, - PRIntervalTime timeout) -{ - PRInt32 rv; - - _MD_BLOCK_CLOCK_INTERRUPTS(); - rv = _connect(osfd,addr,addrlen); - _MD_UNBLOCK_CLOCK_INTERRUPTS(); -} - -PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen, - PRIntervalTime timeout) -{ - PRInt32 rv; - - _MD_BLOCK_CLOCK_INTERRUPTS(); - rv = _accept(osfd,addr,addrlen); - _MD_UNBLOCK_CLOCK_INTERRUPTS(); - return(rv); -} -#endif - -/* - * These are also implemented in pratom.c using NSPR locks. Any reason - * this might be better or worse? If you like this better, define - * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h - */ -#ifdef _PR_HAVE_ATOMIC_OPS -/* Atomic operations */ -#include -static FILE *_uw_semf; - -void -_MD_INIT_ATOMIC(void) -{ - /* Sigh. Sure wish SYSV semaphores weren't such a pain to use */ - if ((_uw_semf = tmpfile()) == NULL) - PR_ASSERT(0); - - return; -} - -void -_MD_ATOMIC_INCREMENT(PRInt32 *val) -{ - flockfile(_uw_semf); - (*val)++; - unflockfile(_uw_semf); -} - -void -_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) -{ - flockfile(_uw_semf); - (*ptr) += val; - unflockfile(_uw_semf); -} - -void -_MD_ATOMIC_DECREMENT(PRInt32 *val) -{ - flockfile(_uw_semf); - (*val)--; - unflockfile(_uw_semf); -} - -void -_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) -{ - flockfile(_uw_semf); - *val = newval; - unflockfile(_uw_semf); -} -#endif - -void -_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) -{ - return; -} - -PRStatus -_MD_InitializeThread(PRThread *thread) -{ - return PR_SUCCESS; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - _PR_MD_SWITCH_CONTEXT(thread); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread) { - PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); - } - return PR_SUCCESS; -} - -/* These functions should not be called for Unixware */ -void -_MD_YIELD(void) -{ - PR_NOT_REACHED("_MD_YIELD should not be called for Unixware."); -} - -PRStatus -_MD_CREATE_THREAD( - PRThread *thread, - void (*start) (void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware."); -} - -#else /* USE_SVR4_THREADS */ - -/* NOTE: - * SPARC v9 (Ultras) do have an atomic test-and-set operation. But - * SPARC v8 doesn't. We should detect in the init if we are running on - * v8 or v9, and then use assembly where we can. - */ - -#include -#include - -static mutex_t _unixware_atomic = DEFAULTMUTEX; - -#define TEST_THEN_ADD(where, inc) \ - if (mutex_lock(&_unixware_atomic) != 0)\ - PR_ASSERT(0);\ - *where += inc;\ - if (mutex_unlock(&_unixware_atomic) != 0)\ - PR_ASSERT(0); - -#define TEST_THEN_SET(where, val) \ - if (mutex_lock(&_unixware_atomic) != 0)\ - PR_ASSERT(0);\ - *where = val;\ - if (mutex_unlock(&_unixware_atomic) != 0)\ - PR_ASSERT(0); - -void -_MD_INIT_ATOMIC(void) -{ -} - -void -_MD_ATOMIC_INCREMENT(PRInt32 *val) -{ - TEST_THEN_ADD(val, 1); -} - -void -_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) -{ - TEST_THEN_ADD(ptr, val); -} - -void -_MD_ATOMIC_DECREMENT(PRInt32 *val) -{ - TEST_THEN_ADD(val, 0xffffffff); -} - -void -_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) -{ - TEST_THEN_SET(val, newval); -} - -#include -#include -#include - -#include -#include -#include - - -THREAD_KEY_T threadid_key; -THREAD_KEY_T cpuid_key; -THREAD_KEY_T last_thread_key; -static sigset_t set, oldset; - -void _MD_EarlyInit(void) -{ - THR_KEYCREATE(&threadid_key, NULL); - THR_KEYCREATE(&cpuid_key, NULL); - THR_KEYCREATE(&last_thread_key, NULL); - sigemptyset(&set); - sigaddset(&set, SIGALRM); -} - -PRStatus _MD_CREATE_THREAD(PRThread *thread, - void (*start)(void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - long flags; - - /* mask out SIGALRM for native thread creation */ - thr_sigsetmask(SIG_BLOCK, &set, &oldset); - - flags = (state == PR_JOINABLE_THREAD ? THR_SUSPENDED/*|THR_NEW_LWP*/ - : THR_SUSPENDED|THR_DETACHED/*|THR_NEW_LWP*/); - if (_PR_IS_GCABLE_THREAD(thread) || - (scope == PR_GLOBAL_BOUND_THREAD)) - flags |= THR_BOUND; - - if (thr_create(NULL, thread->stack->stackSize, - (void *(*)(void *)) start, (void *) thread, - flags, - &thread->md.handle)) { - thr_sigsetmask(SIG_SETMASK, &oldset, NULL); - return PR_FAILURE; - } - - - /* When the thread starts running, then the lwpid is set to the right - * value. Until then we want to mark this as 'uninit' so that - * its register state is initialized properly for GC */ - - thread->md.lwpid = -1; - thr_sigsetmask(SIG_SETMASK, &oldset, NULL); - _MD_NEW_SEM(&thread->md.waiter_sem, 0); - - if ((scope == PR_GLOBAL_THREAD) || (scope == PR_GLOBAL_BOUND_THREAD)) { - thread->flags |= _PR_GLOBAL_SCOPE; - } - - /* - ** Set the thread priority. This will also place the thread on - ** the runQ. - ** - ** Force PR_SetThreadPriority to set the priority by - ** setting thread->priority to 100. - */ - { - int pri; - pri = thread->priority; - thread->priority = 100; - PR_SetThreadPriority( thread, pri ); - - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("(0X%x)[Start]: on to runq at priority %d", - thread, thread->priority)); - } - - /* Activate the thread */ - if (thr_continue( thread->md.handle ) ) { - return PR_FAILURE; - } - return PR_SUCCESS; -} - -void _MD_cleanup_thread(PRThread *thread) -{ - thread_t hdl; - PRMonitor *mon; - - hdl = thread->md.handle; - - /* - ** First, suspend the thread (unless it's the active one) - ** Because we suspend it first, we don't have to use LOCK_SCHEDULER to - ** prevent both of us modifying the thread structure at the same time. - */ - if ( thread != _PR_MD_CURRENT_THREAD() ) { - thr_suspend(hdl); - } - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("(0X%x)[DestroyThread]\n", thread)); - - _MD_DESTROY_SEM(&thread->md.waiter_sem); -} - -void _MD_SET_PRIORITY(_MDThread *md_thread, PRUintn newPri) -{ - if(thr_setprio((thread_t)md_thread->handle, newPri)) { - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("_PR_SetThreadPriority: can't set thread priority\n")); - } -} - -void _MD_WAIT_CV( - struct _MDCVar *md_cv, struct _MDLock *md_lock, PRIntervalTime timeout) -{ - struct timespec tt; - PRUint32 msec; - int rv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - msec = PR_IntervalToMilliseconds(timeout); - - GETTIME (&tt); - - tt.tv_sec += msec / PR_MSEC_PER_SEC; - tt.tv_nsec += (msec % PR_MSEC_PER_SEC) * PR_NSEC_PER_MSEC; - /* Check for nsec overflow - otherwise we'll get an EINVAL */ - if (tt.tv_nsec >= PR_NSEC_PER_SEC) { - tt.tv_sec++; - tt.tv_nsec -= PR_NSEC_PER_SEC; - } - me->md.sp = unixware_getsp(); - - - /* XXX Solaris 2.5.x gives back EINTR occasionally for no reason - * hence ignore EINTR for now */ - - COND_TIMEDWAIT(&md_cv->cv, &md_lock->lock, &tt); -} - -void _MD_lock(struct _MDLock *md_lock) -{ - mutex_lock(&md_lock->lock); -} - -void _MD_unlock(struct _MDLock *md_lock) -{ - mutex_unlock(&((md_lock)->lock)); -} - - -PRThread *_pr_current_thread_tls() -{ - PRThread *ret; - - thr_getspecific(threadid_key, (void **)&ret); - return ret; -} - -PRStatus -_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - _MD_WAIT_SEM(&thread->md.waiter_sem); - return PR_SUCCESS; -} - -PRStatus -_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread == NULL) { - return PR_SUCCESS; - } - _MD_POST_SEM(&thread->md.waiter_sem); - return PR_SUCCESS; -} - -_PRCPU *_pr_current_cpu_tls() -{ - _PRCPU *ret; - - thr_getspecific(cpuid_key, (void **)&ret); - return ret; -} - -PRThread *_pr_last_thread_tls() -{ - PRThread *ret; - - thr_getspecific(last_thread_key, (void **)&ret); - return ret; -} - -_MDLock _pr_ioq_lock; - -void _MD_INIT_IO (void) -{ - _MD_NEW_LOCK(&_pr_ioq_lock); -} - -PRStatus _MD_InitializeThread(PRThread *thread) -{ - if (!_PR_IS_NATIVE_THREAD(thread)) - return; - /* prime the sp; substract 4 so we don't hit the assert that - * curr sp > base_stack - */ - thread->md.sp = (uint_t) thread->stack->allocBase - sizeof(long); - thread->md.lwpid = _lwp_self(); - thread->md.handle = THR_SELF(); - - /* all threads on Solaris are global threads from NSPR's perspective - * since all of them are mapped to Solaris threads. - */ - thread->flags |= _PR_GLOBAL_SCOPE; - - /* For primordial/attached thread, we don't create an underlying native thread. - * So, _MD_CREATE_THREAD() does not get called. We need to do initialization - * like allocating thread's synchronization variables and set the underlying - * native thread's priority. - */ - if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { - _MD_NEW_SEM(&thread->md.waiter_sem, 0); - _MD_SET_PRIORITY(&(thread->md), thread->priority); - } - return PR_SUCCESS; -} - -static sigset_t old_mask; /* store away original gc thread sigmask */ -static int gcprio; /* store away original gc thread priority */ -static lwpid_t *all_lwps=NULL; /* list of lwps that we suspended */ -static int num_lwps ; -static int suspendAllOn = 0; - -#define VALID_SP(sp, bottom, top) \ - (((uint_t)(sp)) > ((uint_t)(bottom)) && ((uint_t)(sp)) < ((uint_t)(top))) - -void unixware_preempt_off() -{ - sigset_t set; - (void)sigfillset(&set); - sigprocmask (SIG_SETMASK, &set, &old_mask); -} - -void unixware_preempt_on() -{ - sigprocmask (SIG_SETMASK, &old_mask, NULL); -} - -void _MD_Begin_SuspendAll() -{ - unixware_preempt_off(); - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin_SuspendAll\n")); - /* run at highest prio so I cannot be preempted */ - thr_getprio(thr_self(), &gcprio); - thr_setprio(thr_self(), 0x7fffffff); - suspendAllOn = 1; -} - -void _MD_End_SuspendAll() -{ -} - -void _MD_End_ResumeAll() -{ - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End_ResumeAll\n")); - thr_setprio(thr_self(), gcprio); - unixware_preempt_on(); - suspendAllOn = 0; -} - -void _MD_Suspend(PRThread *thr) -{ - int lwp_fd, result; - int lwp_main_proc_fd = 0; - - thr_suspend(thr->md.handle); - if (!_PR_IS_GCABLE_THREAD(thr)) - return; - /* XXX Primordial thread can't be bound to an lwp, hence there is no - * way we can assume that we can get the lwp status for primordial - * thread reliably. Hence we skip this for primordial thread, hoping - * that the SP is saved during lock and cond. wait. - * XXX - Again this is concern only for java interpreter, not for the - * server, 'cause primordial thread in the server does not do java work - */ - if (thr->flags & _PR_PRIMORDIAL) - return; - - /* if the thread is not started yet then don't do anything */ - if (!suspendAllOn || thr->md.lwpid == -1) - return; - -} -void _MD_Resume(PRThread *thr) -{ - if (!_PR_IS_GCABLE_THREAD(thr) || !suspendAllOn){ - /*XXX When the suspendAllOn is set, we will be trying to do lwp_suspend - * during that time we can't call any thread lib or libc calls. Hence - * make sure that no resume is requested for Non gcable thread - * during suspendAllOn */ - PR_ASSERT(!suspendAllOn); - thr_continue(thr->md.handle); - return; - } - if (thr->md.lwpid == -1) - return; - - if ( _lwp_continue(thr->md.lwpid) < 0) { - PR_ASSERT(0); /* ARGH, we are hosed! */ - } -} - - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ - if (isCurrent) { - (void) getcontext(CONTEXT(t)); /* XXX tune me: set md_IRIX.c */ - } - *np = NGREG; - if (t->md.lwpid == -1) - memset(&t->md.context.uc_mcontext.gregs[0], 0, NGREG * sizeof(PRWord)); - return (PRWord*) &t->md.context.uc_mcontext.gregs[0]; -} - -int -_pr_unixware_clock_gettime (struct timespec *tp) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - tp->tv_sec = tv.tv_sec; - tp->tv_nsec = tv.tv_usec * 1000; - return 0; -} - - -#endif /* USE_SVR4_THREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxpoll.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxpoll.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxpoll.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxpoll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,676 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#if defined(_PR_PTHREADS) - -#error "This file should not be compiled" - -#else /* defined(_PR_PTHREADS) */ - -#include "primpl.h" - -#include - -#include -#ifdef _PR_USE_POLL -#include -#endif - -#if defined(_PR_USE_POLL) -static PRInt32 NativeThreadPoll( - PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - /* - * This function is mostly duplicated from ptio.s's PR_Poll(). - */ - PRInt32 ready = 0; - /* - * For restarting poll() if it is interrupted by a signal. - * We use these variables to figure out how much time has - * elapsed and how much of the timeout still remains. - */ - PRIntn index, msecs; - struct pollfd *syspoll = NULL; - PRIntervalTime start, elapsed, remaining; - - syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd)); - if (NULL == syspoll) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - for (index = 0; index < npds; ++index) - { - PRFileDesc *bottom; - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) - { - if (pds[index].in_flags & PR_POLL_READ) - { - in_flags_read = (pds[index].fd->methods->poll)( - pds[index].fd, - pds[index].in_flags & ~PR_POLL_WRITE, - &out_flags_read); - } - if (pds[index].in_flags & PR_POLL_WRITE) - { - in_flags_write = (pds[index].fd->methods->poll)( - pds[index].fd, - pds[index].in_flags & ~PR_POLL_READ, - &out_flags_write); - } - if ((0 != (in_flags_read & out_flags_read)) - || (0 != (in_flags_write & out_flags_write))) - { - /* this one is ready right now */ - if (0 == ready) - { - /* - * We will return without calling the system - * poll function. So zero the out_flags - * fields of all the poll descriptors before - * this one. - */ - int i; - for (i = 0; i < index; i++) - { - pds[i].out_flags = 0; - } - } - ready += 1; - pds[index].out_flags = out_flags_read | out_flags_write; - } - else - { - pds[index].out_flags = 0; /* pre-condition */ - /* now locate the NSPR layer at the bottom of the stack */ - bottom = PR_GetIdentitiesLayer(pds[index].fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); /* what to do about that? */ - if ((NULL != bottom) - && (_PR_FILEDESC_OPEN == bottom->secret->state)) - { - if (0 == ready) - { - syspoll[index].fd = bottom->secret->md.osfd; - syspoll[index].events = 0; /* pre-condition */ - if (in_flags_read & PR_POLL_READ) - { - pds[index].out_flags |= - _PR_POLL_READ_SYS_READ; - syspoll[index].events |= POLLIN; - } - if (in_flags_read & PR_POLL_WRITE) - { - pds[index].out_flags |= - _PR_POLL_READ_SYS_WRITE; - syspoll[index].events |= POLLOUT; - } - if (in_flags_write & PR_POLL_READ) - { - pds[index].out_flags |= - _PR_POLL_WRITE_SYS_READ; - syspoll[index].events |= POLLIN; - } - if (in_flags_write & PR_POLL_WRITE) - { - pds[index].out_flags |= - _PR_POLL_WRITE_SYS_WRITE; - syspoll[index].events |= POLLOUT; - } - if (pds[index].in_flags & PR_POLL_EXCEPT) - syspoll[index].events |= POLLPRI; - } - } - else - { - if (0 == ready) - { - int i; - for (i = 0; i < index; i++) - { - pds[i].out_flags = 0; - } - } - ready += 1; /* this will cause an abrupt return */ - pds[index].out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - else - { - /* make poll() ignore this entry */ - syspoll[index].fd = -1; - syspoll[index].events = 0; - pds[index].out_flags = 0; - } - } - - if (0 == ready) - { - switch (timeout) - { - case PR_INTERVAL_NO_WAIT: msecs = 0; break; - case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break; - default: - msecs = PR_IntervalToMilliseconds(timeout); - start = PR_IntervalNow(); - } - -retry: - ready = _MD_POLL(syspoll, npds, msecs); - if (-1 == ready) - { - PRIntn oserror = errno; - - if (EINTR == oserror) - { - if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; - else if (timeout == PR_INTERVAL_NO_WAIT) ready = 0; - else - { - elapsed = (PRIntervalTime)(PR_IntervalNow() - start); - if (elapsed > timeout) ready = 0; /* timed out */ - else - { - remaining = timeout - elapsed; - msecs = PR_IntervalToMilliseconds(remaining); - goto retry; - } - } - } - else _PR_MD_MAP_POLL_ERROR(oserror); - } - else if (ready > 0) - { - for (index = 0; index < npds; ++index) - { - PRInt16 out_flags = 0; - if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) - { - if (0 != syspoll[index].revents) - { - /* - ** Set up the out_flags so that it contains the - ** bits that the highest layer thinks are nice - ** to have. Then the client of that layer will - ** call the appropriate I/O function and maybe - ** the protocol will make progress. - */ - if (syspoll[index].revents & POLLIN) - { - if (pds[index].out_flags - & _PR_POLL_READ_SYS_READ) - { - out_flags |= PR_POLL_READ; - } - if (pds[index].out_flags - & _PR_POLL_WRITE_SYS_READ) - { - out_flags |= PR_POLL_WRITE; - } - } - if (syspoll[index].revents & POLLOUT) - { - if (pds[index].out_flags - & _PR_POLL_READ_SYS_WRITE) - { - out_flags |= PR_POLL_READ; - } - if (pds[index].out_flags - & _PR_POLL_WRITE_SYS_WRITE) - { - out_flags |= PR_POLL_WRITE; - } - } - if (syspoll[index].revents & POLLPRI) - out_flags |= PR_POLL_EXCEPT; - if (syspoll[index].revents & POLLERR) - out_flags |= PR_POLL_ERR; - if (syspoll[index].revents & POLLNVAL) - out_flags |= PR_POLL_NVAL; - if (syspoll[index].revents & POLLHUP) - out_flags |= PR_POLL_HUP; - } - } - pds[index].out_flags = out_flags; - } - } - } - - PR_DELETE(syspoll); - return ready; - -} /* NativeThreadPoll */ -#endif /* defined(_PR_USE_POLL) */ - -#if !defined(_PR_USE_POLL) -static PRInt32 NativeThreadSelect( - PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - /* - * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL(). - */ - fd_set rd, wt, ex; - PRFileDesc *bottom; - PRPollDesc *pd, *epd; - PRInt32 maxfd = -1, ready, err; - PRIntervalTime remaining, elapsed, start; - - struct timeval tv, *tvp = NULL; - - FD_ZERO(&rd); - FD_ZERO(&wt); - FD_ZERO(&ex); - - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - if (pd->in_flags & PR_POLL_READ) - { - in_flags_read = (pd->fd->methods->poll)( - pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); - } - if (pd->in_flags & PR_POLL_WRITE) - { - in_flags_write = (pd->fd->methods->poll)( - pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); - } - if ((0 != (in_flags_read & out_flags_read)) - || (0 != (in_flags_write & out_flags_write))) - { - /* this one's ready right now */ - if (0 == ready) - { - /* - * We will have to return without calling the - * system poll/select function. So zero the - * out_flags fields of all the poll descriptors - * before this one. - */ - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; - pd->out_flags = out_flags_read | out_flags_write; - } - else - { - pd->out_flags = 0; /* pre-condition */ - - /* make sure this is an NSPR supported stack */ - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); /* what to do about that? */ - if ((NULL != bottom) - && (_PR_FILEDESC_OPEN == bottom->secret->state)) - { - if (0 == ready) - { - PRInt32 osfd = bottom->secret->md.osfd; - if (osfd > maxfd) maxfd = osfd; - if (in_flags_read & PR_POLL_READ) - { - pd->out_flags |= _PR_POLL_READ_SYS_READ; - FD_SET(osfd, &rd); - } - if (in_flags_read & PR_POLL_WRITE) - { - pd->out_flags |= _PR_POLL_READ_SYS_WRITE; - FD_SET(osfd, &wt); - } - if (in_flags_write & PR_POLL_READ) - { - pd->out_flags |= _PR_POLL_WRITE_SYS_READ; - FD_SET(osfd, &rd); - } - if (in_flags_write & PR_POLL_WRITE) - { - pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; - FD_SET(osfd, &wt); - } - if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex); - } - } - else - { - if (0 == ready) - { - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; /* this will cause an abrupt return */ - pd->out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - else - { - pd->out_flags = 0; - } - } - - if (0 != ready) return ready; /* no need to block */ - - remaining = timeout; - start = PR_IntervalNow(); - -retry: - if (timeout != PR_INTERVAL_NO_TIMEOUT) - { - PRInt32 ticksPerSecond = PR_TicksPerSecond(); - tv.tv_sec = remaining / ticksPerSecond; - tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); - tvp = &tv; - } - - ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp); - - if (ready == -1 && errno == EINTR) - { - if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; - else - { - elapsed = (PRIntervalTime) (PR_IntervalNow() - start); - if (elapsed > timeout) ready = 0; /* timed out */ - else - { - remaining = timeout - elapsed; - goto retry; - } - } - } - - /* - ** Now to unravel the select sets back into the client's poll - ** descriptor list. Is this possibly an area for pissing away - ** a few cycles or what? - */ - if (ready > 0) - { - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRInt16 out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - PRInt32 osfd; - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); - - osfd = bottom->secret->md.osfd; - - if (FD_ISSET(osfd, &rd)) - { - if (pd->out_flags & _PR_POLL_READ_SYS_READ) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) - out_flags |= PR_POLL_WRITE; - } - if (FD_ISSET(osfd, &wt)) - { - if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) - out_flags |= PR_POLL_WRITE; - } - if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; - } - pd->out_flags = out_flags; - if (out_flags) ready++; - } - PR_ASSERT(ready > 0); - } - else if (ready < 0) - { - err = _MD_ERRNO(); - if (err == EBADF) - { - /* Find the bad fds */ - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - pd->out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1) - { - pd->out_flags = PR_POLL_NVAL; - ready++; - } - } - } - PR_ASSERT(ready > 0); - } - else _PR_MD_MAP_SELECT_ERROR(err); - } - - return ready; -} /* NativeThreadSelect */ -#endif /* !defined(_PR_USE_POLL) */ - -static PRInt32 LocalThreads( - PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - PRPollDesc *pd, *epd; - PRInt32 ready, pdcnt; - _PRUnixPollDesc *unixpds, *unixpd; - - /* - * XXX - * PRPollDesc has a PRFileDesc field, fd, while the IOQ - * is a list of PRPollQueue structures, each of which contains - * a _PRUnixPollDesc. A _PRUnixPollDesc struct contains - * the OS file descriptor, osfd, and not a PRFileDesc. - * So, we have allocate memory for _PRUnixPollDesc structures, - * copy the flags information from the pds list and have pq - * point to this list of _PRUnixPollDesc structures. - * - * It would be better if the memory allocation can be avoided. - */ - - unixpd = unixpds = (_PRUnixPollDesc*) - PR_MALLOC(npds * sizeof(_PRUnixPollDesc)); - if (NULL == unixpds) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - - ready = 0; - for (pdcnt = 0, pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRFileDesc *bottom; - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - if (pd->in_flags & PR_POLL_READ) - { - in_flags_read = (pd->fd->methods->poll)( - pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); - } - if (pd->in_flags & PR_POLL_WRITE) - { - in_flags_write = (pd->fd->methods->poll)( - pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); - } - if ((0 != (in_flags_read & out_flags_read)) - || (0 != (in_flags_write & out_flags_write))) - { - /* this one's ready right now */ - if (0 == ready) - { - /* - * We will have to return without calling the - * system poll/select function. So zero the - * out_flags fields of all the poll descriptors - * before this one. - */ - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; - pd->out_flags = out_flags_read | out_flags_write; - } - else - { - pd->out_flags = 0; /* pre-condition */ - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); /* what to do about that? */ - if ((NULL != bottom) - && (_PR_FILEDESC_OPEN == bottom->secret->state)) - { - if (0 == ready) - { - unixpd->osfd = bottom->secret->md.osfd; - unixpd->in_flags = 0; - if (in_flags_read & PR_POLL_READ) - { - unixpd->in_flags |= _PR_UNIX_POLL_READ; - pd->out_flags |= _PR_POLL_READ_SYS_READ; - } - if (in_flags_read & PR_POLL_WRITE) - { - unixpd->in_flags |= _PR_UNIX_POLL_WRITE; - pd->out_flags |= _PR_POLL_READ_SYS_WRITE; - } - if (in_flags_write & PR_POLL_READ) - { - unixpd->in_flags |= _PR_UNIX_POLL_READ; - pd->out_flags |= _PR_POLL_WRITE_SYS_READ; - } - if (in_flags_write & PR_POLL_WRITE) - { - unixpd->in_flags |= _PR_UNIX_POLL_WRITE; - pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; - } - if ((in_flags_read | in_flags_write) & PR_POLL_EXCEPT) - { - unixpd->in_flags |= _PR_UNIX_POLL_EXCEPT; - } - unixpd++; pdcnt++; - } - } - else - { - if (0 == ready) - { - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; /* this will cause an abrupt return */ - pd->out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - } - - if (0 != ready) - { - /* no need to block */ - PR_DELETE(unixpds); - return ready; - } - - ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout); - - /* - * Copy the out_flags from the _PRUnixPollDesc structures to the - * user's PRPollDesc structures and free the allocated memory - */ - unixpd = unixpds; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRInt16 out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - /* - * take errors from the poll operation, - * the R/W bits from the request - */ - if (0 != unixpd->out_flags) - { - if (unixpd->out_flags & _PR_UNIX_POLL_READ) - { - if (pd->out_flags & _PR_POLL_READ_SYS_READ) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) - out_flags |= PR_POLL_WRITE; - } - if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) - { - if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) - out_flags |= PR_POLL_WRITE; - } - if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) - out_flags |= PR_POLL_EXCEPT; - if (unixpd->out_flags & _PR_UNIX_POLL_ERR) - out_flags |= PR_POLL_ERR; - if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) - out_flags |= PR_POLL_NVAL; - if (unixpd->out_flags & _PR_UNIX_POLL_HUP) - out_flags |= PR_POLL_HUP; - } - unixpd++; - } - pd->out_flags = out_flags; - } - - PR_DELETE(unixpds); - - return ready; -} /* LocalThreads */ - -#if defined(_PR_USE_POLL) -#define NativeThreads NativeThreadPoll -#else -#define NativeThreads NativeThreadSelect -#endif - -PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - PRInt32 rv = 0; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_PENDING_INTERRUPT(me)) - { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - if (0 == npds) PR_Sleep(timeout); - else if (_PR_IS_NATIVE_THREAD(me)) - rv = NativeThreads(pds, npds, timeout); - else rv = LocalThreads(pds, npds, timeout); - - return rv; -} /* _MD_pr_poll */ - -#endif /* defined(_PR_PTHREADS) */ - -/* uxpoll.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxproces.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxproces.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxproces.c 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxproces.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,885 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include -#include -#include -#include -#include -#if defined(AIX) -#include /* For dlopen, dlsym, dlclose */ -#endif - -#if defined(DARWIN) -#if defined(HAVE_CRT_EXTERNS_H) -#include -#endif -#else -PR_IMPORT_DATA(char **) environ; -#endif - -/* - * HP-UX 9 doesn't have the SA_RESTART flag. - */ -#ifndef SA_RESTART -#define SA_RESTART 0 -#endif - -/* - ********************************************************************** - * - * The Unix process routines - * - ********************************************************************** - */ - -#define _PR_SIGNALED_EXITSTATUS 256 - -typedef enum pr_PidState { - _PR_PID_DETACHED, - _PR_PID_REAPED, - _PR_PID_WAITING -} pr_PidState; - -typedef struct pr_PidRecord { - pid_t pid; - int exitStatus; - pr_PidState state; - PRCondVar *reapedCV; - struct pr_PidRecord *next; -} pr_PidRecord; - -/* - * Irix sprocs and LinuxThreads are actually a kind of processes - * that can share the virtual address space and file descriptors. - */ -#if (defined(IRIX) && !defined(_PR_PTHREADS)) \ - || ((defined(LINUX) || defined(__GNU__) || defined(__GLIBC__)) \ - && defined(_PR_PTHREADS)) -#define _PR_SHARE_CLONES -#endif - -/* - * The macro _PR_NATIVE_THREADS indicates that we are - * using native threads only, so waitpid() blocks just the - * calling thread, not the process. In this case, the waitpid - * daemon thread can safely block in waitpid(). So we don't - * need to catch SIGCHLD, and the pipe to unblock PR_Poll() is - * also not necessary. - */ - -#if defined(_PR_GLOBAL_THREADS_ONLY) \ - || (defined(_PR_PTHREADS) \ - && !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__)) -#define _PR_NATIVE_THREADS -#endif - -/* - * All the static variables used by the Unix process routines are - * collected in this structure. - */ - -static struct { - PRCallOnceType once; - PRThread *thread; - PRLock *ml; -#if defined(_PR_NATIVE_THREADS) - PRInt32 numProcs; - PRCondVar *cv; -#else - int pipefd[2]; -#endif - pr_PidRecord **pidTable; - -#ifdef _PR_SHARE_CLONES - struct pr_CreateProcOp *opHead, *opTail; -#endif - -#ifdef AIX - pid_t (*forkptr)(void); /* Newer versions of AIX (starting in 4.3.2) - * have f_fork, which is faster than the - * regular fork in a multithreaded process - * because it skips calling the fork handlers. - * So we look up the f_fork symbol to see if - * it's available and fall back on fork. - */ -#endif /* AIX */ -} pr_wp; - -#ifdef _PR_SHARE_CLONES -static int pr_waitpid_daemon_exit; - -void -_MD_unix_terminate_waitpid_daemon(void) -{ - if (pr_wp.thread) { - pr_waitpid_daemon_exit = 1; - write(pr_wp.pipefd[1], "", 1); - PR_JoinThread(pr_wp.thread); - } -} -#endif - -static PRStatus _MD_InitProcesses(void); -#if !defined(_PR_NATIVE_THREADS) -static void pr_InstallSigchldHandler(void); -#endif - -static PRProcess * -ForkAndExec( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr) -{ - PRProcess *process; - int nEnv, idx; - char *const *childEnvp; - char **newEnvp = NULL; - int flags; - - process = PR_NEW(PRProcess); - if (!process) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - childEnvp = envp; - if (attr && attr->fdInheritBuffer) { - PRBool found = PR_FALSE; - - if (NULL == childEnvp) { -#ifdef DARWIN -#ifdef HAVE_CRT_EXTERNS_H - childEnvp = *(_NSGetEnviron()); -#else - /* _NSGetEnviron() is not available on iOS. */ - PR_DELETE(process); - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -#endif -#else - childEnvp = environ; -#endif - } - - for (nEnv = 0; childEnvp[nEnv]; nEnv++) { - } - newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *)); - if (NULL == newEnvp) { - PR_DELETE(process); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - for (idx = 0; idx < nEnv; idx++) { - newEnvp[idx] = childEnvp[idx]; - if (!found && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) { - newEnvp[idx] = attr->fdInheritBuffer; - found = PR_TRUE; - } - } - if (!found) { - newEnvp[idx++] = attr->fdInheritBuffer; - } - newEnvp[idx] = NULL; - childEnvp = newEnvp; - } - -#ifdef AIX - process->md.pid = (*pr_wp.forkptr)(); -#elif defined(NTO) || defined(SYMBIAN) - /* - * fork() & exec() does not work in a multithreaded process. - * Use spawn() instead. - */ - { - int fd_map[3] = { 0, 1, 2 }; - - if (attr) { - if (attr->stdinFd && attr->stdinFd->secret->md.osfd != 0) { - fd_map[0] = dup(attr->stdinFd->secret->md.osfd); - flags = fcntl(fd_map[0], F_GETFL, 0); - if (flags & O_NONBLOCK) - fcntl(fd_map[0], F_SETFL, flags & ~O_NONBLOCK); - } - if (attr->stdoutFd && attr->stdoutFd->secret->md.osfd != 1) { - fd_map[1] = dup(attr->stdoutFd->secret->md.osfd); - flags = fcntl(fd_map[1], F_GETFL, 0); - if (flags & O_NONBLOCK) - fcntl(fd_map[1], F_SETFL, flags & ~O_NONBLOCK); - } - if (attr->stderrFd && attr->stderrFd->secret->md.osfd != 2) { - fd_map[2] = dup(attr->stderrFd->secret->md.osfd); - flags = fcntl(fd_map[2], F_GETFL, 0); - if (flags & O_NONBLOCK) - fcntl(fd_map[2], F_SETFL, flags & ~O_NONBLOCK); - } - - PR_ASSERT(attr->currentDirectory == NULL); /* not implemented */ - } - -#ifdef SYMBIAN - /* In Symbian OS, we use posix_spawn instead of fork() and exec() */ - posix_spawn(&(process->md.pid), path, NULL, NULL, argv, childEnvp); -#else - process->md.pid = spawn(path, 3, fd_map, NULL, argv, childEnvp); -#endif - - if (fd_map[0] != 0) - close(fd_map[0]); - if (fd_map[1] != 1) - close(fd_map[1]); - if (fd_map[2] != 2) - close(fd_map[2]); - } -#else - process->md.pid = fork(); -#endif - if ((pid_t) -1 == process->md.pid) { - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno); - PR_DELETE(process); - if (newEnvp) { - PR_DELETE(newEnvp); - } - return NULL; - } else if (0 == process->md.pid) { /* the child process */ - /* - * If the child process needs to exit, it must call _exit(). - * Do not call exit(), because exit() will flush and close - * the standard I/O file descriptors, and hence corrupt - * the parent process's standard I/O data structures. - */ - -#if !defined(NTO) && !defined(SYMBIAN) - if (attr) { - /* the osfd's to redirect stdin, stdout, and stderr to */ - int in_osfd = -1, out_osfd = -1, err_osfd = -1; - - if (attr->stdinFd - && attr->stdinFd->secret->md.osfd != 0) { - in_osfd = attr->stdinFd->secret->md.osfd; - if (dup2(in_osfd, 0) != 0) { - _exit(1); /* failed */ - } - flags = fcntl(0, F_GETFL, 0); - if (flags & O_NONBLOCK) { - fcntl(0, F_SETFL, flags & ~O_NONBLOCK); - } - } - if (attr->stdoutFd - && attr->stdoutFd->secret->md.osfd != 1) { - out_osfd = attr->stdoutFd->secret->md.osfd; - if (dup2(out_osfd, 1) != 1) { - _exit(1); /* failed */ - } - flags = fcntl(1, F_GETFL, 0); - if (flags & O_NONBLOCK) { - fcntl(1, F_SETFL, flags & ~O_NONBLOCK); - } - } - if (attr->stderrFd - && attr->stderrFd->secret->md.osfd != 2) { - err_osfd = attr->stderrFd->secret->md.osfd; - if (dup2(err_osfd, 2) != 2) { - _exit(1); /* failed */ - } - flags = fcntl(2, F_GETFL, 0); - if (flags & O_NONBLOCK) { - fcntl(2, F_SETFL, flags & ~O_NONBLOCK); - } - } - if (in_osfd != -1) { - close(in_osfd); - } - if (out_osfd != -1 && out_osfd != in_osfd) { - close(out_osfd); - } - if (err_osfd != -1 && err_osfd != in_osfd - && err_osfd != out_osfd) { - close(err_osfd); - } - if (attr->currentDirectory) { - if (chdir(attr->currentDirectory) < 0) { - _exit(1); /* failed */ - } - } - } - - if (childEnvp) { - (void)execve(path, argv, childEnvp); - } else { - /* Inherit the environment of the parent. */ - (void)execv(path, argv); - } - /* Whoops! It returned. That's a bad sign. */ - _exit(1); -#endif /* !NTO */ - } - - if (newEnvp) { - PR_DELETE(newEnvp); - } - -#if defined(_PR_NATIVE_THREADS) - PR_Lock(pr_wp.ml); - if (0 == pr_wp.numProcs++) { - PR_NotifyCondVar(pr_wp.cv); - } - PR_Unlock(pr_wp.ml); -#endif - return process; -} - -#ifdef _PR_SHARE_CLONES - -struct pr_CreateProcOp { - const char *path; - char *const *argv; - char *const *envp; - const PRProcessAttr *attr; - PRProcess *process; - PRErrorCode prerror; - PRInt32 oserror; - PRBool done; - PRCondVar *doneCV; - struct pr_CreateProcOp *next; -}; - -PRProcess * -_MD_CreateUnixProcess( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr) -{ - struct pr_CreateProcOp *op; - PRProcess *proc; - int rv; - - if (PR_CallOnce(&pr_wp.once, _MD_InitProcesses) == PR_FAILURE) { - return NULL; - } - - op = PR_NEW(struct pr_CreateProcOp); - if (NULL == op) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - op->path = path; - op->argv = argv; - op->envp = envp; - op->attr = attr; - op->done = PR_FALSE; - op->doneCV = PR_NewCondVar(pr_wp.ml); - if (NULL == op->doneCV) { - PR_DELETE(op); - return NULL; - } - PR_Lock(pr_wp.ml); - - /* add to the tail of op queue */ - op->next = NULL; - if (pr_wp.opTail) { - pr_wp.opTail->next = op; - pr_wp.opTail = op; - } else { - PR_ASSERT(NULL == pr_wp.opHead); - pr_wp.opHead = pr_wp.opTail = op; - } - - /* wake up the daemon thread */ - do { - rv = write(pr_wp.pipefd[1], "", 1); - } while (-1 == rv && EINTR == errno); - - while (op->done == PR_FALSE) { - PR_WaitCondVar(op->doneCV, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(pr_wp.ml); - PR_DestroyCondVar(op->doneCV); - proc = op->process; - if (!proc) { - PR_SetError(op->prerror, op->oserror); - } - PR_DELETE(op); - return proc; -} - -#else /* ! _PR_SHARE_CLONES */ - -PRProcess * -_MD_CreateUnixProcess( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr) -{ - if (PR_CallOnce(&pr_wp.once, _MD_InitProcesses) == PR_FAILURE) { - return NULL; - } - return ForkAndExec(path, argv, envp, attr); -} /* _MD_CreateUnixProcess */ - -#endif /* _PR_SHARE_CLONES */ - -/* - * The pid table is a hashtable. - * - * The number of buckets in the hashtable (NBUCKETS) must be a power of 2. - */ -#define NBUCKETS_LOG2 6 -#define NBUCKETS (1 << NBUCKETS_LOG2) -#define PID_HASH_MASK ((pid_t) (NBUCKETS - 1)) - -static pr_PidRecord * -FindPidTable(pid_t pid) -{ - pr_PidRecord *pRec; - int keyHash = (int) (pid & PID_HASH_MASK); - - pRec = pr_wp.pidTable[keyHash]; - while (pRec) { - if (pRec->pid == pid) { - break; - } - pRec = pRec->next; - } - return pRec; -} - -static void -InsertPidTable(pr_PidRecord *pRec) -{ - int keyHash = (int) (pRec->pid & PID_HASH_MASK); - - pRec->next = pr_wp.pidTable[keyHash]; - pr_wp.pidTable[keyHash] = pRec; -} - -static void -DeletePidTable(pr_PidRecord *pRec) -{ - int keyHash = (int) (pRec->pid & PID_HASH_MASK); - - if (pr_wp.pidTable[keyHash] == pRec) { - pr_wp.pidTable[keyHash] = pRec->next; - } else { - pr_PidRecord *pred, *cur; /* predecessor and current */ - - pred = pr_wp.pidTable[keyHash]; - cur = pred->next; - while (cur) { - if (cur == pRec) { - pred->next = cur->next; - break; - } - pred = cur; - cur = cur->next; - } - PR_ASSERT(cur != NULL); - } -} - -static int -ExtractExitStatus(int rawExitStatus) -{ - /* - * We did not specify the WCONTINUED and WUNTRACED options - * for waitpid, so these two events should not be reported. - */ - PR_ASSERT(!WIFSTOPPED(rawExitStatus)); -#ifdef WIFCONTINUED - PR_ASSERT(!WIFCONTINUED(rawExitStatus)); -#endif - if (WIFEXITED(rawExitStatus)) { - return WEXITSTATUS(rawExitStatus); - } else { - PR_ASSERT(WIFSIGNALED(rawExitStatus)); - return _PR_SIGNALED_EXITSTATUS; - } -} - -static void -ProcessReapedChildInternal(pid_t pid, int status) -{ - pr_PidRecord *pRec; - - pRec = FindPidTable(pid); - if (NULL == pRec) { - pRec = PR_NEW(pr_PidRecord); - pRec->pid = pid; - pRec->state = _PR_PID_REAPED; - pRec->exitStatus = ExtractExitStatus(status); - pRec->reapedCV = NULL; - InsertPidTable(pRec); - } else { - PR_ASSERT(pRec->state != _PR_PID_REAPED); - if (_PR_PID_DETACHED == pRec->state) { - PR_ASSERT(NULL == pRec->reapedCV); - DeletePidTable(pRec); - PR_DELETE(pRec); - } else { - PR_ASSERT(_PR_PID_WAITING == pRec->state); - PR_ASSERT(NULL != pRec->reapedCV); - pRec->exitStatus = ExtractExitStatus(status); - pRec->state = _PR_PID_REAPED; - PR_NotifyCondVar(pRec->reapedCV); - } - } -} - -#if defined(_PR_NATIVE_THREADS) - -/* - * If all the threads are native threads, the daemon thread is - * simpler. We don't need to catch the SIGCHLD signal. We can - * just have the daemon thread block in waitpid(). - */ - -static void WaitPidDaemonThread(void *unused) -{ - pid_t pid; - int status; - - while (1) { - PR_Lock(pr_wp.ml); - while (0 == pr_wp.numProcs) { - PR_WaitCondVar(pr_wp.cv, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(pr_wp.ml); - - while (1) { - do { - pid = waitpid((pid_t) -1, &status, 0); - } while ((pid_t) -1 == pid && EINTR == errno); - - /* - * waitpid() cannot return 0 because we did not invoke it - * with the WNOHANG option. - */ - PR_ASSERT(0 != pid); - - /* - * The only possible error code is ECHILD. But if we do - * our accounting correctly, we should only call waitpid() - * when there is a child process to wait for. - */ - PR_ASSERT((pid_t) -1 != pid); - if ((pid_t) -1 == pid) { - break; - } - - PR_Lock(pr_wp.ml); - ProcessReapedChildInternal(pid, status); - pr_wp.numProcs--; - while (0 == pr_wp.numProcs) { - PR_WaitCondVar(pr_wp.cv, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(pr_wp.ml); - } - } -} - -#else /* _PR_NATIVE_THREADS */ - -static void WaitPidDaemonThread(void *unused) -{ - PRPollDesc pd; - PRFileDesc *fd; - int rv; - char buf[128]; - pid_t pid; - int status; -#ifdef _PR_SHARE_CLONES - struct pr_CreateProcOp *op; -#endif - -#ifdef _PR_SHARE_CLONES - pr_InstallSigchldHandler(); -#endif - - fd = PR_ImportFile(pr_wp.pipefd[0]); - PR_ASSERT(NULL != fd); - pd.fd = fd; - pd.in_flags = PR_POLL_READ; - - while (1) { - rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(1 == rv); - -#ifdef _PR_SHARE_CLONES - if (pr_waitpid_daemon_exit) { - return; - } - PR_Lock(pr_wp.ml); -#endif - - do { - rv = read(pr_wp.pipefd[0], buf, sizeof(buf)); - } while (sizeof(buf) == rv || (-1 == rv && EINTR == errno)); - -#ifdef _PR_SHARE_CLONES - PR_Unlock(pr_wp.ml); - while ((op = pr_wp.opHead) != NULL) { - op->process = ForkAndExec(op->path, op->argv, - op->envp, op->attr); - if (NULL == op->process) { - op->prerror = PR_GetError(); - op->oserror = PR_GetOSError(); - } - PR_Lock(pr_wp.ml); - pr_wp.opHead = op->next; - if (NULL == pr_wp.opHead) { - pr_wp.opTail = NULL; - } - op->done = PR_TRUE; - PR_NotifyCondVar(op->doneCV); - PR_Unlock(pr_wp.ml); - } -#endif - - while (1) { - do { - pid = waitpid((pid_t) -1, &status, WNOHANG); - } while ((pid_t) -1 == pid && EINTR == errno); - if (0 == pid) break; - if ((pid_t) -1 == pid) { - /* must be because we have no child processes */ - PR_ASSERT(ECHILD == errno); - break; - } - - PR_Lock(pr_wp.ml); - ProcessReapedChildInternal(pid, status); - PR_Unlock(pr_wp.ml); - } - } -} - -static void pr_SigchldHandler(int sig) -{ - int errnoCopy; - int rv; - - errnoCopy = errno; - - do { - rv = write(pr_wp.pipefd[1], "", 1); - } while (-1 == rv && EINTR == errno); - -#ifdef DEBUG - if (-1 == rv && EAGAIN != errno && EWOULDBLOCK != errno) { - char *msg = "cannot write to pipe\n"; - write(2, msg, strlen(msg) + 1); - _exit(1); - } -#endif - - errno = errnoCopy; -} - -static void pr_InstallSigchldHandler() -{ -#if defined(HPUX) && defined(_PR_DCETHREADS) -#error "HP-UX DCE threads have their own SIGCHLD handler" -#endif - - struct sigaction act, oact; - int rv; - - act.sa_handler = pr_SigchldHandler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_NOCLDSTOP | SA_RESTART; - rv = sigaction(SIGCHLD, &act, &oact); - PR_ASSERT(0 == rv); - /* Make sure we are not overriding someone else's SIGCHLD handler */ -#ifndef _PR_SHARE_CLONES - PR_ASSERT(oact.sa_handler == SIG_DFL); -#endif -} - -#endif /* !defined(_PR_NATIVE_THREADS) */ - -static PRStatus _MD_InitProcesses(void) -{ -#if !defined(_PR_NATIVE_THREADS) - int rv; - int flags; -#endif - -#ifdef AIX - { - void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); - pr_wp.forkptr = (pid_t (*)(void)) dlsym(handle, "f_fork"); - if (!pr_wp.forkptr) { - pr_wp.forkptr = fork; - } - dlclose(handle); - } -#endif /* AIX */ - - pr_wp.ml = PR_NewLock(); - PR_ASSERT(NULL != pr_wp.ml); - -#if defined(_PR_NATIVE_THREADS) - pr_wp.numProcs = 0; - pr_wp.cv = PR_NewCondVar(pr_wp.ml); - PR_ASSERT(NULL != pr_wp.cv); -#else - rv = pipe(pr_wp.pipefd); - PR_ASSERT(0 == rv); - flags = fcntl(pr_wp.pipefd[0], F_GETFL, 0); - fcntl(pr_wp.pipefd[0], F_SETFL, flags | O_NONBLOCK); - flags = fcntl(pr_wp.pipefd[1], F_GETFL, 0); - fcntl(pr_wp.pipefd[1], F_SETFL, flags | O_NONBLOCK); - -#ifndef _PR_SHARE_CLONES - pr_InstallSigchldHandler(); -#endif -#endif /* !_PR_NATIVE_THREADS */ - - pr_wp.thread = PR_CreateThread(PR_SYSTEM_THREAD, - WaitPidDaemonThread, NULL, PR_PRIORITY_NORMAL, -#ifdef _PR_SHARE_CLONES - PR_GLOBAL_THREAD, -#else - PR_LOCAL_THREAD, -#endif - PR_JOINABLE_THREAD, 0); - PR_ASSERT(NULL != pr_wp.thread); - - pr_wp.pidTable = (pr_PidRecord**)PR_CALLOC(NBUCKETS * sizeof(pr_PidRecord *)); - PR_ASSERT(NULL != pr_wp.pidTable); - return PR_SUCCESS; -} - -PRStatus _MD_DetachUnixProcess(PRProcess *process) -{ - PRStatus retVal = PR_SUCCESS; - pr_PidRecord *pRec; - - PR_Lock(pr_wp.ml); - pRec = FindPidTable(process->md.pid); - if (NULL == pRec) { - pRec = PR_NEW(pr_PidRecord); - if (NULL == pRec) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - retVal = PR_FAILURE; - goto done; - } - pRec->pid = process->md.pid; - pRec->state = _PR_PID_DETACHED; - pRec->reapedCV = NULL; - InsertPidTable(pRec); - } else { - PR_ASSERT(_PR_PID_REAPED == pRec->state); - if (_PR_PID_REAPED != pRec->state) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - retVal = PR_FAILURE; - } else { - DeletePidTable(pRec); - PR_ASSERT(NULL == pRec->reapedCV); - PR_DELETE(pRec); - } - } - PR_DELETE(process); - -done: - PR_Unlock(pr_wp.ml); - return retVal; -} - -PRStatus _MD_WaitUnixProcess( - PRProcess *process, - PRInt32 *exitCode) -{ - pr_PidRecord *pRec; - PRStatus retVal = PR_SUCCESS; - PRBool interrupted = PR_FALSE; - - PR_Lock(pr_wp.ml); - pRec = FindPidTable(process->md.pid); - if (NULL == pRec) { - pRec = PR_NEW(pr_PidRecord); - if (NULL == pRec) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - retVal = PR_FAILURE; - goto done; - } - pRec->pid = process->md.pid; - pRec->state = _PR_PID_WAITING; - pRec->reapedCV = PR_NewCondVar(pr_wp.ml); - if (NULL == pRec->reapedCV) { - PR_DELETE(pRec); - retVal = PR_FAILURE; - goto done; - } - InsertPidTable(pRec); - while (!interrupted && _PR_PID_REAPED != pRec->state) { - if (PR_WaitCondVar(pRec->reapedCV, - PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE - && PR_GetError() == PR_PENDING_INTERRUPT_ERROR) { - interrupted = PR_TRUE; - } - } - if (_PR_PID_REAPED == pRec->state) { - if (exitCode) { - *exitCode = pRec->exitStatus; - } - } else { - PR_ASSERT(interrupted); - retVal = PR_FAILURE; - } - DeletePidTable(pRec); - PR_DestroyCondVar(pRec->reapedCV); - PR_DELETE(pRec); - } else { - PR_ASSERT(_PR_PID_REAPED == pRec->state); - PR_ASSERT(NULL == pRec->reapedCV); - DeletePidTable(pRec); - if (exitCode) { - *exitCode = pRec->exitStatus; - } - PR_DELETE(pRec); - } - PR_DELETE(process); - -done: - PR_Unlock(pr_wp.ml); - return retVal; -} /* _MD_WaitUnixProcess */ - -PRStatus _MD_KillUnixProcess(PRProcess *process) -{ - PRErrorCode prerror; - PRInt32 oserror; - -#ifdef SYMBIAN - /* In Symbian OS, we can not kill other process with Open C */ - PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, oserror); - return PR_FAILURE; -#else - if (kill(process->md.pid, SIGKILL) == 0) { - return PR_SUCCESS; - } - oserror = errno; - switch (oserror) { - case EPERM: - prerror = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case ESRCH: - prerror = PR_INVALID_ARGUMENT_ERROR; - break; - default: - prerror = PR_UNKNOWN_ERROR; - break; - } - PR_SetError(prerror, oserror); - return PR_FAILURE; -#endif -} /* _MD_KillUnixProcess */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxrng.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxrng.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxrng.c 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxrng.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,252 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -#include "primpl.h" - -#include -#include -#include -#include - - -#if defined(SOLARIS) - -static size_t -GetHighResClock(void *buf, size_t maxbytes) -{ - hrtime_t t; - t = gethrtime(); - if (t) { - return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); - } - return 0; -} - -#elif defined(HPUX) - -#ifdef __ia64 -#include - -static size_t -GetHighResClock(void *buf, size_t maxbytes) -{ - PRUint64 t; - -#ifdef __GNUC__ - __asm__ __volatile__("mov %0 = ar.itc" : "=r" (t)); -#else - t = _Asm_mov_from_ar(_AREG44); -#endif - return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); -} -#else -static size_t -GetHighResClock(void *buf, size_t maxbytes) -{ - extern int ret_cr16(); - int cr16val; - - cr16val = ret_cr16(); - return(_pr_CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val))); -} -#endif - -#elif defined(OSF1) - -#include - -/* - * Use the "get the cycle counter" instruction on the alpha. - * The low 32 bits completely turn over in less than a minute. - * The high 32 bits are some non-counter gunk that changes sometimes. - */ -static size_t -GetHighResClock(void *buf, size_t maxbytes) -{ - unsigned long t; - -#ifdef __GNUC__ - __asm__("rpcc %0" : "=r" (t)); -#else - t = asm("rpcc %v0"); -#endif - return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); -} - -#elif defined(AIX) - -static size_t -GetHighResClock(void *buf, size_t maxbytes) -{ - return 0; -} - -#elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) \ - || defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD) \ - || defined(SYMBIAN) || defined(__GNU__)) -#include -#include -#include - -static int fdDevURandom; -static PRCallOnceType coOpenDevURandom; - -static PRStatus OpenDevURandom( void ) -{ - fdDevURandom = open( "/dev/urandom", O_RDONLY ); - return((-1 == fdDevURandom)? PR_FAILURE : PR_SUCCESS ); -} /* end OpenDevURandom() */ - -static size_t GetDevURandom( void *buf, size_t size ) -{ - int bytesIn; - int rc; - - rc = PR_CallOnce( &coOpenDevURandom, OpenDevURandom ); - if ( PR_FAILURE == rc ) { - _PR_MD_MAP_OPEN_ERROR( errno ); - return(0); - } - - bytesIn = read( fdDevURandom, buf, size ); - if ( -1 == bytesIn ) { - _PR_MD_MAP_READ_ERROR( errno ); - return(0); - } - - return( bytesIn ); -} /* end GetDevURandom() */ - -static size_t -GetHighResClock(void *buf, size_t maxbytes) -{ - return(GetDevURandom( buf, maxbytes )); -} - -#elif defined(IRIX) -#include -#undef PRIVATE -#include -#include -#include -#include -#include - -static size_t GetHighResClock(void *buf, size_t maxbuf) -{ - unsigned phys_addr, raddr, cycleval; - static volatile unsigned *iotimer_addr = NULL; - static int tries = 0; - static int cntr_size; - int mfd; - unsigned s0[2]; - -#ifndef SGI_CYCLECNTR_SIZE -#define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */ -#endif - - if (iotimer_addr == NULL) { - if (tries++ > 1) { - /* Don't keep trying if it didn't work */ - return 0; - } - - /* - ** For SGI machines we can use the cycle counter, if it has one, - ** to generate some truly random numbers - */ - phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval); - if (phys_addr) { - int pgsz = getpagesize(); - int pgoffmask = pgsz - 1; - - raddr = phys_addr & ~pgoffmask; - mfd = open("/dev/mmem", O_RDONLY); - if (mfd < 0) { - return 0; - } - iotimer_addr = (unsigned *) - mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr); - if (iotimer_addr == (unsigned*)-1) { - close(mfd); - iotimer_addr = NULL; - return 0; - } - iotimer_addr = (unsigned*) - ((__psint_t)iotimer_addr | (phys_addr & pgoffmask)); - /* - * The file 'mfd' is purposefully not closed. - */ - cntr_size = syssgi(SGI_CYCLECNTR_SIZE); - if (cntr_size < 0) { - struct utsname utsinfo; - - /* - * We must be executing on a 6.0 or earlier system, since the - * SGI_CYCLECNTR_SIZE call is not supported. - * - * The only pre-6.1 platforms with 64-bit counters are - * IP19 and IP21 (Challenge, PowerChallenge, Onyx). - */ - uname(&utsinfo); - if (!strncmp(utsinfo.machine, "IP19", 4) || - !strncmp(utsinfo.machine, "IP21", 4)) - cntr_size = 64; - else - cntr_size = 32; - } - cntr_size /= 8; /* Convert from bits to bytes */ - } - } - - s0[0] = *iotimer_addr; - if (cntr_size > 4) - s0[1] = *(iotimer_addr + 1); - memcpy(buf, (char *)&s0[0], cntr_size); - return _pr_CopyLowBits(buf, maxbuf, &s0, cntr_size); -} - -#elif defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \ - || defined(QNX) || defined(DARWIN) || defined(RISCOS) -#include - -static size_t -GetHighResClock(void *buf, size_t maxbytes) -{ - int ticks; - struct tms buffer; - - ticks=times(&buffer); - return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks)); -} -#else -#error! Platform undefined -#endif /* defined(SOLARIS) */ - -extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ) -{ - struct timeval tv; - int n = 0; - int s; - - n += GetHighResClock(buf, size); - size -= n; - - GETTIMEOFDAY(&tv); - - if ( size > 0 ) { - s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec)); - size -= s; - n += s; - } - if ( size > 0 ) { - s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec)); - size -= s; - n += s; - } - - return n; -} /* end _PR_MD_GetRandomNoise() */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxshm.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxshm.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxshm.c 2012-03-06 13:14:16.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxshm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,643 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** uxshm.c -- Unix Implementations NSPR Named Shared Memory -** -** -** lth. Jul-1999. -** -*/ -#include -#include -#include -#include -#include "primpl.h" -#include - -extern PRLogModuleInfo *_pr_shm_lm; - - -#define NSPR_IPC_SHM_KEY 'b' -/* -** Implementation for System V -*/ -#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY -#include -#include -#include -#include - -#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory -#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory -#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory -#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory -#define _MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory - -extern PRSharedMemory * _MD_OpenSharedMemory( - const char *name, - PRSize size, - PRIntn flags, - PRIntn mode -) -{ - PRStatus rc = PR_SUCCESS; - key_t key; - PRSharedMemory *shm; - char ipcname[PR_IPC_NAME_SIZE]; - - rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); - if ( PR_FAILURE == rc ) - { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); - return( NULL ); - } - - shm = PR_NEWZAP( PRSharedMemory ); - if ( NULL == shm ) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); - return( NULL ); - } - - shm->ipcname = (char*)PR_MALLOC( strlen( ipcname ) + 1 ); - if ( NULL == shm->ipcname ) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); - PR_DELETE( shm ); - return( NULL ); - } - - /* copy args to struct */ - strcpy( shm->ipcname, ipcname ); - shm->size = size; - shm->mode = mode; - shm->flags = flags; - shm->ident = _PR_SHM_IDENT; - - /* create the file first */ - if ( flags & PR_SHM_CREATE ) { - int osfd = open( shm->ipcname, (O_RDWR | O_CREAT), shm->mode ); - if ( -1 == osfd ) { - _PR_MD_MAP_OPEN_ERROR( errno ); - PR_FREEIF( shm->ipcname ); - PR_DELETE( shm ); - return( NULL ); - } - if ( close(osfd) == -1 ) { - _PR_MD_MAP_CLOSE_ERROR( errno ); - PR_FREEIF( shm->ipcname ); - PR_DELETE( shm ); - return( NULL ); - } - } - - /* hash the shm.name to an ID */ - key = ftok( shm->ipcname, NSPR_IPC_SHM_KEY ); - if ( -1 == key ) - { - rc = PR_FAILURE; - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_OpenSharedMemory(): ftok() failed on name: %s", shm->ipcname)); - PR_FREEIF( shm->ipcname ); - PR_DELETE( shm ); - return( NULL ); - } - - /* get the shared memory */ - if ( flags & PR_SHM_CREATE ) { - shm->id = shmget( key, shm->size, ( shm->mode | IPC_CREAT|IPC_EXCL)); - if ( shm->id >= 0 ) { - return( shm ); - } - if ((errno == EEXIST) && (flags & PR_SHM_EXCL)) { - PR_SetError( PR_FILE_EXISTS_ERROR, errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_OpenSharedMemory(): shmget() exclusive failed, errno: %d", errno)); - PR_FREEIF(shm->ipcname); - PR_DELETE(shm); - return(NULL); - } - } - - shm->id = shmget( key, shm->size, shm->mode ); - if ( -1 == shm->id ) { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_OpenSharedMemory(): shmget() failed, errno: %d", errno)); - PR_FREEIF(shm->ipcname); - PR_DELETE(shm); - return(NULL); - } - - return( shm ); -} /* end _MD_OpenSharedMemory() */ - -extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) -{ - void *addr; - PRUint32 aFlags = shm->mode; - - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - aFlags |= (flags & PR_SHM_READONLY )? SHM_RDONLY : 0; - - addr = shmat( shm->id, NULL, aFlags ); - if ( (void*)-1 == addr ) - { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_AttachSharedMemory(): shmat() failed on name: %s, OsError: %d", - shm->ipcname, PR_GetOSError() )); - addr = NULL; - } - - return addr; -} - -extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) -{ - PRStatus rc = PR_SUCCESS; - PRIntn urc; - - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - urc = shmdt( addr ); - if ( -1 == urc ) - { - rc = PR_FAILURE; - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DetachSharedMemory(): shmdt() failed on name: %s", shm->ipcname )); - } - - return rc; -} - -extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) -{ - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - PR_FREEIF(shm->ipcname); - PR_DELETE(shm); - - return PR_SUCCESS; -} - -extern PRStatus _MD_DeleteSharedMemory( const char *name ) -{ - PRStatus rc = PR_SUCCESS; - key_t key; - int id; - PRIntn urc; - char ipcname[PR_IPC_NAME_SIZE]; - - rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); - if ( PR_FAILURE == rc ) - { - PR_SetError( PR_UNKNOWN_ERROR , errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DeleteSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); - return(PR_FAILURE); - } - - /* create the file first */ - { - int osfd = open( ipcname, (O_RDWR | O_CREAT), 0666 ); - if ( -1 == osfd ) { - _PR_MD_MAP_OPEN_ERROR( errno ); - return( PR_FAILURE ); - } - if ( close(osfd) == -1 ) { - _PR_MD_MAP_CLOSE_ERROR( errno ); - return( PR_FAILURE ); - } - } - - /* hash the shm.name to an ID */ - key = ftok( ipcname, NSPR_IPC_SHM_KEY ); - if ( -1 == key ) - { - rc = PR_FAILURE; - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DeleteSharedMemory(): ftok() failed on name: %s", ipcname)); - } - -#ifdef SYMBIAN - /* In Symbian OS the system imposed minimum is 1 byte, instead of ZERO */ - id = shmget( key, 1, 0 ); -#else - id = shmget( key, 0, 0 ); -#endif - if ( -1 == id ) { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DeleteSharedMemory(): shmget() failed, errno: %d", errno)); - return(PR_FAILURE); - } - - urc = shmctl( id, IPC_RMID, NULL ); - if ( -1 == urc ) - { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DeleteSharedMemory(): shmctl() failed on name: %s", ipcname )); - return(PR_FAILURE); - } - - urc = unlink( ipcname ); - if ( -1 == urc ) { - _PR_MD_MAP_UNLINK_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DeleteSharedMemory(): unlink() failed: %s", ipcname )); - return(PR_FAILURE); - } - - return rc; -} /* end _MD_DeleteSharedMemory() */ - -/* -** Implementation for Posix -*/ -#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY -#include - -#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory -#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory -#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory -#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory -#define _MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory - -struct _MDSharedMemory { - int handle; -}; - -extern PRSharedMemory * _MD_OpenSharedMemory( - const char *name, - PRSize size, - PRIntn flags, - PRIntn mode -) -{ - PRStatus rc = PR_SUCCESS; - PRInt32 end; - PRSharedMemory *shm; - char ipcname[PR_IPC_NAME_SIZE]; - - rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); - if ( PR_FAILURE == rc ) - { - PR_SetError( PR_UNKNOWN_ERROR , errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); - return( NULL ); - } - - shm = PR_NEWZAP( PRSharedMemory ); - if ( NULL == shm ) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); - return( NULL ); - } - - shm->ipcname = PR_MALLOC( strlen( ipcname ) + 1 ); - if ( NULL == shm->ipcname ) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); - return( NULL ); - } - - /* copy args to struct */ - strcpy( shm->ipcname, ipcname ); - shm->size = size; - shm->mode = mode; - shm->flags = flags; - shm->ident = _PR_SHM_IDENT; - - /* - ** Create the shared memory - */ - if ( flags & PR_SHM_CREATE ) { - int oflag = (O_CREAT | O_RDWR); - - if ( flags & PR_SHM_EXCL ) - oflag |= O_EXCL; - shm->id = shm_open( shm->ipcname, oflag, shm->mode ); - } else { - shm->id = shm_open( shm->ipcname, O_RDWR, shm->mode ); - } - - if ( -1 == shm->id ) { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, - ("_MD_OpenSharedMemory(): shm_open failed: %s, OSError: %d", - shm->ipcname, PR_GetOSError())); - PR_DELETE( shm->ipcname ); - PR_DELETE( shm ); - return(NULL); - } - - end = ftruncate( shm->id, shm->size ); - if ( -1 == end ) { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, - ("_MD_OpenSharedMemory(): ftruncate failed, OSError: %d", - PR_GetOSError())); - PR_DELETE( shm->ipcname ); - PR_DELETE( shm ); - return(NULL); - } - - return(shm); -} /* end _MD_OpenSharedMemory() */ - -extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) -{ - void *addr; - PRIntn prot = (PROT_READ | PROT_WRITE); - - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - if ( PR_SHM_READONLY == flags) - prot ^= PROT_WRITE; - - addr = mmap( (void*)0, shm->size, prot, MAP_SHARED, shm->id, 0 ); - if ((void*)-1 == addr ) - { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_AttachSharedMemory(): mmap failed: %s, errno: %d", - shm->ipcname, PR_GetOSError())); - addr = NULL; - } else { - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_AttachSharedMemory(): name: %s, attached at: %p", shm->ipcname, addr)); - } - - return addr; -} - -extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) -{ - PRStatus rc = PR_SUCCESS; - PRIntn urc; - - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - urc = munmap( addr, shm->size ); - if ( -1 == urc ) - { - rc = PR_FAILURE; - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DetachSharedMemory(): munmap failed: %s, errno: %d", - shm->ipcname, PR_GetOSError())); - } - return rc; -} - -extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) -{ - int urc; - - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - urc = close( shm->id ); - if ( -1 == urc ) { - _PR_MD_MAP_CLOSE_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_CloseSharedMemory(): close() failed, error: %d", PR_GetOSError())); - return(PR_FAILURE); - } - PR_DELETE( shm->ipcname ); - PR_DELETE( shm ); - return PR_SUCCESS; -} - -extern PRStatus _MD_DeleteSharedMemory( const char *name ) -{ - PRStatus rc = PR_SUCCESS; - PRUintn urc; - char ipcname[PR_IPC_NAME_SIZE]; - - rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); - if ( PR_FAILURE == rc ) - { - PR_SetError( PR_UNKNOWN_ERROR , errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); - return rc; - } - - urc = shm_unlink( ipcname ); - if ( -1 == urc ) { - rc = PR_FAILURE; - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DeleteSharedMemory(): shm_unlink failed: %s, errno: %d", - ipcname, PR_GetOSError())); - } else { - PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, - ("_MD_DeleteSharedMemory(): %s, success", ipcname)); - } - - return rc; -} /* end _MD_DeleteSharedMemory() */ -#endif - - - -/* -** Unix implementation for anonymous memory (file) mapping -*/ -extern PRLogModuleInfo *_pr_shma_lm; - -#include - -extern PRFileMap* _md_OpenAnonFileMap( - const char *dirName, - PRSize size, - PRFileMapProtect prot -) -{ - PRFileMap *fm = NULL; - PRFileDesc *fd; - int osfd; - PRIntn urc; - PRIntn mode = 0600; - char *genName; - pid_t pid = getpid(); /* for generating filename */ - PRThread *tid = PR_GetCurrentThread(); /* for generating filename */ - int incr; /* for generating filename */ - const int maxTries = 20; /* maximum # attempts at a unique filename */ - PRInt64 size64; /* 64-bit version of 'size' */ - - /* - ** generate a filename from input and runtime environment - ** open the file, unlink the file. - ** make maxTries number of attempts at uniqueness in the filename - */ - for ( incr = 0; incr < maxTries ; incr++ ) { -#if defined(SYMBIAN) -#define NSPR_AFM_FILENAME "%s\\NSPR-AFM-%d-%p.%d" -#else -#define NSPR_AFM_FILENAME "%s/.NSPR-AFM-%d-%p.%d" -#endif - genName = PR_smprintf( NSPR_AFM_FILENAME, - dirName, (int) pid, tid, incr ); - if ( NULL == genName ) { - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename")); - goto Finished; - } - - /* create the file */ - osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode ); - if ( -1 == osfd ) { - if ( EEXIST == errno ) { - PR_smprintf_free( genName ); - continue; /* name exists, try again */ - } else { - _PR_MD_MAP_OPEN_ERROR( errno ); - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d", - genName, PR_GetOSError())); - PR_smprintf_free( genName ); - goto Finished; - } - } - break; /* name generation and open successful, break; */ - } /* end for() */ - - if ( incr == maxTries ) { - PR_ASSERT( -1 == osfd ); - PR_ASSERT( EEXIST == errno ); - _PR_MD_MAP_OPEN_ERROR( errno ); - goto Finished; - } - - urc = unlink( genName ); -#if defined(SYMBIAN) && defined(__WINS__) - /* If it is being used by the system or another process, Symbian OS - * Emulator(WINS) considers this an error. */ - if ( -1 == urc && EACCES != errno ) { -#else - if ( -1 == urc ) { -#endif - _PR_MD_MAP_UNLINK_ERROR( errno ); - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): failed on unlink(), errno: %d", errno)); - PR_smprintf_free( genName ); - close( osfd ); - goto Finished; - } - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): unlink(): %s", genName )); - - PR_smprintf_free( genName ); - - fd = PR_ImportFile( osfd ); - if ( NULL == fd ) { - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): PR_ImportFile(): failed")); - goto Finished; - } - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): fd: %p", fd )); - - urc = ftruncate( fd->secret->md.osfd, size ); - if ( -1 == urc ) { - _PR_MD_MAP_DEFAULT_ERROR( errno ); - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): failed on ftruncate(), errno: %d", errno)); - PR_Close( fd ); - goto Finished; - } - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): ftruncate(): size: %d", size )); - - LL_UI2L(size64, size); /* PRSize (size_t) is unsigned */ - fm = PR_CreateFileMap( fd, size64, prot ); - if ( NULL == fm ) { - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("PR_OpenAnonFileMap(): failed")); - PR_Close( fd ); - goto Finished; - } - fm->md.isAnonFM = PR_TRUE; /* set fd close */ - - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): PR_CreateFileMap(): fm: %p", fm )); - -Finished: - return(fm); -} /* end md_OpenAnonFileMap() */ - -/* -** _md_ExportFileMapAsString() -** -** -*/ -extern PRStatus _md_ExportFileMapAsString( - PRFileMap *fm, - PRSize bufSize, - char *buf -) -{ - PRIntn written; - PRIntn prot = (PRIntn)fm->prot; - - written = PR_snprintf( buf, bufSize, "%ld:%d", - fm->fd->secret->md.osfd, prot ); - - return((written == -1)? PR_FAILURE : PR_SUCCESS); -} /* end _md_ExportFileMapAsString() */ - - -extern PRFileMap * _md_ImportFileMapFromString( - const char *fmstring -) -{ - PRStatus rc; - PRInt32 osfd; - PRIntn prot; /* really: a PRFileMapProtect */ - PRFileDesc *fd; - PRFileMap *fm = NULL; /* default return value */ - PRFileInfo64 info; - - PR_sscanf( fmstring, "%ld:%d", &osfd, &prot ); - - /* import the os file descriptor */ - fd = PR_ImportFile( osfd ); - if ( NULL == fd ) { - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_ImportFileMapFromString(): PR_ImportFile() failed")); - goto Finished; - } - - rc = PR_GetOpenFileInfo64( fd, &info ); - if ( PR_FAILURE == rc ) { - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_ImportFileMapFromString(): PR_GetOpenFileInfo64() failed")); - goto Finished; - } - - fm = PR_CreateFileMap( fd, info.size, (PRFileMapProtect)prot ); - if ( NULL == fm ) { - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_ImportFileMapFromString(): PR_CreateFileMap() failed")); - } - -Finished: - return(fm); -} /* end _md_ImportFileMapFromString() */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxwrap.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxwrap.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/unix/uxwrap.c 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/unix/uxwrap.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,513 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - *------------------------------------------------------------------------ - * File: uxwrap.c - * - * Our wrapped versions of the Unix select() and poll() system calls. - * - *------------------------------------------------------------------------ - */ - -#include "primpl.h" - -#if defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) || defined(QNX) -/* Do not wrap select() and poll(). */ -#else /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */ -/* The include files for select() */ -#ifdef IRIX -#include -#include -#endif - -#include -#include -#include - -#define ZAP_SET(_to, _width) \ - PR_BEGIN_MACRO \ - memset(_to, 0, \ - ((_width + 8*sizeof(int)-1) / (8*sizeof(int))) \ - * sizeof(int) \ - ); \ - PR_END_MACRO - -/* see comments in ns/cmd/xfe/mozilla.c (look for "PR_XGetXtHackFD") */ -static int _pr_xt_hack_fd = -1; - -int PR_XGetXtHackFD(void) -{ - int fds[2]; - - if (_pr_xt_hack_fd == -1) { - if (!pipe(fds)) { - _pr_xt_hack_fd = fds[0]; - } - } - return _pr_xt_hack_fd; -} - -static int (*_pr_xt_hack_okayToReleaseXLock)(void) = 0; - -void PR_SetXtHackOkayToReleaseXLockFn(int (*fn)(void)) -{ - _pr_xt_hack_okayToReleaseXLock = fn; -} - - -/* - *----------------------------------------------------------------------- - * select() -- - * - * Wrap up the select system call so that we can deschedule - * a thread that tries to wait for i/o. - * - *----------------------------------------------------------------------- - */ - -#if defined(HPUX9) -int select(size_t width, int *rl, int *wl, int *el, const struct timeval *tv) -#elif defined(AIX_RENAME_SELECT) -int wrap_select(unsigned long width, void *rl, void *wl, void *el, - struct timeval *tv) -#elif defined(_PR_SELECT_CONST_TIMEVAL) -int select(int width, fd_set *rd, fd_set *wr, fd_set *ex, - const struct timeval *tv) -#else -int select(int width, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *tv) -#endif -{ - int osfd; - _PRUnixPollDesc *unixpds, *unixpd, *eunixpd; - PRInt32 pdcnt; - PRIntervalTime timeout; - int retVal; -#if defined(HPUX9) || defined(AIX_RENAME_SELECT) - fd_set *rd = (fd_set*) rl; - fd_set *wr = (fd_set*) wl; - fd_set *ex = (fd_set*) el; -#endif - -#if 0 - /* - * Easy special case: zero timeout. Simply call the native - * select() with no fear of blocking. - */ - if (tv != NULL && tv->tv_sec == 0 && tv->tv_usec == 0) { -#if defined(HPUX9) || defined(AIX_RENAME_SELECT) - return _MD_SELECT(width, rl, wl, el, tv); -#else - return _MD_SELECT(width, rd, wr, ex, tv); -#endif - } -#endif - - if (!_pr_initialized) { - _PR_ImplicitInitialization(); - } - -#ifndef _PR_LOCAL_THREADS_ONLY - if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) { - return _MD_SELECT(width, rd, wr, ex, tv); - } -#endif - - if (width < 0 || width > FD_SETSIZE) { - errno = EINVAL; - return -1; - } - - /* Compute timeout */ - if (tv) { - /* - * These acceptable ranges for t_sec and t_usec are taken - * from the select() man pages. - */ - if (tv->tv_sec < 0 || tv->tv_sec > 100000000 - || tv->tv_usec < 0 || tv->tv_usec >= 1000000) { - errno = EINVAL; - return -1; - } - - /* Convert microseconds to ticks */ - timeout = PR_MicrosecondsToInterval(1000000*tv->tv_sec + tv->tv_usec); - } else { - /* tv being a NULL pointer means blocking indefinitely */ - timeout = PR_INTERVAL_NO_TIMEOUT; - } - - /* Check for no descriptors case (just doing a timeout) */ - if ((!rd && !wr && !ex) || !width) { - PR_Sleep(timeout); - return 0; - } - - /* - * Set up for PR_Poll(). The PRPollDesc array is allocated - * dynamically. If this turns out to have high performance - * penalty, one can change to use a large PRPollDesc array - * on the stack, and allocate dynamically only when it turns - * out to be not large enough. - * - * I allocate an array of size 'width', which is the maximum - * number of fds we may need to poll. - */ - unixpds = (_PRUnixPollDesc *) PR_CALLOC(width * sizeof(_PRUnixPollDesc)); - if (!unixpds) { - errno = ENOMEM; - return -1; - } - - pdcnt = 0; - unixpd = unixpds; - for (osfd = 0; osfd < width; osfd++) { - int in_flags = 0; - if (rd && FD_ISSET(osfd, rd)) { - in_flags |= _PR_UNIX_POLL_READ; - } - if (wr && FD_ISSET(osfd, wr)) { - in_flags |= _PR_UNIX_POLL_WRITE; - } - if (ex && FD_ISSET(osfd, ex)) { - in_flags |= _PR_UNIX_POLL_EXCEPT; - } - if (in_flags) { - unixpd->osfd = osfd; - unixpd->in_flags = in_flags; - unixpd->out_flags = 0; - unixpd++; - pdcnt++; - } - } - - /* - * see comments in mozilla/cmd/xfe/mozilla.c (look for - * "PR_XGetXtHackFD") - */ - { - int needToLockXAgain; - - needToLockXAgain = 0; - if (rd && (_pr_xt_hack_fd != -1) - && FD_ISSET(_pr_xt_hack_fd, rd) && PR_XIsLocked() - && (!_pr_xt_hack_okayToReleaseXLock - || _pr_xt_hack_okayToReleaseXLock())) { - PR_XUnlock(); - needToLockXAgain = 1; - } - - /* This is the potentially blocking step */ - retVal = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout); - - if (needToLockXAgain) { - PR_XLock(); - } - } - - if (retVal > 0) { - /* Compute select results */ - if (rd) ZAP_SET(rd, width); - if (wr) ZAP_SET(wr, width); - if (ex) ZAP_SET(ex, width); - - /* - * The return value can be either the number of ready file - * descriptors or the number of set bits in the three fd_set's. - */ - retVal = 0; /* we're going to recompute */ - eunixpd = unixpds + pdcnt; - for (unixpd = unixpds; unixpd < eunixpd; unixpd++) { - if (unixpd->out_flags) { - int nbits = 0; /* The number of set bits on for this fd */ - - if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) { - errno = EBADF; - PR_LOG(_pr_io_lm, PR_LOG_ERROR, - ("select returns EBADF for %d", unixpd->osfd)); - retVal = -1; - break; - } - /* - * If a socket has a pending error, it is considered - * both readable and writable. (See W. Richard Stevens, - * Unix Network Programming, Vol. 1, 2nd Ed., Section 6.3, - * pp. 153-154.) We also consider a socket readable if - * it has a hangup condition. - */ - if (rd && (unixpd->in_flags & _PR_UNIX_POLL_READ) - && (unixpd->out_flags & (_PR_UNIX_POLL_READ - | _PR_UNIX_POLL_ERR | _PR_UNIX_POLL_HUP))) { - FD_SET(unixpd->osfd, rd); - nbits++; - } - if (wr && (unixpd->in_flags & _PR_UNIX_POLL_WRITE) - && (unixpd->out_flags & (_PR_UNIX_POLL_WRITE - | _PR_UNIX_POLL_ERR))) { - FD_SET(unixpd->osfd, wr); - nbits++; - } - if (ex && (unixpd->in_flags & _PR_UNIX_POLL_WRITE) - && (unixpd->out_flags & PR_POLL_EXCEPT)) { - FD_SET(unixpd->osfd, ex); - nbits++; - } - PR_ASSERT(nbits > 0); -#if defined(HPUX) || defined(SOLARIS) || defined(OSF1) || defined(AIX) - retVal += nbits; -#else /* IRIX */ - retVal += 1; -#endif - } - } - } - - PR_ASSERT(tv || retVal != 0); - PR_LOG(_pr_io_lm, PR_LOG_MIN, ("select returns %d", retVal)); - PR_DELETE(unixpds); - - return retVal; -} - -/* - * Redefine poll, when supported on platforms, for local threads - */ - -/* - * I am commenting out the poll() wrapper for Linux for now - * because it is difficult to define _MD_POLL that works on all - * Linux varieties. People reported that glibc 2.0.7 on Debian - * 2.0 Linux machines doesn't have the __syscall_poll symbol - * defined. (WTC 30 Nov. 1998) - */ -#if defined(_PR_POLL_AVAILABLE) && !defined(LINUX) - -/* - *----------------------------------------------------------------------- - * poll() -- - * - * RETURN VALUES: - * -1: fails, errno indicates the error. - * 0: timed out, the revents bitmasks are not set. - * positive value: the number of file descriptors for which poll() - * has set the revents bitmask. - * - *----------------------------------------------------------------------- - */ - -#include - -#if defined(AIX_RENAME_SELECT) -int wrap_poll(void *listptr, unsigned long nfds, long timeout) -#elif (defined(AIX) && !defined(AIX_RENAME_SELECT)) -int poll(void *listptr, unsigned long nfds, long timeout) -#elif defined(OSF1) || (defined(HPUX) && !defined(HPUX9)) -int poll(struct pollfd filedes[], unsigned int nfds, int timeout) -#elif defined(HPUX9) -int poll(struct pollfd filedes[], int nfds, int timeout) -#elif defined(NETBSD) -int poll(struct pollfd *filedes, nfds_t nfds, int timeout) -#elif defined(OPENBSD) -int poll(struct pollfd filedes[], nfds_t nfds, int timeout) -#elif defined(FREEBSD) -int poll(struct pollfd *filedes, unsigned nfds, int timeout) -#else -int poll(struct pollfd *filedes, unsigned long nfds, int timeout) -#endif -{ -#ifdef AIX - struct pollfd *filedes = (struct pollfd *) listptr; -#endif - struct pollfd *pfd, *epfd; - _PRUnixPollDesc *unixpds, *unixpd, *eunixpd; - PRIntervalTime ticks; - PRInt32 pdcnt; - int ready; - - /* - * Easy special case: zero timeout. Simply call the native - * poll() with no fear of blocking. - */ - if (timeout == 0) { -#if defined(AIX) - return _MD_POLL(listptr, nfds, timeout); -#else - return _MD_POLL(filedes, nfds, timeout); -#endif - } - - if (!_pr_initialized) { - _PR_ImplicitInitialization(); - } - -#ifndef _PR_LOCAL_THREADS_ONLY - if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) { - return _MD_POLL(filedes, nfds, timeout); - } -#endif - - /* We do not support the pollmsg structures on AIX */ -#ifdef AIX - PR_ASSERT((nfds & 0xff00) == 0); -#endif - - if (timeout < 0 && timeout != -1) { - errno = EINVAL; - return -1; - } - - /* Convert timeout from miliseconds to ticks */ - if (timeout == -1) { - ticks = PR_INTERVAL_NO_TIMEOUT; - } else { - ticks = PR_MillisecondsToInterval(timeout); - } - - /* Check for no descriptor case (just do a timeout) */ - if (nfds == 0) { - PR_Sleep(ticks); - return 0; - } - - unixpds = (_PRUnixPollDesc *) - PR_MALLOC(nfds * sizeof(_PRUnixPollDesc)); - if (NULL == unixpds) { - errno = EAGAIN; - return -1; - } - - pdcnt = 0; - epfd = filedes + nfds; - unixpd = unixpds; - for (pfd = filedes; pfd < epfd; pfd++) { - /* - * poll() ignores negative fd's. - */ - if (pfd->fd >= 0) { - unixpd->osfd = pfd->fd; -#ifdef _PR_USE_POLL - unixpd->in_flags = pfd->events; -#else - /* - * Map the poll events to one of the three that can be - * represented by the select fd_sets: - * POLLIN, POLLRDNORM ===> readable - * POLLOUT, POLLWRNORM ===> writable - * POLLPRI, POLLRDBAND ===> exception - * POLLNORM, POLLWRBAND (and POLLMSG on some platforms) - * are ignored. - * - * The output events POLLERR and POLLHUP are never turned on. - * POLLNVAL may be turned on. - */ - unixpd->in_flags = 0; - if (pfd->events & (POLLIN -#ifdef POLLRDNORM - | POLLRDNORM -#endif - )) { - unixpd->in_flags |= _PR_UNIX_POLL_READ; - } - if (pfd->events & (POLLOUT -#ifdef POLLWRNORM - | POLLWRNORM -#endif - )) { - unixpd->in_flags |= _PR_UNIX_POLL_WRITE; - } - if (pfd->events & (POLLPRI -#ifdef POLLRDBAND - | POLLRDBAND -#endif - )) { - unixpd->in_flags |= PR_POLL_EXCEPT; - } -#endif /* _PR_USE_POLL */ - unixpd->out_flags = 0; - unixpd++; - pdcnt++; - } - } - - ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, ticks); - if (-1 == ready) { - if (PR_GetError() == PR_PENDING_INTERRUPT_ERROR) { - errno = EINTR; /* XXX we aren't interrupted by a signal, but... */ - } else { - errno = PR_GetOSError(); - } - } - if (ready <= 0) { - goto done; - } - - /* - * Copy the out_flags from the _PRUnixPollDesc structures to the - * user's pollfd structures and free the allocated memory - */ - unixpd = unixpds; - for (pfd = filedes; pfd < epfd; pfd++) { - pfd->revents = 0; - if (pfd->fd >= 0) { -#ifdef _PR_USE_POLL - pfd->revents = unixpd->out_flags; -#else - if (0 != unixpd->out_flags) { - if (unixpd->out_flags & _PR_UNIX_POLL_READ) { - if (pfd->events & POLLIN) { - pfd->revents |= POLLIN; - } -#ifdef POLLRDNORM - if (pfd->events & POLLRDNORM) { - pfd->revents |= POLLRDNORM; - } -#endif - } - if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) { - if (pfd->events & POLLOUT) { - pfd->revents |= POLLOUT; - } -#ifdef POLLWRNORM - if (pfd->events & POLLWRNORM) { - pfd->revents |= POLLWRNORM; - } -#endif - } - if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) { - if (pfd->events & POLLPRI) { - pfd->revents |= POLLPRI; - } -#ifdef POLLRDBAND - if (pfd->events & POLLRDBAND) { - pfd->revents |= POLLRDBAND; - } -#endif - } - if (unixpd->out_flags & _PR_UNIX_POLL_ERR) { - pfd->revents |= POLLERR; - } - if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) { - pfd->revents |= POLLNVAL; - } - if (unixpd->out_flags & _PR_UNIX_POLL_HUP) { - pfd->revents |= POLLHUP; - } - } -#endif /* _PR_USE_POLL */ - unixpd++; - } - } - -done: - PR_DELETE(unixpds); - return ready; -} - -#endif /* !defined(LINUX) */ - -#endif /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */ - -/* uxwrap.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/.cvsignore 2001-05-12 04:42:04.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/Makefile.in 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET))) -CSRCS = \ - ntmisc.c \ - ntsec.c \ - ntsem.c \ - ntinrval.c \ - ntgc.c \ - w95thred.c \ - w95io.c \ - w95cv.c \ - w32rng.c \ - w95sock.c \ - win32_errors.c \ - w32ipcsem.c \ - w32poll.c \ - w32shm.c \ - w95dllmain.c \ - $(NULL) -else -CSRCS = \ - ntdllmn.c \ - ntmisc.c \ - ntsec.c \ - ntsem.c \ - ntinrval.c \ - ntgc.c \ - ntthread.c \ - ntio.c \ - win32_errors.c \ - w32ipcsem.c \ - w32poll.c \ - w32rng.c \ - w32shm.c \ - $(NULL) -endif - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - -# Bug 122433 workaround: disable global optimization (-Og-) on ntio.c. -ifdef MOZ_OPTIMIZE -ifeq ($(OS_TARGET), WINNT) -ifndef NS_USE_GCC -$(OBJDIR)/ntio.$(OBJ_SUFFIX): ntio.c - @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(CFLAGS) -Og- $< -endif -endif -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntdllmn.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntdllmn.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntdllmn.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntdllmn.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * The DLL entry point (DllMain) for NSPR. - * - * The only reason we use DLLMain() now is to find out whether - * the NSPR DLL is statically or dynamically loaded. When - * dynamically loaded, we cannot use static thread-local storage. - * However, static TLS is faster than the TlsXXX() functions. - * So we want to use static TLS whenever we can. A global - * variable _pr_use_static_tls is set in DllMain() during process - * attachment to indicate whether it is safe to use static TLS - * or not. - */ - -#include -#include - -extern BOOL _pr_use_static_tls; /* defined in ntthread.c */ - -BOOL WINAPI DllMain( - HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ -PRThread *me; - - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - /* - * If lpvReserved is NULL, we are dynamically loaded - * and therefore can't use static thread-local storage. - */ - if (lpvReserved == NULL) { - _pr_use_static_tls = FALSE; - } else { - _pr_use_static_tls = TRUE; - } - break; - case DLL_THREAD_ATTACH: - break; - case DLL_THREAD_DETACH: - if (_pr_initialized) { - me = _MD_GET_ATTACHED_THREAD(); - if ((me != NULL) && (me->flags & _PR_ATTACHED)) - _PRI_DetachThread(); - } - break; - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntgc.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntgc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntgc.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntgc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * GC related routines - * - */ -#include -#include "primpl.h" - -PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) -{ -#if defined(_X86_) - CONTEXT context; - context.ContextFlags = CONTEXT_INTEGER; - - if (_PR_IS_NATIVE_THREAD(t)) { - context.ContextFlags |= CONTEXT_CONTROL; - if (GetThreadContext(t->md.handle, &context)) { - t->md.gcContext[0] = context.Eax; - t->md.gcContext[1] = context.Ebx; - t->md.gcContext[2] = context.Ecx; - t->md.gcContext[3] = context.Edx; - t->md.gcContext[4] = context.Esi; - t->md.gcContext[5] = context.Edi; - t->md.gcContext[6] = context.Esp; - t->md.gcContext[7] = context.Ebp; - *np = PR_NUM_GCREGS; - } else { - PR_ASSERT(0);/* XXX */ - } - } else { - /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING - * - * This code is extremely machine dependant and completely - * undocumented by MS. Its only known to work experimentally. - * Ready for a walk on the wild * side? - * - * WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ - -#if !defined WIN95 // Win95 does not have fibers - int *fiberData = t->md.fiber_id; - - /* I found these offsets by disassembling SwitchToFiber(). - * Are your palms sweating yet? - */ - - /* - ** EAX is on the stack (ESP+0) - ** EDX is on the stack (ESP+4) - ** ECX is on the stack (ESP+8) - */ - t->md.gcContext[0] = 0; /* context.Eax */ - t->md.gcContext[1] = fiberData[0x2e]; /* context.Ebx */ - t->md.gcContext[2] = 0; /* context.Ecx */ - t->md.gcContext[3] = 0; /* context.Edx */ - t->md.gcContext[4] = fiberData[0x2d]; /* context.Esi */ - t->md.gcContext[5] = fiberData[0x2c]; /* context.Edi */ - t->md.gcContext[6] = fiberData[0x36]; /* context.Esp */ - t->md.gcContext[7] = fiberData[0x32]; /* context.Ebp */ - *np = PR_NUM_GCREGS; -#endif - } - return (PRWord *)&t->md.gcContext; -#else - PR_NOT_REACHED("not implemented"); - return NULL; -#endif /* defined(_X86_) */ -} - -/* This function is not used right now, but is left as a reference. - * If you ever need to get the fiberID from the currently running fiber, - * this is it. - */ -void * -GetMyFiberID() -{ -#if defined(_X86_) && !defined(__MINGW32__) - void *fiberData; - - /* A pointer to our tib entry is found at FS:[18] - * At offset 10h is the fiberData pointer. The context of the - * fiber is stored in there. - */ - __asm { - mov EDX, FS:[18h] - mov EAX, DWORD PTR [EDX+10h] - mov [fiberData], EAX - } - - return fiberData; -#else - PR_NOT_REACHED("not implemented"); - return NULL; -#endif /* defined(_X86_) */ -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntinrval.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntinrval.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntinrval.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntinrval.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * NT interval timers - * - */ - -#include "primpl.h" - -#ifdef WINCE -typedef DWORD (*IntervalFuncType)(void); -static IntervalFuncType intervalFunc; -#endif - -void -_PR_MD_INTERVAL_INIT() -{ -#ifdef WINCE - HMODULE mmtimerlib = LoadLibraryW(L"mmtimer.dll"); /* XXX leaked! */ - if (mmtimerlib) { - intervalFunc = (IntervalFuncType)GetProcAddress(mmtimerlib, - "timeGetTime"); - } else { - intervalFunc = &GetTickCount; - } -#endif -} - -PRIntervalTime -_PR_MD_GET_INTERVAL() -{ - /* milliseconds since system start */ -#ifdef WINCE - return (*intervalFunc)(); -#else - return timeGetTime(); -#endif -} - -PRIntervalTime -_PR_MD_INTERVAL_PER_SEC() -{ - return 1000; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntio.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntio.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntio.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntio.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,4609 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Windows NT IO module - * - * This module handles IO for LOCAL_SCOPE and GLOBAL_SCOPE threads. - * For LOCAL_SCOPE threads, we're using NT fibers. For GLOBAL_SCOPE threads - * we're using NT-native threads. - * - * When doing IO, we want to use completion ports for optimal performance - * with fibers. But if we use completion ports for all IO, it is difficult - * to project a blocking model with GLOBAL_SCOPE threads. To handle this - * we create an extra thread for completing IO for GLOBAL_SCOPE threads. - * We don't really want to complete IO on a separate thread for LOCAL_SCOPE - * threads because it means extra context switches, which are really slow - * on NT... Since we're using a single completion port, some IO will - * be incorrectly completed on the GLOBAL_SCOPE IO thread; this will mean - * extra context switching; but I don't think there is anything I can do - * about it. - */ - -#include "primpl.h" -#include "pprmwait.h" -#include -#include - -static HANDLE _pr_completion_port; -static PRThread *_pr_io_completion_thread; - -#define RECYCLE_SIZE 512 -static struct _MDLock _pr_recycle_lock; -static PRInt32 _pr_recycle_INET_array[RECYCLE_SIZE]; -static PRInt32 _pr_recycle_INET_tail = 0; -static PRInt32 _pr_recycle_INET6_array[RECYCLE_SIZE]; -static PRInt32 _pr_recycle_INET6_tail = 0; - -__declspec(thread) PRThread *_pr_io_restarted_io = NULL; -DWORD _pr_io_restartedIOIndex; /* The thread local storage slot for each - * thread is initialized to NULL. */ - -PRBool _nt_version_gets_lockfile_completion; - -struct _MDLock _pr_ioq_lock; -extern _MDLock _nt_idleLock; -extern PRCList _nt_idleList; -extern PRUint32 _nt_idleCount; - -#define CLOSE_TIMEOUT PR_SecondsToInterval(5) - -/* - * NSPR-to-NT access right mapping table for files. - */ -static DWORD fileAccessTable[] = { - FILE_GENERIC_READ, - FILE_GENERIC_WRITE, - FILE_GENERIC_EXECUTE -}; - -/* - * NSPR-to-NT access right mapping table for directories. - */ -static DWORD dirAccessTable[] = { - FILE_GENERIC_READ, - FILE_GENERIC_WRITE|FILE_DELETE_CHILD, - FILE_GENERIC_EXECUTE -}; - -static PRBool IsPrevCharSlash(const char *str, const char *current); - -#define _NEED_351_FILE_LOCKING_HACK -#ifdef _NEED_351_FILE_LOCKING_HACK -#define _PR_LOCAL_FILE 1 -#define _PR_REMOTE_FILE 2 -PRBool IsFileLocalInit(); -PRInt32 IsFileLocal(HANDLE hFile); -#endif /* _NEED_351_FILE_LOCKING_HACK */ - -static PRInt32 _md_MakeNonblock(HANDLE); - -static PROsfd _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr *addr, int *addrlen, PRIntervalTime); -static PRInt32 _nt_nonblock_connect(PRFileDesc *fd, struct sockaddr *addr, int addrlen, PRIntervalTime); -static PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime); -static PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime); -static PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime); -static PRInt32 _nt_nonblock_sendto(PRFileDesc *, const char *, int, const struct sockaddr *, int, PRIntervalTime); -static PRInt32 _nt_nonblock_recvfrom(PRFileDesc *, char *, int, struct sockaddr *, int *, PRIntervalTime); - -/* - * We cannot associate a fd (a socket) with an I/O completion port - * if the fd is nonblocking or inheritable. - * - * Nonblocking socket I/O won't work if the socket is associated with - * an I/O completion port. - * - * An inheritable fd cannot be associated with an I/O completion port - * because the completion notification of async I/O initiated by the - * child process is still posted to the I/O completion port in the - * parent process. - */ -#define _NT_USE_NB_IO(fd) \ - ((fd)->secret->nonblocking || (fd)->secret->inheritable == _PR_TRI_TRUE) - -/* - * UDP support - * - * UDP is supported on NT by the continuation thread mechanism. - * The code is borrowed from ptio.c in pthreads nspr, hence the - * PT and pt prefixes. This mechanism is in fact general and - * not limited to UDP. For now, only UDP's recvfrom and sendto - * go through the continuation thread if they get WSAEWOULDBLOCK - * on first try. Recv and send on a connected UDP socket still - * goes through asychronous io. - */ - -#define PT_DEFAULT_SELECT_MSEC 100 - -typedef struct pt_Continuation pt_Continuation; -typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revent); - -typedef enum pr_ContuationStatus -{ - pt_continuation_sumbitted, - pt_continuation_inprogress, - pt_continuation_abort, - pt_continuation_done -} pr_ContuationStatus; - -struct pt_Continuation -{ - /* These objects are linked in ascending timeout order */ - pt_Continuation *next, *prev; /* self linked list of these things */ - - /* The building of the continuation operation */ - ContinuationFn function; /* what function to continue */ - union { SOCKET osfd; } arg1; /* #1 - the op's fd */ - union { void* buffer; } arg2; /* #2 - primary transfer buffer */ - union { PRIntn amount; } arg3; /* #3 - size of 'buffer' */ - union { PRIntn flags; } arg4; /* #4 - read/write flags */ - union { PRNetAddr *addr; } arg5; /* #5 - send/recv address */ - - PRIntervalTime timeout; /* representation of the timeout */ - - PRIntn event; /* flags for select()'s events */ - - /* - ** The representation and notification of the results of the operation. - ** These function can either return an int return code or a pointer to - ** some object. - */ - union { PRIntn code; void *object; } result; - - PRIntn syserrno; /* in case it failed, why (errno) */ - pr_ContuationStatus status; /* the status of the operation */ - PRCondVar *complete; /* to notify the initiating thread */ -}; - -static struct pt_TimedQueue -{ - PRLock *ml; /* a little protection */ - PRThread *thread; /* internal thread's identification */ - PRCondVar *new_op; /* new operation supplied */ - PRCondVar *finish_op; /* an existing operation finished */ - PRUintn op_count; /* number of operations in the list */ - pt_Continuation *head, *tail; /* head/tail of list of operations */ - - pt_Continuation *op; /* timed operation furthest in future */ - PRIntervalTime epoch; /* the epoch of 'timed' */ -} pt_tq; - -#if defined(DEBUG) -static struct pt_debug_s -{ - PRIntn predictionsFoiled; - PRIntn pollingListMax; - PRIntn continuationsServed; -} pt_debug; -#endif /* DEBUG */ - -static void ContinuationThread(void *arg); -static PRInt32 pt_SendTo( - SOCKET osfd, const void *buf, - PRInt32 amount, PRInt32 flags, const PRNetAddr *addr, - PRIntn addrlen, PRIntervalTime timeout); -static PRInt32 pt_RecvFrom(SOCKET osfd, void *buf, PRInt32 amount, - PRInt32 flags, PRNetAddr *addr, PRIntn *addr_len, PRIntervalTime timeout); - - -/* The key returned from GetQueuedCompletionStatus() is used to determine what - * type of completion we have. We differentiate between IO completions and - * CVAR completions. - */ -#define KEY_IO 0xaaaaaaaa -#define KEY_CVAR 0xbbbbbbbb - -PRInt32 -_PR_MD_PAUSE_CPU(PRIntervalTime ticks) -{ - int awoken = 0; - unsigned long bytes, key; - int rv; - LPOVERLAPPED olp; - _MDOverlapped *mdOlp; - PRUint32 timeout; - - if (_nt_idleCount > 0) { - PRThread *deadThread; - - _MD_LOCK(&_nt_idleLock); - while( !PR_CLIST_IS_EMPTY(&_nt_idleList) ) { - deadThread = _PR_THREAD_PTR(PR_LIST_HEAD(&_nt_idleList)); - PR_REMOVE_LINK(&deadThread->links); - - PR_ASSERT(deadThread->state == _PR_DEAD_STATE); - - /* XXXMB - cleanup to do here? */ - if ( !_PR_IS_NATIVE_THREAD(deadThread) ){ - /* Spinlock while user thread is still running. - * There is no way to use a condition variable here. The thread - * is dead, and we have to wait until we switch off the dead - * thread before we can kill the fiber completely. - */ - while ( deadThread->no_sched) - ; - - DeleteFiber(deadThread->md.fiber_id); - } - memset(deadThread, 0xa, sizeof(PRThread)); /* debugging */ - if (!deadThread->threadAllocatedOnStack) - PR_DELETE(deadThread); - _nt_idleCount--; - } - _MD_UNLOCK(&_nt_idleLock); - } - - if (ticks == PR_INTERVAL_NO_TIMEOUT) -#if 0 - timeout = INFINITE; -#else - /* - * temporary hack to poll the runq every 5 seconds because of bug in - * native threads creating user threads and not poking the right cpu. - * - * A local thread that was interrupted is bound to its current - * cpu but there is no easy way for the interrupter to poke the - * right cpu. This is a hack to poll the runq every 5 seconds. - */ - timeout = 5000; -#endif - else - timeout = PR_IntervalToMilliseconds(ticks); - - /* - * The idea of looping here is to complete as many IOs as possible before - * returning. This should minimize trips to the idle thread. - */ - while(1) { - rv = GetQueuedCompletionStatus( - _pr_completion_port, - &bytes, - &key, - &olp, - timeout); - if (rv == 0 && olp == NULL) { - /* Error in GetQueuedCompetionStatus */ - if (GetLastError() != WAIT_TIMEOUT) { - /* ARGH - what can we do here? Log an error? XXXMB */ - return -1; - } else { - /* If awoken == 0, then we just had a timeout */ - return awoken; - } - } - - if (olp == NULL) - return 0; - - mdOlp = (_MDOverlapped *)olp; - - if (mdOlp->ioModel == _MD_MultiWaitIO) { - PRRecvWait *desc; - PRWaitGroup *group; - PRThread *thred = NULL; - PRMWStatus mwstatus; - - desc = mdOlp->data.mw.desc; - PR_ASSERT(desc != NULL); - mwstatus = rv ? PR_MW_SUCCESS : PR_MW_FAILURE; - if (InterlockedCompareExchange((PVOID *)&desc->outcome, - (PVOID)mwstatus, (PVOID)PR_MW_PENDING) - == (PVOID)PR_MW_PENDING) { - if (mwstatus == PR_MW_SUCCESS) { - desc->bytesRecv = bytes; - } else { - mdOlp->data.mw.error = GetLastError(); - } - } - group = mdOlp->data.mw.group; - PR_ASSERT(group != NULL); - - _PR_MD_LOCK(&group->mdlock); - PR_APPEND_LINK(&mdOlp->data.mw.links, &group->io_ready); - PR_ASSERT(desc->fd != NULL); - NT_HashRemoveInternal(group, desc->fd); - if (!PR_CLIST_IS_EMPTY(&group->wait_list)) { - thred = _PR_THREAD_CONDQ_PTR(PR_LIST_HEAD(&group->wait_list)); - PR_REMOVE_LINK(&thred->waitQLinks); - } - _PR_MD_UNLOCK(&group->mdlock); - - if (thred) { - if (!_PR_IS_NATIVE_THREAD(thred)) { - int pri = thred->priority; - _PRCPU *lockedCPU = _PR_MD_CURRENT_CPU(); - _PR_THREAD_LOCK(thred); - if (thred->flags & _PR_ON_PAUSEQ) { - _PR_SLEEPQ_LOCK(thred->cpu); - _PR_DEL_SLEEPQ(thred, PR_TRUE); - _PR_SLEEPQ_UNLOCK(thred->cpu); - _PR_THREAD_UNLOCK(thred); - thred->cpu = lockedCPU; - thred->state = _PR_RUNNABLE; - _PR_RUNQ_LOCK(lockedCPU); - _PR_ADD_RUNQ(thred, lockedCPU, pri); - _PR_RUNQ_UNLOCK(lockedCPU); - } else { - /* - * The thread was just interrupted and moved - * from the pause queue to the run queue. - */ - _PR_THREAD_UNLOCK(thred); - } - } else { - _PR_THREAD_LOCK(thred); - thred->state = _PR_RUNNABLE; - _PR_THREAD_UNLOCK(thred); - ReleaseSemaphore(thred->md.blocked_sema, 1, NULL); - } - } - } else { - PRThread *completed_io; - - PR_ASSERT(mdOlp->ioModel == _MD_BlockingIO); - completed_io = _PR_THREAD_MD_TO_PTR(mdOlp->data.mdThread); - completed_io->md.blocked_io_status = rv; - if (rv == 0) - completed_io->md.blocked_io_error = GetLastError(); - completed_io->md.blocked_io_bytes = bytes; - - if ( !_PR_IS_NATIVE_THREAD(completed_io) ) { - int pri = completed_io->priority; - _PRCPU *lockedCPU = _PR_MD_CURRENT_CPU(); - - /* The KEY_CVAR notification only occurs when a native thread - * is notifying a user thread. For user-user notifications - * the wakeup occurs by having the notifier place the thread - * on the runq directly; for native-native notifications the - * wakeup occurs by calling ReleaseSemaphore. - */ - if ( key == KEY_CVAR ) { - PR_ASSERT(completed_io->io_pending == PR_FALSE); - PR_ASSERT(completed_io->io_suspended == PR_FALSE); - PR_ASSERT(completed_io->md.thr_bound_cpu == NULL); - - /* Thread has already been deleted from sleepQ */ - - /* Switch CPU and add to runQ */ - completed_io->cpu = lockedCPU; - completed_io->state = _PR_RUNNABLE; - _PR_RUNQ_LOCK(lockedCPU); - _PR_ADD_RUNQ(completed_io, lockedCPU, pri); - _PR_RUNQ_UNLOCK(lockedCPU); - } else { - PR_ASSERT(key == KEY_IO); - PR_ASSERT(completed_io->io_pending == PR_TRUE); - - _PR_THREAD_LOCK(completed_io); - - completed_io->io_pending = PR_FALSE; - - /* If io_suspended is true, then this IO has already resumed. - * We don't need to do anything; because the thread is - * already running. - */ - if (completed_io->io_suspended == PR_FALSE) { - if (completed_io->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) { - _PR_SLEEPQ_LOCK(completed_io->cpu); - _PR_DEL_SLEEPQ(completed_io, PR_TRUE); - _PR_SLEEPQ_UNLOCK(completed_io->cpu); - - _PR_THREAD_UNLOCK(completed_io); - - /* - * If an I/O operation is suspended, the thread - * must be running on the same cpu on which the - * I/O operation was issued. - */ - PR_ASSERT(!completed_io->md.thr_bound_cpu || - (completed_io->cpu == completed_io->md.thr_bound_cpu)); - - if (!completed_io->md.thr_bound_cpu) - completed_io->cpu = lockedCPU; - completed_io->state = _PR_RUNNABLE; - _PR_RUNQ_LOCK(completed_io->cpu); - _PR_ADD_RUNQ(completed_io, completed_io->cpu, pri); - _PR_RUNQ_UNLOCK(completed_io->cpu); - } else { - _PR_THREAD_UNLOCK(completed_io); - } - } else { - _PR_THREAD_UNLOCK(completed_io); - } - } - } else { - /* For native threads, they are only notified through this loop - * when completing IO. So, don't worry about this being a CVAR - * notification, because that is not possible. - */ - _PR_THREAD_LOCK(completed_io); - completed_io->io_pending = PR_FALSE; - if (completed_io->io_suspended == PR_FALSE) { - completed_io->state = _PR_RUNNABLE; - _PR_THREAD_UNLOCK(completed_io); - rv = ReleaseSemaphore(completed_io->md.blocked_sema, - 1, NULL); - PR_ASSERT(0 != rv); - } else { - _PR_THREAD_UNLOCK(completed_io); - } - } - } - - awoken++; - timeout = 0; /* Don't block on subsequent trips through the loop */ - } - - /* never reached */ - return 0; -} - -static PRStatus -_native_thread_md_wait(PRThread *thread, PRIntervalTime ticks) -{ - DWORD rv; - PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? - INFINITE : PR_IntervalToMilliseconds(ticks); - - /* - * thread waiting for a cvar or a joining thread - */ - rv = WaitForSingleObject(thread->md.blocked_sema, msecs); - switch(rv) { - case WAIT_OBJECT_0: - return PR_SUCCESS; - break; - case WAIT_TIMEOUT: - _PR_THREAD_LOCK(thread); - PR_ASSERT (thread->state != _PR_IO_WAIT); - if (thread->wait.cvar != NULL) { - PR_ASSERT(thread->state == _PR_COND_WAIT); - thread->wait.cvar = NULL; - thread->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(thread); - } else { - /* The CVAR was notified just as the timeout - * occurred. This left the semaphore in the - * signaled state. Call WaitForSingleObject() - * to clear the semaphore. - */ - _PR_THREAD_UNLOCK(thread); - rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE); - PR_ASSERT(rv == WAIT_OBJECT_0); - } - return PR_SUCCESS; - break; - default: - return PR_FAILURE; - break; - } - - return PR_SUCCESS; -} - -PRStatus -_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - DWORD rv; - - if (_native_threads_only) { - return(_native_thread_md_wait(thread, ticks)); - } - if ( thread->flags & _PR_GLOBAL_SCOPE ) { - PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? - INFINITE : PR_IntervalToMilliseconds(ticks); - rv = WaitForSingleObject(thread->md.blocked_sema, msecs); - switch(rv) { - case WAIT_OBJECT_0: - return PR_SUCCESS; - break; - case WAIT_TIMEOUT: - _PR_THREAD_LOCK(thread); - if (thread->state == _PR_IO_WAIT) { - if (thread->io_pending == PR_TRUE) { - thread->state = _PR_RUNNING; - thread->io_suspended = PR_TRUE; - _PR_THREAD_UNLOCK(thread); - } else { - /* The IO completed just at the same time the timeout - * occurred. This left the semaphore in the signaled - * state. Call WaitForSingleObject() to clear the - * semaphore. - */ - _PR_THREAD_UNLOCK(thread); - rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE); - PR_ASSERT(rv == WAIT_OBJECT_0); - } - } else { - if (thread->wait.cvar != NULL) { - PR_ASSERT(thread->state == _PR_COND_WAIT); - thread->wait.cvar = NULL; - thread->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(thread); - } else { - /* The CVAR was notified just as the timeout - * occurred. This left the semaphore in the - * signaled state. Call WaitForSingleObject() - * to clear the semaphore. - */ - _PR_THREAD_UNLOCK(thread); - rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE); - PR_ASSERT(rv == WAIT_OBJECT_0); - } - } - return PR_SUCCESS; - break; - default: - return PR_FAILURE; - break; - } - } else { - PRInt32 is; - - _PR_INTSOFF(is); - _PR_MD_SWITCH_CONTEXT(thread); - } - - return PR_SUCCESS; -} - -static void -_native_thread_io_nowait( - PRThread *thread, - int rv, - int bytes) -{ - int rc; - - PR_ASSERT(rv != 0); - _PR_THREAD_LOCK(thread); - if (thread->state == _PR_IO_WAIT) { - PR_ASSERT(thread->io_suspended == PR_FALSE); - PR_ASSERT(thread->io_pending == PR_TRUE); - thread->state = _PR_RUNNING; - thread->io_pending = PR_FALSE; - _PR_THREAD_UNLOCK(thread); - } else { - /* The IO completed just at the same time the - * thread was interrupted. This left the semaphore - * in the signaled state. Call WaitForSingleObject() - * to clear the semaphore. - */ - PR_ASSERT(thread->io_suspended == PR_TRUE); - PR_ASSERT(thread->io_pending == PR_TRUE); - thread->io_pending = PR_FALSE; - _PR_THREAD_UNLOCK(thread); - rc = WaitForSingleObject(thread->md.blocked_sema, INFINITE); - PR_ASSERT(rc == WAIT_OBJECT_0); - } - - thread->md.blocked_io_status = rv; - thread->md.blocked_io_bytes = bytes; - rc = ResetEvent(thread->md.thr_event); - PR_ASSERT(rc != 0); - return; -} - -static PRStatus -_native_thread_io_wait(PRThread *thread, PRIntervalTime ticks) -{ - DWORD rv, bytes; -#define _NATIVE_IO_WAIT_HANDLES 2 -#define _NATIVE_WAKEUP_EVENT_INDEX 0 -#define _NATIVE_IO_EVENT_INDEX 1 - - HANDLE wait_handles[_NATIVE_IO_WAIT_HANDLES]; - - PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? - INFINITE : PR_IntervalToMilliseconds(ticks); - - PR_ASSERT(thread->flags & _PR_GLOBAL_SCOPE); - - wait_handles[0] = thread->md.blocked_sema; - wait_handles[1] = thread->md.thr_event; - rv = WaitForMultipleObjects(_NATIVE_IO_WAIT_HANDLES, wait_handles, - FALSE, msecs); - - switch(rv) { - case WAIT_OBJECT_0 + _NATIVE_IO_EVENT_INDEX: - /* - * I/O op completed - */ - _PR_THREAD_LOCK(thread); - if (thread->state == _PR_IO_WAIT) { - - PR_ASSERT(thread->io_suspended == PR_FALSE); - PR_ASSERT(thread->io_pending == PR_TRUE); - thread->state = _PR_RUNNING; - thread->io_pending = PR_FALSE; - _PR_THREAD_UNLOCK(thread); - } else { - /* The IO completed just at the same time the - * thread was interrupted. This led to us being - * notified twice. Call WaitForSingleObject() - * to clear the semaphore. - */ - PR_ASSERT(thread->io_suspended == PR_TRUE); - PR_ASSERT(thread->io_pending == PR_TRUE); - thread->io_pending = PR_FALSE; - _PR_THREAD_UNLOCK(thread); - rv = WaitForSingleObject(thread->md.blocked_sema, - INFINITE); - PR_ASSERT(rv == WAIT_OBJECT_0); - } - - rv = GetOverlappedResult((HANDLE) thread->io_fd, - &thread->md.overlapped.overlapped, &bytes, FALSE); - - thread->md.blocked_io_status = rv; - if (rv != 0) { - thread->md.blocked_io_bytes = bytes; - } else { - thread->md.blocked_io_error = GetLastError(); - PR_ASSERT(ERROR_IO_PENDING != thread->md.blocked_io_error); - } - rv = ResetEvent(thread->md.thr_event); - PR_ASSERT(rv != 0); - break; - case WAIT_OBJECT_0 + _NATIVE_WAKEUP_EVENT_INDEX: - /* - * I/O interrupted; - */ -#ifdef DEBUG - _PR_THREAD_LOCK(thread); - PR_ASSERT(thread->io_suspended == PR_TRUE); - _PR_THREAD_UNLOCK(thread); -#endif - break; - case WAIT_TIMEOUT: - _PR_THREAD_LOCK(thread); - if (thread->state == _PR_IO_WAIT) { - thread->state = _PR_RUNNING; - thread->io_suspended = PR_TRUE; - _PR_THREAD_UNLOCK(thread); - } else { - /* - * The thread was interrupted just as the timeout - * occurred. This left the semaphore in the signaled - * state. Call WaitForSingleObject() to clear the - * semaphore. - */ - PR_ASSERT(thread->io_suspended == PR_TRUE); - _PR_THREAD_UNLOCK(thread); - rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE); - PR_ASSERT(rv == WAIT_OBJECT_0); - } - break; - default: - return PR_FAILURE; - break; - } - - return PR_SUCCESS; -} - - -static PRStatus -_NT_IO_WAIT(PRThread *thread, PRIntervalTime timeout) -{ - PRBool fWait = PR_TRUE; - - if (_native_threads_only) { - return(_native_thread_io_wait(thread, timeout)); - } - if (!_PR_IS_NATIVE_THREAD(thread)) { - - _PR_THREAD_LOCK(thread); - - /* The IO may have already completed; if so, don't add to sleepQ, - * since we are already on the runQ! - */ - if (thread->io_pending == PR_TRUE) { - _PR_SLEEPQ_LOCK(thread->cpu); - _PR_ADD_SLEEPQ(thread, timeout); - _PR_SLEEPQ_UNLOCK(thread->cpu); - } else - fWait = PR_FALSE; - _PR_THREAD_UNLOCK(thread); - } - if (fWait) - return _PR_MD_WAIT(thread, timeout); - else - return PR_SUCCESS; -} - -/* - * Unblock threads waiting for I/O - * used when interrupting threads - * - * NOTE: The thread lock should held when this function is called. - * On return, the thread lock is released. - */ -void _PR_Unblock_IO_Wait(PRThread *thr) -{ - PRStatus rv; - _PRCPU *cpu = thr->cpu; - - PR_ASSERT(thr->state == _PR_IO_WAIT); - /* - * A thread for which an I/O timed out or was interrupted cannot be - * in an IO_WAIT state except as a result of calling PR_Close or - * PR_NT_CancelIo for the FD. For these two cases, _PR_IO_WAIT state - * is not interruptible - */ - if (thr->md.interrupt_disabled == PR_TRUE) { - _PR_THREAD_UNLOCK(thr); - return; - } - thr->io_suspended = PR_TRUE; - thr->state = _PR_RUNNABLE; - - if (!_PR_IS_NATIVE_THREAD(thr)) { - PRThread *me = _PR_MD_CURRENT_THREAD(); - PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ)); - _PR_SLEEPQ_LOCK(cpu); - _PR_DEL_SLEEPQ(thr, PR_TRUE); - _PR_SLEEPQ_UNLOCK(cpu); - /* - * this thread will continue to run on the same cpu until the - * I/O is aborted by closing the FD or calling CancelIO - */ - thr->md.thr_bound_cpu = cpu; - - PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD)); - _PR_AddThreadToRunQ(me, thr); - } - _PR_THREAD_UNLOCK(thr); - rv = _PR_MD_WAKEUP_WAITER(thr); - PR_ASSERT(PR_SUCCESS == rv); -} - -/* Resume an outstanding IO; requires that after the switch, we disable */ -static PRStatus -_NT_ResumeIO(PRThread *thread, PRIntervalTime ticks) -{ - PRBool fWait = PR_TRUE; - - if (!_PR_IS_NATIVE_THREAD(thread)) { - if (_pr_use_static_tls) { - _pr_io_restarted_io = thread; - } else { - TlsSetValue(_pr_io_restartedIOIndex, thread); - } - } else { - _PR_THREAD_LOCK(thread); - if (!thread->io_pending) - fWait = PR_FALSE; - thread->io_suspended = PR_FALSE; - - _PR_THREAD_UNLOCK(thread); - } - /* We don't put ourselves back on the sleepQ yet; until we - * set the suspended bit to false, we can't do that. Just save - * the sleep time here, and then continue. The restarted_io handler - * will add us to the sleepQ if needed. - */ - thread->sleep = ticks; - - if (fWait) { - if (!_PR_IS_NATIVE_THREAD(thread)) - return _PR_MD_WAIT(thread, ticks); - else - return _NT_IO_WAIT(thread, ticks); - } - return PR_SUCCESS; -} - -PRStatus -_PR_MD_WAKEUP_WAITER(PRThread *thread) -{ - if (thread == NULL) { - /* If thread is NULL, we aren't waking a thread, we're just poking - * idle thread - */ - if ( PostQueuedCompletionStatus(_pr_completion_port, 0, - KEY_CVAR, NULL) == FALSE) - return PR_FAILURE; - return PR_SUCCESS; - } - - if ( _PR_IS_NATIVE_THREAD(thread) ) { - if (ReleaseSemaphore(thread->md.blocked_sema, 1, NULL) == FALSE) - return PR_FAILURE; - else - return PR_SUCCESS; - } else { - PRThread *me = _PR_MD_CURRENT_THREAD(); - - /* When a Native thread has to awaken a user thread, it has to poke - * the completion port because all user threads might be idle, and - * thus the CPUs are just waiting for a completion. - * - * XXXMB - can we know when we are truely idle (and not checking - * the runq)? - */ - if ((_PR_IS_NATIVE_THREAD(me) || (thread->cpu != me->cpu)) && - (!thread->md.thr_bound_cpu)) { - /* The thread should not be in any queue */ - PR_ASSERT(thread->queueCount == 0); - if ( PostQueuedCompletionStatus(_pr_completion_port, 0, - KEY_CVAR, &(thread->md.overlapped.overlapped)) == FALSE) - return PR_FAILURE; - } - return PR_SUCCESS; - } -} - -void -_PR_MD_INIT_IO() -{ - WORD WSAVersion = 0x0101; - WSADATA WSAData; - int err; - OSVERSIONINFO OSversion; - - err = WSAStartup( WSAVersion, &WSAData ); - PR_ASSERT(0 == err); - - _pr_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, - NULL, - 0, - 0); - - _MD_NEW_LOCK(&_pr_recycle_lock); - _MD_NEW_LOCK(&_pr_ioq_lock); - - OSversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&OSversion)) { - _nt_version_gets_lockfile_completion = PR_FALSE; - if (OSversion.dwMajorVersion >= 4) { - _nt_version_gets_lockfile_completion = PR_TRUE; - } - } else - PR_ASSERT(0); - -#ifdef _NEED_351_FILE_LOCKING_HACK - IsFileLocalInit(); -#endif /* _NEED_351_FILE_LOCKING_HACK */ - - /* - * UDP support: start up the continuation thread - */ - - pt_tq.op_count = 0; - pt_tq.head = pt_tq.tail = NULL; - pt_tq.ml = PR_NewLock(); - PR_ASSERT(NULL != pt_tq.ml); - pt_tq.new_op = PR_NewCondVar(pt_tq.ml); - PR_ASSERT(NULL != pt_tq.new_op); -#if defined(DEBUG) - memset(&pt_debug, 0, sizeof(struct pt_debug_s)); -#endif - - pt_tq.thread = PR_CreateThread( - PR_SYSTEM_THREAD, ContinuationThread, NULL, - PR_PRIORITY_URGENT, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - - PR_ASSERT(NULL != pt_tq.thread); - -#ifdef DEBUG - /* Doublecheck _pr_filetime_offset's hard-coded value is correct. */ - { - SYSTEMTIME systime; - union { - PRTime prt; - FILETIME ft; - } filetime; - BOOL rv; - - systime.wYear = 1970; - systime.wMonth = 1; - /* wDayOfWeek is ignored */ - systime.wDay = 1; - systime.wHour = 0; - systime.wMinute = 0; - systime.wSecond = 0; - systime.wMilliseconds = 0; - - rv = SystemTimeToFileTime(&systime, &filetime.ft); - PR_ASSERT(0 != rv); - PR_ASSERT(filetime.prt == _pr_filetime_offset); - } -#endif /* DEBUG */ - - _PR_NT_InitSids(); -} - -/* --- SOCKET IO --------------------------------------------------------- */ - -/* _md_get_recycled_socket() - * Get a socket from the recycle bin; if no sockets are in the bin, - * create one. The socket will be passed to AcceptEx() as the - * second argument. - */ -static SOCKET -_md_get_recycled_socket(int af) -{ - SOCKET rv; - - _MD_LOCK(&_pr_recycle_lock); - if (af == AF_INET && _pr_recycle_INET_tail) { - _pr_recycle_INET_tail--; - rv = _pr_recycle_INET_array[_pr_recycle_INET_tail]; - _MD_UNLOCK(&_pr_recycle_lock); - return rv; - } - if (af == AF_INET6 && _pr_recycle_INET6_tail) { - _pr_recycle_INET6_tail--; - rv = _pr_recycle_INET6_array[_pr_recycle_INET6_tail]; - _MD_UNLOCK(&_pr_recycle_lock); - return rv; - } - _MD_UNLOCK(&_pr_recycle_lock); - - rv = _PR_MD_SOCKET(af, SOCK_STREAM, 0); - if (rv != INVALID_SOCKET && _md_Associate((HANDLE)rv) == 0) { - closesocket(rv); - return INVALID_SOCKET; - } - return rv; -} - -/* _md_put_recycled_socket() - * Add a socket to the recycle bin. - */ -static void -_md_put_recycled_socket(SOCKET newsock, int af) -{ - PR_ASSERT(_pr_recycle_INET_tail >= 0); - PR_ASSERT(_pr_recycle_INET6_tail >= 0); - - _MD_LOCK(&_pr_recycle_lock); - if (af == AF_INET && _pr_recycle_INET_tail < RECYCLE_SIZE) { - _pr_recycle_INET_array[_pr_recycle_INET_tail] = newsock; - _pr_recycle_INET_tail++; - _MD_UNLOCK(&_pr_recycle_lock); - } else if (af == AF_INET6 && _pr_recycle_INET6_tail < RECYCLE_SIZE) { - _pr_recycle_INET6_array[_pr_recycle_INET6_tail] = newsock; - _pr_recycle_INET6_tail++; - _MD_UNLOCK(&_pr_recycle_lock); - } else { - _MD_UNLOCK(&_pr_recycle_lock); - closesocket(newsock); - } - - return; -} - -/* _md_Associate() - * Associates a file with the completion port. - * Returns 0 on failure, 1 on success. - */ -PRInt32 -_md_Associate(HANDLE file) -{ - HANDLE port; - - if (!_native_threads_only) { - port = CreateIoCompletionPort((HANDLE)file, - _pr_completion_port, - KEY_IO, - 0); - - /* XXX should map error codes on failures */ - return (port == _pr_completion_port); - } else { - return 1; - } -} - -/* - * _md_MakeNonblock() - * Make a socket nonblocking. - * Returns 0 on failure, 1 on success. - */ -static PRInt32 -_md_MakeNonblock(HANDLE file) -{ - int rv; - u_long one = 1; - - rv = ioctlsocket((SOCKET)file, FIONBIO, &one); - /* XXX should map error codes on failures */ - return (rv == 0); -} - -static int missing_completions = 0; -static int max_wait_loops = 0; - -static PRInt32 -_NT_IO_ABORT(PROsfd sock) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRBool fWait; - PRInt32 rv; - int loop_count; - - /* This is a clumsy way to abort the IO, but it is all we can do. - * It looks a bit racy, but we handle all the cases. - * case 1: IO completes before calling closesocket - * case 1a: fWait is set to PR_FALSE - * This should e the most likely case. We'll properly - * not wait call _NT_IO_WAIT, since the closesocket() - * won't be forcing a completion. - * case 1b: fWait is set to PR_TRUE - * This hopefully won't happen much. When it does, this - * thread will timeout in _NT_IO_WAIT for CLOSE_INTERVAL - * before cleaning up. - * case 2: IO does not complete before calling closesocket - * case 2a: IO never completes - * This is the likely case. We'll close it and wait - * for the completion forced by the close. Return should - * be immediate. - * case 2b: IO completes just after calling closesocket - * Since the closesocket is issued, we'll either get a - * completion back for the real IO or for the close. We - * don't really care. It may not even be possible to get - * a real completion here. In any event, we'll awaken - * from NT_IO_WAIT immediately. - */ - - _PR_THREAD_LOCK(me); - fWait = me->io_pending; - if (fWait) { - /* - * If there's still I/O pending, it should have already timed - * out once before this function is called. - */ - PR_ASSERT(me->io_suspended == PR_TRUE); - - /* Set up to wait for I/O completion again */ - me->state = _PR_IO_WAIT; - me->io_suspended = PR_FALSE; - me->md.interrupt_disabled = PR_TRUE; - } - _PR_THREAD_UNLOCK(me); - - /* Close the socket if there is one */ - if (sock != INVALID_SOCKET) { - rv = closesocket((SOCKET)sock); - } - - /* If there was I/O pending before the close, wait for it to complete */ - if (fWait) { - - /* Wait and wait for the I/O to complete */ - for (loop_count = 0; fWait; ++loop_count) { - - _NT_IO_WAIT(me, CLOSE_TIMEOUT); - - _PR_THREAD_LOCK(me); - fWait = me->io_pending; - if (fWait) { - PR_ASSERT(me->io_suspended == PR_TRUE); - me->state = _PR_IO_WAIT; - me->io_suspended = PR_FALSE; - } - _PR_THREAD_UNLOCK(me); - - if (loop_count > max_wait_loops) { - max_wait_loops = loop_count; - } - } - - if (loop_count > 1) { - ++missing_completions; - } - - me->md.interrupt_disabled = PR_FALSE; - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - } - - PR_ASSERT(me->io_pending == PR_FALSE); - me->md.thr_bound_cpu = NULL; - me->io_suspended = PR_FALSE; - - return rv; -} - - -PROsfd -_PR_MD_SOCKET(int af, int type, int flags) -{ - SOCKET sock; - - sock = socket(af, type, flags); - - if (sock == INVALID_SOCKET) { - _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError()); - } - - return (PROsfd)sock; -} - -struct connect_data_s { - PRInt32 status; - PRInt32 error; - PROsfd osfd; - struct sockaddr *addr; - PRUint32 addrlen; - PRIntervalTime timeout; -}; - -void -_PR_MD_connect_thread(void *cdata) -{ - struct connect_data_s *cd = (struct connect_data_s *)cdata; - - cd->status = connect(cd->osfd, cd->addr, cd->addrlen); - - if (cd->status == SOCKET_ERROR) - cd->error = WSAGetLastError(); - - return; -} - - -PRInt32 -_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, - PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - u_long nbio; - PRInt32 rc; - - if (fd->secret->nonblocking) { - if (!fd->secret->md.io_model_committed) { - rv = _md_MakeNonblock((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - - if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) { - err = WSAGetLastError(); - _PR_MD_MAP_CONNECT_ERROR(err); - } - return rv; - } - - /* - * Temporarily make the socket non-blocking so that we can - * initiate a non-blocking connect and wait for its completion - * (with a timeout) in select. - */ - PR_ASSERT(!fd->secret->md.io_model_committed); - nbio = 1; - rv = ioctlsocket((SOCKET)osfd, FIONBIO, &nbio); - PR_ASSERT(0 == rv); - - rc = _nt_nonblock_connect(fd, (struct sockaddr *) addr, addrlen, timeout); - - /* Set the socket back to blocking. */ - nbio = 0; - rv = ioctlsocket((SOCKET)osfd, FIONBIO, &nbio); - PR_ASSERT(0 == rv); - - return rc; -} - -PRInt32 -_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) -{ - PRInt32 rv; -#if 0 - int one = 1; -#endif - - rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen); - - if (rv == SOCKET_ERROR) { - _PR_MD_MAP_BIND_ERROR(WSAGetLastError()); - return -1; - } - -#if 0 - /* Disable nagle- so far unknown if this is good or not... - */ - rv = setsockopt(fd->secret->md.osfd, - SOL_SOCKET, - TCP_NODELAY, - (const char *)&one, - sizeof(one)); - PR_ASSERT(rv == 0); -#endif - - return 0; -} - -void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd accept_sock, PROsfd listen_sock) -{ - /* Sockets accept()'d with AcceptEx need to call this setsockopt before - * calling anything other than ReadFile(), WriteFile(), send(), recv(), - * Transmitfile(), and closesocket(). In order to call any other - * winsock functions, we have to make this setsockopt call. - * - * XXXMB - For the server, we *NEVER* need this in - * the "normal" code path. But now we have to call it. This is a waste - * of a system call. We'd like to only call it before calling the - * obscure socket calls, but since we don't know at that point what the - * original socket was (or even if it is still alive) we can't do it - * at that point... - */ - setsockopt((SOCKET)accept_sock, - SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, - (char *)&listen_sock, - sizeof(listen_sock)); - -} - -#define INET_ADDR_PADDED (sizeof(PRNetAddr) + 16) -PROsfd -_PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, - PRIntervalTime timeout, PRBool fast, - _PR_AcceptTimeoutCallback callback, void *callbackArg) -{ - PROsfd osfd = fd->secret->md.osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - SOCKET accept_sock; - int bytes; - PRNetAddr *Laddr; - PRNetAddr *Raddr; - PRUint32 llen, err; - int rv; - - if (_NT_USE_NB_IO(fd)) { - if (!fd->secret->md.io_model_committed) { - rv = _md_MakeNonblock((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - /* - * The accepted socket inherits the nonblocking and - * inheritable (HANDLE_FLAG_INHERIT) attributes of - * the listening socket. - */ - accept_sock = _nt_nonblock_accept(fd, (struct sockaddr *)raddr, rlen, timeout); - if (!fd->secret->nonblocking) { - u_long zero = 0; - - rv = ioctlsocket(accept_sock, FIONBIO, &zero); - PR_ASSERT(0 == rv); - } - return accept_sock; - } - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return -1; - } - - if (!fd->secret->md.io_model_committed) { - rv = _md_Associate((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - - if (!me->md.acceptex_buf) { - me->md.acceptex_buf = PR_MALLOC(2*INET_ADDR_PADDED); - if (!me->md.acceptex_buf) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - } - - accept_sock = _md_get_recycled_socket(fd->secret->af); - if (accept_sock == INVALID_SOCKET) - return -1; - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - if (_native_threads_only) - me->md.overlapped.overlapped.hEvent = me->md.thr_event; - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - closesocket(accept_sock); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - me->io_fd = osfd; - - rv = AcceptEx((SOCKET)osfd, - accept_sock, - me->md.acceptex_buf, - 0, - INET_ADDR_PADDED, - INET_ADDR_PADDED, - &bytes, - &(me->md.overlapped.overlapped)); - - if ( (rv == 0) && ((err = WSAGetLastError()) != ERROR_IO_PENDING)) { - /* Argh! The IO failed */ - closesocket(accept_sock); - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - _PR_THREAD_UNLOCK(me); - - _PR_MD_MAP_ACCEPTEX_ERROR(err); - return -1; - } - - if (_native_threads_only && rv) { - _native_thread_io_nowait(me, rv, bytes); - } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { - PR_ASSERT(0); - closesocket(accept_sock); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); - - if (me->io_suspended) { - closesocket(accept_sock); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } - return -1; - } - - if (me->md.blocked_io_status == 0) { - closesocket(accept_sock); - _PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error); - return -1; - } - - if (!fast) - _PR_MD_UPDATE_ACCEPT_CONTEXT((SOCKET)accept_sock, (SOCKET)osfd); - - /* IO is done */ - GetAcceptExSockaddrs( - me->md.acceptex_buf, - 0, - INET_ADDR_PADDED, - INET_ADDR_PADDED, - (LPSOCKADDR *)&(Laddr), - &llen, - (LPSOCKADDR *)&(Raddr), - (unsigned int *)rlen); - - if (raddr != NULL) - memcpy((char *)raddr, (char *)&Raddr->inet, *rlen); - - PR_ASSERT(me->io_pending == PR_FALSE); - - return accept_sock; -} - -PRInt32 -_PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, PRNetAddr **raddr, - void *buf, PRInt32 amount, PRIntervalTime timeout, - PRBool fast, _PR_AcceptTimeoutCallback callback, - void *callbackArg) -{ - PROsfd sock = sd->secret->md.osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - int bytes; - PRNetAddr *Laddr; - PRUint32 llen, rlen, err; - int rv; - PRBool isConnected; - PRBool madeCallback = PR_FALSE; - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return -1; - } - - if (!sd->secret->md.io_model_committed) { - rv = _md_Associate((HANDLE)sock); - PR_ASSERT(0 != rv); - sd->secret->md.io_model_committed = PR_TRUE; - } - - *newSock = _md_get_recycled_socket(sd->secret->af); - if (*newSock == INVALID_SOCKET) - return -1; - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - if (_native_threads_only) - me->md.overlapped.overlapped.hEvent = me->md.thr_event; - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - closesocket(*newSock); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - me->io_fd = sock; - - rv = AcceptEx((SOCKET)sock, - *newSock, - buf, - amount, - INET_ADDR_PADDED, - INET_ADDR_PADDED, - &bytes, - &(me->md.overlapped.overlapped)); - - if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING)) { - closesocket(*newSock); - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - _PR_THREAD_UNLOCK(me); - - _PR_MD_MAP_ACCEPTEX_ERROR(err); - return -1; - } - - if (_native_threads_only && rv) { - _native_thread_io_nowait(me, rv, bytes); - } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { - PR_ASSERT(0); - closesocket(*newSock); - return -1; - } - -retry: - if (me->io_suspended) { - PRInt32 err; - INT seconds; - INT bytes = sizeof(seconds); - - PR_ASSERT(timeout != PR_INTERVAL_NO_TIMEOUT); - - err = getsockopt(*newSock, - SOL_SOCKET, - SO_CONNECT_TIME, - (char *)&seconds, - (PINT)&bytes); - if ( err == NO_ERROR ) { - PRIntervalTime elapsed = PR_SecondsToInterval(seconds); - - if (seconds == 0xffffffff) - isConnected = PR_FALSE; - else - isConnected = PR_TRUE; - - if (!isConnected) { - if (madeCallback == PR_FALSE && callback) - callback(callbackArg); - madeCallback = PR_TRUE; - me->state = _PR_IO_WAIT; - if (_NT_ResumeIO(me, timeout) == PR_FAILURE) { - closesocket(*newSock); - return -1; - } - goto retry; - } - - if (elapsed < timeout) { - /* Socket is connected but time not elapsed, RESUME IO */ - timeout -= elapsed; - me->state = _PR_IO_WAIT; - if (_NT_ResumeIO(me, timeout) == PR_FAILURE) { - closesocket(*newSock); - return -1; - } - goto retry; - } - } else { - /* What to do here? Assume socket not open?*/ - PR_ASSERT(0); - isConnected = PR_FALSE; - } - - rv = _NT_IO_ABORT(*newSock); - - PR_ASSERT(me->io_pending == PR_FALSE); - PR_ASSERT(me->io_suspended == PR_FALSE); - PR_ASSERT(me->md.thr_bound_cpu == NULL); - /* If the IO is still suspended, it means we didn't get any - * completion from NT_IO_WAIT. This is not disasterous, I hope, - * but it may mean we still have an IO outstanding... Try to - * recover by just allowing ourselves to continue. - */ - me->io_suspended = PR_FALSE; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } - me->state = _PR_RUNNING; - closesocket(*newSock); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE); - PR_ASSERT(me->io_suspended == PR_FALSE); - PR_ASSERT(me->md.thr_bound_cpu == NULL); - - if (me->md.blocked_io_status == 0) { - _PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error); - closesocket(*newSock); - return -1; - } - - if (!fast) - _PR_MD_UPDATE_ACCEPT_CONTEXT((SOCKET)*newSock, (SOCKET)sock); - - /* IO is done */ - GetAcceptExSockaddrs( - buf, - amount, - INET_ADDR_PADDED, - INET_ADDR_PADDED, - (LPSOCKADDR *)&(Laddr), - &llen, - (LPSOCKADDR *)(raddr), - (unsigned int *)&rlen); - - return me->md.blocked_io_bytes; -} - -PRInt32 -_PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd, - PRInt32 flags, PRIntervalTime timeout) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRInt32 tflags; - int rv, err; - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return -1; - } - - if (!sock->secret->md.io_model_committed) { - rv = _md_Associate((HANDLE)sock->secret->md.osfd); - PR_ASSERT(0 != rv); - sock->secret->md.io_model_committed = PR_TRUE; - } - if (!me->md.xmit_bufs) { - me->md.xmit_bufs = PR_NEW(TRANSMIT_FILE_BUFFERS); - if (!me->md.xmit_bufs) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - } - me->md.xmit_bufs->Head = (void *)sfd->header; - me->md.xmit_bufs->HeadLength = sfd->hlen; - me->md.xmit_bufs->Tail = (void *)sfd->trailer; - me->md.xmit_bufs->TailLength = sfd->tlen; - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - me->md.overlapped.overlapped.Offset = sfd->file_offset; - if (_native_threads_only) - me->md.overlapped.overlapped.hEvent = me->md.thr_event; - - tflags = 0; - if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) - tflags = TF_DISCONNECT | TF_REUSE_SOCKET; - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - me->io_fd = sock->secret->md.osfd; - - rv = TransmitFile((SOCKET)sock->secret->md.osfd, - (HANDLE)sfd->fd->secret->md.osfd, - (DWORD)sfd->file_nbytes, - (DWORD)0, - (LPOVERLAPPED)&(me->md.overlapped.overlapped), - (TRANSMIT_FILE_BUFFERS *)me->md.xmit_bufs, - (DWORD)tflags); - if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - _PR_THREAD_UNLOCK(me); - - _PR_MD_MAP_TRANSMITFILE_ERROR(err); - return -1; - } - - if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { - PR_ASSERT(0); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); - - if (me->io_suspended) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } - return -1; - } - - if (me->md.blocked_io_status == 0) { - _PR_MD_MAP_TRANSMITFILE_ERROR(me->md.blocked_io_error); - return -1; - } - - if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { - _md_put_recycled_socket(sock->secret->md.osfd, sock->secret->af); - } - - PR_ASSERT(me->io_pending == PR_FALSE); - - return me->md.blocked_io_bytes; -} - -PRInt32 -_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - int bytes; - int rv, err; - - if (_NT_USE_NB_IO(fd)) { - if (!fd->secret->md.io_model_committed) { - rv = _md_MakeNonblock((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - return _nt_nonblock_recv(fd, buf, amount, flags, timeout); - } - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return -1; - } - - if (!fd->secret->md.io_model_committed) { - rv = _md_Associate((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - if (_native_threads_only) - me->md.overlapped.overlapped.hEvent = me->md.thr_event; - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - me->io_fd = osfd; - - rv = ReadFile((HANDLE)osfd, - buf, - amount, - &bytes, - &(me->md.overlapped.overlapped)); - if ( (rv == 0) && (GetLastError() != ERROR_IO_PENDING) ) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - _PR_THREAD_UNLOCK(me); - - if ((err = GetLastError()) == ERROR_HANDLE_EOF) - return 0; - _PR_MD_MAP_READ_ERROR(err); - return -1; - } - - if (_native_threads_only && rv) { - _native_thread_io_nowait(me, rv, bytes); - } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { - PR_ASSERT(0); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); - - if (me->io_suspended) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } - return -1; - } - - if (me->md.blocked_io_status == 0) { - if (me->md.blocked_io_error == ERROR_HANDLE_EOF) - return 0; - _PR_MD_MAP_READ_ERROR(me->md.blocked_io_error); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE); - - return me->md.blocked_io_bytes; -} - -PRInt32 -_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - int bytes; - int rv, err; - - if (_NT_USE_NB_IO(fd)) { - if (!fd->secret->md.io_model_committed) { - rv = _md_MakeNonblock((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - return _nt_nonblock_send(fd, (char *)buf, amount, timeout); - } - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return -1; - } - - if (!fd->secret->md.io_model_committed) { - rv = _md_Associate((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - if (_native_threads_only) - me->md.overlapped.overlapped.hEvent = me->md.thr_event; - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - me->io_fd = osfd; - - rv = WriteFile((HANDLE)osfd, - buf, - amount, - &bytes, - &(me->md.overlapped.overlapped)); - if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - _PR_THREAD_UNLOCK(me); - - _PR_MD_MAP_WRITE_ERROR(err); - return -1; - } - - if (_native_threads_only && rv) { - _native_thread_io_nowait(me, rv, bytes); - } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { - PR_ASSERT(0); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); - - if (me->io_suspended) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } - return -1; - } - - if (me->md.blocked_io_status == 0) { - _PR_MD_MAP_WRITE_ERROR(me->md.blocked_io_error); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE); - - return me->md.blocked_io_bytes; -} - -PRInt32 -_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv; - - if (!fd->secret->md.io_model_committed) { - rv = _md_MakeNonblock((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - if (_NT_USE_NB_IO(fd)) - return _nt_nonblock_sendto(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout); - else - return pt_SendTo(osfd, buf, amount, flags, addr, addrlen, timeout); -} - -PRInt32 -_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv; - - if (!fd->secret->md.io_model_committed) { - rv = _md_MakeNonblock((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - if (_NT_USE_NB_IO(fd)) - return _nt_nonblock_recvfrom(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout); - else - return pt_RecvFrom(osfd, buf, amount, flags, addr, addrlen, timeout); -} - -/* XXXMB - for now this is a sockets call only */ -PRInt32 -_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - int index; - int sent = 0; - int rv; - - if (_NT_USE_NB_IO(fd)) { - if (!fd->secret->md.io_model_committed) { - rv = _md_MakeNonblock((HANDLE)osfd); - PR_ASSERT(0 != rv); - fd->secret->md.io_model_committed = PR_TRUE; - } - return _nt_nonblock_writev(fd, iov, iov_size, timeout); - } - - for (index=0; index 0) - sent += rv; - if ( rv != iov[index].iov_len ) { - if (sent <= 0) - return -1; - return -1; - } - } - - return sent; -} - -PRInt32 -_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog) -{ - PRInt32 rv; - - rv = listen(fd->secret->md.osfd, backlog); - if (rv < 0) - _PR_MD_MAP_LISTEN_ERROR(WSAGetLastError()); - return(rv); -} - -PRInt32 -_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how) -{ - PRInt32 rv; - - rv = shutdown(fd->secret->md.osfd, how); - if (rv < 0) - _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError()); - return(rv); -} - -PRStatus -_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) -{ - PRInt32 rv; - - rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len); - if (rv==0) - return PR_SUCCESS; - else { - _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError()); - return PR_FAILURE; - } -} - -PRStatus -_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) -{ - PRInt32 rv; - - /* - * NT has a bug that, when invoked on a socket accepted by - * AcceptEx(), getpeername() returns an all-zero peer address. - * To work around this bug, we store the peer's address (returned - * by AcceptEx()) with the socket fd and use the cached peer - * address if the socket is an accepted socket. - */ - - if (fd->secret->md.accepted_socket) { - INT seconds; - INT bytes = sizeof(seconds); - - /* - * Determine if the socket is connected. - */ - - rv = getsockopt(fd->secret->md.osfd, - SOL_SOCKET, - SO_CONNECT_TIME, - (char *) &seconds, - (PINT) &bytes); - if (rv == NO_ERROR) { - if (seconds == 0xffffffff) { - PR_SetError(PR_NOT_CONNECTED_ERROR, 0); - return PR_FAILURE; - } - *len = PR_NETADDR_SIZE(&fd->secret->md.peer_addr); - memcpy(addr, &fd->secret->md.peer_addr, *len); - return PR_SUCCESS; - } else { - _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); - return PR_FAILURE; - } - } else { - rv = getpeername((SOCKET)fd->secret->md.osfd, - (struct sockaddr *) addr, len); - if (rv == 0) { - return PR_SUCCESS; - } else { - _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError()); - return PR_FAILURE; - } - } -} - -PRStatus -_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen) -{ - PRInt32 rv; - - rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); - if (rv==0) - return PR_SUCCESS; - else { - _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); - return PR_FAILURE; - } -} - -PRStatus -_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen) -{ - PRInt32 rv; - - rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); - if (rv==0) - return PR_SUCCESS; - else { - _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError()); - return PR_FAILURE; - } -} - -/* --- FILE IO ----------------------------------------------------------- */ - -PROsfd -_PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode) -{ - HANDLE file; - PRInt32 access = 0; - PRInt32 flags = 0; - PRInt32 flag6 = 0; - - if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; - - if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ; - if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE; - - if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) - flags = CREATE_NEW; - else if (osflags & PR_CREATE_FILE) - flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS; - else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING; - else flags = OPEN_EXISTING; - - - flag6 |= FILE_FLAG_OVERLAPPED; - - file = CreateFile(name, - access, - FILE_SHARE_READ|FILE_SHARE_WRITE, - NULL, - flags, - flag6, - NULL); - if (file == INVALID_HANDLE_VALUE) { - _PR_MD_MAP_OPEN_ERROR(GetLastError()); - return -1; - } - - if (osflags & PR_APPEND) { - if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) { - _PR_MD_MAP_LSEEK_ERROR(GetLastError()); - CloseHandle(file); - return -1; - } - } - - return (PROsfd)file; -} - -PROsfd -_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode) -{ - HANDLE file; - PRInt32 access = 0; - PRInt32 flags = 0; - PRInt32 flag6 = 0; - SECURITY_ATTRIBUTES sa; - LPSECURITY_ATTRIBUTES lpSA = NULL; - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - - if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; - - if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ; - if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE; - - if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) - flags = CREATE_NEW; - else if (osflags & PR_CREATE_FILE) - flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS; - else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING; - else flags = OPEN_EXISTING; - - - flag6 |= FILE_FLAG_OVERLAPPED; - - if (osflags & PR_CREATE_FILE) { - if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable, - &pSD, &pACL) == PR_SUCCESS) { - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = FALSE; - lpSA = &sa; - } - } - file = CreateFile(name, - access, - FILE_SHARE_READ|FILE_SHARE_WRITE, - lpSA, - flags, - flag6, - NULL); - if (lpSA != NULL) { - _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); - } - if (file == INVALID_HANDLE_VALUE) { - _PR_MD_MAP_OPEN_ERROR(GetLastError()); - return -1; - } - - if (osflags & PR_APPEND) { - if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) { - _PR_MD_MAP_LSEEK_ERROR(GetLastError()); - CloseHandle(file); - return -1; - } - } - - return (PROsfd)file; -} - -PRInt32 -_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len) -{ - PROsfd f = fd->secret->md.osfd; - PRUint32 bytes; - int rv, err; - LONG hiOffset = 0; - LONG loOffset; - - if (!fd->secret->md.sync_file_io) { - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return -1; - } - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - - me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT); - PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR)); - - if (fd->secret->inheritable == _PR_TRI_TRUE) { - rv = ReadFile((HANDLE)f, - (LPVOID)buf, - len, - &bytes, - &me->md.overlapped.overlapped); - if (rv != 0) { - loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT); - PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR)); - return bytes; - } - err = GetLastError(); - if (err == ERROR_IO_PENDING) { - rv = GetOverlappedResult((HANDLE)f, - &me->md.overlapped.overlapped, &bytes, TRUE); - if (rv != 0) { - loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT); - PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR)); - return bytes; - } - err = GetLastError(); - } - if (err == ERROR_HANDLE_EOF) { - return 0; - } else { - _PR_MD_MAP_READ_ERROR(err); - return -1; - } - } else { - if (!fd->secret->md.io_model_committed) { - rv = _md_Associate((HANDLE)f); - PR_ASSERT(rv != 0); - fd->secret->md.io_model_committed = PR_TRUE; - } - - if (_native_threads_only) - me->md.overlapped.overlapped.hEvent = me->md.thr_event; - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - me->io_fd = f; - - rv = ReadFile((HANDLE)f, - (LPVOID)buf, - len, - &bytes, - &me->md.overlapped.overlapped); - if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - _PR_THREAD_UNLOCK(me); - - if (err == ERROR_HANDLE_EOF) { - return 0; - } - _PR_MD_MAP_READ_ERROR(err); - return -1; - } - - if (_native_threads_only && rv) { - _native_thread_io_nowait(me, rv, bytes); - } else if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { - PR_ASSERT(0); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); - - if (me->io_suspended) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } - return -1; - } - - if (me->md.blocked_io_status == 0) { - if (me->md.blocked_io_error == ERROR_HANDLE_EOF) { - return 0; - } - _PR_MD_MAP_READ_ERROR(me->md.blocked_io_error); - return -1; - } - - SetFilePointer((HANDLE)f, me->md.blocked_io_bytes, 0, FILE_CURRENT); - - PR_ASSERT(me->io_pending == PR_FALSE); - - return me->md.blocked_io_bytes; - } - } else { - - rv = ReadFile((HANDLE)f, - (LPVOID)buf, - len, - &bytes, - NULL); - if (rv == 0) { - err = GetLastError(); - /* ERROR_HANDLE_EOF can only be returned by async io */ - PR_ASSERT(err != ERROR_HANDLE_EOF); - if (err == ERROR_BROKEN_PIPE) { - /* The write end of the pipe has been closed. */ - return 0; - } - _PR_MD_MAP_READ_ERROR(err); - return -1; - } - return bytes; - } -} - -PRInt32 -_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len) -{ - PROsfd f = fd->secret->md.osfd; - PRInt32 bytes; - int rv, err; - LONG hiOffset = 0; - LONG loOffset; - LARGE_INTEGER offset; /* use for the calculation of the new offset */ - - if (!fd->secret->md.sync_file_io) { - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return -1; - } - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - - me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT); - PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR)); - - if (fd->secret->inheritable == _PR_TRI_TRUE) { - rv = WriteFile((HANDLE)f, - (LPVOID)buf, - len, - &bytes, - &me->md.overlapped.overlapped); - if (rv != 0) { - loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT); - PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR)); - return bytes; - } - err = GetLastError(); - if (err == ERROR_IO_PENDING) { - rv = GetOverlappedResult((HANDLE)f, - &me->md.overlapped.overlapped, &bytes, TRUE); - if (rv != 0) { - loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT); - PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR)); - return bytes; - } - err = GetLastError(); - } - _PR_MD_MAP_READ_ERROR(err); - return -1; - } else { - if (!fd->secret->md.io_model_committed) { - rv = _md_Associate((HANDLE)f); - PR_ASSERT(rv != 0); - fd->secret->md.io_model_committed = PR_TRUE; - } - if (_native_threads_only) - me->md.overlapped.overlapped.hEvent = me->md.thr_event; - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - me->io_fd = f; - - rv = WriteFile((HANDLE)f, - buf, - len, - &bytes, - &(me->md.overlapped.overlapped)); - if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - _PR_THREAD_UNLOCK(me); - - _PR_MD_MAP_WRITE_ERROR(err); - return -1; - } - - if (_native_threads_only && rv) { - _native_thread_io_nowait(me, rv, bytes); - } else if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { - PR_ASSERT(0); - return -1; - } - - PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); - - if (me->io_suspended) { - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - } else { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } - return -1; - } - - if (me->md.blocked_io_status == 0) { - _PR_MD_MAP_WRITE_ERROR(me->md.blocked_io_error); - return -1; - } - - /* - * Moving the file pointer by a relative offset (FILE_CURRENT) - * does not work with a file on a network drive exported by a - * Win2K system. We still don't know why. A workaround is to - * move the file pointer by an absolute offset (FILE_BEGIN). - * (Bugzilla bug 70765) - */ - offset.LowPart = me->md.overlapped.overlapped.Offset; - offset.HighPart = me->md.overlapped.overlapped.OffsetHigh; - offset.QuadPart += me->md.blocked_io_bytes; - - SetFilePointer((HANDLE)f, offset.LowPart, &offset.HighPart, FILE_BEGIN); - - PR_ASSERT(me->io_pending == PR_FALSE); - - return me->md.blocked_io_bytes; - } - } else { - rv = WriteFile((HANDLE)f, - buf, - len, - &bytes, - NULL); - if (rv == 0) { - _PR_MD_MAP_WRITE_ERROR(GetLastError()); - return -1; - } - return bytes; - } -} - -PRInt32 -_PR_MD_SOCKETAVAILABLE(PRFileDesc *fd) -{ - PRInt32 result; - - if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError()); - return -1; - } - return result; -} - -PRInt32 -_PR_MD_PIPEAVAILABLE(PRFileDesc *fd) -{ - if (NULL == fd) - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; -} - -PROffset32 -_PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) -{ - DWORD moveMethod; - PROffset32 rv; - - switch (whence) { - case PR_SEEK_SET: - moveMethod = FILE_BEGIN; - break; - case PR_SEEK_CUR: - moveMethod = FILE_CURRENT; - break; - case PR_SEEK_END: - moveMethod = FILE_END; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - - rv = SetFilePointer((HANDLE)fd->secret->md.osfd, offset, NULL, moveMethod); - - /* - * If the lpDistanceToMoveHigh argument (third argument) is - * NULL, SetFilePointer returns 0xffffffff on failure. - */ - if (-1 == rv) { - _PR_MD_MAP_LSEEK_ERROR(GetLastError()); - } - return rv; -} - -PROffset64 -_PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) -{ - DWORD moveMethod; - LARGE_INTEGER li; - DWORD err; - - switch (whence) { - case PR_SEEK_SET: - moveMethod = FILE_BEGIN; - break; - case PR_SEEK_CUR: - moveMethod = FILE_CURRENT; - break; - case PR_SEEK_END: - moveMethod = FILE_END; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - - li.QuadPart = offset; - li.LowPart = SetFilePointer((HANDLE)fd->secret->md.osfd, - li.LowPart, &li.HighPart, moveMethod); - - if (0xffffffff == li.LowPart && (err = GetLastError()) != NO_ERROR) { - _PR_MD_MAP_LSEEK_ERROR(err); - li.QuadPart = -1; - } - return li.QuadPart; -} - -/* - * This is documented to succeed on read-only files, but Win32's - * FlushFileBuffers functions fails with "access denied" in such a - * case. So we only signal an error if the error is *not* "access - * denied". - */ -PRInt32 -_PR_MD_FSYNC(PRFileDesc *fd) -{ - /* - * From the documentation: - * - * On Windows NT, the function FlushFileBuffers fails if hFile - * is a handle to console output. That is because console - * output is not buffered. The function returns FALSE, and - * GetLastError returns ERROR_INVALID_HANDLE. - * - * On the other hand, on Win95, it returns without error. I cannot - * assume that 0, 1, and 2 are console, because if someone closes - * System.out and then opens a file, they might get file descriptor - * 1. An error on *that* version of 1 should be reported, whereas - * an error on System.out (which was the original 1) should be - * ignored. So I use isatty() to ensure that such an error was - * because of this, and if it was, I ignore the error. - */ - - BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd); - - if (!ok) { - DWORD err = GetLastError(); - - if (err != ERROR_ACCESS_DENIED) { /* from winerror.h */ - _PR_MD_MAP_FSYNC_ERROR(err); - return -1; - } - } - return 0; -} - -PRInt32 -_PR_MD_CLOSE(PROsfd osfd, PRBool socket) -{ - PRInt32 rv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (socket) { - rv = closesocket((SOCKET)osfd); - if (rv < 0) - _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError()); - } else { - rv = CloseHandle((HANDLE)osfd)?0:-1; - if (rv < 0) - _PR_MD_MAP_CLOSE_ERROR(GetLastError()); - } - - if (rv == 0 && me->io_suspended) { - if (me->io_fd == osfd) { - PRBool fWait; - - _PR_THREAD_LOCK(me); - me->state = _PR_IO_WAIT; - /* The IO could have completed on another thread just after - * calling closesocket while the io_suspended flag was true. - * So we now grab the lock to do a safe check on io_pending to - * see if we need to wait or not. - */ - fWait = me->io_pending; - me->io_suspended = PR_FALSE; - me->md.interrupt_disabled = PR_TRUE; - _PR_THREAD_UNLOCK(me); - - if (fWait) - _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(me->io_suspended == PR_FALSE); - PR_ASSERT(me->io_pending == PR_FALSE); - /* - * I/O operation is no longer pending; the thread can now - * run on any cpu - */ - _PR_THREAD_LOCK(me); - me->md.interrupt_disabled = PR_FALSE; - me->md.thr_bound_cpu = NULL; - me->io_suspended = PR_FALSE; - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(me); - } - } - return rv; -} - -PRStatus -_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) -{ - BOOL rv; - - if (fd->secret->md.io_model_committed) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - rv = SetHandleInformation( - (HANDLE)fd->secret->md.osfd, - HANDLE_FLAG_INHERIT, - inheritable ? HANDLE_FLAG_INHERIT : 0); - if (0 == rv) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -void -_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported) -{ - if (imported) { - fd->secret->inheritable = _PR_TRI_UNKNOWN; - } else { - fd->secret->inheritable = _PR_TRI_FALSE; - } -} - -void -_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd) -{ - DWORD flags; - - PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); - if (fd->secret->md.io_model_committed) { - return; - } - if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) { - if (flags & HANDLE_FLAG_INHERIT) { - fd->secret->inheritable = _PR_TRI_TRUE; - } else { - fd->secret->inheritable = _PR_TRI_FALSE; - } - } -} - - -/* --- DIR IO ------------------------------------------------------------ */ -#define GetFileFromDIR(d) (d)->d_entry.cFileName -#define FileIsHidden(d) ((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) - -void FlipSlashes(char *cp, int len) -{ - while (--len >= 0) { - if (cp[0] == '/') { - cp[0] = PR_DIRECTORY_SEPARATOR; - } - cp = _mbsinc(cp); - } -} /* end FlipSlashes() */ - -/* -** -** Local implementations of standard Unix RTL functions which are not provided -** by the VC RTL. -** -*/ - -PRInt32 -_PR_MD_CLOSE_DIR(_MDDir *d) -{ - if ( d ) { - if (FindClose( d->d_hdl )) { - d->magic = (PRUint32)-1; - return 0; - } else { - _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError()); - return -1; - } - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; -} - - -PRStatus -_PR_MD_OPEN_DIR(_MDDir *d, const char *name) -{ - char filename[ MAX_PATH ]; - int len; - - len = strlen(name); - /* Need 5 bytes for \*.* and the trailing null byte. */ - if (len + 5 > MAX_PATH) { - PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); - return PR_FAILURE; - } - strcpy(filename, name); - - /* - * If 'name' ends in a slash or backslash, do not append - * another backslash. - */ - if (IsPrevCharSlash(filename, filename + len)) { - len--; - } - strcpy(&filename[len], "\\*.*"); - FlipSlashes( filename, strlen(filename) ); - - d->d_hdl = FindFirstFile( filename, &(d->d_entry) ); - if ( d->d_hdl == INVALID_HANDLE_VALUE ) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return PR_FAILURE; - } - d->firstEntry = PR_TRUE; - d->magic = _MD_MAGIC_DIR; - return PR_SUCCESS; -} - -char * -_PR_MD_READ_DIR(_MDDir *d, PRIntn flags) -{ - PRInt32 err; - BOOL rv; - char *fileName; - - if ( d ) { - while (1) { - if (d->firstEntry) { - d->firstEntry = PR_FALSE; - rv = 1; - } else { - rv = FindNextFile(d->d_hdl, &(d->d_entry)); - } - if (rv == 0) { - break; - } - fileName = GetFileFromDIR(d); - if ( (flags & PR_SKIP_DOT) && - (fileName[0] == '.') && (fileName[1] == '\0')) - continue; - if ( (flags & PR_SKIP_DOT_DOT) && - (fileName[0] == '.') && (fileName[1] == '.') && - (fileName[2] == '\0')) - continue; - if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d)) - continue; - return fileName; - } - err = GetLastError(); - PR_ASSERT(NO_ERROR != err); - _PR_MD_MAP_READDIR_ERROR(err); - return NULL; - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; -} - -PRInt32 -_PR_MD_DELETE(const char *name) -{ - if (DeleteFile(name)) { - return 0; - } else { - _PR_MD_MAP_DELETE_ERROR(GetLastError()); - return -1; - } -} - -void -_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm) -{ - PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime)); - CopyMemory(prtm, filetime, sizeof(PRTime)); -#ifdef __GNUC__ - *prtm = (*prtm - _pr_filetime_offset) / 10LL; -#else - *prtm = (*prtm - _pr_filetime_offset) / 10i64; -#endif - -#ifdef DEBUG - /* Doublecheck our calculation. */ - { - SYSTEMTIME systime; - PRExplodedTime etm; - PRTime cmp; /* for comparison */ - BOOL rv; - - rv = FileTimeToSystemTime(filetime, &systime); - PR_ASSERT(0 != rv); - - /* - * PR_ImplodeTime ignores wday and yday. - */ - etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC; - etm.tm_sec = systime.wSecond; - etm.tm_min = systime.wMinute; - etm.tm_hour = systime.wHour; - etm.tm_mday = systime.wDay; - etm.tm_month = systime.wMonth - 1; - etm.tm_year = systime.wYear; - /* - * It is not well-documented what time zone the FILETIME's - * are in. WIN32_FIND_DATA is documented to be in UTC (GMT). - * But BY_HANDLE_FILE_INFORMATION is unclear about this. - * By our best judgement, we assume that FILETIME is in UTC. - */ - etm.tm_params.tp_gmt_offset = 0; - etm.tm_params.tp_dst_offset = 0; - cmp = PR_ImplodeTime(&etm); - - /* - * SYSTEMTIME is in milliseconds precision, so we convert PRTime's - * microseconds to milliseconds before doing the comparison. - */ - PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC)); - } -#endif /* DEBUG */ -} - -PRInt32 -_PR_MD_STAT(const char *fn, struct stat *info) -{ - PRInt32 rv; - - rv = _stat(fn, (struct _stat *)info); - if (-1 == rv) { - /* - * Check for MSVC runtime library _stat() bug. - * (It's really a bug in FindFirstFile().) - * If a pathname ends in a backslash or slash, - * e.g., c:\temp\ or c:/temp/, _stat() will fail. - * Note: a pathname ending in a slash (e.g., c:/temp/) - * can be handled by _stat() on NT but not on Win95. - * - * We remove the backslash or slash at the end and - * try again. - */ - - int len = strlen(fn); - if (len > 0 && len <= _MAX_PATH - && IsPrevCharSlash(fn, fn + len)) { - char newfn[_MAX_PATH + 1]; - - strcpy(newfn, fn); - newfn[len - 1] = '\0'; - rv = _stat(newfn, (struct _stat *)info); - } - } - - if (-1 == rv) { - _PR_MD_MAP_STAT_ERROR(errno); - } - return rv; -} - -#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\') - -static PRBool -IsPrevCharSlash(const char *str, const char *current) -{ - const char *prev; - - if (str >= current) - return PR_FALSE; - prev = _mbsdec(str, current); - return (prev == current - 1) && _PR_IS_SLASH(*prev); -} - -/* - * IsRootDirectory -- - * - * Return PR_TRUE if the pathname 'fn' is a valid root directory, - * else return PR_FALSE. The char buffer pointed to by 'fn' must - * be writable. During the execution of this function, the contents - * of the buffer pointed to by 'fn' may be modified, but on return - * the original contents will be restored. 'buflen' is the size of - * the buffer pointed to by 'fn'. - * - * Root directories come in three formats: - * 1. / or \, meaning the root directory of the current drive. - * 2. C:/ or C:\, where C is a drive letter. - * 3. \\\\ or - * \\\, meaning the root directory - * of a UNC (Universal Naming Convention) name. - */ - -static PRBool -IsRootDirectory(char *fn, size_t buflen) -{ - char *p; - PRBool slashAdded = PR_FALSE; - PRBool rv = PR_FALSE; - - if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') { - return PR_TRUE; - } - - if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2]) - && fn[3] == '\0') { - rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; - return rv; - } - - /* The UNC root directory */ - - if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) { - /* The 'server' part should have at least one character. */ - p = &fn[2]; - if (*p == '\0' || _PR_IS_SLASH(*p)) { - return PR_FALSE; - } - - /* look for the next slash */ - do { - p = _mbsinc(p); - } while (*p != '\0' && !_PR_IS_SLASH(*p)); - if (*p == '\0') { - return PR_FALSE; - } - - /* The 'share' part should have at least one character. */ - p++; - if (*p == '\0' || _PR_IS_SLASH(*p)) { - return PR_FALSE; - } - - /* look for the final slash */ - do { - p = _mbsinc(p); - } while (*p != '\0' && !_PR_IS_SLASH(*p)); - if (_PR_IS_SLASH(*p) && p[1] != '\0') { - return PR_FALSE; - } - if (*p == '\0') { - /* - * GetDriveType() doesn't work correctly if the - * path is of the form \\server\share, so we add - * a final slash temporarily. - */ - if ((p + 1) < (fn + buflen)) { - *p++ = '\\'; - *p = '\0'; - slashAdded = PR_TRUE; - } else { - return PR_FALSE; /* name too long */ - } - } - rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; - /* restore the 'fn' buffer */ - if (slashAdded) { - *--p = '\0'; - } - } - return rv; -} - -PRInt32 -_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) -{ - WIN32_FILE_ATTRIBUTE_DATA findFileData; - - if (NULL == fn || '\0' == *fn) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - - if (!GetFileAttributesEx(fn, GetFileExInfoStandard, &findFileData)) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return -1; - } - - if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - info->type = PR_FILE_DIRECTORY; - } else { - info->type = PR_FILE_FILE; - } - - info->size = findFileData.nFileSizeHigh; - info->size = (info->size << 32) + findFileData.nFileSizeLow; - - _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime); - - if (0 == findFileData.ftCreationTime.dwLowDateTime && - 0 == findFileData.ftCreationTime.dwHighDateTime) { - info->creationTime = info->modifyTime; - } else { - _PR_FileTimeToPRTime(&findFileData.ftCreationTime, - &info->creationTime); - } - - return 0; -} - -PRInt32 -_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info) -{ - PRFileInfo64 info64; - PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64); - if (0 == rv) - { - info->type = info64.type; - info->size = (PRUint32) info64.size; - info->modifyTime = info64.modifyTime; - info->creationTime = info64.creationTime; - } - return rv; -} - -PRInt32 -_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info) -{ - int rv; - - BY_HANDLE_FILE_INFORMATION hinfo; - - rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo); - if (rv == FALSE) { - _PR_MD_MAP_FSTAT_ERROR(GetLastError()); - return -1; - } - - if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_FILE; - - info->size = hinfo.nFileSizeHigh; - info->size = (info->size << 32) + hinfo.nFileSizeLow; - - _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) ); - _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) ); - - return 0; -} - -PRInt32 -_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) -{ - int rv; - - BY_HANDLE_FILE_INFORMATION hinfo; - - rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo); - if (rv == FALSE) { - _PR_MD_MAP_FSTAT_ERROR(GetLastError()); - return -1; - } - - if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_FILE; - - info->size = hinfo.nFileSizeLow; - - _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) ); - _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) ); - - return 0; -} - -PRInt32 -_PR_MD_RENAME(const char *from, const char *to) -{ - /* Does this work with dot-relative pathnames? */ - if (MoveFile(from, to)) { - return 0; - } else { - _PR_MD_MAP_RENAME_ERROR(GetLastError()); - return -1; - } -} - -PRInt32 -_PR_MD_ACCESS(const char *name, PRAccessHow how) -{ - PRInt32 rv; - - switch (how) { - case PR_ACCESS_WRITE_OK: - rv = _access(name, 02); - break; - case PR_ACCESS_READ_OK: - rv = _access(name, 04); - break; - case PR_ACCESS_EXISTS: - rv = _access(name, 00); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - if (rv < 0) { - _PR_MD_MAP_ACCESS_ERROR(errno); - } - return rv; -} - -PRInt32 -_PR_MD_MKDIR(const char *name, PRIntn mode) -{ - /* XXXMB - how to translate the "mode"??? */ - if (CreateDirectory(name, NULL)) { - return 0; - } else { - _PR_MD_MAP_MKDIR_ERROR(GetLastError()); - return -1; - } -} - -PRInt32 -_PR_MD_MAKE_DIR(const char *name, PRIntn mode) -{ - BOOL rv; - SECURITY_ATTRIBUTES sa; - LPSECURITY_ATTRIBUTES lpSA = NULL; - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - - if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable, - &pSD, &pACL) == PR_SUCCESS) { - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = FALSE; - lpSA = &sa; - } - rv = CreateDirectory(name, lpSA); - if (lpSA != NULL) { - _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); - } - if (rv) { - return 0; - } else { - _PR_MD_MAP_MKDIR_ERROR(GetLastError()); - return -1; - } -} - -PRInt32 -_PR_MD_RMDIR(const char *name) -{ - if (RemoveDirectory(name)) { - return 0; - } else { - _PR_MD_MAP_RMDIR_ERROR(GetLastError()); - return -1; - } -} - -PRStatus -_PR_MD_LOCKFILE(PROsfd f) -{ - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return PR_FAILURE; - } - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - - rv = LockFileEx((HANDLE)f, - LOCKFILE_EXCLUSIVE_LOCK, - 0, - 0x7fffffff, - 0, - &me->md.overlapped.overlapped); - - if (_native_threads_only) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return PR_FAILURE; - } - _PR_THREAD_UNLOCK(me); - - if (rv == FALSE) { - err = GetLastError(); - PR_ASSERT(err != ERROR_IO_PENDING); - _PR_MD_MAP_LOCKF_ERROR(err); - return PR_FAILURE; - } - return PR_SUCCESS; - } - - /* HACK AROUND NT BUG - * NT 3.51 has a bug. In NT 3.51, if LockFileEx returns true, you - * don't get any completion on the completion port. This is a bug. - * - * They fixed it on NT4.0 so that you do get a completion. - * - * If we pretend we won't get a completion, NSPR gets confused later - * when the unexpected completion arrives. If we assume we do get - * a completion, we hang on 3.51. Worse, Microsoft informs me that the - * behavior varies on 3.51 depending on if you are using a network - * file system or a local disk! - * - * Solution: For now, _nt_version_gets_lockfile_completion is set - * depending on whether or not this system is EITHER - * - running NT 4.0 - * - running NT 3.51 with a service pack greater than 5. - * - * In the meantime, this code may not work on network file systems. - * - */ - - if ( rv == FALSE && ((err = GetLastError()) != ERROR_IO_PENDING)) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return PR_FAILURE; - } - _PR_THREAD_UNLOCK(me); - - _PR_MD_MAP_LOCKF_ERROR(err); - return PR_FAILURE; - } -#ifdef _NEED_351_FILE_LOCKING_HACK - else if (rv) { - /* If this is NT 3.51 and the file is local, then we won't get a - * completion back from LockFile when it succeeded. - */ - if (_nt_version_gets_lockfile_completion == PR_FALSE) { - if ( IsFileLocal((HANDLE)f) == _PR_LOCAL_FILE) { - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - return PR_SUCCESS; - } - } - } -#endif /* _NEED_351_FILE_LOCKING_HACK */ - - if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(me); - return PR_FAILURE; - } - - if (me->md.blocked_io_status == 0) { - _PR_MD_MAP_LOCKF_ERROR(me->md.blocked_io_error); - return PR_FAILURE; - } - - return PR_SUCCESS; -} - -PRStatus -_PR_MD_TLOCKFILE(PROsfd f) -{ - PRInt32 rv, err; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return PR_FAILURE; - } - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - - _PR_THREAD_LOCK(me); - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return -1; - } - me->io_pending = PR_TRUE; - me->state = _PR_IO_WAIT; - _PR_THREAD_UNLOCK(me); - - rv = LockFileEx((HANDLE)f, - LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK, - 0, - 0x7fffffff, - 0, - &me->md.overlapped.overlapped); - if (_native_threads_only) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return PR_FAILURE; - } - _PR_THREAD_UNLOCK(me); - - if (rv == FALSE) { - err = GetLastError(); - PR_ASSERT(err != ERROR_IO_PENDING); - _PR_MD_MAP_LOCKF_ERROR(err); - return PR_FAILURE; - } - return PR_SUCCESS; - } - if ( rv == FALSE && ((err = GetLastError()) != ERROR_IO_PENDING)) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return PR_FAILURE; - } - _PR_THREAD_UNLOCK(me); - - _PR_MD_MAP_LOCKF_ERROR(err); - return PR_FAILURE; - } -#ifdef _NEED_351_FILE_LOCKING_HACK - else if (rv) { - /* If this is NT 3.51 and the file is local, then we won't get a - * completion back from LockFile when it succeeded. - */ - if (_nt_version_gets_lockfile_completion == PR_FALSE) { - if ( IsFileLocal((HANDLE)f) == _PR_LOCAL_FILE) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return PR_FAILURE; - } - _PR_THREAD_UNLOCK(me); - - return PR_SUCCESS; - } - } - } -#endif /* _NEED_351_FILE_LOCKING_HACK */ - - if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { - _PR_THREAD_LOCK(me); - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - _PR_THREAD_UNLOCK(me); - return PR_FAILURE; - } - _PR_THREAD_UNLOCK(me); - - return PR_FAILURE; - } - - if (me->md.blocked_io_status == 0) { - _PR_MD_MAP_LOCKF_ERROR(me->md.blocked_io_error); - return PR_FAILURE; - } - - return PR_SUCCESS; -} - - -PRStatus -_PR_MD_UNLOCKFILE(PROsfd f) -{ - PRInt32 rv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (me->io_suspended) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return PR_FAILURE; - } - - memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); - - rv = UnlockFileEx((HANDLE)f, - 0, - 0x7fffffff, - 0, - &me->md.overlapped.overlapped); - - if (rv) - return PR_SUCCESS; - else { - int err = GetLastError(); - _PR_MD_MAP_LOCKF_ERROR(err); - return PR_FAILURE; - } -} - -void -_PR_MD_MAKE_NONBLOCK(PRFileDesc *f) -{ - /* - * On NT, we either call _md_Associate() or _md_MakeNonblock(), - * depending on whether the socket is blocking or not. - * - * Once we associate a socket with the io completion port, - * there is no way to disassociate it from the io completion - * port. So we have to call _md_Associate/_md_MakeNonblock - * lazily. - */ -} - -#ifdef _NEED_351_FILE_LOCKING_HACK -/*************** -** -** Lockfile hacks -** -** The following code is a hack to work around a microsoft bug with lockfile. -** The problem is that on NT 3.51, if LockFileEx() succeeds, you never -** get a completion back for files that are on local disks. So, we need to -** know if a file is local or remote so we can tell if we should expect -** a completion. -** -** The only way to check if a file is local or remote based on the handle is -** to get the serial number for the volume it is mounted on and then to -** compare that with mounted drives. This code caches the volume numbers of -** fixed disks and does a relatively quick check. -** -** Locking: Since the only thing we ever do when multithreaded is a 32bit -** assignment, we probably don't need locking. It is included just -** case anyway. -** -** Limitations: Does not work on floppies because they are too slow -** Unknown if it will work on wierdo 3rd party file systems -** -**************** -*/ - -/* There can only be 26 drive letters on NT */ -#define _PR_MAX_DRIVES 26 - -_MDLock cachedVolumeLock; -DWORD dwCachedVolumeSerialNumbers[_PR_MAX_DRIVES] = {0}; -DWORD dwLastCachedDrive = 0; -DWORD dwRemoveableDrivesToCheck = 0; /* bitmask for removeable drives */ - -PRBool IsFileLocalInit() -{ - TCHAR lpBuffer[_PR_MAX_DRIVES*5]; - DWORD nBufferLength = _PR_MAX_DRIVES*5; - DWORD nBufferNeeded = GetLogicalDriveStrings(0, NULL); - DWORD dwIndex = 0; - DWORD dwDriveType; - DWORD dwVolumeSerialNumber; - DWORD dwDriveIndex = 0; - DWORD oldmode = (DWORD) -1; - - _MD_NEW_LOCK(&cachedVolumeLock); - - nBufferNeeded = GetLogicalDriveStrings(nBufferLength, lpBuffer); - if (nBufferNeeded == 0 || nBufferNeeded > nBufferLength) - return PR_FALSE; - - // Calling GetVolumeInformation on a removeable drive where the - // disk is currently removed will cause a dialog box to the - // console. This is not good. - // Temporarily disable the SEM_FAILCRITICALERRORS to avoid the - // damn dialog. - - dwCachedVolumeSerialNumbers[dwDriveIndex] = 0; - oldmode = SetErrorMode(SEM_FAILCRITICALERRORS); - - // now loop through the logical drives - while(lpBuffer[dwIndex] != TEXT('\0')) - { - // skip the floppy drives. This is *SLOW* - if ((lpBuffer[dwIndex] == TEXT('A')) || (lpBuffer[dwIndex] == TEXT('B'))) - /* Skip over floppies */; - else - { - dwDriveIndex = (lpBuffer[dwIndex] - TEXT('A')); - - dwDriveType = GetDriveType(&lpBuffer[dwIndex]); - - switch(dwDriveType) - { - // Ignore these drive types - case 0: - case 1: - case DRIVE_REMOTE: - default: // If the drive type is unknown, ignore it. - break; - - // Removable media drives can have different serial numbers - // at different times, so cache the current serial number - // but keep track of them so they can be rechecked if necessary. - case DRIVE_REMOVABLE: - - // CDROM is a removable media - case DRIVE_CDROM: - - // no idea if ramdisks can change serial numbers or not - // but it doesn't hurt to treat them as removable. - - case DRIVE_RAMDISK: - - - // Here is where we keep track of removable drives. - dwRemoveableDrivesToCheck |= 1 << dwDriveIndex; - - // removable drives fall through to fixed drives and get cached. - - case DRIVE_FIXED: - - // cache volume serial numbers. - if (GetVolumeInformation( - &lpBuffer[dwIndex], - NULL, 0, - &dwVolumeSerialNumber, - NULL, NULL, NULL, 0) - ) - { - if (dwLastCachedDrive < dwDriveIndex) - dwLastCachedDrive = dwDriveIndex; - dwCachedVolumeSerialNumbers[dwDriveIndex] = dwVolumeSerialNumber; - } - - break; - } - } - - dwIndex += lstrlen(&lpBuffer[dwIndex]) +1; - } - - if (oldmode != (DWORD) -1) { - SetErrorMode(oldmode); - oldmode = (DWORD) -1; - } - - return PR_TRUE; -} - -PRInt32 IsFileLocal(HANDLE hFile) -{ - DWORD dwIndex = 0, dwMask; - BY_HANDLE_FILE_INFORMATION Info; - TCHAR szDrive[4] = TEXT("C:\\"); - DWORD dwVolumeSerialNumber; - DWORD oldmode = (DWORD) -1; - int rv = _PR_REMOTE_FILE; - - if (!GetFileInformationByHandle(hFile, &Info)) - return -1; - - // look to see if the volume serial number has been cached. - _MD_LOCK(&cachedVolumeLock); - while(dwIndex <= dwLastCachedDrive) - if (dwCachedVolumeSerialNumbers[dwIndex++] == Info.dwVolumeSerialNumber) - { - _MD_UNLOCK(&cachedVolumeLock); - return _PR_LOCAL_FILE; - } - _MD_UNLOCK(&cachedVolumeLock); - - // volume serial number not found in the cache. Check removable files. - // removable drives are noted as a bitmask. If the bit associated with - // a specific drive is set, then we should query its volume serial number - // as its possible it has changed. - dwMask = dwRemoveableDrivesToCheck; - dwIndex = 0; - - while(dwMask) - { - while(!(dwMask & 1)) - { - dwIndex++; - dwMask = dwMask >> 1; - } - - szDrive[0] = TEXT('A')+ (TCHAR) dwIndex; - - // Calling GetVolumeInformation on a removeable drive where the - // disk is currently removed will cause a dialog box to the - // console. This is not good. - // Temporarily disable the SEM_FAILCRITICALERRORS to avoid the - // dialog. - - oldmode = SetErrorMode(SEM_FAILCRITICALERRORS); - - if (GetVolumeInformation( - szDrive, - NULL, 0, - &dwVolumeSerialNumber, - NULL, NULL, NULL, 0) - ) - { - if (dwVolumeSerialNumber == Info.dwVolumeSerialNumber) - { - _MD_LOCK(&cachedVolumeLock); - if (dwLastCachedDrive < dwIndex) - dwLastCachedDrive = dwIndex; - dwCachedVolumeSerialNumbers[dwIndex] = dwVolumeSerialNumber; - _MD_UNLOCK(&cachedVolumeLock); - rv = _PR_LOCAL_FILE; - } - } - if (oldmode != (DWORD) -1) { - SetErrorMode(oldmode); - oldmode = (DWORD) -1; - } - - if (rv == _PR_LOCAL_FILE) - return _PR_LOCAL_FILE; - - dwIndex++; - dwMask = dwMask >> 1; - } - - return _PR_REMOTE_FILE; -} -#endif /* _NEED_351_FILE_LOCKING_HACK */ - -PR_IMPLEMENT(PRStatus) PR_NT_CancelIo(PRFileDesc *fd) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRBool fWait; - PRFileDesc *bottom; - - bottom = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER); - if (!me->io_suspended || (NULL == bottom) || - (me->io_fd != bottom->secret->md.osfd)) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return PR_FAILURE; - } - /* - * The CancelIO operation has to be issued by the same NT thread that - * issued the I/O operation - */ - PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || (me->cpu == me->md.thr_bound_cpu)); - if (me->io_pending) { - if (!CancelIo((HANDLE)bottom->secret->md.osfd)) { - PR_SetError(PR_INVALID_STATE_ERROR, GetLastError()); - return PR_FAILURE; - } - } - _PR_THREAD_LOCK(me); - fWait = me->io_pending; - me->io_suspended = PR_FALSE; - me->state = _PR_IO_WAIT; - me->md.interrupt_disabled = PR_TRUE; - _PR_THREAD_UNLOCK(me); - if (fWait) - _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(me->io_suspended == PR_FALSE); - PR_ASSERT(me->io_pending == PR_FALSE); - - _PR_THREAD_LOCK(me); - me->md.interrupt_disabled = PR_FALSE; - me->md.thr_bound_cpu = NULL; - me->io_suspended = PR_FALSE; - me->io_pending = PR_FALSE; - me->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(me); - return PR_SUCCESS; -} - -static PROsfd _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr *addr, int *addrlen, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - SOCKET sock; - PRInt32 rv, err; - fd_set rd; - struct timeval tv, *tvp; - - FD_ZERO(&rd); - FD_SET((SOCKET)osfd, &rd); - if (timeout == PR_INTERVAL_NO_TIMEOUT) { - while ((sock = accept(osfd, addr, addrlen)) == -1) { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) { - if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, - NULL)) == -1) { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - break; - } - } else { - _PR_MD_MAP_ACCEPT_ERROR(err); - break; - } - } - } else if (timeout == PR_INTERVAL_NO_WAIT) { - if ((sock = accept(osfd, addr, addrlen)) == -1) { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } else { - _PR_MD_MAP_ACCEPT_ERROR(err); - } - } - } else { -retry: - if ((sock = accept(osfd, addr, addrlen)) == -1) { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - - rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, tvp); - if (rv > 0) { - goto retry; - } else if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - } else { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - } - } else { - _PR_MD_MAP_ACCEPT_ERROR(err); - } - } - } - return (PROsfd)sock; -} - -static PRInt32 _nt_nonblock_connect(PRFileDesc *fd, struct sockaddr *addr, int addrlen, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv; - int err; - fd_set wr, ex; - struct timeval tv, *tvp; - int len; - - if ((rv = connect(osfd, addr, addrlen)) == -1) { - if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) { - if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { - tvp = NULL; - } else { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - } - FD_ZERO(&wr); - FD_ZERO(&ex); - FD_SET((SOCKET)osfd, &wr); - FD_SET((SOCKET)osfd, &ex); - if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wr, &ex, - tvp)) == -1) { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - return rv; - } - if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - return -1; - } - /* Call Sleep(0) to work around a Winsock timeing bug. */ - Sleep(0); - if (FD_ISSET((SOCKET)osfd, &ex)) { - len = sizeof(err); - if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, - (char *) &err, &len) == SOCKET_ERROR) { - _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); - return -1; - } - _PR_MD_MAP_CONNECT_ERROR(err); - return -1; - } - PR_ASSERT(FD_ISSET((SOCKET)osfd, &wr)); - rv = 0; - } else { - _PR_MD_MAP_CONNECT_ERROR(err); - } - } - return rv; -} - -static PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - struct timeval tv, *tvp; - fd_set rd; - int osflags; - - if (0 == flags) { - osflags = 0; - } else { - PR_ASSERT(PR_MSG_PEEK == flags); - osflags = MSG_PEEK; - } - while ((rv = recv(osfd,buf,len,osflags)) == -1) { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) { - FD_ZERO(&rd); - FD_SET((SOCKET)osfd, &rd); - if (timeout == PR_INTERVAL_NO_TIMEOUT) { - tvp = NULL; - } else { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - } - if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, - tvp)) == -1) { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - break; - } else if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - rv = -1; - break; - } - } else { - _PR_MD_MAP_RECV_ERROR(err); - break; - } - } - return(rv); -} - -static PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - struct timeval tv, *tvp; - fd_set wd; - PRInt32 bytesSent = 0; - - while(bytesSent < len) { - while ((rv = send(osfd,buf,len,0)) == -1) { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) { - if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { - tvp = NULL; - } else { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - } - FD_ZERO(&wd); - FD_SET((SOCKET)osfd, &wd); - if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL, - tvp)) == -1) { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - return -1; - } - if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - return -1; - } - } else { - _PR_MD_MAP_SEND_ERROR(err); - return -1; - } - } - bytesSent += rv; - if (fd->secret->nonblocking) { - break; - } - if (bytesSent < len) { - if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { - tvp = NULL; - } else { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - } - FD_ZERO(&wd); - FD_SET((SOCKET)osfd, &wd); - if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL, - tvp)) == -1) { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - return -1; - } - if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - return -1; - } - } - } - return bytesSent; -} - -static PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime timeout) -{ - int index; - int sent = 0; - int rv; - - for (index=0; index 0) - sent += rv; - if ( rv != iov[index].iov_len ) { - if (rv < 0) { - if (fd->secret->nonblocking - && (PR_GetError() == PR_WOULD_BLOCK_ERROR) - && (sent > 0)) { - return sent; - } else { - return -1; - } - } - /* Only a nonblocking socket can have partial sends */ - PR_ASSERT(fd->secret->nonblocking); - return sent; - } - } - - return sent; -} - -static PRInt32 _nt_nonblock_sendto( - PRFileDesc *fd, const char *buf, int len, - const struct sockaddr *addr, int addrlen, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - struct timeval tv, *tvp; - fd_set wd; - PRInt32 bytesSent = 0; - - while(bytesSent < len) { - while ((rv = sendto(osfd,buf,len,0, addr, addrlen)) == -1) { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) { - if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { - tvp = NULL; - } else { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - } - FD_ZERO(&wd); - FD_SET((SOCKET)osfd, &wd); - if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL, - tvp)) == -1) { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - return -1; - } - if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - return -1; - } - } else { - _PR_MD_MAP_SENDTO_ERROR(err); - return -1; - } - } - bytesSent += rv; - if (fd->secret->nonblocking) { - break; - } - if (bytesSent < len) { - if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { - tvp = NULL; - } else { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - } - FD_ZERO(&wd); - FD_SET((SOCKET)osfd, &wd); - if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL, - tvp)) == -1) { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - return -1; - } - if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - return -1; - } - } - } - return bytesSent; -} - -static PRInt32 _nt_nonblock_recvfrom(PRFileDesc *fd, char *buf, int len, struct sockaddr *addr, int *addrlen, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - struct timeval tv, *tvp; - fd_set rd; - - while ((rv = recvfrom(osfd,buf,len,0,addr, addrlen)) == -1) { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) { - if (timeout == PR_INTERVAL_NO_TIMEOUT) { - tvp = NULL; - } else { - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - } - FD_ZERO(&rd); - FD_SET((SOCKET)osfd, &rd); - if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, - tvp)) == -1) { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - break; - } else if (rv == 0) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - rv = -1; - break; - } - } else { - _PR_MD_MAP_RECVFROM_ERROR(err); - break; - } - } - return(rv); -} - -/* - * UDP support: the continuation thread functions and recvfrom and sendto. - */ - -static void pt_InsertTimedInternal(pt_Continuation *op) -{ - PRInt32 delta = 0; - pt_Continuation *t_op = NULL; - PRIntervalTime now = PR_IntervalNow(), op_tmo, qd_tmo; - - /* - * If this element operation isn't timed, it gets queued at the - * end of the list (just after pt_tq.tail) and we're - * finishd early. - */ - if (PR_INTERVAL_NO_TIMEOUT == op->timeout) - { - t_op = pt_tq.tail; /* put it at the end */ - goto done; - } - - /* - * The rest of this routine actaully deals with timed ops. - */ - - if (NULL != pt_tq.op) - { - /* - * To find where in the list to put the new operation, form - * the absolute time the operations in question will expire. - * - * The new operation ('op') will expire at now() + op->timeout. - * - * The operation that will time out furthest in the future will - * do so at pt_tq.epoch + pt_tq.op->timeout. - * - * Subsequently earlier timeouts are computed based on the latter - * knowledge by subracting the timeout deltas that are stored in - * the operation list. There are operation[n]->timeout ticks - * between the expiration of operation[n-1] and operation[n].e e - * - * Therefore, the operation[n-1] will expire operation[n]->timeout - * ticks prior to operation[n]. - * - * This should be easy! - */ - t_op = pt_tq.op; /* running pointer to queued op */ - op_tmo = now + op->timeout; /* that's in absolute ticks */ - qd_tmo = pt_tq.epoch + t_op->timeout; /* likewise */ - - do - { - /* - * If 'op' expires later than t_op, then insert 'op' just - * ahead of t_op. Otherwise, compute when operation[n-1] - * expires and try again. - * - * The actual different between the expiriation of 'op' - * and the current operation what becomes the new operaton's - * timeout interval. That interval is also subtracted from - * the interval of the operation immediately following where - * we stick 'op' (unless the next one isn't timed). The new - * timeout assigned to 'op' takes into account the values of - * now() and when the previous intervals were compured. - */ - delta = op_tmo - qd_tmo; - if (delta >= 0) - { - op->timeout += (now - pt_tq.epoch); - goto done; - } - - qd_tmo -= t_op->timeout; /* previous operaton expiration */ - t_op = t_op->prev; /* point to previous operation */ - if (NULL != t_op) qd_tmo += t_op->timeout; - } while (NULL != t_op); - - /* - * If we got here we backed off the head of the list. That means that - * this timed entry has to go at the head of the list. This is just - * about like having an empty timer list. - */ - delta = op->timeout; /* $$$ is this right? */ - } - -done: - - /* - * Insert 'op' into the queue just after t_op or if t_op is null, - * at the head of the list. - * - * If t_op is NULL, the list is currently empty and this is pretty - * easy. - */ - if (NULL == t_op) - { - op->prev = NULL; - op->next = pt_tq.head; - pt_tq.head = op; - if (NULL == pt_tq.tail) pt_tq.tail = op; - else op->next->prev = op; - } - else - { - op->prev = t_op; - op->next = t_op->next; - if (NULL != op->prev) - op->prev->next = op; - if (NULL != op->next) - op->next->prev = op; - if (t_op == pt_tq.tail) - pt_tq.tail = op; - } - - /* - * Are we adjusting our epoch, etc? Are we replacing - * what was previously the element due to expire furthest - * out in the future? Is this even a timed operation? - */ - if (PR_INTERVAL_NO_TIMEOUT != op->timeout) - { - if ((NULL == pt_tq.op) /* we're the one and only */ - || (t_op == pt_tq.op)) /* we're replacing */ - { - pt_tq.op = op; - pt_tq.epoch = now; - } - } - - pt_tq.op_count += 1; - -} /* pt_InsertTimedInternal */ - -/* - * function: pt_FinishTimed - * - * Takes the finished operation out of the timed queue. It - * notifies the initiating thread that the opertions is - * complete and returns to the caller the value of the next - * operation in the list (or NULL). - */ -static pt_Continuation *pt_FinishTimedInternal(pt_Continuation *op) -{ - pt_Continuation *next; - - /* remove this one from the list */ - if (NULL == op->prev) pt_tq.head = op->next; - else op->prev->next = op->next; - if (NULL == op->next) pt_tq.tail = op->prev; - else op->next->prev = op->prev; - - /* did we happen to hit the timed op? */ - if (op == pt_tq.op) pt_tq.op = op->prev; - - next = op->next; - op->next = op->prev = NULL; - op->status = pt_continuation_done; - - pt_tq.op_count -= 1; -#if defined(DEBUG) - pt_debug.continuationsServed += 1; -#endif - PR_NotifyCondVar(op->complete); - - return next; -} /* pt_FinishTimedInternal */ - -static void ContinuationThread(void *arg) -{ - /* initialization */ - fd_set readSet, writeSet, exceptSet; - struct timeval tv; - SOCKET *pollingList = 0; /* list built for polling */ - PRIntn pollingListUsed; /* # entries used in the list */ - PRIntn pollingListNeeded; /* # entries needed this time */ - PRIntn pollingSlotsAllocated = 0; /* # entries available in list */ - PRIntervalTime mx_select_ticks = PR_MillisecondsToInterval(PT_DEFAULT_SELECT_MSEC); - - /* do some real work */ - while (1) - { - PRIntn rv; - PRStatus status; - PRIntn pollIndex; - pt_Continuation *op; - PRIntervalTime now = PR_IntervalNow(); - PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; - - PR_Lock(pt_tq.ml); - while (NULL == pt_tq.head) - { - status = PR_WaitCondVar(pt_tq.new_op, PR_INTERVAL_NO_TIMEOUT); - if ((PR_FAILURE == status) - && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break; - } - pollingListNeeded = pt_tq.op_count; - PR_Unlock(pt_tq.ml); - - /* Okay. We're history */ - if ((PR_FAILURE == status) - && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break; - - /* - * We are not holding the pt_tq.ml lock now, so more items may - * get added to pt_tq during this window of time. We hope - * that 10 more spaces in the polling list should be enough. - */ - - FD_ZERO(&readSet); - FD_ZERO(&writeSet); - FD_ZERO(&exceptSet); - pollingListNeeded += 10; - if (pollingListNeeded > pollingSlotsAllocated) - { - if (NULL != pollingList) PR_DELETE(pollingList); - pollingList = PR_MALLOC(pollingListNeeded * sizeof(PRPollDesc)); - PR_ASSERT(NULL != pollingList); - pollingSlotsAllocated = pollingListNeeded; - } - -#if defined(DEBUG) - if (pollingListNeeded > pt_debug.pollingListMax) - pt_debug.pollingListMax = pollingListUsed; -#endif - - /* - * Build up a polling list. - * This list is sorted on time. Operations that have been - * interrupted are completed and not included in the list. - * There is an assertion that the operation is in progress. - */ - pollingListUsed = 0; - PR_Lock(pt_tq.ml); - - for (op = pt_tq.head; NULL != op;) - { - if (pt_continuation_abort == op->status) - { - op->result.code = -1; - op->syserrno = WSAEINTR; - op = pt_FinishTimedInternal(op); - } - else - { - PR_ASSERT(pt_continuation_done != op->status); - op->status = pt_continuation_inprogress; - if (op->event & PR_POLL_READ) { - FD_SET(op->arg1.osfd, &readSet); - } - if (op->event & PR_POLL_WRITE) { - FD_SET(op->arg1.osfd, &writeSet); - } - if (op->event & PR_POLL_EXCEPT) { - FD_SET(op->arg1.osfd, &exceptSet); - } - pollingList[pollingListUsed] = op->arg1.osfd; - pollingListUsed += 1; - if (pollingListUsed == pollingSlotsAllocated) break; - op = op->next; - } - } - - PR_Unlock(pt_tq.ml); - - /* - * If 'op' isn't NULL at this point, then we didn't get to - * the end of the list. That means that more items got added - * to the list than we anticipated. So, forget this iteration, - * go around the horn again. - * One would hope this doesn't happen all that often. - */ - if (NULL != op) - { -#if defined(DEBUG) - pt_debug.predictionsFoiled += 1; /* keep track */ -#endif - continue; /* make it rethink things */ - } - - /* there's a chance that all ops got blown away */ - if (NULL == pt_tq.head) continue; - /* if not, we know this is the shortest timeout */ - timeout = pt_tq.head->timeout; - - /* - * We don't want to wait forever on this poll. So keep - * the interval down. The operations, if they are timed, - * still have to timeout, while those that are not timed - * should persist forever. But they may be aborted. That's - * what this anxiety is all about. - */ - if (timeout > mx_select_ticks) timeout = mx_select_ticks; - - if (PR_INTERVAL_NO_TIMEOUT != pt_tq.head->timeout) - pt_tq.head->timeout -= timeout; - tv.tv_sec = PR_IntervalToSeconds(timeout); - tv.tv_usec = PR_IntervalToMicroseconds(timeout) % PR_USEC_PER_SEC; - - rv = select(0, &readSet, &writeSet, &exceptSet, &tv); - - if (0 == rv) /* poll timed out - what about leading op? */ - { - if (0 == pt_tq.head->timeout) - { - /* - * The leading element of the timed queue has timed - * out. Get rid of it. In any case go around the - * loop again, computing the polling list, checking - * for interrupted operations. - */ - PR_Lock(pt_tq.ml); - do - { - pt_tq.head->result.code = -1; - pt_tq.head->syserrno = WSAETIMEDOUT; - op = pt_FinishTimedInternal(pt_tq.head); - } while ((NULL != op) && (0 == op->timeout)); - PR_Unlock(pt_tq.ml); - } - continue; - } - - if (-1 == rv && (WSAGetLastError() == WSAEINTR - || WSAGetLastError() == WSAEINPROGRESS)) - { - continue; /* go around the loop again */ - } - - /* - * select() says that something in our list is ready for some more - * action or is an invalid fd. Find it, load up the operation and - * see what happens. - */ - - PR_ASSERT(rv > 0 || WSAGetLastError() == WSAENOTSOCK); - - - /* - * $$$ There's a problem here. I'm running the operations list - * and I'm not holding any locks. I don't want to hold the lock - * and do the operation, so this is really messed up.. - * - * This may work out okay. The rule is that only this thread, - * the continuation thread, can remove elements from the list. - * Therefore, the list is at worst, longer than when we built - * the polling list. - */ - op = pt_tq.head; - for (pollIndex = 0; pollIndex < pollingListUsed; ++pollIndex) - { - PRInt16 revents = 0; - - PR_ASSERT(NULL != op); - - /* - * This one wants attention. Redo the operation. - * We know that there can only be more elements - * in the op list than we knew about when we created - * the poll list. Therefore, we might have to skip - * a few ops to find the right one to operation on. - */ - while (pollingList[pollIndex] != op->arg1.osfd ) - { - op = op->next; - PR_ASSERT(NULL != op); - } - - if (FD_ISSET(op->arg1.osfd, &readSet)) { - revents |= PR_POLL_READ; - } - if (FD_ISSET(op->arg1.osfd, &writeSet)) { - revents |= PR_POLL_WRITE; - } - if (FD_ISSET(op->arg1.osfd, &exceptSet)) { - revents |= PR_POLL_EXCEPT; - } - - /* - * Sip over all those not in progress. They'll be - * pruned next time we build a polling list. Call - * the continuation function. If it reports completion, - * finish off the operation. - */ - if (revents && (pt_continuation_inprogress == op->status) - && (op->function(op, revents))) - { - PR_Lock(pt_tq.ml); - op = pt_FinishTimedInternal(op); - PR_Unlock(pt_tq.ml); - } - } - } - if (NULL != pollingList) PR_DELETE(pollingList); -} /* ContinuationThread */ - -static int pt_Continue(pt_Continuation *op) -{ - PRStatus rv; - /* Finish filling in the blank slots */ - op->status = pt_continuation_sumbitted; - op->complete = PR_NewCondVar(pt_tq.ml); - - PR_Lock(pt_tq.ml); /* we provide the locking */ - - pt_InsertTimedInternal(op); /* insert in the structure */ - - PR_NotifyCondVar(pt_tq.new_op); /* notify the continuation thread */ - - while (pt_continuation_done != op->status) /* wait for completion */ - { - rv = PR_WaitCondVar(op->complete, PR_INTERVAL_NO_TIMEOUT); - /* - * If we get interrupted, we set state the continuation thread will - * see and allow it to finish the I/O operation w/ error. That way - * the rule that only the continuation thread is removing elements - * from the list is still valid. - * - * Don't call interrupt on the continuation thread. That'll just - * piss him off. He's cycling around at least every mx_select_ticks - * anyhow and should notice the request in there. - */ - if ((PR_FAILURE == rv) - && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) - op->status = pt_continuation_abort; /* our status */ - } - - PR_Unlock(pt_tq.ml); /* we provide the locking */ - - PR_DestroyCondVar(op->complete); - - return op->result.code; /* and the primary answer */ -} /* pt_Continue */ - -static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents) -{ - PRIntn bytes = sendto( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags, - (struct sockaddr*)op->arg5.addr, sizeof(*(op->arg5.addr))); - op->syserrno = WSAGetLastError(); - if (bytes > 0) /* this is progress */ - { - char *bp = op->arg2.buffer; - bp += bytes; /* adjust the buffer pointer */ - op->arg2.buffer = bp; - op->result.code += bytes; /* accumulate the number sent */ - op->arg3.amount -= bytes; /* and reduce the required count */ - return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; - } - else return ((-1 == bytes) && (WSAEWOULDBLOCK == op->syserrno)) ? - PR_FALSE : PR_TRUE; -} /* pt_sendto_cont */ - -static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents) -{ - PRIntn addr_len = sizeof(*(op->arg5.addr)); - op->result.code = recvfrom( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount, - op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len); - op->syserrno = WSAGetLastError(); - return ((-1 == op->result.code) && (WSAEWOULDBLOCK == op->syserrno)) ? - PR_FALSE : PR_TRUE; -} /* pt_recvfrom_cont */ - -static PRInt32 pt_SendTo( - SOCKET osfd, const void *buf, - PRInt32 amount, PRInt32 flags, const PRNetAddr *addr, - PRIntn addrlen, PRIntervalTime timeout) -{ - PRInt32 bytes = -1, err; - PRBool fNeedContinue = PR_FALSE; - - bytes = sendto( - osfd, buf, amount, flags, - (struct sockaddr*)addr, PR_NETADDR_SIZE(addr)); - if (bytes == -1) { - if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) - fNeedContinue = PR_TRUE; - else - _PR_MD_MAP_SENDTO_ERROR(err); - } - if (fNeedContinue == PR_TRUE) - { - pt_Continuation op; - op.arg1.osfd = osfd; - op.arg2.buffer = (void*)buf; - op.arg3.amount = amount; - op.arg4.flags = flags; - op.arg5.addr = (PRNetAddr*)addr; - op.timeout = timeout; - op.result.code = 0; /* initialize the number sent */ - op.function = pt_sendto_cont; - op.event = PR_POLL_WRITE | PR_POLL_EXCEPT; - bytes = pt_Continue(&op); - if (bytes < 0) { - WSASetLastError(op.syserrno); - _PR_MD_MAP_SENDTO_ERROR(op.syserrno); - } - } - return bytes; -} /* pt_SendTo */ - -static PRInt32 pt_RecvFrom(SOCKET osfd, void *buf, PRInt32 amount, - PRInt32 flags, PRNetAddr *addr, PRIntn *addr_len, PRIntervalTime timeout) -{ - PRInt32 bytes = -1, err; - PRBool fNeedContinue = PR_FALSE; - - bytes = recvfrom( - osfd, buf, amount, flags, - (struct sockaddr*)addr, addr_len); - if (bytes == -1) { - if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) - fNeedContinue = PR_TRUE; - else - _PR_MD_MAP_RECVFROM_ERROR(err); - } - - if (fNeedContinue == PR_TRUE) - { - pt_Continuation op; - op.arg1.osfd = osfd; - op.arg2.buffer = buf; - op.arg3.amount = amount; - op.arg4.flags = flags; - op.arg5.addr = addr; - op.timeout = timeout; - op.function = pt_recvfrom_cont; - op.event = PR_POLL_READ | PR_POLL_EXCEPT; - bytes = pt_Continue(&op); - if (bytes < 0) { - WSASetLastError(op.syserrno); - _PR_MD_MAP_RECVFROM_ERROR(op.syserrno); - } - } - return bytes; -} /* pt_RecvFrom */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntmisc.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntmisc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntmisc.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntmisc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1183 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * ntmisc.c - * - */ - -#include "primpl.h" -#include /* for fabs() */ -#include - -char *_PR_MD_GET_ENV(const char *name) -{ - return getenv(name); -} - -/* -** _PR_MD_PUT_ENV() -- add or change environment variable -** -** -*/ -PRIntn _PR_MD_PUT_ENV(const char *name) -{ - return(putenv(name)); -} - - -/* - ************************************************************************** - ************************************************************************** - ** - ** Date and time routines - ** - ************************************************************************** - ************************************************************************** - */ - -/* - * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME. - * We store the value in a PRTime variable for convenience. - */ -#ifdef __GNUC__ -const PRTime _pr_filetime_offset = 116444736000000000LL; -const PRTime _pr_filetime_divisor = 10LL; -#else -const PRTime _pr_filetime_offset = 116444736000000000i64; -const PRTime _pr_filetime_divisor = 10i64; -#endif - -#ifdef WINCE - -#define FILETIME_TO_INT64(ft) \ - (((PRInt64)ft.dwHighDateTime) << 32 | (PRInt64)ft.dwLowDateTime) - -static void -LowResTime(LPFILETIME lpft) -{ - GetCurrentFT(lpft); -} - -typedef struct CalibrationData { - long double freq; /* The performance counter frequency */ - long double offset; /* The low res 'epoch' */ - long double timer_offset; /* The high res 'epoch' */ - - /* The last high res time that we returned since recalibrating */ - PRInt64 last; - - PRBool calibrated; - - CRITICAL_SECTION data_lock; - CRITICAL_SECTION calibration_lock; - PRInt64 granularity; -} CalibrationData; - -static CalibrationData calibration; - -typedef void (*GetSystemTimeAsFileTimeFcn)(LPFILETIME); -static GetSystemTimeAsFileTimeFcn ce6_GetSystemTimeAsFileTime = NULL; - -static void -NowCalibrate(void) -{ - FILETIME ft, ftStart; - LARGE_INTEGER liFreq, now; - - if (calibration.freq == 0.0) { - if(!QueryPerformanceFrequency(&liFreq)) { - /* High-performance timer is unavailable */ - calibration.freq = -1.0; - } else { - calibration.freq = (long double) liFreq.QuadPart; - } - } - if (calibration.freq > 0.0) { - PRInt64 calibrationDelta = 0; - /* - * By wrapping a timeBegin/EndPeriod pair of calls around this loop, - * the loop seems to take much less time (1 ms vs 15ms) on Vista. - */ - timeBeginPeriod(1); - LowResTime(&ftStart); - do { - LowResTime(&ft); - } while (memcmp(&ftStart,&ft, sizeof(ft)) == 0); - timeEndPeriod(1); - - calibration.granularity = - (FILETIME_TO_INT64(ft) - FILETIME_TO_INT64(ftStart))/10; - - QueryPerformanceCounter(&now); - - calibration.offset = (long double) FILETIME_TO_INT64(ft); - calibration.timer_offset = (long double) now.QuadPart; - /* - * The windows epoch is around 1600. The unix epoch is around 1970. - * _pr_filetime_offset is the difference (in windows time units which - * are 10 times more highres than the JS time unit) - */ - calibration.offset -= _pr_filetime_offset; - calibration.offset *= 0.1; - calibration.last = 0; - - calibration.calibrated = PR_TRUE; - } -} - -#define CALIBRATIONLOCK_SPINCOUNT 0 -#define DATALOCK_SPINCOUNT 4096 -#define LASTLOCK_SPINCOUNT 4096 - -void -_MD_InitTime(void) -{ - /* try for CE6 GetSystemTimeAsFileTime first */ - HANDLE h = GetModuleHandleW(L"coredll.dll"); - ce6_GetSystemTimeAsFileTime = (GetSystemTimeAsFileTimeFcn) - GetProcAddressA(h, "GetSystemTimeAsFileTime"); - - /* otherwise go the slow route */ - if (ce6_GetSystemTimeAsFileTime == NULL) { - memset(&calibration, 0, sizeof(calibration)); - NowCalibrate(); - InitializeCriticalSection(&calibration.calibration_lock); - InitializeCriticalSection(&calibration.data_lock); - } -} - -void -_MD_CleanupTime(void) -{ - if (ce6_GetSystemTimeAsFileTime == NULL) { - DeleteCriticalSection(&calibration.calibration_lock); - DeleteCriticalSection(&calibration.data_lock); - } -} - -#define MUTEX_SETSPINCOUNT(m, c) - -/* - *----------------------------------------------------------------------- - * - * PR_Now -- - * - * Returns the current time in microseconds since the epoch. - * The epoch is midnight January 1, 1970 GMT. - * The implementation is machine dependent. This is the - * implementation for Windows. - * Cf. time_t time(time_t *tp) - * - *----------------------------------------------------------------------- - */ - -PR_IMPLEMENT(PRTime) -PR_Now(void) -{ - long double lowresTime, highresTimerValue; - FILETIME ft; - LARGE_INTEGER now; - PRBool calibrated = PR_FALSE; - PRBool needsCalibration = PR_FALSE; - PRInt64 returnedTime; - long double cachedOffset = 0.0; - - if (ce6_GetSystemTimeAsFileTime) { - union { - FILETIME ft; - PRTime prt; - } currentTime; - - PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime)); - - ce6_GetSystemTimeAsFileTime(¤tTime.ft); - - /* written this way on purpose, since the second term becomes - * a constant, and the entire expression is faster to execute. - */ - return currentTime.prt/_pr_filetime_divisor - - _pr_filetime_offset/_pr_filetime_divisor; - } - - do { - if (!calibration.calibrated || needsCalibration) { - EnterCriticalSection(&calibration.calibration_lock); - EnterCriticalSection(&calibration.data_lock); - - /* Recalibrate only if no one else did before us */ - if (calibration.offset == cachedOffset) { - /* - * Since calibration can take a while, make any other - * threads immediately wait - */ - MUTEX_SETSPINCOUNT(&calibration.data_lock, 0); - - NowCalibrate(); - - calibrated = PR_TRUE; - - /* Restore spin count */ - MUTEX_SETSPINCOUNT(&calibration.data_lock, DATALOCK_SPINCOUNT); - } - LeaveCriticalSection(&calibration.data_lock); - LeaveCriticalSection(&calibration.calibration_lock); - } - - /* Calculate a low resolution time */ - LowResTime(&ft); - lowresTime = - ((long double)(FILETIME_TO_INT64(ft) - _pr_filetime_offset)) * 0.1; - - if (calibration.freq > 0.0) { - long double highresTime, diff; - DWORD timeAdjustment, timeIncrement; - BOOL timeAdjustmentDisabled; - - /* Default to 15.625 ms if the syscall fails */ - long double skewThreshold = 15625.25; - - /* Grab high resolution time */ - QueryPerformanceCounter(&now); - highresTimerValue = (long double)now.QuadPart; - - EnterCriticalSection(&calibration.data_lock); - highresTime = calibration.offset + 1000000L * - (highresTimerValue-calibration.timer_offset)/calibration.freq; - cachedOffset = calibration.offset; - - /* - * On some dual processor/core systems, we might get an earlier - * time so we cache the last time that we returned. - */ - calibration.last = PR_MAX(calibration.last,(PRInt64)highresTime); - returnedTime = calibration.last; - LeaveCriticalSection(&calibration.data_lock); - - /* Get an estimate of clock ticks per second from our own test */ - skewThreshold = calibration.granularity; - /* Check for clock skew */ - diff = lowresTime - highresTime; - - /* - * For some reason that I have not determined, the skew can be - * up to twice a kernel tick. This does not seem to happen by - * itself, but I have only seen it triggered by another program - * doing some kind of file I/O. The symptoms are a negative diff - * followed by an equally large positive diff. - */ - if (fabs(diff) > 2*skewThreshold) { - if (calibrated) { - /* - * If we already calibrated once this instance, and the - * clock is still skewed, then either the processor(s) are - * wildly changing clockspeed or the system is so busy that - * we get switched out for long periods of time. In either - * case, it would be infeasible to make use of high - * resolution results for anything, so let's resort to old - * behavior for this call. It's possible that in the - * future, the user will want the high resolution timer, so - * we don't disable it entirely. - */ - returnedTime = (PRInt64)lowresTime; - needsCalibration = PR_FALSE; - } else { - /* - * It is possible that when we recalibrate, we will return - * a value less than what we have returned before; this is - * unavoidable. We cannot tell the different between a - * faulty QueryPerformanceCounter implementation and user - * changes to the operating system time. Since we must - * respect user changes to the operating system time, we - * cannot maintain the invariant that Date.now() never - * decreases; the old implementation has this behavior as - * well. - */ - needsCalibration = PR_TRUE; - } - } else { - /* No detectable clock skew */ - returnedTime = (PRInt64)highresTime; - needsCalibration = PR_FALSE; - } - } else { - /* No high resolution timer is available, so fall back */ - returnedTime = (PRInt64)lowresTime; - } - } while (needsCalibration); - - return returnedTime; -} - -#else - -PR_IMPLEMENT(PRTime) -PR_Now(void) -{ - PRTime prt; - FILETIME ft; - SYSTEMTIME st; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &ft); - _PR_FileTimeToPRTime(&ft, &prt); - return prt; -} - -#endif - -/* - *********************************************************************** - *********************************************************************** - * - * Process creation routines - * - *********************************************************************** - *********************************************************************** - */ - -/* - * Assemble the command line by concatenating the argv array. - * On success, this function returns 0 and the resulting command - * line is returned in *cmdLine. On failure, it returns -1. - */ -static int assembleCmdLine(char *const *argv, char **cmdLine) -{ - char *const *arg; - char *p, *q; - size_t cmdLineSize; - int numBackslashes; - int i; - int argNeedQuotes; - - /* - * Find out how large the command line buffer should be. - */ - cmdLineSize = 0; - for (arg = argv; *arg; arg++) { - /* - * \ and " need to be escaped by a \. In the worst case, - * every character is a \ or ", so the string of length - * may double. If we quote an argument, that needs two ". - * Finally, we need a space between arguments, and - * a null byte at the end of command line. - */ - cmdLineSize += 2 * strlen(*arg) /* \ and " need to be escaped */ - + 2 /* we quote every argument */ - + 1; /* space in between, or final null */ - } - p = *cmdLine = PR_MALLOC((PRUint32) cmdLineSize); - if (p == NULL) { - return -1; - } - - for (arg = argv; *arg; arg++) { - /* Add a space to separates the arguments */ - if (arg != argv) { - *p++ = ' '; - } - q = *arg; - numBackslashes = 0; - argNeedQuotes = 0; - - /* - * If the argument is empty or contains white space, it needs to - * be quoted. - */ - if (**arg == '\0' || strpbrk(*arg, " \f\n\r\t\v")) { - argNeedQuotes = 1; - } - - if (argNeedQuotes) { - *p++ = '"'; - } - while (*q) { - if (*q == '\\') { - numBackslashes++; - q++; - } else if (*q == '"') { - if (numBackslashes) { - /* - * Double the backslashes since they are followed - * by a quote - */ - for (i = 0; i < 2 * numBackslashes; i++) { - *p++ = '\\'; - } - numBackslashes = 0; - } - /* To escape the quote */ - *p++ = '\\'; - *p++ = *q++; - } else { - if (numBackslashes) { - /* - * Backslashes are not followed by a quote, so - * don't need to double the backslashes. - */ - for (i = 0; i < numBackslashes; i++) { - *p++ = '\\'; - } - numBackslashes = 0; - } - *p++ = *q++; - } - } - - /* Now we are at the end of this argument */ - if (numBackslashes) { - /* - * Double the backslashes if we have a quote string - * delimiter at the end. - */ - if (argNeedQuotes) { - numBackslashes *= 2; - } - for (i = 0; i < numBackslashes; i++) { - *p++ = '\\'; - } - } - if (argNeedQuotes) { - *p++ = '"'; - } - } - - *p = '\0'; - return 0; -} - -/* - * Assemble the environment block by concatenating the envp array - * (preserving the terminating null byte in each array element) - * and adding a null byte at the end. - * - * Returns 0 on success. The resulting environment block is returned - * in *envBlock. Note that if envp is NULL, a NULL pointer is returned - * in *envBlock. Returns -1 on failure. - */ -static int assembleEnvBlock(char **envp, char **envBlock) -{ - char *p; - char *q; - char **env; - char *curEnv; - char *cwdStart, *cwdEnd; - size_t envBlockSize; - - if (envp == NULL) { - *envBlock = NULL; - return 0; - } - -#ifdef WINCE - { - PRUnichar *wideCurEnv = mozce_GetEnvString(); - int len = WideCharToMultiByte(CP_ACP, 0, wideCurEnv, -1, - NULL, 0, NULL, NULL); - curEnv = (char *) PR_MALLOC(len * sizeof(char)); - WideCharToMultiByte(CP_ACP, 0, wideCurEnv, -1, - curEnv, len, NULL, NULL); - free(wideCurEnv); - } -#else - curEnv = GetEnvironmentStrings(); -#endif - - cwdStart = curEnv; - while (*cwdStart) { - if (cwdStart[0] == '=' && cwdStart[1] != '\0' - && cwdStart[2] == ':' && cwdStart[3] == '=') { - break; - } - cwdStart += strlen(cwdStart) + 1; - } - cwdEnd = cwdStart; - if (*cwdEnd) { - cwdEnd += strlen(cwdEnd) + 1; - while (*cwdEnd) { - if (cwdEnd[0] != '=' || cwdEnd[1] == '\0' - || cwdEnd[2] != ':' || cwdEnd[3] != '=') { - break; - } - cwdEnd += strlen(cwdEnd) + 1; - } - } - envBlockSize = cwdEnd - cwdStart; - - for (env = envp; *env; env++) { - envBlockSize += strlen(*env) + 1; - } - envBlockSize++; - - p = *envBlock = PR_MALLOC((PRUint32) envBlockSize); - if (p == NULL) { -#ifdef WINCE - PR_Free(curEnv); -#else - FreeEnvironmentStrings(curEnv); -#endif - return -1; - } - - q = cwdStart; - while (q < cwdEnd) { - *p++ = *q++; - } -#ifdef WINCE - PR_Free(curEnv); -#else - FreeEnvironmentStrings(curEnv); -#endif - - for (env = envp; *env; env++) { - q = *env; - while (*q) { - *p++ = *q++; - } - *p++ = '\0'; - } - *p = '\0'; - return 0; -} - -/* - * For qsort. We sort (case-insensitive) the environment strings - * before generating the environment block. - */ -static int compare(const void *arg1, const void *arg2) -{ - return _stricmp(* (char**)arg1, * (char**)arg2); -} - -PRProcess * _PR_CreateWindowsProcess( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr) -{ -#ifdef WINCE - STARTUPINFOW startupInfo; - PRUnichar *wideCmdLine; - PRUnichar *wideCwd; - int len = 0; -#else - STARTUPINFO startupInfo; -#endif - DWORD creationFlags = 0; - PROCESS_INFORMATION procInfo; - BOOL retVal; - char *cmdLine = NULL; - char *envBlock = NULL; - char **newEnvp = NULL; - const char *cwd = NULL; /* current working directory */ - PRProcess *proc = NULL; - PRBool hasFdInheritBuffer; - - proc = PR_NEW(PRProcess); - if (!proc) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto errorExit; - } - - if (assembleCmdLine(argv, &cmdLine) == -1) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto errorExit; - } - -#ifndef WINCE - /* - * If attr->fdInheritBuffer is not NULL, we need to insert - * it into the envp array, so envp cannot be NULL. - */ - hasFdInheritBuffer = (attr && attr->fdInheritBuffer); - if ((envp == NULL) && hasFdInheritBuffer) { - envp = environ; - } - - if (envp != NULL) { - int idx; - int numEnv; - PRBool found = PR_FALSE; - - numEnv = 0; - while (envp[numEnv]) { - numEnv++; - } - newEnvp = (char **) PR_MALLOC((numEnv + 2) * sizeof(char *)); - for (idx = 0; idx < numEnv; idx++) { - newEnvp[idx] = envp[idx]; - if (hasFdInheritBuffer && !found - && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) { - newEnvp[idx] = attr->fdInheritBuffer; - found = PR_TRUE; - } - } - if (hasFdInheritBuffer && !found) { - newEnvp[idx++] = attr->fdInheritBuffer; - } - newEnvp[idx] = NULL; - qsort((void *) newEnvp, (size_t) idx, sizeof(char *), compare); - } - if (assembleEnvBlock(newEnvp, &envBlock) == -1) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto errorExit; - } - - ZeroMemory(&startupInfo, sizeof(startupInfo)); - startupInfo.cb = sizeof(startupInfo); - - if (attr) { - PRBool redirected = PR_FALSE; - - /* - * XXX the default value for stdin, stdout, and stderr - * should probably be the console input and output, not - * those of the parent process. - */ - startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); - startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); - if (attr->stdinFd) { - startupInfo.hStdInput = (HANDLE) attr->stdinFd->secret->md.osfd; - redirected = PR_TRUE; - } - if (attr->stdoutFd) { - startupInfo.hStdOutput = (HANDLE) attr->stdoutFd->secret->md.osfd; - redirected = PR_TRUE; - /* - * If stdout is redirected, we can assume that the process will - * not write anything useful to the console windows, and therefore - * automatically set the CREATE_NO_WINDOW flag. - */ - creationFlags |= CREATE_NO_WINDOW; - } - if (attr->stderrFd) { - startupInfo.hStdError = (HANDLE) attr->stderrFd->secret->md.osfd; - redirected = PR_TRUE; - } - if (redirected) { - startupInfo.dwFlags |= STARTF_USESTDHANDLES; - } - cwd = attr->currentDirectory; - } -#endif - -#ifdef WINCE - len = MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, NULL, 0); - wideCmdLine = (PRUnichar *)PR_MALLOC(len * sizeof(PRUnichar)); - MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, wideCmdLine, len); - len = MultiByteToWideChar(CP_ACP, 0, cwd, -1, NULL, 0); - wideCwd = PR_MALLOC(len * sizeof(PRUnichar)); - MultiByteToWideChar(CP_ACP, 0, cwd, -1, wideCwd, len); - retVal = CreateProcessW(NULL, - wideCmdLine, - NULL, /* security attributes for the new - * process */ - NULL, /* security attributes for the primary - * thread in the new process */ - TRUE, /* inherit handles */ - creationFlags, - envBlock, /* an environment block, consisting - * of a null-terminated block of - * null-terminated strings. Each - * string is in the form: - * name=value - * XXX: usually NULL */ - wideCwd, /* current drive and directory */ - &startupInfo, - &procInfo - ); - PR_Free(wideCmdLine); - PR_Free(wideCwd); -#else - retVal = CreateProcess(NULL, - cmdLine, - NULL, /* security attributes for the new - * process */ - NULL, /* security attributes for the primary - * thread in the new process */ - TRUE, /* inherit handles */ - creationFlags, - envBlock, /* an environment block, consisting - * of a null-terminated block of - * null-terminated strings. Each - * string is in the form: - * name=value - * XXX: usually NULL */ - cwd, /* current drive and directory */ - &startupInfo, - &procInfo - ); -#endif - - if (retVal == FALSE) { - /* XXX what error code? */ - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - goto errorExit; - } - - CloseHandle(procInfo.hThread); - proc->md.handle = procInfo.hProcess; - proc->md.id = procInfo.dwProcessId; - - PR_DELETE(cmdLine); - if (newEnvp) { - PR_DELETE(newEnvp); - } - if (envBlock) { - PR_DELETE(envBlock); - } - return proc; - -errorExit: - if (cmdLine) { - PR_DELETE(cmdLine); - } - if (newEnvp) { - PR_DELETE(newEnvp); - } - if (envBlock) { - PR_DELETE(envBlock); - } - if (proc) { - PR_DELETE(proc); - } - return NULL; -} /* _PR_CreateWindowsProcess */ - -PRStatus _PR_DetachWindowsProcess(PRProcess *process) -{ - CloseHandle(process->md.handle); - PR_DELETE(process); - return PR_SUCCESS; -} - -/* - * XXX: This implementation is a temporary quick solution. - * It can be called by native threads only (not by fibers). - */ -PRStatus _PR_WaitWindowsProcess(PRProcess *process, - PRInt32 *exitCode) -{ - DWORD dwRetVal; - - dwRetVal = WaitForSingleObject(process->md.handle, INFINITE); - if (dwRetVal == WAIT_FAILED) { - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - return PR_FAILURE; - } - PR_ASSERT(dwRetVal == WAIT_OBJECT_0); - if (exitCode != NULL && - GetExitCodeProcess(process->md.handle, exitCode) == FALSE) { - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - return PR_FAILURE; - } - CloseHandle(process->md.handle); - PR_DELETE(process); - return PR_SUCCESS; -} - -PRStatus _PR_KillWindowsProcess(PRProcess *process) -{ - /* - * On Unix, if a process terminates normally, its exit code is - * between 0 and 255. So here on Windows, we use the exit code - * 256 to indicate that the process is killed. - */ - if (TerminateProcess(process->md.handle, 256)) { - return PR_SUCCESS; - } - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - return PR_FAILURE; -} - -PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen) -{ - PRIntn rv; - PRInt32 syserror; - - rv = gethostname(name, (PRInt32) namelen); - if (0 == rv) { - return PR_SUCCESS; - } - syserror = WSAGetLastError(); - PR_ASSERT(WSANOTINITIALISED != syserror); - _PR_MD_MAP_GETHOSTNAME_ERROR(syserror); - return PR_FAILURE; -} - -PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen) -{ - OSVERSIONINFO osvi; - - PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE)); - - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - if (! GetVersionEx (&osvi) ) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - return PR_FAILURE; - } - - switch (osvi.dwPlatformId) { - case VER_PLATFORM_WIN32_NT: - if (PR_SI_SYSNAME == cmd) - (void)PR_snprintf(name, namelen, "Windows_NT"); - else if (PR_SI_RELEASE == cmd) - (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, - osvi.dwMinorVersion); - break; - case VER_PLATFORM_WIN32_WINDOWS: - if (PR_SI_SYSNAME == cmd) { - if ((osvi.dwMajorVersion > 4) || - ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0))) - (void)PR_snprintf(name, namelen, "Windows_98"); - else - (void)PR_snprintf(name, namelen, "Windows_95"); - } else if (PR_SI_RELEASE == cmd) { - (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, - osvi.dwMinorVersion); - } - break; -#ifdef VER_PLATFORM_WIN32_CE - case VER_PLATFORM_WIN32_CE: - if (PR_SI_SYSNAME == cmd) - (void)PR_snprintf(name, namelen, "Windows_CE"); - else if (PR_SI_RELEASE == cmd) - (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, - osvi.dwMinorVersion); - break; -#endif - default: - if (PR_SI_SYSNAME == cmd) - (void)PR_snprintf(name, namelen, "Windows_Unknown"); - else if (PR_SI_RELEASE == cmd) - (void)PR_snprintf(name, namelen, "%d.%d",0,0); - break; - } - return PR_SUCCESS; -} - -PRStatus _MD_WindowsGetReleaseName(char *name, PRUint32 namelen) -{ - OSVERSIONINFO osvi; - - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - if (! GetVersionEx (&osvi) ) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - return PR_FAILURE; - } - - switch (osvi.dwPlatformId) { - case VER_PLATFORM_WIN32_NT: - case VER_PLATFORM_WIN32_WINDOWS: - (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, - osvi.dwMinorVersion); - break; - default: - (void)PR_snprintf(name, namelen, "%d.%d",0,0); - break; - } - return PR_SUCCESS; -} - -/* - ********************************************************************** - * - * Memory-mapped files - * - ********************************************************************** - */ - -PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size) -{ - DWORD dwHi, dwLo; - DWORD flProtect; - PROsfd osfd; - - osfd = ( fmap->fd == (PRFileDesc*)-1 )? -1 : fmap->fd->secret->md.osfd; - - dwLo = (DWORD) (size & 0xffffffff); - dwHi = (DWORD) (((PRUint64) size >> 32) & 0xffffffff); - - if (fmap->prot == PR_PROT_READONLY) { - flProtect = PAGE_READONLY; - fmap->md.dwAccess = FILE_MAP_READ; - } else if (fmap->prot == PR_PROT_READWRITE) { - flProtect = PAGE_READWRITE; - fmap->md.dwAccess = FILE_MAP_WRITE; - } else { - PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY); -#ifdef WINCE - /* WINCE does not have FILE_MAP_COPY. */ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -#else - flProtect = PAGE_WRITECOPY; - fmap->md.dwAccess = FILE_MAP_COPY; -#endif - } - - fmap->md.hFileMap = CreateFileMapping( - (HANDLE) osfd, - NULL, - flProtect, - dwHi, - dwLo, - NULL); - - if (fmap->md.hFileMap == NULL) { - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PRInt32 _MD_GetMemMapAlignment(void) -{ - SYSTEM_INFO info; - GetSystemInfo(&info); - return info.dwAllocationGranularity; -} - -extern PRLogModuleInfo *_pr_shma_lm; - -void * _MD_MemMap( - PRFileMap *fmap, - PROffset64 offset, - PRUint32 len) -{ - DWORD dwHi, dwLo; - void *addr; - - dwLo = (DWORD) (offset & 0xffffffff); - dwHi = (DWORD) (((PRUint64) offset >> 32) & 0xffffffff); - if ((addr = MapViewOfFile(fmap->md.hFileMap, fmap->md.dwAccess, - dwHi, dwLo, len)) == NULL) { - { - LPVOID lpMsgBuf; - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, ("md_memmap(): %s", lpMsgBuf )); - } - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - } - return addr; -} - -PRStatus _MD_MemUnmap(void *addr, PRUint32 len) -{ - if (UnmapViewOfFile(addr)) { - return PR_SUCCESS; - } else { - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - return PR_FAILURE; - } -} - -PRStatus _MD_CloseFileMap(PRFileMap *fmap) -{ - CloseHandle(fmap->md.hFileMap); - PR_DELETE(fmap); - return PR_SUCCESS; -} - -/* - *********************************************************************** - * - * Atomic increment and decrement operations for x86 processors - * - * We don't use InterlockedIncrement and InterlockedDecrement - * because on NT 3.51 and Win95, they return a number with - * the same sign as the incremented/decremented result, rather - * than the result itself. On NT 4.0 these functions do return - * the incremented/decremented result. - * - * The result is returned in the eax register by the inline - * assembly code. We disable the harmless "no return value" - * warning (4035) for these two functions. - * - *********************************************************************** - */ - -#if defined(_M_IX86) || defined(_X86_) - -#pragma warning(disable: 4035) -PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *val) -{ -#if defined(__GNUC__) - PRInt32 result; - asm volatile ("lock ; xadd %0, %1" - : "=r"(result), "=m"(*val) - : "0"(1), "m"(*val)); - return result + 1; -#else - __asm - { - mov ecx, val - mov eax, 1 - lock xadd dword ptr [ecx], eax - inc eax - } -#endif /* __GNUC__ */ -} -#pragma warning(default: 4035) - -#pragma warning(disable: 4035) -PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *val) -{ -#if defined(__GNUC__) - PRInt32 result; - asm volatile ("lock ; xadd %0, %1" - : "=r"(result), "=m"(*val) - : "0"(-1), "m"(*val)); - //asm volatile("lock ; xadd %0, %1" : "=m" (val), "=a" (result) : "-1" (1)); - return result - 1; -#else - __asm - { - mov ecx, val - mov eax, 0ffffffffh - lock xadd dword ptr [ecx], eax - dec eax - } -#endif /* __GNUC__ */ -} -#pragma warning(default: 4035) - -#pragma warning(disable: 4035) -PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *intp, PRInt32 val) -{ -#if defined(__GNUC__) - PRInt32 result; - //asm volatile("lock ; xadd %1, %0" : "=m" (intp), "=a" (result) : "1" (val)); - asm volatile ("lock ; xadd %0, %1" - : "=r"(result), "=m"(*intp) - : "0"(val), "m"(*intp)); - return result + val; -#else - __asm - { - mov ecx, intp - mov eax, val - mov edx, eax - lock xadd dword ptr [ecx], eax - add eax, edx - } -#endif /* __GNUC__ */ -} -#pragma warning(default: 4035) - -#ifdef _PR_HAVE_ATOMIC_CAS - -#pragma warning(disable: 4035) -void -PR_StackPush(PRStack *stack, PRStackElem *stack_elem) -{ -#if defined(__GNUC__) - void **tos = (void **) stack; - void *tmp; - - retry: - if (*tos == (void *) -1) - goto retry; - - __asm__("xchg %0,%1" - : "=r" (tmp), "=m"(*tos) - : "0" (-1), "m"(*tos)); - - if (tmp == (void *) -1) - goto retry; - - *(void **)stack_elem = tmp; - __asm__("" : : : "memory"); - *tos = stack_elem; -#else - __asm - { - mov ebx, stack - mov ecx, stack_elem -retry: mov eax,[ebx] - cmp eax,-1 - je retry - mov eax,-1 - xchg dword ptr [ebx], eax - cmp eax,-1 - je retry - mov [ecx],eax - mov [ebx],ecx - } -#endif /* __GNUC__ */ -} -#pragma warning(default: 4035) - -#pragma warning(disable: 4035) -PRStackElem * -PR_StackPop(PRStack *stack) -{ -#if defined(__GNUC__) - void **tos = (void **) stack; - void *tmp; - - retry: - if (*tos == (void *) -1) - goto retry; - - __asm__("xchg %0,%1" - : "=r" (tmp), "=m"(*tos) - : "0" (-1), "m"(*tos)); - - if (tmp == (void *) -1) - goto retry; - - if (tmp != (void *) 0) - { - void *next = *(void **)tmp; - *tos = next; - *(void **)tmp = 0; - } - else - *tos = tmp; - - return tmp; -#else - __asm - { - mov ebx, stack -retry: mov eax,[ebx] - cmp eax,-1 - je retry - mov eax,-1 - xchg dword ptr [ebx], eax - cmp eax,-1 - je retry - cmp eax,0 - je empty - mov ecx,[eax] - mov [ebx],ecx - mov [eax],0 - jmp done -empty: - mov [ebx],eax -done: - } -#endif /* __GNUC__ */ -} -#pragma warning(default: 4035) - -#endif /* _PR_HAVE_ATOMIC_CAS */ - -#endif /* x86 processors */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntsec.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntsec.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntsec.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntsec.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -/* - * ntsec.c - * - * Implement the POSIX-style mode bits (access permissions) for - * files and other securable objects in Windows NT using Windows - * NT's security descriptors with appropriate discretionary - * access-control lists. - */ - -/* - * The security identifiers (SIDs) for owner, primary group, - * and the Everyone (World) group. - * - * These SIDs are looked up during NSPR initialization and - * saved in this global structure (see _PR_NT_InitSids) so - * that _PR_NT_MakeSecurityDescriptorACL doesn't need to - * look them up every time. - */ -static struct { - PSID owner; - PSID group; - PSID everyone; -} _pr_nt_sids; - -/* - * Initialize the SIDs for owner, primary group, and the Everyone - * group in the _pr_nt_sids structure. - * - * This function needs to be called by NSPR initialization. - */ -void _PR_NT_InitSids(void) -{ -#ifdef WINCE /* not supported */ - return; -#else - SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; - HANDLE hToken = NULL; /* initialized to an arbitrary value to - * silence a Purify UMR warning */ - PSID infoBuffer[1024/sizeof(PSID)]; /* defined as an array of PSIDs - * to force proper alignment */ - PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer; - PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup - = (PTOKEN_PRIMARY_GROUP) infoBuffer; - DWORD dwLength; - BOOL rv; - - /* - * Look up and make a copy of the owner and primary group - * SIDs in the access token of the calling process. - */ - rv = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken); - if (rv == 0) { - /* - * On non-NT systems, this function is not implemented - * (error code ERROR_CALL_NOT_IMPLEMENTED), and neither are - * the other security functions. There is no point in - * going further. - * - * A process with insufficient access permissions may fail - * with the error code ERROR_ACCESS_DENIED. - */ - PR_LOG(_pr_io_lm, PR_LOG_DEBUG, - ("_PR_NT_InitSids: OpenProcessToken() failed. Error: %d", - GetLastError())); - return; - } - - rv = GetTokenInformation(hToken, TokenOwner, infoBuffer, - sizeof(infoBuffer), &dwLength); - PR_ASSERT(rv != 0); - dwLength = GetLengthSid(pTokenOwner->Owner); - _pr_nt_sids.owner = (PSID) PR_Malloc(dwLength); - PR_ASSERT(_pr_nt_sids.owner != NULL); - rv = CopySid(dwLength, _pr_nt_sids.owner, pTokenOwner->Owner); - PR_ASSERT(rv != 0); - - rv = GetTokenInformation(hToken, TokenPrimaryGroup, infoBuffer, - sizeof(infoBuffer), &dwLength); - PR_ASSERT(rv != 0); - dwLength = GetLengthSid(pTokenPrimaryGroup->PrimaryGroup); - _pr_nt_sids.group = (PSID) PR_Malloc(dwLength); - PR_ASSERT(_pr_nt_sids.group != NULL); - rv = CopySid(dwLength, _pr_nt_sids.group, - pTokenPrimaryGroup->PrimaryGroup); - PR_ASSERT(rv != 0); - - rv = CloseHandle(hToken); - PR_ASSERT(rv != 0); - - /* Create a well-known SID for the Everyone group. */ - rv = AllocateAndInitializeSid(&SIDAuthWorld, 1, - SECURITY_WORLD_RID, - 0, 0, 0, 0, 0, 0, 0, - &_pr_nt_sids.everyone); - PR_ASSERT(rv != 0); -#endif -} - -/* - * Free the SIDs for owner, primary group, and the Everyone group - * in the _pr_nt_sids structure. - * - * This function needs to be called by NSPR cleanup. - */ -void -_PR_NT_FreeSids(void) -{ -#ifdef WINCE - return; -#else - if (_pr_nt_sids.owner) { - PR_Free(_pr_nt_sids.owner); - } - if (_pr_nt_sids.group) { - PR_Free(_pr_nt_sids.group); - } - if (_pr_nt_sids.everyone) { - FreeSid(_pr_nt_sids.everyone); - } -#endif -} - -/* - * Construct a security descriptor whose discretionary access-control - * list implements the specified mode bits. The SIDs for owner, group, - * and everyone are obtained from the global _pr_nt_sids structure. - * Both the security descriptor and access-control list are returned - * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call. - * - * The accessTable array maps NSPR's read, write, and execute access - * rights to the corresponding NT access rights for the securable - * object. - */ -PRStatus -_PR_NT_MakeSecurityDescriptorACL( - PRIntn mode, - DWORD accessTable[], - PSECURITY_DESCRIPTOR *resultSD, - PACL *resultACL) -{ -#ifdef WINCE - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -#else - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - DWORD cbACL; /* size of ACL */ - DWORD accessMask; - - if (_pr_nt_sids.owner == NULL) { - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; - } - - pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); - if (pSD == NULL) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - - /* - * Construct a discretionary access-control list with three - * access-control entries, one each for owner, primary group, - * and Everyone. - */ - - cbACL = sizeof(ACL) - + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) - + GetLengthSid(_pr_nt_sids.owner) - + GetLengthSid(_pr_nt_sids.group) - + GetLengthSid(_pr_nt_sids.everyone); - pACL = (PACL) PR_Malloc(cbACL); - if (pACL == NULL) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - accessMask = 0; - if (mode & 00400) accessMask |= accessTable[0]; - if (mode & 00200) accessMask |= accessTable[1]; - if (mode & 00100) accessMask |= accessTable[2]; - if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, - _pr_nt_sids.owner)) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - accessMask = 0; - if (mode & 00040) accessMask |= accessTable[0]; - if (mode & 00020) accessMask |= accessTable[1]; - if (mode & 00010) accessMask |= accessTable[2]; - if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, - _pr_nt_sids.group)) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - accessMask = 0; - if (mode & 00004) accessMask |= accessTable[0]; - if (mode & 00002) accessMask |= accessTable[1]; - if (mode & 00001) accessMask |= accessTable[2]; - if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, - _pr_nt_sids.everyone)) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - - if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - goto failed; - } - - *resultSD = pSD; - *resultACL = pACL; - return PR_SUCCESS; - -failed: - if (pSD) { - PR_Free(pSD); - } - if (pACL) { - PR_Free(pACL); - } - return PR_FAILURE; -#endif -} - -/* - * Free the specified security descriptor and access-control list - * previously created by _PR_NT_MakeSecurityDescriptorACL. - */ -void -_PR_NT_FreeSecurityDescriptorACL(PSECURITY_DESCRIPTOR pSD, PACL pACL) -{ - if (pSD) { - PR_Free(pSD); - } - if (pACL) { - PR_Free(pACL); - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntsem.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntsem.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntsem.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntsem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * NT-specific semaphore handling code. - * - */ - - -#include "primpl.h" - - -void -_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value) -{ - md->sem = CreateSemaphore(NULL, value, 0x7fffffff, NULL); -} - -void -_PR_MD_DESTROY_SEM(_MDSemaphore *md) -{ - CloseHandle(md->sem); -} - -PRStatus -_PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks) -{ - int rv; - - rv = WaitForSingleObject(md->sem, PR_IntervalToMilliseconds(ticks)); - - if (rv == WAIT_OBJECT_0) - return PR_SUCCESS; - else - return PR_FAILURE; -} - -PRStatus -_PR_MD_WAIT_SEM(_MDSemaphore *md) -{ - return _PR_MD_TIMED_WAIT_SEM(md, PR_INTERVAL_NO_TIMEOUT); -} - -void -_PR_MD_POST_SEM(_MDSemaphore *md) -{ - int old_count; - - ReleaseSemaphore(md->sem, 1, &old_count); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntthread.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntthread.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/ntthread.c 2012-06-13 02:17:05.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/ntthread.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,564 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include /* for _beginthreadex() */ - -/* --- globals ------------------------------------------------ */ -PRLock *_pr_schedLock = NULL; -_PRInterruptTable _pr_interruptTable[] = { { 0 } }; - -BOOL _pr_use_static_tls = TRUE; -__declspec(thread) PRThread *_pr_current_fiber; -__declspec(thread) PRThread *_pr_fiber_last_run; -__declspec(thread) _PRCPU *_pr_current_cpu; -__declspec(thread) PRUintn _pr_ints_off; -DWORD _pr_currentFiberIndex; -DWORD _pr_lastFiberIndex; -DWORD _pr_currentCPUIndex; -DWORD _pr_intsOffIndex; - -_MDLock _nt_idleLock; -PRCList _nt_idleList; -PRUint32 _nt_idleCount; - -extern __declspec(thread) PRThread *_pr_io_restarted_io; -extern DWORD _pr_io_restartedIOIndex; - -/* Must check the restarted_io *before* decrementing no_sched to 0 */ -#define POST_SWITCH_WORK() \ - PR_BEGIN_MACRO \ - PRThread *restarted_io = \ - (_pr_use_static_tls ? _pr_io_restarted_io \ - : (PRThread *) TlsGetValue(_pr_io_restartedIOIndex)); \ - if (restarted_io) { \ - _nt_handle_restarted_io(restarted_io); \ - } \ - _PR_MD_LAST_THREAD()->no_sched = 0; \ - PR_END_MACRO - -void -_nt_handle_restarted_io(PRThread *restarted_io) -{ - /* After the switch we can resume an IO if needed. - * XXXMB - this needs to be done in create thread, since that could - * be the result for a context switch too.. - */ - PR_ASSERT(restarted_io->io_suspended == PR_TRUE); - PR_ASSERT(restarted_io->md.thr_bound_cpu == restarted_io->cpu); - - _PR_THREAD_LOCK(restarted_io); - if (restarted_io->io_pending == PR_FALSE) { - - /* The IO already completed, put us back on the runq. */ - int pri = restarted_io->priority; - - restarted_io->state = _PR_RUNNABLE; - _PR_RUNQ_LOCK(restarted_io->cpu); - _PR_ADD_RUNQ(restarted_io, restarted_io->cpu, pri); - _PR_RUNQ_UNLOCK(restarted_io->cpu); - } else { - _PR_SLEEPQ_LOCK(restarted_io->cpu); - _PR_ADD_SLEEPQ(restarted_io, restarted_io->sleep); - _PR_SLEEPQ_UNLOCK(restarted_io->cpu); - } - restarted_io->io_suspended = PR_FALSE; - restarted_io->md.thr_bound_cpu = NULL; - - _PR_THREAD_UNLOCK(restarted_io); - - if (_pr_use_static_tls) { - _pr_io_restarted_io = NULL; - } else { - TlsSetValue(_pr_io_restartedIOIndex, NULL); - } -} - -void -_PR_MD_EARLY_INIT() -{ - _MD_NEW_LOCK( &_nt_idleLock ); - _nt_idleCount = 0; - PR_INIT_CLIST(&_nt_idleList); - -#if 0 - /* Make the clock tick at least once per millisecond */ - if ( timeBeginPeriod(1) == TIMERR_NOCANDO) { - /* deep yoghurt; clock doesn't tick fast enough! */ - PR_ASSERT(0); - } -#endif - - if (!_pr_use_static_tls) { - _pr_currentFiberIndex = TlsAlloc(); - _pr_lastFiberIndex = TlsAlloc(); - _pr_currentCPUIndex = TlsAlloc(); - _pr_intsOffIndex = TlsAlloc(); - _pr_io_restartedIOIndex = TlsAlloc(); - } -} - -void _PR_MD_CLEANUP_BEFORE_EXIT(void) -{ - _PR_NT_FreeSids(); - - WSACleanup(); - - if (!_pr_use_static_tls) { - TlsFree(_pr_currentFiberIndex); - TlsFree(_pr_lastFiberIndex); - TlsFree(_pr_currentCPUIndex); - TlsFree(_pr_intsOffIndex); - TlsFree(_pr_io_restartedIOIndex); - } -} - -PRStatus -_PR_MD_INIT_THREAD(PRThread *thread) -{ - thread->md.overlapped.ioModel = _MD_BlockingIO; - thread->md.overlapped.data.mdThread = &thread->md; - - if (thread->flags & _PR_GLOBAL_SCOPE) { - if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { - /* - ** Warning: - ** -------- - ** NSPR requires a real handle to every thread. - ** GetCurrentThread() returns a pseudo-handle which - ** is not suitable for some thread operations (e.g., - ** suspending). Therefore, get a real handle from - ** the pseudo handle via DuplicateHandle(...) - */ - DuplicateHandle( - GetCurrentProcess(), /* Process of source handle */ - GetCurrentThread(), /* Pseudo Handle to dup */ - GetCurrentProcess(), /* Process of handle */ - &(thread->md.handle), /* resulting handle */ - 0L, /* access flags */ - FALSE, /* Inheritable */ - DUPLICATE_SAME_ACCESS); /* Options */ - } - - /* Create the blocking IO semaphore */ - thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL); - if (thread->md.blocked_sema == NULL) { - return PR_FAILURE; - } - if (_native_threads_only) { - /* Create the blocking IO semaphore */ - thread->md.thr_event = CreateEvent(NULL, TRUE, FALSE, NULL); - if (thread->md.thr_event == NULL) { - return PR_FAILURE; - } - } - } - - return PR_SUCCESS; -} - -static unsigned __stdcall -pr_root(void *arg) -{ - PRThread *thread = (PRThread *)arg; - thread->md.start(thread); - return 0; -} - -PRStatus -_PR_MD_CREATE_THREAD(PRThread *thread, - void (*start)(void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - - thread->md.start = start; - thread->md.handle = (HANDLE) _beginthreadex( - NULL, - thread->stack->stackSize, - pr_root, - (void *)thread, - CREATE_SUSPENDED, - &(thread->id)); - if(!thread->md.handle) { - PRErrorCode prerror; - thread->md.fiber_last_error = GetLastError(); - switch (errno) { - case ENOMEM: - prerror = PR_OUT_OF_MEMORY_ERROR; - break; - case EAGAIN: - prerror = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case EINVAL: - prerror = PR_INVALID_ARGUMENT_ERROR; - break; - default: - prerror = PR_UNKNOWN_ERROR; - } - PR_SetError(prerror, errno); - return PR_FAILURE; - } - - thread->md.id = thread->id; - /* - * On windows, a thread is created with a thread priority of - * THREAD_PRIORITY_NORMAL. - */ - if (priority != PR_PRIORITY_NORMAL) { - _PR_MD_SET_PRIORITY(&(thread->md), priority); - } - - /* Activate the thread */ - if ( ResumeThread( thread->md.handle ) != -1) - return PR_SUCCESS; - - PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); - return PR_FAILURE; -} - -void -_PR_MD_JOIN_THREAD(_MDThread *md) -{ - DWORD rv; - - rv = WaitForSingleObject(md->handle, INFINITE); - PR_ASSERT(WAIT_OBJECT_0 == rv); -} - -void -_PR_MD_END_THREAD(void) -{ - _endthreadex(0); -} - -void -_PR_MD_YIELD(void) -{ - /* Can NT really yield at all? */ - Sleep(0); -} - -void -_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) -{ - int nativePri; - BOOL rv; - - if (newPri < PR_PRIORITY_FIRST) { - newPri = PR_PRIORITY_FIRST; - } else if (newPri > PR_PRIORITY_LAST) { - newPri = PR_PRIORITY_LAST; - } - switch (newPri) { - case PR_PRIORITY_LOW: - nativePri = THREAD_PRIORITY_BELOW_NORMAL; - break; - case PR_PRIORITY_NORMAL: - nativePri = THREAD_PRIORITY_NORMAL; - break; - case PR_PRIORITY_HIGH: - nativePri = THREAD_PRIORITY_ABOVE_NORMAL; - break; - case PR_PRIORITY_URGENT: - nativePri = THREAD_PRIORITY_HIGHEST; - } - rv = SetThreadPriority(thread->handle, nativePri); - PR_ASSERT(rv); - if (!rv) { - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("PR_SetThreadPriority: can't set thread priority\n")); - } - return; -} - -const DWORD MS_VC_EXCEPTION = 0x406D1388; - -#pragma pack(push,8) -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -void -_PR_MD_SET_CURRENT_THREAD_NAME(const char *name) -{ -#ifdef _MSC_VER - THREADNAME_INFO info; - - if (!IsDebuggerPresent()) - return; - - info.dwType = 0x1000; - info.szName = (char*) name; - info.dwThreadID = -1; - info.dwFlags = 0; - - __try { - RaiseException(MS_VC_EXCEPTION, - 0, - sizeof(info) / sizeof(ULONG_PTR), - (ULONG_PTR*)&info); - } __except(EXCEPTION_CONTINUE_EXECUTION) { - } -#endif -} - -void -_PR_MD_CLEAN_THREAD(PRThread *thread) -{ - BOOL rv; - - if (thread->md.acceptex_buf) { - PR_DELETE(thread->md.acceptex_buf); - } - - if (thread->md.xmit_bufs) { - PR_DELETE(thread->md.xmit_bufs); - } - - if (thread->md.blocked_sema) { - rv = CloseHandle(thread->md.blocked_sema); - PR_ASSERT(rv); - thread->md.blocked_sema = 0; - } - if (_native_threads_only) { - if (thread->md.thr_event) { - rv = CloseHandle(thread->md.thr_event); - PR_ASSERT(rv); - thread->md.thr_event = 0; - } - } - - if (thread->md.handle) { - rv = CloseHandle(thread->md.handle); - PR_ASSERT(rv); - thread->md.handle = 0; - } - - /* Don't call DeleteFiber on current fiber or we'll kill the whole thread. - * Don't call free(thread) until we've switched off the thread. - * So put this fiber (or thread) on a list to be deleted by the idle - * fiber next time we have a chance. - */ - if (!(thread->flags & (_PR_ATTACHED|_PR_GLOBAL_SCOPE))) { - _MD_LOCK(&_nt_idleLock); - _nt_idleCount++; - PR_APPEND_LINK(&thread->links, &_nt_idleList); - _MD_UNLOCK(&_nt_idleLock); - } -} - -void -_PR_MD_EXIT_THREAD(PRThread *thread) -{ - BOOL rv; - - if (thread->md.acceptex_buf) { - PR_DELETE(thread->md.acceptex_buf); - } - - if (thread->md.xmit_bufs) { - PR_DELETE(thread->md.xmit_bufs); - } - - if (thread->md.blocked_sema) { - rv = CloseHandle(thread->md.blocked_sema); - PR_ASSERT(rv); - thread->md.blocked_sema = 0; - } - - if (_native_threads_only) { - if (thread->md.thr_event) { - rv = CloseHandle(thread->md.thr_event); - PR_ASSERT(rv); - thread->md.thr_event = 0; - } - } - - if (thread->md.handle) { - rv = CloseHandle(thread->md.handle); - PR_ASSERT(rv); - thread->md.handle = 0; - } - - if (thread->flags & _PR_GLOBAL_SCOPE) { - _MD_SET_CURRENT_THREAD(NULL); - } -} - - -void -_PR_MD_EXIT(PRIntn status) -{ - _exit(status); -} - -#ifdef HAVE_FIBERS - -void -_pr_fiber_mainline(void *unused) -{ - PRThread *fiber = _PR_MD_CURRENT_THREAD(); - - POST_SWITCH_WORK(); - - fiber->md.fiber_fn(fiber->md.fiber_arg); -} - -PRThread *_PR_MD_CREATE_USER_THREAD( - PRUint32 stacksize, void (*start)(void *), void *arg) -{ - PRThread *thread; - - if ( (thread = PR_NEW(PRThread)) == NULL ) { - return NULL; - } - - memset(thread, 0, sizeof(PRThread)); - thread->md.fiber_fn = start; - thread->md.fiber_arg = arg; - thread->md.fiber_stacksize = stacksize; - return thread; -} - -void -_PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *thread) -{ - thread->md.fiber_id = ConvertThreadToFiber(NULL); - PR_ASSERT(thread->md.fiber_id); - _MD_SET_CURRENT_THREAD(thread); - _MD_SET_LAST_THREAD(thread); - thread->no_sched = 1; - return; -} - -void -_PR_MD_INIT_CONTEXT(PRThread *thread, char *top, void (*start) (void), PRBool *status) -{ - thread->md.fiber_fn = (void (*)(void *))start; - thread->md.fiber_id = CreateFiber(thread->md.fiber_stacksize, - (LPFIBER_START_ROUTINE)_pr_fiber_mainline, NULL); - if (thread->md.fiber_id != 0) - *status = PR_TRUE; - else { - DWORD oserror = GetLastError(); - PRErrorCode prerror; - if (oserror == ERROR_NOT_ENOUGH_MEMORY) { - prerror = PR_OUT_OF_MEMORY_ERROR; - } else { - prerror = PR_UNKNOWN_ERROR; - } - PR_SetError(prerror, oserror); - *status = PR_FALSE; - } -} - -void -_PR_MD_SWITCH_CONTEXT(PRThread *thread) -{ - PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); - - thread->md.fiber_last_error = GetLastError(); - _PR_Schedule(); -} - -void -_PR_MD_RESTORE_CONTEXT(PRThread *thread) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); - - /* The user-level code for yielding will happily add ourselves to the runq - * and then switch to ourselves; the NT fibers can't handle switching to - * ourselves. - */ - if (thread != me) { - SetLastError(thread->md.fiber_last_error); - _MD_SET_CURRENT_THREAD(thread); - _PR_MD_SET_LAST_THREAD(me); - thread->no_sched = 1; - SwitchToFiber(thread->md.fiber_id); - POST_SWITCH_WORK(); - } -} - - -#endif /* HAVE_FIBERS */ - -PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ) -{ - int rv; - - rv = SetThreadAffinityMask(thread->md.handle, mask); - - return rv?0:-1; -} - -PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask) -{ - PRInt32 rv, system_mask; - - rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask); - - return rv?0:-1; -} - -void -_PR_MD_SUSPEND_CPU(_PRCPU *cpu) -{ - _PR_MD_SUSPEND_THREAD(cpu->thread); -} - -void -_PR_MD_RESUME_CPU(_PRCPU *cpu) -{ - _PR_MD_RESUME_THREAD(cpu->thread); -} - -void -_PR_MD_SUSPEND_THREAD(PRThread *thread) -{ - if (_PR_IS_NATIVE_THREAD(thread)) { - /* - ** There seems to be some doubt about whether or not SuspendThread - ** is a synchronous function. The test afterwards is to help veriry - ** that it is, which is what Microsoft says it is. - */ - PRUintn rv = SuspendThread(thread->md.handle); - PR_ASSERT(0xffffffffUL != rv); - } -} - -void -_PR_MD_RESUME_THREAD(PRThread *thread) -{ - if (_PR_IS_NATIVE_THREAD(thread)) { - ResumeThread(thread->md.handle); - } -} - -PRThread* -_MD_CURRENT_THREAD(void) -{ -PRThread *thread; - - thread = _MD_GET_ATTACHED_THREAD(); - - if (NULL == thread) { - thread = _PRI_AttachThread( - PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); - } - PR_ASSERT(thread != NULL); - return thread; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/objs.mk nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/objs.mk --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/objs.mk 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/objs.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -ifeq ($(OS_TARGET),WINNT) -CSRCS = ntmisc.c \ - ntsec.c \ - ntsem.c \ - ntinrval.c \ - ntgc.c \ - ntio.c \ - ntthread.c \ - ntdllmn.c \ - win32_errors.c \ - w32ipcsem.c \ - w32poll.c \ - w32rng.c \ - w32shm.c -else -ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET))) -CSRCS = ntmisc.c \ - ntsec.c \ - ntsem.c \ - ntinrval.c \ - ntgc.c \ - w95thred.c \ - w95io.c \ - w95cv.c \ - w95sock.c \ - win32_errors.c \ - w32ipcsem.c \ - w32poll.c \ - w32rng.c \ - w32shm.c \ - w95dllmain.c -else -endif # win95 -endif # winnt - -CSRCS += $(PR_MD_CSRCS) -ASFILES += $(PR_MD_ASFILES) - -OBJS += $(addprefix md/windows/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \ - $(addprefix md/windows/$(OBJDIR)/,$(ASFILES:.s=.$(OBJ_SUFFIX))) - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w32ipcsem.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w32ipcsem.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w32ipcsem.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w32ipcsem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,228 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: w32ipcsem.c - * Description: implements named semaphores for NT and WIN95. - */ - -#include "primpl.h" - -#ifdef WINCE -static HANDLE OpenSemaphore(DWORD inDesiredAccess, - BOOL inInheritHandle, - const char *inName) -{ - HANDLE retval = NULL; - HANDLE semaphore = NULL; - PRUnichar wideName[MAX_PATH]; /* name size is limited to MAX_PATH */ - - MultiByteToWideChar(CP_ACP, 0, inName, -1, wideName, MAX_PATH); - /* 0x7fffffff is the max count for our semaphore */ - semaphore = CreateSemaphoreW(NULL, 0, 0x7fffffff, wideName); - if (NULL != semaphore) { - DWORD lastErr = GetLastError(); - - if (ERROR_ALREADY_EXISTS != lastErr) - CloseHandle(semaphore); - else - retval = semaphore; - } - return retval; -} -#endif - -/* - * NSPR-to-NT access right mapping table for semaphore objects. - * - * The SYNCHRONIZE access is required by WaitForSingleObject. - * The SEMAPHORE_MODIFY_STATE access is required by ReleaseSemaphore. - * The OR of these three access masks must equal SEMAPHORE_ALL_ACCESS. - * This is because if a semaphore object with the specified name - * exists, CreateSemaphore requests SEMAPHORE_ALL_ACCESS access to - * the existing object. - */ -static DWORD semAccessTable[] = { - STANDARD_RIGHTS_REQUIRED|0x1, /* read (0x1 is "query state") */ - STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, /* write */ - 0 /* execute */ -}; - -#ifndef _PR_GLOBAL_THREADS_ONLY - -/* - * A fiber cannot call WaitForSingleObject because that - * will block the other fibers running on the same thread. - * If a fiber needs to wait on a (semaphore) handle, we - * create a native thread to call WaitForSingleObject and - * have the fiber join the native thread. - */ - -/* - * Arguments, return value, and error code for WaitForSingleObject - */ -struct WaitSingleArg { - HANDLE handle; - DWORD timeout; - DWORD rv; - DWORD error; -}; - -static void WaitSingleThread(void *arg) -{ - struct WaitSingleArg *warg = (struct WaitSingleArg *) arg; - - warg->rv = WaitForSingleObject(warg->handle, warg->timeout); - if (warg->rv == WAIT_FAILED) { - warg->error = GetLastError(); - } -} - -static DWORD FiberSafeWaitForSingleObject( - HANDLE hHandle, - DWORD dwMilliseconds -) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_PR_IS_NATIVE_THREAD(me)) { - return WaitForSingleObject(hHandle, dwMilliseconds); - } else { - PRThread *waitThread; - struct WaitSingleArg warg; - PRStatus rv; - - warg.handle = hHandle; - warg.timeout = dwMilliseconds; - waitThread = PR_CreateThread( - PR_USER_THREAD, WaitSingleThread, &warg, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (waitThread == NULL) { - return WAIT_FAILED; - } - - rv = PR_JoinThread(waitThread); - PR_ASSERT(rv == PR_SUCCESS); - if (rv == PR_FAILURE) { - return WAIT_FAILED; - } - if (warg.rv == WAIT_FAILED) { - SetLastError(warg.error); - } - return warg.rv; - } -} - -#endif /* !_PR_GLOBAL_THREADS_ONLY */ - -PRSem *_PR_MD_OPEN_SEMAPHORE( - const char *osname, PRIntn flags, PRIntn mode, PRUintn value) -{ - PRSem *sem; - SECURITY_ATTRIBUTES sa; - LPSECURITY_ATTRIBUTES lpSA = NULL; - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - - sem = PR_NEW(PRSem); - if (sem == NULL) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - if (flags & PR_SEM_CREATE) { - if (_PR_NT_MakeSecurityDescriptorACL(mode, semAccessTable, - &pSD, &pACL) == PR_SUCCESS) { - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = FALSE; - lpSA = &sa; - } -#ifdef WINCE - { - /* The size of a sem's name is limited to MAX_PATH. */ - PRUnichar wosname[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, osname, -1, wosname, MAX_PATH); - sem->sem = CreateSemaphoreW(lpSA, value, 0x7fffffff, wosname); - } -#else - sem->sem = CreateSemaphoreA(lpSA, value, 0x7fffffff, osname); -#endif - if (lpSA != NULL) { - _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); - } - if (sem->sem == NULL) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - PR_DELETE(sem); - return NULL; - } - if ((flags & PR_SEM_EXCL) && (GetLastError() == ERROR_ALREADY_EXISTS)) { - PR_SetError(PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS); - CloseHandle(sem->sem); - PR_DELETE(sem); - return NULL; - } - } else { - sem->sem = OpenSemaphore( - SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, FALSE, osname); - if (sem->sem == NULL) { - DWORD err = GetLastError(); - - /* - * If we open a nonexistent named semaphore, NT - * returns ERROR_FILE_NOT_FOUND, while Win95 - * returns ERROR_INVALID_NAME - */ - if (err == ERROR_INVALID_NAME) { - PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); - } else { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - } - PR_DELETE(sem); - return NULL; - } - } - return sem; -} - -PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem) -{ - DWORD rv; - -#ifdef _PR_GLOBAL_THREADS_ONLY - rv = WaitForSingleObject(sem->sem, INFINITE); -#else - rv = FiberSafeWaitForSingleObject(sem->sem, INFINITE); -#endif - PR_ASSERT(rv == WAIT_FAILED || rv == WAIT_OBJECT_0); - if (rv == WAIT_FAILED) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - return PR_FAILURE; - } - if (rv != WAIT_OBJECT_0) { - /* Should not happen */ - PR_SetError(PR_UNKNOWN_ERROR, 0); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem) -{ - if (ReleaseSemaphore(sem->sem, 1, NULL) == FALSE) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem) -{ - if (CloseHandle(sem->sem) == FALSE) { - _PR_MD_MAP_CLOSE_ERROR(GetLastError()); - return PR_FAILURE; - } - PR_DELETE(sem); - return PR_SUCCESS; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w32poll.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w32poll.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w32poll.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w32poll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,325 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This file implements _PR_MD_PR_POLL for Win32. - */ - -/* The default value of FD_SETSIZE is 64. */ -#define FD_SETSIZE 1024 - -#include "primpl.h" - -#if !defined(_PR_GLOBAL_THREADS_ONLY) - -struct select_data_s { - PRInt32 status; - PRInt32 error; - fd_set *rd, *wt, *ex; - const struct timeval *tv; -}; - -static void -_PR_MD_select_thread(void *cdata) -{ - struct select_data_s *cd = (struct select_data_s *)cdata; - - cd->status = select(0, cd->rd, cd->wt, cd->ex, cd->tv); - - if (cd->status == SOCKET_ERROR) { - cd->error = WSAGetLastError(); - } -} - -int _PR_NTFiberSafeSelect( - int nfds, - fd_set *readfds, - fd_set *writefds, - fd_set *exceptfds, - const struct timeval *timeout) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - int ready; - - if (_PR_IS_NATIVE_THREAD(me)) { - ready = _MD_SELECT(nfds, readfds, writefds, exceptfds, timeout); - } - else - { - /* - ** Creating a new thread on each call!! - ** I guess web server doesn't use non-block I/O. - */ - PRThread *selectThread; - struct select_data_s data; - data.status = 0; - data.error = 0; - data.rd = readfds; - data.wt = writefds; - data.ex = exceptfds; - data.tv = timeout; - - selectThread = PR_CreateThread( - PR_USER_THREAD, _PR_MD_select_thread, &data, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (selectThread == NULL) return -1; - - PR_JoinThread(selectThread); - ready = data.status; - if (ready == SOCKET_ERROR) WSASetLastError(data.error); - } - return ready; -} - -#endif /* !defined(_PR_GLOBAL_THREADS_ONLY) */ - -PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - int ready, err; - fd_set rd, wt, ex; - fd_set *rdp, *wtp, *exp; - int nrd, nwt, nex; - PRFileDesc *bottom; - PRPollDesc *pd, *epd; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - struct timeval tv, *tvp = NULL; - - if (_PR_PENDING_INTERRUPT(me)) - { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - return -1; - } - - /* - ** Is it an empty set? If so, just sleep for the timeout and return - */ - if (0 == npds) - { - PR_Sleep(timeout); - return 0; - } - - nrd = nwt = nex = 0; - FD_ZERO(&rd); - FD_ZERO(&wt); - FD_ZERO(&ex); - - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - SOCKET osfd; - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - if (pd->in_flags & PR_POLL_READ) - { - in_flags_read = (pd->fd->methods->poll)( - pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_WRITE), - &out_flags_read); - } - if (pd->in_flags & PR_POLL_WRITE) - { - in_flags_write = (pd->fd->methods->poll)( - pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_READ), - &out_flags_write); - } - if ((0 != (in_flags_read & out_flags_read)) - || (0 != (in_flags_write & out_flags_write))) - { - /* this one's ready right now (buffered input) */ - if (0 == ready) - { - /* - * We will have to return without calling the - * system poll/select function. So zero the - * out_flags fields of all the poll descriptors - * before this one. - */ - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; - pd->out_flags = out_flags_read | out_flags_write; - } - else - { - pd->out_flags = 0; /* pre-condition */ - /* make sure this is an NSPR supported stack */ - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); /* what to do about that? */ - if ((NULL != bottom) - && (_PR_FILEDESC_OPEN == bottom->secret->state)) - { - if (0 == ready) - { - osfd = (SOCKET) bottom->secret->md.osfd; - if (in_flags_read & PR_POLL_READ) - { - pd->out_flags |= _PR_POLL_READ_SYS_READ; - FD_SET(osfd, &rd); - nrd++; - } - if (in_flags_read & PR_POLL_WRITE) - { - pd->out_flags |= _PR_POLL_READ_SYS_WRITE; - FD_SET(osfd, &wt); - nwt++; - } - if (in_flags_write & PR_POLL_READ) - { - pd->out_flags |= _PR_POLL_WRITE_SYS_READ; - FD_SET(osfd, &rd); - nrd++; - } - if (in_flags_write & PR_POLL_WRITE) - { - pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; - FD_SET(osfd, &wt); - nwt++; - } - if (pd->in_flags & PR_POLL_EXCEPT) { - FD_SET(osfd, &ex); - nex++; - } - } - } - else - { - if (0 == ready) - { - PRPollDesc *prev; - for (prev = pds; prev < pd; prev++) - { - prev->out_flags = 0; - } - } - ready += 1; /* this will cause an abrupt return */ - pd->out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - else - { - pd->out_flags = 0; - } - } - - if (0 != ready) return ready; /* no need to block */ - - /* - * FD_SET does nothing if the fd_set's internal fd_array is full. If - * nrd, nwt, or nex is greater than FD_SETSIZE, we know FD_SET must - * have failed to insert an osfd into the corresponding fd_set, and - * therefore we should fail. - */ - if ((nrd > FD_SETSIZE) || (nwt > FD_SETSIZE) || (nex > FD_SETSIZE)) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - - rdp = (0 == nrd) ? NULL : &rd; - wtp = (0 == nwt) ? NULL : &wt; - exp = (0 == nex) ? NULL : &ex; - - if ((NULL == rdp) && (NULL == wtp) && (NULL == exp)) { - PR_Sleep(timeout); - return 0; - } - - if (timeout != PR_INTERVAL_NO_TIMEOUT) - { - PRInt32 ticksPerSecond = PR_TicksPerSecond(); - tv.tv_sec = timeout / ticksPerSecond; - tv.tv_usec = PR_IntervalToMicroseconds( timeout % ticksPerSecond ); - tvp = &tv; - } - -#if defined(_PR_GLOBAL_THREADS_ONLY) - ready = _MD_SELECT(0, rdp, wtp, exp, tvp); -#else - ready = _PR_NTFiberSafeSelect(0, rdp, wtp, exp, tvp); -#endif - - /* - ** Now to unravel the select sets back into the client's poll - ** descriptor list. Is this possibly an area for pissing away - ** a few cycles or what? - */ - if (ready > 0) - { - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - PRInt16 out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - SOCKET osfd; - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); - - osfd = (SOCKET) bottom->secret->md.osfd; - - if (FD_ISSET(osfd, &rd)) - { - if (pd->out_flags & _PR_POLL_READ_SYS_READ) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) - out_flags |= PR_POLL_WRITE; - } - if (FD_ISSET(osfd, &wt)) - { - if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) - out_flags |= PR_POLL_READ; - if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) - out_flags |= PR_POLL_WRITE; - } - if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; - } - pd->out_flags = out_flags; - if (out_flags) ready++; - } - PR_ASSERT(ready > 0); - } - else if (ready == SOCKET_ERROR) - { - err = WSAGetLastError(); - if (err == WSAENOTSOCK) - { - /* Find the bad fds */ - int optval; - int optlen = sizeof(optval); - ready = 0; - for (pd = pds, epd = pd + npds; pd < epd; pd++) - { - pd->out_flags = 0; - if ((NULL != pd->fd) && (0 != pd->in_flags)) - { - bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET, - SO_TYPE, (char *) &optval, &optlen) == -1) - { - PR_ASSERT(WSAGetLastError() == WSAENOTSOCK); - if (WSAGetLastError() == WSAENOTSOCK) - { - pd->out_flags = PR_POLL_NVAL; - ready++; - } - } - } - } - PR_ASSERT(ready > 0); - } - else _PR_MD_MAP_SELECT_ERROR(err); - } - - return ready; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w32rng.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w32rng.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w32rng.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w32rng.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include -#include -#include -#include -#include - -static BOOL -CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow) -{ - LARGE_INTEGER liCount; - - if (!QueryPerformanceCounter(&liCount)) - return FALSE; - - *lpdwHigh = liCount.u.HighPart; - *lpdwLow = liCount.u.LowPart; - return TRUE; -} - -extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ) -{ - DWORD dwHigh, dwLow, dwVal; - size_t n = 0; - size_t nBytes; - time_t sTime; - - if (size <= 0) - return 0; - - CurrentClockTickTime(&dwHigh, &dwLow); - - // get the maximally changing bits first - nBytes = sizeof(dwLow) > size ? size : sizeof(dwLow); - memcpy((char *)buf, &dwLow, nBytes); - n += nBytes; - size -= nBytes; - - if (size <= 0) - return n; - - nBytes = sizeof(dwHigh) > size ? size : sizeof(dwHigh); - memcpy(((char *)buf) + n, &dwHigh, nBytes); - n += nBytes; - size -= nBytes; - - if (size <= 0) - return n; - - // get the number of milliseconds that have elapsed since Windows started - dwVal = GetTickCount(); - - nBytes = sizeof(dwVal) > size ? size : sizeof(dwVal); - memcpy(((char *)buf) + n, &dwVal, nBytes); - n += nBytes; - size -= nBytes; - - if (size <= 0) - return n; - - // get the time in seconds since midnight Jan 1, 1970 - time(&sTime); - nBytes = sizeof(sTime) > size ? size : sizeof(sTime); - memcpy(((char *)buf) + n, &sTime, nBytes); - n += nBytes; - - return n; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w32shm.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w32shm.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w32shm.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w32shm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,347 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include -#include -#include - -#if defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY) - -extern PRLogModuleInfo *_pr_shm_lm; - -/* - * NSPR-to-NT access right mapping table for file-mapping objects. - * - * The OR of these three access masks must equal FILE_MAP_ALL_ACCESS. - * This is because if a file-mapping object with the specified name - * exists, CreateFileMapping requests full access to the existing - * object. - */ -static DWORD filemapAccessTable[] = { - FILE_MAP_ALL_ACCESS & ~FILE_MAP_WRITE, /* read */ - FILE_MAP_ALL_ACCESS & ~FILE_MAP_READ, /* write */ - 0 /* execute */ -}; - -extern PRSharedMemory * _MD_OpenSharedMemory( - const char *name, - PRSize size, - PRIntn flags, - PRIntn mode -) -{ - char ipcname[PR_IPC_NAME_SIZE]; - PRStatus rc = PR_SUCCESS; - DWORD dwHi, dwLo; - PRSharedMemory *shm; - DWORD flProtect = ( PAGE_READWRITE ); - SECURITY_ATTRIBUTES sa; - LPSECURITY_ATTRIBUTES lpSA = NULL; - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - - rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); - if ( PR_FAILURE == rc ) - { - PR_SetError(PR_UNKNOWN_ERROR, 0 ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: name is invalid")); - return(NULL); - } - - shm = PR_NEWZAP( PRSharedMemory ); - if ( NULL == shm ) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); - return(NULL); - } - - shm->ipcname = PR_MALLOC( (PRUint32) (strlen( ipcname ) + 1) ); - if ( NULL == shm->ipcname ) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); - PR_DELETE(shm); - return(NULL); - } - - /* copy args to struct */ - strcpy( shm->ipcname, ipcname ); - shm->size = size; - shm->mode = mode; - shm->flags = flags; - shm->ident = _PR_SHM_IDENT; - - if (flags & PR_SHM_CREATE ) { - dwHi = (DWORD) (((PRUint64) shm->size >> 32) & 0xffffffff); - dwLo = (DWORD) (shm->size & 0xffffffff); - - if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable, - &pSD, &pACL) == PR_SUCCESS) { - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = FALSE; - lpSA = &sa; - } -#ifdef WINCE - { - /* - * This is assuming that the name will never be larger than - * MAX_PATH. Should we dynamically allocate? - */ - PRUnichar wideIpcName[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, shm->ipcname, -1, - wideIpcName, MAX_PATH); - shm->handle = CreateFileMappingW( - (HANDLE)-1 , - lpSA, - flProtect, - dwHi, - dwLo, - wideIpcName); - } -#else - shm->handle = CreateFileMappingA( - (HANDLE)-1 , - lpSA, - flProtect, - dwHi, - dwLo, - shm->ipcname); -#endif - if (lpSA != NULL) { - _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); - } - - if ( NULL == shm->handle ) { - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, - ( "PR_OpenSharedMemory: CreateFileMapping() failed: %s", - shm->ipcname )); - _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); - PR_FREEIF( shm->ipcname ) - PR_DELETE( shm ); - return(NULL); - } else { - if (( flags & PR_SHM_EXCL) && ( GetLastError() == ERROR_ALREADY_EXISTS )) { - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, - ( "PR_OpenSharedMemory: Request exclusive & already exists", - shm->ipcname )); - PR_SetError( PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS ); - CloseHandle( shm->handle ); - PR_FREEIF( shm->ipcname ) - PR_DELETE( shm ); - return(NULL); - } else { - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, - ( "PR_OpenSharedMemory: CreateFileMapping() success: %s, handle: %d", - shm->ipcname, shm->handle )); - return(shm); - } - } - } else { -#ifdef WINCE - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - shm->handle = NULL; /* OpenFileMapping not supported */ -#else - shm->handle = OpenFileMapping( FILE_MAP_WRITE, TRUE, shm->ipcname ); -#endif - if ( NULL == shm->handle ) { - _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, - ( "PR_OpenSharedMemory: OpenFileMapping() failed: %s, error: %d", - shm->ipcname, PR_GetOSError())); - PR_FREEIF( shm->ipcname ); - PR_DELETE( shm ); - return(NULL); - } else { - PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, - ( "PR_OpenSharedMemory: OpenFileMapping() success: %s, handle: %d", - shm->ipcname, shm->handle )); - return(shm); - } - } - /* returns from separate paths */ -} - -extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) -{ - PRUint32 access = FILE_MAP_WRITE; - void *addr; - - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - if ( PR_SHM_READONLY & flags ) - access = FILE_MAP_READ; - - addr = MapViewOfFile( shm->handle, - access, - 0, 0, - shm->size ); - - if ( NULL == addr ) { - _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); - PR_LOG( _pr_shm_lm, PR_LOG_ERROR, - ("_MD_AttachSharedMemory: MapViewOfFile() failed. OSerror: %d", PR_GetOSError())); - } - - return( addr ); -} /* end _MD_ATTACH_SHARED_MEMORY() */ - - -extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) -{ - PRStatus rc = PR_SUCCESS; - BOOL wrc; - - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - wrc = UnmapViewOfFile( addr ); - if ( FALSE == wrc ) - { - _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); - PR_LOG( _pr_shm_lm, PR_LOG_ERROR, - ("_MD_DetachSharedMemory: UnmapViewOfFile() failed. OSerror: %d", PR_GetOSError())); - rc = PR_FAILURE; - } - - return( rc ); -} - - -extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) -{ - PRStatus rc = PR_SUCCESS; - BOOL wrc; - - PR_ASSERT( shm->ident == _PR_SHM_IDENT ); - - wrc = CloseHandle( shm->handle ); - if ( FALSE == wrc ) - { - _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); - PR_LOG( _pr_shm_lm, PR_LOG_ERROR, - ("_MD_CloseSharedMemory: CloseHandle() failed. OSerror: %d", PR_GetOSError())); - rc = PR_FAILURE; - } - PR_FREEIF( shm->ipcname ); - PR_DELETE( shm ); - - return( rc ); -} /* end _MD_CLOSE_SHARED_MEMORY() */ - -extern PRStatus _MD_DeleteSharedMemory( const char *name ) -{ - return( PR_SUCCESS ); -} - - -/* -** Windows implementation of anonymous memory (file) map -*/ -extern PRLogModuleInfo *_pr_shma_lm; - -extern PRFileMap* _md_OpenAnonFileMap( - const char *dirName, - PRSize size, - PRFileMapProtect prot -) -{ - PRFileMap *fm; - HANDLE hFileMap; - - fm = PR_CreateFileMap( (PRFileDesc*)-1, size, prot ); - if ( NULL == fm ) { - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): PR_CreateFileMap(): failed")); - goto Finished; - } - - /* - ** Make fm->md.hFileMap inheritable. We can't use - ** GetHandleInformation and SetHandleInformation - ** because these two functions fail with - ** ERROR_CALL_NOT_IMPLEMENTED on Win95. - */ - if (DuplicateHandle(GetCurrentProcess(), fm->md.hFileMap, - GetCurrentProcess(), &hFileMap, - 0, TRUE /* inheritable */, - DUPLICATE_SAME_ACCESS) == FALSE) { - PR_SetError( PR_UNKNOWN_ERROR, GetLastError() ); - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_OpenAnonFileMap(): DuplicateHandle(): failed")); - PR_CloseFileMap( fm ); - fm = NULL; - goto Finished; - } - CloseHandle(fm->md.hFileMap); - fm->md.hFileMap = hFileMap; - -Finished: - return(fm); -} /* end md_OpenAnonFileMap() */ - -/* -** _md_ExportFileMapAsString() -** -*/ -extern PRStatus _md_ExportFileMapAsString( - PRFileMap *fm, - PRSize bufSize, - char *buf -) -{ - PRIntn written; - - written = PR_snprintf( buf, (PRUint32) bufSize, "%d:%" PR_PRIdOSFD ":%ld", - (PRIntn)fm->prot, (PROsfd)fm->md.hFileMap, (PRInt32)fm->md.dwAccess ); - - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_ExportFileMapAsString(): prot: %x, hFileMap: %x, dwAccess: %x", - fm->prot, fm->md.hFileMap, fm->md.dwAccess )); - - return((written == -1)? PR_FAILURE : PR_SUCCESS); -} /* end _md_ExportFileMapAsString() */ - - -/* -** _md_ImportFileMapFromString() -** -*/ -extern PRFileMap * _md_ImportFileMapFromString( - const char *fmstring -) -{ - PRIntn prot; - PROsfd hFileMap; - PRInt32 dwAccess; - PRFileMap *fm = NULL; - - PR_sscanf( fmstring, "%d:%" PR_SCNdOSFD ":%ld", - &prot, &hFileMap, &dwAccess ); - - fm = PR_NEWZAP(PRFileMap); - if ( NULL == fm ) { - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_ImportFileMapFromString(): PR_NEWZAP(): Failed")); - return(fm); - } - - fm->prot = (PRFileMapProtect)prot; - fm->md.hFileMap = (HANDLE)hFileMap; - fm->md.dwAccess = (DWORD)dwAccess; - fm->fd = (PRFileDesc*)-1; - - PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, - ("_md_ImportFileMapFromString(): fm: %p, prot: %d, hFileMap: %8.8x, dwAccess: %8.8x, fd: %x", - fm, prot, fm->md.hFileMap, fm->md.dwAccess, fm->fd)); - return(fm); -} /* end _md_ImportFileMapFromString() */ - -#else -Error! Why is PR_HAVE_WIN32_NAMED_SHARED_MEMORY not defined? -#endif /* PR_HAVE_WIN32_NAMED_SHARED_MEMORY */ -/* --- end w32shm.c --- */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95cv.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95cv.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95cv.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95cv.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,315 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * w95cv.c -- Windows 95 Machine-Dependent Code for Condition Variables - * - * We implement our own condition variable wait queue. Each thread - * has a semaphore object (thread->md.blocked_sema) to block on while - * waiting on a condition variable. - * - * We use a deferred condition notify algorithm. When PR_NotifyCondVar - * or PR_NotifyAllCondVar is called, the condition notifies are simply - * recorded in the _MDLock structure. We defer the condition notifies - * until right after we unlock the lock. This way the awakened threads - * have a better chance to reaquire the lock. - */ - -#include "primpl.h" - -/* - * AddThreadToCVWaitQueueInternal -- - * - * Add the thread to the end of the condition variable's wait queue. - * The CV's lock must be locked when this function is called. - */ - -static void -AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv) -{ - PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL) - || (cv->waitTail == NULL && cv->waitHead == NULL)); - cv->nwait += 1; - thred->md.inCVWaitQueue = PR_TRUE; - thred->md.next = NULL; - thred->md.prev = cv->waitTail; - if (cv->waitHead == NULL) { - cv->waitHead = thred; - } else { - cv->waitTail->md.next = thred; - } - cv->waitTail = thred; -} - -/* - * md_UnlockAndPostNotifies -- - * - * Unlock the lock, and then do the deferred condition notifies. - * If waitThred and waitCV are not NULL, waitThred is added to - * the wait queue of waitCV before the lock is unlocked. - * - * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK, - * the two places where a lock is unlocked. - */ -static void -md_UnlockAndPostNotifies( - _MDLock *lock, - PRThread *waitThred, - _MDCVar *waitCV) -{ - PRIntn index; - _MDNotified post; - _MDNotified *notified, *prev = NULL; - - /* - * Time to actually notify any conditions that were affected - * while the lock was held. Get a copy of the list that's in - * the lock structure and then zero the original. If it's - * linked to other such structures, we own that storage. - */ - post = lock->notified; /* a safe copy; we own the lock */ - -#if defined(DEBUG) - ZeroMemory(&lock->notified, sizeof(_MDNotified)); /* reset */ -#else - lock->notified.length = 0; /* these are really sufficient */ - lock->notified.link = NULL; -#endif - - /* - * Figure out how many threads we need to wake up. - */ - notified = &post; /* this is where we start */ - do { - for (index = 0; index < notified->length; ++index) { - _MDCVar *cv = notified->cv[index].cv; - PRThread *thred; - int i; - - /* Fast special case: no waiting threads */ - if (cv->waitHead == NULL) { - notified->cv[index].notifyHead = NULL; - continue; - } - - /* General case */ - if (-1 == notified->cv[index].times) { - /* broadcast */ - thred = cv->waitHead; - while (thred != NULL) { - thred->md.inCVWaitQueue = PR_FALSE; - thred = thred->md.next; - } - notified->cv[index].notifyHead = cv->waitHead; - cv->waitHead = cv->waitTail = NULL; - cv->nwait = 0; - } else { - thred = cv->waitHead; - i = notified->cv[index].times; - while (thred != NULL && i > 0) { - thred->md.inCVWaitQueue = PR_FALSE; - thred = thred->md.next; - i--; - } - notified->cv[index].notifyHead = cv->waitHead; - cv->waitHead = thred; - if (cv->waitHead == NULL) { - cv->waitTail = NULL; - } else { - if (cv->waitHead->md.prev != NULL) { - cv->waitHead->md.prev->md.next = NULL; - cv->waitHead->md.prev = NULL; - } - } - cv->nwait -= notified->cv[index].times - i; - } - } - notified = notified->link; - } while (NULL != notified); - - if (waitThred) { - AddThreadToCVWaitQueueInternal(waitThred, waitCV); - } - - /* Release the lock before notifying */ - LeaveCriticalSection(&lock->mutex); - - notified = &post; /* this is where we start */ - do { - for (index = 0; index < notified->length; ++index) { - PRThread *thred; - PRThread *next; - - thred = notified->cv[index].notifyHead; - while (thred != NULL) { - BOOL rv; - - next = thred->md.next; - thred->md.prev = thred->md.next = NULL; - - rv = ReleaseSemaphore(thred->md.blocked_sema, 1, NULL); - PR_ASSERT(rv != 0); - thred = next; - } - } - prev = notified; - notified = notified->link; - if (&post != prev) PR_DELETE(prev); - } while (NULL != notified); -} - -/* - * Notifies just get posted to the protecting mutex. The - * actual notification is done when the lock is released so that - * MP systems don't contend for a lock that they can't have. - */ -static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock, - PRBool broadcast) -{ - PRIntn index = 0; - _MDNotified *notified = &lock->notified; - - while (1) { - for (index = 0; index < notified->length; ++index) { - if (notified->cv[index].cv == cvar) { - if (broadcast) { - notified->cv[index].times = -1; - } else if (-1 != notified->cv[index].times) { - notified->cv[index].times += 1; - } - return; - } - } - /* if not full, enter new CV in this array */ - if (notified->length < _MD_CV_NOTIFIED_LENGTH) break; - - /* if there's no link, create an empty array and link it */ - if (NULL == notified->link) { - notified->link = PR_NEWZAP(_MDNotified); - } - - notified = notified->link; - } - - /* A brand new entry in the array */ - notified->cv[index].times = (broadcast) ? -1 : 1; - notified->cv[index].cv = cvar; - notified->length += 1; -} - -/* - * _PR_MD_NEW_CV() -- Creating new condition variable - * ... Solaris uses cond_init() in similar function. - * - * returns: -1 on failure - * 0 when it succeeds. - * - */ -PRInt32 -_PR_MD_NEW_CV(_MDCVar *cv) -{ - cv->magic = _MD_MAGIC_CV; - /* - * The waitHead, waitTail, and nwait fields are zeroed - * when the PRCondVar structure is created. - */ - return 0; -} - -void _PR_MD_FREE_CV(_MDCVar *cv) -{ - cv->magic = (PRUint32)-1; - return; -} - -/* - * _PR_MD_WAIT_CV() -- Wait on condition variable - */ -void _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout ) -{ - PRThread *thred = _PR_MD_CURRENT_THREAD(); - DWORD rv; - DWORD msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ? - INFINITE : PR_IntervalToMilliseconds(timeout); - - /* - * If we have pending notifies, post them now. - */ - if (0 != lock->notified.length) { - md_UnlockAndPostNotifies(lock, thred, cv); - } else { - AddThreadToCVWaitQueueInternal(thred, cv); - LeaveCriticalSection(&lock->mutex); - } - - /* Wait for notification or timeout; don't really care which */ - rv = WaitForSingleObject(thred->md.blocked_sema, msecs); - - EnterCriticalSection(&(lock->mutex)); - - PR_ASSERT(rv != WAIT_ABANDONED); - PR_ASSERT(rv != WAIT_FAILED); - PR_ASSERT(rv != WAIT_OBJECT_0 || thred->md.inCVWaitQueue == PR_FALSE); - - if (rv == WAIT_TIMEOUT) { - if (thred->md.inCVWaitQueue) { - PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL) - || (cv->waitTail == NULL && cv->waitHead == NULL)); - cv->nwait -= 1; - thred->md.inCVWaitQueue = PR_FALSE; - if (cv->waitHead == thred) { - cv->waitHead = thred->md.next; - if (cv->waitHead == NULL) { - cv->waitTail = NULL; - } else { - cv->waitHead->md.prev = NULL; - } - } else { - PR_ASSERT(thred->md.prev != NULL); - thred->md.prev->md.next = thred->md.next; - if (thred->md.next != NULL) { - thred->md.next->md.prev = thred->md.prev; - } else { - PR_ASSERT(cv->waitTail == thred); - cv->waitTail = thred->md.prev; - } - } - thred->md.next = thred->md.prev = NULL; - } else { - /* - * This thread must have been notified, but the - * ReleaseSemaphore call happens after WaitForSingleObject - * times out. Wait on the semaphore again to make it - * non-signaled. We assume this wait won't take long. - */ - rv = WaitForSingleObject(thred->md.blocked_sema, INFINITE); - PR_ASSERT(rv == WAIT_OBJECT_0); - } - } - PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE); - return; -} /* --- end _PR_MD_WAIT_CV() --- */ - -void _PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock) -{ - md_PostNotifyToCvar(cv, lock, PR_FALSE); - return; -} - -void _PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock) -{ - md_PostNotifyToCvar(cv, lock, PR_TRUE); - return; -} - -void _PR_MD_UNLOCK(_MDLock *lock) -{ - if (0 != lock->notified.length) { - md_UnlockAndPostNotifies(lock, NULL, NULL); - } else { - LeaveCriticalSection(&lock->mutex); - } - return; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95dllmain.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95dllmain.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95dllmain.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95dllmain.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * The DLL entry point (DllMain) for NSPR. - * - * This is used to detach threads that were automatically attached by - * nspr. - */ - -#include -#include - -BOOL WINAPI DllMain( - HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ -PRThread *me; - - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - break; - case DLL_THREAD_ATTACH: - break; - case DLL_THREAD_DETACH: - if (_pr_initialized) { - me = _MD_GET_ATTACHED_THREAD(); - if ((me != NULL) && (me->flags & _PR_ATTACHED)) - _PRI_DetachThread(); - } - break; - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95io.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95io.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95io.c 2012-03-06 13:14:17.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95io.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1753 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Windows 95 IO module - * - * Assumes synchronous I/O. - * - */ - -#include "primpl.h" -#include -#include -#ifdef MOZ_UNICODE -#include -#endif /* MOZ_UNICODE */ - -#ifdef WINCE - -static HANDLE CreateFileA(LPCSTR lpFileName, - DWORD dwDesiredAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile) -{ - PRUnichar wFileName[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, wFileName, MAX_PATH); - return CreateFileW(wFileName, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, - dwFlagsAndAttributes, hTemplateFile); -} - -/* - * We seem to call FindFirstFileA and FindNextFileA just to get - * the file names in a directory listing. If so, we could define - * a custom WIN32_FIND_DATAA structure with just the cFileName - * member, and the CopyFindFileDataW2A function could just - * copy/convert the cFileName member. - */ -static void CopyFindFileDataW2A(LPWIN32_FIND_DATAW from, - LPWIN32_FIND_DATAA to) -{ - /* - * WIN32_FIND_DATAA and WIN32_FIND_DATAW are slightly different. - * The dwReserved0, dwReserved1, and cAlternateFileName members - * exist only in WIN32_FIND_DATAA. The dwOID member exists only - * in WIN32_FIND_DATAW. - */ - to->dwFileAttributes = from->dwFileAttributes; - to->ftCreationTime = from->ftCreationTime; - to->ftLastAccessTime = from->ftLastAccessTime; - to->ftLastWriteTime = from->ftLastWriteTime; - to->nFileSizeHigh = from->nFileSizeHigh; - to->nFileSizeLow = from->nFileSizeLow; - to->dwReserved0 = 0; - to->dwReserved1 = 0; - WideCharToMultiByte(CP_ACP, 0, from->cFileName, -1, - to->cFileName, MAX_PATH, NULL, NULL); - to->cAlternateFileName[0] = '\0'; -} - -static HANDLE FindFirstFileA(LPCSTR lpFileName, - LPWIN32_FIND_DATAA lpFindFileData) -{ - PRUnichar wFileName[MAX_PATH]; - HANDLE hFindFile; - WIN32_FIND_DATAW wFindFileData; - - MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, wFileName, MAX_PATH); - hFindFile = FindFirstFileW(wFileName, &wFindFileData); - if (hFindFile != INVALID_HANDLE_VALUE) { - CopyFindFileDataW2A(&wFindFileData, lpFindFileData); - } - return hFindFile; -} - -static BOOL FindNextFileA(HANDLE hFindFile, - LPWIN32_FIND_DATAA lpFindFileData) -{ - WIN32_FIND_DATAW wFindFileData; - BOOL rv; - - rv = FindNextFileW(hFindFile, &wFindFileData); - if (rv) { - CopyFindFileDataW2A(&wFindFileData, lpFindFileData); - } - return rv; -} - -static BOOL GetFileAttributesExA(LPCSTR lpFileName, - GET_FILEEX_INFO_LEVELS fInfoLevelId, - LPVOID lpFileInformation) -{ - PRUnichar wFileName[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, wFileName, MAX_PATH); - return GetFileAttributesExW(wFileName, fInfoLevelId, lpFileInformation); -} - -static BOOL DeleteFileA(LPCSTR lpFileName) -{ - PRUnichar wFileName[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, wFileName, MAX_PATH); - return DeleteFileW(wFileName); -} - -static BOOL MoveFileA(LPCSTR from, LPCSTR to) -{ - PRUnichar wFrom[MAX_PATH]; - PRUnichar wTo[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, from, -1, wFrom, MAX_PATH); - MultiByteToWideChar(CP_ACP, 0, to, -1, wTo, MAX_PATH); - return MoveFileW(wFrom, wTo); -} - -static BOOL CreateDirectoryA(LPCSTR lpPathName, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) -{ - PRUnichar wPathName[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, lpPathName, -1, wPathName, MAX_PATH); - return CreateDirectoryW(wPathName, lpSecurityAttributes); -} - -static BOOL RemoveDirectoryA(LPCSTR lpPathName) -{ - PRUnichar wPathName[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, lpPathName, -1, wPathName, MAX_PATH); - return RemoveDirectoryW(wPathName); -} - -static long GetDriveType(const char *lpRootPathName) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return 0; // The drive type cannot be determined. -} - -static DWORD GetFullPathName(const char *lpFileName, - DWORD nBufferLength, - const char *lpBuffer, - const char **lpFilePart) -{ - // needs work dft - DWORD len = strlen(lpFileName); - if (len > nBufferLength) - return len; - - strncpy((char *)lpBuffer, lpFileName, len); - ((char *)lpBuffer)[len] = '\0'; - - if (lpFilePart) { - char *sep = strrchr(lpBuffer, '\\'); - if (sep) { - sep++; // pass the seperator - *lpFilePart = sep; - } else { - *lpFilePart = lpBuffer; - } - } - return len; -} - -static BOOL LockFile(HANDLE hFile, - DWORD dwFileOffsetLow, - DWORD dwFileOffsetHigh, - DWORD nNumberOfBytesToLockLow, - DWORD nNumberOfBytesToLockHigh) -{ - OVERLAPPED overlapped = {0}; - overlapped.Offset = dwFileOffsetLow; - overlapped.OffsetHigh = dwFileOffsetHigh; - return LockFileEx(hFile, - LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, - 0, // reserved - nNumberOfBytesToLockLow, - nNumberOfBytesToLockHigh, &overlapped); -} - -static BOOL UnlockFile(HANDLE hFile, - DWORD dwFileOffsetLow, - DWORD dwFileOffsetHigh, - DWORD nNumberOfBytesToUnlockLow, - DWORD nNumberOfBytesToUnlockHigh) -{ - OVERLAPPED overlapped = {0}; - overlapped.Offset = dwFileOffsetLow; - overlapped.OffsetHigh = dwFileOffsetHigh; - return UnlockFileEx(hFile, - 0, // reserved - nNumberOfBytesToUnlockLow, - nNumberOfBytesToUnlockHigh, &overlapped); -} - -static unsigned char *_mbsdec(const unsigned char *string1, - const unsigned char *string2) -{ - // needs work dft - return NULL; -} - -static unsigned char *_mbsinc(const unsigned char *inCurrent) -{ - // needs work dft - return (unsigned char *)(inCurrent + 1); -} - -#endif - -struct _MDLock _pr_ioq_lock; - -/* - * NSPR-to-NT access right mapping table for files. - */ -static DWORD fileAccessTable[] = { - FILE_GENERIC_READ, - FILE_GENERIC_WRITE, - FILE_GENERIC_EXECUTE -}; - -/* - * NSPR-to-NT access right mapping table for directories. - */ -static DWORD dirAccessTable[] = { - FILE_GENERIC_READ, - FILE_GENERIC_WRITE|FILE_DELETE_CHILD, - FILE_GENERIC_EXECUTE -}; - -/* Windows CE has GetFileAttributesEx. */ -#ifndef WINCE -typedef BOOL (WINAPI *GetFileAttributesExFn)(LPCTSTR, - GET_FILEEX_INFO_LEVELS, - LPVOID); -static GetFileAttributesExFn getFileAttributesEx; -static void InitGetFileInfo(void); -#endif - -static void InitUnicodeSupport(void); - -static PRBool IsPrevCharSlash(const char *str, const char *current); - -void -_PR_MD_INIT_IO() -{ - WORD WSAVersion = 0x0101; - WSADATA WSAData; - int err; - - err = WSAStartup( WSAVersion, &WSAData ); - PR_ASSERT(0 == err); - -#ifdef DEBUG - /* Doublecheck _pr_filetime_offset's hard-coded value is correct. */ - { - SYSTEMTIME systime; - union { - PRTime prt; - FILETIME ft; - } filetime; - BOOL rv; - - systime.wYear = 1970; - systime.wMonth = 1; - /* wDayOfWeek is ignored */ - systime.wDay = 1; - systime.wHour = 0; - systime.wMinute = 0; - systime.wSecond = 0; - systime.wMilliseconds = 0; - - rv = SystemTimeToFileTime(&systime, &filetime.ft); - PR_ASSERT(0 != rv); - PR_ASSERT(filetime.prt == _pr_filetime_offset); - } -#endif /* DEBUG */ - - _PR_NT_InitSids(); - -#ifndef WINCE - InitGetFileInfo(); -#endif - - InitUnicodeSupport(); - - _PR_MD_InitSockets(); -} - -PRStatus -_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) -{ - DWORD rv; - - PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? - INFINITE : PR_IntervalToMilliseconds(ticks); - rv = WaitForSingleObject(thread->md.blocked_sema, msecs); - switch(rv) - { - case WAIT_OBJECT_0: - return PR_SUCCESS; - break; - case WAIT_TIMEOUT: - _PR_THREAD_LOCK(thread); - if (thread->state == _PR_IO_WAIT) { - ; - } else { - if (thread->wait.cvar != NULL) { - thread->wait.cvar = NULL; - _PR_THREAD_UNLOCK(thread); - } else { - /* The CVAR was notified just as the timeout - * occurred. This led to us being notified twice. - * call WaitForSingleObject() to clear the semaphore. - */ - _PR_THREAD_UNLOCK(thread); - rv = WaitForSingleObject(thread->md.blocked_sema, 0); - PR_ASSERT(rv == WAIT_OBJECT_0); - } - } - return PR_SUCCESS; - break; - default: - return PR_FAILURE; - break; - } -} -PRStatus -_PR_MD_WAKEUP_WAITER(PRThread *thread) -{ - if ( _PR_IS_NATIVE_THREAD(thread) ) - { - if (ReleaseSemaphore(thread->md.blocked_sema, 1, NULL) == FALSE) - return PR_FAILURE; - else - return PR_SUCCESS; - } -} - - -/* --- FILE IO ----------------------------------------------------------- */ -/* - * _PR_MD_OPEN() -- Open a file - * - * returns: a fileHandle - * - * The NSPR open flags (osflags) are translated into flags for Win95 - * - * Mode seems to be passed in as a unix style file permissions argument - * as in 0666, in the case of opening the logFile. - * - */ -PROsfd -_PR_MD_OPEN(const char *name, PRIntn osflags, int mode) -{ - HANDLE file; - PRInt32 access = 0; - PRInt32 flags = 0; - PRInt32 flag6 = 0; - - if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; - - if (osflags & PR_RDONLY || osflags & PR_RDWR) - access |= GENERIC_READ; - if (osflags & PR_WRONLY || osflags & PR_RDWR) - access |= GENERIC_WRITE; - - if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) - flags = CREATE_NEW; - else if (osflags & PR_CREATE_FILE) { - if (osflags & PR_TRUNCATE) - flags = CREATE_ALWAYS; - else - flags = OPEN_ALWAYS; - } else { - if (osflags & PR_TRUNCATE) - flags = TRUNCATE_EXISTING; - else - flags = OPEN_EXISTING; - } - - file = CreateFileA(name, - access, - FILE_SHARE_READ|FILE_SHARE_WRITE, - NULL, - flags, - flag6, - NULL); - if (file == INVALID_HANDLE_VALUE) { - _PR_MD_MAP_OPEN_ERROR(GetLastError()); - return -1; - } - - return (PROsfd)file; -} - -PROsfd -_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, int mode) -{ - HANDLE file; - PRInt32 access = 0; - PRInt32 flags = 0; - PRInt32 flag6 = 0; - SECURITY_ATTRIBUTES sa; - LPSECURITY_ATTRIBUTES lpSA = NULL; - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - - if (osflags & PR_CREATE_FILE) { - if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable, - &pSD, &pACL) == PR_SUCCESS) { - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = FALSE; - lpSA = &sa; - } - } - - if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; - - if (osflags & PR_RDONLY || osflags & PR_RDWR) - access |= GENERIC_READ; - if (osflags & PR_WRONLY || osflags & PR_RDWR) - access |= GENERIC_WRITE; - - if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) - flags = CREATE_NEW; - else if (osflags & PR_CREATE_FILE) { - if (osflags & PR_TRUNCATE) - flags = CREATE_ALWAYS; - else - flags = OPEN_ALWAYS; - } else { - if (osflags & PR_TRUNCATE) - flags = TRUNCATE_EXISTING; - else - flags = OPEN_EXISTING; - } - - file = CreateFileA(name, - access, - FILE_SHARE_READ|FILE_SHARE_WRITE, - lpSA, - flags, - flag6, - NULL); - if (lpSA != NULL) { - _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); - } - if (file == INVALID_HANDLE_VALUE) { - _PR_MD_MAP_OPEN_ERROR(GetLastError()); - return -1; - } - - return (PROsfd)file; -} - -PRInt32 -_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len) -{ - PRUint32 bytes; - int rv, err; - - rv = ReadFile((HANDLE)fd->secret->md.osfd, - (LPVOID)buf, - len, - &bytes, - NULL); - - if (rv == 0) - { - err = GetLastError(); - /* ERROR_HANDLE_EOF can only be returned by async io */ - PR_ASSERT(err != ERROR_HANDLE_EOF); - if (err == ERROR_BROKEN_PIPE) - return 0; - else { - _PR_MD_MAP_READ_ERROR(err); - return -1; - } - } - return bytes; -} - -PRInt32 -_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len) -{ - PROsfd f = fd->secret->md.osfd; - PRInt32 bytes; - int rv; - - rv = WriteFile((HANDLE)f, - buf, - len, - &bytes, - NULL ); - - if (rv == 0) - { - _PR_MD_MAP_WRITE_ERROR(GetLastError()); - return -1; - } - return bytes; -} /* --- end _PR_MD_WRITE() --- */ - -PROffset32 -_PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) -{ - DWORD moveMethod; - PROffset32 rv; - - switch (whence) { - case PR_SEEK_SET: - moveMethod = FILE_BEGIN; - break; - case PR_SEEK_CUR: - moveMethod = FILE_CURRENT; - break; - case PR_SEEK_END: - moveMethod = FILE_END; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - - rv = SetFilePointer((HANDLE)fd->secret->md.osfd, offset, NULL, moveMethod); - - /* - * If the lpDistanceToMoveHigh argument (third argument) is - * NULL, SetFilePointer returns 0xffffffff on failure. - */ - if (-1 == rv) { - _PR_MD_MAP_LSEEK_ERROR(GetLastError()); - } - return rv; -} - -PROffset64 -_PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) -{ - DWORD moveMethod; - LARGE_INTEGER li; - DWORD err; - - switch (whence) { - case PR_SEEK_SET: - moveMethod = FILE_BEGIN; - break; - case PR_SEEK_CUR: - moveMethod = FILE_CURRENT; - break; - case PR_SEEK_END: - moveMethod = FILE_END; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - - li.QuadPart = offset; - li.LowPart = SetFilePointer((HANDLE)fd->secret->md.osfd, - li.LowPart, &li.HighPart, moveMethod); - - if (0xffffffff == li.LowPart && (err = GetLastError()) != NO_ERROR) { - _PR_MD_MAP_LSEEK_ERROR(err); - li.QuadPart = -1; - } - return li.QuadPart; -} - -/* - * This is documented to succeed on read-only files, but Win32's - * FlushFileBuffers functions fails with "access denied" in such a - * case. So we only signal an error if the error is *not* "access - * denied". - */ -PRInt32 -_PR_MD_FSYNC(PRFileDesc *fd) -{ - /* - * From the documentation: - * - * On Windows NT, the function FlushFileBuffers fails if hFile - * is a handle to console output. That is because console - * output is not buffered. The function returns FALSE, and - * GetLastError returns ERROR_INVALID_HANDLE. - * - * On the other hand, on Win95, it returns without error. I cannot - * assume that 0, 1, and 2 are console, because if someone closes - * System.out and then opens a file, they might get file descriptor - * 1. An error on *that* version of 1 should be reported, whereas - * an error on System.out (which was the original 1) should be - * ignored. So I use isatty() to ensure that such an error was due - * to this bogosity, and if it was, I ignore the error. - */ - - BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd); - - if (!ok) { - DWORD err = GetLastError(); - if (err != ERROR_ACCESS_DENIED) { // from winerror.h - _PR_MD_MAP_FSYNC_ERROR(err); - return -1; - } - } - return 0; -} - -PRInt32 -_MD_CloseFile(PROsfd osfd) -{ - PRInt32 rv; - - rv = (CloseHandle((HANDLE)osfd))?0:-1; - if (rv == -1) - _PR_MD_MAP_CLOSE_ERROR(GetLastError()); - return rv; -} - - -/* --- DIR IO ------------------------------------------------------------ */ -#define GetFileFromDIR(d) (d)->d_entry.cFileName -#define FileIsHidden(d) ((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) - -static void FlipSlashes(char *cp, size_t len) -{ - while (len-- > 0) { - if (cp[0] == '/') { - cp[0] = PR_DIRECTORY_SEPARATOR; - } - cp = _mbsinc(cp); - } -} /* end FlipSlashes() */ - - -/* -** -** Local implementations of standard Unix RTL functions which are not provided -** by the VC RTL. -** -*/ - -PRInt32 -_PR_MD_CLOSE_DIR(_MDDir *d) -{ - if ( d ) { - if (FindClose(d->d_hdl)) { - d->magic = (PRUint32)-1; - return 0; - } else { - _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError()); - return -1; - } - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; -} - - -PRStatus -_PR_MD_OPEN_DIR(_MDDir *d, const char *name) -{ - char filename[ MAX_PATH ]; - size_t len; - - len = strlen(name); - /* Need 5 bytes for \*.* and the trailing null byte. */ - if (len + 5 > MAX_PATH) { - PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); - return PR_FAILURE; - } - strcpy(filename, name); - - /* - * If 'name' ends in a slash or backslash, do not append - * another backslash. - */ - if (IsPrevCharSlash(filename, filename + len)) { - len--; - } - strcpy(&filename[len], "\\*.*"); - FlipSlashes( filename, strlen(filename) ); - - d->d_hdl = FindFirstFileA( filename, &(d->d_entry) ); - if ( d->d_hdl == INVALID_HANDLE_VALUE ) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return PR_FAILURE; - } - d->firstEntry = PR_TRUE; - d->magic = _MD_MAGIC_DIR; - return PR_SUCCESS; -} - -char * -_PR_MD_READ_DIR(_MDDir *d, PRIntn flags) -{ - PRInt32 err; - BOOL rv; - char *fileName; - - if ( d ) { - while (1) { - if (d->firstEntry) { - d->firstEntry = PR_FALSE; - rv = 1; - } else { - rv = FindNextFileA(d->d_hdl, &(d->d_entry)); - } - if (rv == 0) { - break; - } - fileName = GetFileFromDIR(d); - if ( (flags & PR_SKIP_DOT) && - (fileName[0] == '.') && (fileName[1] == '\0')) - continue; - if ( (flags & PR_SKIP_DOT_DOT) && - (fileName[0] == '.') && (fileName[1] == '.') && - (fileName[2] == '\0')) - continue; - if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d)) - continue; - return fileName; - } - err = GetLastError(); - PR_ASSERT(NO_ERROR != err); - _PR_MD_MAP_READDIR_ERROR(err); - return NULL; - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; -} - -PRInt32 -_PR_MD_DELETE(const char *name) -{ - if (DeleteFileA(name)) { - return 0; - } else { - _PR_MD_MAP_DELETE_ERROR(GetLastError()); - return -1; - } -} - -void -_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm) -{ - PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime)); - CopyMemory(prtm, filetime, sizeof(PRTime)); -#if defined(__MINGW32__) - *prtm = (*prtm - _pr_filetime_offset) / 10LL; -#else - *prtm = (*prtm - _pr_filetime_offset) / 10i64; -#endif - -#ifdef DEBUG - /* Doublecheck our calculation. */ - { - SYSTEMTIME systime; - PRExplodedTime etm; - PRTime cmp; /* for comparison */ - BOOL rv; - - rv = FileTimeToSystemTime(filetime, &systime); - PR_ASSERT(0 != rv); - - /* - * PR_ImplodeTime ignores wday and yday. - */ - etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC; - etm.tm_sec = systime.wSecond; - etm.tm_min = systime.wMinute; - etm.tm_hour = systime.wHour; - etm.tm_mday = systime.wDay; - etm.tm_month = systime.wMonth - 1; - etm.tm_year = systime.wYear; - /* - * It is not well-documented what time zone the FILETIME's - * are in. WIN32_FIND_DATA is documented to be in UTC (GMT). - * But BY_HANDLE_FILE_INFORMATION is unclear about this. - * By our best judgement, we assume that FILETIME is in UTC. - */ - etm.tm_params.tp_gmt_offset = 0; - etm.tm_params.tp_dst_offset = 0; - cmp = PR_ImplodeTime(&etm); - - /* - * SYSTEMTIME is in milliseconds precision, so we convert PRTime's - * microseconds to milliseconds before doing the comparison. - */ - PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC)); - } -#endif /* DEBUG */ -} - -PRInt32 -_PR_MD_STAT(const char *fn, struct stat *info) -{ -#ifdef WINCE - // needs work. dft - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; -#else - PRInt32 rv; - - rv = _stat(fn, (struct _stat *)info); - if (-1 == rv) { - /* - * Check for MSVC runtime library _stat() bug. - * (It's really a bug in FindFirstFile().) - * If a pathname ends in a backslash or slash, - * e.g., c:\temp\ or c:/temp/, _stat() will fail. - * Note: a pathname ending in a slash (e.g., c:/temp/) - * can be handled by _stat() on NT but not on Win95. - * - * We remove the backslash or slash at the end and - * try again. - */ - - size_t len = strlen(fn); - if (len > 0 && len <= _MAX_PATH - && IsPrevCharSlash(fn, fn + len)) { - char newfn[_MAX_PATH + 1]; - - strcpy(newfn, fn); - newfn[len - 1] = '\0'; - rv = _stat(newfn, (struct _stat *)info); - } - } - - if (-1 == rv) { - _PR_MD_MAP_STAT_ERROR(errno); - } - return rv; -#endif -} - -#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\') - -static PRBool -IsPrevCharSlash(const char *str, const char *current) -{ - const char *prev; - - if (str >= current) - return PR_FALSE; - prev = _mbsdec(str, current); - return (prev == current - 1) && _PR_IS_SLASH(*prev); -} - -/* - * IsRootDirectory -- - * - * Return PR_TRUE if the pathname 'fn' is a valid root directory, - * else return PR_FALSE. The char buffer pointed to by 'fn' must - * be writable. During the execution of this function, the contents - * of the buffer pointed to by 'fn' may be modified, but on return - * the original contents will be restored. 'buflen' is the size of - * the buffer pointed to by 'fn'. - * - * Root directories come in three formats: - * 1. / or \, meaning the root directory of the current drive. - * 2. C:/ or C:\, where C is a drive letter. - * 3. \\\\ or - * \\\, meaning the root directory - * of a UNC (Universal Naming Convention) name. - */ - -static PRBool -IsRootDirectory(char *fn, size_t buflen) -{ - char *p; - PRBool slashAdded = PR_FALSE; - PRBool rv = PR_FALSE; - - if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') { - return PR_TRUE; - } - - if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2]) - && fn[3] == '\0') { - rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; - return rv; - } - - /* The UNC root directory */ - - if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) { - /* The 'server' part should have at least one character. */ - p = &fn[2]; - if (*p == '\0' || _PR_IS_SLASH(*p)) { - return PR_FALSE; - } - - /* look for the next slash */ - do { - p = _mbsinc(p); - } while (*p != '\0' && !_PR_IS_SLASH(*p)); - if (*p == '\0') { - return PR_FALSE; - } - - /* The 'share' part should have at least one character. */ - p++; - if (*p == '\0' || _PR_IS_SLASH(*p)) { - return PR_FALSE; - } - - /* look for the final slash */ - do { - p = _mbsinc(p); - } while (*p != '\0' && !_PR_IS_SLASH(*p)); - if (_PR_IS_SLASH(*p) && p[1] != '\0') { - return PR_FALSE; - } - if (*p == '\0') { - /* - * GetDriveType() doesn't work correctly if the - * path is of the form \\server\share, so we add - * a final slash temporarily. - */ - if ((p + 1) < (fn + buflen)) { - *p++ = '\\'; - *p = '\0'; - slashAdded = PR_TRUE; - } else { - return PR_FALSE; /* name too long */ - } - } - rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; - /* restore the 'fn' buffer */ - if (slashAdded) { - *--p = '\0'; - } - } - return rv; -} - -#ifndef WINCE -/* - * InitGetFileInfo -- - * - * Called during IO init. Checks for the existence of the system function - * GetFileAttributeEx, which when available is used in GETFILEINFO calls. - * If the routine exists, then the address of the routine is stored in the - * variable getFileAttributesEx, which will be used to call the routine. - */ -static void InitGetFileInfo(void) -{ - HMODULE module; - module = GetModuleHandle("Kernel32.dll"); - if (!module) { - PR_LOG(_pr_io_lm, PR_LOG_DEBUG, - ("InitGetFileInfo: GetModuleHandle() failed: %d", - GetLastError())); - return; - } - - getFileAttributesEx = (GetFileAttributesExFn) - GetProcAddress(module, "GetFileAttributesExA"); -} - -/* - * If GetFileAttributeEx doesn't exist, we call FindFirstFile as a - * fallback. - */ -static BOOL -GetFileAttributesExFB(const char *fn, WIN32_FIND_DATA *findFileData) -{ - HANDLE hFindFile; - - /* - * FindFirstFile() expands wildcard characters. So - * we make sure the pathname contains no wildcard. - */ - if (NULL != _mbspbrk(fn, "?*")) { - SetLastError(ERROR_INVALID_NAME); - return FALSE; - } - - hFindFile = FindFirstFile(fn, findFileData); - if (INVALID_HANDLE_VALUE == hFindFile) { - DWORD len; - char *filePart; - char pathbuf[MAX_PATH + 1]; - - /* - * FindFirstFile() does not work correctly on root directories. - * It also doesn't work correctly on a pathname that ends in a - * slash. So we first check to see if the pathname specifies a - * root directory. If not, and if the pathname ends in a slash, - * we remove the final slash and try again. - */ - - /* - * If the pathname does not contain ., \, and /, it cannot be - * a root directory or a pathname that ends in a slash. - */ - if (NULL == _mbspbrk(fn, ".\\/")) { - return FALSE; - } - len = GetFullPathName(fn, sizeof(pathbuf), pathbuf, - &filePart); - if (0 == len) { - return FALSE; - } - if (len > sizeof(pathbuf)) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - return FALSE; - } - if (IsRootDirectory(pathbuf, sizeof(pathbuf))) { - findFileData->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; - /* The file size doesn't have a meaning for directories. */ - findFileData->nFileSizeHigh = 0; - findFileData->nFileSizeLow = 0; - /* - * For a directory, these timestamps all specify when the - * directory is created. The creation time doesn't make - * sense for root directories, so we set it to (NSPR) time 0. - */ - memcpy(&findFileData->ftCreationTime, &_pr_filetime_offset, 8); - findFileData->ftLastAccessTime = findFileData->ftCreationTime; - findFileData->ftLastWriteTime = findFileData->ftCreationTime; - return TRUE; - } - if (!IsPrevCharSlash(pathbuf, pathbuf + len)) { - return FALSE; - } else { - pathbuf[len - 1] = '\0'; - hFindFile = FindFirstFile(pathbuf, findFileData); - if (INVALID_HANDLE_VALUE == hFindFile) { - return FALSE; - } - } - } - - FindClose(hFindFile); - return TRUE; -} -#endif - -PRInt32 -_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) -{ -#ifdef WINCE - WIN32_FILE_ATTRIBUTE_DATA findFileData; -#else - WIN32_FIND_DATA findFileData; -#endif - BOOL rv; - - if (NULL == fn || '\0' == *fn) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - -#ifdef WINCE - rv = GetFileAttributesExA(fn, GetFileExInfoStandard, &findFileData); -#else - /* GetFileAttributesEx is supported on Win 2K and up. */ - if (getFileAttributesEx) { - rv = getFileAttributesEx(fn, GetFileExInfoStandard, &findFileData); - } else { - rv = GetFileAttributesExFB(fn, &findFileData); - } -#endif - if (!rv) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return -1; - } - - if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - info->type = PR_FILE_DIRECTORY; - } else { - info->type = PR_FILE_FILE; - } - - info->size = findFileData.nFileSizeHigh; - info->size = (info->size << 32) + findFileData.nFileSizeLow; - - _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime); - - if (0 == findFileData.ftCreationTime.dwLowDateTime && - 0 == findFileData.ftCreationTime.dwHighDateTime) { - info->creationTime = info->modifyTime; - } else { - _PR_FileTimeToPRTime(&findFileData.ftCreationTime, - &info->creationTime); - } - - return 0; -} - -PRInt32 -_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info) -{ - PRFileInfo64 info64; - PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64); - if (0 == rv) - { - info->type = info64.type; - info->size = (PRUint32) info64.size; - info->modifyTime = info64.modifyTime; - info->creationTime = info64.creationTime; - } - return rv; -} - -PRInt32 -_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info) -{ - int rv; - - BY_HANDLE_FILE_INFORMATION hinfo; - - rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo); - if (rv == FALSE) { - _PR_MD_MAP_FSTAT_ERROR(GetLastError()); - return -1; - } - - if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - info->type = PR_FILE_DIRECTORY; - else - info->type = PR_FILE_FILE; - - info->size = hinfo.nFileSizeHigh; - info->size = (info->size << 32) + hinfo.nFileSizeLow; - - _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) ); - _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) ); - - return 0; -} - -PRInt32 -_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) -{ - PRFileInfo64 info64; - int rv = _PR_MD_GETOPENFILEINFO64(fd, &info64); - if (0 == rv) - { - info->type = info64.type; - info->modifyTime = info64.modifyTime; - info->creationTime = info64.creationTime; - LL_L2I(info->size, info64.size); - } - return rv; -} - -PRStatus -_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) -{ -#ifdef WINCE - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -#else - BOOL rv; - - /* - * The SetHandleInformation function fails with the - * ERROR_CALL_NOT_IMPLEMENTED error on Win95. - */ - rv = SetHandleInformation( - (HANDLE)fd->secret->md.osfd, - HANDLE_FLAG_INHERIT, - inheritable ? HANDLE_FLAG_INHERIT : 0); - if (0 == rv) { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - return PR_FAILURE; - } - return PR_SUCCESS; -#endif -} - -void -_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported) -{ - if (imported) { - fd->secret->inheritable = _PR_TRI_UNKNOWN; - } else { - fd->secret->inheritable = _PR_TRI_FALSE; - } -} - -void -_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd) -{ -#ifdef WINCE - fd->secret->inheritable = _PR_TRI_FALSE; -#else - DWORD flags; - - PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); - if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) { - if (flags & HANDLE_FLAG_INHERIT) { - fd->secret->inheritable = _PR_TRI_TRUE; - } else { - fd->secret->inheritable = _PR_TRI_FALSE; - } - } -#endif -} - -PRInt32 -_PR_MD_RENAME(const char *from, const char *to) -{ - /* Does this work with dot-relative pathnames? */ - if (MoveFileA(from, to)) { - return 0; - } else { - _PR_MD_MAP_RENAME_ERROR(GetLastError()); - return -1; - } -} - -PRInt32 -_PR_MD_ACCESS(const char *name, PRAccessHow how) -{ -#ifdef WINCE - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; -#else -PRInt32 rv; - switch (how) { - case PR_ACCESS_WRITE_OK: - rv = _access(name, 02); - break; - case PR_ACCESS_READ_OK: - rv = _access(name, 04); - break; - case PR_ACCESS_EXISTS: - return _access(name, 00); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - if (rv < 0) - _PR_MD_MAP_ACCESS_ERROR(errno); - return rv; -#endif -} - -PRInt32 -_PR_MD_MKDIR(const char *name, PRIntn mode) -{ - /* XXXMB - how to translate the "mode"??? */ - if (CreateDirectoryA(name, NULL)) { - return 0; - } else { - _PR_MD_MAP_MKDIR_ERROR(GetLastError()); - return -1; - } -} - -PRInt32 -_PR_MD_MAKE_DIR(const char *name, PRIntn mode) -{ - BOOL rv; - SECURITY_ATTRIBUTES sa; - LPSECURITY_ATTRIBUTES lpSA = NULL; - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - - if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable, - &pSD, &pACL) == PR_SUCCESS) { - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = FALSE; - lpSA = &sa; - } - rv = CreateDirectoryA(name, lpSA); - if (lpSA != NULL) { - _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); - } - if (rv) { - return 0; - } else { - _PR_MD_MAP_MKDIR_ERROR(GetLastError()); - return -1; - } -} - -PRInt32 -_PR_MD_RMDIR(const char *name) -{ - if (RemoveDirectoryA(name)) { - return 0; - } else { - _PR_MD_MAP_RMDIR_ERROR(GetLastError()); - return -1; - } -} - -PRStatus -_PR_MD_LOCKFILE(PROsfd f) -{ - PRStatus rc = PR_SUCCESS; - DWORD rv; - - rv = LockFile( (HANDLE)f, - 0l, 0l, - 0x0l, 0xffffffffl ); - if ( rv == 0 ) { - DWORD rc = GetLastError(); - PR_LOG( _pr_io_lm, PR_LOG_ERROR, - ("_PR_MD_LOCKFILE() failed. Error: %d", rc )); - rc = PR_FAILURE; - } - - return rc; -} /* end _PR_MD_LOCKFILE() */ - -PRStatus -_PR_MD_TLOCKFILE(PROsfd f) -{ - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return PR_FAILURE; -} /* end _PR_MD_TLOCKFILE() */ - - -PRStatus -_PR_MD_UNLOCKFILE(PROsfd f) -{ - PRInt32 rv; - - rv = UnlockFile( (HANDLE) f, - 0l, 0l, - 0x0l, 0xffffffffl ); - - if ( rv ) - { - return PR_SUCCESS; - } - else - { - _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); - return PR_FAILURE; - } -} /* end _PR_MD_UNLOCKFILE() */ - -PRInt32 -_PR_MD_PIPEAVAILABLE(PRFileDesc *fd) -{ - if (NULL == fd) - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; -} - -#ifdef MOZ_UNICODE - -typedef HANDLE (WINAPI *CreateFileWFn) (LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); -static CreateFileWFn createFileW = CreateFileW; -typedef HANDLE (WINAPI *FindFirstFileWFn) (LPCWSTR, LPWIN32_FIND_DATAW); -static FindFirstFileWFn findFirstFileW = FindFirstFileW; -typedef BOOL (WINAPI *FindNextFileWFn) (HANDLE, LPWIN32_FIND_DATAW); -static FindNextFileWFn findNextFileW = FindNextFileW; -typedef DWORD (WINAPI *GetFullPathNameWFn) (LPCWSTR, DWORD, LPWSTR, LPWSTR *); -static GetFullPathNameWFn getFullPathNameW = GetFullPathNameW; -typedef UINT (WINAPI *GetDriveTypeWFn) (LPCWSTR); -static GetDriveTypeWFn getDriveTypeW = GetDriveTypeW; - -#endif /* MOZ_UNICODE */ - -PRBool _pr_useUnicode = PR_FALSE; - -static void InitUnicodeSupport(void) -{ -#ifdef WINCE - /* The A functions don't even exist in Windows Mobile. */ - _pr_useUnicode = PR_TRUE; -#else - /* - * The W functions exist on Win9x as stubs that fail with the - * ERROR_CALL_NOT_IMPLEMENTED error. We plan to emulate the - * MSLU W functions on Win9x in the future. - */ - - /* Find out if we are running on a Unicode enabled version of Windows */ - OSVERSIONINFOA osvi = {0}; - - osvi.dwOSVersionInfoSize = sizeof(osvi); - if (GetVersionExA(&osvi)) { - _pr_useUnicode = (osvi.dwPlatformId >= VER_PLATFORM_WIN32_NT); - } else { - _pr_useUnicode = PR_FALSE; - } -#ifdef DEBUG - /* - * In debug builds, allow explicit use of ANSI methods to simulate - * a Win9x environment for testing purposes. - */ - if (getenv("WINAPI_USE_ANSI")) - _pr_useUnicode = PR_FALSE; -#endif -#endif -} - -#ifdef MOZ_UNICODE - -/* ================ UTF16 Interfaces ================================ */ -static void FlipSlashesW(PRUnichar *cp, size_t len) -{ - while (len-- > 0) { - if (cp[0] == L'/') { - cp[0] = L'\\'; - } - cp++; - } -} /* end FlipSlashesW() */ - -PROsfd -_PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, int mode) -{ - HANDLE file; - PRInt32 access = 0; - PRInt32 flags = 0; - PRInt32 flag6 = 0; - SECURITY_ATTRIBUTES sa; - LPSECURITY_ATTRIBUTES lpSA = NULL; - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - - if (osflags & PR_CREATE_FILE) { - if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable, - &pSD, &pACL) == PR_SUCCESS) { - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = FALSE; - lpSA = &sa; - } - } - - if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; - - if (osflags & PR_RDONLY || osflags & PR_RDWR) - access |= GENERIC_READ; - if (osflags & PR_WRONLY || osflags & PR_RDWR) - access |= GENERIC_WRITE; - - if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) - flags = CREATE_NEW; - else if (osflags & PR_CREATE_FILE) { - if (osflags & PR_TRUNCATE) - flags = CREATE_ALWAYS; - else - flags = OPEN_ALWAYS; - } else { - if (osflags & PR_TRUNCATE) - flags = TRUNCATE_EXISTING; - else - flags = OPEN_EXISTING; - } - - file = createFileW(name, - access, - FILE_SHARE_READ|FILE_SHARE_WRITE, - lpSA, - flags, - flag6, - NULL); - if (lpSA != NULL) { - _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); - } - if (file == INVALID_HANDLE_VALUE) { - _PR_MD_MAP_OPEN_ERROR(GetLastError()); - return -1; - } - - return (PROsfd)file; -} - -PRStatus -_PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *d, const PRUnichar *name) -{ - PRUnichar filename[ MAX_PATH ]; - int len; - - len = wcslen(name); - /* Need 5 bytes for \*.* and the trailing null byte. */ - if (len + 5 > MAX_PATH) { - PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); - return PR_FAILURE; - } - wcscpy(filename, name); - - /* - * If 'name' ends in a slash or backslash, do not append - * another backslash. - */ - if (filename[len - 1] == L'/' || filename[len - 1] == L'\\') { - len--; - } - wcscpy(&filename[len], L"\\*.*"); - FlipSlashesW( filename, wcslen(filename) ); - - d->d_hdl = findFirstFileW( filename, &(d->d_entry) ); - if ( d->d_hdl == INVALID_HANDLE_VALUE ) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return PR_FAILURE; - } - d->firstEntry = PR_TRUE; - d->magic = _MD_MAGIC_DIR; - return PR_SUCCESS; -} - -PRUnichar * -_PR_MD_READ_DIR_UTF16(_MDDirUTF16 *d, PRIntn flags) -{ - PRInt32 err; - BOOL rv; - PRUnichar *fileName; - - if ( d ) { - while (1) { - if (d->firstEntry) { - d->firstEntry = PR_FALSE; - rv = 1; - } else { - rv = findNextFileW(d->d_hdl, &(d->d_entry)); - } - if (rv == 0) { - break; - } - fileName = GetFileFromDIR(d); - if ( (flags & PR_SKIP_DOT) && - (fileName[0] == L'.') && (fileName[1] == L'\0')) - continue; - if ( (flags & PR_SKIP_DOT_DOT) && - (fileName[0] == L'.') && (fileName[1] == L'.') && - (fileName[2] == L'\0')) - continue; - if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d)) - continue; - return fileName; - } - err = GetLastError(); - PR_ASSERT(NO_ERROR != err); - _PR_MD_MAP_READDIR_ERROR(err); - return NULL; - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; -} - -PRInt32 -_PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *d) -{ - if ( d ) { - if (FindClose(d->d_hdl)) { - d->magic = (PRUint32)-1; - return 0; - } else { - _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError()); - return -1; - } - } - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; -} - -#define _PR_IS_W_SLASH(ch) ((ch) == L'/' || (ch) == L'\\') - -/* - * IsRootDirectoryW -- - * - * Return PR_TRUE if the pathname 'fn' is a valid root directory, - * else return PR_FALSE. The PRUnichar buffer pointed to by 'fn' must - * be writable. During the execution of this function, the contents - * of the buffer pointed to by 'fn' may be modified, but on return - * the original contents will be restored. 'buflen' is the size of - * the buffer pointed to by 'fn', in PRUnichars. - * - * Root directories come in three formats: - * 1. / or \, meaning the root directory of the current drive. - * 2. C:/ or C:\, where C is a drive letter. - * 3. \\\\ or - * \\\, meaning the root directory - * of a UNC (Universal Naming Convention) name. - */ - -static PRBool -IsRootDirectoryW(PRUnichar *fn, size_t buflen) -{ - PRUnichar *p; - PRBool slashAdded = PR_FALSE; - PRBool rv = PR_FALSE; - - if (_PR_IS_W_SLASH(fn[0]) && fn[1] == L'\0') { - return PR_TRUE; - } - - if (iswalpha(fn[0]) && fn[1] == L':' && _PR_IS_W_SLASH(fn[2]) - && fn[3] == L'\0') { - rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE; - return rv; - } - - /* The UNC root directory */ - - if (_PR_IS_W_SLASH(fn[0]) && _PR_IS_W_SLASH(fn[1])) { - /* The 'server' part should have at least one character. */ - p = &fn[2]; - if (*p == L'\0' || _PR_IS_W_SLASH(*p)) { - return PR_FALSE; - } - - /* look for the next slash */ - do { - p++; - } while (*p != L'\0' && !_PR_IS_W_SLASH(*p)); - if (*p == L'\0') { - return PR_FALSE; - } - - /* The 'share' part should have at least one character. */ - p++; - if (*p == L'\0' || _PR_IS_W_SLASH(*p)) { - return PR_FALSE; - } - - /* look for the final slash */ - do { - p++; - } while (*p != L'\0' && !_PR_IS_W_SLASH(*p)); - if (_PR_IS_W_SLASH(*p) && p[1] != L'\0') { - return PR_FALSE; - } - if (*p == L'\0') { - /* - * GetDriveType() doesn't work correctly if the - * path is of the form \\server\share, so we add - * a final slash temporarily. - */ - if ((p + 1) < (fn + buflen)) { - *p++ = L'\\'; - *p = L'\0'; - slashAdded = PR_TRUE; - } else { - return PR_FALSE; /* name too long */ - } - } - rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE; - /* restore the 'fn' buffer */ - if (slashAdded) { - *--p = L'\0'; - } - } - return rv; -} - -PRInt32 -_PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info) -{ - HANDLE hFindFile; - WIN32_FIND_DATAW findFileData; - PRUnichar pathbuf[MAX_PATH + 1]; - - if (NULL == fn || L'\0' == *fn) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } - - /* - * FindFirstFile() expands wildcard characters. So - * we make sure the pathname contains no wildcard. - */ - if (NULL != wcspbrk(fn, L"?*")) { - PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0); - return -1; - } - - hFindFile = findFirstFileW(fn, &findFileData); - if (INVALID_HANDLE_VALUE == hFindFile) { - DWORD len; - PRUnichar *filePart; - - /* - * FindFirstFile() does not work correctly on root directories. - * It also doesn't work correctly on a pathname that ends in a - * slash. So we first check to see if the pathname specifies a - * root directory. If not, and if the pathname ends in a slash, - * we remove the final slash and try again. - */ - - /* - * If the pathname does not contain ., \, and /, it cannot be - * a root directory or a pathname that ends in a slash. - */ - if (NULL == wcspbrk(fn, L".\\/")) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return -1; - } - len = getFullPathNameW(fn, sizeof(pathbuf)/sizeof(pathbuf[0]), pathbuf, - &filePart); - if (0 == len) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return -1; - } - if (len > sizeof(pathbuf)/sizeof(pathbuf[0])) { - PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); - return -1; - } - if (IsRootDirectoryW(pathbuf, sizeof(pathbuf)/sizeof(pathbuf[0]))) { - info->type = PR_FILE_DIRECTORY; - info->size = 0; - /* - * These timestamps don't make sense for root directories. - */ - info->modifyTime = 0; - info->creationTime = 0; - return 0; - } - if (!_PR_IS_W_SLASH(pathbuf[len - 1])) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return -1; - } else { - pathbuf[len - 1] = L'\0'; - hFindFile = findFirstFileW(pathbuf, &findFileData); - if (INVALID_HANDLE_VALUE == hFindFile) { - _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); - return -1; - } - } - } - - FindClose(hFindFile); - - if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - info->type = PR_FILE_DIRECTORY; - } else { - info->type = PR_FILE_FILE; - } - - info->size = findFileData.nFileSizeHigh; - info->size = (info->size << 32) + findFileData.nFileSizeLow; - - _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime); - - if (0 == findFileData.ftCreationTime.dwLowDateTime && - 0 == findFileData.ftCreationTime.dwHighDateTime) { - info->creationTime = info->modifyTime; - } else { - _PR_FileTimeToPRTime(&findFileData.ftCreationTime, - &info->creationTime); - } - - return 0; -} -/* ================ end of UTF16 Interfaces ================================ */ -#endif /* MOZ_UNICODE */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95sock.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95sock.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95sock.c 2012-03-06 13:14:18.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95sock.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,766 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Win95 Sockets module - * - */ - -#include "primpl.h" - -#define READ_FD 1 -#define WRITE_FD 2 -#define CONNECT_FD 3 - -static PRInt32 socket_io_wait( - PROsfd osfd, - PRInt32 fd_type, - PRIntervalTime timeout); - - -/* --- SOCKET IO --------------------------------------------------------- */ - -/* - * we only want to call WSAIoctl() on Vista and later - * so don't pay for it at build time (and avoid including winsock2.h) - */ - -/* from ws2def.h */ -#define IOC_IN 0x80000000 /* copy in parameters */ -#define IOC_VENDOR 0x18000000 -#define _WSAIOW(x,y) (IOC_IN|(x)|(y)) -/* from MSWSockDef.h */ -#define SIO_SET_COMPATIBILITY_MODE _WSAIOW(IOC_VENDOR,300) - -typedef enum _WSA_COMPATIBILITY_BEHAVIOR_ID { - WsaBehaviorAll = 0, - WsaBehaviorReceiveBuffering, - WsaBehaviorAutoTuning -} WSA_COMPATIBILITY_BEHAVIOR_ID, *PWSA_COMPATIBILITY_BEHAVIOR_ID; - -/* from sdkddkver.h */ -#define NTDDI_WIN6 0x06000000 /* Windows Vista */ - -/* from winsock2.h */ -#define WSAEVENT HANDLE - -#define WSAOVERLAPPED OVERLAPPED -typedef struct _OVERLAPPED * LPWSAOVERLAPPED; - -typedef void (CALLBACK * LPWSAOVERLAPPED_COMPLETION_ROUTINE)( - IN DWORD dwError, - IN DWORD cbTransferred, - IN LPWSAOVERLAPPED lpOverlapped, - IN DWORD dwFlags -); - -typedef int (__stdcall * WSAIOCTLPROC) ( - SOCKET s, - DWORD dwIoControlCode, - LPVOID lpvInBuffer, - DWORD cbInBuffer, - LPVOID lpvOutBuffer, - DWORD cbOutBuffer, - LPDWORD lpcbBytesReturned, - LPWSAOVERLAPPED lpOverlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine -); - -typedef struct _WSA_COMPATIBILITY_MODE { - WSA_COMPATIBILITY_BEHAVIOR_ID BehaviorId; - ULONG TargetOsVersion; -} WSA_COMPATIBILITY_MODE, *PWSA_COMPATIBILITY_MODE; - -static HMODULE libWinsock2 = NULL; -static WSAIOCTLPROC wsaioctlProc = NULL; -static PRBool socketSetCompatMode = PR_FALSE; -static PRBool socketFixInet6RcvBuf = PR_FALSE; - -void _PR_MD_InitSockets(void) -{ - OSVERSIONINFO osvi; - - memset(&osvi, 0, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(osvi); - GetVersionEx(&osvi); - - /* if Vista or later... */ - if (osvi.dwMajorVersion >= 6) - { - libWinsock2 = LoadLibraryW(L"Ws2_32.dll"); - if (libWinsock2) - { - wsaioctlProc = (WSAIOCTLPROC)GetProcAddress(libWinsock2, - "WSAIoctl"); - if (wsaioctlProc) - { - socketSetCompatMode = PR_TRUE; - } - } - } - else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) - { - /* if Windows XP (32-bit) */ - socketFixInet6RcvBuf = PR_TRUE; - } -} - -void _PR_MD_CleanupSockets(void) -{ - socketSetCompatMode = PR_FALSE; - wsaioctlProc = NULL; - if (libWinsock2) - { - FreeLibrary(libWinsock2); - libWinsock2 = NULL; - } -} - -PROsfd -_PR_MD_SOCKET(int af, int type, int flags) -{ - SOCKET sock; - u_long one = 1; - - sock = socket(af, type, flags); - - if (sock == INVALID_SOCKET ) - { - _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError()); - return (PROsfd)sock; - } - - /* - ** Make the socket Non-Blocking - */ - if (ioctlsocket( sock, FIONBIO, &one) != 0) - { - PR_SetError(PR_UNKNOWN_ERROR, WSAGetLastError()); - closesocket(sock); - return -1; - } - - if ((af == AF_INET || af == AF_INET6) && - type == SOCK_STREAM && socketSetCompatMode) - { - WSA_COMPATIBILITY_MODE mode; - char dummy[4]; - int ret_dummy; - - mode.BehaviorId = WsaBehaviorAutoTuning; - mode.TargetOsVersion = NTDDI_WIN6; - if (wsaioctlProc(sock, SIO_SET_COMPATIBILITY_MODE, - (char *)&mode, sizeof(mode), - dummy, 4, &ret_dummy, 0, NULL) == SOCKET_ERROR) - { - int err = WSAGetLastError(); - PR_LOG(_pr_io_lm, PR_LOG_DEBUG, ("WSAIoctl() failed with %d", err)); - - /* SIO_SET_COMPATIBILITY_MODE may not be supported. - ** If the call to WSAIoctl() fails with WSAEOPNOTSUPP, - ** don't close the socket. - */ - } - } - - if (af == AF_INET6 && socketFixInet6RcvBuf) - { - int bufsize; - int len = sizeof(bufsize); - int rv; - - /* Windows XP 32-bit returns an error on getpeername() for AF_INET6 - * sockets if the receive buffer size is greater than 65535 before - * the connection is initiated. The default receive buffer size may - * be 128000 so fix it here to always be <= 65535. See bug 513659 - * and IBM DB2 support technote "Receive/Send IPv6 Socket Size - * Problem in Windows XP SP2 & SP3". - */ - rv = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, &len); - if (rv == 0 && bufsize > 65535) - { - bufsize = 65535; - setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, len); - } - } - - return (PROsfd)sock; -} - -/* -** _MD_CloseSocket() -- Close a socket -** -*/ -PRInt32 -_MD_CloseSocket(PROsfd osfd) -{ - PRInt32 rv; - - rv = closesocket((SOCKET) osfd ); - if (rv < 0) - _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError()); - - return rv; -} - -PRInt32 -_MD_SocketAvailable(PRFileDesc *fd) -{ - PRInt32 result; - - if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError()); - return -1; - } - return result; -} - -PROsfd _MD_Accept( - PRFileDesc *fd, - PRNetAddr *raddr, - PRUint32 *rlen, - PRIntervalTime timeout ) -{ - PROsfd osfd = fd->secret->md.osfd; - SOCKET sock; - PRInt32 rv, err; - - while ((sock = accept(osfd, (struct sockaddr *) raddr, rlen)) == -1) - { - err = WSAGetLastError(); - if ((err == WSAEWOULDBLOCK) && (!fd->secret->nonblocking)) - { - if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) - { - break; - } - } - else - { - _PR_MD_MAP_ACCEPT_ERROR(err); - break; - } - } - return(sock); -} /* end _MD_accept() */ - -PRInt32 -_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, - PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv; - int err; - - if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) - { - err = WSAGetLastError(); - if ((!fd->secret->nonblocking) && (err == WSAEWOULDBLOCK)) - { - rv = socket_io_wait(osfd, CONNECT_FD, timeout); - if ( rv < 0 ) - { - return(-1); - } - else - { - PR_ASSERT(rv > 0); - /* it's connected */ - return(0); - } - } - _PR_MD_MAP_CONNECT_ERROR(err); - } - return rv; -} - -PRInt32 -_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) -{ - PRInt32 rv; - - rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen); - - if (rv == SOCKET_ERROR) { - _PR_MD_MAP_BIND_ERROR(WSAGetLastError()); - return -1; - } - - return 0; -} - -PRInt32 -_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog) -{ - PRInt32 rv; - - rv = listen(fd->secret->md.osfd, backlog); - - if (rv == SOCKET_ERROR) { - _PR_MD_MAP_DEFAULT_ERROR(WSAGetLastError()); - return -1; - } - - return 0; -} - -PRInt32 -_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - int osflags; - - if (0 == flags) { - osflags = 0; - } else { - PR_ASSERT(PR_MSG_PEEK == flags); - osflags = MSG_PEEK; - } - while ((rv = recv( osfd, buf, amount, osflags)) == -1) - { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) - { - rv = socket_io_wait(osfd, READ_FD, timeout); - if ( rv < 0 ) - { - return -1; - } - } - else - { - _PR_MD_MAP_RECV_ERROR(err); - break; - } - } /* end while() */ - return(rv); -} - -PRInt32 -_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRInt32 bytesSent = 0; - - while(bytesSent < amount ) - { - while ((rv = send( osfd, buf, amount, 0 )) == -1) - { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) - { - rv = socket_io_wait(osfd, WRITE_FD, timeout); - if ( rv < 0 ) - { - return -1; - } - } - else - { - _PR_MD_MAP_SEND_ERROR(err); - return -1; - } - } - bytesSent += rv; - if (fd->secret->nonblocking) - { - break; - } - if (bytesSent < amount) - { - rv = socket_io_wait(osfd, WRITE_FD, timeout); - if ( rv < 0 ) - { - return -1; - } - } - } - return bytesSent; -} - -PRInt32 -_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - PRInt32 bytesSent = 0; - - while(bytesSent < amount) - { - while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr, - addrlen)) == -1) - { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) - { - rv = socket_io_wait(osfd, WRITE_FD, timeout); - if ( rv < 0 ) - { - return -1; - } - } - else - { - _PR_MD_MAP_SENDTO_ERROR(err); - return -1; - } - } - bytesSent += rv; - if (fd->secret->nonblocking) - { - break; - } - if (bytesSent < amount) - { - rv = socket_io_wait(osfd, WRITE_FD, timeout); - if (rv < 0) - { - return -1; - } - } - } - return bytesSent; -} - -PRInt32 -_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, - PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) -{ - PROsfd osfd = fd->secret->md.osfd; - PRInt32 rv, err; - - while ((rv = recvfrom( osfd, buf, amount, 0, (struct sockaddr *) addr, - addrlen)) == -1) - { - if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) - && (!fd->secret->nonblocking)) - { - rv = socket_io_wait(osfd, READ_FD, timeout); - if ( rv < 0) - { - return -1; - } - } - else - { - _PR_MD_MAP_RECVFROM_ERROR(err); - break; - } - } - return(rv); -} - -PRInt32 -_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) -{ - int index; - int sent = 0; - int rv; - - for (index=0; index < iov_size; index++) - { - rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0, timeout); - if (rv > 0) - sent += rv; - if ( rv != iov[index].iov_len ) - { - if (rv < 0) - { - if (fd->secret->nonblocking - && (PR_GetError() == PR_WOULD_BLOCK_ERROR) - && (sent > 0)) - { - return sent; - } - else - { - return -1; - } - } - /* Only a nonblocking socket can have partial sends */ - PR_ASSERT(fd->secret->nonblocking); - return sent; - } - } - return sent; -} - -PRInt32 -_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how) -{ -PRInt32 rv; - - rv = shutdown(fd->secret->md.osfd, how); - if (rv < 0) - _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError()); - return rv; -} - -PRStatus -_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) -{ - PRInt32 rv; - - rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len); - if (rv==0) { - return PR_SUCCESS; - } else { - _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError()); - return PR_FAILURE; - } -} - -PRStatus -_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) -{ - PRInt32 rv; - - rv = getpeername((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len); - if (rv==0) { - return PR_SUCCESS; - } else { - _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError()); - return PR_FAILURE; - } -} - -PRStatus -_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen) -{ - PRInt32 rv; - - rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); - if (rv==0) { - return PR_SUCCESS; - } else { - _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); - return PR_FAILURE; - } -} - -PRStatus -_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen) -{ - PRInt32 rv; - - rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); - if (rv==0) { - return PR_SUCCESS; - } else { - _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError()); - return PR_FAILURE; - } -} - -void -_MD_MakeNonblock(PRFileDesc *f) -{ - return; /* do nothing */ -} - - - -/* - * socket_io_wait -- - * - * Wait for socket i/o, periodically checking for interrupt. - * - * This function returns 1 on success. On failure, it returns - * -1 and sets the error codes. It never returns 0. - */ -#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 - -static PRInt32 socket_io_wait( - PROsfd osfd, - PRInt32 fd_type, - PRIntervalTime timeout) -{ - PRInt32 rv = -1; - struct timeval tv; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRIntervalTime elapsed, remaining; - PRBool wait_for_remaining; - fd_set rd_wr, ex; - int err, len; - - switch (timeout) { - case PR_INTERVAL_NO_WAIT: - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - break; - case PR_INTERVAL_NO_TIMEOUT: - /* - * This is a special case of the 'default' case below. - * Please see the comments there. - */ - tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; - tv.tv_usec = 0; - FD_ZERO(&rd_wr); - FD_ZERO(&ex); - do { - FD_SET(osfd, &rd_wr); - FD_SET(osfd, &ex); - switch( fd_type ) - { - case READ_FD: - rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv); - break; - case WRITE_FD: - rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv); - break; - case CONNECT_FD: - rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv); - break; - default: - PR_ASSERT(0); - break; - } /* end switch() */ - if (rv == -1 ) - { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - break; - } - if ( rv > 0 && fd_type == CONNECT_FD ) - { - /* - * Call Sleep(0) to work around a Winsock timing bug. - */ - Sleep(0); - if (FD_ISSET((SOCKET)osfd, &ex)) - { - len = sizeof(err); - if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, - (char *) &err, &len) == SOCKET_ERROR) - { - _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); - return -1; - } - if (err != 0) - _PR_MD_MAP_CONNECT_ERROR(err); - else - PR_SetError(PR_UNKNOWN_ERROR, 0); - return -1; - } - if (FD_ISSET((SOCKET)osfd, &rd_wr)) - { - /* it's connected */ - return 1; - } - PR_ASSERT(0); - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - } while (rv == 0); - break; - default: - remaining = timeout; - FD_ZERO(&rd_wr); - FD_ZERO(&ex); - do { - /* - * We block in _MD_SELECT for at most - * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, - * so that there is an upper limit on the delay - * before the interrupt bit is checked. - */ - wait_for_remaining = PR_TRUE; - tv.tv_sec = PR_IntervalToSeconds(remaining); - if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { - wait_for_remaining = PR_FALSE; - tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; - tv.tv_usec = 0; - } else { - tv.tv_usec = PR_IntervalToMicroseconds( - remaining - - PR_SecondsToInterval(tv.tv_sec)); - } - FD_SET(osfd, &rd_wr); - FD_SET(osfd, &ex); - switch( fd_type ) - { - case READ_FD: - rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv); - break; - case WRITE_FD: - rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv); - break; - case CONNECT_FD: - rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv); - break; - default: - PR_ASSERT(0); - break; - } /* end switch() */ - if (rv == -1) - { - _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); - break; - } - if ( rv > 0 && fd_type == CONNECT_FD ) - { - /* - * Call Sleep(0) to work around a Winsock timing bug. - */ - Sleep(0); - if (FD_ISSET((SOCKET)osfd, &ex)) - { - len = sizeof(err); - if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, - (char *) &err, &len) == SOCKET_ERROR) - { - _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); - return -1; - } - if (err != 0) - _PR_MD_MAP_CONNECT_ERROR(err); - else - PR_SetError(PR_UNKNOWN_ERROR, 0); - return -1; - } - if (FD_ISSET((SOCKET)osfd, &rd_wr)) - { - /* it's connected */ - return 1; - } - PR_ASSERT(0); - } - if (_PR_PENDING_INTERRUPT(me)) { - me->flags &= ~_PR_INTERRUPT; - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - rv = -1; - break; - } - /* - * We loop again if _MD_SELECT timed out and the - * timeout deadline has not passed yet. - */ - if (rv == 0 ) - { - if (wait_for_remaining) { - elapsed = remaining; - } else { - elapsed = PR_SecondsToInterval(tv.tv_sec) - + PR_MicrosecondsToInterval(tv.tv_usec); - } - if (elapsed >= remaining) { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - rv = -1; - break; - } else { - remaining = remaining - elapsed; - } - } - } while (rv == 0 ); - break; - } - return(rv); -} /* end socket_io_wait() */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95thred.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95thred.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/w95thred.c 2012-06-13 02:17:05.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/w95thred.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,320 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include /* for _beginthreadex() */ - -#if defined(_MSC_VER) && _MSC_VER <= 1200 -/* - * VC++ 6.0 doesn't have DWORD_PTR. - */ - -typedef DWORD DWORD_PTR; -#endif /* _MSC_VER <= 1200 */ - -/* --- globals ------------------------------------------------ */ -#ifdef _PR_USE_STATIC_TLS -__declspec(thread) struct PRThread *_pr_thread_last_run; -__declspec(thread) struct PRThread *_pr_currentThread; -__declspec(thread) struct _PRCPU *_pr_currentCPU; -#else -DWORD _pr_currentThreadIndex; -DWORD _pr_lastThreadIndex; -DWORD _pr_currentCPUIndex; -#endif -int _pr_intsOff = 0; -_PRInterruptTable _pr_interruptTable[] = { { 0 } }; - -void -_PR_MD_EARLY_INIT() -{ -#ifndef _PR_USE_STATIC_TLS - _pr_currentThreadIndex = TlsAlloc(); - _pr_lastThreadIndex = TlsAlloc(); - _pr_currentCPUIndex = TlsAlloc(); -#endif -} - -void _PR_MD_CLEANUP_BEFORE_EXIT(void) -{ - _PR_NT_FreeSids(); - - _PR_MD_CleanupSockets(); - - WSACleanup(); - -#ifndef _PR_USE_STATIC_TLS - TlsFree(_pr_currentThreadIndex); - TlsFree(_pr_lastThreadIndex); - TlsFree(_pr_currentCPUIndex); -#endif -} - -PRStatus -_PR_MD_INIT_THREAD(PRThread *thread) -{ - if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { - /* - ** Warning: - ** -------- - ** NSPR requires a real handle to every thread. - ** GetCurrentThread() returns a pseudo-handle which - ** is not suitable for some thread operations (e.g., - ** suspending). Therefore, get a real handle from - ** the pseudo handle via DuplicateHandle(...) - */ - DuplicateHandle( - GetCurrentProcess(), /* Process of source handle */ - GetCurrentThread(), /* Pseudo Handle to dup */ - GetCurrentProcess(), /* Process of handle */ - &(thread->md.handle), /* resulting handle */ - 0L, /* access flags */ - FALSE, /* Inheritable */ - DUPLICATE_SAME_ACCESS); /* Options */ - } - - /* Create the blocking IO semaphore */ - thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL); - if (thread->md.blocked_sema == NULL) - return PR_FAILURE; - else - return PR_SUCCESS; -} - -static unsigned __stdcall -pr_root(void *arg) -{ - PRThread *thread = (PRThread *)arg; - thread->md.start(thread); - return 0; -} - -PRStatus -_PR_MD_CREATE_THREAD(PRThread *thread, - void (*start)(void *), - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - - thread->md.start = start; - thread->md.handle = (HANDLE) _beginthreadex( - NULL, - thread->stack->stackSize, - pr_root, - (void *)thread, - CREATE_SUSPENDED, - &(thread->id)); - if(!thread->md.handle) { - return PR_FAILURE; - } - - thread->md.id = thread->id; - /* - * On windows, a thread is created with a thread priority of - * THREAD_PRIORITY_NORMAL. - */ - if (priority != PR_PRIORITY_NORMAL) { - _PR_MD_SET_PRIORITY(&(thread->md), priority); - } - - /* Activate the thread */ - if ( ResumeThread( thread->md.handle ) != -1) - return PR_SUCCESS; - - return PR_FAILURE; -} - -void -_PR_MD_YIELD(void) -{ - /* Can NT really yield at all? */ - Sleep(0); -} - -void -_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) -{ - int nativePri; - BOOL rv; - - if (newPri < PR_PRIORITY_FIRST) { - newPri = PR_PRIORITY_FIRST; - } else if (newPri > PR_PRIORITY_LAST) { - newPri = PR_PRIORITY_LAST; - } - switch (newPri) { - case PR_PRIORITY_LOW: - nativePri = THREAD_PRIORITY_BELOW_NORMAL; - break; - case PR_PRIORITY_NORMAL: - nativePri = THREAD_PRIORITY_NORMAL; - break; - case PR_PRIORITY_HIGH: - nativePri = THREAD_PRIORITY_ABOVE_NORMAL; - break; - case PR_PRIORITY_URGENT: - nativePri = THREAD_PRIORITY_HIGHEST; - } - rv = SetThreadPriority(thread->handle, nativePri); - PR_ASSERT(rv); - if (!rv) { - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("PR_SetThreadPriority: can't set thread priority\n")); - } - return; -} - -const DWORD MS_VC_EXCEPTION = 0x406D1388; - -#pragma pack(push,8) -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -void -_PR_MD_SET_CURRENT_THREAD_NAME(const char *name) -{ -#ifdef _MSC_VER - THREADNAME_INFO info; - - if (!IsDebuggerPresent()) - return; - - info.dwType = 0x1000; - info.szName = (char*) name; - info.dwThreadID = -1; - info.dwFlags = 0; - - __try { - RaiseException(MS_VC_EXCEPTION, - 0, - sizeof(info) / sizeof(ULONG_PTR), - (ULONG_PTR*)&info); - } __except(EXCEPTION_CONTINUE_EXECUTION) { - } -#endif -} - -void -_PR_MD_CLEAN_THREAD(PRThread *thread) -{ - BOOL rv; - - if (thread->md.blocked_sema) { - rv = CloseHandle(thread->md.blocked_sema); - PR_ASSERT(rv); - thread->md.blocked_sema = 0; - } - - if (thread->md.handle) { - rv = CloseHandle(thread->md.handle); - PR_ASSERT(rv); - thread->md.handle = 0; - } -} - -void -_PR_MD_EXIT_THREAD(PRThread *thread) -{ - _PR_MD_CLEAN_THREAD(thread); - _PR_MD_SET_CURRENT_THREAD(NULL); -} - - -void -_PR_MD_EXIT(PRIntn status) -{ - _exit(status); -} - -PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ) -{ -#ifdef WINCE - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return -1; -#else - DWORD_PTR rv; - - rv = SetThreadAffinityMask(thread->md.handle, mask); - - return rv?0:-1; -#endif -} - -PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask) -{ -#ifdef WINCE - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return -1; -#else - BOOL rv; - DWORD_PTR process_mask; - DWORD_PTR system_mask; - - rv = GetProcessAffinityMask(GetCurrentProcess(), - &process_mask, &system_mask); - if (rv) - *mask = (PRUint32)process_mask; - - return rv?0:-1; -#endif -} - -void -_PR_MD_SUSPEND_CPU(_PRCPU *cpu) -{ - _PR_MD_SUSPEND_THREAD(cpu->thread); -} - -void -_PR_MD_RESUME_CPU(_PRCPU *cpu) -{ - _PR_MD_RESUME_THREAD(cpu->thread); -} - -void -_PR_MD_SUSPEND_THREAD(PRThread *thread) -{ - if (_PR_IS_NATIVE_THREAD(thread)) { - DWORD previousSuspendCount; - /* XXXMB - SuspendThread() is not a blocking call; how do we - * know when the thread is *REALLY* suspended? - */ - previousSuspendCount = SuspendThread(thread->md.handle); - PR_ASSERT(previousSuspendCount == 0); - } -} - -void -_PR_MD_RESUME_THREAD(PRThread *thread) -{ - if (_PR_IS_NATIVE_THREAD(thread)) { - DWORD previousSuspendCount; - previousSuspendCount = ResumeThread(thread->md.handle); - PR_ASSERT(previousSuspendCount == 1); - } -} - -PRThread* -_MD_CURRENT_THREAD(void) -{ -PRThread *thread; - - thread = _MD_GET_ATTACHED_THREAD(); - - if (NULL == thread) { - thread = _PRI_AttachThread( - PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); - } - PR_ASSERT(thread != NULL); - return thread; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/win32_errors.c nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/win32_errors.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/md/windows/win32_errors.c 2012-03-06 13:14:18.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/md/windows/win32_errors.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,533 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prerror.h" -#include "prlog.h" -#include -#include - -/* - * On Win32, we map three kinds of error codes: - * - GetLastError(): for Win32 functions - * - WSAGetLastError(): for Winsock functions - * - errno: for standard C library functions - * - * GetLastError() and WSAGetLastError() return error codes in - * non-overlapping ranges, so their error codes (ERROR_* and - * WSAE*) can be mapped by the same function. On the other hand, - * errno and GetLastError() have overlapping ranges, so we need - * to use a separate function to map errno. - * - * We do not check for WSAEINPROGRESS and WSAEINTR because we do not - * use blocking Winsock 1.1 calls. - * - * Except for the 'socket' call, we do not check for WSAEINITIALISED. - * It is assumed that if Winsock is not initialized, that fact will - * be detected at the time we create new sockets. - */ - -static void _MD_win32_map_default_errno(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case EACCES: - prError = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case ENOENT: - prError = PR_FILE_NOT_FOUND_ERROR; - break; - default: - prError = PR_UNKNOWN_ERROR; - break; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_default_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case ERROR_ACCESS_DENIED: - prError = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case ERROR_ALREADY_EXISTS: - prError = PR_FILE_EXISTS_ERROR; - break; - case ERROR_CALL_NOT_IMPLEMENTED: - prError = PR_NOT_IMPLEMENTED_ERROR; - break; - case ERROR_DISK_CORRUPT: - prError = PR_IO_ERROR; - break; - case ERROR_DISK_FULL: - prError = PR_NO_DEVICE_SPACE_ERROR; - break; - case ERROR_DISK_OPERATION_FAILED: - prError = PR_IO_ERROR; - break; - case ERROR_DRIVE_LOCKED: - prError = PR_FILE_IS_LOCKED_ERROR; - break; - case ERROR_FILENAME_EXCED_RANGE: - prError = PR_NAME_TOO_LONG_ERROR; - break; - case ERROR_FILE_CORRUPT: - prError = PR_IO_ERROR; - break; - case ERROR_FILE_EXISTS: - prError = PR_FILE_EXISTS_ERROR; - break; - case ERROR_FILE_INVALID: - prError = PR_BAD_DESCRIPTOR_ERROR; - break; - case ERROR_FILE_NOT_FOUND: - prError = PR_FILE_NOT_FOUND_ERROR; - break; - case ERROR_HANDLE_DISK_FULL: - prError = PR_NO_DEVICE_SPACE_ERROR; - break; - case ERROR_INVALID_ADDRESS: - prError = PR_ACCESS_FAULT_ERROR; - break; - case ERROR_INVALID_HANDLE: - prError = PR_BAD_DESCRIPTOR_ERROR; - break; - case ERROR_INVALID_NAME: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case ERROR_INVALID_PARAMETER: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case ERROR_INVALID_USER_BUFFER: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case ERROR_LOCKED: - prError = PR_FILE_IS_LOCKED_ERROR; - break; - case ERROR_NETNAME_DELETED: - prError = PR_CONNECT_RESET_ERROR; - break; - case ERROR_NOACCESS: - prError = PR_ACCESS_FAULT_ERROR; - break; - case ERROR_NOT_ENOUGH_MEMORY: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case ERROR_NOT_ENOUGH_QUOTA: - prError = PR_OUT_OF_MEMORY_ERROR; - break; - case ERROR_NOT_READY: - prError = PR_IO_ERROR; - break; - case ERROR_NO_MORE_FILES: - prError = PR_NO_MORE_FILES_ERROR; - break; - case ERROR_OPEN_FAILED: - prError = PR_IO_ERROR; - break; - case ERROR_OPEN_FILES: - prError = PR_IO_ERROR; - break; - case ERROR_OPERATION_ABORTED: - prError = PR_OPERATION_ABORTED_ERROR; - break; - case ERROR_OUTOFMEMORY: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case ERROR_PATH_BUSY: - prError = PR_IO_ERROR; - break; - case ERROR_PATH_NOT_FOUND: - prError = PR_FILE_NOT_FOUND_ERROR; - break; - case ERROR_SEEK_ON_DEVICE: - prError = PR_IO_ERROR; - break; - case ERROR_SHARING_VIOLATION: - prError = PR_FILE_IS_BUSY_ERROR; - break; - case ERROR_STACK_OVERFLOW: - prError = PR_ACCESS_FAULT_ERROR; - break; - case ERROR_TOO_MANY_OPEN_FILES: - prError = PR_SYS_DESC_TABLE_FULL_ERROR; - break; - case ERROR_WRITE_PROTECT: - prError = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case WSAEACCES: - prError = PR_NO_ACCESS_RIGHTS_ERROR; - break; - case WSAEADDRINUSE: - prError = PR_ADDRESS_IN_USE_ERROR; - break; - case WSAEADDRNOTAVAIL: - prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; - break; - case WSAEAFNOSUPPORT: - prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; - break; - case WSAEALREADY: - prError = PR_ALREADY_INITIATED_ERROR; - break; - case WSAEBADF: - prError = PR_BAD_DESCRIPTOR_ERROR; - break; - case WSAECONNABORTED: - prError = PR_CONNECT_ABORTED_ERROR; - break; - case WSAECONNREFUSED: - prError = PR_CONNECT_REFUSED_ERROR; - break; - case WSAECONNRESET: - prError = PR_CONNECT_RESET_ERROR; - break; - case WSAEDESTADDRREQ: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case WSAEFAULT: - prError = PR_ACCESS_FAULT_ERROR; - break; - case WSAEHOSTUNREACH: - prError = PR_HOST_UNREACHABLE_ERROR; - break; - case WSAEINVAL: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case WSAEISCONN: - prError = PR_IS_CONNECTED_ERROR; - break; - case WSAEMFILE: - prError = PR_PROC_DESC_TABLE_FULL_ERROR; - break; - case WSAEMSGSIZE: - prError = PR_BUFFER_OVERFLOW_ERROR; - break; - case WSAENETDOWN: - prError = PR_NETWORK_DOWN_ERROR; - break; - case WSAENETRESET: - prError = PR_CONNECT_ABORTED_ERROR; - break; - case WSAENETUNREACH: - prError = PR_NETWORK_UNREACHABLE_ERROR; - break; - case WSAENOBUFS: - prError = PR_INSUFFICIENT_RESOURCES_ERROR; - break; - case WSAENOPROTOOPT: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case WSAENOTCONN: - prError = PR_NOT_CONNECTED_ERROR; - break; - case WSAENOTSOCK: - prError = PR_NOT_SOCKET_ERROR; - break; - case WSAEOPNOTSUPP: - prError = PR_OPERATION_NOT_SUPPORTED_ERROR; - break; - case WSAEPROTONOSUPPORT: - prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; - break; - case WSAEPROTOTYPE: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case WSAESHUTDOWN: - prError = PR_SOCKET_SHUTDOWN_ERROR; - break; - case WSAESOCKTNOSUPPORT: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - case WSAETIMEDOUT: - prError = PR_CONNECT_ABORTED_ERROR; - break; - case WSAEWOULDBLOCK: - prError = PR_WOULD_BLOCK_ERROR; - break; - default: - prError = PR_UNKNOWN_ERROR; - break; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_opendir_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_closedir_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_unix_readdir_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_delete_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -/* The error code for stat() is in errno. */ -void _MD_win32_map_stat_error(PRInt32 err) -{ - _MD_win32_map_default_errno(err); -} - -void _MD_win32_map_fstat_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_rename_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -/* The error code for access() is in errno. */ -void _MD_win32_map_access_error(PRInt32 err) -{ - _MD_win32_map_default_errno(err); -} - -void _MD_win32_map_mkdir_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_rmdir_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_read_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_transmitfile_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_write_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_lseek_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_fsync_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -/* - * For both CloseHandle() and closesocket(). - */ -void _MD_win32_map_close_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_socket_error(PRInt32 err) -{ - PR_ASSERT(err != WSANOTINITIALISED); - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_recv_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_recvfrom_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_send_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case WSAEMSGSIZE: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - default: - _MD_win32_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_sendto_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case WSAEMSGSIZE: - prError = PR_INVALID_ARGUMENT_ERROR; - break; - default: - _MD_win32_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_accept_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case WSAEOPNOTSUPP: - prError = PR_NOT_TCP_SOCKET_ERROR; - break; - case WSAEINVAL: - prError = PR_INVALID_STATE_ERROR; - break; - default: - _MD_win32_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_acceptex_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_connect_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case WSAEWOULDBLOCK: - prError = PR_IN_PROGRESS_ERROR; - break; - case WSAEINVAL: - prError = PR_ALREADY_INITIATED_ERROR; - break; - case WSAETIMEDOUT: - prError = PR_IO_TIMEOUT_ERROR; - break; - default: - _MD_win32_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_bind_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case WSAEINVAL: - prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; - break; - default: - _MD_win32_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_listen_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case WSAEOPNOTSUPP: - prError = PR_NOT_TCP_SOCKET_ERROR; - break; - case WSAEINVAL: - prError = PR_INVALID_STATE_ERROR; - break; - default: - _MD_win32_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_shutdown_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_getsockname_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case WSAEINVAL: - prError = PR_INVALID_STATE_ERROR; - break; - default: - _MD_win32_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_getpeername_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_getsockopt_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_setsockopt_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_open_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -void _MD_win32_map_gethostname_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} - -/* Win32 select() only works on sockets. So in this -** context, WSAENOTSOCK is equivalent to EBADF on Unix. -*/ -void _MD_win32_map_select_error(PRInt32 err) -{ - PRErrorCode prError; - - switch (err) { - case WSAENOTSOCK: - prError = PR_BAD_DESCRIPTOR_ERROR; - break; - default: - _MD_win32_map_default_error(err); - return; - } - PR_SetError(prError, err); -} - -void _MD_win32_map_lockf_error(PRInt32 err) -{ - _MD_win32_map_default_error(err); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/memory/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/memory/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/memory/.cvsignore 2001-05-12 04:47:04.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/memory/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/memory/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/memory/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/memory/Makefile.in 2012-03-06 13:14:18.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/memory/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CSRCS = prseg.c prshm.c prshma.c - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/memory/prseg.c nspr-4.10.7/mozilla/nsprpub/pr/src/memory/prseg.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/memory/prseg.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/memory/prseg.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#if defined(_PR_PTHREADS) - -/* -** The pthreads version doesn't use these functions. -*/ -void _PR_InitSegs(void) -{ -} - -#else /* _PR_PTHREADS */ - -void _PR_InitSegs(void) -{ - _PR_MD_INIT_SEGS(); -} - -/* -** Allocate a memory segment. The size value is rounded up to the native -** system page size and a page aligned portion of memory is returned. -** This memory is not part of the malloc heap. If "vaddr" is not NULL -** then PR tries to allocate the segment at the desired virtual address. -*/ -PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr) -{ - PRSegment *seg; - - /* calloc the data structure for the segment */ - seg = PR_NEWZAP(PRSegment); - - if (seg) { - size = ((size + _pr_pageSize - 1) >> _pr_pageShift) << _pr_pageShift; - /* - ** Now, allocate the actual segment memory (or map under some OS) - ** The OS specific code decides from where or how to allocate memory. - */ - if (_PR_MD_ALLOC_SEGMENT(seg, size, vaddr) != PR_SUCCESS) { - PR_DELETE(seg); - return NULL; - } - } - - return seg; -} - -/* -** Free a memory segment. -*/ -void _PR_DestroySegment(PRSegment *seg) -{ - _PR_MD_FREE_SEGMENT(seg); - PR_DELETE(seg); -} - -#endif /* _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/memory/prshma.c nspr-4.10.7/mozilla/nsprpub/pr/src/memory/prshma.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/memory/prshma.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/memory/prshma.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** prshma.h -- NSPR Anonymous Shared Memory -** -** -*/ - -#include "primpl.h" - -extern PRLogModuleInfo *_pr_shma_lm; - -#if defined(XP_UNIX) -/* defined in pr/src/md/unix/uxshm.c */ -#elif defined(WIN32) -/* defined in pr/src/md/windows/w32shm.c */ -#else -extern PRFileMap * _PR_MD_OPEN_ANON_FILE_MAP( const char *dirName, PRSize size, PRFileMapProtect prot ) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} -extern PRStatus _PR_MD_EXPORT_FILE_MAP_AS_STRING(PRFileMap *fm, PRSize bufSize, char *buf) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} -extern PRFileMap * _PR_MD_IMPORT_FILE_MAP_FROM_STRING(const char *fmstring) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} -#endif - -/* -** PR_OpenAnonFileMap() -- Creates an anonymous file-mapped shared memory -** -*/ -PR_IMPLEMENT(PRFileMap*) -PR_OpenAnonFileMap( - const char *dirName, - PRSize size, - PRFileMapProtect prot -) -{ - return(_PR_MD_OPEN_ANON_FILE_MAP( dirName, size, prot )); -} /* end PR_OpenAnonFileMap() */ - -/* -** PR_ProcessAttrSetInheritableFileMap() -- Prepare FileMap for export -** to my children processes via PR_CreateProcess() -** -** -*/ -PR_IMPLEMENT( PRStatus) -PR_ProcessAttrSetInheritableFileMap( - PRProcessAttr *attr, - PRFileMap *fm, - const char *shmname -) -{ - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return( PR_FAILURE); -} /* end PR_ProcessAttrSetInheritableFileMap() */ - -/* -** PR_GetInheritedFileMap() -- Import a PRFileMap previously exported -** by my parent process via PR_CreateProcess() -** -*/ -PR_IMPLEMENT( PRFileMap *) -PR_GetInheritedFileMap( - const char *shmname -) -{ - PRFileMap *fm = NULL; - PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); - return( fm ); -} /* end PR_GetInhteritedFileMap() */ - -/* -** PR_ExportFileMapAsString() -- Creates a string identifying a PRFileMap -** -*/ -PR_IMPLEMENT( PRStatus ) -PR_ExportFileMapAsString( - PRFileMap *fm, - PRSize bufSize, - char *buf -) -{ - return( _PR_MD_EXPORT_FILE_MAP_AS_STRING( fm, bufSize, buf )); -} /* end PR_ExportFileMapAsString() */ - -/* -** PR_ImportFileMapFromString() -- Creates a PRFileMap from the identifying string -** -** -*/ -PR_IMPLEMENT( PRFileMap * ) -PR_ImportFileMapFromString( - const char *fmstring -) -{ - return( _PR_MD_IMPORT_FILE_MAP_FROM_STRING(fmstring)); -} /* end PR_ImportFileMapFromString() */ -/* end prshma.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/memory/prshm.c nspr-4.10.7/mozilla/nsprpub/pr/src/memory/prshm.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/memory/prshm.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/memory/prshm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** prshm.c -- NSPR Named Shared Memory -** -** lth. Jul-1999. -*/ -#include -#include "primpl.h" - -extern PRLogModuleInfo *_pr_shm_lm; - - -#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY -/* SysV implementation is in pr/src/md/unix/uxshm.c */ -#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY -/* Posix implementation is in pr/src/md/unix/uxshm.c */ -#elif defined PR_HAVE_WIN32_NAMED_SHARED_MEMORY -/* Win32 implementation is in pr/src/md/windows/w32shm.c */ -#else -/* -** there is no named_shared_memory -*/ -extern PRSharedMemory* _MD_OpenSharedMemory( const char *name, PRSize size, PRIntn flags, PRIntn mode ) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -extern PRStatus _MD_DeleteSharedMemory( const char *name ) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} -#endif /* HAVE_SYSV_NAMED_SHARED_MEMORY */ - -/* -** FUNCTION: PR_OpenSharedMemory() -** -*/ -PR_IMPLEMENT( PRSharedMemory * ) - PR_OpenSharedMemory( - const char *name, - PRSize size, - PRIntn flags, - PRIntn mode -) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - return( _PR_MD_OPEN_SHARED_MEMORY( name, size, flags, mode )); -} /* end PR_OpenSharedMemory() */ - -/* -** FUNCTION: PR_AttachSharedMemory() -** -*/ -PR_IMPLEMENT( void * ) - PR_AttachSharedMemory( - PRSharedMemory *shm, - PRIntn flags -) -{ - return( _PR_MD_ATTACH_SHARED_MEMORY( shm, flags )); -} /* end PR_AttachSharedMemory() */ - -/* -** FUNCTION: PR_DetachSharedMemory() -** -*/ -PR_IMPLEMENT( PRStatus ) - PR_DetachSharedMemory( - PRSharedMemory *shm, - void *addr -) -{ - return( _PR_MD_DETACH_SHARED_MEMORY( shm, addr )); -} /* end PR_DetachSharedMemory() */ - -/* -** FUNCTION: PR_CloseSharedMemory() -** -*/ -PR_IMPLEMENT( PRStatus ) - PR_CloseSharedMemory( - PRSharedMemory *shm -) -{ - return( _PR_MD_CLOSE_SHARED_MEMORY( shm )); -} /* end PR_CloseSharedMemory() */ - -/* -** FUNCTION: PR_DeleteSharedMemory() -** -*/ -PR_EXTERN( PRStatus ) - PR_DeleteSharedMemory( - const char *name -) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - return(_PR_MD_DELETE_SHARED_MEMORY( name )); -} /* end PR_DestroySharedMemory() */ -/* end prshm.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/compile-et.pl nspr-4.10.7/mozilla/nsprpub/pr/src/misc/compile-et.pl --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/compile-et.pl 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/compile-et.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -#!/usr/bin/perl - -# usage: compile-et input.et - -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -sub header -{ - local($filename, $comment) = @_; - -< 0x7fffff); - $base*256; -} - -sub code { - local($macro, $text) = @_; - $code = $table_base + $table_item_count; - - print H "\n"; - print H "/* ", $text, " */\n"; - printf H "#define %-40s (%dL)\n", $macro, $code; - - print C "\t{\"", $macro, "\", \"", $text, "\"},\n"; - - print PROPERTIES $macro, "=", $text, "\n"; - - $table_item_count++; -} - - -$filename = $ARGV[0]; -open(INPUT, "< $filename") || die "Can't read $filename: $!\n"; - -$base = "$filename"; -$base =~ s/\.et$//; -$base =~ s#.*/##; - -open(H, "> ${base}.h") || die "Can't write ${base}.h\n"; -open(C, "> ${base}.c") || die "Can't write ${base}.c\n"; -open(PROPERTIES, "> ${base}.properties") || die "Can't write ${base}.properties\n"; - -print H "/*\n", &header("${base}.h", " *"), " */\n"; -print C "/*\n", &header("${base}.c", " *"), " */\n"; -print PROPERTIES &header("${base}.properties", "#"); - -$skipone = 0; - -while ($_ = ) { - next if /^#/; - - if (/^[ \t]*(error_table|et)[ \t]+([a-zA-Z][a-zA-Z0-9_]+) *(-?[0-9]*)/) { - $table_name = $2; - if ($3) { - $table_base = $3; - } - else { - $table_base = &table_base($table_name); - } - $table_item_count = 0; - - print C "#include \"prerror.h\"\n"; - print C "static const struct PRErrorMessage text[] = {\n"; - } - elsif (/^[ \t]*(error_code|ec)[ \t]+([A-Z_0-9]+),[ \t]*$/) { - $skipone = 1; - $macro = $2; - } - elsif (/^[ \t]*(error_code|ec)[ \t]+([A-Z_0-9]+),[ \t]*"(.*)"[ \t]*$/) { - &code($2, $3); - } - elsif ($skipone && /^[ \t]*"(.*)"[ \t]*$/) { - &code($macro, $1); - } -} - -print H "\n"; -print H "extern void ", $table_name, "_InitializePRErrorTable","(void);\n"; -printf H "#define ERROR_TABLE_BASE_%s (%dL)\n", $table_name, $table_base; - -print C "\t{0, 0}\n"; -print C "};\n\n"; -printf C "static const struct PRErrorTable et = { text, \"%s\", %dL, %d };\n", - $base, $table_base, $table_item_count; -print C "\n"; -print C "void ", $table_name, "_InitializePRErrorTable", "(void) {\n"; -print C " PR_ErrorInstallTable(&et);\n"; -print C "}\n"; - -0; diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/misc/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/.cvsignore 2001-05-12 04:52:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/dtoa.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/dtoa.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/dtoa.c 2012-04-19 19:54:14.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/dtoa.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,4356 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ - -/* On a machine with IEEE extended-precision registers, it is - * necessary to specify double-precision (53-bit) rounding precision - * before invoking strtod or dtoa. If the machine uses (the equivalent - * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); - * does this with many compilers. Whether this or another call is - * appropriate depends on the compiler; for this to work, it may be - * necessary to #include "float.h" or another system-dependent header - * file. - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* - * #define IEEE_8087 for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_MC68k for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic (D_floating). - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. This will cause dtoa modes 4 and 5 to be - * treated the same as modes 2 and 3 for some inputs. - * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS - * is also #defined, fegetround() will be queried for the rounding mode. - * Note that both FLT_ROUNDS and fegetround() are specified by the C99 - * standard (and are specified to be consistent, with fesetround() - * affecting the value of FLT_ROUNDS), but that some (Linux) systems - * do not work correctly in this regard, so using fegetround() is more - * portable than using FLT_ROUNDS directly. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic - * that rounds toward +Infinity. - * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased - * rounding when the underlying floating-point arithmetic uses - * unbiased rounding. This prevent using ordinary floating-point - * arithmetic when the result could be computed with one rounding error. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define NO_LONG_LONG on machines that do not have a "long long" - * integer type (of >= 64 bits). On such machines, you can - * #define Just_16 to store 16 bits per 32-bit Long when doing - * high-precision integer arithmetic. Whether this speeds things - * up or slows things down depends on the machine and the number - * being converted. If long long is available and the name is - * something other than "long long", #define Llong to be the name, - * and if "unsigned Llong" does not work as an unsigned version of - * Llong, #define #ULLong to be the corresponding unsigned type. - * #define KR_headers for old-style C function headers. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. Similarly, if you - * want something other than the system's free() to be called to - * recycle memory acquired from MALLOC, #define FREE to be the - * name of the alternate routine. (FREE or free is only called in - * pathological cases, e.g., in a dtoa call after a dtoa return in - * mode 3 with thousands of digits requested.) - * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK - * #defined automatically on IEEE systems. On such systems, - * when INFNAN_CHECK is #defined, strtod checks - * for Infinity and NaN (case insensitively). On some systems - * (e.g., some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. - * #define MULTIPLE_THREADS if the system offers preemptively scheduled - * multiple threads. In this case, you must provide (or suitably - * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed - * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed - * in pow5mult, ensures lazy evaluation of only one copy of high - * powers of 5; omitting this lock would introduce a small - * probability of wasting memory, but would otherwise be harmless.) - * You must also invoke freedtoa(s) to free the value s returned by - * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. - * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. - * #define USE_LOCALE to use the current locale's decimal_point value. - * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). - * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. - * #define NO_HEX_FP to omit recognition of hexadecimal floating-point - * values by strtod. - * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now) - * to disable logic for "fast" testing of very long input strings - * to strtod. This testing proceeds by initially truncating the - * input string, then if necessary comparing the whole string with - * a decimal expansion to decide close cases. This logic is only - * used for input more than STRTOD_DIGLIM digits long (default 40). - */ - -#ifndef Long -#define Long long -#endif -#ifndef ULong -typedef unsigned Long ULong; -#endif - -#ifdef DEBUG -#include "stdio.h" -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#include "stdlib.h" -#include "string.h" - -#ifdef USE_LOCALE -#include "locale.h" -#endif - -#ifdef Honor_FLT_ROUNDS -#ifndef Trust_FLT_ROUNDS -#include -#endif -#endif - -#ifdef MALLOC -#ifdef KR_headers -extern char *MALLOC(); -#else -extern void *MALLOC(size_t); -#endif -#else -#define MALLOC malloc -#endif - -#ifndef Omit_Private_Memory -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#endif - -#undef IEEE_Arith -#undef Avoid_Underflow -#ifdef IEEE_MC68k -#define IEEE_Arith -#endif -#ifdef IEEE_8087 -#define IEEE_Arith -#endif - -#ifdef IEEE_Arith -#ifndef NO_INFNAN_CHECK -#undef INFNAN_CHECK -#define INFNAN_CHECK -#endif -#else -#undef INFNAN_CHECK -#define NO_STRTOD_BIGCOMP -#endif - -#include "errno.h" - -#ifdef Bad_float_h - -#ifdef IEEE_Arith -#define DBL_DIG 15 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define FLT_RADIX 2 -#endif /*IEEE_Arith*/ - -#ifdef IBM -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 75 -#define DBL_MAX_EXP 63 -#define FLT_RADIX 16 -#define DBL_MAX 7.2370055773322621e+75 -#endif - -#ifdef VAX -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 38 -#define DBL_MAX_EXP 127 -#define FLT_RADIX 2 -#define DBL_MAX 1.7014118346046923e+38 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 2147483647 -#endif - -#else /* ifndef Bad_float_h */ -#include "float.h" -#endif /* Bad_float_h */ - -#ifndef __MATH_H__ -#include "math.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CONST -#ifdef KR_headers -#define CONST /* blank */ -#else -#define CONST const -#endif -#endif - -#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 -Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. -#endif - -typedef union { double d; ULong L[2]; } U; - -#ifdef IEEE_8087 -#define word0(x) (x)->L[1] -#define word1(x) (x)->L[0] -#else -#define word0(x) (x)->L[0] -#define word1(x) (x)->L[1] -#endif -#define dval(x) (x)->d - -#ifndef STRTOD_DIGLIM -#define STRTOD_DIGLIM 40 -#endif - -#ifdef DIGLIM_DEBUG -extern int strtod_diglim; -#else -#define strtod_diglim STRTOD_DIGLIM -#endif - -/* The following definition of Storeinc is appropriate for MIPS processors. - * An alternative that might be better on some machines is - * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) - */ -#if defined(IEEE_8087) + defined(VAX) -#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ -((unsigned short *)a)[0] = (unsigned short)c, a++) -#else -#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ -((unsigned short *)a)[1] = (unsigned short)c, a++) -#endif - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#ifdef IEEE_Arith -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Nbits 53 -#define Bias 1023 -#define Emax 1023 -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#ifndef NO_IEEE_Scale -#define Avoid_Underflow -#ifdef Flush_Denorm /* debugging option */ -#undef Sudden_Underflow -#endif -#endif - -#ifndef Flt_Rounds -#ifdef FLT_ROUNDS -#define Flt_Rounds FLT_ROUNDS -#else -#define Flt_Rounds 1 -#endif -#endif /*Flt_Rounds*/ - -#ifdef Honor_FLT_ROUNDS -#undef Check_FLT_ROUNDS -#define Check_FLT_ROUNDS -#else -#define Rounding Flt_Rounds -#endif - -#else /* ifndef IEEE_Arith */ -#undef Check_FLT_ROUNDS -#undef Honor_FLT_ROUNDS -#undef SET_INEXACT -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#undef Flt_Rounds -#define Flt_Rounds 0 -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Nbits 56 -#define Bias 65 -#define Emax 248 -#define Emin (-260) -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#undef Flt_Rounds -#define Flt_Rounds 1 -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Nbits 56 -#define Bias 129 -#define Emax 126 -#define Emin (-129) -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif /* IBM, VAX */ -#endif /* IEEE_Arith */ - -#ifndef IEEE_Arith -#define ROUND_BIASED -#else -#ifdef ROUND_BIASED_without_Round_Up -#undef ROUND_BIASED -#define ROUND_BIASED -#endif -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) a = rnd_prod(a, b) -#define rounded_quotient(a,b) a = rnd_quot(a, b) -#ifdef KR_headers -extern double rnd_prod(), rnd_quot(); -#else -extern double rnd_prod(double, double), rnd_quot(double, double); -#endif -#else -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b -#endif - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -#ifndef Pack_32 -#define Pack_32 -#endif - -typedef struct BCinfo BCinfo; - struct -BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; }; - -#ifdef KR_headers -#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) -#else -#define FFFFFFFF 0xffffffffUL -#endif - -#ifdef NO_LONG_LONG -#undef ULLong -#ifdef Just_16 -#undef Pack_32 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#endif -#else /* long long available */ -#ifndef Llong -#define Llong long long -#endif -#ifndef ULLong -#define ULLong unsigned Llong -#endif -#endif /* NO_LONG_LONG */ - -#ifndef MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ -#define FREE_DTOA_LOCK(n) /*nothing*/ -#endif - -#define Kmax 7 - -#ifdef __cplusplus -extern "C" double strtod(const char *s00, char **se); -extern "C" char *dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve); -#endif - - struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; - - typedef struct Bigint Bigint; - - static Bigint *freelist[Kmax+1]; - - static Bigint * -Balloc -#ifdef KR_headers - (k) int k; -#else - (int k) -#endif -{ - int x; - Bigint *rv; -#ifndef Omit_Private_Memory - unsigned int len; -#endif - - ACQUIRE_DTOA_LOCK(0); - /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ - /* but this case seems very unlikely. */ - if (k <= Kmax && (rv = freelist[k])) - freelist[k] = rv->next; - else { - x = 1 << k; -#ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); -#else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } - else - rv = (Bigint*)MALLOC(len*sizeof(double)); -#endif - rv->k = k; - rv->maxwds = x; - } - FREE_DTOA_LOCK(0); - rv->sign = rv->wds = 0; - return rv; - } - - static void -Bfree -#ifdef KR_headers - (v) Bigint *v; -#else - (Bigint *v) -#endif -{ - if (v) { - if (v->k > Kmax) -#ifdef FREE - FREE((void*)v); -#else - free((void*)v); -#endif - else { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); - } - } - } - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) - - static Bigint * -multadd -#ifdef KR_headers - (b, m, a) Bigint *b; int m, a; -#else - (Bigint *b, int m, int a) /* multiply by m and add a */ -#endif -{ - int i, wds; -#ifdef ULLong - ULong *x; - ULLong carry, y; -#else - ULong carry, *x, y; -#ifdef Pack_32 - ULong xi, z; -#endif -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { -#ifdef ULLong - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + carry; - z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif -#endif - } - while(++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = carry; - b->wds = wds; - } - return b; - } - - static Bigint * -s2b -#ifdef KR_headers - (s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9; -#else - (const char *s, int nd0, int nd, ULong y9, int dplen) -#endif -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s += dplen; - } - else - s += dplen + 9; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - static int -hi0bits -#ifdef KR_headers - (x) ULong x; -#else - (ULong x) -#endif -{ - int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; - } - - static int -lo0bits -#ifdef KR_headers - (y) ULong *y; -#else - (ULong *y) -#endif -{ - int k; - ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; - return k; - } - - static Bigint * -i2b -#ifdef KR_headers - (i) int i; -#else - (int i) -#endif -{ - Bigint *b; - - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; - } - - static Bigint * -mult -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; -#ifdef ULLong - ULLong carry, z; -#else - ULong carry, z; -#ifdef Pack_32 - ULong z2; -#endif -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; -#ifdef ULLong - for(; xb < xbe; xc0++) { - if ((y = *xb++)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = z & FFFFFFFF; - } - while(x < xae); - *xc = carry; - } - } -#else -#ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if (y = *xb & 0xffff) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if (y = *xb >> 16) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } - - static Bigint *p5s; - - static Bigint * -pow5mult -#ifdef KR_headers - (b, k) Bigint *b; int k; -#else - (Bigint *b, int k) -#endif -{ - Bigint *b1, *p5, *p51; - int i; - static int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3)) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p5 = p5s)) { - p5 = p5s = i2b(625); - p5->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p5 = p5s = i2b(625); - p5->next = 0; -#endif - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p51 = p5->next = mult(p5,p5); - p51->next = 0; -#endif - } - p5 = p51; - } - return b; - } - - static Bigint * -lshift -#ifdef KR_headers - (b, k) Bigint *b; int k; -#else - (Bigint *b, int k) -#endif -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if ((*x1 = z)) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; - } - - static int -cmp -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; - } - - static Bigint * -diff -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef ULLong - ULLong borrow, y; -#else - ULong borrow, y; -#ifdef Pack_32 - ULong z; -#endif -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; -#ifdef ULLong - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } -#else -#ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } - - static double -ulp -#ifdef KR_headers - (x) U *x; -#else - (U *x) -#endif -{ - Long L; - U u; - - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#endif -#ifdef IBM - L |= Exp_msk1 >> 4; -#endif - word0(&u) = L; - word1(&u) = 0; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(&u) = 0x80000 >> L; - word1(&u) = 0; - } - else { - word0(&u) = 0; - L -= Exp_shift; - word1(&u) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif - return dval(&u); - } - - static double -b2d -#ifdef KR_headers - (a, e) Bigint *a; int *e; -#else - (Bigint *a, int *e) -#endif -{ - ULong *xa, *xa0, w, y, z; - int k; - U d; -#ifdef VAX - ULong d0, d1; -#else -#define d0 word0(&d) -#define d1 word1(&d) -#endif - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; -#ifdef Pack_32 - if (k < Ebits) { - d0 = Exp_1 | y >> (Ebits - k); - w = xa > xa0 ? *--xa : 0; - d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> (32 - k); - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> (32 - k); - } - else { - d0 = Exp_1 | y; - d1 = z; - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif - ret_d: -#ifdef VAX - word0(&d) = d0 >> 16 | d0 << 16; - word1(&d) = d1 >> 16 | d1 << 16; -#else -#undef d0 -#undef d1 -#endif - return dval(&d); - } - - static Bigint * -d2b -#ifdef KR_headers - (d, e, bits) U *d; int *e, *bits; -#else - (U *d, int *e, int *bits) -#endif -{ - Bigint *b; - int de, k; - ULong *x, y, z; -#ifndef Sudden_Underflow - int i; -#endif -#ifdef VAX - ULong d0, d1; - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - -#ifdef Pack_32 - b = Balloc(1); -#else - b = Balloc(2); -#endif - x = b->x; - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); -#ifndef IBM - z |= Exp_msk11; -#endif -#else - if ((de = (int)(d0 >> Exp_shift))) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - if ((y = d1)) { - if ((k = lo0bits(&y))) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; -#ifndef Sudden_Underflow - i = -#endif - b->wds = (x[1] = z) ? 2 : 1; - } - else { - k = lo0bits(&z); - x[0] = z; -#ifndef Sudden_Underflow - i = -#endif - b->wds = 1; - k += 32; - } -#else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; -#endif -#ifndef Sudden_Underflow - if (de) { -#endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); -#else - *e = de - Bias - (P-1) + k; - *bits = P - k; -#endif -#ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif - } -#endif - return b; - } -#undef d0 -#undef d1 - - static double -ratio -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - U da, db; - int k, ka, kb; - - dval(&da) = b2d(a, &ka); - dval(&db) = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - word0(&da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(&da) *= 1 << k; - } - else { - k = -k; - word0(&db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(&db) *= 1 << k; - } -#else - if (k > 0) - word0(&da) += k*Exp_msk1; - else { - k = -k; - word0(&db) += k*Exp_msk1; - } -#endif - return dval(&da) / dval(&db); - } - - static CONST double -tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif - }; - - static CONST double -#ifdef IEEE_Arith -bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, -#ifdef Avoid_Underflow - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-256 */ -#else - 1e-256 -#endif - }; -/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ -/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ -#define Scale_Bit 0x10 -#define n_bigtens 5 -#else -#ifdef IBM -bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - -#undef Need_Hexdig -#ifdef INFNAN_CHECK -#ifndef No_Hex_NaN -#define Need_Hexdig -#endif -#endif - -#ifndef Need_Hexdig -#ifndef NO_HEX_FP -#define Need_Hexdig -#endif -#endif - -#ifdef Need_Hexdig /*{*/ -static unsigned char hexdig[256]; - - static void -#ifdef KR_headers -htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; -#else -htinit(unsigned char *h, unsigned char *s, int inc) -#endif -{ - int i, j; - for(i = 0; (j = s[i]) !=0; i++) - h[j] = i + inc; - } - - static void -#ifdef KR_headers -hexdig_init() -#else -hexdig_init(void) -#endif -{ -#define USC (unsigned char *) - htinit(hexdig, USC "0123456789", 0x10); - htinit(hexdig, USC "abcdef", 0x10 + 10); - htinit(hexdig, USC "ABCDEF", 0x10 + 10); - } -#endif /* } Need_Hexdig */ - -#ifdef INFNAN_CHECK - -#ifndef NAN_WORD0 -#define NAN_WORD0 0x7ff80000 -#endif - -#ifndef NAN_WORD1 -#define NAN_WORD1 0 -#endif - - static int -match -#ifdef KR_headers - (sp, t) char **sp, *t; -#else - (const char **sp, const char *t) -#endif -{ - int c, d; - CONST char *s = *sp; - - while((d = *t++)) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; - } - -#ifndef No_Hex_NaN - static void -hexnan -#ifdef KR_headers - (rvp, sp) U *rvp; CONST char **sp; -#else - (U *rvp, const char **sp) -#endif -{ - ULong c, x[2]; - CONST char *s; - int c1, havedig, udx0, xshift; - - if (!hexdig['0']) - hexdig_init(); - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - /* allow optional initial 0x or 0X */ - while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') - ++s; - if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) - s += 2; - while((c = *(CONST unsigned char*)++s)) { - if ((c1 = hexdig[c])) - c = c1 & 0xf; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } -#ifdef GDTOA_NON_PEDANTIC_NANCHECK - else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } - else - return; /* invalid form: don't change *sp */ -#else - else { - do { - if (/*(*/ c == ')') { - *sp = s + 1; - break; - } - } while((c = *++s)); - break; - } -#endif - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(rvp) = Exp_mask | x[0]; - word1(rvp) = x[1]; - } - } -#endif /*No_Hex_NaN*/ -#endif /* INFNAN_CHECK */ - -#ifdef Pack_32 -#define ULbits 32 -#define kshift 5 -#define kmask 31 -#else -#define ULbits 16 -#define kshift 4 -#define kmask 15 -#endif - -#if !defined(NO_HEX_FP) || defined(Honor_FLT_ROUNDS) /*{*/ - static Bigint * -#ifdef KR_headers -increment(b) Bigint *b; -#else -increment(Bigint *b) -#endif -{ - ULong *x, *xe; - Bigint *b1; - - x = b->x; - xe = x + b->wds; - do { - if (*x < (ULong)0xffffffffL) { - ++*x; - return b; - } - *x++ = 0; - } while(x < xe); - { - if (b->wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1,b); - Bfree(b); - b = b1; - } - b->x[b->wds++] = 1; - } - return b; - } - -#endif /*}*/ - -#ifndef NO_HEX_FP /*{*/ - - static void -#ifdef KR_headers -rshift(b, k) Bigint *b; int k; -#else -rshift(Bigint *b, int k) -#endif -{ - ULong *x, *x1, *xe, y; - int n; - - x = x1 = b->x; - n = k >> kshift; - if (n < b->wds) { - xe = x + b->wds; - x += n; - if (k &= kmask) { - n = 32 - k; - y = *x++ >> k; - while(x < xe) { - *x1++ = (y | (*x << n)) & 0xffffffff; - y = *x++ >> k; - } - if ((*x1 = y) !=0) - x1++; - } - else - while(x < xe) - *x1++ = *x++; - } - if ((b->wds = x1 - b->x) == 0) - b->x[0] = 0; - } - - static ULong -#ifdef KR_headers -any_on(b, k) Bigint *b; int k; -#else -any_on(Bigint *b, int k) -#endif -{ - int n, nwds; - ULong *x, *x0, x1, x2; - - x = b->x; - nwds = b->wds; - n = k >> kshift; - if (n > nwds) - n = nwds; - else if (n < nwds && (k &= kmask)) { - x1 = x2 = x[n]; - x1 >>= k; - x1 <<= k; - if (x1 != x2) - return 1; - } - x0 = x; - x += n; - while(x > x0) - if (*--x) - return 1; - return 0; - } - -enum { /* rounding values: same as FLT_ROUNDS */ - Round_zero = 0, - Round_near = 1, - Round_up = 2, - Round_down = 3 - }; - - void -#ifdef KR_headers -gethex(sp, rvp, rounding, sign) - CONST char **sp; U *rvp; int rounding, sign; -#else -gethex( CONST char **sp, U *rvp, int rounding, int sign) -#endif -{ - Bigint *b; - CONST unsigned char *decpt, *s0, *s, *s1; - Long e, e1; - ULong L, lostbits, *x; - int big, denorm, esign, havedig, k, n, nbits, up, zret; -#ifdef IBM - int j; -#endif - enum { -#ifdef IEEE_Arith /*{{*/ - emax = 0x7fe - Bias - P + 1, - emin = Emin - P + 1 -#else /*}{*/ - emin = Emin - P, -#ifdef VAX - emax = 0x7ff - Bias - P + 1 -#endif -#ifdef IBM - emax = 0x7f - Bias - P -#endif -#endif /*}}*/ - }; -#ifdef USE_LOCALE - int i; -#ifdef NO_LOCALE_CACHE - const unsigned char *decimalpoint = (unsigned char*) - localeconv()->decimal_point; -#else - const unsigned char *decimalpoint; - static unsigned char *decimalpoint_cache; - if (!(s0 = decimalpoint_cache)) { - s0 = (unsigned char*)localeconv()->decimal_point; - if ((decimalpoint_cache = (unsigned char*) - MALLOC(strlen((CONST char*)s0) + 1))) { - strcpy((char*)decimalpoint_cache, (CONST char*)s0); - s0 = decimalpoint_cache; - } - } - decimalpoint = s0; -#endif -#endif - - if (!hexdig['0']) - hexdig_init(); - havedig = 0; - s0 = *(CONST unsigned char **)sp + 2; - while(s0[havedig] == '0') - havedig++; - s0 += havedig; - s = s0; - decpt = 0; - zret = 0; - e = 0; - if (hexdig[*s]) - havedig++; - else { - zret = 1; -#ifdef USE_LOCALE - for(i = 0; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; -#else - if (*s != '.') - goto pcheck; - decpt = ++s; -#endif - if (!hexdig[*s]) - goto pcheck; - while(*s == '0') - s++; - if (hexdig[*s]) - zret = 0; - havedig = 1; - s0 = s; - } - while(hexdig[*s]) - s++; -#ifdef USE_LOCALE - if (*s == *decimalpoint && !decpt) { - for(i = 1; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; -#else - if (*s == '.' && !decpt) { - decpt = ++s; -#endif - while(hexdig[*s]) - s++; - }/*}*/ - if (decpt) - e = -(((Long)(s-decpt)) << 2); - pcheck: - s1 = s; - big = esign = 0; - switch(*s) { - case 'p': - case 'P': - switch(*++s) { - case '-': - esign = 1; - /* no break */ - case '+': - s++; - } - if ((n = hexdig[*s]) == 0 || n > 0x19) { - s = s1; - break; - } - e1 = n - 0x10; - while((n = hexdig[*++s]) !=0 && n <= 0x19) { - if (e1 & 0xf8000000) - big = 1; - e1 = 10*e1 + n - 0x10; - } - if (esign) - e1 = -e1; - e += e1; - } - *sp = (char*)s; - if (!havedig) - *sp = (char*)s0 - 1; - if (zret) - goto retz1; - if (big) { - if (esign) { -#ifdef IEEE_Arith - switch(rounding) { - case Round_up: - if (sign) - break; - goto ret_tiny; - case Round_down: - if (!sign) - break; - goto ret_tiny; - } -#endif - goto retz; -#ifdef IEEE_Arith - ret_tiny: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = 0; - word1(rvp) = 1; - return; -#endif /* IEEE_Arith */ - } - switch(rounding) { - case Round_near: - goto ovfl1; - case Round_up: - if (!sign) - goto ovfl1; - goto ret_big; - case Round_down: - if (sign) - goto ovfl1; - goto ret_big; - } - ret_big: - word0(rvp) = Big0; - word1(rvp) = Big1; - return; - } - n = s1 - s0 - 1; - for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) - k++; - b = Balloc(k); - x = b->x; - n = 0; - L = 0; -#ifdef USE_LOCALE - for(i = 0; decimalpoint[i+1]; ++i); -#endif - while(s1 > s0) { -#ifdef USE_LOCALE - if (*--s1 == decimalpoint[i]) { - s1 -= i; - continue; - } -#else - if (*--s1 == '.') - continue; -#endif - if (n == ULbits) { - *x++ = L; - L = 0; - n = 0; - } - L |= (hexdig[*s1] & 0x0f) << n; - n += 4; - } - *x++ = L; - b->wds = n = x - b->x; - n = ULbits*n - hi0bits(L); - nbits = Nbits; - lostbits = 0; - x = b->x; - if (n > nbits) { - n -= nbits; - if (any_on(b,n)) { - lostbits = 1; - k = n - 1; - if (x[k>>kshift] & 1 << (k & kmask)) { - lostbits = 2; - if (k > 0 && any_on(b,k)) - lostbits = 3; - } - } - rshift(b, n); - e += n; - } - else if (n < nbits) { - n = nbits - n; - b = lshift(b, n); - e -= n; - x = b->x; - } - if (e > Emax) { - ovfl: - Bfree(b); - ovfl1: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = Exp_mask; - word1(rvp) = 0; - return; - } - denorm = 0; - if (e < emin) { - denorm = 1; - n = emin - e; - if (n >= nbits) { -#ifdef IEEE_Arith /*{*/ - switch (rounding) { - case Round_near: - if (n == nbits && (n < 2 || any_on(b,n-1))) - goto ret_tiny; - break; - case Round_up: - if (!sign) - goto ret_tiny; - break; - case Round_down: - if (sign) - goto ret_tiny; - } -#endif /* } IEEE_Arith */ - Bfree(b); - retz: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - retz1: - rvp->d = 0.; - return; - } - k = n - 1; - if (lostbits) - lostbits = 1; - else if (k > 0) - lostbits = any_on(b,k); - if (x[k>>kshift] & 1 << (k & kmask)) - lostbits |= 2; - nbits -= n; - rshift(b,n); - e = emin; - } - if (lostbits) { - up = 0; - switch(rounding) { - case Round_zero: - break; - case Round_near: - if (lostbits & 2 - && (lostbits & 1) | (x[0] & 1)) - up = 1; - break; - case Round_up: - up = 1 - sign; - break; - case Round_down: - up = sign; - } - if (up) { - k = b->wds; - b = increment(b); - x = b->x; - if (denorm) { -#if 0 - if (nbits == Nbits - 1 - && x[nbits >> kshift] & 1 << (nbits & kmask)) - denorm = 0; /* not currently used */ -#endif - } - else if (b->wds > k - || ((n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n)) { - rshift(b,1); - if (++e > Emax) - goto ovfl; - } - } - } -#ifdef IEEE_Arith - if (denorm) - word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0; - else - word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20); - word1(rvp) = b->x[0]; -#endif -#ifdef IBM - if ((j = e & 3)) { - k = b->x[0] & ((1 << j) - 1); - rshift(b,j); - if (k) { - switch(rounding) { - case Round_up: - if (!sign) - increment(b); - break; - case Round_down: - if (sign) - increment(b); - break; - case Round_near: - j = 1 << (j-1); - if (k & j && ((k & (j-1)) | lostbits)) - increment(b); - } - } - } - e >>= 2; - word0(rvp) = b->x[1] | ((e + 65 + 13) << 24); - word1(rvp) = b->x[0]; -#endif -#ifdef VAX - /* The next two lines ignore swap of low- and high-order 2 bytes. */ - /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */ - /* word1(rvp) = b->x[0]; */ - word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16); - word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16); -#endif - Bfree(b); - } -#endif /*!NO_HEX_FP}*/ - - static int -#ifdef KR_headers -dshift(b, p2) Bigint *b; int p2; -#else -dshift(Bigint *b, int p2) -#endif -{ - int rv = hi0bits(b->x[b->wds-1]) - 4; - if (p2 > 0) - rv -= p2; - return rv & kmask; - } - - static int -quorem -#ifdef KR_headers - (b, S) Bigint *b, *S; -#else - (Bigint *b, Bigint *S) -#endif -{ - int n; - ULong *bx, *bxe, q, *sx, *sxe; -#ifdef ULLong - ULLong borrow, carry, y, ys; -#else - ULong borrow, carry, y, ys; -#ifdef Pack_32 - ULong si, z, zs; -#endif -#endif - - n = S->wds; -#ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef DEBUG -#ifdef NO_STRTOD_BIGCOMP - /*debug*/ if (q > 9) -#else - /* An oversized q is possible when quorem is called from bigcomp and */ - /* the input is near, e.g., twice the smallest denormalized number. */ - /*debug*/ if (q > 15) -#endif - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { -#ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } - -#if defined(Avoid_Underflow) || !defined(NO_STRTOD_BIGCOMP) /*{*/ - static double -sulp -#ifdef KR_headers - (x, bc) U *x; BCinfo *bc; -#else - (U *x, BCinfo *bc) -#endif -{ - U u; - double rv; - int i; - - rv = ulp(x); - if (!bc->scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) - return rv; /* Is there an example where i <= 0 ? */ - word0(&u) = Exp_1 + (i << Exp_shift); - word1(&u) = 0; - return rv * u.d; - } -#endif /*}*/ - -#ifndef NO_STRTOD_BIGCOMP - static void -bigcomp -#ifdef KR_headers - (rv, s0, bc) - U *rv; CONST char *s0; BCinfo *bc; -#else - (U *rv, const char *s0, BCinfo *bc) -#endif -{ - Bigint *b, *d; - int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; - - dsign = bc->dsign; - nd = bc->nd; - nd0 = bc->nd0; - p5 = nd + bc->e0 - 1; - speccase = 0; -#ifndef Sudden_Underflow - if (rv->d == 0.) { /* special case: value near underflow-to-zero */ - /* threshold was rounded to zero */ - b = i2b(1); - p2 = Emin - P + 1; - bbits = 1; -#ifdef Avoid_Underflow - word0(rv) = (P+2) << Exp_shift; -#else - word1(rv) = 1; -#endif - i = 0; -#ifdef Honor_FLT_ROUNDS - if (bc->rounding == 1) -#endif - { - speccase = 1; - --p2; - dsign = 0; - goto have_i; - } - } - else -#endif - b = d2b(rv, &p2, &bbits); -#ifdef Avoid_Underflow - p2 -= bc->scale; -#endif - /* floor(log2(rv)) == bbits - 1 + p2 */ - /* Check for denormal case. */ - i = P - bbits; - if (i > (j = P - Emin - 1 + p2)) { -#ifdef Sudden_Underflow - Bfree(b); - b = i2b(1); - p2 = Emin; - i = P - 1; -#ifdef Avoid_Underflow - word0(rv) = (1 + bc->scale) << Exp_shift; -#else - word0(rv) = Exp_msk1; -#endif - word1(rv) = 0; -#else - i = j; -#endif - } -#ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (i > 0) - b = lshift(b, i); - if (dsign) - b = increment(b); - } - else -#endif - { - b = lshift(b, ++i); - b->x[0] |= 1; - } -#ifndef Sudden_Underflow - have_i: -#endif - p2 -= p5 + i; - d = i2b(1); - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - */ - if (p5 > 0) - d = pow5mult(d, p5); - else if (p5 < 0) - b = pow5mult(b, -p5); - if (p2 > 0) { - b2 = p2; - d2 = 0; - } - else { - b2 = 0; - d2 = -p2; - } - i = dshift(d, d2); - if ((b2 += i) > 0) - b = lshift(b, b2); - if ((d2 += i) > 0) - d = lshift(d, d2); - - /* Now b/d = exactly half-way between the two floating-point values */ - /* on either side of the input string. Compute first digit of b/d. */ - - if (!(dig = quorem(b,d))) { - b = multadd(b, 10, 0); /* very unlikely */ - dig = quorem(b,d); - } - - /* Compare b/d with s0 */ - - for(i = 0; i < nd0; ) { - if ((dd = s0[i++] - '0' - dig)) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - dig = quorem(b,d); - } - for(j = bc->dp1; i++ < nd;) { - if ((dd = s0[j++] - '0' - dig)) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - dig = quorem(b,d); - } - if (b->x[0] || b->wds > 1 || dig > 0) - dd = -1; - ret: - Bfree(b); - Bfree(d); -#ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (dd < 0) { - if (bc->rounding == 0) { - if (!dsign) - goto retlow1; - } - else if (dsign) - goto rethi1; - } - else if (dd > 0) { - if (bc->rounding == 0) { - if (dsign) - goto rethi1; - goto ret1; - } - if (!dsign) - goto rethi1; - dval(rv) += 2.*sulp(rv,bc); - } - else { - bc->inexact = 0; - if (dsign) - goto rethi1; - } - } - else -#endif - if (speccase) { - if (dd <= 0) - rv->d = 0.; - } - else if (dd < 0) { - if (!dsign) /* does not happen for round-near */ -retlow1: - dval(rv) -= sulp(rv,bc); - } - else if (dd > 0) { - if (dsign) { - rethi1: - dval(rv) += sulp(rv,bc); - } - } - else { - /* Exact half-way case: apply round-even rule. */ - if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) { - i = 1 - j; - if (i <= 31) { - if (word1(rv) & (0x1 << i)) - goto odd; - } - else if (word0(rv) & (0x1 << (i-32))) - goto odd; - } - else if (word1(rv) & 1) { - odd: - if (dsign) - goto rethi1; - goto retlow1; - } - } - -#ifdef Honor_FLT_ROUNDS - ret1: -#endif - return; - } -#endif /* NO_STRTOD_BIGCOMP */ - - double -strtod -#ifdef KR_headers - (s00, se) CONST char *s00; char **se; -#else - (const char *s00, char **se) -#endif -{ - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; - int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1; - Long L; - U aadj2, adj, rv, rv0; - ULong y, z; - BCinfo bc; - Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; -#ifdef Avoid_Underflow - ULong Lsb, Lsb1; -#endif -#ifdef SET_INEXACT - int oldinexact; -#endif -#ifndef NO_STRTOD_BIGCOMP - int req_bigcomp = 0; -#endif -#ifdef Honor_FLT_ROUNDS /*{*/ -#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - bc.rounding = Flt_Rounds; -#else /*}{*/ - bc.rounding = 1; - switch(fegetround()) { - case FE_TOWARDZERO: bc.rounding = 0; break; - case FE_UPWARD: bc.rounding = 2; break; - case FE_DOWNWARD: bc.rounding = 3; - } -#endif /*}}*/ -#endif /*}*/ -#ifdef USE_LOCALE - CONST char *s2; -#endif - - sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0; - dval(&rv) = 0.; - for(s = s00;;s++) switch(*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } - break2: - if (*s == '0') { -#ifndef NO_HEX_FP /*{*/ - switch(s[1]) { - case 'x': - case 'X': -#ifdef Honor_FLT_ROUNDS - gethex(&s, &rv, bc.rounding, sign); -#else - gethex(&s, &rv, 1, sign); -#endif - goto ret; - } -#endif /*}*/ - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; - bc.dp0 = bc.dp1 = s - s0; - for(s1 = s; s1 > s0 && *--s1 == '0'; ) - ++nz1; -#ifdef USE_LOCALE - s1 = localeconv()->decimal_point; - if (c == *s1) { - c = '.'; - if (*++s1) { - s2 = s; - for(;;) { - if (*++s2 != *s1) { - c = 0; - break; - } - if (!*++s1) { - s = s2; - break; - } - } - } - } -#endif - if (c == '.') { - c = *++s; - bc.dp1 = s - s0; - bc.dplen = bc.dp1 - bc.dp0; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - bc.dp0 = s0 - s; - bc.dp1 = bc.dp0 + bc.dplen; - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = nz1 = 0; - } - } - } - dig_done: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - goto ret0; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { -#ifdef INFNAN_CHECK - /* Check for Nan and Infinity */ - if (!bc.dplen) - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(&rv) = 0x7ff00000; - word1(&rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; -#ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); -#endif - goto ret; - } - } -#endif /* INFNAN_CHECK */ - ret0: - s = s00; - sign = 0; - } - goto ret; - } - bc.e0 = e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(&rv) = y; - if (k > 9) { -#ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); -#endif - dval(&rv) = tens[k - 9] * dval(&rv) + z; - } - bd0 = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT -#ifndef Honor_FLT_ROUNDS - && Flt_Rounds == 1 -#endif -#endif - ) { - if (!e) - goto ret; -#ifndef ROUND_BIASED_without_Round_Up - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif - /* rv = */ rounded_product(dval(&rv), tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif - e -= i; - dval(&rv) *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - word0(&rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(&rv), tens[e]); - if ((word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(&rv) += P*Exp_msk1; -#else - /* rv = */ rounded_product(dval(&rv), tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif - /* rv = */ rounded_quotient(dval(&rv), tens[-e]); - goto ret; - } -#endif -#endif /* ROUND_BIASED_without_Round_Up */ - } - e1 += nd - k; - -#ifdef IEEE_Arith -#ifdef SET_INEXACT - bc.inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); -#endif -#ifdef Avoid_Underflow - bc.scale = 0; -#endif -#ifdef Honor_FLT_ROUNDS - if (bc.rounding >= 2) { - if (sign) - bc.rounding = bc.rounding == 2 ? 0 : 2; - else - if (bc.rounding != 2) - bc.rounding = 0; - } -#endif -#endif /*IEEE_Arith*/ - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if ((i = e1 & 15)) - dval(&rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith -#ifdef Honor_FLT_ROUNDS - switch(bc.rounding) { - case 0: /* toward 0 */ - case 3: /* toward -infinity */ - word0(&rv) = Big0; - word1(&rv) = Big1; - break; - default: - word0(&rv) = Exp_mask; - word1(&rv) = 0; - } -#else /*Honor_FLT_ROUNDS*/ - word0(&rv) = Exp_mask; - word1(&rv) = 0; -#endif /*Honor_FLT_ROUNDS*/ -#ifdef SET_INEXACT - /* set overflow bit */ - dval(&rv0) = 1e300; - dval(&rv0) *= dval(&rv0); -#endif -#else /*IEEE_Arith*/ - word0(&rv) = Big0; - word1(&rv) = Big1; -#endif /*IEEE_Arith*/ - range_err: - if (bd0) { - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - } -#ifndef NO_ERRNO - errno = ERANGE; -#endif - goto ret; - } - e1 >>= 4; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(&rv) -= P*Exp_msk1; - dval(&rv) *= bigtens[j]; - if ((z = word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(&rv) = Big0; - word1(&rv) = Big1; - } - else - word0(&rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - e1 = -e1; - if ((i = e1 & 15)) - dval(&rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; -#ifdef Avoid_Underflow - if (e1 & Scale_Bit) - bc.scale = 2*P; - for(j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; clear j low bits */ - if (j >= 32) { - if (j > 54) - goto undfl; - word1(&rv) = 0; - if (j >= 53) - word0(&rv) = (P+2)*Exp_msk1; - else - word0(&rv) &= 0xffffffff << (j-32); - } - else - word1(&rv) &= 0xffffffff << j; - } -#else - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(&rv0) = dval(&rv); - dval(&rv) *= tinytens[j]; - if (!dval(&rv)) { - dval(&rv) = 2.*dval(&rv0); - dval(&rv) *= tinytens[j]; -#endif - if (!dval(&rv)) { - undfl: - dval(&rv) = 0.; - goto range_err; - } -#ifndef Avoid_Underflow - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bc.nd = nd - nz1; -#ifndef NO_STRTOD_BIGCOMP - bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ - /* to silence an erroneous warning about bc.nd0 */ - /* possibly not being initialized. */ - if (nd > strtod_diglim) { - /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ - /* minimum number of decimal digits to distinguish double values */ - /* in IEEE arithmetic. */ - i = j = 18; - if (i > nd0) - j += bc.dplen; - for(;;) { - if (--j < bc.dp1 && j >= bc.dp0) - j = bc.dp0 - 1; - if (s0[j] != '0') - break; - --i; - } - e += nd - i; - nd = i; - if (nd0 > nd) - nd0 = nd; - if (nd < 9) { /* must recompute y */ - y = 0; - for(i = 0; i < nd0; ++i) - y = 10*y + s0[i] - '0'; - for(j = bc.dp1; i < nd; ++i) - y = 10*y + s0[j++] - '0'; - } - } -#endif - bd0 = s2b(s0, nd0, nd, y, bc.dplen); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) - bs2++; -#endif -#ifdef Avoid_Underflow - Lsb = LSB; - Lsb1 = 0; - j = bbe - bc.scale; - i = j + bbbits - 1; /* logb(rv) */ - j = P + 1 - bbbits; - if (i < Emin) { /* denormal */ - i = Emin - i; - j -= i; - if (i < 32) - Lsb <<= i; - else if (i < 52) - Lsb1 = Lsb << (i-32); - else - Lsb1 = Exp_mask; - } -#else /*Avoid_Underflow*/ -#ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - bb2 += j; - bd2 += j; -#ifdef Avoid_Underflow - bd2 += bc.scale; -#endif - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - bc.dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); -#ifndef NO_STRTOD_BIGCOMP /*{*/ - if (bc.nd > nd && i <= 0) { - if (bc.dsign) { - /* Must use bigcomp(). */ - req_bigcomp = 1; - break; - } -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) { - if (i < 0) { - req_bigcomp = 1; - break; - } - } - else -#endif - i = -1; /* Discarded digits make delta smaller. */ - } -#endif /*}*/ -#ifdef Honor_FLT_ROUNDS /*{*/ - if (bc.rounding != 1) { - if (i < 0) { - /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) { - /* exact */ -#ifdef SET_INEXACT - bc.inexact = 0; -#endif - break; - } - if (bc.rounding) { - if (bc.dsign) { - adj.d = 1.; - goto apply_adj; - } - } - else if (!bc.dsign) { - adj.d = -1.; - if (!word1(&rv) - && !(word0(&rv) & Frac_mask)) { - y = word0(&rv) & Exp_mask; -#ifdef Avoid_Underflow - if (!bc.scale || y > 2*P*Exp_msk1) -#else - if (y) -#endif - { - delta = lshift(delta,Log2P); - if (cmp(delta, bs) <= 0) - adj.d = -0.5; - } - } - apply_adj: -#ifdef Avoid_Underflow /*{*/ - if (bc.scale && (y = word0(&rv) & Exp_mask) - <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= - P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - dval(&rv) += adj.d*ulp(dval(&rv)); - word0(&rv) -= P*Exp_msk1; - } - else -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow}*/ - dval(&rv) += adj.d*ulp(&rv); - } - break; - } - adj.d = ratio(delta, bs); - if (adj.d < 1.) - adj.d = 1.; - if (adj.d <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj.d; - if (y != adj.d) { - if (!((bc.rounding>>1) ^ bc.dsign)) - y++; - adj.d = y; - } - } -#ifdef Avoid_Underflow /*{*/ - if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - adj.d *= ulp(dval(&rv)); - if (bc.dsign) - dval(&rv) += adj.d; - else - dval(&rv) -= adj.d; - word0(&rv) -= P*Exp_msk1; - goto cont; - } -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow}*/ - adj.d *= ulp(&rv); - if (bc.dsign) { - if (word0(&rv) == Big0 && word1(&rv) == Big1) - goto ovfl; - dval(&rv) += adj.d; - } - else - dval(&rv) -= adj.d; - goto cont; - } -#endif /*}Honor_FLT_ROUNDS*/ - - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask -#ifdef IEEE_Arith /*{*/ -#ifdef Avoid_Underflow - || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 -#else - || (word0(&rv) & Exp_mask) <= Exp_msk1 -#endif -#endif /*}*/ - ) { -#ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) - bc.inexact = 0; -#endif - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ -#ifdef SET_INEXACT - bc.inexact = 0; -#endif - break; - } - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (bc.dsign) { - if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 - && word1(&rv) == ( -#ifdef Avoid_Underflow - (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : -#endif - 0xffffffff)) { - /*boundary case -- increment exponent*/ - if (word0(&rv) == Big0 && word1(&rv) == Big1) - goto ovfl; - word0(&rv) = (word0(&rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ; - word1(&rv) = 0; -#ifdef Avoid_Underflow - bc.dsign = 0; -#endif - break; - } - } - else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { - drop_down: - /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow /*{{*/ - L = word0(&rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else -#ifdef Avoid_Underflow - if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) -#else - if (L <= Exp_msk1) -#endif /*Avoid_Underflow*/ -#endif /*IBM*/ - { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - L -= Exp_msk1; -#else /*Sudden_Underflow}{*/ -#ifdef Avoid_Underflow - if (bc.scale) { - L = word0(&rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - } -#endif /*Avoid_Underflow*/ - L = (word0(&rv) & Exp_mask) - Exp_msk1; -#endif /*Sudden_Underflow}}*/ - word0(&rv) = L | Bndry_mask1; - word1(&rv) = 0xffffffff; -#ifdef IBM - goto cont; -#else -#ifndef NO_STRTOD_BIGCOMP - if (bc.nd > nd) - goto cont; -#endif - break; -#endif - } -#ifndef ROUND_BIASED -#ifdef Avoid_Underflow - if (Lsb1) { - if (!(word0(&rv) & Lsb1)) - break; - } - else if (!(word1(&rv) & Lsb)) - break; -#else - if (!(word1(&rv) & LSB)) - break; -#endif -#endif - if (bc.dsign) -#ifdef Avoid_Underflow - dval(&rv) += sulp(&rv, &bc); -#else - dval(&rv) += ulp(&rv); -#endif -#ifndef ROUND_BIASED - else { -#ifdef Avoid_Underflow - dval(&rv) -= sulp(&rv, &bc); -#else - dval(&rv) -= ulp(&rv); -#endif -#ifndef Sudden_Underflow - if (!dval(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } -#endif - } -#ifdef Avoid_Underflow - bc.dsign = 1 - bc.dsign; -#endif -#endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (bc.dsign) - aadj = aadj1 = 1.; - else if (word1(&rv) || word0(&rv) & Bndry_mask) { -#ifndef Sudden_Underflow - if (word1(&rv) == Tiny1 && !word0(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = bc.dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch(bc.rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (Flt_Rounds == 0) - aadj1 += 0.5; -#endif /*Check_FLT_ROUNDS*/ - } - y = word0(&rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(&rv0) = dval(&rv); - word0(&rv) -= P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(&rv0) == Big0 && word1(&rv0) == Big1) - goto ovfl; - word0(&rv) = Big0; - word1(&rv) = Big1; - goto cont; - } - else - word0(&rv) += P*Exp_msk1; - } - else { -#ifdef Avoid_Underflow - if (bc.scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = aadj) <= 0) - z = 1; - aadj = z; - aadj1 = bc.dsign ? aadj : -aadj; - } - dval(&aadj2) = aadj1; - word0(&aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(&aadj2); - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if (rv.d == 0.) -#ifdef NO_STRTOD_BIGCOMP - goto undfl; -#else - { - if (bc.nd > nd) - bc.dsign = 1; - break; - } -#endif - } - else { - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - dval(&rv0) = dval(&rv); - word0(&rv) += P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; -#ifdef IBM - if ((word0(&rv) & Exp_mask) < P*Exp_msk1) -#else - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (word0(&rv0) == Tiny0 - && word1(&rv0) == Tiny1) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - goto cont; - } - else - word0(&rv) -= P*Exp_msk1; - } - else { - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } -#else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!bc.dsign) - aadj1 = -aadj1; - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - } - z = word0(&rv) & Exp_mask; -#ifndef SET_INEXACT - if (bc.nd == nd) { -#ifdef Avoid_Underflow - if (!bc.scale) -#endif - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } - } -#endif - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); -#ifndef NO_STRTOD_BIGCOMP - if (req_bigcomp) { - bd0 = 0; - bc.e0 += nz1; - bigcomp(&rv, s0, &bc); - y = word0(&rv) & Exp_mask; - if (y == Exp_mask) - goto ovfl; - if (y == 0 && rv.d == 0.) - goto undfl; - } -#endif -#ifdef SET_INEXACT - if (bc.inexact) { - if (!oldinexact) { - word0(&rv0) = Exp_1 + (70 << Exp_shift); - word1(&rv0) = 0; - dval(&rv0) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif -#ifdef Avoid_Underflow - if (bc.scale) { - word0(&rv0) = Exp_1 - 2*P*Exp_msk1; - word1(&rv0) = 0; - dval(&rv) *= dval(&rv0); -#ifndef NO_ERRNO - /* try to avoid the bug of testing an 8087 register value */ -#ifdef IEEE_Arith - if (!(word0(&rv) & Exp_mask)) -#else - if (word0(&rv) == 0 && word1(&rv) == 0) -#endif - errno = ERANGE; -#endif - } -#endif /* Avoid_Underflow */ -#ifdef SET_INEXACT - if (bc.inexact && !(word0(&rv) & Exp_mask)) { - /* set underflow bit */ - dval(&rv0) = 1e-300; - dval(&rv0) *= dval(&rv0); - } -#endif - ret: - if (se) - *se = (char *)s; - return sign ? -dval(&rv) : dval(&rv); - } - -#ifndef MULTIPLE_THREADS - static char *dtoa_result; -#endif - - static char * -#ifdef KR_headers -rv_alloc(i) int i; -#else -rv_alloc(int i) -#endif -{ - int j, k, *r; - - j = sizeof(ULong); - for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; - j <<= 1) - k++; - r = (int*)Balloc(k); - *r = k; - return -#ifndef MULTIPLE_THREADS - dtoa_result = -#endif - (char *)(r+1); - } - - static char * -#ifdef KR_headers -nrv_alloc(s, rve, n) char *s, **rve; int n; -#else -nrv_alloc(const char *s, char **rve, int n) -#endif -{ - char *rv, *t; - - t = rv = rv_alloc(n); - while((*t = *s++)) t++; - if (rve) - *rve = t; - return rv; - } - -/* freedtoa(s) must be used to free values s returned by dtoa - * when MULTIPLE_THREADS is #defined. It should be used in all cases, - * but for consistency with earlier versions of dtoa, it is optional - * when MULTIPLE_THREADS is not defined. - */ - - void -#ifdef KR_headers -freedtoa(s) char *s; -#else -freedtoa(char *s) -#endif -{ - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); -#ifndef MULTIPLE_THREADS - if (s == dtoa_result) - dtoa_result = 0; -#endif - } - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - char * -dtoa -#ifdef KR_headers - (dd, mode, ndigits, decpt, sign, rve) - double dd; int mode, ndigits, *decpt, *sign; char **rve; -#else - (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) -#endif -{ - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; -#ifndef Sudden_Underflow - int denorm; - ULong x; -#endif - Bigint *b, *b1, *delta, *mlo, *mhi, *S; - U d2, eps, u; - double ds; - char *s, *s0; -#ifndef No_leftright -#ifdef IEEE_Arith - U eps1; -#endif -#endif -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif -#ifdef Honor_FLT_ROUNDS /*{*/ - int Rounding; -#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - Rounding = Flt_Rounds; -#else /*}{*/ - Rounding = 1; - switch(fegetround()) { - case FE_TOWARDZERO: Rounding = 0; break; - case FE_UPWARD: Rounding = 2; break; - case FE_DOWNWARD: Rounding = 3; - } -#endif /*}}*/ -#endif /*}*/ - -#ifndef MULTIPLE_THREADS - if (dtoa_result) { - freedtoa(dtoa_result); - dtoa_result = 0; - } -#endif - - u.d = dd; - if (word0(&u) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(&u) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - -#if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith - if ((word0(&u) & Exp_mask) == Exp_mask) -#else - if (word0(&u) == 0x8000) -#endif - { - /* Infinity or NaN */ - *decpt = 9999; -#ifdef IEEE_Arith - if (!word1(&u) && !(word0(&u) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); -#endif - return nrv_alloc("NaN", rve, 3); - } -#endif -#ifdef IBM - dval(&u) += 0; /* normalize */ -#endif - if (!dval(&u)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } - -#ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; -#endif -#ifdef Honor_FLT_ROUNDS - if (Rounding >= 2) { - if (*sign) - Rounding = Rounding == 2 ? 0 : 2; - else - if (Rounding != 2) - Rounding = 0; - } -#endif - - b = d2b(&u, &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#else - if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { -#endif - dval(&d2) = dval(&u); - word0(&d2) &= Frac_mask1; - word0(&d2) |= Exp_11; -#ifdef IBM - if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) - dval(&d2) /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif -#ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) - : word1(&u) << (32 - i); - dval(&d2) = x; - word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(&u) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - -#ifndef SET_INEXACT -#ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; -#else - try_quick = 1; -#endif -#endif /*SET_INEXACT*/ - - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ - /* silence erroneous "gcc -Wall" warning. */ - switch(mode) { - case 0: - case 1: - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s = s0 = rv_alloc(i); - -#ifdef Honor_FLT_ROUNDS - if (mode > 1 && Rounding != 1) - leftright = 0; -#endif - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(&d2) = dval(&u); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(&u) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(&u) /= ds; - } - else if ((j1 = -k)) { - dval(&u) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(&u) *= bigtens[i]; - } - } - if (k_check && dval(&u) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(&u) *= 10.; - ieps++; - } - dval(&eps) = ieps*dval(&u) + 7.; - word0(&eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(&u) -= 5.; - if (dval(&u) > dval(&eps)) - goto one_digit; - if (dval(&u) < -dval(&eps)) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); -#ifdef IEEE_Arith - if (k0 < 0 && j1 >= 307) { - eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */ - word0(&eps1) -= Exp_msk1 * (Bias+P-1); - dval(&eps1) *= tens[j1 & 0xf]; - for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++) - if (j & 1) - dval(&eps1) *= bigtens[i]; - if (eps.d < eps1.d) - eps.d = eps1.d; - } -#endif - for(i = 0;;) { - L = dval(&u); - dval(&u) -= L; - *s++ = '0' + (int)L; - if (1. - dval(&u) < dval(&eps)) - goto bump_up; - if (dval(&u) < dval(&eps)) - goto ret1; - if (++i >= ilim) - break; - dval(&eps) *= 10.; - dval(&u) *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - dval(&eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u)); - if (!(dval(&u) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(&u) > 0.5 + dval(&eps)) - goto bump_up; - else if (dval(&u) < 0.5 - dval(&eps)) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } -#ifndef No_leftright - } -#endif - fast_failed: - s = s0; - dval(&u) = dval(&d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(&u) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u) / ds); - dval(&u) -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(&u) < 0) { - L--; - dval(&u) += ds; - } -#endif - *s++ = '0' + (int)L; - if (!dval(&u)) { -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (i == ilim) { -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(Rounding) { - case 0: goto ret1; - case 2: goto bump_up; - } -#endif - dval(&u) += dval(&u); -#ifdef ROUND_BIASED - if (dval(&u) >= ds) -#else - if (dval(&u) > ds || (dval(&u) == ds && L & 1)) -#endif - { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - if ((j = b5 - m5)) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) -#ifdef Honor_FLT_ROUNDS - && Rounding == 1 -#endif - ) { - if (!word1(&u) && !(word0(&u) & Bndry_mask) -#ifndef Sudden_Underflow - && word0(&u) & (Exp_mask & ~Exp_msk1) -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ - i = dshift(S, s2); - b2 += i; - m2 += i; - s2 += i; - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(&u) & 1) -#ifdef Honor_FLT_ROUNDS - && Rounding >= 1 -#endif - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; -#ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; -#endif - *s++ = dig; - goto ret; - } -#endif - if (j < 0 || (j == 0 && mode != 1 -#ifndef ROUND_BIASED - && !(word1(&u) & 1) -#endif - )) { - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto accept_dig; - } -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(Rounding) { - case 0: goto accept_dig; - case 2: goto keep_dig; - } -#endif /*Honor_FLT_ROUNDS*/ - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); -#ifdef ROUND_BIASED - if (j1 >= 0 /*)*/ -#else - if ((j1 > 0 || (j1 == 0 && dig & 1)) -#endif - && dig++ == '9') - goto round_9_up; - } - accept_dig: - *s++ = dig; - goto ret; - } - if (j1 > 0) { -#ifdef Honor_FLT_ROUNDS - if (!Rounding) - goto accept_dig; -#endif - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } -#ifdef Honor_FLT_ROUNDS - keep_dig: -#endif - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } - - /* Round off last digit */ - -#ifdef Honor_FLT_ROUNDS - switch(Rounding) { - case 0: goto trimzeros; - case 2: goto roundoff; - } -#endif - b = lshift(b, 1); - j = cmp(b, S); -#ifdef ROUND_BIASED - if (j >= 0) -#else - if (j > 0 || (j == 0 && dig & 1)) -#endif - { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { -#ifdef Honor_FLT_ROUNDS - trimzeros: -#endif - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(&u) = Exp_1 + (70 << Exp_shift); - word1(&u) = 0; - dval(&u) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - } -#ifdef __cplusplus -} -#endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/misc/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/Makefile.in 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CSRCS = \ - pralarm.c \ - pratom.c \ - prcountr.c \ - prdtoa.c \ - prenv.c \ - prerr.c \ - prerror.c \ - prerrortable.c \ - prinit.c \ - prinrval.c \ - pripc.c \ - prlog2.c \ - prlong.c \ - prnetdb.c \ - praton.c \ - prolock.c \ - prrng.c \ - prsystem.c \ - prtime.c \ - prthinfo.c \ - prtpool.c \ - prtrace.c \ - $(NULL) - -ifndef USE_PTHREADS -CSRCS += \ - pripcsem.c \ - $(NULL) -endif - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -RELEASE_BINS = $(srcdir)/compile-et.pl $(srcdir)/prerr.properties - -include $(topsrcdir)/config/rules.mk - -# Prevent floating point errors caused by MSVC 6.0 Processor Pack -# optimizations (bug 207421). This disables optimizations that -# could change the precision of floating-point calculations for -# this single compilation unit. -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) -$(OBJDIR)/prdtoa.$(OBJ_SUFFIX): prdtoa.c - @$(MAKE_OBJDIR) -ifeq (,$(filter-out 1100 1200 1300 1310,$(MSC_VER))) - $(CC) -Fo$@ -c $(CFLAGS) -Op $(call pr_abspath,$<) -else - $(CC) -Fo$@ -c $(CFLAGS) -fp:precise $(call pr_abspath,$<) -endif -endif - -# -# Generate prerr.h, prerr.c, and prerr.properties from prerr.et. -# -build_prerr: - cd $(srcdir); $(PERL) compile-et.pl prerr.et - -export:: $(TARGETS) - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/pralarm.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/pralarm.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/pralarm.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/pralarm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,246 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -/**********************************************************************/ -/******************************* PRALARM ******************************/ -/**********************************************************************/ - -#include "obsolete/pralarm.h" - -struct PRAlarmID { /* typedef'd in pralarm.h */ - PRCList list; /* circular list linkage */ - PRAlarm *alarm; /* back pointer to owning alarm */ - PRPeriodicAlarmFn function; /* function to call for notify */ - void *clientData; /* opaque client context */ - PRIntervalTime period; /* the client defined period */ - PRUint32 rate; /* rate of notification */ - - PRUint32 accumulator; /* keeps track of # notifies */ - PRIntervalTime epoch; /* when timer was started */ - PRIntervalTime nextNotify; /* when we'll next do our thing */ - PRIntervalTime lastNotify; /* when we last did our thing */ -}; - -typedef enum {alarm_active, alarm_inactive} _AlarmState; - -struct PRAlarm { /* typedef'd in pralarm.h */ - PRCList timers; /* base of alarm ids list */ - PRLock *lock; /* lock used to protect data */ - PRCondVar *cond; /* condition that used to wait */ - PRThread *notifier; /* thread to deliver notifies */ - PRAlarmID *current; /* current alarm being served */ - _AlarmState state; /* used to delete the alarm */ -}; - -static PRAlarmID *pr_getNextAlarm(PRAlarm *alarm, PRAlarmID *id) -{ -/* - * Puts 'id' back into the sorted list iff it's not NULL. - * Removes the first element from the list and returns it (or NULL). - * List is "assumed" to be short. - * - * NB: Caller is providing locking - */ - PRCList *timer; - PRAlarmID *result = id; - PRIntervalTime now = PR_IntervalNow(); - - if (!PR_CLIST_IS_EMPTY(&alarm->timers)) - { - if (id != NULL) /* have to put this id back in */ - { - PRIntervalTime idDelta = now - id->nextNotify; - timer = alarm->timers.next; - do - { - result = (PRAlarmID*)timer; - if ((PRIntervalTime)(now - result->nextNotify) > idDelta) - { - PR_INSERT_BEFORE(&id->list, &alarm->timers); - break; - } - timer = timer->next; - } while (timer != &alarm->timers); - } - result = (PRAlarmID*)(timer = PR_LIST_HEAD(&alarm->timers)); - PR_REMOVE_LINK(timer); /* remove it from the list */ - } - - return result; -} /* pr_getNextAlarm */ - -static PRIntervalTime pr_PredictNextNotifyTime(PRAlarmID *id) -{ - PRIntervalTime delta; - PRFloat64 baseRate = (PRFloat64)id->period / (PRFloat64)id->rate; - PRFloat64 offsetFromEpoch = (PRFloat64)id->accumulator * baseRate; - - id->accumulator += 1; /* every call advances to next period */ - id->lastNotify = id->nextNotify; /* just keeping track of things */ - id->nextNotify = (PRIntervalTime)(offsetFromEpoch + 0.5); - - delta = id->nextNotify - id->lastNotify; - return delta; -} /* pr_PredictNextNotifyTime */ - -static void PR_CALLBACK pr_alarmNotifier(void *arg) -{ - /* - * This is the root of the notifier thread. There is one such thread - * for each PRAlarm. It may service an arbitrary (though assumed to be - * small) number of alarms using the same thread and structure. It - * continues to run until the alarm is destroyed. - */ - PRAlarmID *id = NULL; - PRAlarm *alarm = (PRAlarm*)arg; - enum {notify, abort, scan} why = scan; - - while (why != abort) - { - PRIntervalTime pause; - - PR_Lock(alarm->lock); - while (why == scan) - { - alarm->current = NULL; /* reset current id */ - if (alarm->state == alarm_inactive) why = abort; /* we're toast */ - else if (why == scan) /* the dominant case */ - { - id = pr_getNextAlarm(alarm, id); /* even if it's the same */ - if (id == NULL) /* there are no alarms set */ - (void)PR_WaitCondVar(alarm->cond, PR_INTERVAL_NO_TIMEOUT); - else - { - pause = id->nextNotify - (PR_IntervalNow() - id->epoch); - if ((PRInt32)pause <= 0) /* is this one's time up? */ - { - why = notify; /* set up to do our thing */ - alarm->current = id; /* id we're about to schedule */ - } - else - (void)PR_WaitCondVar(alarm->cond, pause); /* dally */ - } - } - } - PR_Unlock(alarm->lock); - - if (why == notify) - { - (void)pr_PredictNextNotifyTime(id); - if (!id->function(id, id->clientData, ~pause)) - { - /* - * Notified function decided not to continue. Free - * the alarm id to make sure it doesn't get back on - * the list. - */ - PR_DELETE(id); /* free notifier object */ - id = NULL; /* so it doesn't get back into the list */ - } - why = scan; /* so we can cycle through the loop again */ - } - } - -} /* pr_alarm_notifier */ - -PR_IMPLEMENT(PRAlarm*) PR_CreateAlarm(void) -{ - PRAlarm *alarm = PR_NEWZAP(PRAlarm); - if (alarm != NULL) - { - if ((alarm->lock = PR_NewLock()) == NULL) goto done; - if ((alarm->cond = PR_NewCondVar(alarm->lock)) == NULL) goto done; - alarm->state = alarm_active; - PR_INIT_CLIST(&alarm->timers); - alarm->notifier = PR_CreateThread( - PR_USER_THREAD, pr_alarmNotifier, alarm, - PR_GetThreadPriority(PR_GetCurrentThread()), - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - if (alarm->notifier == NULL) goto done; - } - return alarm; - -done: - if (alarm->cond != NULL) PR_DestroyCondVar(alarm->cond); - if (alarm->lock != NULL) PR_DestroyLock(alarm->lock); - PR_DELETE(alarm); - return NULL; -} /* CreateAlarm */ - -PR_IMPLEMENT(PRStatus) PR_DestroyAlarm(PRAlarm *alarm) -{ - PRStatus rv; - - PR_Lock(alarm->lock); - alarm->state = alarm_inactive; - rv = PR_NotifyCondVar(alarm->cond); - PR_Unlock(alarm->lock); - - if (rv == PR_SUCCESS) - rv = PR_JoinThread(alarm->notifier); - if (rv == PR_SUCCESS) - { - PR_DestroyCondVar(alarm->cond); - PR_DestroyLock(alarm->lock); - PR_DELETE(alarm); - } - return rv; -} /* PR_DestroyAlarm */ - -PR_IMPLEMENT(PRAlarmID*) PR_SetAlarm( - PRAlarm *alarm, PRIntervalTime period, PRUint32 rate, - PRPeriodicAlarmFn function, void *clientData) -{ - /* - * Create a new periodic alarm an existing current structure. - * Set up the context and compute the first notify time (immediate). - * Link the new ID into the head of the list (since it's notifying - * immediately). - */ - - PRAlarmID *id = PR_NEWZAP(PRAlarmID); - - if (!id) - return NULL; - - id->alarm = alarm; - PR_INIT_CLIST(&id->list); - id->function = function; - id->clientData = clientData; - id->period = period; - id->rate = rate; - id->epoch = id->nextNotify = PR_IntervalNow(); - (void)pr_PredictNextNotifyTime(id); - - PR_Lock(alarm->lock); - PR_INSERT_BEFORE(&id->list, &alarm->timers); - PR_NotifyCondVar(alarm->cond); - PR_Unlock(alarm->lock); - - return id; -} /* PR_SetAlarm */ - -PR_IMPLEMENT(PRStatus) PR_ResetAlarm( - PRAlarmID *id, PRIntervalTime period, PRUint32 rate) -{ - /* - * Can only be called from within the notify routine. Doesn't - * need locking because it can only be called from within the - * notify routine. - */ - if (id != id->alarm->current) - return PR_FAILURE; - id->period = period; - id->rate = rate; - id->accumulator = 1; - id->epoch = PR_IntervalNow(); - (void)pr_PredictNextNotifyTime(id); - return PR_SUCCESS; -} /* PR_ResetAlarm */ - - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/pratom.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/pratom.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/pratom.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/pratom.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,379 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** PR Atomic operations -*/ - - -#include "pratom.h" -#include "primpl.h" - -#include - -/* - * The following is a fallback implementation that emulates - * atomic operations for platforms without atomic operations. - * If a platform has atomic operations, it should define the - * macro _PR_HAVE_ATOMIC_OPS, and the following will not be - * compiled in. - */ - -#if !defined(_PR_HAVE_ATOMIC_OPS) - -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) -/* - * PR_AtomicDecrement() is used in NSPR's thread-specific data - * destructor. Because thread-specific data destructors may be - * invoked after a PR_Cleanup() call, we need an implementation - * of the atomic routines that doesn't need NSPR to be initialized. - */ - -/* - * We use a set of locks for all the emulated atomic operations. - * By hashing on the address of the integer to be locked the - * contention between multiple threads should be lessened. - * - * The number of atomic locks can be set by the environment variable - * NSPR_ATOMIC_HASH_LOCKS - */ - -/* - * lock counts should be a power of 2 - */ -#define DEFAULT_ATOMIC_LOCKS 16 /* should be in sync with the number of initializers - below */ -#define MAX_ATOMIC_LOCKS (4 * 1024) - -static pthread_mutex_t static_atomic_locks[DEFAULT_ATOMIC_LOCKS] = { - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }; - -#ifdef DEBUG -static PRInt32 static_hash_lock_counts[DEFAULT_ATOMIC_LOCKS]; -static PRInt32 *hash_lock_counts = static_hash_lock_counts; -#endif - -static PRUint32 num_atomic_locks = DEFAULT_ATOMIC_LOCKS; -static pthread_mutex_t *atomic_locks = static_atomic_locks; -static PRUint32 atomic_hash_mask = DEFAULT_ATOMIC_LOCKS - 1; - -#define _PR_HASH_FOR_LOCK(ptr) \ - ((PRUint32) (((PRUptrdiff) (ptr) >> 2) ^ \ - ((PRUptrdiff) (ptr) >> 8)) & \ - atomic_hash_mask) - -void _PR_MD_INIT_ATOMIC() -{ -char *eval; -int index; - - - PR_ASSERT(PR_FloorLog2(MAX_ATOMIC_LOCKS) == - PR_CeilingLog2(MAX_ATOMIC_LOCKS)); - - PR_ASSERT(PR_FloorLog2(DEFAULT_ATOMIC_LOCKS) == - PR_CeilingLog2(DEFAULT_ATOMIC_LOCKS)); - - if (((eval = getenv("NSPR_ATOMIC_HASH_LOCKS")) != NULL) && - ((num_atomic_locks = atoi(eval)) != DEFAULT_ATOMIC_LOCKS)) { - - if (num_atomic_locks > MAX_ATOMIC_LOCKS) - num_atomic_locks = MAX_ATOMIC_LOCKS; - else if (num_atomic_locks < 1) - num_atomic_locks = 1; - else { - num_atomic_locks = PR_FloorLog2(num_atomic_locks); - num_atomic_locks = 1L << num_atomic_locks; - } - atomic_locks = (pthread_mutex_t *) PR_Malloc(sizeof(pthread_mutex_t) * - num_atomic_locks); - if (atomic_locks) { - for (index = 0; index < num_atomic_locks; index++) { - if (pthread_mutex_init(&atomic_locks[index], NULL)) { - PR_DELETE(atomic_locks); - atomic_locks = NULL; - break; - } - } - } -#ifdef DEBUG - if (atomic_locks) { - hash_lock_counts = PR_CALLOC(num_atomic_locks * sizeof(PRInt32)); - if (hash_lock_counts == NULL) { - PR_DELETE(atomic_locks); - atomic_locks = NULL; - } - } -#endif - if (atomic_locks == NULL) { - /* - * Use statically allocated locks - */ - atomic_locks = static_atomic_locks; - num_atomic_locks = DEFAULT_ATOMIC_LOCKS; - #ifdef DEBUG - hash_lock_counts = static_hash_lock_counts; - #endif - } - atomic_hash_mask = num_atomic_locks - 1; - } - PR_ASSERT(PR_FloorLog2(num_atomic_locks) == - PR_CeilingLog2(num_atomic_locks)); -} - -PRInt32 -_PR_MD_ATOMIC_INCREMENT(PRInt32 *val) -{ - PRInt32 rv; - PRInt32 idx = _PR_HASH_FOR_LOCK(val); - - pthread_mutex_lock(&atomic_locks[idx]); - rv = ++(*val); -#ifdef DEBUG - hash_lock_counts[idx]++; -#endif - pthread_mutex_unlock(&atomic_locks[idx]); - return rv; -} - -PRInt32 -_PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) -{ - PRInt32 rv; - PRInt32 idx = _PR_HASH_FOR_LOCK(ptr); - - pthread_mutex_lock(&atomic_locks[idx]); - rv = ((*ptr) += val); -#ifdef DEBUG - hash_lock_counts[idx]++; -#endif - pthread_mutex_unlock(&atomic_locks[idx]); - return rv; -} - -PRInt32 -_PR_MD_ATOMIC_DECREMENT(PRInt32 *val) -{ - PRInt32 rv; - PRInt32 idx = _PR_HASH_FOR_LOCK(val); - - pthread_mutex_lock(&atomic_locks[idx]); - rv = --(*val); -#ifdef DEBUG - hash_lock_counts[idx]++; -#endif - pthread_mutex_unlock(&atomic_locks[idx]); - return rv; -} - -PRInt32 -_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) -{ - PRInt32 rv; - PRInt32 idx = _PR_HASH_FOR_LOCK(val); - - pthread_mutex_lock(&atomic_locks[idx]); - rv = *val; - *val = newval; -#ifdef DEBUG - hash_lock_counts[idx]++; -#endif - pthread_mutex_unlock(&atomic_locks[idx]); - return rv; -} -#else /* _PR_PTHREADS && !_PR_DCETHREADS */ -/* - * We use a single lock for all the emulated atomic operations. - * The lock contention should be acceptable. - */ -static PRLock *atomic_lock = NULL; -void _PR_MD_INIT_ATOMIC(void) -{ - if (atomic_lock == NULL) { - atomic_lock = PR_NewLock(); - } -} - -PRInt32 -_PR_MD_ATOMIC_INCREMENT(PRInt32 *val) -{ - PRInt32 rv; - - if (!_pr_initialized) { - _PR_ImplicitInitialization(); - } - PR_Lock(atomic_lock); - rv = ++(*val); - PR_Unlock(atomic_lock); - return rv; -} - -PRInt32 -_PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) -{ - PRInt32 rv; - - if (!_pr_initialized) { - _PR_ImplicitInitialization(); - } - PR_Lock(atomic_lock); - rv = ((*ptr) += val); - PR_Unlock(atomic_lock); - return rv; -} - -PRInt32 -_PR_MD_ATOMIC_DECREMENT(PRInt32 *val) -{ - PRInt32 rv; - - if (!_pr_initialized) { - _PR_ImplicitInitialization(); - } - PR_Lock(atomic_lock); - rv = --(*val); - PR_Unlock(atomic_lock); - return rv; -} - -PRInt32 -_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) -{ - PRInt32 rv; - - if (!_pr_initialized) { - _PR_ImplicitInitialization(); - } - PR_Lock(atomic_lock); - rv = *val; - *val = newval; - PR_Unlock(atomic_lock); - return rv; -} -#endif /* _PR_PTHREADS && !_PR_DCETHREADS */ - -#endif /* !_PR_HAVE_ATOMIC_OPS */ - -void _PR_InitAtomic(void) -{ - _PR_MD_INIT_ATOMIC(); -} - -PR_IMPLEMENT(PRInt32) -PR_AtomicIncrement(PRInt32 *val) -{ - return _PR_MD_ATOMIC_INCREMENT(val); -} - -PR_IMPLEMENT(PRInt32) -PR_AtomicDecrement(PRInt32 *val) -{ - return _PR_MD_ATOMIC_DECREMENT(val); -} - -PR_IMPLEMENT(PRInt32) -PR_AtomicSet(PRInt32 *val, PRInt32 newval) -{ - return _PR_MD_ATOMIC_SET(val, newval); -} - -PR_IMPLEMENT(PRInt32) -PR_AtomicAdd(PRInt32 *ptr, PRInt32 val) -{ - return _PR_MD_ATOMIC_ADD(ptr, val); -} -/* - * For platforms, which don't support the CAS (compare-and-swap) instruction - * (or an equivalent), the stack operations are implemented by use of PRLock - */ - -PR_IMPLEMENT(PRStack *) -PR_CreateStack(const char *stack_name) -{ -PRStack *stack; - - if (!_pr_initialized) { - _PR_ImplicitInitialization(); - } - - if ((stack = PR_NEW(PRStack)) == NULL) { - return NULL; - } - if (stack_name) { - stack->prstk_name = (char *) PR_Malloc(strlen(stack_name) + 1); - if (stack->prstk_name == NULL) { - PR_DELETE(stack); - return NULL; - } - strcpy(stack->prstk_name, stack_name); - } else - stack->prstk_name = NULL; - -#ifndef _PR_HAVE_ATOMIC_CAS - stack->prstk_lock = PR_NewLock(); - if (stack->prstk_lock == NULL) { - PR_Free(stack->prstk_name); - PR_DELETE(stack); - return NULL; - } -#endif /* !_PR_HAVE_ATOMIC_CAS */ - - stack->prstk_head.prstk_elem_next = NULL; - - return stack; -} - -PR_IMPLEMENT(PRStatus) -PR_DestroyStack(PRStack *stack) -{ - if (stack->prstk_head.prstk_elem_next != NULL) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return PR_FAILURE; - } - - if (stack->prstk_name) - PR_Free(stack->prstk_name); -#ifndef _PR_HAVE_ATOMIC_CAS - PR_DestroyLock(stack->prstk_lock); -#endif /* !_PR_HAVE_ATOMIC_CAS */ - PR_DELETE(stack); - - return PR_SUCCESS; -} - -#ifndef _PR_HAVE_ATOMIC_CAS - -PR_IMPLEMENT(void) -PR_StackPush(PRStack *stack, PRStackElem *stack_elem) -{ - PR_Lock(stack->prstk_lock); - stack_elem->prstk_elem_next = stack->prstk_head.prstk_elem_next; - stack->prstk_head.prstk_elem_next = stack_elem; - PR_Unlock(stack->prstk_lock); - return; -} - -PR_IMPLEMENT(PRStackElem *) -PR_StackPop(PRStack *stack) -{ -PRStackElem *element; - - PR_Lock(stack->prstk_lock); - element = stack->prstk_head.prstk_elem_next; - if (element != NULL) { - stack->prstk_head.prstk_elem_next = element->prstk_elem_next; - element->prstk_elem_next = NULL; /* debugging aid */ - } - PR_Unlock(stack->prstk_lock); - return element; -} -#endif /* !_PR_HAVE_ATOMIC_CAS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/praton.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/praton.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/praton.c 2009-12-19 09:06:07.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/praton.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/******************************************************************************* - * The following function pr_inet_aton is based on the BSD function inet_aton - * with some modifications. The license and copyright notices applying to this - * function appear below. Modifications are also according to the license below. - ******************************************************************************/ - -#include "prnetdb.h" - -/* - * Copyright (c) 1983, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define XX 127 -static const unsigned char index_hex[256] = { - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX, - XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -}; - -static PRBool _isdigit(char c) { return c >= '0' && c <= '9'; } -static PRBool _isxdigit(char c) { return index_hex[(unsigned char) c] != XX; } -static PRBool _isspace(char c) { return c == ' ' || (c >= '\t' && c <= '\r'); } -#undef XX - -int -pr_inet_aton(const char *cp, PRUint32 *addr) -{ - PRUint32 val; - int base, n; - char c; - PRUint8 parts[4]; - PRUint8 *pp = parts; - int digit; - - c = *cp; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, isdigit=decimal. - */ - if (!_isdigit(c)) - return (0); - val = 0; base = 10; digit = 0; - if (c == '0') { - c = *++cp; - if (c == 'x' || c == 'X') - base = 16, c = *++cp; - else { - base = 8; - digit = 1; - } - } - for (;;) { - if (_isdigit(c)) { - if (base == 8 && (c == '8' || c == '9')) - return (0); - val = (val * base) + (c - '0'); - c = *++cp; - digit = 1; - } else if (base == 16 && _isxdigit(c)) { - val = (val << 4) + index_hex[(unsigned char) c]; - c = *++cp; - digit = 1; - } else - break; - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3 || val > 0xffU) - return (0); - *pp++ = val; - c = *++cp; - } else - break; - } - /* - * Check for trailing characters. - */ - if (c != '\0' && !_isspace(c)) - return (0); - /* - * Did we get a valid digit? - */ - if (!digit) - return (0); - /* - * Concoct the address according to - * the number of parts specified. - */ - n = pp - parts + 1; - switch (n) { - case 1: /*%< a -- 32 bits */ - break; - - case 2: /*%< a.b -- 8.24 bits */ - if (val > 0xffffffU) - return (0); - val |= parts[0] << 24; - break; - - case 3: /*%< a.b.c -- 8.8.16 bits */ - if (val > 0xffffU) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /*%< a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xffU) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - } - *addr = PR_htonl(val); - return (1); -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prcountr.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prcountr.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prcountr.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prcountr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,474 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** prcountr.c -- NSPR Instrumentation Counters -** -** Implement the interface defined in prcountr.h -** -** Design Notes: -** -** The Counter Facility (CF) has a single anchor: qNameList. -** The anchor is a PRCList. qNameList is a list of links in QName -** structures. From qNameList any QName structure and its -** associated RName structure can be located. -** -** For each QName, a list of RName structures is anchored at -** rnLink in the QName structure. -** -** The counter itself is embedded in the RName structure. -** -** For manipulating the counter database, single lock is used to -** protect the entire list: counterLock. -** -** A PRCounterHandle, defined in prcountr.h, is really a pointer -** to a RName structure. References by PRCounterHandle are -** dead-reconed to the RName structure. The PRCounterHandle is -** "overloaded" for traversing the QName structures; only the -** function PR_FindNextQnameHandle() uses this overloading. -** -** -** ToDo (lth): decide on how to lock or atomically update -** individual counters. Candidates are: the global lock; a lock -** per RName structure; Atomic operations (Note that there are -** not adaquate atomic operations (yet) to achieve this goal). At -** this writing (6/19/98) , the update of the counter variable in -** a QName structure is unprotected. -** -*/ - -#include "prcountr.h" -#include "prclist.h" -#include "prlock.h" -#include "prlog.h" -#include "prmem.h" -#include - -/* -** -*/ -typedef struct QName -{ - PRCList link; - PRCList rNameList; - char name[PRCOUNTER_NAME_MAX+1]; -} QName; - -/* -** -*/ -typedef struct RName -{ - PRCList link; - QName *qName; - PRLock *lock; - volatile PRUint32 counter; - char name[PRCOUNTER_NAME_MAX+1]; - char desc[PRCOUNTER_DESC_MAX+1]; -} RName; - - -/* -** Define the Counter Facility database -*/ -static PRLock *counterLock; -static PRCList qNameList; -static PRLogModuleInfo *lm; - -/* -** _PR_CounterInitialize() -- Initialize the Counter Facility -** -*/ -static void _PR_CounterInitialize( void ) -{ - /* - ** This function should be called only once - */ - PR_ASSERT( counterLock == NULL ); - - counterLock = PR_NewLock(); - PR_INIT_CLIST( &qNameList ); - lm = PR_NewLogModule("counters"); - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Initialization complete")); - - return; -} /* end _PR_CounterInitialize() */ - -/* -** PR_CreateCounter() -- Create a counter -** -** ValidateArguments -** Lock -** if (qName not already in database) -** NewQname -** if (rName already in database ) -** Assert -** else NewRname -** NewCounter -** link 'em up -** Unlock -** -*/ -PR_IMPLEMENT(PRCounterHandle) - PR_CreateCounter( - const char *qName, - const char *rName, - const char *description -) -{ - QName *qnp; - RName *rnp; - PRBool matchQname = PR_FALSE; - - /* Self initialize, if necessary */ - if ( counterLock == NULL ) - _PR_CounterInitialize(); - - /* Validate input arguments */ - PR_ASSERT( strlen(qName) <= PRCOUNTER_NAME_MAX ); - PR_ASSERT( strlen(rName) <= PRCOUNTER_NAME_MAX ); - PR_ASSERT( strlen(description) <= PRCOUNTER_DESC_MAX ); - - /* Lock the Facility */ - PR_Lock( counterLock ); - - /* Do we already have a matching QName? */ - if (!PR_CLIST_IS_EMPTY( &qNameList )) - { - qnp = (QName *) PR_LIST_HEAD( &qNameList ); - do { - if ( strcmp(qnp->name, qName) == 0) - { - matchQname = PR_TRUE; - break; - } - qnp = (QName *)PR_NEXT_LINK( &qnp->link ); - } while( qnp != (QName *)PR_LIST_HEAD( &qNameList )); - } - /* - ** If we did not find a matching QName, - ** allocate one and initialize it. - ** link it onto the qNameList. - ** - */ - if ( matchQname != PR_TRUE ) - { - qnp = PR_NEWZAP( QName ); - PR_ASSERT( qnp != NULL ); - PR_INIT_CLIST( &qnp->link ); - PR_INIT_CLIST( &qnp->rNameList ); - strcpy( qnp->name, qName ); - PR_APPEND_LINK( &qnp->link, &qNameList ); - } - - /* Do we already have a matching RName? */ - if (!PR_CLIST_IS_EMPTY( &qnp->rNameList )) - { - rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList ); - do { - /* - ** No duplicate RNames are allowed within a QName - ** - */ - PR_ASSERT( strcmp(rnp->name, rName)); - rnp = (RName *)PR_NEXT_LINK( &rnp->link ); - } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList )); - } - - /* Get a new RName structure; initialize its members */ - rnp = PR_NEWZAP( RName ); - PR_ASSERT( rnp != NULL ); - PR_INIT_CLIST( &rnp->link ); - strcpy( rnp->name, rName ); - strcpy( rnp->desc, description ); - rnp->lock = PR_NewLock(); - if ( rnp->lock == NULL ) - { - PR_ASSERT(0); - } - - PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ - rnp->qName = qnp; /* point the RName to the QName */ - - /* Unlock the Facility */ - PR_Unlock( counterLock ); - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t", - qName, qnp, rName, rnp )); - - return((PRCounterHandle)rnp); -} /* end PR_CreateCounter() */ - - -/* -** -*/ -PR_IMPLEMENT(void) - PR_DestroyCounter( - PRCounterHandle handle -) -{ - RName *rnp = (RName *)handle; - QName *qnp = rnp->qName; - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s", - qnp->name, rnp->name)); - - /* Lock the Facility */ - PR_Lock( counterLock ); - - /* - ** Remove RName from the list of RNames in QName - ** and free RName - */ - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p", - rnp->name, rnp)); - PR_REMOVE_LINK( &rnp->link ); - PR_Free( rnp->lock ); - PR_DELETE( rnp ); - - /* - ** If this is the last RName within QName - ** remove QName from the qNameList and free it - */ - if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) ) - { - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p", - qnp->name, qnp)); - PR_REMOVE_LINK( &qnp->link ); - PR_DELETE( qnp ); - } - - /* Unlock the Facility */ - PR_Unlock( counterLock ); - return; -} /* end PR_DestroyCounter() */ - -/* -** -*/ -PR_IMPLEMENT(PRCounterHandle) - PR_GetCounterHandleFromName( - const char *qName, - const char *rName -) -{ - const char *qn, *rn, *desc; - PRCounterHandle qh, rh = NULL; - RName *rnp = NULL; - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounterHandleFromName:\n\t" - "QName: %s, RName: %s", qName, rName )); - - qh = PR_FindNextCounterQname( NULL ); - while (qh != NULL) - { - rh = PR_FindNextCounterRname( NULL, qh ); - while ( rh != NULL ) - { - PR_GetCounterNameFromHandle( rh, &qn, &rn, &desc ); - if ( (strcmp( qName, qn ) == 0) - && (strcmp( rName, rn ) == 0 )) - { - rnp = (RName *)rh; - goto foundIt; - } - rh = PR_FindNextCounterRname( rh, qh ); - } - qh = PR_FindNextCounterQname( NULL ); - } - -foundIt: - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp )); - return(rh); -} /* end PR_GetCounterHandleFromName() */ - -/* -** -*/ -PR_IMPLEMENT(void) - PR_GetCounterNameFromHandle( - PRCounterHandle handle, - const char **qName, - const char **rName, - const char **description -) -{ - RName *rnp = (RName *)handle; - QName *qnp = rnp->qName; - - *qName = qnp->name; - *rName = rnp->name; - *description = rnp->desc; - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterNameFromHandle: " - "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", - qnp, rnp, qnp->name, rnp->name, rnp->desc )); - - return; -} /* end PR_GetCounterNameFromHandle() */ - - -/* -** -*/ -PR_IMPLEMENT(void) - PR_IncrementCounter( - PRCounterHandle handle -) -{ - PR_Lock(((RName *)handle)->lock); - ((RName *)handle)->counter++; - PR_Unlock(((RName *)handle)->lock); - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld", - handle, ((RName *)handle)->counter )); - - return; -} /* end PR_IncrementCounter() */ - - - -/* -** -*/ -PR_IMPLEMENT(void) - PR_DecrementCounter( - PRCounterHandle handle -) -{ - PR_Lock(((RName *)handle)->lock); - ((RName *)handle)->counter--; - PR_Unlock(((RName *)handle)->lock); - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld", - handle, ((RName *)handle)->counter )); - - return; -} /* end PR_DecrementCounter() */ - - -/* -** -*/ -PR_IMPLEMENT(void) - PR_AddToCounter( - PRCounterHandle handle, - PRUint32 value -) -{ - PR_Lock(((RName *)handle)->lock); - ((RName *)handle)->counter += value; - PR_Unlock(((RName *)handle)->lock); - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld", - handle, ((RName *)handle)->counter )); - - return; -} /* end PR_AddToCounter() */ - - -/* -** -*/ -PR_IMPLEMENT(void) - PR_SubtractFromCounter( - PRCounterHandle handle, - PRUint32 value -) -{ - PR_Lock(((RName *)handle)->lock); - ((RName *)handle)->counter -= value; - PR_Unlock(((RName *)handle)->lock); - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld", - handle, ((RName *)handle)->counter )); - - return; -} /* end PR_SubtractFromCounter() */ - -/* -** -*/ -PR_IMPLEMENT(PRUint32) - PR_GetCounter( - PRCounterHandle handle -) -{ - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld", - handle, ((RName *)handle)->counter )); - - return(((RName *)handle)->counter); -} /* end PR_GetCounter() */ - -/* -** -*/ -PR_IMPLEMENT(void) - PR_SetCounter( - PRCounterHandle handle, - PRUint32 value -) -{ - ((RName *)handle)->counter = value; - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld", - handle, ((RName *)handle)->counter )); - - return; -} /* end PR_SetCounter() */ - -/* -** -*/ -PR_IMPLEMENT(PRCounterHandle) - PR_FindNextCounterQname( - PRCounterHandle handle -) -{ - QName *qnp = (QName *)handle; - - if ( PR_CLIST_IS_EMPTY( &qNameList )) - qnp = NULL; - else if ( qnp == NULL ) - qnp = (QName *)PR_LIST_HEAD( &qNameList ); - else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) - qnp = NULL; - else - qnp = (QName *)PR_NEXT_LINK( &qnp->link ); - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", - handle, qnp )); - - return((PRCounterHandle)qnp); -} /* end PR_FindNextCounterQname() */ - - -/* -** -*/ -PR_IMPLEMENT(PRCounterHandle) - PR_FindNextCounterRname( - PRCounterHandle rhandle, - PRCounterHandle qhandle -) -{ - RName *rnp = (RName *)rhandle; - QName *qnp = (QName *)qhandle; - - - if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) - rnp = NULL; - else if ( rnp == NULL ) - rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList ); - else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) - rnp = NULL; - else - rnp = (RName *)PR_NEXT_LINK( &rnp->link ); - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", - rhandle, qhandle, rnp )); - - return((PRCounterHandle)rnp); -} /* end PR_FindNextCounterRname() */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prdtoa.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prdtoa.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prdtoa.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prdtoa.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,3522 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This file is based on the third-party code dtoa.c. We minimize our - * modifications to third-party code to make it easy to merge new versions. - * The author of dtoa.c was not willing to add the parentheses suggested by - * GCC, so we suppress these warnings. - */ -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) -#pragma GCC diagnostic ignored "-Wparentheses" -#endif - -#include "primpl.h" -#include "prbit.h" - -#define MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) PR_Lock(dtoa_lock[n]) -#define FREE_DTOA_LOCK(n) PR_Unlock(dtoa_lock[n]) - -static PRLock *dtoa_lock[2]; - -void _PR_InitDtoa(void) -{ - dtoa_lock[0] = PR_NewLock(); - dtoa_lock[1] = PR_NewLock(); -} - -void _PR_CleanupDtoa(void) -{ - PR_DestroyLock(dtoa_lock[0]); - dtoa_lock[0] = NULL; - PR_DestroyLock(dtoa_lock[1]); - dtoa_lock[1] = NULL; - - /* FIXME: deal with freelist and p5s. */ -} - -#if !defined(__ARM_EABI__) \ - && (defined(__arm) || defined(__arm__) || defined(__arm26__) \ - || defined(__arm32__)) -#define IEEE_ARM -#elif defined(IS_LITTLE_ENDIAN) -#define IEEE_8087 -#else -#define IEEE_MC68k -#endif - -#define Long PRInt32 -#define ULong PRUint32 -#define NO_LONG_LONG - -#define No_Hex_NaN - -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ - -/* On a machine with IEEE extended-precision registers, it is - * necessary to specify double-precision (53-bit) rounding precision - * before invoking strtod or dtoa. If the machine uses (the equivalent - * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); - * does this with many compilers. Whether this or another call is - * appropriate depends on the compiler; for this to work, it may be - * necessary to #include "float.h" or another system-dependent header - * file. - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* - * #define IEEE_8087 for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_MC68k for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define IEEE_ARM for IEEE-arithmetic machines where the two words - * in a double are stored in big endian order but the two shorts - * in a word are still stored in little endian order. - * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic (D_floating). - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. - * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define NO_LONG_LONG on machines that do not have a "long long" - * integer type (of >= 64 bits). On such machines, you can - * #define Just_16 to store 16 bits per 32-bit Long when doing - * high-precision integer arithmetic. Whether this speeds things - * up or slows things down depends on the machine and the number - * being converted. If long long is available and the name is - * something other than "long long", #define Llong to be the name, - * and if "unsigned Llong" does not work as an unsigned version of - * Llong, #define #ULLong to be the corresponding unsigned type. - * #define KR_headers for old-style C function headers. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. Similarly, if you - * want something other than the system's free() to be called to - * recycle memory acquired from MALLOC, #define FREE to be the - * name of the alternate routine. (FREE or free is only called in - * pathological cases, e.g., in a dtoa call after a dtoa return in - * mode 3 with thousands of digits requested.) - * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). On some systems (e.g., - * some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. - * #define MULTIPLE_THREADS if the system offers preemptively scheduled - * multiple threads. In this case, you must provide (or suitably - * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed - * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed - * in pow5mult, ensures lazy evaluation of only one copy of high - * powers of 5; omitting this lock would introduce a small - * probability of wasting memory, but would otherwise be harmless.) - * You must also invoke freedtoa(s) to free the value s returned by - * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. - * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. - * #define USE_LOCALE to use the current locale's decimal_point value. - * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). - * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. - */ - -#ifndef Long -#define Long long -#endif -#ifndef ULong -typedef unsigned Long ULong; -#endif - -#ifdef DEBUG -#include "stdio.h" -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#include "stdlib.h" -#include "string.h" - -#ifdef USE_LOCALE -#include "locale.h" -#endif - -#ifdef MALLOC -#ifdef KR_headers -extern char *MALLOC(); -#else -extern void *MALLOC(size_t); -#endif -#else -#define MALLOC malloc -#endif - -#ifndef Omit_Private_Memory -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#endif - -#undef IEEE_Arith -#undef Avoid_Underflow -#ifdef IEEE_MC68k -#define IEEE_Arith -#endif -#ifdef IEEE_8087 -#define IEEE_Arith -#endif -#ifdef IEEE_ARM -#define IEEE_Arith -#endif - -#include "errno.h" - -#ifdef Bad_float_h - -#ifdef IEEE_Arith -#define DBL_DIG 15 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define FLT_RADIX 2 -#endif /*IEEE_Arith*/ - -#ifdef IBM -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 75 -#define DBL_MAX_EXP 63 -#define FLT_RADIX 16 -#define DBL_MAX 7.2370055773322621e+75 -#endif - -#ifdef VAX -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 38 -#define DBL_MAX_EXP 127 -#define FLT_RADIX 2 -#define DBL_MAX 1.7014118346046923e+38 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 2147483647 -#endif - -#else /* ifndef Bad_float_h */ -#include "float.h" -/* - * MacOS 10.2 defines the macro FLT_ROUNDS to an internal function - * which does not exist on 10.1. We can safely #define it to 1 here - * to allow 10.2 builds to run on 10.1, since we can't use fesetround() - * (which does not exist on 10.1 either). - */ -#if defined(XP_MACOSX) && (!defined(MAC_OS_X_VERSION_10_2) || \ - MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2) -#undef FLT_ROUNDS -#define FLT_ROUNDS 1 -#endif /* DT < 10.2 */ -#endif /* Bad_float_h */ - -#ifndef __MATH_H__ -#include "math.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CONST -#ifdef KR_headers -#define CONST /* blank */ -#else -#define CONST const -#endif -#endif - -#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) + defined(VAX) + defined(IBM) != 1 -Exactly one of IEEE_8087, IEEE_MC68k, IEEE_ARM, VAX, or IBM should be defined. -#endif - -typedef union { double d; ULong L[2]; } U; - -#define dval(x) (x).d -#ifdef IEEE_8087 -#define word0(x) (x).L[1] -#define word1(x) (x).L[0] -#else -#define word0(x) (x).L[0] -#define word1(x) (x).L[1] -#endif - -/* The following definition of Storeinc is appropriate for MIPS processors. - * An alternative that might be better on some machines is - * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) - */ -#if defined(IEEE_8087) + defined(IEEE_ARM) + defined(VAX) -#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ -((unsigned short *)a)[0] = (unsigned short)c, a++) -#else -#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ -((unsigned short *)a)[1] = (unsigned short)c, a++) -#endif - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#ifdef IEEE_Arith -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Bias 1023 -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#ifndef NO_IEEE_Scale -#define Avoid_Underflow -#ifdef Flush_Denorm /* debugging option */ -#undef Sudden_Underflow -#endif -#endif - -#ifndef Flt_Rounds -#ifdef FLT_ROUNDS -#define Flt_Rounds FLT_ROUNDS -#else -#define Flt_Rounds 1 -#endif -#endif /*Flt_Rounds*/ - -#ifdef Honor_FLT_ROUNDS -#define Rounding rounding -#undef Check_FLT_ROUNDS -#define Check_FLT_ROUNDS -#else -#define Rounding Flt_Rounds -#endif - -#else /* ifndef IEEE_Arith */ -#undef Check_FLT_ROUNDS -#undef Honor_FLT_ROUNDS -#undef SET_INEXACT -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#undef Flt_Rounds -#define Flt_Rounds 0 -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Bias 65 -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#undef Flt_Rounds -#define Flt_Rounds 1 -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Bias 129 -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif /* IBM, VAX */ -#endif /* IEEE_Arith */ - -#ifndef IEEE_Arith -#define ROUND_BIASED -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) a = rnd_prod(a, b) -#define rounded_quotient(a,b) a = rnd_quot(a, b) -#ifdef KR_headers -extern double rnd_prod(), rnd_quot(); -#else -extern double rnd_prod(double, double), rnd_quot(double, double); -#endif -#else -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b -#endif - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -#ifndef Pack_32 -#define Pack_32 -#endif - -#ifdef KR_headers -#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) -#else -#define FFFFFFFF 0xffffffffUL -#endif - -#ifdef NO_LONG_LONG -#undef ULLong -#ifdef Just_16 -#undef Pack_32 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#endif -#else /* long long available */ -#ifndef Llong -#define Llong long long -#endif -#ifndef ULLong -#define ULLong unsigned Llong -#endif -#endif /* NO_LONG_LONG */ - -#ifndef MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ -#define FREE_DTOA_LOCK(n) /*nothing*/ -#endif - -#define Kmax 7 - - struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; - - typedef struct Bigint Bigint; - - static Bigint *freelist[Kmax+1]; - - static Bigint * -Balloc -#ifdef KR_headers - (k) int k; -#else - (int k) -#endif -{ - int x; - Bigint *rv; -#ifndef Omit_Private_Memory - unsigned int len; -#endif - - ACQUIRE_DTOA_LOCK(0); - /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ - /* but this case seems very unlikely. */ - if (k <= Kmax && (rv = freelist[k])) - freelist[k] = rv->next; - else { - x = 1 << k; -#ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); -#else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } - else - rv = (Bigint*)MALLOC(len*sizeof(double)); -#endif - rv->k = k; - rv->maxwds = x; - } - FREE_DTOA_LOCK(0); - rv->sign = rv->wds = 0; - return rv; - } - - static void -Bfree -#ifdef KR_headers - (v) Bigint *v; -#else - (Bigint *v) -#endif -{ - if (v) { - if (v->k > Kmax) -#ifdef FREE - FREE((void*)v); -#else - free((void*)v); -#endif - else { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); - } - } - } - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) - - static Bigint * -multadd -#ifdef KR_headers - (b, m, a) Bigint *b; int m, a; -#else - (Bigint *b, int m, int a) /* multiply by m and add a */ -#endif -{ - int i, wds; -#ifdef ULLong - ULong *x; - ULLong carry, y; -#else - ULong carry, *x, y; -#ifdef Pack_32 - ULong xi, z; -#endif -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { -#ifdef ULLong - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + carry; - z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif -#endif - } - while(++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = carry; - b->wds = wds; - } - return b; - } - - static Bigint * -s2b -#ifdef KR_headers - (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; -#else - (CONST char *s, int nd0, int nd, ULong y9) -#endif -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s++; - } - else - s += 10; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - static int -hi0bits -#ifdef KR_headers - (x) register ULong x; -#else - (register ULong x) -#endif -{ -#ifdef PR_HAVE_BUILTIN_BITSCAN32 - return( (!x) ? 32 : pr_bitscan_clz32(x) ); -#else - register int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; -#endif /* PR_HAVE_BUILTIN_BITSCAN32 */ - } - - static int -lo0bits -#ifdef KR_headers - (y) ULong *y; -#else - (ULong *y) -#endif -{ -#ifdef PR_HAVE_BUILTIN_BITSCAN32 - int k; - ULong x = *y; - - if (x>1) - *y = ( x >> (k = pr_bitscan_ctz32(x)) ); - else - k = ((x ^ 1) << 5); -#else - register int k; - register ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; -#endif /* PR_HAVE_BUILTIN_BITSCAN32 */ - return k; - } - - static Bigint * -i2b -#ifdef KR_headers - (i) int i; -#else - (int i) -#endif -{ - Bigint *b; - - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; - } - - static Bigint * -mult -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; -#ifdef ULLong - ULLong carry, z; -#else - ULong carry, z; -#ifdef Pack_32 - ULong z2; -#endif -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; -#ifdef ULLong - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = z & FFFFFFFF; - } - while(x < xae); - *xc = carry; - } - } -#else -#ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if (y = *xb & 0xffff) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if (y = *xb >> 16) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } - - static Bigint *p5s; - - static Bigint * -pow5mult -#ifdef KR_headers - (b, k) Bigint *b; int k; -#else - (Bigint *b, int k) -#endif -{ - Bigint *b1, *p5, *p51; - int i; - static int p05[3] = { 5, 25, 125 }; - - if (i = k & 3) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p5 = p5s)) { - p5 = p5s = i2b(625); - p5->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p5 = p5s = i2b(625); - p5->next = 0; -#endif - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p51 = p5->next = mult(p5,p5); - p51->next = 0; -#endif - } - p5 = p51; - } - return b; - } - - static Bigint * -lshift -#ifdef KR_headers - (b, k) Bigint *b; int k; -#else - (Bigint *b, int k) -#endif -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; - } - - static int -cmp -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; - } - - static Bigint * -diff -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef ULLong - ULLong borrow, y; -#else - ULong borrow, y; -#ifdef Pack_32 - ULong z; -#endif -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; -#ifdef ULLong - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } -#else -#ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } - - static double -ulp -#ifdef KR_headers - (dx) double dx; -#else - (double dx) -#endif -{ - register Long L; - U x, a; - - dval(x) = dx; - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#endif -#ifdef IBM - L |= Exp_msk1 >> 4; -#endif - word0(a) = L; - word1(a) = 0; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(a) = 0x80000 >> L; - word1(a) = 0; - } - else { - word0(a) = 0; - L -= Exp_shift; - word1(a) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif - return dval(a); - } - - static double -b2d -#ifdef KR_headers - (a, e) Bigint *a; int *e; -#else - (Bigint *a, int *e) -#endif -{ - ULong *xa, *xa0, w, y, z; - int k; - U d; -#ifdef VAX - ULong d0, d1; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; -#ifdef Pack_32 - if (k < Ebits) { - d0 = Exp_1 | y >> Ebits - k; - w = xa > xa0 ? *--xa : 0; - d1 = y << (32-Ebits) + k | w >> Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> 32 - k; - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> 32 - k; - } - else { - d0 = Exp_1 | y; - d1 = z; - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif - ret_d: -#ifdef VAX - word0(d) = d0 >> 16 | d0 << 16; - word1(d) = d1 >> 16 | d1 << 16; -#else -#undef d0 -#undef d1 -#endif - return dval(d); - } - - static Bigint * -d2b -#ifdef KR_headers - (dd, e, bits) double dd; int *e, *bits; -#else - (double dd, int *e, int *bits) -#endif -{ - U d; - Bigint *b; - int de, k; - ULong *x, y, z; -#ifndef Sudden_Underflow - int i; -#endif -#ifdef VAX - ULong d0, d1; -#endif - - dval(d) = dd; -#ifdef VAX - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - -#ifdef Pack_32 - b = Balloc(1); -#else - b = Balloc(2); -#endif - x = b->x; - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); -#ifndef IBM - z |= Exp_msk11; -#endif -#else - if (de = (int)(d0 >> Exp_shift)) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - if (y = d1) { - if (k = lo0bits(&y)) { - x[0] = y | z << 32 - k; - z >>= k; - } - else - x[0] = y; -#ifndef Sudden_Underflow - i = -#endif - b->wds = (x[1] = z) ? 2 : 1; - } - else { - k = lo0bits(&z); - x[0] = z; -#ifndef Sudden_Underflow - i = -#endif - b->wds = 1; - k += 32; - } -#else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; -#endif -#ifndef Sudden_Underflow - if (de) { -#endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); -#else - *e = de - Bias - (P-1) + k; - *bits = P - k; -#endif -#ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif - } -#endif - return b; - } -#undef d0 -#undef d1 - - static double -ratio -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - U da, db; - int k, ka, kb; - - dval(da) = b2d(a, &ka); - dval(db) = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(da) *= 1 << k; - } - else { - k = -k; - word0(db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(db) *= 1 << k; - } -#else - if (k > 0) - word0(da) += k*Exp_msk1; - else { - k = -k; - word0(db) += k*Exp_msk1; - } -#endif - return dval(da) / dval(db); - } - - static CONST double -tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif - }; - - static CONST double -#ifdef IEEE_Arith -bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, -#ifdef Avoid_Underflow - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-53 */ -#else - 1e-256 -#endif - }; -/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ -/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ -#define Scale_Bit 0x10 -#define n_bigtens 5 -#else -#ifdef IBM -bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - -#ifndef IEEE_Arith -#undef INFNAN_CHECK -#endif - -#ifdef INFNAN_CHECK - -#ifndef NAN_WORD0 -#define NAN_WORD0 0x7ff80000 -#endif - -#ifndef NAN_WORD1 -#define NAN_WORD1 0 -#endif - - static int -match -#ifdef KR_headers - (sp, t) char **sp, *t; -#else - (CONST char **sp, char *t) -#endif -{ - int c, d; - CONST char *s = *sp; - - while(d = *t++) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; - } - -#ifndef No_Hex_NaN - static void -hexnan -#ifdef KR_headers - (rvp, sp) double *rvp; CONST char **sp; -#else - (double *rvp, CONST char **sp) -#endif -{ - ULong c, x[2]; - CONST char *s; - int havedig, udx0, xshift; - - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - while(c = *(CONST unsigned char*)++s) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'a' && c <= 'f') - c += 10 - 'a'; - else if (c >= 'A' && c <= 'F') - c += 10 - 'A'; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } - else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } - else - return; /* invalid form: don't change *sp */ - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(*rvp) = Exp_mask | x[0]; - word1(*rvp) = x[1]; - } - } -#endif /*No_Hex_NaN*/ -#endif /* INFNAN_CHECK */ - - PR_IMPLEMENT(double) -PR_strtod -#ifdef KR_headers - (s00, se) CONST char *s00; char **se; -#else - (CONST char *s00, char **se) -#endif -{ -#ifdef Avoid_Underflow - int scale; -#endif - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1, adj; - U aadj2, rv, rv0; - Long L; - ULong y, z; - Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif -#ifdef Honor_FLT_ROUNDS - int rounding; -#endif -#ifdef USE_LOCALE - CONST char *s2; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - sign = nz0 = nz = 0; - dval(rv) = 0.; - for(s = s00;;s++) switch(*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } - break2: - if (*s == '0') { - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; -#ifdef USE_LOCALE - s1 = localeconv()->decimal_point; - if (c == *s1) { - c = '.'; - if (*++s1) { - s2 = s; - for(;;) { - if (*++s2 != *s1) { - c = 0; - break; - } - if (!*++s1) { - s = s2; - break; - } - } - } - } -#endif - if (c == '.') { - c = *++s; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = 0; - } - } - } - dig_done: - if (nd > 64 * 1024) - goto ret0; - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - goto ret0; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { -#ifdef INFNAN_CHECK - /* Check for Nan and Infinity */ - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(rv) = 0x7ff00000; - word1(rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(rv) = NAN_WORD0; - word1(rv) = NAN_WORD1; -#ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); -#endif - goto ret; - } - } -#endif /* INFNAN_CHECK */ - ret0: - s = s00; - sign = 0; - } - goto ret; - } - e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; - if (k > 9) { -#ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); -#endif - dval(rv) = tens[k - 9] * dval(rv) + z; - } - bd0 = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT -#ifndef Honor_FLT_ROUNDS - && Flt_Rounds == 1 -#endif -#endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } -#endif - /* rv = */ rounded_product(dval(rv), tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } -#endif - e -= i; - dval(rv) *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - word0(rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(rv), tens[e]); - if ((word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(rv) += P*Exp_msk1; -#else - /* rv = */ rounded_product(dval(rv), tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } -#endif - /* rv = */ rounded_quotient(dval(rv), tens[-e]); - goto ret; - } -#endif - } - e1 += nd - k; - -#ifdef IEEE_Arith -#ifdef SET_INEXACT - inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); -#endif -#ifdef Avoid_Underflow - scale = 0; -#endif -#ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { - if (sign) - rounding = rounding == 2 ? 0 : 2; - else - if (rounding != 2) - rounding = 0; - } -#endif -#endif /*IEEE_Arith*/ - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if (i = e1 & 15) - dval(rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: -#ifndef NO_ERRNO - PR_SetError(PR_RANGE_ERROR, 0); -#endif - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith -#ifdef Honor_FLT_ROUNDS - switch(rounding) { - case 0: /* toward 0 */ - case 3: /* toward -infinity */ - word0(rv) = Big0; - word1(rv) = Big1; - break; - default: - word0(rv) = Exp_mask; - word1(rv) = 0; - } -#else /*Honor_FLT_ROUNDS*/ - word0(rv) = Exp_mask; - word1(rv) = 0; -#endif /*Honor_FLT_ROUNDS*/ -#ifdef SET_INEXACT - /* set overflow bit */ - dval(rv0) = 1e300; - dval(rv0) *= dval(rv0); -#endif -#else /*IEEE_Arith*/ - word0(rv) = Big0; - word1(rv) = Big1; -#endif /*IEEE_Arith*/ - if (bd0) - goto retfree; - goto ret; - } - e1 >>= 4; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - dval(rv) *= bigtens[j]; - if ((z = word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(rv) = Big0; - word1(rv) = Big1; - } - else - word0(rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - e1 = -e1; - if (i = e1 & 15) - dval(rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; -#ifdef Avoid_Underflow - if (e1 & Scale_Bit) - scale = 2*P; - for(j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= tinytens[j]; - if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; zap j low bits */ - if (j >= 32) { - word1(rv) = 0; - if (j >= 53) - word0(rv) = (P+2)*Exp_msk1; - else - word0(rv) &= 0xffffffff << j-32; - } - else - word1(rv) &= 0xffffffff << j; - } -#else - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(rv0) = dval(rv); - dval(rv) *= tinytens[j]; - if (!dval(rv)) { - dval(rv) = 2.*dval(rv0); - dval(rv) *= tinytens[j]; -#endif - if (!dval(rv)) { - undfl: - dval(rv) = 0.; -#ifndef NO_ERRNO - PR_SetError(PR_RANGE_ERROR, 0); -#endif - if (bd0) - goto retfree; - goto ret; - } -#ifndef Avoid_Underflow - word0(rv) = Tiny0; - word1(rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bd0 = s2b(s0, nd0, nd, y); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; -#ifdef Honor_FLT_ROUNDS - if (rounding != 1) - bs2++; -#endif -#ifdef Avoid_Underflow - j = bbe - scale; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#else /*Avoid_Underflow*/ -#ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - bb2 += j; - bd2 += j; -#ifdef Avoid_Underflow - bd2 += scale; -#endif - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); -#ifdef Honor_FLT_ROUNDS - if (rounding != 1) { - if (i < 0) { - /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) { - /* exact */ -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (rounding) { - if (dsign) { - adj = 1.; - goto apply_adj; - } - } - else if (!dsign) { - adj = -1.; - if (!word1(rv) - && !(word0(rv) & Frac_mask)) { - y = word0(rv) & Exp_mask; -#ifdef Avoid_Underflow - if (!scale || y > 2*P*Exp_msk1) -#else - if (y) -#endif - { - delta = lshift(delta,Log2P); - if (cmp(delta, bs) <= 0) - adj = -0.5; - } - } - apply_adj: -#ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) - <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= - P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - dval(rv) += adj*ulp(dval(rv)); - word0(rv) -= P*Exp_msk1; - } - else -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - dval(rv) += adj*ulp(dval(rv)); - } - break; - } - adj = ratio(delta, bs); - if (adj < 1.) - adj = 1.; - if (adj <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj; - if (y != adj) { - if (!((rounding>>1) ^ dsign)) - y++; - adj = y; - } - } -#ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; - else - dval(rv) -= adj; - word0(rv) -= P*Exp_msk1; - goto cont; - } -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; - else - dval(rv) -= adj; - goto cont; - } -#endif /*Honor_FLT_ROUNDS*/ - - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask -#ifdef IEEE_Arith -#ifdef Avoid_Underflow - || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 -#else - || (word0(rv) & Exp_mask) <= Exp_msk1 -#endif -#endif - ) { -#ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) - inexact = 0; -#endif - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == ( -#ifdef Avoid_Underflow - (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : -#endif - 0xffffffff)) { - /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ; - word1(rv) = 0; -#ifdef Avoid_Underflow - dsign = 0; -#endif - break; - } - } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { - drop_down: - /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow /*{{*/ - L = word0(rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else -#ifdef Avoid_Underflow - if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) -#else - if (L <= Exp_msk1) -#endif /*Avoid_Underflow*/ -#endif /*IBM*/ - goto undfl; - L -= Exp_msk1; -#else /*Sudden_Underflow}{*/ -#ifdef Avoid_Underflow - if (scale) { - L = word0(rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - goto undfl; - } - } -#endif /*Avoid_Underflow*/ - L = (word0(rv) & Exp_mask) - Exp_msk1; -#endif /*Sudden_Underflow}}*/ - word0(rv) = L | Bndry_mask1; - word1(rv) = 0xffffffff; -#ifdef IBM - goto cont; -#else - break; -#endif - } -#ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) - break; -#endif - if (dsign) - dval(rv) += ulp(dval(rv)); -#ifndef ROUND_BIASED - else { - dval(rv) -= ulp(dval(rv)); -#ifndef Sudden_Underflow - if (!dval(rv)) - goto undfl; -#endif - } -#ifdef Avoid_Underflow - dsign = 1 - dsign; -#endif -#endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = aadj1 = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { -#ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) - goto undfl; -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch(Rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (Flt_Rounds == 0) - aadj1 += 0.5; -#endif /*Check_FLT_ROUNDS*/ - } - y = word0(rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(rv0) = dval(rv); - word0(rv) -= P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; - if ((word0(rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) - goto ovfl; - word0(rv) = Big0; - word1(rv) = Big1; - goto cont; - } - else - word0(rv) += P*Exp_msk1; - } - else { -#ifdef Avoid_Underflow - if (scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = aadj) <= 0) - z = 1; - aadj = z; - aadj1 = dsign ? aadj : -aadj; - } - dval(aadj2) = aadj1; - word0(aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(aadj2); - } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - dval(rv0) = dval(rv); - word0(rv) += P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; -#ifdef IBM - if ((word0(rv) & Exp_mask) < P*Exp_msk1) -#else - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (word0(rv0) == Tiny0 - && word1(rv0) == Tiny1) - goto undfl; - word0(rv) = Tiny0; - word1(rv) = Tiny1; - goto cont; - } - else - word0(rv) -= P*Exp_msk1; - } - else { - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; - } -#else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!dsign) - aadj1 = -aadj1; - } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - } - z = word0(rv) & Exp_mask; -#ifndef SET_INEXACT -#ifdef Avoid_Underflow - if (!scale) -#endif - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } -#endif - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(rv0) = Exp_1 + (70 << Exp_shift); - word1(rv0) = 0; - dval(rv0) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif -#ifdef Avoid_Underflow - if (scale) { - word0(rv0) = Exp_1 - 2*P*Exp_msk1; - word1(rv0) = 0; - dval(rv) *= dval(rv0); -#ifndef NO_ERRNO - /* try to avoid the bug of testing an 8087 register value */ - if (word0(rv) == 0 && word1(rv) == 0) - PR_SetError(PR_RANGE_ERROR, 0); -#endif - } -#endif /* Avoid_Underflow */ -#ifdef SET_INEXACT - if (inexact && !(word0(rv) & Exp_mask)) { - /* set underflow bit */ - dval(rv0) = 1e-300; - dval(rv0) *= dval(rv0); - } -#endif - retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - ret: - if (se) - *se = (char *)s; - return sign ? -dval(rv) : dval(rv); - } - - static int -quorem -#ifdef KR_headers - (b, S) Bigint *b, *S; -#else - (Bigint *b, Bigint *S) -#endif -{ - int n; - ULong *bx, *bxe, q, *sx, *sxe; -#ifdef ULLong - ULLong borrow, carry, y, ys; -#else - ULong borrow, carry, y, ys; -#ifdef Pack_32 - ULong si, z, zs; -#endif -#endif - - n = S->wds; -#ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { -#ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } - -#ifndef MULTIPLE_THREADS - static char *dtoa_result; -#endif - - static char * -#ifdef KR_headers -rv_alloc(i) int i; -#else -rv_alloc(int i) -#endif -{ - int j, k, *r; - - j = sizeof(ULong); - for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; - j <<= 1) - k++; - r = (int*)Balloc(k); - *r = k; - return -#ifndef MULTIPLE_THREADS - dtoa_result = -#endif - (char *)(r+1); - } - - static char * -#ifdef KR_headers -nrv_alloc(s, rve, n) char *s, **rve; int n; -#else -nrv_alloc(char *s, char **rve, int n) -#endif -{ - char *rv, *t; - - t = rv = rv_alloc(n); - while(*t = *s++) t++; - if (rve) - *rve = t; - return rv; - } - -/* freedtoa(s) must be used to free values s returned by dtoa - * when MULTIPLE_THREADS is #defined. It should be used in all cases, - * but for consistency with earlier versions of dtoa, it is optional - * when MULTIPLE_THREADS is not defined. - */ - - static void -#ifdef KR_headers -freedtoa(s) char *s; -#else -freedtoa(char *s) -#endif -{ - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); -#ifndef MULTIPLE_THREADS - if (s == dtoa_result) - dtoa_result = 0; -#endif - } - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - static char * -dtoa -#ifdef KR_headers - (dd, mode, ndigits, decpt, sign, rve) - double dd; int mode, ndigits, *decpt, *sign; char **rve; -#else - (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) -#endif -{ - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; -#ifndef Sudden_Underflow - int denorm; - ULong x; -#endif - Bigint *b, *b1, *delta, *mlo, *mhi, *S; - U d, d2, eps; - double ds; - char *s, *s0; -#ifdef Honor_FLT_ROUNDS - int rounding; -#endif -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif - -#ifndef MULTIPLE_THREADS - if (dtoa_result) { - freedtoa(dtoa_result); - dtoa_result = 0; - } -#endif - - dval(d) = dd; - if (word0(d) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - -#if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) -#else - if (word0(d) == 0x8000) -#endif - { - /* Infinity or NaN */ - *decpt = 9999; -#ifdef IEEE_Arith - if (!word1(d) && !(word0(d) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); -#endif - return nrv_alloc("NaN", rve, 3); - } -#endif -#ifdef IBM - dval(d) += 0; /* normalize */ -#endif - if (!dval(d)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } - -#ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; -#endif -#ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { - if (*sign) - rounding = rounding == 2 ? 0 : 2; - else - if (rounding != 2) - rounding = 0; - } -#endif - - b = d2b(dval(d), &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#else - if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { -#endif - dval(d2) = dval(d); - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; -#ifdef IBM - if (j = 11 - hi0bits(word0(d2) & Frac_mask)) - dval(d2) /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif -#ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 - : word1(d) << 32 - i; - dval(d2) = x; - word0(d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - -#ifndef SET_INEXACT -#ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; -#else - try_quick = 1; -#endif -#endif /*SET_INEXACT*/ - - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - switch(mode) { - case 0: - case 1: - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s = s0 = rv_alloc(i); - -#ifdef Honor_FLT_ROUNDS - if (mode > 1 && rounding != 1) - leftright = 0; -#endif - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(d2) = dval(d); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(d) /= ds; - } - else if (j1 = -k) { - dval(d) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(d) *= bigtens[i]; - } - } - if (k_check && dval(d) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(d) *= 10.; - ieps++; - } - dval(eps) = ieps*dval(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(d) -= 5.; - if (dval(d) > dval(eps)) - goto one_digit; - if (dval(d) < -dval(eps)) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(eps) = 0.5/tens[ilim-1] - dval(eps); - for(i = 0;;) { - L = dval(d); - dval(d) -= L; - *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) - goto ret1; - if (1. - dval(d) < dval(eps)) - goto bump_up; - if (++i >= ilim) - break; - dval(eps) *= 10.; - dval(d) *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - dval(eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d)); - if (!(dval(d) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(d) > 0.5 + dval(eps)) - goto bump_up; - else if (dval(d) < 0.5 - dval(eps)) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } -#ifndef No_leftright - } -#endif - fast_failed: - s = s0; - dval(d) = dval(d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1; i <= k+1; i++, dval(d) *= 10.) { - L = (Long)(dval(d) / ds); - dval(d) -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { - L--; - dval(d) += ds; - } -#endif - *s++ = '0' + (int)L; - if (!dval(d)) { -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (i == ilim) { -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(rounding) { - case 0: goto ret1; - case 2: goto bump_up; - } -#endif - dval(d) += dval(d); - if (dval(d) > ds || dval(d) == ds && L & 1) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - if (j = b5 - m5) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) -#ifdef Honor_FLT_ROUNDS - && rounding == 1 -#endif - ) { - if (!word1(d) && !(word0(d) & Bndry_mask) -#ifndef Sudden_Underflow - && word0(d) & (Exp_mask & ~Exp_msk1) -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ -#ifdef Pack_32 - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) - i = 32 - i; -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(d) & 1) -#ifdef Honor_FLT_ROUNDS - && rounding >= 1 -#endif - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; -#ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; -#endif - *s++ = dig; - goto ret; - } -#endif - if (j < 0 || j == 0 && mode != 1 -#ifndef ROUND_BIASED - && !(word1(d) & 1) -#endif - ) { - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto accept_dig; - } -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(rounding) { - case 0: goto accept_dig; - case 2: goto keep_dig; - } -#endif /*Honor_FLT_ROUNDS*/ - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) - && dig++ == '9') - goto round_9_up; - } - accept_dig: - *s++ = dig; - goto ret; - } - if (j1 > 0) { -#ifdef Honor_FLT_ROUNDS - if (!rounding) - goto accept_dig; -#endif - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } -#ifdef Honor_FLT_ROUNDS - keep_dig: -#endif - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } - - /* Round off last digit */ - -#ifdef Honor_FLT_ROUNDS - switch(rounding) { - case 0: goto trimzeros; - case 2: goto roundoff; - } -#endif - b = lshift(b, 1); - j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { -#ifdef Honor_FLT_ROUNDS - trimzeros: -#endif - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(d) = Exp_1 + (70 << Exp_shift); - word1(d) = 0; - dval(d) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - } -#ifdef __cplusplus -} -#endif - -PR_IMPLEMENT(PRStatus) -PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits, - PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize) -{ - char *result; - PRSize resultlen; - PRStatus rv = PR_FAILURE; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (mode < 0 || mode > 3) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return rv; - } - result = dtoa(d, mode, ndigits, decpt, sign, rve); - if (!result) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return rv; - } - resultlen = strlen(result)+1; - if (bufsize < resultlen) { - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); - } else { - memcpy(buf, result, resultlen); - if (rve) { - *rve = buf + (*rve - result); - } - rv = PR_SUCCESS; - } - freedtoa(result); - return rv; -} - -/* -** conversion routines for floating point -** prcsn - number of digits of precision to generate floating -** point value. -** This should be reparameterized so that you can send in a -** prcn for the positive and negative ranges. For now, -** conform to the ECMA JavaScript spec which says numbers -** less than 1e-6 are in scientific notation. -** Also, the ECMA spec says that there should always be a -** '+' or '-' after the 'e' in scientific notation -*/ -PR_IMPLEMENT(void) -PR_cnvtf(char *buf, int bufsz, int prcsn, double dfval) -{ - PRIntn decpt, sign, numdigits; - char *num, *nump; - char *bufp = buf; - char *endnum; - U fval; - - dval(fval) = dfval; - /* If anything fails, we store an empty string in 'buf' */ - num = (char*)PR_MALLOC(bufsz); - if (num == NULL) { - buf[0] = '\0'; - return; - } - /* XXX Why use mode 1? */ - if (PR_dtoa(dval(fval),1,prcsn,&decpt,&sign,&endnum,num,bufsz) - == PR_FAILURE) { - buf[0] = '\0'; - goto done; - } - numdigits = endnum - num; - nump = num; - - if (sign && - !(word0(fval) == Sign_bit && word1(fval) == 0) && - !((word0(fval) & Exp_mask) == Exp_mask && - (word1(fval) || (word0(fval) & 0xfffff)))) { - *bufp++ = '-'; - } - - if (decpt == 9999) { - while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */ - goto done; - } - - if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) { - *bufp++ = *nump++; - if (numdigits != 1) { - *bufp++ = '.'; - } - - while (*nump != '\0') { - *bufp++ = *nump++; - } - *bufp++ = 'e'; - PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1); - } else if (decpt >= 0) { - if (decpt == 0) { - *bufp++ = '0'; - } else { - while (decpt--) { - if (*nump != '\0') { - *bufp++ = *nump++; - } else { - *bufp++ = '0'; - } - } - } - if (*nump != '\0') { - *bufp++ = '.'; - while (*nump != '\0') { - *bufp++ = *nump++; - } - } - *bufp++ = '\0'; - } else if (decpt < 0) { - *bufp++ = '0'; - *bufp++ = '.'; - while (decpt++) { - *bufp++ = '0'; - } - - while (*nump != '\0') { - *bufp++ = *nump++; - } - *bufp++ = '\0'; - } -done: - PR_DELETE(num); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prenv.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prenv.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prenv.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prenv.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "primpl.h" - -/* Lock used to lock the environment */ -#if defined(_PR_NO_PREEMPT) -#define _PR_NEW_LOCK_ENV() -#define _PR_DELETE_LOCK_ENV() -#define _PR_LOCK_ENV() -#define _PR_UNLOCK_ENV() -#elif defined(_PR_LOCAL_THREADS_ONLY) -extern _PRCPU * _pr_primordialCPU; -static PRIntn _is; -#define _PR_NEW_LOCK_ENV() -#define _PR_DELETE_LOCK_ENV() -#define _PR_LOCK_ENV() if (_pr_primordialCPU) _PR_INTSOFF(_is); -#define _PR_UNLOCK_ENV() if (_pr_primordialCPU) _PR_INTSON(_is); -#else -static PRLock *_pr_envLock = NULL; -#define _PR_NEW_LOCK_ENV() {_pr_envLock = PR_NewLock();} -#define _PR_DELETE_LOCK_ENV() \ - { if (_pr_envLock) { PR_DestroyLock(_pr_envLock); _pr_envLock = NULL; } } -#define _PR_LOCK_ENV() { if (_pr_envLock) PR_Lock(_pr_envLock); } -#define _PR_UNLOCK_ENV() { if (_pr_envLock) PR_Unlock(_pr_envLock); } -#endif - -/************************************************************************/ - -void _PR_InitEnv(void) -{ - _PR_NEW_LOCK_ENV(); -} - -void _PR_CleanupEnv(void) -{ - _PR_DELETE_LOCK_ENV(); -} - -PR_IMPLEMENT(char*) PR_GetEnv(const char *var) -{ - char *ev; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - _PR_LOCK_ENV(); - ev = _PR_MD_GET_ENV(var); - _PR_UNLOCK_ENV(); - return ev; -} - -PR_IMPLEMENT(PRStatus) PR_SetEnv(const char *string) -{ - PRIntn result; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if ( !strchr(string, '=')) return(PR_FAILURE); - - _PR_LOCK_ENV(); - result = _PR_MD_PUT_ENV(string); - _PR_UNLOCK_ENV(); - return (result)? PR_FAILURE : PR_SUCCESS; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerr.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerr.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerr.c 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * - * prerr.c - * This file is automatically generated; please do not edit it. - */ -#include "prerror.h" -static const struct PRErrorMessage text[] = { - {"PR_OUT_OF_MEMORY_ERROR", "Memory allocation attempt failed"}, - {"PR_BAD_DESCRIPTOR_ERROR", "Invalid file descriptor"}, - {"PR_WOULD_BLOCK_ERROR", "The operation would have blocked"}, - {"PR_ACCESS_FAULT_ERROR", "Invalid memory address argument"}, - {"PR_INVALID_METHOD_ERROR", "Invalid function for file type"}, - {"PR_ILLEGAL_ACCESS_ERROR", "Invalid memory address argument"}, - {"PR_UNKNOWN_ERROR", "Some unknown error has occurred"}, - {"PR_PENDING_INTERRUPT_ERROR", "Operation interrupted by another thread"}, - {"PR_NOT_IMPLEMENTED_ERROR", "function not implemented"}, - {"PR_IO_ERROR", "I/O function error"}, - {"PR_IO_TIMEOUT_ERROR", "I/O operation timed out"}, - {"PR_IO_PENDING_ERROR", "I/O operation on busy file descriptor"}, - {"PR_DIRECTORY_OPEN_ERROR", "The directory could not be opened"}, - {"PR_INVALID_ARGUMENT_ERROR", "Invalid function argument"}, - {"PR_ADDRESS_NOT_AVAILABLE_ERROR", "Network address not available (in use?)"}, - {"PR_ADDRESS_NOT_SUPPORTED_ERROR", "Network address type not supported"}, - {"PR_IS_CONNECTED_ERROR", "Already connected"}, - {"PR_BAD_ADDRESS_ERROR", "Network address is invalid"}, - {"PR_ADDRESS_IN_USE_ERROR", "Local Network address is in use"}, - {"PR_CONNECT_REFUSED_ERROR", "Connection refused by peer"}, - {"PR_NETWORK_UNREACHABLE_ERROR", "Network address is presently unreachable"}, - {"PR_CONNECT_TIMEOUT_ERROR", "Connection attempt timed out"}, - {"PR_NOT_CONNECTED_ERROR", "Network file descriptor is not connected"}, - {"PR_LOAD_LIBRARY_ERROR", "Failure to load dynamic library"}, - {"PR_UNLOAD_LIBRARY_ERROR", "Failure to unload dynamic library"}, - {"PR_FIND_SYMBOL_ERROR", "Symbol not found in any of the loaded dynamic libraries"}, - {"PR_INSUFFICIENT_RESOURCES_ERROR", "Insufficient system resources"}, - {"PR_DIRECTORY_LOOKUP_ERROR", "A directory lookup on a network address has failed"}, - {"PR_TPD_RANGE_ERROR", "Attempt to access a TPD key that is out of range"}, - {"PR_PROC_DESC_TABLE_FULL_ERROR", "Process open FD table is full"}, - {"PR_SYS_DESC_TABLE_FULL_ERROR", "System open FD table is full"}, - {"PR_NOT_SOCKET_ERROR", "Network operation attempted on non-network file descriptor"}, - {"PR_NOT_TCP_SOCKET_ERROR", "TCP-specific function attempted on a non-TCP file descriptor"}, - {"PR_SOCKET_ADDRESS_IS_BOUND_ERROR", "TCP file descriptor is already bound"}, - {"PR_NO_ACCESS_RIGHTS_ERROR", "Access Denied"}, - {"PR_OPERATION_NOT_SUPPORTED_ERROR", "The requested operation is not supported by the platform"}, - {"PR_PROTOCOL_NOT_SUPPORTED_ERROR", "The host operating system does not support the protocol requested"}, - {"PR_REMOTE_FILE_ERROR", "Access to the remote file has been severed"}, - {"PR_BUFFER_OVERFLOW_ERROR", "The value requested is too large to be stored in the data buffer provided"}, - {"PR_CONNECT_RESET_ERROR", "TCP connection reset by peer"}, - {"PR_RANGE_ERROR", "Unused"}, - {"PR_DEADLOCK_ERROR", "The operation would have deadlocked"}, - {"PR_FILE_IS_LOCKED_ERROR", "The file is already locked"}, - {"PR_FILE_TOO_BIG_ERROR", "Write would result in file larger than the system allows"}, - {"PR_NO_DEVICE_SPACE_ERROR", "The device for storing the file is full"}, - {"PR_PIPE_ERROR", "Unused"}, - {"PR_NO_SEEK_DEVICE_ERROR", "Unused"}, - {"PR_IS_DIRECTORY_ERROR", "Cannot perform a normal file operation on a directory"}, - {"PR_LOOP_ERROR", "Symbolic link loop"}, - {"PR_NAME_TOO_LONG_ERROR", "File name is too long"}, - {"PR_FILE_NOT_FOUND_ERROR", "File not found"}, - {"PR_NOT_DIRECTORY_ERROR", "Cannot perform directory operation on a normal file"}, - {"PR_READ_ONLY_FILESYSTEM_ERROR", "Cannot write to a read-only file system"}, - {"PR_DIRECTORY_NOT_EMPTY_ERROR", "Cannot delete a directory that is not empty"}, - {"PR_FILESYSTEM_MOUNTED_ERROR", "Cannot delete or rename a file object while the file system is busy"}, - {"PR_NOT_SAME_DEVICE_ERROR", "Cannot rename a file to a file system on another device"}, - {"PR_DIRECTORY_CORRUPTED_ERROR", "The directory object in the file system is corrupted"}, - {"PR_FILE_EXISTS_ERROR", "Cannot create or rename a filename that already exists"}, - {"PR_MAX_DIRECTORY_ENTRIES_ERROR", "Directory is full. No additional filenames may be added"}, - {"PR_INVALID_DEVICE_STATE_ERROR", "The required device was in an invalid state"}, - {"PR_DEVICE_IS_LOCKED_ERROR", "The device is locked"}, - {"PR_NO_MORE_FILES_ERROR", "No more entries in the directory"}, - {"PR_END_OF_FILE_ERROR", "Encountered end of file"}, - {"PR_FILE_SEEK_ERROR", "Seek error"}, - {"PR_FILE_IS_BUSY_ERROR", "The file is busy"}, - {"PR_OPERATION_ABORTED_ERROR", "The I/O operation was aborted"}, - {"PR_IN_PROGRESS_ERROR", "Operation is still in progress (probably a non-blocking connect)"}, - {"PR_ALREADY_INITIATED_ERROR", "Operation has already been initiated (probably a non-blocking connect)"}, - {"PR_GROUP_EMPTY_ERROR", "The wait group is empty"}, - {"PR_INVALID_STATE_ERROR", "Object state improper for request"}, - {"PR_NETWORK_DOWN_ERROR", "Network is down"}, - {"PR_SOCKET_SHUTDOWN_ERROR", "Socket shutdown"}, - {"PR_CONNECT_ABORTED_ERROR", "Connection aborted"}, - {"PR_HOST_UNREACHABLE_ERROR", "Host is unreachable"}, - {"PR_LIBRARY_NOT_LOADED_ERROR", "The library is not loaded"}, - {"PR_CALL_ONCE_ERROR", "The one-time function was previously called and failed. Its error code is no longer available"}, - {"PR_MAX_ERROR", "Placeholder for the end of the list"}, - {0, 0} -}; - -static const struct PRErrorTable et = { text, "prerr", -6000L, 77 }; - -void nspr_InitializePRErrorTable(void) { - PR_ErrorInstallTable(&et); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerr.et nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerr.et --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerr.et 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerr.et 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -et nspr -6000 - -ec PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed" -ec PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor" -ec PR_WOULD_BLOCK_ERROR, "The operation would have blocked" -ec PR_ACCESS_FAULT_ERROR, "Invalid memory address argument" -ec PR_INVALID_METHOD_ERROR, "Invalid function for file type" -ec PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument" -ec PR_UNKNOWN_ERROR, "Some unknown error has occurred" -ec PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread" -ec PR_NOT_IMPLEMENTED_ERROR, "function not implemented" -ec PR_IO_ERROR, "I/O function error" -ec PR_IO_TIMEOUT_ERROR, "I/O operation timed out" -ec PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor" -ec PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened" -ec PR_INVALID_ARGUMENT_ERROR, "Invalid function argument" -ec PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)" -ec PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported" -ec PR_IS_CONNECTED_ERROR, "Already connected" -ec PR_BAD_ADDRESS_ERROR, "Network address is invalid" -ec PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use" -ec PR_CONNECT_REFUSED_ERROR, "Connection refused by peer" -ec PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable" -ec PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out" -ec PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected" -ec PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library" -ec PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library" -ec PR_FIND_SYMBOL_ERROR, -"Symbol not found in any of the loaded dynamic libraries" -ec PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources" -ec PR_DIRECTORY_LOOKUP_ERROR, -"A directory lookup on a network address has failed" -ec PR_TPD_RANGE_ERROR, -"Attempt to access a TPD key that is out of range" -ec PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full" -ec PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full" -ec PR_NOT_SOCKET_ERROR, -"Network operation attempted on non-network file descriptor" -ec PR_NOT_TCP_SOCKET_ERROR, -"TCP-specific function attempted on a non-TCP file descriptor" -ec PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound" -ec PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied" -ec PR_OPERATION_NOT_SUPPORTED_ERROR, -"The requested operation is not supported by the platform" -ec PR_PROTOCOL_NOT_SUPPORTED_ERROR, -"The host operating system does not support the protocol requested" -ec PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed" -ec PR_BUFFER_OVERFLOW_ERROR, -"The value requested is too large to be stored in the data buffer provided" -ec PR_CONNECT_RESET_ERROR, "TCP connection reset by peer" -ec PR_RANGE_ERROR, "Unused" -ec PR_DEADLOCK_ERROR, "The operation would have deadlocked" -ec PR_FILE_IS_LOCKED_ERROR, "The file is already locked" -ec PR_FILE_TOO_BIG_ERROR, -"Write would result in file larger than the system allows" -ec PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full" -ec PR_PIPE_ERROR, "Unused" -ec PR_NO_SEEK_DEVICE_ERROR, "Unused" -ec PR_IS_DIRECTORY_ERROR, -"Cannot perform a normal file operation on a directory" -ec PR_LOOP_ERROR, "Symbolic link loop" -ec PR_NAME_TOO_LONG_ERROR, "File name is too long" -ec PR_FILE_NOT_FOUND_ERROR, "File not found" -ec PR_NOT_DIRECTORY_ERROR, -"Cannot perform directory operation on a normal file" -ec PR_READ_ONLY_FILESYSTEM_ERROR, -"Cannot write to a read-only file system" -ec PR_DIRECTORY_NOT_EMPTY_ERROR, -"Cannot delete a directory that is not empty" -ec PR_FILESYSTEM_MOUNTED_ERROR, -"Cannot delete or rename a file object while the file system is busy" -ec PR_NOT_SAME_DEVICE_ERROR, -"Cannot rename a file to a file system on another device" -ec PR_DIRECTORY_CORRUPTED_ERROR, -"The directory object in the file system is corrupted" -ec PR_FILE_EXISTS_ERROR, -"Cannot create or rename a filename that already exists" -ec PR_MAX_DIRECTORY_ENTRIES_ERROR, -"Directory is full. No additional filenames may be added" -ec PR_INVALID_DEVICE_STATE_ERROR, -"The required device was in an invalid state" -ec PR_DEVICE_IS_LOCKED_ERROR, "The device is locked" -ec PR_NO_MORE_FILES_ERROR, "No more entries in the directory" -ec PR_END_OF_FILE_ERROR, "Encountered end of file" -ec PR_FILE_SEEK_ERROR, "Seek error" -ec PR_FILE_IS_BUSY_ERROR, "The file is busy" -ec PR_OPERATION_ABORTED_ERROR, "The I/O operation was aborted" -ec PR_IN_PROGRESS_ERROR, -"Operation is still in progress (probably a non-blocking connect)" -ec PR_ALREADY_INITIATED_ERROR, -"Operation has already been initiated (probably a non-blocking connect)" -ec PR_GROUP_EMPTY_ERROR, "The wait group is empty" -ec PR_INVALID_STATE_ERROR, "Object state improper for request" -ec PR_NETWORK_DOWN_ERROR, "Network is down" -ec PR_SOCKET_SHUTDOWN_ERROR, "Socket shutdown" -ec PR_CONNECT_ABORTED_ERROR, "Connection aborted" -ec PR_HOST_UNREACHABLE_ERROR, "Host is unreachable" -ec PR_LIBRARY_NOT_LOADED_ERROR, "The library is not loaded" -ec PR_CALL_ONCE_ERROR, "The one-time function was previously called and failed. Its error code is no longer available" - -ec PR_MAX_ERROR, "Placeholder for the end of the list" - -end diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerror.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerror.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerror.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerror.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include - -PR_IMPLEMENT(PRErrorCode) PR_GetError(void) -{ - PRThread *thread = PR_GetCurrentThread(); - return thread->errorCode; -} - -PR_IMPLEMENT(PRInt32) PR_GetOSError(void) -{ - PRThread *thread = PR_GetCurrentThread(); - return thread->osErrorCode; -} - -PR_IMPLEMENT(void) PR_SetError(PRErrorCode code, PRInt32 osErr) -{ - PRThread *thread = PR_GetCurrentThread(); - thread->errorCode = code; - thread->osErrorCode = osErr; - thread->errorStringLength = 0; -} - -PR_IMPLEMENT(void) PR_SetErrorText(PRIntn textLength, const char *text) -{ - PRThread *thread = PR_GetCurrentThread(); - - if (0 == textLength) - { - if (NULL != thread->errorString) - PR_DELETE(thread->errorString); - thread->errorStringSize = 0; - } - else - { - PRIntn size = textLength + 31; /* actual length to allocate. Plus a little extra */ - if (thread->errorStringSize < textLength+1) /* do we have room? */ - { - if (NULL != thread->errorString) - PR_DELETE(thread->errorString); - thread->errorString = (char*)PR_MALLOC(size); - if ( NULL == thread->errorString ) { - thread->errorStringSize = 0; - thread->errorStringLength = 0; - return; - } - thread->errorStringSize = size; - } - memcpy(thread->errorString, text, textLength+1 ); - } - thread->errorStringLength = textLength; -} - -PR_IMPLEMENT(PRInt32) PR_GetErrorTextLength(void) -{ - PRThread *thread = PR_GetCurrentThread(); - return thread->errorStringLength; -} /* PR_GetErrorTextLength */ - -PR_IMPLEMENT(PRInt32) PR_GetErrorText(char *text) -{ - PRThread *thread = PR_GetCurrentThread(); - if (0 != thread->errorStringLength) - memcpy(text, thread->errorString, thread->errorStringLength+1); - return thread->errorStringLength; -} /* PR_GetErrorText */ - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerrortable.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerrortable.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerrortable.c 2012-10-24 22:19:10.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerrortable.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,205 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - - - -/* - -Copyright 1987, 1988 by the Student Information Processing Board - of the Massachusetts Institute of Technology - -Permission to use, copy, modify, and distribute this software -and its documentation for any purpose and without fee is -hereby granted, provided that the above copyright notice -appear in all copies and that both that copyright notice and -this permission notice appear in supporting documentation, -and that the names of M.I.T. and the M.I.T. S.I.P.B. not be -used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -M.I.T. and the M.I.T. S.I.P.B. make no representations about -the suitability of this software for any purpose. It is -provided "as is" without express or implied warranty. - -*/ - -#include -#include -#include -#include "prmem.h" -#include "prerror.h" - -#define ERRCODE_RANGE 8 /* # of bits to shift table number */ -#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ - -#ifdef NEED_SYS_ERRLIST -extern char const * const sys_errlist[]; -extern const int sys_nerr; -#endif - -/* List of error tables */ -struct PRErrorTableList { - struct PRErrorTableList *next; - const struct PRErrorTable *table; - struct PRErrorCallbackTablePrivate *table_private; -}; -static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL; - -/* Supported languages */ -static const char * default_languages[] = { "i-default", "en", 0 }; -static const char * const * callback_languages = default_languages; - -/* Callback info */ -static struct PRErrorCallbackPrivate *callback_private = 0; -static PRErrorCallbackLookupFn *callback_lookup = 0; -static PRErrorCallbackNewTableFn *callback_newtable = 0; - - -static const char char_set[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; - -static const char * -error_table_name (PRErrorCode num) -{ - static char buf[6]; /* only used if internal code problems exist */ - - long ch; - int i; - char *p; - - /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */ - p = buf; - num >>= ERRCODE_RANGE; - /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */ - num &= 077777777; - /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ - for (i = 4; i >= 0; i--) { - ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); - if (ch != 0) - *p++ = char_set[ch-1]; - } - *p = '\0'; - return(buf); -} - -PR_IMPLEMENT(const char *) -PR_ErrorToString(PRErrorCode code, PRLanguageCode language) -{ - /* static buffer only used if code is using inconsistent error message - * numbers, so just ignore the possible thread contention - */ - static char buffer[25]; - - const char *msg; - int offset; - PRErrorCode table_num; - struct PRErrorTableList *et; - int started = 0; - char *cp; - - for (et = Table_List; et; et = et->next) { - if (et->table->base <= code && - et->table->base + et->table->n_msgs > code) { - /* This is the right table */ - if (callback_lookup) { - msg = callback_lookup(code, language, et->table, - callback_private, et->table_private); - if (msg) return msg; - } - - return(et->table->msgs[code - et->table->base].en_text); - } - } - - if (code >= 0 && code < 256) { - return strerror(code); - } - - offset = (int) (code & ((1<= 100) { - *cp++ = (char)('0' + offset / 100); - offset %= 100; - started++; - } - if (started || offset >= 10) { - *cp++ = (char)('0' + offset / 10); - offset %= 10; - } - *cp++ = (char)('0' + offset); - *cp = '\0'; - return(buffer); -} - -PR_IMPLEMENT(const char *) -PR_ErrorToName(PRErrorCode code) -{ - struct PRErrorTableList *et; - - for (et = Table_List; et; et = et->next) { - if (et->table->base <= code && - et->table->base + et->table->n_msgs > code) { - /* This is the right table */ - return(et->table->msgs[code - et->table->base].name); - } - } - - return 0; -} - -PR_IMPLEMENT(const char * const *) -PR_ErrorLanguages(void) -{ - return callback_languages; -} - -PR_IMPLEMENT(PRErrorCode) -PR_ErrorInstallTable(const struct PRErrorTable *table) -{ - struct PRErrorTableList * new_et; - - new_et = (struct PRErrorTableList *) - PR_Malloc(sizeof(struct PRErrorTableList)); - if (!new_et) - return errno; /* oops */ - new_et->table = table; - if (callback_newtable) { - new_et->table_private = callback_newtable(table, callback_private); - } else { - new_et->table_private = 0; - } - new_et->next = Table_List; - Table_List = new_et; - return 0; -} - -PR_IMPLEMENT(void) -PR_ErrorInstallCallback(const char * const * languages, - PRErrorCallbackLookupFn *lookup, - PRErrorCallbackNewTableFn *newtable, - struct PRErrorCallbackPrivate *cb_private) -{ - struct PRErrorTableList *et; - - assert(strcmp(languages[0], "i-default") == 0); - assert(strcmp(languages[1], "en") == 0); - - callback_languages = languages; - callback_lookup = lookup; - callback_newtable = newtable; - callback_private = cb_private; - - if (callback_newtable) { - for (et = Table_List; et; et = et->next) { - et->table_private = callback_newtable(et->table, callback_private); - } - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerr.properties nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerr.properties --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prerr.properties 2012-03-06 13:14:19.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prerr.properties 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# -# prerr.properties -# This file is automatically generated; please do not edit it. -PR_OUT_OF_MEMORY_ERROR=Memory allocation attempt failed -PR_BAD_DESCRIPTOR_ERROR=Invalid file descriptor -PR_WOULD_BLOCK_ERROR=The operation would have blocked -PR_ACCESS_FAULT_ERROR=Invalid memory address argument -PR_INVALID_METHOD_ERROR=Invalid function for file type -PR_ILLEGAL_ACCESS_ERROR=Invalid memory address argument -PR_UNKNOWN_ERROR=Some unknown error has occurred -PR_PENDING_INTERRUPT_ERROR=Operation interrupted by another thread -PR_NOT_IMPLEMENTED_ERROR=function not implemented -PR_IO_ERROR=I/O function error -PR_IO_TIMEOUT_ERROR=I/O operation timed out -PR_IO_PENDING_ERROR=I/O operation on busy file descriptor -PR_DIRECTORY_OPEN_ERROR=The directory could not be opened -PR_INVALID_ARGUMENT_ERROR=Invalid function argument -PR_ADDRESS_NOT_AVAILABLE_ERROR=Network address not available (in use?) -PR_ADDRESS_NOT_SUPPORTED_ERROR=Network address type not supported -PR_IS_CONNECTED_ERROR=Already connected -PR_BAD_ADDRESS_ERROR=Network address is invalid -PR_ADDRESS_IN_USE_ERROR=Local Network address is in use -PR_CONNECT_REFUSED_ERROR=Connection refused by peer -PR_NETWORK_UNREACHABLE_ERROR=Network address is presently unreachable -PR_CONNECT_TIMEOUT_ERROR=Connection attempt timed out -PR_NOT_CONNECTED_ERROR=Network file descriptor is not connected -PR_LOAD_LIBRARY_ERROR=Failure to load dynamic library -PR_UNLOAD_LIBRARY_ERROR=Failure to unload dynamic library -PR_FIND_SYMBOL_ERROR=Symbol not found in any of the loaded dynamic libraries -PR_INSUFFICIENT_RESOURCES_ERROR=Insufficient system resources -PR_DIRECTORY_LOOKUP_ERROR=A directory lookup on a network address has failed -PR_TPD_RANGE_ERROR=Attempt to access a TPD key that is out of range -PR_PROC_DESC_TABLE_FULL_ERROR=Process open FD table is full -PR_SYS_DESC_TABLE_FULL_ERROR=System open FD table is full -PR_NOT_SOCKET_ERROR=Network operation attempted on non-network file descriptor -PR_NOT_TCP_SOCKET_ERROR=TCP-specific function attempted on a non-TCP file descriptor -PR_SOCKET_ADDRESS_IS_BOUND_ERROR=TCP file descriptor is already bound -PR_NO_ACCESS_RIGHTS_ERROR=Access Denied -PR_OPERATION_NOT_SUPPORTED_ERROR=The requested operation is not supported by the platform -PR_PROTOCOL_NOT_SUPPORTED_ERROR=The host operating system does not support the protocol requested -PR_REMOTE_FILE_ERROR=Access to the remote file has been severed -PR_BUFFER_OVERFLOW_ERROR=The value requested is too large to be stored in the data buffer provided -PR_CONNECT_RESET_ERROR=TCP connection reset by peer -PR_RANGE_ERROR=Unused -PR_DEADLOCK_ERROR=The operation would have deadlocked -PR_FILE_IS_LOCKED_ERROR=The file is already locked -PR_FILE_TOO_BIG_ERROR=Write would result in file larger than the system allows -PR_NO_DEVICE_SPACE_ERROR=The device for storing the file is full -PR_PIPE_ERROR=Unused -PR_NO_SEEK_DEVICE_ERROR=Unused -PR_IS_DIRECTORY_ERROR=Cannot perform a normal file operation on a directory -PR_LOOP_ERROR=Symbolic link loop -PR_NAME_TOO_LONG_ERROR=File name is too long -PR_FILE_NOT_FOUND_ERROR=File not found -PR_NOT_DIRECTORY_ERROR=Cannot perform directory operation on a normal file -PR_READ_ONLY_FILESYSTEM_ERROR=Cannot write to a read-only file system -PR_DIRECTORY_NOT_EMPTY_ERROR=Cannot delete a directory that is not empty -PR_FILESYSTEM_MOUNTED_ERROR=Cannot delete or rename a file object while the file system is busy -PR_NOT_SAME_DEVICE_ERROR=Cannot rename a file to a file system on another device -PR_DIRECTORY_CORRUPTED_ERROR=The directory object in the file system is corrupted -PR_FILE_EXISTS_ERROR=Cannot create or rename a filename that already exists -PR_MAX_DIRECTORY_ENTRIES_ERROR=Directory is full. No additional filenames may be added -PR_INVALID_DEVICE_STATE_ERROR=The required device was in an invalid state -PR_DEVICE_IS_LOCKED_ERROR=The device is locked -PR_NO_MORE_FILES_ERROR=No more entries in the directory -PR_END_OF_FILE_ERROR=Encountered end of file -PR_FILE_SEEK_ERROR=Seek error -PR_FILE_IS_BUSY_ERROR=The file is busy -PR_OPERATION_ABORTED_ERROR=The I/O operation was aborted -PR_IN_PROGRESS_ERROR=Operation is still in progress (probably a non-blocking connect) -PR_ALREADY_INITIATED_ERROR=Operation has already been initiated (probably a non-blocking connect) -PR_GROUP_EMPTY_ERROR=The wait group is empty -PR_INVALID_STATE_ERROR=Object state improper for request -PR_NETWORK_DOWN_ERROR=Network is down -PR_SOCKET_SHUTDOWN_ERROR=Socket shutdown -PR_CONNECT_ABORTED_ERROR=Connection aborted -PR_HOST_UNREACHABLE_ERROR=Host is unreachable -PR_LIBRARY_NOT_LOADED_ERROR=The library is not loaded -PR_CALL_ONCE_ERROR=The one-time function was previously called and failed. Its error code is no longer available -PR_MAX_ERROR=Placeholder for the end of the list diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prinit.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prinit.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prinit.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prinit.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,836 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include -#include - -PRLogModuleInfo *_pr_clock_lm; -PRLogModuleInfo *_pr_cmon_lm; -PRLogModuleInfo *_pr_io_lm; -PRLogModuleInfo *_pr_cvar_lm; -PRLogModuleInfo *_pr_mon_lm; -PRLogModuleInfo *_pr_linker_lm; -PRLogModuleInfo *_pr_sched_lm; -PRLogModuleInfo *_pr_thread_lm; -PRLogModuleInfo *_pr_gc_lm; -PRLogModuleInfo *_pr_shm_lm; -PRLogModuleInfo *_pr_shma_lm; - -PRFileDesc *_pr_stdin; -PRFileDesc *_pr_stdout; -PRFileDesc *_pr_stderr; - -#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - -PRCList _pr_active_local_threadQ = - PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ); -PRCList _pr_active_global_threadQ = - PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ); - -_MDLock _pr_cpuLock; /* lock for the CPU Q */ -PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ); - -PRUint32 _pr_utid; - -PRInt32 _pr_userActive; -PRInt32 _pr_systemActive; -PRUintn _pr_maxPTDs; - -#ifdef _PR_LOCAL_THREADS_ONLY - -struct _PRCPU *_pr_currentCPU; -PRThread *_pr_currentThread; -PRThread *_pr_lastThread; -PRInt32 _pr_intsOff; - -#endif /* _PR_LOCAL_THREADS_ONLY */ - -/* Lock protecting all "termination" condition variables of all threads */ -PRLock *_pr_terminationCVLock; - -#endif /* !defined(_PR_PTHREADS) */ - -PRLock *_pr_sleeplock; /* used in PR_Sleep(), classic and pthreads */ - -static void _PR_InitCallOnce(void); - -PRBool _pr_initialized = PR_FALSE; - - -PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion) -{ - /* - ** This is the secret handshake algorithm. - ** - ** This release has a simple version compatibility - ** check algorithm. This release is not backward - ** compatible with previous major releases. It is - ** not compatible with future major, minor, or - ** patch releases. - */ - int vmajor = 0, vminor = 0, vpatch = 0; - const char *ptr = importedVersion; - - while (isdigit(*ptr)) { - vmajor = 10 * vmajor + *ptr - '0'; - ptr++; - } - if (*ptr == '.') { - ptr++; - while (isdigit(*ptr)) { - vminor = 10 * vminor + *ptr - '0'; - ptr++; - } - if (*ptr == '.') { - ptr++; - while (isdigit(*ptr)) { - vpatch = 10 * vpatch + *ptr - '0'; - ptr++; - } - } - } - - if (vmajor != PR_VMAJOR) { - return PR_FALSE; - } - if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) { - return PR_FALSE; - } - if (vmajor == PR_VMAJOR && vminor == PR_VMINOR && vpatch > PR_VPATCH) { - return PR_FALSE; - } - return PR_TRUE; -} /* PR_VersionCheck */ - -PR_IMPLEMENT(const char*) PR_GetVersion(void) -{ - return PR_VERSION; -} - -PR_IMPLEMENT(PRBool) PR_Initialized(void) -{ - return _pr_initialized; -} - -PRInt32 _native_threads_only = 0; - -#ifdef WINNT -static void _pr_SetNativeThreadsOnlyMode(void) -{ - HMODULE mainExe; - PRBool *globalp; - char *envp; - - mainExe = GetModuleHandle(NULL); - PR_ASSERT(NULL != mainExe); - globalp = (PRBool *) GetProcAddress(mainExe, "nspr_native_threads_only"); - if (globalp) { - _native_threads_only = (*globalp != PR_FALSE); - } else if (envp = getenv("NSPR_NATIVE_THREADS_ONLY")) { - _native_threads_only = (atoi(envp) == 1); - } -} -#endif - -static void _PR_InitStuff(void) -{ - - if (_pr_initialized) return; - _pr_initialized = PR_TRUE; -#ifdef _PR_ZONE_ALLOCATOR - _PR_InitZones(); -#endif -#ifdef WINNT - _pr_SetNativeThreadsOnlyMode(); -#endif - - - (void) PR_GetPageSize(); - - _pr_clock_lm = PR_NewLogModule("clock"); - _pr_cmon_lm = PR_NewLogModule("cmon"); - _pr_io_lm = PR_NewLogModule("io"); - _pr_mon_lm = PR_NewLogModule("mon"); - _pr_linker_lm = PR_NewLogModule("linker"); - _pr_cvar_lm = PR_NewLogModule("cvar"); - _pr_sched_lm = PR_NewLogModule("sched"); - _pr_thread_lm = PR_NewLogModule("thread"); - _pr_gc_lm = PR_NewLogModule("gc"); - _pr_shm_lm = PR_NewLogModule("shm"); - _pr_shma_lm = PR_NewLogModule("shma"); - - /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */ - _PR_MD_EARLY_INIT(); - - _PR_InitLocks(); - _PR_InitAtomic(); - _PR_InitSegs(); - _PR_InitStacks(); - _PR_InitTPD(); - _PR_InitEnv(); - _PR_InitLayerCache(); - _PR_InitClock(); - - _pr_sleeplock = PR_NewLock(); - PR_ASSERT(NULL != _pr_sleeplock); - - _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - -#ifdef WIN16 - { - PRInt32 top; /* artificial top of stack, win16 */ - _pr_top_of_task_stack = (char *) ⊤ - } -#endif - -#ifndef _PR_GLOBAL_THREADS_ONLY - _PR_InitCPUs(); -#endif - -/* - * XXX: call _PR_InitMem only on those platforms for which nspr implements - * malloc, for now. - */ -#ifdef _PR_OVERRIDE_MALLOC - _PR_InitMem(); -#endif - - _PR_InitCMon(); - _PR_InitIO(); - _PR_InitNet(); - _PR_InitTime(); - _PR_InitLog(); - _PR_InitLinker(); - _PR_InitCallOnce(); - _PR_InitDtoa(); - _PR_InitMW(); - _PR_InitRWLocks(); - - nspr_InitializePRErrorTable(); - - _PR_MD_FINAL_INIT(); -} - -void _PR_ImplicitInitialization(void) -{ - _PR_InitStuff(); - - /* Enable interrupts */ -#if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) - _PR_MD_START_INTERRUPTS(); -#endif - -} - -PR_IMPLEMENT(void) PR_DisableClockInterrupts(void) -{ -#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - if (!_pr_initialized) { - _PR_InitStuff(); - } else { - _PR_MD_DISABLE_CLOCK_INTERRUPTS(); - } -#endif -} - -PR_IMPLEMENT(void) PR_EnableClockInterrupts(void) -{ -#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - if (!_pr_initialized) { - _PR_InitStuff(); - } - _PR_MD_ENABLE_CLOCK_INTERRUPTS(); -#endif -} - -PR_IMPLEMENT(void) PR_BlockClockInterrupts(void) -{ -#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - _PR_MD_BLOCK_CLOCK_INTERRUPTS(); -#endif -} - -PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void) -{ -#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(); -#endif -} - -PR_IMPLEMENT(void) PR_Init( - PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs) -{ - _PR_ImplicitInitialization(); -} - -PR_IMPLEMENT(PRIntn) PR_Initialize( - PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs) -{ - PRIntn rv; - _PR_ImplicitInitialization(); - rv = prmain(argc, argv); - PR_Cleanup(); - return rv; -} /* PR_Initialize */ - -/* - *----------------------------------------------------------------------- - * - * _PR_CleanupBeforeExit -- - * - * Perform the cleanup work before exiting the process. - * We first do the cleanup generic to all platforms. Then - * we call _PR_MD_CLEANUP_BEFORE_EXIT(), where platform-dependent - * cleanup is done. This function is used by PR_Cleanup(). - * - * See also: PR_Cleanup(). - * - *----------------------------------------------------------------------- - */ -#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) - /* see ptthread.c */ -#else -static void -_PR_CleanupBeforeExit(void) -{ -/* -Do not make any calls here other than to destroy resources. For example, -do not make any calls that eventually may end up in PR_Lock. Because the -thread is destroyed, can not access current thread any more. -*/ - _PR_CleanupTPD(); - if (_pr_terminationCVLock) - /* - * In light of the comment above, this looks real suspicious. - * I'd go so far as to say it's just a problem waiting to happen. - */ - PR_DestroyLock(_pr_terminationCVLock); - - _PR_MD_CLEANUP_BEFORE_EXIT(); -} -#endif /* defined(_PR_PTHREADS) */ - -/* - *---------------------------------------------------------------------- - * - * PR_Cleanup -- - * - * Perform a graceful shutdown of the NSPR runtime. PR_Cleanup() may - * only be called from the primordial thread, typically at the - * end of the main() function. It returns when it has completed - * its platform-dependent duty and the process must not make any other - * NSPR library calls prior to exiting from main(). - * - * PR_Cleanup() first blocks the primordial thread until all the - * other user (non-system) threads, if any, have terminated. - * Then it performs cleanup in preparation for exiting the process. - * PR_Cleanup() does not exit the primordial thread (which would - * in turn exit the process). - * - * PR_Cleanup() only responds when it is called by the primordial - * thread. Calls by any other thread are silently ignored. - * - * See also: PR_ExitProcess() - * - *---------------------------------------------------------------------- - */ -#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) - /* see ptthread.c */ -#else - -PR_IMPLEMENT(PRStatus) PR_Cleanup() -{ - PRThread *me = PR_GetCurrentThread(); - PR_ASSERT((NULL != me) && (me->flags & _PR_PRIMORDIAL)); - if ((NULL != me) && (me->flags & _PR_PRIMORDIAL)) - { - PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR")); - - /* - * No more recycling of threads - */ - _pr_recycleThreads = 0; - - /* - * Wait for all other user (non-system/daemon) threads - * to terminate. - */ - PR_Lock(_pr_activeLock); - while (_pr_userActive > _pr_primordialExitCount) { - PR_WaitCondVar(_pr_primordialExitCVar, PR_INTERVAL_NO_TIMEOUT); - } - if (me->flags & _PR_SYSTEM) { - _pr_systemActive--; - } else { - _pr_userActive--; - } - PR_Unlock(_pr_activeLock); - -#ifdef IRIX - _PR_MD_PRE_CLEANUP(me); - /* - * The primordial thread must now be running on the primordial cpu - */ - PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0)); -#endif - - _PR_MD_EARLY_CLEANUP(); - - _PR_CleanupMW(); - _PR_CleanupTime(); - _PR_CleanupDtoa(); - _PR_CleanupCallOnce(); - _PR_ShutdownLinker(); - _PR_CleanupNet(); - _PR_CleanupIO(); - /* Release the primordial thread's private data, etc. */ - _PR_CleanupThread(me); - - _PR_MD_STOP_INTERRUPTS(); - - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("PR_Cleanup: clean up before destroying thread")); - _PR_LogCleanup(); - - /* - * This part should look like the end of _PR_NativeRunThread - * and _PR_UserRunThread. - */ - if (_PR_IS_NATIVE_THREAD(me)) { - _PR_MD_EXIT_THREAD(me); - _PR_NativeDestroyThread(me); - } else { - _PR_UserDestroyThread(me); - PR_DELETE(me->stack); - PR_DELETE(me); - } - - /* - * XXX: We are freeing the heap memory here so that Purify won't - * complain, but we should also free other kinds of resources - * that are allocated by the _PR_InitXXX() functions. - * Ideally, for each _PR_InitXXX(), there should be a corresponding - * _PR_XXXCleanup() that we can call here. - */ -#ifdef WINNT - _PR_CleanupCPUs(); -#endif - _PR_CleanupThreads(); - _PR_CleanupCMon(); - PR_DestroyLock(_pr_sleeplock); - _pr_sleeplock = NULL; - _PR_CleanupLayerCache(); - _PR_CleanupEnv(); - _PR_CleanupStacks(); - _PR_CleanupBeforeExit(); - _pr_initialized = PR_FALSE; - return PR_SUCCESS; - } - return PR_FAILURE; -} -#endif /* defined(_PR_PTHREADS) */ - -/* - *------------------------------------------------------------------------ - * PR_ProcessExit -- - * - * Cause an immediate, nongraceful, forced termination of the process. - * It takes a PRIntn argument, which is the exit status code of the - * process. - * - * See also: PR_Cleanup() - * - *------------------------------------------------------------------------ - */ - -#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) - /* see ptthread.c */ -#else -PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status) -{ - _PR_MD_EXIT(status); -} - -#endif /* defined(_PR_PTHREADS) */ - -PR_IMPLEMENT(PRProcessAttr *) -PR_NewProcessAttr(void) -{ - PRProcessAttr *attr; - - attr = PR_NEWZAP(PRProcessAttr); - if (!attr) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - } - return attr; -} - -PR_IMPLEMENT(void) -PR_ResetProcessAttr(PRProcessAttr *attr) -{ - PR_FREEIF(attr->currentDirectory); - PR_FREEIF(attr->fdInheritBuffer); - memset(attr, 0, sizeof(*attr)); -} - -PR_IMPLEMENT(void) -PR_DestroyProcessAttr(PRProcessAttr *attr) -{ - PR_FREEIF(attr->currentDirectory); - PR_FREEIF(attr->fdInheritBuffer); - PR_DELETE(attr); -} - -PR_IMPLEMENT(void) -PR_ProcessAttrSetStdioRedirect( - PRProcessAttr *attr, - PRSpecialFD stdioFd, - PRFileDesc *redirectFd) -{ - switch (stdioFd) { - case PR_StandardInput: - attr->stdinFd = redirectFd; - break; - case PR_StandardOutput: - attr->stdoutFd = redirectFd; - break; - case PR_StandardError: - attr->stderrFd = redirectFd; - break; - default: - PR_ASSERT(0); - } -} - -/* - * OBSOLETE - */ -PR_IMPLEMENT(void) -PR_SetStdioRedirect( - PRProcessAttr *attr, - PRSpecialFD stdioFd, - PRFileDesc *redirectFd) -{ -#if defined(DEBUG) - static PRBool warn = PR_TRUE; - if (warn) { - warn = _PR_Obsolete("PR_SetStdioRedirect()", - "PR_ProcessAttrSetStdioRedirect()"); - } -#endif - PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd); -} - -PR_IMPLEMENT(PRStatus) -PR_ProcessAttrSetCurrentDirectory( - PRProcessAttr *attr, - const char *dir) -{ - PR_FREEIF(attr->currentDirectory); - attr->currentDirectory = (char *) PR_MALLOC(strlen(dir) + 1); - if (!attr->currentDirectory) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return PR_FAILURE; - } - strcpy(attr->currentDirectory, dir); - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) -PR_ProcessAttrSetInheritableFD( - PRProcessAttr *attr, - PRFileDesc *fd, - const char *name) -{ - /* We malloc the fd inherit buffer in multiples of this number. */ -#define FD_INHERIT_BUFFER_INCR 128 - /* The length of "NSPR_INHERIT_FDS=" */ -#define NSPR_INHERIT_FDS_STRLEN 17 - /* The length of osfd (PROsfd) printed in hexadecimal with 0x prefix */ -#ifdef _WIN64 -#define OSFD_STRLEN 18 -#else -#define OSFD_STRLEN 10 -#endif - /* The length of fd type (PRDescType) printed in decimal */ -#define FD_TYPE_STRLEN 1 - PRSize newSize; - int remainder; - char *newBuffer; - int nwritten; - char *cur; - int freeSize; - - if (fd->identity != PR_NSPR_IO_LAYER) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - if (fd->secret->inheritable == _PR_TRI_UNKNOWN) { - _PR_MD_QUERY_FD_INHERITABLE(fd); - } - if (fd->secret->inheritable != _PR_TRI_TRUE) { - PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0); - return PR_FAILURE; - } - - /* - * We also need to account for the : separators and the - * terminating null byte. - */ - if (NULL == attr->fdInheritBuffer) { - /* The first time, we print "NSPR_INHERIT_FDS=::" */ - newSize = NSPR_INHERIT_FDS_STRLEN + strlen(name) - + FD_TYPE_STRLEN + OSFD_STRLEN + 2 + 1; - } else { - /* At other times, we print ":::" */ - newSize = attr->fdInheritBufferUsed + strlen(name) - + FD_TYPE_STRLEN + OSFD_STRLEN + 3 + 1; - } - if (newSize > attr->fdInheritBufferSize) { - /* Make newSize a multiple of FD_INHERIT_BUFFER_INCR */ - remainder = newSize % FD_INHERIT_BUFFER_INCR; - if (remainder != 0) { - newSize += (FD_INHERIT_BUFFER_INCR - remainder); - } - if (NULL == attr->fdInheritBuffer) { - newBuffer = (char *) PR_MALLOC(newSize); - } else { - newBuffer = (char *) PR_REALLOC(attr->fdInheritBuffer, newSize); - } - if (NULL == newBuffer) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return PR_FAILURE; - } - attr->fdInheritBuffer = newBuffer; - attr->fdInheritBufferSize = newSize; - } - cur = attr->fdInheritBuffer + attr->fdInheritBufferUsed; - freeSize = attr->fdInheritBufferSize - attr->fdInheritBufferUsed; - if (0 == attr->fdInheritBufferUsed) { - nwritten = PR_snprintf(cur, freeSize, - "NSPR_INHERIT_FDS=%s:%d:0x%" PR_PRIxOSFD, - name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); - } else { - nwritten = PR_snprintf(cur, freeSize, ":%s:%d:0x%" PR_PRIxOSFD, - name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); - } - attr->fdInheritBufferUsed += nwritten; - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRFileDesc *) PR_GetInheritedFD( - const char *name) -{ - PRFileDesc *fd; - const char *envVar; - const char *ptr; - int len = strlen(name); - PROsfd osfd; - int nColons; - PRIntn fileType; - - envVar = PR_GetEnv("NSPR_INHERIT_FDS"); - if (NULL == envVar || '\0' == envVar[0]) { - PR_SetError(PR_UNKNOWN_ERROR, 0); - return NULL; - } - - ptr = envVar; - while (1) { - if ((ptr[len] == ':') && (strncmp(ptr, name, len) == 0)) { - ptr += len + 1; - PR_sscanf(ptr, "%d:0x%" PR_SCNxOSFD, &fileType, &osfd); - switch ((PRDescType)fileType) { - case PR_DESC_FILE: - fd = PR_ImportFile(osfd); - break; - case PR_DESC_PIPE: - fd = PR_ImportPipe(osfd); - break; - case PR_DESC_SOCKET_TCP: - fd = PR_ImportTCPSocket(osfd); - break; - case PR_DESC_SOCKET_UDP: - fd = PR_ImportUDPSocket(osfd); - break; - default: - PR_ASSERT(0); - PR_SetError(PR_UNKNOWN_ERROR, 0); - fd = NULL; - break; - } - if (fd) { - /* - * An inherited FD is inheritable by default. - * The child process needs to call PR_SetFDInheritable - * to make it non-inheritable if so desired. - */ - fd->secret->inheritable = _PR_TRI_TRUE; - } - return fd; - } - /* Skip three colons */ - nColons = 0; - while (*ptr) { - if (*ptr == ':') { - if (++nColons == 3) { - break; - } - } - ptr++; - } - if (*ptr == '\0') { - PR_SetError(PR_UNKNOWN_ERROR, 0); - return NULL; - } - ptr++; - } -} - -PR_IMPLEMENT(PRProcess*) PR_CreateProcess( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr) -{ - return _PR_MD_CREATE_PROCESS(path, argv, envp, attr); -} /* PR_CreateProcess */ - -PR_IMPLEMENT(PRStatus) PR_CreateProcessDetached( - const char *path, - char *const *argv, - char *const *envp, - const PRProcessAttr *attr) -{ - PRProcess *process; - PRStatus rv; - - process = PR_CreateProcess(path, argv, envp, attr); - if (NULL == process) { - return PR_FAILURE; - } - rv = PR_DetachProcess(process); - PR_ASSERT(PR_SUCCESS == rv); - if (rv == PR_FAILURE) { - PR_DELETE(process); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_DetachProcess(PRProcess *process) -{ - return _PR_MD_DETACH_PROCESS(process); -} - -PR_IMPLEMENT(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode) -{ - return _PR_MD_WAIT_PROCESS(process, exitCode); -} /* PR_WaitProcess */ - -PR_IMPLEMENT(PRStatus) PR_KillProcess(PRProcess *process) -{ - return _PR_MD_KILL_PROCESS(process); -} - -/* - ******************************************************************** - * - * Module initialization - * - ******************************************************************** - */ - -static struct { - PRLock *ml; - PRCondVar *cv; -} mod_init; - -static void _PR_InitCallOnce(void) { - mod_init.ml = PR_NewLock(); - PR_ASSERT(NULL != mod_init.ml); - mod_init.cv = PR_NewCondVar(mod_init.ml); - PR_ASSERT(NULL != mod_init.cv); -} - -void _PR_CleanupCallOnce() -{ - PR_DestroyLock(mod_init.ml); - mod_init.ml = NULL; - PR_DestroyCondVar(mod_init.cv); - mod_init.cv = NULL; -} - -PR_IMPLEMENT(PRStatus) PR_CallOnce( - PRCallOnceType *once, - PRCallOnceFN func) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (!once->initialized) { - if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { - once->status = (*func)(); - PR_Lock(mod_init.ml); - once->initialized = 1; - PR_NotifyAllCondVar(mod_init.cv); - PR_Unlock(mod_init.ml); - } else { - PR_Lock(mod_init.ml); - while (!once->initialized) { - PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(mod_init.ml); - } - } else { - if (PR_SUCCESS != once->status) { - PR_SetError(PR_CALL_ONCE_ERROR, 0); - } - } - return once->status; -} - -PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg( - PRCallOnceType *once, - PRCallOnceWithArgFN func, - void *arg) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (!once->initialized) { - if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { - once->status = (*func)(arg); - PR_Lock(mod_init.ml); - once->initialized = 1; - PR_NotifyAllCondVar(mod_init.cv); - PR_Unlock(mod_init.ml); - } else { - PR_Lock(mod_init.ml); - while (!once->initialized) { - PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(mod_init.ml); - } - } else { - if (PR_SUCCESS != once->status) { - PR_SetError(PR_CALL_ONCE_ERROR, 0); - } - } - return once->status; -} - -PRBool _PR_Obsolete(const char *obsolete, const char *preferred) -{ -#if defined(DEBUG) - PR_fprintf( - PR_STDERR, "'%s' is obsolete. Use '%s' instead.\n", - obsolete, (NULL == preferred) ? "something else" : preferred); -#endif - return PR_FALSE; -} /* _PR_Obsolete */ - -/* prinit.c */ - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prinrval.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prinrval.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prinrval.c 2012-10-24 22:33:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prinrval.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * file: prinrval.c - * description: implementation for the kernel interval timing functions - */ - -#include "primpl.h" - -/* - *----------------------------------------------------------------------- - * - * _PR_InitClock -- - * - * - *----------------------------------------------------------------------- - */ - -void _PR_InitClock(void) -{ - _PR_MD_INTERVAL_INIT(); -#ifdef DEBUG - { - PRIntervalTime ticksPerSec = PR_TicksPerSecond(); - - PR_ASSERT(ticksPerSec >= PR_INTERVAL_MIN); - PR_ASSERT(ticksPerSec <= PR_INTERVAL_MAX); - } -#endif /* DEBUG */ -} - -PR_IMPLEMENT(PRIntervalTime) PR_IntervalNow(void) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - return _PR_MD_GET_INTERVAL(); -} /* PR_IntervalNow */ - -PR_EXTERN(PRUint32) PR_TicksPerSecond(void) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - return _PR_MD_INTERVAL_PER_SEC(); -} /* PR_TicksPerSecond */ - -PR_IMPLEMENT(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds) -{ - return seconds * PR_TicksPerSecond(); -} /* PR_SecondsToInterval */ - -PR_IMPLEMENT(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli) -{ - PRIntervalTime ticks; - PRUint64 tock, tps, msecPerSec, rounding; - LL_UI2L(tock, milli); - LL_I2L(msecPerSec, PR_MSEC_PER_SEC); - LL_I2L(rounding, (PR_MSEC_PER_SEC >> 1)); - LL_I2L(tps, PR_TicksPerSecond()); - LL_MUL(tock, tock, tps); - LL_ADD(tock, tock, rounding); - LL_DIV(tock, tock, msecPerSec); - LL_L2UI(ticks, tock); - return ticks; -} /* PR_MillisecondsToInterval */ - -PR_IMPLEMENT(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro) -{ - PRIntervalTime ticks; - PRUint64 tock, tps, usecPerSec, rounding; - LL_UI2L(tock, micro); - LL_I2L(usecPerSec, PR_USEC_PER_SEC); - LL_I2L(rounding, (PR_USEC_PER_SEC >> 1)); - LL_I2L(tps, PR_TicksPerSecond()); - LL_MUL(tock, tock, tps); - LL_ADD(tock, tock, rounding); - LL_DIV(tock, tock, usecPerSec); - LL_L2UI(ticks, tock); - return ticks; -} /* PR_MicrosecondsToInterval */ - -PR_IMPLEMENT(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks) -{ - return ticks / PR_TicksPerSecond(); -} /* PR_IntervalToSeconds */ - -PR_IMPLEMENT(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks) -{ - PRUint32 milli; - PRUint64 tock, tps, msecPerSec, rounding; - LL_UI2L(tock, ticks); - LL_I2L(msecPerSec, PR_MSEC_PER_SEC); - LL_I2L(tps, PR_TicksPerSecond()); - LL_USHR(rounding, tps, 1); - LL_MUL(tock, tock, msecPerSec); - LL_ADD(tock, tock, rounding); - LL_DIV(tock, tock, tps); - LL_L2UI(milli, tock); - return milli; -} /* PR_IntervalToMilliseconds */ - -PR_IMPLEMENT(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks) -{ - PRUint32 micro; - PRUint64 tock, tps, usecPerSec, rounding; - LL_UI2L(tock, ticks); - LL_I2L(usecPerSec, PR_USEC_PER_SEC); - LL_I2L(tps, PR_TicksPerSecond()); - LL_USHR(rounding, tps, 1); - LL_MUL(tock, tock, usecPerSec); - LL_ADD(tock, tock, rounding); - LL_DIV(tock, tock, tps); - LL_L2UI(micro, tock); - return micro; -} /* PR_IntervalToMicroseconds */ - -/* prinrval.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/pripc.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/pripc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/pripc.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/pripc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: pripc.c - * - * Description: functions for IPC support - */ - -#include "primpl.h" - -#include - -/* - * A POSIX IPC name must begin with a '/'. - * A POSIX IPC name on Solaris cannot contain any '/' except - * the required leading '/'. - * A POSIX IPC name on HP-UX and OSF1 must be a valid pathname - * in the file system. - * - * The ftok() function for System V IPC requires a valid pathname - * in the file system. - * - * A Win32 IPC name cannot contain '\'. - */ - -static void _pr_ConvertSemName(char *result) -{ -#ifdef _PR_HAVE_POSIX_SEMAPHORES -#if defined(SOLARIS) - char *p; - - /* Convert '/' to '_' except for the leading '/' */ - for (p = result+1; *p; p++) { - if (*p == '/') { - *p = '_'; - } - } - return; -#else - return; -#endif -#elif defined(_PR_HAVE_SYSV_SEMAPHORES) - return; -#elif defined(WIN32) - return; -#endif -} - -static void _pr_ConvertShmName(char *result) -{ -#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY) -#if defined(SOLARIS) - char *p; - - /* Convert '/' to '_' except for the leading '/' */ - for (p = result+1; *p; p++) { - if (*p == '/') { - *p = '_'; - } - } - return; -#else - return; -#endif -#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY) - return; -#elif defined(WIN32) - return; -#else - return; -#endif -} - -PRStatus _PR_MakeNativeIPCName( - const char *name, - char *result, - PRIntn size, - _PRIPCType type) -{ - if (strlen(name) >= (PRSize)size) { - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); - return PR_FAILURE; - } - strcpy(result, name); - switch (type) { - case _PRIPCSem: - _pr_ConvertSemName(result); - break; - case _PRIPCShm: - _pr_ConvertShmName(result); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - return PR_SUCCESS; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/pripcsem.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/pripcsem.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/pripcsem.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/pripcsem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: pripcsem.c - * - * Description: implements the named semaphores API in prsemipc.h - * for classic NSPR. If _PR_HAVE_NAMED_SEMAPHORES is not defined, - * the named semaphore functions all fail with the error code - * PR_NOT_IMPLEMENTED_ERROR. - */ - -#include "primpl.h" - -#ifdef _PR_PTHREADS - -#error "This file should not be compiled for the pthreads version" - -#else - -#ifndef _PR_HAVE_NAMED_SEMAPHORES - -PRSem * _PR_MD_OPEN_SEMAPHORE( - const char *osname, PRIntn flags, PRIntn mode, PRUintn value) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -#endif /* !_PR_HAVE_NAMED_SEMAPHORES */ - -PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( - const char *name, PRIntn flags, PRIntn mode, PRUintn value) -{ - char osname[PR_IPC_NAME_SIZE]; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) - == PR_FAILURE) { - return NULL; - } - return _PR_MD_OPEN_SEMAPHORE(osname, flags, mode, value); -} - -PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem) -{ - return _PR_MD_WAIT_SEMAPHORE(sem); -} - -PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem) -{ - return _PR_MD_POST_SEMAPHORE(sem); -} - -PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem) -{ - return _PR_MD_CLOSE_SEMAPHORE(sem); -} - -PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) -{ - char osname[PR_IPC_NAME_SIZE]; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) - == PR_FAILURE) { - return PR_FAILURE; - } - return _PR_MD_DELETE_SEMAPHORE(osname); -} - -#endif /* _PR_PTHREADS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prlog2.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prlog2.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prlog2.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prlog2.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prbit.h" - -/* -** Compute the log of the least power of 2 greater than or equal to n -*/ -PR_IMPLEMENT(PRIntn) PR_CeilingLog2(PRUint32 n) -{ - PRIntn log2; - PR_CEILING_LOG2(log2, n); - return log2; -} - -/* -** Compute the log of the greatest power of 2 less than or equal to n. -** This really just finds the highest set bit in the word. -*/ -PR_IMPLEMENT(PRIntn) PR_FloorLog2(PRUint32 n) -{ - PRIntn log2; - PR_FLOOR_LOG2(log2, n); - return log2; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prlong.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prlong.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prlong.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prlong.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,239 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -static PRInt64 ll_zero = LL_INIT( 0x00000000,0x00000000 ); -static PRInt64 ll_maxint = LL_INIT( 0x7fffffff, 0xffffffff ); -static PRInt64 ll_minint = LL_INIT( 0x80000000, 0x00000000 ); -static PRUint64 ll_maxuint = LL_INIT( 0xffffffff, 0xffffffff ); - -PR_IMPLEMENT(PRInt64) LL_Zero(void) { return ll_zero; } -PR_IMPLEMENT(PRInt64) LL_MaxInt(void) { return ll_maxint; } -PR_IMPLEMENT(PRInt64) LL_MinInt(void) { return ll_minint; } -PR_IMPLEMENT(PRUint64) LL_MaxUint(void) { return ll_maxuint; } - -#ifndef HAVE_LONG_LONG -/* -** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1. -*/ -static void norm_udivmod32(PRUint32 *qp, PRUint32 *rp, PRUint64 a, PRUint32 b) -{ - PRUint32 d1, d0, q1, q0; - PRUint32 r1, r0, m; - - d1 = _hi16(b); - d0 = _lo16(b); - r1 = a.hi % d1; - q1 = a.hi / d1; - m = q1 * d0; - r1 = (r1 << 16) | _hi16(a.lo); - if (r1 < m) { - q1--, r1 += b; - if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */ - && r1 < m) { - q1--, r1 += b; - } - } - r1 -= m; - r0 = r1 % d1; - q0 = r1 / d1; - m = q0 * d0; - r0 = (r0 << 16) | _lo16(a.lo); - if (r0 < m) { - q0--, r0 += b; - if (r0 >= b - && r0 < m) { - q0--, r0 += b; - } - } - *qp = (q1 << 16) | q0; - *rp = r0 - m; -} - -static PRUint32 CountLeadingZeros(PRUint32 a) -{ - PRUint32 t; - PRUint32 r = 32; - - if ((t = a >> 16) != 0) - r -= 16, a = t; - if ((t = a >> 8) != 0) - r -= 8, a = t; - if ((t = a >> 4) != 0) - r -= 4, a = t; - if ((t = a >> 2) != 0) - r -= 2, a = t; - if ((t = a >> 1) != 0) - r -= 1, a = t; - if (a & 1) - r--; - return r; -} - -PR_IMPLEMENT(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b) -{ - PRUint32 n0, n1, n2; - PRUint32 q0, q1; - PRUint32 rsh, lsh; - - n0 = a.lo; - n1 = a.hi; - - if (b.hi == 0) { - if (b.lo > n1) { - /* (0 q0) = (n1 n0) / (0 D0) */ - - lsh = CountLeadingZeros(b.lo); - - if (lsh) { - /* - * Normalize, i.e. make the most significant bit of the - * denominator be set. - */ - b.lo = b.lo << lsh; - n1 = (n1 << lsh) | (n0 >> (32 - lsh)); - n0 = n0 << lsh; - } - - a.lo = n0, a.hi = n1; - norm_udivmod32(&q0, &n0, a, b.lo); - q1 = 0; - - /* remainder is in n0 >> lsh */ - } else { - /* (q1 q0) = (n1 n0) / (0 d0) */ - - if (b.lo == 0) /* user wants to divide by zero! */ - b.lo = 1 / b.lo; /* so go ahead and crash */ - - lsh = CountLeadingZeros(b.lo); - - if (lsh == 0) { - /* - * From (n1 >= b.lo) - * && (the most significant bit of b.lo is set), - * conclude that - * (the most significant bit of n1 is set) - * && (the leading quotient digit q1 = 1). - * - * This special case is necessary, not an optimization - * (Shifts counts of 32 are undefined). - */ - n1 -= b.lo; - q1 = 1; - } else { - /* - * Normalize. - */ - rsh = 32 - lsh; - - b.lo = b.lo << lsh; - n2 = n1 >> rsh; - n1 = (n1 << lsh) | (n0 >> rsh); - n0 = n0 << lsh; - - a.lo = n1, a.hi = n2; - norm_udivmod32(&q1, &n1, a, b.lo); - } - - /* n1 != b.lo... */ - - a.lo = n0, a.hi = n1; - norm_udivmod32(&q0, &n0, a, b.lo); - - /* remainder in n0 >> lsh */ - } - - if (rp) { - rp->lo = n0 >> lsh; - rp->hi = 0; - } - } else { - if (b.hi > n1) { - /* (0 0) = (n1 n0) / (D1 d0) */ - - q0 = 0; - q1 = 0; - - /* remainder in (n1 n0) */ - if (rp) { - rp->lo = n0; - rp->hi = n1; - } - } else { - /* (0 q0) = (n1 n0) / (d1 d0) */ - - lsh = CountLeadingZeros(b.hi); - if (lsh == 0) { - /* - * From (n1 >= b.hi) - * && (the most significant bit of b.hi is set), - * conclude that - * (the most significant bit of n1 is set) - * && (the quotient digit q0 = 0 or 1). - * - * This special case is necessary, not an optimization. - */ - - /* - * The condition on the next line takes advantage of that - * n1 >= b.hi (true due to control flow). - */ - if (n1 > b.hi || n0 >= b.lo) { - q0 = 1; - a.lo = n0, a.hi = n1; - LL_SUB(a, a, b); - } else { - q0 = 0; - } - q1 = 0; - - if (rp) { - rp->lo = n0; - rp->hi = n1; - } - } else { - PRInt64 m; - - /* - * Normalize. - */ - rsh = 32 - lsh; - - b.hi = (b.hi << lsh) | (b.lo >> rsh); - b.lo = b.lo << lsh; - n2 = n1 >> rsh; - n1 = (n1 << lsh) | (n0 >> rsh); - n0 = n0 << lsh; - - a.lo = n1, a.hi = n2; - norm_udivmod32(&q0, &n1, a, b.hi); - LL_MUL32(m, q0, b.lo); - - if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) { - q0--; - LL_SUB(m, m, b); - } - - q1 = 0; - - /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */ - if (rp) { - a.lo = n0, a.hi = n1; - LL_SUB(a, a, m); - rp->lo = (a.hi << rsh) | (a.lo >> lsh); - rp->hi = a.hi >> lsh; - } - } - } - } - - if (qp) { - qp->lo = q0; - qp->hi = q1; - } -} -#endif /* !HAVE_LONG_LONG */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prnetdb.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prnetdb.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prnetdb.c 2012-09-28 14:33:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prnetdb.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2342 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -/* - * On Unix, the error code for gethostbyname() and gethostbyaddr() - * is returned in the global variable h_errno, instead of the usual - * errno. - */ -#if defined(XP_UNIX) -#if defined(_PR_NEED_H_ERRNO) -extern int h_errno; -#endif -#define _MD_GETHOST_ERRNO() h_errno -#else -#define _MD_GETHOST_ERRNO() _MD_ERRNO() -#endif - -/* - * The meaning of the macros related to gethostbyname, gethostbyaddr, - * and gethostbyname2 is defined below. - * - _PR_HAVE_THREADSAFE_GETHOST: the gethostbyXXX functions return - * the result in thread specific storage. For example, AIX, HP-UX, - * and OSF1. - * - _PR_HAVE_GETHOST_R: have the gethostbyXXX_r functions. See next - * two macros. - * - _PR_HAVE_GETHOST_R_INT: the gethostbyXXX_r functions return an - * int. For example, Linux glibc. - * - _PR_HAVE_GETHOST_R_POINTER: the gethostbyXXX_r functions return - * a struct hostent* pointer. For example, Solaris and IRIX. - */ -#if defined(_PR_NO_PREEMPT) || defined(_PR_HAVE_GETHOST_R) \ - || defined(_PR_HAVE_THREADSAFE_GETHOST) -#define _PR_NO_DNS_LOCK -#endif - -#if defined(_PR_NO_DNS_LOCK) -#define LOCK_DNS() -#define UNLOCK_DNS() -#else -PRLock *_pr_dnsLock = NULL; -#define LOCK_DNS() PR_Lock(_pr_dnsLock) -#define UNLOCK_DNS() PR_Unlock(_pr_dnsLock) -#endif /* defined(_PR_NO_DNS_LOCK) */ - -/* - * Some platforms have the reentrant getprotobyname_r() and - * getprotobynumber_r(). However, they come in three flavors. - * Some return a pointer to struct protoent, others return - * an int, and glibc's flavor takes five arguments. - */ -#if defined(XP_BEOS) && defined(BONE_VERSION) -#include /* pick up define for inet_addr */ -#include -#define _PR_HAVE_GETPROTO_R -#define _PR_HAVE_GETPROTO_R_POINTER -#endif - -#if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \ - || (defined(LINUX) && defined(_REENTRANT) \ - && !(defined(__GLIBC__) && __GLIBC__ >= 2) \ - && !defined(ANDROID)) -#define _PR_HAVE_GETPROTO_R -#define _PR_HAVE_GETPROTO_R_POINTER -#endif - -#if defined(OSF1) \ - || defined(AIX4_3_PLUS) || (defined(AIX) && defined(_THREAD_SAFE)) \ - || (defined(HPUX10_10) && defined(_REENTRANT)) \ - || (defined(HPUX10_20) && defined(_REENTRANT)) \ - || defined(OPENBSD) -#define _PR_HAVE_GETPROTO_R -#define _PR_HAVE_GETPROTO_R_INT -#endif - -#if __FreeBSD_version >= 602000 -#define _PR_HAVE_GETPROTO_R -#define _PR_HAVE_5_ARG_GETPROTO_R -#endif - -/* BeOS has glibc but not the glibc-style getprotobyxxx_r functions. */ -#if (defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(XP_BEOS)) -#define _PR_HAVE_GETPROTO_R -#define _PR_HAVE_5_ARG_GETPROTO_R -#endif - -#if !defined(_PR_HAVE_GETPROTO_R) -PRLock* _getproto_lock = NULL; -#endif - -#if defined(_PR_INET6_PROBE) -extern PRBool _pr_ipv6_is_present(void); -#endif - -#define _PR_IN6_IS_ADDR_UNSPECIFIED(a) \ - (((a)->pr_s6_addr32[0] == 0) && \ - ((a)->pr_s6_addr32[1] == 0) && \ - ((a)->pr_s6_addr32[2] == 0) && \ - ((a)->pr_s6_addr32[3] == 0)) - -#define _PR_IN6_IS_ADDR_LOOPBACK(a) \ - (((a)->pr_s6_addr32[0] == 0) && \ - ((a)->pr_s6_addr32[1] == 0) && \ - ((a)->pr_s6_addr32[2] == 0) && \ - ((a)->pr_s6_addr[12] == 0) && \ - ((a)->pr_s6_addr[13] == 0) && \ - ((a)->pr_s6_addr[14] == 0) && \ - ((a)->pr_s6_addr[15] == 0x1U)) - -const PRIPv6Addr _pr_in6addr_any = {{{ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 }}}; - -const PRIPv6Addr _pr_in6addr_loopback = {{{ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0x1U }}}; -/* - * The values at bytes 10 and 11 are compared using pointers to - * 8-bit fields, and not 32-bit fields, to make the comparison work on - * both big-endian and little-endian systems - */ - -#define _PR_IN6_IS_ADDR_V4MAPPED(a) \ - (((a)->pr_s6_addr32[0] == 0) && \ - ((a)->pr_s6_addr32[1] == 0) && \ - ((a)->pr_s6_addr[8] == 0) && \ - ((a)->pr_s6_addr[9] == 0) && \ - ((a)->pr_s6_addr[10] == 0xff) && \ - ((a)->pr_s6_addr[11] == 0xff)) - -#define _PR_IN6_IS_ADDR_V4COMPAT(a) \ - (((a)->pr_s6_addr32[0] == 0) && \ - ((a)->pr_s6_addr32[1] == 0) && \ - ((a)->pr_s6_addr32[2] == 0)) - -#define _PR_IN6_V4MAPPED_TO_IPADDR(a) ((a)->pr_s6_addr32[3]) - -#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) - -/* - * The _pr_QueryNetIfs() function finds out if the system has - * IPv4 or IPv6 source addresses configured and sets _pr_have_inet_if - * and _pr_have_inet6_if accordingly. - * - * We have an implementation using SIOCGIFCONF ioctl and a - * default implementation that simply sets _pr_have_inet_if - * and _pr_have_inet6_if to true. A better implementation - * would be to use the routing sockets (see Chapter 17 of - * W. Richard Stevens' Unix Network Programming, Vol. 1, 2nd. Ed.) - */ - -static PRLock *_pr_query_ifs_lock = NULL; -static PRBool _pr_have_inet_if = PR_FALSE; -static PRBool _pr_have_inet6_if = PR_FALSE; - -#undef DEBUG_QUERY_IFS - -#if defined(AIX) \ - || (defined(DARWIN) && (!defined(HAVE_GETIFADDRS) \ - || (defined(XP_MACOSX) && (!defined(MAC_OS_X_VERSION_10_2) || \ - MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2)))) - -/* - * Use SIOCGIFCONF ioctl on platforms that don't have routing - * sockets. Warning: whether SIOCGIFCONF ioctl returns AF_INET6 - * network interfaces is not portable. - * - * The _pr_QueryNetIfs() function is derived from the code in - * src/lib/libc/net/getifaddrs.c in BSD Unix and the code in - * Section 16.6 of W. Richard Stevens' Unix Network Programming, - * Vol. 1, 2nd. Ed. - */ - -#include -#include -#include -#include - -#ifdef DEBUG_QUERY_IFS -static void -_pr_PrintIfreq(struct ifreq *ifr) -{ - PRNetAddr addr; - struct sockaddr *sa; - const char* family; - char addrstr[64]; - - sa = &ifr->ifr_addr; - if (sa->sa_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - family = "inet"; - memcpy(&addr.inet.ip, &sin->sin_addr, sizeof(sin->sin_addr)); - } else if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - family = "inet6"; - memcpy(&addr.ipv6.ip, &sin6->sin6_addr, sizeof(sin6->sin6_addr)); - } else { - return; /* skip if not AF_INET or AF_INET6 */ - } - addr.raw.family = sa->sa_family; - PR_NetAddrToString(&addr, addrstr, sizeof(addrstr)); - printf("%s: %s %s\n", ifr->ifr_name, family, addrstr); -} -#endif - -static void -_pr_QueryNetIfs(void) -{ - int sock; - int rv; - struct ifconf ifc; - struct ifreq *ifr; - struct ifreq *lifr; - PRUint32 len, lastlen; - char *buf; - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - return; - } - - /* Issue SIOCGIFCONF request in a loop. */ - lastlen = 0; - len = 100 * sizeof(struct ifreq); /* initial buffer size guess */ - for (;;) { - buf = (char *)PR_Malloc(len); - if (NULL == buf) { - close(sock); - return; - } - ifc.ifc_buf = buf; - ifc.ifc_len = len; - rv = ioctl(sock, SIOCGIFCONF, &ifc); - if (rv < 0) { - if (errno != EINVAL || lastlen != 0) { - close(sock); - PR_Free(buf); - return; - } - } else { - if (ifc.ifc_len == lastlen) - break; /* success, len has not changed */ - lastlen = ifc.ifc_len; - } - len += 10 * sizeof(struct ifreq); /* increment */ - PR_Free(buf); - } - close(sock); - - ifr = ifc.ifc_req; - lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; - - while (ifr < lifr) { - struct sockaddr *sa; - int sa_len; - -#ifdef DEBUG_QUERY_IFS - _pr_PrintIfreq(ifr); -#endif - sa = &ifr->ifr_addr; - if (sa->sa_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *) sa; - if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { - _pr_have_inet_if = PR_TRUE; - } - } else if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; - if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) - && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - _pr_have_inet6_if = PR_TRUE; - } - } - -#ifdef _PR_HAVE_SOCKADDR_LEN - sa_len = PR_MAX(sa->sa_len, sizeof(struct sockaddr)); -#else - switch (sa->sa_family) { -#ifdef AF_LINK - case AF_LINK: - sa_len = sizeof(struct sockaddr_dl); - break; -#endif - case AF_INET6: - sa_len = sizeof(struct sockaddr_in6); - break; - default: - sa_len = sizeof(struct sockaddr); - break; - } -#endif - ifr = (struct ifreq *)(((char *)sa) + sa_len); - } - PR_Free(buf); -} - -#elif (defined(DARWIN) && defined(HAVE_GETIFADDRS)) || defined(FREEBSD) \ - || defined(NETBSD) || defined(OPENBSD) - -/* - * Use the BSD getifaddrs function. - */ - -#include -#include -#include -#include - -#ifdef DEBUG_QUERY_IFS -static void -_pr_PrintIfaddrs(struct ifaddrs *ifa) -{ - struct sockaddr *sa; - const char* family; - void *addrp; - char addrstr[64]; - - sa = ifa->ifa_addr; - if (sa->sa_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - family = "inet"; - addrp = &sin->sin_addr; - } else if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - family = "inet6"; - addrp = &sin6->sin6_addr; - } else { - return; /* skip if not AF_INET or AF_INET6 */ - } - inet_ntop(sa->sa_family, addrp, addrstr, sizeof(addrstr)); - printf("%s: %s %s\n", ifa->ifa_name, family, addrstr); -} -#endif - -static void -_pr_QueryNetIfs(void) -{ - struct ifaddrs *ifp; - struct ifaddrs *ifa; - - if (getifaddrs(&ifp) == -1) { - return; - } - for (ifa = ifp; ifa; ifa = ifa->ifa_next) { - struct sockaddr *sa; - -#ifdef DEBUG_QUERY_IFS - _pr_PrintIfaddrs(ifa); -#endif - sa = ifa->ifa_addr; - if (sa->sa_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *) sa; - if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { - _pr_have_inet_if = 1; - } - } else if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; - if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) - && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - _pr_have_inet6_if = 1; - } - } - } - freeifaddrs(ifp); -} - -#else /* default */ - -/* - * Emulate the code in NSPR 4.2 or older. PR_GetIPNodeByName behaves - * as if the system had both IPv4 and IPv6 source addresses configured. - */ -static void -_pr_QueryNetIfs(void) -{ - _pr_have_inet_if = PR_TRUE; - _pr_have_inet6_if = PR_TRUE; -} - -#endif - -#endif /* _PR_INET6 && _PR_HAVE_GETHOSTBYNAME2 */ - -void _PR_InitNet(void) -{ -#if defined(XP_UNIX) -#ifdef HAVE_NETCONFIG - /* - * This one-liner prevents the endless re-open's and re-read's of - * /etc/netconfig on EACH and EVERY call to accept(), connect(), etc. - */ - (void)setnetconfig(); -#endif -#endif -#if !defined(_PR_NO_DNS_LOCK) - _pr_dnsLock = PR_NewLock(); -#endif -#if !defined(_PR_HAVE_GETPROTO_R) - _getproto_lock = PR_NewLock(); -#endif -#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) - _pr_query_ifs_lock = PR_NewLock(); -#endif -} - -void _PR_CleanupNet(void) -{ -#if !defined(_PR_NO_DNS_LOCK) - if (_pr_dnsLock) { - PR_DestroyLock(_pr_dnsLock); - _pr_dnsLock = NULL; - } -#endif -#if !defined(_PR_HAVE_GETPROTO_R) - if (_getproto_lock) { - PR_DestroyLock(_getproto_lock); - _getproto_lock = NULL; - } -#endif -#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) - if (_pr_query_ifs_lock) { - PR_DestroyLock(_pr_query_ifs_lock); - _pr_query_ifs_lock = NULL; - } -#endif -} - -/* -** Allocate space from the buffer, aligning it to "align" before doing -** the allocation. "align" must be a power of 2. -*/ -static char *Alloc(PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align) -{ - char *buf = *bufp; - PRIntn buflen = *buflenp; - - if (align && ((long)buf & (align - 1))) { - PRIntn skip = align - ((ptrdiff_t)buf & (align - 1)); - if (buflen < skip) { - return 0; - } - buf += skip; - buflen -= skip; - } - if (buflen < amount) { - return 0; - } - *bufp = buf + amount; - *buflenp = buflen - amount; - return buf; -} - -typedef enum _PRIPAddrConversion { - _PRIPAddrNoConversion, - _PRIPAddrIPv4Mapped, - _PRIPAddrIPv4Compat -} _PRIPAddrConversion; - -/* -** Convert an IPv4 address (v4) to an IPv4-mapped IPv6 address (v6). -*/ -static void MakeIPv4MappedAddr(const char *v4, char *v6) -{ - memset(v6, 0, 10); - memset(v6 + 10, 0xff, 2); - memcpy(v6 + 12, v4, 4); -} - -/* -** Convert an IPv4 address (v4) to an IPv4-compatible IPv6 address (v6). -*/ -static void MakeIPv4CompatAddr(const char *v4, char *v6) -{ - memset(v6, 0, 12); - memcpy(v6 + 12, v4, 4); -} - -/* -** Copy a hostent, and all of the memory that it refers to into -** (hopefully) stacked buffers. -*/ -static PRStatus CopyHostent( - struct hostent *from, - char **buf, - PRIntn *bufsize, - _PRIPAddrConversion conversion, - PRHostEnt *to) -{ - PRIntn len, na; - char **ap; - - if (conversion != _PRIPAddrNoConversion - && from->h_addrtype == AF_INET) { - PR_ASSERT(from->h_length == 4); - to->h_addrtype = PR_AF_INET6; - to->h_length = 16; - } else { -#if defined(_PR_INET6) || defined(_PR_INET6_PROBE) - if (AF_INET6 == from->h_addrtype) - to->h_addrtype = PR_AF_INET6; - else -#endif - to->h_addrtype = from->h_addrtype; - to->h_length = from->h_length; - } - - /* Copy the official name */ - if (!from->h_name) return PR_FAILURE; - len = strlen(from->h_name) + 1; - to->h_name = Alloc(len, buf, bufsize, 0); - if (!to->h_name) return PR_FAILURE; - memcpy(to->h_name, from->h_name, len); - - /* Count the aliases, then allocate storage for the pointers */ - if (!from->h_aliases) { - na = 1; - } else { - for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */ - } - to->h_aliases = (char**)Alloc( - na * sizeof(char*), buf, bufsize, sizeof(char**)); - if (!to->h_aliases) return PR_FAILURE; - - /* Copy the aliases, one at a time */ - if (!from->h_aliases) { - to->h_aliases[0] = 0; - } else { - for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) { - len = strlen(*ap) + 1; - to->h_aliases[na] = Alloc(len, buf, bufsize, 0); - if (!to->h_aliases[na]) return PR_FAILURE; - memcpy(to->h_aliases[na], *ap, len); - } - to->h_aliases[na] = 0; - } - - /* Count the addresses, then allocate storage for the pointers */ - for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++){;} /* nothing to execute */ - to->h_addr_list = (char**)Alloc( - na * sizeof(char*), buf, bufsize, sizeof(char**)); - if (!to->h_addr_list) return PR_FAILURE; - - /* Copy the addresses, one at a time */ - for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) { - to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0); - if (!to->h_addr_list[na]) return PR_FAILURE; - if (conversion != _PRIPAddrNoConversion - && from->h_addrtype == AF_INET) { - if (conversion == _PRIPAddrIPv4Mapped) { - MakeIPv4MappedAddr(*ap, to->h_addr_list[na]); - } else { - PR_ASSERT(conversion == _PRIPAddrIPv4Compat); - MakeIPv4CompatAddr(*ap, to->h_addr_list[na]); - } - } else { - memcpy(to->h_addr_list[na], *ap, to->h_length); - } - } - to->h_addr_list[na] = 0; - return PR_SUCCESS; -} - -#ifdef SYMBIAN -/* Set p_aliases by hand because Symbian's getprotobyname() returns NULL. */ -static void AssignAliases(struct protoent *Protoent, char** aliases) -{ - if (NULL == Protoent->p_aliases) { - if (0 == strcmp(Protoent->p_name, "ip")) - aliases[0] = "IP"; - else if (0 == strcmp(Protoent->p_name, "tcp")) - aliases[0] = "TCP"; - else if (0 == strcmp(Protoent->p_name, "udp")) - aliases[0] = "UDP"; - else - aliases[0] = "UNKNOWN"; - aliases[1] = NULL; - Protoent->p_aliases = aliases; - } -} -#endif - -#if !defined(_PR_HAVE_GETPROTO_R) -/* -** Copy a protoent, and all of the memory that it refers to into -** (hopefully) stacked buffers. -*/ -static PRStatus CopyProtoent( - struct protoent *from, char *buf, PRIntn bufsize, PRProtoEnt *to) -{ - PRIntn len, na; - char **ap; - - /* Do the easy stuff */ - to->p_num = from->p_proto; - - /* Copy the official name */ - if (!from->p_name) return PR_FAILURE; - len = strlen(from->p_name) + 1; - to->p_name = Alloc(len, &buf, &bufsize, 0); - if (!to->p_name) return PR_FAILURE; - memcpy(to->p_name, from->p_name, len); - - /* Count the aliases, then allocate storage for the pointers */ - for (na = 1, ap = from->p_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */ - to->p_aliases = (char**)Alloc( - na * sizeof(char*), &buf, &bufsize, sizeof(char**)); - if (!to->p_aliases) return PR_FAILURE; - - /* Copy the aliases, one at a time */ - for (na = 0, ap = from->p_aliases; *ap != 0; na++, ap++) { - len = strlen(*ap) + 1; - to->p_aliases[na] = Alloc(len, &buf, &bufsize, 0); - if (!to->p_aliases[na]) return PR_FAILURE; - memcpy(to->p_aliases[na], *ap, len); - } - to->p_aliases[na] = 0; - - return PR_SUCCESS; -} -#endif /* !defined(_PR_HAVE_GETPROTO_R) */ - -/* - * ################################################################# - * NOTE: tmphe, tmpbuf, bufsize, h, and h_err are local variables - * or arguments of PR_GetHostByName, PR_GetIPNodeByName, and - * PR_GetHostByAddr. DO NOT CHANGE THE NAMES OF THESE LOCAL - * VARIABLES OR ARGUMENTS. - * ################################################################# - */ -#if defined(_PR_HAVE_GETHOST_R_INT) - -#define GETHOSTBYNAME(name) \ - (gethostbyname_r(name, &tmphe, tmpbuf, bufsize, &h, &h_err), h) -#define GETHOSTBYNAME2(name, af) \ - (gethostbyname2_r(name, af, &tmphe, tmpbuf, bufsize, &h, &h_err), h) -#define GETHOSTBYADDR(addr, addrlen, af) \ - (gethostbyaddr_r(addr, addrlen, af, \ - &tmphe, tmpbuf, bufsize, &h, &h_err), h) - -#elif defined(_PR_HAVE_GETHOST_R_POINTER) - -#define GETHOSTBYNAME(name) \ - gethostbyname_r(name, &tmphe, tmpbuf, bufsize, &h_err) -#define GETHOSTBYNAME2(name, af) \ - gethostbyname2_r(name, af, &tmphe, tmpbuf, bufsize, &h_err) -#define GETHOSTBYADDR(addr, addrlen, af) \ - gethostbyaddr_r(addr, addrlen, af, &tmphe, tmpbuf, bufsize, &h_err) - -#else - -#define GETHOSTBYNAME(name) gethostbyname(name) -#define GETHOSTBYNAME2(name, af) gethostbyname2(name, af) -#define GETHOSTBYADDR(addr, addrlen, af) gethostbyaddr(addr, addrlen, af) - -#endif /* definition of GETHOSTBYXXX */ - -PR_IMPLEMENT(PRStatus) PR_GetHostByName( - const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp) -{ - struct hostent *h; - PRStatus rv = PR_FAILURE; -#if defined(_PR_HAVE_GETHOST_R) - char localbuf[PR_NETDB_BUF_SIZE]; - char *tmpbuf; - struct hostent tmphe; - int h_err; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - -#if defined(_PR_HAVE_GETHOST_R) - tmpbuf = localbuf; - if (bufsize > sizeof(localbuf)) - { - tmpbuf = (char *)PR_Malloc(bufsize); - if (NULL == tmpbuf) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return rv; - } - } -#endif - - LOCK_DNS(); - - h = GETHOSTBYNAME(name); - - if (NULL == h) - { - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); - } - else - { - _PRIPAddrConversion conversion = _PRIPAddrNoConversion; - rv = CopyHostent(h, &buf, &bufsize, conversion, hp); - if (PR_SUCCESS != rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } - UNLOCK_DNS(); -#if defined(_PR_HAVE_GETHOST_R) - if (tmpbuf != localbuf) - PR_Free(tmpbuf); -#endif - return rv; -} - -#if !defined(_PR_INET6) && \ - defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) -typedef struct hostent * (*_pr_getipnodebyname_t)(const char *, int, - int, int *); -typedef struct hostent * (*_pr_getipnodebyaddr_t)(const void *, size_t, - int, int *); -typedef void (*_pr_freehostent_t)(struct hostent *); -static void * _pr_getipnodebyname_fp; -static void * _pr_getipnodebyaddr_fp; -static void * _pr_freehostent_fp; - -/* - * Look up the addresses of getipnodebyname, getipnodebyaddr, - * and freehostent. - */ -PRStatus -_pr_find_getipnodebyname(void) -{ - PRLibrary *lib; - PRStatus rv; -#define GETIPNODEBYNAME "getipnodebyname" -#define GETIPNODEBYADDR "getipnodebyaddr" -#define FREEHOSTENT "freehostent" - - _pr_getipnodebyname_fp = PR_FindSymbolAndLibrary(GETIPNODEBYNAME, &lib); - if (NULL != _pr_getipnodebyname_fp) { - _pr_freehostent_fp = PR_FindSymbol(lib, FREEHOSTENT); - if (NULL != _pr_freehostent_fp) { - _pr_getipnodebyaddr_fp = PR_FindSymbol(lib, GETIPNODEBYADDR); - if (NULL != _pr_getipnodebyaddr_fp) - rv = PR_SUCCESS; - else - rv = PR_FAILURE; - } else - rv = PR_FAILURE; - (void)PR_UnloadLibrary(lib); - } else - rv = PR_FAILURE; - return rv; -} -#endif - -#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) -/* -** Append the V4 addresses to the end of the list -*/ -static PRStatus AppendV4AddrsToHostent( - struct hostent *from, - char **buf, - PRIntn *bufsize, - PRHostEnt *to) -{ - PRIntn na, na_old; - char **ap; - char **new_addr_list; - - /* Count the addresses, then grow storage for the pointers */ - for (na_old = 0, ap = to->h_addr_list; *ap != 0; na_old++, ap++) - {;} /* nothing to execute */ - for (na = na_old + 1, ap = from->h_addr_list; *ap != 0; na++, ap++) - {;} /* nothing to execute */ - new_addr_list = (char**)Alloc( - na * sizeof(char*), buf, bufsize, sizeof(char**)); - if (!new_addr_list) return PR_FAILURE; - - /* Copy the V6 addresses, one at a time */ - for (na = 0, ap = to->h_addr_list; *ap != 0; na++, ap++) { - new_addr_list[na] = to->h_addr_list[na]; - } - to->h_addr_list = new_addr_list; - - /* Copy the V4 addresses, one at a time */ - for (ap = from->h_addr_list; *ap != 0; na++, ap++) { - to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0); - if (!to->h_addr_list[na]) return PR_FAILURE; - MakeIPv4MappedAddr(*ap, to->h_addr_list[na]); - } - to->h_addr_list[na] = 0; - return PR_SUCCESS; -} -#endif - -PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName( - const char *name, PRUint16 af, PRIntn flags, - char *buf, PRIntn bufsize, PRHostEnt *hp) -{ - struct hostent *h = 0; - PRStatus rv = PR_FAILURE; -#if defined(_PR_HAVE_GETHOST_R) - char localbuf[PR_NETDB_BUF_SIZE]; - char *tmpbuf; - struct hostent tmphe; - int h_err; -#endif -#if defined(_PR_HAVE_GETIPNODEBYNAME) - PRUint16 md_af = af; - int error_num; - int tmp_flags = 0; -#endif -#if defined(_PR_HAVE_GETHOSTBYNAME2) - PRBool did_af_inet = PR_FALSE; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (af != PR_AF_INET && af != PR_AF_INET6) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - -#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) - PR_Lock(_pr_query_ifs_lock); - /* - * Keep querying the presence of IPv4 and IPv6 interfaces until - * at least one is up. This allows us to detect the local - * machine going from offline to online. - */ - if (!_pr_have_inet_if && !_pr_have_inet6_if) { - _pr_QueryNetIfs(); -#ifdef DEBUG_QUERY_IFS - if (_pr_have_inet_if) - printf("Have IPv4 source address\n"); - if (_pr_have_inet6_if) - printf("Have IPv6 source address\n"); -#endif - } - PR_Unlock(_pr_query_ifs_lock); -#endif - -#if defined(_PR_HAVE_GETIPNODEBYNAME) - if (flags & PR_AI_V4MAPPED) - tmp_flags |= AI_V4MAPPED; - if (flags & PR_AI_ADDRCONFIG) - tmp_flags |= AI_ADDRCONFIG; - if (flags & PR_AI_ALL) - tmp_flags |= AI_ALL; - if (af == PR_AF_INET6) - md_af = AF_INET6; - else - md_af = af; -#endif - -#if defined(_PR_HAVE_GETHOST_R) - tmpbuf = localbuf; - if (bufsize > sizeof(localbuf)) - { - tmpbuf = (char *)PR_Malloc(bufsize); - if (NULL == tmpbuf) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return rv; - } - } -#endif - - /* Do not need to lock the DNS lock if getipnodebyname() is called */ -#ifdef _PR_INET6 -#ifdef _PR_HAVE_GETHOSTBYNAME2 - LOCK_DNS(); - if (af == PR_AF_INET6) - { - if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet6_if) - { -#ifdef _PR_INET6_PROBE - if (_pr_ipv6_is_present()) -#endif - h = GETHOSTBYNAME2(name, AF_INET6); - } - if ((NULL == h) && (flags & PR_AI_V4MAPPED) - && ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if)) - { - did_af_inet = PR_TRUE; - h = GETHOSTBYNAME2(name, AF_INET); - } - } - else - { - if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if) - { - did_af_inet = PR_TRUE; - h = GETHOSTBYNAME2(name, af); - } - } -#elif defined(_PR_HAVE_GETIPNODEBYNAME) - h = getipnodebyname(name, md_af, tmp_flags, &error_num); -#else -#error "Unknown name-to-address translation function" -#endif /* _PR_HAVE_GETHOSTBYNAME2 */ -#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) - if (_pr_ipv6_is_present()) - { -#ifdef PR_GETIPNODE_NOT_THREADSAFE - LOCK_DNS(); -#endif - h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num); - } - else - { - LOCK_DNS(); - h = GETHOSTBYNAME(name); - } -#else /* _PR_INET6 */ - LOCK_DNS(); - h = GETHOSTBYNAME(name); -#endif /* _PR_INET6 */ - - if (NULL == h) - { -#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); -#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) - if (_pr_ipv6_is_present()) - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); - else - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); -#else - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); -#endif - } - else - { - _PRIPAddrConversion conversion = _PRIPAddrNoConversion; - - if (af == PR_AF_INET6) conversion = _PRIPAddrIPv4Mapped; - rv = CopyHostent(h, &buf, &bufsize, conversion, hp); - if (PR_SUCCESS != rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); -#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) - freehostent(h); -#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) - if (_pr_ipv6_is_present()) - (*((_pr_freehostent_t)_pr_freehostent_fp))(h); -#endif -#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) - if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED) - && ((flags & PR_AI_ALL) - || ((flags & PR_AI_ADDRCONFIG) && _pr_have_inet_if)) - && !did_af_inet && (h = GETHOSTBYNAME2(name, AF_INET)) != 0) { - rv = AppendV4AddrsToHostent(h, &buf, &bufsize, hp); - if (PR_SUCCESS != rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } -#endif - } - - /* Must match the convoluted logic above for LOCK_DNS() */ -#ifdef _PR_INET6 -#ifdef _PR_HAVE_GETHOSTBYNAME2 - UNLOCK_DNS(); -#endif /* _PR_HAVE_GETHOSTBYNAME2 */ -#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) -#ifdef PR_GETIPNODE_NOT_THREADSAFE - UNLOCK_DNS(); -#else - if (!_pr_ipv6_is_present()) - UNLOCK_DNS(); -#endif -#else /* _PR_INET6 */ - UNLOCK_DNS(); -#endif /* _PR_INET6 */ - -#if defined(_PR_HAVE_GETHOST_R) - if (tmpbuf != localbuf) - PR_Free(tmpbuf); -#endif - - return rv; -} - -PR_IMPLEMENT(PRStatus) PR_GetHostByAddr( - const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry) -{ - struct hostent *h; - PRStatus rv = PR_FAILURE; - const void *addr; - PRUint32 tmp_ip; - int addrlen; - PRInt32 af; -#if defined(_PR_HAVE_GETHOST_R) - char localbuf[PR_NETDB_BUF_SIZE]; - char *tmpbuf; - struct hostent tmphe; - int h_err; -#endif -#if defined(_PR_HAVE_GETIPNODEBYADDR) - int error_num; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (hostaddr->raw.family == PR_AF_INET6) - { -#if defined(_PR_INET6_PROBE) - af = _pr_ipv6_is_present() ? AF_INET6 : AF_INET; -#elif defined(_PR_INET6) - af = AF_INET6; -#else - af = AF_INET; -#endif -#if defined(_PR_GHBA_DISALLOW_V4MAPPED) - if (_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) - af = AF_INET; -#endif - } - else - { - PR_ASSERT(hostaddr->raw.family == AF_INET); - af = AF_INET; - } - if (hostaddr->raw.family == PR_AF_INET6) { -#if defined(_PR_INET6) || defined(_PR_INET6_PROBE) - if (af == AF_INET6) { - addr = &hostaddr->ipv6.ip; - addrlen = sizeof(hostaddr->ipv6.ip); - } - else -#endif - { - PR_ASSERT(af == AF_INET); - if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return rv; - } - tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *) - &hostaddr->ipv6.ip); - addr = &tmp_ip; - addrlen = sizeof(tmp_ip); - } - } else { - PR_ASSERT(hostaddr->raw.family == AF_INET); - PR_ASSERT(af == AF_INET); - addr = &hostaddr->inet.ip; - addrlen = sizeof(hostaddr->inet.ip); - } - -#if defined(_PR_HAVE_GETHOST_R) - tmpbuf = localbuf; - if (bufsize > sizeof(localbuf)) - { - tmpbuf = (char *)PR_Malloc(bufsize); - if (NULL == tmpbuf) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return rv; - } - } -#endif - - /* Do not need to lock the DNS lock if getipnodebyaddr() is called */ -#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6) - h = getipnodebyaddr(addr, addrlen, af, &error_num); -#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE) - if (_pr_ipv6_is_present()) - { -#ifdef PR_GETIPNODE_NOT_THREADSAFE - LOCK_DNS(); -#endif - h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen, - af, &error_num); - } - else - { - LOCK_DNS(); - h = GETHOSTBYADDR(addr, addrlen, af); - } -#else /* _PR_HAVE_GETIPNODEBYADDR */ - LOCK_DNS(); - h = GETHOSTBYADDR(addr, addrlen, af); -#endif /* _PR_HAVE_GETIPNODEBYADDR */ - if (NULL == h) - { -#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR) - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); -#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR) - if (_pr_ipv6_is_present()) - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); - else - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); -#else - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); -#endif - } - else - { - _PRIPAddrConversion conversion = _PRIPAddrNoConversion; - if (hostaddr->raw.family == PR_AF_INET6) { - if (af == AF_INET) { - if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*) - &hostaddr->ipv6.ip)) { - conversion = _PRIPAddrIPv4Mapped; - } else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *) - &hostaddr->ipv6.ip)) { - conversion = _PRIPAddrIPv4Compat; - } - } - } - rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry); - if (PR_SUCCESS != rv) { - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } -#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR) - freehostent(h); -#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR) - if (_pr_ipv6_is_present()) - (*((_pr_freehostent_t)_pr_freehostent_fp))(h); -#endif - } - - /* Must match the convoluted logic above for LOCK_DNS() */ -#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6) -#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE) -#ifdef PR_GETIPNODE_NOT_THREADSAFE - UNLOCK_DNS(); -#else - if (!_pr_ipv6_is_present()) - UNLOCK_DNS(); -#endif -#else /* _PR_HAVE_GETIPNODEBYADDR */ - UNLOCK_DNS(); -#endif /* _PR_HAVE_GETIPNODEBYADDR */ - -#if defined(_PR_HAVE_GETHOST_R) - if (tmpbuf != localbuf) - PR_Free(tmpbuf); -#endif - - return rv; -} - -/******************************************************************************/ -/* - * Some systems define a reentrant version of getprotobyname(). Too bad - * the signature isn't always the same. But hey, they tried. If there - * is such a definition, use it. Otherwise, grab a lock and do it here. - */ -/******************************************************************************/ - -#if !defined(_PR_HAVE_GETPROTO_R) -/* - * This may seem like a silly thing to do, but the compiler SHOULD - * complain if getprotobyname_r() is implemented on some system and - * we're not using it. For sure these signatures are different than - * any usable implementation. - */ - -#if defined(ANDROID) -/* Android's Bionic libc system includes prototypes for these in netdb.h, - * but doesn't actually include implementations. It uses the 5-arg form, - * so these functions end up not matching the prototype. So just rename - * them if not found. - */ -#define getprotobyname_r _pr_getprotobyname_r -#define getprotobynumber_r _pr_getprotobynumber_r -#endif - -static struct protoent *getprotobyname_r(const char* name) -{ - return getprotobyname(name); -} /* getprotobyname_r */ - -static struct protoent *getprotobynumber_r(PRInt32 number) -{ - return getprotobynumber(number); -} /* getprotobynumber_r */ - -#endif /* !defined(_PR_HAVE_GETPROTO_R) */ - -PR_IMPLEMENT(PRStatus) PR_GetProtoByName( - const char* name, char* buffer, PRInt32 buflen, PRProtoEnt* result) -{ - PRStatus rv = PR_SUCCESS; -#if defined(_PR_HAVE_GETPROTO_R) - struct protoent* res = (struct protoent*)result; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - -#if defined(_PR_HAVE_GETPROTO_R_INT) - { - /* - ** The protoent_data has a pointer as the first field. - ** That implies the buffer better be aligned, and char* - ** doesn't promise much. - */ - PRUptrdiff aligned = (PRUptrdiff)buffer; - if (0 != (aligned & (sizeof(struct protoent_data*) - 1))) - { - aligned += sizeof(struct protoent_data*) - 1; - aligned &= ~(sizeof(struct protoent_data*) - 1); - buflen -= (aligned - (PRUptrdiff)buffer); - buffer = (char*)aligned; - } - } -#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */ - - if (PR_NETDB_BUF_SIZE > buflen) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - -#if defined(_PR_HAVE_GETPROTO_R_POINTER) - if (NULL == getprotobyname_r(name, res, buffer, buflen)) - { - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } -#elif defined(_PR_HAVE_GETPROTO_R_INT) - /* - ** The buffer needs to be zero'd, and it should be - ** at least the size of a struct protoent_data. - */ - memset(buffer, 0, buflen); - if (-1 == getprotobyname_r(name, res, (struct protoent_data*)buffer)) - { - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } -#elif defined(_PR_HAVE_5_ARG_GETPROTO_R) - /* The 5th argument for getprotobyname_r() cannot be NULL */ - if (-1 == getprotobyname_r(name, res, buffer, buflen, &res)) - { - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } -#else /* do it the hard way */ - { - struct protoent *staticBuf; - PR_Lock(_getproto_lock); - staticBuf = getprotobyname_r(name); - if (NULL == staticBuf) - { - rv = PR_FAILURE; - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - } - else - { -#if defined(SYMBIAN) - char* aliases[2]; - AssignAliases(staticBuf, aliases); -#endif - rv = CopyProtoent(staticBuf, buffer, buflen, result); - if (PR_FAILURE == rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } - PR_Unlock(_getproto_lock); - } -#endif /* all that */ - return rv; -} - -PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber( - PRInt32 number, char* buffer, PRInt32 buflen, PRProtoEnt* result) -{ - PRStatus rv = PR_SUCCESS; -#if defined(_PR_HAVE_GETPROTO_R) - struct protoent* res = (struct protoent*)result; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - -#if defined(_PR_HAVE_GETPROTO_R_INT) - { - /* - ** The protoent_data has a pointer as the first field. - ** That implies the buffer better be aligned, and char* - ** doesn't promise much. - */ - PRUptrdiff aligned = (PRUptrdiff)buffer; - if (0 != (aligned & (sizeof(struct protoent_data*) - 1))) - { - aligned += sizeof(struct protoent_data*) - 1; - aligned &= ~(sizeof(struct protoent_data*) - 1); - buflen -= (aligned - (PRUptrdiff)buffer); - buffer = (char*)aligned; - } - } -#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */ - - if (PR_NETDB_BUF_SIZE > buflen) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - -#if defined(_PR_HAVE_GETPROTO_R_POINTER) - if (NULL == getprotobynumber_r(number, res, buffer, buflen)) - { - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } - -#elif defined(_PR_HAVE_GETPROTO_R_INT) - /* - ** The buffer needs to be zero'd for these OS's. - */ - memset(buffer, 0, buflen); - if (-1 == getprotobynumber_r(number, res, (struct protoent_data*)buffer)) - { - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } -#elif defined(_PR_HAVE_5_ARG_GETPROTO_R) - /* The 5th argument for getprotobynumber_r() cannot be NULL */ - if (-1 == getprotobynumber_r(number, res, buffer, buflen, &res)) - { - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - return PR_FAILURE; - } -#else /* do it the hard way */ - { - struct protoent *staticBuf; - PR_Lock(_getproto_lock); - staticBuf = getprotobynumber_r(number); - if (NULL == staticBuf) - { - rv = PR_FAILURE; - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - } - else - { -#if defined(SYMBIAN) - char* aliases[2]; - AssignAliases(staticBuf, aliases); -#endif - rv = CopyProtoent(staticBuf, buffer, buflen, result); - if (PR_FAILURE == rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } - PR_Unlock(_getproto_lock); - } -#endif /* all that crap */ - return rv; - -} - -PRUintn _PR_NetAddrSize(const PRNetAddr* addr) -{ - PRUintn addrsize; - - /* - * RFC 2553 added a new field (sin6_scope_id) to - * struct sockaddr_in6. PRNetAddr's ipv6 member has a - * scope_id field to match the new field. In order to - * work with older implementations supporting RFC 2133, - * we take the size of struct sockaddr_in6 instead of - * addr->ipv6. - */ - if (AF_INET == addr->raw.family) - addrsize = sizeof(addr->inet); - else if (PR_AF_INET6 == addr->raw.family) -#if defined(_PR_INET6) - addrsize = sizeof(struct sockaddr_in6); -#else - addrsize = sizeof(addr->ipv6); -#endif -#if defined(XP_UNIX) || defined(XP_OS2) - else if (AF_UNIX == addr->raw.family) - addrsize = sizeof(addr->local); -#endif - else addrsize = 0; - - return addrsize; -} /* _PR_NetAddrSize */ - -PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt( - PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address) -{ - void *addr = hostEnt->h_addr_list[enumIndex++]; - memset(address, 0, sizeof(PRNetAddr)); - if (NULL == addr) enumIndex = 0; - else - { - address->raw.family = hostEnt->h_addrtype; - if (PR_AF_INET6 == hostEnt->h_addrtype) - { - address->ipv6.port = htons(port); - address->ipv6.flowinfo = 0; - address->ipv6.scope_id = 0; - memcpy(&address->ipv6.ip, addr, hostEnt->h_length); - } - else - { - PR_ASSERT(AF_INET == hostEnt->h_addrtype); - address->inet.port = htons(port); - memcpy(&address->inet.ip, addr, hostEnt->h_length); - } - } - return enumIndex; -} /* PR_EnumerateHostEnt */ - -PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr( - PRNetAddrValue val, PRUint16 port, PRNetAddr *addr) -{ - PRStatus rv = PR_SUCCESS; - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet)); - addr->inet.family = AF_INET; - addr->inet.port = htons(port); - switch (val) - { - case PR_IpAddrNull: - break; /* don't overwrite the address */ - case PR_IpAddrAny: - addr->inet.ip = htonl(INADDR_ANY); - break; - case PR_IpAddrLoopback: - addr->inet.ip = htonl(INADDR_LOOPBACK); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; - } - return rv; -} /* PR_InitializeNetAddr */ - -PR_IMPLEMENT(PRStatus) PR_SetNetAddr( - PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr) -{ - PRStatus rv = PR_SUCCESS; - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (af == PR_AF_INET6) - { - if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->ipv6)); - addr->ipv6.family = af; - addr->ipv6.port = htons(port); - addr->ipv6.flowinfo = 0; - addr->ipv6.scope_id = 0; - switch (val) - { - case PR_IpAddrNull: - break; /* don't overwrite the address */ - case PR_IpAddrAny: - addr->ipv6.ip = _pr_in6addr_any; - break; - case PR_IpAddrLoopback: - addr->ipv6.ip = _pr_in6addr_loopback; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; - } - } - else - { - if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet)); - addr->inet.family = af; - addr->inet.port = htons(port); - switch (val) - { - case PR_IpAddrNull: - break; /* don't overwrite the address */ - case PR_IpAddrAny: - addr->inet.ip = htonl(INADDR_ANY); - break; - case PR_IpAddrLoopback: - addr->inet.ip = htonl(INADDR_LOOPBACK); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; - } - } - return rv; -} /* PR_SetNetAddr */ - -PR_IMPLEMENT(PRBool) -PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val) -{ - if (addr->raw.family == PR_AF_INET6) { - if (val == PR_IpAddrAny) { - if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) { - return PR_TRUE; - } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip) - && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip) - == htonl(INADDR_ANY)) { - return PR_TRUE; - } - } else if (val == PR_IpAddrLoopback) { - if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) { - return PR_TRUE; - } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip) - && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip) - == htonl(INADDR_LOOPBACK)) { - return PR_TRUE; - } - } else if (val == PR_IpAddrV4Mapped - && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) { - return PR_TRUE; - } - } else { - if (addr->raw.family == AF_INET) { - if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) { - return PR_TRUE; - } else if (val == PR_IpAddrLoopback - && addr->inet.ip == htonl(INADDR_LOOPBACK)) { - return PR_TRUE; - } - } - } - return PR_FALSE; -} - -extern int pr_inet_aton(const char *cp, PRUint32 *addr); - -#define XX 127 -static const unsigned char index_hex[256] = { - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX, - XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, -}; - -/* - * StringToV6Addr() returns 1 if the conversion succeeds, - * or 0 if the input is not a valid IPv6 address string. - * (Same as inet_pton(AF_INET6, string, addr).) - */ -static int StringToV6Addr(const char *string, PRIPv6Addr *addr) -{ - const unsigned char *s = (const unsigned char *)string; - int section = 0; /* index of the current section (a 16-bit - * piece of the address */ - int double_colon = -1; /* index of the section after the first - * 16-bit group of zeros represented by - * the double colon */ - unsigned int val; - int len; - - /* Handle initial (double) colon */ - if (*s == ':') { - if (s[1] != ':') return 0; - s += 2; - addr->pr_s6_addr16[0] = 0; - section = double_colon = 1; - } - - while (*s) { - if (section == 8) return 0; /* too long */ - if (*s == ':') { - if (double_colon != -1) return 0; /* two double colons */ - addr->pr_s6_addr16[section++] = 0; - double_colon = section; - s++; - continue; - } - for (len = val = 0; len < 4 && index_hex[*s] != XX; len++) { - val = (val << 4) + index_hex[*s++]; - } - if (*s == '.') { - if (len == 0) return 0; /* nothing between : and . */ - break; - } - if (*s == ':') { - s++; - if (!*s) return 0; /* cannot end with single colon */ - } else if (*s) { - return 0; /* bad character */ - } - addr->pr_s6_addr16[section++] = htons((unsigned short)val); - } - - if (*s == '.') { - /* Have a trailing v4 format address */ - if (section > 6) return 0; /* not enough room */ - - /* - * The number before the '.' is decimal, but we parsed it - * as hex. That means it is in BCD. Check it for validity - * and convert it to binary. - */ - if (val > 0x0255 || (val & 0xf0) > 0x90 || (val & 0xf) > 9) return 0; - val = (val >> 8) * 100 + ((val >> 4) & 0xf) * 10 + (val & 0xf); - addr->pr_s6_addr[2 * section] = val; - - s++; - val = index_hex[*s++]; - if (val > 9) return 0; - while (*s >= '0' && *s <= '9') { - val = val * 10 + *s++ - '0'; - if (val > 255) return 0; - } - if (*s != '.') return 0; /* must have exactly 4 decimal numbers */ - addr->pr_s6_addr[2 * section + 1] = val; - section++; - - s++; - val = index_hex[*s++]; - if (val > 9) return 0; - while (*s >= '0' && *s <= '9') { - val = val * 10 + *s++ - '0'; - if (val > 255) return 0; - } - if (*s != '.') return 0; /* must have exactly 4 decimal numbers */ - addr->pr_s6_addr[2 * section] = val; - - s++; - val = index_hex[*s++]; - if (val > 9) return 0; - while (*s >= '0' && *s <= '9') { - val = val * 10 + *s++ - '0'; - if (val > 255) return 0; - } - if (*s) return 0; /* must have exactly 4 decimal numbers */ - addr->pr_s6_addr[2 * section + 1] = val; - section++; - } - - if (double_colon != -1) { - /* Stretch the double colon */ - int tosection; - int ncopy = section - double_colon; - for (tosection = 7; ncopy--; tosection--) { - addr->pr_s6_addr16[tosection] = - addr->pr_s6_addr16[double_colon + ncopy]; - } - while (tosection >= double_colon) { - addr->pr_s6_addr16[tosection--] = 0; - } - } else if (section != 8) { - return 0; /* too short */ - } - return 1; -} -#undef XX - -#ifndef _PR_HAVE_INET_NTOP -static const char *basis_hex = "0123456789abcdef"; - -/* - * V6AddrToString() returns a pointer to the buffer containing - * the text string if the conversion succeeds, and NULL otherwise. - * (Same as inet_ntop(AF_INET6, addr, buf, size), except that errno - * is not set on failure.) - */ -static const char *V6AddrToString( - const PRIPv6Addr *addr, char *buf, PRUint32 size) -{ -#define STUFF(c) do { \ - if (!size--) return NULL; \ - *buf++ = (c); \ -} while (0) - - int double_colon = -1; /* index of the first 16-bit - * group of zeros represented - * by the double colon */ - int double_colon_length = 1; /* use double colon only if - * there are two or more 16-bit - * groups of zeros */ - int zero_length; - int section; - unsigned int val; - const char *bufcopy = buf; - - /* Scan to find the placement of the double colon */ - for (section = 0; section < 8; section++) { - if (addr->pr_s6_addr16[section] == 0) { - zero_length = 1; - section++; - while (section < 8 && addr->pr_s6_addr16[section] == 0) { - zero_length++; - section++; - } - /* Select the longest sequence of zeros */ - if (zero_length > double_colon_length) { - double_colon = section - zero_length; - double_colon_length = zero_length; - } - } - } - - /* Now start converting to a string */ - section = 0; - - if (double_colon == 0) { - if (double_colon_length == 6 || - (double_colon_length == 5 && addr->pr_s6_addr16[5] == 0xffff)) { - /* ipv4 format address */ - STUFF(':'); - STUFF(':'); - if (double_colon_length == 5) { - STUFF('f'); - STUFF('f'); - STUFF('f'); - STUFF('f'); - STUFF(':'); - } - if (addr->pr_s6_addr[12] > 99) STUFF(addr->pr_s6_addr[12]/100 + '0'); - if (addr->pr_s6_addr[12] > 9) STUFF((addr->pr_s6_addr[12]%100)/10 + '0'); - STUFF(addr->pr_s6_addr[12]%10 + '0'); - STUFF('.'); - if (addr->pr_s6_addr[13] > 99) STUFF(addr->pr_s6_addr[13]/100 + '0'); - if (addr->pr_s6_addr[13] > 9) STUFF((addr->pr_s6_addr[13]%100)/10 + '0'); - STUFF(addr->pr_s6_addr[13]%10 + '0'); - STUFF('.'); - if (addr->pr_s6_addr[14] > 99) STUFF(addr->pr_s6_addr[14]/100 + '0'); - if (addr->pr_s6_addr[14] > 9) STUFF((addr->pr_s6_addr[14]%100)/10 + '0'); - STUFF(addr->pr_s6_addr[14]%10 + '0'); - STUFF('.'); - if (addr->pr_s6_addr[15] > 99) STUFF(addr->pr_s6_addr[15]/100 + '0'); - if (addr->pr_s6_addr[15] > 9) STUFF((addr->pr_s6_addr[15]%100)/10 + '0'); - STUFF(addr->pr_s6_addr[15]%10 + '0'); - STUFF('\0'); - return bufcopy; - } - } - - while (section < 8) { - if (section == double_colon) { - STUFF(':'); - STUFF(':'); - section += double_colon_length; - continue; - } - val = ntohs(addr->pr_s6_addr16[section]); - if (val > 0xfff) { - STUFF(basis_hex[val >> 12]); - } - if (val > 0xff) { - STUFF(basis_hex[(val >> 8) & 0xf]); - } - if (val > 0xf) { - STUFF(basis_hex[(val >> 4) & 0xf]); - } - STUFF(basis_hex[val & 0xf]); - section++; - if (section < 8 && section != double_colon) STUFF(':'); - } - STUFF('\0'); - return bufcopy; -#undef STUFF -} -#endif /* !_PR_HAVE_INET_NTOP */ - -/* - * Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr - */ -PR_IMPLEMENT(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr) -{ - PRUint8 *dstp; - dstp = v6addr->pr_s6_addr; - memset(dstp, 0, 10); - memset(dstp + 10, 0xff, 2); - memcpy(dstp + 12,(char *) &v4addr, 4); -} - -PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { return ntohs(n); } -PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { return ntohl(n); } -PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { return htons(n); } -PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { return htonl(n); } -PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n) -{ -#ifdef IS_BIG_ENDIAN - return n; -#else - PRUint64 tmp; - PRUint32 hi, lo; - LL_L2UI(lo, n); - LL_SHR(tmp, n, 32); - LL_L2UI(hi, tmp); - hi = PR_ntohl(hi); - lo = PR_ntohl(lo); - LL_UI2L(n, lo); - LL_SHL(n, n, 32); - LL_UI2L(tmp, hi); - LL_ADD(n, n, tmp); - return n; -#endif -} /* ntohll */ - -PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n) -{ -#ifdef IS_BIG_ENDIAN - return n; -#else - PRUint64 tmp; - PRUint32 hi, lo; - LL_L2UI(lo, n); - LL_SHR(tmp, n, 32); - LL_L2UI(hi, tmp); - hi = htonl(hi); - lo = htonl(lo); - LL_UI2L(n, lo); - LL_SHL(n, n, 32); - LL_UI2L(tmp, hi); - LL_ADD(n, n, tmp); - return n; -#endif -} /* htonll */ - - -/* - * Implementation of PR_GetAddrInfoByName and friends - * - * Compile-time options: - * - * _PR_HAVE_GETADDRINFO Define this macro if the target system provides - * getaddrinfo. With this defined, NSPR will require - * getaddrinfo at run time. If this if not defined, - * then NSPR will attempt to dynamically resolve - * getaddrinfo, falling back to PR_GetHostByName if - * getaddrinfo does not exist on the target system. - * - * Since getaddrinfo is a relatively new system call on many systems, - * we are forced to dynamically resolve it at run time in most cases. - * The exception includes any system (such as Mac OS X) that is known to - * provide getaddrinfo in all versions that NSPR cares to support. - */ - -#if defined(_PR_HAVE_GETADDRINFO) - -#if defined(_PR_INET6) - -typedef struct addrinfo PRADDRINFO; -#define GETADDRINFO getaddrinfo -#define FREEADDRINFO freeaddrinfo -#define GETNAMEINFO getnameinfo - -#elif defined(_PR_INET6_PROBE) - -typedef struct addrinfo PRADDRINFO; - -/* getaddrinfo/freeaddrinfo/getnameinfo prototypes */ -#if defined(WIN32) -#define FUNC_MODIFIER __stdcall -#else -#define FUNC_MODIFIER -#endif -typedef int (FUNC_MODIFIER * FN_GETADDRINFO) - (const char *nodename, - const char *servname, - const PRADDRINFO *hints, - PRADDRINFO **res); -typedef int (FUNC_MODIFIER * FN_FREEADDRINFO) - (PRADDRINFO *ai); -typedef int (FUNC_MODIFIER * FN_GETNAMEINFO) - (const struct sockaddr *addr, int addrlen, - char *host, int hostlen, - char *serv, int servlen, int flags); - -/* global state */ -static FN_GETADDRINFO _pr_getaddrinfo = NULL; -static FN_FREEADDRINFO _pr_freeaddrinfo = NULL; -static FN_GETNAMEINFO _pr_getnameinfo = NULL; - -#define GETADDRINFO_SYMBOL "getaddrinfo" -#define FREEADDRINFO_SYMBOL "freeaddrinfo" -#define GETNAMEINFO_SYMBOL "getnameinfo" - -PRStatus -_pr_find_getaddrinfo(void) -{ - PRLibrary *lib; -#ifdef WIN32 - /* - * On windows, we need to search ws2_32.dll or wship6.dll - * (Microsoft IPv6 Technology Preview for Windows 2000) for - * getaddrinfo and freeaddrinfo. These libraries might not - * be loaded yet. - */ - const char *libname[] = { "ws2_32.dll", "wship6.dll" }; - int i; - - for (i = 0; i < sizeof(libname)/sizeof(libname[0]); i++) { - lib = PR_LoadLibrary(libname[i]); - if (!lib) { - continue; - } - _pr_getaddrinfo = (FN_GETADDRINFO) - PR_FindFunctionSymbol(lib, GETADDRINFO_SYMBOL); - if (!_pr_getaddrinfo) { - PR_UnloadLibrary(lib); - continue; - } - _pr_freeaddrinfo = (FN_FREEADDRINFO) - PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL); - _pr_getnameinfo = (FN_GETNAMEINFO) - PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL); - if (!_pr_freeaddrinfo || !_pr_getnameinfo) { - PR_UnloadLibrary(lib); - continue; - } - /* Keep the library loaded. */ - return PR_SUCCESS; - } - return PR_FAILURE; -#else - /* - * Resolve getaddrinfo by searching all loaded libraries. Then - * search library containing getaddrinfo for freeaddrinfo. - */ - _pr_getaddrinfo = (FN_GETADDRINFO) - PR_FindFunctionSymbolAndLibrary(GETADDRINFO_SYMBOL, &lib); - if (!_pr_getaddrinfo) { - return PR_FAILURE; - } - _pr_freeaddrinfo = (FN_FREEADDRINFO) - PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL); - _pr_getnameinfo = (FN_GETNAMEINFO) - PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL); - PR_UnloadLibrary(lib); - if (!_pr_freeaddrinfo || !_pr_getnameinfo) { - return PR_FAILURE; - } - return PR_SUCCESS; -#endif -} - -#define GETADDRINFO (*_pr_getaddrinfo) -#define FREEADDRINFO (*_pr_freeaddrinfo) -#define GETNAMEINFO (*_pr_getnameinfo) - -#endif /* _PR_INET6 */ - -#endif /* _PR_HAVE_GETADDRINFO */ - -#if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE) -/* - * If getaddrinfo does not exist, then we will fall back on - * PR_GetHostByName, which requires that we allocate a buffer for the - * PRHostEnt data structure and its members. - */ -typedef struct PRAddrInfoFB { - char buf[PR_NETDB_BUF_SIZE]; - PRHostEnt hostent; - PRBool has_cname; -} PRAddrInfoFB; - -static PRAddrInfo * -pr_GetAddrInfoByNameFB(const char *hostname, - PRUint16 af, - PRIntn flags) -{ - PRStatus rv; - PRAddrInfoFB *ai; - /* fallback on PR_GetHostByName */ - ai = PR_NEW(PRAddrInfoFB); - if (!ai) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - rv = PR_GetHostByName(hostname, ai->buf, sizeof ai->buf, &ai->hostent); - if (rv == PR_FAILURE) { - PR_Free(ai); - return NULL; - } - ai->has_cname = !(flags & PR_AI_NOCANONNAME); - - return (PRAddrInfo *) ai; -} -#endif /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */ - -PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, - PRUint16 af, - PRIntn flags) -{ - /* restrict input to supported values */ - if ((af != PR_AF_INET && af != PR_AF_UNSPEC) || - (flags & ~ PR_AI_NOCANONNAME) != PR_AI_ADDRCONFIG) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } - - if (!_pr_initialized) _PR_ImplicitInitialization(); - -#if !defined(_PR_HAVE_GETADDRINFO) - return pr_GetAddrInfoByNameFB(hostname, af, flags); -#else -#if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) { - return pr_GetAddrInfoByNameFB(hostname, af, flags); - } -#endif - { - PRADDRINFO *res, hints; - int rv; - - /* - * we assume a RFC 2553 compliant getaddrinfo. this may at some - * point need to be customized as platforms begin to adopt the - * RFC 3493. - */ - - memset(&hints, 0, sizeof(hints)); - if (!(flags & PR_AI_NOCANONNAME)) - hints.ai_flags |= AI_CANONNAME; -#ifdef AI_ADDRCONFIG - /* - * Propagate AI_ADDRCONFIG to the GETADDRINFO call if PR_AI_ADDRCONFIG - * is set. - * - * Need a workaround for loopback host addresses: - * The problem is that in glibc and Windows, AI_ADDRCONFIG applies the - * existence of an outgoing network interface to IP addresses of the - * loopback interface, due to a strict interpretation of the - * specification. For example, if a computer does not have any - * outgoing IPv6 network interface, but its loopback network interface - * supports IPv6, a getaddrinfo call on "localhost" with AI_ADDRCONFIG - * won't return the IPv6 loopback address "::1", because getaddrinfo - * thinks the computer cannot connect to any IPv6 destination, - * ignoring the remote vs. local/loopback distinction. - */ - if ((flags & PR_AI_ADDRCONFIG) && - strcmp(hostname, "localhost") != 0 && - strcmp(hostname, "localhost.localdomain") != 0 && - strcmp(hostname, "localhost6") != 0 && - strcmp(hostname, "localhost6.localdomain6") != 0) { - hints.ai_flags |= AI_ADDRCONFIG; - } -#endif - hints.ai_family = (af == PR_AF_INET) ? AF_INET : AF_UNSPEC; - - /* - * it is important to select a socket type in the hints, otherwise we - * will get back repetitive entries: one for each socket type. since - * we do not expose ai_socktype through our API, it is okay to do this - * here. the application may still choose to create a socket of some - * other type. - */ - hints.ai_socktype = SOCK_STREAM; - - rv = GETADDRINFO(hostname, NULL, &hints, &res); -#ifdef AI_ADDRCONFIG - if (rv == EAI_BADFLAGS && (hints.ai_flags & AI_ADDRCONFIG)) { - hints.ai_flags &= ~AI_ADDRCONFIG; - rv = GETADDRINFO(hostname, NULL, &hints, &res); - } -#endif - if (rv == 0) - return (PRAddrInfo *) res; - - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv); - } - return NULL; -#endif -} - -PR_IMPLEMENT(void) PR_FreeAddrInfo(PRAddrInfo *ai) -{ -#if defined(_PR_HAVE_GETADDRINFO) -#if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) - PR_Free((PRAddrInfoFB *) ai); - else -#endif - FREEADDRINFO((PRADDRINFO *) ai); -#else - PR_Free((PRAddrInfoFB *) ai); -#endif -} - -PR_IMPLEMENT(void *) PR_EnumerateAddrInfo(void *iterPtr, - const PRAddrInfo *base, - PRUint16 port, - PRNetAddr *result) -{ -#if defined(_PR_HAVE_GETADDRINFO) - PRADDRINFO *ai; -#if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) { - /* using PRAddrInfoFB */ - PRIntn iter = (PRIntn)(PRPtrdiff) iterPtr; - iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result); - if (iter < 0) - iter = 0; - return (void *)(PRPtrdiff) iter; - } -#endif - - if (iterPtr) - ai = ((PRADDRINFO *) iterPtr)->ai_next; - else - ai = (PRADDRINFO *) base; - - while (ai && ai->ai_addrlen > sizeof(PRNetAddr)) - ai = ai->ai_next; - - if (ai) { - /* copy sockaddr to PRNetAddr */ - memcpy(result, ai->ai_addr, ai->ai_addrlen); - result->raw.family = ai->ai_addr->sa_family; -#ifdef _PR_INET6 - if (AF_INET6 == result->raw.family) - result->raw.family = PR_AF_INET6; -#endif - if (ai->ai_addrlen < sizeof(PRNetAddr)) - memset(((char*)result)+ai->ai_addrlen, 0, sizeof(PRNetAddr) - ai->ai_addrlen); - - if (result->raw.family == PR_AF_INET) - result->inet.port = htons(port); - else - result->ipv6.port = htons(port); - } - - return ai; -#else - /* using PRAddrInfoFB */ - PRIntn iter = (PRIntn) iterPtr; - iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result); - if (iter < 0) - iter = 0; - return (void *) iter; -#endif -} - -PR_IMPLEMENT(const char *) PR_GetCanonNameFromAddrInfo(const PRAddrInfo *ai) -{ -#if defined(_PR_HAVE_GETADDRINFO) -#if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) { - const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai; - return fb->has_cname ? fb->hostent.h_name : NULL; - } -#endif - return ((const PRADDRINFO *) ai)->ai_canonname; -#else - const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai; - return fb->has_cname ? fb->hostent.h_name : NULL; -#endif -} - -#if defined(_PR_HAVE_GETADDRINFO) -static PRStatus pr_StringToNetAddrGAI(const char *string, PRNetAddr *addr) -{ - PRADDRINFO *res, hints; - int rv; /* 0 for success, or the error code EAI_xxx */ - PRNetAddr laddr; - PRStatus status = PR_SUCCESS; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - rv = GETADDRINFO(string, NULL, &hints, &res); - if (rv != 0) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv); - return PR_FAILURE; - } - - /* pick up the first addr */ - memcpy(&laddr, res->ai_addr, res->ai_addrlen); - if (AF_INET6 == res->ai_addr->sa_family) - { - addr->ipv6.family = PR_AF_INET6; - addr->ipv6.ip = laddr.ipv6.ip; - addr->ipv6.scope_id = laddr.ipv6.scope_id; - } - else if (AF_INET == res->ai_addr->sa_family) - { - addr->inet.family = PR_AF_INET; - addr->inet.ip = laddr.inet.ip; - } - else - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - status = PR_FAILURE; - } - - FREEADDRINFO(res); - return status; -} -#endif /* _PR_HAVE_GETADDRINFO */ - -static PRStatus pr_StringToNetAddrFB(const char *string, PRNetAddr *addr) -{ - PRIntn rv; - - rv = pr_inet_aton(string, &addr->inet.ip); - if (1 == rv) - { - addr->raw.family = AF_INET; - return PR_SUCCESS; - } - - PR_ASSERT(0 == rv); - /* clean up after the failed call */ - memset(&addr->inet.ip, 0, sizeof(addr->inet.ip)); - - rv = StringToV6Addr(string, &addr->ipv6.ip); - if (1 == rv) - { - addr->raw.family = PR_AF_INET6; - return PR_SUCCESS; - } - - PR_ASSERT(0 == rv); - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (!addr || !string || !*string) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - -#if !defined(_PR_HAVE_GETADDRINFO) - return pr_StringToNetAddrFB(string, addr); -#else -#if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) - return pr_StringToNetAddrFB(string, addr); -#endif - /* - * getaddrinfo with AI_NUMERICHOST is much slower than pr_inet_aton on some - * platforms, such as Mac OS X (bug 404399), Linux glibc 2.10 (bug 344809), - * and most likely others. So we only use it to convert literal IP addresses - * that contain IPv6 scope IDs, which pr_inet_aton cannot convert. - */ - if (!strchr(string, '%')) - return pr_StringToNetAddrFB(string, addr); - - return pr_StringToNetAddrGAI(string, addr); -#endif -} - -#if defined(_PR_HAVE_GETADDRINFO) -static PRStatus pr_NetAddrToStringGNI( - const PRNetAddr *addr, char *string, PRUint32 size) -{ - int addrlen; - const PRNetAddr *addrp = addr; -#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) - PRUint16 md_af = addr->raw.family; - PRNetAddr addrcopy; -#endif - int rv; /* 0 for success, or the error code EAI_xxx */ - -#ifdef _PR_INET6 - if (addr->raw.family == PR_AF_INET6) - { - md_af = AF_INET6; -#ifndef _PR_HAVE_SOCKADDR_LEN - addrcopy = *addr; - addrcopy.raw.family = AF_INET6; - addrp = &addrcopy; -#endif - } -#endif - - addrlen = PR_NETADDR_SIZE(addr); -#ifdef _PR_HAVE_SOCKADDR_LEN - addrcopy = *addr; - ((struct sockaddr*)&addrcopy)->sa_len = addrlen; - ((struct sockaddr*)&addrcopy)->sa_family = md_af; - addrp = &addrcopy; -#endif - rv = GETNAMEINFO((const struct sockaddr *)addrp, addrlen, - string, size, NULL, 0, NI_NUMERICHOST); - if (rv != 0) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv); - return PR_FAILURE; - } - return PR_SUCCESS; -} -#endif /* _PR_HAVE_GETADDRINFO */ - -#if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE) -static PRStatus pr_NetAddrToStringFB( - const PRNetAddr *addr, char *string, PRUint32 size) -{ - if (PR_AF_INET6 == addr->raw.family) - { -#if defined(_PR_HAVE_INET_NTOP) - if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size)) -#else - if (NULL == V6AddrToString(&addr->ipv6.ip, string, size)) -#endif - { - /* the size of the result buffer is inadequate */ - PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); - return PR_FAILURE; - } - } - else - { - if (size < 16) goto failed; - if (AF_INET != addr->raw.family) goto failed; - else - { - unsigned char *byte = (unsigned char*)&addr->inet.ip; - PR_snprintf(string, size, "%u.%u.%u.%u", - byte[0], byte[1], byte[2], byte[3]); - } - } - - return PR_SUCCESS; - -failed: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - -} /* pr_NetAddrToStringFB */ -#endif /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */ - -PR_IMPLEMENT(PRStatus) PR_NetAddrToString( - const PRNetAddr *addr, char *string, PRUint32 size) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - -#if !defined(_PR_HAVE_GETADDRINFO) - return pr_NetAddrToStringFB(addr, string, size); -#else -#if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) - return pr_NetAddrToStringFB(addr, string, size); -#endif - return pr_NetAddrToStringGNI(addr, string, size); -#endif -} /* PR_NetAddrToString */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prolock.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prolock.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prolock.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prolock.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** prolock.c -- NSPR Ordered Lock -** -** Implement the API defined in prolock.h -** -*/ -#include "prolock.h" -#include "prlog.h" -#include "prerror.h" - -PR_IMPLEMENT(PROrderedLock *) - PR_CreateOrderedLock( - PRInt32 order, - const char *name -) -{ - PR_ASSERT(!"Not implemented"); /* Not implemented yet */ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} /* end PR_CreateOrderedLock() */ - - -PR_IMPLEMENT(void) - PR_DestroyOrderedLock( - PROrderedLock *lock -) -{ - PR_ASSERT(!"Not implemented"); /* Not implemented yet */ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); -} /* end PR_DestroyOrderedLock() */ - - -PR_IMPLEMENT(void) - PR_LockOrderedLock( - PROrderedLock *lock -) -{ - PR_ASSERT(!"Not implemented"); /* Not implemented yet */ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); -} /* end PR_LockOrderedLock() */ - - -PR_IMPLEMENT(PRStatus) - PR_UnlockOrderedLock( - PROrderedLock *lock -) -{ - PR_ASSERT(!"Not implemented"); /* Not implemented yet */ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} /* end PR_UnlockOrderedLock() */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prrng.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prrng.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prrng.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prrng.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -/* - * We were not including in optimized builds. On AIX this - * caused libnspr4.so to export memcpy and some binaries linked with - * libnspr4.so resolved their memcpy references with libnspr4.so. To - * be backward compatible with old libnspr4.so binaries, we do not - * include in optimized builds for AIX. (bug 200561) - */ -#if !(defined(AIX) && !defined(DEBUG)) -#include -#endif - -PRSize _pr_CopyLowBits( - void *dst, - PRSize dstlen, - void *src, - PRSize srclen ) -{ - if (srclen <= dstlen) { - memcpy(dst, src, srclen); - return srclen; - } -#if defined IS_BIG_ENDIAN - memcpy(dst, (char*)src + (srclen - dstlen), dstlen); -#else - memcpy(dst, src, dstlen); -#endif - return dstlen; -} - -PR_IMPLEMENT(PRSize) PR_GetRandomNoise( - void *buf, - PRSize size -) -{ - return( _PR_MD_GET_RANDOM_NOISE( buf, size )); -} /* end PR_GetRandomNoise() */ -/* end prrng.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prsystem.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prsystem.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prsystem.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prsystem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,382 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include "prsystem.h" -#include "prprf.h" -#include "prlong.h" - -#if defined(BEOS) -#include -#endif - -#if defined(OS2) -#define INCL_DOS -#define INCL_DOSMISC -#include -/* define the required constant if it is not already defined in the headers */ -#ifndef QSV_NUMPROCESSORS -#define QSV_NUMPROCESSORS 26 -#endif -#endif - -/* BSD-derived systems use sysctl() to get the number of processors */ -#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \ - || defined(OPENBSD) || defined(DARWIN) -#define _PR_HAVE_SYSCTL -#include -#include -#endif - -#if defined(DARWIN) -#include -#include -#endif - -#if defined(HPUX) -#include -#include -#endif - -#if defined(XP_UNIX) -#include -#include -#endif - -#if defined(LINUX) -#include -#include -#define MAX_LINE 512 -#endif - -#if defined(AIX) -#include -#include -#endif - -#if defined(WIN32) -/* This struct is not present in VC6 headers, so declare it here */ -typedef struct { - DWORD dwLength; - DWORD dwMemoryLoad; - DWORDLONG ullTotalPhys; - DWORDLONG ullAvailPhys; - DWORDLONG ullToalPageFile; - DWORDLONG ullAvailPageFile; - DWORDLONG ullTotalVirtual; - DWORDLONG ullAvailVirtual; - DWORDLONG ullAvailExtendedVirtual; -} PR_MEMORYSTATUSEX; - -/* Typedef for dynamic lookup of GlobalMemoryStatusEx(). */ -typedef BOOL (WINAPI *GlobalMemoryStatusExFn)(PR_MEMORYSTATUSEX *); -#endif - -PR_IMPLEMENT(char) PR_GetDirectorySeparator(void) -{ - return PR_DIRECTORY_SEPARATOR; -} /* PR_GetDirectorySeparator */ - -/* -** OBSOLETE -- the function name is misspelled. -*/ -PR_IMPLEMENT(char) PR_GetDirectorySepartor(void) -{ -#if defined(DEBUG) - static PRBool warn = PR_TRUE; - if (warn) { - warn = _PR_Obsolete("PR_GetDirectorySepartor()", - "PR_GetDirectorySeparator()"); - } -#endif - return PR_GetDirectorySeparator(); -} /* PR_GetDirectorySepartor */ - -PR_IMPLEMENT(char) PR_GetPathSeparator(void) -{ - return PR_PATH_SEPARATOR; -} /* PR_GetPathSeparator */ - -PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen) -{ - PRUintn len = 0; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - switch(cmd) - { - case PR_SI_HOSTNAME: - case PR_SI_HOSTNAME_UNTRUNCATED: - if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen)) - return PR_FAILURE; - - if (cmd == PR_SI_HOSTNAME_UNTRUNCATED) - break; - /* - * On some platforms a system does not have a hostname and - * its IP address is returned instead. The following code - * should be skipped on those platforms. - */ -#ifndef _PR_GET_HOST_ADDR_AS_NAME - /* Return the unqualified hostname */ - while (buf[len] && (len < buflen)) { - if (buf[len] == '.') { - buf[len] = '\0'; - break; - } - len += 1; - } -#endif - break; - - case PR_SI_SYSNAME: - /* Return the operating system name */ -#if defined(XP_UNIX) || defined(WIN32) - if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) - return PR_FAILURE; -#else - (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME); -#endif - break; - - case PR_SI_RELEASE: - /* Return the version of the operating system */ -#if defined(XP_UNIX) || defined(WIN32) - if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) - return PR_FAILURE; -#endif -#if defined(XP_OS2) - { - ULONG os2ver[2] = {0}; - DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION, - &os2ver, sizeof(os2ver)); - /* Formatting for normal usage (2.11, 3.0, 4.0, 4.5); officially, - Warp 4 is version 2.40.00, WSeB 2.45.00 */ - if (os2ver[0] < 30) - (void)PR_snprintf(buf, buflen, "%s%lu", - "2.", os2ver[0]); - else if (os2ver[0] < 45) - (void)PR_snprintf(buf, buflen, "%lu%s%lu", - os2ver[0]/10, ".", os2ver[1]); - else - (void)PR_snprintf(buf, buflen, "%.1f", - os2ver[0]/10.0); - } -#endif /* OS2 */ - break; - - case PR_SI_ARCHITECTURE: - /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/ - (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -/* -** PR_GetNumberOfProcessors() -** -** Implementation notes: -** Every platform does it a bit different. -** numCpus is the returned value. -** for each platform's "if defined" section -** declare your local variable -** do your thing, assign to numCpus -** order of the if defined()s may be important, -** especially for unix variants. Do platform -** specific implementations before XP_UNIX. -** -*/ -PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void ) -{ - PRInt32 numCpus; -#if defined(WIN32) - SYSTEM_INFO info; - - GetSystemInfo( &info ); - numCpus = info.dwNumberOfProcessors; -#elif defined(BEOS) - system_info sysInfo; - - get_system_info(&sysInfo); - numCpus = sysInfo.cpu_count; -#elif defined(OS2) - DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus)); -#elif defined(_PR_HAVE_SYSCTL) - int mib[2]; - int rc; - size_t len = sizeof(numCpus); - - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - rc = sysctl( mib, 2, &numCpus, &len, NULL, 0 ); - if ( -1 == rc ) { - numCpus = -1; /* set to -1 for return value on error */ - _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() ); - } -#elif defined(HPUX) - numCpus = mpctl( MPC_GETNUMSPUS, 0, 0 ); - if ( numCpus < 1 ) { - numCpus = -1; /* set to -1 for return value on error */ - _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() ); - } -#elif defined(IRIX) - numCpus = sysconf( _SC_NPROC_ONLN ); -#elif defined(RISCOS) || defined(SYMBIAN) - numCpus = 1; -#elif defined(LINUX) - /* for the benefit of devices with advanced power-saving, that - actually hotplug their cpus in heavy load, try to figure out - the real number of CPUs */ - char buf[MAX_LINE]; - FILE *fin; - const char *cpu_present = "/sys/devices/system/cpu/present"; - size_t strsize; - numCpus = 0; - fin = fopen(cpu_present, "r"); - if (fin != NULL) { - if (fgets(buf, MAX_LINE, fin) != NULL) { - /* check that the format is what we expect */ - if (buf[0] == '0') { - strsize = strlen(buf); - if (strsize == 1) { - /* single core */ - numCpus = 1; - } else if (strsize >= 3 && strsize <= 5) { - /* should be of the form 0-999 */ - /* parse the part after the 0-, note count is 0-based */ - if (buf[1] == '-' && isdigit(buf[2])) { - numCpus = 1 + atoi(buf + 2); - } - } - } - } - fclose(fin); - } - /* if that fails, fall back to more standard methods */ - if (!numCpus) { - numCpus = sysconf( _SC_NPROCESSORS_CONF ); - } -#elif defined(XP_UNIX) - numCpus = sysconf( _SC_NPROCESSORS_CONF ); -#else -#error "An implementation is required" -#endif - return(numCpus); -} /* end PR_GetNumberOfProcessors() */ - -/* -** PR_GetPhysicalMemorySize() -** -** Implementation notes: -** Every platform does it a bit different. -** bytes is the returned value. -** for each platform's "if defined" section -** declare your local variable -** do your thing, assign to bytes. -** -*/ -PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void) -{ - PRUint64 bytes = 0; - -#if defined(LINUX) || defined(SOLARIS) - - long pageSize = sysconf(_SC_PAGESIZE); - long pageCount = sysconf(_SC_PHYS_PAGES); - if (pageSize >= 0 && pageCount >= 0) - bytes = (PRUint64) pageSize * pageCount; - -#elif defined(NETBSD) || defined(OPENBSD) - - int mib[2]; - int rc; - uint64_t memSize; - size_t len = sizeof(memSize); - - mib[0] = CTL_HW; - mib[1] = HW_PHYSMEM64; - rc = sysctl(mib, 2, &memSize, &len, NULL, 0); - if (-1 != rc) { - bytes = memSize; - } - -#elif defined(HPUX) - - struct pst_static info; - int result = pstat_getstatic(&info, sizeof(info), 1, 0); - if (result == 1) - bytes = (PRUint64) info.physical_memory * info.page_size; - -#elif defined(DARWIN) - - struct host_basic_info hInfo; - mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; - - int result = host_info(mach_host_self(), - HOST_BASIC_INFO, - (host_info_t) &hInfo, - &count); - if (result == KERN_SUCCESS) - bytes = hInfo.max_mem; - -#elif defined(WIN32) - - /* Try to use the newer GlobalMemoryStatusEx API for Windows 2000+. */ - GlobalMemoryStatusExFn globalMemory = (GlobalMemoryStatusExFn) NULL; - HMODULE module = GetModuleHandleW(L"kernel32.dll"); - - if (module) { - globalMemory = (GlobalMemoryStatusExFn)GetProcAddress(module, "GlobalMemoryStatusEx"); - - if (globalMemory) { - PR_MEMORYSTATUSEX memStat; - memStat.dwLength = sizeof(memStat); - - if (globalMemory(&memStat)) - bytes = memStat.ullTotalPhys; - } - } - - if (!bytes) { - /* Fall back to the older API. */ - MEMORYSTATUS memStat; - memset(&memStat, 0, sizeof(memStat)); - GlobalMemoryStatus(&memStat); - bytes = memStat.dwTotalPhys; - } - -#elif defined(OS2) - - ULONG ulPhysMem; - DosQuerySysInfo(QSV_TOTPHYSMEM, - QSV_TOTPHYSMEM, - &ulPhysMem, - sizeof(ulPhysMem)); - bytes = ulPhysMem; - -#elif defined(AIX) - - if (odm_initialize() == 0) { - int how_many; - struct CuAt *obj = getattr("sys0", "realmem", 0, &how_many); - if (obj != NULL) { - bytes = (PRUint64) atoi(obj->value) * 1024; - free(obj); - } - odm_terminate(); - } - -#else - - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - -#endif - - return bytes; -} /* end PR_GetPhysicalMemorySize() */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prthinfo.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prthinfo.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prthinfo.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prthinfo.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prlog.h" -#include "prthread.h" -#include "private/pprthred.h" -#include "primpl.h" - -PR_IMPLEMENT(PRWord *) -PR_GetGCRegisters(PRThread *t, int isCurrent, int *np) -{ - return _MD_HomeGCRegisters(t, isCurrent, np); -} - -PR_IMPLEMENT(PRStatus) -PR_ThreadScanStackPointers(PRThread* t, - PRScanStackFun scanFun, void* scanClosure) -{ - PRThread* current = PR_GetCurrentThread(); - PRWord *sp, *esp, *p0; - int n; - void **ptd; - PRStatus status; - PRUint32 index; - int stack_end; - - /* - ** Store the thread's registers in the thread structure so the GC - ** can scan them. Then scan them. - */ - p0 = _MD_HomeGCRegisters(t, t == current, &n); - status = scanFun(t, (void**)p0, n, scanClosure); - if (status != PR_SUCCESS) - return status; - - /* Scan the C stack for pointers into the GC heap */ -#if defined(XP_PC) && defined(WIN16) - /* - ** Under WIN16, the stack of the current thread is always mapped into - ** the "task stack" (at SS:xxxx). So, if t is the current thread, scan - ** the "task stack". Otherwise, scan the "cached stack" of the inactive - ** thread... - */ - if (t == current) { - sp = (PRWord*) &stack_end; - esp = (PRWord*) _pr_top_of_task_stack; - - PR_ASSERT(sp <= esp); - } else { - sp = (PRWord*) PR_GetSP(t); - esp = (PRWord*) t->stack->stackTop; - - PR_ASSERT((t->stack->stackSize == 0) || - ((sp > (PRWord*)t->stack->stackBottom) && - (sp <= (PRWord*)t->stack->stackTop))); - } -#else /* ! WIN16 */ -#ifdef HAVE_STACK_GROWING_UP - if (t == current) { - esp = (PRWord*) &stack_end; - } else { - esp = (PRWord*) PR_GetSP(t); - } - sp = (PRWord*) t->stack->stackTop; - if (t->stack->stackSize) { - PR_ASSERT((esp > (PRWord*)t->stack->stackTop) && - (esp < (PRWord*)t->stack->stackBottom)); - } -#else /* ! HAVE_STACK_GROWING_UP */ - if (t == current) { - sp = (PRWord*) &stack_end; - } else { - sp = (PRWord*) PR_GetSP(t); - } - esp = (PRWord*) t->stack->stackTop; - if (t->stack->stackSize) { - PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) && - (sp < (PRWord*)t->stack->stackTop)); - } -#endif /* ! HAVE_STACK_GROWING_UP */ -#endif /* ! WIN16 */ - -#if defined(WIN16) - { - prword_t scan; - prword_t limit; - - scan = (prword_t) sp; - limit = (prword_t) esp; - while (scan < limit) { - prword_t *test; - - test = *((prword_t **)scan); - status = scanFun(t, (void**)&test, 1, scanClosure); - if (status != PR_SUCCESS) - return status; - scan += sizeof(char); - } - } -#else - if (sp < esp) { - status = scanFun(t, (void**)sp, esp - sp, scanClosure); - if (status != PR_SUCCESS) - return status; - } -#endif - - /* - ** Mark all of the per-thread-data items attached to this thread - ** - ** The execution environment better be accounted for otherwise it - ** will be collected - */ - status = scanFun(t, (void**)&t->environment, 1, scanClosure); - if (status != PR_SUCCESS) - return status; - - /* if thread is not allocated on stack, this is redundant. */ - ptd = t->privateData; - for (index = 0; index < t->tpdLength; index++, ptd++) { - status = scanFun(t, (void**)ptd, 1, scanClosure); - if (status != PR_SUCCESS) - return status; - } - - return PR_SUCCESS; -} - -/* transducer for PR_EnumerateThreads */ -typedef struct PRScanStackData { - PRScanStackFun scanFun; - void* scanClosure; -} PRScanStackData; - -static PRStatus PR_CALLBACK -pr_ScanStack(PRThread* t, int i, void* arg) -{ - PRScanStackData* data = (PRScanStackData*)arg; - return PR_ThreadScanStackPointers(t, data->scanFun, data->scanClosure); -} - -PR_IMPLEMENT(PRStatus) -PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure) -{ - PRScanStackData data; - data.scanFun = scanFun; - data.scanClosure = scanClosure; - return PR_EnumerateThreads(pr_ScanStack, &data); -} - -PR_IMPLEMENT(PRUword) -PR_GetStackSpaceLeft(PRThread* t) -{ - PRThread *current = PR_GetCurrentThread(); - PRWord *sp, *esp; - int stack_end; - -#if defined(WIN16) - /* - ** Under WIN16, the stack of the current thread is always mapped into - ** the "task stack" (at SS:xxxx). So, if t is the current thread, scan - ** the "task stack". Otherwise, scan the "cached stack" of the inactive - ** thread... - */ - if (t == current) { - sp = (PRWord*) &stack_end; - esp = (PRWord*) _pr_top_of_task_stack; - - PR_ASSERT(sp <= esp); - } else { - sp = (PRWord*) PR_GetSP(t); - esp = (PRWord*) t->stack->stackTop; - - PR_ASSERT((t->stack->stackSize == 0) || - ((sp > (PRWord*)t->stack->stackBottom) && - (sp <= (PRWord*)t->stack->stackTop))); - } -#else /* ! WIN16 */ -#ifdef HAVE_STACK_GROWING_UP - if (t == current) { - esp = (PRWord*) &stack_end; - } else { - esp = (PRWord*) PR_GetSP(t); - } - sp = (PRWord*) t->stack->stackTop; - if (t->stack->stackSize) { - PR_ASSERT((esp > (PRWord*)t->stack->stackTop) && - (esp < (PRWord*)t->stack->stackBottom)); - } -#else /* ! HAVE_STACK_GROWING_UP */ - if (t == current) { - sp = (PRWord*) &stack_end; - } else { - sp = (PRWord*) PR_GetSP(t); - } - esp = (PRWord*) t->stack->stackTop; - if (t->stack->stackSize) { - PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) && - (sp < (PRWord*)t->stack->stackTop)); - } -#endif /* ! HAVE_STACK_GROWING_UP */ -#endif /* ! WIN16 */ - return (PRUword)t->stack->stackSize - ((PRWord)esp - (PRWord)sp); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prtime.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prtime.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prtime.c 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prtime.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2011 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * prtime.c -- - * - * NSPR date and time functions - * - */ - -#include "prinit.h" -#include "prtime.h" -#include "prlock.h" -#include "prprf.h" -#include "prlog.h" - -#include -#include -#include /* for EINVAL */ -#include - -/* - * The COUNT_LEAPS macro counts the number of leap years passed by - * till the start of the given year Y. At the start of the year 4 - * A.D. the number of leap years passed by is 0, while at the start of - * the year 5 A.D. this count is 1. The number of years divisible by - * 100 but not divisible by 400 (the non-leap years) is deducted from - * the count to get the correct number of leap years. - * - * The COUNT_DAYS macro counts the number of days since 01/01/01 till the - * start of the given year Y. The number of days at the start of the year - * 1 is 0 while the number of days at the start of the year 2 is 365 - * (which is ((2)-1) * 365) and so on. The reference point is 01/01/01 - * midnight 00:00:00. - */ - -#define COUNT_LEAPS(Y) ( ((Y)-1)/4 - ((Y)-1)/100 + ((Y)-1)/400 ) -#define COUNT_DAYS(Y) ( ((Y)-1)*365 + COUNT_LEAPS(Y) ) -#define DAYS_BETWEEN_YEARS(A, B) (COUNT_DAYS(B) - COUNT_DAYS(A)) - -/* - * Static variables used by functions in this file - */ - -/* - * The following array contains the day of year for the last day of - * each month, where index 1 is January, and day 0 is January 1. - */ - -static const int lastDayOfMonth[2][13] = { - {-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364}, - {-1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365} -}; - -/* - * The number of days in a month - */ - -static const PRInt8 nDays[2][12] = { - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -}; - -/* - * Declarations for internal functions defined later in this file. - */ - -static void ComputeGMT(PRTime time, PRExplodedTime *gmt); -static int IsLeapYear(PRInt16 year); -static void ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset); - -/* - *------------------------------------------------------------------------ - * - * ComputeGMT -- - * - * Caveats: - * - we ignore leap seconds - * - *------------------------------------------------------------------------ - */ - -static void -ComputeGMT(PRTime time, PRExplodedTime *gmt) -{ - PRInt32 tmp, rem; - PRInt32 numDays; - PRInt64 numDays64, rem64; - int isLeap; - PRInt64 sec; - PRInt64 usec; - PRInt64 usecPerSec; - PRInt64 secPerDay; - - /* - * We first do the usec, sec, min, hour thing so that we do not - * have to do LL arithmetic. - */ - - LL_I2L(usecPerSec, 1000000L); - LL_DIV(sec, time, usecPerSec); - LL_MOD(usec, time, usecPerSec); - LL_L2I(gmt->tm_usec, usec); - /* Correct for weird mod semantics so the remainder is always positive */ - if (gmt->tm_usec < 0) { - PRInt64 one; - - LL_I2L(one, 1L); - LL_SUB(sec, sec, one); - gmt->tm_usec += 1000000L; - } - - LL_I2L(secPerDay, 86400L); - LL_DIV(numDays64, sec, secPerDay); - LL_MOD(rem64, sec, secPerDay); - /* We are sure both of these numbers can fit into PRInt32 */ - LL_L2I(numDays, numDays64); - LL_L2I(rem, rem64); - if (rem < 0) { - numDays--; - rem += 86400L; - } - - /* Compute day of week. Epoch started on a Thursday. */ - - gmt->tm_wday = (numDays + 4) % 7; - if (gmt->tm_wday < 0) { - gmt->tm_wday += 7; - } - - /* Compute the time of day. */ - - gmt->tm_hour = rem / 3600; - rem %= 3600; - gmt->tm_min = rem / 60; - gmt->tm_sec = rem % 60; - - /* - * Compute the year by finding the 400 year period, then working - * down from there. - * - * Since numDays is originally the number of days since January 1, 1970, - * we must change it to be the number of days from January 1, 0001. - */ - - numDays += 719162; /* 719162 = days from year 1 up to 1970 */ - tmp = numDays / 146097; /* 146097 = days in 400 years */ - rem = numDays % 146097; - gmt->tm_year = tmp * 400 + 1; - - /* Compute the 100 year period. */ - - tmp = rem / 36524; /* 36524 = days in 100 years */ - rem %= 36524; - if (tmp == 4) { /* the 400th year is a leap year */ - tmp = 3; - rem = 36524; - } - gmt->tm_year += tmp * 100; - - /* Compute the 4 year period. */ - - tmp = rem / 1461; /* 1461 = days in 4 years */ - rem %= 1461; - gmt->tm_year += tmp * 4; - - /* Compute which year in the 4. */ - - tmp = rem / 365; - rem %= 365; - if (tmp == 4) { /* the 4th year is a leap year */ - tmp = 3; - rem = 365; - } - - gmt->tm_year += tmp; - gmt->tm_yday = rem; - isLeap = IsLeapYear(gmt->tm_year); - - /* Compute the month and day of month. */ - - for (tmp = 1; lastDayOfMonth[isLeap][tmp] < gmt->tm_yday; tmp++) { - } - gmt->tm_month = --tmp; - gmt->tm_mday = gmt->tm_yday - lastDayOfMonth[isLeap][tmp]; - - gmt->tm_params.tp_gmt_offset = 0; - gmt->tm_params.tp_dst_offset = 0; -} - - -/* - *------------------------------------------------------------------------ - * - * PR_ExplodeTime -- - * - * Cf. struct tm *gmtime(const time_t *tp) and - * struct tm *localtime(const time_t *tp) - * - *------------------------------------------------------------------------ - */ - -PR_IMPLEMENT(void) -PR_ExplodeTime( - PRTime usecs, - PRTimeParamFn params, - PRExplodedTime *exploded) -{ - ComputeGMT(usecs, exploded); - exploded->tm_params = params(exploded); - ApplySecOffset(exploded, exploded->tm_params.tp_gmt_offset - + exploded->tm_params.tp_dst_offset); -} - - -/* - *------------------------------------------------------------------------ - * - * PR_ImplodeTime -- - * - * Cf. time_t mktime(struct tm *tp) - * Note that 1 year has < 2^25 seconds. So an PRInt32 is large enough. - * - *------------------------------------------------------------------------ - */ -PR_IMPLEMENT(PRTime) -PR_ImplodeTime(const PRExplodedTime *exploded) -{ - PRExplodedTime copy; - PRTime retVal; - PRInt64 secPerDay, usecPerSec; - PRInt64 temp; - PRInt64 numSecs64; - PRInt32 numDays; - PRInt32 numSecs; - - /* Normalize first. Do this on our copy */ - copy = *exploded; - PR_NormalizeTime(©, PR_GMTParameters); - - numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year); - - numSecs = copy.tm_yday * 86400 + copy.tm_hour * 3600 - + copy.tm_min * 60 + copy.tm_sec; - - LL_I2L(temp, numDays); - LL_I2L(secPerDay, 86400); - LL_MUL(temp, temp, secPerDay); - LL_I2L(numSecs64, numSecs); - LL_ADD(numSecs64, numSecs64, temp); - - /* apply the GMT and DST offsets */ - LL_I2L(temp, copy.tm_params.tp_gmt_offset); - LL_SUB(numSecs64, numSecs64, temp); - LL_I2L(temp, copy.tm_params.tp_dst_offset); - LL_SUB(numSecs64, numSecs64, temp); - - LL_I2L(usecPerSec, 1000000L); - LL_MUL(temp, numSecs64, usecPerSec); - LL_I2L(retVal, copy.tm_usec); - LL_ADD(retVal, retVal, temp); - - return retVal; -} - -/* - *------------------------------------------------------------------------- - * - * IsLeapYear -- - * - * Returns 1 if the year is a leap year, 0 otherwise. - * - *------------------------------------------------------------------------- - */ - -static int IsLeapYear(PRInt16 year) -{ - if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) - return 1; - else - return 0; -} - -/* - * 'secOffset' should be less than 86400 (i.e., a day). - * 'time' should point to a normalized PRExplodedTime. - */ - -static void -ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset) -{ - time->tm_sec += secOffset; - - /* Note that in this implementation we do not count leap seconds */ - if (time->tm_sec < 0 || time->tm_sec >= 60) { - time->tm_min += time->tm_sec / 60; - time->tm_sec %= 60; - if (time->tm_sec < 0) { - time->tm_sec += 60; - time->tm_min--; - } - } - - if (time->tm_min < 0 || time->tm_min >= 60) { - time->tm_hour += time->tm_min / 60; - time->tm_min %= 60; - if (time->tm_min < 0) { - time->tm_min += 60; - time->tm_hour--; - } - } - - if (time->tm_hour < 0) { - /* Decrement mday, yday, and wday */ - time->tm_hour += 24; - time->tm_mday--; - time->tm_yday--; - if (time->tm_mday < 1) { - time->tm_month--; - if (time->tm_month < 0) { - time->tm_month = 11; - time->tm_year--; - if (IsLeapYear(time->tm_year)) - time->tm_yday = 365; - else - time->tm_yday = 364; - } - time->tm_mday = nDays[IsLeapYear(time->tm_year)][time->tm_month]; - } - time->tm_wday--; - if (time->tm_wday < 0) - time->tm_wday = 6; - } else if (time->tm_hour > 23) { - /* Increment mday, yday, and wday */ - time->tm_hour -= 24; - time->tm_mday++; - time->tm_yday++; - if (time->tm_mday > - nDays[IsLeapYear(time->tm_year)][time->tm_month]) { - time->tm_mday = 1; - time->tm_month++; - if (time->tm_month > 11) { - time->tm_month = 0; - time->tm_year++; - time->tm_yday = 0; - } - } - time->tm_wday++; - if (time->tm_wday > 6) - time->tm_wday = 0; - } -} - -PR_IMPLEMENT(void) -PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params) -{ - int daysInMonth; - PRInt32 numDays; - - /* Get back to GMT */ - time->tm_sec -= time->tm_params.tp_gmt_offset - + time->tm_params.tp_dst_offset; - time->tm_params.tp_gmt_offset = 0; - time->tm_params.tp_dst_offset = 0; - - /* Now normalize GMT */ - - if (time->tm_usec < 0 || time->tm_usec >= 1000000) { - time->tm_sec += time->tm_usec / 1000000; - time->tm_usec %= 1000000; - if (time->tm_usec < 0) { - time->tm_usec += 1000000; - time->tm_sec--; - } - } - - /* Note that we do not count leap seconds in this implementation */ - if (time->tm_sec < 0 || time->tm_sec >= 60) { - time->tm_min += time->tm_sec / 60; - time->tm_sec %= 60; - if (time->tm_sec < 0) { - time->tm_sec += 60; - time->tm_min--; - } - } - - if (time->tm_min < 0 || time->tm_min >= 60) { - time->tm_hour += time->tm_min / 60; - time->tm_min %= 60; - if (time->tm_min < 0) { - time->tm_min += 60; - time->tm_hour--; - } - } - - if (time->tm_hour < 0 || time->tm_hour >= 24) { - time->tm_mday += time->tm_hour / 24; - time->tm_hour %= 24; - if (time->tm_hour < 0) { - time->tm_hour += 24; - time->tm_mday--; - } - } - - /* Normalize month and year before mday */ - if (time->tm_month < 0 || time->tm_month >= 12) { - time->tm_year += time->tm_month / 12; - time->tm_month %= 12; - if (time->tm_month < 0) { - time->tm_month += 12; - time->tm_year--; - } - } - - /* Now that month and year are in proper range, normalize mday */ - - if (time->tm_mday < 1) { - /* mday too small */ - do { - /* the previous month */ - time->tm_month--; - if (time->tm_month < 0) { - time->tm_month = 11; - time->tm_year--; - } - time->tm_mday += nDays[IsLeapYear(time->tm_year)][time->tm_month]; - } while (time->tm_mday < 1); - } else { - daysInMonth = nDays[IsLeapYear(time->tm_year)][time->tm_month]; - while (time->tm_mday > daysInMonth) { - /* mday too large */ - time->tm_mday -= daysInMonth; - time->tm_month++; - if (time->tm_month > 11) { - time->tm_month = 0; - time->tm_year++; - } - daysInMonth = nDays[IsLeapYear(time->tm_year)][time->tm_month]; - } - } - - /* Recompute yday and wday */ - time->tm_yday = time->tm_mday + - lastDayOfMonth[IsLeapYear(time->tm_year)][time->tm_month]; - - numDays = DAYS_BETWEEN_YEARS(1970, time->tm_year) + time->tm_yday; - time->tm_wday = (numDays + 4) % 7; - if (time->tm_wday < 0) { - time->tm_wday += 7; - } - - /* Recompute time parameters */ - - time->tm_params = params(time); - - ApplySecOffset(time, time->tm_params.tp_gmt_offset - + time->tm_params.tp_dst_offset); -} - - -/* - *------------------------------------------------------------------------- - * - * PR_LocalTimeParameters -- - * - * returns the time parameters for the local time zone - * - * The following uses localtime() from the standard C library. - * (time.h) This is our fallback implementation. Unix, PC, and BeOS - * use this version. A platform may have its own machine-dependent - * implementation of this function. - * - *------------------------------------------------------------------------- - */ - -#if defined(HAVE_INT_LOCALTIME_R) - -/* - * In this case we could define the macro as - * #define MT_safe_localtime(timer, result) \ - * (localtime_r(timer, result) == 0 ? result : NULL) - * I chose to compare the return value of localtime_r with -1 so - * that I can catch the cases where localtime_r returns a pointer - * to struct tm. The macro definition above would not be able to - * detect such mistakes because it is legal to compare a pointer - * with 0. - */ - -#define MT_safe_localtime(timer, result) \ - (localtime_r(timer, result) == -1 ? NULL: result) - -#elif defined(HAVE_POINTER_LOCALTIME_R) - -#define MT_safe_localtime localtime_r - -#else - -#define HAVE_LOCALTIME_MONITOR 1 /* We use 'monitor' to serialize our calls - * to localtime(). */ -static PRLock *monitor = NULL; - -static struct tm *MT_safe_localtime(const time_t *clock, struct tm *result) -{ - struct tm *tmPtr; - int needLock = PR_Initialized(); /* We need to use a lock to protect - * against NSPR threads only when the - * NSPR thread system is activated. */ - - if (needLock) PR_Lock(monitor); - - /* - * Microsoft (all flavors) localtime() returns a NULL pointer if 'clock' - * represents a time before midnight January 1, 1970. In - * that case, we also return a NULL pointer and the struct tm - * object pointed to by 'result' is not modified. - * - * Watcom C/C++ 11.0 localtime() treats time_t as unsigned long - * hence, does not recognize negative values of clock as pre-1/1/70. - * We have to manually check (WIN16 only) for negative value of - * clock and return NULL. - * - * With negative values of clock, OS/2 returns the struct tm for - * clock plus ULONG_MAX. So we also have to check for the invalid - * structs returned for timezones west of Greenwich when clock == 0. - */ - - tmPtr = localtime(clock); - -#if defined(WIN16) || defined(XP_OS2) - if ( (PRInt32) *clock < 0 || - ( (PRInt32) *clock == 0 && tmPtr->tm_year != 70)) - result = NULL; - else - *result = *tmPtr; -#else - if (tmPtr) { - *result = *tmPtr; - } else { - result = NULL; - } -#endif /* WIN16 */ - - if (needLock) PR_Unlock(monitor); - - return result; -} - -#endif /* definition of MT_safe_localtime() */ - -void _PR_InitTime(void) -{ -#ifdef HAVE_LOCALTIME_MONITOR - monitor = PR_NewLock(); -#endif -#ifdef WINCE - _MD_InitTime(); -#endif -} - -void _PR_CleanupTime(void) -{ -#ifdef HAVE_LOCALTIME_MONITOR - if (monitor) { - PR_DestroyLock(monitor); - monitor = NULL; - } -#endif -#ifdef WINCE - _MD_CleanupTime(); -#endif -} - -#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS) - -PR_IMPLEMENT(PRTimeParameters) -PR_LocalTimeParameters(const PRExplodedTime *gmt) -{ - - PRTimeParameters retVal; - struct tm localTime; - time_t secs; - PRTime secs64; - PRInt64 usecPerSec; - PRInt64 usecPerSec_1; - PRInt64 maxInt32; - PRInt64 minInt32; - PRInt32 dayOffset; - PRInt32 offset2Jan1970; - PRInt32 offsetNew; - int isdst2Jan1970; - - /* - * Calculate the GMT offset. First, figure out what is - * 00:00:00 Jan. 2, 1970 GMT (which is exactly a day, or 86400 - * seconds, since the epoch) in local time. Then we calculate - * the difference between local time and GMT in seconds: - * gmt_offset = local_time - GMT - * - * Caveat: the validity of this calculation depends on two - * assumptions: - * 1. Daylight saving time was not in effect on Jan. 2, 1970. - * 2. The time zone of the geographic location has not changed - * since Jan. 2, 1970. - */ - - secs = 86400L; - (void) MT_safe_localtime(&secs, &localTime); - - /* GMT is 00:00:00, 2nd of Jan. */ - - offset2Jan1970 = (PRInt32)localTime.tm_sec - + 60L * (PRInt32)localTime.tm_min - + 3600L * (PRInt32)localTime.tm_hour - + 86400L * (PRInt32)((PRInt32)localTime.tm_mday - 2L); - - isdst2Jan1970 = localTime.tm_isdst; - - /* - * Now compute DST offset. We calculate the overall offset - * of local time from GMT, similar to above. The overall - * offset has two components: gmt offset and dst offset. - * We subtract gmt offset from the overall offset to get - * the dst offset. - * overall_offset = local_time - GMT - * overall_offset = gmt_offset + dst_offset - * ==> dst_offset = local_time - GMT - gmt_offset - */ - - secs64 = PR_ImplodeTime(gmt); /* This is still in microseconds */ - LL_I2L(usecPerSec, PR_USEC_PER_SEC); - LL_I2L(usecPerSec_1, PR_USEC_PER_SEC - 1); - /* Convert to seconds, truncating down (3.1 -> 3 and -3.1 -> -4) */ - if (LL_GE_ZERO(secs64)) { - LL_DIV(secs64, secs64, usecPerSec); - } else { - LL_NEG(secs64, secs64); - LL_ADD(secs64, secs64, usecPerSec_1); - LL_DIV(secs64, secs64, usecPerSec); - LL_NEG(secs64, secs64); - } - LL_I2L(maxInt32, PR_INT32_MAX); - LL_I2L(minInt32, PR_INT32_MIN); - if (LL_CMP(secs64, >, maxInt32) || LL_CMP(secs64, <, minInt32)) { - /* secs64 is too large or too small for time_t (32-bit integer) */ - retVal.tp_gmt_offset = offset2Jan1970; - retVal.tp_dst_offset = 0; - return retVal; - } - LL_L2I(secs, secs64); - - /* - * On Windows, localtime() (and our MT_safe_localtime() too) - * returns a NULL pointer for time before midnight January 1, - * 1970 GMT. In that case, we just use the GMT offset for - * Jan 2, 1970 and assume that DST was not in effect. - */ - - if (MT_safe_localtime(&secs, &localTime) == NULL) { - retVal.tp_gmt_offset = offset2Jan1970; - retVal.tp_dst_offset = 0; - return retVal; - } - - /* - * dayOffset is the offset between local time and GMT in - * the day component, which can only be -1, 0, or 1. We - * use the day of the week to compute dayOffset. - */ - - dayOffset = (PRInt32) localTime.tm_wday - gmt->tm_wday; - - /* - * Need to adjust for wrapping around of day of the week from - * 6 back to 0. - */ - - if (dayOffset == -6) { - /* Local time is Sunday (0) and GMT is Saturday (6) */ - dayOffset = 1; - } else if (dayOffset == 6) { - /* Local time is Saturday (6) and GMT is Sunday (0) */ - dayOffset = -1; - } - - offsetNew = (PRInt32)localTime.tm_sec - gmt->tm_sec - + 60L * ((PRInt32)localTime.tm_min - gmt->tm_min) - + 3600L * ((PRInt32)localTime.tm_hour - gmt->tm_hour) - + 86400L * (PRInt32)dayOffset; - - if (localTime.tm_isdst <= 0) { - /* DST is not in effect */ - retVal.tp_gmt_offset = offsetNew; - retVal.tp_dst_offset = 0; - } else { - /* DST is in effect */ - if (isdst2Jan1970 <=0) { - /* - * DST was not in effect back in 2 Jan. 1970. - * Use the offset back then as the GMT offset, - * assuming the time zone has not changed since then. - */ - retVal.tp_gmt_offset = offset2Jan1970; - retVal.tp_dst_offset = offsetNew - offset2Jan1970; - } else { - /* - * DST was also in effect back in 2 Jan. 1970. - * Then our clever trick (or rather, ugly hack) fails. - * We will just assume DST offset is an hour. - */ - retVal.tp_gmt_offset = offsetNew - 3600; - retVal.tp_dst_offset = 3600; - } - } - - return retVal; -} - -#endif /* defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS) */ - -/* - *------------------------------------------------------------------------ - * - * PR_USPacificTimeParameters -- - * - * The time parameters function for the US Pacific Time Zone. - * - *------------------------------------------------------------------------ - */ - -/* - * Returns the mday of the first sunday of the month, where - * mday and wday are for a given day in the month. - * mdays start with 1 (e.g. 1..31). - * wdays start with 0 and are in the range 0..6. 0 = Sunday. - */ -#define firstSunday(mday, wday) (((mday - wday + 7 - 1) % 7) + 1) - -/* - * Returns the mday for the N'th Sunday of the month, where - * mday and wday are for a given day in the month. - * mdays start with 1 (e.g. 1..31). - * wdays start with 0 and are in the range 0..6. 0 = Sunday. - * N has the following values: 0 = first, 1 = second (etc), -1 = last. - * ndays is the number of days in that month, the same value as the - * mday of the last day of the month. - */ -static PRInt32 -NthSunday(PRInt32 mday, PRInt32 wday, PRInt32 N, PRInt32 ndays) -{ - PRInt32 firstSun = firstSunday(mday, wday); - - if (N < 0) - N = (ndays - firstSun) / 7; - return firstSun + (7 * N); -} - -typedef struct DSTParams { - PRInt8 dst_start_month; /* 0 = January */ - PRInt8 dst_start_Nth_Sunday; /* N as defined above */ - PRInt8 dst_start_month_ndays; /* ndays as defined above */ - PRInt8 dst_end_month; /* 0 = January */ - PRInt8 dst_end_Nth_Sunday; /* N as defined above */ - PRInt8 dst_end_month_ndays; /* ndays as defined above */ -} DSTParams; - -static const DSTParams dstParams[2] = { - /* year < 2007: First April Sunday - Last October Sunday */ - { 3, 0, 30, 9, -1, 31 }, - /* year >= 2007: Second March Sunday - First November Sunday */ - { 2, 1, 31, 10, 0, 30 } -}; - -PR_IMPLEMENT(PRTimeParameters) -PR_USPacificTimeParameters(const PRExplodedTime *gmt) -{ - const DSTParams *dst; - PRTimeParameters retVal; - PRExplodedTime st; - - /* - * Based on geographic location and GMT, figure out offset of - * standard time from GMT. In this example implementation, we - * assume the local time zone is US Pacific Time. - */ - - retVal.tp_gmt_offset = -8L * 3600L; - - /* - * Make a copy of GMT. Note that the tm_params field of this copy - * is ignored. - */ - - st.tm_usec = gmt->tm_usec; - st.tm_sec = gmt->tm_sec; - st.tm_min = gmt->tm_min; - st.tm_hour = gmt->tm_hour; - st.tm_mday = gmt->tm_mday; - st.tm_month = gmt->tm_month; - st.tm_year = gmt->tm_year; - st.tm_wday = gmt->tm_wday; - st.tm_yday = gmt->tm_yday; - - /* Apply the offset to GMT to obtain the local standard time */ - ApplySecOffset(&st, retVal.tp_gmt_offset); - - if (st.tm_year < 2007) { /* first April Sunday - Last October Sunday */ - dst = &dstParams[0]; - } else { /* Second March Sunday - First November Sunday */ - dst = &dstParams[1]; - } - - /* - * Apply the rules on standard time or GMT to obtain daylight saving - * time offset. In this implementation, we use the US DST rule. - */ - if (st.tm_month < dst->dst_start_month) { - retVal.tp_dst_offset = 0L; - } else if (st.tm_month == dst->dst_start_month) { - int NthSun = NthSunday(st.tm_mday, st.tm_wday, - dst->dst_start_Nth_Sunday, - dst->dst_start_month_ndays); - if (st.tm_mday < NthSun) { /* Before starting Sunday */ - retVal.tp_dst_offset = 0L; - } else if (st.tm_mday == NthSun) { /* Starting Sunday */ - /* 01:59:59 PST -> 03:00:00 PDT */ - if (st.tm_hour < 2) { - retVal.tp_dst_offset = 0L; - } else { - retVal.tp_dst_offset = 3600L; - } - } else { /* After starting Sunday */ - retVal.tp_dst_offset = 3600L; - } - } else if (st.tm_month < dst->dst_end_month) { - retVal.tp_dst_offset = 3600L; - } else if (st.tm_month == dst->dst_end_month) { - int NthSun = NthSunday(st.tm_mday, st.tm_wday, - dst->dst_end_Nth_Sunday, - dst->dst_end_month_ndays); - if (st.tm_mday < NthSun) { /* Before ending Sunday */ - retVal.tp_dst_offset = 3600L; - } else if (st.tm_mday == NthSun) { /* Ending Sunday */ - /* 01:59:59 PDT -> 01:00:00 PST */ - if (st.tm_hour < 1) { - retVal.tp_dst_offset = 3600L; - } else { - retVal.tp_dst_offset = 0L; - } - } else { /* After ending Sunday */ - retVal.tp_dst_offset = 0L; - } - } else { - retVal.tp_dst_offset = 0L; - } - return retVal; -} - -/* - *------------------------------------------------------------------------ - * - * PR_GMTParameters -- - * - * Returns the PRTimeParameters for Greenwich Mean Time. - * Trivially, both the tp_gmt_offset and tp_dst_offset fields are 0. - * - *------------------------------------------------------------------------ - */ - -PR_IMPLEMENT(PRTimeParameters) -PR_GMTParameters(const PRExplodedTime *gmt) -{ - PRTimeParameters retVal = { 0, 0 }; - return retVal; -} - -/* - * The following code implements PR_ParseTimeString(). It is based on - * ns/lib/xp/xp_time.c, revision 1.25, by Jamie Zawinski . - */ - -/* - * We only recognize the abbreviations of a small subset of time zones - * in North America, Europe, and Japan. - * - * PST/PDT: Pacific Standard/Daylight Time - * MST/MDT: Mountain Standard/Daylight Time - * CST/CDT: Central Standard/Daylight Time - * EST/EDT: Eastern Standard/Daylight Time - * AST: Atlantic Standard Time - * NST: Newfoundland Standard Time - * GMT: Greenwich Mean Time - * BST: British Summer Time - * MET: Middle Europe Time - * EET: Eastern Europe Time - * JST: Japan Standard Time - */ - -typedef enum -{ - TT_UNKNOWN, - - TT_SUN, TT_MON, TT_TUE, TT_WED, TT_THU, TT_FRI, TT_SAT, - - TT_JAN, TT_FEB, TT_MAR, TT_APR, TT_MAY, TT_JUN, - TT_JUL, TT_AUG, TT_SEP, TT_OCT, TT_NOV, TT_DEC, - - TT_PST, TT_PDT, TT_MST, TT_MDT, TT_CST, TT_CDT, TT_EST, TT_EDT, - TT_AST, TT_NST, TT_GMT, TT_BST, TT_MET, TT_EET, TT_JST -} TIME_TOKEN; - -/* - * This parses a time/date string into a PRTime - * (microseconds after "1-Jan-1970 00:00:00 GMT"). - * It returns PR_SUCCESS on success, and PR_FAILURE - * if the time/date string can't be parsed. - * - * Many formats are handled, including: - * - * 14 Apr 89 03:20:12 - * 14 Apr 89 03:20 GMT - * Fri, 17 Mar 89 4:01:33 - * Fri, 17 Mar 89 4:01 GMT - * Mon Jan 16 16:12 PDT 1989 - * Mon Jan 16 16:12 +0130 1989 - * 6 May 1992 16:41-JST (Wednesday) - * 22-AUG-1993 10:59:12.82 - * 22-AUG-1993 10:59pm - * 22-AUG-1993 12:59am - * 22-AUG-1993 12:59 PM - * Friday, August 04, 1995 3:54 PM - * 06/21/95 04:24:34 PM - * 20/06/95 21:07 - * 95-06-08 19:32:48 EDT - * - * If the input string doesn't contain a description of the timezone, - * we consult the `default_to_gmt' to decide whether the string should - * be interpreted relative to the local time zone (PR_FALSE) or GMT (PR_TRUE). - * The correct value for this argument depends on what standard specified - * the time string which you are parsing. - */ - -PR_IMPLEMENT(PRStatus) -PR_ParseTimeStringToExplodedTime( - const char *string, - PRBool default_to_gmt, - PRExplodedTime *result) -{ - TIME_TOKEN dotw = TT_UNKNOWN; - TIME_TOKEN month = TT_UNKNOWN; - TIME_TOKEN zone = TT_UNKNOWN; - int zone_offset = -1; - int dst_offset = 0; - int date = -1; - PRInt32 year = -1; - int hour = -1; - int min = -1; - int sec = -1; - - const char *rest = string; - - int iterations = 0; - - PR_ASSERT(string && result); - if (!string || !result) return PR_FAILURE; - - while (*rest) - { - - if (iterations++ > 1000) - { - return PR_FAILURE; - } - - switch (*rest) - { - case 'a': case 'A': - if (month == TT_UNKNOWN && - (rest[1] == 'p' || rest[1] == 'P') && - (rest[2] == 'r' || rest[2] == 'R')) - month = TT_APR; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_AST; - else if (month == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'g' || rest[2] == 'G')) - month = TT_AUG; - break; - case 'b': case 'B': - if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_BST; - break; - case 'c': case 'C': - if (zone == TT_UNKNOWN && - (rest[1] == 'd' || rest[1] == 'D') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_CDT; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_CST; - break; - case 'd': case 'D': - if (month == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 'c' || rest[2] == 'C')) - month = TT_DEC; - break; - case 'e': case 'E': - if (zone == TT_UNKNOWN && - (rest[1] == 'd' || rest[1] == 'D') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_EDT; - else if (zone == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_EET; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_EST; - break; - case 'f': case 'F': - if (month == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 'b' || rest[2] == 'B')) - month = TT_FEB; - else if (dotw == TT_UNKNOWN && - (rest[1] == 'r' || rest[1] == 'R') && - (rest[2] == 'i' || rest[2] == 'I')) - dotw = TT_FRI; - break; - case 'g': case 'G': - if (zone == TT_UNKNOWN && - (rest[1] == 'm' || rest[1] == 'M') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_GMT; - break; - case 'j': case 'J': - if (month == TT_UNKNOWN && - (rest[1] == 'a' || rest[1] == 'A') && - (rest[2] == 'n' || rest[2] == 'N')) - month = TT_JAN; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_JST; - else if (month == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'l' || rest[2] == 'L')) - month = TT_JUL; - else if (month == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'n' || rest[2] == 'N')) - month = TT_JUN; - break; - case 'm': case 'M': - if (month == TT_UNKNOWN && - (rest[1] == 'a' || rest[1] == 'A') && - (rest[2] == 'r' || rest[2] == 'R')) - month = TT_MAR; - else if (month == TT_UNKNOWN && - (rest[1] == 'a' || rest[1] == 'A') && - (rest[2] == 'y' || rest[2] == 'Y')) - month = TT_MAY; - else if (zone == TT_UNKNOWN && - (rest[1] == 'd' || rest[1] == 'D') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_MDT; - else if (zone == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_MET; - else if (dotw == TT_UNKNOWN && - (rest[1] == 'o' || rest[1] == 'O') && - (rest[2] == 'n' || rest[2] == 'N')) - dotw = TT_MON; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_MST; - break; - case 'n': case 'N': - if (month == TT_UNKNOWN && - (rest[1] == 'o' || rest[1] == 'O') && - (rest[2] == 'v' || rest[2] == 'V')) - month = TT_NOV; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_NST; - break; - case 'o': case 'O': - if (month == TT_UNKNOWN && - (rest[1] == 'c' || rest[1] == 'C') && - (rest[2] == 't' || rest[2] == 'T')) - month = TT_OCT; - break; - case 'p': case 'P': - if (zone == TT_UNKNOWN && - (rest[1] == 'd' || rest[1] == 'D') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_PDT; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_PST; - break; - case 's': case 'S': - if (dotw == TT_UNKNOWN && - (rest[1] == 'a' || rest[1] == 'A') && - (rest[2] == 't' || rest[2] == 'T')) - dotw = TT_SAT; - else if (month == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 'p' || rest[2] == 'P')) - month = TT_SEP; - else if (dotw == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'n' || rest[2] == 'N')) - dotw = TT_SUN; - break; - case 't': case 'T': - if (dotw == TT_UNKNOWN && - (rest[1] == 'h' || rest[1] == 'H') && - (rest[2] == 'u' || rest[2] == 'U')) - dotw = TT_THU; - else if (dotw == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'e' || rest[2] == 'E')) - dotw = TT_TUE; - break; - case 'u': case 'U': - if (zone == TT_UNKNOWN && - (rest[1] == 't' || rest[1] == 'T') && - !(rest[2] >= 'A' && rest[2] <= 'Z') && - !(rest[2] >= 'a' && rest[2] <= 'z')) - /* UT is the same as GMT but UTx is not. */ - zone = TT_GMT; - break; - case 'w': case 'W': - if (dotw == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 'd' || rest[2] == 'D')) - dotw = TT_WED; - break; - - case '+': case '-': - { - const char *end; - int sign; - if (zone_offset != -1) - { - /* already got one... */ - rest++; - break; - } - if (zone != TT_UNKNOWN && zone != TT_GMT) - { - /* GMT+0300 is legal, but PST+0300 is not. */ - rest++; - break; - } - - sign = ((*rest == '+') ? 1 : -1); - rest++; /* move over sign */ - end = rest; - while (*end >= '0' && *end <= '9') - end++; - if (rest == end) /* no digits here */ - break; - - if ((end - rest) == 4) - /* offset in HHMM */ - zone_offset = (((((rest[0]-'0')*10) + (rest[1]-'0')) * 60) + - (((rest[2]-'0')*10) + (rest[3]-'0'))); - else if ((end - rest) == 2) - /* offset in hours */ - zone_offset = (((rest[0]-'0')*10) + (rest[1]-'0')) * 60; - else if ((end - rest) == 1) - /* offset in hours */ - zone_offset = (rest[0]-'0') * 60; - else - /* 3 or >4 */ - break; - - zone_offset *= sign; - zone = TT_GMT; - break; - } - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - int tmp_hour = -1; - int tmp_min = -1; - int tmp_sec = -1; - const char *end = rest + 1; - while (*end >= '0' && *end <= '9') - end++; - - /* end is now the first character after a range of digits. */ - - if (*end == ':') - { - if (hour >= 0 && min >= 0) /* already got it */ - break; - - /* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */ - if ((end - rest) > 2) - /* it is [0-9][0-9][0-9]+: */ - break; - else if ((end - rest) == 2) - tmp_hour = ((rest[0]-'0')*10 + - (rest[1]-'0')); - else - tmp_hour = (rest[0]-'0'); - - /* move over the colon, and parse minutes */ - - rest = ++end; - while (*end >= '0' && *end <= '9') - end++; - - if (end == rest) - /* no digits after first colon? */ - break; - else if ((end - rest) > 2) - /* it is [0-9][0-9][0-9]+: */ - break; - else if ((end - rest) == 2) - tmp_min = ((rest[0]-'0')*10 + - (rest[1]-'0')); - else - tmp_min = (rest[0]-'0'); - - /* now go for seconds */ - rest = end; - if (*rest == ':') - rest++; - end = rest; - while (*end >= '0' && *end <= '9') - end++; - - if (end == rest) - /* no digits after second colon - that's ok. */ - ; - else if ((end - rest) > 2) - /* it is [0-9][0-9][0-9]+: */ - break; - else if ((end - rest) == 2) - tmp_sec = ((rest[0]-'0')*10 + - (rest[1]-'0')); - else - tmp_sec = (rest[0]-'0'); - - /* If we made it here, we've parsed hour and min, - and possibly sec, so it worked as a unit. */ - - /* skip over whitespace and see if there's an AM or PM - directly following the time. - */ - if (tmp_hour <= 12) - { - const char *s = end; - while (*s && (*s == ' ' || *s == '\t')) - s++; - if ((s[0] == 'p' || s[0] == 'P') && - (s[1] == 'm' || s[1] == 'M')) - /* 10:05pm == 22:05, and 12:05pm == 12:05 */ - tmp_hour = (tmp_hour == 12 ? 12 : tmp_hour + 12); - else if (tmp_hour == 12 && - (s[0] == 'a' || s[0] == 'A') && - (s[1] == 'm' || s[1] == 'M')) - /* 12:05am == 00:05 */ - tmp_hour = 0; - } - - hour = tmp_hour; - min = tmp_min; - sec = tmp_sec; - rest = end; - break; - } - else if ((*end == '/' || *end == '-') && - end[1] >= '0' && end[1] <= '9') - { - /* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95 - or even 95-06-05... - #### But it doesn't handle 1995-06-22. - */ - int n1, n2, n3; - const char *s; - - if (month != TT_UNKNOWN) - /* if we saw a month name, this can't be. */ - break; - - s = rest; - - n1 = (*s++ - '0'); /* first 1 or 2 digits */ - if (*s >= '0' && *s <= '9') - n1 = n1*10 + (*s++ - '0'); - - if (*s != '/' && *s != '-') /* slash */ - break; - s++; - - if (*s < '0' || *s > '9') /* second 1 or 2 digits */ - break; - n2 = (*s++ - '0'); - if (*s >= '0' && *s <= '9') - n2 = n2*10 + (*s++ - '0'); - - if (*s != '/' && *s != '-') /* slash */ - break; - s++; - - if (*s < '0' || *s > '9') /* third 1, 2, 4, or 5 digits */ - break; - n3 = (*s++ - '0'); - if (*s >= '0' && *s <= '9') - n3 = n3*10 + (*s++ - '0'); - - if (*s >= '0' && *s <= '9') /* optional digits 3, 4, and 5 */ - { - n3 = n3*10 + (*s++ - '0'); - if (*s < '0' || *s > '9') - break; - n3 = n3*10 + (*s++ - '0'); - if (*s >= '0' && *s <= '9') - n3 = n3*10 + (*s++ - '0'); - } - - if ((*s >= '0' && *s <= '9') || /* followed by non-alphanum */ - (*s >= 'A' && *s <= 'Z') || - (*s >= 'a' && *s <= 'z')) - break; - - /* Ok, we parsed three 1-2 digit numbers, with / or - - between them. Now decide what the hell they are - (DD/MM/YY or MM/DD/YY or YY/MM/DD.) - */ - - if (n1 > 31 || n1 == 0) /* must be YY/MM/DD */ - { - if (n2 > 12) break; - if (n3 > 31) break; - year = n1; - if (year < 70) - year += 2000; - else if (year < 100) - year += 1900; - month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1); - date = n3; - rest = s; - break; - } - - if (n1 > 12 && n2 > 12) /* illegal */ - { - rest = s; - break; - } - - if (n3 < 70) - n3 += 2000; - else if (n3 < 100) - n3 += 1900; - - if (n1 > 12) /* must be DD/MM/YY */ - { - date = n1; - month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1); - year = n3; - } - else /* assume MM/DD/YY */ - { - /* #### In the ambiguous case, should we consult the - locale to find out the local default? */ - month = (TIME_TOKEN)(n1 + ((int)TT_JAN) - 1); - date = n2; - year = n3; - } - rest = s; - } - else if ((*end >= 'A' && *end <= 'Z') || - (*end >= 'a' && *end <= 'z')) - /* Digits followed by non-punctuation - what's that? */ - ; - else if ((end - rest) == 5) /* five digits is a year */ - year = (year < 0 - ? ((rest[0]-'0')*10000L + - (rest[1]-'0')*1000L + - (rest[2]-'0')*100L + - (rest[3]-'0')*10L + - (rest[4]-'0')) - : year); - else if ((end - rest) == 4) /* four digits is a year */ - year = (year < 0 - ? ((rest[0]-'0')*1000L + - (rest[1]-'0')*100L + - (rest[2]-'0')*10L + - (rest[3]-'0')) - : year); - else if ((end - rest) == 2) /* two digits - date or year */ - { - int n = ((rest[0]-'0')*10 + - (rest[1]-'0')); - /* If we don't have a date (day of the month) and we see a number - less than 32, then assume that is the date. - - Otherwise, if we have a date and not a year, assume this is the - year. If it is less than 70, then assume it refers to the 21st - century. If it is two digits (>= 70), assume it refers to this - century. Otherwise, assume it refers to an unambiguous year. - - The world will surely end soon. - */ - if (date < 0 && n < 32) - date = n; - else if (year < 0) - { - if (n < 70) - year = 2000 + n; - else if (n < 100) - year = 1900 + n; - else - year = n; - } - /* else what the hell is this. */ - } - else if ((end - rest) == 1) /* one digit - date */ - date = (date < 0 ? (rest[0]-'0') : date); - /* else, three or more than five digits - what's that? */ - - break; - } - } - - /* Skip to the end of this token, whether we parsed it or not. - Tokens are delimited by whitespace, or ,;-/ - But explicitly not :+-. - */ - while (*rest && - *rest != ' ' && *rest != '\t' && - *rest != ',' && *rest != ';' && - *rest != '-' && *rest != '+' && - *rest != '/' && - *rest != '(' && *rest != ')' && *rest != '[' && *rest != ']') - rest++; - /* skip over uninteresting chars. */ - SKIP_MORE: - while (*rest && - (*rest == ' ' || *rest == '\t' || - *rest == ',' || *rest == ';' || *rest == '/' || - *rest == '(' || *rest == ')' || *rest == '[' || *rest == ']')) - rest++; - - /* "-" is ignored at the beginning of a token if we have not yet - parsed a year (e.g., the second "-" in "30-AUG-1966"), or if - the character after the dash is not a digit. */ - if (*rest == '-' && ((rest > string && - isalpha((unsigned char)rest[-1]) && year < 0) || - rest[1] < '0' || rest[1] > '9')) - { - rest++; - goto SKIP_MORE; - } - - } - - if (zone != TT_UNKNOWN && zone_offset == -1) - { - switch (zone) - { - case TT_PST: zone_offset = -8 * 60; break; - case TT_PDT: zone_offset = -8 * 60; dst_offset = 1 * 60; break; - case TT_MST: zone_offset = -7 * 60; break; - case TT_MDT: zone_offset = -7 * 60; dst_offset = 1 * 60; break; - case TT_CST: zone_offset = -6 * 60; break; - case TT_CDT: zone_offset = -6 * 60; dst_offset = 1 * 60; break; - case TT_EST: zone_offset = -5 * 60; break; - case TT_EDT: zone_offset = -5 * 60; dst_offset = 1 * 60; break; - case TT_AST: zone_offset = -4 * 60; break; - case TT_NST: zone_offset = -3 * 60 - 30; break; - case TT_GMT: zone_offset = 0 * 60; break; - case TT_BST: zone_offset = 0 * 60; dst_offset = 1 * 60; break; - case TT_MET: zone_offset = 1 * 60; break; - case TT_EET: zone_offset = 2 * 60; break; - case TT_JST: zone_offset = 9 * 60; break; - default: - PR_ASSERT (0); - break; - } - } - - /* If we didn't find a year, month, or day-of-the-month, we can't - possibly parse this, and in fact, mktime() will do something random - (I'm seeing it return "Tue Feb 5 06:28:16 2036", which is no doubt - a numerologically significant date... */ - if (month == TT_UNKNOWN || date == -1 || year == -1 || year > PR_INT16_MAX) - return PR_FAILURE; - - memset(result, 0, sizeof(*result)); - if (sec != -1) - result->tm_sec = sec; - if (min != -1) - result->tm_min = min; - if (hour != -1) - result->tm_hour = hour; - if (date != -1) - result->tm_mday = date; - if (month != TT_UNKNOWN) - result->tm_month = (((int)month) - ((int)TT_JAN)); - if (year != -1) - result->tm_year = year; - if (dotw != TT_UNKNOWN) - result->tm_wday = (((int)dotw) - ((int)TT_SUN)); - /* - * Mainly to compute wday and yday, but normalized time is also required - * by the check below that works around a Visual C++ 2005 mktime problem. - */ - PR_NormalizeTime(result, PR_GMTParameters); - /* The remaining work is to set the gmt and dst offsets in tm_params. */ - - if (zone == TT_UNKNOWN && default_to_gmt) - { - /* No zone was specified, so pretend the zone was GMT. */ - zone = TT_GMT; - zone_offset = 0; - } - - if (zone_offset == -1) - { - /* no zone was specified, and we're to assume that everything - is local. */ - struct tm localTime; - time_t secs; - - PR_ASSERT(result->tm_month > -1 && - result->tm_mday > 0 && - result->tm_hour > -1 && - result->tm_min > -1 && - result->tm_sec > -1); - - /* - * To obtain time_t from a tm structure representing the local - * time, we call mktime(). However, we need to see if we are - * on 1-Jan-1970 or before. If we are, we can't call mktime() - * because mktime() will crash on win16. In that case, we - * calculate zone_offset based on the zone offset at - * 00:00:00, 2 Jan 1970 GMT, and subtract zone_offset from the - * date we are parsing to transform the date to GMT. We also - * do so if mktime() returns (time_t) -1 (time out of range). - */ - - /* month, day, hours, mins and secs are always non-negative - so we dont need to worry about them. */ - if(result->tm_year >= 1970) - { - PRInt64 usec_per_sec; - - localTime.tm_sec = result->tm_sec; - localTime.tm_min = result->tm_min; - localTime.tm_hour = result->tm_hour; - localTime.tm_mday = result->tm_mday; - localTime.tm_mon = result->tm_month; - localTime.tm_year = result->tm_year - 1900; - /* Set this to -1 to tell mktime "I don't care". If you set - it to 0 or 1, you are making assertions about whether the - date you are handing it is in daylight savings mode or not; - and if you're wrong, it will "fix" it for you. */ - localTime.tm_isdst = -1; - -#if _MSC_VER == 1400 /* 1400 = Visual C++ 2005 (8.0) */ - /* - * mktime will return (time_t) -1 if the input is a date - * after 23:59:59, December 31, 3000, US Pacific Time (not - * UTC as documented): - * http://msdn.microsoft.com/en-us/library/d1y53h2a(VS.80).aspx - * But if the year is 3001, mktime also invokes the invalid - * parameter handler, causing the application to crash. This - * problem has been reported in - * http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=266036. - * We avoid this crash by not calling mktime if the date is - * out of range. To use a simple test that works in any time - * zone, we consider year 3000 out of range as well. (See - * bug 480740.) - */ - if (result->tm_year >= 3000) { - /* Emulate what mktime would have done. */ - errno = EINVAL; - secs = (time_t) -1; - } else { - secs = mktime(&localTime); - } -#else - secs = mktime(&localTime); -#endif - if (secs != (time_t) -1) - { - PRTime usecs64; - LL_I2L(usecs64, secs); - LL_I2L(usec_per_sec, PR_USEC_PER_SEC); - LL_MUL(usecs64, usecs64, usec_per_sec); - PR_ExplodeTime(usecs64, PR_LocalTimeParameters, result); - return PR_SUCCESS; - } - } - - /* So mktime() can't handle this case. We assume the - zone_offset for the date we are parsing is the same as - the zone offset on 00:00:00 2 Jan 1970 GMT. */ - secs = 86400; - (void) MT_safe_localtime(&secs, &localTime); - zone_offset = localTime.tm_min - + 60 * localTime.tm_hour - + 1440 * (localTime.tm_mday - 2); - } - - result->tm_params.tp_gmt_offset = zone_offset * 60; - result->tm_params.tp_dst_offset = dst_offset * 60; - - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) -PR_ParseTimeString( - const char *string, - PRBool default_to_gmt, - PRTime *result) -{ - PRExplodedTime tm; - PRStatus rv; - - rv = PR_ParseTimeStringToExplodedTime(string, - default_to_gmt, - &tm); - if (rv != PR_SUCCESS) - return rv; - - *result = PR_ImplodeTime(&tm); - - return PR_SUCCESS; -} - -/* - ******************************************************************* - ******************************************************************* - ** - ** OLD COMPATIBILITY FUNCTIONS - ** - ******************************************************************* - ******************************************************************* - */ - - -/* - *----------------------------------------------------------------------- - * - * PR_FormatTime -- - * - * Format a time value into a buffer. Same semantics as strftime(). - * - *----------------------------------------------------------------------- - */ - -PR_IMPLEMENT(PRUint32) -PR_FormatTime(char *buf, int buflen, const char *fmt, const PRExplodedTime *tm) -{ - size_t rv; - struct tm a; - struct tm *ap; - - if (tm) { - ap = &a; - a.tm_sec = tm->tm_sec; - a.tm_min = tm->tm_min; - a.tm_hour = tm->tm_hour; - a.tm_mday = tm->tm_mday; - a.tm_mon = tm->tm_month; - a.tm_wday = tm->tm_wday; - a.tm_year = tm->tm_year - 1900; - a.tm_yday = tm->tm_yday; - a.tm_isdst = tm->tm_params.tp_dst_offset ? 1 : 0; - - /* - * On some platforms, for example SunOS 4, struct tm has two - * additional fields: tm_zone and tm_gmtoff. - */ - -#if (__GLIBC__ >= 2) || defined(XP_BEOS) \ - || defined(NETBSD) || defined(OPENBSD) || defined(FREEBSD) \ - || defined(DARWIN) || defined(SYMBIAN) || defined(ANDROID) - a.tm_zone = NULL; - a.tm_gmtoff = tm->tm_params.tp_gmt_offset + - tm->tm_params.tp_dst_offset; -#endif - } else { - ap = NULL; - } - - rv = strftime(buf, buflen, fmt, ap); - if (!rv && buf && buflen > 0) { - /* - * When strftime fails, the contents of buf are indeterminate. - * Some callers don't check the return value from this function, - * so store an empty string in buf in case they try to print it. - */ - buf[0] = '\0'; - } - return rv; -} - - -/* - * The following string arrays and macros are used by PR_FormatTimeUSEnglish(). - */ - -static const char* abbrevDays[] = -{ - "Sun","Mon","Tue","Wed","Thu","Fri","Sat" -}; - -static const char* days[] = -{ - "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" -}; - -static const char* abbrevMonths[] = -{ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -static const char* months[] = -{ - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" -}; - - -/* - * Add a single character to the given buffer, incrementing the buffer pointer - * and decrementing the buffer size. Return 0 on error. - */ -#define ADDCHAR( buf, bufSize, ch ) \ -do \ -{ \ - if( bufSize < 1 ) \ - { \ - *(--buf) = '\0'; \ - return 0; \ - } \ - *buf++ = ch; \ - bufSize--; \ -} \ -while(0) - - -/* - * Add a string to the given buffer, incrementing the buffer pointer - * and decrementing the buffer size appropriately. Return 0 on error. - */ -#define ADDSTR( buf, bufSize, str ) \ -do \ -{ \ - PRUint32 strSize = strlen( str ); \ - if( strSize > bufSize ) \ - { \ - if( bufSize==0 ) \ - *(--buf) = '\0'; \ - else \ - *buf = '\0'; \ - return 0; \ - } \ - memcpy(buf, str, strSize); \ - buf += strSize; \ - bufSize -= strSize; \ -} \ -while(0) - -/* Needed by PR_FormatTimeUSEnglish() */ -static unsigned int pr_WeekOfYear(const PRExplodedTime* time, - unsigned int firstDayOfWeek); - - -/*********************************************************************************** - * - * Description: - * This is a dumbed down version of strftime that will format the date in US - * English regardless of the setting of the global locale. This functionality is - * needed to write things like MIME headers which must always be in US English. - * - **********************************************************************************/ - -PR_IMPLEMENT(PRUint32) -PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize, - const char* format, const PRExplodedTime* time ) -{ - char* bufPtr = buf; - const char* fmtPtr; - char tmpBuf[ 40 ]; - const int tmpBufSize = sizeof( tmpBuf ); - - - for( fmtPtr=format; *fmtPtr != '\0'; fmtPtr++ ) - { - if( *fmtPtr != '%' ) - { - ADDCHAR( bufPtr, bufSize, *fmtPtr ); - } - else - { - switch( *(++fmtPtr) ) - { - case '%': - /* escaped '%' character */ - ADDCHAR( bufPtr, bufSize, '%' ); - break; - - case 'a': - /* abbreviated weekday name */ - ADDSTR( bufPtr, bufSize, abbrevDays[ time->tm_wday ] ); - break; - - case 'A': - /* full weekday name */ - ADDSTR( bufPtr, bufSize, days[ time->tm_wday ] ); - break; - - case 'b': - /* abbreviated month name */ - ADDSTR( bufPtr, bufSize, abbrevMonths[ time->tm_month ] ); - break; - - case 'B': - /* full month name */ - ADDSTR(bufPtr, bufSize, months[ time->tm_month ] ); - break; - - case 'c': - /* Date and time. */ - PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%a %b %d %H:%M:%S %Y", time ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'd': - /* day of month ( 01 - 31 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_mday ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'H': - /* hour ( 00 - 23 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_hour ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'I': - /* hour ( 01 - 12 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld", - (time->tm_hour%12) ? time->tm_hour%12 : (PRInt32) 12 ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'j': - /* day number of year ( 001 - 366 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.3d",time->tm_yday + 1); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'm': - /* month number ( 01 - 12 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_month+1); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'M': - /* minute ( 00 - 59 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_min ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'p': - /* locale's equivalent of either AM or PM */ - ADDSTR( bufPtr, bufSize, (time->tm_hour<12)?"AM":"PM" ); - break; - - case 'S': - /* seconds ( 00 - 61 ), allows for leap seconds */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_sec ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'U': - /* week number of year ( 00 - 53 ), Sunday is the first day of week 1 */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 0 ) ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'w': - /* weekday number ( 0 - 6 ), Sunday = 0 */ - PR_snprintf(tmpBuf,tmpBufSize,"%d",time->tm_wday ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'W': - /* Week number of year ( 00 - 53 ), Monday is the first day of week 1 */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 1 ) ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'x': - /* Date representation */ - PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%m/%d/%y", time ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'X': - /* Time representation. */ - PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%H:%M:%S", time ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'y': - /* year within century ( 00 - 99 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2d",time->tm_year % 100 ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'Y': - /* year as ccyy ( for example 1986 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.4d",time->tm_year ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'Z': - /* Time zone name or no characters if no time zone exists. - * Since time zone name is supposed to be independant of locale, we - * defer to PR_FormatTime() for this option. - */ - PR_FormatTime( tmpBuf, tmpBufSize, "%Z", time ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - default: - /* Unknown format. Simply copy format into output buffer. */ - ADDCHAR( bufPtr, bufSize, '%' ); - ADDCHAR( bufPtr, bufSize, *fmtPtr ); - break; - - } - } - } - - ADDCHAR( bufPtr, bufSize, '\0' ); - return (PRUint32)(bufPtr - buf - 1); -} - - - -/*********************************************************************************** - * - * Description: - * Returns the week number of the year (0-53) for the given time. firstDayOfWeek - * is the day on which the week is considered to start (0=Sun, 1=Mon, ...). - * Week 1 starts the first time firstDayOfWeek occurs in the year. In other words, - * a partial week at the start of the year is considered week 0. - * - **********************************************************************************/ - -static unsigned int -pr_WeekOfYear(const PRExplodedTime* time, unsigned int firstDayOfWeek) -{ - int dayOfWeek; - int dayOfYear; - - /* Get the day of the year for the given time then adjust it to represent the - * first day of the week containing the given time. - */ - dayOfWeek = time->tm_wday - firstDayOfWeek; - if (dayOfWeek < 0) - dayOfWeek += 7; - - dayOfYear = time->tm_yday - dayOfWeek; - - - if( dayOfYear <= 0 ) - { - /* If dayOfYear is <= 0, it is in the first partial week of the year. */ - return 0; - } - else - { - /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there - * are any days left over ( dayOfYear % 7 ). Because we are only counting to - * the first day of the week containing the given time, rather than to the - * actual day representing the given time, any days in week 0 will be "absorbed" - * as extra days in the given week. - */ - return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 ); - } -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prtpool.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prtpool.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prtpool.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prtpool.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1187 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" - -/* - * Thread pools - * Thread pools create and manage threads to provide support for - * scheduling jobs onto one or more threads. - * - */ -#ifdef OPT_WINNT -#include -#endif - -/* - * worker thread - */ -typedef struct wthread { - PRCList links; - PRThread *thread; -} wthread; - -/* - * queue of timer jobs - */ -typedef struct timer_jobq { - PRCList list; - PRLock *lock; - PRCondVar *cv; - PRInt32 cnt; - PRCList wthreads; -} timer_jobq; - -/* - * queue of jobs - */ -typedef struct tp_jobq { - PRCList list; - PRInt32 cnt; - PRLock *lock; - PRCondVar *cv; - PRCList wthreads; -#ifdef OPT_WINNT - HANDLE nt_completion_port; -#endif -} tp_jobq; - -/* - * queue of IO jobs - */ -typedef struct io_jobq { - PRCList list; - PRPollDesc *pollfds; - PRInt32 npollfds; - PRJob **polljobs; - PRLock *lock; - PRInt32 cnt; - PRFileDesc *notify_fd; - PRCList wthreads; -} io_jobq; - -/* - * Threadpool - */ -struct PRThreadPool { - PRInt32 init_threads; - PRInt32 max_threads; - PRInt32 current_threads; - PRInt32 idle_threads; - PRUint32 stacksize; - tp_jobq jobq; - io_jobq ioq; - timer_jobq timerq; - PRLock *join_lock; /* used with jobp->join_cv */ - PRCondVar *shutdown_cv; - PRBool shutdown; -}; - -typedef enum io_op_type - { JOB_IO_READ, JOB_IO_WRITE, JOB_IO_CONNECT, JOB_IO_ACCEPT } io_op_type; - -#ifdef OPT_WINNT -typedef struct NT_notifier { - OVERLAPPED overlapped; /* must be first */ - PRJob *jobp; -} NT_notifier; -#endif - -struct PRJob { - PRCList links; /* for linking jobs */ - PRBool on_ioq; /* job on ioq */ - PRBool on_timerq; /* job on timerq */ - PRJobFn job_func; - void *job_arg; - PRCondVar *join_cv; - PRBool join_wait; /* == PR_TRUE, when waiting to join */ - PRCondVar *cancel_cv; /* for cancelling IO jobs */ - PRBool cancel_io; /* for cancelling IO jobs */ - PRThreadPool *tpool; /* back pointer to thread pool */ - PRJobIoDesc *iod; - io_op_type io_op; - PRInt16 io_poll_flags; - PRNetAddr *netaddr; - PRIntervalTime timeout; /* relative value */ - PRIntervalTime absolute; -#ifdef OPT_WINNT - NT_notifier nt_notifier; -#endif -}; - -#define JOB_LINKS_PTR(_qp) \ - ((PRJob *) ((char *) (_qp) - offsetof(PRJob, links))) - -#define WTHREAD_LINKS_PTR(_qp) \ - ((wthread *) ((char *) (_qp) - offsetof(wthread, links))) - -#define JOINABLE_JOB(_jobp) (NULL != (_jobp)->join_cv) - -#define JOIN_NOTIFY(_jobp) \ - PR_BEGIN_MACRO \ - PR_Lock(_jobp->tpool->join_lock); \ - _jobp->join_wait = PR_FALSE; \ - PR_NotifyCondVar(_jobp->join_cv); \ - PR_Unlock(_jobp->tpool->join_lock); \ - PR_END_MACRO - -#define CANCEL_IO_JOB(jobp) \ - PR_BEGIN_MACRO \ - jobp->cancel_io = PR_FALSE; \ - jobp->on_ioq = PR_FALSE; \ - PR_REMOVE_AND_INIT_LINK(&jobp->links); \ - tp->ioq.cnt--; \ - PR_NotifyCondVar(jobp->cancel_cv); \ - PR_END_MACRO - -static void delete_job(PRJob *jobp); -static PRThreadPool * alloc_threadpool(void); -static PRJob * alloc_job(PRBool joinable, PRThreadPool *tp); -static void notify_ioq(PRThreadPool *tp); -static void notify_timerq(PRThreadPool *tp); - -/* - * locks are acquired in the following order - * - * tp->ioq.lock,tp->timerq.lock - * | - * V - * tp->jobq->lock - */ - -/* - * worker thread function - */ -static void wstart(void *arg) -{ -PRThreadPool *tp = (PRThreadPool *) arg; -PRCList *head; - - /* - * execute jobs until shutdown - */ - while (!tp->shutdown) { - PRJob *jobp; -#ifdef OPT_WINNT - BOOL rv; - DWORD unused, shutdown; - LPOVERLAPPED olp; - - PR_Lock(tp->jobq.lock); - tp->idle_threads++; - PR_Unlock(tp->jobq.lock); - rv = GetQueuedCompletionStatus(tp->jobq.nt_completion_port, - &unused, &shutdown, &olp, INFINITE); - - PR_ASSERT(rv); - if (shutdown) - break; - jobp = ((NT_notifier *) olp)->jobp; - PR_Lock(tp->jobq.lock); - tp->idle_threads--; - tp->jobq.cnt--; - PR_Unlock(tp->jobq.lock); -#else - - PR_Lock(tp->jobq.lock); - while (PR_CLIST_IS_EMPTY(&tp->jobq.list) && (!tp->shutdown)) { - tp->idle_threads++; - PR_WaitCondVar(tp->jobq.cv, PR_INTERVAL_NO_TIMEOUT); - tp->idle_threads--; - } - if (tp->shutdown) { - PR_Unlock(tp->jobq.lock); - break; - } - head = PR_LIST_HEAD(&tp->jobq.list); - /* - * remove job from queue - */ - PR_REMOVE_AND_INIT_LINK(head); - tp->jobq.cnt--; - jobp = JOB_LINKS_PTR(head); - PR_Unlock(tp->jobq.lock); -#endif - - jobp->job_func(jobp->job_arg); - if (!JOINABLE_JOB(jobp)) { - delete_job(jobp); - } else { - JOIN_NOTIFY(jobp); - } - } - PR_Lock(tp->jobq.lock); - tp->current_threads--; - PR_Unlock(tp->jobq.lock); -} - -/* - * add a job to the work queue - */ -static void -add_to_jobq(PRThreadPool *tp, PRJob *jobp) -{ - /* - * add to jobq - */ -#ifdef OPT_WINNT - PR_Lock(tp->jobq.lock); - tp->jobq.cnt++; - PR_Unlock(tp->jobq.lock); - /* - * notify worker thread(s) - */ - PostQueuedCompletionStatus(tp->jobq.nt_completion_port, 0, - FALSE, &jobp->nt_notifier.overlapped); -#else - PR_Lock(tp->jobq.lock); - PR_APPEND_LINK(&jobp->links,&tp->jobq.list); - tp->jobq.cnt++; - if ((tp->idle_threads < tp->jobq.cnt) && - (tp->current_threads < tp->max_threads)) { - wthread *wthrp; - /* - * increment thread count and unlock the jobq lock - */ - tp->current_threads++; - PR_Unlock(tp->jobq.lock); - /* create new worker thread */ - wthrp = PR_NEWZAP(wthread); - if (wthrp) { - wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart, - tp, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize); - if (NULL == wthrp->thread) { - PR_DELETE(wthrp); /* this sets wthrp to NULL */ - } - } - PR_Lock(tp->jobq.lock); - if (NULL == wthrp) { - tp->current_threads--; - } else { - PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); - } - } - /* - * wakeup a worker thread - */ - PR_NotifyCondVar(tp->jobq.cv); - PR_Unlock(tp->jobq.lock); -#endif -} - -/* - * io worker thread function - */ -static void io_wstart(void *arg) -{ -PRThreadPool *tp = (PRThreadPool *) arg; -int pollfd_cnt, pollfds_used; -int rv; -PRCList *qp, *nextqp; -PRPollDesc *pollfds; -PRJob **polljobs; -int poll_timeout; -PRIntervalTime now; - - /* - * scan io_jobq - * construct poll list - * call PR_Poll - * for all fds, for which poll returns true, move the job to - * jobq and wakeup worker thread. - */ - while (!tp->shutdown) { - PRJob *jobp; - - pollfd_cnt = tp->ioq.cnt + 10; - if (pollfd_cnt > tp->ioq.npollfds) { - - /* - * re-allocate pollfd array if the current one is not large - * enough - */ - if (NULL != tp->ioq.pollfds) - PR_Free(tp->ioq.pollfds); - tp->ioq.pollfds = (PRPollDesc *) PR_Malloc(pollfd_cnt * - (sizeof(PRPollDesc) + sizeof(PRJob *))); - PR_ASSERT(NULL != tp->ioq.pollfds); - /* - * array of pollfds - */ - pollfds = tp->ioq.pollfds; - tp->ioq.polljobs = (PRJob **) (&tp->ioq.pollfds[pollfd_cnt]); - /* - * parallel array of jobs - */ - polljobs = tp->ioq.polljobs; - tp->ioq.npollfds = pollfd_cnt; - } - - pollfds_used = 0; - /* - * add the notify fd; used for unblocking io thread(s) - */ - pollfds[pollfds_used].fd = tp->ioq.notify_fd; - pollfds[pollfds_used].in_flags = PR_POLL_READ; - pollfds[pollfds_used].out_flags = 0; - polljobs[pollfds_used] = NULL; - pollfds_used++; - /* - * fill in the pollfd array - */ - PR_Lock(tp->ioq.lock); - for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) { - nextqp = qp->next; - jobp = JOB_LINKS_PTR(qp); - if (jobp->cancel_io) { - CANCEL_IO_JOB(jobp); - continue; - } - if (pollfds_used == (pollfd_cnt)) - break; - pollfds[pollfds_used].fd = jobp->iod->socket; - pollfds[pollfds_used].in_flags = jobp->io_poll_flags; - pollfds[pollfds_used].out_flags = 0; - polljobs[pollfds_used] = jobp; - - pollfds_used++; - } - if (!PR_CLIST_IS_EMPTY(&tp->ioq.list)) { - qp = tp->ioq.list.next; - jobp = JOB_LINKS_PTR(qp); - if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout) - poll_timeout = PR_INTERVAL_NO_TIMEOUT; - else if (PR_INTERVAL_NO_WAIT == jobp->timeout) - poll_timeout = PR_INTERVAL_NO_WAIT; - else { - poll_timeout = jobp->absolute - PR_IntervalNow(); - if (poll_timeout <= 0) /* already timed out */ - poll_timeout = PR_INTERVAL_NO_WAIT; - } - } else { - poll_timeout = PR_INTERVAL_NO_TIMEOUT; - } - PR_Unlock(tp->ioq.lock); - - /* - * XXXX - * should retry if more jobs have been added to the queue? - * - */ - PR_ASSERT(pollfds_used <= pollfd_cnt); - rv = PR_Poll(tp->ioq.pollfds, pollfds_used, poll_timeout); - - if (tp->shutdown) { - break; - } - - if (rv > 0) { - /* - * at least one io event is set - */ - PRStatus rval_status; - PRInt32 index; - - PR_ASSERT(pollfds[0].fd == tp->ioq.notify_fd); - /* - * reset the pollable event, if notified - */ - if (pollfds[0].out_flags & PR_POLL_READ) { - rval_status = PR_WaitForPollableEvent(tp->ioq.notify_fd); - PR_ASSERT(PR_SUCCESS == rval_status); - } - - for(index = 1; index < (pollfds_used); index++) { - PRInt16 events = pollfds[index].in_flags; - PRInt16 revents = pollfds[index].out_flags; - jobp = polljobs[index]; - - if ((revents & PR_POLL_NVAL) || /* busted in all cases */ - (revents & PR_POLL_ERR) || - ((events & PR_POLL_WRITE) && - (revents & PR_POLL_HUP))) { /* write op & hup */ - PR_Lock(tp->ioq.lock); - if (jobp->cancel_io) { - CANCEL_IO_JOB(jobp); - PR_Unlock(tp->ioq.lock); - continue; - } - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->ioq.cnt--; - jobp->on_ioq = PR_FALSE; - PR_Unlock(tp->ioq.lock); - - /* set error */ - if (PR_POLL_NVAL & revents) - jobp->iod->error = PR_BAD_DESCRIPTOR_ERROR; - else if (PR_POLL_HUP & revents) - jobp->iod->error = PR_CONNECT_RESET_ERROR; - else - jobp->iod->error = PR_IO_ERROR; - - /* - * add to jobq - */ - add_to_jobq(tp, jobp); - } else if (revents) { - /* - * add to jobq - */ - PR_Lock(tp->ioq.lock); - if (jobp->cancel_io) { - CANCEL_IO_JOB(jobp); - PR_Unlock(tp->ioq.lock); - continue; - } - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->ioq.cnt--; - jobp->on_ioq = PR_FALSE; - PR_Unlock(tp->ioq.lock); - - if (jobp->io_op == JOB_IO_CONNECT) { - if (PR_GetConnectStatus(&pollfds[index]) == PR_SUCCESS) - jobp->iod->error = 0; - else - jobp->iod->error = PR_GetError(); - } else - jobp->iod->error = 0; - - add_to_jobq(tp, jobp); - } - } - } - /* - * timeout processing - */ - now = PR_IntervalNow(); - PR_Lock(tp->ioq.lock); - for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) { - nextqp = qp->next; - jobp = JOB_LINKS_PTR(qp); - if (jobp->cancel_io) { - CANCEL_IO_JOB(jobp); - continue; - } - if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout) - break; - if ((PR_INTERVAL_NO_WAIT != jobp->timeout) && - ((PRInt32)(jobp->absolute - now) > 0)) - break; - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->ioq.cnt--; - jobp->on_ioq = PR_FALSE; - jobp->iod->error = PR_IO_TIMEOUT_ERROR; - add_to_jobq(tp, jobp); - } - PR_Unlock(tp->ioq.lock); - } -} - -/* - * timer worker thread function - */ -static void timer_wstart(void *arg) -{ -PRThreadPool *tp = (PRThreadPool *) arg; -PRCList *qp; -PRIntervalTime timeout; -PRIntervalTime now; - - /* - * call PR_WaitCondVar with minimum value of all timeouts - */ - while (!tp->shutdown) { - PRJob *jobp; - - PR_Lock(tp->timerq.lock); - if (PR_CLIST_IS_EMPTY(&tp->timerq.list)) { - timeout = PR_INTERVAL_NO_TIMEOUT; - } else { - PRCList *qp; - - qp = tp->timerq.list.next; - jobp = JOB_LINKS_PTR(qp); - - timeout = jobp->absolute - PR_IntervalNow(); - if (timeout <= 0) - timeout = PR_INTERVAL_NO_WAIT; /* already timed out */ - } - if (PR_INTERVAL_NO_WAIT != timeout) - PR_WaitCondVar(tp->timerq.cv, timeout); - if (tp->shutdown) { - PR_Unlock(tp->timerq.lock); - break; - } - /* - * move expired-timer jobs to jobq - */ - now = PR_IntervalNow(); - while (!PR_CLIST_IS_EMPTY(&tp->timerq.list)) { - qp = tp->timerq.list.next; - jobp = JOB_LINKS_PTR(qp); - - if ((PRInt32)(jobp->absolute - now) > 0) { - break; - } - /* - * job timed out - */ - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->timerq.cnt--; - jobp->on_timerq = PR_FALSE; - add_to_jobq(tp, jobp); - } - PR_Unlock(tp->timerq.lock); - } -} - -static void -delete_threadpool(PRThreadPool *tp) -{ - if (NULL != tp) { - if (NULL != tp->shutdown_cv) - PR_DestroyCondVar(tp->shutdown_cv); - if (NULL != tp->jobq.cv) - PR_DestroyCondVar(tp->jobq.cv); - if (NULL != tp->jobq.lock) - PR_DestroyLock(tp->jobq.lock); - if (NULL != tp->join_lock) - PR_DestroyLock(tp->join_lock); -#ifdef OPT_WINNT - if (NULL != tp->jobq.nt_completion_port) - CloseHandle(tp->jobq.nt_completion_port); -#endif - /* Timer queue */ - if (NULL != tp->timerq.cv) - PR_DestroyCondVar(tp->timerq.cv); - if (NULL != tp->timerq.lock) - PR_DestroyLock(tp->timerq.lock); - - if (NULL != tp->ioq.lock) - PR_DestroyLock(tp->ioq.lock); - if (NULL != tp->ioq.pollfds) - PR_Free(tp->ioq.pollfds); - if (NULL != tp->ioq.notify_fd) - PR_DestroyPollableEvent(tp->ioq.notify_fd); - PR_Free(tp); - } - return; -} - -static PRThreadPool * -alloc_threadpool(void) -{ -PRThreadPool *tp; - - tp = (PRThreadPool *) PR_CALLOC(sizeof(*tp)); - if (NULL == tp) - goto failed; - tp->jobq.lock = PR_NewLock(); - if (NULL == tp->jobq.lock) - goto failed; - tp->jobq.cv = PR_NewCondVar(tp->jobq.lock); - if (NULL == tp->jobq.cv) - goto failed; - tp->join_lock = PR_NewLock(); - if (NULL == tp->join_lock) - goto failed; -#ifdef OPT_WINNT - tp->jobq.nt_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, - NULL, 0, 0); - if (NULL == tp->jobq.nt_completion_port) - goto failed; -#endif - - tp->ioq.lock = PR_NewLock(); - if (NULL == tp->ioq.lock) - goto failed; - - /* Timer queue */ - - tp->timerq.lock = PR_NewLock(); - if (NULL == tp->timerq.lock) - goto failed; - tp->timerq.cv = PR_NewCondVar(tp->timerq.lock); - if (NULL == tp->timerq.cv) - goto failed; - - tp->shutdown_cv = PR_NewCondVar(tp->jobq.lock); - if (NULL == tp->shutdown_cv) - goto failed; - tp->ioq.notify_fd = PR_NewPollableEvent(); - if (NULL == tp->ioq.notify_fd) - goto failed; - return tp; -failed: - delete_threadpool(tp); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; -} - -/* Create thread pool */ -PR_IMPLEMENT(PRThreadPool *) -PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads, - PRUint32 stacksize) -{ -PRThreadPool *tp; -PRThread *thr; -int i; -wthread *wthrp; - - tp = alloc_threadpool(); - if (NULL == tp) - return NULL; - - tp->init_threads = initial_threads; - tp->max_threads = max_threads; - tp->stacksize = stacksize; - PR_INIT_CLIST(&tp->jobq.list); - PR_INIT_CLIST(&tp->ioq.list); - PR_INIT_CLIST(&tp->timerq.list); - PR_INIT_CLIST(&tp->jobq.wthreads); - PR_INIT_CLIST(&tp->ioq.wthreads); - PR_INIT_CLIST(&tp->timerq.wthreads); - tp->shutdown = PR_FALSE; - - PR_Lock(tp->jobq.lock); - for(i=0; i < initial_threads; ++i) { - - thr = PR_CreateThread(PR_USER_THREAD, wstart, - tp, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,stacksize); - PR_ASSERT(thr); - wthrp = PR_NEWZAP(wthread); - PR_ASSERT(wthrp); - wthrp->thread = thr; - PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); - } - tp->current_threads = initial_threads; - - thr = PR_CreateThread(PR_USER_THREAD, io_wstart, - tp, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); - PR_ASSERT(thr); - wthrp = PR_NEWZAP(wthread); - PR_ASSERT(wthrp); - wthrp->thread = thr; - PR_APPEND_LINK(&wthrp->links, &tp->ioq.wthreads); - - thr = PR_CreateThread(PR_USER_THREAD, timer_wstart, - tp, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); - PR_ASSERT(thr); - wthrp = PR_NEWZAP(wthread); - PR_ASSERT(wthrp); - wthrp->thread = thr; - PR_APPEND_LINK(&wthrp->links, &tp->timerq.wthreads); - - PR_Unlock(tp->jobq.lock); - return tp; -} - -static void -delete_job(PRJob *jobp) -{ - if (NULL != jobp) { - if (NULL != jobp->join_cv) { - PR_DestroyCondVar(jobp->join_cv); - jobp->join_cv = NULL; - } - if (NULL != jobp->cancel_cv) { - PR_DestroyCondVar(jobp->cancel_cv); - jobp->cancel_cv = NULL; - } - PR_DELETE(jobp); - } -} - -static PRJob * -alloc_job(PRBool joinable, PRThreadPool *tp) -{ - PRJob *jobp; - - jobp = PR_NEWZAP(PRJob); - if (NULL == jobp) - goto failed; - if (joinable) { - jobp->join_cv = PR_NewCondVar(tp->join_lock); - jobp->join_wait = PR_TRUE; - if (NULL == jobp->join_cv) - goto failed; - } else { - jobp->join_cv = NULL; - } -#ifdef OPT_WINNT - jobp->nt_notifier.jobp = jobp; -#endif - return jobp; -failed: - delete_job(jobp); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; -} - -/* queue a job */ -PR_IMPLEMENT(PRJob *) -PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable) -{ - PRJob *jobp; - - jobp = alloc_job(joinable, tpool); - if (NULL == jobp) - return NULL; - - jobp->job_func = fn; - jobp->job_arg = arg; - jobp->tpool = tpool; - - add_to_jobq(tpool, jobp); - return jobp; -} - -/* queue a job, when a socket is readable or writeable */ -static PRJob * -queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg, - PRBool joinable, io_op_type op) -{ - PRJob *jobp; - PRIntervalTime now; - - jobp = alloc_job(joinable, tpool); - if (NULL == jobp) { - return NULL; - } - - /* - * Add a new job to io_jobq - * wakeup io worker thread - */ - - jobp->job_func = fn; - jobp->job_arg = arg; - jobp->tpool = tpool; - jobp->iod = iod; - if (JOB_IO_READ == op) { - jobp->io_op = JOB_IO_READ; - jobp->io_poll_flags = PR_POLL_READ; - } else if (JOB_IO_WRITE == op) { - jobp->io_op = JOB_IO_WRITE; - jobp->io_poll_flags = PR_POLL_WRITE; - } else if (JOB_IO_ACCEPT == op) { - jobp->io_op = JOB_IO_ACCEPT; - jobp->io_poll_flags = PR_POLL_READ; - } else if (JOB_IO_CONNECT == op) { - jobp->io_op = JOB_IO_CONNECT; - jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT; - } else { - delete_job(jobp); - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } - - jobp->timeout = iod->timeout; - if ((PR_INTERVAL_NO_TIMEOUT == iod->timeout) || - (PR_INTERVAL_NO_WAIT == iod->timeout)) { - jobp->absolute = iod->timeout; - } else { - now = PR_IntervalNow(); - jobp->absolute = now + iod->timeout; - } - - - PR_Lock(tpool->ioq.lock); - - if (PR_CLIST_IS_EMPTY(&tpool->ioq.list) || - (PR_INTERVAL_NO_TIMEOUT == iod->timeout)) { - PR_APPEND_LINK(&jobp->links,&tpool->ioq.list); - } else if (PR_INTERVAL_NO_WAIT == iod->timeout) { - PR_INSERT_LINK(&jobp->links,&tpool->ioq.list); - } else { - PRCList *qp; - PRJob *tmp_jobp; - /* - * insert into the timeout-sorted ioq - */ - for (qp = tpool->ioq.list.prev; qp != &tpool->ioq.list; - qp = qp->prev) { - tmp_jobp = JOB_LINKS_PTR(qp); - if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { - break; - } - } - PR_INSERT_AFTER(&jobp->links,qp); - } - - jobp->on_ioq = PR_TRUE; - tpool->ioq.cnt++; - /* - * notify io worker thread(s) - */ - PR_Unlock(tpool->ioq.lock); - notify_ioq(tpool); - return jobp; -} - -/* queue a job, when a socket is readable */ -PR_IMPLEMENT(PRJob *) -PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg, - PRBool joinable) -{ - return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_READ)); -} - -/* queue a job, when a socket is writeable */ -PR_IMPLEMENT(PRJob *) -PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,void * arg, - PRBool joinable) -{ - return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE)); -} - - -/* queue a job, when a socket has a pending connection */ -PR_IMPLEMENT(PRJob *) -PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, - void * arg, PRBool joinable) -{ - return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_ACCEPT)); -} - -/* queue a job, when a socket can be connected */ -PR_IMPLEMENT(PRJob *) -PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod, - const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable) -{ - PRStatus rv; - PRErrorCode err; - - rv = PR_Connect(iod->socket, addr, PR_INTERVAL_NO_WAIT); - if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){ - /* connection pending */ - return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT)); - } else { - /* - * connection succeeded or failed; add to jobq right away - */ - if (rv == PR_FAILURE) - iod->error = err; - else - iod->error = 0; - return(PR_QueueJob(tpool, fn, arg, joinable)); - } -} - -/* queue a job, when a timer expires */ -PR_IMPLEMENT(PRJob *) -PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout, - PRJobFn fn, void * arg, PRBool joinable) -{ - PRIntervalTime now; - PRJob *jobp; - - if (PR_INTERVAL_NO_TIMEOUT == timeout) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } - if (PR_INTERVAL_NO_WAIT == timeout) { - /* - * no waiting; add to jobq right away - */ - return(PR_QueueJob(tpool, fn, arg, joinable)); - } - jobp = alloc_job(joinable, tpool); - if (NULL == jobp) { - return NULL; - } - - /* - * Add a new job to timer_jobq - * wakeup timer worker thread - */ - - jobp->job_func = fn; - jobp->job_arg = arg; - jobp->tpool = tpool; - jobp->timeout = timeout; - - now = PR_IntervalNow(); - jobp->absolute = now + timeout; - - - PR_Lock(tpool->timerq.lock); - jobp->on_timerq = PR_TRUE; - if (PR_CLIST_IS_EMPTY(&tpool->timerq.list)) - PR_APPEND_LINK(&jobp->links,&tpool->timerq.list); - else { - PRCList *qp; - PRJob *tmp_jobp; - /* - * insert into the sorted timer jobq - */ - for (qp = tpool->timerq.list.prev; qp != &tpool->timerq.list; - qp = qp->prev) { - tmp_jobp = JOB_LINKS_PTR(qp); - if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { - break; - } - } - PR_INSERT_AFTER(&jobp->links,qp); - } - tpool->timerq.cnt++; - /* - * notify timer worker thread(s) - */ - notify_timerq(tpool); - PR_Unlock(tpool->timerq.lock); - return jobp; -} - -static void -notify_timerq(PRThreadPool *tp) -{ - /* - * wakeup the timer thread(s) - */ - PR_NotifyCondVar(tp->timerq.cv); -} - -static void -notify_ioq(PRThreadPool *tp) -{ -PRStatus rval_status; - - /* - * wakeup the io thread(s) - */ - rval_status = PR_SetPollableEvent(tp->ioq.notify_fd); - PR_ASSERT(PR_SUCCESS == rval_status); -} - -/* - * cancel a job - * - * XXXX: is this needed? likely to be removed - */ -PR_IMPLEMENT(PRStatus) -PR_CancelJob(PRJob *jobp) { - - PRStatus rval = PR_FAILURE; - PRThreadPool *tp; - - if (jobp->on_timerq) { - /* - * now, check again while holding the timerq lock - */ - tp = jobp->tpool; - PR_Lock(tp->timerq.lock); - if (jobp->on_timerq) { - jobp->on_timerq = PR_FALSE; - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->timerq.cnt--; - PR_Unlock(tp->timerq.lock); - if (!JOINABLE_JOB(jobp)) { - delete_job(jobp); - } else { - JOIN_NOTIFY(jobp); - } - rval = PR_SUCCESS; - } else - PR_Unlock(tp->timerq.lock); - } else if (jobp->on_ioq) { - /* - * now, check again while holding the ioq lock - */ - tp = jobp->tpool; - PR_Lock(tp->ioq.lock); - if (jobp->on_ioq) { - jobp->cancel_cv = PR_NewCondVar(tp->ioq.lock); - if (NULL == jobp->cancel_cv) { - PR_Unlock(tp->ioq.lock); - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - return PR_FAILURE; - } - /* - * mark job 'cancelled' and notify io thread(s) - * XXXX: - * this assumes there is only one io thread; when there - * are multiple threads, the io thread processing this job - * must be notified. - */ - jobp->cancel_io = PR_TRUE; - PR_Unlock(tp->ioq.lock); /* release, reacquire ioq lock */ - notify_ioq(tp); - PR_Lock(tp->ioq.lock); - while (jobp->cancel_io) - PR_WaitCondVar(jobp->cancel_cv, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(tp->ioq.lock); - PR_ASSERT(!jobp->on_ioq); - if (!JOINABLE_JOB(jobp)) { - delete_job(jobp); - } else { - JOIN_NOTIFY(jobp); - } - rval = PR_SUCCESS; - } else - PR_Unlock(tp->ioq.lock); - } - if (PR_FAILURE == rval) - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return rval; -} - -/* join a job, wait until completion */ -PR_IMPLEMENT(PRStatus) -PR_JoinJob(PRJob *jobp) -{ - if (!JOINABLE_JOB(jobp)) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - PR_Lock(jobp->tpool->join_lock); - while(jobp->join_wait) - PR_WaitCondVar(jobp->join_cv, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(jobp->tpool->join_lock); - delete_job(jobp); - return PR_SUCCESS; -} - -/* shutdown threadpool */ -PR_IMPLEMENT(PRStatus) -PR_ShutdownThreadPool(PRThreadPool *tpool) -{ -PRStatus rval = PR_SUCCESS; - - PR_Lock(tpool->jobq.lock); - tpool->shutdown = PR_TRUE; - PR_NotifyAllCondVar(tpool->shutdown_cv); - PR_Unlock(tpool->jobq.lock); - - return rval; -} - -/* - * join thread pool - * wait for termination of worker threads - * reclaim threadpool resources - */ -PR_IMPLEMENT(PRStatus) -PR_JoinThreadPool(PRThreadPool *tpool) -{ -PRStatus rval = PR_SUCCESS; -PRCList *head; -PRStatus rval_status; - - PR_Lock(tpool->jobq.lock); - while (!tpool->shutdown) - PR_WaitCondVar(tpool->shutdown_cv, PR_INTERVAL_NO_TIMEOUT); - - /* - * wakeup worker threads - */ -#ifdef OPT_WINNT - /* - * post shutdown notification for all threads - */ - { - int i; - for(i=0; i < tpool->current_threads; i++) { - PostQueuedCompletionStatus(tpool->jobq.nt_completion_port, 0, - TRUE, NULL); - } - } -#else - PR_NotifyAllCondVar(tpool->jobq.cv); -#endif - - /* - * wakeup io thread(s) - */ - notify_ioq(tpool); - - /* - * wakeup timer thread(s) - */ - PR_Lock(tpool->timerq.lock); - notify_timerq(tpool); - PR_Unlock(tpool->timerq.lock); - - while (!PR_CLIST_IS_EMPTY(&tpool->jobq.wthreads)) { - wthread *wthrp; - - head = PR_LIST_HEAD(&tpool->jobq.wthreads); - PR_REMOVE_AND_INIT_LINK(head); - PR_Unlock(tpool->jobq.lock); - wthrp = WTHREAD_LINKS_PTR(head); - rval_status = PR_JoinThread(wthrp->thread); - PR_ASSERT(PR_SUCCESS == rval_status); - PR_DELETE(wthrp); - PR_Lock(tpool->jobq.lock); - } - PR_Unlock(tpool->jobq.lock); - while (!PR_CLIST_IS_EMPTY(&tpool->ioq.wthreads)) { - wthread *wthrp; - - head = PR_LIST_HEAD(&tpool->ioq.wthreads); - PR_REMOVE_AND_INIT_LINK(head); - wthrp = WTHREAD_LINKS_PTR(head); - rval_status = PR_JoinThread(wthrp->thread); - PR_ASSERT(PR_SUCCESS == rval_status); - PR_DELETE(wthrp); - } - - while (!PR_CLIST_IS_EMPTY(&tpool->timerq.wthreads)) { - wthread *wthrp; - - head = PR_LIST_HEAD(&tpool->timerq.wthreads); - PR_REMOVE_AND_INIT_LINK(head); - wthrp = WTHREAD_LINKS_PTR(head); - rval_status = PR_JoinThread(wthrp->thread); - PR_ASSERT(PR_SUCCESS == rval_status); - PR_DELETE(wthrp); - } - - /* - * Delete queued jobs - */ - while (!PR_CLIST_IS_EMPTY(&tpool->jobq.list)) { - PRJob *jobp; - - head = PR_LIST_HEAD(&tpool->jobq.list); - PR_REMOVE_AND_INIT_LINK(head); - jobp = JOB_LINKS_PTR(head); - tpool->jobq.cnt--; - delete_job(jobp); - } - - /* delete io jobs */ - while (!PR_CLIST_IS_EMPTY(&tpool->ioq.list)) { - PRJob *jobp; - - head = PR_LIST_HEAD(&tpool->ioq.list); - PR_REMOVE_AND_INIT_LINK(head); - tpool->ioq.cnt--; - jobp = JOB_LINKS_PTR(head); - delete_job(jobp); - } - - /* delete timer jobs */ - while (!PR_CLIST_IS_EMPTY(&tpool->timerq.list)) { - PRJob *jobp; - - head = PR_LIST_HEAD(&tpool->timerq.list); - PR_REMOVE_AND_INIT_LINK(head); - tpool->timerq.cnt--; - jobp = JOB_LINKS_PTR(head); - delete_job(jobp); - } - - PR_ASSERT(0 == tpool->jobq.cnt); - PR_ASSERT(0 == tpool->ioq.cnt); - PR_ASSERT(0 == tpool->timerq.cnt); - - delete_threadpool(tpool); - return rval; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prtrace.c nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prtrace.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/misc/prtrace.c 2012-03-06 13:14:20.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/misc/prtrace.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,888 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** prtrace.c -- NSPR Trace Instrumentation -** -** Implement the API defined in prtrace.h -** -** -** -*/ - -#include -#include "primpl.h" - - -#define DEFAULT_TRACE_BUFSIZE ( 1024 * 1024 ) -#define DEFAULT_BUFFER_SEGMENTS 2 - -/* -** Enumerate states in a RName structure -*/ -typedef enum TraceState -{ - Running = 1, - Suspended = 2 -} TraceState; - -/* -** Define QName structure -*/ -typedef struct QName -{ - PRCList link; - PRCList rNameList; - char name[PRTRACE_NAME_MAX+1]; -} QName; - -/* -** Define RName structure -*/ -typedef struct RName -{ - PRCList link; - PRLock *lock; - QName *qName; - TraceState state; - char name[PRTRACE_NAME_MAX+1]; - char desc[PRTRACE_DESC_MAX+1]; -} RName; - - -/* -** The Trace Facility database -** -*/ -static PRLogModuleInfo *lm; - -static PRLock *traceLock; /* Facility Lock */ -static PRCList qNameList; /* anchor to all QName structures */ -static TraceState traceState = Running; - -/* -** in-memory trace buffer controls -*/ -static PRTraceEntry *tBuf; /* pointer to buffer */ -static PRInt32 bufSize; /* size of buffer, in bytes, rounded up to sizeof(PRTraceEntry) */ -static volatile PRInt32 next; /* index to next PRTraceEntry */ -static PRInt32 last; /* index of highest numbered trace entry */ - -/* -** Real-time buffer capture controls -*/ -static PRInt32 fetchLastSeen = 0; -static PRBool fetchLostData = PR_FALSE; - -/* -** Buffer write-to-file controls -*/ -static PRLock *logLock; /* Sync lock */ -static PRCondVar *logCVar; /* Sync Condidtion Variable */ -/* -** Inter-thread state communication. -** Controling thread writes to logOrder under protection of logCVar -** the logging thread reads logOrder and sets logState on Notify. -** -** logSegments, logCount, logLostData must be read and written under -** protection of logLock, logCVar. -** -*/ -static enum LogState -{ - LogNotRunning, /* Initial state */ - LogReset, /* Causes logger to re-calc controls */ - LogActive, /* Logging in progress, set only by log thread */ - LogSuspend, /* Suspend Logging */ - LogResume, /* Resume Logging => LogActive */ - LogStop /* Stop the log thread */ -} logOrder, logState, localState; /* controlling state variables */ -static PRInt32 logSegments; /* Number of buffer segments */ -static PRInt32 logEntries; /* number of Trace Entries in the buffer */ -static PRInt32 logEntriesPerSegment; /* number of PRTraceEntries per buffer segment */ -static PRInt32 logSegSize; /* size of buffer segment */ -static PRInt32 logCount; /* number of segments pending output */ -static PRInt32 logLostData; /* number of lost log buffer segments */ - -/* -** end Trace Database -** -*/ - -/* -** _PR_InitializeTrace() -- Initialize the trace facility -*/ -static void NewTraceBuffer( PRInt32 size ) -{ - /* - ** calculate the size of the buffer - ** round down so that each segment has the same number of - ** trace entries - */ - logSegments = DEFAULT_BUFFER_SEGMENTS; - logEntries = size / sizeof(PRTraceEntry); - logEntriesPerSegment = logEntries / logSegments; - logEntries = logSegments * logEntriesPerSegment; - bufSize = logEntries * sizeof(PRTraceEntry); - logSegSize = logEntriesPerSegment * sizeof(PRTraceEntry); - PR_ASSERT( bufSize != 0); - PR_LOG( lm, PR_LOG_ERROR, - ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegment: %ld, logSegSize: %ld", - logSegments, logEntries, logEntriesPerSegment, logSegSize )); - - - tBuf = PR_Malloc( bufSize ); - if ( tBuf == NULL ) - { - PR_LOG( lm, PR_LOG_ERROR, - ("PRTrace: Failed to get trace buffer")); - PR_ASSERT( 0 ); - } - else - { - PR_LOG( lm, PR_LOG_NOTICE, - ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf)); - } - - next = 0; - last = logEntries -1; - logCount = 0; - logLostData = PR_TRUE; /* not really on first call */ - logOrder = LogReset; - -} /* end NewTraceBuffer() */ - -/* -** _PR_InitializeTrace() -- Initialize the trace facility -*/ -static void _PR_InitializeTrace( void ) -{ - /* The lock pointer better be null on this call */ - PR_ASSERT( traceLock == NULL ); - - traceLock = PR_NewLock(); - PR_ASSERT( traceLock != NULL ); - - PR_Lock( traceLock ); - - PR_INIT_CLIST( &qNameList ); - - lm = PR_NewLogModule("trace"); - - bufSize = DEFAULT_TRACE_BUFSIZE; - NewTraceBuffer( bufSize ); - - /* Initialize logging controls */ - logLock = PR_NewLock(); - logCVar = PR_NewCondVar( logLock ); - - PR_Unlock( traceLock ); - return; -} /* end _PR_InitializeTrace() */ - -/* -** Create a Trace Handle -*/ -PR_IMPLEMENT(PRTraceHandle) - PR_CreateTrace( - const char *qName, /* QName for this trace handle */ - const char *rName, /* RName for this trace handle */ - const char *description /* description for this trace handle */ -) -{ - QName *qnp; - RName *rnp; - PRBool matchQname = PR_FALSE; - - /* Self initialize, if necessary */ - if ( traceLock == NULL ) - _PR_InitializeTrace(); - - /* Validate input arguments */ - PR_ASSERT( strlen(qName) <= PRTRACE_NAME_MAX ); - PR_ASSERT( strlen(rName) <= PRTRACE_NAME_MAX ); - PR_ASSERT( strlen(description) <= PRTRACE_DESC_MAX ); - - PR_LOG( lm, PR_LOG_DEBUG, - ("PRTRACE: CreateTrace: Qname: %s, RName: %s", qName, rName)); - - /* Lock the Facility */ - PR_Lock( traceLock ); - - /* Do we already have a matching QName? */ - if (!PR_CLIST_IS_EMPTY( &qNameList )) - { - qnp = (QName *) PR_LIST_HEAD( &qNameList ); - do { - if ( strcmp(qnp->name, qName) == 0) - { - matchQname = PR_TRUE; - break; - } - qnp = (QName *)PR_NEXT_LINK( &qnp->link ); - } while( qnp != (QName *)PR_LIST_HEAD( &qNameList )); - } - /* - ** If we did not find a matching QName, - ** allocate one and initialize it. - ** link it onto the qNameList. - ** - */ - if ( matchQname != PR_TRUE ) - { - qnp = PR_NEWZAP( QName ); - PR_ASSERT( qnp != NULL ); - PR_INIT_CLIST( &qnp->link ); - PR_INIT_CLIST( &qnp->rNameList ); - strcpy( qnp->name, qName ); - PR_APPEND_LINK( &qnp->link, &qNameList ); - } - - /* Do we already have a matching RName? */ - if (!PR_CLIST_IS_EMPTY( &qnp->rNameList )) - { - rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList ); - do { - /* - ** No duplicate RNames are allowed within a QName - ** - */ - PR_ASSERT( strcmp(rnp->name, rName)); - rnp = (RName *)PR_NEXT_LINK( &rnp->link ); - } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList )); - } - - /* Get a new RName structure; initialize its members */ - rnp = PR_NEWZAP( RName ); - PR_ASSERT( rnp != NULL ); - PR_INIT_CLIST( &rnp->link ); - strcpy( rnp->name, rName ); - strcpy( rnp->desc, description ); - rnp->lock = PR_NewLock(); - rnp->state = Running; - if ( rnp->lock == NULL ) - { - PR_ASSERT(0); - } - - PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ - rnp->qName = qnp; /* point the RName to the QName */ - - /* Unlock the Facility */ - PR_Unlock( traceLock ); - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Create: QName: %s %p, RName: %s %p\n\t", - qName, qnp, rName, rnp )); - - return((PRTraceHandle)rnp); -} /* end PR_CreateTrace() */ - -/* -** -*/ -PR_IMPLEMENT(void) - PR_DestroyTrace( - PRTraceHandle handle /* Handle to be destroyed */ -) -{ - RName *rnp = (RName *)handle; - QName *qnp = rnp->qName; - - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s", - qnp->name, rnp->name)); - - /* Lock the Facility */ - PR_Lock( traceLock ); - - /* - ** Remove RName from the list of RNames in QName - ** and free RName - */ - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p", - rnp->name, rnp)); - PR_REMOVE_LINK( &rnp->link ); - PR_Free( rnp->lock ); - PR_DELETE( rnp ); - - /* - ** If this is the last RName within QName - ** remove QName from the qNameList and free it - */ - if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) ) - { - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p", - qnp->name, qnp)); - PR_REMOVE_LINK( &qnp->link ); - PR_DELETE( qnp ); - } - - /* Unlock the Facility */ - PR_Unlock( traceLock ); - return; -} /* end PR_DestroyTrace() */ - -/* -** Create a TraceEntry in the trace buffer -*/ -PR_IMPLEMENT(void) - PR_Trace( - PRTraceHandle handle, /* use this trace handle */ - PRUint32 userData0, /* User supplied data word 0 */ - PRUint32 userData1, /* User supplied data word 1 */ - PRUint32 userData2, /* User supplied data word 2 */ - PRUint32 userData3, /* User supplied data word 3 */ - PRUint32 userData4, /* User supplied data word 4 */ - PRUint32 userData5, /* User supplied data word 5 */ - PRUint32 userData6, /* User supplied data word 6 */ - PRUint32 userData7 /* User supplied data word 7 */ -) -{ - PRTraceEntry *tep; - PRInt32 mark; - - if ( (traceState == Suspended ) - || ( ((RName *)handle)->state == Suspended )) - return; - - /* - ** Get the next trace entry slot w/ minimum delay - */ - PR_Lock( traceLock ); - - tep = &tBuf[next++]; - if ( next > last ) - next = 0; - if ( fetchLostData == PR_FALSE && next == fetchLastSeen ) - fetchLostData = PR_TRUE; - - mark = next; - - PR_Unlock( traceLock ); - - /* - ** We have a trace entry. Fill it in. - */ - tep->thread = PR_GetCurrentThread(); - tep->handle = handle; - tep->time = PR_Now(); - tep->userData[0] = userData0; - tep->userData[1] = userData1; - tep->userData[2] = userData2; - tep->userData[3] = userData3; - tep->userData[4] = userData4; - tep->userData[5] = userData5; - tep->userData[6] = userData6; - tep->userData[7] = userData7; - - /* When buffer segment is full, signal trace log thread to run */ - if (( mark % logEntriesPerSegment) == 0 ) - { - PR_Lock( logLock ); - logCount++; - PR_NotifyCondVar( logCVar ); - PR_Unlock( logLock ); - /* - ** Gh0D! This is awful! - ** Anyway, to minimize lost trace data segments, - ** I inserted the PR_Sleep(0) to cause a context switch - ** so that the log thread could run. - ** I know, it perturbs the universe and may cause - ** funny things to happen in the optimized builds. - ** Take it out, lose data; leave it in risk Heisenberg. - */ - /* PR_Sleep(0); */ - } - - return; -} /* end PR_Trace() */ - -/* -** -*/ -PR_IMPLEMENT(void) - PR_SetTraceOption( - PRTraceOption command, /* One of the enumerated values */ - void *value /* command value or NULL */ -) -{ - RName * rnp; - - switch ( command ) - { - case PRTraceBufSize : - PR_Lock( traceLock ); - PR_Free( tBuf ); - bufSize = *(PRInt32 *)value; - NewTraceBuffer( bufSize ); - PR_Unlock( traceLock ); - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize)); - break; - - case PRTraceEnable : - rnp = *(RName **)value; - rnp->state = Running; - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceEnable: %p", rnp)); - break; - - case PRTraceDisable : - rnp = *(RName **)value; - rnp->state = Suspended; - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceDisable: %p", rnp)); - break; - - case PRTraceSuspend : - traceState = Suspended; - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceSuspend")); - break; - - case PRTraceResume : - traceState = Running; - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceResume")); - break; - - case PRTraceSuspendRecording : - PR_Lock( logLock ); - logOrder = LogSuspend; - PR_NotifyCondVar( logCVar ); - PR_Unlock( logLock ); - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceSuspendRecording")); - break; - - case PRTraceResumeRecording : - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceResumeRecording")); - if ( logState != LogSuspend ) - break; - PR_Lock( logLock ); - logOrder = LogResume; - PR_NotifyCondVar( logCVar ); - PR_Unlock( logLock ); - break; - - case PRTraceStopRecording : - PR_Lock( logLock ); - logOrder = LogStop; - PR_NotifyCondVar( logCVar ); - PR_Unlock( logLock ); - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceStopRecording")); - break; - - case PRTraceLockHandles : - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceLockTraceHandles")); - PR_Lock( traceLock ); - break; - - case PRTraceUnLockHandles : - PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceUnLockHandles")); - PR_Unlock( traceLock ); - break; - - default: - PR_LOG( lm, PR_LOG_ERROR, - ("PRSetTraceOption: Invalid command %ld", command )); - PR_ASSERT( 0 ); - break; - } /* end switch() */ - return; -} /* end PR_SetTraceOption() */ - -/* -** -*/ -PR_IMPLEMENT(void) - PR_GetTraceOption( - PRTraceOption command, /* One of the enumerated values */ - void *value /* command value or NULL */ -) -{ - switch ( command ) - { - case PRTraceBufSize : - *((PRInt32 *)value) = bufSize; - PR_LOG( lm, PR_LOG_DEBUG, - ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize )); - break; - - default: - PR_LOG( lm, PR_LOG_ERROR, - ("PRGetTraceOption: Invalid command %ld", command )); - PR_ASSERT( 0 ); - break; - } /* end switch() */ - return; -} /* end PR_GetTraceOption() */ - -/* -** -*/ -PR_IMPLEMENT(PRTraceHandle) - PR_GetTraceHandleFromName( - const char *qName, /* QName search argument */ - const char *rName /* RName search argument */ -) -{ - const char *qn, *rn, *desc; - PRTraceHandle qh, rh = NULL; - RName *rnp = NULL; - - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetTraceHandleFromName:\n\t" - "QName: %s, RName: %s", qName, rName )); - - qh = PR_FindNextTraceQname( NULL ); - while (qh != NULL) - { - rh = PR_FindNextTraceRname( NULL, qh ); - while ( rh != NULL ) - { - PR_GetTraceNameFromHandle( rh, &qn, &rn, &desc ); - if ( (strcmp( qName, qn ) == 0) - && (strcmp( rName, rn ) == 0 )) - { - rnp = (RName *)rh; - goto foundIt; - } - rh = PR_FindNextTraceRname( rh, qh ); - } - qh = PR_FindNextTraceQname( NULL ); - } - -foundIt: - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp )); - return(rh); -} /* end PR_GetTraceHandleFromName() */ - -/* -** -*/ -PR_IMPLEMENT(void) - PR_GetTraceNameFromHandle( - PRTraceHandle handle, /* handle as search argument */ - const char **qName, /* pointer to associated QName */ - const char **rName, /* pointer to associated RName */ - const char **description /* pointer to associated description */ -) -{ - RName *rnp = (RName *)handle; - QName *qnp = rnp->qName; - - *qName = qnp->name; - *rName = rnp->name; - *description = rnp->desc; - - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetConterNameFromHandle: " - "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", - qnp, rnp, qnp->name, rnp->name, rnp->desc )); - - return; -} /* end PR_GetTraceNameFromHandle() */ - -/* -** -*/ -PR_IMPLEMENT(PRTraceHandle) - PR_FindNextTraceQname( - PRTraceHandle handle -) -{ - QName *qnp = (QName *)handle; - - if ( PR_CLIST_IS_EMPTY( &qNameList )) - qnp = NULL; - else if ( qnp == NULL ) - qnp = (QName *)PR_LIST_HEAD( &qNameList ); - else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) - qnp = NULL; - else - qnp = (QName *)PR_NEXT_LINK( &qnp->link ); - - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p", - handle, qnp )); - - return((PRTraceHandle)qnp); -} /* end PR_FindNextTraceQname() */ - -/* -** -*/ -PR_IMPLEMENT(PRTraceHandle) - PR_FindNextTraceRname( - PRTraceHandle rhandle, - PRTraceHandle qhandle -) -{ - RName *rnp = (RName *)rhandle; - QName *qnp = (QName *)qhandle; - - - if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) - rnp = NULL; - else if ( rnp == NULL ) - rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList ); - else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) - rnp = NULL; - else - rnp = (RName *)PR_NEXT_LINK( &rnp->link ); - - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", - rhandle, qhandle, rnp )); - - return((PRTraceHandle)rnp); -} /* end PR_FindNextTraceRname() */ - -/* -** -*/ -static PRFileDesc * InitializeRecording( void ) -{ - char *logFileName; - PRFileDesc *logFile; - - /* Self initialize, if necessary */ - if ( traceLock == NULL ) - _PR_InitializeTrace(); - - PR_LOG( lm, PR_LOG_DEBUG, - ("PR_RecordTraceEntries: begins")); - - logLostData = 0; /* reset at entry */ - logState = LogReset; - -#ifdef XP_UNIX - if ((getuid() != geteuid()) || (getgid() != getegid())) { - return NULL; - } -#endif /* XP_UNIX */ - - /* Get the filename for the logfile from the environment */ - logFileName = PR_GetEnv( "NSPR_TRACE_LOG" ); - if ( logFileName == NULL ) - { - PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: Environment variable not defined. Exiting")); - return NULL; - } - - /* Open the logfile */ - logFile = PR_Open( logFileName, PR_WRONLY | PR_CREATE_FILE, 0666 ); - if ( logFile == NULL ) - { - PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %ld", - logFileName, PR_GetOSError())); - return NULL; - } - return logFile; -} /* end InitializeRecording() */ - -/* -** -*/ -static void ProcessOrders( void ) -{ - switch ( logOrder ) - { - case LogReset : - logOrder = logState = localState; - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: LogReset")); - break; - - case LogSuspend : - localState = logOrder = logState = LogSuspend; - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: LogSuspend")); - break; - - case LogResume : - localState = logOrder = logState = LogActive; - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: LogResume")); - break; - - case LogStop : - logOrder = logState = LogStop; - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: LogStop")); - break; - - default : - PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: Invalid logOrder: %ld", logOrder )); - PR_ASSERT( 0 ); - break; - } /* end switch() */ - return ; -} /* end ProcessOrders() */ - -/* -** -*/ -static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount ) -{ - PRInt32 rc; - - - PR_LOG( lm, PR_LOG_ERROR, - ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount)); - rc = PR_Write( logFile, buf , amount ); - if ( rc == -1 ) - PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() )); - else if ( rc != amount ) - PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", amount, rc)); - else - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amount)); - - return; -} /* end WriteTraceSegment() */ - -/* -** -*/ -PR_IMPLEMENT(void) - PR_RecordTraceEntries( - void -) -{ - PRFileDesc *logFile; - PRInt32 lostSegments; - PRInt32 currentSegment = 0; - void *buf; - PRBool doWrite; - - logFile = InitializeRecording(); - if ( logFile == NULL ) - { - PR_LOG( lm, PR_LOG_DEBUG, - ("PR_RecordTraceEntries: Failed to initialize")); - return; - } - - /* Do this until told to stop */ - while ( logState != LogStop ) - { - - PR_Lock( logLock ); - - while ( (logCount == 0) && ( logOrder == logState ) ) - PR_WaitCondVar( logCVar, PR_INTERVAL_NO_TIMEOUT ); - - /* Handle state transitions */ - if ( logOrder != logState ) - ProcessOrders(); - - /* recalculate local controls */ - if ( logCount ) - { - lostSegments = logCount - logSegments; - if ( lostSegments > 0 ) - { - logLostData += ( logCount - logSegments ); - logCount = (logCount % logSegments); - currentSegment = logCount; - PR_LOG( lm, PR_LOG_DEBUG, - ("PR_RecordTraceEntries: LostData segments: %ld", logLostData)); - } - else - { - logCount--; - } - - buf = tBuf + ( logEntriesPerSegment * currentSegment ); - if (++currentSegment >= logSegments ) - currentSegment = 0; - doWrite = PR_TRUE; - } - else - doWrite = PR_FALSE; - - PR_Unlock( logLock ); - - if ( doWrite == PR_TRUE ) - { - if ( localState != LogSuspend ) - WriteTraceSegment( logFile, buf, logSegSize ); - else - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: PR_Write(): is suspended" )); - } - - } /* end while(logState...) */ - - PR_Close( logFile ); - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: exiting")); - return; -} /* end PR_RecordTraceEntries() */ - -/* -** -*/ -PR_IMPLEMENT(PRIntn) - PR_GetTraceEntries( - PRTraceEntry *buffer, /* where to write output */ - PRInt32 count, /* number to get */ - PRInt32 *found /* number you got */ -) -{ - PRInt32 rc; - PRInt32 copied = 0; - - PR_Lock( traceLock ); - - /* - ** Depending on where the LastSeen and Next indices are, - ** copy the trace buffer in one or two pieces. - */ - PR_LOG( lm, PR_LOG_ERROR, - ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen)); - - if ( fetchLastSeen <= next ) - { - while (( count-- > 0 ) && (fetchLastSeen < next )) - { - *(buffer + copied++) = *(tBuf + fetchLastSeen++); - } - PR_LOG( lm, PR_LOG_ERROR, - ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); - } - else /* copy in 2 parts */ - { - while ( count-- > 0 && fetchLastSeen <= last ) - { - *(buffer + copied++) = *(tBuf + fetchLastSeen++); - } - fetchLastSeen = 0; - - PR_LOG( lm, PR_LOG_ERROR, - ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); - - while ( count-- > 0 && fetchLastSeen < next ) - { - *(buffer + copied++) = *(tBuf + fetchLastSeen++); - } - PR_LOG( lm, PR_LOG_ERROR, - ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); - } - - *found = copied; - rc = ( fetchLostData == PR_TRUE )? 1 : 0; - fetchLostData = PR_FALSE; - - PR_Unlock( traceLock ); - return rc; -} /* end PR_GetTraceEntries() */ - -/* end prtrace.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/nspr.def nspr-4.10.7/mozilla/nsprpub/pr/src/nspr.def --- nspr-4.9.5/mozilla/nsprpub/pr/src/nspr.def 2012-06-06 23:22:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/nspr.def 1970-01-01 00:00:00.000000000 +0000 @@ -1,453 +0,0 @@ -;+# -;+# This Source Code Form is subject to the terms of the Mozilla Public -;+# License, v. 2.0. If a copy of the MPL was not distributed with this -;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -;+# -;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS -;+# 1. For all unix platforms, the string ";-" means "remove this line" -;+# 2. For all unix platforms, the string " DATA " will be removed from any -;+# line on which it occurs. -;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. -;+# On AIX, lines containing ";+" will be removed. -;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. -;+# 5. For all unix platforms, after the above processing has taken place, -;+# all characters after the first ";" on the line will be removed. -;+# And for AIX, the first ";" will also be removed. -;+# This file is passed directly to windows. Since ';' is a comment, all UNIX -;+# directives are hidden behind ";", ";+", and ";-" -;+# -;+NSPR_4.0 { -;+ global: -LIBRARY nspr4 ;- -EXPORTS ;- - LL_MaxInt; - LL_MinInt; - LL_Zero; - PR_Abort; - PR_AddToCounter; - PR_Accept; - PR_AcceptRead; - PR_Access; - PR_AddWaitFileDesc; - PR_AllocFileDesc; - PR_Assert; - PR_AtomicAdd; - PR_AtomicDecrement; - PR_AtomicIncrement; - PR_AtomicSet; - PR_AttachSharedMemory; - PR_AttachThread; - PR_Available; - PR_Available64; - PR_Bind; - PR_BlockClockInterrupts; - PR_BlockInterrupt; - PR_CEnterMonitor; - PR_CExitMonitor; - PR_CNotify; - PR_CNotifyAll; - PR_CSetOnMonitorRecycle; - PR_CWait; - PR_CallOnce; - PR_Calloc; - PR_CancelJob; - PR_CancelWaitFileDesc; - PR_CancelWaitGroup; - PR_CeilingLog2; - PR_ChangeFileDescNativeHandle; - PR_Cleanup; - PR_ClearInterrupt; - PR_ClearThreadGCAble; - PR_Close; - PR_CloseDir; - PR_CloseFileMap; - PR_CloseSemaphore; - PR_CloseSharedMemory; - PR_Connect; - PR_CreateCounter; - PR_ConvertIPv4AddrToIPv6; - PR_CreateAlarm; - PR_CreateFileMap; - PR_CreateIOLayerStub; - PR_CreateOrderedLock; - PR_CreateMWaitEnumerator; - PR_CreatePipe; - PR_CreateProcess; - PR_CreateProcessDetached; - PR_CreateSocketPollFd; - PR_CreateStack; - PR_CreateThread; - PR_CreateThreadGCAble; - PR_CreateTrace; - PR_CreateThreadPool; - PR_DecrementCounter; - PR_CreateWaitGroup; - PR_Delete; - PR_DeleteSemaphore; - PR_DeleteSharedMemory; - PR_DestroyAlarm; - PR_DestroyCounter; - PR_DestroyCondVar; - PR_DestroyLock; - PR_DestroyMWaitEnumerator; - PR_DestroyOrderedLock; - PR_DestroyMonitor; - PR_DestroyPollableEvent; - PR_DestroyProcessAttr; - PR_DestroyRWLock; - PR_DestroySem; - PR_DestroySocketPollFd; - PR_DestroyTrace; - PR_DestroyStack; - PR_DestroyWaitGroup; - PR_DetachProcess; - PR_DetachSharedMemory; - PR_DetachThread; - PR_DisableClockInterrupts; - PR_EnableClockInterrupts; - PR_EnterMonitor; - PR_EnumerateHostEnt; - PR_EnumerateThreads; - PR_EnumerateWaitGroup; - PR_ErrorInstallCallback; - PR_ErrorInstallTable; - PR_ErrorLanguages; - PR_ErrorToName; - PR_ErrorToString; - PR_ExitMonitor; - PR_ExplodeTime; - PR_ExportFileMapAsString; - PR_FD_CLR; - PR_FD_ISSET; - PR_FD_NCLR; - PR_FD_NISSET; - PR_FD_NSET; - PR_FD_SET; - PR_FD_ZERO; - PR_FileDesc2NativeHandle; - PR_FindSymbol; - PR_FindSymbolAndLibrary; - PR_FloorLog2; - PR_FormatTime; - PR_FindNextCounterQname; - PR_FindNextCounterRname; - PR_FindNextTraceQname; - PR_FindNextTraceRname; - PR_FormatTimeUSEnglish; - PR_Free; - PR_FreeLibraryName; - PR_GMTParameters; - PR_GetConnectStatus; - PR_GetCurrentThread; - PR_GetDefaultIOMethods; - PR_GetDescType; - PR_GetDirectorySeparator; - PR_GetCounter; - PR_GetCounterHandleFromName; - PR_GetCounterNameFromHandle; - PR_GetDirectorySepartor; - PR_GetEnv; - PR_GetError; - PR_GetErrorText; - PR_GetErrorTextLength; - PR_GetFileInfo; - PR_GetFileInfo64; - PR_GetFileMethods; - PR_GetGCRegisters; - PR_GetHostByAddr; - PR_GetHostByName; - PR_GetIPNodeByName; - PR_GetIdentitiesLayer; - PR_GetInheritedFD; - PR_GetInheritedFileMap; - PR_GetLayersIdentity; - PR_GetLibraryName; - PR_GetLibraryPath; - PR_GetMonitorEntryCount; - PR_GetNameForIdentity; - PR_GetOSError; - PR_GetOpenFileInfo; - PR_GetOpenFileInfo64; - PR_GetPageShift; - PR_GetPageSize; - PR_GetPeerName; - PR_GetPipeMethods; - PR_GetProtoByName; - PR_GetProtoByNumber; - PR_GetRandomNoise; - PR_GetSP; - PR_GetSockName; - PR_GetSocketOption; - PR_GetSpecialFD; - PR_GetStackSpaceLeft; - PR_GetSysfdTableMax; - PR_GetSystemInfo; - PR_GetTCPMethods; - PR_GetThreadAffinityMask; - PR_GetThreadID; - PR_GetThreadPriority; - PR_GetThreadPrivate; - PR_GetThreadScope; - PR_GetThreadState; - PR_GetThreadType; - PR_GetUDPMethods; - PR_GetUniqueIdentity; - PR_ImplodeTime; - PR_ImportFile; - PR_ImportFileMapFromString; - PR_ImportTCPSocket; - PR_ImportUDPSocket; - PR_GetTraceEntries; - PR_GetTraceHandleFromName; - PR_GetTraceNameFromHandle; - PR_GetTraceOption; - PR_Init; - PR_Initialize; - PR_InitializeNetAddr; - PR_Initialized; - PR_Interrupt; - PR_IntervalNow; - PR_IntervalToMicroseconds; - PR_IntervalToMilliseconds; - PR_IncrementCounter; - PR_IntervalToSeconds; - PR_IsNetAddrType; - PR_JoinJob; - PR_JoinThread; - PR_JoinThreadPool; - PR_KillProcess; - PR_Listen; - PR_LoadLibrary; - PR_LoadLibraryWithFlags; - PR_LoadStaticLibrary; - PR_LocalTimeParameters; - PR_Lock; - PR_LockFile; - PR_LogFlush; - PR_LogPrint; - PR_MakeDir; - PR_Malloc; - PR_MemMap; - PR_MemUnmap; - PR_MicrosecondsToInterval; - PR_MillisecondsToInterval; - PR_LockOrderedLock; - PR_MkDir; - PR_NetAddrToString; - PR_NewCondVar; - PR_NewLock; - PR_NewLogModule; - PR_NewMonitor; - PR_NewNamedMonitor; - PR_NewPollableEvent; - PR_NewProcessAttr; - PR_NewRWLock; - PR_NewSem; - PR_NewTCPSocket; - PR_NewTCPSocketPair; - PR_NewThreadPrivateIndex; - PR_NewUDPSocket; - PR_NormalizeTime; - PR_Notify; - PR_NotifyAll; - PR_NotifyAllCondVar; - PR_NotifyCondVar; - PR_Now; - PR_Open; - PR_OpenAnonFileMap; - PR_OpenDir; - PR_OpenFile; - PR_OpenSemaphore; - PR_OpenSharedMemory; - PR_OpenTCPSocket; - PR_OpenUDPSocket; - PR_ParseTimeString; - PR_Poll; - PR_PopIOLayer; - PR_PostSem; - PR_PostSemaphore; - PR_ProcessAttrSetCurrentDirectory; - PR_ProcessAttrSetInheritableFD; - PR_ProcessAttrSetInheritableFileMap; - PR_ProcessAttrSetStdioRedirect; - PR_ProcessExit; - PR_PushIOLayer; - PR_QueueJob; - PR_QueueJob_Accept; - PR_QueueJob_Connect; - PR_QueueJob_Read; - PR_QueueJob_Timer; - PR_QueueJob_Write; - PR_RWLock_Rlock; - PR_RWLock_Unlock; - PR_RWLock_Wlock; - PR_Read; - PR_ReadDir; - PR_Realloc; - PR_Recv; - PR_RecvFrom; - PR_Rename; - PR_ResetAlarm; - PR_ResetProcessAttr; - PR_ResumeAll; - PR_RmDir; - PR_ScanStackPointers; - PR_RecordTraceEntries; - PR_SecondsToInterval; - PR_Seek; - PR_Seek64; - PR_Select; - PR_Send; - PR_SendFile; - PR_SendTo; - PR_SetAlarm; - PR_SetConcurrency; - PR_SetError; - PR_SetErrorText; - PR_SetFDCacheSize; - PR_SetFDInheritable; - PR_SetLibraryPath; - PR_SetLogBuffering; - PR_SetLogFile; - PR_SetNetAddr; - PR_SetPollableEvent; - PR_SetSocketOption; - PR_SetCounter; - PR_SetStdioRedirect; - PR_SetSysfdTableSize; - PR_SetThreadAffinityMask; - PR_SetThreadDumpProc; - PR_SetThreadGCAble; - PR_SetThreadPriority; - PR_SetThreadPrivate; - PR_SetThreadRecycleMode; - PR_Shutdown; - PR_ShutdownThreadPool; - PR_Sleep; - PR_Socket; - PR_StackPop; - PR_StackPush; - PR_Stat; - PR_StringToNetAddr; - PR_SuspendAll; - PR_Sync; - PR_TLockFile; - PR_ThreadScanStackPointers; - PR_SetTraceOption; - PR_TicksPerSecond; - PR_TransmitFile; - PR_USPacificTimeParameters; - PR_UnblockClockInterrupts; - PR_UnblockInterrupt; - PR_UnloadLibrary; - PR_SubtractFromCounter; - PR_Unlock; - PR_UnlockFile; - PR_VersionCheck; - PR_Wait; - PR_WaitCondVar; - PR_WaitForPollableEvent; - PR_Trace; - PR_WaitProcess; - PR_WaitRecvReady; - PR_WaitSem; - PR_WaitSemaphore; - PR_Write; - PR_Writev; - PR_Yield; - PR_UnlockOrderedLock; - PR_cnvtf; - PR_dtoa; - PR_fprintf; - PR_htonl; - PR_htonll; - PR_htons; - PR_ntohl; - PR_ntohll; - PR_ntohs; - PR_smprintf; - PR_smprintf_free; - PR_snprintf; - PR_sprintf_append; - PR_sscanf; - PR_strtod; - PR_sxprintf; - PR_vfprintf; - PR_vsmprintf; - PR_vsnprintf; - PR_vsprintf_append; - PR_vsxprintf; - PRP_DestroyNakedCondVar; - PRP_NakedBroadcast; - PRP_NakedNotify; - PRP_NakedWait; - PRP_NewNakedCondVar; - PRP_TryLock; - libVersionPoint; -;+ local: *; -;+}; -;+ -;+NSPRprivate { -;+ global: - GetExecutionEnvironment; - PT_FPrintStats; - SetExecutionEnvironment; -;+ local: *; -;+}; -;+ -;+NSPR_4.1 { -;+ global: - PR_ConnectContinue; - PR_CreateIOLayer; - PR_EmulateAcceptRead; - PR_EmulateSendFile; - PR_FindFunctionSymbol; - PR_FindFunctionSymbolAndLibrary; - PR_GetMemMapAlignment; - PR_GetNumberOfProcessors; - PR_ImportPipe; - PR_SetEnv; -;+} NSPR_4.0; -;+ -;+NSPR_4.3 { -;+ global: - LL_MaxUint; - PR_CallOnceWithArg; - PR_GetLibraryFilePathname; -;+} NSPR_4.1; -;+ -;+NSPR_4.4 { -;+ global: - PR_GetPathSeparator; -;+} NSPR_4.3; -;+ -;+NSPR_4.5 { -;+ global: - PR_EnumerateAddrInfo; - PR_FreeAddrInfo; - PR_GetAddrInfoByName; - PR_GetCanonNameFromAddrInfo; -;+} NSPR_4.4; -;+ -;+NSPR_4.6 { -;+ global: - PR_GetPhysicalMemorySize; -;+} NSPR_4.5; -;+NSPR_4.7 { -;+ global: - PR_ParseTimeStringToExplodedTime; -;+} NSPR_4.6; -;+NSPR_4.8 { -;+ global: - PR_AssertCurrentThreadOwnsLock; - PR_AssertCurrentThreadInMonitor; -;+} NSPR_4.7; -;+NSPR_4.8.9 { -;+ global: - PR_GetVersion; -;+} NSPR_4.8; -;+NSPR_4.9.2 { -;+ global: - PR_GetThreadName; - PR_SetCurrentThreadName; -;+} NSPR_4.8.9; diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/nspr.rc nspr-4.10.7/mozilla/nsprpub/pr/src/nspr.rc --- nspr-4.9.5/mozilla/nsprpub/pr/src/nspr.rc 2012-03-06 13:13:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/nspr.rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include - -#define MY_LIBNAME "nspr" -#define MY_FILEDESCRIPTION "NSPR Library" - -#define STRINGIZE(x) #x -#define STRINGIZE2(x) STRINGIZE(x) -#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR) - -#ifdef _DEBUG -#define MY_DEBUG_STR " (debug)" -#define MY_FILEFLAGS_1 VS_FF_DEBUG -#else -#define MY_DEBUG_STR "" -#define MY_FILEFLAGS_1 0x0L -#endif -#if PR_BETA -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE -#else -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 -#endif - -#ifdef WINNT -#define MY_FILEOS VOS_NT_WINDOWS32 -#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR -#else -#define MY_FILEOS VOS__WINDOWS32 -#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR -#endif - -///////////////////////////////////////////////////////////////////////////// -// -// Version-information resource -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 - PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS MY_FILEFLAGS_2 - FILEOS MY_FILEOS - FILETYPE VFT_DLL - FILESUBTYPE 0x0L // not used - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" // Lang=US English, CharSet=Unicode - BEGIN - VALUE "CompanyName", "Mozilla Foundation\0" - VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" - VALUE "FileVersion", PR_VERSION "\0" - VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" - VALUE "ProductName", "Netscape Portable Runtime\0" - VALUE "ProductVersion", PR_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/os2extra.def nspr-4.10.7/mozilla/nsprpub/pr/src/os2extra.def --- nspr-4.9.5/mozilla/nsprpub/pr/src/os2extra.def 2012-03-06 13:14:00.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/os2extra.def 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. - - ; - ; Support plugins that were explicitly linked to the Visual Age - ; version of nspr4.dll. - ; - PR_NewMonitor - PR_EnterMonitor - PR_ExitMonitor - PR_GetCurrentThread - PR_AttachThread - PR_DetachThread - ; - ; Exception handler functions that are used by nsAppRunner.cpp - ; - _PR_OS2_SetFloatExcpHandler - _PR_OS2_UnsetFloatExcpHandler - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/prvrsion.c nspr-4.10.7/mozilla/nsprpub/pr/src/prvrsion.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/prvrsion.c 2012-03-06 13:14:00.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/prvrsion.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include "prvrsion.h" - -/************************************************************************/ -/**************************IDENTITY AND VERSIONING***********************/ -/************************************************************************/ -#include "_pr_bld.h" -#if !defined(_BUILD_TIME) -#ifdef HAVE_LONG_LONG -#define _BUILD_TIME 0 -#else -#define _BUILD_TIME {0, 0} -#endif -#endif -#if !defined(_BUILD_STRING) -#define _BUILD_STRING "" -#endif -#if !defined(_PRODUCTION) -#define _PRODUCTION "" -#endif -#if defined(DEBUG) -#define _DEBUG_STRING " (debug)" -#else -#define _DEBUG_STRING "" -#endif - -/* - * A trick to expand the PR_VMAJOR macro before concatenation. - */ -#define CONCAT(x, y) x ## y -#define CONCAT2(x, y) CONCAT(x, y) -#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libnspr, PR_VMAJOR) - -PRVersionDescription VERSION_DESC_NAME = -{ - /* version */ 2, /* this is the only one supported */ - /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */ - /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */ - /* vMajor */ PR_VMAJOR, /* NSPR's version number */ - /* vMinor */ PR_VMINOR, /* and minor version */ - /* vPatch */ PR_VPATCH, /* and patch */ - /* beta */ PR_BETA, /* beta build boolean */ -#if defined(DEBUG) - /* debug */ PR_TRUE, /* a debug build */ -#else - /* debug */ PR_FALSE, /* an optomized build */ -#endif - /* special */ PR_FALSE, /* they're all special, but ... */ - /* filename */ _PRODUCTION, /* the produced library name */ - /* description */ "Portable runtime", /* what we are */ - /* security */ "N/A", /* not applicable here */ - /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved", - /* comment */ "License information: http://www.mozilla.org/MPL/", - /* specialString */ "" -}; - -#ifdef XP_UNIX - -/* - * Version information for the 'ident' and 'what commands - * - * NOTE: the first component of the concatenated rcsid string - * must not end in a '$' to prevent rcs keyword substitution. - */ -static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING - " " _BUILD_STRING " $"; -static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING - " " _BUILD_STRING; - -#endif /* XP_UNIX */ - -PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void) -{ -#ifdef XP_UNIX - /* - * Add dummy references to rcsid and sccsid to prevent them - * from being optimized away as unused variables. - */ - const char *dummy; - - dummy = rcsid; - dummy = sccsid; -#endif - return &VERSION_DESC_NAME; -} /* versionEntryPointType */ - -/* prvrsion.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/.cvsignore 2001-05-12 04:53:48.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/Makefile.in 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CSRCS = \ - ptio.c \ - ptsynch.c \ - ptthread.c \ - ptmisc.c \ - $(NULL) - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/ptio.c nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/ptio.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/ptio.c 2012-12-14 03:14:45.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/ptio.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,5010 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: ptio.c -** Descritpion: Implemenation of I/O methods for pthreads -*/ - -#if defined(_PR_PTHREADS) - -#if defined(_PR_POLL_WITH_SELECT) -#if !(defined(HPUX) && defined(_USE_BIG_FDS)) -/* set fd limit for select(), before including system header files */ -#define FD_SETSIZE (16 * 1024) -#endif -#endif - -#include -#include /* for memset() */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(DARWIN) -#include /* for uname */ -#endif -#if defined(SOLARIS) || defined(UNIXWARE) -#include /* to pick up FIONREAD */ -#endif -#ifdef _PR_POLL_AVAILABLE -#include -#endif -#ifdef AIX -/* To pick up sysconf() */ -#include -#include /* for dlopen */ -#else -/* To pick up getrlimit() etc. */ -#include -#include -#endif - -#ifdef SOLARIS -/* - * Define HAVE_SENDFILEV if the system has the sendfilev() system call. - * Code built this way won't run on a system without sendfilev(). - * We can define HAVE_SENDFILEV by default when the minimum release - * of Solaris that NSPR supports has sendfilev(). - */ -#ifdef HAVE_SENDFILEV - -#include - -#define SOLARIS_SENDFILEV(a, b, c, d) sendfilev((a), (b), (c), (d)) - -#else - -#include /* for dlopen */ - -/* - * Match the definitions in . - */ -typedef struct sendfilevec { - int sfv_fd; /* input fd */ - uint_t sfv_flag; /* flags */ - off_t sfv_off; /* offset to start reading from */ - size_t sfv_len; /* amount of data */ -} sendfilevec_t; - -#define SFV_FD_SELF (-2) - -/* - * extern ssize_t sendfilev(int, const struct sendfilevec *, int, size_t *); - */ -static ssize_t (*pt_solaris_sendfilev_fptr)() = NULL; - -#define SOLARIS_SENDFILEV(a, b, c, d) \ - (*pt_solaris_sendfilev_fptr)((a), (b), (c), (d)) - -#endif /* HAVE_SENDFILEV */ -#endif /* SOLARIS */ - -/* - * The send_file() system call is available in AIX 4.3.2 or later. - * If this file is compiled on an older AIX system, it attempts to - * look up the send_file symbol at run time to determine whether - * we can use the faster PR_SendFile/PR_TransmitFile implementation based on - * send_file(). On AIX 4.3.2 or later, we can safely skip this - * runtime function dispatching and just use the send_file based - * implementation. - */ -#ifdef AIX -#ifdef SF_CLOSE -#define HAVE_SEND_FILE -#endif - -#ifdef HAVE_SEND_FILE - -#define AIX_SEND_FILE(a, b, c) send_file(a, b, c) - -#else /* HAVE_SEND_FILE */ - -/* - * The following definitions match those in - * on AIX 4.3.2. - */ - -/* - * Structure for the send_file() system call - */ -struct sf_parms { - /* --------- header parms ---------- */ - void *header_data; /* Input/Output. Points to header buf */ - uint_t header_length; /* Input/Output. Length of the header */ - /* --------- file parms ------------ */ - int file_descriptor; /* Input. File descriptor of the file */ - unsigned long long file_size; /* Output. Size of the file */ - unsigned long long file_offset; /* Input/Output. Starting offset */ - long long file_bytes; /* Input/Output. no. of bytes to send */ - /* --------- trailer parms --------- */ - void *trailer_data; /* Input/Output. Points to trailer buf */ - uint_t trailer_length; /* Input/Output. Length of the trailer */ - /* --------- return info ----------- */ - unsigned long long bytes_sent; /* Output. no. of bytes sent */ -}; - -/* - * Flags for the send_file() system call - */ -#define SF_CLOSE 0x00000001 /* close the socket after completion */ -#define SF_REUSE 0x00000002 /* reuse socket. not supported */ -#define SF_DONT_CACHE 0x00000004 /* don't apply network buffer cache */ -#define SF_SYNC_CACHE 0x00000008 /* sync/update network buffer cache */ - -/* - * prototype: size_t send_file(int *, struct sf_parms *, uint_t); - */ -static ssize_t (*pt_aix_sendfile_fptr)() = NULL; - -#define AIX_SEND_FILE(a, b, c) (*pt_aix_sendfile_fptr)(a, b, c) - -#endif /* HAVE_SEND_FILE */ -#endif /* AIX */ - -#ifdef LINUX -#include -#endif - -#include "primpl.h" - -#ifdef HAVE_NETINET_TCP_H -#include /* TCP_NODELAY, TCP_MAXSEG */ -#endif - -#ifdef LINUX -/* TCP_CORK is not defined in on Red Hat Linux 6.0 */ -#ifndef TCP_CORK -#define TCP_CORK 3 -#endif -#endif - -#ifdef _PR_IPV6_V6ONLY_PROBE -static PRBool _pr_ipv6_v6only_on_by_default; -#endif - -#if (defined(HPUX) && !defined(HPUX10_30) && !defined(HPUX11)) -#define _PRSelectFdSetArg_t int * -#elif defined(AIX4_1) -#define _PRSelectFdSetArg_t void * -#elif defined(IRIX) || (defined(AIX) && !defined(AIX4_1)) \ - || defined(OSF1) || defined(SOLARIS) \ - || defined(HPUX10_30) || defined(HPUX11) \ - || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ - || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ - || defined(BSDI) || defined(NTO) || defined(DARWIN) \ - || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) -#define _PRSelectFdSetArg_t fd_set * -#else -#error "Cannot determine architecture" -#endif - -#if defined(SOLARIS) -#ifndef PROTO_SDP -/* on solaris, SDP is a new type of protocol */ -#define PROTO_SDP 257 -#endif -#define _PR_HAVE_SDP -#elif defined(LINUX) -#ifndef AF_INET_SDP -/* on linux, SDP is a new type of address family */ -#define AF_INET_SDP 27 -#endif -#define _PR_HAVE_SDP -#endif /* LINUX */ - -static PRFileDesc *pt_SetMethods( - PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported); - -static PRLock *_pr_flock_lock; /* For PR_LockFile() etc. */ -static PRCondVar *_pr_flock_cv; /* For PR_LockFile() etc. */ -static PRLock *_pr_rename_lock; /* For PR_Rename() */ - -/**************************************************************************/ - -/* These two functions are only used in assertions. */ -#if defined(DEBUG) - -PRBool IsValidNetAddr(const PRNetAddr *addr) -{ - if ((addr != NULL) - && (addr->raw.family != AF_UNIX) - && (addr->raw.family != PR_AF_INET6) - && (addr->raw.family != AF_INET)) { - return PR_FALSE; - } - return PR_TRUE; -} - -static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len) -{ - /* - * The definition of the length of a Unix domain socket address - * is not uniform, so we don't check it. - */ - if ((addr != NULL) - && (addr->raw.family != AF_UNIX) - && (PR_NETADDR_SIZE(addr) != addr_len)) { -#if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1 - /* - * In glibc 2.1, struct sockaddr_in6 is 24 bytes. In glibc 2.2 - * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id - * field and is 28 bytes. It is possible for socket functions - * to return an addr_len greater than sizeof(struct sockaddr_in6). - * We need to allow that. (Bugzilla bug #77264) - */ - if ((PR_AF_INET6 == addr->raw.family) - && (sizeof(addr->ipv6) == addr_len)) { - return PR_TRUE; - } -#endif - return PR_FALSE; - } - return PR_TRUE; -} - -#endif /* DEBUG */ - -/*****************************************************************************/ -/************************* I/O Continuation machinery ************************/ -/*****************************************************************************/ - -/* - * The polling interval defines the maximum amount of time that a thread - * might hang up before an interrupt is noticed. - */ -#define PT_DEFAULT_POLL_MSEC 5000 -#if defined(_PR_POLL_WITH_SELECT) -#define PT_DEFAULT_SELECT_SEC (PT_DEFAULT_POLL_MSEC/PR_MSEC_PER_SEC) -#define PT_DEFAULT_SELECT_USEC \ - ((PT_DEFAULT_POLL_MSEC % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC) -#endif - -/* - * pt_SockLen is the type for the length of a socket address - * structure, used in the address length argument to bind, - * connect, accept, getsockname, getpeername, etc. Posix.1g - * defines this type as socklen_t. It is size_t or int on - * most current systems. - */ -#if defined(HAVE_SOCKLEN_T) \ - || (defined(__GLIBC__) && __GLIBC__ >= 2) -typedef socklen_t pt_SockLen; -#elif (defined(AIX) && !defined(AIX4_1)) -typedef PRSize pt_SockLen; -#else -typedef PRIntn pt_SockLen; -#endif - -typedef struct pt_Continuation pt_Continuation; -typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revents); - -typedef enum pr_ContuationStatus -{ - pt_continuation_pending, - pt_continuation_done -} pr_ContuationStatus; - -struct pt_Continuation -{ - /* The building of the continuation operation */ - ContinuationFn function; /* what function to continue */ - union { PRIntn osfd; } arg1; /* #1 - the op's fd */ - union { void* buffer; } arg2; /* #2 - primary transfer buffer */ - union { - PRSize amount; /* #3 - size of 'buffer', or */ - pt_SockLen *addr_len; /* - length of address */ -#ifdef HPUX11 - /* - * For sendfile() - */ - struct file_spec { - off_t offset; /* offset in file to send */ - size_t nbytes; /* length of file data to send */ - size_t st_size; /* file size */ - } file_spec; -#endif - } arg3; - union { PRIntn flags; } arg4; /* #4 - read/write flags */ - union { PRNetAddr *addr; } arg5; /* #5 - send/recv address */ - -#ifdef HPUX11 - /* - * For sendfile() - */ - int filedesc; /* descriptor of file to send */ - int nbytes_to_send; /* size of header and file */ -#endif /* HPUX11 */ - -#ifdef SOLARIS - /* - * For sendfilev() - */ - int nbytes_to_send; /* size of header and file */ -#endif /* SOLARIS */ - -#ifdef LINUX - /* - * For sendfile() - */ - int in_fd; /* descriptor of file to send */ - off_t offset; - size_t count; -#endif /* LINUX */ - - PRIntervalTime timeout; /* client (relative) timeout */ - - PRInt16 event; /* flags for poll()'s events */ - - /* - ** The representation and notification of the results of the operation. - ** These function can either return an int return code or a pointer to - ** some object. - */ - union { PRSize code; void *object; } result; - - PRIntn syserrno; /* in case it failed, why (errno) */ - pr_ContuationStatus status; /* the status of the operation */ -}; - -#if defined(DEBUG) - -PTDebug pt_debug; /* this is shared between several modules */ - -PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) -{ - PTDebug stats; - char buffer[100]; - PRExplodedTime tod; - PRInt64 elapsed, aMil; - stats = pt_debug; /* a copy */ - PR_ExplodeTime(stats.timeStarted, PR_LocalTimeParameters, &tod); - (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod); - - LL_SUB(elapsed, PR_Now(), stats.timeStarted); - LL_I2L(aMil, 1000000); - LL_DIV(elapsed, elapsed, aMil); - - if (NULL != msg) PR_fprintf(debug_out, "%s", msg); - PR_fprintf( - debug_out, "\tstarted: %s[%lld]\n", buffer, elapsed); - PR_fprintf( - debug_out, "\tlocks [created: %u, destroyed: %u]\n", - stats.locks_created, stats.locks_destroyed); - PR_fprintf( - debug_out, "\tlocks [acquired: %u, released: %u]\n", - stats.locks_acquired, stats.locks_released); - PR_fprintf( - debug_out, "\tcvars [created: %u, destroyed: %u]\n", - stats.cvars_created, stats.cvars_destroyed); - PR_fprintf( - debug_out, "\tcvars [notified: %u, delayed_delete: %u]\n", - stats.cvars_notified, stats.delayed_cv_deletes); -} /* PT_FPrintStats */ - -#else - -PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) -{ - /* do nothing */ -} /* PT_FPrintStats */ - -#endif /* DEBUG */ - -#if defined(_PR_POLL_WITH_SELECT) -/* - * OSF1 and HPUX report the POLLHUP event for a socket when the - * shutdown(SHUT_WR) operation is called for the remote end, even though - * the socket is still writeable. Use select(), instead of poll(), to - * workaround this problem. - */ -static void pt_poll_now_with_select(pt_Continuation *op) -{ - PRInt32 msecs; - fd_set rd, wr, *rdp, *wrp; - struct timeval tv; - PRIntervalTime epoch, now, elapsed, remaining; - PRBool wait_for_remaining; - PRThread *self = PR_GetCurrentThread(); - - PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout); - PR_ASSERT(op->arg1.osfd < FD_SETSIZE); - - switch (op->timeout) { - case PR_INTERVAL_NO_TIMEOUT: - tv.tv_sec = PT_DEFAULT_SELECT_SEC; - tv.tv_usec = PT_DEFAULT_SELECT_USEC; - do - { - PRIntn rv; - - if (op->event & POLLIN) { - FD_ZERO(&rd); - FD_SET(op->arg1.osfd, &rd); - rdp = &rd; - } else - rdp = NULL; - if (op->event & POLLOUT) { - FD_ZERO(&wr); - FD_SET(op->arg1.osfd, &wr); - wrp = ≀ - } else - wrp = NULL; - - rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv); - - if (_PT_THREAD_INTERRUPTED(self)) - { - self->state &= ~PT_THREAD_ABORTED; - op->result.code = -1; - op->syserrno = EINTR; - op->status = pt_continuation_done; - return; - } - - if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN))) - continue; /* go around the loop again */ - - if (rv > 0) - { - PRInt16 revents = 0; - - if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd)) - revents |= POLLIN; - if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr)) - revents |= POLLOUT; - - if (op->function(op, revents)) - op->status = pt_continuation_done; - } else if (rv == -1) { - op->result.code = -1; - op->syserrno = errno; - op->status = pt_continuation_done; - } - /* else, select timed out */ - } while (pt_continuation_done != op->status); - break; - default: - now = epoch = PR_IntervalNow(); - remaining = op->timeout; - do - { - PRIntn rv; - - if (op->event & POLLIN) { - FD_ZERO(&rd); - FD_SET(op->arg1.osfd, &rd); - rdp = &rd; - } else - rdp = NULL; - if (op->event & POLLOUT) { - FD_ZERO(&wr); - FD_SET(op->arg1.osfd, &wr); - wrp = ≀ - } else - wrp = NULL; - - wait_for_remaining = PR_TRUE; - msecs = (PRInt32)PR_IntervalToMilliseconds(remaining); - if (msecs > PT_DEFAULT_POLL_MSEC) { - wait_for_remaining = PR_FALSE; - msecs = PT_DEFAULT_POLL_MSEC; - } - tv.tv_sec = msecs/PR_MSEC_PER_SEC; - tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC; - rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv); - - if (_PT_THREAD_INTERRUPTED(self)) - { - self->state &= ~PT_THREAD_ABORTED; - op->result.code = -1; - op->syserrno = EINTR; - op->status = pt_continuation_done; - return; - } - - if (rv > 0) { - PRInt16 revents = 0; - - if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd)) - revents |= POLLIN; - if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr)) - revents |= POLLOUT; - - if (op->function(op, revents)) - op->status = pt_continuation_done; - - } else if ((rv == 0) || - ((errno == EINTR) || (errno == EAGAIN))) { - if (rv == 0) { /* select timed out */ - if (wait_for_remaining) - now += remaining; - else - now += PR_MillisecondsToInterval(msecs); - } else - now = PR_IntervalNow(); - elapsed = (PRIntervalTime) (now - epoch); - if (elapsed >= op->timeout) { - op->result.code = -1; - op->syserrno = ETIMEDOUT; - op->status = pt_continuation_done; - } else - remaining = op->timeout - elapsed; - } else { - op->result.code = -1; - op->syserrno = errno; - op->status = pt_continuation_done; - } - } while (pt_continuation_done != op->status); - break; - } - -} /* pt_poll_now_with_select */ - -#endif /* _PR_POLL_WITH_SELECT */ - -static void pt_poll_now(pt_Continuation *op) -{ - PRInt32 msecs; - PRIntervalTime epoch, now, elapsed, remaining; - PRBool wait_for_remaining; - PRThread *self = PR_GetCurrentThread(); - - PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout); -#if defined (_PR_POLL_WITH_SELECT) - /* - * If the fd is small enough call the select-based poll operation - */ - if (op->arg1.osfd < FD_SETSIZE) { - pt_poll_now_with_select(op); - return; - } -#endif - - switch (op->timeout) { - case PR_INTERVAL_NO_TIMEOUT: - msecs = PT_DEFAULT_POLL_MSEC; - do - { - PRIntn rv; - struct pollfd tmp_pfd; - - tmp_pfd.revents = 0; - tmp_pfd.fd = op->arg1.osfd; - tmp_pfd.events = op->event; - - rv = poll(&tmp_pfd, 1, msecs); - - if (_PT_THREAD_INTERRUPTED(self)) - { - self->state &= ~PT_THREAD_ABORTED; - op->result.code = -1; - op->syserrno = EINTR; - op->status = pt_continuation_done; - return; - } - - if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN))) - continue; /* go around the loop again */ - - if (rv > 0) - { - PRInt16 events = tmp_pfd.events; - PRInt16 revents = tmp_pfd.revents; - - if ((revents & POLLNVAL) /* busted in all cases */ - || ((events & POLLOUT) && (revents & POLLHUP))) - /* write op & hup */ - { - op->result.code = -1; - if (POLLNVAL & revents) op->syserrno = EBADF; - else if (POLLHUP & revents) op->syserrno = EPIPE; - op->status = pt_continuation_done; - } else { - if (op->function(op, revents)) - op->status = pt_continuation_done; - } - } else if (rv == -1) { - op->result.code = -1; - op->syserrno = errno; - op->status = pt_continuation_done; - } - /* else, poll timed out */ - } while (pt_continuation_done != op->status); - break; - default: - now = epoch = PR_IntervalNow(); - remaining = op->timeout; - do - { - PRIntn rv; - struct pollfd tmp_pfd; - - tmp_pfd.revents = 0; - tmp_pfd.fd = op->arg1.osfd; - tmp_pfd.events = op->event; - - wait_for_remaining = PR_TRUE; - msecs = (PRInt32)PR_IntervalToMilliseconds(remaining); - if (msecs > PT_DEFAULT_POLL_MSEC) - { - wait_for_remaining = PR_FALSE; - msecs = PT_DEFAULT_POLL_MSEC; - } - rv = poll(&tmp_pfd, 1, msecs); - - if (_PT_THREAD_INTERRUPTED(self)) - { - self->state &= ~PT_THREAD_ABORTED; - op->result.code = -1; - op->syserrno = EINTR; - op->status = pt_continuation_done; - return; - } - - if (rv > 0) - { - PRInt16 events = tmp_pfd.events; - PRInt16 revents = tmp_pfd.revents; - - if ((revents & POLLNVAL) /* busted in all cases */ - || ((events & POLLOUT) && (revents & POLLHUP))) - /* write op & hup */ - { - op->result.code = -1; - if (POLLNVAL & revents) op->syserrno = EBADF; - else if (POLLHUP & revents) op->syserrno = EPIPE; - op->status = pt_continuation_done; - } else { - if (op->function(op, revents)) - { - op->status = pt_continuation_done; - } - } - } else if ((rv == 0) || - ((errno == EINTR) || (errno == EAGAIN))) { - if (rv == 0) /* poll timed out */ - { - if (wait_for_remaining) - now += remaining; - else - now += PR_MillisecondsToInterval(msecs); - } - else - now = PR_IntervalNow(); - elapsed = (PRIntervalTime) (now - epoch); - if (elapsed >= op->timeout) { - op->result.code = -1; - op->syserrno = ETIMEDOUT; - op->status = pt_continuation_done; - } else - remaining = op->timeout - elapsed; - } else { - op->result.code = -1; - op->syserrno = errno; - op->status = pt_continuation_done; - } - } while (pt_continuation_done != op->status); - break; - } - -} /* pt_poll_now */ - -static PRIntn pt_Continue(pt_Continuation *op) -{ - op->status = pt_continuation_pending; /* set default value */ - /* - * let each thread call poll directly - */ - pt_poll_now(op); - PR_ASSERT(pt_continuation_done == op->status); - return op->result.code; -} /* pt_Continue */ - -/*****************************************************************************/ -/*********************** specific continuation functions *********************/ -/*****************************************************************************/ -static PRBool pt_connect_cont(pt_Continuation *op, PRInt16 revents) -{ - op->syserrno = _MD_unix_get_nonblocking_connect_error(op->arg1.osfd); - if (op->syserrno != 0) { - op->result.code = -1; - } else { - op->result.code = 0; - } - return PR_TRUE; /* this one is cooked */ -} /* pt_connect_cont */ - -static PRBool pt_accept_cont(pt_Continuation *op, PRInt16 revents) -{ - op->syserrno = 0; - op->result.code = accept( - op->arg1.osfd, op->arg2.buffer, op->arg3.addr_len); - if (-1 == op->result.code) - { - op->syserrno = errno; - if (EWOULDBLOCK == errno || EAGAIN == errno || ECONNABORTED == errno) - return PR_FALSE; /* do nothing - this one ain't finished */ - } - return PR_TRUE; -} /* pt_accept_cont */ - -static PRBool pt_read_cont(pt_Continuation *op, PRInt16 revents) -{ - /* - * Any number of bytes will complete the operation. It need - * not (and probably will not) satisfy the request. The only - * error we continue is EWOULDBLOCK|EAGAIN. - */ - op->result.code = read( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount); - op->syserrno = errno; - return ((-1 == op->result.code) && - (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ? - PR_FALSE : PR_TRUE; -} /* pt_read_cont */ - -static PRBool pt_recv_cont(pt_Continuation *op, PRInt16 revents) -{ - /* - * Any number of bytes will complete the operation. It need - * not (and probably will not) satisfy the request. The only - * error we continue is EWOULDBLOCK|EAGAIN. - */ -#if defined(SOLARIS) - if (0 == op->arg4.flags) - op->result.code = read( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount); - else - op->result.code = recv( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags); -#else - op->result.code = recv( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags); -#endif - op->syserrno = errno; - return ((-1 == op->result.code) && - (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ? - PR_FALSE : PR_TRUE; -} /* pt_recv_cont */ - -static PRBool pt_send_cont(pt_Continuation *op, PRInt16 revents) -{ - PRIntn bytes; -#if defined(SOLARIS) - PRInt32 tmp_amount = op->arg3.amount; -#endif - /* - * We want to write the entire amount out, no matter how many - * tries it takes. Keep advancing the buffer and the decrementing - * the amount until the amount goes away. Return the total bytes - * (which should be the original amount) when finished (or an - * error). - */ -#if defined(SOLARIS) -retry: - bytes = write(op->arg1.osfd, op->arg2.buffer, tmp_amount); -#else - bytes = send( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags); -#endif - op->syserrno = errno; - -#if defined(SOLARIS) - /* - * The write system call has been reported to return the ERANGE error - * on occasion. Try to write in smaller chunks to workaround this bug. - */ - if ((bytes == -1) && (op->syserrno == ERANGE)) - { - if (tmp_amount > 1) - { - tmp_amount = tmp_amount/2; /* half the bytes */ - goto retry; - } - } -#endif - - if (bytes >= 0) /* this is progress */ - { - char *bp = (char*)op->arg2.buffer; - bp += bytes; /* adjust the buffer pointer */ - op->arg2.buffer = bp; - op->result.code += bytes; /* accumulate the number sent */ - op->arg3.amount -= bytes; /* and reduce the required count */ - return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; - } - else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno)) - { - op->result.code = -1; - return PR_TRUE; - } - else return PR_FALSE; -} /* pt_send_cont */ - -static PRBool pt_write_cont(pt_Continuation *op, PRInt16 revents) -{ - PRIntn bytes; - /* - * We want to write the entire amount out, no matter how many - * tries it takes. Keep advancing the buffer and the decrementing - * the amount until the amount goes away. Return the total bytes - * (which should be the original amount) when finished (or an - * error). - */ - bytes = write(op->arg1.osfd, op->arg2.buffer, op->arg3.amount); - op->syserrno = errno; - if (bytes >= 0) /* this is progress */ - { - char *bp = (char*)op->arg2.buffer; - bp += bytes; /* adjust the buffer pointer */ - op->arg2.buffer = bp; - op->result.code += bytes; /* accumulate the number sent */ - op->arg3.amount -= bytes; /* and reduce the required count */ - return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; - } - else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno)) - { - op->result.code = -1; - return PR_TRUE; - } - else return PR_FALSE; -} /* pt_write_cont */ - -static PRBool pt_writev_cont(pt_Continuation *op, PRInt16 revents) -{ - PRIntn bytes; - struct iovec *iov = (struct iovec*)op->arg2.buffer; - /* - * Same rules as write, but continuing seems to be a bit more - * complicated. As the number of bytes sent grows, we have to - * redefine the vector we're pointing at. We might have to - * modify an individual vector parms or we might have to eliminate - * a pair altogether. - */ - bytes = writev(op->arg1.osfd, iov, op->arg3.amount); - op->syserrno = errno; - if (bytes >= 0) /* this is progress */ - { - PRIntn iov_index; - op->result.code += bytes; /* accumulate the number sent */ - for (iov_index = 0; iov_index < op->arg3.amount; ++iov_index) - { - /* how much progress did we make in the i/o vector? */ - if (bytes < iov[iov_index].iov_len) - { - /* this element's not done yet */ - char **bp = (char**)&(iov[iov_index].iov_base); - iov[iov_index].iov_len -= bytes; /* there's that much left */ - *bp += bytes; /* starting there */ - break; /* go off and do that */ - } - bytes -= iov[iov_index].iov_len; /* that element's consumed */ - } - op->arg2.buffer = &iov[iov_index]; /* new start of array */ - op->arg3.amount -= iov_index; /* and array length */ - return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; - } - else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno)) - { - op->result.code = -1; - return PR_TRUE; - } - else return PR_FALSE; -} /* pt_writev_cont */ - -static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents) -{ - PRIntn bytes = sendto( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags, - (struct sockaddr*)op->arg5.addr, PR_NETADDR_SIZE(op->arg5.addr)); - op->syserrno = errno; - if (bytes >= 0) /* this is progress */ - { - char *bp = (char*)op->arg2.buffer; - bp += bytes; /* adjust the buffer pointer */ - op->arg2.buffer = bp; - op->result.code += bytes; /* accumulate the number sent */ - op->arg3.amount -= bytes; /* and reduce the required count */ - return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; - } - else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno)) - { - op->result.code = -1; - return PR_TRUE; - } - else return PR_FALSE; -} /* pt_sendto_cont */ - -static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents) -{ - pt_SockLen addr_len = sizeof(PRNetAddr); - op->result.code = recvfrom( - op->arg1.osfd, op->arg2.buffer, op->arg3.amount, - op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len); - op->syserrno = errno; - return ((-1 == op->result.code) && - (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ? - PR_FALSE : PR_TRUE; -} /* pt_recvfrom_cont */ - -#ifdef AIX -static PRBool pt_aix_sendfile_cont(pt_Continuation *op, PRInt16 revents) -{ - struct sf_parms *sf_struct = (struct sf_parms *) op->arg2.buffer; - ssize_t rv; - unsigned long long saved_file_offset; - long long saved_file_bytes; - - saved_file_offset = sf_struct->file_offset; - saved_file_bytes = sf_struct->file_bytes; - sf_struct->bytes_sent = 0; - - if ((sf_struct->file_bytes > 0) && (sf_struct->file_size > 0)) - PR_ASSERT((sf_struct->file_bytes + sf_struct->file_offset) <= - sf_struct->file_size); - rv = AIX_SEND_FILE(&op->arg1.osfd, sf_struct, op->arg4.flags); - op->syserrno = errno; - - if (rv != -1) { - op->result.code += sf_struct->bytes_sent; - /* - * A bug in AIX 4.3.2 prevents the 'file_bytes' field from - * being updated. So, 'file_bytes' is maintained by NSPR to - * avoid conflict when this bug is fixed in AIX, in the future. - */ - if (saved_file_bytes != -1) - saved_file_bytes -= (sf_struct->file_offset - saved_file_offset); - sf_struct->file_bytes = saved_file_bytes; - } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) { - op->result.code = -1; - } else { - return PR_FALSE; - } - - if (rv == 1) { /* more data to send */ - return PR_FALSE; - } - - return PR_TRUE; -} -#endif /* AIX */ - -#ifdef HPUX11 -static PRBool pt_hpux_sendfile_cont(pt_Continuation *op, PRInt16 revents) -{ - struct iovec *hdtrl = (struct iovec *) op->arg2.buffer; - int count; - - count = sendfile(op->arg1.osfd, op->filedesc, op->arg3.file_spec.offset, - op->arg3.file_spec.nbytes, hdtrl, op->arg4.flags); - PR_ASSERT(count <= op->nbytes_to_send); - op->syserrno = errno; - - if (count != -1) { - op->result.code += count; - } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) { - op->result.code = -1; - } else { - return PR_FALSE; - } - if (count != -1 && count < op->nbytes_to_send) { - if (count < hdtrl[0].iov_len) { - /* header not sent */ - - hdtrl[0].iov_base = ((char *) hdtrl[0].iov_base) + count; - hdtrl[0].iov_len -= count; - - } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes)) { - /* header sent, file not sent */ - PRUint32 file_nbytes_sent = count - hdtrl[0].iov_len; - - hdtrl[0].iov_base = NULL; - hdtrl[0].iov_len = 0; - - op->arg3.file_spec.offset += file_nbytes_sent; - op->arg3.file_spec.nbytes -= file_nbytes_sent; - } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes + - hdtrl[1].iov_len)) { - PRUint32 trailer_nbytes_sent = count - (hdtrl[0].iov_len + - op->arg3.file_spec.nbytes); - - /* header sent, file sent, trailer not sent */ - - hdtrl[0].iov_base = NULL; - hdtrl[0].iov_len = 0; - /* - * set file offset and len so that no more file data is - * sent - */ - op->arg3.file_spec.offset = op->arg3.file_spec.st_size; - op->arg3.file_spec.nbytes = 0; - - hdtrl[1].iov_base =((char *) hdtrl[1].iov_base)+ trailer_nbytes_sent; - hdtrl[1].iov_len -= trailer_nbytes_sent; - } - op->nbytes_to_send -= count; - return PR_FALSE; - } - - return PR_TRUE; -} -#endif /* HPUX11 */ - -#ifdef SOLARIS -static PRBool pt_solaris_sendfile_cont(pt_Continuation *op, PRInt16 revents) -{ - struct sendfilevec *vec = (struct sendfilevec *) op->arg2.buffer; - size_t xferred; - ssize_t count; - - count = SOLARIS_SENDFILEV(op->arg1.osfd, vec, op->arg3.amount, &xferred); - op->syserrno = errno; - PR_ASSERT((count == -1) || (count == xferred)); - - if (count == -1) { - if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN - && op->syserrno != EINTR) { - op->result.code = -1; - return PR_TRUE; - } - count = xferred; - } else if (count == 0) { - /* - * We are now at EOF. The file was truncated. Solaris sendfile is - * supposed to return 0 and no error in this case, though some versions - * may return -1 and EINVAL . - */ - op->result.code = -1; - op->syserrno = 0; /* will be treated as EOF */ - return PR_TRUE; - } - PR_ASSERT(count <= op->nbytes_to_send); - - op->result.code += count; - if (count < op->nbytes_to_send) { - op->nbytes_to_send -= count; - - while (count >= vec->sfv_len) { - count -= vec->sfv_len; - vec++; - op->arg3.amount--; - } - PR_ASSERT(op->arg3.amount > 0); - - vec->sfv_off += count; - vec->sfv_len -= count; - PR_ASSERT(vec->sfv_len > 0); - op->arg2.buffer = vec; - - return PR_FALSE; - } - - return PR_TRUE; -} -#endif /* SOLARIS */ - -#ifdef LINUX -static PRBool pt_linux_sendfile_cont(pt_Continuation *op, PRInt16 revents) -{ - ssize_t rv; - off_t oldoffset; - - oldoffset = op->offset; - rv = sendfile(op->arg1.osfd, op->in_fd, &op->offset, op->count); - op->syserrno = errno; - - if (rv == -1) { - if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) { - op->result.code = -1; - return PR_TRUE; - } - rv = 0; - } - PR_ASSERT(rv == op->offset - oldoffset); - op->result.code += rv; - if (rv < op->count) { - op->count -= rv; - return PR_FALSE; - } - return PR_TRUE; -} -#endif /* LINUX */ - -void _PR_InitIO(void) -{ -#if defined(DEBUG) - memset(&pt_debug, 0, sizeof(PTDebug)); - pt_debug.timeStarted = PR_Now(); -#endif - - _pr_flock_lock = PR_NewLock(); - PR_ASSERT(NULL != _pr_flock_lock); - _pr_flock_cv = PR_NewCondVar(_pr_flock_lock); - PR_ASSERT(NULL != _pr_flock_cv); - _pr_rename_lock = PR_NewLock(); - PR_ASSERT(NULL != _pr_rename_lock); - - _PR_InitFdCache(); /* do that */ - - _pr_stdin = pt_SetMethods(0, PR_DESC_FILE, PR_FALSE, PR_TRUE); - _pr_stdout = pt_SetMethods(1, PR_DESC_FILE, PR_FALSE, PR_TRUE); - _pr_stderr = pt_SetMethods(2, PR_DESC_FILE, PR_FALSE, PR_TRUE); - PR_ASSERT(_pr_stdin && _pr_stdout && _pr_stderr); - -#ifdef _PR_IPV6_V6ONLY_PROBE - /* In Mac OS X v10.3 Panther Beta the IPV6_V6ONLY socket option - * is turned on by default, contrary to what RFC 3493, Section - * 5.3 says. So we have to turn it off. Find out whether we - * are running on such a system. - */ - { - int osfd; - osfd = socket(AF_INET6, SOCK_STREAM, 0); - if (osfd != -1) { - int on; - socklen_t optlen = sizeof(on); - if (getsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY, - &on, &optlen) == 0) { - _pr_ipv6_v6only_on_by_default = on; - } - close(osfd); - } - } -#endif -} /* _PR_InitIO */ - -void _PR_CleanupIO(void) -{ - _PR_Putfd(_pr_stdin); - _pr_stdin = NULL; - _PR_Putfd(_pr_stdout); - _pr_stdout = NULL; - _PR_Putfd(_pr_stderr); - _pr_stderr = NULL; - - _PR_CleanupFdCache(); - - if (_pr_flock_cv) - { - PR_DestroyCondVar(_pr_flock_cv); - _pr_flock_cv = NULL; - } - if (_pr_flock_lock) - { - PR_DestroyLock(_pr_flock_lock); - _pr_flock_lock = NULL; - } - if (_pr_rename_lock) - { - PR_DestroyLock(_pr_rename_lock); - _pr_rename_lock = NULL; - } -} /* _PR_CleanupIO */ - -PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd) -{ - PRFileDesc *result = NULL; - PR_ASSERT(osfd >= PR_StandardInput && osfd <= PR_StandardError); - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - switch (osfd) - { - case PR_StandardInput: result = _pr_stdin; break; - case PR_StandardOutput: result = _pr_stdout; break; - case PR_StandardError: result = _pr_stderr; break; - default: - (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - } - return result; -} /* PR_GetSpecialFD */ - -/*****************************************************************************/ -/***************************** I/O private methods ***************************/ -/*****************************************************************************/ - -static PRBool pt_TestAbort(void) -{ - PRThread *me = PR_GetCurrentThread(); - if(_PT_THREAD_INTERRUPTED(me)) - { - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - me->state &= ~PT_THREAD_ABORTED; - return PR_TRUE; - } - return PR_FALSE; -} /* pt_TestAbort */ - -static void pt_MapError(void (*mapper)(PRIntn), PRIntn syserrno) -{ - switch (syserrno) - { - case EINTR: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); break; - case ETIMEDOUT: - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); break; - default: - mapper(syserrno); - } -} /* pt_MapError */ - -static PRStatus pt_Close(PRFileDesc *fd) -{ - if ((NULL == fd) || (NULL == fd->secret) - || ((_PR_FILEDESC_OPEN != fd->secret->state) - && (_PR_FILEDESC_CLOSED != fd->secret->state))) - { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - return PR_FAILURE; - } - if (pt_TestAbort()) return PR_FAILURE; - - if (_PR_FILEDESC_OPEN == fd->secret->state) - { - if (-1 == close(fd->secret->md.osfd)) - { -#ifdef OSF1 - /* - * Bug 86941: On Tru64 UNIX V5.0A and V5.1, the close() - * system call, when called to close a TCP socket, may - * return -1 with errno set to EINVAL but the system call - * does close the socket successfully. An application - * may safely ignore the EINVAL error. This bug is fixed - * on Tru64 UNIX V5.1A and later. The defect tracking - * number is QAR 81431. - */ - if (PR_DESC_SOCKET_TCP != fd->methods->file_type - || EINVAL != errno) - { - pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno); - return PR_FAILURE; - } -#else - pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno); - return PR_FAILURE; -#endif - } - fd->secret->state = _PR_FILEDESC_CLOSED; - } - _PR_Putfd(fd); - return PR_SUCCESS; -} /* pt_Close */ - -static PRInt32 pt_Read(PRFileDesc *fd, void *buf, PRInt32 amount) -{ - PRInt32 syserrno, bytes = -1; - - if (pt_TestAbort()) return bytes; - - bytes = read(fd->secret->md.osfd, buf, amount); - syserrno = errno; - - if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) - && (!fd->secret->nonblocking)) - { - pt_Continuation op; - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = buf; - op.arg3.amount = amount; - op.timeout = PR_INTERVAL_NO_TIMEOUT; - op.function = pt_read_cont; - op.event = POLLIN | POLLPRI; - bytes = pt_Continue(&op); - syserrno = op.syserrno; - } - if (bytes < 0) - pt_MapError(_PR_MD_MAP_READ_ERROR, syserrno); - return bytes; -} /* pt_Read */ - -static PRInt32 pt_Write(PRFileDesc *fd, const void *buf, PRInt32 amount) -{ - PRInt32 syserrno, bytes = -1; - PRBool fNeedContinue = PR_FALSE; - - if (pt_TestAbort()) return bytes; - - bytes = write(fd->secret->md.osfd, buf, amount); - syserrno = errno; - - if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) ) - { - buf = (char *) buf + bytes; - amount -= bytes; - fNeedContinue = PR_TRUE; - } - if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) - && (!fd->secret->nonblocking) ) - { - bytes = 0; - fNeedContinue = PR_TRUE; - } - - if (fNeedContinue == PR_TRUE) - { - pt_Continuation op; - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = (void*)buf; - op.arg3.amount = amount; - op.timeout = PR_INTERVAL_NO_TIMEOUT; - op.result.code = bytes; /* initialize the number sent */ - op.function = pt_write_cont; - op.event = POLLOUT | POLLPRI; - bytes = pt_Continue(&op); - syserrno = op.syserrno; - } - if (bytes == -1) - pt_MapError(_PR_MD_MAP_WRITE_ERROR, syserrno); - return bytes; -} /* pt_Write */ - -static PRInt32 pt_Writev( - PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_len, PRIntervalTime timeout) -{ - PRIntn iov_index; - PRBool fNeedContinue = PR_FALSE; - PRInt32 syserrno, bytes, rv = -1; - struct iovec osiov_local[PR_MAX_IOVECTOR_SIZE], *osiov; - int osiov_len; - - if (pt_TestAbort()) return rv; - - /* Ensured by PR_Writev */ - PR_ASSERT(iov_len <= PR_MAX_IOVECTOR_SIZE); - - /* - * We can't pass iov to writev because PRIOVec and struct iovec - * may not be binary compatible. Make osiov a copy of iov and - * pass osiov to writev. We can modify osiov if we need to - * continue the operation. - */ - osiov = osiov_local; - osiov_len = iov_len; - for (iov_index = 0; iov_index < osiov_len; iov_index++) - { - osiov[iov_index].iov_base = iov[iov_index].iov_base; - osiov[iov_index].iov_len = iov[iov_index].iov_len; - } - - rv = bytes = writev(fd->secret->md.osfd, osiov, osiov_len); - syserrno = errno; - - if (!fd->secret->nonblocking) - { - if (bytes >= 0) - { - /* - * If we moved some bytes, how does that implicate the - * i/o vector list? In other words, exactly where are - * we within that array? What are the parameters for - * resumption? Maybe we're done! - */ - for ( ;osiov_len > 0; osiov++, osiov_len--) - { - if (bytes < osiov->iov_len) - { - /* this one's not done yet */ - osiov->iov_base = (char*)osiov->iov_base + bytes; - osiov->iov_len -= bytes; - break; /* go off and do that */ - } - bytes -= osiov->iov_len; /* this one's done cooked */ - } - PR_ASSERT(osiov_len > 0 || bytes == 0); - if (osiov_len > 0) - { - if (PR_INTERVAL_NO_WAIT == timeout) - { - rv = -1; - syserrno = ETIMEDOUT; - } - else fNeedContinue = PR_TRUE; - } - } - else if (syserrno == EWOULDBLOCK || syserrno == EAGAIN) - { - if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; - else - { - rv = 0; - fNeedContinue = PR_TRUE; - } - } - } - - if (fNeedContinue == PR_TRUE) - { - pt_Continuation op; - - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = (void*)osiov; - op.arg3.amount = osiov_len; - op.timeout = timeout; - op.result.code = rv; - op.function = pt_writev_cont; - op.event = POLLOUT | POLLPRI; - rv = pt_Continue(&op); - syserrno = op.syserrno; - } - if (rv == -1) pt_MapError(_PR_MD_MAP_WRITEV_ERROR, syserrno); - return rv; -} /* pt_Writev */ - -static PRInt32 pt_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence) -{ - return _PR_MD_LSEEK(fd, offset, whence); -} /* pt_Seek */ - -static PRInt64 pt_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence) -{ - return _PR_MD_LSEEK64(fd, offset, whence); -} /* pt_Seek64 */ - -static PRInt32 pt_Available_f(PRFileDesc *fd) -{ - PRInt32 result, cur, end; - - cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR); - - if (cur >= 0) - end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END); - - if ((cur < 0) || (end < 0)) { - return -1; - } - - result = end - cur; - _PR_MD_LSEEK(fd, cur, PR_SEEK_SET); - - return result; -} /* pt_Available_f */ - -static PRInt64 pt_Available64_f(PRFileDesc *fd) -{ - PRInt64 result, cur, end; - PRInt64 minus_one; - - LL_I2L(minus_one, -1); - cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR); - - if (LL_GE_ZERO(cur)) - end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END); - - if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one; - - LL_SUB(result, end, cur); - (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET); - - return result; -} /* pt_Available64_f */ - -static PRInt32 pt_Available_s(PRFileDesc *fd) -{ - PRInt32 rv, bytes = -1; - if (pt_TestAbort()) return bytes; - - rv = ioctl(fd->secret->md.osfd, FIONREAD, &bytes); - - if (rv == -1) - pt_MapError(_PR_MD_MAP_SOCKETAVAILABLE_ERROR, errno); - return bytes; -} /* pt_Available_s */ - -static PRInt64 pt_Available64_s(PRFileDesc *fd) -{ - PRInt64 rv; - LL_I2L(rv, pt_Available_s(fd)); - return rv; -} /* pt_Available64_s */ - -static PRStatus pt_FileInfo(PRFileDesc *fd, PRFileInfo *info) -{ - PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, info); - return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; -} /* pt_FileInfo */ - -static PRStatus pt_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info) -{ - PRInt32 rv = _PR_MD_GETOPENFILEINFO64(fd, info); - return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; -} /* pt_FileInfo64 */ - -static PRStatus pt_Synch(PRFileDesc *fd) -{ - return (NULL == fd) ? PR_FAILURE : PR_SUCCESS; -} /* pt_Synch */ - -static PRStatus pt_Fsync(PRFileDesc *fd) -{ - PRIntn rv = -1; - if (pt_TestAbort()) return PR_FAILURE; - - rv = fsync(fd->secret->md.osfd); - if (rv < 0) { - pt_MapError(_PR_MD_MAP_FSYNC_ERROR, errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} /* pt_Fsync */ - -static PRStatus pt_Connect( - PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) -{ - PRIntn rv = -1, syserrno; - pt_SockLen addr_len; - const PRNetAddr *addrp = addr; -#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) - PRUint16 md_af = addr->raw.family; - PRNetAddr addrCopy; -#endif - - if (pt_TestAbort()) return PR_FAILURE; - - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - addr_len = PR_NETADDR_SIZE(addr); -#if defined(_PR_INET6) - if (addr->raw.family == PR_AF_INET6) { - md_af = AF_INET6; -#ifndef _PR_HAVE_SOCKADDR_LEN - addrCopy = *addr; - addrCopy.raw.family = AF_INET6; - addrp = &addrCopy; -#endif - } -#endif - -#ifdef _PR_HAVE_SOCKADDR_LEN - addrCopy = *addr; - ((struct sockaddr*)&addrCopy)->sa_len = addr_len; - ((struct sockaddr*)&addrCopy)->sa_family = md_af; - addrp = &addrCopy; -#endif - rv = connect(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len); - syserrno = errno; - if ((-1 == rv) && (EINPROGRESS == syserrno) && (!fd->secret->nonblocking)) - { - if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; - else - { - pt_Continuation op; - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = (void*)addrp; - op.arg3.amount = addr_len; - op.timeout = timeout; - op.function = pt_connect_cont; - op.event = POLLOUT | POLLPRI; - rv = pt_Continue(&op); - syserrno = op.syserrno; - } - } - if (-1 == rv) { - pt_MapError(_PR_MD_MAP_CONNECT_ERROR, syserrno); - return PR_FAILURE; - } - return PR_SUCCESS; -} /* pt_Connect */ - -static PRStatus pt_ConnectContinue( - PRFileDesc *fd, PRInt16 out_flags) -{ - int err; - PRInt32 osfd; - - if (out_flags & PR_POLL_NVAL) - { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - return PR_FAILURE; - } - if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR - | PR_POLL_HUP)) == 0) - { - PR_ASSERT(out_flags == 0); - PR_SetError(PR_IN_PROGRESS_ERROR, 0); - return PR_FAILURE; - } - - osfd = fd->secret->md.osfd; - - err = _MD_unix_get_nonblocking_connect_error(osfd); - if (err != 0) - { - _PR_MD_MAP_CONNECT_ERROR(err); - return PR_FAILURE; - } - return PR_SUCCESS; -} /* pt_ConnectContinue */ - -PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd) -{ - /* Find the NSPR layer and invoke its connectcontinue method */ - PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - - if (NULL == bottom) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - return pt_ConnectContinue(bottom, pd->out_flags); -} /* PR_GetConnectStatus */ - -static PRFileDesc* pt_Accept( - PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout) -{ - PRFileDesc *newfd = NULL; - PRIntn syserrno, osfd = -1; - pt_SockLen addr_len = sizeof(PRNetAddr); -#ifdef SYMBIAN - PRNetAddr dummy_addr; -#endif - - if (pt_TestAbort()) return newfd; - -#ifdef SYMBIAN - /* On Symbian OS, accept crashes if addr is NULL. */ - if (!addr) - addr = &dummy_addr; -#endif - -#ifdef _PR_STRICT_ADDR_LEN - if (addr) - { - /* - * Set addr->raw.family just so that we can use the - * PR_NETADDR_SIZE macro. - */ - addr->raw.family = fd->secret->af; - addr_len = PR_NETADDR_SIZE(addr); - } -#endif - - osfd = accept(fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len); - syserrno = errno; - - if (osfd == -1) - { - if (fd->secret->nonblocking) goto failed; - - if (EWOULDBLOCK != syserrno && EAGAIN != syserrno - && ECONNABORTED != syserrno) - goto failed; - else - { - if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; - else - { - pt_Continuation op; - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = addr; - op.arg3.addr_len = &addr_len; - op.timeout = timeout; - op.function = pt_accept_cont; - op.event = POLLIN | POLLPRI; - osfd = pt_Continue(&op); - syserrno = op.syserrno; - } - if (osfd < 0) goto failed; - } - } -#ifdef _PR_HAVE_SOCKADDR_LEN - /* ignore the sa_len field of struct sockaddr */ - if (addr) - { - addr->raw.family = ((struct sockaddr*)addr)->sa_family; - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ -#ifdef _PR_INET6 - if (addr && (AF_INET6 == addr->raw.family)) - addr->raw.family = PR_AF_INET6; -#endif - newfd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_TRUE, PR_FALSE); - if (newfd == NULL) close(osfd); /* $$$ whoops! this doesn't work $$$ */ - else - { - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); -#ifdef LINUX - /* - * On Linux, experiments showed that the accepted sockets - * inherit the TCP_NODELAY socket option of the listening - * socket. - */ - newfd->secret->md.tcp_nodelay = fd->secret->md.tcp_nodelay; -#endif - } - return newfd; - -failed: - pt_MapError(_PR_MD_MAP_ACCEPT_ERROR, syserrno); - return NULL; -} /* pt_Accept */ - -static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr) -{ - PRIntn rv; - pt_SockLen addr_len; - const PRNetAddr *addrp = addr; -#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) - PRUint16 md_af = addr->raw.family; - PRNetAddr addrCopy; -#endif - - if (pt_TestAbort()) return PR_FAILURE; - - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - if (addr->raw.family == AF_UNIX) - { - /* Disallow relative pathnames */ - if (addr->local.path[0] != '/') - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - } - -#if defined(_PR_INET6) - if (addr->raw.family == PR_AF_INET6) { - md_af = AF_INET6; -#ifndef _PR_HAVE_SOCKADDR_LEN - addrCopy = *addr; - addrCopy.raw.family = AF_INET6; - addrp = &addrCopy; -#endif - } -#endif - - addr_len = PR_NETADDR_SIZE(addr); -#ifdef _PR_HAVE_SOCKADDR_LEN - addrCopy = *addr; - ((struct sockaddr*)&addrCopy)->sa_len = addr_len; - ((struct sockaddr*)&addrCopy)->sa_family = md_af; - addrp = &addrCopy; -#endif - rv = bind(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len); - - if (rv == -1) { - pt_MapError(_PR_MD_MAP_BIND_ERROR, errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} /* pt_Bind */ - -static PRStatus pt_Listen(PRFileDesc *fd, PRIntn backlog) -{ - PRIntn rv; - - if (pt_TestAbort()) return PR_FAILURE; - - rv = listen(fd->secret->md.osfd, backlog); - if (rv == -1) { - pt_MapError(_PR_MD_MAP_LISTEN_ERROR, errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} /* pt_Listen */ - -static PRStatus pt_Shutdown(PRFileDesc *fd, PRIntn how) -{ - PRIntn rv = -1; - if (pt_TestAbort()) return PR_FAILURE; - - rv = shutdown(fd->secret->md.osfd, how); - - if (rv == -1) { - pt_MapError(_PR_MD_MAP_SHUTDOWN_ERROR, errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} /* pt_Shutdown */ - -static PRInt16 pt_Poll(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) -{ - *out_flags = 0; - return in_flags; -} /* pt_Poll */ - -static PRInt32 pt_Recv( - PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - PRInt32 syserrno, bytes = -1; - PRIntn osflags; - - if (0 == flags) - osflags = 0; - else if (PR_MSG_PEEK == flags) - { -#ifdef SYMBIAN - /* MSG_PEEK doesn't work as expected. */ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return bytes; -#else - osflags = MSG_PEEK; -#endif - } - else - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return bytes; - } - - if (pt_TestAbort()) return bytes; - - /* recv() is a much slower call on pre-2.6 Solaris than read(). */ -#if defined(SOLARIS) - if (0 == osflags) - bytes = read(fd->secret->md.osfd, buf, amount); - else - bytes = recv(fd->secret->md.osfd, buf, amount, osflags); -#else - bytes = recv(fd->secret->md.osfd, buf, amount, osflags); -#endif - syserrno = errno; - - if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) - && (!fd->secret->nonblocking)) - { - if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; - else - { - pt_Continuation op; - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = buf; - op.arg3.amount = amount; - op.arg4.flags = osflags; - op.timeout = timeout; - op.function = pt_recv_cont; - op.event = POLLIN | POLLPRI; - bytes = pt_Continue(&op); - syserrno = op.syserrno; - } - } - if (bytes < 0) - pt_MapError(_PR_MD_MAP_RECV_ERROR, syserrno); - return bytes; -} /* pt_Recv */ - -static PRInt32 pt_SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount) -{ - return pt_Recv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); -} /* pt_SocketRead */ - -static PRInt32 pt_Send( - PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - PRInt32 syserrno, bytes = -1; - PRBool fNeedContinue = PR_FALSE; -#if defined(SOLARIS) - PRInt32 tmp_amount = amount; -#endif - - /* - * Under HP-UX DCE threads, pthread.h includes dce/cma_ux.h, - * which has the following: - * # define send cma_send - * extern int cma_send (int , void *, int, int ); - * So we need to cast away the 'const' of argument #2 for send(). - */ -#if defined (HPUX) && defined(_PR_DCETHREADS) -#define PT_SENDBUF_CAST (void *) -#else -#define PT_SENDBUF_CAST -#endif - - if (pt_TestAbort()) return bytes; - - /* - * On pre-2.6 Solaris, send() is much slower than write(). - * On 2.6 and beyond, with in-kernel sockets, send() and - * write() are fairly equivalent in performance. - */ -#if defined(SOLARIS) - PR_ASSERT(0 == flags); -retry: - bytes = write(fd->secret->md.osfd, PT_SENDBUF_CAST buf, tmp_amount); -#else - bytes = send(fd->secret->md.osfd, PT_SENDBUF_CAST buf, amount, flags); -#endif - syserrno = errno; - -#if defined(SOLARIS) - /* - * The write system call has been reported to return the ERANGE error - * on occasion. Try to write in smaller chunks to workaround this bug. - */ - if ((bytes == -1) && (syserrno == ERANGE)) - { - if (tmp_amount > 1) - { - tmp_amount = tmp_amount/2; /* half the bytes */ - goto retry; - } - } -#endif - - if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) ) - { - if (PR_INTERVAL_NO_WAIT == timeout) - { - bytes = -1; - syserrno = ETIMEDOUT; - } - else - { - buf = (char *) buf + bytes; - amount -= bytes; - fNeedContinue = PR_TRUE; - } - } - if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) - && (!fd->secret->nonblocking) ) - { - if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; - else - { - bytes = 0; - fNeedContinue = PR_TRUE; - } - } - - if (fNeedContinue == PR_TRUE) - { - pt_Continuation op; - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = (void*)buf; - op.arg3.amount = amount; - op.arg4.flags = flags; - op.timeout = timeout; - op.result.code = bytes; /* initialize the number sent */ - op.function = pt_send_cont; - op.event = POLLOUT | POLLPRI; - bytes = pt_Continue(&op); - syserrno = op.syserrno; - } - if (bytes == -1) - pt_MapError(_PR_MD_MAP_SEND_ERROR, syserrno); - return bytes; -} /* pt_Send */ - -static PRInt32 pt_SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount) -{ - return pt_Send(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); -} /* pt_SocketWrite */ - -static PRInt32 pt_SendTo( - PRFileDesc *fd, const void *buf, - PRInt32 amount, PRIntn flags, const PRNetAddr *addr, - PRIntervalTime timeout) -{ - PRInt32 syserrno, bytes = -1; - PRBool fNeedContinue = PR_FALSE; - pt_SockLen addr_len; - const PRNetAddr *addrp = addr; -#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) - PRUint16 md_af = addr->raw.family; - PRNetAddr addrCopy; -#endif - - if (pt_TestAbort()) return bytes; - - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); -#if defined(_PR_INET6) - if (addr->raw.family == PR_AF_INET6) { - md_af = AF_INET6; -#ifndef _PR_HAVE_SOCKADDR_LEN - addrCopy = *addr; - addrCopy.raw.family = AF_INET6; - addrp = &addrCopy; -#endif - } -#endif - - addr_len = PR_NETADDR_SIZE(addr); -#ifdef _PR_HAVE_SOCKADDR_LEN - addrCopy = *addr; - ((struct sockaddr*)&addrCopy)->sa_len = addr_len; - ((struct sockaddr*)&addrCopy)->sa_family = md_af; - addrp = &addrCopy; -#endif - bytes = sendto( - fd->secret->md.osfd, buf, amount, flags, - (struct sockaddr*)addrp, addr_len); - syserrno = errno; - if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) - && (!fd->secret->nonblocking) ) - { - if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; - else fNeedContinue = PR_TRUE; - } - if (fNeedContinue == PR_TRUE) - { - pt_Continuation op; - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = (void*)buf; - op.arg3.amount = amount; - op.arg4.flags = flags; - op.arg5.addr = (PRNetAddr*)addrp; - op.timeout = timeout; - op.result.code = 0; /* initialize the number sent */ - op.function = pt_sendto_cont; - op.event = POLLOUT | POLLPRI; - bytes = pt_Continue(&op); - syserrno = op.syserrno; - } - if (bytes < 0) - pt_MapError(_PR_MD_MAP_SENDTO_ERROR, syserrno); - return bytes; -} /* pt_SendTo */ - -static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) -{ - PRBool fNeedContinue = PR_FALSE; - PRInt32 syserrno, bytes = -1; - pt_SockLen addr_len = sizeof(PRNetAddr); - - if (pt_TestAbort()) return bytes; - - bytes = recvfrom( - fd->secret->md.osfd, buf, amount, flags, - (struct sockaddr*)addr, &addr_len); - syserrno = errno; - - if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) - && (!fd->secret->nonblocking) ) - { - if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; - else fNeedContinue = PR_TRUE; - } - - if (fNeedContinue == PR_TRUE) - { - pt_Continuation op; - op.arg1.osfd = fd->secret->md.osfd; - op.arg2.buffer = buf; - op.arg3.amount = amount; - op.arg4.flags = flags; - op.arg5.addr = addr; - op.timeout = timeout; - op.function = pt_recvfrom_cont; - op.event = POLLIN | POLLPRI; - bytes = pt_Continue(&op); - syserrno = op.syserrno; - } - if (bytes >= 0) - { -#ifdef _PR_HAVE_SOCKADDR_LEN - /* ignore the sa_len field of struct sockaddr */ - if (addr) - { - addr->raw.family = ((struct sockaddr*)addr)->sa_family; - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ -#ifdef _PR_INET6 - if (addr && (AF_INET6 == addr->raw.family)) - addr->raw.family = PR_AF_INET6; -#endif - } - else - pt_MapError(_PR_MD_MAP_RECVFROM_ERROR, syserrno); - return bytes; -} /* pt_RecvFrom */ - -#ifdef AIX -#ifndef HAVE_SEND_FILE -static pthread_once_t pt_aix_sendfile_once_block = PTHREAD_ONCE_INIT; - -static void pt_aix_sendfile_init_routine(void) -{ - void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); - pt_aix_sendfile_fptr = (ssize_t (*)()) dlsym(handle, "send_file"); - dlclose(handle); -} - -/* - * pt_AIXDispatchSendFile - */ -static PRInt32 pt_AIXDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - int rv; - - rv = pthread_once(&pt_aix_sendfile_once_block, - pt_aix_sendfile_init_routine); - PR_ASSERT(0 == rv); - if (pt_aix_sendfile_fptr) { - return pt_AIXSendFile(sd, sfd, flags, timeout); - } else { - return PR_EmulateSendFile(sd, sfd, flags, timeout); - } -} -#endif /* !HAVE_SEND_FILE */ - - -/* - * pt_AIXSendFile - * - * Send file sfd->fd across socket sd. If specified, header and trailer - * buffers are sent before and after the file, respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - * This implementation takes advantage of the send_file() system - * call available in AIX 4.3.2. - */ - -static PRInt32 pt_AIXSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - struct sf_parms sf_struct; - uint_t send_flags; - ssize_t rv; - int syserrno; - PRInt32 count; - unsigned long long saved_file_offset; - long long saved_file_bytes; - - sf_struct.header_data = (void *) sfd->header; /* cast away the 'const' */ - sf_struct.header_length = sfd->hlen; - sf_struct.file_descriptor = sfd->fd->secret->md.osfd; - sf_struct.file_size = 0; - sf_struct.file_offset = sfd->file_offset; - if (sfd->file_nbytes == 0) - sf_struct.file_bytes = -1; - else - sf_struct.file_bytes = sfd->file_nbytes; - sf_struct.trailer_data = (void *) sfd->trailer; - sf_struct.trailer_length = sfd->tlen; - sf_struct.bytes_sent = 0; - - saved_file_offset = sf_struct.file_offset; - saved_file_bytes = sf_struct.file_bytes; - - send_flags = 0; /* flags processed at the end */ - - /* The first argument to send_file() is int*. */ - PR_ASSERT(sizeof(int) == sizeof(sd->secret->md.osfd)); - do { - rv = AIX_SEND_FILE(&sd->secret->md.osfd, &sf_struct, send_flags); - } while (rv == -1 && (syserrno = errno) == EINTR); - - if (rv == -1) { - if (syserrno == EAGAIN || syserrno == EWOULDBLOCK) { - count = 0; /* Not a real error. Need to continue. */ - } else { - count = -1; - } - } else { - count = sf_struct.bytes_sent; - /* - * A bug in AIX 4.3.2 prevents the 'file_bytes' field from - * being updated. So, 'file_bytes' is maintained by NSPR to - * avoid conflict when this bug is fixed in AIX, in the future. - */ - if (saved_file_bytes != -1) - saved_file_bytes -= (sf_struct.file_offset - saved_file_offset); - sf_struct.file_bytes = saved_file_bytes; - } - - if ((rv == 1) || ((rv == -1) && (count == 0))) { - pt_Continuation op; - - op.arg1.osfd = sd->secret->md.osfd; - op.arg2.buffer = &sf_struct; - op.arg4.flags = send_flags; - op.result.code = count; - op.timeout = timeout; - op.function = pt_aix_sendfile_cont; - op.event = POLLOUT | POLLPRI; - count = pt_Continue(&op); - syserrno = op.syserrno; - } - - if (count == -1) { - pt_MapError(_MD_aix_map_sendfile_error, syserrno); - return -1; - } - if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { - PR_Close(sd); - } - PR_ASSERT(count == (sfd->hlen + sfd->tlen + - ((sfd->file_nbytes == 0) ? - sf_struct.file_size - sfd->file_offset : - sfd->file_nbytes))); - return count; -} -#endif /* AIX */ - -#ifdef HPUX11 -/* - * pt_HPUXSendFile - * - * Send file sfd->fd across socket sd. If specified, header and trailer - * buffers are sent before and after the file, respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - * This implementation takes advantage of the sendfile() system - * call available in HP-UX B.11.00. - */ - -static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - struct stat statbuf; - size_t nbytes_to_send, file_nbytes_to_send; - struct iovec hdtrl[2]; /* optional header and trailer buffers */ - int send_flags; - PRInt32 count; - int syserrno; - - if (sfd->file_nbytes == 0) { - /* Get file size */ - if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { - _PR_MD_MAP_FSTAT_ERROR(errno); - return -1; - } - file_nbytes_to_send = statbuf.st_size - sfd->file_offset; - } else { - file_nbytes_to_send = sfd->file_nbytes; - } - nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send; - - hdtrl[0].iov_base = (void *) sfd->header; /* cast away the 'const' */ - hdtrl[0].iov_len = sfd->hlen; - hdtrl[1].iov_base = (void *) sfd->trailer; - hdtrl[1].iov_len = sfd->tlen; - /* - * SF_DISCONNECT seems to close the socket even if sendfile() - * only does a partial send on a nonblocking socket. This - * would prevent the subsequent sendfile() calls on that socket - * from working. So we don't use the SD_DISCONNECT flag. - */ - send_flags = 0; - - do { - count = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd, - sfd->file_offset, file_nbytes_to_send, hdtrl, send_flags); - } while (count == -1 && (syserrno = errno) == EINTR); - - if (count == -1 && (syserrno == EAGAIN || syserrno == EWOULDBLOCK)) { - count = 0; - } - if (count != -1 && count < nbytes_to_send) { - pt_Continuation op; - - if (count < sfd->hlen) { - /* header not sent */ - - hdtrl[0].iov_base = ((char *) sfd->header) + count; - hdtrl[0].iov_len = sfd->hlen - count; - op.arg3.file_spec.offset = sfd->file_offset; - op.arg3.file_spec.nbytes = file_nbytes_to_send; - } else if (count < (sfd->hlen + file_nbytes_to_send)) { - /* header sent, file not sent */ - - hdtrl[0].iov_base = NULL; - hdtrl[0].iov_len = 0; - - op.arg3.file_spec.offset = sfd->file_offset + count - sfd->hlen; - op.arg3.file_spec.nbytes = file_nbytes_to_send - (count - sfd->hlen); - } else if (count < (sfd->hlen + file_nbytes_to_send + sfd->tlen)) { - PRUint32 trailer_nbytes_sent; - - /* header sent, file sent, trailer not sent */ - - hdtrl[0].iov_base = NULL; - hdtrl[0].iov_len = 0; - /* - * set file offset and len so that no more file data is - * sent - */ - op.arg3.file_spec.offset = statbuf.st_size; - op.arg3.file_spec.nbytes = 0; - - trailer_nbytes_sent = count - sfd->hlen - file_nbytes_to_send; - hdtrl[1].iov_base = ((char *) sfd->trailer) + trailer_nbytes_sent; - hdtrl[1].iov_len = sfd->tlen - trailer_nbytes_sent; - } - - op.arg1.osfd = sd->secret->md.osfd; - op.filedesc = sfd->fd->secret->md.osfd; - op.arg2.buffer = hdtrl; - op.arg3.file_spec.st_size = statbuf.st_size; - op.arg4.flags = send_flags; - op.nbytes_to_send = nbytes_to_send - count; - op.result.code = count; - op.timeout = timeout; - op.function = pt_hpux_sendfile_cont; - op.event = POLLOUT | POLLPRI; - count = pt_Continue(&op); - syserrno = op.syserrno; - } - - if (count == -1) { - pt_MapError(_MD_hpux_map_sendfile_error, syserrno); - return -1; - } - if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { - PR_Close(sd); - } - PR_ASSERT(count == nbytes_to_send); - return count; -} - -#endif /* HPUX11 */ - -#ifdef SOLARIS - -/* - * pt_SolarisSendFile - * - * Send file sfd->fd across socket sd. If specified, header and trailer - * buffers are sent before and after the file, respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - * This implementation takes advantage of the sendfilev() system - * call available in Solaris 8. - */ - -static PRInt32 pt_SolarisSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - struct stat statbuf; - size_t nbytes_to_send, file_nbytes_to_send; - struct sendfilevec sfv_struct[3]; - int sfvcnt = 0; - size_t xferred; - PRInt32 count; - int syserrno; - - if (sfd->file_nbytes == 0) { - /* Get file size */ - if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { - _PR_MD_MAP_FSTAT_ERROR(errno); - return -1; - } - file_nbytes_to_send = statbuf.st_size - sfd->file_offset; - } else { - file_nbytes_to_send = sfd->file_nbytes; - } - - nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send; - - if (sfd->hlen != 0) { - sfv_struct[sfvcnt].sfv_fd = SFV_FD_SELF; - sfv_struct[sfvcnt].sfv_flag = 0; - sfv_struct[sfvcnt].sfv_off = (off_t) sfd->header; - sfv_struct[sfvcnt].sfv_len = sfd->hlen; - sfvcnt++; - } - - if (file_nbytes_to_send != 0) { - sfv_struct[sfvcnt].sfv_fd = sfd->fd->secret->md.osfd; - sfv_struct[sfvcnt].sfv_flag = 0; - sfv_struct[sfvcnt].sfv_off = sfd->file_offset; - sfv_struct[sfvcnt].sfv_len = file_nbytes_to_send; - sfvcnt++; - } - - if (sfd->tlen != 0) { - sfv_struct[sfvcnt].sfv_fd = SFV_FD_SELF; - sfv_struct[sfvcnt].sfv_flag = 0; - sfv_struct[sfvcnt].sfv_off = (off_t) sfd->trailer; - sfv_struct[sfvcnt].sfv_len = sfd->tlen; - sfvcnt++; - } - - if (0 == sfvcnt) { - count = 0; - goto done; - } - - /* - * Strictly speaking, we may have sent some bytes when the - * sendfilev() is interrupted and we should retry it from an - * updated offset. We are not doing that here. - */ - count = SOLARIS_SENDFILEV(sd->secret->md.osfd, sfv_struct, - sfvcnt, &xferred); - - PR_ASSERT((count == -1) || (count == xferred)); - - if (count == -1) { - syserrno = errno; - if (syserrno == EINTR - || syserrno == EAGAIN || syserrno == EWOULDBLOCK) { - count = xferred; - } - } else if (count == 0) { - /* - * We are now at EOF. The file was truncated. Solaris sendfile is - * supposed to return 0 and no error in this case, though some versions - * may return -1 and EINVAL . - */ - count = -1; - syserrno = 0; /* will be treated as EOF */ - } - - if (count != -1 && count < nbytes_to_send) { - pt_Continuation op; - struct sendfilevec *vec = sfv_struct; - PRInt32 rem = count; - - while (rem >= vec->sfv_len) { - rem -= vec->sfv_len; - vec++; - sfvcnt--; - } - PR_ASSERT(sfvcnt > 0); - - vec->sfv_off += rem; - vec->sfv_len -= rem; - PR_ASSERT(vec->sfv_len > 0); - - op.arg1.osfd = sd->secret->md.osfd; - op.arg2.buffer = vec; - op.arg3.amount = sfvcnt; - op.arg4.flags = 0; - op.nbytes_to_send = nbytes_to_send - count; - op.result.code = count; - op.timeout = timeout; - op.function = pt_solaris_sendfile_cont; - op.event = POLLOUT | POLLPRI; - count = pt_Continue(&op); - syserrno = op.syserrno; - } - -done: - if (count == -1) { - pt_MapError(_MD_solaris_map_sendfile_error, syserrno); - return -1; - } - if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { - PR_Close(sd); - } - PR_ASSERT(count == nbytes_to_send); - return count; -} - -#ifndef HAVE_SENDFILEV -static pthread_once_t pt_solaris_sendfilev_once_block = PTHREAD_ONCE_INIT; - -static void pt_solaris_sendfilev_init_routine(void) -{ - void *handle; - PRBool close_it = PR_FALSE; - - /* - * We do not want to unload libsendfile.so. This handle is leaked - * intentionally. - */ - handle = dlopen("libsendfile.so", RTLD_LAZY | RTLD_GLOBAL); - PR_LOG(_pr_io_lm, PR_LOG_DEBUG, - ("dlopen(libsendfile.so) returns %p", handle)); - - if (NULL == handle) { - /* - * The dlopen(0, mode) call is to allow for the possibility that - * sendfilev() may become part of a standard system library in a - * future Solaris release. - */ - handle = dlopen(0, RTLD_LAZY | RTLD_GLOBAL); - PR_LOG(_pr_io_lm, PR_LOG_DEBUG, - ("dlopen(0) returns %p", handle)); - close_it = PR_TRUE; - } - pt_solaris_sendfilev_fptr = (ssize_t (*)()) dlsym(handle, "sendfilev"); - PR_LOG(_pr_io_lm, PR_LOG_DEBUG, - ("dlsym(sendfilev) returns %p", pt_solaris_sendfilev_fptr)); - - if (close_it) { - dlclose(handle); - } -} - -/* - * pt_SolarisDispatchSendFile - */ -static PRInt32 pt_SolarisDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - int rv; - - rv = pthread_once(&pt_solaris_sendfilev_once_block, - pt_solaris_sendfilev_init_routine); - PR_ASSERT(0 == rv); - if (pt_solaris_sendfilev_fptr) { - return pt_SolarisSendFile(sd, sfd, flags, timeout); - } else { - return PR_EmulateSendFile(sd, sfd, flags, timeout); - } -} -#endif /* !HAVE_SENDFILEV */ - -#endif /* SOLARIS */ - -#ifdef LINUX -/* - * pt_LinuxSendFile - * - * Send file sfd->fd across socket sd. If specified, header and trailer - * buffers are sent before and after the file, respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - * This implementation takes advantage of the sendfile() system - * call available in Linux kernel 2.2 or higher. - */ - -static PRInt32 pt_LinuxSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - struct stat statbuf; - size_t file_nbytes_to_send; - PRInt32 count = 0; - ssize_t rv; - int syserrno; - off_t offset; - PRBool tcp_cork_enabled = PR_FALSE; - int tcp_cork; - - if (sfd->file_nbytes == 0) { - /* Get file size */ - if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { - _PR_MD_MAP_FSTAT_ERROR(errno); - return -1; - } - file_nbytes_to_send = statbuf.st_size - sfd->file_offset; - } else { - file_nbytes_to_send = sfd->file_nbytes; - } - - if ((sfd->hlen != 0 || sfd->tlen != 0) - && sd->secret->md.tcp_nodelay == 0) { - tcp_cork = 1; - if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK, - &tcp_cork, sizeof tcp_cork) == 0) { - tcp_cork_enabled = PR_TRUE; - } else { - syserrno = errno; - if (syserrno != EINVAL) { - _PR_MD_MAP_SETSOCKOPT_ERROR(syserrno); - return -1; - } - /* - * The most likely reason for the EINVAL error is that - * TCP_NODELAY is set (with a function other than - * PR_SetSocketOption). This is not fatal, so we keep - * on going. - */ - PR_LOG(_pr_io_lm, PR_LOG_WARNING, - ("pt_LinuxSendFile: " - "setsockopt(TCP_CORK) failed with EINVAL\n")); - } - } - - if (sfd->hlen != 0) { - count = PR_Send(sd, sfd->header, sfd->hlen, 0, timeout); - if (count == -1) { - goto failed; - } - } - - if (file_nbytes_to_send != 0) { - offset = sfd->file_offset; - do { - rv = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd, - &offset, file_nbytes_to_send); - } while (rv == -1 && (syserrno = errno) == EINTR); - if (rv == -1) { - if (syserrno != EAGAIN && syserrno != EWOULDBLOCK) { - _MD_linux_map_sendfile_error(syserrno); - count = -1; - goto failed; - } - rv = 0; - } - PR_ASSERT(rv == offset - sfd->file_offset); - count += rv; - - if (rv < file_nbytes_to_send) { - pt_Continuation op; - - op.arg1.osfd = sd->secret->md.osfd; - op.in_fd = sfd->fd->secret->md.osfd; - op.offset = offset; - op.count = file_nbytes_to_send - rv; - op.result.code = count; - op.timeout = timeout; - op.function = pt_linux_sendfile_cont; - op.event = POLLOUT | POLLPRI; - count = pt_Continue(&op); - syserrno = op.syserrno; - if (count == -1) { - pt_MapError(_MD_linux_map_sendfile_error, syserrno); - goto failed; - } - } - } - - if (sfd->tlen != 0) { - rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout); - if (rv == -1) { - count = -1; - goto failed; - } - count += rv; - } - -failed: - if (tcp_cork_enabled) { - tcp_cork = 0; - if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK, - &tcp_cork, sizeof tcp_cork) == -1 && count != -1) { - _PR_MD_MAP_SETSOCKOPT_ERROR(errno); - count = -1; - } - } - if (count != -1) { - if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { - PR_Close(sd); - } - PR_ASSERT(count == sfd->hlen + sfd->tlen + file_nbytes_to_send); - } - return count; -} -#endif /* LINUX */ - -#ifdef AIX -extern int _pr_aix_send_file_use_disabled; -#endif - -static PRInt32 pt_SendFile( - PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - if (pt_TestAbort()) return -1; - /* The socket must be in blocking mode. */ - if (sd->secret->nonblocking) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } -#ifdef HPUX11 - return(pt_HPUXSendFile(sd, sfd, flags, timeout)); -#elif defined(AIX) -#ifdef HAVE_SEND_FILE - /* - * A bug in AIX 4.3.2 results in corruption of data transferred by - * send_file(); AIX patch PTF U463956 contains the fix. A user can - * disable the use of send_file function in NSPR, when this patch is - * not installed on the system, by setting the envionment variable - * NSPR_AIX_SEND_FILE_USE_DISABLED to 1. - */ - if (_pr_aix_send_file_use_disabled) - return(PR_EmulateSendFile(sd, sfd, flags, timeout)); - else - return(pt_AIXSendFile(sd, sfd, flags, timeout)); -#else - return(PR_EmulateSendFile(sd, sfd, flags, timeout)); - /* return(pt_AIXDispatchSendFile(sd, sfd, flags, timeout));*/ -#endif /* HAVE_SEND_FILE */ -#elif defined(SOLARIS) -#ifdef HAVE_SENDFILEV - return(pt_SolarisSendFile(sd, sfd, flags, timeout)); -#else - return(pt_SolarisDispatchSendFile(sd, sfd, flags, timeout)); -#endif /* HAVE_SENDFILEV */ -#elif defined(LINUX) - return(pt_LinuxSendFile(sd, sfd, flags, timeout)); -#else - return(PR_EmulateSendFile(sd, sfd, flags, timeout)); -#endif -} - -static PRInt32 pt_TransmitFile( - PRFileDesc *sd, PRFileDesc *fd, const void *headers, - PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - PRSendFileData sfd; - - sfd.fd = fd; - sfd.file_offset = 0; - sfd.file_nbytes = 0; - sfd.header = headers; - sfd.hlen = hlen; - sfd.trailer = NULL; - sfd.tlen = 0; - - return(pt_SendFile(sd, &sfd, flags, timeout)); -} /* pt_TransmitFile */ - -static PRInt32 pt_AcceptRead( - PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, - void *buf, PRInt32 amount, PRIntervalTime timeout) -{ - PRInt32 rv = -1; - - if (pt_TestAbort()) return rv; - /* The socket must be in blocking mode. */ - if (sd->secret->nonblocking) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return rv; - } - - rv = PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout); - return rv; -} /* pt_AcceptRead */ - -static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr) -{ - PRIntn rv = -1; - pt_SockLen addr_len = sizeof(PRNetAddr); - - if (pt_TestAbort()) return PR_FAILURE; - - rv = getsockname( - fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len); - if (rv == -1) { - pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno); - return PR_FAILURE; - } else { -#ifdef _PR_HAVE_SOCKADDR_LEN - /* ignore the sa_len field of struct sockaddr */ - if (addr) - { - addr->raw.family = ((struct sockaddr*)addr)->sa_family; - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ -#ifdef _PR_INET6 - if (AF_INET6 == addr->raw.family) - addr->raw.family = PR_AF_INET6; -#endif - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); - return PR_SUCCESS; - } -} /* pt_GetSockName */ - -static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) -{ - PRIntn rv = -1; - pt_SockLen addr_len = sizeof(PRNetAddr); - - if (pt_TestAbort()) return PR_FAILURE; - - rv = getpeername( - fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len); - - if (rv == -1) { - pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno); - return PR_FAILURE; - } else { -#ifdef _PR_HAVE_SOCKADDR_LEN - /* ignore the sa_len field of struct sockaddr */ - if (addr) - { - addr->raw.family = ((struct sockaddr*)addr)->sa_family; - } -#endif /* _PR_HAVE_SOCKADDR_LEN */ -#ifdef _PR_INET6 - if (AF_INET6 == addr->raw.family) - addr->raw.family = PR_AF_INET6; -#endif - PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); - PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); - return PR_SUCCESS; - } -} /* pt_GetPeerName */ - -static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data) -{ - PRIntn rv; - pt_SockLen length; - PRInt32 level, name; - - /* - * PR_SockOpt_Nonblocking is a special case that does not - * translate to a getsockopt() call - */ - if (PR_SockOpt_Nonblocking == data->option) - { - data->value.non_blocking = fd->secret->nonblocking; - return PR_SUCCESS; - } - - rv = _PR_MapOptionName(data->option, &level, &name); - if (PR_SUCCESS == rv) - { - switch (data->option) - { - case PR_SockOpt_Linger: - { - struct linger linger; - length = sizeof(linger); - rv = getsockopt( - fd->secret->md.osfd, level, name, (char *) &linger, &length); - PR_ASSERT((-1 == rv) || (sizeof(linger) == length)); - data->value.linger.polarity = - (linger.l_onoff) ? PR_TRUE : PR_FALSE; - data->value.linger.linger = - PR_SecondsToInterval(linger.l_linger); - break; - } - case PR_SockOpt_Reuseaddr: - case PR_SockOpt_Keepalive: - case PR_SockOpt_NoDelay: - case PR_SockOpt_Broadcast: - { - PRIntn value; - length = sizeof(PRIntn); - rv = getsockopt( - fd->secret->md.osfd, level, name, (char*)&value, &length); - PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length)); - data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE; - break; - } - case PR_SockOpt_McastLoopback: - { - PRUint8 xbool; - length = sizeof(xbool); - rv = getsockopt( - fd->secret->md.osfd, level, name, - (char*)&xbool, &length); - PR_ASSERT((-1 == rv) || (sizeof(xbool) == length)); - data->value.mcast_loopback = (0 == xbool) ? PR_FALSE : PR_TRUE; - break; - } - case PR_SockOpt_RecvBufferSize: - case PR_SockOpt_SendBufferSize: - case PR_SockOpt_MaxSegment: - { - PRIntn value; - length = sizeof(PRIntn); - rv = getsockopt( - fd->secret->md.osfd, level, name, (char*)&value, &length); - PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length)); - data->value.recv_buffer_size = value; - break; - } - case PR_SockOpt_IpTimeToLive: - case PR_SockOpt_IpTypeOfService: - { - length = sizeof(PRUintn); - rv = getsockopt( - fd->secret->md.osfd, level, name, - (char*)&data->value.ip_ttl, &length); - PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length)); - break; - } - case PR_SockOpt_McastTimeToLive: - { - PRUint8 ttl; - length = sizeof(ttl); - rv = getsockopt( - fd->secret->md.osfd, level, name, - (char*)&ttl, &length); - PR_ASSERT((-1 == rv) || (sizeof(ttl) == length)); - data->value.mcast_ttl = ttl; - break; - } - case PR_SockOpt_AddMember: - case PR_SockOpt_DropMember: - { - struct ip_mreq mreq; - length = sizeof(mreq); - rv = getsockopt( - fd->secret->md.osfd, level, name, (char*)&mreq, &length); - PR_ASSERT((-1 == rv) || (sizeof(mreq) == length)); - data->value.add_member.mcaddr.inet.ip = - mreq.imr_multiaddr.s_addr; - data->value.add_member.ifaddr.inet.ip = - mreq.imr_interface.s_addr; - break; - } - case PR_SockOpt_McastInterface: - { - length = sizeof(data->value.mcast_if.inet.ip); - rv = getsockopt( - fd->secret->md.osfd, level, name, - (char*)&data->value.mcast_if.inet.ip, &length); - PR_ASSERT((-1 == rv) - || (sizeof(data->value.mcast_if.inet.ip) == length)); - break; - } - default: - PR_NOT_REACHED("Unknown socket option"); - break; - } - if (-1 == rv) _PR_MD_MAP_GETSOCKOPT_ERROR(errno); - } - return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; -} /* pt_GetSocketOption */ - -static PRStatus pt_SetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data) -{ - PRIntn rv; - PRInt32 level, name; - - /* - * PR_SockOpt_Nonblocking is a special case that does not - * translate to a setsockopt call. - */ - if (PR_SockOpt_Nonblocking == data->option) - { - fd->secret->nonblocking = data->value.non_blocking; - return PR_SUCCESS; - } - - rv = _PR_MapOptionName(data->option, &level, &name); - if (PR_SUCCESS == rv) - { - switch (data->option) - { - case PR_SockOpt_Linger: - { - struct linger linger; - linger.l_onoff = data->value.linger.polarity; - linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger); - rv = setsockopt( - fd->secret->md.osfd, level, name, (char*)&linger, sizeof(linger)); - break; - } - case PR_SockOpt_Reuseaddr: - case PR_SockOpt_Keepalive: - case PR_SockOpt_NoDelay: - case PR_SockOpt_Broadcast: - { - PRIntn value = (data->value.reuse_addr) ? 1 : 0; - rv = setsockopt( - fd->secret->md.osfd, level, name, - (char*)&value, sizeof(PRIntn)); -#ifdef LINUX - /* for pt_LinuxSendFile */ - if (name == TCP_NODELAY && rv == 0) { - fd->secret->md.tcp_nodelay = value; - } -#endif - break; - } - case PR_SockOpt_McastLoopback: - { - PRUint8 xbool = data->value.mcast_loopback ? 1 : 0; - rv = setsockopt( - fd->secret->md.osfd, level, name, - (char*)&xbool, sizeof(xbool)); - break; - } - case PR_SockOpt_RecvBufferSize: - case PR_SockOpt_SendBufferSize: - case PR_SockOpt_MaxSegment: - { - PRIntn value = data->value.recv_buffer_size; - rv = setsockopt( - fd->secret->md.osfd, level, name, - (char*)&value, sizeof(PRIntn)); - break; - } - case PR_SockOpt_IpTimeToLive: - case PR_SockOpt_IpTypeOfService: - { - rv = setsockopt( - fd->secret->md.osfd, level, name, - (char*)&data->value.ip_ttl, sizeof(PRUintn)); - break; - } - case PR_SockOpt_McastTimeToLive: - { - PRUint8 ttl = data->value.mcast_ttl; - rv = setsockopt( - fd->secret->md.osfd, level, name, - (char*)&ttl, sizeof(ttl)); - break; - } - case PR_SockOpt_AddMember: - case PR_SockOpt_DropMember: - { - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = - data->value.add_member.mcaddr.inet.ip; - mreq.imr_interface.s_addr = - data->value.add_member.ifaddr.inet.ip; - rv = setsockopt( - fd->secret->md.osfd, level, name, - (char*)&mreq, sizeof(mreq)); - break; - } - case PR_SockOpt_McastInterface: - { - rv = setsockopt( - fd->secret->md.osfd, level, name, - (char*)&data->value.mcast_if.inet.ip, - sizeof(data->value.mcast_if.inet.ip)); - break; - } - default: - PR_NOT_REACHED("Unknown socket option"); - break; - } - if (-1 == rv) _PR_MD_MAP_SETSOCKOPT_ERROR(errno); - } - return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; -} /* pt_SetSocketOption */ - -/*****************************************************************************/ -/****************************** I/O method objects ***************************/ -/*****************************************************************************/ - -static PRIOMethods _pr_file_methods = { - PR_DESC_FILE, - pt_Close, - pt_Read, - pt_Write, - pt_Available_f, - pt_Available64_f, - pt_Fsync, - pt_Seek, - pt_Seek64, - pt_FileInfo, - pt_FileInfo64, - (PRWritevFN)_PR_InvalidInt, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt, - (PRSendFN)_PR_InvalidInt, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - pt_Poll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - (PRGetsocknameFN)_PR_InvalidStatus, - (PRGetpeernameFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -static PRIOMethods _pr_pipe_methods = { - PR_DESC_PIPE, - pt_Close, - pt_Read, - pt_Write, - pt_Available_s, - pt_Available64_s, - pt_Synch, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - (PRWritevFN)_PR_InvalidInt, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt, - (PRSendFN)_PR_InvalidInt, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - pt_Poll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - (PRGetsocknameFN)_PR_InvalidStatus, - (PRGetpeernameFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -static PRIOMethods _pr_tcp_methods = { - PR_DESC_SOCKET_TCP, - pt_Close, - pt_SocketRead, - pt_SocketWrite, - pt_Available_s, - pt_Available64_s, - pt_Synch, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - pt_Writev, - pt_Connect, - pt_Accept, - pt_Bind, - pt_Listen, - pt_Shutdown, - pt_Recv, - pt_Send, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - pt_Poll, - pt_AcceptRead, - pt_TransmitFile, - pt_GetSockName, - pt_GetPeerName, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - pt_GetSocketOption, - pt_SetSocketOption, - pt_SendFile, - pt_ConnectContinue, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -static PRIOMethods _pr_udp_methods = { - PR_DESC_SOCKET_UDP, - pt_Close, - pt_SocketRead, - pt_SocketWrite, - pt_Available_s, - pt_Available64_s, - pt_Synch, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - pt_Writev, - pt_Connect, - (PRAcceptFN)_PR_InvalidDesc, - pt_Bind, - pt_Listen, - pt_Shutdown, - pt_Recv, - pt_Send, - pt_RecvFrom, - pt_SendTo, - pt_Poll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - pt_GetSockName, - pt_GetPeerName, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - pt_GetSocketOption, - pt_SetSocketOption, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -static PRIOMethods _pr_socketpollfd_methods = { - (PRDescType) 0, - (PRCloseFN)_PR_InvalidStatus, - (PRReadFN)_PR_InvalidInt, - (PRWriteFN)_PR_InvalidInt, - (PRAvailableFN)_PR_InvalidInt, - (PRAvailable64FN)_PR_InvalidInt64, - (PRFsyncFN)_PR_InvalidStatus, - (PRSeekFN)_PR_InvalidInt, - (PRSeek64FN)_PR_InvalidInt64, - (PRFileInfoFN)_PR_InvalidStatus, - (PRFileInfo64FN)_PR_InvalidStatus, - (PRWritevFN)_PR_InvalidInt, - (PRConnectFN)_PR_InvalidStatus, - (PRAcceptFN)_PR_InvalidDesc, - (PRBindFN)_PR_InvalidStatus, - (PRListenFN)_PR_InvalidStatus, - (PRShutdownFN)_PR_InvalidStatus, - (PRRecvFN)_PR_InvalidInt, - (PRSendFN)_PR_InvalidInt, - (PRRecvfromFN)_PR_InvalidInt, - (PRSendtoFN)_PR_InvalidInt, - pt_Poll, - (PRAcceptreadFN)_PR_InvalidInt, - (PRTransmitfileFN)_PR_InvalidInt, - (PRGetsocknameFN)_PR_InvalidStatus, - (PRGetpeernameFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRGetsocketoptionFN)_PR_InvalidStatus, - (PRSetsocketoptionFN)_PR_InvalidStatus, - (PRSendfileFN)_PR_InvalidInt, - (PRConnectcontinueFN)_PR_InvalidStatus, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt, - (PRReservedFN)_PR_InvalidInt -}; - -#if defined(HPUX) || defined(OSF1) || defined(SOLARIS) || defined (IRIX) \ - || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ - || defined(AIX) || defined(FREEBSD) || defined(NETBSD) \ - || defined(OPENBSD) || defined(BSDI) || defined(NTO) \ - || defined(DARWIN) || defined(UNIXWARE) || defined(RISCOS) \ - || defined(SYMBIAN) -#define _PR_FCNTL_FLAGS O_NONBLOCK -#else -#error "Can't determine architecture" -#endif - -/* - * Put a Unix file descriptor in non-blocking mode. - */ -static void pt_MakeFdNonblock(PRIntn osfd) -{ - PRIntn flags; - flags = fcntl(osfd, F_GETFL, 0); - flags |= _PR_FCNTL_FLAGS; - (void)fcntl(osfd, F_SETFL, flags); -} - -/* - * Put a Unix socket fd in non-blocking mode that can - * ideally be inherited by an accepted socket. - * - * Why doesn't pt_MakeFdNonblock do? This is to deal with - * the special case of HP-UX. HP-UX has three kinds of - * non-blocking modes for sockets: the fcntl() O_NONBLOCK - * and O_NDELAY flags and ioctl() FIOSNBIO request. Only - * the ioctl() FIOSNBIO form of non-blocking mode is - * inherited by an accepted socket. - * - * Other platforms just use the generic pt_MakeFdNonblock - * to put a socket in non-blocking mode. - */ -#ifdef HPUX -static void pt_MakeSocketNonblock(PRIntn osfd) -{ - PRIntn one = 1; - (void)ioctl(osfd, FIOSNBIO, &one); -} -#else -#define pt_MakeSocketNonblock pt_MakeFdNonblock -#endif - -static PRFileDesc *pt_SetMethods( - PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported) -{ - PRFileDesc *fd = _PR_Getfd(); - - if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - else - { - fd->secret->md.osfd = osfd; - fd->secret->state = _PR_FILEDESC_OPEN; - if (imported) fd->secret->inheritable = _PR_TRI_UNKNOWN; - else - { - /* By default, a Unix fd is not closed on exec. */ -#ifdef DEBUG - PRIntn flags; - flags = fcntl(osfd, F_GETFD, 0); - PR_ASSERT(0 == flags); -#endif - fd->secret->inheritable = _PR_TRI_TRUE; - } - switch (type) - { - case PR_DESC_FILE: - fd->methods = PR_GetFileMethods(); - break; - case PR_DESC_SOCKET_TCP: - fd->methods = PR_GetTCPMethods(); -#ifdef _PR_ACCEPT_INHERIT_NONBLOCK - if (!isAcceptedSocket) pt_MakeSocketNonblock(osfd); -#else - pt_MakeSocketNonblock(osfd); -#endif - break; - case PR_DESC_SOCKET_UDP: - fd->methods = PR_GetUDPMethods(); - pt_MakeFdNonblock(osfd); - break; - case PR_DESC_PIPE: - fd->methods = PR_GetPipeMethods(); - pt_MakeFdNonblock(osfd); - break; - default: - break; - } - } - return fd; -} /* pt_SetMethods */ - -PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void) -{ - return &_pr_file_methods; -} /* PR_GetFileMethods */ - -PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void) -{ - return &_pr_pipe_methods; -} /* PR_GetPipeMethods */ - -PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods(void) -{ - return &_pr_tcp_methods; -} /* PR_GetTCPMethods */ - -PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods(void) -{ - return &_pr_udp_methods; -} /* PR_GetUDPMethods */ - -static const PRIOMethods* PR_GetSocketPollFdMethods(void) -{ - return &_pr_socketpollfd_methods; -} /* PR_GetSocketPollFdMethods */ - -PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc( - PRInt32 osfd, const PRIOMethods *methods) -{ - PRFileDesc *fd = _PR_Getfd(); - - if (NULL == fd) goto failed; - - fd->methods = methods; - fd->secret->md.osfd = osfd; - /* Make fd non-blocking */ - if (osfd > 2) - { - /* Don't mess around with stdin, stdout or stderr */ - if (&_pr_tcp_methods == methods) pt_MakeSocketNonblock(osfd); - else pt_MakeFdNonblock(osfd); - } - fd->secret->state = _PR_FILEDESC_OPEN; - fd->secret->inheritable = _PR_TRI_UNKNOWN; - return fd; - -failed: - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return fd; -} /* PR_AllocFileDesc */ - -#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE) -PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd); -#if defined(_PR_INET6_PROBE) -extern PRBool _pr_ipv6_is_present(void); -PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket() -{ -PRInt32 osfd; - -#if defined(DARWIN) - /* - * Disable IPv6 if Darwin version is less than 7.0.0 (OS X 10.3). IPv6 on - * lesser versions is not ready for general use (see bug 222031). - */ - { - struct utsname u; - if (uname(&u) != 0 || atoi(u.release) < 7) - return PR_FALSE; - } -#endif - - /* - * HP-UX only: HP-UX IPv6 Porting Guide (dated February 2001) - * suggests that we call open("/dev/ip6", O_RDWR) to determine - * whether IPv6 APIs and the IPv6 stack are on the system. - * Our portable test below seems to work fine, so I am using it. - */ - osfd = socket(AF_INET6, SOCK_STREAM, 0); - if (osfd != -1) { - close(osfd); - return PR_TRUE; - } - return PR_FALSE; -} -#endif /* _PR_INET6_PROBE */ -#endif - -PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto) -{ - PRIntn osfd; - PRDescType ftype; - PRFileDesc *fd = NULL; -#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6) - PRInt32 tmp_domain = domain; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (pt_TestAbort()) return NULL; - - if (PF_INET != domain - && PR_AF_INET6 != domain -#if defined(_PR_HAVE_SDP) - && PR_AF_INET_SDP != domain -#if defined(SOLARIS) - && PR_AF_INET6_SDP != domain -#endif /* SOLARIS */ -#endif /* _PR_HAVE_SDP */ - && PF_UNIX != domain) - { - PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return fd; - } - if (type == SOCK_STREAM) ftype = PR_DESC_SOCKET_TCP; - else if (type == SOCK_DGRAM) ftype = PR_DESC_SOCKET_UDP; - else - { - (void)PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); - return fd; - } -#if defined(_PR_HAVE_SDP) -#if defined(LINUX) - if (PR_AF_INET_SDP == domain) - domain = AF_INET_SDP; -#elif defined(SOLARIS) - if (PR_AF_INET_SDP == domain) { - domain = AF_INET; - proto = PROTO_SDP; - } else if(PR_AF_INET6_SDP == domain) { - domain = AF_INET6; - proto = PROTO_SDP; - } -#endif /* SOLARIS */ -#endif /* _PR_HAVE_SDP */ -#if defined(_PR_INET6_PROBE) - if (PR_AF_INET6 == domain) - domain = _pr_ipv6_is_present() ? AF_INET6 : AF_INET; -#elif defined(_PR_INET6) - if (PR_AF_INET6 == domain) - domain = AF_INET6; -#else - if (PR_AF_INET6 == domain) - domain = AF_INET; -#endif - - osfd = socket(domain, type, proto); - if (osfd == -1) pt_MapError(_PR_MD_MAP_SOCKET_ERROR, errno); - else - { -#ifdef _PR_IPV6_V6ONLY_PROBE - if ((domain == AF_INET6) && _pr_ipv6_v6only_on_by_default) - { - int on = 0; - (void)setsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY, - &on, sizeof(on)); - } -#endif - fd = pt_SetMethods(osfd, ftype, PR_FALSE, PR_FALSE); - if (fd == NULL) close(osfd); - } -#ifdef _PR_NEED_SECRET_AF - if (fd != NULL) fd->secret->af = domain; -#endif -#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6) - if (fd != NULL) { - /* - * For platforms with no support for IPv6 - * create layered socket for IPv4-mapped IPv6 addresses - */ - if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) { - if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) { - PR_Close(fd); - fd = NULL; - } - } - } -#endif - return fd; -} /* PR_Socket */ - -/*****************************************************************************/ -/****************************** I/O public methods ***************************/ -/*****************************************************************************/ - -PR_IMPLEMENT(PRFileDesc*) PR_OpenFile( - const char *name, PRIntn flags, PRIntn mode) -{ - PRFileDesc *fd = NULL; - PRIntn syserrno, osfd = -1, osflags = 0;; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (pt_TestAbort()) return NULL; - - if (flags & PR_RDONLY) osflags |= O_RDONLY; - if (flags & PR_WRONLY) osflags |= O_WRONLY; - if (flags & PR_RDWR) osflags |= O_RDWR; - if (flags & PR_APPEND) osflags |= O_APPEND; - if (flags & PR_TRUNCATE) osflags |= O_TRUNC; - if (flags & PR_EXCL) osflags |= O_EXCL; - if (flags & PR_SYNC) - { -#if defined(O_SYNC) - osflags |= O_SYNC; -#elif defined(O_FSYNC) - osflags |= O_FSYNC; -#else -#error "Neither O_SYNC nor O_FSYNC is defined on this platform" -#endif - } - - /* - ** We have to hold the lock across the creation in order to - ** enforce the sematics of PR_Rename(). (see the latter for - ** more details) - */ - if (flags & PR_CREATE_FILE) - { - osflags |= O_CREAT; - if (NULL !=_pr_rename_lock) - PR_Lock(_pr_rename_lock); - } - - osfd = _md_iovector._open64(name, osflags, mode); - syserrno = errno; - - if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock)) - PR_Unlock(_pr_rename_lock); - - if (osfd == -1) - pt_MapError(_PR_MD_MAP_OPEN_ERROR, syserrno); - else - { - fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_FALSE); - if (fd == NULL) close(osfd); /* $$$ whoops! this is bad $$$ */ - } - return fd; -} /* PR_OpenFile */ - -PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode) -{ - return PR_OpenFile(name, flags, mode); -} /* PR_Open */ - -PR_IMPLEMENT(PRStatus) PR_Delete(const char *name) -{ - PRIntn rv = -1; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (pt_TestAbort()) return PR_FAILURE; - - rv = unlink(name); - - if (rv == -1) { - pt_MapError(_PR_MD_MAP_UNLINK_ERROR, errno); - return PR_FAILURE; - } else - return PR_SUCCESS; -} /* PR_Delete */ - -PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how) -{ - PRIntn rv; - - if (pt_TestAbort()) return PR_FAILURE; - - switch (how) - { - case PR_ACCESS_READ_OK: - rv = access(name, R_OK); - break; - case PR_ACCESS_WRITE_OK: - rv = access(name, W_OK); - break; - case PR_ACCESS_EXISTS: - default: - rv = access(name, F_OK); - } - if (0 == rv) return PR_SUCCESS; - pt_MapError(_PR_MD_MAP_ACCESS_ERROR, errno); - return PR_FAILURE; - -} /* PR_Access */ - -PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info) -{ - PRInt32 rv = _PR_MD_GETFILEINFO(fn, info); - return (0 == rv) ? PR_SUCCESS : PR_FAILURE; -} /* PR_GetFileInfo */ - -PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info) -{ - PRInt32 rv; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - rv = _PR_MD_GETFILEINFO64(fn, info); - return (0 == rv) ? PR_SUCCESS : PR_FAILURE; -} /* PR_GetFileInfo64 */ - -PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to) -{ - PRIntn rv = -1; - - if (pt_TestAbort()) return PR_FAILURE; - - /* - ** We have to acquire a lock here to stiffle anybody trying to create - ** a new file at the same time. And we have to hold that lock while we - ** test to see if the file exists and do the rename. The other place - ** where the lock is held is in PR_Open() when possibly creating a - ** new file. - */ - - PR_Lock(_pr_rename_lock); - rv = access(to, F_OK); - if (0 == rv) - { - PR_SetError(PR_FILE_EXISTS_ERROR, 0); - rv = -1; - } - else - { - rv = rename(from, to); - if (rv == -1) - pt_MapError(_PR_MD_MAP_RENAME_ERROR, errno); - } - PR_Unlock(_pr_rename_lock); - return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; -} /* PR_Rename */ - -PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir) -{ - if (pt_TestAbort()) return PR_FAILURE; - - if (NULL != dir->md.d) - { - if (closedir(dir->md.d) == -1) - { - _PR_MD_MAP_CLOSEDIR_ERROR(errno); - return PR_FAILURE; - } - dir->md.d = NULL; - PR_DELETE(dir); - } - return PR_SUCCESS; -} /* PR_CloseDir */ - -PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode) -{ - PRInt32 rv = -1; - - if (pt_TestAbort()) return PR_FAILURE; - - /* - ** This lock is used to enforce rename semantics as described - ** in PR_Rename. - */ - if (NULL !=_pr_rename_lock) - PR_Lock(_pr_rename_lock); - rv = mkdir(name, mode); - if (-1 == rv) - pt_MapError(_PR_MD_MAP_MKDIR_ERROR, errno); - if (NULL !=_pr_rename_lock) - PR_Unlock(_pr_rename_lock); - - return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; -} /* PR_Makedir */ - -PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode) -{ - return PR_MakeDir(name, mode); -} /* PR_Mkdir */ - -PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name) -{ - PRInt32 rv; - - if (pt_TestAbort()) return PR_FAILURE; - - rv = rmdir(name); - if (0 == rv) { - return PR_SUCCESS; - } else { - pt_MapError(_PR_MD_MAP_RMDIR_ERROR, errno); - return PR_FAILURE; - } -} /* PR_Rmdir */ - - -PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name) -{ - DIR *osdir; - PRDir *dir = NULL; - - if (pt_TestAbort()) return dir; - - osdir = opendir(name); - if (osdir == NULL) - pt_MapError(_PR_MD_MAP_OPENDIR_ERROR, errno); - else - { - dir = PR_NEWZAP(PRDir); - if (dir) - dir->md.d = osdir; - else - (void)closedir(osdir); - } - return dir; -} /* PR_OpenDir */ - -static PRInt32 _pr_poll_with_poll( - PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - PRInt32 ready = 0; - /* - * For restarting poll() if it is interrupted by a signal. - * We use these variables to figure out how much time has - * elapsed and how much of the timeout still remains. - */ - PRIntervalTime start, elapsed, remaining; - - if (pt_TestAbort()) return -1; - - if (0 == npds) PR_Sleep(timeout); - else - { -#define STACK_POLL_DESC_COUNT 64 - struct pollfd stack_syspoll[STACK_POLL_DESC_COUNT]; - struct pollfd *syspoll; - PRIntn index, msecs; - - if (npds <= STACK_POLL_DESC_COUNT) - { - syspoll = stack_syspoll; - } - else - { - PRThread *me = PR_GetCurrentThread(); - if (npds > me->syspoll_count) - { - PR_Free(me->syspoll_list); - me->syspoll_list = - (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd)); - if (NULL == me->syspoll_list) - { - me->syspoll_count = 0; - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - me->syspoll_count = npds; - } - syspoll = me->syspoll_list; - } - - for (index = 0; index < npds; ++index) - { - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) - { - if (pds[index].in_flags & PR_POLL_READ) - { - in_flags_read = (pds[index].fd->methods->poll)( - pds[index].fd, - pds[index].in_flags & ~PR_POLL_WRITE, - &out_flags_read); - } - if (pds[index].in_flags & PR_POLL_WRITE) - { - in_flags_write = (pds[index].fd->methods->poll)( - pds[index].fd, - pds[index].in_flags & ~PR_POLL_READ, - &out_flags_write); - } - if ((0 != (in_flags_read & out_flags_read)) - || (0 != (in_flags_write & out_flags_write))) - { - /* this one is ready right now */ - if (0 == ready) - { - /* - * We will return without calling the system - * poll function. So zero the out_flags - * fields of all the poll descriptors before - * this one. - */ - int i; - for (i = 0; i < index; i++) - { - pds[i].out_flags = 0; - } - } - ready += 1; - pds[index].out_flags = out_flags_read | out_flags_write; - } - else - { - /* now locate the NSPR layer at the bottom of the stack */ - PRFileDesc *bottom = PR_GetIdentitiesLayer( - pds[index].fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); /* what to do about that? */ - pds[index].out_flags = 0; /* pre-condition */ - if ((NULL != bottom) - && (_PR_FILEDESC_OPEN == bottom->secret->state)) - { - if (0 == ready) - { - syspoll[index].fd = bottom->secret->md.osfd; - syspoll[index].events = 0; - if (in_flags_read & PR_POLL_READ) - { - pds[index].out_flags |= - _PR_POLL_READ_SYS_READ; - syspoll[index].events |= POLLIN; - } - if (in_flags_read & PR_POLL_WRITE) - { - pds[index].out_flags |= - _PR_POLL_READ_SYS_WRITE; - syspoll[index].events |= POLLOUT; - } - if (in_flags_write & PR_POLL_READ) - { - pds[index].out_flags |= - _PR_POLL_WRITE_SYS_READ; - syspoll[index].events |= POLLIN; - } - if (in_flags_write & PR_POLL_WRITE) - { - pds[index].out_flags |= - _PR_POLL_WRITE_SYS_WRITE; - syspoll[index].events |= POLLOUT; - } - if (pds[index].in_flags & PR_POLL_EXCEPT) - syspoll[index].events |= POLLPRI; - } - } - else - { - if (0 == ready) - { - int i; - for (i = 0; i < index; i++) - { - pds[i].out_flags = 0; - } - } - ready += 1; /* this will cause an abrupt return */ - pds[index].out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - else - { - /* make poll() ignore this entry */ - syspoll[index].fd = -1; - syspoll[index].events = 0; - pds[index].out_flags = 0; - } - } - if (0 == ready) - { - switch (timeout) - { - case PR_INTERVAL_NO_WAIT: msecs = 0; break; - case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break; - default: - msecs = PR_IntervalToMilliseconds(timeout); - start = PR_IntervalNow(); - } - -retry: - ready = poll(syspoll, npds, msecs); - if (-1 == ready) - { - PRIntn oserror = errno; - - if (EINTR == oserror) - { - if (timeout == PR_INTERVAL_NO_TIMEOUT) - goto retry; - else if (timeout == PR_INTERVAL_NO_WAIT) - ready = 0; /* don't retry, just time out */ - else - { - elapsed = (PRIntervalTime) (PR_IntervalNow() - - start); - if (elapsed > timeout) - ready = 0; /* timed out */ - else - { - remaining = timeout - elapsed; - msecs = PR_IntervalToMilliseconds(remaining); - goto retry; - } - } - } - else - { - _PR_MD_MAP_POLL_ERROR(oserror); - } - } - else if (ready > 0) - { - for (index = 0; index < npds; ++index) - { - PRInt16 out_flags = 0; - if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) - { - if (0 != syspoll[index].revents) - { - if (syspoll[index].revents & POLLIN) - { - if (pds[index].out_flags - & _PR_POLL_READ_SYS_READ) - { - out_flags |= PR_POLL_READ; - } - if (pds[index].out_flags - & _PR_POLL_WRITE_SYS_READ) - { - out_flags |= PR_POLL_WRITE; - } - } - if (syspoll[index].revents & POLLOUT) - { - if (pds[index].out_flags - & _PR_POLL_READ_SYS_WRITE) - { - out_flags |= PR_POLL_READ; - } - if (pds[index].out_flags - & _PR_POLL_WRITE_SYS_WRITE) - { - out_flags |= PR_POLL_WRITE; - } - } - if (syspoll[index].revents & POLLPRI) - out_flags |= PR_POLL_EXCEPT; - if (syspoll[index].revents & POLLERR) - out_flags |= PR_POLL_ERR; - if (syspoll[index].revents & POLLNVAL) - out_flags |= PR_POLL_NVAL; - if (syspoll[index].revents & POLLHUP) - out_flags |= PR_POLL_HUP; - } - } - pds[index].out_flags = out_flags; - } - } - } - } - return ready; - -} /* _pr_poll_with_poll */ - -#if defined(_PR_POLL_WITH_SELECT) -/* - * OSF1 and HPUX report the POLLHUP event for a socket when the - * shutdown(SHUT_WR) operation is called for the remote end, even though - * the socket is still writeable. Use select(), instead of poll(), to - * workaround this problem. - */ -static PRInt32 _pr_poll_with_select( - PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ - PRInt32 ready = 0; - /* - * For restarting select() if it is interrupted by a signal. - * We use these variables to figure out how much time has - * elapsed and how much of the timeout still remains. - */ - PRIntervalTime start, elapsed, remaining; - - if (pt_TestAbort()) return -1; - - if (0 == npds) PR_Sleep(timeout); - else - { -#define STACK_POLL_DESC_COUNT 64 - int stack_selectfd[STACK_POLL_DESC_COUNT]; - int *selectfd; - fd_set rd, wr, ex, *rdp = NULL, *wrp = NULL, *exp = NULL; - struct timeval tv, *tvp; - PRIntn index, msecs, maxfd = 0; - - if (npds <= STACK_POLL_DESC_COUNT) - { - selectfd = stack_selectfd; - } - else - { - PRThread *me = PR_GetCurrentThread(); - if (npds > me->selectfd_count) - { - PR_Free(me->selectfd_list); - me->selectfd_list = (int *)PR_MALLOC(npds * sizeof(int)); - if (NULL == me->selectfd_list) - { - me->selectfd_count = 0; - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - me->selectfd_count = npds; - } - selectfd = me->selectfd_list; - } - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); - - for (index = 0; index < npds; ++index) - { - PRInt16 in_flags_read = 0, in_flags_write = 0; - PRInt16 out_flags_read = 0, out_flags_write = 0; - - if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) - { - if (pds[index].in_flags & PR_POLL_READ) - { - in_flags_read = (pds[index].fd->methods->poll)( - pds[index].fd, - pds[index].in_flags & ~PR_POLL_WRITE, - &out_flags_read); - } - if (pds[index].in_flags & PR_POLL_WRITE) - { - in_flags_write = (pds[index].fd->methods->poll)( - pds[index].fd, - pds[index].in_flags & ~PR_POLL_READ, - &out_flags_write); - } - if ((0 != (in_flags_read & out_flags_read)) - || (0 != (in_flags_write & out_flags_write))) - { - /* this one is ready right now */ - if (0 == ready) - { - /* - * We will return without calling the system - * poll function. So zero the out_flags - * fields of all the poll descriptors before - * this one. - */ - int i; - for (i = 0; i < index; i++) - { - pds[i].out_flags = 0; - } - } - ready += 1; - pds[index].out_flags = out_flags_read | out_flags_write; - } - else - { - /* now locate the NSPR layer at the bottom of the stack */ - PRFileDesc *bottom = PR_GetIdentitiesLayer( - pds[index].fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottom); /* what to do about that? */ - pds[index].out_flags = 0; /* pre-condition */ - if ((NULL != bottom) - && (_PR_FILEDESC_OPEN == bottom->secret->state)) - { - if (0 == ready) - { - PRBool add_to_rd = PR_FALSE; - PRBool add_to_wr = PR_FALSE; - PRBool add_to_ex = PR_FALSE; - - selectfd[index] = bottom->secret->md.osfd; - if (in_flags_read & PR_POLL_READ) - { - pds[index].out_flags |= - _PR_POLL_READ_SYS_READ; - add_to_rd = PR_TRUE; - } - if (in_flags_read & PR_POLL_WRITE) - { - pds[index].out_flags |= - _PR_POLL_READ_SYS_WRITE; - add_to_wr = PR_TRUE; - } - if (in_flags_write & PR_POLL_READ) - { - pds[index].out_flags |= - _PR_POLL_WRITE_SYS_READ; - add_to_rd = PR_TRUE; - } - if (in_flags_write & PR_POLL_WRITE) - { - pds[index].out_flags |= - _PR_POLL_WRITE_SYS_WRITE; - add_to_wr = PR_TRUE; - } - if (pds[index].in_flags & PR_POLL_EXCEPT) - { - add_to_ex = PR_TRUE; - } - if ((selectfd[index] > maxfd) && - (add_to_rd || add_to_wr || add_to_ex)) - { - maxfd = selectfd[index]; - /* - * If maxfd is too large to be used with - * select, fall back to calling poll. - */ - if (maxfd >= FD_SETSIZE) - break; - } - if (add_to_rd) - { - FD_SET(bottom->secret->md.osfd, &rd); - rdp = &rd; - } - if (add_to_wr) - { - FD_SET(bottom->secret->md.osfd, &wr); - wrp = ≀ - } - if (add_to_ex) - { - FD_SET(bottom->secret->md.osfd, &ex); - exp = &ex; - } - } - } - else - { - if (0 == ready) - { - int i; - for (i = 0; i < index; i++) - { - pds[i].out_flags = 0; - } - } - ready += 1; /* this will cause an abrupt return */ - pds[index].out_flags = PR_POLL_NVAL; /* bogii */ - } - } - } - else - { - pds[index].out_flags = 0; - } - } - if (0 == ready) - { - if (maxfd >= FD_SETSIZE) - { - /* - * maxfd too large to be used with select, fall back to - * calling poll - */ - return(_pr_poll_with_poll(pds, npds, timeout)); - } - switch (timeout) - { - case PR_INTERVAL_NO_WAIT: - tv.tv_sec = 0; - tv.tv_usec = 0; - tvp = &tv; - break; - case PR_INTERVAL_NO_TIMEOUT: - tvp = NULL; - break; - default: - msecs = PR_IntervalToMilliseconds(timeout); - tv.tv_sec = msecs/PR_MSEC_PER_SEC; - tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC; - tvp = &tv; - start = PR_IntervalNow(); - } - -retry: - ready = select(maxfd + 1, rdp, wrp, exp, tvp); - if (-1 == ready) - { - PRIntn oserror = errno; - - if ((EINTR == oserror) || (EAGAIN == oserror)) - { - if (timeout == PR_INTERVAL_NO_TIMEOUT) - goto retry; - else if (timeout == PR_INTERVAL_NO_WAIT) - ready = 0; /* don't retry, just time out */ - else - { - elapsed = (PRIntervalTime) (PR_IntervalNow() - - start); - if (elapsed > timeout) - ready = 0; /* timed out */ - else - { - remaining = timeout - elapsed; - msecs = PR_IntervalToMilliseconds(remaining); - tv.tv_sec = msecs/PR_MSEC_PER_SEC; - tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * - PR_USEC_PER_MSEC; - goto retry; - } - } - } else if (EBADF == oserror) - { - /* find all the bad fds */ - ready = 0; - for (index = 0; index < npds; ++index) - { - pds[index].out_flags = 0; - if ((NULL != pds[index].fd) && - (0 != pds[index].in_flags)) - { - if (fcntl(selectfd[index], F_GETFL, 0) == -1) - { - pds[index].out_flags = PR_POLL_NVAL; - ready++; - } - } - } - } else - _PR_MD_MAP_SELECT_ERROR(oserror); - } - else if (ready > 0) - { - for (index = 0; index < npds; ++index) - { - PRInt16 out_flags = 0; - if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) - { - if (FD_ISSET(selectfd[index], &rd)) - { - if (pds[index].out_flags - & _PR_POLL_READ_SYS_READ) - { - out_flags |= PR_POLL_READ; - } - if (pds[index].out_flags - & _PR_POLL_WRITE_SYS_READ) - { - out_flags |= PR_POLL_WRITE; - } - } - if (FD_ISSET(selectfd[index], &wr)) - { - if (pds[index].out_flags - & _PR_POLL_READ_SYS_WRITE) - { - out_flags |= PR_POLL_READ; - } - if (pds[index].out_flags - & _PR_POLL_WRITE_SYS_WRITE) - { - out_flags |= PR_POLL_WRITE; - } - } - if (FD_ISSET(selectfd[index], &ex)) - out_flags |= PR_POLL_EXCEPT; - } - pds[index].out_flags = out_flags; - } - } - } - } - return ready; - -} /* _pr_poll_with_select */ -#endif /* _PR_POLL_WITH_SELECT */ - -PR_IMPLEMENT(PRInt32) PR_Poll( - PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) -{ -#if defined(_PR_POLL_WITH_SELECT) - return(_pr_poll_with_select(pds, npds, timeout)); -#else - return(_pr_poll_with_poll(pds, npds, timeout)); -#endif -} - -PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags) -{ - struct dirent *dp; - - if (pt_TestAbort()) return NULL; - - for (;;) - { - errno = 0; - dp = readdir(dir->md.d); - if (NULL == dp) - { - pt_MapError(_PR_MD_MAP_READDIR_ERROR, errno); - return NULL; - } - if ((flags & PR_SKIP_DOT) - && ('.' == dp->d_name[0]) - && (0 == dp->d_name[1])) continue; - if ((flags & PR_SKIP_DOT_DOT) - && ('.' == dp->d_name[0]) - && ('.' == dp->d_name[1]) - && (0 == dp->d_name[2])) continue; - if ((flags & PR_SKIP_HIDDEN) && ('.' == dp->d_name[0])) - continue; - break; - } - dir->d.name = dp->d_name; - return &dir->d; -} /* PR_ReadDir */ - -PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void) -{ - PRIntn domain = PF_INET; - - return PR_Socket(domain, SOCK_DGRAM, 0); -} /* PR_NewUDPSocket */ - -PR_IMPLEMENT(PRFileDesc*) PR_NewTCPSocket(void) -{ - PRIntn domain = PF_INET; - - return PR_Socket(domain, SOCK_STREAM, 0); -} /* PR_NewTCPSocket */ - -PR_IMPLEMENT(PRFileDesc*) PR_OpenUDPSocket(PRIntn af) -{ - return PR_Socket(af, SOCK_DGRAM, 0); -} /* PR_NewUDPSocket */ - -PR_IMPLEMENT(PRFileDesc*) PR_OpenTCPSocket(PRIntn af) -{ - return PR_Socket(af, SOCK_STREAM, 0); -} /* PR_NewTCPSocket */ - -PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]) -{ -#ifdef SYMBIAN - /* - * For the platforms that don't have socketpair. - * - * Copied from prsocket.c, with the parameter f[] renamed fds[] and the - * _PR_CONNECT_DOES_NOT_BIND code removed. - */ - PRFileDesc *listenSock; - PRNetAddr selfAddr, peerAddr; - PRUint16 port; - - fds[0] = fds[1] = NULL; - listenSock = PR_NewTCPSocket(); - if (listenSock == NULL) { - goto failed; - } - PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */ - if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) { - goto failed; - } - if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) { - goto failed; - } - port = ntohs(selfAddr.inet.port); - if (PR_Listen(listenSock, 5) == PR_FAILURE) { - goto failed; - } - fds[0] = PR_NewTCPSocket(); - if (fds[0] == NULL) { - goto failed; - } - PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr); - - /* - * Only a thread is used to do the connect and accept. - * I am relying on the fact that PR_Connect returns - * successfully as soon as the connect request is put - * into the listen queue (but before PR_Accept is called). - * This is the behavior of the BSD socket code. If - * connect does not return until accept is called, we - * will need to create another thread to call connect. - */ - if (PR_Connect(fds[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT) - == PR_FAILURE) { - goto failed; - } - /* - * A malicious local process may connect to the listening - * socket, so we need to verify that the accepted connection - * is made from our own socket fds[0]. - */ - if (PR_GetSockName(fds[0], &selfAddr) == PR_FAILURE) { - goto failed; - } - fds[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT); - if (fds[1] == NULL) { - goto failed; - } - if (peerAddr.inet.port != selfAddr.inet.port) { - /* the connection we accepted is not from fds[0] */ - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - goto failed; - } - PR_Close(listenSock); - return PR_SUCCESS; - -failed: - if (listenSock) { - PR_Close(listenSock); - } - if (fds[0]) { - PR_Close(fds[0]); - } - if (fds[1]) { - PR_Close(fds[1]); - } - return PR_FAILURE; -#else - PRInt32 osfd[2]; - - if (pt_TestAbort()) return PR_FAILURE; - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, osfd) == -1) { - pt_MapError(_PR_MD_MAP_SOCKETPAIR_ERROR, errno); - return PR_FAILURE; - } - - fds[0] = pt_SetMethods(osfd[0], PR_DESC_SOCKET_TCP, PR_FALSE, PR_FALSE); - if (fds[0] == NULL) { - close(osfd[0]); - close(osfd[1]); - return PR_FAILURE; - } - fds[1] = pt_SetMethods(osfd[1], PR_DESC_SOCKET_TCP, PR_FALSE, PR_FALSE); - if (fds[1] == NULL) { - PR_Close(fds[0]); - close(osfd[1]); - return PR_FAILURE; - } - return PR_SUCCESS; -#endif -} /* PR_NewTCPSocketPair */ - -PR_IMPLEMENT(PRStatus) PR_CreatePipe( - PRFileDesc **readPipe, - PRFileDesc **writePipe -) -{ - int pipefd[2]; - - if (pt_TestAbort()) return PR_FAILURE; - - if (pipe(pipefd) == -1) - { - /* XXX map pipe error */ - PR_SetError(PR_UNKNOWN_ERROR, errno); - return PR_FAILURE; - } - *readPipe = pt_SetMethods(pipefd[0], PR_DESC_PIPE, PR_FALSE, PR_FALSE); - if (NULL == *readPipe) - { - close(pipefd[0]); - close(pipefd[1]); - return PR_FAILURE; - } - *writePipe = pt_SetMethods(pipefd[1], PR_DESC_PIPE, PR_FALSE, PR_FALSE); - if (NULL == *writePipe) - { - PR_Close(*readPipe); - close(pipefd[1]); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -/* -** Set the inheritance attribute of a file descriptor. -*/ -PR_IMPLEMENT(PRStatus) PR_SetFDInheritable( - PRFileDesc *fd, - PRBool inheritable) -{ - /* - * Only a non-layered, NSPR file descriptor can be inherited - * by a child process. - */ - if (fd->identity != PR_NSPR_IO_LAYER) - { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - if (fd->secret->inheritable != inheritable) - { - if (fcntl(fd->secret->md.osfd, F_SETFD, - inheritable ? 0 : FD_CLOEXEC) == -1) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - fd->secret->inheritable = (_PRTriStateBool) inheritable; - } - return PR_SUCCESS; -} - -/*****************************************************************************/ -/***************************** I/O friends methods ***************************/ -/*****************************************************************************/ - -PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PRInt32 osfd) -{ - PRFileDesc *fd; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_TRUE); - if (NULL == fd) close(osfd); - return fd; -} /* PR_ImportFile */ - -PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PRInt32 osfd) -{ - PRFileDesc *fd; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - fd = pt_SetMethods(osfd, PR_DESC_PIPE, PR_FALSE, PR_TRUE); - if (NULL == fd) close(osfd); - return fd; -} /* PR_ImportPipe */ - -PR_IMPLEMENT(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd) -{ - PRFileDesc *fd; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_FALSE, PR_TRUE); - if (NULL == fd) close(osfd); -#ifdef _PR_NEED_SECRET_AF - if (NULL != fd) fd->secret->af = PF_INET; -#endif - return fd; -} /* PR_ImportTCPSocket */ - -PR_IMPLEMENT(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd) -{ - PRFileDesc *fd; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - fd = pt_SetMethods(osfd, PR_DESC_SOCKET_UDP, PR_FALSE, PR_TRUE); - if (NULL != fd) close(osfd); - return fd; -} /* PR_ImportUDPSocket */ - -PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PRInt32 osfd) -{ - PRFileDesc *fd; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - fd = _PR_Getfd(); - - if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - else - { - fd->secret->md.osfd = osfd; - fd->secret->inheritable = _PR_TRI_FALSE; - fd->secret->state = _PR_FILEDESC_OPEN; - fd->methods = PR_GetSocketPollFdMethods(); - } - - return fd; -} /* PR_CreateSocketPollFD */ - -PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd) -{ - if (NULL == fd) - { - PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); - return PR_FAILURE; - } - fd->secret->state = _PR_FILEDESC_CLOSED; - _PR_Putfd(fd); - return PR_SUCCESS; -} /* PR_DestroySocketPollFd */ - -PR_IMPLEMENT(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *bottom) -{ - PRInt32 osfd = -1; - bottom = (NULL == bottom) ? - NULL : PR_GetIdentitiesLayer(bottom, PR_NSPR_IO_LAYER); - if (NULL == bottom) PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - else osfd = bottom->secret->md.osfd; - return osfd; -} /* PR_FileDesc2NativeHandle */ - -PR_IMPLEMENT(void) PR_ChangeFileDescNativeHandle(PRFileDesc *fd, - PRInt32 handle) -{ - if (fd) fd->secret->md.osfd = handle; -} /* PR_ChangeFileDescNativeHandle*/ - -PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd) -{ - PRStatus status = PR_SUCCESS; - - if (pt_TestAbort()) return PR_FAILURE; - - PR_Lock(_pr_flock_lock); - while (-1 == fd->secret->lockCount) - PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT); - if (0 == fd->secret->lockCount) - { - fd->secret->lockCount = -1; - PR_Unlock(_pr_flock_lock); - status = _PR_MD_LOCKFILE(fd->secret->md.osfd); - PR_Lock(_pr_flock_lock); - fd->secret->lockCount = (PR_SUCCESS == status) ? 1 : 0; - PR_NotifyAllCondVar(_pr_flock_cv); - } - else - { - fd->secret->lockCount += 1; - } - PR_Unlock(_pr_flock_lock); - - return status; -} /* PR_LockFile */ - -PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd) -{ - PRStatus status = PR_SUCCESS; - - if (pt_TestAbort()) return PR_FAILURE; - - PR_Lock(_pr_flock_lock); - if (0 == fd->secret->lockCount) - { - status = _PR_MD_TLOCKFILE(fd->secret->md.osfd); - if (PR_SUCCESS == status) fd->secret->lockCount = 1; - } - else fd->secret->lockCount += 1; - PR_Unlock(_pr_flock_lock); - - return status; -} /* PR_TLockFile */ - -PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd) -{ - PRStatus status = PR_SUCCESS; - - if (pt_TestAbort()) return PR_FAILURE; - - PR_Lock(_pr_flock_lock); - if (fd->secret->lockCount == 1) - { - status = _PR_MD_UNLOCKFILE(fd->secret->md.osfd); - if (PR_SUCCESS == status) fd->secret->lockCount = 0; - } - else fd->secret->lockCount -= 1; - PR_Unlock(_pr_flock_lock); - - return status; -} - -/* - * The next two entry points should not be in the API, but they are - * defined here for historical (or hysterical) reasons. - */ - -PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void) -{ -#if defined(AIX) || defined(SYMBIAN) - return sysconf(_SC_OPEN_MAX); -#else - struct rlimit rlim; - - if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) - return -1; - - return rlim.rlim_max; -#endif -} - -PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(PRIntn table_size) -{ -#if defined(AIX) || defined(SYMBIAN) - return -1; -#else - struct rlimit rlim; - PRInt32 tableMax = PR_GetSysfdTableMax(); - - if (tableMax < 0) return -1; - rlim.rlim_max = tableMax; - - /* Grow as much as we can; even if too big */ - if ( rlim.rlim_max < table_size ) - rlim.rlim_cur = rlim.rlim_max; - else - rlim.rlim_cur = table_size; - - if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) - return -1; - - return rlim.rlim_cur; -#endif -} - -/* - * PR_Stat is supported for backward compatibility; some existing Java - * code uses it. New code should use PR_GetFileInfo. - */ - -#ifndef NO_NSPR_10_SUPPORT -PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf) -{ - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete("PR_Stat", "PR_GetFileInfo"); - - if (pt_TestAbort()) return -1; - - if (-1 == stat(name, buf)) { - pt_MapError(_PR_MD_MAP_STAT_ERROR, errno); - return -1; - } else { - return 0; - } -} -#endif /* ! NO_NSPR_10_SUPPORT */ - - -PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set) -{ - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete("PR_FD_ZERO (PR_Select)", "PR_Poll"); - memset(set, 0, sizeof(PR_fd_set)); -} - -PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set) -{ - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete("PR_FD_SET (PR_Select)", "PR_Poll"); - PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC ); - - set->harray[set->hsize++] = fh; -} - -PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set) -{ - PRUint32 index, index2; - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete("PR_FD_CLR (PR_Select)", "PR_Poll"); - - for (index = 0; indexhsize; index++) - if (set->harray[index] == fh) { - for (index2=index; index2 < (set->hsize-1); index2++) { - set->harray[index2] = set->harray[index2+1]; - } - set->hsize--; - break; - } -} - -PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set) -{ - PRUint32 index; - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete("PR_FD_ISSET (PR_Select)", "PR_Poll"); - for (index = 0; indexhsize; index++) - if (set->harray[index] == fh) { - return 1; - } - return 0; -} - -PR_IMPLEMENT(void) PR_FD_NSET(PRInt32 fd, PR_fd_set *set) -{ - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete("PR_FD_NSET (PR_Select)", "PR_Poll"); - PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC ); - - set->narray[set->nsize++] = fd; -} - -PR_IMPLEMENT(void) PR_FD_NCLR(PRInt32 fd, PR_fd_set *set) -{ - PRUint32 index, index2; - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete("PR_FD_NCLR (PR_Select)", "PR_Poll"); - - for (index = 0; indexnsize; index++) - if (set->narray[index] == fd) { - for (index2=index; index2 < (set->nsize-1); index2++) { - set->narray[index2] = set->narray[index2+1]; - } - set->nsize--; - break; - } -} - -PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PRInt32 fd, PR_fd_set *set) -{ - PRUint32 index; - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete("PR_FD_NISSET (PR_Select)", "PR_Poll"); - for (index = 0; indexnsize; index++) - if (set->narray[index] == fd) { - return 1; - } - return 0; -} - -#include -#include -#if !defined(HPUX) \ - && !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__) -#include -#endif - -static PRInt32 -_PR_getset(PR_fd_set *pr_set, fd_set *set) -{ - PRUint32 index; - PRInt32 max = 0; - - if (!pr_set) - return 0; - - FD_ZERO(set); - - /* First set the pr file handle osfds */ - for (index=0; indexhsize; index++) { - FD_SET(pr_set->harray[index]->secret->md.osfd, set); - if (pr_set->harray[index]->secret->md.osfd > max) - max = pr_set->harray[index]->secret->md.osfd; - } - /* Second set the native osfds */ - for (index=0; indexnsize; index++) { - FD_SET(pr_set->narray[index], set); - if (pr_set->narray[index] > max) - max = pr_set->narray[index]; - } - return max; -} - -static void -_PR_setset(PR_fd_set *pr_set, fd_set *set) -{ - PRUint32 index, last_used; - - if (!pr_set) - return; - - for (last_used=0, index=0; indexhsize; index++) { - if ( FD_ISSET(pr_set->harray[index]->secret->md.osfd, set) ) { - pr_set->harray[last_used++] = pr_set->harray[index]; - } - } - pr_set->hsize = last_used; - - for (last_used=0, index=0; indexnsize; index++) { - if ( FD_ISSET(pr_set->narray[index], set) ) { - pr_set->narray[last_used++] = pr_set->narray[index]; - } - } - pr_set->nsize = last_used; -} - -PR_IMPLEMENT(PRInt32) PR_Select( - PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, - PR_fd_set *pr_ex, PRIntervalTime timeout) -{ - fd_set rd, wr, ex; - struct timeval tv, *tvp; - PRInt32 max, max_fd; - PRInt32 rv; - /* - * For restarting select() if it is interrupted by a Unix signal. - * We use these variables to figure out how much time has elapsed - * and how much of the timeout still remains. - */ - PRIntervalTime start, elapsed, remaining; - - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete( "PR_Select", "PR_Poll"); - - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); - - max_fd = _PR_getset(pr_rd, &rd); - max_fd = (max = _PR_getset(pr_wr, &wr))>max_fd?max:max_fd; - max_fd = (max = _PR_getset(pr_ex, &ex))>max_fd?max:max_fd; - - if (timeout == PR_INTERVAL_NO_TIMEOUT) { - tvp = NULL; - } else { - tv.tv_sec = (PRInt32)PR_IntervalToSeconds(timeout); - tv.tv_usec = (PRInt32)PR_IntervalToMicroseconds( - timeout - PR_SecondsToInterval(tv.tv_sec)); - tvp = &tv; - start = PR_IntervalNow(); - } - -retry: - rv = select(max_fd + 1, (_PRSelectFdSetArg_t) &rd, - (_PRSelectFdSetArg_t) &wr, (_PRSelectFdSetArg_t) &ex, tvp); - - if (rv == -1 && errno == EINTR) { - if (timeout == PR_INTERVAL_NO_TIMEOUT) { - goto retry; - } else { - elapsed = (PRIntervalTime) (PR_IntervalNow() - start); - if (elapsed > timeout) { - rv = 0; /* timed out */ - } else { - remaining = timeout - elapsed; - tv.tv_sec = (PRInt32)PR_IntervalToSeconds(remaining); - tv.tv_usec = (PRInt32)PR_IntervalToMicroseconds( - remaining - PR_SecondsToInterval(tv.tv_sec)); - goto retry; - } - } - } - - if (rv > 0) { - _PR_setset(pr_rd, &rd); - _PR_setset(pr_wr, &wr); - _PR_setset(pr_ex, &ex); - } else if (rv == -1) { - pt_MapError(_PR_MD_MAP_SELECT_ERROR, errno); - } - return rv; -} -#endif /* defined(_PR_PTHREADS) */ - -#ifdef MOZ_UNICODE -/* ================ UTF16 Interfaces ================================ */ -PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16( - const PRUnichar *name, PRIntn flags, PRIntn mode) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDir *dir) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} -/* ================ UTF16 Interfaces ================================ */ -#endif /* MOZ_UNICODE */ - -/* ptio.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/ptmisc.c nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/ptmisc.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/ptmisc.c 2012-03-06 13:14:21.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/ptmisc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: ptmisc.c -** Descritpion: Implemenation of miscellaneous methods for pthreads -*/ - -#if defined(_PR_PTHREADS) - -#include "primpl.h" - -#include -#ifdef SOLARIS -#include -#endif - -#define PT_LOG(f) - -void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")} -void _PR_InitStacks(void) {PT_LOG("_PR_InitStacks")} - -PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs) -{ -#ifdef SOLARIS - thr_setconcurrency(numCPUs); -#else - PT_LOG("PR_SetConcurrency"); -#endif -} - -PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 flag) - {PT_LOG("PR_SetThreadRecycleMode")} - -#endif /* defined(_PR_PTHREADS) */ - -/* ptmisc.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/ptsynch.c nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/ptsynch.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/ptsynch.c 2012-03-06 13:14:21.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/ptsynch.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1138 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: ptsynch.c -** Descritpion: Implemenation for thread synchronization using pthreads -** Exports: prlock.h, prcvar.h, prmon.h, prcmon.h -*/ - -#if defined(_PR_PTHREADS) - -#include "primpl.h" -#include "obsolete/prsem.h" - -#include -#include -#include - -static pthread_mutexattr_t _pt_mattr; -static pthread_condattr_t _pt_cvar_attr; - -#if defined(DEBUG) -extern PTDebug pt_debug; /* this is shared between several modules */ - -#if defined(_PR_DCETHREADS) -static pthread_t pt_zero_tid; /* a null pthread_t (pthread_t is a struct - * in DCE threads) to compare with */ -#endif /* defined(_PR_DCETHREADS) */ -#endif /* defined(DEBUG) */ - -#if defined(FREEBSD) -/* - * On older versions of FreeBSD, pthread_mutex_trylock returns EDEADLK. - * Newer versions return EBUSY. We still need to support both. - */ -static int -pt_pthread_mutex_is_locked(pthread_mutex_t *m) -{ - int rv = pthread_mutex_trylock(m); - return (EBUSY == rv || EDEADLK == rv); -} -#endif - -/**************************************************************/ -/**************************************************************/ -/*****************************LOCKS****************************/ -/**************************************************************/ -/**************************************************************/ - -void _PR_InitLocks(void) -{ - int rv; - rv = _PT_PTHREAD_MUTEXATTR_INIT(&_pt_mattr); - PR_ASSERT(0 == rv); - -#ifdef LINUX -#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) - rv = pthread_mutexattr_settype(&_pt_mattr, PTHREAD_MUTEX_ADAPTIVE_NP); - PR_ASSERT(0 == rv); -#endif -#endif - - rv = _PT_PTHREAD_CONDATTR_INIT(&_pt_cvar_attr); - PR_ASSERT(0 == rv); -} - -static void pt_PostNotifies(PRLock *lock, PRBool unlock) -{ - PRIntn index, rv; - _PT_Notified post; - _PT_Notified *notified, *prev = NULL; - /* - * Time to actually notify any conditions that were affected - * while the lock was held. Get a copy of the list that's in - * the lock structure and then zero the original. If it's - * linked to other such structures, we own that storage. - */ - post = lock->notified; /* a safe copy; we own the lock */ - -#if defined(DEBUG) - memset(&lock->notified, 0, sizeof(_PT_Notified)); /* reset */ -#else - lock->notified.length = 0; /* these are really sufficient */ - lock->notified.link = NULL; -#endif - - /* should (may) we release lock before notifying? */ - if (unlock) - { - rv = pthread_mutex_unlock(&lock->mutex); - PR_ASSERT(0 == rv); - } - - notified = &post; /* this is where we start */ - do - { - for (index = 0; index < notified->length; ++index) - { - PRCondVar *cv = notified->cv[index].cv; - PR_ASSERT(NULL != cv); - PR_ASSERT(0 != notified->cv[index].times); - if (-1 == notified->cv[index].times) - { - rv = pthread_cond_broadcast(&cv->cv); - PR_ASSERT(0 == rv); - } - else - { - while (notified->cv[index].times-- > 0) - { - rv = pthread_cond_signal(&cv->cv); - PR_ASSERT(0 == rv); - } - } -#if defined(DEBUG) - pt_debug.cvars_notified += 1; - if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending)) - { - pt_debug.delayed_cv_deletes += 1; - PR_DestroyCondVar(cv); - } -#else /* defined(DEBUG) */ - if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending)) - PR_DestroyCondVar(cv); -#endif /* defined(DEBUG) */ - } - prev = notified; - notified = notified->link; - if (&post != prev) PR_DELETE(prev); - } while (NULL != notified); -} /* pt_PostNotifies */ - -PR_IMPLEMENT(PRLock*) PR_NewLock(void) -{ - PRIntn rv; - PRLock *lock; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - lock = PR_NEWZAP(PRLock); - if (lock != NULL) - { - rv = _PT_PTHREAD_MUTEX_INIT(lock->mutex, _pt_mattr); - PR_ASSERT(0 == rv); - } -#if defined(DEBUG) - pt_debug.locks_created += 1; -#endif - return lock; -} /* PR_NewLock */ - -PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock) -{ - PRIntn rv; - PR_ASSERT(NULL != lock); - PR_ASSERT(PR_FALSE == lock->locked); - PR_ASSERT(0 == lock->notified.length); - PR_ASSERT(NULL == lock->notified.link); - rv = pthread_mutex_destroy(&lock->mutex); - PR_ASSERT(0 == rv); -#if defined(DEBUG) - memset(lock, 0xaf, sizeof(PRLock)); - pt_debug.locks_destroyed += 1; -#endif - PR_Free(lock); -} /* PR_DestroyLock */ - -PR_IMPLEMENT(void) PR_Lock(PRLock *lock) -{ - PRIntn rv; - PR_ASSERT(lock != NULL); - rv = pthread_mutex_lock(&lock->mutex); - PR_ASSERT(0 == rv); - PR_ASSERT(0 == lock->notified.length); - PR_ASSERT(NULL == lock->notified.link); - PR_ASSERT(PR_FALSE == lock->locked); - /* Nb: the order of the next two statements is not critical to - * the correctness of PR_AssertCurrentThreadOwnsLock(), but - * this particular order makes the assertion more likely to - * catch errors. */ - lock->owner = pthread_self(); - lock->locked = PR_TRUE; -#if defined(DEBUG) - pt_debug.locks_acquired += 1; -#endif -} /* PR_Lock */ - -PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock) -{ - PRIntn rv; - - PR_ASSERT(lock != NULL); - PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(lock->mutex)); - PR_ASSERT(PR_TRUE == lock->locked); - PR_ASSERT(pthread_equal(lock->owner, pthread_self())); - - if (!lock->locked || !pthread_equal(lock->owner, pthread_self())) - return PR_FAILURE; - - lock->locked = PR_FALSE; - if (0 == lock->notified.length) /* shortcut */ - { - rv = pthread_mutex_unlock(&lock->mutex); - PR_ASSERT(0 == rv); - } - else pt_PostNotifies(lock, PR_TRUE); - -#if defined(DEBUG) - pt_debug.locks_released += 1; -#endif - return PR_SUCCESS; -} /* PR_Unlock */ - -PR_IMPLEMENT(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock) -{ - /* Nb: the order of the |locked| and |owner==me| checks is not critical - * to the correctness of PR_AssertCurrentThreadOwnsLock(), but - * this particular order makes the assertion more likely to - * catch errors. */ - PR_ASSERT(lock->locked && pthread_equal(lock->owner, pthread_self())); -} - -/**************************************************************/ -/**************************************************************/ -/***************************CONDITIONS*************************/ -/**************************************************************/ -/**************************************************************/ - - -/* - * This code is used to compute the absolute time for the wakeup. - * It's moderately ugly, so it's defined here and called in a - * couple of places. - */ -#define PT_NANOPERMICRO 1000UL -#define PT_BILLION 1000000000UL - -static PRIntn pt_TimedWait( - pthread_cond_t *cv, pthread_mutex_t *ml, PRIntervalTime timeout) -{ - int rv; - struct timeval now; - struct timespec tmo; - PRUint32 ticks = PR_TicksPerSecond(); - - tmo.tv_sec = (PRInt32)(timeout / ticks); - tmo.tv_nsec = (PRInt32)(timeout - (tmo.tv_sec * ticks)); - tmo.tv_nsec = (PRInt32)PR_IntervalToMicroseconds(PT_NANOPERMICRO * tmo.tv_nsec); - - /* pthreads wants this in absolute time, off we go ... */ - (void)GETTIMEOFDAY(&now); - /* that one's usecs, this one's nsecs - grrrr! */ - tmo.tv_sec += now.tv_sec; - tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec); - tmo.tv_sec += tmo.tv_nsec / PT_BILLION; - tmo.tv_nsec %= PT_BILLION; - - rv = pthread_cond_timedwait(cv, ml, &tmo); - - /* NSPR doesn't report timeouts */ -#ifdef _PR_DCETHREADS - if (rv == -1) return (errno == EAGAIN) ? 0 : errno; - else return rv; -#else - return (rv == ETIMEDOUT) ? 0 : rv; -#endif -} /* pt_TimedWait */ - - -/* - * Notifies just get posted to the protecting mutex. The - * actual notification is done when the lock is released so that - * MP systems don't contend for a lock that they can't have. - */ -static void pt_PostNotifyToCvar(PRCondVar *cvar, PRBool broadcast) -{ - PRIntn index = 0; - _PT_Notified *notified = &cvar->lock->notified; - - PR_ASSERT(PR_TRUE == cvar->lock->locked); - PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self())); - PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(cvar->lock->mutex)); - - while (1) - { - for (index = 0; index < notified->length; ++index) - { - if (notified->cv[index].cv == cvar) - { - if (broadcast) - notified->cv[index].times = -1; - else if (-1 != notified->cv[index].times) - notified->cv[index].times += 1; - goto finished; /* we're finished */ - } - } - /* if not full, enter new CV in this array */ - if (notified->length < PT_CV_NOTIFIED_LENGTH) break; - - /* if there's no link, create an empty array and link it */ - if (NULL == notified->link) - notified->link = PR_NEWZAP(_PT_Notified); - notified = notified->link; - } - - /* A brand new entry in the array */ - (void)PR_ATOMIC_INCREMENT(&cvar->notify_pending); - notified->cv[index].times = (broadcast) ? -1 : 1; - notified->cv[index].cv = cvar; - notified->length += 1; - -finished: - PR_ASSERT(PR_TRUE == cvar->lock->locked); - PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self())); -} /* pt_PostNotifyToCvar */ - -PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock) -{ - PRCondVar *cv = PR_NEW(PRCondVar); - PR_ASSERT(lock != NULL); - if (cv != NULL) - { - int rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); - PR_ASSERT(0 == rv); - cv->lock = lock; - cv->notify_pending = 0; -#if defined(DEBUG) - pt_debug.cvars_created += 1; -#endif - } - return cv; -} /* PR_NewCondVar */ - -PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar) -{ - if (0 > PR_ATOMIC_DECREMENT(&cvar->notify_pending)) - { - PRIntn rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv); -#if defined(DEBUG) - memset(cvar, 0xaf, sizeof(PRCondVar)); - pt_debug.cvars_destroyed += 1; -#endif - PR_Free(cvar); - } -} /* PR_DestroyCondVar */ - -PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout) -{ - PRIntn rv; - PRThread *thred = PR_GetCurrentThread(); - - PR_ASSERT(cvar != NULL); - /* We'd better be locked */ - PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(cvar->lock->mutex)); - PR_ASSERT(PR_TRUE == cvar->lock->locked); - /* and it better be by us */ - PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self())); - - if (_PT_THREAD_INTERRUPTED(thred)) goto aborted; - - /* - * The thread waiting is used for PR_Interrupt - */ - thred->waiting = cvar; /* this is where we're waiting */ - - /* - * If we have pending notifies, post them now. - * - * This is not optimal. We're going to post these notifies - * while we're holding the lock. That means on MP systems - * that they are going to collide for the lock that we will - * hold until we actually wait. - */ - if (0 != cvar->lock->notified.length) - pt_PostNotifies(cvar->lock, PR_FALSE); - - /* - * We're surrendering the lock, so clear out the locked field. - */ - cvar->lock->locked = PR_FALSE; - - if (timeout == PR_INTERVAL_NO_TIMEOUT) - rv = pthread_cond_wait(&cvar->cv, &cvar->lock->mutex); - else - rv = pt_TimedWait(&cvar->cv, &cvar->lock->mutex, timeout); - - /* We just got the lock back - this better be empty */ - PR_ASSERT(PR_FALSE == cvar->lock->locked); - cvar->lock->locked = PR_TRUE; - cvar->lock->owner = pthread_self(); - - PR_ASSERT(0 == cvar->lock->notified.length); - thred->waiting = NULL; /* and now we're not */ - if (_PT_THREAD_INTERRUPTED(thred)) goto aborted; - if (rv != 0) - { - _PR_MD_MAP_DEFAULT_ERROR(rv); - return PR_FAILURE; - } - return PR_SUCCESS; - -aborted: - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - thred->state &= ~PT_THREAD_ABORTED; - return PR_FAILURE; -} /* PR_WaitCondVar */ - -PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar) -{ - PR_ASSERT(cvar != NULL); - pt_PostNotifyToCvar(cvar, PR_FALSE); - return PR_SUCCESS; -} /* PR_NotifyCondVar */ - -PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar) -{ - PR_ASSERT(cvar != NULL); - pt_PostNotifyToCvar(cvar, PR_TRUE); - return PR_SUCCESS; -} /* PR_NotifyAllCondVar */ - -/**************************************************************/ -/**************************************************************/ -/***************************MONITORS***************************/ -/**************************************************************/ -/**************************************************************/ - -PR_IMPLEMENT(PRMonitor*) PR_NewMonitor(void) -{ - PRMonitor *mon; - PRCondVar *cvar; - int rv; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - cvar = PR_NEWZAP(PRCondVar); - if (NULL == cvar) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - mon = PR_NEWZAP(PRMonitor); - if (mon == NULL) - { - PR_Free(cvar); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - rv = _PT_PTHREAD_MUTEX_INIT(mon->lock.mutex, _pt_mattr); - PR_ASSERT(0 == rv); - if (0 != rv) - { - PR_Free(mon); - PR_Free(cvar); - PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0); - return NULL; - } - - _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); - - mon->cvar = cvar; - rv = _PT_PTHREAD_COND_INIT(mon->cvar->cv, _pt_cvar_attr); - PR_ASSERT(0 == rv); - mon->entryCount = 0; - mon->cvar->lock = &mon->lock; - if (0 != rv) - { - pthread_mutex_destroy(&mon->lock.mutex); - PR_Free(mon); - PR_Free(cvar); - PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0); - return NULL; - } - return mon; -} /* PR_NewMonitor */ - -PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name) -{ - PRMonitor* mon = PR_NewMonitor(); - if (mon) - mon->name = name; - return mon; -} - -PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon) -{ - int rv; - PR_ASSERT(mon != NULL); - PR_DestroyCondVar(mon->cvar); - rv = pthread_mutex_destroy(&mon->lock.mutex); PR_ASSERT(0 == rv); -#if defined(DEBUG) - memset(mon, 0xaf, sizeof(PRMonitor)); -#endif - PR_Free(mon); -} /* PR_DestroyMonitor */ - - -/* The GC uses this; it is quite arguably a bad interface. I'm just - * duplicating it for now - XXXMB - */ -PR_IMPLEMENT(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon) -{ - pthread_t self = pthread_self(); - if (pthread_equal(mon->owner, self)) - return mon->entryCount; - return 0; -} - -PR_IMPLEMENT(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon) -{ - PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(&mon->lock); -} - -PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon) -{ - pthread_t self = pthread_self(); - - PR_ASSERT(mon != NULL); - /* - * This is safe only if mon->owner (a pthread_t) can be - * read in one instruction. Perhaps mon->owner should be - * a "PRThread *"? - */ - if (!pthread_equal(mon->owner, self)) - { - PR_Lock(&mon->lock); - /* and now I have the lock */ - PR_ASSERT(0 == mon->entryCount); - PR_ASSERT(_PT_PTHREAD_THR_HANDLE_IS_INVALID(mon->owner)); - _PT_PTHREAD_COPY_THR_HANDLE(self, mon->owner); - } - mon->entryCount += 1; -} /* PR_EnterMonitor */ - -PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon) -{ - pthread_t self = pthread_self(); - - PR_ASSERT(mon != NULL); - /* The lock better be that - locked */ - PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex)); - /* we'd better be the owner */ - PR_ASSERT(pthread_equal(mon->owner, self)); - if (!pthread_equal(mon->owner, self)) - return PR_FAILURE; - - /* if it's locked and we have it, then the entries should be > 0 */ - PR_ASSERT(mon->entryCount > 0); - mon->entryCount -= 1; /* reduce by one */ - if (mon->entryCount == 0) - { - /* and if it transitioned to zero - unlock */ - _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); /* make the owner unknown */ - PR_Unlock(&mon->lock); - } - return PR_SUCCESS; -} /* PR_ExitMonitor */ - -PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime timeout) -{ - PRStatus rv; - PRInt16 saved_entries; - pthread_t saved_owner; - - PR_ASSERT(mon != NULL); - /* we'd better be locked */ - PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex)); - /* and the entries better be positive */ - PR_ASSERT(mon->entryCount > 0); - /* and it better be by us */ - PR_ASSERT(pthread_equal(mon->owner, pthread_self())); - - /* tuck these away 'till later */ - saved_entries = mon->entryCount; - mon->entryCount = 0; - _PT_PTHREAD_COPY_THR_HANDLE(mon->owner, saved_owner); - _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); - - rv = PR_WaitCondVar(mon->cvar, timeout); - - /* reinstate the intresting information */ - mon->entryCount = saved_entries; - _PT_PTHREAD_COPY_THR_HANDLE(saved_owner, mon->owner); - - return rv; -} /* PR_Wait */ - -PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon) -{ - PR_ASSERT(NULL != mon); - /* we'd better be locked */ - PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex)); - /* and the entries better be positive */ - PR_ASSERT(mon->entryCount > 0); - /* and it better be by us */ - PR_ASSERT(pthread_equal(mon->owner, pthread_self())); - - pt_PostNotifyToCvar(mon->cvar, PR_FALSE); - - return PR_SUCCESS; -} /* PR_Notify */ - -PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon) -{ - PR_ASSERT(mon != NULL); - /* we'd better be locked */ - PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex)); - /* and the entries better be positive */ - PR_ASSERT(mon->entryCount > 0); - /* and it better be by us */ - PR_ASSERT(pthread_equal(mon->owner, pthread_self())); - - pt_PostNotifyToCvar(mon->cvar, PR_TRUE); - - return PR_SUCCESS; -} /* PR_NotifyAll */ - -/**************************************************************/ -/**************************************************************/ -/**************************SEMAPHORES**************************/ -/**************************************************************/ -/**************************************************************/ -PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *semaphore) -{ - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete( - "PR_PostSem", "locks & condition variables"); - PR_Lock(semaphore->cvar->lock); - PR_NotifyCondVar(semaphore->cvar); - semaphore->count += 1; - PR_Unlock(semaphore->cvar->lock); -} /* PR_PostSem */ - -PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *semaphore) -{ - PRStatus status = PR_SUCCESS; - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete( - "PR_WaitSem", "locks & condition variables"); - PR_Lock(semaphore->cvar->lock); - while ((semaphore->count == 0) && (PR_SUCCESS == status)) - status = PR_WaitCondVar(semaphore->cvar, PR_INTERVAL_NO_TIMEOUT); - if (PR_SUCCESS == status) semaphore->count -= 1; - PR_Unlock(semaphore->cvar->lock); - return status; -} /* PR_WaitSem */ - -PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *semaphore) -{ - static PRBool unwarned = PR_TRUE; - if (unwarned) unwarned = _PR_Obsolete( - "PR_DestroySem", "locks & condition variables"); - PR_DestroyLock(semaphore->cvar->lock); - PR_DestroyCondVar(semaphore->cvar); - PR_Free(semaphore); -} /* PR_DestroySem */ - -PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value) -{ - PRSemaphore *semaphore; - static PRBool unwarned = PR_TRUE; - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (unwarned) unwarned = _PR_Obsolete( - "PR_NewSem", "locks & condition variables"); - - semaphore = PR_NEWZAP(PRSemaphore); - if (NULL != semaphore) - { - PRLock *lock = PR_NewLock(); - if (NULL != lock) - { - semaphore->cvar = PR_NewCondVar(lock); - if (NULL != semaphore->cvar) - { - semaphore->count = value; - return semaphore; - } - PR_DestroyLock(lock); - } - PR_Free(semaphore); - } - return NULL; -} - -/* - * Define the interprocess named semaphore functions. - * There are three implementations: - * 1. POSIX semaphore based; - * 2. System V semaphore based; - * 3. unsupported (fails with PR_NOT_IMPLEMENTED_ERROR). - */ - -#ifdef _PR_HAVE_POSIX_SEMAPHORES -#include - -PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( - const char *name, - PRIntn flags, - PRIntn mode, - PRUintn value) -{ - PRSem *sem; - char osname[PR_IPC_NAME_SIZE]; - - if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) - == PR_FAILURE) - { - return NULL; - } - - sem = PR_NEW(PRSem); - if (NULL == sem) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - if (flags & PR_SEM_CREATE) - { - int oflag = O_CREAT; - - if (flags & PR_SEM_EXCL) oflag |= O_EXCL; - sem->sem = sem_open(osname, oflag, mode, value); - } - else - { -#ifdef HPUX - /* Pass 0 as the mode and value arguments to work around a bug. */ - sem->sem = sem_open(osname, 0, 0, 0); -#else - sem->sem = sem_open(osname, 0); -#endif - } - if ((sem_t *) -1 == sem->sem) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - PR_Free(sem); - return NULL; - } - return sem; -} - -PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem) -{ - int rv; - rv = sem_wait(sem->sem); - if (0 != rv) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem) -{ - int rv; - rv = sem_post(sem->sem); - if (0 != rv) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem) -{ - int rv; - rv = sem_close(sem->sem); - if (0 != rv) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - PR_Free(sem); - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) -{ - int rv; - char osname[PR_IPC_NAME_SIZE]; - - if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) - == PR_FAILURE) - { - return PR_FAILURE; - } - rv = sem_unlink(osname); - if (0 != rv) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -#elif defined(_PR_HAVE_SYSV_SEMAPHORES) - -#include -#include - -/* - * From the semctl(2) man page in glibc 2.0 - */ -#if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \ - || defined(FREEBSD) || defined(OPENBSD) || defined(BSDI) \ - || defined(DARWIN) || defined(SYMBIAN) -/* union semun is defined by including */ -#else -/* according to X/OPEN we have to define it ourselves */ -union semun { - int val; - struct semid_ds *buf; - unsigned short *array; -}; -#endif - -/* - * 'a' (97) is the final closing price of NSCP stock. - */ -#define NSPR_IPC_KEY_ID 'a' /* the id argument for ftok() */ - -#define NSPR_SEM_MODE 0666 - -PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( - const char *name, - PRIntn flags, - PRIntn mode, - PRUintn value) -{ - PRSem *sem; - key_t key; - union semun arg; - struct sembuf sop; - struct semid_ds seminfo; -#define MAX_TRIES 60 - PRIntn i; - char osname[PR_IPC_NAME_SIZE]; - - if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) - == PR_FAILURE) - { - return NULL; - } - - /* Make sure the file exists before calling ftok. */ - if (flags & PR_SEM_CREATE) - { - int osfd = open(osname, O_RDWR|O_CREAT, mode); - if (-1 == osfd) - { - _PR_MD_MAP_OPEN_ERROR(errno); - return NULL; - } - if (close(osfd) == -1) - { - _PR_MD_MAP_CLOSE_ERROR(errno); - return NULL; - } - } - key = ftok(osname, NSPR_IPC_KEY_ID); - if ((key_t)-1 == key) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return NULL; - } - - sem = PR_NEW(PRSem); - if (NULL == sem) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - if (flags & PR_SEM_CREATE) - { - sem->semid = semget(key, 1, mode|IPC_CREAT|IPC_EXCL); - if (sem->semid >= 0) - { - /* creator of a semaphore is responsible for initializing it */ - arg.val = 0; - if (semctl(sem->semid, 0, SETVAL, arg) == -1) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - PR_Free(sem); - return NULL; - } - /* call semop to set sem_otime to nonzero */ - sop.sem_num = 0; - sop.sem_op = value; - sop.sem_flg = 0; - if (semop(sem->semid, &sop, 1) == -1) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - PR_Free(sem); - return NULL; - } - return sem; - } - - if (errno != EEXIST || flags & PR_SEM_EXCL) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - PR_Free(sem); - return NULL; - } - } - - sem->semid = semget(key, 1, NSPR_SEM_MODE); - if (sem->semid == -1) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - PR_Free(sem); - return NULL; - } - for (i = 0; i < MAX_TRIES; i++) - { - arg.buf = &seminfo; - semctl(sem->semid, 0, IPC_STAT, arg); - if (seminfo.sem_otime != 0) break; - sleep(1); - } - if (i == MAX_TRIES) - { - PR_SetError(PR_IO_TIMEOUT_ERROR, 0); - PR_Free(sem); - return NULL; - } - return sem; -} - -PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem) -{ - struct sembuf sop; - - sop.sem_num = 0; - sop.sem_op = -1; - sop.sem_flg = 0; - if (semop(sem->semid, &sop, 1) == -1) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem) -{ - struct sembuf sop; - - sop.sem_num = 0; - sop.sem_op = 1; - sop.sem_flg = 0; - if (semop(sem->semid, &sop, 1) == -1) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem) -{ - PR_Free(sem); - return PR_SUCCESS; -} - -PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) -{ - key_t key; - int semid; - /* On some systems (e.g., glibc 2.0) semctl requires a fourth argument */ - union semun unused; - char osname[PR_IPC_NAME_SIZE]; - - if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) - == PR_FAILURE) - { - return PR_FAILURE; - } - key = ftok(osname, NSPR_IPC_KEY_ID); - if ((key_t) -1 == key) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - if (unlink(osname) == -1) - { - _PR_MD_MAP_UNLINK_ERROR(errno); - return PR_FAILURE; - } - semid = semget(key, 1, NSPR_SEM_MODE); - if (-1 == semid) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - unused.val = 0; - if (semctl(semid, 0, IPC_RMID, unused) == -1) - { - _PR_MD_MAP_DEFAULT_ERROR(errno); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -#else /* neither POSIX nor System V semaphores are available */ - -PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( - const char *name, - PRIntn flags, - PRIntn mode, - PRUintn value) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) -{ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return PR_FAILURE; -} - -#endif /* end of interprocess named semaphore functions */ - -/**************************************************************/ -/**************************************************************/ -/******************ROUTINES FOR DCE EMULATION******************/ -/**************************************************************/ -/**************************************************************/ - -#include "prpdce.h" - -PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock) -{ - PRIntn rv = pthread_mutex_trylock(&lock->mutex); - if (rv == PT_TRYLOCK_SUCCESS) - { - PR_ASSERT(PR_FALSE == lock->locked); - lock->locked = PR_TRUE; - lock->owner = pthread_self(); - } - /* XXX set error code? */ - return (PT_TRYLOCK_SUCCESS == rv) ? PR_SUCCESS : PR_FAILURE; -} /* PRP_TryLock */ - -PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void) -{ - PRCondVar *cv; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - cv = PR_NEW(PRCondVar); - if (cv != NULL) - { - int rv; - rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); - PR_ASSERT(0 == rv); - cv->lock = _PR_NAKED_CV_LOCK; - } - return cv; -} /* PRP_NewNakedCondVar */ - -PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar) -{ - int rv; - rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv); -#if defined(DEBUG) - memset(cvar, 0xaf, sizeof(PRCondVar)); -#endif - PR_Free(cvar); -} /* PRP_DestroyNakedCondVar */ - -PR_IMPLEMENT(PRStatus) PRP_NakedWait( - PRCondVar *cvar, PRLock *ml, PRIntervalTime timeout) -{ - PRIntn rv; - PR_ASSERT(cvar != NULL); - /* XXX do we really want to assert this in a naked wait? */ - PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(ml->mutex)); - if (timeout == PR_INTERVAL_NO_TIMEOUT) - rv = pthread_cond_wait(&cvar->cv, &ml->mutex); - else - rv = pt_TimedWait(&cvar->cv, &ml->mutex, timeout); - if (rv != 0) - { - _PR_MD_MAP_DEFAULT_ERROR(rv); - return PR_FAILURE; - } - return PR_SUCCESS; -} /* PRP_NakedWait */ - -PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar) -{ - int rv; - PR_ASSERT(cvar != NULL); - rv = pthread_cond_signal(&cvar->cv); - PR_ASSERT(0 == rv); - return PR_SUCCESS; -} /* PRP_NakedNotify */ - -PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar) -{ - int rv; - PR_ASSERT(cvar != NULL); - rv = pthread_cond_broadcast(&cvar->cv); - PR_ASSERT(0 == rv); - return PR_SUCCESS; -} /* PRP_NakedBroadcast */ - -#endif /* defined(_PR_PTHREADS) */ - -/* ptsynch.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/ptthread.c nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/ptthread.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/pthreads/ptthread.c 2012-10-23 01:27:10.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/pthreads/ptthread.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1704 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: ptthread.c -** Descritpion: Implemenation for threds using pthreds -** Exports: ptthread.h -*/ - -#if defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) - -#include "prlog.h" -#include "primpl.h" -#include "prpdce.h" - -#include -#include -#include -#include -#include - -#ifdef SYMBIAN -/* In Open C sched_get_priority_min/max do not work properly, so we undefine - * _POSIX_THREAD_PRIORITY_SCHEDULING here. - */ -#undef _POSIX_THREAD_PRIORITY_SCHEDULING -#endif - -/* - * Record whether or not we have the privilege to set the scheduling - * policy and priority of threads. 0 means that privilege is available. - * EPERM means that privilege is not available. - */ - -static PRIntn pt_schedpriv = 0; -extern PRLock *_pr_sleeplock; - -static struct _PT_Bookeeping -{ - PRLock *ml; /* a lock to protect ourselves */ - PRCondVar *cv; /* used to signal global things */ - PRInt32 system, user; /* a count of the two different types */ - PRUintn this_many; /* number of threads allowed for exit */ - pthread_key_t key; /* thread private data key */ - PRThread *first, *last; /* list of threads we know about */ -#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - PRInt32 minPrio, maxPrio; /* range of scheduling priorities */ -#endif -} pt_book = {0}; - -static void _pt_thread_death(void *arg); -static void _pt_thread_death_internal(void *arg, PRBool callDestructors); -static void init_pthread_gc_support(void); - -#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) -static PRIntn pt_PriorityMap(PRThreadPriority pri) -{ -#ifdef NTO - /* This priority algorithm causes lots of problems on Neutrino - * for now I have just hard coded everything to run at priority 10 - * until I can come up with a new algorithm. - * Jerry.Kirk@Nexwarecorp.com - */ - return 10; -#else - return pt_book.minPrio + - pri * (pt_book.maxPrio - pt_book.minPrio) / PR_PRIORITY_LAST; -#endif -} -#endif - -/* -** Initialize a stack for a native pthread thread -*/ -static void _PR_InitializeStack(PRThreadStack *ts) -{ - if( ts && (ts->stackTop == 0) ) { - ts->allocBase = (char *) &ts; - ts->allocSize = ts->stackSize; - - /* - ** Setup stackTop and stackBottom values. - */ -#ifdef HAVE_STACK_GROWING_UP - ts->stackBottom = ts->allocBase + ts->stackSize; - ts->stackTop = ts->allocBase; -#else - ts->stackTop = ts->allocBase; - ts->stackBottom = ts->allocBase - ts->stackSize; -#endif - } -} - -static void *_pt_root(void *arg) -{ - PRIntn rv; - PRThread *thred = (PRThread*)arg; - PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE; - - /* - * Both the parent thread and this new thread set thred->id. - * The new thread must ensure that thred->id is set before - * it executes its startFunc. The parent thread must ensure - * that thred->id is set before PR_CreateThread() returns. - * Both threads set thred->id without holding a lock. Since - * they are writing the same value, this unprotected double - * write should be safe. - */ - thred->id = pthread_self(); - - /* - ** DCE Threads can't detach during creation, so do it late. - ** I would like to do it only here, but that doesn't seem - ** to work. - */ -#if defined(_PR_DCETHREADS) - if (detached) - { - /* pthread_detach() modifies its argument, so we must pass a copy */ - pthread_t self = thred->id; - rv = pthread_detach(&self); - PR_ASSERT(0 == rv); - } -#endif /* defined(_PR_DCETHREADS) */ - - /* Set up the thread stack information */ - _PR_InitializeStack(thred->stack); - - /* - * Set within the current thread the pointer to our object. - * This object will be deleted when the thread termintates, - * whether in a join or detached (see _PR_InitThreads()). - */ - rv = pthread_setspecific(pt_book.key, thred); - PR_ASSERT(0 == rv); - - /* make the thread visible to the rest of the runtime */ - PR_Lock(pt_book.ml); - - /* If this is a GCABLE thread, set its state appropriately */ - if (thred->suspend & PT_THREAD_SETGCABLE) - thred->state |= PT_THREAD_GCABLE; - thred->suspend = 0; - - thred->prev = pt_book.last; - if (pt_book.last) - pt_book.last->next = thred; - else - pt_book.first = thred; - thred->next = NULL; - pt_book.last = thred; - PR_Unlock(pt_book.ml); - - thred->startFunc(thred->arg); /* make visible to the client */ - - /* unhook the thread from the runtime */ - PR_Lock(pt_book.ml); - /* - * At this moment, PR_CreateThread() may not have set thred->id yet. - * It is safe for a detached thread to free thred only after - * PR_CreateThread() has set thred->id. - */ - if (detached) - { - while (!thred->okToDelete) - PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT); - } - - if (thred->state & PT_THREAD_SYSTEM) - pt_book.system -= 1; - else if (--pt_book.user == pt_book.this_many) - PR_NotifyAllCondVar(pt_book.cv); - if (NULL == thred->prev) - pt_book.first = thred->next; - else - thred->prev->next = thred->next; - if (NULL == thred->next) - pt_book.last = thred->prev; - else - thred->next->prev = thred->prev; - PR_Unlock(pt_book.ml); - - /* - * Here we set the pthread's backpointer to the PRThread to NULL. - * Otherwise the destructor would get called eagerly as the thread - * returns to the pthread runtime. The joining thread would them be - * the proud possessor of a dangling reference. However, this is the - * last chance to delete the object if the thread is detached, so - * just let the destructor do the work. - */ - if (PR_FALSE == detached) - { - /* Call TPD destructors on this thread. */ - _PR_DestroyThreadPrivate(thred); - rv = pthread_setspecific(pt_book.key, NULL); - PR_ASSERT(0 == rv); - } - - return NULL; -} /* _pt_root */ - -static PRThread* pt_AttachThread(void) -{ - PRThread *thred = NULL; - - /* - * NSPR must have been initialized when PR_AttachThread is called. - * We cannot have PR_AttachThread call implicit initialization - * because if multiple threads call PR_AttachThread simultaneously, - * NSPR may be initialized more than once. - * We can't call any function that calls PR_GetCurrentThread() - * either (e.g., PR_SetError()) as that will result in infinite - * recursion. - */ - if (!_pr_initialized) return NULL; - - /* PR_NEWZAP must not call PR_GetCurrentThread() */ - thred = PR_NEWZAP(PRThread); - if (NULL != thred) - { - int rv; - - thred->priority = PR_PRIORITY_NORMAL; - thred->id = pthread_self(); - rv = pthread_setspecific(pt_book.key, thred); - PR_ASSERT(0 == rv); - - thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN; - PR_Lock(pt_book.ml); - - /* then put it into the list */ - thred->prev = pt_book.last; - if (pt_book.last) - pt_book.last->next = thred; - else - pt_book.first = thred; - thred->next = NULL; - pt_book.last = thred; - PR_Unlock(pt_book.ml); - - } - return thred; /* may be NULL */ -} /* pt_AttachThread */ - -static PRThread* _PR_CreateThread( - PRThreadType type, void (*start)(void *arg), - void *arg, PRThreadPriority priority, PRThreadScope scope, - PRThreadState state, PRUint32 stackSize, PRBool isGCAble) -{ - int rv; - PRThread *thred; - pthread_attr_t tattr; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if ((PRIntn)PR_PRIORITY_FIRST > (PRIntn)priority) - priority = PR_PRIORITY_FIRST; - else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)priority) - priority = PR_PRIORITY_LAST; - - rv = _PT_PTHREAD_ATTR_INIT(&tattr); - PR_ASSERT(0 == rv); - - if (EPERM != pt_schedpriv) - { -#if !defined(_PR_DCETHREADS) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - struct sched_param schedule; -#endif - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - rv = pthread_attr_setinheritsched(&tattr, PTHREAD_EXPLICIT_SCHED); - PR_ASSERT(0 == rv); -#endif - - /* Use the default scheduling policy */ - -#if defined(_PR_DCETHREADS) - rv = pthread_attr_setprio(&tattr, pt_PriorityMap(priority)); - PR_ASSERT(0 == rv); -#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - rv = pthread_attr_getschedparam(&tattr, &schedule); - PR_ASSERT(0 == rv); - schedule.sched_priority = pt_PriorityMap(priority); - rv = pthread_attr_setschedparam(&tattr, &schedule); - PR_ASSERT(0 == rv); -#ifdef NTO - rv = pthread_attr_setschedpolicy(&tattr, SCHED_RR); /* Round Robin */ - PR_ASSERT(0 == rv); -#endif -#endif /* !defined(_PR_DCETHREADS) */ - } - - /* - * DCE threads can't set detach state before creating the thread. - * AIX can't set detach late. Why can't we all just get along? - */ -#if !defined(_PR_DCETHREADS) - rv = pthread_attr_setdetachstate(&tattr, - ((PR_JOINABLE_THREAD == state) ? - PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED)); - PR_ASSERT(0 == rv); -#endif /* !defined(_PR_DCETHREADS) */ - - /* - * If stackSize is 0, we use the default pthread stack size. - */ - if (stackSize) - { -#ifdef _MD_MINIMUM_STACK_SIZE - if (stackSize < _MD_MINIMUM_STACK_SIZE) - stackSize = _MD_MINIMUM_STACK_SIZE; -#endif - rv = pthread_attr_setstacksize(&tattr, stackSize); - PR_ASSERT(0 == rv); - } - - thred = PR_NEWZAP(PRThread); - if (NULL == thred) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, errno); - goto done; - } - else - { - pthread_t id; - - thred->arg = arg; - thred->startFunc = start; - thred->priority = priority; - if (PR_UNJOINABLE_THREAD == state) - thred->state |= PT_THREAD_DETACHED; - - if (PR_LOCAL_THREAD == scope) - scope = PR_GLOBAL_THREAD; - - if (PR_GLOBAL_BOUND_THREAD == scope) { -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM); - if (rv) { - /* - * system scope not supported - */ - scope = PR_GLOBAL_THREAD; - /* - * reset scope - */ - rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS); - PR_ASSERT(0 == rv); - } -#endif - } - if (PR_GLOBAL_THREAD == scope) - thred->state |= PT_THREAD_GLOBAL; - else if (PR_GLOBAL_BOUND_THREAD == scope) - thred->state |= (PT_THREAD_GLOBAL | PT_THREAD_BOUND); - else /* force it global */ - thred->state |= PT_THREAD_GLOBAL; - if (PR_SYSTEM_THREAD == type) - thred->state |= PT_THREAD_SYSTEM; - - thred->suspend =(isGCAble) ? PT_THREAD_SETGCABLE : 0; - - thred->stack = PR_NEWZAP(PRThreadStack); - if (thred->stack == NULL) { - PRIntn oserr = errno; - PR_Free(thred); /* all that work ... poof! */ - PR_SetError(PR_OUT_OF_MEMORY_ERROR, oserr); - thred = NULL; /* and for what? */ - goto done; - } - thred->stack->stackSize = stackSize; - thred->stack->thr = thred; - -#ifdef PT_NO_SIGTIMEDWAIT - pthread_mutex_init(&thred->suspendResumeMutex,NULL); - pthread_cond_init(&thred->suspendResumeCV,NULL); -#endif - - /* make the thread counted to the rest of the runtime */ - PR_Lock(pt_book.ml); - if (PR_SYSTEM_THREAD == type) - pt_book.system += 1; - else pt_book.user += 1; - PR_Unlock(pt_book.ml); - - /* - * We pass a pointer to a local copy (instead of thred->id) - * to pthread_create() because who knows what wacky things - * pthread_create() may be doing to its argument. - */ - rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred); - -#if !defined(_PR_DCETHREADS) - if (EPERM == rv) - { -#if defined(IRIX) - if (PR_GLOBAL_BOUND_THREAD == scope) { - /* - * SCOPE_SYSTEM requires appropriate privilege - * reset to process scope and try again - */ - rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS); - PR_ASSERT(0 == rv); - thred->state &= ~PT_THREAD_BOUND; - } -#else - /* Remember that we don't have thread scheduling privilege. */ - pt_schedpriv = EPERM; - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("_PR_CreateThread: no thread scheduling privilege")); - /* Try creating the thread again without setting priority. */ -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - rv = pthread_attr_setinheritsched(&tattr, PTHREAD_INHERIT_SCHED); - PR_ASSERT(0 == rv); -#endif -#endif /* IRIX */ - rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred); - } -#endif - - if (0 != rv) - { -#if defined(_PR_DCETHREADS) - PRIntn oserr = errno; -#else - PRIntn oserr = rv; -#endif - PR_Lock(pt_book.ml); - if (thred->state & PT_THREAD_SYSTEM) - pt_book.system -= 1; - else if (--pt_book.user == pt_book.this_many) - PR_NotifyAllCondVar(pt_book.cv); - PR_Unlock(pt_book.ml); - - PR_Free(thred->stack); - PR_Free(thred); /* all that work ... poof! */ - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, oserr); - thred = NULL; /* and for what? */ - goto done; - } - - /* - * Both the parent thread and this new thread set thred->id. - * The parent thread must ensure that thred->id is set before - * PR_CreateThread() returns. (See comments in _pt_root().) - */ - thred->id = id; - - /* - * If the new thread is detached, tell it that PR_CreateThread() - * has set thred->id so it's ok to delete thred. - */ - if (PR_UNJOINABLE_THREAD == state) - { - PR_Lock(pt_book.ml); - thred->okToDelete = PR_TRUE; - PR_NotifyAllCondVar(pt_book.cv); - PR_Unlock(pt_book.ml); - } - } - -done: - rv = _PT_PTHREAD_ATTR_DESTROY(&tattr); - PR_ASSERT(0 == rv); - - return thred; -} /* _PR_CreateThread */ - -PR_IMPLEMENT(PRThread*) PR_CreateThread( - PRThreadType type, void (*start)(void *arg), void *arg, - PRThreadPriority priority, PRThreadScope scope, - PRThreadState state, PRUint32 stackSize) -{ - return _PR_CreateThread( - type, start, arg, priority, scope, state, stackSize, PR_FALSE); -} /* PR_CreateThread */ - -PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble( - PRThreadType type, void (*start)(void *arg), void *arg, - PRThreadPriority priority, PRThreadScope scope, - PRThreadState state, PRUint32 stackSize) -{ - return _PR_CreateThread( - type, start, arg, priority, scope, state, stackSize, PR_TRUE); -} /* PR_CreateThreadGCAble */ - -PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thred) -{ - return thred->environment; -} /* GetExecutionEnvironment */ - -PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thred, void *env) -{ - thred->environment = env; -} /* SetExecutionEnvironment */ - -PR_IMPLEMENT(PRThread*) PR_AttachThread( - PRThreadType type, PRThreadPriority priority, PRThreadStack *stack) -{ - return PR_GetCurrentThread(); -} /* PR_AttachThread */ - - -PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thred) -{ - int rv = -1; - void *result = NULL; - PR_ASSERT(thred != NULL); - - if ((0xafafafaf == thred->state) - || (PT_THREAD_DETACHED == (PT_THREAD_DETACHED & thred->state)) - || (PT_THREAD_FOREIGN == (PT_THREAD_FOREIGN & thred->state))) - { - /* - * This might be a bad address, but if it isn't, the state should - * either be an unjoinable thread or it's already had the object - * deleted. However, the client that called join on a detached - * thread deserves all the rath I can muster.... - */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - PR_LogPrint( - "PR_JoinThread: %p not joinable | already smashed\n", thred); - } - else - { - pthread_t id = thred->id; - rv = pthread_join(id, &result); - PR_ASSERT(rv == 0 && result == NULL); - if (0 == rv) - { -#ifdef _PR_DCETHREADS - rv = pthread_detach(&id); - PR_ASSERT(0 == rv); -#endif - /* - * PR_FALSE, because the thread already called the TPD - * destructors before exiting _pt_root. - */ - _pt_thread_death_internal(thred, PR_FALSE); - } - else - { - PRErrorCode prerror; - switch (rv) - { - case EINVAL: /* not a joinable thread */ - case ESRCH: /* no thread with given ID */ - prerror = PR_INVALID_ARGUMENT_ERROR; - break; - case EDEADLK: /* a thread joining with itself */ - prerror = PR_DEADLOCK_ERROR; - break; - default: - prerror = PR_UNKNOWN_ERROR; - break; - } - PR_SetError(prerror, rv); - } - } - return (0 == rv) ? PR_SUCCESS : PR_FAILURE; -} /* PR_JoinThread */ - -PR_IMPLEMENT(void) PR_DetachThread(void) -{ - void *thred; - int rv; - - _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); - if (NULL == thred) return; - _pt_thread_death(thred); - rv = pthread_setspecific(pt_book.key, NULL); - PR_ASSERT(0 == rv); -} /* PR_DetachThread */ - -PR_IMPLEMENT(PRThread*) PR_GetCurrentThread(void) -{ - void *thred; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); - if (NULL == thred) thred = pt_AttachThread(); - PR_ASSERT(NULL != thred); - return (PRThread*)thred; -} /* PR_GetCurrentThread */ - -PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thred) -{ - return (thred->state & PT_THREAD_BOUND) ? - PR_GLOBAL_BOUND_THREAD : PR_GLOBAL_THREAD; -} /* PR_GetThreadScope() */ - -PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thred) -{ - return (thred->state & PT_THREAD_SYSTEM) ? - PR_SYSTEM_THREAD : PR_USER_THREAD; -} - -PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thred) -{ - return (thred->state & PT_THREAD_DETACHED) ? - PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD; -} /* PR_GetThreadState */ - -PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thred) -{ - PR_ASSERT(thred != NULL); - return thred->priority; -} /* PR_GetThreadPriority */ - -PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred, PRThreadPriority newPri) -{ - PRIntn rv = -1; - - PR_ASSERT(NULL != thred); - - if ((PRIntn)PR_PRIORITY_FIRST > (PRIntn)newPri) - newPri = PR_PRIORITY_FIRST; - else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)newPri) - newPri = PR_PRIORITY_LAST; - -#if defined(_PR_DCETHREADS) - rv = pthread_setprio(thred->id, pt_PriorityMap(newPri)); - /* pthread_setprio returns the old priority */ -#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - if (EPERM != pt_schedpriv) - { - int policy; - struct sched_param schedule; - - rv = pthread_getschedparam(thred->id, &policy, &schedule); - if(0 == rv) { - schedule.sched_priority = pt_PriorityMap(newPri); - rv = pthread_setschedparam(thred->id, policy, &schedule); - if (EPERM == rv) - { - pt_schedpriv = EPERM; - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("PR_SetThreadPriority: no thread scheduling privilege")); - } - } - if (rv != 0) - rv = -1; - } -#endif - - thred->priority = newPri; -} /* PR_SetThreadPriority */ - -PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred) -{ - /* - ** If the target thread indicates that it's waiting, - ** find the condition and broadcast to it. Broadcast - ** since we don't know which thread (if there are more - ** than one). This sounds risky, but clients must - ** test their invariants when resumed from a wait and - ** I don't expect very many threads to be waiting on - ** a single condition and I don't expect interrupt to - ** be used very often. - ** - ** I don't know why I thought this would work. Must have - ** been one of those weaker momements after I'd been - ** smelling the vapors. - ** - ** Even with the followng changes it is possible that - ** the pointer to the condition variable is pointing - ** at a bogus value. Will the unerlying code detect - ** that? - */ - PRCondVar *cv; - PR_ASSERT(NULL != thred); - if (NULL == thred) return PR_FAILURE; - - thred->state |= PT_THREAD_ABORTED; - - cv = thred->waiting; - if ((NULL != cv) && !thred->interrupt_blocked) - { - PRIntn rv; - (void)PR_ATOMIC_INCREMENT(&cv->notify_pending); - rv = pthread_cond_broadcast(&cv->cv); - PR_ASSERT(0 == rv); - if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending)) - PR_DestroyCondVar(cv); - } - return PR_SUCCESS; -} /* PR_Interrupt */ - -PR_IMPLEMENT(void) PR_ClearInterrupt(void) -{ - PRThread *me = PR_GetCurrentThread(); - me->state &= ~PT_THREAD_ABORTED; -} /* PR_ClearInterrupt */ - -PR_IMPLEMENT(void) PR_BlockInterrupt(void) -{ - PRThread *me = PR_GetCurrentThread(); - _PT_THREAD_BLOCK_INTERRUPT(me); -} /* PR_BlockInterrupt */ - -PR_IMPLEMENT(void) PR_UnblockInterrupt(void) -{ - PRThread *me = PR_GetCurrentThread(); - _PT_THREAD_UNBLOCK_INTERRUPT(me); -} /* PR_UnblockInterrupt */ - -PR_IMPLEMENT(PRStatus) PR_Yield(void) -{ - static PRBool warning = PR_TRUE; - if (warning) warning = _PR_Obsolete( - "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)"); - return PR_Sleep(PR_INTERVAL_NO_WAIT); -} - -PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks) -{ - PRStatus rv = PR_SUCCESS; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (PR_INTERVAL_NO_WAIT == ticks) - { - _PT_PTHREAD_YIELD(); - } - else - { - PRCondVar *cv; - PRIntervalTime timein; - - timein = PR_IntervalNow(); - cv = PR_NewCondVar(_pr_sleeplock); - PR_ASSERT(cv != NULL); - PR_Lock(_pr_sleeplock); - do - { - PRIntervalTime now = PR_IntervalNow(); - PRIntervalTime delta = now - timein; - if (delta > ticks) break; - rv = PR_WaitCondVar(cv, ticks - delta); - } while (PR_SUCCESS == rv); - PR_Unlock(_pr_sleeplock); - PR_DestroyCondVar(cv); - } - return rv; -} /* PR_Sleep */ - -static void _pt_thread_death(void *arg) -{ - void *thred; - int rv; - - _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); - if (NULL == thred) - { - /* - * Have PR_GetCurrentThread return the expected value to the - * destructors. - */ - rv = pthread_setspecific(pt_book.key, arg); - PR_ASSERT(0 == rv); - } - - /* PR_TRUE for: call destructors */ - _pt_thread_death_internal(arg, PR_TRUE); - - if (NULL == thred) - { - rv = pthread_setspecific(pt_book.key, NULL); - PR_ASSERT(0 == rv); - } -} - -static void _pt_thread_death_internal(void *arg, PRBool callDestructors) -{ - PRThread *thred = (PRThread*)arg; - - if (thred->state & (PT_THREAD_FOREIGN|PT_THREAD_PRIMORD)) - { - PR_Lock(pt_book.ml); - if (NULL == thred->prev) - pt_book.first = thred->next; - else - thred->prev->next = thred->next; - if (NULL == thred->next) - pt_book.last = thred->prev; - else - thred->next->prev = thred->prev; - PR_Unlock(pt_book.ml); - } - if (callDestructors) - _PR_DestroyThreadPrivate(thred); - PR_Free(thred->privateData); - if (NULL != thred->errorString) - PR_Free(thred->errorString); - if (NULL != thred->name) - PR_Free(thred->name); - PR_Free(thred->stack); - if (NULL != thred->syspoll_list) - PR_Free(thred->syspoll_list); -#if defined(_PR_POLL_WITH_SELECT) - if (NULL != thred->selectfd_list) - PR_Free(thred->selectfd_list); -#endif -#if defined(DEBUG) - memset(thred, 0xaf, sizeof(PRThread)); -#endif /* defined(DEBUG) */ - PR_Free(thred); -} /* _pt_thread_death */ - -void _PR_InitThreads( - PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs) -{ - int rv; - PRThread *thred; - -#ifdef _PR_NEED_PTHREAD_INIT - /* - * On BSD/OS (3.1 and 4.0), the pthread subsystem is lazily - * initialized, but pthread_self() fails to initialize - * pthreads and hence returns a null thread ID if invoked - * by the primordial thread before any other pthread call. - * So we explicitly initialize pthreads here. - */ - pthread_init(); -#endif - -#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) -#if defined(FREEBSD) - { - pthread_attr_t attr; - int policy; - /* get the min and max priorities of the default policy */ - pthread_attr_init(&attr); - pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_getschedpolicy(&attr, &policy); - pt_book.minPrio = sched_get_priority_min(policy); - PR_ASSERT(-1 != pt_book.minPrio); - pt_book.maxPrio = sched_get_priority_max(policy); - PR_ASSERT(-1 != pt_book.maxPrio); - pthread_attr_destroy(&attr); - } -#else - /* - ** These might be function evaluations - */ - pt_book.minPrio = PT_PRIO_MIN; - pt_book.maxPrio = PT_PRIO_MAX; -#endif -#endif - - PR_ASSERT(NULL == pt_book.ml); - pt_book.ml = PR_NewLock(); - PR_ASSERT(NULL != pt_book.ml); - pt_book.cv = PR_NewCondVar(pt_book.ml); - PR_ASSERT(NULL != pt_book.cv); - thred = PR_NEWZAP(PRThread); - PR_ASSERT(NULL != thred); - thred->arg = NULL; - thred->startFunc = NULL; - thred->priority = priority; - thred->id = pthread_self(); - - thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD); - if (PR_SYSTEM_THREAD == type) - { - thred->state |= PT_THREAD_SYSTEM; - pt_book.system += 1; - pt_book.this_many = 0; - } - else - { - pt_book.user += 1; - pt_book.this_many = 1; - } - thred->next = thred->prev = NULL; - pt_book.first = pt_book.last = thred; - - thred->stack = PR_NEWZAP(PRThreadStack); - PR_ASSERT(thred->stack != NULL); - thred->stack->stackSize = 0; - thred->stack->thr = thred; - _PR_InitializeStack(thred->stack); - - /* - * Create a key for our use to store a backpointer in the pthread - * to our PRThread object. This object gets deleted when the thread - * returns from its root in the case of a detached thread. Other - * threads delete the objects in Join. - * - * NB: The destructor logic seems to have a bug so it isn't used. - * NBB: Oh really? I'm going to give it a spin - AOF 19 June 1998. - * More info - the problem is that pthreads calls the destructor - * eagerly as the thread returns from its root, rather than lazily - * after the thread is joined. Therefore, threads that are joining - * and holding PRThread references are actually holding pointers to - * nothing. - */ - rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death); - PR_ASSERT(0 == rv); - rv = pthread_setspecific(pt_book.key, thred); - PR_ASSERT(0 == rv); - PR_SetThreadPriority(thred, priority); -} /* _PR_InitThreads */ - -#ifdef __GNUC__ -/* - * GCC supports the constructor and destructor attributes as of - * version 2.5. - */ -static void _PR_Fini(void) __attribute__ ((destructor)); -#elif defined(__SUNPRO_C) -/* - * Sun Studio compiler - */ -#pragma fini(_PR_Fini) -static void _PR_Fini(void); -#elif defined(HPUX) -/* - * Current versions of HP C compiler define __HP_cc. - * HP C compiler A.11.01.20 doesn't define __HP_cc. - */ -#if defined(__ia64) || defined(_LP64) -#pragma FINI "_PR_Fini" -static void _PR_Fini(void); -#else -/* - * Only HP-UX 10.x style initializers are supported in 32-bit links. - * Need to use the +I PR_HPUX10xInit linker option. - */ -#include - -static void _PR_Fini(void); - -void PR_HPUX10xInit(shl_t handle, int loading) -{ - /* - * This function is called when a shared library is loaded as well - * as when the shared library is unloaded. Note that it may not - * be called when the user's program terminates. - * - * handle is the shl_load API handle for the shared library being - * initialized. - * - * loading is non-zero at startup and zero at termination. - */ - if (loading) { - /* ... do some initializations ... */ - } else { - _PR_Fini(); - } -} -#endif -#elif defined(AIX) -/* Need to use the -binitfini::_PR_Fini linker option. */ -#endif - -void _PR_Fini(void) -{ - void *thred; - int rv; - - if (!_pr_initialized) return; - - _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); - if (NULL != thred) - { - /* - * PR_FALSE, because it is unsafe to call back to the - * thread private data destructors at final cleanup. - */ - _pt_thread_death_internal(thred, PR_FALSE); - rv = pthread_setspecific(pt_book.key, NULL); - PR_ASSERT(0 == rv); - } - rv = pthread_key_delete(pt_book.key); - PR_ASSERT(0 == rv); - /* TODO: free other resources used by NSPR */ - /* _pr_initialized = PR_FALSE; */ -} /* _PR_Fini */ - -PR_IMPLEMENT(PRStatus) PR_Cleanup(void) -{ - PRThread *me = PR_GetCurrentThread(); - int rv; - PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR")); - PR_ASSERT(me->state & PT_THREAD_PRIMORD); - if (me->state & PT_THREAD_PRIMORD) - { - PR_Lock(pt_book.ml); - while (pt_book.user > pt_book.this_many) - PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT); - if (me->state & PT_THREAD_SYSTEM) - pt_book.system -= 1; - else - pt_book.user -= 1; - PR_Unlock(pt_book.ml); - - _PR_MD_EARLY_CLEANUP(); - - _PR_CleanupMW(); - _PR_CleanupTime(); - _PR_CleanupDtoa(); - _PR_CleanupCallOnce(); - _PR_ShutdownLinker(); - _PR_LogCleanup(); - _PR_CleanupNet(); - /* Close all the fd's before calling _PR_CleanupIO */ - _PR_CleanupIO(); - _PR_CleanupCMon(); - - _pt_thread_death(me); - rv = pthread_setspecific(pt_book.key, NULL); - PR_ASSERT(0 == rv); - /* - * I am not sure if it's safe to delete the cv and lock here, - * since there may still be "system" threads around. If this - * call isn't immediately prior to exiting, then there's a - * problem. - */ - if (0 == pt_book.system) - { - PR_DestroyCondVar(pt_book.cv); pt_book.cv = NULL; - PR_DestroyLock(pt_book.ml); pt_book.ml = NULL; - } - PR_DestroyLock(_pr_sleeplock); - _pr_sleeplock = NULL; - _PR_CleanupLayerCache(); - _PR_CleanupEnv(); -#ifdef _PR_ZONE_ALLOCATOR - _PR_DestroyZones(); -#endif - _pr_initialized = PR_FALSE; - return PR_SUCCESS; - } - return PR_FAILURE; -} /* PR_Cleanup */ - -PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status) -{ - _exit(status); -} - -PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thred) -{ -#if defined(_PR_DCETHREADS) - return (PRUint32)&thred->id; /* this is really a sham! */ -#else - return (PRUint32)thred->id; /* and I don't know what they will do with it */ -#endif -} - -/* - * $$$ - * The following two thread-to-processor affinity functions are not - * yet implemented for pthreads. By the way, these functions should return - * PRStatus rather than PRInt32 to indicate the success/failure status. - * $$$ - */ - -PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask) -{ - return 0; /* not implemented */ -} - -PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask ) -{ - return 0; /* not implemented */ -} - -PR_IMPLEMENT(void) -PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg) -{ - thread->dump = dump; - thread->dumpArg = arg; -} - -/* - * Garbage collection support follows. - */ - -#if defined(_PR_DCETHREADS) - -/* - * statics for Garbage Collection support. We don't need to protect these - * signal masks since the garbage collector itself is protected by a lock - * and multiple threads will not be garbage collecting at the same time. - */ -static sigset_t javagc_vtalarm_sigmask; -static sigset_t javagc_intsoff_sigmask; - -#else /* defined(_PR_DCETHREADS) */ - -/* a bogus signal mask for forcing a timed wait */ -/* Not so bogus in AIX as we really do a sigwait */ -static sigset_t sigwait_set; - -static struct timespec onemillisec = {0, 1000000L}; -#ifndef PT_NO_SIGTIMEDWAIT -static struct timespec hundredmillisec = {0, 100000000L}; -#endif - -static void suspend_signal_handler(PRIntn sig); - -#ifdef PT_NO_SIGTIMEDWAIT -static void null_signal_handler(PRIntn sig); -#endif - -#endif /* defined(_PR_DCETHREADS) */ - -/* - * Linux pthreads use SIGUSR1 and SIGUSR2 internally, which - * conflict with the use of these two signals in our GC support. - * So we don't know how to support GC on Linux pthreads. - */ -static void init_pthread_gc_support(void) -{ -#ifndef SYMBIAN - PRIntn rv; - -#if defined(_PR_DCETHREADS) - rv = sigemptyset(&javagc_vtalarm_sigmask); - PR_ASSERT(0 == rv); - rv = sigaddset(&javagc_vtalarm_sigmask, SIGVTALRM); - PR_ASSERT(0 == rv); -#else /* defined(_PR_DCETHREADS) */ - { - struct sigaction sigact_usr2; - - sigact_usr2.sa_handler = suspend_signal_handler; - sigact_usr2.sa_flags = SA_RESTART; - sigemptyset (&sigact_usr2.sa_mask); - - rv = sigaction (SIGUSR2, &sigact_usr2, NULL); - PR_ASSERT(0 == rv); - - sigemptyset (&sigwait_set); -#if defined(PT_NO_SIGTIMEDWAIT) - sigaddset (&sigwait_set, SIGUSR1); -#else - sigaddset (&sigwait_set, SIGUSR2); -#endif /* defined(PT_NO_SIGTIMEDWAIT) */ - } -#if defined(PT_NO_SIGTIMEDWAIT) - { - struct sigaction sigact_null; - sigact_null.sa_handler = null_signal_handler; - sigact_null.sa_flags = SA_RESTART; - sigemptyset (&sigact_null.sa_mask); - rv = sigaction (SIGUSR1, &sigact_null, NULL); - PR_ASSERT(0 ==rv); - } -#endif /* defined(PT_NO_SIGTIMEDWAIT) */ -#endif /* defined(_PR_DCETHREADS) */ -#endif /* SYMBIAN */ -} - -PR_IMPLEMENT(void) PR_SetThreadGCAble(void) -{ - PR_Lock(pt_book.ml); - PR_GetCurrentThread()->state |= PT_THREAD_GCABLE; - PR_Unlock(pt_book.ml); -} - -PR_IMPLEMENT(void) PR_ClearThreadGCAble(void) -{ - PR_Lock(pt_book.ml); - PR_GetCurrentThread()->state &= (~PT_THREAD_GCABLE); - PR_Unlock(pt_book.ml); -} - -#if defined(DEBUG) -static PRBool suspendAllOn = PR_FALSE; -#endif - -static PRBool suspendAllSuspended = PR_FALSE; - -PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg) -{ - PRIntn count = 0; - PRStatus rv = PR_SUCCESS; - PRThread* thred = pt_book.first; - -#if defined(DEBUG) || defined(FORCE_PR_ASSERT) -#if !defined(_PR_DCETHREADS) - PRThread *me = PR_GetCurrentThread(); -#endif -#endif - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_EnumerateThreads\n")); - /* - * $$$ - * Need to suspend all threads other than me before doing this. - * This is really a gross and disgusting thing to do. The only - * good thing is that since all other threads are suspended, holding - * the lock during a callback seems like child's play. - * $$$ - */ - PR_ASSERT(suspendAllOn); - - while (thred != NULL) - { - /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking - * qp->next after applying the function "func". In particular, "func" - * might remove the thread from the queue and put it into another one in - * which case qp->next no longer points to the next entry in the original - * queue. - * - * To get around this problem, we save qp->next in qp_next before applying - * "func" and use that saved value as the next value after applying "func". - */ - PRThread* next = thred->next; - - if (_PT_IS_GCABLE_THREAD(thred)) - { -#if !defined(_PR_DCETHREADS) - PR_ASSERT((thred == me) || (thred->suspend & PT_THREAD_SUSPENDED)); -#endif - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("In PR_EnumerateThreads callback thread %p thid = %X\n", - thred, thred->id)); - - rv = func(thred, count++, arg); - if (rv != PR_SUCCESS) - return rv; - } - thred = next; - } - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("End PR_EnumerateThreads count = %d \n", count)); - return rv; -} /* PR_EnumerateThreads */ - -/* - * PR_SuspendAll and PR_ResumeAll are called during garbage collection. The strategy - * we use is to send a SIGUSR2 signal to every gc able thread that we intend to suspend. - * The signal handler will record the stack pointer and will block until resumed by - * the resume call. Since the signal handler is the last routine called for the - * suspended thread, the stack pointer will also serve as a place where all the - * registers have been saved on the stack for the previously executing routines. - * - * Through global variables, we also make sure that PR_Suspend and PR_Resume does not - * proceed until the thread is suspended or resumed. - */ - -#if !defined(_PR_DCETHREADS) - -/* - * In the signal handler, we can not use condition variable notify or wait. - * This does not work consistently across all pthread platforms. We also can not - * use locking since that does not seem to work reliably across platforms. - * Only thing we can do is yielding while testing for a global condition - * to change. This does work on pthread supported platforms. We may have - * to play with priortities if there are any problems detected. - */ - - /* - * In AIX, you cannot use ANY pthread calls in the signal handler except perhaps - * pthread_yield. But that is horribly inefficient. Hence we use only sigwait, no - * sigtimedwait is available. We need to use another user signal, SIGUSR1. Actually - * SIGUSR1 is also used by exec in Java. So our usage here breaks the exec in Java, - * for AIX. You cannot use pthread_cond_wait or pthread_delay_np in the signal - * handler as all synchronization mechanisms just break down. - */ - -#if defined(PT_NO_SIGTIMEDWAIT) -static void null_signal_handler(PRIntn sig) -{ - return; -} -#endif - -static void suspend_signal_handler(PRIntn sig) -{ - PRThread *me = PR_GetCurrentThread(); - - PR_ASSERT(me != NULL); - PR_ASSERT(_PT_IS_GCABLE_THREAD(me)); - PR_ASSERT((me->suspend & PT_THREAD_SUSPENDED) == 0); - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("Begin suspend_signal_handler thred %p thread id = %X\n", - me, me->id)); - - /* - * save stack pointer - */ - me->sp = &me; - - /* - At this point, the thread's stack pointer has been saved, - And it is going to enter a wait loop until it is resumed. - So it is _really_ suspended - */ - - me->suspend |= PT_THREAD_SUSPENDED; - - /* - * now, block current thread - */ -#if defined(PT_NO_SIGTIMEDWAIT) - pthread_cond_signal(&me->suspendResumeCV); - while (me->suspend & PT_THREAD_SUSPENDED) - { -#if !defined(FREEBSD) && !defined(NETBSD) && !defined(OPENBSD) \ - && !defined(BSDI) && !defined(UNIXWARE) \ - && !defined(DARWIN) && !defined(RISCOS) \ - && !defined(SYMBIAN) /*XXX*/ - PRIntn rv; - sigwait(&sigwait_set, &rv); -#endif - } - me->suspend |= PT_THREAD_RESUMED; - pthread_cond_signal(&me->suspendResumeCV); -#else /* defined(PT_NO_SIGTIMEDWAIT) */ - while (me->suspend & PT_THREAD_SUSPENDED) - { - PRIntn rv = sigtimedwait(&sigwait_set, NULL, &hundredmillisec); - PR_ASSERT(-1 == rv); - } - me->suspend |= PT_THREAD_RESUMED; -#endif - - /* - * At this point, thread has been resumed, so set a global condition. - * The ResumeAll needs to know that this has really been resumed. - * So the signal handler sets a flag which PR_ResumeAll will reset. - * The PR_ResumeAll must reset this flag ... - */ - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("End suspend_signal_handler thred = %p tid = %X\n", me, me->id)); -} /* suspend_signal_handler */ - -static void pt_SuspendSet(PRThread *thred) -{ - PRIntn rv; - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("pt_SuspendSet thred %p thread id = %X\n", thred, thred->id)); - - - /* - * Check the thread state and signal the thread to suspend - */ - - PR_ASSERT((thred->suspend & PT_THREAD_SUSPENDED) == 0); - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("doing pthread_kill in pt_SuspendSet thred %p tid = %X\n", - thred, thred->id)); -#if defined(SYMBIAN) - /* All signal group functions are not implemented in Symbian OS */ - rv = 0; -#else - rv = pthread_kill (thred->id, SIGUSR2); -#endif - PR_ASSERT(0 == rv); -} - -static void pt_SuspendTest(PRThread *thred) -{ - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("Begin pt_SuspendTest thred %p thread id = %X\n", thred, thred->id)); - - - /* - * Wait for the thread to be really suspended. This happens when the - * suspend signal handler stores the stack pointer and sets the state - * to suspended. - */ - -#if defined(PT_NO_SIGTIMEDWAIT) - pthread_mutex_lock(&thred->suspendResumeMutex); - while ((thred->suspend & PT_THREAD_SUSPENDED) == 0) - { - pthread_cond_timedwait( - &thred->suspendResumeCV, &thred->suspendResumeMutex, &onemillisec); - } - pthread_mutex_unlock(&thred->suspendResumeMutex); -#else - while ((thred->suspend & PT_THREAD_SUSPENDED) == 0) - { - PRIntn rv = sigtimedwait(&sigwait_set, NULL, &onemillisec); - PR_ASSERT(-1 == rv); - } -#endif - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("End pt_SuspendTest thred %p tid %X\n", thred, thred->id)); -} /* pt_SuspendTest */ - -static void pt_ResumeSet(PRThread *thred) -{ - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("pt_ResumeSet thred %p thread id = %X\n", thred, thred->id)); - - /* - * Clear the global state and set the thread state so that it will - * continue past yield loop in the suspend signal handler - */ - - PR_ASSERT(thred->suspend & PT_THREAD_SUSPENDED); - - - thred->suspend &= ~PT_THREAD_SUSPENDED; - -#if defined(PT_NO_SIGTIMEDWAIT) -#if defined(SYMBIAN) - /* All signal group functions are not implemented in Symbian OS */ -#else - pthread_kill(thred->id, SIGUSR1); -#endif -#endif - -} /* pt_ResumeSet */ - -static void pt_ResumeTest(PRThread *thred) -{ - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("Begin pt_ResumeTest thred %p thread id = %X\n", thred, thred->id)); - - /* - * Wait for the threads resume state to change - * to indicate it is really resumed - */ -#if defined(PT_NO_SIGTIMEDWAIT) - pthread_mutex_lock(&thred->suspendResumeMutex); - while ((thred->suspend & PT_THREAD_RESUMED) == 0) - { - pthread_cond_timedwait( - &thred->suspendResumeCV, &thred->suspendResumeMutex, &onemillisec); - } - pthread_mutex_unlock(&thred->suspendResumeMutex); -#else - while ((thred->suspend & PT_THREAD_RESUMED) == 0) { - PRIntn rv = sigtimedwait(&sigwait_set, NULL, &onemillisec); - PR_ASSERT(-1 == rv); - } -#endif - - thred->suspend &= ~PT_THREAD_RESUMED; - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ( - "End pt_ResumeTest thred %p tid %X\n", thred, thred->id)); -} /* pt_ResumeTest */ - -static pthread_once_t pt_gc_support_control = PTHREAD_ONCE_INIT; - -PR_IMPLEMENT(void) PR_SuspendAll(void) -{ -#ifdef DEBUG - PRIntervalTime stime, etime; -#endif - PRThread* thred = pt_book.first; - PRThread *me = PR_GetCurrentThread(); - int rv; - - rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support); - PR_ASSERT(0 == rv); - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n")); - /* - * Stop all threads which are marked GC able. - */ - PR_Lock(pt_book.ml); -#ifdef DEBUG - suspendAllOn = PR_TRUE; - stime = PR_IntervalNow(); -#endif - while (thred != NULL) - { - if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) - pt_SuspendSet(thred); - thred = thred->next; - } - - /* Wait till they are really suspended */ - thred = pt_book.first; - while (thred != NULL) - { - if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) - pt_SuspendTest(thred); - thred = thred->next; - } - - suspendAllSuspended = PR_TRUE; - -#ifdef DEBUG - etime = PR_IntervalNow(); - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,\ - ("End PR_SuspendAll (time %dms)\n", - PR_IntervalToMilliseconds(etime - stime))); -#endif -} /* PR_SuspendAll */ - -PR_IMPLEMENT(void) PR_ResumeAll(void) -{ -#ifdef DEBUG - PRIntervalTime stime, etime; -#endif - PRThread* thred = pt_book.first; - PRThread *me = PR_GetCurrentThread(); - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n")); - /* - * Resume all previously suspended GC able threads. - */ - suspendAllSuspended = PR_FALSE; -#ifdef DEBUG - stime = PR_IntervalNow(); -#endif - - while (thred != NULL) - { - if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) - pt_ResumeSet(thred); - thred = thred->next; - } - - thred = pt_book.first; - while (thred != NULL) - { - if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) - pt_ResumeTest(thred); - thred = thred->next; - } - - PR_Unlock(pt_book.ml); -#ifdef DEBUG - suspendAllOn = PR_FALSE; - etime = PR_IntervalNow(); - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("End PR_ResumeAll (time %dms)\n", - PR_IntervalToMilliseconds(etime - stime))); -#endif -} /* PR_ResumeAll */ - -/* Return the stack pointer for the given thread- used by the GC */ -PR_IMPLEMENT(void *)PR_GetSP(PRThread *thred) -{ - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, - ("in PR_GetSP thred %p thid = %X, sp = %p\n", - thred, thred->id, thred->sp)); - return thred->sp; -} /* PR_GetSP */ - -#else /* !defined(_PR_DCETHREADS) */ - -static pthread_once_t pt_gc_support_control = pthread_once_init; - -/* - * For DCE threads, there is no pthread_kill or a way of suspending or resuming a - * particular thread. We will just disable the preemption (virtual timer alarm) and - * let the executing thread finish the garbage collection. This stops all other threads - * (GC able or not) and is very inefficient but there is no other choice. - */ -PR_IMPLEMENT(void) PR_SuspendAll() -{ - PRIntn rv; - - rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support); - PR_ASSERT(0 == rv); /* returns -1 on failure */ -#ifdef DEBUG - suspendAllOn = PR_TRUE; -#endif - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n")); - /* - * turn off preemption - i.e add virtual alarm signal to the set of - * blocking signals - */ - rv = sigprocmask( - SIG_BLOCK, &javagc_vtalarm_sigmask, &javagc_intsoff_sigmask); - PR_ASSERT(0 == rv); - suspendAllSuspended = PR_TRUE; - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_SuspendAll\n")); -} /* PR_SuspendAll */ - -PR_IMPLEMENT(void) PR_ResumeAll() -{ - PRIntn rv; - - suspendAllSuspended = PR_FALSE; - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n")); - /* turn on preemption - i.e re-enable virtual alarm signal */ - - rv = sigprocmask(SIG_SETMASK, &javagc_intsoff_sigmask, (sigset_t *)NULL); - PR_ASSERT(0 == rv); -#ifdef DEBUG - suspendAllOn = PR_FALSE; -#endif - - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_ResumeAll\n")); -} /* PR_ResumeAll */ - -/* Return the stack pointer for the given thread- used by the GC */ -PR_IMPLEMENT(void*)PR_GetSP(PRThread *thred) -{ - pthread_t tid = thred->id; - char *thread_tcb, *top_sp; - - /* - * For HPUX DCE threads, pthread_t is a struct with the - * following three fields (see pthread.h, dce/cma.h): - * cma_t_address field1; - * short int field2; - * short int field3; - * where cma_t_address is typedef'd to be either void* - * or char*. - */ - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_GetSP\n")); - thread_tcb = (char*)tid.field1; - top_sp = *(char**)(thread_tcb + 128); - PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_GetSP %p \n", top_sp)); - return top_sp; -} /* PR_GetSP */ - -#endif /* !defined(_PR_DCETHREADS) */ - -PR_IMPLEMENT(PRStatus) PR_SetCurrentThreadName(const char *name) -{ - PRThread *thread; - size_t nameLen; - int result; - - if (!name) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - - thread = PR_GetCurrentThread(); - if (!thread) - return PR_FAILURE; - - PR_Free(thread->name); - nameLen = strlen(name); - thread->name = (char *)PR_Malloc(nameLen + 1); - if (!thread->name) - return PR_FAILURE; - memcpy(thread->name, name, nameLen + 1); - -#if defined(OPENBSD) || defined(FREEBSD) - result = pthread_set_name_np(thread->id, name); -#else /* not BSD */ - /* - * On OSX, pthread_setname_np is only available in 10.6 or later, so test - * for it at runtime. It also may not be available on all linux distros. - */ -#if defined(DARWIN) - int (*dynamic_pthread_setname_np)(const char*); -#else - int (*dynamic_pthread_setname_np)(pthread_t, const char*); -#endif - - *(void**)(&dynamic_pthread_setname_np) = - dlsym(RTLD_DEFAULT, "pthread_setname_np"); - if (!dynamic_pthread_setname_np) - return PR_SUCCESS; - - /* - * The 15-character name length limit is an experimentally determined - * length of a null-terminated string that most linux distros and OS X - * accept as an argument to pthread_setname_np. Otherwise the E2BIG - * error is returned by the function. - */ -#define SETNAME_LENGTH_CONSTRAINT 15 -#define SETNAME_FRAGMENT1_LENGTH (SETNAME_LENGTH_CONSTRAINT >> 1) -#define SETNAME_FRAGMENT2_LENGTH \ - (SETNAME_LENGTH_CONSTRAINT - SETNAME_FRAGMENT1_LENGTH - 1) - char name_dup[SETNAME_LENGTH_CONSTRAINT + 1]; - if (nameLen > SETNAME_LENGTH_CONSTRAINT) { - memcpy(name_dup, name, SETNAME_FRAGMENT1_LENGTH); - name_dup[SETNAME_FRAGMENT1_LENGTH] = '~'; - /* Note that this also copies the null terminator. */ - memcpy(name_dup + SETNAME_FRAGMENT1_LENGTH + 1, - name + nameLen - SETNAME_FRAGMENT2_LENGTH, - SETNAME_FRAGMENT2_LENGTH + 1); - name = name_dup; - } - -#if defined(DARWIN) - result = dynamic_pthread_setname_np(name); -#else - result = dynamic_pthread_setname_np(thread->id, name); -#endif -#endif /* not BSD */ - - if (result) { - PR_SetError(PR_UNKNOWN_ERROR, result); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) -{ - if (!thread) - return NULL; - return thread->name; -} - -#endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */ - -/* ptthread.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/.cvsignore 2001-05-12 04:56:56.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/Makefile.in 2012-11-13 23:17:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -ifdef USE_PTHREADS -CSRCS = \ - $(NULL) -else -CSRCS = \ - prucpu.c \ - prucv.c \ - prulock.c \ - pruthr.c \ - prustack.c \ - $(NULL) -endif - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prucpu.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/prucpu.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prucpu.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/prucpu.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,405 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -_PRCPU *_pr_primordialCPU = NULL; - -PRInt32 _pr_md_idle_cpus; /* number of idle cpus */ -/* - * The idle threads in MxN models increment/decrement _pr_md_idle_cpus. - * If _PR_HAVE_ATOMIC_OPS is not defined, they can't use the atomic - * increment/decrement routines (which are based on PR_Lock/PR_Unlock), - * because PR_Lock asserts that the calling thread is not an idle thread. - * So we use a _MDLock to protect _pr_md_idle_cpus. - */ -#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY) -#ifndef _PR_HAVE_ATOMIC_OPS -static _MDLock _pr_md_idle_cpus_lock; -#endif -#endif -PRUintn _pr_numCPU; -PRInt32 _pr_cpus_exit; -PRUint32 _pr_cpu_affinity_mask = 0; - -#if !defined (_PR_GLOBAL_THREADS_ONLY) - -static PRUintn _pr_cpuID; - -static void PR_CALLBACK _PR_CPU_Idle(void *); - -static _PRCPU *_PR_CreateCPU(void); -static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread); - -#if !defined(_PR_LOCAL_THREADS_ONLY) -static void _PR_RunCPU(void *arg); -#endif - -void _PR_InitCPUs() -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (_native_threads_only) - return; - - _pr_cpuID = 0; - _MD_NEW_LOCK( &_pr_cpuLock); -#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY) -#ifndef _PR_HAVE_ATOMIC_OPS - _MD_NEW_LOCK(&_pr_md_idle_cpus_lock); -#endif -#endif - -#ifdef _PR_LOCAL_THREADS_ONLY - -#ifdef HAVE_CUSTOM_USER_THREADS - _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me); -#endif - - /* Now start the first CPU. */ - _pr_primordialCPU = _PR_CreateCPU(); - _pr_numCPU = 1; - _PR_StartCPU(_pr_primordialCPU, me); - - _PR_MD_SET_CURRENT_CPU(_pr_primordialCPU); - - /* Initialize cpu for current thread (could be different from me) */ - _PR_MD_CURRENT_THREAD()->cpu = _pr_primordialCPU; - - _PR_MD_SET_LAST_THREAD(me); - -#else /* Combined MxN model */ - - _pr_primordialCPU = _PR_CreateCPU(); - _pr_numCPU = 1; - _PR_CreateThread(PR_SYSTEM_THREAD, - _PR_RunCPU, - _pr_primordialCPU, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0, - _PR_IDLE_THREAD); - -#endif /* _PR_LOCAL_THREADS_ONLY */ - - _PR_MD_INIT_CPUS(); -} - -#ifdef WINNT -/* - * Right now this function merely stops the CPUs and does - * not do any other cleanup. - * - * It is only implemented for WINNT because bug 161998 only - * affects the WINNT version of NSPR, but it would be nice - * to implement this function for other platforms too. - */ -void _PR_CleanupCPUs(void) -{ - PRUintn i; - PRCList *qp; - _PRCPU *cpu; - - _pr_cpus_exit = 1; - for (i = 0; i < _pr_numCPU; i++) { - _PR_MD_WAKEUP_WAITER(NULL); - } - for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) { - cpu = _PR_CPU_PTR(qp); - _PR_MD_JOIN_THREAD(&cpu->thread->md); - } -} -#endif - -static _PRCPUQueue *_PR_CreateCPUQueue(void) -{ - PRInt32 index; - _PRCPUQueue *cpuQueue; - cpuQueue = PR_NEWZAP(_PRCPUQueue); - - _MD_NEW_LOCK( &cpuQueue->runQLock ); - _MD_NEW_LOCK( &cpuQueue->sleepQLock ); - _MD_NEW_LOCK( &cpuQueue->miscQLock ); - - for (index = 0; index < PR_PRIORITY_LAST + 1; index++) - PR_INIT_CLIST( &(cpuQueue->runQ[index]) ); - PR_INIT_CLIST( &(cpuQueue->sleepQ) ); - PR_INIT_CLIST( &(cpuQueue->pauseQ) ); - PR_INIT_CLIST( &(cpuQueue->suspendQ) ); - PR_INIT_CLIST( &(cpuQueue->waitingToJoinQ) ); - - cpuQueue->numCPUs = 1; - - return cpuQueue; -} - -/* - * Create a new CPU. - * - * This function initializes enough of the _PRCPU structure so - * that it can be accessed safely by a global thread or another - * CPU. This function does not create the native thread that - * will run the CPU nor does it initialize the parts of _PRCPU - * that must be initialized by that native thread. - * - * The reason we cannot simply have the native thread create - * and fully initialize a new CPU is that we need to be able to - * create a usable _pr_primordialCPU in _PR_InitCPUs without - * assuming that the primordial CPU thread we created can run - * during NSPR initialization. For example, on Windows while - * new threads can be created by DllMain, they won't be able - * to run during DLL initialization. If NSPR is initialized - * by DllMain, the primordial CPU thread won't run until DLL - * initialization is finished. - */ -static _PRCPU *_PR_CreateCPU(void) -{ - _PRCPU *cpu; - - cpu = PR_NEWZAP(_PRCPU); - if (cpu) { - cpu->queue = _PR_CreateCPUQueue(); - if (!cpu->queue) { - PR_DELETE(cpu); - return NULL; - } - } - return cpu; -} - -/* - * Start a new CPU. - * - * 'cpu' is a _PRCPU structure created by _PR_CreateCPU(). - * 'thread' is the native thread that will run the CPU. - * - * If this function fails, 'cpu' is destroyed. - */ -static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread) -{ - /* - ** Start a new cpu. The assumption this code makes is that the - ** underlying operating system creates a stack to go with the new - ** native thread. That stack will be used by the cpu when pausing. - */ - - PR_ASSERT(!_native_threads_only); - - cpu->last_clock = PR_IntervalNow(); - - /* Before we create any threads on this CPU we have to - * set the current CPU - */ - _PR_MD_SET_CURRENT_CPU(cpu); - _PR_MD_INIT_RUNNING_CPU(cpu); - thread->cpu = cpu; - - cpu->idle_thread = _PR_CreateThread(PR_SYSTEM_THREAD, - _PR_CPU_Idle, - (void *)cpu, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0, - _PR_IDLE_THREAD); - - if (!cpu->idle_thread) { - /* didn't clean up CPU queue XXXMB */ - PR_DELETE(cpu); - return PR_FAILURE; - } - PR_ASSERT(cpu->idle_thread->cpu == cpu); - - cpu->idle_thread->no_sched = 0; - - cpu->thread = thread; - - if (_pr_cpu_affinity_mask) - PR_SetThreadAffinityMask(thread, _pr_cpu_affinity_mask); - - /* Created and started a new CPU */ - _PR_CPU_LIST_LOCK(); - cpu->id = _pr_cpuID++; - PR_APPEND_LINK(&cpu->links, &_PR_CPUQ()); - _PR_CPU_LIST_UNLOCK(); - - return PR_SUCCESS; -} - -#if !defined(_PR_GLOBAL_THREADS_ONLY) && !defined(_PR_LOCAL_THREADS_ONLY) -/* -** This code is used during a cpu's initial creation. -*/ -static void _PR_RunCPU(void *arg) -{ - _PRCPU *cpu = (_PRCPU *)arg; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(NULL != me); - - /* - * _PR_StartCPU calls _PR_CreateThread to create the - * idle thread. Because _PR_CreateThread calls PR_Lock, - * the current thread has to remain a global thread - * during the _PR_StartCPU call so that it can wait for - * the lock if the lock is held by another thread. If - * we clear the _PR_GLOBAL_SCOPE flag in - * _PR_MD_CREATE_PRIMORDIAL_THREAD, the current thread - * will be treated as a local thread and have trouble - * waiting for the lock because the CPU is not fully - * constructed yet. - * - * After the CPU is started, it is safe to mark the - * current thread as a local thread. - */ - -#ifdef HAVE_CUSTOM_USER_THREADS - _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me); -#endif - - me->no_sched = 1; - _PR_StartCPU(cpu, me); - -#ifdef HAVE_CUSTOM_USER_THREADS - me->flags &= (~_PR_GLOBAL_SCOPE); -#endif - - _PR_MD_SET_CURRENT_CPU(cpu); - _PR_MD_SET_CURRENT_THREAD(cpu->thread); - me->cpu = cpu; - - while(1) { - PRInt32 is; - if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); - _PR_MD_START_INTERRUPTS(); - _PR_MD_SWITCH_CONTEXT(me); - } -} -#endif - -static void PR_CALLBACK _PR_CPU_Idle(void *_cpu) -{ - _PRCPU *cpu = (_PRCPU *)_cpu; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(NULL != me); - - me->cpu = cpu; - cpu->idle_thread = me; - if (_MD_LAST_THREAD()) - _MD_LAST_THREAD()->no_sched = 0; - if (!_PR_IS_NATIVE_THREAD(me)) _PR_MD_SET_INTSOFF(0); - while(1) { - PRInt32 is; - PRIntervalTime timeout; - if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); - - _PR_RUNQ_LOCK(cpu); -#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY) -#ifdef _PR_HAVE_ATOMIC_OPS - _PR_MD_ATOMIC_INCREMENT(&_pr_md_idle_cpus); -#else - _PR_MD_LOCK(&_pr_md_idle_cpus_lock); - _pr_md_idle_cpus++; - _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock); -#endif /* _PR_HAVE_ATOMIC_OPS */ -#endif - /* If someone on runq; do a nonblocking PAUSECPU */ - if (_PR_RUNQREADYMASK(me->cpu) != 0) { - _PR_RUNQ_UNLOCK(cpu); - timeout = PR_INTERVAL_NO_WAIT; - } else { - _PR_RUNQ_UNLOCK(cpu); - - _PR_SLEEPQ_LOCK(cpu); - if (PR_CLIST_IS_EMPTY(&_PR_SLEEPQ(me->cpu))) { - timeout = PR_INTERVAL_NO_TIMEOUT; - } else { - PRThread *wakeThread; - wakeThread = _PR_THREAD_PTR(_PR_SLEEPQ(me->cpu).next); - timeout = wakeThread->sleep; - } - _PR_SLEEPQ_UNLOCK(cpu); - } - - /* Wait for an IO to complete */ - (void)_PR_MD_PAUSE_CPU(timeout); - -#ifdef WINNT - if (_pr_cpus_exit) { - /* _PR_CleanupCPUs tells us to exit */ - _PR_MD_END_THREAD(); - } -#endif - -#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY) -#ifdef _PR_HAVE_ATOMIC_OPS - _PR_MD_ATOMIC_DECREMENT(&_pr_md_idle_cpus); -#else - _PR_MD_LOCK(&_pr_md_idle_cpus_lock); - _pr_md_idle_cpus--; - _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock); -#endif /* _PR_HAVE_ATOMIC_OPS */ -#endif - - _PR_ClockInterrupt(); - - /* Now schedule any thread that is on the runq - * INTS must be OFF when calling PR_Schedule() - */ - me->state = _PR_RUNNABLE; - _PR_MD_SWITCH_CONTEXT(me); - if (!_PR_IS_NATIVE_THREAD(me)) _PR_FAST_INTSON(is); - } -} -#endif /* _PR_GLOBAL_THREADS_ONLY */ - -PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs) -{ -#if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_LOCAL_THREADS_ONLY) - - /* do nothing */ - -#else /* combined, MxN thread model */ - - PRUintn newCPU; - _PRCPU *cpu; - PRThread *thr; - - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (_native_threads_only) - return; - - _PR_CPU_LIST_LOCK(); - if (_pr_numCPU < numCPUs) { - newCPU = numCPUs - _pr_numCPU; - _pr_numCPU = numCPUs; - } else newCPU = 0; - _PR_CPU_LIST_UNLOCK(); - - for (; newCPU; newCPU--) { - cpu = _PR_CreateCPU(); - thr = _PR_CreateThread(PR_SYSTEM_THREAD, - _PR_RunCPU, - cpu, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0, - _PR_IDLE_THREAD); - } -#endif -} - -PR_IMPLEMENT(_PRCPU *) _PR_GetPrimordialCPU(void) -{ - if (_pr_primordialCPU) - return _pr_primordialCPU; - else - return _PR_MD_CURRENT_CPU(); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prucv.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/prucv.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prucv.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/prucv.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,645 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -#include "primpl.h" -#include "prinrval.h" -#include "prtypes.h" - -#if defined(WIN95) -/* -** Some local variables report warnings on Win95 because the code paths -** using them are conditioned on HAVE_CUSTOME_USER_THREADS. -** The pragma suppresses the warning. -** -*/ -#pragma warning(disable : 4101) -#endif - - -/* -** Notify one thread that it has finished waiting on a condition variable -** Caller must hold the _PR_CVAR_LOCK(cv) -*/ -PRBool _PR_NotifyThread (PRThread *thread, PRThread *me) -{ - PRBool rv; - - PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); - - _PR_THREAD_LOCK(thread); - PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); - if ( !_PR_IS_NATIVE_THREAD(thread) ) { - if (thread->wait.cvar != NULL) { - thread->wait.cvar = NULL; - - _PR_SLEEPQ_LOCK(thread->cpu); - /* The notify and timeout can collide; in which case both may - * attempt to delete from the sleepQ; only let one do it. - */ - if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) - _PR_DEL_SLEEPQ(thread, PR_TRUE); - _PR_SLEEPQ_UNLOCK(thread->cpu); - - if (thread->flags & _PR_SUSPENDING) { - /* - * set thread state to SUSPENDED; a Resume operation - * on the thread will move it to the runQ - */ - thread->state = _PR_SUSPENDED; - _PR_MISCQ_LOCK(thread->cpu); - _PR_ADD_SUSPENDQ(thread, thread->cpu); - _PR_MISCQ_UNLOCK(thread->cpu); - _PR_THREAD_UNLOCK(thread); - } else { - /* Make thread runnable */ - thread->state = _PR_RUNNABLE; - _PR_THREAD_UNLOCK(thread); - - _PR_AddThreadToRunQ(me, thread); - _PR_MD_WAKEUP_WAITER(thread); - } - - rv = PR_TRUE; - } else { - /* Thread has already been notified */ - _PR_THREAD_UNLOCK(thread); - rv = PR_FALSE; - } - } else { /* If the thread is a native thread */ - if (thread->wait.cvar) { - thread->wait.cvar = NULL; - - if (thread->flags & _PR_SUSPENDING) { - /* - * set thread state to SUSPENDED; a Resume operation - * on the thread will enable the thread to run - */ - thread->state = _PR_SUSPENDED; - } else - thread->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(thread); - _PR_MD_WAKEUP_WAITER(thread); - rv = PR_TRUE; - } else { - _PR_THREAD_UNLOCK(thread); - rv = PR_FALSE; - } - } - - return rv; -} - -/* - * Notify thread waiting on cvar; called when thread is interrupted - * The thread lock is held on entry and released before return - */ -void _PR_NotifyLockedThread (PRThread *thread) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRCondVar *cvar; - PRThreadPriority pri; - - if ( !_PR_IS_NATIVE_THREAD(me)) - PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); - - cvar = thread->wait.cvar; - thread->wait.cvar = NULL; - _PR_THREAD_UNLOCK(thread); - - _PR_CVAR_LOCK(cvar); - _PR_THREAD_LOCK(thread); - - if (!_PR_IS_NATIVE_THREAD(thread)) { - _PR_SLEEPQ_LOCK(thread->cpu); - /* The notify and timeout can collide; in which case both may - * attempt to delete from the sleepQ; only let one do it. - */ - if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) - _PR_DEL_SLEEPQ(thread, PR_TRUE); - _PR_SLEEPQ_UNLOCK(thread->cpu); - - /* Make thread runnable */ - pri = thread->priority; - thread->state = _PR_RUNNABLE; - - PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); - - _PR_AddThreadToRunQ(me, thread); - _PR_THREAD_UNLOCK(thread); - - _PR_MD_WAKEUP_WAITER(thread); - } else { - if (thread->flags & _PR_SUSPENDING) { - /* - * set thread state to SUSPENDED; a Resume operation - * on the thread will enable the thread to run - */ - thread->state = _PR_SUSPENDED; - } else - thread->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(thread); - _PR_MD_WAKEUP_WAITER(thread); - } - - _PR_CVAR_UNLOCK(cvar); - return; -} - -/* -** Make the given thread wait for the given condition variable -*/ -PRStatus _PR_WaitCondVar( - PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout) -{ - PRIntn is; - PRStatus rv = PR_SUCCESS; - - PR_ASSERT(thread == _PR_MD_CURRENT_THREAD()); - PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); - -#ifdef _PR_GLOBAL_THREADS_ONLY - if (_PR_PENDING_INTERRUPT(thread)) { - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - thread->flags &= ~_PR_INTERRUPT; - return PR_FAILURE; - } - - thread->wait.cvar = cvar; - lock->owner = NULL; - _PR_MD_WAIT_CV(&cvar->md,&lock->ilock, timeout); - thread->wait.cvar = NULL; - lock->owner = thread; - if (_PR_PENDING_INTERRUPT(thread)) { - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - thread->flags &= ~_PR_INTERRUPT; - return PR_FAILURE; - } - - return PR_SUCCESS; -#else /* _PR_GLOBAL_THREADS_ONLY */ - - if ( !_PR_IS_NATIVE_THREAD(thread)) - _PR_INTSOFF(is); - - _PR_CVAR_LOCK(cvar); - _PR_THREAD_LOCK(thread); - - if (_PR_PENDING_INTERRUPT(thread)) { - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - thread->flags &= ~_PR_INTERRUPT; - _PR_CVAR_UNLOCK(cvar); - _PR_THREAD_UNLOCK(thread); - if ( !_PR_IS_NATIVE_THREAD(thread)) - _PR_INTSON(is); - return PR_FAILURE; - } - - thread->state = _PR_COND_WAIT; - thread->wait.cvar = cvar; - - /* - ** Put the caller thread on the condition variable's wait Q - */ - PR_APPEND_LINK(&thread->waitQLinks, &cvar->condQ); - - /* Note- for global scope threads, we don't put them on the - * global sleepQ, so each global thread must put itself - * to sleep only for the time it wants to. - */ - if ( !_PR_IS_NATIVE_THREAD(thread) ) { - _PR_SLEEPQ_LOCK(thread->cpu); - _PR_ADD_SLEEPQ(thread, timeout); - _PR_SLEEPQ_UNLOCK(thread->cpu); - } - _PR_CVAR_UNLOCK(cvar); - _PR_THREAD_UNLOCK(thread); - - /* - ** Release lock protecting the condition variable and thereby giving time - ** to the next thread which can potentially notify on the condition variable - */ - PR_Unlock(lock); - - PR_LOG(_pr_cvar_lm, PR_LOG_MIN, - ("PR_Wait: cvar=%p waiting for %d", cvar, timeout)); - - rv = _PR_MD_WAIT(thread, timeout); - - _PR_CVAR_LOCK(cvar); - PR_REMOVE_LINK(&thread->waitQLinks); - _PR_CVAR_UNLOCK(cvar); - - PR_LOG(_pr_cvar_lm, PR_LOG_MIN, - ("PR_Wait: cvar=%p done waiting", cvar)); - - if ( !_PR_IS_NATIVE_THREAD(thread)) - _PR_INTSON(is); - - /* Acquire lock again that we had just relinquished */ - PR_Lock(lock); - - if (_PR_PENDING_INTERRUPT(thread)) { - PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); - thread->flags &= ~_PR_INTERRUPT; - return PR_FAILURE; - } - - return rv; -#endif /* _PR_GLOBAL_THREADS_ONLY */ -} - -void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me) -{ -#ifdef _PR_GLOBAL_THREADS_ONLY - _PR_MD_NOTIFY_CV(&cvar->md, &cvar->lock->ilock); -#else /* _PR_GLOBAL_THREADS_ONLY */ - - PRCList *q; - PRIntn is; - - if ( !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); - - _PR_CVAR_LOCK(cvar); - q = cvar->condQ.next; - while (q != &cvar->condQ) { - PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar)); - if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar) { - if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE) - break; - } - q = q->next; - } - _PR_CVAR_UNLOCK(cvar); - - if ( !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); - -#endif /* _PR_GLOBAL_THREADS_ONLY */ -} - -/* -** Cndition variable debugging log info. -*/ -PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen) -{ - PRUint32 nb; - - if (cvar->lock->owner) { - nb = PR_snprintf(buf, buflen, "[%p] owner=%ld[%p]", - cvar, cvar->lock->owner->id, cvar->lock->owner); - } else { - nb = PR_snprintf(buf, buflen, "[%p]", cvar); - } - return nb; -} - -/* -** Expire condition variable waits that are ready to expire. "now" is the current -** time. -*/ -void _PR_ClockInterrupt(void) -{ - PRThread *thread, *me = _PR_MD_CURRENT_THREAD(); - _PRCPU *cpu = me->cpu; - PRIntervalTime elapsed, now; - - PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); - /* Figure out how much time elapsed since the last clock tick */ - now = PR_IntervalNow(); - elapsed = now - cpu->last_clock; - cpu->last_clock = now; - - PR_LOG(_pr_clock_lm, PR_LOG_MAX, - ("ExpireWaits: elapsed=%lld usec", elapsed)); - - while(1) { - _PR_SLEEPQ_LOCK(cpu); - if (_PR_SLEEPQ(cpu).next == &_PR_SLEEPQ(cpu)) { - _PR_SLEEPQ_UNLOCK(cpu); - break; - } - - thread = _PR_THREAD_PTR(_PR_SLEEPQ(cpu).next); - PR_ASSERT(thread->cpu == cpu); - - if (elapsed < thread->sleep) { - thread->sleep -= elapsed; - _PR_SLEEPQMAX(thread->cpu) -= elapsed; - _PR_SLEEPQ_UNLOCK(cpu); - break; - } - _PR_SLEEPQ_UNLOCK(cpu); - - PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread)); - - _PR_THREAD_LOCK(thread); - - if (thread->cpu != cpu) { - /* - ** The thread was switched to another CPU - ** between the time we unlocked the sleep - ** queue and the time we acquired the thread - ** lock, so it is none of our business now. - */ - _PR_THREAD_UNLOCK(thread); - continue; - } - - /* - ** Consume this sleeper's amount of elapsed time from the elapsed - ** time value. The next remaining piece of elapsed time will be - ** available for the next sleeping thread's timer. - */ - _PR_SLEEPQ_LOCK(cpu); - PR_ASSERT(!(thread->flags & _PR_ON_PAUSEQ)); - if (thread->flags & _PR_ON_SLEEPQ) { - _PR_DEL_SLEEPQ(thread, PR_FALSE); - elapsed -= thread->sleep; - _PR_SLEEPQ_UNLOCK(cpu); - } else { - /* Thread was already handled; Go get another one */ - _PR_SLEEPQ_UNLOCK(cpu); - _PR_THREAD_UNLOCK(thread); - continue; - } - - /* Notify the thread waiting on the condition variable */ - if (thread->flags & _PR_SUSPENDING) { - PR_ASSERT((thread->state == _PR_IO_WAIT) || - (thread->state == _PR_COND_WAIT)); - /* - ** Thread is suspended and its condition timeout - ** expired. Transfer thread from sleepQ to suspendQ. - */ - thread->wait.cvar = NULL; - _PR_MISCQ_LOCK(cpu); - thread->state = _PR_SUSPENDED; - _PR_ADD_SUSPENDQ(thread, cpu); - _PR_MISCQ_UNLOCK(cpu); - } else { - if (thread->wait.cvar) { - PRThreadPriority pri; - - /* Do work very similar to what _PR_NotifyThread does */ - PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); - - /* Make thread runnable */ - pri = thread->priority; - thread->state = _PR_RUNNABLE; - PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); - - PR_ASSERT(thread->cpu == cpu); - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(thread, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - - if (pri > me->priority) - _PR_SET_RESCHED_FLAG(); - - thread->wait.cvar = NULL; - - _PR_MD_WAKEUP_WAITER(thread); - - } else if (thread->io_pending == PR_TRUE) { - /* Need to put IO sleeper back on runq */ - int pri = thread->priority; - - thread->io_suspended = PR_TRUE; -#ifdef WINNT - /* - * For NT, record the cpu on which I/O was issued - * I/O cancellation is done on the same cpu - */ - thread->md.thr_bound_cpu = cpu; -#endif - - PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); - PR_ASSERT(thread->cpu == cpu); - thread->state = _PR_RUNNABLE; - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(thread, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - } - } - _PR_THREAD_UNLOCK(thread); - } -} - -/************************************************************************/ - -/* -** Create a new condition variable. -** "lock" is the lock to use with the condition variable. -** -** Condition variables are synchronization objects that threads can use -** to wait for some condition to occur. -** -** This may fail if memory is tight or if some operating system resource -** is low. -*/ -PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock) -{ - PRCondVar *cvar; - - PR_ASSERT(lock != NULL); - - cvar = PR_NEWZAP(PRCondVar); - if (cvar) { -#ifdef _PR_GLOBAL_THREADS_ONLY - if(_PR_MD_NEW_CV(&cvar->md)) { - PR_DELETE(cvar); - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - return NULL; - } -#endif - if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) { - PR_DELETE(cvar); - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - return NULL; - } - cvar->lock = lock; - PR_INIT_CLIST(&cvar->condQ); - - } else { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - } - return cvar; -} - -/* -** Destroy a condition variable. There must be no thread -** waiting on the condvar. The caller is responsible for guaranteeing -** that the condvar is no longer in use. -** -*/ -PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar) -{ - PR_ASSERT(cvar->condQ.next == &cvar->condQ); - -#ifdef _PR_GLOBAL_THREADS_ONLY - _PR_MD_FREE_CV(&cvar->md); -#endif - _PR_MD_FREE_LOCK(&(cvar->ilock)); - - PR_DELETE(cvar); -} - -/* -** Wait for a notify on the condition variable. Sleep for "tiemout" amount -** of ticks (if "timeout" is zero then the sleep is indefinite). While -** the thread is waiting it unlocks lock. When the wait has -** finished the thread regains control of the condition variable after -** locking the associated lock. -** -** The thread waiting on the condvar will be resumed when the condvar is -** notified (assuming the thread is the next in line to receive the -** notify) or when the timeout elapses. -** -** Returns PR_FAILURE if the caller has not locked the lock associated -** with the condition variable or the thread has been interrupted. -*/ -extern PRThread *suspendAllThread; -PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(cvar->lock->owner == me); - PR_ASSERT(me != suspendAllThread); - if (cvar->lock->owner != me) return PR_FAILURE; - - return _PR_WaitCondVar(me, cvar, cvar->lock, timeout); -} - -/* -** Notify the highest priority thread waiting on the condition -** variable. If a thread is waiting on the condition variable (using -** PR_Wait) then it is awakened and begins waiting on the lock. -*/ -PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(cvar->lock->owner == me); - PR_ASSERT(me != suspendAllThread); - if (cvar->lock->owner != me) return PR_FAILURE; - - _PR_NotifyCondVar(cvar, me); - return PR_SUCCESS; -} - -/* -** Notify all of the threads waiting on the condition variable. All of -** threads are notified in turn. The highest priority thread will -** probably acquire the lock. -*/ -PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar) -{ - PRCList *q; - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(cvar->lock->owner == me); - if (cvar->lock->owner != me) return PR_FAILURE; - -#ifdef _PR_GLOBAL_THREADS_ONLY - _PR_MD_NOTIFYALL_CV(&cvar->md, &cvar->lock->ilock); - return PR_SUCCESS; -#else /* _PR_GLOBAL_THREADS_ONLY */ - if ( !_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - _PR_CVAR_LOCK(cvar); - q = cvar->condQ.next; - while (q != &cvar->condQ) { - PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)); - _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me); - q = q->next; - } - _PR_CVAR_UNLOCK(cvar); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); - - return PR_SUCCESS; -#endif /* _PR_GLOBAL_THREADS_ONLY */ -} - - -/*********************************************************************/ -/*********************************************************************/ -/********************ROUTINES FOR DCE EMULATION***********************/ -/*********************************************************************/ -/*********************************************************************/ -#include "prpdce.h" - -PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void) -{ - PRCondVar *cvar = PR_NEWZAP(PRCondVar); - if (NULL != cvar) - { - if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) - { - PR_DELETE(cvar); cvar = NULL; - } - else - { - PR_INIT_CLIST(&cvar->condQ); - cvar->lock = _PR_NAKED_CV_LOCK; - } - - } - return cvar; -} - -PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar) -{ - PR_ASSERT(cvar->condQ.next == &cvar->condQ); - PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); - - _PR_MD_FREE_LOCK(&(cvar->ilock)); - - PR_DELETE(cvar); -} - -PR_IMPLEMENT(PRStatus) PRP_NakedWait( - PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); - return _PR_WaitCondVar(me, cvar, lock, timeout); -} /* PRP_NakedWait */ - -PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); - - _PR_NotifyCondVar(cvar, me); - - return PR_SUCCESS; -} /* PRP_NakedNotify */ - -PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar) -{ - PRCList *q; - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); - - if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); - _PR_MD_LOCK( &(cvar->ilock) ); - q = cvar->condQ.next; - while (q != &cvar->condQ) { - PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)); - _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me); - q = q->next; - } - _PR_MD_UNLOCK( &(cvar->ilock) ); - if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); - - return PR_SUCCESS; -} /* PRP_NakedBroadcast */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prulock.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/prulock.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prulock.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/prulock.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,433 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#if defined(WIN95) -/* -** Some local variables report warnings on Win95 because the code paths -** using them are conditioned on HAVE_CUSTOME_USER_THREADS. -** The pragma suppresses the warning. -** -*/ -#pragma warning(disable : 4101) -#endif - - -void _PR_InitLocks(void) -{ - _PR_MD_INIT_LOCKS(); -} - -/* -** Deal with delayed interrupts/requested reschedule during interrupt -** re-enables. -*/ -void _PR_IntsOn(_PRCPU *cpu) -{ - PRUintn missed, pri, i; - _PRInterruptTable *it; - PRThread *me; - - PR_ASSERT(cpu); /* Global threads don't have CPUs */ - PR_ASSERT(_PR_MD_GET_INTSOFF() > 0); - me = _PR_MD_CURRENT_THREAD(); - PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); - - /* - ** Process delayed interrupts. This logic is kinda scary because we - ** need to avoid losing an interrupt (it's ok to delay an interrupt - ** until later). - ** - ** There are two missed state words. _pr_ints.where indicates to the - ** interrupt handler which state word is currently safe for - ** modification. - ** - ** This code scans both interrupt state words, using the where flag - ** to indicate to the interrupt which state word is safe for writing. - ** If an interrupt comes in during a scan the other word will be - ** modified. This modification will be noticed during the next - ** iteration of the loop or during the next call to this routine. - */ - for (i = 0; i < 2; i++) { - cpu->where = (1 - i); - missed = cpu->u.missed[i]; - if (missed != 0) { - cpu->u.missed[i] = 0; - for (it = _pr_interruptTable; it->name; it++) { - if (missed & it->missed_bit) { - PR_LOG(_pr_sched_lm, PR_LOG_MIN, - ("IntsOn[0]: %s intr", it->name)); - (*it->handler)(); - } - } - } - } - - if (cpu->u.missed[3] != 0) { - _PRCPU *cpu; - - _PR_THREAD_LOCK(me); - me->state = _PR_RUNNABLE; - pri = me->priority; - - cpu = me->cpu; - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(me, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - _PR_THREAD_UNLOCK(me); - _PR_MD_SWITCH_CONTEXT(me); - } -} - -/* -** Unblock the first runnable waiting thread. Skip over -** threads that are trying to be suspended -** Note: Caller must hold _PR_LOCK_LOCK() -*/ -void _PR_UnblockLockWaiter(PRLock *lock) -{ - PRThread *t = NULL; - PRThread *me; - PRCList *q; - - q = lock->waitQ.next; - PR_ASSERT(q != &lock->waitQ); - while (q != &lock->waitQ) { - /* Unblock first waiter */ - t = _PR_THREAD_CONDQ_PTR(q); - - /* - ** We are about to change the thread's state to runnable and for local - ** threads, we are going to assign a cpu to it. So, protect thread's - ** data structure. - */ - _PR_THREAD_LOCK(t); - - if (t->flags & _PR_SUSPENDING) { - q = q->next; - _PR_THREAD_UNLOCK(t); - continue; - } - - /* Found a runnable thread */ - PR_ASSERT(t->state == _PR_LOCK_WAIT); - PR_ASSERT(t->wait.lock == lock); - t->wait.lock = 0; - PR_REMOVE_LINK(&t->waitQLinks); /* take it off lock's waitQ */ - - /* - ** If this is a native thread, nothing else to do except to wake it - ** up by calling the machine dependent wakeup routine. - ** - ** If this is a local thread, we need to assign it a cpu and - ** put the thread on that cpu's run queue. There are two cases to - ** take care of. If the currently running thread is also a local - ** thread, we just assign our own cpu to that thread and put it on - ** the cpu's run queue. If the the currently running thread is a - ** native thread, we assign the primordial cpu to it (on NT, - ** MD_WAKEUP handles the cpu assignment). - */ - - if ( !_PR_IS_NATIVE_THREAD(t) ) { - - t->state = _PR_RUNNABLE; - - me = _PR_MD_CURRENT_THREAD(); - - _PR_AddThreadToRunQ(me, t); - _PR_THREAD_UNLOCK(t); - } else { - t->state = _PR_RUNNING; - _PR_THREAD_UNLOCK(t); - } - _PR_MD_WAKEUP_WAITER(t); - break; - } - return; -} - -/************************************************************************/ - - -PR_IMPLEMENT(PRLock*) PR_NewLock(void) -{ - PRLock *lock; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - lock = PR_NEWZAP(PRLock); - if (lock) { - if (_PR_MD_NEW_LOCK(&lock->ilock) == PR_FAILURE) { - PR_DELETE(lock); - return(NULL); - } - PR_INIT_CLIST(&lock->links); - PR_INIT_CLIST(&lock->waitQ); - } - return lock; -} - -/* -** Destroy the given lock "lock". There is no point in making this race -** free because if some other thread has the pointer to this lock all -** bets are off. -*/ -PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock) -{ - PR_ASSERT(lock->owner == 0); - _PR_MD_FREE_LOCK(&lock->ilock); - PR_DELETE(lock); -} - -extern PRThread *suspendAllThread; -/* -** Lock the lock. -*/ -PR_IMPLEMENT(void) PR_Lock(PRLock *lock) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRIntn is; - PRThread *t; - PRCList *q; - - PR_ASSERT(me != suspendAllThread); - PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); - PR_ASSERT(lock != NULL); -#ifdef _PR_GLOBAL_THREADS_ONLY - PR_ASSERT(lock->owner != me); - _PR_MD_LOCK(&lock->ilock); - lock->owner = me; - return; -#else /* _PR_GLOBAL_THREADS_ONLY */ - - if (_native_threads_only) { - PR_ASSERT(lock->owner != me); - _PR_MD_LOCK(&lock->ilock); - lock->owner = me; - return; - } - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - - PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); - -retry: - _PR_LOCK_LOCK(lock); - if (lock->owner == 0) { - /* Just got the lock */ - lock->owner = me; - lock->priority = me->priority; - /* Add the granted lock to this owning thread's lock list */ - PR_APPEND_LINK(&lock->links, &me->lockList); - _PR_LOCK_UNLOCK(lock); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_FAST_INTSON(is); - return; - } - - /* If this thread already owns this lock, then it is a deadlock */ - PR_ASSERT(lock->owner != me); - - PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); - -#if 0 - if (me->priority > lock->owner->priority) { - /* - ** Give the lock owner a priority boost until we get the - ** lock. Record the priority we boosted it to. - */ - lock->boostPriority = me->priority; - _PR_SetThreadPriority(lock->owner, me->priority); - } -#endif - - /* - Add this thread to the asked for lock's list of waiting threads. We - add this thread thread in the right priority order so when the unlock - occurs, the thread with the higher priority will get the lock. - */ - q = lock->waitQ.next; - if (q == &lock->waitQ || _PR_THREAD_CONDQ_PTR(q)->priority == - _PR_THREAD_CONDQ_PTR(lock->waitQ.prev)->priority) { - /* - * If all the threads in the lock waitQ have the same priority, - * then avoid scanning the list: insert the element at the end. - */ - q = &lock->waitQ; - } else { - /* Sort thread into lock's waitQ at appropriate point */ - /* Now scan the list for where to insert this entry */ - while (q != &lock->waitQ) { - t = _PR_THREAD_CONDQ_PTR(lock->waitQ.next); - if (me->priority > t->priority) { - /* Found a lower priority thread to insert in front of */ - break; - } - q = q->next; - } - } - PR_INSERT_BEFORE(&me->waitQLinks, q); - - /* - Now grab the threadLock since we are about to change the state. We have - to do this since a PR_Suspend or PR_SetThreadPriority type call that takes - a PRThread* as an argument could be changing the state of this thread from - a thread running on a different cpu. - */ - - _PR_THREAD_LOCK(me); - me->state = _PR_LOCK_WAIT; - me->wait.lock = lock; - _PR_THREAD_UNLOCK(me); - - _PR_LOCK_UNLOCK(lock); - - _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT); - goto retry; - -#endif /* _PR_GLOBAL_THREADS_ONLY */ -} - -/* -** Unlock the lock. -*/ -PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock) -{ - PRCList *q; - PRThreadPriority pri, boost; - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(lock != NULL); - PR_ASSERT(lock->owner == me); - PR_ASSERT(me != suspendAllThread); - PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); - if (lock->owner != me) { - return PR_FAILURE; - } - -#ifdef _PR_GLOBAL_THREADS_ONLY - lock->owner = 0; - _PR_MD_UNLOCK(&lock->ilock); - return PR_SUCCESS; -#else /* _PR_GLOBAL_THREADS_ONLY */ - - if (_native_threads_only) { - lock->owner = 0; - _PR_MD_UNLOCK(&lock->ilock); - return PR_SUCCESS; - } - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - _PR_LOCK_LOCK(lock); - - /* Remove the lock from the owning thread's lock list */ - PR_REMOVE_LINK(&lock->links); - pri = lock->priority; - boost = lock->boostPriority; - if (boost > pri) { - /* - ** We received a priority boost during the time we held the lock. - ** We need to figure out what priority to move to by scanning - ** down our list of lock's that we are still holding and using - ** the highest boosted priority found. - */ - q = me->lockList.next; - while (q != &me->lockList) { - PRLock *ll = _PR_LOCK_PTR(q); - if (ll->boostPriority > pri) { - pri = ll->boostPriority; - } - q = q->next; - } - if (pri != me->priority) { - _PR_SetThreadPriority(me, pri); - } - } - - /* Unblock the first waiting thread */ - q = lock->waitQ.next; - if (q != &lock->waitQ) - _PR_UnblockLockWaiter(lock); - lock->boostPriority = PR_PRIORITY_LOW; - lock->owner = 0; - _PR_LOCK_UNLOCK(lock); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); - return PR_SUCCESS; -#endif /* _PR_GLOBAL_THREADS_ONLY */ -} - -/* -** If the current thread owns |lock|, this assertion is guaranteed to -** succeed. Otherwise, the behavior of this function is undefined. -*/ -PR_IMPLEMENT(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PR_ASSERT(lock->owner == me); -} - -/* -** Test and then lock the lock if it's not already locked by some other -** thread. Return PR_FALSE if some other thread owned the lock at the -** time of the call. -*/ -PR_IMPLEMENT(PRBool) PR_TestAndLock(PRLock *lock) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRBool rv = PR_FALSE; - PRIntn is; - -#ifdef _PR_GLOBAL_THREADS_ONLY - is = _PR_MD_TEST_AND_LOCK(&lock->ilock); - if (is == 0) { - lock->owner = me; - return PR_TRUE; - } - return PR_FALSE; -#else /* _PR_GLOBAL_THREADS_ONLY */ - -#ifndef _PR_LOCAL_THREADS_ONLY - if (_native_threads_only) { - is = _PR_MD_TEST_AND_LOCK(&lock->ilock); - if (is == 0) { - lock->owner = me; - return PR_TRUE; - } - return PR_FALSE; - } -#endif - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - - _PR_LOCK_LOCK(lock); - if (lock->owner == 0) { - /* Just got the lock */ - lock->owner = me; - lock->priority = me->priority; - /* Add the granted lock to this owning thread's lock list */ - PR_APPEND_LINK(&lock->links, &me->lockList); - rv = PR_TRUE; - } - _PR_LOCK_UNLOCK(lock); - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); - return rv; -#endif /* _PR_GLOBAL_THREADS_ONLY */ -} - -/************************************************************************/ -/************************************************************************/ -/***********************ROUTINES FOR DCE EMULATION***********************/ -/************************************************************************/ -/************************************************************************/ -PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock) - { return (PR_TestAndLock(lock)) ? PR_SUCCESS : PR_FAILURE; } diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prustack.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/prustack.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prustack.c 2012-03-06 13:14:23.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/prustack.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,174 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -/* List of free stack virtual memory chunks */ -PRLock *_pr_stackLock; -PRCList _pr_freeStacks = PR_INIT_STATIC_CLIST(&_pr_freeStacks); -PRIntn _pr_numFreeStacks; -PRIntn _pr_maxFreeStacks = 4; - -#ifdef DEBUG -/* -** A variable that can be set via the debugger... -*/ -PRBool _pr_debugStacks = PR_FALSE; -#endif - -/* How much space to leave between the stacks, at each end */ -#define REDZONE (2 << _pr_pageShift) - -#define _PR_THREAD_STACK_PTR(_qp) \ - ((PRThreadStack*) ((char*) (_qp) - offsetof(PRThreadStack,links))) - -void _PR_InitStacks(void) -{ - _pr_stackLock = PR_NewLock(); -} - -void _PR_CleanupStacks(void) -{ - if (_pr_stackLock) { - PR_DestroyLock(_pr_stackLock); - _pr_stackLock = NULL; - } -} - -/* -** Allocate a stack for a thread. -*/ -PRThreadStack *_PR_NewStack(PRUint32 stackSize) -{ - PRCList *qp; - PRThreadStack *ts; - PRThread *thr; - - /* - ** Trim the list of free stacks. Trim it backwards, tossing out the - ** oldest stack found first (this way more recent stacks have a - ** chance of being present in the data cache). - */ - PR_Lock(_pr_stackLock); - qp = _pr_freeStacks.prev; - while ((_pr_numFreeStacks > _pr_maxFreeStacks) && (qp != &_pr_freeStacks)) { - ts = _PR_THREAD_STACK_PTR(qp); - thr = _PR_THREAD_STACK_TO_PTR(ts); - qp = qp->prev; - /* - * skip stacks which are still being used - */ - if (thr->no_sched) - continue; - PR_REMOVE_LINK(&ts->links); - - /* Give platform OS to clear out the stack for debugging */ - _PR_MD_CLEAR_STACK(ts); - - _pr_numFreeStacks--; - _PR_DestroySegment(ts->seg); - PR_DELETE(ts); - } - - /* - ** Find a free thread stack. This searches the list of free'd up - ** virtually mapped thread stacks. - */ - qp = _pr_freeStacks.next; - ts = 0; - while (qp != &_pr_freeStacks) { - ts = _PR_THREAD_STACK_PTR(qp); - thr = _PR_THREAD_STACK_TO_PTR(ts); - qp = qp->next; - /* - * skip stacks which are still being used - */ - if ((!(thr->no_sched)) && ((ts->allocSize - 2*REDZONE) >= stackSize)) { - /* - ** Found a stack that is not in use and is big enough. Change - ** stackSize to fit it. - */ - stackSize = ts->allocSize - 2*REDZONE; - PR_REMOVE_LINK(&ts->links); - _pr_numFreeStacks--; - ts->links.next = 0; - ts->links.prev = 0; - PR_Unlock(_pr_stackLock); - goto done; - } - ts = 0; - } - PR_Unlock(_pr_stackLock); - - if (!ts) { - /* Make a new thread stack object. */ - ts = PR_NEWZAP(PRThreadStack); - if (!ts) { - return NULL; - } - - /* - ** Assign some of the virtual space to the new stack object. We - ** may not get that piece of VM, but if nothing else we will - ** advance the pointer so we don't collide (unless the OS screws - ** up). - */ - ts->allocSize = stackSize + 2*REDZONE; - ts->seg = _PR_NewSegment(ts->allocSize, 0); - if (!ts->seg) { - PR_DELETE(ts); - return NULL; - } - } - - done: - ts->allocBase = (char*)ts->seg->vaddr; - ts->flags = _PR_STACK_MAPPED; - ts->stackSize = stackSize; - -#ifdef HAVE_STACK_GROWING_UP - ts->stackTop = ts->allocBase + REDZONE; - ts->stackBottom = ts->stackTop + stackSize; -#else - ts->stackBottom = ts->allocBase + REDZONE; - ts->stackTop = ts->stackBottom + stackSize; -#endif - - PR_LOG(_pr_thread_lm, PR_LOG_NOTICE, - ("thread stack: base=0x%x limit=0x%x bottom=0x%x top=0x%x\n", - ts->allocBase, ts->allocBase + ts->allocSize - 1, - ts->allocBase + REDZONE, - ts->allocBase + REDZONE + stackSize - 1)); - - _PR_MD_INIT_STACK(ts,REDZONE); - - return ts; -} - -/* -** Free the stack for the current thread -*/ -void _PR_FreeStack(PRThreadStack *ts) -{ - if (!ts) { - return; - } - if (ts->flags & _PR_STACK_PRIMORDIAL) { - PR_DELETE(ts); - return; - } - - /* - ** Put the stack on the free list. This is done because we are still - ** using the stack. Next time a thread is created we will trim the - ** list down; it's safe to do it then because we will have had to - ** context switch to a live stack before another thread can be - ** created. - */ - PR_Lock(_pr_stackLock); - PR_APPEND_LINK(&ts->links, _pr_freeStacks.prev); - _pr_numFreeStacks++; - PR_Unlock(_pr_stackLock); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/pruthr.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/pruthr.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/pruthr.c 2012-06-20 16:44:23.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/pruthr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1887 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include -#include - -#if defined(WIN95) -/* -** Some local variables report warnings on Win95 because the code paths -** using them are conditioned on HAVE_CUSTOME_USER_THREADS. -** The pragma suppresses the warning. -** -*/ -#pragma warning(disable : 4101) -#endif - -/* _pr_activeLock protects the following global variables */ -PRLock *_pr_activeLock; -PRInt32 _pr_primordialExitCount; /* In PR_Cleanup(), the primordial thread - * waits until all other user (non-system) - * threads have terminated before it exits. - * So whenever we decrement _pr_userActive, - * it is compared with - * _pr_primordialExitCount. - * If the primordial thread is a system - * thread, then _pr_primordialExitCount - * is 0. If the primordial thread is - * itself a user thread, then - * _pr_primordialThread is 1. - */ -PRCondVar *_pr_primordialExitCVar; /* When _pr_userActive is decremented to - * _pr_primordialExitCount, this condition - * variable is notified. - */ - -PRLock *_pr_deadQLock; -PRUint32 _pr_numNativeDead; -PRUint32 _pr_numUserDead; -PRCList _pr_deadNativeQ; -PRCList _pr_deadUserQ; - -PRUint32 _pr_join_counter; - -PRUint32 _pr_local_threads; -PRUint32 _pr_global_threads; - -PRBool suspendAllOn = PR_FALSE; -PRThread *suspendAllThread = NULL; - -extern PRCList _pr_active_global_threadQ; -extern PRCList _pr_active_local_threadQ; - -static void _PR_DecrActiveThreadCount(PRThread *thread); -static PRThread *_PR_AttachThread(PRThreadType, PRThreadPriority, PRThreadStack *); -static void _PR_InitializeNativeStack(PRThreadStack *ts); -static void _PR_InitializeRecycledThread(PRThread *thread); -static void _PR_UserRunThread(void); - -void _PR_InitThreads(PRThreadType type, PRThreadPriority priority, - PRUintn maxPTDs) -{ - PRThread *thread; - PRThreadStack *stack; - - _pr_terminationCVLock = PR_NewLock(); - _pr_activeLock = PR_NewLock(); - -#ifndef HAVE_CUSTOM_USER_THREADS - stack = PR_NEWZAP(PRThreadStack); -#ifdef HAVE_STACK_GROWING_UP - stack->stackTop = (char*) ((((long)&type) >> _pr_pageShift) - << _pr_pageShift); -#else -#if defined(SOLARIS) || defined (UNIXWARE) && defined (USR_SVR4_THREADS) - stack->stackTop = (char*) &thread; -#else - stack->stackTop = (char*) ((((long)&type + _pr_pageSize - 1) - >> _pr_pageShift) << _pr_pageShift); -#endif -#endif -#else - /* If stack is NULL, we're using custom user threads like NT fibers. */ - stack = PR_NEWZAP(PRThreadStack); - if (stack) { - stack->stackSize = 0; - _PR_InitializeNativeStack(stack); - } -#endif /* HAVE_CUSTOM_USER_THREADS */ - - thread = _PR_AttachThread(type, priority, stack); - if (thread) { - _PR_MD_SET_CURRENT_THREAD(thread); - - if (type == PR_SYSTEM_THREAD) { - thread->flags = _PR_SYSTEM; - _pr_systemActive++; - _pr_primordialExitCount = 0; - } else { - _pr_userActive++; - _pr_primordialExitCount = 1; - } - thread->no_sched = 1; - _pr_primordialExitCVar = PR_NewCondVar(_pr_activeLock); - } - - if (!thread) PR_Abort(); -#ifdef _PR_LOCAL_THREADS_ONLY - thread->flags |= _PR_PRIMORDIAL; -#else - thread->flags |= _PR_PRIMORDIAL | _PR_GLOBAL_SCOPE; -#endif - - /* - * Needs _PR_PRIMORDIAL flag set before calling - * _PR_MD_INIT_THREAD() - */ - if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) { - /* - * XXX do what? - */ - } - - if (_PR_IS_NATIVE_THREAD(thread)) { - PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ()); - _pr_global_threads++; - } else { - PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ()); - _pr_local_threads++; - } - - _pr_recycleThreads = 0; - _pr_deadQLock = PR_NewLock(); - _pr_numNativeDead = 0; - _pr_numUserDead = 0; - PR_INIT_CLIST(&_pr_deadNativeQ); - PR_INIT_CLIST(&_pr_deadUserQ); -} - -void _PR_CleanupThreads(void) -{ - if (_pr_terminationCVLock) { - PR_DestroyLock(_pr_terminationCVLock); - _pr_terminationCVLock = NULL; - } - if (_pr_activeLock) { - PR_DestroyLock(_pr_activeLock); - _pr_activeLock = NULL; - } - if (_pr_primordialExitCVar) { - PR_DestroyCondVar(_pr_primordialExitCVar); - _pr_primordialExitCVar = NULL; - } - /* TODO _pr_dead{Native,User}Q need to be deleted */ - if (_pr_deadQLock) { - PR_DestroyLock(_pr_deadQLock); - _pr_deadQLock = NULL; - } -} - -/* -** Initialize a stack for a native thread -*/ -static void _PR_InitializeNativeStack(PRThreadStack *ts) -{ - if( ts && (ts->stackTop == 0) ) { - ts->allocSize = ts->stackSize; - - /* - ** Setup stackTop and stackBottom values. - */ -#ifdef HAVE_STACK_GROWING_UP - ts->allocBase = (char*) ((((long)&ts) >> _pr_pageShift) - << _pr_pageShift); - ts->stackBottom = ts->allocBase + ts->stackSize; - ts->stackTop = ts->allocBase; -#else - ts->allocBase = (char*) ((((long)&ts + _pr_pageSize - 1) - >> _pr_pageShift) << _pr_pageShift); - ts->stackTop = ts->allocBase; - ts->stackBottom = ts->allocBase - ts->stackSize; -#endif - } -} - -void _PR_NotifyJoinWaiters(PRThread *thread) -{ - /* - ** Handle joinable threads. Change the state to waiting for join. - ** Remove from our run Q and put it on global waiting to join Q. - ** Notify on our "termination" condition variable so that joining - ** thread will know about our termination. Switch our context and - ** come back later on to continue the cleanup. - */ - PR_ASSERT(thread == _PR_MD_CURRENT_THREAD()); - if (thread->term != NULL) { - PR_Lock(_pr_terminationCVLock); - _PR_THREAD_LOCK(thread); - thread->state = _PR_JOIN_WAIT; - if ( !_PR_IS_NATIVE_THREAD(thread) ) { - _PR_MISCQ_LOCK(thread->cpu); - _PR_ADD_JOINQ(thread, thread->cpu); - _PR_MISCQ_UNLOCK(thread->cpu); - } - _PR_THREAD_UNLOCK(thread); - PR_NotifyCondVar(thread->term); - PR_Unlock(_pr_terminationCVLock); - _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(thread->state != _PR_JOIN_WAIT); - } - -} - -/* - * Zero some of the data members of a recycled thread. - * - * Note that we can do this either when a dead thread is added to - * the dead thread queue or when it is reused. Here, we are doing - * this lazily, when the thread is reused in _PR_CreateThread(). - */ -static void _PR_InitializeRecycledThread(PRThread *thread) -{ - /* - * Assert that the following data members are already zeroed - * by _PR_CleanupThread(). - */ -#ifdef DEBUG - if (thread->privateData) { - unsigned int i; - for (i = 0; i < thread->tpdLength; i++) { - PR_ASSERT(thread->privateData[i] == NULL); - } - } -#endif - PR_ASSERT(thread->dumpArg == 0 && thread->dump == 0); - PR_ASSERT(thread->errorString == 0 && thread->errorStringSize == 0); - PR_ASSERT(thread->errorStringLength == 0); - PR_ASSERT(thread->name == 0); - - /* Reset data members in thread structure */ - thread->errorCode = thread->osErrorCode = 0; - thread->io_pending = thread->io_suspended = PR_FALSE; - thread->environment = 0; - PR_INIT_CLIST(&thread->lockList); -} - -PRStatus _PR_RecycleThread(PRThread *thread) -{ - if ( _PR_IS_NATIVE_THREAD(thread) && - _PR_NUM_DEADNATIVE < _pr_recycleThreads) { - _PR_DEADQ_LOCK; - PR_APPEND_LINK(&thread->links, &_PR_DEADNATIVEQ); - _PR_INC_DEADNATIVE; - _PR_DEADQ_UNLOCK; - return (PR_SUCCESS); - } else if ( !_PR_IS_NATIVE_THREAD(thread) && - _PR_NUM_DEADUSER < _pr_recycleThreads) { - _PR_DEADQ_LOCK; - PR_APPEND_LINK(&thread->links, &_PR_DEADUSERQ); - _PR_INC_DEADUSER; - _PR_DEADQ_UNLOCK; - return (PR_SUCCESS); - } - return (PR_FAILURE); -} - -/* - * Decrement the active thread count, either _pr_systemActive or - * _pr_userActive, depending on whether the thread is a system thread - * or a user thread. If all the user threads, except possibly - * the primordial thread, have terminated, we notify the primordial - * thread of this condition. - * - * Since this function will lock _pr_activeLock, do not call this - * function while holding the _pr_activeLock lock, as this will result - * in a deadlock. - */ - -static void -_PR_DecrActiveThreadCount(PRThread *thread) -{ - PR_Lock(_pr_activeLock); - if (thread->flags & _PR_SYSTEM) { - _pr_systemActive--; - } else { - _pr_userActive--; - if (_pr_userActive == _pr_primordialExitCount) { - PR_NotifyCondVar(_pr_primordialExitCVar); - } - } - PR_Unlock(_pr_activeLock); -} - -/* -** Detach thread structure -*/ -static void -_PR_DestroyThread(PRThread *thread) -{ - _PR_MD_FREE_LOCK(&thread->threadLock); - PR_DELETE(thread); -} - -void -_PR_NativeDestroyThread(PRThread *thread) -{ - if(thread->term) { - PR_DestroyCondVar(thread->term); - thread->term = 0; - } - if (NULL != thread->privateData) { - PR_ASSERT(0 != thread->tpdLength); - PR_DELETE(thread->privateData); - thread->tpdLength = 0; - } - PR_DELETE(thread->stack); - _PR_DestroyThread(thread); -} - -void -_PR_UserDestroyThread(PRThread *thread) -{ - if(thread->term) { - PR_DestroyCondVar(thread->term); - thread->term = 0; - } - if (NULL != thread->privateData) { - PR_ASSERT(0 != thread->tpdLength); - PR_DELETE(thread->privateData); - thread->tpdLength = 0; - } - _PR_MD_FREE_LOCK(&thread->threadLock); - if (thread->threadAllocatedOnStack == 1) { - _PR_MD_CLEAN_THREAD(thread); - /* - * Because the no_sched field is set, this thread/stack will - * will not be re-used until the flag is cleared by the thread - * we will context switch to. - */ - _PR_FreeStack(thread->stack); - } else { -#ifdef WINNT - _PR_MD_CLEAN_THREAD(thread); -#else - /* - * This assertion does not apply to NT. On NT, every fiber - * has its threadAllocatedOnStack equal to 0. Elsewhere, - * only the primordial thread has its threadAllocatedOnStack - * equal to 0. - */ - PR_ASSERT(thread->flags & _PR_PRIMORDIAL); -#endif - } -} - - -/* -** Run a thread's start function. When the start function returns the -** thread is done executing and no longer needs the CPU. If there are no -** more user threads running then we can exit the program. -*/ -void _PR_NativeRunThread(void *arg) -{ - PRThread *thread = (PRThread *)arg; - - _PR_MD_SET_CURRENT_THREAD(thread); - - _PR_MD_SET_CURRENT_CPU(NULL); - - /* Set up the thread stack information */ - _PR_InitializeNativeStack(thread->stack); - - /* Set up the thread md information */ - if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) { - /* - * thread failed to initialize itself, possibly due to - * failure to allocate per-thread resources - */ - return; - } - - while(1) { - thread->state = _PR_RUNNING; - - /* - * Add to list of active threads - */ - PR_Lock(_pr_activeLock); - PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ()); - _pr_global_threads++; - PR_Unlock(_pr_activeLock); - - (*thread->startFunc)(thread->arg); - - /* - * The following two assertions are meant for NT asynch io. - * - * The thread should have no asynch io in progress when it - * exits, otherwise the overlapped buffer, which is part of - * the thread structure, would become invalid. - */ - PR_ASSERT(thread->io_pending == PR_FALSE); - /* - * This assertion enforces the programming guideline that - * if an io function times out or is interrupted, the thread - * should close the fd to force the asynch io to abort - * before it exits. Right now, closing the fd is the only - * way to clear the io_suspended flag. - */ - PR_ASSERT(thread->io_suspended == PR_FALSE); - - /* - * remove thread from list of active threads - */ - PR_Lock(_pr_activeLock); - PR_REMOVE_LINK(&thread->active); - _pr_global_threads--; - PR_Unlock(_pr_activeLock); - - PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting")); - - /* All done, time to go away */ - _PR_CleanupThread(thread); - - _PR_NotifyJoinWaiters(thread); - - _PR_DecrActiveThreadCount(thread); - - thread->state = _PR_DEAD_STATE; - - if (!_pr_recycleThreads || (_PR_RecycleThread(thread) == - PR_FAILURE)) { - /* - * thread not recycled - * platform-specific thread exit processing - * - for stuff like releasing native-thread resources, etc. - */ - _PR_MD_EXIT_THREAD(thread); - /* - * Free memory allocated for the thread - */ - _PR_NativeDestroyThread(thread); - /* - * thread gone, cannot de-reference thread now - */ - return; - } - - /* Now wait for someone to activate us again... */ - _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT); - } -} - -static void _PR_UserRunThread(void) -{ - PRThread *thread = _PR_MD_CURRENT_THREAD(); - PRIntn is; - - if (_MD_LAST_THREAD()) - _MD_LAST_THREAD()->no_sched = 0; - -#ifdef HAVE_CUSTOM_USER_THREADS - if (thread->stack == NULL) { - thread->stack = PR_NEWZAP(PRThreadStack); - _PR_InitializeNativeStack(thread->stack); - } -#endif /* HAVE_CUSTOM_USER_THREADS */ - - while(1) { - /* Run thread main */ - if ( !_PR_IS_NATIVE_THREAD(thread)) _PR_MD_SET_INTSOFF(0); - - /* - * Add to list of active threads - */ - if (!(thread->flags & _PR_IDLE_THREAD)) { - PR_Lock(_pr_activeLock); - PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ()); - _pr_local_threads++; - PR_Unlock(_pr_activeLock); - } - - (*thread->startFunc)(thread->arg); - - /* - * The following two assertions are meant for NT asynch io. - * - * The thread should have no asynch io in progress when it - * exits, otherwise the overlapped buffer, which is part of - * the thread structure, would become invalid. - */ - PR_ASSERT(thread->io_pending == PR_FALSE); - /* - * This assertion enforces the programming guideline that - * if an io function times out or is interrupted, the thread - * should close the fd to force the asynch io to abort - * before it exits. Right now, closing the fd is the only - * way to clear the io_suspended flag. - */ - PR_ASSERT(thread->io_suspended == PR_FALSE); - - PR_Lock(_pr_activeLock); - /* - * remove thread from list of active threads - */ - if (!(thread->flags & _PR_IDLE_THREAD)) { - PR_REMOVE_LINK(&thread->active); - _pr_local_threads--; - } - PR_Unlock(_pr_activeLock); - PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting")); - - /* All done, time to go away */ - _PR_CleanupThread(thread); - - _PR_INTSOFF(is); - - _PR_NotifyJoinWaiters(thread); - - _PR_DecrActiveThreadCount(thread); - - thread->state = _PR_DEAD_STATE; - - if (!_pr_recycleThreads || (_PR_RecycleThread(thread) == - PR_FAILURE)) { - /* - ** Destroy the thread resources - */ - _PR_UserDestroyThread(thread); - } - - /* - ** Find another user thread to run. This cpu has finished the - ** previous threads main and is now ready to run another thread. - */ - { - PRInt32 is; - _PR_INTSOFF(is); - _PR_MD_SWITCH_CONTEXT(thread); - } - - /* Will land here when we get scheduled again if we are recycling... */ - } -} - -void _PR_SetThreadPriority(PRThread *thread, PRThreadPriority newPri) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRIntn is; - - if ( _PR_IS_NATIVE_THREAD(thread) ) { - _PR_MD_SET_PRIORITY(&(thread->md), newPri); - return; - } - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - _PR_THREAD_LOCK(thread); - if (newPri != thread->priority) { - _PRCPU *cpu = thread->cpu; - - switch (thread->state) { - case _PR_RUNNING: - /* Change my priority */ - - _PR_RUNQ_LOCK(cpu); - thread->priority = newPri; - if (_PR_RUNQREADYMASK(cpu) >> (newPri + 1)) { - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_SET_RESCHED_FLAG(); - } - _PR_RUNQ_UNLOCK(cpu); - break; - - case _PR_RUNNABLE: - - _PR_RUNQ_LOCK(cpu); - /* Move to different runQ */ - _PR_DEL_RUNQ(thread); - thread->priority = newPri; - PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); - _PR_ADD_RUNQ(thread, cpu, newPri); - _PR_RUNQ_UNLOCK(cpu); - - if (newPri > me->priority) { - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_SET_RESCHED_FLAG(); - } - - break; - - case _PR_LOCK_WAIT: - case _PR_COND_WAIT: - case _PR_IO_WAIT: - case _PR_SUSPENDED: - - thread->priority = newPri; - break; - } - } - _PR_THREAD_UNLOCK(thread); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); -} - -/* -** Suspend the named thread and copy its gc registers into regBuf -*/ -static void _PR_Suspend(PRThread *thread) -{ - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - PR_ASSERT(thread != me); - PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread) || (!thread->cpu)); - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - _PR_THREAD_LOCK(thread); - switch (thread->state) { - case _PR_RUNNABLE: - if (!_PR_IS_NATIVE_THREAD(thread)) { - _PR_RUNQ_LOCK(thread->cpu); - _PR_DEL_RUNQ(thread); - _PR_RUNQ_UNLOCK(thread->cpu); - - _PR_MISCQ_LOCK(thread->cpu); - _PR_ADD_SUSPENDQ(thread, thread->cpu); - _PR_MISCQ_UNLOCK(thread->cpu); - } else { - /* - * Only LOCAL threads are suspended by _PR_Suspend - */ - PR_ASSERT(0); - } - thread->state = _PR_SUSPENDED; - break; - - case _PR_RUNNING: - /* - * The thread being suspended should be a LOCAL thread with - * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state - */ - PR_ASSERT(0); - break; - - case _PR_LOCK_WAIT: - case _PR_IO_WAIT: - case _PR_COND_WAIT: - if (_PR_IS_NATIVE_THREAD(thread)) { - _PR_MD_SUSPEND_THREAD(thread); - } - thread->flags |= _PR_SUSPENDING; - break; - - default: - PR_Abort(); - } - _PR_THREAD_UNLOCK(thread); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); -} - -static void _PR_Resume(PRThread *thread) -{ - PRThreadPriority pri; - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - _PR_THREAD_LOCK(thread); - switch (thread->state) { - case _PR_SUSPENDED: - thread->state = _PR_RUNNABLE; - thread->flags &= ~_PR_SUSPENDING; - if (!_PR_IS_NATIVE_THREAD(thread)) { - _PR_MISCQ_LOCK(thread->cpu); - _PR_DEL_SUSPENDQ(thread); - _PR_MISCQ_UNLOCK(thread->cpu); - - pri = thread->priority; - - _PR_RUNQ_LOCK(thread->cpu); - _PR_ADD_RUNQ(thread, thread->cpu, pri); - _PR_RUNQ_UNLOCK(thread->cpu); - - if (pri > _PR_MD_CURRENT_THREAD()->priority) { - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_SET_RESCHED_FLAG(); - } - } else { - PR_ASSERT(0); - } - break; - - case _PR_IO_WAIT: - case _PR_COND_WAIT: - thread->flags &= ~_PR_SUSPENDING; -/* PR_ASSERT(thread->wait.monitor->stickyCount == 0); */ - break; - - case _PR_LOCK_WAIT: - { - PRLock *wLock = thread->wait.lock; - - thread->flags &= ~_PR_SUSPENDING; - - _PR_LOCK_LOCK(wLock); - if (thread->wait.lock->owner == 0) { - _PR_UnblockLockWaiter(thread->wait.lock); - } - _PR_LOCK_UNLOCK(wLock); - break; - } - case _PR_RUNNABLE: - break; - case _PR_RUNNING: - /* - * The thread being suspended should be a LOCAL thread with - * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state - */ - PR_ASSERT(0); - break; - - default: - /* - * thread should have been in one of the above-listed blocked states - * (_PR_JOIN_WAIT, _PR_IO_WAIT, _PR_UNBORN, _PR_DEAD_STATE) - */ - PR_Abort(); - } - _PR_THREAD_UNLOCK(thread); - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); - -} - -#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) -static PRThread *get_thread(_PRCPU *cpu, PRBool *wakeup_cpus) -{ - PRThread *thread; - PRIntn pri; - PRUint32 r; - PRCList *qp; - PRIntn priMin, priMax; - - _PR_RUNQ_LOCK(cpu); - r = _PR_RUNQREADYMASK(cpu); - if (r==0) { - priMin = priMax = PR_PRIORITY_FIRST; - } else if (r == (1<= priMin ; pri-- ) { - if (r & (1 << pri)) { - for (qp = _PR_RUNQ(cpu)[pri].next; - qp != &_PR_RUNQ(cpu)[pri]; - qp = qp->next) { - thread = _PR_THREAD_PTR(qp); - /* - * skip non-schedulable threads - */ - PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); - if (thread->no_sched) { - thread = NULL; - /* - * Need to wakeup cpus to avoid missing a - * runnable thread - * Waking up all CPU's need happen only once. - */ - - *wakeup_cpus = PR_TRUE; - continue; - } else if (thread->flags & _PR_BOUND_THREAD) { - /* - * Thread bound to cpu 0 - */ - - thread = NULL; -#ifdef IRIX - _PR_MD_WAKEUP_PRIMORDIAL_CPU(); -#endif - continue; - } else if (thread->io_pending == PR_TRUE) { - /* - * A thread that is blocked for I/O needs to run - * on the same cpu on which it was blocked. This is because - * the cpu's ioq is accessed without lock protection and scheduling - * the thread on a different cpu would preclude this optimization. - */ - thread = NULL; - continue; - } else { - /* Pull thread off of its run queue */ - _PR_DEL_RUNQ(thread); - _PR_RUNQ_UNLOCK(cpu); - return(thread); - } - } - } - thread = NULL; - } - _PR_RUNQ_UNLOCK(cpu); - return(thread); -} -#endif /* !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) */ - -/* -** Schedule this native thread by finding the highest priority nspr -** thread that is ready to run. -** -** Note- everyone really needs to call _PR_MD_SWITCH_CONTEXT (which calls -** PR_Schedule() rather than calling PR_Schedule. Otherwise if there -** is initialization required for switching from SWITCH_CONTEXT, -** it will not get done! -*/ -void _PR_Schedule(void) -{ - PRThread *thread, *me = _PR_MD_CURRENT_THREAD(); - _PRCPU *cpu = _PR_MD_CURRENT_CPU(); - PRIntn pri; - PRUint32 r; - PRCList *qp; - PRIntn priMin, priMax; -#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) - PRBool wakeup_cpus; -#endif - - /* Interrupts must be disabled */ - PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); - - /* Since we are rescheduling, we no longer want to */ - _PR_CLEAR_RESCHED_FLAG(); - - /* - ** Find highest priority thread to run. Bigger priority numbers are - ** higher priority threads - */ - _PR_RUNQ_LOCK(cpu); - /* - * if we are in SuspendAll mode, can schedule only the thread - * that called PR_SuspendAll - * - * The thread may be ready to run now, after completing an I/O - * operation, for example - */ - if ((thread = suspendAllThread) != 0) { - if ((!(thread->no_sched)) && (thread->state == _PR_RUNNABLE)) { - /* Pull thread off of its run queue */ - _PR_DEL_RUNQ(thread); - _PR_RUNQ_UNLOCK(cpu); - goto found_thread; - } else { - thread = NULL; - _PR_RUNQ_UNLOCK(cpu); - goto idle_thread; - } - } - r = _PR_RUNQREADYMASK(cpu); - if (r==0) { - priMin = priMax = PR_PRIORITY_FIRST; - } else if (r == (1<= priMin ; pri-- ) { - if (r & (1 << pri)) { - for (qp = _PR_RUNQ(cpu)[pri].next; - qp != &_PR_RUNQ(cpu)[pri]; - qp = qp->next) { - thread = _PR_THREAD_PTR(qp); - /* - * skip non-schedulable threads - */ - PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); - if ((thread->no_sched) && (me != thread)){ - thread = NULL; - continue; - } else { - /* Pull thread off of its run queue */ - _PR_DEL_RUNQ(thread); - _PR_RUNQ_UNLOCK(cpu); - goto found_thread; - } - } - } - thread = NULL; - } - _PR_RUNQ_UNLOCK(cpu); - -#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) - - wakeup_cpus = PR_FALSE; - _PR_CPU_LIST_LOCK(); - for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) { - if (cpu != _PR_CPU_PTR(qp)) { - if ((thread = get_thread(_PR_CPU_PTR(qp), &wakeup_cpus)) - != NULL) { - thread->cpu = cpu; - _PR_CPU_LIST_UNLOCK(); - if (wakeup_cpus == PR_TRUE) - _PR_MD_WAKEUP_CPUS(); - goto found_thread; - } - } - } - _PR_CPU_LIST_UNLOCK(); - if (wakeup_cpus == PR_TRUE) - _PR_MD_WAKEUP_CPUS(); - -#endif /* _PR_LOCAL_THREADS_ONLY */ - -idle_thread: - /* - ** There are no threads to run. Switch to the idle thread - */ - PR_LOG(_pr_sched_lm, PR_LOG_MAX, ("pausing")); - thread = _PR_MD_CURRENT_CPU()->idle_thread; - -found_thread: - PR_ASSERT((me == thread) || ((thread->state == _PR_RUNNABLE) && - (!(thread->no_sched)))); - - /* Resume the thread */ - PR_LOG(_pr_sched_lm, PR_LOG_MAX, - ("switching to %d[%p]", thread->id, thread)); - PR_ASSERT(thread->state != _PR_RUNNING); - thread->state = _PR_RUNNING; - - /* If we are on the runq, it just means that we went to sleep on some - * resource, and by the time we got here another real native thread had - * already given us the resource and put us back on the runqueue - */ - PR_ASSERT(thread->cpu == _PR_MD_CURRENT_CPU()); - if (thread != me) - _PR_MD_RESTORE_CONTEXT(thread); -#if 0 - /* XXXMB; with setjmp/longjmp it is impossible to land here, but - * it is not with fibers... Is this a bad thing? I believe it is - * still safe. - */ - PR_NOT_REACHED("impossible return from schedule"); -#endif -} - -/* -** Attaches a thread. -** Does not set the _PR_MD_CURRENT_THREAD. -** Does not specify the scope of the thread. -*/ -static PRThread * -_PR_AttachThread(PRThreadType type, PRThreadPriority priority, - PRThreadStack *stack) -{ - PRThread *thread; - char *mem; - - if (priority > PR_PRIORITY_LAST) { - priority = PR_PRIORITY_LAST; - } else if (priority < PR_PRIORITY_FIRST) { - priority = PR_PRIORITY_FIRST; - } - - mem = (char*) PR_CALLOC(sizeof(PRThread)); - if (mem) { - thread = (PRThread*) mem; - thread->priority = priority; - thread->stack = stack; - thread->state = _PR_RUNNING; - PR_INIT_CLIST(&thread->lockList); - if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) { - PR_DELETE(thread); - return 0; - } - - return thread; - } - return 0; -} - - - -PR_IMPLEMENT(PRThread*) -_PR_NativeCreateThread(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize, - PRUint32 flags) -{ - PRThread *thread; - - thread = _PR_AttachThread(type, priority, NULL); - - if (thread) { - PR_Lock(_pr_activeLock); - thread->flags = (flags | _PR_GLOBAL_SCOPE); - thread->id = ++_pr_utid; - if (type == PR_SYSTEM_THREAD) { - thread->flags |= _PR_SYSTEM; - _pr_systemActive++; - } else { - _pr_userActive++; - } - PR_Unlock(_pr_activeLock); - - thread->stack = PR_NEWZAP(PRThreadStack); - if (!thread->stack) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - goto done; - } - thread->stack->stackSize = stackSize?stackSize:_MD_DEFAULT_STACK_SIZE; - thread->stack->thr = thread; - thread->startFunc = start; - thread->arg = arg; - - /* - Set thread flags related to scope and joinable state. If joinable - thread, allocate a "termination" conidition variable. - */ - if (state == PR_JOINABLE_THREAD) { - thread->term = PR_NewCondVar(_pr_terminationCVLock); - if (thread->term == NULL) { - PR_DELETE(thread->stack); - goto done; - } - } - - thread->state = _PR_RUNNING; - if (_PR_MD_CREATE_THREAD(thread, _PR_NativeRunThread, priority, - scope,state,stackSize) == PR_SUCCESS) { - return thread; - } - if (thread->term) { - PR_DestroyCondVar(thread->term); - thread->term = NULL; - } - PR_DELETE(thread->stack); - } - -done: - if (thread) { - _PR_DecrActiveThreadCount(thread); - _PR_DestroyThread(thread); - } - return NULL; -} - -/************************************************************************/ - -PR_IMPLEMENT(PRThread*) _PR_CreateThread(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize, - PRUint32 flags) -{ - PRThread *me; - PRThread *thread = NULL; - PRThreadStack *stack; - char *top; - PRIntn is; - PRIntn native = 0; - PRIntn useRecycled = 0; - PRBool status; - - /* - First, pin down the priority. Not all compilers catch passing out of - range enum here. If we let bad values thru, priority queues won't work. - */ - if (priority > PR_PRIORITY_LAST) { - priority = PR_PRIORITY_LAST; - } else if (priority < PR_PRIORITY_FIRST) { - priority = PR_PRIORITY_FIRST; - } - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (! (flags & _PR_IDLE_THREAD)) - me = _PR_MD_CURRENT_THREAD(); - -#if defined(_PR_GLOBAL_THREADS_ONLY) - /* - * can create global threads only - */ - if (scope == PR_LOCAL_THREAD) - scope = PR_GLOBAL_THREAD; -#endif - - if (_native_threads_only) - scope = PR_GLOBAL_THREAD; - - native = (((scope == PR_GLOBAL_THREAD)|| (scope == PR_GLOBAL_BOUND_THREAD)) - && _PR_IS_NATIVE_THREAD_SUPPORTED()); - - _PR_ADJUST_STACKSIZE(stackSize); - - if (native) { - /* - * clear the IDLE_THREAD flag which applies to LOCAL - * threads only - */ - flags &= ~_PR_IDLE_THREAD; - flags |= _PR_GLOBAL_SCOPE; - if (_PR_NUM_DEADNATIVE > 0) { - _PR_DEADQ_LOCK; - - if (_PR_NUM_DEADNATIVE == 0) { /* Thread safe check */ - _PR_DEADQ_UNLOCK; - } else { - thread = _PR_THREAD_PTR(_PR_DEADNATIVEQ.next); - PR_REMOVE_LINK(&thread->links); - _PR_DEC_DEADNATIVE; - _PR_DEADQ_UNLOCK; - - _PR_InitializeRecycledThread(thread); - thread->startFunc = start; - thread->arg = arg; - thread->flags = (flags | _PR_GLOBAL_SCOPE); - if (type == PR_SYSTEM_THREAD) - { - thread->flags |= _PR_SYSTEM; - PR_ATOMIC_INCREMENT(&_pr_systemActive); - } - else PR_ATOMIC_INCREMENT(&_pr_userActive); - - if (state == PR_JOINABLE_THREAD) { - if (!thread->term) - thread->term = PR_NewCondVar(_pr_terminationCVLock); - } - else { - if(thread->term) { - PR_DestroyCondVar(thread->term); - thread->term = 0; - } - } - - thread->priority = priority; - _PR_MD_SET_PRIORITY(&(thread->md), priority); - /* XXX what about stackSize? */ - thread->state = _PR_RUNNING; - _PR_MD_WAKEUP_WAITER(thread); - return thread; - } - } - thread = _PR_NativeCreateThread(type, start, arg, priority, - scope, state, stackSize, flags); - } else { - if (_PR_NUM_DEADUSER > 0) { - _PR_DEADQ_LOCK; - - if (_PR_NUM_DEADUSER == 0) { /* thread safe check */ - _PR_DEADQ_UNLOCK; - } else { - PRCList *ptr; - - /* Go down list checking for a recycled thread with a - * large enough stack. XXXMB - this has a bad degenerate case. - */ - ptr = _PR_DEADUSERQ.next; - while( ptr != &_PR_DEADUSERQ ) { - thread = _PR_THREAD_PTR(ptr); - if ((thread->stack->stackSize >= stackSize) && - (!thread->no_sched)) { - PR_REMOVE_LINK(&thread->links); - _PR_DEC_DEADUSER; - break; - } else { - ptr = ptr->next; - thread = NULL; - } - } - - _PR_DEADQ_UNLOCK; - - if (thread) { - _PR_InitializeRecycledThread(thread); - thread->startFunc = start; - thread->arg = arg; - thread->priority = priority; - if (state == PR_JOINABLE_THREAD) { - if (!thread->term) - thread->term = PR_NewCondVar(_pr_terminationCVLock); - } else { - if(thread->term) { - PR_DestroyCondVar(thread->term); - thread->term = 0; - } - } - useRecycled++; - } - } - } - if (thread == NULL) { -#ifndef HAVE_CUSTOM_USER_THREADS - stack = _PR_NewStack(stackSize); - if (!stack) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - - /* Allocate thread object and per-thread data off the top of the stack*/ - top = stack->stackTop; -#ifdef HAVE_STACK_GROWING_UP - thread = (PRThread*) top; - top = top + sizeof(PRThread); - /* - * Make stack 64-byte aligned - */ - if ((PRUptrdiff)top & 0x3f) { - top = (char*)(((PRUptrdiff)top + 0x40) & ~0x3f); - } -#else - top = top - sizeof(PRThread); - thread = (PRThread*) top; - /* - * Make stack 64-byte aligned - */ - if ((PRUptrdiff)top & 0x3f) { - top = (char*)((PRUptrdiff)top & ~0x3f); - } -#endif - stack->thr = thread; - memset(thread, 0, sizeof(PRThread)); - thread->threadAllocatedOnStack = 1; -#else - thread = _PR_MD_CREATE_USER_THREAD(stackSize, start, arg); - if (!thread) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - thread->threadAllocatedOnStack = 0; - stack = NULL; - top = NULL; -#endif - - /* Initialize thread */ - thread->tpdLength = 0; - thread->privateData = NULL; - thread->stack = stack; - thread->priority = priority; - thread->startFunc = start; - thread->arg = arg; - PR_INIT_CLIST(&thread->lockList); - - if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) { - if (thread->threadAllocatedOnStack == 1) - _PR_FreeStack(thread->stack); - else { - PR_DELETE(thread); - } - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - return NULL; - } - - if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) { - if (thread->threadAllocatedOnStack == 1) - _PR_FreeStack(thread->stack); - else { - PR_DELETE(thread->privateData); - PR_DELETE(thread); - } - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - return NULL; - } - - _PR_MD_INIT_CONTEXT(thread, top, _PR_UserRunThread, &status); - - if (status == PR_FALSE) { - _PR_MD_FREE_LOCK(&thread->threadLock); - if (thread->threadAllocatedOnStack == 1) - _PR_FreeStack(thread->stack); - else { - PR_DELETE(thread->privateData); - PR_DELETE(thread); - } - return NULL; - } - - /* - Set thread flags related to scope and joinable state. If joinable - thread, allocate a "termination" condition variable. - */ - if (state == PR_JOINABLE_THREAD) { - thread->term = PR_NewCondVar(_pr_terminationCVLock); - if (thread->term == NULL) { - _PR_MD_FREE_LOCK(&thread->threadLock); - if (thread->threadAllocatedOnStack == 1) - _PR_FreeStack(thread->stack); - else { - PR_DELETE(thread->privateData); - PR_DELETE(thread); - } - return NULL; - } - } - - } - - /* Update thread type counter */ - PR_Lock(_pr_activeLock); - thread->flags = flags; - thread->id = ++_pr_utid; - if (type == PR_SYSTEM_THREAD) { - thread->flags |= _PR_SYSTEM; - _pr_systemActive++; - } else { - _pr_userActive++; - } - - /* Make thread runnable */ - thread->state = _PR_RUNNABLE; - /* - * Add to list of active threads - */ - PR_Unlock(_pr_activeLock); - - if ((! (thread->flags & _PR_IDLE_THREAD)) && _PR_IS_NATIVE_THREAD(me) ) - thread->cpu = _PR_GetPrimordialCPU(); - else - thread->cpu = _PR_MD_CURRENT_CPU(); - - PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread)); - - if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me)) { - _PR_INTSOFF(is); - _PR_RUNQ_LOCK(thread->cpu); - _PR_ADD_RUNQ(thread, thread->cpu, priority); - _PR_RUNQ_UNLOCK(thread->cpu); - } - - if (thread->flags & _PR_IDLE_THREAD) { - /* - ** If the creating thread is a kernel thread, we need to - ** awaken the user thread idle thread somehow; potentially - ** it could be sleeping in its idle loop, and we need to poke - ** it. To do so, wake the idle thread... - */ - _PR_MD_WAKEUP_WAITER(NULL); - } else if (_PR_IS_NATIVE_THREAD(me)) { - _PR_MD_WAKEUP_WAITER(thread); - } - if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me) ) - _PR_INTSON(is); - } - - return thread; -} - -PR_IMPLEMENT(PRThread*) PR_CreateThread(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - return _PR_CreateThread(type, start, arg, priority, scope, state, - stackSize, 0); -} - -/* -** Associate a thread object with an existing native thread. -** "type" is the type of thread object to attach -** "priority" is the priority to assign to the thread -** "stack" defines the shape of the threads stack -** -** This can return NULL if some kind of error occurs, or if memory is -** tight. -** -** This call is not normally needed unless you create your own native -** thread. PR_Init does this automatically for the primordial thread. -*/ -PRThread* _PRI_AttachThread(PRThreadType type, - PRThreadPriority priority, PRThreadStack *stack, PRUint32 flags) -{ - PRThread *thread; - - if ((thread = _PR_MD_GET_ATTACHED_THREAD()) != NULL) { - return thread; - } - _PR_MD_SET_CURRENT_THREAD(NULL); - - /* Clear out any state if this thread was attached before */ - _PR_MD_SET_CURRENT_CPU(NULL); - - thread = _PR_AttachThread(type, priority, stack); - if (thread) { - PRIntn is; - - _PR_MD_SET_CURRENT_THREAD(thread); - - thread->flags = flags | _PR_GLOBAL_SCOPE | _PR_ATTACHED; - - if (!stack) { - thread->stack = PR_NEWZAP(PRThreadStack); - if (!thread->stack) { - _PR_DestroyThread(thread); - return NULL; - } - thread->stack->stackSize = _MD_DEFAULT_STACK_SIZE; - } - PR_INIT_CLIST(&thread->links); - - if (_PR_MD_INIT_ATTACHED_THREAD(thread) == PR_FAILURE) { - PR_DELETE(thread->stack); - _PR_DestroyThread(thread); - return NULL; - } - - _PR_MD_SET_CURRENT_CPU(NULL); - - if (_PR_MD_CURRENT_CPU()) { - _PR_INTSOFF(is); - PR_Lock(_pr_activeLock); - } - if (type == PR_SYSTEM_THREAD) { - thread->flags |= _PR_SYSTEM; - _pr_systemActive++; - } else { - _pr_userActive++; - } - if (_PR_MD_CURRENT_CPU()) { - PR_Unlock(_pr_activeLock); - _PR_INTSON(is); - } - } - return thread; -} - -PR_IMPLEMENT(PRThread*) PR_AttachThread(PRThreadType type, - PRThreadPriority priority, PRThreadStack *stack) -{ - return PR_GetCurrentThread(); -} - -PR_IMPLEMENT(void) PR_DetachThread(void) -{ - /* - * On IRIX, Solaris, and Windows, foreign threads are detached when - * they terminate. - */ -#if !defined(IRIX) && !defined(WIN32) \ - && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)) - PRThread *me; - if (_pr_initialized) { - me = _PR_MD_GET_ATTACHED_THREAD(); - if ((me != NULL) && (me->flags & _PR_ATTACHED)) - _PRI_DetachThread(); - } -#endif -} - -void _PRI_DetachThread(void) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (me->flags & _PR_PRIMORDIAL) { - /* - * ignore, if primordial thread - */ - return; - } - PR_ASSERT(me->flags & _PR_ATTACHED); - PR_ASSERT(_PR_IS_NATIVE_THREAD(me)); - _PR_CleanupThread(me); - PR_DELETE(me->privateData); - - _PR_DecrActiveThreadCount(me); - - _PR_MD_CLEAN_THREAD(me); - _PR_MD_SET_CURRENT_THREAD(NULL); - if (!me->threadAllocatedOnStack) - PR_DELETE(me->stack); - _PR_MD_FREE_LOCK(&me->threadLock); - PR_DELETE(me); -} - -/* -** Wait for thread termination: -** "thread" is the target thread -** -** This can return PR_FAILURE if no joinable thread could be found -** corresponding to the specified target thread. -** -** The calling thread is suspended until the target thread completes. -** Several threads cannot wait for the same thread to complete; one thread -** will complete successfully and others will terminate with an error PR_FAILURE. -** The calling thread will not be blocked if the target thread has already -** terminated. -*/ -PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thread) -{ - PRIntn is; - PRCondVar *term; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - term = thread->term; - /* can't join a non-joinable thread */ - if (term == NULL) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - goto ErrorExit; - } - - /* multiple threads can't wait on the same joinable thread */ - if (term->condQ.next != &term->condQ) { - goto ErrorExit; - } - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); - - /* wait for the target thread's termination cv invariant */ - PR_Lock (_pr_terminationCVLock); - while (thread->state != _PR_JOIN_WAIT) { - (void) PR_WaitCondVar(term, PR_INTERVAL_NO_TIMEOUT); - } - (void) PR_Unlock (_pr_terminationCVLock); - - /* - Remove target thread from global waiting to join Q; make it runnable - again and put it back on its run Q. When it gets scheduled later in - _PR_RunThread code, it will clean up its stack. - */ - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - thread->state = _PR_RUNNABLE; - if ( !_PR_IS_NATIVE_THREAD(thread) ) { - _PR_THREAD_LOCK(thread); - - _PR_MISCQ_LOCK(thread->cpu); - _PR_DEL_JOINQ(thread); - _PR_MISCQ_UNLOCK(thread->cpu); - - _PR_AddThreadToRunQ(me, thread); - _PR_THREAD_UNLOCK(thread); - } - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); - - _PR_MD_WAKEUP_WAITER(thread); - - return PR_SUCCESS; - -ErrorExit: - if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); - return PR_FAILURE; -} - -PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thread, - PRThreadPriority newPri) -{ - - /* - First, pin down the priority. Not all compilers catch passing out of - range enum here. If we let bad values thru, priority queues won't work. - */ - if ((PRIntn)newPri > (PRIntn)PR_PRIORITY_LAST) { - newPri = PR_PRIORITY_LAST; - } else if ((PRIntn)newPri < (PRIntn)PR_PRIORITY_FIRST) { - newPri = PR_PRIORITY_FIRST; - } - - if ( _PR_IS_NATIVE_THREAD(thread) ) { - thread->priority = newPri; - _PR_MD_SET_PRIORITY(&(thread->md), newPri); - } else _PR_SetThreadPriority(thread, newPri); -} - -PR_IMPLEMENT(PRStatus) PR_SetCurrentThreadName(const char *name) -{ - PRThread *thread; - size_t nameLen; - - if (!name) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - - thread = PR_GetCurrentThread(); - if (!thread) - return PR_FAILURE; - - PR_Free(thread->name); - nameLen = strlen(name); - thread->name = (char *)PR_Malloc(nameLen + 1); - if (!thread->name) - return PR_FAILURE; - memcpy(thread->name, name, nameLen + 1); - _PR_MD_SET_CURRENT_THREAD_NAME(thread->name); - return PR_SUCCESS; -} - -PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) -{ - if (!thread) - return NULL; - return thread->name; -} - - -/* -** This routine prevents all other threads from running. This call is needed by -** the garbage collector. -*/ -PR_IMPLEMENT(void) PR_SuspendAll(void) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRCList *qp; - - /* - * Stop all user and native threads which are marked GC able. - */ - PR_Lock(_pr_activeLock); - suspendAllOn = PR_TRUE; - suspendAllThread = _PR_MD_CURRENT_THREAD(); - _PR_MD_BEGIN_SUSPEND_ALL(); - for (qp = _PR_ACTIVE_LOCAL_THREADQ().next; - qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) { - if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && - _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) { - _PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp)); - PR_ASSERT((_PR_ACTIVE_THREAD_PTR(qp))->state != _PR_RUNNING); - } - } - for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next; - qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) { - if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && - _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) - /* PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp)); */ - _PR_MD_SUSPEND_THREAD(_PR_ACTIVE_THREAD_PTR(qp)); - } - _PR_MD_END_SUSPEND_ALL(); -} - -/* -** This routine unblocks all other threads that were suspended from running by -** PR_SuspendAll(). This call is needed by the garbage collector. -*/ -PR_IMPLEMENT(void) PR_ResumeAll(void) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - PRCList *qp; - - /* - * Resume all user and native threads which are marked GC able. - */ - _PR_MD_BEGIN_RESUME_ALL(); - for (qp = _PR_ACTIVE_LOCAL_THREADQ().next; - qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) { - if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && - _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) - _PR_Resume(_PR_ACTIVE_THREAD_PTR(qp)); - } - for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next; - qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) { - if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && - _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) - _PR_MD_RESUME_THREAD(_PR_ACTIVE_THREAD_PTR(qp)); - } - _PR_MD_END_RESUME_ALL(); - suspendAllThread = NULL; - suspendAllOn = PR_FALSE; - PR_Unlock(_pr_activeLock); -} - -PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg) -{ - PRCList *qp, *qp_next; - PRIntn i = 0; - PRStatus rv = PR_SUCCESS; - PRThread* t; - - /* - ** Currently Enumerate threads happen only with suspension and - ** pr_activeLock held - */ - PR_ASSERT(suspendAllOn); - - /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking - * qp->next after applying the function "func". In particular, "func" - * might remove the thread from the queue and put it into another one in - * which case qp->next no longer points to the next entry in the original - * queue. - * - * To get around this problem, we save qp->next in qp_next before applying - * "func" and use that saved value as the next value after applying "func". - */ - - /* - * Traverse the list of local and global threads - */ - for (qp = _PR_ACTIVE_LOCAL_THREADQ().next; - qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp_next) - { - qp_next = qp->next; - t = _PR_ACTIVE_THREAD_PTR(qp); - if (_PR_IS_GCABLE_THREAD(t)) - { - rv = (*func)(t, i, arg); - if (rv != PR_SUCCESS) - return rv; - i++; - } - } - for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next; - qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp_next) - { - qp_next = qp->next; - t = _PR_ACTIVE_THREAD_PTR(qp); - if (_PR_IS_GCABLE_THREAD(t)) - { - rv = (*func)(t, i, arg); - if (rv != PR_SUCCESS) - return rv; - i++; - } - } - return rv; -} - -/* FUNCTION: _PR_AddSleepQ -** DESCRIPTION: -** Adds a thread to the sleep/pauseQ. -** RESTRICTIONS: -** Caller must have the RUNQ lock. -** Caller must be a user level thread -*/ -PR_IMPLEMENT(void) -_PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout) -{ - _PRCPU *cpu = thread->cpu; - - if (timeout == PR_INTERVAL_NO_TIMEOUT) { - /* append the thread to the global pause Q */ - PR_APPEND_LINK(&thread->links, &_PR_PAUSEQ(thread->cpu)); - thread->flags |= _PR_ON_PAUSEQ; - } else { - PRIntervalTime sleep; - PRCList *q; - PRThread *t; - - /* sort onto global sleepQ */ - sleep = timeout; - - /* Check if we are longest timeout */ - if (timeout >= _PR_SLEEPQMAX(cpu)) { - PR_INSERT_BEFORE(&thread->links, &_PR_SLEEPQ(cpu)); - thread->sleep = timeout - _PR_SLEEPQMAX(cpu); - _PR_SLEEPQMAX(cpu) = timeout; - } else { - /* Sort thread into global sleepQ at appropriate point */ - q = _PR_SLEEPQ(cpu).next; - - /* Now scan the list for where to insert this entry */ - while (q != &_PR_SLEEPQ(cpu)) { - t = _PR_THREAD_PTR(q); - if (sleep < t->sleep) { - /* Found sleeper to insert in front of */ - break; - } - sleep -= t->sleep; - q = q->next; - } - thread->sleep = sleep; - PR_INSERT_BEFORE(&thread->links, q); - - /* - ** Subtract our sleep time from the sleeper that follows us (there - ** must be one) so that they remain relative to us. - */ - PR_ASSERT (thread->links.next != &_PR_SLEEPQ(cpu)); - - t = _PR_THREAD_PTR(thread->links.next); - PR_ASSERT(_PR_THREAD_PTR(t->links.prev) == thread); - t->sleep -= sleep; - } - - thread->flags |= _PR_ON_SLEEPQ; - } -} - -/* FUNCTION: _PR_DelSleepQ -** DESCRIPTION: -** Removes a thread from the sleep/pauseQ. -** INPUTS: -** If propogate_time is true, then the thread following the deleted -** thread will be get the time from the deleted thread. This is used -** when deleting a sleeper that has not timed out. -** RESTRICTIONS: -** Caller must have the RUNQ lock. -** Caller must be a user level thread -*/ -PR_IMPLEMENT(void) -_PR_DelSleepQ(PRThread *thread, PRBool propogate_time) -{ - _PRCPU *cpu = thread->cpu; - - /* Remove from pauseQ/sleepQ */ - if (thread->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { - if (thread->flags & _PR_ON_SLEEPQ) { - PRCList *q = thread->links.next; - if (q != &_PR_SLEEPQ(cpu)) { - if (propogate_time == PR_TRUE) { - PRThread *after = _PR_THREAD_PTR(q); - after->sleep += thread->sleep; - } else - _PR_SLEEPQMAX(cpu) -= thread->sleep; - } else { - /* Check if prev is the beggining of the list; if so, - * we are the only element on the list. - */ - if (thread->links.prev != &_PR_SLEEPQ(cpu)) - _PR_SLEEPQMAX(cpu) -= thread->sleep; - else - _PR_SLEEPQMAX(cpu) = 0; - } - thread->flags &= ~_PR_ON_SLEEPQ; - } else { - thread->flags &= ~_PR_ON_PAUSEQ; - } - PR_REMOVE_LINK(&thread->links); - } else - PR_ASSERT(0); -} - -void -_PR_AddThreadToRunQ( - PRThread *me, /* the current thread */ - PRThread *thread) /* the local thread to be added to a run queue */ -{ - PRThreadPriority pri = thread->priority; - _PRCPU *cpu = thread->cpu; - - PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread)); - -#if defined(WINNT) - /* - * On NT, we can only reliably know that the current CPU - * is not idle. We add the awakened thread to the run - * queue of its CPU if its CPU is the current CPU. - * For any other CPU, we don't really know whether it - * is busy or idle. So in all other cases, we just - * "post" the awakened thread to the IO completion port - * for the next idle CPU to execute (this is done in - * _PR_MD_WAKEUP_WAITER). - * Threads with a suspended I/O operation remain bound to - * the same cpu until I/O is cancelled - * - * NOTE: the boolean expression below must be the exact - * opposite of the corresponding boolean expression in - * _PR_MD_WAKEUP_WAITER. - */ - if ((!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) || - (thread->md.thr_bound_cpu)) { - PR_ASSERT(!thread->md.thr_bound_cpu || - (thread->md.thr_bound_cpu == cpu)); - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(thread, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - } -#else - _PR_RUNQ_LOCK(cpu); - _PR_ADD_RUNQ(thread, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - if (!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) { - if (pri > me->priority) { - _PR_SET_RESCHED_FLAG(); - } - } -#endif -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/README nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/README --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/README 1998-03-28 03:37:59.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/combined/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -NSPR 2.0 evolution ------------------- - - -Phase 1- today - -Currently (Oct 10, 1996) NSPR 2.0 has two modes. Either _PR_NTHREAD -is defined, in which case the PR_CreateThread() call always creates a -native kernel thread, or _PR_NTHREAD is not defined and PR_CreateThread() -always creates user level threads within the single, original process. This -source code is reflected in two directories, nspr20/pr/src/threads/native, and -nspr20/pr/src/threads/user. Although the PR_CreateThread() function has -a paramter to specify the "scope" of a thread, this parameter is not yet -used- except on solaris where it uses it to specify bound vs unbound threads. - -Phase 2 - next week - -The next step is to provide a combination of user and native threads. The -idea, of course, is to have some small number of native threads and each of -those threads be able to run user level threads. The number of native -threads created will most likely be proportional to the number of CPUs in -the system. For this reason, the specific set of native threads which are -used to run the user-level threads will be called "CPU" threads. - -The user level threads which will be run on the CPU threads are able to -run on any of the CPU threads available, and over the course of a user-level -thread's lifetime, it may drift from one CPU thread to another. All -user-level threads will compete for processing time via a single run queue. - -Creation of a CPU thread will be primarily controlled by NSPR itself or by -the user running a function PR_Concurrency(). The details of PR_Concurrency() -have not yet been worked out; but the idea is that the user can specify to -NSPR how many CPU threads are desired. - -In this system, user-level threads are created by using PR_CreateThread() and -specifying the PR_LOCAL_SCOPE option. LOCAL_SCOPE indicates that the thread -will be under the control of the "local" scheduler. Creating threads with -GLOBAL_SCOPE, on the other hand will create a thread which is under the -control of the system's scheduler. In otherwords, this creates a native thread -which is not a CPU thread; it runs a single thread task and never has more -than one task to run. LOCAL_SCOPE is much like creating a Solaris unbound -thread, while GLOBAL_SCOPE is similar to creating a Solaris bound thread. - -To implement this architecture, the source code will still maintain the "user" -and "native" directories which is has today. However a third directory -"combined" will also exist. To compile a version of NSPR which only creates -native threads, the user can define _PR_NTHREAD. For exclusive user-level -threads, do not define _PR_NTHREAD. To get the combined threads, define -_PR_NTHREAD and _PR_USE_CPUS. - - -Phase 3 - later than next week - -The goal is to eliminate the 3 directories. Once these three models are in -place, the remaining work will be to eliminate the native and user thread -directories for all platforms, so that the entire thread model is contained -within what is today called the "combined" model. This new and glorious -source code will attempt to make the "combined" model on any platforms which -provide the necessary underlying native threading, but will also be -capable of using exclusive user-level threads on systems which don't have -native threads. - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/src/threads/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/.cvsignore 2001-05-12 04:55:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/src/threads/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/Makefile.in 2012-03-06 13:14:21.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -ifdef USE_PTHREADS - DIRS = -else -ifdef USE_BTHREADS - DIRS = -else - DIRS = combined -endif -endif - -ifdef USE_PTHREADS -CSRCS = \ - prcmon.c \ - prrwlock.c \ - prtpd.c \ - $(NULL) -else -ifdef USE_BTHREADS -CSRCS = \ - prcmon.c \ - prrwlock.c \ - prtpd.c \ - $(NULL) -else -CSRCS = \ - prcmon.c \ - prdump.c \ - prmon.c \ - prsem.c \ - prrwlock.c \ - prcthr.c \ - prtpd.c \ - $(NULL) -endif -endif - -TARGETS = $(OBJS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -DEFINES += -D_NSPR_BUILD_ - -include $(topsrcdir)/config/rules.mk - -export:: $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prcmon.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prcmon.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prcmon.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prcmon.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,431 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include -#include - -/* Lock used to lock the monitor cache */ -#ifdef _PR_NO_PREEMPT -#define _PR_NEW_LOCK_MCACHE() -#define _PR_DESTROY_LOCK_MCACHE() -#define _PR_LOCK_MCACHE() -#define _PR_UNLOCK_MCACHE() -#else -#ifdef _PR_LOCAL_THREADS_ONLY -#define _PR_NEW_LOCK_MCACHE() -#define _PR_DESTROY_LOCK_MCACHE() -#define _PR_LOCK_MCACHE() { PRIntn _is; _PR_INTSOFF(_is) -#define _PR_UNLOCK_MCACHE() _PR_INTSON(_is); } -#else -PRLock *_pr_mcacheLock; -#define _PR_NEW_LOCK_MCACHE() (_pr_mcacheLock = PR_NewLock()) -#define _PR_DESTROY_LOCK_MCACHE() \ - PR_BEGIN_MACRO \ - if (_pr_mcacheLock) { \ - PR_DestroyLock(_pr_mcacheLock); \ - _pr_mcacheLock = NULL; \ - } \ - PR_END_MACRO -#define _PR_LOCK_MCACHE() PR_Lock(_pr_mcacheLock) -#define _PR_UNLOCK_MCACHE() PR_Unlock(_pr_mcacheLock) -#endif -#endif - -/************************************************************************/ - -typedef struct MonitorCacheEntryStr MonitorCacheEntry; - -struct MonitorCacheEntryStr { - MonitorCacheEntry* next; - void* address; - PRMonitor* mon; - long cacheEntryCount; -}; - -/* -** An array of MonitorCacheEntry's, plus a pointer to link these -** arrays together. -*/ - -typedef struct MonitorCacheEntryBlockStr MonitorCacheEntryBlock; - -struct MonitorCacheEntryBlockStr { - MonitorCacheEntryBlock* next; - MonitorCacheEntry entries[1]; -}; - -static PRUint32 hash_mask; -static PRUintn num_hash_buckets; -static PRUintn num_hash_buckets_log2; -static MonitorCacheEntry **hash_buckets; -static MonitorCacheEntry *free_entries; -static PRUintn num_free_entries; -static PRBool expanding; -static MonitorCacheEntryBlock *mcache_blocks; - -static void (*OnMonitorRecycle)(void *address); - -#define HASH(address) \ - ((PRUint32) ( ((PRUptrdiff)(address) >> 2) ^ \ - ((PRUptrdiff)(address) >> 10) ) \ - & hash_mask) - -/* -** Expand the monitor cache. This grows the hash buckets and allocates a -** new chunk of cache entries and throws them on the free list. We keep -** as many hash buckets as there are entries. -** -** Because we call malloc and malloc may need the monitor cache, we must -** ensure that there are several free monitor cache entries available for -** malloc to get. FREE_THRESHOLD is used to prevent monitor cache -** starvation during monitor cache expansion. -*/ - -#define FREE_THRESHOLD 5 - -static PRStatus ExpandMonitorCache(PRUintn new_size_log2) -{ - MonitorCacheEntry **old_hash_buckets, *p; - PRUintn i, entries, old_num_hash_buckets, added; - MonitorCacheEntry **new_hash_buckets; - MonitorCacheEntryBlock *new_block; - - entries = 1L << new_size_log2; - - /* - ** Expand the monitor-cache-entry free list - */ - new_block = (MonitorCacheEntryBlock*) - PR_CALLOC(sizeof(MonitorCacheEntryBlock) - + (entries - 1) * sizeof(MonitorCacheEntry)); - if (NULL == new_block) return PR_FAILURE; - - /* - ** Allocate system monitors for the new monitor cache entries. If we - ** run out of system monitors, break out of the loop. - */ - for (i = 0, p = new_block->entries; i < entries; i++, p++) { - p->mon = PR_NewMonitor(); - if (!p->mon) - break; - } - added = i; - if (added != entries) { - MonitorCacheEntryBlock *realloc_block; - - if (added == 0) { - /* Totally out of system monitors. Lossage abounds */ - PR_DELETE(new_block); - return PR_FAILURE; - } - - /* - ** We were able to allocate some of the system monitors. Use - ** realloc to shrink down the new_block memory. If that fails, - ** carry on with the too-large new_block. - */ - realloc_block = (MonitorCacheEntryBlock*) - PR_REALLOC(new_block, sizeof(MonitorCacheEntryBlock) - + (added - 1) * sizeof(MonitorCacheEntry)); - if (realloc_block) - new_block = realloc_block; - } - - /* - ** Now that we have allocated all of the system monitors, build up - ** the new free list. We can just update the free_list because we own - ** the mcache-lock and we aren't calling anyone who might want to use - ** it. - */ - for (i = 0, p = new_block->entries; i < added - 1; i++, p++) - p->next = p + 1; - p->next = free_entries; - free_entries = new_block->entries; - num_free_entries += added; - new_block->next = mcache_blocks; - mcache_blocks = new_block; - - /* Try to expand the hash table */ - new_hash_buckets = (MonitorCacheEntry**) - PR_CALLOC(entries * sizeof(MonitorCacheEntry*)); - if (NULL == new_hash_buckets) { - /* - ** Partial lossage. In this situation we don't get any more hash - ** buckets, which just means that the table lookups will take - ** longer. This is bad, but not fatal - */ - PR_LOG(_pr_cmon_lm, PR_LOG_WARNING, - ("unable to grow monitor cache hash buckets")); - return PR_SUCCESS; - } - - /* - ** Compute new hash mask value. This value is used to mask an address - ** until it's bits are in the right spot for indexing into the hash - ** table. - */ - hash_mask = entries - 1; - - /* - ** Expand the hash table. We have to rehash everything in the old - ** table into the new table. - */ - old_hash_buckets = hash_buckets; - old_num_hash_buckets = num_hash_buckets; - for (i = 0; i < old_num_hash_buckets; i++) { - p = old_hash_buckets[i]; - while (p) { - MonitorCacheEntry *next = p->next; - - /* Hash based on new table size, and then put p in the new table */ - PRUintn hash = HASH(p->address); - p->next = new_hash_buckets[hash]; - new_hash_buckets[hash] = p; - - p = next; - } - } - - /* - ** Switch over to new hash table and THEN call free of the old - ** table. Since free might re-enter _pr_mcache_lock, things would - ** break terribly if it used the old hash table. - */ - hash_buckets = new_hash_buckets; - num_hash_buckets = entries; - num_hash_buckets_log2 = new_size_log2; - PR_DELETE(old_hash_buckets); - - PR_LOG(_pr_cmon_lm, PR_LOG_NOTICE, - ("expanded monitor cache to %d (buckets %d)", - num_free_entries, entries)); - - return PR_SUCCESS; -} /* ExpandMonitorCache */ - -/* -** Lookup a monitor cache entry by address. Return a pointer to the -** pointer to the monitor cache entry on success, null on failure. -*/ -static MonitorCacheEntry **LookupMonitorCacheEntry(void *address) -{ - PRUintn hash; - MonitorCacheEntry **pp, *p; - - hash = HASH(address); - pp = hash_buckets + hash; - while ((p = *pp) != 0) { - if (p->address == address) { - if (p->cacheEntryCount > 0) - return pp; - return NULL; - } - pp = &p->next; - } - return NULL; -} - -/* -** Try to create a new cached monitor. If it's already in the cache, -** great - return it. Otherwise get a new free cache entry and set it -** up. If the cache free space is getting low, expand the cache. -*/ -static PRMonitor *CreateMonitor(void *address) -{ - PRUintn hash; - MonitorCacheEntry **pp, *p; - - hash = HASH(address); - pp = hash_buckets + hash; - while ((p = *pp) != 0) { - if (p->address == address) goto gotit; - - pp = &p->next; - } - - /* Expand the monitor cache if we have run out of free slots in the table */ - if (num_free_entries < FREE_THRESHOLD) { - /* Expand monitor cache */ - - /* - ** This function is called with the lock held. So what's the 'expanding' - ** boolean all about? Seems a bit redundant. - */ - if (!expanding) { - PRStatus rv; - - expanding = PR_TRUE; - rv = ExpandMonitorCache(num_hash_buckets_log2 + 1); - expanding = PR_FALSE; - if (PR_FAILURE == rv) return NULL; - - /* redo the hash because it'll be different now */ - hash = HASH(address); - } else { - /* - ** We are in process of expanding and we need a cache - ** monitor. Make sure we have enough! - */ - PR_ASSERT(num_free_entries > 0); - } - } - - /* Make a new monitor */ - p = free_entries; - free_entries = p->next; - num_free_entries--; - if (OnMonitorRecycle && p->address) - OnMonitorRecycle(p->address); - p->address = address; - p->next = hash_buckets[hash]; - hash_buckets[hash] = p; - PR_ASSERT(p->cacheEntryCount == 0); - - gotit: - p->cacheEntryCount++; - return p->mon; -} - -/* -** Initialize the monitor cache -*/ -void _PR_InitCMon(void) -{ - _PR_NEW_LOCK_MCACHE(); - ExpandMonitorCache(3); -} - -/* -** Destroy the monitor cache -*/ -void _PR_CleanupCMon(void) -{ - _PR_DESTROY_LOCK_MCACHE(); - - while (free_entries) { - PR_DestroyMonitor(free_entries->mon); - free_entries = free_entries->next; - } - num_free_entries = 0; - - while (mcache_blocks) { - MonitorCacheEntryBlock *block; - - block = mcache_blocks; - mcache_blocks = block->next; - PR_DELETE(block); - } - - PR_DELETE(hash_buckets); - hash_mask = 0; - num_hash_buckets = 0; - num_hash_buckets_log2 = 0; - - expanding = PR_FALSE; - OnMonitorRecycle = NULL; -} - -/* -** Create monitor for address. Don't enter the monitor while we have the -** mcache locked because we might block! -*/ -PR_IMPLEMENT(PRMonitor*) PR_CEnterMonitor(void *address) -{ - PRMonitor *mon; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - _PR_LOCK_MCACHE(); - mon = CreateMonitor(address); - _PR_UNLOCK_MCACHE(); - - if (!mon) return NULL; - - PR_EnterMonitor(mon); - return mon; -} - -PR_IMPLEMENT(PRStatus) PR_CExitMonitor(void *address) -{ - MonitorCacheEntry **pp, *p; - PRStatus status = PR_SUCCESS; - - _PR_LOCK_MCACHE(); - pp = LookupMonitorCacheEntry(address); - if (pp != NULL) { - p = *pp; - if (--p->cacheEntryCount == 0) { - /* - ** Nobody is using the system monitor. Put it on the cached free - ** list. We are safe from somebody trying to use it because we - ** have the mcache locked. - */ - p->address = 0; /* defensive move */ - *pp = p->next; /* unlink from hash_buckets */ - p->next = free_entries; /* link into free list */ - free_entries = p; - num_free_entries++; /* count it as free */ - } - status = PR_ExitMonitor(p->mon); - } else { - status = PR_FAILURE; - } - _PR_UNLOCK_MCACHE(); - - return status; -} - -PR_IMPLEMENT(PRStatus) PR_CWait(void *address, PRIntervalTime ticks) -{ - MonitorCacheEntry **pp; - PRMonitor *mon; - - _PR_LOCK_MCACHE(); - pp = LookupMonitorCacheEntry(address); - mon = pp ? ((*pp)->mon) : NULL; - _PR_UNLOCK_MCACHE(); - - if (mon == NULL) - return PR_FAILURE; - return PR_Wait(mon, ticks); -} - -PR_IMPLEMENT(PRStatus) PR_CNotify(void *address) -{ - MonitorCacheEntry **pp; - PRMonitor *mon; - - _PR_LOCK_MCACHE(); - pp = LookupMonitorCacheEntry(address); - mon = pp ? ((*pp)->mon) : NULL; - _PR_UNLOCK_MCACHE(); - - if (mon == NULL) - return PR_FAILURE; - return PR_Notify(mon); -} - -PR_IMPLEMENT(PRStatus) PR_CNotifyAll(void *address) -{ - MonitorCacheEntry **pp; - PRMonitor *mon; - - _PR_LOCK_MCACHE(); - pp = LookupMonitorCacheEntry(address); - mon = pp ? ((*pp)->mon) : NULL; - _PR_UNLOCK_MCACHE(); - - if (mon == NULL) - return PR_FAILURE; - return PR_NotifyAll(mon); -} - -PR_IMPLEMENT(void) -PR_CSetOnMonitorRecycle(void (*callback)(void *address)) -{ - OnMonitorRecycle = callback; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prcthr.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prcthr.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prcthr.c 2012-05-26 00:15:24.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prcthr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,395 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#if defined(WIN95) -/* -** Some local variables report warnings on Win95 because the code paths -** using them are conditioned on HAVE_CUSTOME_USER_THREADS. -** The pragma suppresses the warning. -** -*/ -#pragma warning(disable : 4101) -#endif - - -extern PRLock *_pr_sleeplock; /* allocated and initialized in prinit */ -/* -** Routines common to both native and user threads. -** -** -** Clean up a thread object, releasing all of the attached data. Do not -** free the object itself (it may not have been malloc'd) -*/ -void _PR_CleanupThread(PRThread *thread) -{ - /* Free up per-thread-data */ - _PR_DestroyThreadPrivate(thread); - - /* Free any thread dump procs */ - if (thread->dumpArg) { - PR_DELETE(thread->dumpArg); - } - thread->dump = 0; - - PR_DELETE(thread->name); - PR_DELETE(thread->errorString); - thread->errorStringSize = 0; - thread->errorStringLength = 0; - thread->environment = NULL; -} - -PR_IMPLEMENT(PRStatus) PR_Yield() -{ - static PRBool warning = PR_TRUE; - if (warning) warning = _PR_Obsolete( - "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)"); - return (PR_Sleep(PR_INTERVAL_NO_WAIT)); -} - -/* -** Make the current thread sleep until "timeout" ticks amount of time -** has expired. If "timeout" is PR_INTERVAL_NO_WAIT then the call is -** equivalent to a yield. Waiting for an infinite amount of time is -** allowed in the expectation that another thread will interrupt(). -** -** A single lock is used for all threads calling sleep. Each caller -** does get its own condition variable since each is expected to have -** a unique 'timeout'. -*/ -PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime timeout) -{ - PRStatus rv = PR_SUCCESS; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (PR_INTERVAL_NO_WAIT == timeout) - { - /* - ** This is a simple yield, nothing more, nothing less. - */ - PRIntn is; - PRThread *me = PR_GetCurrentThread(); - PRUintn pri = me->priority; - _PRCPU *cpu = _PR_MD_CURRENT_CPU(); - - if ( _PR_IS_NATIVE_THREAD(me) ) _PR_MD_YIELD(); - else - { - _PR_INTSOFF(is); - _PR_RUNQ_LOCK(cpu); - if (_PR_RUNQREADYMASK(cpu) >> pri) { - me->cpu = cpu; - me->state = _PR_RUNNABLE; - _PR_ADD_RUNQ(me, cpu, pri); - _PR_RUNQ_UNLOCK(cpu); - - PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: yielding")); - _PR_MD_SWITCH_CONTEXT(me); - PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: done")); - - _PR_FAST_INTSON(is); - } - else - { - _PR_RUNQ_UNLOCK(cpu); - _PR_INTSON(is); - } - } - } - else - { - /* - ** This is waiting for some finite period of time. - ** A thread in this state is interruptible (PR_Interrupt()), - ** but the lock and cvar used are local to the implementation - ** and not visible to the caller, therefore not notifiable. - */ - PRCondVar *cv; - PRIntervalTime timein; - - timein = PR_IntervalNow(); - cv = PR_NewCondVar(_pr_sleeplock); - PR_ASSERT(cv != NULL); - PR_Lock(_pr_sleeplock); - do - { - PRIntervalTime delta = PR_IntervalNow() - timein; - if (delta > timeout) break; - rv = PR_WaitCondVar(cv, timeout - delta); - } while (rv == PR_SUCCESS); - PR_Unlock(_pr_sleeplock); - PR_DestroyCondVar(cv); - } - return rv; -} - -PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thread) -{ - return thread->id; -} - -PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread) -{ - return (PRThreadPriority) thread->priority; -} - -PR_IMPLEMENT(PRThread *) PR_GetCurrentThread() -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - return _PR_MD_CURRENT_THREAD(); -} - -/* -** Set the interrupt flag for a thread. The thread will be unable to -** block in i/o functions when this happens. Also, any PR_Wait's in -** progress will be undone. The interrupt remains in force until -** PR_ClearInterrupt is called. -*/ -PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thread) -{ -#ifdef _PR_GLOBAL_THREADS_ONLY - PRCondVar *victim; - - _PR_THREAD_LOCK(thread); - thread->flags |= _PR_INTERRUPT; - victim = thread->wait.cvar; - _PR_THREAD_UNLOCK(thread); - if ((NULL != victim) && (!(thread->flags & _PR_INTERRUPT_BLOCKED))) { - int haveLock = (victim->lock->owner == _PR_MD_CURRENT_THREAD()); - - if (!haveLock) PR_Lock(victim->lock); - PR_NotifyAllCondVar(victim); - if (!haveLock) PR_Unlock(victim->lock); - } - return PR_SUCCESS; -#else /* ! _PR_GLOBAL_THREADS_ONLY */ - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSOFF(is); - - _PR_THREAD_LOCK(thread); - thread->flags |= _PR_INTERRUPT; - switch (thread->state) { - case _PR_COND_WAIT: - /* - * call is made with thread locked; - * on return lock is released - */ - if (!(thread->flags & _PR_INTERRUPT_BLOCKED)) - _PR_NotifyLockedThread(thread); - break; - case _PR_IO_WAIT: - /* - * Need to hold the thread lock when calling - * _PR_Unblock_IO_Wait(). On return lock is - * released. - */ -#if defined(XP_UNIX) || defined(WINNT) || defined(WIN16) - if (!(thread->flags & _PR_INTERRUPT_BLOCKED)) - _PR_Unblock_IO_Wait(thread); -#else - _PR_THREAD_UNLOCK(thread); -#endif - break; - case _PR_RUNNING: - case _PR_RUNNABLE: - case _PR_LOCK_WAIT: - default: - _PR_THREAD_UNLOCK(thread); - break; - } - if (!_PR_IS_NATIVE_THREAD(me)) - _PR_INTSON(is); - return PR_SUCCESS; -#endif /* _PR_GLOBAL_THREADS_ONLY */ -} - -/* -** Clear the interrupt flag for self. -*/ -PR_IMPLEMENT(void) PR_ClearInterrupt() -{ - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); - _PR_THREAD_LOCK(me); - me->flags &= ~_PR_INTERRUPT; - _PR_THREAD_UNLOCK(me); - if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); -} - -PR_IMPLEMENT(void) PR_BlockInterrupt() -{ - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); - _PR_THREAD_LOCK(me); - _PR_THREAD_BLOCK_INTERRUPT(me); - _PR_THREAD_UNLOCK(me); - if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); -} /* PR_BlockInterrupt */ - -PR_IMPLEMENT(void) PR_UnblockInterrupt() -{ - PRIntn is; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); - _PR_THREAD_LOCK(me); - _PR_THREAD_UNBLOCK_INTERRUPT(me); - _PR_THREAD_UNLOCK(me); - if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); -} /* PR_UnblockInterrupt */ - -/* -** Return the thread stack pointer of the given thread. -*/ -PR_IMPLEMENT(void *) PR_GetSP(PRThread *thread) -{ - return (void *)_PR_MD_GET_SP(thread); -} - -PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thread) -{ - return thread->environment; -} - -PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thread, void *env) -{ - thread->environment = env; -} - - -PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask) -{ -#ifdef HAVE_THREAD_AFFINITY - return _PR_MD_GETTHREADAFFINITYMASK(thread, mask); -#else - return 0; -#endif -} - -PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask ) -{ -#ifdef HAVE_THREAD_AFFINITY -#ifndef IRIX - return _PR_MD_SETTHREADAFFINITYMASK(thread, mask); -#else - return 0; -#endif -#else - return 0; -#endif -} - -/* This call is thread unsafe if another thread is calling SetConcurrency() - */ -PR_IMPLEMENT(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask) -{ -#ifdef HAVE_THREAD_AFFINITY - PRCList *qp; - extern PRUint32 _pr_cpu_affinity_mask; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - _pr_cpu_affinity_mask = mask; - - qp = _PR_CPUQ().next; - while(qp != &_PR_CPUQ()) { - _PRCPU *cpu; - - cpu = _PR_CPU_PTR(qp); - PR_SetThreadAffinityMask(cpu->thread, mask); - - qp = qp->next; - } -#endif - - return 0; -} - -PRUint32 _pr_recycleThreads = 0; -PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 count) -{ - _pr_recycleThreads = count; -} - -PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - return _PR_CreateThread(type, start, arg, priority, scope, state, - stackSize, _PR_GCABLE_THREAD); -} - -#ifdef SOLARIS -PR_IMPLEMENT(PRThread*) PR_CreateThreadBound(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRUintn priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize) -{ - return _PR_CreateThread(type, start, arg, priority, scope, state, - stackSize, _PR_BOUND_THREAD); -} -#endif - - -PR_IMPLEMENT(PRThread*) PR_AttachThreadGCAble( - PRThreadType type, PRThreadPriority priority, PRThreadStack *stack) -{ - /* $$$$ not sure how to finese this one */ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return NULL; -} - -PR_IMPLEMENT(void) PR_SetThreadGCAble() -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - PR_Lock(_pr_activeLock); - _PR_MD_CURRENT_THREAD()->flags |= _PR_GCABLE_THREAD; - PR_Unlock(_pr_activeLock); -} - -PR_IMPLEMENT(void) PR_ClearThreadGCAble() -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - PR_Lock(_pr_activeLock); - _PR_MD_CURRENT_THREAD()->flags &= (~_PR_GCABLE_THREAD); - PR_Unlock(_pr_activeLock); -} - -PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thread) -{ - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (_PR_IS_NATIVE_THREAD(thread)) { - return (thread->flags & _PR_BOUND_THREAD) ? PR_GLOBAL_BOUND_THREAD : - PR_GLOBAL_THREAD; - } else - return PR_LOCAL_THREAD; -} - -PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thread) -{ - return (thread->flags & _PR_SYSTEM) ? PR_SYSTEM_THREAD : PR_USER_THREAD; -} - -PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thread) -{ - return (NULL == thread->term) ? PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD; -} /* PR_GetThreadState */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prdump.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prdump.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prdump.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prdump.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#if defined(WIN95) -/* -** Some local variables report warnings on Win95 because the code paths -** using them are conditioned on HAVE_CUSTOME_USER_THREADS. -** The pragma suppresses the warning. -** -*/ -#pragma warning(disable : 4101) -#endif - -/* XXX use unbuffered nspr stdio */ - -PRFileDesc *_pr_dumpOut; - -PRUint32 _PR_DumpPrintf(PRFileDesc *fd, const char *fmt, ...) -{ - char buf[100]; - PRUint32 nb; - va_list ap; - - va_start(ap, fmt); - nb = PR_vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - PR_Write(fd, buf, nb); - - return nb; -} - -void _PR_DumpThread(PRFileDesc *fd, PRThread *thread) -{ - -#ifndef _PR_GLOBAL_THREADS_ONLY - _PR_DumpPrintf(fd, "%05d[%08p] pri=%2d flags=0x%02x", - thread->id, thread, thread->priority, thread->flags); - switch (thread->state) { - case _PR_RUNNABLE: - case _PR_RUNNING: - break; - case _PR_LOCK_WAIT: - _PR_DumpPrintf(fd, " lock=%p", thread->wait.lock); - break; - case _PR_COND_WAIT: - _PR_DumpPrintf(fd, " condvar=%p sleep=%lldms", - thread->wait.cvar, thread->sleep); - break; - case _PR_SUSPENDED: - _PR_DumpPrintf(fd, " suspended"); - break; - } - PR_Write(fd, "\n", 1); -#endif - - /* Now call dump routine */ - if (thread->dump) { - thread->dump(fd, thread, thread->dumpArg); - } -} - -static void DumpThreadQueue(PRFileDesc *fd, PRCList *list) -{ -#ifndef _PR_GLOBAL_THREADS_ONLY - PRCList *q; - - q = list->next; - while (q != list) { - PRThread *t = _PR_THREAD_PTR(q); - _PR_DumpThread(fd, t); - q = q->next; - } -#endif -} - -void _PR_DumpThreads(PRFileDesc *fd) -{ - PRThread *t; - PRIntn i; - - _PR_DumpPrintf(fd, "Current Thread:\n"); - t = _PR_MD_CURRENT_THREAD(); - _PR_DumpThread(fd, t); - - _PR_DumpPrintf(fd, "Runnable Threads:\n"); - for (i = 0; i < 32; i++) { - DumpThreadQueue(fd, &_PR_RUNQ(t->cpu)[i]); - } - - _PR_DumpPrintf(fd, "CondVar timed wait Threads:\n"); - DumpThreadQueue(fd, &_PR_SLEEPQ(t->cpu)); - - _PR_DumpPrintf(fd, "CondVar wait Threads:\n"); - DumpThreadQueue(fd, &_PR_PAUSEQ(t->cpu)); - - _PR_DumpPrintf(fd, "Suspended Threads:\n"); - DumpThreadQueue(fd, &_PR_SUSPENDQ(t->cpu)); -} - -PR_IMPLEMENT(void) PR_ShowStatus(void) -{ - PRIntn is; - - if ( _PR_MD_CURRENT_THREAD() - && !_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) _PR_INTSOFF(is); - _pr_dumpOut = _pr_stderr; - _PR_DumpThreads(_pr_dumpOut); - if ( _PR_MD_CURRENT_THREAD() - && !_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) _PR_FAST_INTSON(is); -} - -PR_IMPLEMENT(void) -PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg) -{ - thread->dump = dump; - thread->dumpArg = arg; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prmon.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prmon.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prmon.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prmon.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,199 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -/************************************************************************/ - -/* -** Create a new monitor. -*/ -PR_IMPLEMENT(PRMonitor*) PR_NewMonitor() -{ - PRMonitor *mon; - PRCondVar *cvar; - PRLock *lock; - - mon = PR_NEWZAP(PRMonitor); - if (mon) { - lock = PR_NewLock(); - if (!lock) { - PR_DELETE(mon); - return 0; - } - - cvar = PR_NewCondVar(lock); - if (!cvar) { - PR_DestroyLock(lock); - PR_DELETE(mon); - return 0; - } - mon->cvar = cvar; - mon->name = NULL; - } - return mon; -} - -PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name) -{ - PRMonitor* mon = PR_NewMonitor(); - if (mon) - mon->name = name; - return mon; -} - -/* -** Destroy a monitor. There must be no thread waiting on the monitor's -** condition variable. The caller is responsible for guaranteeing that the -** monitor is no longer in use. -*/ -PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon) -{ - PR_DestroyLock(mon->cvar->lock); - PR_DestroyCondVar(mon->cvar); - PR_DELETE(mon); -} - -/* -** Enter the lock associated with the monitor. -*/ -PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon) -{ - if (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) { - mon->entryCount++; - } else { - PR_Lock(mon->cvar->lock); - mon->entryCount = 1; - } -} - -/* -** Test and then enter the lock associated with the monitor if it's not -** already entered by some other thread. Return PR_FALSE if some other -** thread owned the lock at the time of the call. -*/ -PR_IMPLEMENT(PRBool) PR_TestAndEnterMonitor(PRMonitor *mon) -{ - if (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) { - mon->entryCount++; - return PR_TRUE; - } else { - if (PR_TestAndLock(mon->cvar->lock)) { - mon->entryCount = 1; - return PR_TRUE; - } - } - return PR_FALSE; -} - -/* -** Exit the lock associated with the monitor once. -*/ -PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon) -{ - if (mon->cvar->lock->owner != _PR_MD_CURRENT_THREAD()) { - return PR_FAILURE; - } - if (--mon->entryCount == 0) { - return PR_Unlock(mon->cvar->lock); - } - return PR_SUCCESS; -} - -/* -** Return the number of times that the current thread has entered the -** lock. Returns zero if the current thread has not entered the lock. -*/ -PR_IMPLEMENT(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon) -{ - return (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) ? - mon->entryCount : 0; -} - -/* -** If the current thread is in |mon|, this assertion is guaranteed to -** succeed. Otherwise, the behavior of this function is undefined. -*/ -PR_IMPLEMENT(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon) -{ - PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mon->cvar->lock); -} - -/* -** Wait for a notify on the condition variable. Sleep for "ticks" amount -** of time (if "tick" is 0 then the sleep is indefinite). While -** the thread is waiting it exits the monitors lock (as if it called -** PR_ExitMonitor as many times as it had called PR_EnterMonitor). When -** the wait has finished the thread regains control of the monitors lock -** with the same entry count as before the wait began. -** -** The thread waiting on the monitor will be resumed when the monitor is -** notified (assuming the thread is the next in line to receive the -** notify) or when the "ticks" elapses. -** -** Returns PR_FAILURE if the caller has not locked the lock associated -** with the condition variable. -** This routine can return PR_PENDING_INTERRUPT if the waiting thread -** has been interrupted. -*/ -PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks) -{ - PRUintn entryCount; - PRStatus status; - PRThread *me = _PR_MD_CURRENT_THREAD(); - - if (mon->cvar->lock->owner != me) return PR_FAILURE; - - entryCount = mon->entryCount; - mon->entryCount = 0; - - status = _PR_WaitCondVar(me, mon->cvar, mon->cvar->lock, ticks); - - mon->entryCount = entryCount; - - return status; -} - -/* -** Notify the highest priority thread waiting on the condition -** variable. If a thread is waiting on the condition variable (using -** PR_Wait) then it is awakened and begins waiting on the monitor's lock. -*/ -PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - if (mon->cvar->lock->owner != me) return PR_FAILURE; - PR_NotifyCondVar(mon->cvar); - return PR_SUCCESS; -} - -/* -** Notify all of the threads waiting on the condition variable. All of -** threads are notified in turn. The highest priority thread will -** probably acquire the monitor first when the monitor is exited. -*/ -PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon) -{ - PRThread *me = _PR_MD_CURRENT_THREAD(); - if (mon->cvar->lock->owner != me) return PR_FAILURE; - PR_NotifyAllCondVar(mon->cvar); - return PR_SUCCESS; -} - -/************************************************************************/ - -PRUint32 _PR_MonitorToString(PRMonitor *mon, char *buf, PRUint32 buflen) -{ - PRUint32 nb; - - if (mon->cvar->lock->owner) { - nb = PR_snprintf(buf, buflen, "[%p] owner=%d[%p] count=%ld", - mon, mon->cvar->lock->owner->id, - mon->cvar->lock->owner, mon->entryCount); - } else { - nb = PR_snprintf(buf, buflen, "[%p]", mon); - } - return nb; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prrwlock.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prrwlock.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prrwlock.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prrwlock.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,480 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" - -#include - -#if defined(HPUX) && defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) - -#include -#define HAVE_UNIX98_RWLOCK -#define RWLOCK_T pthread_rwlock_t -#define RWLOCK_INIT(lock) pthread_rwlock_init(lock, NULL) -#define RWLOCK_DESTROY(lock) pthread_rwlock_destroy(lock) -#define RWLOCK_RDLOCK(lock) pthread_rwlock_rdlock(lock) -#define RWLOCK_WRLOCK(lock) pthread_rwlock_wrlock(lock) -#define RWLOCK_UNLOCK(lock) pthread_rwlock_unlock(lock) - -#elif defined(SOLARIS) && (defined(_PR_PTHREADS) \ - || defined(_PR_GLOBAL_THREADS_ONLY)) - -#include -#define HAVE_UI_RWLOCK -#define RWLOCK_T rwlock_t -#define RWLOCK_INIT(lock) rwlock_init(lock, USYNC_THREAD, NULL) -#define RWLOCK_DESTROY(lock) rwlock_destroy(lock) -#define RWLOCK_RDLOCK(lock) rw_rdlock(lock) -#define RWLOCK_WRLOCK(lock) rw_wrlock(lock) -#define RWLOCK_UNLOCK(lock) rw_unlock(lock) - -#endif - -/* - * Reader-writer lock - */ -struct PRRWLock { - char *rw_name; /* lock name */ - PRUint32 rw_rank; /* rank of the lock */ - -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) - RWLOCK_T rw_lock; -#else - PRLock *rw_lock; - PRInt32 rw_lock_cnt; /* == 0, if unlocked */ - /* == -1, if write-locked */ - /* > 0 , # of read locks */ - PRUint32 rw_reader_cnt; /* number of waiting readers */ - PRUint32 rw_writer_cnt; /* number of waiting writers */ - PRCondVar *rw_reader_waitq; /* cvar for readers */ - PRCondVar *rw_writer_waitq; /* cvar for writers */ -#ifdef DEBUG - PRThread *rw_owner; /* lock owner for write-lock */ -#endif -#endif -}; - -#ifdef DEBUG -#define _PR_RWLOCK_RANK_ORDER_DEBUG /* enable deadlock detection using - rank-order for locks - */ -#endif - -#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG - -static PRUintn pr_thread_rwlock_key; /* TPD key for lock stack */ -static PRUintn pr_thread_rwlock_alloc_failed; - -#define _PR_RWLOCK_RANK_ORDER_LIMIT 10 - -typedef struct thread_rwlock_stack { - PRInt32 trs_index; /* top of stack */ - PRRWLock *trs_stack[_PR_RWLOCK_RANK_ORDER_LIMIT]; /* stack of lock - pointers */ - -} thread_rwlock_stack; - -static void _PR_SET_THREAD_RWLOCK_RANK(PRRWLock *rwlock); -static PRUint32 _PR_GET_THREAD_RWLOCK_RANK(void); -static void _PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock); -static void _PR_RELEASE_LOCK_STACK(void *lock_stack); - -#endif - -/* - * Reader/Writer Locks - */ - -/* - * PR_NewRWLock - * Create a reader-writer lock, with the given lock rank and lock name - * - */ - -PR_IMPLEMENT(PRRWLock *) -PR_NewRWLock(PRUint32 lock_rank, const char *lock_name) -{ - PRRWLock *rwlock; -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) - int err; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - rwlock = PR_NEWZAP(PRRWLock); - if (rwlock == NULL) - return NULL; - - rwlock->rw_rank = lock_rank; - if (lock_name != NULL) { - rwlock->rw_name = (char*) PR_Malloc(strlen(lock_name) + 1); - if (rwlock->rw_name == NULL) { - PR_DELETE(rwlock); - return(NULL); - } - strcpy(rwlock->rw_name, lock_name); - } else { - rwlock->rw_name = NULL; - } - -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) - err = RWLOCK_INIT(&rwlock->rw_lock); - if (err != 0) { - PR_SetError(PR_UNKNOWN_ERROR, err); - PR_Free(rwlock->rw_name); - PR_DELETE(rwlock); - return NULL; - } - return rwlock; -#else - rwlock->rw_lock = PR_NewLock(); - if (rwlock->rw_lock == NULL) { - goto failed; - } - rwlock->rw_reader_waitq = PR_NewCondVar(rwlock->rw_lock); - if (rwlock->rw_reader_waitq == NULL) { - goto failed; - } - rwlock->rw_writer_waitq = PR_NewCondVar(rwlock->rw_lock); - if (rwlock->rw_writer_waitq == NULL) { - goto failed; - } - rwlock->rw_reader_cnt = 0; - rwlock->rw_writer_cnt = 0; - rwlock->rw_lock_cnt = 0; - return rwlock; - -failed: - if (rwlock->rw_reader_waitq != NULL) { - PR_DestroyCondVar(rwlock->rw_reader_waitq); - } - if (rwlock->rw_lock != NULL) { - PR_DestroyLock(rwlock->rw_lock); - } - PR_Free(rwlock->rw_name); - PR_DELETE(rwlock); - return NULL; -#endif -} - -/* -** Destroy the given RWLock "lock". -*/ -PR_IMPLEMENT(void) -PR_DestroyRWLock(PRRWLock *rwlock) -{ -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) - int err; - err = RWLOCK_DESTROY(&rwlock->rw_lock); - PR_ASSERT(err == 0); -#else - PR_ASSERT(rwlock->rw_reader_cnt == 0); - PR_DestroyCondVar(rwlock->rw_reader_waitq); - PR_DestroyCondVar(rwlock->rw_writer_waitq); - PR_DestroyLock(rwlock->rw_lock); -#endif - if (rwlock->rw_name != NULL) - PR_Free(rwlock->rw_name); - PR_DELETE(rwlock); -} - -/* -** Read-lock the RWLock. -*/ -PR_IMPLEMENT(void) -PR_RWLock_Rlock(PRRWLock *rwlock) -{ -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) -int err; -#endif - -#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG - /* - * assert that rank ordering is not violated; the rank of 'rwlock' should - * be equal to or greater than the highest rank of all the locks held by - * the thread. - */ - PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || - (rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK())); -#endif - -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) - err = RWLOCK_RDLOCK(&rwlock->rw_lock); - PR_ASSERT(err == 0); -#else - PR_Lock(rwlock->rw_lock); - /* - * wait if write-locked or if a writer is waiting; preference for writers - */ - while ((rwlock->rw_lock_cnt < 0) || - (rwlock->rw_writer_cnt > 0)) { - rwlock->rw_reader_cnt++; - PR_WaitCondVar(rwlock->rw_reader_waitq, PR_INTERVAL_NO_TIMEOUT); - rwlock->rw_reader_cnt--; - } - /* - * Increment read-lock count - */ - rwlock->rw_lock_cnt++; - - PR_Unlock(rwlock->rw_lock); -#endif - -#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG - /* - * update thread's lock rank - */ - _PR_SET_THREAD_RWLOCK_RANK(rwlock); -#endif -} - -/* -** Write-lock the RWLock. -*/ -PR_IMPLEMENT(void) -PR_RWLock_Wlock(PRRWLock *rwlock) -{ -#if defined(DEBUG) -PRThread *me = PR_GetCurrentThread(); -#endif -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) -int err; -#endif - -#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG - /* - * assert that rank ordering is not violated; the rank of 'rwlock' should - * be equal to or greater than the highest rank of all the locks held by - * the thread. - */ - PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || - (rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK())); -#endif - -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) - err = RWLOCK_WRLOCK(&rwlock->rw_lock); - PR_ASSERT(err == 0); -#else - PR_Lock(rwlock->rw_lock); - /* - * wait if read locked - */ - while (rwlock->rw_lock_cnt != 0) { - rwlock->rw_writer_cnt++; - PR_WaitCondVar(rwlock->rw_writer_waitq, PR_INTERVAL_NO_TIMEOUT); - rwlock->rw_writer_cnt--; - } - /* - * apply write lock - */ - rwlock->rw_lock_cnt--; - PR_ASSERT(rwlock->rw_lock_cnt == -1); -#ifdef DEBUG - PR_ASSERT(me != NULL); - rwlock->rw_owner = me; -#endif - PR_Unlock(rwlock->rw_lock); -#endif - -#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG - /* - * update thread's lock rank - */ - _PR_SET_THREAD_RWLOCK_RANK(rwlock); -#endif -} - -/* -** Unlock the RW lock. -*/ -PR_IMPLEMENT(void) -PR_RWLock_Unlock(PRRWLock *rwlock) -{ -#if defined(DEBUG) -PRThread *me = PR_GetCurrentThread(); -#endif -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) -int err; -#endif - -#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) - err = RWLOCK_UNLOCK(&rwlock->rw_lock); - PR_ASSERT(err == 0); -#else - PR_Lock(rwlock->rw_lock); - /* - * lock must be read or write-locked - */ - PR_ASSERT(rwlock->rw_lock_cnt != 0); - if (rwlock->rw_lock_cnt > 0) { - - /* - * decrement read-lock count - */ - rwlock->rw_lock_cnt--; - if (rwlock->rw_lock_cnt == 0) { - /* - * lock is not read-locked anymore; wakeup a waiting writer - */ - if (rwlock->rw_writer_cnt > 0) - PR_NotifyCondVar(rwlock->rw_writer_waitq); - } - } else { - PR_ASSERT(rwlock->rw_lock_cnt == -1); - - rwlock->rw_lock_cnt = 0; -#ifdef DEBUG - PR_ASSERT(rwlock->rw_owner == me); - rwlock->rw_owner = NULL; -#endif - /* - * wakeup a writer, if present; preference for writers - */ - if (rwlock->rw_writer_cnt > 0) - PR_NotifyCondVar(rwlock->rw_writer_waitq); - /* - * else, wakeup all readers, if any - */ - else if (rwlock->rw_reader_cnt > 0) - PR_NotifyAllCondVar(rwlock->rw_reader_waitq); - } - PR_Unlock(rwlock->rw_lock); -#endif - -#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG - /* - * update thread's lock rank - */ - _PR_UNSET_THREAD_RWLOCK_RANK(rwlock); -#endif - return; -} - -#ifndef _PR_RWLOCK_RANK_ORDER_DEBUG - -void _PR_InitRWLocks(void) { } - -#else - -void _PR_InitRWLocks(void) -{ - /* - * allocated thread-private-data index for rwlock list - */ - if (PR_NewThreadPrivateIndex(&pr_thread_rwlock_key, - _PR_RELEASE_LOCK_STACK) == PR_FAILURE) { - pr_thread_rwlock_alloc_failed = 1; - return; - } -} - -/* - * _PR_SET_THREAD_RWLOCK_RANK - * Set a thread's lock rank, which is the highest of the ranks of all - * the locks held by the thread. Pointers to the locks are added to a - * per-thread list, which is anchored off a thread-private data key. - */ - -static void -_PR_SET_THREAD_RWLOCK_RANK(PRRWLock *rwlock) -{ -thread_rwlock_stack *lock_stack; -PRStatus rv; - - /* - * allocate a lock stack - */ - if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL) { - lock_stack = (thread_rwlock_stack *) - PR_CALLOC(1 * sizeof(thread_rwlock_stack)); - if (lock_stack) { - rv = PR_SetThreadPrivate(pr_thread_rwlock_key, lock_stack); - if (rv == PR_FAILURE) { - PR_DELETE(lock_stack); - pr_thread_rwlock_alloc_failed = 1; - return; - } - } else { - pr_thread_rwlock_alloc_failed = 1; - return; - } - } - /* - * add rwlock to lock stack, if limit is not exceeded - */ - if (lock_stack) { - if (lock_stack->trs_index < _PR_RWLOCK_RANK_ORDER_LIMIT) - lock_stack->trs_stack[lock_stack->trs_index++] = rwlock; - } -} - -static void -_PR_RELEASE_LOCK_STACK(void *lock_stack) -{ - PR_ASSERT(lock_stack); - PR_DELETE(lock_stack); -} - -/* - * _PR_GET_THREAD_RWLOCK_RANK - * - * return thread's lock rank. If thread-private-data for the lock - * stack is not allocated, return PR_RWLOCK_RANK_NONE. - */ - -static PRUint32 -_PR_GET_THREAD_RWLOCK_RANK(void) -{ - thread_rwlock_stack *lock_stack; - - if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL) - return (PR_RWLOCK_RANK_NONE); - else - return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank); -} - -/* - * _PR_UNSET_THREAD_RWLOCK_RANK - * - * remove the rwlock from the lock stack. Since locks may not be - * unlocked in a FIFO order, the entire lock stack is searched. - */ - -static void -_PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock) -{ - thread_rwlock_stack *lock_stack; - int new_index = 0, index, done = 0; - - lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key); - - PR_ASSERT(lock_stack != NULL); - - index = lock_stack->trs_index - 1; - while (index-- >= 0) { - if ((lock_stack->trs_stack[index] == rwlock) && !done) { - /* - * reset the slot for rwlock - */ - lock_stack->trs_stack[index] = NULL; - done = 1; - } - /* - * search for the lowest-numbered empty slot, above which there are - * no non-empty slots - */ - if ((lock_stack->trs_stack[index] != NULL) && !new_index) - new_index = index + 1; - if (done && new_index) - break; - } - /* - * set top of stack to highest numbered empty slot - */ - lock_stack->trs_index = new_index; - -} - -#endif /* _PR_RWLOCK_RANK_ORDER_DEBUG */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prsem.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prsem.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prsem.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prsem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "primpl.h" -#include "obsolete/prsem.h" - -/************************************************************************/ - -/* -** Create a new semaphore. -*/ -PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value) -{ - PRSemaphore *sem; - PRCondVar *cvar; - PRLock *lock; - - sem = PR_NEWZAP(PRSemaphore); - if (sem) { -#ifdef HAVE_CVAR_BUILT_ON_SEM - _PR_MD_NEW_SEM(&sem->md, value); -#else - lock = PR_NewLock(); - if (!lock) { - PR_DELETE(sem); - return NULL; - } - - cvar = PR_NewCondVar(lock); - if (!cvar) { - PR_DestroyLock(lock); - PR_DELETE(sem); - return NULL; - } - sem->cvar = cvar; - sem->count = value; -#endif - } - return sem; -} - -/* -** Destroy a semaphore. There must be no thread waiting on the semaphore. -** The caller is responsible for guaranteeing that the semaphore is -** no longer in use. -*/ -PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *sem) -{ -#ifdef HAVE_CVAR_BUILT_ON_SEM - _PR_MD_DESTROY_SEM(&sem->md); -#else - PR_ASSERT(sem->waiters == 0); - - PR_DestroyLock(sem->cvar->lock); - PR_DestroyCondVar(sem->cvar); -#endif - PR_DELETE(sem); -} - -/* -** Wait on a Semaphore. -** -** This routine allows a calling thread to wait or proceed depending upon the -** state of the semahore sem. The thread can proceed only if the counter value -** of the semaphore sem is currently greater than 0. If the value of semaphore -** sem is positive, it is decremented by one and the routine returns immediately -** allowing the calling thread to continue. If the value of semaphore sem is 0, -** the calling thread blocks awaiting the semaphore to be released by another -** thread. -** -** This routine can return PR_PENDING_INTERRUPT if the waiting thread -** has been interrupted. -*/ -PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *sem) -{ - PRStatus status = PR_SUCCESS; - -#ifdef HAVE_CVAR_BUILT_ON_SEM - return _PR_MD_WAIT_SEM(&sem->md); -#else - PR_Lock(sem->cvar->lock); - while (sem->count == 0) { - sem->waiters++; - status = PR_WaitCondVar(sem->cvar, PR_INTERVAL_NO_TIMEOUT); - sem->waiters--; - if (status != PR_SUCCESS) - break; - } - if (status == PR_SUCCESS) - sem->count--; - PR_Unlock(sem->cvar->lock); -#endif - - return (status); -} - -/* -** This routine increments the counter value of the semaphore. If other threads -** are blocked for the semaphore, then the scheduler will determine which ONE -** thread will be unblocked. -*/ -PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *sem) -{ -#ifdef HAVE_CVAR_BUILT_ON_SEM - _PR_MD_POST_SEM(&sem->md); -#else - PR_Lock(sem->cvar->lock); - if (sem->waiters) - PR_NotifyCondVar(sem->cvar); - sem->count++; - PR_Unlock(sem->cvar->lock); -#endif -} - -#if DEBUG -/* -** Returns the value of the semaphore referenced by sem without affecting -** the state of the semaphore. The value represents the semaphore vaule -** at the time of the call, but may not be the actual value when the -** caller inspects it. (FOR DEBUGGING ONLY) -*/ -PR_IMPLEMENT(PRUintn) PR_GetValueSem(PRSemaphore *sem) -{ - PRUintn rv; - -#ifdef HAVE_CVAR_BUILT_ON_SEM - rv = _PR_MD_GET_VALUE_SEM(&sem->md); -#else - PR_Lock(sem->cvar->lock); - rv = sem->count; - PR_Unlock(sem->cvar->lock); -#endif - - return rv; -} -#endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prtpd.c nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prtpd.c --- nspr-4.9.5/mozilla/nsprpub/pr/src/threads/prtpd.c 2012-03-06 13:14:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/src/threads/prtpd.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Thread Private Data -** -** There is an aribitrary limit on the number of keys that will be allocated -** by the runtime. It's largish, so it is intended to be a sanity check, not -** an impediment. -** -** There is a counter, initialized to zero and incremented every time a -** client asks for a new key, that holds the high water mark for keys. All -** threads logically have the same high water mark and are permitted to -** ask for TPD up to that key value. -** -** The vector to hold the TPD are allocated when PR_SetThreadPrivate() is -** called. The size of the vector will be some value greater than or equal -** to the current high water mark. Each thread has its own TPD length and -** vector. -** -** Threads that get private data for keys they have not set (or perhaps -** don't even exist for that thread) get a NULL return. If the key is -** beyond the high water mark, an error will be returned. -*/ - -/* -** As of this time, BeOS has its own TPD implementation. Integrating -** this standard one is a TODO for anyone with a bit of spare time on -** their hand. For now, we just #ifdef out this whole file and use -** the routines in pr/src/btthreads/ -*/ - -#ifndef XP_BEOS - -#include "primpl.h" - -#include - -#if defined(WIN95) -/* -** Some local variables report warnings on Win95 because the code paths -** using them are conditioned on HAVE_CUSTOME_USER_THREADS. -** The pragma suppresses the warning. -** -*/ -#pragma warning(disable : 4101) -#endif - -#define _PR_TPD_LIMIT 128 /* arbitary limit on the TPD slots */ -static PRInt32 _pr_tpd_length = 0; /* current length of destructor vector */ -static PRInt32 _pr_tpd_highwater = 0; /* next TPD key to be assigned */ -static PRThreadPrivateDTOR *_pr_tpd_destructors = NULL; - /* the destructors are associated with - the keys, therefore asserting that - the TPD key depicts the data's 'type' */ - -/* -** Initialize the thread private data manipulation -*/ -void _PR_InitTPD(void) -{ - _pr_tpd_destructors = (PRThreadPrivateDTOR*) - PR_CALLOC(_PR_TPD_LIMIT * sizeof(PRThreadPrivateDTOR*)); - PR_ASSERT(NULL != _pr_tpd_destructors); - _pr_tpd_length = _PR_TPD_LIMIT; -} - -/* -** Clean up the thread private data manipulation -*/ -void _PR_CleanupTPD(void) -{ -} /* _PR_CleanupTPD */ - -/* -** This routine returns a new index for per-thread-private data table. -** The index is visible to all threads within a process. This index can -** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines -** to save and retrieve data associated with the index for a thread. -** -** The index independently maintains specific values for each binding thread. -** A thread can only get access to its own thread-specific-data. -** -** Upon a new index return the value associated with the index for all threads -** is NULL, and upon thread creation the value associated with all indices for -** that thread is NULL. -** -** "dtor" is the destructor function to invoke when the private -** data is set or destroyed -** -** Returns PR_FAILURE if the total number of indices will exceed the maximun -** allowed. -*/ - -PR_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndex( - PRUintn *newIndex, PRThreadPrivateDTOR dtor) -{ - PRStatus rv; - PRInt32 index; - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - PR_ASSERT(NULL != newIndex); - PR_ASSERT(NULL != _pr_tpd_destructors); - - index = PR_ATOMIC_INCREMENT(&_pr_tpd_highwater) - 1; /* allocate index */ - if (_PR_TPD_LIMIT <= index) - { - PR_SetError(PR_TPD_RANGE_ERROR, 0); - rv = PR_FAILURE; /* that's just wrong */ - } - else - { - _pr_tpd_destructors[index] = dtor; /* record destructor @index */ - *newIndex = (PRUintn)index; /* copy into client's location */ - rv = PR_SUCCESS; /* that's okay */ - } - - return rv; -} - -/* -** Define some per-thread-private data. -** "index" is an index into the per-thread private data table -** "priv" is the per-thread-private data -** -** If the per-thread private data table has a previously registered -** destructor function and a non-NULL per-thread-private data value, -** the destructor function is invoked. -** -** This can return PR_FAILURE if index is invalid (ie., beyond the current -** high water mark) or memory is insufficient to allocate an exanded vector. -*/ - -PR_IMPLEMENT(PRStatus) PR_SetThreadPrivate(PRUintn index, void *priv) -{ - PRThread *self = PR_GetCurrentThread(); - - /* - ** The index being set might not have a sufficient vector in this - ** thread. But if the index has been allocated, it's okay to go - ** ahead and extend this one now. - */ - if ((index >= _PR_TPD_LIMIT) || (index >= _pr_tpd_highwater)) - { - PR_SetError(PR_TPD_RANGE_ERROR, 0); - return PR_FAILURE; - } - - PR_ASSERT(((NULL == self->privateData) && (0 == self->tpdLength)) - || ((NULL != self->privateData) && (0 != self->tpdLength))); - - if ((NULL == self->privateData) || (self->tpdLength <= index)) - { - void *extension = PR_CALLOC(_pr_tpd_length * sizeof(void*)); - if (NULL == extension) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return PR_FAILURE; - } - if (self->privateData) { - (void)memcpy( - extension, self->privateData, - self->tpdLength * sizeof(void*)); - PR_DELETE(self->privateData); - } - self->tpdLength = _pr_tpd_length; - self->privateData = (void**)extension; - } - /* - ** There wasn't much chance of having to call the destructor - ** unless the slot already existed. - */ - else if (self->privateData[index] && _pr_tpd_destructors[index]) - { - void *data = self->privateData[index]; - self->privateData[index] = NULL; - (*_pr_tpd_destructors[index])(data); - } - - PR_ASSERT(index < self->tpdLength); - self->privateData[index] = priv; - - return PR_SUCCESS; -} - -/* -** Recover the per-thread-private data for the current thread. "index" is -** the index into the per-thread private data table. -** -** The returned value may be NULL which is indistinguishable from an error -** condition. -** -*/ - -PR_IMPLEMENT(void*) PR_GetThreadPrivate(PRUintn index) -{ - PRThread *self = PR_GetCurrentThread(); - void *tpd = ((NULL == self->privateData) || (index >= self->tpdLength)) ? - NULL : self->privateData[index]; - - return tpd; -} - -/* -** Destroy the thread's private data, if any exists. This is called at -** thread termination time only. There should be no threading issues -** since this is being called by the thread itself. -*/ -void _PR_DestroyThreadPrivate(PRThread* self) -{ -#define _PR_TPD_DESTRUCTOR_ITERATIONS 4 - - if (NULL != self->privateData) /* we have some */ - { - PRBool clean; - PRUint32 index; - PRInt32 passes = _PR_TPD_DESTRUCTOR_ITERATIONS; - PR_ASSERT(0 != self->tpdLength); - do - { - clean = PR_TRUE; - for (index = 0; index < self->tpdLength; ++index) - { - void *priv = self->privateData[index]; /* extract */ - if (NULL != priv) /* we have data at this index */ - { - if (NULL != _pr_tpd_destructors[index]) - { - self->privateData[index] = NULL; /* precondition */ - (*_pr_tpd_destructors[index])(priv); /* destroy */ - clean = PR_FALSE; /* unknown side effects */ - } - } - } - } while ((--passes > 0) && !clean); /* limit # of passes */ - /* - ** We give up after a fixed number of passes. Any non-NULL - ** thread-private data value with a registered destructor - ** function is not destroyed. - */ - memset(self->privateData, 0, self->tpdLength * sizeof(void*)); - } -} /* _PR_DestroyThreadPrivate */ - -#endif /* !XP_BEOS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/accept.c nspr-4.10.7/mozilla/nsprpub/pr/tests/accept.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/accept.c 2012-03-06 13:14:23.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/accept.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,487 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1996 - Netscape Communications Corporation -** -** Name: accept.c -** -** Description: Run accept() sucessful connection tests. -** -** Modification History: -** 04-Jun-97 AGarcia - Reconvert test file to return a 0 for PASS and a 1 for FAIL -** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** 12-June-97 Revert to return code 0 and 1. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ - -#include "nspr.h" -#include "prpriv.h" - -#include -#include - -#include "plgetopt.h" -#include "plerror.h" - -#define BASE_PORT 10000 - -#define CLIENT_DATA 128 - -#define ACCEPT_NORMAL 0x1 -#define ACCEPT_FAST 0x2 -#define ACCEPT_READ 0x3 -#define ACCEPT_READ_FAST 0x4 -#define ACCEPT_READ_FAST_CB 0x5 - -#define CLIENT_NORMAL 0x1 -#define CLIENT_TIMEOUT_ACCEPT 0x2 -#define CLIENT_TIMEOUT_SEND 0x3 - -#define SERVER_MAX_BIND_COUNT 100 - -#if defined(XP_OS2) || defined(SYMBIAN) -#define TIMEOUTSECS 10 -#else -#define TIMEOUTSECS 2 -#endif -PRIntervalTime timeoutTime; - -static PRInt32 count = 1; -static PRFileDesc *output; -static PRNetAddr serverAddr; -static PRThreadScope thread_scope = PR_LOCAL_THREAD; -static PRInt32 clientCommand; -static PRInt32 iterations; -static PRStatus rv; -static PRFileDesc *listenSock; -static PRFileDesc *clientSock = NULL; -static PRNetAddr listenAddr; -static PRNetAddr clientAddr; -static PRThread *clientThread; -static PRNetAddr *raddr; -static char buf[4096 + 2*sizeof(PRNetAddr) + 32]; -static PRInt32 status; -static PRInt32 bytesRead; - -PRIntn failed_already=0; -PRIntn debug_mode; - -void Test_Assert(const char *msg, const char *file, PRIntn line) -{ - failed_already=1; - if (debug_mode) { - PR_fprintf(output, "@%s:%d ", file, line); - PR_fprintf(output, msg); - } -} /* Test_Assert */ - -#define TEST_ASSERT(expr) \ - if (!(expr)) Test_Assert(#expr, __FILE__, __LINE__) - -#ifdef WINNT -#define CALLBACK_MAGIC 0x12345678 - -void timeout_callback(void *magic) -{ - TEST_ASSERT(magic == (void *)CALLBACK_MAGIC); - if (debug_mode) - PR_fprintf(output, "timeout callback called okay\n"); -} -#endif - - -static void PR_CALLBACK -ClientThread(void *_action) -{ - PRInt32 action = * (PRInt32 *) _action; - PRInt32 iterations = count; - PRFileDesc *sock = NULL; - - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = listenAddr.inet.port; - serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - - for (; iterations--;) { - PRInt32 rv; - char buf[CLIENT_DATA]; - - memset(buf, 0xaf, sizeof(buf)); /* initialize with arbitrary data */ - sock = PR_NewTCPSocket(); - if (!sock) { - if (!debug_mode) - failed_already=1; - else - PR_fprintf(output, "client: unable to create socket\n"); - return; - } - - if (action != CLIENT_TIMEOUT_ACCEPT) { - - if ((rv = PR_Connect(sock, &serverAddr, - timeoutTime)) < 0) { - if (!debug_mode) - failed_already=1; - else - PR_fprintf(output, - "client: unable to connect to server (%ld, %ld, %ld, %ld)\n", - iterations, rv, PR_GetError(), PR_GetOSError()); - goto ErrorExit; - } - - if (action != CLIENT_TIMEOUT_SEND) { - if ((rv = PR_Send(sock, buf, CLIENT_DATA, - 0, timeoutTime))< 0) { - if (!debug_mode) - failed_already=1; - else - PR_fprintf(output, - "client: unable to send to server (%d, %ld, %ld)\n", - CLIENT_DATA, rv, PR_GetError()); - goto ErrorExit; - } - } else { - PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1)); - } - } else { - PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1)); - } - if (debug_mode) - PR_fprintf(output, "."); - PR_Close(sock); - sock = NULL; - } - if (debug_mode) - PR_fprintf(output, "\n"); - -ErrorExit: - if (sock != NULL) - PR_Close(sock); -} - - -static void -RunTest(PRInt32 acceptType, PRInt32 clientAction) -{ -int i; - - /* First bind to the socket */ - listenSock = PR_NewTCPSocket(); - if (!listenSock) { - failed_already=1; - if (debug_mode) - PR_fprintf(output, "unable to create listen socket\n"); - return; - } - memset(&listenAddr, 0 , sizeof(listenAddr)); - listenAddr.inet.family = PR_AF_INET; - listenAddr.inet.port = PR_htons(BASE_PORT); - listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY); - /* - * try a few times to bind server's address, if addresses are in - * use - */ - i = 0; - while (PR_Bind(listenSock, &listenAddr) == PR_FAILURE) { - if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { - listenAddr.inet.port += 2; - if (i++ < SERVER_MAX_BIND_COUNT) - continue; - } - failed_already=1; - if (debug_mode) - PR_fprintf(output,"accept: ERROR - PR_Bind failed\n"); - return; - } - - - rv = PR_Listen(listenSock, 100); - if (rv == PR_FAILURE) { - failed_already=1; - if (debug_mode) - PR_fprintf(output, "unable to listen\n"); - return; - } - - clientCommand = clientAction; - clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread, - (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 0); - if (!clientThread) { - failed_already=1; - if (debug_mode) - PR_fprintf(output, "error creating client thread\n"); - return; - } - - iterations = count; - for (;iterations--;) { - switch (acceptType) { - case ACCEPT_NORMAL: - clientSock = PR_Accept(listenSock, &clientAddr, - timeoutTime); - switch(clientAction) { - case CLIENT_TIMEOUT_ACCEPT: - TEST_ASSERT(clientSock == 0); - TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); - break; - case CLIENT_NORMAL: - TEST_ASSERT(clientSock); - bytesRead = PR_Recv(clientSock, - buf, CLIENT_DATA, 0, timeoutTime); - TEST_ASSERT(bytesRead == CLIENT_DATA); - break; - case CLIENT_TIMEOUT_SEND: - TEST_ASSERT(clientSock); - bytesRead = PR_Recv(clientSock, - buf, CLIENT_DATA, 0, timeoutTime); - TEST_ASSERT(bytesRead == -1); - TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); - break; - } - break; - case ACCEPT_READ: - status = PR_AcceptRead(listenSock, &clientSock, - &raddr, buf, CLIENT_DATA, timeoutTime); - switch(clientAction) { - case CLIENT_TIMEOUT_ACCEPT: - /* Invalid test case */ - TEST_ASSERT(0); - break; - case CLIENT_NORMAL: - TEST_ASSERT(clientSock); - TEST_ASSERT(status == CLIENT_DATA); - break; - case CLIENT_TIMEOUT_SEND: - TEST_ASSERT(status == -1); - TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); - break; - } - break; -#ifdef WINNT - case ACCEPT_FAST: - clientSock = PR_NTFast_Accept(listenSock, - &clientAddr, timeoutTime); - switch(clientAction) { - case CLIENT_TIMEOUT_ACCEPT: - TEST_ASSERT(clientSock == 0); - if (debug_mode) - PR_fprintf(output, "PR_GetError is %ld\n", PR_GetError()); - TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); - break; - case CLIENT_NORMAL: - TEST_ASSERT(clientSock); - bytesRead = PR_Recv(clientSock, - buf, CLIENT_DATA, 0, timeoutTime); - TEST_ASSERT(bytesRead == CLIENT_DATA); - break; - case CLIENT_TIMEOUT_SEND: - TEST_ASSERT(clientSock); - bytesRead = PR_Recv(clientSock, - buf, CLIENT_DATA, 0, timeoutTime); - TEST_ASSERT(bytesRead == -1); - TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); - break; - } - break; - break; - case ACCEPT_READ_FAST: - status = PR_NTFast_AcceptRead(listenSock, - &clientSock, &raddr, buf, 4096, timeoutTime); - switch(clientAction) { - case CLIENT_TIMEOUT_ACCEPT: - /* Invalid test case */ - TEST_ASSERT(0); - break; - case CLIENT_NORMAL: - TEST_ASSERT(clientSock); - TEST_ASSERT(status == CLIENT_DATA); - break; - case CLIENT_TIMEOUT_SEND: - TEST_ASSERT(clientSock == NULL); - TEST_ASSERT(status == -1); - TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); - break; - } - break; - case ACCEPT_READ_FAST_CB: - status = PR_NTFast_AcceptRead_WithTimeoutCallback( - listenSock, &clientSock, &raddr, buf, 4096, - timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC); - switch(clientAction) { - case CLIENT_TIMEOUT_ACCEPT: - /* Invalid test case */ - TEST_ASSERT(0); - break; - case CLIENT_NORMAL: - TEST_ASSERT(clientSock); - TEST_ASSERT(status == CLIENT_DATA); - break; - case CLIENT_TIMEOUT_SEND: - if (debug_mode) - PR_fprintf(output, "clientSock = 0x%8.8lx\n", clientSock); - TEST_ASSERT(clientSock == NULL); - TEST_ASSERT(status == -1); - TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); - break; - } - break; -#endif - } - if (clientSock != NULL) { - PR_Close(clientSock); - clientSock = NULL; - } - } - PR_Close(listenSock); - - PR_JoinThread(clientThread); -} - - -void AcceptUpdatedTest(void) -{ - RunTest(ACCEPT_NORMAL, CLIENT_NORMAL); -} -void AcceptNotUpdatedTest(void) -{ - RunTest(ACCEPT_FAST, CLIENT_NORMAL); -} -void AcceptReadTest(void) -{ - RunTest(ACCEPT_READ, CLIENT_NORMAL); -} -void AcceptReadNotUpdatedTest(void) -{ - RunTest(ACCEPT_READ_FAST, CLIENT_NORMAL); -} -void AcceptReadCallbackTest(void) -{ - RunTest(ACCEPT_READ_FAST_CB, CLIENT_NORMAL); -} - -void TimeoutAcceptUpdatedTest(void) -{ - RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_ACCEPT); -} -void TimeoutAcceptNotUpdatedTest(void) -{ - RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_ACCEPT); -} -void TimeoutAcceptReadCallbackTest(void) -{ - RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_ACCEPT); -} - -void TimeoutReadUpdatedTest(void) -{ - RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_SEND); -} -void TimeoutReadNotUpdatedTest(void) -{ - RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_SEND); -} -void TimeoutReadReadTest(void) -{ - RunTest(ACCEPT_READ, CLIENT_TIMEOUT_SEND); -} -void TimeoutReadReadNotUpdatedTest(void) -{ - RunTest(ACCEPT_READ_FAST, CLIENT_TIMEOUT_SEND); -} -void TimeoutReadReadCallbackTest(void) -{ - RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_SEND); -} - -/************************************************************************/ - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - if (debug_mode) - PR_fprintf(output, "%40s: %6.2f usec\n", msg, d / count); - -} - -int main(int argc, char **argv) -{ - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name [-d] [-c n] - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "Gdc:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'G': /* global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'c': /* loop counter */ - count = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - output = PR_STDERR; - PR_STDIO_INIT(); - - timeoutTime = PR_SecondsToInterval(TIMEOUTSECS); - if (debug_mode) - PR_fprintf(output, "\nRun accept() sucessful connection tests\n"); - - Measure(AcceptUpdatedTest, "PR_Accept()"); - Measure(AcceptReadTest, "PR_AcceptRead()"); -#ifdef WINNT - Measure(AcceptNotUpdatedTest, "PR_NTFast_Accept()"); - Measure(AcceptReadNotUpdatedTest, "PR_NTFast_AcceptRead()"); - Measure(AcceptReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()"); -#endif - if (debug_mode) - PR_fprintf(output, "\nRun accept() timeout in the accept tests\n"); -#ifdef WINNT - Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()"); -#endif - Measure(TimeoutReadUpdatedTest, "PR_Accept()"); - if (debug_mode) - PR_fprintf(output, "\nRun accept() timeout in the read tests\n"); - Measure(TimeoutReadReadTest, "PR_AcceptRead()"); -#ifdef WINNT - Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()"); - Measure(TimeoutReadReadNotUpdatedTest, "PR_NTFast_AcceptRead()"); - Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()"); -#endif - PR_fprintf(output, "%s\n", (failed_already) ? "FAIL" : "PASS"); - return failed_already; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/acceptread.c nspr-4.10.7/mozilla/nsprpub/pr/tests/acceptread.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/acceptread.c 2012-03-06 13:14:23.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/acceptread.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,244 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define DEFAULT_PORT 12273 -#define GET "GET / HTTP/1.0\n\n" -static PRFileDesc *std_out, *err_out; -static PRIntervalTime write_dally, accept_timeout; - -static PRStatus PrintAddress(const PRNetAddr* address) -{ - char buffer[100]; - PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); - if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString"); - else PR_fprintf( - std_out, "Accepted connection from (0x%p)%s:%d\n", - address, buffer, address->inet.port); - return rv; -} /* PrintAddress */ - -static void ConnectingThread(void *arg) -{ - PRInt32 nbytes; -#ifdef SYMBIAN - char buf[256]; -#else - char buf[1024]; -#endif - PRFileDesc *sock; - PRNetAddr peer_addr, *addr; - - addr = (PRNetAddr*)arg; - - sock = PR_NewTCPSocket(); - if (sock == NULL) - { - PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed"); - PR_ProcessExit(1); - } - - if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) - { - PL_FPrintError(err_out, "PR_Connect (client) failed"); - PR_ProcessExit(1); - } - if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE) - { - PL_FPrintError(err_out, "PR_GetPeerName (client) failed"); - PR_ProcessExit(1); - } - - /* - ** Then wait between the connection coming up and sending the expected - ** data. At some point in time, the server should fail due to a timeou - ** on the AcceptRead() operation, which according to the document is - ** only due to the read() portion. - */ - PR_Sleep(write_dally); - - nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT); - if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed"); - - nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); - if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed"); - else - { - PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes); - buf[sizeof(buf) - 1] = '\0'; - PR_fprintf(std_out, "%s\n", buf); - } - - if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH)) - PL_FPrintError(err_out, "PR_Shutdown (client) failed"); - - if (PR_FAILURE == PR_Close(sock)) - PL_FPrintError(err_out, "PR_Close (client) failed"); - - return; -} /* ConnectingThread */ - -#define BUF_SIZE 117 -static void AcceptingThread(void *arg) -{ - PRStatus rv; - PRInt32 bytes; - PRSize buf_size = BUF_SIZE; - PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32]; - PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg; - PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket(); - PRSocketOptionData sock_opt; - - if (NULL == listen_sock) - { - PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed"); - PR_ProcessExit(1); - } - sock_opt.option = PR_SockOpt_Reuseaddr; - sock_opt.value.reuse_addr = PR_TRUE; - rv = PR_SetSocketOption(listen_sock, &sock_opt); - if (PR_FAILURE == rv) - { - PL_FPrintError(err_out, "PR_SetSocketOption (server) failed"); - PR_ProcessExit(1); - } - rv = PR_Bind(listen_sock, listen_addr); - if (PR_FAILURE == rv) - { - PL_FPrintError(err_out, "PR_Bind (server) failed"); - PR_ProcessExit(1); - } - rv = PR_Listen(listen_sock, 10); - if (PR_FAILURE == rv) - { - PL_FPrintError(err_out, "PR_Listen (server) failed"); - PR_ProcessExit(1); - } - bytes = PR_AcceptRead( - listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout); - - if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed"); - else - { - PrintAddress(accept_addr); - PR_fprintf( - std_out, "(Server) read [0x%p..0x%p) %s\n", - buf, &buf[BUF_SIZE], buf); - bytes = PR_Write(accept_sock, buf, bytes); - rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH); - if (PR_FAILURE == rv) - PL_FPrintError(err_out, "PR_Shutdown (server) failed"); - } - - if (-1 != bytes) - { - rv = PR_Close(accept_sock); - if (PR_FAILURE == rv) - PL_FPrintError(err_out, "PR_Close (server) failed"); - } - - rv = PR_Close(listen_sock); - if (PR_FAILURE == rv) - PL_FPrintError(err_out, "PR_Close (server) failed"); -} /* AcceptingThread */ - -int main(int argc, char **argv) -{ - PRHostEnt he; - PRStatus status; - PRIntn next_index; - PRUint16 port_number; - char netdb_buf[PR_NETDB_BUF_SIZE]; - PRNetAddr client_addr, server_addr; - PRThread *client_thread, *server_thread; - PRIntervalTime delta = PR_MillisecondsToInterval(500); - - err_out = PR_STDERR; - std_out = PR_STDOUT; - accept_timeout = PR_SecondsToInterval(2); - - if (argc != 2 && argc != 3) port_number = DEFAULT_PORT; - else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]); - - status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr); - if (PR_SUCCESS != status) - { - PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); - PR_ProcessExit(1); - } - if (argc < 3) - { - status = PR_InitializeNetAddr( - PR_IpAddrLoopback, port_number, &client_addr); - if (PR_SUCCESS != status) - { - PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); - PR_ProcessExit(1); - } - } - else - { - status = PR_GetHostByName( - argv[1], netdb_buf, sizeof(netdb_buf), &he); - if (status == PR_FAILURE) - { - PL_FPrintError(err_out, "PR_GetHostByName failed"); - PR_ProcessExit(1); - } - next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr); - if (next_index == -1) - { - PL_FPrintError(err_out, "PR_EnumerateHostEnt failed"); - PR_ProcessExit(1); - } - } - - for ( - write_dally = 0; - write_dally < accept_timeout + (2 * delta); - write_dally += delta) - { - PR_fprintf( - std_out, "Testing w/ write_dally = %d msec\n", - PR_IntervalToMilliseconds(write_dally)); - server_thread = PR_CreateThread( - PR_USER_THREAD, AcceptingThread, &server_addr, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (server_thread == NULL) - { - PL_FPrintError(err_out, "PR_CreateThread (server) failed"); - PR_ProcessExit(1); - } - - PR_Sleep(delta); /* let the server pot thicken */ - - client_thread = PR_CreateThread( - PR_USER_THREAD, ConnectingThread, &client_addr, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (client_thread == NULL) - { - PL_FPrintError(err_out, "PR_CreateThread (client) failed"); - PR_ProcessExit(1); - } - - if (PR_JoinThread(client_thread) == PR_FAILURE) - PL_FPrintError(err_out, "PR_JoinThread (client) failed"); - - if (PR_JoinThread(server_thread) == PR_FAILURE) - PL_FPrintError(err_out, "PR_JoinThread (server) failed"); - } - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/acceptreademu.c nspr-4.10.7/mozilla/nsprpub/pr/tests/acceptreademu.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/acceptreademu.c 2012-03-06 13:14:23.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/acceptreademu.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,274 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This test is the same as acceptread.c except that it uses the - * emulated acceptread method instead of the regular acceptread. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define DEFAULT_PORT 12273 -#define GET "GET / HTTP/1.0\n\n" -static PRFileDesc *std_out, *err_out; -static PRIntervalTime write_dally, accept_timeout; -static PRDescIdentity emu_layer_ident; -static PRIOMethods emu_layer_methods; - -/* the acceptread method in emu_layer_methods */ -static PRInt32 PR_CALLBACK emu_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, - PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout) -{ - return PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout); -} - -static PRStatus PrintAddress(const PRNetAddr* address) -{ - char buffer[100]; - PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); - if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString"); - else PR_fprintf( - std_out, "Accepted connection from (0x%p)%s:%d\n", - address, buffer, address->inet.port); - return rv; -} /* PrintAddress */ - -static void ConnectingThread(void *arg) -{ - PRInt32 nbytes; -#ifdef SYMBIAN - char buf[256]; -#else - char buf[1024]; -#endif - PRFileDesc *sock; - PRNetAddr peer_addr, *addr; - - addr = (PRNetAddr*)arg; - - sock = PR_NewTCPSocket(); - if (sock == NULL) - { - PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed"); - PR_ProcessExit(1); - } - - if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) - { - PL_FPrintError(err_out, "PR_Connect (client) failed"); - PR_ProcessExit(1); - } - if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE) - { - PL_FPrintError(err_out, "PR_GetPeerName (client) failed"); - PR_ProcessExit(1); - } - - /* - ** Then wait between the connection coming up and sending the expected - ** data. At some point in time, the server should fail due to a timeou - ** on the AcceptRead() operation, which according to the document is - ** only due to the read() portion. - */ - PR_Sleep(write_dally); - - nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT); - if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed"); - - nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); - if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed"); - else - { - PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes); - buf[sizeof(buf) - 1] = '\0'; - PR_fprintf(std_out, "%s\n", buf); - } - - if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH)) - PL_FPrintError(err_out, "PR_Shutdown (client) failed"); - - if (PR_FAILURE == PR_Close(sock)) - PL_FPrintError(err_out, "PR_Close (client) failed"); - - return; -} /* ConnectingThread */ - -#define BUF_SIZE 117 -static void AcceptingThread(void *arg) -{ - PRStatus rv; - PRInt32 bytes; - PRSize buf_size = BUF_SIZE; - PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32]; - PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg; - PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket(); - PRFileDesc *layer; - PRSocketOptionData sock_opt; - - if (NULL == listen_sock) - { - PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed"); - PR_ProcessExit(1); - } - layer = PR_CreateIOLayerStub(emu_layer_ident, &emu_layer_methods); - if (NULL == layer) - { - PL_FPrintError(err_out, "PR_CreateIOLayerStub (server) failed"); - PR_ProcessExit(1); - } - if (PR_PushIOLayer(listen_sock, PR_TOP_IO_LAYER, layer) == PR_FAILURE) - { - PL_FPrintError(err_out, "PR_PushIOLayer (server) failed"); - PR_ProcessExit(1); - } - sock_opt.option = PR_SockOpt_Reuseaddr; - sock_opt.value.reuse_addr = PR_TRUE; - rv = PR_SetSocketOption(listen_sock, &sock_opt); - if (PR_FAILURE == rv) - { - PL_FPrintError(err_out, "PR_SetSocketOption (server) failed"); - PR_ProcessExit(1); - } - rv = PR_Bind(listen_sock, listen_addr); - if (PR_FAILURE == rv) - { - PL_FPrintError(err_out, "PR_Bind (server) failed"); - PR_ProcessExit(1); - } - rv = PR_Listen(listen_sock, 10); - if (PR_FAILURE == rv) - { - PL_FPrintError(err_out, "PR_Listen (server) failed"); - PR_ProcessExit(1); - } - bytes = PR_AcceptRead( - listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout); - - if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed"); - else - { - PrintAddress(accept_addr); - PR_fprintf( - std_out, "(Server) read [0x%p..0x%p) %s\n", - buf, &buf[BUF_SIZE], buf); - bytes = PR_Write(accept_sock, buf, bytes); - rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH); - if (PR_FAILURE == rv) - PL_FPrintError(err_out, "PR_Shutdown (server) failed"); - } - - if (-1 != bytes) - { - rv = PR_Close(accept_sock); - if (PR_FAILURE == rv) - PL_FPrintError(err_out, "PR_Close (server) failed"); - } - - rv = PR_Close(listen_sock); - if (PR_FAILURE == rv) - PL_FPrintError(err_out, "PR_Close (server) failed"); -} /* AcceptingThread */ - -int main(int argc, char **argv) -{ - PRHostEnt he; - PRStatus status; - PRIntn next_index; - PRUint16 port_number; - char netdb_buf[PR_NETDB_BUF_SIZE]; - PRNetAddr client_addr, server_addr; - PRThread *client_thread, *server_thread; - PRIntervalTime delta = PR_MillisecondsToInterval(500); - - err_out = PR_STDERR; - std_out = PR_STDOUT; - accept_timeout = PR_SecondsToInterval(2); - emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead"); - emu_layer_methods = *PR_GetDefaultIOMethods(); - emu_layer_methods.acceptread = emu_AcceptRead; - - if (argc != 2 && argc != 3) port_number = DEFAULT_PORT; - else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]); - - status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr); - if (PR_SUCCESS != status) - { - PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); - PR_ProcessExit(1); - } - if (argc < 3) - { - status = PR_InitializeNetAddr( - PR_IpAddrLoopback, port_number, &client_addr); - if (PR_SUCCESS != status) - { - PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); - PR_ProcessExit(1); - } - } - else - { - status = PR_GetHostByName( - argv[1], netdb_buf, sizeof(netdb_buf), &he); - if (status == PR_FAILURE) - { - PL_FPrintError(err_out, "PR_GetHostByName failed"); - PR_ProcessExit(1); - } - next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr); - if (next_index == -1) - { - PL_FPrintError(err_out, "PR_EnumerateHostEnt failed"); - PR_ProcessExit(1); - } - } - - for ( - write_dally = 0; - write_dally < accept_timeout + (2 * delta); - write_dally += delta) - { - PR_fprintf( - std_out, "Testing w/ write_dally = %d msec\n", - PR_IntervalToMilliseconds(write_dally)); - server_thread = PR_CreateThread( - PR_USER_THREAD, AcceptingThread, &server_addr, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (server_thread == NULL) - { - PL_FPrintError(err_out, "PR_CreateThread (server) failed"); - PR_ProcessExit(1); - } - - PR_Sleep(delta); /* let the server pot thicken */ - - client_thread = PR_CreateThread( - PR_USER_THREAD, ConnectingThread, &client_addr, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (client_thread == NULL) - { - PL_FPrintError(err_out, "PR_CreateThread (client) failed"); - PR_ProcessExit(1); - } - - if (PR_JoinThread(client_thread) == PR_FAILURE) - PL_FPrintError(err_out, "PR_JoinThread (client) failed"); - - if (PR_JoinThread(server_thread) == PR_FAILURE) - PL_FPrintError(err_out, "PR_JoinThread (server) failed"); - } - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/addrstr.c nspr-4.10.7/mozilla/nsprpub/pr/tests/addrstr.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/addrstr.c 2012-03-06 13:14:23.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/addrstr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prnetdb.h" - -#include -#include -#include - -const char *testaddrs[] = { - "::", "::", - "::1", "::1", - "::ffff", "::ffff", - "::1:0", "::0.1.0.0", - "::127.0.0.1", "::127.0.0.1", - "::FFFF:127.0.0.1", "::ffff:127.0.0.1", - "::FFFE:9504:3501", "::fffe:9504:3501", - "0:0:1:0:35c:0:0:0", "0:0:1:0:35c::", - "0:0:3f4c:0:0:4552:0:0", "::3f4c:0:0:4552:0:0", - "0:0:1245:0:0:0:0567:0", "0:0:1245::567:0", - "0:1:2:3:4:5:6:7", "0:1:2:3:4:5:6:7", - "1:2:3:0:4:5:6:7", "1:2:3:0:4:5:6:7", - "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:0", - "1:2:3:4:5:6:7:8", "1:2:3:4:5:6:7:8", - "1:2:3:4:5:6::7", "1:2:3:4:5:6:0:7", - 0 -}; - -const char *badaddrs[] = { - "::.1.2.3", - "ffff::.1.2.3", - "1:2:3:4:5:6:7::8", - "1:2:3:4:5:6::7:8", - "::ff99.2.3.4", - 0 -}; - -int failed_already = 0; - -int main(int argc, char **argv) -{ - const char **nexttestaddr = testaddrs; - const char **nextbadaddr = badaddrs; - const char *in, *expected_out; - PRNetAddr addr; - char buf[256]; - PRStatus rv; - - while ((in = *nexttestaddr++) != 0) { - expected_out = *nexttestaddr++; - rv = PR_StringToNetAddr(in, &addr); - if (rv) { - printf("cannot convert %s to addr: %d\n", in, rv); - failed_already = 1; - continue; - } - rv = PR_NetAddrToString(&addr, buf, sizeof(buf)); - if (rv) { - printf("cannot convert %s back to string: %d\n", in, rv); - failed_already = 1; - continue; - } - if (strcmp(buf, expected_out)) { - /* This is not necessarily an error */ - printf("%s expected %s got %s\n", in, expected_out, buf); - } - } - while ((in = *nextbadaddr++) != 0) { - if (PR_StringToNetAddr(in, &addr) == PR_SUCCESS) { - printf("converted bad addr %s\n", in); - failed_already = 1; - } - } - if (failed_already) { - printf("FAIL\n"); - return 1; - } - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/affinity.c nspr-4.10.7/mozilla/nsprpub/pr/tests/affinity.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/affinity.c 2012-03-06 13:14:24.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/affinity.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "pprthred.h" -#include "plgetopt.h" - -#include -#include -#include - -#ifndef XP_BEOS - -/* - * Test PR_GetThreadAffinityMask - * The function is called by each of local, global and global bound threads - * The test should be run on both single and multi-cpu systems - */ -static void PR_CALLBACK thread_start(void *arg) -{ -PRUint32 mask = 0; - - if (PR_GetThreadAffinityMask(PR_GetCurrentThread(), &mask)) - printf("\tthread_start: PR_GetCurrentThreadAffinityMask failed\n"); - else - printf("\tthread_start: AffinityMask = 0x%x\n",mask); - -} - -int main(int argc, char **argv) -{ - PRThread *t; - - printf("main: creating local thread\n"); - - t = PR_CreateThread(PR_USER_THREAD, - thread_start, 0, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0); - - if (NULL == t) { - printf("main: cannot create local thread\n"); - exit(1); - } - - PR_JoinThread(t); - - printf("main: creating global thread\n"); - t = PR_CreateThread(PR_USER_THREAD, - thread_start, 0, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - 0); - - if (NULL == t) { - printf("main: cannot create global thread\n"); - exit(1); - } - - PR_JoinThread(t); - - printf("main: creating global bound thread\n"); - t = PR_CreateThread(PR_USER_THREAD, - thread_start, 0, - PR_PRIORITY_NORMAL, - PR_GLOBAL_BOUND_THREAD, - PR_JOINABLE_THREAD, - 0); - - if (NULL == t) { - printf("main: cannot create global bound thread\n"); - exit(1); - } - - PR_JoinThread(t); - - return 0; -} - -#else /* !XP_BEOS */ - -int main() -{ - printf( "This test is not supported on the BeOS\n" ); - return 0; -} -#endif /* !XP_BEOS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/alarm.c nspr-4.10.7/mozilla/nsprpub/pr/tests/alarm.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/alarm.c 2012-03-06 13:14:24.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/alarm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,519 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1996 - Netscape Communications Corporation -** -** Name: alarmtst.c -** -** Description: Test alarms -** -** Modification History: -** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ - -#include "prlog.h" -#include "prinit.h" -#include "obsolete/pralarm.h" -#include "prlock.h" -#include "prlong.h" -#include "prcvar.h" -#include "prinrval.h" -#include "prtime.h" - -/* Used to get the command line option */ -#include "plgetopt.h" -#include -#include - -#if defined(XP_UNIX) -#include -#endif - -static PRIntn debug_mode; -static PRIntn failed_already=0; -static PRThreadScope thread_scope = PR_LOCAL_THREAD; - -typedef struct notifyData { - PRLock *ml; - PRCondVar *child; - PRCondVar *parent; - PRBool pending; - PRUint32 counter; -} NotifyData; - -static void Notifier(void *arg) -{ - NotifyData *notifyData = (NotifyData*)arg; - PR_Lock(notifyData->ml); - while (notifyData->counter > 0) - { - while (!notifyData->pending) - PR_WaitCondVar(notifyData->child, PR_INTERVAL_NO_TIMEOUT); - notifyData->counter -= 1; - notifyData->pending = PR_FALSE; - PR_NotifyCondVar(notifyData->parent); - } - PR_Unlock(notifyData->ml); -} /* Notifier */ -/*********************************************************************** -** PRIVATE FUNCTION: ConditionNotify -** DESCRIPTION: -** -** INPUTS: loops -** OUTPUTS: None -** RETURN: overhead -** SIDE EFFECTS: -** -** RESTRICTIONS: -** None -** MEMORY: NA -** ALGORITHM: -** -***********************************************************************/ - - -static PRIntervalTime ConditionNotify(PRUint32 loops) -{ - PRThread *thread; - NotifyData notifyData; - PRIntervalTime timein, overhead; - - timein = PR_IntervalNow(); - - notifyData.counter = loops; - notifyData.ml = PR_NewLock(); - notifyData.child = PR_NewCondVar(notifyData.ml); - notifyData.parent = PR_NewCondVar(notifyData.ml); - thread = PR_CreateThread( - PR_USER_THREAD, Notifier, ¬ifyData, - PR_GetThreadPriority(PR_GetCurrentThread()), - thread_scope, PR_JOINABLE_THREAD, 0); - - overhead = PR_IntervalNow() - timein; /* elapsed so far */ - - PR_Lock(notifyData.ml); - while (notifyData.counter > 0) - { - notifyData.pending = PR_TRUE; - PR_NotifyCondVar(notifyData.child); - while (notifyData.pending) - PR_WaitCondVar(notifyData.parent, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(notifyData.ml); - - timein = PR_IntervalNow(); - - (void)PR_JoinThread(thread); - PR_DestroyCondVar(notifyData.child); - PR_DestroyCondVar(notifyData.parent); - PR_DestroyLock(notifyData.ml); - - overhead += (PR_IntervalNow() - timein); /* more overhead */ - - return overhead; -} /* ConditionNotify */ - -static PRIntervalTime ConditionTimeout(PRUint32 loops) -{ - PRUintn count; - PRIntervalTime overhead, timein = PR_IntervalNow(); - - PRLock *ml = PR_NewLock(); - PRCondVar *cv = PR_NewCondVar(ml); - PRIntervalTime interval = PR_MillisecondsToInterval(50); - - overhead = PR_IntervalNow() - timein; - - PR_Lock(ml); - for (count = 0; count < loops; ++count) - { - overhead += interval; - PR_ASSERT(PR_WaitCondVar(cv, interval) == PR_SUCCESS); - } - PR_Unlock(ml); - - timein = PR_IntervalNow(); - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); - overhead += (PR_IntervalNow() - timein); - - return overhead; -} /* ConditionTimeout */ - -typedef struct AlarmData { - PRLock *ml; - PRCondVar *cv; - PRUint32 rate, late, times; - PRIntervalTime duration, timein, period; -} AlarmData; - -static PRBool AlarmFn1(PRAlarmID *id, void *clientData, PRUint32 late) -{ - PRStatus rv = PR_SUCCESS; - PRBool keepGoing, resetAlarm; - PRIntervalTime interval, now = PR_IntervalNow(); - AlarmData *ad = (AlarmData*)clientData; - - PR_Lock(ad->ml); - ad->late += late; - ad->times += 1; - keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ? - PR_TRUE : PR_FALSE; - if (!keepGoing) - rv = PR_NotifyCondVar(ad->cv); - resetAlarm = ((ad->times % 31) == 0) ? PR_TRUE : PR_FALSE; - - interval = (ad->period + ad->rate - 1) / ad->rate; - if (!late && (interval > 10)) - { - interval &= (now & 0x03) + 1; - PR_WaitCondVar(ad->cv, interval); - } - - PR_Unlock(ad->ml); - - if (rv != PR_SUCCESS) - { - if (!debug_mode) failed_already=1; - else - printf("AlarmFn: notify status: FAIL\n"); - - } - - if (resetAlarm) - { - ad->rate += 3; - ad->late = ad->times = 0; - if (PR_ResetAlarm(id, ad->period, ad->rate) != PR_SUCCESS) - { - if (!debug_mode) - failed_already=1; - else - printf("AlarmFn: Resetting alarm status: FAIL\n"); - - keepGoing = PR_FALSE; - } - - } - - return keepGoing; -} /* AlarmFn1 */ - -static PRIntervalTime Alarms1(PRUint32 loops) -{ - PRAlarm *alarm; - AlarmData ad; - PRIntervalTime overhead, timein = PR_IntervalNow(); - PRIntervalTime duration = PR_SecondsToInterval(3); - - PRLock *ml = PR_NewLock(); - PRCondVar *cv = PR_NewCondVar(ml); - - ad.ml = ml; - ad.cv = cv; - ad.rate = 1; - ad.times = loops; - ad.late = ad.times = 0; - ad.duration = duration; - ad.timein = PR_IntervalNow(); - ad.period = PR_SecondsToInterval(1); - - alarm = PR_CreateAlarm(); - - (void)PR_SetAlarm( - alarm, ad.period, ad.rate, AlarmFn1, &ad); - - overhead = PR_IntervalNow() - timein; - - PR_Lock(ml); - while ((PRIntervalTime)(PR_IntervalNow() - ad.timein) < duration) - PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(ml); - - timein = PR_IntervalNow(); - (void)PR_DestroyAlarm(alarm); - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); - overhead += (PR_IntervalNow() - timein); - - return duration + overhead; -} /* Alarms1 */ - -static PRBool AlarmFn2(PRAlarmID *id, void *clientData, PRUint32 late) -{ - PRBool keepGoing; - PRStatus rv = PR_SUCCESS; - AlarmData *ad = (AlarmData*)clientData; - PRIntervalTime interval, now = PR_IntervalNow(); - - PR_Lock(ad->ml); - ad->times += 1; - keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ? - PR_TRUE : PR_FALSE; - interval = (ad->period + ad->rate - 1) / ad->rate; - - if (!late && (interval > 10)) - { - interval &= (now & 0x03) + 1; - PR_WaitCondVar(ad->cv, interval); - } - - if (!keepGoing) rv = PR_NotifyCondVar(ad->cv); - - PR_Unlock(ad->ml); - - - if (rv != PR_SUCCESS) - failed_already=1;; - - return keepGoing; -} /* AlarmFn2 */ - -static PRIntervalTime Alarms2(PRUint32 loops) -{ - PRStatus rv; - PRAlarm *alarm; - PRIntervalTime overhead, timein = PR_IntervalNow(); - AlarmData ad; - PRIntervalTime duration = PR_SecondsToInterval(30); - - PRLock *ml = PR_NewLock(); - PRCondVar *cv = PR_NewCondVar(ml); - - ad.ml = ml; - ad.cv = cv; - ad.rate = 1; - ad.times = loops; - ad.late = ad.times = 0; - ad.duration = duration; - ad.timein = PR_IntervalNow(); - ad.period = PR_SecondsToInterval(1); - - alarm = PR_CreateAlarm(); - - (void)PR_SetAlarm( - alarm, ad.period, ad.rate, AlarmFn2, &ad); - - overhead = PR_IntervalNow() - timein; - - PR_Lock(ml); - while ((PRIntervalTime)(PR_IntervalNow() - ad.timein) < duration) - PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(ml); - - timein = PR_IntervalNow(); - - rv = PR_DestroyAlarm(alarm); - if (rv != PR_SUCCESS) - { - if (!debug_mode) - failed_already=1; - else - printf("***Destroying alarm status: FAIL\n"); - } - - - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); - - overhead += (PR_IntervalNow() - timein); - - return duration + overhead; -} /* Alarms2 */ - -static PRIntervalTime Alarms3(PRUint32 loops) -{ - PRIntn i; - PRStatus rv; - PRAlarm *alarm; - AlarmData ad[3]; - PRIntervalTime duration = PR_SecondsToInterval(30); - PRIntervalTime overhead, timein = PR_IntervalNow(); - - PRLock *ml = PR_NewLock(); - PRCondVar *cv = PR_NewCondVar(ml); - - for (i = 0; i < 3; ++i) - { - ad[i].ml = ml; - ad[i].cv = cv; - ad[i].rate = 1; - ad[i].times = loops; - ad[i].duration = duration; - ad[i].late = ad[i].times = 0; - ad[i].timein = PR_IntervalNow(); - ad[i].period = PR_SecondsToInterval(1); - - /* more loops, faster rate => same elapsed time */ - ad[i].times = (i + 1) * loops; - ad[i].rate = (i + 1) * 10; - } - - alarm = PR_CreateAlarm(); - - for (i = 0; i < 3; ++i) - { - (void)PR_SetAlarm( - alarm, ad[i].period, ad[i].rate, - AlarmFn2, &ad[i]); - } - - overhead = PR_IntervalNow() - timein; - - PR_Lock(ml); - for (i = 0; i < 3; ++i) - { - while ((PRIntervalTime)(PR_IntervalNow() - ad[i].timein) < duration) - PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(ml); - - timein = PR_IntervalNow(); - - if (debug_mode) - printf - ("Alarms3 finished at %u, %u, %u\n", - ad[0].timein, ad[1].timein, ad[2].timein); - - rv = PR_DestroyAlarm(alarm); - if (rv != PR_SUCCESS) - { - if (!debug_mode) - failed_already=1; - else - printf("***Destroying alarm status: FAIL\n"); - } - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); - - overhead += (duration / 3); - overhead += (PR_IntervalNow() - timein); - - return overhead; -} /* Alarms3 */ - -static PRUint32 TimeThis( - const char *msg, PRUint32 (*func)(PRUint32 loops), PRUint32 loops) -{ - PRUint32 overhead, usecs; - PRIntervalTime predicted, timein, timeout, ticks; - - if (debug_mode) - printf("Testing %s ...", msg); - - timein = PR_IntervalNow(); - predicted = func(loops); - timeout = PR_IntervalNow(); - - if (debug_mode) - printf(" done\n"); - - ticks = timeout - timein; - usecs = PR_IntervalToMicroseconds(ticks); - overhead = PR_IntervalToMicroseconds(predicted); - - if(ticks < predicted) - { - if (debug_mode) { - printf("\tFinished in negative time\n"); - printf("\tpredicted overhead was %d usecs\n", overhead); - printf("\ttest completed in %d usecs\n\n", usecs); - } - } - else - { - if (debug_mode) - printf( - "\ttotal: %d usecs\n\toverhead: %d usecs\n\tcost: %6.3f usecs\n\n", - usecs, overhead, ((double)(usecs - overhead) / (double)loops)); - } - - return overhead; -} /* TimeThis */ - -int prmain(int argc, char** argv) -{ - PRUint32 cpu, cpus = 0, loops = 0; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name [-d] - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:c:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'G': /* GLOBAL threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'l': /* loop count */ - loops = atoi(opt->value); - break; - case 'c': /* concurrency limit */ - cpus = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - - if (cpus == 0) cpus = 1; - if (loops == 0) loops = 4; - - if (debug_mode) - printf("Alarm: Using %d loops\n", loops); - - if (debug_mode) - printf("Alarm: Using %d cpu(s)\n", cpus); - - for (cpu = 1; cpu <= cpus; ++cpu) - { - if (debug_mode) - printf("\nAlarm: Using %d CPU(s)\n", cpu); - - PR_SetConcurrency(cpu); - - /* some basic time test */ - (void)TimeThis("ConditionNotify", ConditionNotify, loops); - (void)TimeThis("ConditionTimeout", ConditionTimeout, loops); - (void)TimeThis("Alarms1", Alarms1, loops); - (void)TimeThis("Alarms2", Alarms2, loops); - (void)TimeThis("Alarms3", Alarms3, loops); - } - return 0; -} - -int main(int argc, char** argv) -{ - PR_Initialize(prmain, argc, argv, 0); - PR_STDIO_INIT(); - if (failed_already) return 1; - else return 0; - -} /* main */ - - -/* alarmtst.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/anonfm.c nspr-4.10.7/mozilla/nsprpub/pr/tests/anonfm.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/anonfm.c 2012-03-06 13:14:24.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/anonfm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,311 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: anonfm.c -** Description: Test anonymous file map -** -** Synopsis: anonfm [options] [dirName] -** -** Options: -** -d enable debug mode -** -h display a help message -** -s size of the anonymous memory map, in KBytes. default: 100KBytes. -** -C 1 Operate this process as ClientOne() -** -C 2 Operate this process as ClientTwo() -** -** anonfn.c contains two tests, corresponding to the two protocols for -** passing an anonymous file map to a child process. -** -** ServerOne()/ClientOne() tests the passing of "raw" file map; it uses -** PR_CreateProcess() [for portability of the test case] to create the -** child process, but does not use the PRProcessAttr structure for -** passing the file map data. -** -** ServerTwo()/ClientTwo() tests the passing of the file map using the -** PRProcessAttr structure. -** -*/ -#include -#include -#include -#include -#include -#include - -/* -** Test harness infrastructure -*/ -PRLogModuleInfo *lm; -PRLogModuleLevel msgLevel = PR_LOG_NONE; -PRUint32 failed_already = 0; - -PRIntn debug = 0; -PRIntn client = 0; /* invoke client, style */ -char dirName[512] = "."; /* directory name to contain anon mapped file */ -PRSize fmSize = (100 * 1024 ); -PRUint32 fmMode = 0600; -PRFileMapProtect fmProt = PR_PROT_READWRITE; -const char *fmEnvName = "nsprFileMapEnvVariable"; - -/* -** Emit help text for this test -*/ -static void Help( void ) -{ - printf("anonfm [options] [dirName]\n"); - printf("-d -- enable debug mode\n"); - printf("dirName is alternate directory name. Default: . (current directory)\n"); - exit(1); -} /* end Help() */ - - -/* -** ClientOne() -- -*/ -static void ClientOne( void ) -{ - PRFileMap *fm; - char *fmString; - char *addr; - PRStatus rc; - - PR_LOG(lm, msgLevel, - ("ClientOne() starting")); - - fmString = PR_GetEnv( fmEnvName ); - if ( NULL == fmString ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_Getenv() failed")); - return; - } - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_Getenv(): found: %s", fmString)); - - fm = PR_ImportFileMapFromString( fmString ); - if ( NULL == fm ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_ImportFileMapFromString() failed")); - return; - } - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_ImportFileMapFromString(): fm: %p", fm )); - - addr = PR_MemMap( fm, LL_ZERO, fmSize ); - if ( NULL == addr ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_MemMap() failed, OSError: %d", PR_GetOSError() )); - return; - } - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_MemMap(): addr: %p", addr )); - - /* write to memory map to release server */ - *addr = 1; - - rc = PR_MemUnmap( addr, fmSize ); - PR_ASSERT( rc == PR_SUCCESS ); - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_MemUnap(): success" )); - - rc = PR_CloseFileMap( fm ); - if ( PR_FAILURE == rc ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_MemUnap() failed, OSError: %d", PR_GetOSError() )); - return; - } - PR_LOG(lm, msgLevel, - ("ClientOne(): PR_CloseFileMap(): success" )); - - return; -} /* end ClientOne() */ - -/* -** ClientTwo() -- -*/ -static void ClientTwo( void ) -{ - failed_already = 1; -} /* end ClientTwo() */ - -/* -** ServerOne() -- -*/ -static void ServerOne( void ) -{ - PRFileMap *fm; - PRStatus rc; - PRIntn i; - char *addr; - char fmString[256]; - char envBuf[256]; - char *child_argv[8]; - PRProcess *proc; - PRInt32 exit_status; - - PR_LOG(lm, msgLevel, - ("ServerOne() starting")); - - fm = PR_OpenAnonFileMap( dirName, fmSize, fmProt ); - if ( NULL == fm ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("PR_OpenAnonFileMap() failed")); - return; - } - PR_LOG(lm, msgLevel, - ("ServerOne(): FileMap: %p", fm )); - - rc = PR_ExportFileMapAsString( fm, sizeof(fmString), fmString ); - if ( PR_FAILURE == rc ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("PR_ExportFileMap() failed")); - return; - } - - /* - ** put the string into the environment - */ - PR_snprintf( envBuf, sizeof(envBuf), "%s=%s", fmEnvName, fmString); - putenv( envBuf ); - - addr = PR_MemMap( fm, LL_ZERO, fmSize ); - if ( NULL == addr ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("PR_MemMap() failed")); - return; - } - - /* set initial value for client */ - for (i = 0; i < (PRIntn)fmSize ; i++ ) - *(addr+i) = 0x00; - - PR_LOG(lm, msgLevel, - ("ServerOne(): PR_MemMap(): addr: %p", addr )); - - /* - ** set arguments for child process - */ - child_argv[0] = "anonfm"; - child_argv[1] = "-C"; - child_argv[2] = "1"; - child_argv[3] = NULL; - - proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); - PR_ASSERT( proc ); - PR_LOG(lm, msgLevel, - ("ServerOne(): PR_CreateProcess(): proc: %x", proc )); - - /* - ** ClientOne() will set the memory to 1 - */ - PR_LOG(lm, msgLevel, - ("ServerOne(): waiting on Client, *addr: %x", *addr )); - while( *addr == 0x00 ) { - if ( debug ) - fprintf(stderr, "."); - PR_Sleep(PR_MillisecondsToInterval(300)); - } - if ( debug ) - fprintf(stderr, "\n"); - PR_LOG(lm, msgLevel, - ("ServerOne(): Client responded" )); - - rc = PR_WaitProcess( proc, &exit_status ); - PR_ASSERT( PR_FAILURE != rc ); - - rc = PR_MemUnmap( addr, fmSize); - if ( PR_FAILURE == rc ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("PR_MemUnmap() failed")); - return; - } - PR_LOG(lm, msgLevel, - ("ServerOne(): PR_MemUnmap(): success" )); - - rc = PR_CloseFileMap(fm); - if ( PR_FAILURE == rc ) { - failed_already = 1; - PR_LOG(lm, msgLevel, - ("PR_CloseFileMap() failed")); - return; - } - PR_LOG(lm, msgLevel, - ("ServerOne(): PR_CloseFileMap() success" )); - - return; -} /* end ServerOne() */ - -/* -** ServerTwo() -- -*/ -static void ServerTwo( void ) -{ - PR_LOG(lm, msgLevel, - ("ServerTwo(): Not implemented yet" )); -} /* end ServerTwo() */ - - -int main(int argc, char **argv) -{ - { - /* - ** Get command line options - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "hdC:"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'C': /* Client style */ - client = atol(opt->value); - break; - case 's': /* file size */ - fmSize = atol( opt->value ) * 1024; - break; - case 'd': /* debug */ - debug = 1; - msgLevel = PR_LOG_DEBUG; - break; - case 'h': /* help message */ - Help(); - break; - default: - strcpy(dirName, opt->value); - break; - } - } - PL_DestroyOptState(opt); - } - - lm = PR_NewLogModule("Test"); /* Initialize logging */ - - if ( client == 1 ) { - ClientOne(); - } else if ( client == 2 ) { - ClientTwo(); - } else { - ServerOne(); - if ( failed_already ) goto Finished; - ServerTwo(); - } - -Finished: - if ( debug ) - printf("%s\n", (failed_already)? "FAIL" : "PASS"); - return( (failed_already == PR_TRUE )? 1 : 0 ); -} /* main() */ -/* end anonfm.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/append.c nspr-4.10.7/mozilla/nsprpub/pr/tests/append.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/append.c 2012-03-06 13:14:24.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/append.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: append.c -** Description: Testing File writes where PR_APPEND was used on open -** -** append attempts to verify that a file opened with PR_APPEND -** will always append to the end of file, regardless where the -** current file pointer is positioned. To do this, PR_Seek() is -** called before each write with the position set to beginning of -** file. Subsequent writes should always append. -** The file is read back, summing the integer data written to the -** file. If the expected result is equal, the test passes. -** -** See BugSplat: 4090 -*/ -#include "plgetopt.h" -#include "nspr.h" - -#include -#include - -PRIntn debug = 0; -PRIntn verbose = 0; -PRBool failedAlready = PR_FALSE; -const PRInt32 addedBytes = 1000; -const PRInt32 buf = 1; /* constant written to fd, addedBytes times */ -PRInt32 inBuf; /* read it back into here */ - -int main(int argc, char **argv) -{ - PRStatus rc; - PRInt32 rv; - PRFileDesc *fd; - PRIntn i; - PRInt32 sum = 0; - - { /* Get command line options */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "vd"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug */ - debug = 1; - break; - case 'v': /* verbose */ - verbose = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - } /* end block "Get command line options" */ -/* ---------------------------------------------------------------------- */ - fd = PR_Open( "/tmp/nsprAppend", (PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE | PR_WRONLY), 0666 ); - if ( NULL == fd ) { - if (debug) printf("PR_Open() failed for writing: %d\n", PR_GetError()); - failedAlready = PR_TRUE; - goto Finished; - } - - for ( i = 0; i < addedBytes ; i++ ) { - rv = PR_Write( fd, &buf, sizeof(buf)); - if ( sizeof(buf) != rv ) { - if (debug) printf("PR_Write() failed: %d\n", PR_GetError()); - failedAlready = PR_TRUE; - goto Finished; - } - rv = PR_Seek( fd, 0 , PR_SEEK_SET ); - if ( -1 == rv ) { - if (debug) printf("PR_Seek() failed: %d\n", PR_GetError()); - failedAlready = PR_TRUE; - goto Finished; - } - } - rc = PR_Close( fd ); - if ( PR_FAILURE == rc ) { - if (debug) printf("PR_Close() failed after writing: %d\n", PR_GetError()); - failedAlready = PR_TRUE; - goto Finished; - } -/* ---------------------------------------------------------------------- */ - fd = PR_Open( "/tmp/nsprAppend", PR_RDONLY, 0 ); - if ( NULL == fd ) { - if (debug) printf("PR_Open() failed for reading: %d\n", PR_GetError()); - failedAlready = PR_TRUE; - goto Finished; - } - - for ( i = 0; i < addedBytes ; i++ ) { - rv = PR_Read( fd, &inBuf, sizeof(inBuf)); - if ( sizeof(inBuf) != rv) { - if (debug) printf("PR_Write() failed: %d\n", PR_GetError()); - failedAlready = PR_TRUE; - goto Finished; - } - sum += inBuf; - } - - rc = PR_Close( fd ); - if ( PR_FAILURE == rc ) { - if (debug) printf("PR_Close() failed after reading: %d\n", PR_GetError()); - failedAlready = PR_TRUE; - goto Finished; - } - if ( sum != addedBytes ) { - if (debug) printf("Uh Oh! addedBytes: %d. Sum: %d\n", addedBytes, sum); - failedAlready = PR_TRUE; - goto Finished; - } - -/* ---------------------------------------------------------------------- */ -Finished: - if (debug || verbose) printf("%s\n", (failedAlready)? "FAILED" : "PASSED" ); - return( (failedAlready)? 1 : 0 ); -} /* main() */ - -/* append.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/atomic.c nspr-4.10.7/mozilla/nsprpub/pr/tests/atomic.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/atomic.c 2012-03-06 13:14:24.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/atomic.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,183 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prprf.h" -#include "pratom.h" - -/* - * TODO: create a macro to generate the six lines of code that are repeated - * for every test. Also rewrite the statement - * result = result | ((EXPRESSION) ? 0 : 1); - * as - * result |= !(EXPRESSION); - */ - -int main(int argc, char **argv) -{ - PRInt32 rv, oldval, test, result = 0; - PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput); - - /***********************/ - /* Test the functions. */ - /***********************/ - - oldval = test = -2; - rv = PR_AtomicIncrement(&test); - result = result | ((rv == -1) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicIncrement(%d) == %d: %s\n", - oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_AtomicIncrement(&test); - result = result | ((rv == 0) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicIncrement(%d) == %d: %s\n", - oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_AtomicIncrement(&test); - result = result | ((rv == 1) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicIncrement(%d) == %d: %s\n", - oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); - - oldval = test = -2; - rv = PR_AtomicAdd(&test,1); - result = result | ((rv == -1) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicAdd(%d,%d) == %d: %s\n", - oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_AtomicAdd(&test, 4); - result = result | ((rv == 3) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicAdd(%d,%d) == %d: %s\n", - oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_AtomicAdd(&test, -6); - result = result | ((rv == -3) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicAdd(%d,%d) == %d: %s\n", - oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED"); - - oldval = test = 2; - rv = PR_AtomicDecrement(&test); - result = result | ((rv == 1) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicDecrement(%d) == %d: %s\n", - oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_AtomicDecrement(&test); - result = result | ((rv == 0) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicDecrement(%d) == %d: %s\n", - oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_AtomicDecrement(&test); - result = result | ((rv == -1) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicDecrement(%d) == %d: %s\n", - oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); - - /* set to a different value */ - oldval = test = -2; - rv = PR_AtomicSet(&test, 2); - result = result | (((rv == -2) && (test == 2)) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicSet(%d, %d) == %d: %s\n", - oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED"); - - /* set to the same value */ - oldval = test = -2; - rv = PR_AtomicSet(&test, -2); - result = result | (((rv == -2) && (test == -2)) ? 0 : 1); - PR_fprintf( - output, "PR_AtomicSet(%d, %d) == %d: %s\n", - oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED"); - - /***********************/ - /* Test the macros. */ - /***********************/ - - oldval = test = -2; - rv = PR_ATOMIC_INCREMENT(&test); - result = result | ((rv == -1) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", - oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_ATOMIC_INCREMENT(&test); - result = result | ((rv == 0) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", - oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_ATOMIC_INCREMENT(&test); - result = result | ((rv == 1) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", - oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); - - oldval = test = -2; - rv = PR_ATOMIC_ADD(&test,1); - result = result | ((rv == -1) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", - oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_ATOMIC_ADD(&test, 4); - result = result | ((rv == 3) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", - oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_ATOMIC_ADD(&test, -6); - result = result | ((rv == -3) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", - oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED"); - - oldval = test = 2; - rv = PR_ATOMIC_DECREMENT(&test); - result = result | ((rv == 1) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", - oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_ATOMIC_DECREMENT(&test); - result = result | ((rv == 0) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", - oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); - oldval = test; - rv = PR_ATOMIC_DECREMENT(&test); - result = result | ((rv == -1) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", - oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); - - /* set to a different value */ - oldval = test = -2; - rv = PR_ATOMIC_SET(&test, 2); - result = result | (((rv == -2) && (test == 2)) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_SET(%d, %d) == %d: %s\n", - oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED"); - - /* set to the same value */ - oldval = test = -2; - rv = PR_ATOMIC_SET(&test, -2); - result = result | (((rv == -2) && (test == -2)) ? 0 : 1); - PR_fprintf( - output, "PR_ATOMIC_SET(%d, %d) == %d: %s\n", - oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED"); - - PR_fprintf( - output, "Atomic operations test %s\n", - (result == 0) ? "PASSED" : "FAILED"); - return result; -} /* main */ - -/* atomic.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/attach.c nspr-4.10.7/mozilla/nsprpub/pr/tests/attach.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/attach.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/attach.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,355 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1996 - Netscape Communications Corporation -** -** Name: attach.c -** -** Description: Platform-specific code to create a native thread. The native thread will -** repeatedly call PR_AttachThread and PR_DetachThread. The -** primordial thread waits for this new thread to finish. -** -** Modification History: -** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** 12-June-97 Revert to return code 0 and 1. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ - -/* Used to get the command line option */ -#include "nspr.h" -#include "pprthred.h" -#include "plgetopt.h" - -#include - -#ifdef WIN32 -#include -#include -#elif defined(_PR_PTHREADS) -#include -#include "md/_pth.h" -#elif defined(IRIX) -#include -#include -#include -#include -#elif defined(SOLARIS) -#include -#elif defined(OS2) -#define INCL_DOS -#define INCL_ERRORS -#include -#include -#elif defined(XP_BEOS) -#include -#endif - -#define DEFAULT_COUNT 1000 -PRIntn failed_already=0; -PRIntn debug_mode; - - -int count; - - -static void -AttachDetach(void) -{ - PRThread *me; - PRInt32 index; - - for (index=0;indexoption) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'c': /* loop count */ - count = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - -#if defined(WIN16) - printf("attach: This test is not valid for Win16\n"); - goto exit_now; -#endif - - if(0 == count) count = DEFAULT_COUNT; - - /* - * To force the implicit initialization of nspr20 - */ - PR_SetError(0, 0); - PR_STDIO_INIT(); - - /* - * Platform-specific code to create a native thread. The native - * thread will repeatedly call PR_AttachThread and PR_DetachThread. - * The primordial thread waits for this new thread to finish. - */ - -#ifdef _PR_PTHREADS - - rv = _PT_PTHREAD_ATTR_INIT(&attr); - if (debug_mode) PR_ASSERT(0 == rv); - else if (0 != rv) { - failed_already=1; - goto exit_now; - } - -#ifndef _PR_DCETHREADS - rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - if (debug_mode) PR_ASSERT(0 == rv); - else if (0 != rv) { - failed_already=1; - goto exit_now; - } -#endif /* !_PR_DCETHREADS */ - rv = _PT_PTHREAD_CREATE(&threadID, attr, threadStartFunc, NULL); - if (rv != 0) { - fprintf(stderr, "thread creation failed: error code %d\n", rv); - failed_already=1; - goto exit_now; - } - else { - if (debug_mode) - printf ("thread creation succeeded \n"); - - } - rv = _PT_PTHREAD_ATTR_DESTROY(&attr); - if (debug_mode) PR_ASSERT(0 == rv); - else if (0 != rv) { - failed_already=1; - goto exit_now; - } - rv = pthread_join(threadID, NULL); - if (debug_mode) PR_ASSERT(0 == rv); - else if (0 != rv) { - failed_already=1; - goto exit_now; - } - -#elif defined(SOLARIS) - - rv = thr_create(NULL, 0, threadStartFunc, NULL, 0, &threadID); - if (rv != 0) { - if(!debug_mode) { - failed_already=1; - goto exit_now; - } else - fprintf(stderr, "thread creation failed: error code %d\n", rv); - } - rv = thr_join(threadID, NULL, NULL); - if (debug_mode) PR_ASSERT(0 == rv); - else if (0 != rv) - { - failed_already=1; - goto exit_now; - } - - -#elif defined(WIN32) - - hThread = (HANDLE) _beginthreadex(NULL, 0, threadStartFunc, NULL, - 0, &threadID); - if (hThread == 0) { - fprintf(stderr, "thread creation failed: error code %d\n", - GetLastError()); - failed_already=1; - goto exit_now; - } - rv = WaitForSingleObject(hThread, INFINITE); - if (debug_mode)PR_ASSERT(rv != WAIT_FAILED); - else if (rv == WAIT_FAILED) { - failed_already=1; - goto exit_now; - } - -#elif defined(IRIX) - - threadID = sproc(threadStartFunc, PR_SALL, NULL); - if (threadID == -1) { - - fprintf(stderr, "thread creation failed: error code %d\n", - errno); - failed_already=1; - goto exit_now; - - } - else { - if (debug_mode) - printf ("thread creation succeeded \n"); - sleep(3); - goto exit_now; - } - rv = waitpid(threadID, NULL, 0); - if (debug_mode) PR_ASSERT(rv != -1); - else if (rv != -1) { - failed_already=1; - goto exit_now; - } - -#elif defined(OS2) - - threadID = (TID) _beginthread((void *)threadStartFunc, NULL, - 32768, NULL); - if (threadID == -1) { - fprintf(stderr, "thread creation failed: error code %d\n", errno); - failed_already=1; - goto exit_now; - } - rv = DosWaitThread(&threadID, DCWW_WAIT); - if (debug_mode) { - PR_ASSERT(rv == NO_ERROR); - } else if (rv != NO_ERROR) { - failed_already=1; - goto exit_now; - } - -#elif defined(XP_BEOS) - - threadID = spawn_thread(threadStartFunc, NULL, B_NORMAL_PRIORITY, NULL); - if (threadID <= B_ERROR) { - fprintf(stderr, "thread creation failed: error code %08lx\n", threadID); - failed_already = 1; - goto exit_now; - } - if (resume_thread(threadID) != B_OK) { - fprintf(stderr, "failed starting thread: error code %08lx\n", threadID); - failed_already = 1; - goto exit_now; - } - - waitRV = wait_for_thread(threadID, &threadRV); - if (debug_mode) - PR_ASSERT(waitRV == B_OK); - else if (waitRV != B_OK) { - failed_already = 1; - goto exit_now; - } - -#else - if (!debug_mode) - failed_already=1; - else - printf("The attach test does not apply to this platform because\n" - "either this platform does not have native threads or the\n" - "test needs to be written for this platform.\n"); - goto exit_now; -#endif - -exit_now: - if(failed_already) - return 1; - else - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/bigfile2.c nspr-4.10.7/mozilla/nsprpub/pr/tests/bigfile2.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/bigfile2.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/bigfile2.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" - -#include -#include -#include -#ifdef _WIN32 -#include -#endif - -#define TEST_FILE_NAME "bigfile2.txt" -#ifdef WINCE -#define TEST_FILE_NAME_FOR_CREATEFILE L"bigfile2.txt" -#else -#define TEST_FILE_NAME_FOR_CREATEFILE TEST_FILE_NAME -#endif - -#define MESSAGE "Hello world!" -#define MESSAGE_SIZE 13 - -int main(int argc, char **argv) -{ - PRFileDesc *fd; - PRInt64 offset, position; - PRInt32 nbytes; - char buf[MESSAGE_SIZE]; -#ifdef _WIN32 - HANDLE hFile; - LARGE_INTEGER li; -#endif /* _WIN32 */ - - LL_I2L(offset, 1); - LL_SHL(offset, offset, 32); - - fd = PR_Open(TEST_FILE_NAME, - PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0666); - if (fd == NULL) { - fprintf(stderr, "PR_Open failed\n"); - exit(1); - } - position = PR_Seek64(fd, offset, PR_SEEK_SET); - if (!LL_GE_ZERO(position)) { - fprintf(stderr, "PR_Seek64 failed\n"); - exit(1); - } - PR_ASSERT(LL_EQ(position, offset)); - strcpy(buf, MESSAGE); - nbytes = PR_Write(fd, buf, sizeof(buf)); - if (nbytes != sizeof(buf)) { - fprintf(stderr, "PR_Write failed\n"); - exit(1); - } - if (PR_Close(fd) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - - memset(buf, 0, sizeof(buf)); - -#ifdef _WIN32 - hFile = CreateFile(TEST_FILE_NAME_FOR_CREATEFILE, GENERIC_READ, 0, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) { - fprintf(stderr, "CreateFile failed\n"); - exit(1); - } - li.QuadPart = offset; - li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN); - if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) { - fprintf(stderr, "SetFilePointer failed\n"); - exit(1); - } - PR_ASSERT(li.QuadPart == offset); - if (ReadFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) { - fprintf(stderr, "ReadFile failed\n"); - exit(1); - } - PR_ASSERT(nbytes == sizeof(buf)); - if (strcmp(buf, MESSAGE)) { - fprintf(stderr, "corrupt data:$%s$\n", buf); - exit(1); - } - if (CloseHandle(hFile) == 0) { - fprintf(stderr, "CloseHandle failed\n"); - exit(1); - } -#endif /* _WIN32 */ - - if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) { - fprintf(stderr, "PR_Delete failed\n"); - exit(1); - } - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/bigfile3.c nspr-4.10.7/mozilla/nsprpub/pr/tests/bigfile3.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/bigfile3.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/bigfile3.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" - -#include -#include -#include -#ifdef _WIN32 -#include -#endif - -#define TEST_FILE_NAME "bigfile3.txt" -#ifdef WINCE -#define TEST_FILE_NAME_FOR_CREATEFILE L"bigfile3.txt" -#else -#define TEST_FILE_NAME_FOR_CREATEFILE TEST_FILE_NAME -#endif - -#define MESSAGE "Hello world!" -#define MESSAGE_SIZE 13 - -int main(int argc, char **argv) -{ - PRFileDesc *fd; - PRInt64 offset, position; - PRInt32 nbytes; - char buf[MESSAGE_SIZE]; -#ifdef _WIN32 - HANDLE hFile; - LARGE_INTEGER li; -#endif /* _WIN32 */ - - LL_I2L(offset, 1); - LL_SHL(offset, offset, 32); - -#ifdef _WIN32 - hFile = CreateFile(TEST_FILE_NAME_FOR_CREATEFILE, GENERIC_WRITE, 0, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) { - fprintf(stderr, "CreateFile failed\n"); - exit(1); - } - li.QuadPart = offset; - li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN); - if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) { - fprintf(stderr, "SetFilePointer failed\n"); - exit(1); - } - PR_ASSERT(li.QuadPart == offset); - strcpy(buf, MESSAGE); - if (WriteFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) { - fprintf(stderr, "WriteFile failed\n"); - exit(1); - } - PR_ASSERT(nbytes == sizeof(buf)); - if (CloseHandle(hFile) == 0) { - fprintf(stderr, "CloseHandle failed\n"); - exit(1); - } -#endif /* _WIN32 */ - - memset(buf, 0, sizeof(buf)); - - fd = PR_Open(TEST_FILE_NAME, PR_RDONLY, 0666); - if (fd == NULL) { - fprintf(stderr, "PR_Open failed\n"); - exit(1); - } - position = PR_Seek64(fd, offset, PR_SEEK_SET); - if (!LL_GE_ZERO(position)) { - fprintf(stderr, "PR_Seek64 failed\n"); - exit(1); - } - PR_ASSERT(LL_EQ(position, offset)); - nbytes = PR_Read(fd, buf, sizeof(buf)); - if (nbytes != sizeof(buf)) { - fprintf(stderr, "PR_Read failed\n"); - exit(1); - } - if (strcmp(buf, MESSAGE)) { - fprintf(stderr, "corrupt data:$%s$\n", buf); - exit(1); - } - if (PR_Close(fd) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - - if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) { - fprintf(stderr, "PR_Delete failed\n"); - exit(1); - } - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/bigfile.c nspr-4.10.7/mozilla/nsprpub/pr/tests/bigfile.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/bigfile.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/bigfile.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,291 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prmem.h" -#include "prprf.h" -#include "prinit.h" -#include "prerror.h" -#include "prthread.h" - -#include "plerror.h" -#include "plgetopt.h" - -#define DEFAULT_COUNT 10 -#define DEFAULT_FILESIZE 1 -#define BUFFER_SIZE 1000000 - -typedef enum {v_silent, v_whisper, v_shout} Verbosity; -static void Verbose(Verbosity, const char*, const char*, PRIntn); - -#define VERBOSE(_l, _m) Verbose(_l, _m, __FILE__, __LINE__) - -static PRIntn test_result = 2; -static PRFileDesc *output = NULL; -static PRIntn verbose = v_silent; -static PRIntn filesize = DEFAULT_FILESIZE; - -static PRIntn Usage(void) -{ - PR_fprintf(output, "Bigfile test usage:\n"); - PR_fprintf(output, ">bigfile [-G] [-d] [-v[*v]] [-s ] \n"); - PR_fprintf(output, "\td\tdebug mode (equivalent to -vvv)\t(false)\n"); - PR_fprintf(output, "\tv\tAdditional levels of output\t(none)\n"); - PR_fprintf(output, "\tk\tKeep data file after exit\t(false)\n"); - PR_fprintf(output, "\ts \tFile size in megabytes\t\t(1 megabyte)\n"); - PR_fprintf(output, "\t\tName of test file\t(none)\n"); - return 2; /* nothing happened */ -} /* Usage */ - -static PRStatus DeleteIfFound(const char *filename) -{ - PRStatus rv; - VERBOSE(v_shout, "Checking for existing file"); - rv = PR_Access(filename, PR_ACCESS_WRITE_OK); - if (PR_SUCCESS == rv) - { - VERBOSE(v_shout, "Deleting existing file"); - rv = PR_Delete(filename); - if (PR_FAILURE == rv) VERBOSE(v_shout, "Cannot delete big file"); - } - else if (PR_FILE_NOT_FOUND_ERROR != PR_GetError()) - VERBOSE(v_shout, "Cannot access big file"); - else rv = PR_SUCCESS; - return rv; -} /* DeleteIfFound */ - -static PRIntn Error(const char *msg, const char *filename) -{ - PRInt32 error = PR_GetError(); - if (NULL != msg) - { - if (0 == error) PR_fprintf(output, msg); - else PL_FPrintError(output, msg); - } - (void)DeleteIfFound(filename); - if (v_shout == verbose) PR_Abort(); - return 1; -} /* Error */ - -static void Verbose( - Verbosity level, const char *msg, const char *file, PRIntn line) -{ - if (level <= verbose) - PR_fprintf(output, "[%s : %d]: %s\n", file, line, msg); -} /* Verbose */ - -static void PrintInfo(PRFileInfo64 *info, const char *filename) -{ - PRExplodedTime tm; - char ctime[40], mtime[40]; - static const char *types[] = {"FILE", "DIRECTORY", "OTHER"}; - PR_fprintf( - output, "[%s : %d]: File info for %s\n", - __FILE__, __LINE__, filename); - PR_fprintf( - output, " type: %s, size: %llu bytes,\n", - types[info->type - 1], info->size); - - PR_ExplodeTime(info->creationTime, PR_GMTParameters, &tm); - (void)PR_FormatTime(ctime, sizeof(ctime), "%c GMT", &tm); - PR_ExplodeTime(info->modifyTime, PR_GMTParameters, &tm); - (void)PR_FormatTime(mtime, sizeof(mtime), "%c GMT", &tm); - - PR_fprintf( - output, " creation: %s,\n modify: %s\n", ctime, mtime); -} /* PrintInfo */ - -int main(int argc, char **argv) -{ - PRStatus rv; - char *buffer; - PLOptStatus os; - PRInt32 loop, bytes; - PRFileInfo small_info; - PRFileInfo64 big_info; - PRBool keep = PR_FALSE; - PRFileDesc *file = NULL; - const char *filename = NULL; - PRIntn count = DEFAULT_COUNT; - PRInt64 filesize64, big_answer, big_size, one_meg, zero_meg, big_fragment; - PRInt64 sevenFox = LL_INIT(0,0x7fffffff); - - PLOptState *opt = PL_CreateOptState(argc, argv, "dtvhs:"); - - output = PR_GetSpecialFD(PR_StandardError); - PR_STDIO_INIT(); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: - filename = opt->value; - break; - case 'd': /* debug mode */ - verbose = v_shout; - break; - case 'k': /* keep file */ - keep = PR_TRUE; - break; - case 'v': /* verbosity */ - if (v_shout > verbose) verbose += 1; - break; - case 'c': /* loop counter */ - count = atoi(opt->value); - break; - case 's': /* filesize */ - filesize = atoi(opt->value); - break; - case 'h': /* confused */ - default: - return Usage(); - } - } - PL_DestroyOptState(opt); - - if (0 == count) count = DEFAULT_COUNT; - if (0 == filesize) filesize = DEFAULT_FILESIZE; - if (NULL == filename) - { -#ifdef SYMBIAN -#define FILE_NAME "c:\\data\\bigfile.dat" -#else -#define FILE_NAME "bigfile.dat" -#endif - if (DEFAULT_FILESIZE != filesize) return Usage(); - else filename = FILE_NAME; - } - - if (PR_FAILURE == DeleteIfFound(filename)) return 1; - - test_result = 0; - - LL_I2L(zero_meg, 0); - LL_I2L(one_meg, 1000000); - LL_I2L(filesize64, filesize); - buffer = (char*)PR_MALLOC(BUFFER_SIZE); - LL_I2L(big_fragment, BUFFER_SIZE); - LL_MUL(filesize64, filesize64, one_meg); - - for (loop = 0; loop < BUFFER_SIZE; ++loop) buffer[loop] = (char)loop; - - VERBOSE(v_whisper, "Creating big file"); - file = PR_Open(filename, PR_CREATE_FILE | PR_WRONLY, 0666); - if (NULL == file) return Error("PR_Open()", filename); - - VERBOSE(v_whisper, "Testing available space in empty file"); - big_answer = file->methods->available64(file); - if (!LL_IS_ZERO(big_answer)) return Error("empty available64()", filename); - - LL_SUB(big_size, filesize64, one_meg); - VERBOSE(v_whisper, "Creating sparse big file by seeking to end"); - big_answer = file->methods->seek64(file, big_size, PR_SEEK_SET); - if (!LL_EQ(big_answer, big_size)) return Error("seek", filename); - - VERBOSE(v_whisper, "Writing block at end of sparse file"); - bytes = file->methods->write(file, buffer, BUFFER_SIZE); - if (bytes != BUFFER_SIZE) return Error("write", filename); - - VERBOSE(v_whisper, "Testing available space at end of sparse file"); - big_answer = file->methods->available64(file); - if (!LL_IS_ZERO(big_answer)) return Error("eof available64()", filename); - - VERBOSE(v_whisper, "Getting big info on sparse big file"); - rv = file->methods->fileInfo64(file, &big_info); - if (PR_FAILURE == rv) return Error("fileInfo64()", filename); - if (v_shout <= verbose) PrintInfo(&big_info, filename); - - VERBOSE(v_whisper, "Getting small info on sparse big file"); - rv = file->methods->fileInfo(file, &small_info); - if (LL_CMP(sevenFox, <, filesize64) && (PR_SUCCESS == rv)) - { - VERBOSE(v_whisper, "Should have failed and didn't"); - return Error("fileInfo()", filename); - } - else if (LL_CMP(sevenFox, >, filesize64) && (PR_FAILURE == rv)) - { - VERBOSE(v_whisper, "Should have succeeded and didn't"); - return Error("fileInfo()", filename); - } - - VERBOSE(v_whisper, "Rewinding big file"); - big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_SET); - if (!LL_IS_ZERO(big_answer)) return Error("rewind seek64()", filename); - - VERBOSE(v_whisper, "Establishing available space in rewound file"); - big_answer = file->methods->available64(file); - if (LL_NE(filesize64, big_answer)) - return Error("bof available64()", filename); - - VERBOSE(v_whisper, "Closing big file"); - rv = file->methods->close(file); - if (PR_FAILURE == rv) return Error("close()", filename); - - VERBOSE(v_whisper, "Reopening big file"); - file = PR_Open(filename, PR_RDWR, 0666); - if (NULL == file) return Error("open failed", filename); - - VERBOSE(v_whisper, "Checking available data in reopened file"); - big_answer = file->methods->available64(file); - if (LL_NE(filesize64, big_answer)) - return Error("reopened available64()", filename); - - big_answer = zero_meg; - VERBOSE(v_whisper, "Rewriting every byte of big file data"); - do - { - bytes = file->methods->write(file, buffer, BUFFER_SIZE); - if (bytes != BUFFER_SIZE) - return Error("write", filename); - LL_ADD(big_answer, big_answer, big_fragment); - } while (LL_CMP(big_answer, <, filesize64)); - - VERBOSE(v_whisper, "Checking position at eof"); - big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_CUR); - if (LL_NE(big_answer, filesize64)) - return Error("file size error", filename); - - VERBOSE(v_whisper, "Testing available space at eof"); - big_answer = file->methods->available64(file); - if (!LL_IS_ZERO(big_answer)) - return Error("eof available64()", filename); - - VERBOSE(v_whisper, "Rewinding full file"); - big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_SET); - if (!LL_IS_ZERO(big_answer)) return Error("bof seek64()", filename); - - VERBOSE(v_whisper, "Testing available space in rewound file"); - big_answer = file->methods->available64(file); - if (LL_NE(big_answer, filesize64)) return Error("bof available64()", filename); - - VERBOSE(v_whisper, "Seeking to end of big file"); - big_answer = file->methods->seek64(file, filesize64, PR_SEEK_SET); - if (LL_NE(big_answer, filesize64)) return Error("eof seek64()", filename); - - VERBOSE(v_whisper, "Getting info on big file while it's open"); - rv = file->methods->fileInfo64(file, &big_info); - if (PR_FAILURE == rv) return Error("fileInfo64()", filename); - if (v_shout <= verbose) PrintInfo(&big_info, filename); - - VERBOSE(v_whisper, "Closing big file"); - rv = file->methods->close(file); - if (PR_FAILURE == rv) return Error("close()", filename); - - VERBOSE(v_whisper, "Getting info on big file after it's closed"); - rv = PR_GetFileInfo64(filename, &big_info); - if (PR_FAILURE == rv) return Error("fileInfo64()", filename); - if (v_shout <= verbose) PrintInfo(&big_info, filename); - - VERBOSE(v_whisper, "Deleting big file"); - rv = PR_Delete(filename); - if (PR_FAILURE == rv) return Error("PR_Delete()", filename); - - PR_DELETE(buffer); - return test_result; -} /* main */ - -/* bigfile.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/bug1test.c nspr-4.10.7/mozilla/nsprpub/pr/tests/bug1test.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/bug1test.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/bug1test.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,225 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -Attached is a test program that uses the nspr1 to demonstrate a bug -under NT4.0. The fix has already been mentioned (add a ResetEvent just -before leaving the critical section in _PR_CondWait in hwmon.c). -*/ - -#include "prthread.h" -#include "prtypes.h" -#include "prinit.h" -#include "prmon.h" -#include "prlog.h" - -typedef struct Arg_s -{ - PRInt32 a, b; -} Arg_t; - -PRMonitor* gMonitor; // the monitor -PRInt32 gReading; // number of read locks -PRInt32 gWriteWaiting; // number of threads waiting for write lock -PRInt32 gReadWaiting; // number of threads waiting for read lock - -PRInt32 gCounter; // a counter - - // stats -PRInt32 gReads; // number of successful reads -PRInt32 gMaxReads; // max number of simultaneous reads -PRInt32 gMaxWriteWaits; // max number of writes that waited for read -PRInt32 gMaxReadWaits; // max number of reads that waited for write wait - - -void spin (PRInt32 aDelay) -{ - PRInt32 index; - PRInt32 delay = aDelay * 1000; - - PR_Sleep(0); - - // randomize delay a bit - delay = (delay / 2) + (PRInt32)((float)delay * - ((float)rand () / (float)RAND_MAX)); - - for (index = 0; index < delay * 10; index++) - // consume a bunch of cpu cycles - ; - PR_Sleep(0); -} - -void doWriteThread (void* arg) -{ - PRInt32 last; - Arg_t *args = (Arg_t*)arg; - PRInt32 aWorkDelay = args->a, aWaitDelay = args->b; - PR_Sleep(0); - - while (1) - { - // -- enter write lock - PR_EnterMonitor (gMonitor); - - if (0 < gReading) // wait for read locks to go away - { - PRIntervalTime fiveSecs = PR_SecondsToInterval(5); - - gWriteWaiting++; - if (gWriteWaiting > gMaxWriteWaits) // stats - gMaxWriteWaits = gWriteWaiting; - while (0 < gReading) - PR_Wait (gMonitor, fiveSecs); - gWriteWaiting--; - } - // -- write lock entered - - last = gCounter; - gCounter++; - - spin (aWorkDelay); - - PR_ASSERT (gCounter == (last + 1)); // test invariance - - // -- exit write lock -// if (0 < gReadWaiting) // notify waiting reads (do it anyway to show off the CondWait bug) - PR_NotifyAll (gMonitor); - - PR_ExitMonitor (gMonitor); - // -- write lock exited - - spin (aWaitDelay); - } -} - -void doReadThread (void* arg) -{ - PRInt32 last; - Arg_t *args = (Arg_t*)arg; - PRInt32 aWorkDelay = args->a, aWaitDelay = args->b; - PR_Sleep(0); - - while (1) - { - // -- enter read lock - PR_EnterMonitor (gMonitor); - - if (0 < gWriteWaiting) // give up the monitor to waiting writes - { - PRIntervalTime fiveSecs = PR_SecondsToInterval(5); - - gReadWaiting++; - if (gReadWaiting > gMaxReadWaits) // stats - gMaxReadWaits = gReadWaiting; - while (0 < gWriteWaiting) - PR_Wait (gMonitor, fiveSecs); - gReadWaiting--; - } - - gReading++; - - gReads++; // stats - if (gReading > gMaxReads) // stats - gMaxReads = gReading; - - PR_ExitMonitor (gMonitor); - // -- read lock entered - - last = gCounter; - - spin (aWorkDelay); - - PR_ASSERT (gCounter == last); // test invariance - - // -- exit read lock - PR_EnterMonitor (gMonitor); // read unlock - gReading--; - -// if ((0 == gReading) && (0 < gWriteWaiting)) // notify waiting writes (do it anyway to show off the CondWait bug) - PR_NotifyAll (gMonitor); - PR_ExitMonitor (gMonitor); - // -- read lock exited - - spin (aWaitDelay); - } -} - - -void fireThread ( - char* aName, void (*aProc)(void *arg), Arg_t *aArg) -{ - PRThread *thread = PR_CreateThread( - PR_USER_THREAD, aProc, aArg, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); -} - -int pseudoMain (int argc, char** argv, char *pad) -{ - PRInt32 lastWriteCount = gCounter; - PRInt32 lastReadCount = gReads; - Arg_t a1 = {500, 250}; - Arg_t a2 = {500, 500}; - Arg_t a3 = {250, 500}; - Arg_t a4 = {750, 250}; - Arg_t a5 = {100, 750}; - Arg_t a6 = {100, 500}; - Arg_t a7 = {100, 750}; - - gMonitor = PR_NewMonitor (); - - fireThread ("R1", doReadThread, &a1); - fireThread ("R2", doReadThread, &a2); - fireThread ("R3", doReadThread, &a3); - fireThread ("R4", doReadThread, &a4); - - fireThread ("W1", doWriteThread, &a5); - fireThread ("W2", doWriteThread, &a6); - fireThread ("W3", doWriteThread, &a7); - - fireThread ("R5", doReadThread, &a1); - fireThread ("R6", doReadThread, &a2); - fireThread ("R7", doReadThread, &a3); - fireThread ("R8", doReadThread, &a4); - - fireThread ("W4", doWriteThread, &a5); - fireThread ("W5", doWriteThread, &a6); - fireThread ("W6", doWriteThread, &a7); - - while (1) - { - PRInt32 writeCount, readCount; - PRIntervalTime fiveSecs = PR_SecondsToInterval(5); - PR_Sleep (fiveSecs); // get out of the way - - // print some stats, not threadsafe, informative only - writeCount = gCounter; - readCount = gReads; - printf ("\ntick %d writes (+%d), %d reads (+%d) [max %d, %d, %d]", - writeCount, writeCount - lastWriteCount, - readCount, readCount - lastReadCount, - gMaxReads, gMaxWriteWaits, gMaxReadWaits); - lastWriteCount = writeCount; - lastReadCount = readCount; - gMaxReads = gMaxWriteWaits = gMaxReadWaits = 0; - } - return 0; -} - - -static void padStack (int argc, char** argv) -{ - char pad[512]; /* Work around bug in nspr on windoze */ - pseudoMain (argc, argv, pad); -} - -int main(int argc, char **argv) -{ - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - padStack (argc, argv); -} - - -/* bug1test.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/cleanup.c nspr-4.10.7/mozilla/nsprpub/pr/tests/cleanup.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/cleanup.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/cleanup.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prprf.h" -#include "prio.h" -#include "prinit.h" -#include "prthread.h" -#include "prinrval.h" - -#include "plgetopt.h" - -#include - -static void PR_CALLBACK Thread(void *sleep) -{ - PR_Sleep(PR_SecondsToInterval((PRUint32)sleep)); - printf("Thread exiting\n"); -} - -static void Help(void) -{ - PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); - PR_fprintf(err, "Cleanup usage: [-g] [-s n] [-t n] [-c n] [-h]\n"); - PR_fprintf(err, "\t-c Call cleanup before exiting (default: false)\n"); - PR_fprintf(err, "\t-G Use global threads only (default: local)\n"); - PR_fprintf(err, "\t-t n Number of threads involved (default: 1)\n"); - PR_fprintf(err, "\t-s n Seconds thread(s) should dally (defaut: 10)\n"); - PR_fprintf(err, "\t-S n Seconds main() should dally (defaut: 5)\n"); - PR_fprintf(err, "\t-C n Value to set concurrency (default 1)\n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PLOptStatus os; - PRBool cleanup = PR_FALSE; - PRThreadScope type = PR_LOCAL_THREAD; - PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); - PLOptState *opt = PL_CreateOptState(argc, argv, "Ghs:S:t:cC:"); - PRIntn concurrency = 1, child_sleep = 10, main_sleep = 5, threads = 1; - - PR_STDIO_INIT(); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'c': /* call PR_Cleanup() before exiting */ - cleanup = PR_TRUE; - break; - case 'G': /* local vs global threads */ - type = PR_GLOBAL_THREAD; - break; - case 's': /* time to sleep */ - child_sleep = atoi(opt->value); - break; - case 'S': /* time to sleep */ - main_sleep = atoi(opt->value); - break; - case 'C': /* number of cpus to create */ - concurrency = atoi(opt->value); - break; - case 't': /* number of threads to create */ - threads = atoi(opt->value); - break; - case 'h': /* user wants some guidance */ - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_fprintf(err, "Cleanup settings\n"); - PR_fprintf(err, "\tThread type: %s\n", - (PR_LOCAL_THREAD == type) ? "LOCAL" : "GLOBAL"); - PR_fprintf(err, "\tConcurrency: %d\n", concurrency); - PR_fprintf(err, "\tNumber of threads: %d\n", threads); - PR_fprintf(err, "\tThread sleep: %d\n", child_sleep); - PR_fprintf(err, "\tMain sleep: %d\n", main_sleep); - PR_fprintf(err, "\tCleanup will %sbe called\n\n", (cleanup) ? "" : "NOT "); - - PR_SetConcurrency(concurrency); - - while (threads-- > 0) - (void)PR_CreateThread( - PR_USER_THREAD, Thread, (void*)child_sleep, PR_PRIORITY_NORMAL, - type, PR_UNJOINABLE_THREAD, 0); - PR_Sleep(PR_SecondsToInterval(main_sleep)); - - if (cleanup) PR_Cleanup(); - - PR_fprintf(err, "main() exiting\n"); - return 0; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/cltsrv.c nspr-4.10.7/mozilla/nsprpub/pr/tests/cltsrv.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/cltsrv.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/cltsrv.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1182 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * - * Notes: - * [1] lth. The call to Sleep() is a hack to get the test case to run - * on Windows 95. Without it, the test case fails with an error - * WSAECONNRESET following a recv() call. The error is caused by the - * server side thread termination without a shutdown() or closesocket() - * call. Windows docmunentation suggests that this is predicted - * behavior; that other platforms get away with it is ... serindipity. - * The test case should shutdown() or closesocket() before - * thread termination. I didn't have time to figure out where or how - * to do it. The Sleep() call inserts enough delay to allow the - * client side to recv() all his data before the server side thread - * terminates. Whew! ... - * - ** Modification History: - * 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. - * The debug mode will print all of the printfs associated with this test. - * The regress mode will be the default mode. Since the regress tool limits - * the output to a one line status:PASS or FAIL,all of the printf statements - * have been handled with an if (debug_mode) statement. - */ - -#include "prclist.h" -#include "prcvar.h" -#include "prerror.h" -#include "prinit.h" -#include "prinrval.h" -#include "prio.h" -#include "prlock.h" -#include "prlog.h" -#include "prtime.h" -#include "prmem.h" -#include "prnetdb.h" -#include "prprf.h" -#include "prthread.h" - -#include "pprio.h" -#include "primpl.h" - -#include "plstr.h" -#include "plerror.h" -#include "plgetopt.h" - -#include -#include - -#if defined(XP_UNIX) -#include -#endif - -/* -** This is the beginning of the test -*/ - -#define RECV_FLAGS 0 -#define SEND_FLAGS 0 -#define DEFAULT_LOW 0 -#define DEFAULT_HIGH 0 -#define BUFFER_SIZE 1024 -#define DEFAULT_BACKLOG 5 -#define DEFAULT_PORT 12849 -#define DEFAULT_CLIENTS 1 -#define ALLOWED_IN_ACCEPT 1 -#define DEFAULT_CLIPPING 1000 -#define DEFAULT_WORKERS_MIN 1 -#define DEFAULT_WORKERS_MAX 1 -#define DEFAULT_SERVER "localhost" -#define DEFAULT_EXECUTION_TIME 10 -#define DEFAULT_CLIENT_TIMEOUT 4000 -#define DEFAULT_SERVER_TIMEOUT 4000 -#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGH - -typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t; - -static void PR_CALLBACK Worker(void *arg); -typedef struct CSPool_s CSPool_t; -typedef struct CSWorker_s CSWorker_t; -typedef struct CSServer_s CSServer_t; -typedef enum Verbosity -{ - TEST_LOG_ALWAYS, - TEST_LOG_ERROR, - TEST_LOG_WARNING, - TEST_LOG_NOTICE, - TEST_LOG_INFO, - TEST_LOG_STATUS, - TEST_LOG_VERBOSE -} Verbosity; - -static PRInt32 domain = AF_INET; -static PRInt32 protocol = 6; /* TCP */ -static PRFileDesc *debug_out = NULL; -static PRBool debug_mode = PR_FALSE; -static PRBool pthread_stats = PR_FALSE; -static Verbosity verbosity = TEST_LOG_ALWAYS; -static PRThreadScope thread_scope = PR_LOCAL_THREAD; - -struct CSWorker_s -{ - PRCList element; /* list of the server's workers */ - - PRThread *thread; /* this worker objects thread */ - CSServer_t *server; /* back pointer to server structure */ -}; - -struct CSPool_s -{ - PRCondVar *exiting; - PRCondVar *acceptComplete; - PRUint32 accepting, active, workers; -}; - -struct CSServer_s -{ - PRCList list; /* head of worker list */ - - PRLock *ml; - PRThread *thread; /* the main server thread */ - PRCondVar *stateChange; - - PRUint16 port; /* port we're listening on */ - PRUint32 backlog; /* size of our listener backlog */ - PRFileDesc *listener; /* the fd accepting connections */ - - CSPool_t pool; /* statistics on worker threads */ - CSState_t state; /* the server's state */ - struct /* controlling worker counts */ - { - PRUint32 minimum, maximum, accepting; - } workers; - - /* statistics */ - PRIntervalTime started, stopped; - PRUint32 operations, bytesTransferred; -}; - -typedef struct CSDescriptor_s -{ - PRInt32 size; /* size of transfer */ - char filename[60]; /* filename, null padded */ -} CSDescriptor_t; - -typedef struct CSClient_s -{ - PRLock *ml; - PRThread *thread; - PRCondVar *stateChange; - PRNetAddr serverAddress; - - CSState_t state; - - /* statistics */ - PRIntervalTime started, stopped; - PRUint32 operations, bytesTransferred; -} CSClient_t; - -#define TEST_LOG(l, p, a) \ - do { \ - if (debug_mode || (p <= verbosity)) printf a; \ - } while (0) - -PRLogModuleInfo *cltsrv_log_file = NULL; - -#define MY_ASSERT(_expr) \ - ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__)) - -#define TEST_ASSERT(_expr) \ - ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__)) - -static void _MY_Assert(const char *s, const char *file, PRIntn ln) -{ - PL_PrintError(NULL); - PR_Assert(s, file, ln); -} /* _MY_Assert */ - -static PRBool Aborted(PRStatus rv) -{ - return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ? - PR_TRUE : PR_FALSE; -} - -static void TimeOfDayMessage(const char *msg, PRThread* me) -{ - char buffer[100]; - PRExplodedTime tod; - PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod); - (void)PR_FormatTime(buffer, sizeof(buffer), "%H:%M:%S", &tod); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("%s(0x%p): %s\n", msg, me, buffer)); -} /* TimeOfDayMessage */ - - -static void PR_CALLBACK Client(void *arg) -{ - PRStatus rv; - PRIntn index; - char buffer[1024]; - PRFileDesc *fd = NULL; - PRUintn clipping = DEFAULT_CLIPPING; - PRThread *me = PR_GetCurrentThread(); - CSClient_t *client = (CSClient_t*)arg; - CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); - PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT); - - - for (index = 0; index < sizeof(buffer); ++index) - buffer[index] = (char)index; - - client->started = PR_IntervalNow(); - - PR_Lock(client->ml); - client->state = cs_run; - PR_NotifyCondVar(client->stateChange); - PR_Unlock(client->ml); - - TimeOfDayMessage("Client started at", me); - - while (cs_run == client->state) - { - PRInt32 bytes, descbytes, filebytes, netbytes; - - (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer)); - TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, - ("\tClient(0x%p): connecting to server at %s\n", me, buffer)); - - fd = PR_Socket(domain, SOCK_STREAM, protocol); - TEST_ASSERT(NULL != fd); - rv = PR_Connect(fd, &client->serverAddress, timeout); - if (PR_FAILURE == rv) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): conection failed (%d, %d)\n", - me, PR_GetError(), PR_GetOSError())); - goto aborted; - } - - memset(descriptor, 0, sizeof(*descriptor)); - descriptor->size = PR_htonl(descbytes = rand() % clipping); - PR_snprintf( - descriptor->filename, sizeof(descriptor->filename), - "CS%p%p-%p.dat", client->started, me, client->operations); - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes)); - bytes = PR_Send( - fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout); - if (sizeof(CSDescriptor_t) != bytes) - { - if (Aborted(PR_FAILURE)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): send descriptor timeout\n", me)); - goto retry; - } - } - TEST_ASSERT(sizeof(*descriptor) == bytes); - - netbytes = 0; - while (netbytes < descbytes) - { - filebytes = sizeof(buffer); - if ((descbytes - netbytes) < filebytes) - filebytes = descbytes - netbytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tClient(0x%p): sending %d bytes\n", me, filebytes)); - bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); - if (filebytes != bytes) - { - if (Aborted(PR_FAILURE)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): send data timeout\n", me)); - goto retry; - } - } - TEST_ASSERT(bytes == filebytes); - netbytes += bytes; - } - filebytes = 0; - while (filebytes < descbytes) - { - netbytes = sizeof(buffer); - if ((descbytes - filebytes) < netbytes) - netbytes = descbytes - filebytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tClient(0x%p): receiving %d bytes\n", me, netbytes)); - bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); - if (-1 == bytes) - { - if (Aborted(PR_FAILURE)) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): receive data aborted\n", me)); - goto aborted; - } - else if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): receive data timeout\n", me)); - else - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): receive error (%d, %d)\n", - me, PR_GetError(), PR_GetOSError())); - goto retry; - } - if (0 == bytes) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tClient(0x%p): unexpected end of stream\n", - PR_GetCurrentThread())); - break; - } - filebytes += bytes; - } - - rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); - if (Aborted(rv)) goto aborted; - TEST_ASSERT(PR_SUCCESS == rv); -retry: - (void)PR_Close(fd); fd = NULL; - TEST_LOG( - cltsrv_log_file, TEST_LOG_INFO, - ("\tClient(0x%p): disconnected from server\n", me)); - - PR_Lock(client->ml); - client->operations += 1; - client->bytesTransferred += 2 * descbytes; - rv = PR_WaitCondVar(client->stateChange, rand() % clipping); - PR_Unlock(client->ml); - if (Aborted(rv)) break; - } - -aborted: - client->stopped = PR_IntervalNow(); - - PR_ClearInterrupt(); - if (NULL != fd) rv = PR_Close(fd); - - PR_Lock(client->ml); - client->state = cs_exit; - PR_NotifyCondVar(client->stateChange); - PR_Unlock(client->ml); - PR_DELETE(descriptor); - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("\tClient(0x%p): stopped after %u operations and %u bytes\n", - PR_GetCurrentThread(), client->operations, client->bytesTransferred)); - -} /* Client */ - -static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server) -{ - PRStatus drv, rv; - char buffer[1024]; - PRFileDesc *file = NULL; - PRThread * me = PR_GetCurrentThread(); - PRInt32 bytes, descbytes, netbytes, filebytes = 0; - CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); - PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tProcessRequest(0x%p): receiving desciptor\n", me)); - bytes = PR_Recv( - fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout); - if (-1 == bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto exit; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tProcessRequest(0x%p): receive timeout\n", me)); - } - goto exit; - } - if (0 == bytes) - { - rv = PR_FAILURE; - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tProcessRequest(0x%p): unexpected end of file\n", me)); - goto exit; - } - descbytes = PR_ntohl(descriptor->size); - TEST_ASSERT(sizeof(*descriptor) == bytes); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", - me, descbytes, descriptor->filename)); - - file = PR_Open( - descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666); - if (NULL == file) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tProcessRequest(0x%p): open file timeout\n", me)); - goto aborted; - } - } - TEST_ASSERT(NULL != file); - - filebytes = 0; - while (filebytes < descbytes) - { - netbytes = sizeof(buffer); - if ((descbytes - filebytes) < netbytes) - netbytes = descbytes - filebytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)); - bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); - if (-1 == bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): receive data timeout\n", me)); - goto aborted; - } - /* - * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED) - * on NT here. This is equivalent to ECONNRESET on Unix. - * -wtc - */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_WARNING, - ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", - me, PR_GetError(), PR_GetOSError())); - goto aborted; - } - if(0 == bytes) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_WARNING, - ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)); - rv = PR_FAILURE; - goto aborted; - } - filebytes += bytes; - netbytes = bytes; - /* The byte count for PR_Write should be positive */ - MY_ASSERT(netbytes > 0); - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes)); - bytes = PR_Write(file, buffer, netbytes); - if (netbytes != bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): write file timeout\n", me)); - goto aborted; - } - } - TEST_ASSERT(bytes > 0); - } - - PR_Lock(server->ml); - server->operations += 1; - server->bytesTransferred += filebytes; - PR_Unlock(server->ml); - - rv = PR_Close(file); - if (Aborted(rv)) goto aborted; - TEST_ASSERT(PR_SUCCESS == rv); - file = NULL; - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename)); - file = PR_Open(descriptor->filename, PR_RDONLY, 0); - if (NULL == file) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): open file timeout\n", - PR_GetCurrentThread())); - goto aborted; - } - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n", - me, PR_GetError(), PR_GetOSError())); - goto aborted; - } - TEST_ASSERT(NULL != file); - - netbytes = 0; - while (netbytes < descbytes) - { - filebytes = sizeof(buffer); - if ((descbytes - netbytes) < filebytes) - filebytes = descbytes - netbytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes)); - bytes = PR_Read(file, buffer, filebytes); - if (filebytes != bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): read file timeout\n", me)); - else - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", - me, PR_GetError(), PR_GetOSError())); - goto aborted; - } - TEST_ASSERT(bytes > 0); - netbytes += bytes; - filebytes = bytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes)); - bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); - if (filebytes != bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): send data timeout\n", me)); - goto aborted; - } - break; - } - TEST_ASSERT(bytes > 0); - } - - PR_Lock(server->ml); - server->bytesTransferred += filebytes; - PR_Unlock(server->ml); - - rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); - if (Aborted(rv)) goto aborted; - - rv = PR_Close(file); - if (Aborted(rv)) goto aborted; - TEST_ASSERT(PR_SUCCESS == rv); - file = NULL; - -aborted: - PR_ClearInterrupt(); - if (NULL != file) PR_Close(file); - drv = PR_Delete(descriptor->filename); - TEST_ASSERT(PR_SUCCESS == drv); -exit: - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tProcessRequest(0x%p): Finished\n", me)); - - PR_DELETE(descriptor); - -#if defined(WIN95) - PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */ -#endif - return rv; -} /* ProcessRequest */ - -static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool) -{ - CSWorker_t *worker = PR_NEWZAP(CSWorker_t); - worker->server = server; - PR_INIT_CLIST(&worker->element); - worker->thread = PR_CreateThread( - PR_USER_THREAD, Worker, worker, - DEFAULT_SERVER_PRIORITY, thread_scope, - PR_UNJOINABLE_THREAD, 0); - if (NULL == worker->thread) - { - PR_DELETE(worker); - return PR_FAILURE; - } - - TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, - ("\tCreateWorker(0x%p): create new worker (0x%p)\n", - PR_GetCurrentThread(), worker->thread)); - - return PR_SUCCESS; -} /* CreateWorker */ - -static void PR_CALLBACK Worker(void *arg) -{ - PRStatus rv; - PRNetAddr from; - PRFileDesc *fd = NULL; - PRThread *me = PR_GetCurrentThread(); - CSWorker_t *worker = (CSWorker_t*)arg; - CSServer_t *server = worker->server; - CSPool_t *pool = &server->pool; - - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1)); - - PR_Lock(server->ml); - PR_APPEND_LINK(&worker->element, &server->list); - pool->workers += 1; /* define our existance */ - - while (cs_run == server->state) - { - while (pool->accepting >= server->workers.accepting) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tWorker(0x%p): waiting for accept slot[%d]\n", - me, pool->accepting)); - rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT); - if (Aborted(rv) || (cs_run != server->state)) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("\tWorker(0x%p): has been %s\n", - me, (Aborted(rv) ? "interrupted" : "stopped"))); - goto exit; - } - } - pool->accepting += 1; /* how many are really in accept */ - PR_Unlock(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tWorker(0x%p): calling accept\n", me)); - fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT); - - PR_Lock(server->ml); - pool->accepting -= 1; - PR_NotifyCondVar(pool->acceptComplete); - - if ((NULL == fd) && Aborted(PR_FAILURE)) - { - if (NULL != server->listener) - { - PR_Close(server->listener); - server->listener = NULL; - } - goto exit; - } - - if (NULL != fd) - { - /* - ** Create another worker of the total number of workers is - ** less than the minimum specified or we have none left in - ** accept() AND we're not over the maximum. - ** This sort of presumes that the number allowed in accept - ** is at least as many as the minimum. Otherwise we'll keep - ** creating new threads and deleting them soon after. - */ - PRBool another = - ((pool->workers < server->workers.minimum) || - ((0 == pool->accepting) - && (pool->workers < server->workers.maximum))) ? - PR_TRUE : PR_FALSE; - pool->active += 1; - PR_Unlock(server->ml); - - if (another) (void)CreateWorker(server, pool); - - rv = ProcessRequest(fd, server); - if (PR_SUCCESS != rv) - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tWorker(0x%p): server process ended abnormally\n", me)); - (void)PR_Close(fd); fd = NULL; - - PR_Lock(server->ml); - pool->active -= 1; - } - } - -exit: - PR_ClearInterrupt(); - PR_Unlock(server->ml); - - if (NULL != fd) - { - (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH); - (void)PR_Close(fd); - } - - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers)); - - PR_Lock(server->ml); - pool->workers -= 1; /* undefine our existance */ - PR_REMOVE_AND_INIT_LINK(&worker->element); - PR_NotifyCondVar(pool->exiting); - PR_Unlock(server->ml); - - PR_DELETE(worker); /* destruction of the "worker" object */ - -} /* Worker */ - -static void PR_CALLBACK Server(void *arg) -{ - PRStatus rv; - PRNetAddr serverAddress; - PRThread *me = PR_GetCurrentThread(); - CSServer_t *server = (CSServer_t*)arg; - PRSocketOptionData sockOpt; - - server->listener = PR_Socket(domain, SOCK_STREAM, protocol); - - sockOpt.option = PR_SockOpt_Reuseaddr; - sockOpt.value.reuse_addr = PR_TRUE; - rv = PR_SetSocketOption(server->listener, &sockOpt); - TEST_ASSERT(PR_SUCCESS == rv); - - memset(&serverAddress, 0, sizeof(serverAddress)); - if (PR_AF_INET6 != domain) - rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress); - else - rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, DEFAULT_PORT, - &serverAddress); - rv = PR_Bind(server->listener, &serverAddress); - TEST_ASSERT(PR_SUCCESS == rv); - - rv = PR_Listen(server->listener, server->backlog); - TEST_ASSERT(PR_SUCCESS == rv); - - server->started = PR_IntervalNow(); - TimeOfDayMessage("Server started at", me); - - PR_Lock(server->ml); - server->state = cs_run; - PR_NotifyCondVar(server->stateChange); - PR_Unlock(server->ml); - - /* - ** Create the first worker (actually, a thread that accepts - ** connections and then processes the work load as needed). - ** From this point on, additional worker threads are created - ** as they are needed by existing worker threads. - */ - rv = CreateWorker(server, &server->pool); - TEST_ASSERT(PR_SUCCESS == rv); - - /* - ** From here on this thread is merely hanging around as the contact - ** point for the main test driver. It's just waiting for the driver - ** to declare the test complete. - */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tServer(0x%p): waiting for state change\n", me)); - - PR_Lock(server->ml); - while ((cs_run == server->state) && !Aborted(rv)) - { - rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(server->ml); - PR_ClearInterrupt(); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_INFO, - ("\tServer(0x%p): shutting down workers\n", me)); - - /* - ** Get all the worker threads to exit. They know how to - ** clean up after themselves, so this is just a matter of - ** waiting for clorine in the pool to take effect. During - ** this stage we're ignoring interrupts. - */ - server->workers.minimum = server->workers.maximum = 0; - - PR_Lock(server->ml); - while (!PR_CLIST_IS_EMPTY(&server->list)) - { - PRCList *head = PR_LIST_HEAD(&server->list); - CSWorker_t *worker = (CSWorker_t*)head; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker)); - rv = PR_Interrupt(worker->thread); - TEST_ASSERT(PR_SUCCESS == rv); - PR_REMOVE_AND_INIT_LINK(head); - } - - while (server->pool.workers > 0) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("\tServer(0x%p): waiting for %u workers to exit\n", - me, server->pool.workers)); - (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT); - } - - server->state = cs_exit; - PR_NotifyCondVar(server->stateChange); - PR_Unlock(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("\tServer(0x%p): stopped after %u operations and %u bytes\n", - me, server->operations, server->bytesTransferred)); - - if (NULL != server->listener) PR_Close(server->listener); - server->stopped = PR_IntervalNow(); - -} /* Server */ - -static void WaitForCompletion(PRIntn execution) -{ - while (execution > 0) - { - PRIntn dally = (execution > 30) ? 30 : execution; - PR_Sleep(PR_SecondsToInterval(dally)); - if (pthread_stats) PT_FPrintStats(debug_out, "\nPThread Statistics\n"); - execution -= dally; - } -} /* WaitForCompletion */ - -static void Help(void) -{ - PR_fprintf(debug_out, "cltsrv test program usage:\n"); - PR_fprintf(debug_out, "\t-a threads allowed in accept (5)\n"); - PR_fprintf(debug_out, "\t-b backlock for listen (5)\n"); - PR_fprintf(debug_out, "\t-c number of clients to create (1)\n"); - PR_fprintf(debug_out, "\t-f low water mark for fd caching (0)\n"); - PR_fprintf(debug_out, "\t-F high water mark for fd caching (0)\n"); - PR_fprintf(debug_out, "\t-w minimal number of server threads (1)\n"); - PR_fprintf(debug_out, "\t-W maximum number of server threads (1)\n"); - PR_fprintf(debug_out, "\t-e duration of the test in seconds (10)\n"); - PR_fprintf(debug_out, "\t-s dsn name of server (localhost)\n"); - PR_fprintf(debug_out, "\t-G use GLOBAL threads (LOCAL)\n"); - PR_fprintf(debug_out, "\t-X use XTP as transport (TCP)\n"); - PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n"); - PR_fprintf(debug_out, "\t-v verbosity (accumulative) (0)\n"); - PR_fprintf(debug_out, "\t-p pthread statistics (FALSE)\n"); - PR_fprintf(debug_out, "\t-d debug mode (FALSE)\n"); - PR_fprintf(debug_out, "\t-h this message\n"); -} /* Help */ - -static Verbosity IncrementVerbosity(void) -{ - PRIntn verboge = (PRIntn)verbosity + 1; - return (Verbosity)verboge; -} /* IncrementVerbosity */ - -int main(int argc, char** argv) -{ - PRUintn index; - PRBool boolean; - CSClient_t *client; - PRStatus rv, joinStatus; - CSServer_t *server = NULL; - - PRUintn backlog = DEFAULT_BACKLOG; - PRUintn clients = DEFAULT_CLIENTS; - const char *serverName = DEFAULT_SERVER; - PRBool serverIsLocal = PR_TRUE; - PRUintn accepting = ALLOWED_IN_ACCEPT; - PRUintn workersMin = DEFAULT_WORKERS_MIN; - PRUintn workersMax = DEFAULT_WORKERS_MAX; - PRIntn execution = DEFAULT_EXECUTION_TIME; - PRIntn low = DEFAULT_LOW, high = DEFAULT_HIGH; - - /* - * -G use global threads - * -a threads allowed in accept - * -b backlock for listen - * -c number of clients to create - * -f low water mark for caching FDs - * -F high water mark for caching FDs - * -w minimal number of server threads - * -W maximum number of server threads - * -e duration of the test in seconds - * -s dsn name of server (implies no server here) - * -v verbosity - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:f:F:w:W:e:s:vdhp"); - - debug_out = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'G': /* use global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'X': /* use XTP as transport */ - protocol = 36; - break; - case '6': /* Use IPv6 */ - domain = PR_AF_INET6; - break; - case 'a': /* the value for accepting */ - accepting = atoi(opt->value); - break; - case 'b': /* the value for backlock */ - backlog = atoi(opt->value); - break; - case 'c': /* number of client threads */ - clients = atoi(opt->value); - break; - case 'f': /* low water fd cache */ - low = atoi(opt->value); - break; - case 'F': /* low water fd cache */ - high = atoi(opt->value); - break; - case 'w': /* minimum server worker threads */ - workersMin = atoi(opt->value); - break; - case 'W': /* maximum server worker threads */ - workersMax = atoi(opt->value); - break; - case 'e': /* program execution time in seconds */ - execution = atoi(opt->value); - break; - case 's': /* server's address */ - serverName = opt->value; - break; - case 'v': /* verbosity */ - verbosity = IncrementVerbosity(); - break; - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'p': /* pthread mode */ - pthread_stats = PR_TRUE; - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE; - if (0 == execution) execution = DEFAULT_EXECUTION_TIME; - if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX; - if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN; - if (0 == accepting) accepting = ALLOWED_IN_ACCEPT; - if (0 == backlog) backlog = DEFAULT_BACKLOG; - - if (workersMin > accepting) accepting = workersMin; - - PR_STDIO_INIT(); - TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread()); - - cltsrv_log_file = PR_NewLogModule("cltsrv_log"); - MY_ASSERT(NULL != cltsrv_log_file); - boolean = PR_SetLogFile("cltsrv.log"); - MY_ASSERT(boolean); - - rv = PR_SetFDCacheSize(low, high); - PR_ASSERT(PR_SUCCESS == rv); - - if (serverIsLocal) - { - /* Establish the server */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_INFO, - ("main(0x%p): starting server\n", PR_GetCurrentThread())); - - server = PR_NEWZAP(CSServer_t); - PR_INIT_CLIST(&server->list); - server->state = cs_init; - server->ml = PR_NewLock(); - server->backlog = backlog; - server->port = DEFAULT_PORT; - server->workers.minimum = workersMin; - server->workers.maximum = workersMax; - server->workers.accepting = accepting; - server->stateChange = PR_NewCondVar(server->ml); - server->pool.exiting = PR_NewCondVar(server->ml); - server->pool.acceptComplete = PR_NewCondVar(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("main(0x%p): creating server thread\n", PR_GetCurrentThread())); - - server->thread = PR_CreateThread( - PR_USER_THREAD, Server, server, PR_PRIORITY_HIGH, - thread_scope, PR_JOINABLE_THREAD, 0); - TEST_ASSERT(NULL != server->thread); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("main(0x%p): waiting for server init\n", PR_GetCurrentThread())); - - PR_Lock(server->ml); - while (server->state == cs_init) - PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("main(0x%p): server init complete (port #%d)\n", - PR_GetCurrentThread(), server->port)); - } - - if (clients != 0) - { - /* Create all of the clients */ - PRHostEnt host; - char buffer[BUFFER_SIZE]; - client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t)); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("main(0x%p): creating %d client threads\n", - PR_GetCurrentThread(), clients)); - - if (!serverIsLocal) - { - rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host); - if (PR_SUCCESS != rv) - { - PL_FPrintError(PR_STDERR, "PR_GetHostByName"); - return 2; - } - } - - for (index = 0; index < clients; ++index) - { - client[index].state = cs_init; - client[index].ml = PR_NewLock(); - if (serverIsLocal) - { - if (PR_AF_INET6 != domain) - (void)PR_InitializeNetAddr( - PR_IpAddrLoopback, DEFAULT_PORT, - &client[index].serverAddress); - else - rv = PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, - DEFAULT_PORT, &client[index].serverAddress); - } - else - { - (void)PR_EnumerateHostEnt( - 0, &host, DEFAULT_PORT, &client[index].serverAddress); - } - client[index].stateChange = PR_NewCondVar(client[index].ml); - TEST_LOG( - cltsrv_log_file, TEST_LOG_INFO, - ("main(0x%p): creating client threads\n", PR_GetCurrentThread())); - client[index].thread = PR_CreateThread( - PR_USER_THREAD, Client, &client[index], PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - TEST_ASSERT(NULL != client[index].thread); - PR_Lock(client[index].ml); - while (cs_init == client[index].state) - PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(client[index].ml); - } - } - - /* Then just let them go at it for a bit */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("main(0x%p): waiting for execution interval (%d seconds)\n", - PR_GetCurrentThread(), execution)); - - WaitForCompletion(execution); - - TimeOfDayMessage("Shutting down", PR_GetCurrentThread()); - - if (clients != 0) - { - for (index = 0; index < clients; ++index) - { - TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, - ("main(0x%p): notifying client(0x%p) to stop\n", - PR_GetCurrentThread(), client[index].thread)); - - PR_Lock(client[index].ml); - if (cs_run == client[index].state) - { - client[index].state = cs_stop; - PR_Interrupt(client[index].thread); - while (cs_stop == client[index].state) - PR_WaitCondVar( - client[index].stateChange, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(client[index].ml); - - TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, - ("main(0x%p): joining client(0x%p)\n", - PR_GetCurrentThread(), client[index].thread)); - - joinStatus = PR_JoinThread(client[index].thread); - TEST_ASSERT(PR_SUCCESS == joinStatus); - PR_DestroyCondVar(client[index].stateChange); - PR_DestroyLock(client[index].ml); - } - PR_DELETE(client); - } - - if (NULL != server) - { - /* All clients joined - retrieve the server */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("main(0x%p): notifying server(0x%p) to stop\n", - PR_GetCurrentThread(), server->thread)); - - PR_Lock(server->ml); - server->state = cs_stop; - PR_Interrupt(server->thread); - while (cs_exit != server->state) - PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("main(0x%p): joining server(0x%p)\n", - PR_GetCurrentThread(), server->thread)); - joinStatus = PR_JoinThread(server->thread); - TEST_ASSERT(PR_SUCCESS == joinStatus); - - PR_DestroyCondVar(server->stateChange); - PR_DestroyCondVar(server->pool.exiting); - PR_DestroyCondVar(server->pool.acceptComplete); - PR_DestroyLock(server->ml); - PR_DELETE(server); - } - - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("main(0x%p): test complete\n", PR_GetCurrentThread())); - - PT_FPrintStats(debug_out, "\nPThread Statistics\n"); - - TimeOfDayMessage("Test exiting at", PR_GetCurrentThread()); - PR_Cleanup(); - return 0; -} /* main */ - -/* cltsrv.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/concur.c nspr-4.10.7/mozilla/nsprpub/pr/tests/concur.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/concur.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/concur.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: concur.c -** Description: test of adding and removing concurrency options -*/ - -#include "prcvar.h" -#include "prinit.h" -#include "prinrval.h" -#include "prlock.h" -#include "prprf.h" -#include "prmem.h" -#include "prlog.h" - -#include "plgetopt.h" - -#include "private/pprio.h" - -#include - -#define DEFAULT_RANGE 10 -#define DEFAULT_LOOPS 100 - -static PRThreadScope thread_scope = PR_LOCAL_THREAD; - -typedef struct Context -{ - PRLock *ml; - PRCondVar *cv; - PRIntn want, have; -} Context; - - -/* -** Make the instance of 'context' static (not on the stack) -** for Win16 threads -*/ -static Context context = {NULL, NULL, 0, 0}; - -static void PR_CALLBACK Dull(void *arg) -{ - Context *context = (Context*)arg; - PR_Lock(context->ml); - context->have += 1; - while (context->want >= context->have) - PR_WaitCondVar(context->cv, PR_INTERVAL_NO_TIMEOUT); - context->have -= 1; - PR_Unlock(context->ml); -} /* Dull */ - -PRIntn PR_CALLBACK Concur(PRIntn argc, char **argv) -{ - PRUintn cpus; - PLOptStatus os; - PRThread **threads; - PRBool debug = PR_FALSE; - PRUintn range = DEFAULT_RANGE; - PRStatus rc; - PRUintn cnt; - PRUintn loops = DEFAULT_LOOPS; - PRIntervalTime hundredMills = PR_MillisecondsToInterval(100); - PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:r:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'G': /* GLOBAL threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'd': /* debug mode */ - debug = PR_TRUE; - break; - case 'r': /* range limit */ - range = atoi(opt->value); - break; - case 'l': /* loop counter */ - loops = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (0 == range) range = DEFAULT_RANGE; - if (0 == loops) loops = DEFAULT_LOOPS; - - context.ml = PR_NewLock(); - context.cv = PR_NewCondVar(context.ml); - - if (debug) - PR_fprintf( - PR_STDERR, "Testing with %d CPUs and %d interations\n", range, loops); - - threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * range); - while (--loops > 0) - { - for (cpus = 1; cpus <= range; ++cpus) - { - PR_SetConcurrency(cpus); - context.want = cpus; - - threads[cpus - 1] = PR_CreateThread( - PR_USER_THREAD, Dull, &context, PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - } - - PR_Sleep(hundredMills); - - for (cpus = range; cpus > 0; cpus--) - { - PR_SetConcurrency(cpus); - context.want = cpus - 1; - - PR_Lock(context.ml); - PR_NotifyCondVar(context.cv); - PR_Unlock(context.ml); - } - for(cnt = 0; cnt < range; cnt++) { - rc = PR_JoinThread(threads[cnt]); - PR_ASSERT(rc == PR_SUCCESS); - } - } - - - if (debug) - PR_fprintf( - PR_STDERR, "Waiting for %d thread(s) to exit\n", context.have); - - while (context.have > 0) PR_Sleep(hundredMills); - - if (debug) - PR_fprintf( - PR_STDERR, "Finished [want: %d, have: %d]\n", - context.want, context.have); - - PR_DestroyLock(context.ml); - PR_DestroyCondVar(context.cv); - PR_DELETE(threads); - - PR_fprintf(PR_STDERR, "PASSED\n"); - - return 0; -} /* Concur */ - -int main(int argc, char **argv) -{ - PR_STDIO_INIT(); - return PR_Initialize(Concur, argc, argv, 0); -} /* main */ - -/* concur.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/cvar2.c nspr-4.10.7/mozilla/nsprpub/pr/tests/cvar2.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/cvar2.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/cvar2.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,960 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1996 - Netscape Communications Corporation -** -** Name: cvar2.c -** -** Description: Simple test creates several local and global threads; -** half use a single,shared condvar, and the -** other half have their own condvar. The main thread then loops -** notifying them to wakeup. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ - -#include "nspr.h" -#include "plerror.h" -#include "plgetopt.h" - -#include -#include -#include - -int _debug_on = 0; -#define DPRINTF(arg) if (_debug_on) printf arg - -#define DEFAULT_COUNT 100 -#define DEFAULT_THREADS 5 -PRInt32 count = DEFAULT_COUNT; - -typedef struct threadinfo { - PRThread *thread; - PRInt32 id; - PRBool internal; - PRInt32 *tcount; - PRLock *lock; - PRCondVar *cvar; - PRIntervalTime timeout; - PRInt32 loops; - - PRLock *exitlock; - PRCondVar *exitcvar; - PRInt32 *exitcount; -} threadinfo; - -/* -** Make exitcount, tcount static. for Win16. -*/ -static PRInt32 exitcount=0; -static PRInt32 tcount=0; - - -/* Thread that gets notified; many threads share the same condvar */ -void PR_CALLBACK -SharedCondVarThread(void *_info) -{ - threadinfo *info = (threadinfo *)_info; - PRInt32 index; - - for (index=0; indexloops; index++) { - PR_Lock(info->lock); - if (*info->tcount == 0) - PR_WaitCondVar(info->cvar, info->timeout); -#if 0 - printf("shared thread %ld notified in loop %ld\n", info->id, index); -#endif - (*info->tcount)--; - PR_Unlock(info->lock); - - PR_Lock(info->exitlock); - (*info->exitcount)++; - PR_NotifyCondVar(info->exitcvar); - PR_Unlock(info->exitlock); - } -#if 0 - printf("shared thread %ld terminating\n", info->id); -#endif -} - -/* Thread that gets notified; no other threads use the same condvar */ -void PR_CALLBACK -PrivateCondVarThread(void *_info) -{ - threadinfo *info = (threadinfo *)_info; - PRInt32 index; - - for (index=0; indexloops; index++) { - PR_Lock(info->lock); - if (*info->tcount == 0) { - DPRINTF(("PrivateCondVarThread: thread 0x%lx waiting on cvar = 0x%lx\n", - PR_GetCurrentThread(), info->cvar)); - PR_WaitCondVar(info->cvar, info->timeout); - } -#if 0 - printf("solo thread %ld notified in loop %ld\n", info->id, index); -#endif - (*info->tcount)--; - PR_Unlock(info->lock); - - PR_Lock(info->exitlock); - (*info->exitcount)++; - PR_NotifyCondVar(info->exitcvar); -DPRINTF(("PrivateCondVarThread: thread 0x%lx notified exitcvar = 0x%lx cnt = %ld\n", - PR_GetCurrentThread(), info->exitcvar,(*info->exitcount))); - PR_Unlock(info->exitlock); - } -#if 0 - printf("solo thread %ld terminating\n", info->id); -#endif -} - -void -CreateTestThread(threadinfo *info, - PRInt32 id, - PRLock *lock, - PRCondVar *cvar, - PRInt32 loops, - PRIntervalTime timeout, - PRInt32 *tcount, - PRLock *exitlock, - PRCondVar *exitcvar, - PRInt32 *exitcount, - PRBool shared, - PRThreadScope scope) -{ - info->id = id; - info->internal = (shared) ? PR_FALSE : PR_TRUE; - info->lock = lock; - info->cvar = cvar; - info->loops = loops; - info->timeout = timeout; - info->tcount = tcount; - info->exitlock = exitlock; - info->exitcvar = exitcvar; - info->exitcount = exitcount; - info->thread = PR_CreateThread( - PR_USER_THREAD, - shared?SharedCondVarThread:PrivateCondVarThread, - info, - PR_PRIORITY_NORMAL, - scope, - PR_JOINABLE_THREAD, - 0); - if (!info->thread) - PL_PrintError("error creating thread\n"); -} - - -void -CondVarTestSUU(void *_arg) -{ - PRInt32 arg = (PRInt32)_arg; - PRInt32 index, loops; - threadinfo *list; - PRLock *sharedlock; - PRCondVar *sharedcvar; - PRLock *exitlock; - PRCondVar *exitcvar; - - exitcount=0; - tcount=0; - list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); - - sharedlock = PR_NewLock(); - sharedcvar = PR_NewCondVar(sharedlock); - exitlock = PR_NewLock(); - exitcvar = PR_NewCondVar(exitlock); - - /* Create the threads */ - for(index=0; index= arg); - exitcount -= arg; - PR_Unlock(exitlock); - } - - /* Join all the threads */ - for(index=0; index<(arg); index++) - PR_JoinThread(list[index].thread); - - PR_DestroyCondVar(sharedcvar); - PR_DestroyLock(sharedlock); - PR_DestroyCondVar(exitcvar); - PR_DestroyLock(exitlock); - - PR_DELETE(list); -} - -void -CondVarTestSUK(void *_arg) -{ - PRInt32 arg = (PRInt32)_arg; - PRInt32 index, loops; - threadinfo *list; - PRLock *sharedlock; - PRCondVar *sharedcvar; - PRLock *exitlock; - PRCondVar *exitcvar; - exitcount=0; - tcount=0; - - list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); - - sharedlock = PR_NewLock(); - sharedcvar = PR_NewCondVar(sharedlock); - exitlock = PR_NewLock(); - exitcvar = PR_NewCondVar(exitlock); - - /* Create the threads */ - for(index=0; index= arg); - exitcount -= arg; - PR_Unlock(exitlock); -#if 0 - printf("threads ready\n"); -#endif - } - - /* Join all the threads */ - for(index=0; index<(arg); index++) - PR_JoinThread(list[index].thread); - - PR_DestroyCondVar(sharedcvar); - PR_DestroyLock(sharedlock); - PR_DestroyCondVar(exitcvar); - PR_DestroyLock(exitlock); - - PR_DELETE(list); -} - -void -CondVarTestPUU(void *_arg) -{ - PRInt32 arg = (PRInt32)_arg; - PRInt32 index, loops; - threadinfo *list; - PRLock *sharedlock; - PRCondVar *sharedcvar; - PRLock *exitlock; - PRCondVar *exitcvar; - PRInt32 *tcount, *saved_tcount; - - exitcount=0; - list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); - saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4)); - - sharedlock = PR_NewLock(); - sharedcvar = PR_NewCondVar(sharedlock); - exitlock = PR_NewLock(); - exitcvar = PR_NewCondVar(exitlock); - - /* Create the threads */ - for(index=0; index= arg); - exitcount -= arg; - PR_Unlock(exitlock); - } - - /* Join all the threads */ - for(index=0; index<(arg); index++) { - DPRINTF(("CondVarTestPUU: joining thread 0x%lx\n",list[index].thread)); - PR_JoinThread(list[index].thread); - if (list[index].internal) { - PR_Lock(list[index].lock); - PR_DestroyCondVar(list[index].cvar); - PR_Unlock(list[index].lock); - PR_DestroyLock(list[index].lock); - } - } - - PR_DestroyCondVar(sharedcvar); - PR_DestroyLock(sharedlock); - PR_DestroyCondVar(exitcvar); - PR_DestroyLock(exitlock); - - PR_DELETE(list); - PR_DELETE(saved_tcount); -} - -void -CondVarTestPUK(void *_arg) -{ - PRInt32 arg = (PRInt32)_arg; - PRInt32 index, loops; - threadinfo *list; - PRLock *sharedlock; - PRCondVar *sharedcvar; - PRLock *exitlock; - PRCondVar *exitcvar; - PRInt32 *tcount, *saved_tcount; - - exitcount=0; - list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); - saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4)); - - sharedlock = PR_NewLock(); - sharedcvar = PR_NewCondVar(sharedlock); - exitlock = PR_NewLock(); - exitcvar = PR_NewCondVar(exitlock); - - /* Create the threads */ - for(index=0; index= arg); - exitcount -= arg; - PR_Unlock(exitlock); - } - - /* Join all the threads */ - for(index=0; index<(arg); index++) { - PR_JoinThread(list[index].thread); - if (list[index].internal) { - PR_Lock(list[index].lock); - PR_DestroyCondVar(list[index].cvar); - PR_Unlock(list[index].lock); - PR_DestroyLock(list[index].lock); - } - } - - PR_DestroyCondVar(sharedcvar); - PR_DestroyLock(sharedlock); - PR_DestroyCondVar(exitcvar); - PR_DestroyLock(exitlock); - - PR_DELETE(list); - PR_DELETE(saved_tcount); -} - -void -CondVarTest(void *_arg) -{ - PRInt32 arg = (PRInt32)_arg; - PRInt32 index, loops; - threadinfo *list; - PRLock *sharedlock; - PRCondVar *sharedcvar; - PRLock *exitlock; - PRCondVar *exitcvar; - PRInt32 *ptcount, *saved_ptcount; - - exitcount=0; - tcount=0; - list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); - saved_ptcount = ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4)); - - sharedlock = PR_NewLock(); - sharedcvar = PR_NewCondVar(sharedlock); - exitlock = PR_NewLock(); - exitcvar = PR_NewCondVar(exitlock); - - /* Create the threads */ - for(index=0; index= arg*4); - exitcount -= arg*4; - PR_Unlock(exitlock); -#if 0 - printf("threads ready\n"); -#endif - } - - /* Join all the threads */ - for(index=0; index<(arg*4); index++) { - PR_JoinThread(list[index].thread); - if (list[index].internal) { - PR_Lock(list[index].lock); - PR_DestroyCondVar(list[index].cvar); - PR_Unlock(list[index].lock); - PR_DestroyLock(list[index].lock); - } - } - - PR_DestroyCondVar(sharedcvar); - PR_DestroyLock(sharedlock); - PR_DestroyCondVar(exitcvar); - PR_DestroyLock(exitlock); - - PR_DELETE(list); - PR_DELETE(saved_ptcount); -} - -void -CondVarTimeoutTest(void *_arg) -{ - PRInt32 arg = (PRInt32)_arg; - PRInt32 index, loops; - threadinfo *list; - PRLock *sharedlock; - PRCondVar *sharedcvar; - PRLock *exitlock; - PRCondVar *exitcvar; - - list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); - - sharedlock = PR_NewLock(); - sharedcvar = PR_NewCondVar(sharedlock); - exitlock = PR_NewLock(); - exitcvar = PR_NewCondVar(exitlock); - - /* Create the threads */ - for(index=0; index= arg*4); - exitcount -= arg*4; - PR_Unlock(exitlock); - } - - - /* Join all the threads */ - for(index=0; index<(arg*4); index++) { - PR_JoinThread(list[index].thread); - if (list[index].internal) { - PR_Lock(list[index].lock); - PR_DestroyCondVar(list[index].cvar); - PR_Unlock(list[index].lock); - PR_DestroyLock(list[index].lock); - } - } - - PR_DestroyCondVar(sharedcvar); - PR_DestroyLock(sharedlock); - PR_DestroyCondVar(exitcvar); - PR_DestroyLock(exitlock); - - PR_DELETE(list); -} - -void -CondVarMixedTest(void *_arg) -{ - PRInt32 arg = (PRInt32)_arg; - PRInt32 index, loops; - threadinfo *list; - PRLock *sharedlock; - PRCondVar *sharedcvar; - PRLock *exitlock; - PRCondVar *exitcvar; - PRInt32 *ptcount; - - exitcount=0; - tcount=0; - list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); - ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4)); - - sharedlock = PR_NewLock(); - sharedcvar = PR_NewCondVar(sharedlock); - exitlock = PR_NewLock(); - exitcvar = PR_NewCondVar(exitlock); - - /* Create the threads */ - for(index=0; index= arg*4); - exitcount -= arg*4; - PR_Unlock(exitlock); - } - - /* Join all the threads */ - for(index=0; index<(arg*4); index++) { - PR_JoinThread(list[index].thread); - if (list[index].internal) { - PR_Lock(list[index].lock); - PR_DestroyCondVar(list[index].cvar); - PR_Unlock(list[index].lock); - PR_DestroyLock(list[index].lock); - } - } - - PR_DestroyCondVar(sharedcvar); - PR_DestroyLock(sharedlock); - - PR_DELETE(list); -} - -void -CondVarCombinedTest(void *arg) -{ - PRThread *threads[3]; - - threads[0] = PR_CreateThread(PR_USER_THREAD, - CondVarTest, - (void *)arg, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - 0); - threads[1] = PR_CreateThread(PR_USER_THREAD, - CondVarTimeoutTest, - (void *)arg, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - 0); - threads[2] = PR_CreateThread(PR_USER_THREAD, - CondVarMixedTest, - (void *)arg, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - 0); - - PR_JoinThread(threads[0]); - PR_JoinThread(threads[1]); - PR_JoinThread(threads[2]); -} - -/************************************************************************/ - -static void Measure(void (*func)(void *), PRInt32 arg, const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)((void *)arg); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - - printf("%40s: %6.2f usec\n", msg, d / count); -} - -static PRIntn PR_CALLBACK RealMain(int argc, char **argv) -{ - PRInt32 threads, default_threads = DEFAULT_THREADS; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "vc:t:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'v': /* debug mode */ - _debug_on = 1; - break; - case 'c': /* loop counter */ - count = atoi(opt->value); - break; - case 't': /* number of threads involved */ - default_threads = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (0 == count) count = DEFAULT_COUNT; - if (0 == default_threads) default_threads = DEFAULT_THREADS; - - printf("\n\ -CondVar Test: \n\ - \n\ -Simple test creates several local and global threads; half use a single,\n\ -shared condvar, and the other half have their own condvar. The main \n\ -thread then loops notifying them to wakeup. \n\ - \n\ -The timeout test is very similar except that the threads are not \n\ -notified. They will all wakeup on a 1 second timeout. \n\ - \n\ -The mixed test combines the simple test and the timeout test; every \n\ -third thread is notified, the other threads are expected to timeout \n\ -correctly. \n\ - \n\ -Lastly, the combined test creates a thread for each of the above three \n\ -cases and they all run simultaneously. \n\ - \n\ -This test is run with %d, %d, %d, and %d threads of each type.\n\n", -default_threads, default_threads*2, default_threads*3, default_threads*4); - - PR_SetConcurrency(2); - - for (threads = default_threads; threads < default_threads*5; threads+=default_threads) { - printf("\n%ld Thread tests\n", threads); - Measure(CondVarTestSUU, threads, "Condvar simple test shared UU"); - Measure(CondVarTestSUK, threads, "Condvar simple test shared UK"); - Measure(CondVarTestPUU, threads, "Condvar simple test priv UU"); - Measure(CondVarTestPUK, threads, "Condvar simple test priv UK"); - Measure(CondVarTest, threads, "Condvar simple test All"); - Measure(CondVarTimeoutTest, threads, "Condvar timeout test"); -#if 0 - Measure(CondVarMixedTest, threads, "Condvar mixed timeout test"); - Measure(CondVarCombinedTest, threads, "Combined condvar test"); -#endif - } - - printf("PASS\n"); - - return 0; -} - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/cvar.c nspr-4.10.7/mozilla/nsprpub/pr/tests/cvar.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/cvar.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/cvar.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,291 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1996 - Netscape Communications Corporation -** -** Name: cvar.c -** -** Description: Tests Condition Variable Operations -** -** Modification History: -** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** 12-June-97 Revert to return code 0 and 1. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ - -#include "nspr.h" - -/* Used to get the command line option */ -#include "plgetopt.h" - -#include -#include -#include - -PRMonitor *mon; -#define DEFAULT_COUNT 1000 -PRInt32 count = 0; -PRIntn debug_mode; - -#define kQSIZE 1 - -typedef struct { - PRLock *bufLock; - int startIdx; - int numFull; - PRCondVar *notFull; - PRCondVar *notEmpty; - void *data[kQSIZE]; -} CircBuf; - -static PRBool failed = PR_FALSE; - -/* -** NewCB creates and initializes a new circular buffer. -*/ -static CircBuf* NewCB(void) -{ - CircBuf *cbp; - - cbp = PR_NEW(CircBuf); - if (cbp == NULL) - return (NULL); - - cbp->bufLock = PR_NewLock(); - cbp->startIdx = 0; - cbp->numFull = 0; - cbp->notFull = PR_NewCondVar(cbp->bufLock); - cbp->notEmpty = PR_NewCondVar(cbp->bufLock); - - return (cbp); -} - -/* -** DeleteCB frees a circular buffer. -*/ -static void DeleteCB(CircBuf *cbp) -{ - PR_DestroyLock(cbp->bufLock); - PR_DestroyCondVar(cbp->notFull); - PR_DestroyCondVar(cbp->notEmpty); - PR_DELETE(cbp); -} - - -/* -** PutCBData puts new data on the queue. If the queue is full, it waits -** until there is room. -*/ -static void PutCBData(CircBuf *cbp, void *data) -{ - PR_Lock(cbp->bufLock); - /* wait while the buffer is full */ - while (cbp->numFull == kQSIZE) - PR_WaitCondVar(cbp->notFull,PR_INTERVAL_NO_TIMEOUT); - cbp->data[(cbp->startIdx + cbp->numFull) % kQSIZE] = data; - cbp->numFull += 1; - - /* let a waiting reader know that there is data */ - PR_NotifyCondVar(cbp->notEmpty); - PR_Unlock(cbp->bufLock); - -} - - -/* -** GetCBData gets the oldest data on the queue. If the queue is empty, it waits -** until new data appears. -*/ -static void* GetCBData(CircBuf *cbp) -{ - void *data; - - PR_Lock(cbp->bufLock); - /* wait while the buffer is empty */ - while (cbp->numFull == 0) - PR_WaitCondVar(cbp->notEmpty,PR_INTERVAL_NO_TIMEOUT); - data = cbp->data[cbp->startIdx]; - cbp->startIdx =(cbp->startIdx + 1) % kQSIZE; - cbp->numFull -= 1; - - /* let a waiting writer know that there is room */ - PR_NotifyCondVar(cbp->notFull); - PR_Unlock(cbp->bufLock); - - return (data); -} - - -/************************************************************************/ - -static int alive; - -static void PR_CALLBACK CXReader(void *arg) -{ - CircBuf *cbp = (CircBuf *)arg; - PRInt32 i, n; - void *data; - - n = count / 2; - for (i = 0; i < n; i++) { - data = GetCBData(cbp); - if ((int)data != i) - if (debug_mode) printf("data mismatch at for i = %d usec\n", i); - } - - PR_EnterMonitor(mon); - --alive; - PR_Notify(mon); - PR_ExitMonitor(mon); -} - -static void PR_CALLBACK CXWriter(void *arg) -{ - CircBuf *cbp = (CircBuf *)arg; - PRInt32 i, n; - - n = count / 2; - for (i = 0; i < n; i++) - PutCBData(cbp, (void *)i); - - PR_EnterMonitor(mon); - --alive; - PR_Notify(mon); - PR_ExitMonitor(mon); -} - -static void CondWaitContextSwitch(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *t1, *t2; - CircBuf *cbp; - - PR_EnterMonitor(mon); - - alive = 2; - - cbp = NewCB(); - - t1 = PR_CreateThread(PR_USER_THREAD, - CXReader, cbp, - PR_PRIORITY_NORMAL, - scope1, - PR_UNJOINABLE_THREAD, - 0); - PR_ASSERT(t1); - t2 = PR_CreateThread(PR_USER_THREAD, - CXWriter, cbp, - PR_PRIORITY_NORMAL, - scope2, - PR_UNJOINABLE_THREAD, - 0); - PR_ASSERT(t2); - - /* Wait for both of the threads to exit */ - while (alive) { - PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); - } - - DeleteCB(cbp); - - PR_ExitMonitor(mon); -} - -static void CondWaitContextSwitchUU(void) -{ - CondWaitContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD); -} - -static void CondWaitContextSwitchUK(void) -{ - CondWaitContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); -} - -static void CondWaitContextSwitchKK(void) -{ - CondWaitContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); -} - -/************************************************************************/ - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - - if (debug_mode) printf("%40s: %6.2f usec\n", msg, d / count); - - if (0 == d) failed = PR_TRUE; -} - -static PRIntn PR_CALLBACK RealMain(int argc, char **argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name [-d] [-c n] - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dc:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'c': /* loop count */ - count = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (0 == count) count = DEFAULT_COUNT; - - mon = PR_NewMonitor(); - - Measure(CondWaitContextSwitchUU, "cond var wait context switch- user/user"); - Measure(CondWaitContextSwitchUK, "cond var wait context switch- user/kernel"); - Measure(CondWaitContextSwitchKK, "cond var wait context switch- kernel/kernel"); - - PR_DestroyMonitor(mon); - - if (debug_mode) printf("%s\n", (failed) ? "FAILED" : "PASSED"); - - if(failed) - return 1; - else - return 0; -} - - -int main(int argc, char *argv[]) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/tests/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/tests/.cvsignore 2001-05-12 05:06:18.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dbmalloc1.c nspr-4.10.7/mozilla/nsprpub/pr/tests/dbmalloc1.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dbmalloc1.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dbmalloc1.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: dbmalloc1.c (OBSOLETE) -** -** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** -** 12-June-97 AGarcia Revert to return code 0 and 1, remove debug option (obsolete). -***********************************************************************/ - - -/*********************************************************************** -** Includes -***********************************************************************/ -#include -#include -#include "nspr.h" - -PRIntn failed_already=0; -PRIntn debug_mode; - -/* variable used for both r1 and r2 tests */ -int should_fail =0; -int actually_failed=0; - - -void -r1 -( - void -) -{ - int i; - actually_failed=0; - for( i = 0; i < 5; i++ ) - { - void *x = PR_MALLOC(128); - if( (void *)0 == x ) { - if (debug_mode) printf("\tMalloc %d failed.\n", i+1); - actually_failed = 1; - } - PR_DELETE(x); - } - - if (((should_fail != actually_failed) & (!debug_mode))) failed_already=1; - - - return; -} - -void -r2 -( - void -) -{ - int i; - - for( i = 0; i <= 5; i++ ) - { - should_fail =0; - if( 0 == i ) { - if (debug_mode) printf("No malloc should fail:\n"); - } - else { - if (debug_mode) printf("Malloc %d should fail:\n", i); - should_fail = 1; - } - PR_SetMallocCountdown(i); - r1(); - PR_ClearMallocCountdown(); - } -} - -int main(int argc, char **argv) -{ - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - r2(); - - if(failed_already) - return 1; - else - return 0; - - -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dbmalloc.c nspr-4.10.7/mozilla/nsprpub/pr/tests/dbmalloc.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dbmalloc.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dbmalloc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,310 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: dbmalloc.c -** -** Description: Testing malloc (OBSOLETE) -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ -#include -#include -#include -#include -#include "nspr.h" - -void -usage -( - void -) -{ - fprintf(stderr, "Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename [...]\n"); - exit(0); -} - -typedef struct node_struct -{ - struct node_struct *next, *prev; - int line; - char value[4]; -} - node_t, - *node_pt; - -node_pt get_node(const char *line) -{ - node_pt rv; - int l = strlen(line); - rv = (node_pt)PR_MALLOC(sizeof(node_t) + l + 1 - 4); - if( (node_pt)0 == rv ) return (node_pt)0; - memcpy(&rv->value[0], line, l+1); - rv->next = rv->prev = (node_pt)0; - return rv; -} - -void -dump -( - const char *name, - node_pt node, - int mf, - int debug -) -{ - if( (node_pt)0 != node->prev ) dump(name, node->prev, mf, debug); - if( 0 != debug ) printf("[%s]: %6d: %s", name, node->line, node->value); - if( node->line == mf ) fprintf(stderr, "[%s]: Line %d was allocated!\n", name, node->line); - if( (node_pt)0 != node->next ) dump(name, node->next, mf, debug); - return; -} - -void -release -( - node_pt node -) -{ - if( (node_pt)0 != node->prev ) release(node->prev); - if( (node_pt)0 != node->next ) release(node->next); - PR_DELETE(node); -} - -int -t2 -( - const char *name, - int mf, - int debug -) -{ - int rv; - FILE *fp; - int l = 0; - node_pt head = (node_pt)0; - char buffer[ BUFSIZ ]; - - fp = fopen(name, "r"); - if( (FILE *)0 == fp ) - { - fprintf(stderr, "[%s]: Cannot open \"%s.\"\n", name, name); - return -1; - } - - /* fgets mallocs a buffer, first time through. */ - if( (char *)0 == fgets(buffer, BUFSIZ, fp) ) - { - fprintf(stderr, "[%s]: \"%s\" is empty.\n", name, name); - (void)fclose(fp); - return -1; - } - - rewind(fp); - - if( PR_SUCCESS != PR_ClearMallocCount() ) - { - fprintf(stderr, "[%s]: Cannot clear malloc count.\n", name); - (void)fclose(fp); - return -1; - } - - if( PR_SUCCESS != PR_SetMallocCountdown(mf) ) - { - fprintf(stderr, "[%s]: Cannot set malloc countdown to %d\n", name, mf); - (void)fclose(fp); - return -1; - } - - while( fgets(buffer, BUFSIZ, fp) ) - { - node_pt n; - node_pt *w = &head; - - if( (strlen(buffer) == (BUFSIZ-1)) && (buffer[BUFSIZ-2] != '\n') ) - buffer[BUFSIZ-2] == '\n'; - - l++; - - n = get_node(buffer); - if( (node_pt)0 == n ) - { - printf("[%s]: Line %d: malloc failure!\n", name, l); - continue; - } - - n->line = l; - - while( 1 ) - { - int comp; - - if( (node_pt)0 == *w ) - { - *w = n; - break; - } - - comp = strcmp((*w)->value, n->value); - if( comp < 0 ) w = &(*w)->next; - else w = &(*w)->prev; - } - } - - (void)fclose(fp); - - dump(name, head, mf, debug); - - rv = PR_GetMallocCount(); - PR_ClearMallocCountdown(); - - release(head); - - return rv; -} - -int nf = 0; -int debug = 0; - -void -test -( - const char *name -) -{ - int n, i; - - extern int nf, debug; - - printf("[%s]: starting test 0\n", name); - n = t2(name, 0, debug); - if( -1 == n ) return; - printf("[%s]: test 0 had %ld allocations.\n", name, n); - - if( 0 >= n ) return; - - for( i = 0; i < nf; i++ ) - { - int which = rand() % n; - if( 0 == which ) printf("[%s]: starting test %d -- no allocation should fail\n", name, i+1); - else printf("[%s]: starting test %d -- allocation %d should fail\n", name, i+1, which); - (void)t2(name, which, debug); - printf("[%s]: test %d done.\n", name, i+1); - } - - return; -} - -int main(int argc, char **argv) -{ - int okay = 0; - int multithread = 0; - - struct threadlist - { - struct threadlist *next; - PRThread *thread; - } - *threadhead = (struct threadlist *)0; - - extern int nf, debug; - - srand(time(0)); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - printf("[main]: We %s using the debugging malloc.\n", - PR_IsDebuggingMalloc() ? "ARE" : "ARE NOT"); - - while( argv++, --argc ) - { - if( '-' == argv[0][0] ) - { - switch( argv[0][1] ) - { - case 'f': - nf = atoi(argv[0][2] ? &argv[0][2] : - --argc ? *++argv : "0"); - break; - case 'd': - debug = 1; - break; - case 'n': - debug = 0; - break; - case 'm': - multithread = 1; - break; - case 's': - multithread = 0; - break; - default: - usage(); - break; - } - } - else - { - FILE *fp = fopen(*argv, "r"); - if( (FILE *)0 == fp ) - { - fprintf(stderr, "Cannot open \"%s.\"\n", *argv); - continue; - } - - okay++; - (void)fclose(fp); - if( multithread ) - { - struct threadlist *n; - - n = (struct threadlist *)malloc(sizeof(struct threadlist)); - if( (struct threadlist *)0 == n ) - { - fprintf(stderr, "This is getting tedious. \"%s\"\n", *argv); - continue; - } - - n->next = threadhead; - n->thread = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))test, - *argv, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, - 0); - if( (PRThread *)0 == n->thread ) - { - fprintf(stderr, "Can't create thread for \"%s.\"\n", *argv); - continue; - } - else - { - threadhead = n; - } - } - else - { - test(*argv); - } - } - } - - if( okay == 0 ) usage(); - else while( (struct threadlist *)0 != threadhead ) - { - struct threadlist *x = threadhead->next; - (void)PR_JoinThread(threadhead->thread); - PR_DELETE(threadhead); - threadhead = x; - } - - return 0; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dceemu.c nspr-4.10.7/mozilla/nsprpub/pr/tests/dceemu.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dceemu.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dceemu.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: dceemu.c -** Description: testing the DCE emulation api -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete). -**/ - -/*********************************************************************** -** Includes -***********************************************************************/ - -#include "prlog.h" -#include "prinit.h" -#include "prpdce.h" - -#include -#include - -#if defined(_PR_DCETHREADS) - -PRIntn failed_already=0; -PRIntn debug_mode=0; - -static PRIntn prmain(PRIntn argc, char **argv) -{ - PRStatus rv; - PRLock *ml = PR_NewLock(); - PRCondVar *cv = PRP_NewNakedCondVar(); - PRIntervalTime tenmsecs = PR_MillisecondsToInterval(10); - - rv = PRP_TryLock(ml); - PR_ASSERT(PR_SUCCESS == rv); - if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; - - rv = PRP_TryLock(ml); - PR_ASSERT(PR_FAILURE == rv); - if ((rv != PR_FAILURE) & (!debug_mode)) failed_already=1; - - rv = PRP_NakedNotify(cv); - PR_ASSERT(PR_SUCCESS == rv); - if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; - - rv = PRP_NakedBroadcast(cv); - PR_ASSERT(PR_SUCCESS == rv); - if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; - - rv = PRP_NakedWait(cv, ml, tenmsecs); - PR_ASSERT(PR_SUCCESS == rv); - if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; - - PR_Unlock(ml); - - rv = PRP_NakedNotify(cv); - PR_ASSERT(PR_SUCCESS == rv); - if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; - - rv = PRP_NakedBroadcast(cv); - PR_ASSERT(PR_SUCCESS == rv); - if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; - - PRP_DestroyNakedCondVar(cv); - PR_DestroyLock(ml); - - if (debug_mode) printf("Test succeeded\n"); - - return 0; - -} /* prmain */ - -#endif /* #if defined(_PR_DCETHREADS) */ - -int main(int argc, char **argv) -{ - -#if defined(_PR_DCETHREADS) - PR_Initialize(prmain, argc, argv, 0); - if(failed_already) - return 1; - else - return 0; -#else - return 0; -#endif -} /* main */ - - -/* decemu.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/depend.c nspr-4.10.7/mozilla/nsprpub/pr/tests/depend.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/depend.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/depend.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1996 - Netscape Communications Corporation -** -** -** Name: depend.c -** Description: Test to enumerate the dependencies -* -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ -#include "prinit.h" - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include -#include - -static void PrintVersion( - const char *msg, const PRVersion* info, PRIntn tab) -{ - static const len = 20; - static const char *tabs = {" "}; - - tab *= 2; - if (tab > len) tab = len; - printf("%s", &tabs[len - tab]); - printf("%s ", msg); - printf("%s ", info->id); - printf("%d.%d", info->major, info->minor); - if (0 != info->patch) - printf(".p%d", info->patch); - printf("\n"); -} /* PrintDependency */ - -static void ChaseDependents(const PRVersionInfo *info, PRIntn tab) -{ - PrintVersion("exports", &info->selfExport, tab); - if (NULL != info->importEnumerator) - { - const PRDependencyInfo *dependent = NULL; - while (NULL != (dependent = info->importEnumerator(dependent))) - { - const PRVersionInfo *import = dependent->exportInfoFn(); - PrintVersion("imports", &dependent->importNeeded, tab); - ChaseDependents(import, tab + 1); - } - } -} /* ChaseDependents */ - -static PRVersionInfo hack_export; -static PRVersionInfo dummy_export; -static PRDependencyInfo dummy_imports[2]; - -static const PRVersionInfo *HackExportInfo(void) -{ - hack_export.selfExport.major = 11; - hack_export.selfExport.minor = 10; - hack_export.selfExport.patch = 200; - hack_export.selfExport.id = "Hack"; - hack_export.importEnumerator = NULL; - return &hack_export; -} - -static const PRDependencyInfo *DummyImports( - const PRDependencyInfo *previous) -{ - if (NULL == previous) return &dummy_imports[0]; - else if (&dummy_imports[0] == previous) return &dummy_imports[1]; - else if (&dummy_imports[1] == previous) return NULL; -} /* DummyImports */ - -static const PRVersionInfo *DummyLibVersion(void) -{ - dummy_export.selfExport.major = 1; - dummy_export.selfExport.minor = 0; - dummy_export.selfExport.patch = 0; - dummy_export.selfExport.id = "Dumbass application"; - dummy_export.importEnumerator = DummyImports; - - dummy_imports[0].importNeeded.major = 2; - dummy_imports[0].importNeeded.minor = 0; - dummy_imports[0].importNeeded.patch = 0; - dummy_imports[0].importNeeded.id = "Netscape Portable Runtime"; - dummy_imports[0].exportInfoFn = PR_ExportInfo; - - dummy_imports[1].importNeeded.major = 5; - dummy_imports[1].importNeeded.minor = 1; - dummy_imports[1].importNeeded.patch = 2; - dummy_imports[1].importNeeded.id = "Hack Library"; - dummy_imports[1].exportInfoFn = HackExportInfo; - - return &dummy_export; -} /* DummyLibVersion */ - -int main(int argc, char **argv) -{ - PRIntn tab = 0; - const PRVersionInfo *info = DummyLibVersion(); - const char *buildDate = __DATE__, *buildTime = __TIME__; - - printf("Depend.c build time is %s %s\n", buildDate, buildTime); - - if (NULL != info) ChaseDependents(info, tab); - - return 0; -} /* main */ - -/* depend.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/.cvsignore nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/.cvsignore 2001-05-12 05:07:36.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/Makefile.in 2012-11-13 23:18:00.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -CSRCS = mygetval.c mysetval.c - -INCLUDES = -I$(dist_includedir) - -OBJS = $(OBJDIR)/mygetval.$(OBJ_SUFFIX) \ - $(OBJDIR)/mysetval.$(OBJ_SUFFIX) - -ifeq ($(OS_TARGET), WIN16) -W16OBJS = $(subst $(space),$(comma)$(space),$(OBJS)) -endif - -ifeq ($(OS_ARCH), WINNT) -ifeq ($(OS_TARGET), WIN16) -# do nothing -else -RES=$(OBJDIR)/my.res -RESNAME=../../../pr/src/nspr.rc -endif -endif - -ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) -IMPORT_LIBRARY = $(OBJDIR)/my.$(LIB_SUFFIX) -SHARED_LIBRARY = $(OBJDIR)/my.dll -ifeq ($(OS_ARCH), OS2) -MAPFILE = $(OBJDIR)/my.def -GARBAGE += $(MAPFILE) -MKSHLIB += $(MAPFILE) -endif -TARGETS = $(SHARED_LIBRARY) $(IMPORT_LIBRARY) -else -ifdef MKSHLIB -SHARED_LIBRARY = $(OBJDIR)/libmy.$(DLL_SUFFIX) -endif -TARGETS = $(SHARED_LIBRARY) -endif - -# -# To create a loadable module on Darwin, we must override -# -dynamiclib with -bundle. -# -ifeq ($(OS_ARCH),Darwin) -DSO_LDOPTS = -bundle -endif - -include $(topsrcdir)/config/rules.mk - -ifeq ($(OS_TARGET), WIN16) -# Note: The Win16 target: my.dll requires these macros -# to be overridden to build the test .dll -# default values in win16...mk are for release targets. -# -OS_DLL_OPTION = NOCASEEXACT -OS_LIB_FLAGS = -irn -endif - -ifdef SHARED_LIBRARY -export:: $(TARGETS) - -clean:: - rm -rf $(TARGETS) -endif diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/my.def nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/my.def --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/my.def 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/my.def 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -;+# -;+# This Source Code Form is subject to the terms of the Mozilla Public -;+# License, v. 2.0. If a copy of the MPL was not distributed with this -;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -;+# -;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS -;+# 1. For all unix platforms, the string ";-" means "remove this line" -;+# 2. For all unix platforms, the string " DATA " will be removed from any -;+# line on which it occurs. -;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. -;+# On AIX, lines containing ";+" will be removed. -;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. -;+# 5. For all unix platforms, after the above processing has taken place, -;+# all characters after the first ";" on the line will be removed. -;+# And for AIX, the first ";" will also be removed. -;+# This file is passed directly to windows. Since ';' is a comment, all UNIX -;+# directives are hidden behind ";", ";+", and ";-" -;+# -;+MY_1.0 { -;+ global: -LIBRARY my ;- -EXPORTS ;- - My_GetValue; - My_SetValue; -;+ local: *; -;+}; diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/mygetval.c nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/mygetval.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/mygetval.c 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/mygetval.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -#if defined(WIN16) -#include -#endif -#include "prtypes.h" - -extern PRIntn my_global; - -PR_IMPLEMENT(PRIntn) My_GetValue() -{ - return my_global; -} - -#if defined(WIN16) -int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg, - WORD cbHeapSize, LPSTR lpszCmdLine ) -{ - return TRUE; -} -#endif /* WIN16 */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/mysetval.c nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/mysetval.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dll/mysetval.c 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dll/mysetval.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prtypes.h" - -PRIntn my_global = 0; - -PR_IMPLEMENT(void) My_SetValue(PRIntn val) -{ - my_global = val; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dlltest.c nspr-4.10.7/mozilla/nsprpub/pr/tests/dlltest.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dlltest.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dlltest.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: dlltest.c -** -** Description: test dll functionality. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** 12-June-97 Revert to return code 0 and 1. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -#include "prinit.h" -#include "prlink.h" -#include "prmem.h" -#include "prerror.h" - -#include "plstr.h" - -#include -#include - -typedef PRIntn (PR_CALLBACK *GetFcnType)(void); -typedef void (PR_CALLBACK *SetFcnType)(PRIntn); - -PRIntn failed_already=0; -PRIntn debug_mode; - -int main(int argc, char** argv) -{ - PRLibrary *lib, *lib2; /* two handles to the same library */ - GetFcnType getFcn; - SetFcnType setFcn; - PRIntn value; - PRStatus status; - char *libName; - - if (argc >= 2 && PL_strcmp(argv[1], "-d") == 0) { - debug_mode = 1; - } - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - /* - * Test 1: load the library, look up the symbols, call the functions, - * and check the results. - */ - - libName = PR_GetLibraryName("dll", "my"); - if (debug_mode) printf("Loading library %s\n", libName); - lib = PR_LoadLibrary(libName); - PR_FreeLibraryName(libName); - if (lib == NULL) { - PRInt32 textLength = PR_GetErrorTextLength(); - char *text = (char*)PR_MALLOC(textLength + 1); - text[0] = '\0'; - (void)PR_GetErrorText(text); - fprintf( - stderr, "PR_LoadLibrary failed (%d, %d, %s)\n", - PR_GetError(), PR_GetOSError(), text); - if (!debug_mode) failed_already=1; - } - getFcn = (GetFcnType) PR_FindSymbol(lib, "My_GetValue"); - setFcn = (SetFcnType) PR_FindFunctionSymbol(lib, "My_SetValue"); - (*setFcn)(888); - value = (*getFcn)(); - if (value != 888) { - fprintf(stderr, "Test 1 failed: set value to 888, but got %d\n", value); - if (!debug_mode) failed_already=1; - } - if (debug_mode) printf("Test 1 passed\n"); - - /* - * Test 2: get a second handle to the same library (this should increment - * the reference count), look up the symbols, call the functions, and - * check the results. - */ - - getFcn = (GetFcnType) PR_FindSymbolAndLibrary("My_GetValue", &lib2); - if (NULL == getFcn || lib != lib2) { - fprintf(stderr, "Test 2 failed: handles for the same library are not " - "equal: handle 1: %p, handle 2: %p\n", lib, lib2); - if (!debug_mode) failed_already=1; - } - setFcn = (SetFcnType) PR_FindSymbol(lib2, "My_SetValue"); - value = (*getFcn)(); - if (value != 888) { - fprintf(stderr, "Test 2 failed: value should be 888, but got %d\n", - value); - if (!debug_mode) failed_already=1; - } - (*setFcn)(777); - value = (*getFcn)(); - if (value != 777) { - fprintf(stderr, "Test 2 failed: set value to 777, but got %d\n", value); - if (!debug_mode) failed_already=1; - goto exit_now; - } - if (debug_mode) printf("Test 2 passed\n"); - - /* - * Test 3: unload the library. The library should still be accessible - * via the second handle. do the same things as above. - */ - - status = PR_UnloadLibrary(lib); - if (PR_FAILURE == status) { - fprintf(stderr, "Test 3 failed: cannot unload library: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - if (!debug_mode) failed_already=1; - goto exit_now; - } - getFcn = (GetFcnType) PR_FindFunctionSymbol(lib2, "My_GetValue"); - setFcn = (SetFcnType) PR_FindSymbol(lib2, "My_SetValue"); - (*setFcn)(666); - value = (*getFcn)(); - if (value != 666) { - fprintf(stderr, "Test 3 failed: set value to 666, but got %d\n", value); - if (!debug_mode) failed_already=1; - goto exit_now; - } - if (debug_mode) printf("Test 3 passed\n"); - - /* - * Test 4: unload the library, testing the reference count mechanism. - */ - - status = PR_UnloadLibrary(lib2); - if (PR_FAILURE == status) { - fprintf(stderr, "Test 4 failed: cannot unload library: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - if (!debug_mode) failed_already=1; - goto exit_now; - } - getFcn = (GetFcnType) PR_FindFunctionSymbolAndLibrary("My_GetValue", &lib2); - if (NULL != getFcn) { - fprintf(stderr, "Test 4 failed: how can we find a symbol " - "in an already unloaded library?\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - if (debug_mode) { - printf("Test 4 passed\n"); - } - - /* - ** Test 5: LoadStaticLibrary() - */ - { - PRStaticLinkTable slt[10]; - PRLibrary *lib; - - lib = PR_LoadStaticLibrary( "my.dll", slt ); - if ( lib == NULL ) - { - fprintf(stderr, "Test 5: LoadStatiLibrary() failed\n" ); - goto exit_now; - } - if (debug_mode) - { - printf("Test 5 passed\n"); - } - } - - goto exit_now; -exit_now: - PR_Cleanup(); - - if (failed_already) { - printf("FAILED\n"); - return 1; - } else { - printf("PASSED\n"); - return 0; - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/dtoa.c nspr-4.10.7/mozilla/nsprpub/pr/tests/dtoa.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/dtoa.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/dtoa.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,213 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/****************************************************************************** - * - * This file contains a test program for the function conversion functions - * for double precision code: - * PR_strtod - * PR_dtoa - * PR_cnvtf - * - * This file was ns/nspr/tests/dtoa.c, created by rrj on 1996/06/22. - * - *****************************************************************************/ -#include -#include -#include -#include -#include -#include "prprf.h" -#include "prdtoa.h" - -static int failed_already = 0; - -int main(int argc, char **argv) -{ - double num; - double num1; - double zero = 0.0; - char cnvt[50]; - char *thousands; - - num = 1e24; - num1 = PR_strtod("1e24",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n","1e24"); - failed_already = 1; - } - - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("1e+24",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - num = 0.001e7; - num1 = PR_strtod("0.001e7",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n","0.001e7"); - failed_already = 1; - } - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("10000",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - num = 0.0000000000000753; - num1 = PR_strtod("0.0000000000000753",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n", - "0.0000000000000753"); - failed_already = 1; - } - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("7.53e-14",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - num = 1.867e73; - num1 = PR_strtod("1.867e73",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n","1.867e73"); - failed_already = 1; - } - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("1.867e+73",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - - num = -1.867e73; - num1 = PR_strtod("-1.867e73",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e73"); - failed_already = 1; - } - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("-1.867e+73",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - num = -1.867e-73; - num1 = PR_strtod("-1.867e-73",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e-73"); - failed_already = 1; - } - - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("-1.867e-73",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - /* Testing for infinity */ - num = 1.0 / zero; - num1 = PR_strtod("1.867e765",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n","1.867e765"); - failed_already = 1; - } - - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("Infinity",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - num = -1.0 / zero; - num1 = PR_strtod("-1.867e765",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e765"); - failed_already = 1; - } - - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("-Infinity",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - /* Testing for NaN. PR_strtod can't parse "NaN" and "Infinity" */ - num = zero / zero; - - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("NaN",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - num = - zero / zero; - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("NaN",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - num = 1.0000000001e21; - num1 = PR_strtod("1.0000000001e21",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n", - "1.0000000001e21"); - failed_already = 1; - } - - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("1.0000000001e+21",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - num = -1.0000000001e-21; - num1 = PR_strtod("-1.0000000001e-21",NULL); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n", - "-1.0000000001e-21"); - failed_already = 1; - } - PR_cnvtf(cnvt,sizeof(cnvt),20,num); - if(strcmp("-1.0000000001e-21",cnvt) != 0){ - fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); - failed_already = 1; - } - - /* - * Bug 414772: should not exit with "Zero passed to d2b" in debug - * build. - */ - num1 = PR_strtod("4e-356",NULL); - - /* - * A very long input with ~384K digits. - * Bug 516396: Should not crash. - * Bug 521306: Should return 0 without converting the input. - */ -#define LENGTH (384 * 1024) - thousands = (char *)malloc(LENGTH); - thousands[0] = '0'; - thousands[1] = '.'; - memset(&thousands[2], '1', LENGTH - 3); - thousands[LENGTH - 1] = '\0'; - num = 0; - num1 = PR_strtod(thousands,NULL); - free(thousands); - if(num1 != num){ - fprintf(stderr,"Failed to convert numeric value %s\n", - "0.1111111111111111..."); - failed_already = 1; - } - - if (failed_already) { - printf("FAILED\n"); - } else { - printf("PASSED\n"); - } - return failed_already; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/env.c nspr-4.10.7/mozilla/nsprpub/pr/tests/env.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/env.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/env.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: env.c -** Description: Testing environment variable operations -** -*/ -#include "prenv.h" -#include "plgetopt.h" - -#include -#include -#include - -PRIntn debug = 0; -PRIntn verbose = 0; -PRBool failedAlready = PR_FALSE; - -#define ENVNAME "NSPR_ENVIRONMENT_TEST_VARIABLE" -#define ENVVALUE "The expected result" -#define ENVBUFSIZE 256 - -char *envBuf; /* buffer pointer. We leak memory here on purpose! */ - -static char * NewBuffer( size_t size ) -{ - char *buf = malloc( size ); - if ( NULL == buf ) { - printf("env: NewBuffer() failed\n"); - exit(1); - } - return(buf); -} /* end NewBuffer() */ - -int main(int argc, char **argv) -{ - char *value; - PRStatus rc; - - { /* Get command line options */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "vd"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug */ - debug = 1; - break; - case 'v': /* verbose */ - verbose = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - } /* end block "Get command line options" */ - -#if 0 - { - /* - ** This uses Windows native environment manipulation - ** as an experiment. Note the separation of namespace! - */ - BOOL rv; - DWORD size; - rv = SetEnvironmentVariable( ENVNAME, ENVVALUE ); - if ( rv == 0 ) { - if (debug) printf("env: Shit! SetEnvironmentVariable() failed\n"); - failedAlready = PR_TRUE; - } - if (verbose) printf("env: SetEnvironmentVariable() worked\n"); - - size = GetEnvironmentVariable( ENVNAME, envBuf, ENVBUFSIZE ); - if ( size == 0 ) { - if (debug) printf("env: Shit! GetEnvironmentVariable() failed. Found: %s\n", envBuf ); - failedAlready = PR_TRUE; - } - if (verbose) printf("env: GetEnvironmentVariable() worked. Found: %s\n", envBuf); - - value = PR_GetEnv( ENVNAME ); - if ( (NULL == value ) || (strcmp( value, ENVVALUE))) { - if (debug) printf( "env: PR_GetEnv() failed retrieving WinNative. Found: %s\n", value); - failedAlready = PR_TRUE; - } - if (verbose) printf("env: PR_GetEnv() worked. Found: %s\n", value); - } -#endif - - /* set an environment variable, read it back */ - envBuf = NewBuffer( ENVBUFSIZE ); - sprintf( envBuf, ENVNAME "=" ENVVALUE ); - rc = PR_SetEnv( envBuf ); - if ( PR_FAILURE == rc ) { - if (debug) printf( "env: PR_SetEnv() failed setting\n"); - failedAlready = PR_TRUE; - } else { - if (verbose) printf("env: PR_SetEnv() worked.\n"); - } - - value = PR_GetEnv( ENVNAME ); - if ( (NULL == value ) || (strcmp( value, ENVVALUE))) { - if (debug) printf( "env: PR_GetEnv() Failed after setting\n" ); - failedAlready = PR_TRUE; - } else { - if (verbose) printf("env: PR_GetEnv() worked after setting it. Found: %s\n", value ); - } - -/* ---------------------------------------------------------------------- */ - /* un-set the variable, using RAW name... should not work */ - envBuf = NewBuffer( ENVBUFSIZE ); - sprintf( envBuf, ENVNAME ); - rc = PR_SetEnv( envBuf ); - if ( PR_FAILURE == rc ) { - if (verbose) printf( "env: PR_SetEnv() not un-set using RAW name. Good!\n"); - } else { - if (debug) printf("env: PR_SetEnv() un-set using RAW name. Bad!\n" ); - failedAlready = PR_TRUE; - } - - value = PR_GetEnv( ENVNAME ); - if ( NULL == value ) { - if (debug) printf("env: PR_GetEnv() after un-set using RAW name. Bad!\n" ); - failedAlready = PR_TRUE; - } else { - if (verbose) printf( "env: PR_GetEnv() after RAW un-set found: %s\n", value ); - } - -/* ---------------------------------------------------------------------- */ - /* set it again ... */ - envBuf = NewBuffer( ENVBUFSIZE ); - sprintf( envBuf, ENVNAME "=" ENVVALUE ); - rc = PR_SetEnv( envBuf ); - if ( PR_FAILURE == rc ) { - if (debug) printf( "env: PR_SetEnv() failed setting the second time.\n"); - failedAlready = PR_TRUE; - } else { - if (verbose) printf("env: PR_SetEnv() worked.\n"); - } - - /* un-set the variable using the form name= */ - envBuf = NewBuffer( ENVBUFSIZE ); - sprintf( envBuf, ENVNAME "=" ); - rc = PR_SetEnv( envBuf ); - if ( PR_FAILURE == rc ) { - if (debug) printf( "env: PR_SetEnv() failed un-setting using name=\n"); - failedAlready = PR_TRUE; - } else { - if (verbose) printf("env: PR_SetEnv() un-set using name= worked\n" ); - } - - value = PR_GetEnv( ENVNAME ); - if (( NULL == value ) || ( 0x00 == *value )) { - if (verbose) printf("env: PR_GetEnv() after un-set using name= worked\n" ); - } else { - if (debug) printf( "env: PR_GetEnv() after un-set using name=. Found: %s\n", value ); - failedAlready = PR_TRUE; - } -/* ---------------------------------------------------------------------- */ - /* un-set the variable using the form name= */ - envBuf = NewBuffer( ENVBUFSIZE ); - sprintf( envBuf, ENVNAME "999=" ); - rc = PR_SetEnv( envBuf ); - if ( PR_FAILURE == rc ) { - if (debug) printf( "env: PR_SetEnv() failed un-setting using name=\n"); - failedAlready = PR_TRUE; - } else { - if (verbose) printf("env: PR_SetEnv() un-set using name= worked\n" ); - } - - value = PR_GetEnv( ENVNAME "999" ); - if (( NULL == value ) || ( 0x00 == *value )) { - if (verbose) printf("env: PR_GetEnv() after un-set using name= worked\n" ); - } else { - if (debug) printf( "env: PR_GetEnv() after un-set using name=. Found: %s\n", value ); - failedAlready = PR_TRUE; - } - -/* ---------------------------------------------------------------------- */ - if (debug || verbose) printf("\n%s\n", (failedAlready)? "FAILED" : "PASSED" ); - return( (failedAlready)? 1 : 0 ); -} /* main() */ - -/* env.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/errcodes.c nspr-4.10.7/mozilla/nsprpub/pr/tests/errcodes.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/errcodes.c 2012-03-06 13:14:25.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/errcodes.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: errcodes.c -** -** Description: print nspr error codes -** -*/ -#include "prerror.h" -#include "plgetopt.h" - -#include - -static int _debug_on = 0; - -struct errinfo { - PRErrorCode errcode; - char *errname; -}; - -struct errinfo errcodes[] = { -{PR_OUT_OF_MEMORY_ERROR, "PR_OUT_OF_MEMORY_ERROR"}, -{PR_BAD_DESCRIPTOR_ERROR, "PR_BAD_DESCRIPTOR_ERROR"}, -{PR_WOULD_BLOCK_ERROR, "PR_WOULD_BLOCK_ERROR"}, -{PR_ACCESS_FAULT_ERROR, "PR_ACCESS_FAULT_ERROR"}, -{PR_INVALID_METHOD_ERROR, "PR_INVALID_METHOD_ERROR"}, -{PR_ILLEGAL_ACCESS_ERROR, "PR_ILLEGAL_ACCESS_ERROR"}, -{PR_UNKNOWN_ERROR, "PR_UNKNOWN_ERROR"}, -{PR_PENDING_INTERRUPT_ERROR, "PR_PENDING_INTERRUPT_ERROR"}, -{PR_NOT_IMPLEMENTED_ERROR, "PR_NOT_IMPLEMENTED_ERROR"}, -{PR_IO_ERROR, "PR_IO_ERROR"}, -{PR_IO_TIMEOUT_ERROR, "PR_IO_TIMEOUT_ERROR"}, -{PR_IO_PENDING_ERROR, "PR_IO_PENDING_ERROR"}, -{PR_DIRECTORY_OPEN_ERROR, "PR_DIRECTORY_OPEN_ERROR"}, -{PR_INVALID_ARGUMENT_ERROR, "PR_INVALID_ARGUMENT_ERROR"}, -{PR_ADDRESS_NOT_AVAILABLE_ERROR, "PR_ADDRESS_NOT_AVAILABLE_ERROR"}, -{PR_ADDRESS_NOT_SUPPORTED_ERROR, "PR_ADDRESS_NOT_SUPPORTED_ERROR"}, -{PR_IS_CONNECTED_ERROR, "PR_IS_CONNECTED_ERROR"}, -{PR_BAD_ADDRESS_ERROR, "PR_BAD_ADDRESS_ERROR"}, -{PR_ADDRESS_IN_USE_ERROR, "PR_ADDRESS_IN_USE_ERROR"}, -{PR_CONNECT_REFUSED_ERROR, "PR_CONNECT_REFUSED_ERROR"}, -{PR_NETWORK_UNREACHABLE_ERROR, "PR_NETWORK_UNREACHABLE_ERROR"}, -{PR_CONNECT_TIMEOUT_ERROR, "PR_CONNECT_TIMEOUT_ERROR"}, -{PR_NOT_CONNECTED_ERROR, "PR_NOT_CONNECTED_ERROR"}, -{PR_LOAD_LIBRARY_ERROR, "PR_LOAD_LIBRARY_ERROR"}, -{PR_UNLOAD_LIBRARY_ERROR, "PR_UNLOAD_LIBRARY_ERROR"}, -{PR_FIND_SYMBOL_ERROR, "PR_FIND_SYMBOL_ERROR"}, -{PR_INSUFFICIENT_RESOURCES_ERROR, "PR_INSUFFICIENT_RESOURCES_ERROR"}, -{PR_DIRECTORY_LOOKUP_ERROR, "PR_DIRECTORY_LOOKUP_ERROR"}, -{PR_TPD_RANGE_ERROR, "PR_TPD_RANGE_ERROR"}, -{PR_PROC_DESC_TABLE_FULL_ERROR, "PR_PROC_DESC_TABLE_FULL_ERROR"}, -{PR_SYS_DESC_TABLE_FULL_ERROR, "PR_SYS_DESC_TABLE_FULL_ERROR"}, -{PR_NOT_SOCKET_ERROR, "PR_NOT_SOCKET_ERROR"}, -{PR_NOT_TCP_SOCKET_ERROR, "PR_NOT_TCP_SOCKET_ERROR"}, -{PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "PR_SOCKET_ADDRESS_IS_BOUND_ERROR"}, -{PR_NO_ACCESS_RIGHTS_ERROR, "PR_NO_ACCESS_RIGHTS_ERROR"}, -{PR_OPERATION_NOT_SUPPORTED_ERROR, "PR_OPERATION_NOT_SUPPORTED_ERROR"}, -{PR_PROTOCOL_NOT_SUPPORTED_ERROR, "PR_PROTOCOL_NOT_SUPPORTED_ERROR"}, -{PR_REMOTE_FILE_ERROR, "PR_REMOTE_FILE_ERROR"}, -{PR_BUFFER_OVERFLOW_ERROR, "PR_BUFFER_OVERFLOW_ERROR"}, -{PR_CONNECT_RESET_ERROR, "PR_CONNECT_RESET_ERROR"}, -{PR_RANGE_ERROR, "PR_RANGE_ERROR"}, -{PR_DEADLOCK_ERROR, "PR_DEADLOCK_ERROR"}, -{PR_FILE_IS_LOCKED_ERROR, "PR_FILE_IS_LOCKED_ERROR"}, -{PR_FILE_TOO_BIG_ERROR, "PR_FILE_TOO_BIG_ERROR"}, -{PR_NO_DEVICE_SPACE_ERROR, "PR_NO_DEVICE_SPACE_ERROR"}, -{PR_PIPE_ERROR, "PR_PIPE_ERROR"}, -{PR_NO_SEEK_DEVICE_ERROR, "PR_NO_SEEK_DEVICE_ERROR"}, -{PR_IS_DIRECTORY_ERROR, "PR_IS_DIRECTORY_ERROR"}, -{PR_LOOP_ERROR, "PR_LOOP_ERROR"}, -{PR_NAME_TOO_LONG_ERROR, "PR_NAME_TOO_LONG_ERROR"}, -{PR_FILE_NOT_FOUND_ERROR, "PR_FILE_NOT_FOUND_ERROR"}, -{PR_NOT_DIRECTORY_ERROR, "PR_NOT_DIRECTORY_ERROR"}, -{PR_READ_ONLY_FILESYSTEM_ERROR, "PR_READ_ONLY_FILESYSTEM_ERROR"}, -{PR_DIRECTORY_NOT_EMPTY_ERROR, "PR_DIRECTORY_NOT_EMPTY_ERROR"}, -{PR_FILESYSTEM_MOUNTED_ERROR, "PR_FILESYSTEM_MOUNTED_ERROR"}, -{PR_NOT_SAME_DEVICE_ERROR, "PR_NOT_SAME_DEVICE_ERROR"}, -{PR_DIRECTORY_CORRUPTED_ERROR, "PR_DIRECTORY_CORRUPTED_ERROR"}, -{PR_FILE_EXISTS_ERROR, "PR_FILE_EXISTS_ERROR"}, -{PR_MAX_DIRECTORY_ENTRIES_ERROR, "PR_MAX_DIRECTORY_ENTRIES_ERROR"}, -{PR_INVALID_DEVICE_STATE_ERROR, "PR_INVALID_DEVICE_STATE_ERROR"}, -{PR_DEVICE_IS_LOCKED_ERROR, "PR_DEVICE_IS_LOCKED_ERROR"}, -{PR_NO_MORE_FILES_ERROR, "PR_NO_MORE_FILES_ERROR"}, -{PR_END_OF_FILE_ERROR, "PR_END_OF_FILE_ERROR"}, -{PR_FILE_SEEK_ERROR, "PR_FILE_SEEK_ERROR"}, -{PR_FILE_IS_BUSY_ERROR, "PR_FILE_IS_BUSY_ERROR"}, -{PR_IN_PROGRESS_ERROR, "PR_IN_PROGRESS_ERROR"}, -{PR_ALREADY_INITIATED_ERROR, "PR_ALREADY_INITIATED_ERROR"}, -{PR_GROUP_EMPTY_ERROR, "PR_GROUP_EMPTY_ERROR"}, -{PR_INVALID_STATE_ERROR, "PR_INVALID_STATE_ERROR"}, -{PR_NETWORK_DOWN_ERROR, "PR_NETWORK_DOWN_ERROR"}, -{PR_SOCKET_SHUTDOWN_ERROR, "PR_SOCKET_SHUTDOWN_ERROR"}, -{PR_CONNECT_ABORTED_ERROR, "PR_CONNECT_ABORTED_ERROR"}, -{PR_HOST_UNREACHABLE_ERROR, "PR_HOST_UNREACHABLE_ERROR"} -}; - -int main(int argc, char **argv) -{ - - int count, errnum; - - /* - * -d debug mode - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - count = sizeof(errcodes)/sizeof(errcodes[0]); - printf("\nNumber of error codes = %d\n\n",count); - for (errnum = 0; errnum < count; errnum++) { - printf("%-40s = %d\n",errcodes[errnum].errname, - errcodes[errnum].errcode); - } - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/errset.c nspr-4.10.7/mozilla/nsprpub/pr/tests/errset.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/errset.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/errset.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: errset.c -** -** Description: errset.c exercises the functions in prerror.c. -** This code is a unit test of the prerror.c capability. -** -** Note: There's some fluff in here. The guts of the test -** were plagerized from another test. So, sue me. -** -** -*/ -#include "prerror.h" -#include "plgetopt.h" -#include "prlog.h" - -#include -#include - -static int _debug_on = 0; - -struct errinfo { - PRErrorCode errcode; - char *errname; -}; - -struct errinfo errcodes[] = { -{PR_OUT_OF_MEMORY_ERROR, "PR_OUT_OF_MEMORY_ERROR"}, -{PR_UNKNOWN_ERROR, "An intentionally long error message text intended to force a delete of the current errorString buffer and get another one."}, -{PR_BAD_DESCRIPTOR_ERROR, "PR_BAD_DESCRIPTOR_ERROR"}, -{PR_WOULD_BLOCK_ERROR, "PR_WOULD_BLOCK_ERROR"}, -{PR_ACCESS_FAULT_ERROR, "PR_ACCESS_FAULT_ERROR"}, -{PR_INVALID_METHOD_ERROR, "PR_INVALID_METHOD_ERROR"}, -{PR_ILLEGAL_ACCESS_ERROR, "PR_ILLEGAL_ACCESS_ERROR"}, -{PR_UNKNOWN_ERROR, "PR_UNKNOWN_ERROR"}, -{PR_PENDING_INTERRUPT_ERROR, "PR_PENDING_INTERRUPT_ERROR"}, -{PR_NOT_IMPLEMENTED_ERROR, "PR_NOT_IMPLEMENTED_ERROR"}, -{PR_IO_ERROR, "PR_IO_ERROR"}, -{PR_IO_TIMEOUT_ERROR, "PR_IO_TIMEOUT_ERROR"}, -{PR_IO_PENDING_ERROR, "PR_IO_PENDING_ERROR"}, -{PR_DIRECTORY_OPEN_ERROR, "PR_DIRECTORY_OPEN_ERROR"}, -{PR_INVALID_ARGUMENT_ERROR, "PR_INVALID_ARGUMENT_ERROR"}, -{PR_ADDRESS_NOT_AVAILABLE_ERROR, "PR_ADDRESS_NOT_AVAILABLE_ERROR"}, -{PR_ADDRESS_NOT_SUPPORTED_ERROR, "PR_ADDRESS_NOT_SUPPORTED_ERROR"}, -{PR_IS_CONNECTED_ERROR, "PR_IS_CONNECTED_ERROR"}, -{PR_BAD_ADDRESS_ERROR, "PR_BAD_ADDRESS_ERROR"}, -{PR_ADDRESS_IN_USE_ERROR, "PR_ADDRESS_IN_USE_ERROR"}, -{PR_CONNECT_REFUSED_ERROR, "PR_CONNECT_REFUSED_ERROR"}, -{PR_NETWORK_UNREACHABLE_ERROR, "PR_NETWORK_UNREACHABLE_ERROR"}, -{PR_CONNECT_TIMEOUT_ERROR, "PR_CONNECT_TIMEOUT_ERROR"}, -{PR_NOT_CONNECTED_ERROR, "PR_NOT_CONNECTED_ERROR"}, -{PR_LOAD_LIBRARY_ERROR, "PR_LOAD_LIBRARY_ERROR"}, -{PR_UNLOAD_LIBRARY_ERROR, "PR_UNLOAD_LIBRARY_ERROR"}, -{PR_FIND_SYMBOL_ERROR, "PR_FIND_SYMBOL_ERROR"}, -{PR_INSUFFICIENT_RESOURCES_ERROR, "PR_INSUFFICIENT_RESOURCES_ERROR"}, -{PR_DIRECTORY_LOOKUP_ERROR, "PR_DIRECTORY_LOOKUP_ERROR"}, -{PR_TPD_RANGE_ERROR, "PR_TPD_RANGE_ERROR"}, -{PR_PROC_DESC_TABLE_FULL_ERROR, "PR_PROC_DESC_TABLE_FULL_ERROR"}, -{PR_SYS_DESC_TABLE_FULL_ERROR, "PR_SYS_DESC_TABLE_FULL_ERROR"}, -{PR_NOT_SOCKET_ERROR, "PR_NOT_SOCKET_ERROR"}, -{PR_NOT_TCP_SOCKET_ERROR, "PR_NOT_TCP_SOCKET_ERROR"}, -{PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "PR_SOCKET_ADDRESS_IS_BOUND_ERROR"}, -{PR_NO_ACCESS_RIGHTS_ERROR, "PR_NO_ACCESS_RIGHTS_ERROR"}, -{PR_OPERATION_NOT_SUPPORTED_ERROR, "PR_OPERATION_NOT_SUPPORTED_ERROR"}, -{PR_PROTOCOL_NOT_SUPPORTED_ERROR, "PR_PROTOCOL_NOT_SUPPORTED_ERROR"}, -{PR_REMOTE_FILE_ERROR, "PR_REMOTE_FILE_ERROR"}, -{PR_BUFFER_OVERFLOW_ERROR, "PR_BUFFER_OVERFLOW_ERROR"}, -{PR_CONNECT_RESET_ERROR, "PR_CONNECT_RESET_ERROR"}, -{PR_RANGE_ERROR, "PR_RANGE_ERROR"}, -{PR_DEADLOCK_ERROR, "PR_DEADLOCK_ERROR"}, -{PR_FILE_IS_LOCKED_ERROR, "PR_FILE_IS_LOCKED_ERROR"}, -{PR_FILE_TOO_BIG_ERROR, "PR_FILE_TOO_BIG_ERROR"}, -{PR_NO_DEVICE_SPACE_ERROR, "PR_NO_DEVICE_SPACE_ERROR"}, -{PR_PIPE_ERROR, "PR_PIPE_ERROR"}, -{PR_NO_SEEK_DEVICE_ERROR, "PR_NO_SEEK_DEVICE_ERROR"}, -{PR_IS_DIRECTORY_ERROR, "PR_IS_DIRECTORY_ERROR"}, -{PR_LOOP_ERROR, "PR_LOOP_ERROR"}, -{PR_NAME_TOO_LONG_ERROR, "PR_NAME_TOO_LONG_ERROR"}, -{PR_FILE_NOT_FOUND_ERROR, "PR_FILE_NOT_FOUND_ERROR"}, -{PR_NOT_DIRECTORY_ERROR, "PR_NOT_DIRECTORY_ERROR"}, -{PR_READ_ONLY_FILESYSTEM_ERROR, "PR_READ_ONLY_FILESYSTEM_ERROR"}, -{PR_DIRECTORY_NOT_EMPTY_ERROR, "PR_DIRECTORY_NOT_EMPTY_ERROR"}, -{PR_FILESYSTEM_MOUNTED_ERROR, "PR_FILESYSTEM_MOUNTED_ERROR"}, -{PR_NOT_SAME_DEVICE_ERROR, "PR_NOT_SAME_DEVICE_ERROR"}, -{PR_DIRECTORY_CORRUPTED_ERROR, "PR_DIRECTORY_CORRUPTED_ERROR"}, -{PR_FILE_EXISTS_ERROR, "PR_FILE_EXISTS_ERROR"}, -{PR_MAX_DIRECTORY_ENTRIES_ERROR, "PR_MAX_DIRECTORY_ENTRIES_ERROR"}, -{PR_INVALID_DEVICE_STATE_ERROR, "PR_INVALID_DEVICE_STATE_ERROR"}, -{PR_DEVICE_IS_LOCKED_ERROR, "PR_DEVICE_IS_LOCKED_ERROR"}, -{PR_NO_MORE_FILES_ERROR, "PR_NO_MORE_FILES_ERROR"}, -{PR_END_OF_FILE_ERROR, "PR_END_OF_FILE_ERROR"}, -{PR_FILE_SEEK_ERROR, "PR_FILE_SEEK_ERROR"}, -{PR_FILE_IS_BUSY_ERROR, "PR_FILE_IS_BUSY_ERROR"}, -{PR_IN_PROGRESS_ERROR, "PR_IN_PROGRESS_ERROR"}, -{PR_ALREADY_INITIATED_ERROR, "PR_ALREADY_INITIATED_ERROR"}, -{PR_GROUP_EMPTY_ERROR, "PR_GROUP_EMPTY_ERROR"}, -{PR_INVALID_STATE_ERROR, "PR_INVALID_STATE_ERROR"}, -{PR_NETWORK_DOWN_ERROR, "PR_NETWORK_DOWN_ERROR"}, -{PR_SOCKET_SHUTDOWN_ERROR, "PR_SOCKET_SHUTDOWN_ERROR"}, -{PR_CONNECT_ABORTED_ERROR, "PR_CONNECT_ABORTED_ERROR"}, -{PR_HOST_UNREACHABLE_ERROR, "PR_HOST_UNREACHABLE_ERROR"} -}; - -int main(int argc, char **argv) -{ - - int count, errnum; - - /* - * -d debug mode - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - count = sizeof(errcodes)/sizeof(errcodes[0]); - printf("\nNumber of error codes = %d\n\n",count); - for (errnum = 0; errnum < count; errnum++) { - PRInt32 len1, len2, err; - char msg[256]; - - PR_SetError( errnum, -5 ); - err = PR_GetError(); - PR_ASSERT( err == errnum ); - err = PR_GetOSError(); - PR_ASSERT( err == -5 ); - PR_SetErrorText( strlen(errcodes[errnum].errname), errcodes[errnum].errname ); - len1 = PR_GetErrorTextLength(); - len2 = PR_GetErrorText( msg ); - PR_ASSERT( len1 == len2 ); - printf("%5.5d -- %s\n", errnum, msg ); - } - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/exit.c nspr-4.10.7/mozilla/nsprpub/pr/tests/exit.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/exit.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/exit.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prprf.h" -#include "prinit.h" -#include "prthread.h" -#include "prproces.h" -#include "prinrval.h" - -#include "plgetopt.h" - -#include - -static PRInt32 dally = 0; -static PRFileDesc *err = NULL; -static PRBool verbose = PR_FALSE, force = PR_FALSE; - -static void Help(void) -{ - PR_fprintf(err, "Usage: [-t s] [-h]\n"); - PR_fprintf(err, "\t-d Verbose output (default: FALSE)\n"); - PR_fprintf(err, "\t-x Forced termination (default: FALSE)\n"); - PR_fprintf(err, "\t-t Time for thread to block (default: 10 seconds)\n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); -} /* Help */ - -static void Dull(void *arg) -{ - PR_Sleep(PR_SecondsToInterval(dally)); - if (verbose && force) - PR_fprintf(err, "If you see this, the test failed\n"); -} /* Dull */ - -static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv) -{ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "ht:dx"); - - err = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* verbosity */ - verbose = PR_TRUE; - break; - case 'x': /* force exit */ - force = PR_TRUE; - break; - case 't': /* seconds to dally in child */ - dally = atoi(opt->value); - break; - case 'h': /* user wants some guidance */ - default: - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - } - } - PL_DestroyOptState(opt); - - if (0 == dally) dally = 10; - - /* - * Create LOCAL and GLOBAL threads - */ - (void)PR_CreateThread( - PR_USER_THREAD, Dull, NULL, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); - - (void)PR_CreateThread( - PR_USER_THREAD, Dull, NULL, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); - - if (verbose) - PR_fprintf( - err, "Main is exiting now. Program should exit %s.\n", - (force) ? "immediately" : "after child dally time"); - - if (force) - { - PR_ProcessExit(0); - if (verbose) - { - PR_fprintf(err, "You should not have gotten here.\n"); - return 1; - } - } - return 0; - -} - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/fdcach.c nspr-4.10.7/mozilla/nsprpub/pr/tests/fdcach.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/fdcach.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/fdcach.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,227 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: fdcach.c - * Description: - * This test verifies that the fd cache and stack are working - * correctly. - */ - -#include "nspr.h" - -#include -#include - -/* - * Define ORDER_PRESERVED if the implementation of PR_SetFDCacheSize - * preserves the ordering of the fd's when moving them between the - * cache and the stack. - */ -#define ORDER_PRESERVED 1 - -/* - * NUM_FDS must be <= FD_CACHE_SIZE. - */ -#define FD_CACHE_SIZE 1024 -#define NUM_FDS 20 - -int main(int argc, char **argv) -{ - int i; - PRFileDesc *fds[NUM_FDS]; - PRFileDesc *savefds[NUM_FDS]; - int numfds = sizeof(fds)/sizeof(fds[0]); - - /* - * Switch between cache and stack when they are empty. - * Then start with the fd cache. - */ - PR_SetFDCacheSize(0, FD_CACHE_SIZE); - PR_SetFDCacheSize(0, 0); - PR_SetFDCacheSize(0, FD_CACHE_SIZE); - - /* Add some fd's to the fd cache. */ - for (i = 0; i < numfds; i++) { - savefds[i] = PR_NewTCPSocket(); - if (NULL == savefds[i]) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - } - for (i = 0; i < numfds; i++) { - if (PR_Close(savefds[i]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - - /* - * Create some fd's. These fd's should come from - * the fd cache. Verify the FIFO ordering of the fd - * cache. - */ - for (i = 0; i < numfds; i++) { - fds[i] = PR_NewTCPSocket(); - if (NULL == fds[i]) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - if (fds[i] != savefds[i]) { - fprintf(stderr, "fd cache malfunctioned\n"); - exit(1); - } - } - /* Put the fd's back to the fd cache. */ - for (i = 0; i < numfds; i++) { - if (PR_Close(savefds[i]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - - /* Switch to the fd stack. */ - PR_SetFDCacheSize(0, 0); - - /* - * Create some fd's. These fd's should come from - * the fd stack. - */ - for (i = 0; i < numfds; i++) { - fds[i] = PR_NewTCPSocket(); - if (NULL == fds[i]) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } -#ifdef ORDER_PRESERVED - if (fds[i] != savefds[numfds-1-i]) { - fprintf(stderr, "fd stack malfunctioned\n"); - exit(1); - } -#else - savefds[numfds-1-i] = fds[i]; -#endif - } - /* Put the fd's back to the fd stack. */ - for (i = 0; i < numfds; i++) { - if (PR_Close(savefds[i]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - - /* - * Now create some fd's and verify the LIFO ordering of - * the fd stack. - */ - for (i = 0; i < numfds; i++) { - fds[i] = PR_NewTCPSocket(); - if (NULL == fds[i]) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - if (fds[i] != savefds[numfds-1-i]) { - fprintf(stderr, "fd stack malfunctioned\n"); - exit(1); - } - } - /* Put the fd's back to the fd stack. */ - for (i = 0; i < numfds; i++) { - if (PR_Close(savefds[i]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - - /* Switch to the fd cache. */ - PR_SetFDCacheSize(0, FD_CACHE_SIZE); - - for (i = 0; i < numfds; i++) { - fds[i] = PR_NewTCPSocket(); - if (NULL == fds[i]) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } -#ifdef ORDER_PRESERVED - if (fds[i] != savefds[i]) { - fprintf(stderr, "fd cache malfunctioned\n"); - exit(1); - } -#else - savefds[i] = fds[i]; -#endif - } - for (i = 0; i < numfds; i++) { - if (PR_Close(savefds[i]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - - for (i = 0; i < numfds; i++) { - fds[i] = PR_NewTCPSocket(); - if (NULL == fds[i]) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - if (fds[i] != savefds[i]) { - fprintf(stderr, "fd cache malfunctioned\n"); - exit(1); - } - } - for (i = 0; i < numfds; i++) { - if (PR_Close(savefds[i]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - - /* Switch to the fd stack. */ - PR_SetFDCacheSize(0, 0); - - for (i = 0; i < numfds; i++) { - fds[i] = PR_NewTCPSocket(); - if (NULL == fds[i]) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } -#ifdef ORDER_PRESERVED - if (fds[i] != savefds[numfds-1-i]) { - fprintf(stderr, "fd stack malfunctioned\n"); - exit(1); - } -#else - savefds[numfds-1-i]; -#endif - } - for (i = 0; i < numfds; i++) { - if (PR_Close(savefds[i]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - - for (i = 0; i < numfds; i++) { - fds[i] = PR_NewTCPSocket(); - if (NULL == fds[i]) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - if (fds[i] != savefds[numfds-1-i]) { - fprintf(stderr, "fd stack malfunctioned\n"); - exit(1); - } - } - for (i = 0; i < numfds; i++) { - if (PR_Close(savefds[i]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - - PR_Cleanup(); - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/fileio.c nspr-4.10.7/mozilla/nsprpub/pr/tests/fileio.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/fileio.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/fileio.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: fileio.c -** -** Description: Program to copy one file to another. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete). -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -#include "prinit.h" -#include "prthread.h" -#include "prlock.h" -#include "prcvar.h" -#include "prmon.h" -#include "prmem.h" -#include "prio.h" -#include "prlog.h" - -#include - -#include "obsolete/prsem.h" - - -#define TBSIZE 1024 - -static PRUint8 tbuf[TBSIZE]; - -static PRFileDesc *t1, *t2; - -PRIntn failed_already=0; -PRIntn debug_mode; -static void InitialSetup(void) -{ - PRUintn i; - PRInt32 nWritten, rv; - - t1 = PR_Open("t1.tmp", PR_CREATE_FILE | PR_RDWR, 0); - PR_ASSERT(t1 != NULL); - - for (i=0; i= 0) { - buf[i].nbytes = nbytes; - PR_PostSem(fullBufs); - i = (i + 1) % 2; - } - } while (nbytes > 0); -} - -static void PR_CALLBACK writer(void *arg) -{ - PRUintn i = 0; - PRInt32 nbytes; - - do { - (void) PR_WaitSem(fullBufs); - nbytes = buf[i].nbytes; - if (nbytes > 0) { - nbytes = PR_Write((PRFileDesc*)arg, buf[i].data, nbytes); - PR_PostSem(emptyBufs); - i = (i + 1) % 2; - } - } while (nbytes > 0); -} - -int main(int argc, char **argv) -{ - PRThread *r, *w; - - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - emptyBufs = PR_NewSem(2); /* two empty buffers */ - - fullBufs = PR_NewSem(0); /* zero full buffers */ - - /* Create initial temp file setup */ - InitialSetup(); - - /* create the reader thread */ - - r = PR_CreateThread(PR_USER_THREAD, - reader, t1, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0); - - w = PR_CreateThread(PR_USER_THREAD, - writer, t2, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0); - - /* Do the joining for both threads */ - (void) PR_JoinThread(r); - (void) PR_JoinThread(w); - - /* Do the verification and clean up */ - VerifyAndCleanup(); - - PR_DestroySem(emptyBufs); - PR_DestroySem(fullBufs); - - PR_Cleanup(); - - if(failed_already) - { - printf("Fail\n"); - return 1; - } - else - { - printf("PASS\n"); - return 0; - } - - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/foreign.c nspr-4.10.7/mozilla/nsprpub/pr/tests/foreign.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/foreign.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/foreign.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,353 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: foreign.c -** Description: Testing various functions w/ foreign threads -** -** We create a thread and get it to call exactly one runtime function. -** The thread is allowed to be created by some other environment that -** NSPR, but it does not announce itself to the runtime prior to calling -** in. -** -** The goal: try to survive. -** -*/ - -#include "prcvar.h" -#include "prenv.h" -#include "prerror.h" -#include "prinit.h" -#include "prinrval.h" -#include "prio.h" -#include "prlock.h" -#include "prlog.h" -#include "prmem.h" -#include "prthread.h" -#include "prtypes.h" -#include "prprf.h" -#include "plgetopt.h" - -#include -#include - -static enum { - thread_nspr, thread_pthread, thread_sproc, thread_win32 -} thread_provider; - -typedef void (*StartFn)(void*); -typedef struct StartObject -{ - StartFn start; - void *arg; -} StartObject; - -static PRFileDesc *output; - -static int _debug_on = 0; - -#define DEFAULT_THREAD_COUNT 10 - -#define DPRINTF(arg) if (_debug_on) PR_fprintf arg - -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) -#include -#include "md/_pth.h" -static void *pthread_start(void *arg) -{ - StartFn start = ((StartObject*)arg)->start; - void *data = ((StartObject*)arg)->arg; - PR_Free(arg); - start(data); - return NULL; -} /* pthread_start */ -#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ - -#if defined(IRIX) && !defined(_PR_PTHREADS) -#include -#include -static void sproc_start(void *arg, PRSize size) -{ - StartObject *so = (StartObject*)arg; - StartFn start = so->start; - void *data = so->arg; - PR_Free(so); - start(data); -} /* sproc_start */ -#endif /* defined(IRIX) && !defined(_PR_PTHREADS) */ - -#if defined(WIN32) -#if defined(WINCE) -#include -#endif -#include /* for _beginthreadex() */ - -static PRUintn __stdcall windows_start(void *arg) -{ - StartObject *so = (StartObject*)arg; - StartFn start = so->start; - void *data = so->arg; - PR_Free(so); - start(data); - return 0; -} /* windows_start */ -#endif /* defined(WIN32) */ - -static PRStatus NSPRPUB_TESTS_CreateThread(StartFn start, void *arg) -{ - PRStatus rv; - - switch (thread_provider) - { - case thread_nspr: - { - PRThread *thread = PR_CreateThread( - PR_USER_THREAD, start, arg, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS; - } - break; - case thread_pthread: -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) - { - int rv; - pthread_t id; - pthread_attr_t tattr; - StartObject *start_object; - start_object = PR_NEW(StartObject); - PR_ASSERT(NULL != start_object); - start_object->start = start; - start_object->arg = arg; - - rv = _PT_PTHREAD_ATTR_INIT(&tattr); - PR_ASSERT(0 == rv); - - rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); - PR_ASSERT(0 == rv); - - rv = pthread_attr_setstacksize(&tattr, 64 * 1024); - PR_ASSERT(0 == rv); - - rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object); - (void)_PT_PTHREAD_ATTR_DESTROY(&tattr); - return (0 == rv) ? PR_SUCCESS : PR_FAILURE; - } -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - rv = PR_FAILURE; - break; -#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ - - case thread_sproc: -#if defined(IRIX) && !defined(_PR_PTHREADS) - { - PRInt32 pid; - StartObject *start_object; - start_object = PR_NEW(StartObject); - PR_ASSERT(NULL != start_object); - start_object->start = start; - start_object->arg = arg; - pid = sprocsp( - sproc_start, PR_SALL, start_object, NULL, 64 * 1024); - rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE; - } -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - rv = PR_FAILURE; -#endif /* defined(IRIX) && !defined(_PR_PTHREADS) */ - break; - case thread_win32: -#if defined(WIN32) - { - void *th; - PRUintn id; - StartObject *start_object; - start_object = PR_NEW(StartObject); - PR_ASSERT(NULL != start_object); - start_object->start = start; - start_object->arg = arg; - th = (void*)_beginthreadex( - NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */ - 0U, /* DWORD - initial thread stack size, in bytes */ - windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */ - start_object, /* LPVOID - argument for new thread */ - 0U, /*DWORD dwCreationFlags - creation flags */ - &id /* LPDWORD - pointer to returned thread identifier */ ); - - rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS; - } -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - rv = PR_FAILURE; -#endif - break; - default: - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - rv = PR_FAILURE; - } - return rv; -} /* NSPRPUB_TESTS_CreateThread */ - -static void PR_CALLBACK lazyEntry(void *arg) -{ - PR_ASSERT(NULL == arg); -} /* lazyEntry */ - - -static void OneShot(void *arg) -{ - PRUintn pdkey; - PRLock *lock; - PRFileDesc *fd; - PRDir *dir; - PRFileDesc *pair[2]; - PRIntn test = (PRIntn)arg; - - for (test = 0; test < 12; ++test) { - - switch (test) - { - case 0: - lock = PR_NewLock(); - DPRINTF((output,"Thread[0x%x] called PR_NewLock\n", - PR_GetCurrentThread())); - PR_DestroyLock(lock); - break; - - case 1: - (void)PR_SecondsToInterval(1); - DPRINTF((output,"Thread[0x%x] called PR_SecondsToInterval\n", - PR_GetCurrentThread())); - break; - - case 2: (void)PR_CreateThread( - PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); - DPRINTF((output,"Thread[0x%x] called PR_CreateThread\n", - PR_GetCurrentThread())); - break; - - case 3: - fd = PR_Open("foreign.tmp", PR_CREATE_FILE | PR_RDWR, 0666); - DPRINTF((output,"Thread[0x%x] called PR_Open\n", - PR_GetCurrentThread())); - PR_Close(fd); - break; - - case 4: - fd = PR_NewUDPSocket(); - DPRINTF((output,"Thread[0x%x] called PR_NewUDPSocket\n", - PR_GetCurrentThread())); - PR_Close(fd); - break; - - case 5: - fd = PR_NewTCPSocket(); - DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocket\n", - PR_GetCurrentThread())); - PR_Close(fd); - break; - - case 6: -#ifdef SYMBIAN -#define TEMP_DIR "c:\\data\\" -#else -#define TEMP_DIR "/tmp/" -#endif - dir = PR_OpenDir(TEMP_DIR); - DPRINTF((output,"Thread[0x%x] called PR_OpenDir\n", - PR_GetCurrentThread())); - PR_CloseDir(dir); - break; - - case 7: - (void)PR_NewThreadPrivateIndex(&pdkey, NULL); - DPRINTF((output,"Thread[0x%x] called PR_NewThreadPrivateIndex\n", - PR_GetCurrentThread())); - break; - - case 8: - (void)PR_GetEnv("PATH"); - DPRINTF((output,"Thread[0x%x] called PR_GetEnv\n", - PR_GetCurrentThread())); - break; - - case 9: - (void)PR_NewTCPSocketPair(pair); - DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocketPair\n", - PR_GetCurrentThread())); - PR_Close(pair[0]); - PR_Close(pair[1]); - break; - - case 10: - PR_SetConcurrency(2); - DPRINTF((output,"Thread[0x%x] called PR_SetConcurrency\n", - PR_GetCurrentThread())); - break; - - case 11: - PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH); - DPRINTF((output,"Thread[0x%x] called PR_SetThreadPriority\n", - PR_GetCurrentThread())); - break; - - default: - break; - } /* switch() */ - } -} /* OneShot */ - -int main(int argc, char **argv) -{ - PRStatus rv; - PRInt32 thread_cnt = DEFAULT_THREAD_COUNT; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dt:"); - -#if defined(WIN32) - thread_provider = thread_win32; -#elif defined(_PR_PTHREADS) - thread_provider = thread_pthread; -#elif defined(IRIX) - thread_provider = thread_sproc; -#else - thread_provider = thread_nspr; -#endif - - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - case 't': /* thread count */ - thread_cnt = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_SetConcurrency(2); - - output = PR_GetSpecialFD(PR_StandardOutput); - - while (thread_cnt-- > 0) - { - rv = NSPRPUB_TESTS_CreateThread(OneShot, (void*)thread_cnt); - PR_ASSERT(PR_SUCCESS == rv); - PR_Sleep(PR_MillisecondsToInterval(5)); - } - PR_Sleep(PR_SecondsToInterval(3)); - return (PR_SUCCESS == PR_Cleanup()) ? 0 : 1; -} /* main */ - -/* foreign.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/forktest.c nspr-4.10.7/mozilla/nsprpub/pr/tests/forktest.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/forktest.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/forktest.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,311 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: forktest.c -** -** Description: UNIX test for fork functions. -** -** Modification History: -** 15-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** 12-June-97 AGarcic - Revert to return code 0 and 1, remove debug option (obsolete). -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include -#include -#include - -PRIntn failed_already=0; - -#ifdef XP_UNIX - -#include -#include -#include -#include - -static char *message = "Hello world!"; - -static void -ClientThreadFunc(void *arg) -{ - PRNetAddr addr; - PRFileDesc *sock = NULL; - PRInt32 tmp = (PRInt32)arg; - - /* - * Make sure the PR_Accept call will block - */ - - printf("Wait one second before connect\n"); - fflush(stdout); - PR_Sleep(PR_SecondsToInterval(1)); - - addr.inet.family = AF_INET; - addr.inet.ip = PR_htonl(INADDR_ANY); - addr.inet.port = 0; - if ((sock = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "failed to create TCP socket: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - if (PR_Bind(sock, &addr) != PR_SUCCESS) { - fprintf(stderr, "PR_Bind failed: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - addr.inet.ip = PR_htonl(INADDR_LOOPBACK); - addr.inet.port = PR_htons((PRInt16)tmp); - printf("Connecting to port %hu\n", PR_ntohs(addr.inet.port)); - fflush(stdout); - if (PR_Connect(sock, &addr, PR_SecondsToInterval(5)) != - PR_SUCCESS) { - fprintf(stderr, "PR_Connect failed: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - printf("Writing message \"%s\"\n", message); - fflush(stdout); - if (PR_Send(sock, message, strlen(message) + 1, 0, PR_INTERVAL_NO_TIMEOUT) == - -1) { - fprintf(stderr, "PR_Send failed: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } -finish: - if (sock) { - PR_Close(sock); - } - return; -} - -/* - * DoIO -- - * This function creates a thread that acts as a client and itself. - * acts as a server. Then it joins the client thread. - */ -static void -DoIO(void) -{ - PRThread *clientThread; - PRFileDesc *listenSock = NULL; - PRFileDesc *sock = NULL; - PRNetAddr addr; - PRInt32 nBytes; - char buf[128]; - - listenSock = PR_NewTCPSocket(); - if (!listenSock) { - fprintf(stderr, "failed to create a TCP socket: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - addr.inet.family = AF_INET; - addr.inet.ip = PR_htonl(INADDR_ANY); - addr.inet.port = 0; - if (PR_Bind(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "failed to bind socket: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "failed to get socket port number: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - if (PR_Listen(listenSock, 5) == PR_FAILURE) { - fprintf(stderr, "PR_Listen failed: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - clientThread = PR_CreateThread( PR_USER_THREAD, ClientThreadFunc, - (void *) PR_ntohs(addr.inet.port), PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "Cannot create client thread: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - failed_already = 1; - goto finish; - } - printf("Accepting connection at port %hu\n", PR_ntohs(addr.inet.port)); - fflush(stdout); - sock = PR_Accept(listenSock, &addr, PR_SecondsToInterval(5)); - if (!sock) { - fprintf(stderr, "PR_Accept failed: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - nBytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); - if (nBytes == -1) { - fprintf(stderr, "PR_Recv failed: error code %d\n", - PR_GetError()); - failed_already = 1; - goto finish; - } - - /* - * Make sure it has proper null byte to mark end of string - */ - - buf[sizeof(buf) - 1] = '\0'; - printf("Received \"%s\" from the client\n", buf); - fflush(stdout); - if (!strcmp(buf, message)) { - PR_JoinThread(clientThread); - - printf("The message is received correctly\n"); - fflush(stdout); - } else { - fprintf(stderr, "The message should be \"%s\"\n", - message); - failed_already = 1; - } - -finish: - if (listenSock) { - PR_Close(listenSock); - } - if (sock) { - PR_Close(sock); - } - return; -} - -#ifdef _PR_DCETHREADS - -#include - -pid_t PR_UnixFork1(void) -{ - pid_t parent = getpid(); - int rv = syscall(SYS_fork); - - if (rv == -1) { - return (pid_t) -1; - } else { - /* For each process, rv is the pid of the other process */ - if (rv == parent) { - /* the child */ - return 0; - } else { - /* the parent */ - return rv; - } - } -} - -#elif defined(SOLARIS) - -/* - * It seems like that in Solaris 2.4 one must call fork1() if the - * the child process is going to use thread functions. Solaris 2.5 - * doesn't have this problem. Calling fork() also works. - */ - -pid_t PR_UnixFork1(void) -{ - return fork1(); -} - -#else - -pid_t PR_UnixFork1(void) -{ - return fork(); -} - -#endif /* PR_DCETHREADS */ - -int main(int argc, char **argv) -{ - pid_t pid; - int rv; - - /* main test program */ - - DoIO(); - - pid = PR_UnixFork1(); - - if (pid == (pid_t) -1) { - fprintf(stderr, "Fork failed: errno %d\n", errno); - failed_already=1; - return 1; - } else if (pid > 0) { - int childStatus; - - printf("Fork succeeded. Parent process continues.\n"); - DoIO(); - if ((rv = waitpid(pid, &childStatus, 0)) != pid) { -#if defined(IRIX) && !defined(_PR_PTHREADS) - /* - * nspr may handle SIGCLD signal - */ - if ((rv < 0) && (errno == ECHILD)) { - } else -#endif - { - fprintf(stderr, "waitpid failed: %d\n", errno); - failed_already = 1; - } - } else if (!WIFEXITED(childStatus) - || WEXITSTATUS(childStatus) != 0) { - failed_already = 1; - } - printf("Parent process exits.\n"); - if (!failed_already) { - printf("PASSED\n"); - } else { - printf("FAILED\n"); - } - return failed_already; - } else { -#if defined(IRIX) && !defined(_PR_PTHREADS) - extern void _PR_IRIX_CHILD_PROCESS(void); - _PR_IRIX_CHILD_PROCESS(); -#endif - printf("Fork succeeded. Child process continues.\n"); - DoIO(); - printf("Child process exits.\n"); - return failed_already; - } -} - -#else /* XP_UNIX */ - -int main( int argc, -char *argv[] -) -{ - - printf("The fork test is applicable to Unix only.\n"); - return 0; - -} - -#endif /* XP_UNIX */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/formattm.c nspr-4.10.7/mozilla/nsprpub/pr/tests/formattm.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/formattm.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/formattm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* A test program for PR_FormatTime and PR_FormatTimeUSEnglish */ - -#include "prtime.h" - -#include - -int main(int argc, char **argv) -{ - char buffer[256]; - char small_buffer[8]; - PRTime now; - PRExplodedTime tod; - - now = PR_Now(); - PR_ExplodeTime(now, PR_LocalTimeParameters, &tod); - - if (PR_FormatTime(buffer, sizeof(buffer), - "%a %b %d %H:%M:%S %Z %Y", &tod) != 0) { - printf("%s\n", buffer); - } else { - fprintf(stderr, "PR_FormatTime(buffer) failed\n"); - return 1; - } - - small_buffer[0] = '?'; - if (PR_FormatTime(small_buffer, sizeof(small_buffer), - "%a %b %d %H:%M:%S %Z %Y", &tod) == 0) { - if (small_buffer[0] != '\0') { - fprintf(stderr, "PR_FormatTime(small_buffer) did not output " - "an empty string on failure\n"); - return 1; - } - printf("%s\n", small_buffer); - } else { - fprintf(stderr, "PR_FormatTime(small_buffer) succeeded " - "unexpectedly\n"); - return 1; - } - - (void)PR_FormatTimeUSEnglish(buffer, sizeof(buffer), - "%a %b %d %H:%M:%S %Z %Y", &tod); - printf("%s\n", buffer); - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/freeif.c nspr-4.10.7/mozilla/nsprpub/pr/tests/freeif.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/freeif.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/freeif.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * A test to see if the macros PR_DELETE and PR_FREEIF are - * properly defined. (See Bugzilla bug #39110.) - */ - -#include "nspr.h" - -#include -#include - -static void Noop(void) { } - -static void Fail(void) -{ - printf("FAIL\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - int foo = 1; - char *ptr = NULL; - - /* this fails to compile with the old definition of PR_DELETE */ - if (foo) - PR_DELETE(ptr); - else - Noop(); - - /* this nests incorrectly with the old definition of PR_FREEIF */ - if (foo) - PR_FREEIF(ptr); - else - Fail(); - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/fsync.c nspr-4.10.7/mozilla/nsprpub/pr/tests/fsync.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/fsync.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/fsync.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prmem.h" -#include "prprf.h" -#include "prinrval.h" - -#include "plerror.h" -#include "plgetopt.h" - -static PRFileDesc *err = NULL; - -static void Help(void) -{ - PR_fprintf(err, "Usage: [-S] [-K ] [-h] \n"); - PR_fprintf(err, "\t-c Nuber of iterations (default: 10)\n"); - PR_fprintf(err, "\t-S Sync the file (default: FALSE)\n"); - PR_fprintf(err, "\t-K Size of file (K bytes) (default: 10)\n"); - PR_fprintf(err, "\t Name of file to write (default: /usr/tmp/sync.dat)\n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PRStatus rv; - PLOptStatus os; - PRUint8 *buffer; - PRFileDesc *file = NULL; - const char *filename = "sync.dat"; - PRUint32 index, loops, iterations = 10, filesize = 10; - PRIntn flags = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE; - PLOptState *opt = PL_CreateOptState(argc, argv, "hSK:c:"); - PRIntervalTime time, total = 0, shortest = 0x7fffffff, longest = 0; - - err = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: /* Name of file to create */ - filename = opt->value; - break; - case 'S': /* Use sych option on file */ - flags |= PR_SYNC; - break; - case 'K': /* Size of file to write */ - filesize = atoi(opt->value); - break; - case 'c': /* Number of iterations */ - iterations = atoi(opt->value); - break; - case 'h': /* user wants some guidance */ - default: /* user needs some guidance */ - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - } - } - PL_DestroyOptState(opt); - - file = PR_Open(filename, flags, 0666); - if (NULL == file) - { - PL_FPrintError(err, "Failed to open file"); - return 1; - } - - buffer = (PRUint8*)PR_CALLOC(1024); - if (NULL == buffer) - { - PL_FPrintError(err, "Cannot allocate buffer"); - return 1; - } - - for (index = 0; index < sizeof(buffer); ++index) - buffer[index] = (PRUint8)index; - - for (loops = 0; loops < iterations; ++loops) - { - time = PR_IntervalNow(); - for (index = 0; index < filesize; ++index) - { - PR_Write(file, buffer, 1024); - } - time = (PR_IntervalNow() - time); - - total += time; - if (time < shortest) shortest = time; - else if (time > longest) longest = time; - if (0 != PR_Seek(file, 0, PR_SEEK_SET)) - { - PL_FPrintError(err, "Rewinding file"); - return 1; - } - } - - total = total / iterations; - PR_fprintf( - err, "%u iterations over a %u kbyte %sfile: %u [%u] %u\n", - iterations, filesize, ((flags & PR_SYNC) ? "SYNCH'd " : ""), - PR_IntervalToMicroseconds(shortest), - PR_IntervalToMicroseconds(total), - PR_IntervalToMicroseconds(longest)); - - PR_DELETE(buffer); - rv = PR_Close(file); - if (PR_SUCCESS != rv) - { - PL_FPrintError(err, "Closing file failed"); - return 1; - } - rv = PR_Delete(filename); - if (PR_SUCCESS != rv) - { - PL_FPrintError(err, "Deleting file failed"); - return 1; - } - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/getai.c nspr-4.10.7/mozilla/nsprpub/pr/tests/getai.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/getai.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/getai.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" - -#include -#include - -int main(int argc, char **argv) -{ - PRAddrInfo *ai; - void *iter; - PRNetAddr addr; - - ai = PR_GetAddrInfoByName(argv[1], PR_AF_UNSPEC, PR_AI_ADDRCONFIG); - if (ai == NULL) { - fprintf(stderr, "PR_GetAddrInfoByName failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - printf("%s\n", PR_GetCanonNameFromAddrInfo(ai)); - iter = NULL; - while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) { - char buf[128]; - PR_NetAddrToString(&addr, buf, sizeof buf); - printf("%s\n", buf); - } - PR_FreeAddrInfo(ai); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/gethost.c nspr-4.10.7/mozilla/nsprpub/pr/tests/gethost.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/gethost.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/gethost.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,259 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: gethost.c - * - * Description: tests various functions in prnetdb.h - * - * Usage: gethost [-6] [hostname] - */ - -#include "prio.h" -#include "prnetdb.h" -#include "plgetopt.h" - -#include -#include - -#define DEFAULT_HOST_NAME "mcom.com" - -static void Help(void) -{ - fprintf(stderr, "Usage: gethost [-h] [hostname]\n"); - fprintf(stderr, "\t-h help\n"); - fprintf(stderr, "\thostname Name of host (default: %s)\n", - DEFAULT_HOST_NAME); -} /* Help */ - -/* - * Prints the contents of a PRHostEnt structure - */ -void PrintHostent(const PRHostEnt *he) -{ - int i; - int j; - - printf("h_name: %s\n", he->h_name); - for (i = 0; he->h_aliases[i]; i++) { - printf("h_aliases[%d]: %s\n", i, he->h_aliases[i]); - } - printf("h_addrtype: %d\n", he->h_addrtype); - printf("h_length: %d\n", he->h_length); - for (i = 0; he->h_addr_list[i]; i++) { - printf("h_addr_list[%d]: ", i); - for (j = 0; j < he->h_length; j++) { - if (j != 0) printf("."); - printf("%u", (unsigned char)he->h_addr_list[i][j]); - } - printf("\n"); - } -} - -int main(int argc, char **argv) -{ - const char *hostName = DEFAULT_HOST_NAME; - PRHostEnt he, reversehe; - char buf[PR_NETDB_BUF_SIZE]; - char reversebuf[PR_NETDB_BUF_SIZE]; - PRIntn idx; - PRNetAddr addr; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "h"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) continue; - switch (opt->option) { - case 0: /* naked */ - hostName = opt->value; - break; - case 'h': /* Help message */ - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - if (PR_GetHostByName(hostName, buf, sizeof(buf), &he) == PR_FAILURE) { - fprintf(stderr, "PR_GetHostByName failed\n"); - exit(1); - } - PrintHostent(&he); - idx = 0; - while (1) { - idx = PR_EnumerateHostEnt(idx, &he, 0, &addr); - if (idx == -1) { - fprintf(stderr, "PR_EnumerateHostEnt failed\n"); - exit(1); - } - if (idx == 0) break; /* normal loop termination */ - printf("reverse lookup\n"); - if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf), - &reversehe) == PR_FAILURE) { - fprintf(stderr, "PR_GetHostByAddr failed\n"); - exit(1); - } - PrintHostent(&reversehe); - } - - printf("PR_GetIPNodeByName with PR_AF_INET\n"); - if (PR_GetIPNodeByName(hostName, PR_AF_INET, PR_AI_DEFAULT, - buf, sizeof(buf), &he) == PR_FAILURE) { - fprintf(stderr, "PR_GetIPNodeByName failed\n"); - exit(1); - } - PrintHostent(&he); - printf("PR_GetIPNodeByName with PR_AF_INET6\n"); - if (PR_GetIPNodeByName(hostName, PR_AF_INET6, PR_AI_DEFAULT, - buf, sizeof(buf), &he) == PR_FAILURE) { - fprintf(stderr, "PR_GetIPNodeByName failed\n"); - exit(1); - } - PrintHostent(&he); - idx = 0; - printf("PR_GetHostByAddr with PR_AF_INET6\n"); - while (1) { - idx = PR_EnumerateHostEnt(idx, &he, 0, &addr); - if (idx == -1) { - fprintf(stderr, "PR_EnumerateHostEnt failed\n"); - exit(1); - } - if (idx == 0) break; /* normal loop termination */ - printf("reverse lookup\n"); - if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf), - &reversehe) == PR_FAILURE) { - fprintf(stderr, "PR_GetHostByAddr failed\n"); - exit(1); - } - PrintHostent(&reversehe); - } - printf("PR_GetHostByAddr with PR_AF_INET6 done\n"); - - PR_StringToNetAddr("::1", &addr); - if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_TRUE) { - fprintf(stderr, "addr should not be ipv4 mapped address\n"); - exit(1); - } - if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { - fprintf(stderr, "addr should be loopback address\n"); - exit(1); - } - - PR_StringToNetAddr("127.0.0.1", &addr); - if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { - fprintf(stderr, "addr should be loopback address\n"); - exit(1); - } - PR_StringToNetAddr("::FFFF:127.0.0.1", &addr); - if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_FALSE) { - fprintf(stderr, "addr should be ipv4 mapped address\n"); - exit(1); - } - if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { - fprintf(stderr, "addr should be loopback address\n"); - exit(1); - } - - if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_InitializeNetAddr failed\n"); - exit(1); - } - if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { - fprintf(stderr, "addr should be unspecified address\n"); - exit(1); - } - if (PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_InitializeNetAddr failed\n"); - exit(1); - } - if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { - fprintf(stderr, "addr should be loopback address\n"); - exit(1); - } - - if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_SetNetAddr failed\n"); - exit(1); - } - if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { - fprintf(stderr, "addr should be unspecified address\n"); - exit(1); - } - if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_SetNetAddr failed\n"); - exit(1); - } - if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { - fprintf(stderr, "addr should be loopback address\n"); - exit(1); - } - - addr.inet.family = PR_AF_INET; - addr.inet.port = 0; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { - fprintf(stderr, "addr should be unspecified address\n"); - exit(1); - } - { - char buf[256]; - PR_NetAddrToString(&addr, buf, 256); - printf("IPv4 INADDRANY: %s\n", buf); - } - addr.inet.family = PR_AF_INET; - addr.inet.port = 0; - addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { - fprintf(stderr, "addr should be loopback address\n"); - exit(1); - } - { - char buf[256]; - PR_NetAddrToString(&addr, buf, 256); - printf("IPv4 LOOPBACK: %s\n", buf); - } - - if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_SetNetAddr failed\n"); - exit(1); - } - if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { - fprintf(stderr, "addr should be unspecified address\n"); - exit(1); - } - { - char buf[256]; - PR_NetAddrToString(&addr, buf, 256); - printf("IPv6 INADDRANY: %s\n", buf); - } - if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_SetNetAddr failed\n"); - exit(1); - } - if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { - fprintf(stderr, "addr should be loopback address\n"); - exit(1); - } - { - char buf[256]; - PR_NetAddrToString(&addr, buf, 256); - printf("IPv6 LOOPBACK: %s\n", buf); - } - { - PRIPv6Addr v6addr; - char tmp_buf[256]; - - PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr); - - PR_ConvertIPv4AddrToIPv6(addr.inet.ip, &v6addr); - PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr); - addr.ipv6.ip = v6addr; - PR_NetAddrToString(&addr, tmp_buf, 256); - printf("IPv4-mapped IPv6 LOOPBACK: %s\n", tmp_buf); - } - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/getproto.c nspr-4.10.7/mozilla/nsprpub/pr/tests/getproto.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/getproto.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/getproto.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - ************************************************************************* - * - * File: getproto.c - * - * A test program for PR_GetProtoByName and PR_GetProtoByNumber - * - ************************************************************************* - */ - -#include "plstr.h" -#include "plerror.h" -#include "prinit.h" -#include "prprf.h" -#include "prnetdb.h" -#include "prerror.h" - -int main(int argc, char **argv) -{ - PRFileDesc *prstderr = PR_GetSpecialFD(PR_StandardError); - PRBool failed = PR_FALSE; - PRProtoEnt proto; - char buf[2048]; - PRStatus rv; - - PR_STDIO_INIT(); - rv = PR_GetProtoByName("tcp", buf, sizeof(buf), &proto); - if (PR_FAILURE == rv) { - failed = PR_TRUE; - PL_FPrintError(prstderr, "PR_GetProtoByName failed"); - } - else if (6 != proto.p_num) { - PR_fprintf( - prstderr,"tcp is usually 6, but is %d on this machine\n", - proto.p_num); - } - else PR_fprintf(prstderr, "tcp is protocol number %d\n", proto.p_num); - - rv = PR_GetProtoByName("udp", buf, sizeof(buf), &proto); - if (PR_FAILURE == rv) { - failed = PR_TRUE; - PL_FPrintError(prstderr, "PR_GetProtoByName failed"); - } - else if (17 != proto.p_num) { - PR_fprintf( - prstderr, "udp is usually 17, but is %d on this machine\n", - proto.p_num); - } - else PR_fprintf(prstderr, "udp is protocol number %d\n", proto.p_num); - - rv = PR_GetProtoByNumber(6, buf, sizeof(buf), &proto); - if (PR_FAILURE == rv) { - failed = PR_TRUE; - PL_FPrintError(prstderr, "PR_GetProtoByNumber failed"); - } - else if (PL_strcmp("tcp", proto.p_name)) { - PR_fprintf( - prstderr, "Protocol number 6 is usually tcp, but is %s" - " on this platform\n", proto.p_name); - } - else PR_fprintf(prstderr, "Protocol number 6 is %s\n", proto.p_name); - - rv = PR_GetProtoByNumber(17, buf, sizeof(buf), &proto); - if (PR_FAILURE == rv) { - failed = PR_TRUE; - PL_FPrintError(prstderr, "PR_GetProtoByNumber failed"); - } - else if (PL_strcmp("udp", proto.p_name)) { - PR_fprintf( - prstderr, "Protocol number 17 is usually udp, but is %s" - " on this platform\n", proto.p_name); - } - else PR_fprintf(prstderr, "Protocol number 17 is %s\n", proto.p_name); - - PR_fprintf(prstderr, (failed) ? "FAILED\n" : "PASSED\n"); - return (failed) ? 1 : 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/i2l.c nspr-4.10.7/mozilla/nsprpub/pr/tests/i2l.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/i2l.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/i2l.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "prio.h" -#include "prinit.h" -#include "prprf.h" -#include "prlong.h" - -#include "plerror.h" -#include "plgetopt.h" - -typedef union Overlay_i -{ - PRInt32 i; - PRInt64 l; -} Overlay_i; - -typedef union Overlay_u -{ - PRUint32 i; - PRUint64 l; -} Overlay_u; - -static PRFileDesc *err = NULL; - -static void Help(void) -{ - PR_fprintf(err, "Usage: -i n | -u n | -h\n"); - PR_fprintf(err, "\t-i n treat following number as signed integer\n"); - PR_fprintf(err, "\t-u n treat following number as unsigned integer\n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); -} /* Help */ - -static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv) -{ - Overlay_i si; - Overlay_u ui; - PLOptStatus os; - PRBool bsi = PR_FALSE, bui = PR_FALSE; - PLOptState *opt = PL_CreateOptState(argc, argv, "hi:u:"); - err = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'i': /* signed integer */ - si.i = (PRInt32)atoi(opt->value); - bsi = PR_TRUE; - break; - case 'u': /* unsigned */ - ui.i = (PRUint32)atoi(opt->value); - bui = PR_TRUE; - break; - case 'h': /* user wants some guidance */ - default: - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - } - } - PL_DestroyOptState(opt); - -#if defined(HAVE_LONG_LONG) - PR_fprintf(err, "We have long long\n"); -#else - PR_fprintf(err, "We don't have long long\n"); -#endif - - if (bsi) - { - PR_fprintf(err, "Converting %ld: ", si.i); - LL_I2L(si.l, si.i); - PR_fprintf(err, "%lld\n", si.l); - } - - if (bui) - { - PR_fprintf(err, "Converting %lu: ", ui.i); - LL_I2L(ui.l, ui.i); - PR_fprintf(err, "%llu\n", ui.l); - } - return 0; - -} /* main */ - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ - -/* i2l.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/initclk.c nspr-4.10.7/mozilla/nsprpub/pr/tests/initclk.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/initclk.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/initclk.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This is a regression test for the bug that the interval timer - * is not initialized when _PR_CreateCPU calls PR_IntervalNow. - * The bug would make this test program finish prematurely, - * when the SHORT_TIMEOUT period expires. The correct behavior - * is for the test to finish when the LONG_TIMEOUT period expires. - */ - -#include "prlock.h" -#include "prcvar.h" -#include "prthread.h" -#include "prinrval.h" -#include "prlog.h" -#include -#include - -/* The timeouts, in milliseconds */ -#define SHORT_TIMEOUT 1000 -#define LONG_TIMEOUT 3000 - -PRLock *lock1, *lock2; -PRCondVar *cv1, *cv2; - -void ThreadFunc(void *arg) -{ - PR_Lock(lock1); - PR_WaitCondVar(cv1, PR_MillisecondsToInterval(SHORT_TIMEOUT)); - PR_Unlock(lock1); -} - -int main(int argc, char **argv) -{ - PRThread *thread; - PRIntervalTime start, end; - PRUint32 elapsed_ms; - - lock1 = PR_NewLock(); - PR_ASSERT(NULL != lock1); - cv1 = PR_NewCondVar(lock1); - PR_ASSERT(NULL != cv1); - lock2 = PR_NewLock(); - PR_ASSERT(NULL != lock2); - cv2 = PR_NewCondVar(lock2); - PR_ASSERT(NULL != cv2); - start = PR_IntervalNow(); - thread = PR_CreateThread( - PR_USER_THREAD, - ThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0); - PR_ASSERT(NULL != thread); - PR_Lock(lock2); - PR_WaitCondVar(cv2, PR_MillisecondsToInterval(LONG_TIMEOUT)); - PR_Unlock(lock2); - PR_JoinThread(thread); - end = PR_IntervalNow(); - elapsed_ms = PR_IntervalToMilliseconds((PRIntervalTime)(end - start)); - /* Allow 100ms imprecision */ - if (elapsed_ms < LONG_TIMEOUT - 100 || elapsed_ms > LONG_TIMEOUT + 100) { - printf("Elapsed time should be %u ms but is %u ms\n", - LONG_TIMEOUT, elapsed_ms); - printf("FAIL\n"); - exit(1); - } - printf("Elapsed time: %u ms, expected time: %u ms\n", - LONG_TIMEOUT, elapsed_ms); - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/inrval.c nspr-4.10.7/mozilla/nsprpub/pr/tests/inrval.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/inrval.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/inrval.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** file: inrval.c -** description: Interval conversion test. -** Modification History: -** 15-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -**/ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prinit.h" -#include "obsolete/pralarm.h" - -#include "prio.h" -#include "prprf.h" -#include "prlock.h" -#include "prlong.h" -#include "prcvar.h" -#include "prinrval.h" -#include "prtime.h" - -#include "plgetopt.h" - -#include -#include - -static PRIntn debug_mode; -static PRFileDesc *output; - - -static void TestConversions(void) -{ - PRIntervalTime ticks = PR_TicksPerSecond(); - - if (debug_mode) { - PR_fprintf(output, "PR_TicksPerSecond: %ld\n\n", ticks); - PR_fprintf(output, "PR_SecondsToInterval(1): %ld\n", PR_SecondsToInterval(1)); - PR_fprintf(output, "PR_MillisecondsToInterval(1000): %ld\n", PR_MillisecondsToInterval(1000)); - PR_fprintf(output, "PR_MicrosecondsToInterval(1000000): %ld\n\n", PR_MicrosecondsToInterval(1000000)); - - PR_fprintf(output, "PR_SecondsToInterval(3): %ld\n", PR_SecondsToInterval(3)); - PR_fprintf(output, "PR_MillisecondsToInterval(3000): %ld\n", PR_MillisecondsToInterval(3000)); - PR_fprintf(output, "PR_MicrosecondsToInterval(3000000): %ld\n\n", PR_MicrosecondsToInterval(3000000)); - - PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks)); - PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks)); - PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks)); - - ticks *= 3; - PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks)); - PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks)); - PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks)); - } /*end debug mode */ -} /* TestConversions */ - -static void TestIntervalOverhead(void) -{ - /* Hopefully the optimizer won't delete this function */ - PRUint32 elapsed, per_call, loops = 1000000; - - PRIntervalTime timeout, timein = PR_IntervalNow(); - while (--loops > 0) - timeout = PR_IntervalNow(); - - elapsed = 1000U * PR_IntervalToMicroseconds(timeout - timein); - per_call = elapsed / 1000000U; - PR_fprintf( - output, "Overhead of 'PR_IntervalNow()' is %u nsecs\n\n", per_call); -} /* TestIntervalOverhead */ - -static void TestNowOverhead(void) -{ - PRTime timeout, timein; - PRInt32 overhead, loops = 1000000; - PRInt64 elapsed, per_call, ten23rd, ten26th; - - LL_I2L(ten23rd, 1000); - LL_I2L(ten26th, 1000000); - - timein = PR_Now(); - while (--loops > 0) - timeout = PR_Now(); - - LL_SUB(elapsed, timeout, timein); - LL_MUL(elapsed, elapsed, ten23rd); - LL_DIV(per_call, elapsed, ten26th); - LL_L2I(overhead, per_call); - PR_fprintf( - output, "Overhead of 'PR_Now()' is %u nsecs\n\n", overhead); -} /* TestNowOverhead */ - -static void TestIntervals(void) -{ - PRStatus rv; - PRUint32 delta; - PRInt32 seconds; - PRUint64 elapsed, thousand; - PRTime timein, timeout; - PRLock *ml = PR_NewLock(); - PRCondVar *cv = PR_NewCondVar(ml); - for (seconds = 0; seconds < 10; ++seconds) - { - PRIntervalTime ticks = PR_SecondsToInterval(seconds); - PR_Lock(ml); - timein = PR_Now(); - rv = PR_WaitCondVar(cv, ticks); - timeout = PR_Now(); - PR_Unlock(ml); - LL_SUB(elapsed, timeout, timein); - LL_I2L(thousand, 1000); - LL_DIV(elapsed, elapsed, thousand); - LL_L2UI(delta, elapsed); - if (debug_mode) PR_fprintf(output, - "TestIntervals: %swaiting %ld seconds took %ld msecs\n", - ((rv == PR_SUCCESS) ? "" : "FAILED "), seconds, delta); - } - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); - if (debug_mode) PR_fprintf(output, "\n"); -} /* TestIntervals */ - -static PRIntn PR_CALLBACK RealMain(int argc, char** argv) -{ - PRUint32 vcpu, cpus = 0, loops = 1000; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - - /* main test */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dl:c:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'c': /* concurrency counter */ - cpus = atoi(opt->value); - break; - case 'l': /* loop counter */ - loops = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - output = PR_GetSpecialFD(PR_StandardOutput); - PR_fprintf(output, "inrval: Examine stdout to determine results.\n"); - - if (cpus == 0) cpus = 8; - if (loops == 0) loops = 1000; - - if (debug_mode > 0) - { - PR_fprintf(output, "Inrval: Using %d loops\n", loops); - PR_fprintf(output, "Inrval: Using 1 and %d cpu(s)\n", cpus); - } - - for (vcpu = 1; vcpu <= cpus; vcpu += cpus - 1) - { - if (debug_mode) - PR_fprintf(output, "\nInrval: Using %d CPU(s)\n\n", vcpu); - PR_SetConcurrency(vcpu); - - TestNowOverhead(); - TestIntervalOverhead(); - TestConversions(); - TestIntervals(); - } - - return 0; -} - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/instrumt.c nspr-4.10.7/mozilla/nsprpub/pr/tests/instrumt.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/instrumt.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/instrumt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,475 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: instrumt.c -** Description: This test is for the NSPR debug aids defined in -** prcountr.h, prtrace.h, prolock.h -** -** The test case tests the three debug aids in NSPR: -** -** Diagnostic messages can be enabled using "instrumt -v 6" -** This sets the msgLevel to something that PR_LOG() likes. -** Also define in the environment "NSPR_LOG_MODULES=Test:6" -** -** CounterTest() tests the counter facility. This test -** creates 4 threads. Each thread either increments, decrements, -** adds to or subtracts from a counter, depending on an argument -** passed to the thread at thread-create time. Each of these threads -** does COUNT_LIMIT iterations doing its thing. When all 4 threads -** are done, the result of the counter is evaluated. If all was atomic, -** the the value of the counter should be zero. -** -** TraceTest(): -** This test mingles with the counter test. Counters trace. -** A thread to extract trace entries on the fly is started. -** A thread to dump trace entries to a file is started. -** -** OrderedLockTest(): -** -** -** -** -** -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define COUNT_LIMIT (10 * ( 1024)) - -#define SMALL_TRACE_BUFSIZE ( 60 * 1024 ) - -typedef enum -{ - CountLoop = 1, - TraceLoop = 2, - TraceFlow = 3 -} TraceTypes; - - -PRLogModuleLevel msgLevel = PR_LOG_ALWAYS; - -PRBool help = PR_FALSE; -PRBool failed = PR_FALSE; - - -PRLogModuleInfo *lm; -PRMonitor *mon; -PRInt32 activeThreads = 0; -PR_DEFINE_COUNTER( hCounter ); -PR_DEFINE_TRACE( hTrace ); - -static void Help(void) -{ - printf("Help? ... Ha!\n"); -} - -static void ListCounters(void) -{ - PR_DEFINE_COUNTER( qh ); - PR_DEFINE_COUNTER( rh ); - const char *qn, *rn, *dn; - const char **qname = &qn, **rname = &rn, **desc = &dn; - PRUint32 tCtr; - - PR_INIT_COUNTER_HANDLE( qh, NULL ); - PR_FIND_NEXT_COUNTER_QNAME(qh, qh ); - while ( qh != NULL ) - { - PR_INIT_COUNTER_HANDLE( rh, NULL ); - PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh ); - while ( rh != NULL ) - { - PR_GET_COUNTER_NAME_FROM_HANDLE( rh, qname, rname, desc ); - tCtr = PR_GET_COUNTER(tCtr, rh); - PR_LOG( lm, msgLevel, - ( "QName: %s RName: %s Desc: %s Value: %ld\n", - qn, rn, dn, tCtr )); - PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh ); - } - PR_FIND_NEXT_COUNTER_QNAME(qh, qh); - } - return; -} /* end ListCounters() */ - -static void ListTraces(void) -{ - PR_DEFINE_TRACE( qh ); - PR_DEFINE_TRACE( rh ); - const char *qn, *rn, *dn; - const char **qname = &qn, **rname = &rn, **desc = &dn; - - PR_INIT_TRACE_HANDLE( qh, NULL ); - PR_FIND_NEXT_TRACE_QNAME(qh, qh ); - while ( qh != NULL ) - { - PR_INIT_TRACE_HANDLE( rh, NULL ); - PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh ); - while ( rh != NULL ) - { - PR_GET_TRACE_NAME_FROM_HANDLE( rh, qname, rname, desc ); - PR_LOG( lm, msgLevel, - ( "QName: %s RName: %s Desc: %s", - qn, rn, dn )); - PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh ); - } - PR_FIND_NEXT_TRACE_QNAME(qh, qh); - } - return; -} /* end ListCounters() */ - - -static PRInt32 one = 1; -static PRInt32 two = 2; -static PRInt32 three = 3; -static PRInt32 four = 4; - -/* -** Thread to iteratively count something. -*/ -static void PR_CALLBACK CountSomething( void *arg ) -{ - PRInt32 switchVar = *((PRInt32 *)arg); - PRInt32 i; - - PR_LOG( lm, msgLevel, - ("CountSomething: begin thread %ld", switchVar )); - - for ( i = 0; i < COUNT_LIMIT ; i++) - { - switch ( switchVar ) - { - case 1 : - PR_INCREMENT_COUNTER( hCounter ); - break; - case 2 : - PR_DECREMENT_COUNTER( hCounter ); - break; - case 3 : - PR_ADD_TO_COUNTER( hCounter, 1 ); - break; - case 4 : - PR_SUBTRACT_FROM_COUNTER( hCounter, 1 ); - break; - default : - PR_ASSERT( 0 ); - break; - } - PR_TRACE( hTrace, CountLoop, switchVar, i, 0, 0, 0, 0, 0 ); - } /* end for() */ - - PR_LOG( lm, msgLevel, - ("CounterSomething: end thread %ld", switchVar )); - - PR_EnterMonitor(mon); - --activeThreads; - PR_Notify( mon ); - PR_ExitMonitor(mon); - - return; -} /* end CountSomething() */ - -/* -** Create the counter threads. -*/ -static void CounterTest( void ) -{ - PRThread *t1, *t2, *t3, *t4; - PRIntn i = 0; - PR_DEFINE_COUNTER( tc ); - PR_DEFINE_COUNTER( zCounter ); - - PR_LOG( lm, msgLevel, - ("Begin CounterTest")); - - /* - ** Test Get and Set of a counter. - ** - */ - PR_CREATE_COUNTER( zCounter, "Atomic", "get/set test", "test get and set of counter" ); - PR_SET_COUNTER( zCounter, 9 ); - PR_GET_COUNTER( i, zCounter ); - if ( i != 9 ) - { - failed = PR_TRUE; - PR_LOG( lm, msgLevel, - ("Counter set/get failed")); - } - - activeThreads += 4; - PR_CREATE_COUNTER( hCounter, "Atomic", "SMP Tests", "test atomic nature of counter" ); - - PR_GET_COUNTER_HANDLE_FROM_NAME( tc, "Atomic", "SMP Tests" ); - PR_ASSERT( tc == hCounter ); - - t1 = PR_CreateThread(PR_USER_THREAD, - CountSomething, &one, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - PR_ASSERT(t1); - - t2 = PR_CreateThread(PR_USER_THREAD, - CountSomething, &two, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - PR_ASSERT(t2); - - t3 = PR_CreateThread(PR_USER_THREAD, - CountSomething, &three, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - PR_ASSERT(t3); - - t4 = PR_CreateThread(PR_USER_THREAD, - CountSomething, &four, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - PR_ASSERT(t4); - - PR_LOG( lm, msgLevel, - ("Counter Threads started")); - - ListCounters(); - return; -} /* end CounterTest() */ - -/* -** Thread to dump trace buffer to a file. -*/ -static void PR_CALLBACK RecordTrace(void *arg ) -{ - PR_RECORD_TRACE_ENTRIES(); - - PR_EnterMonitor(mon); - --activeThreads; - PR_Notify( mon ); - PR_ExitMonitor(mon); - - return; -} /* end RecordTrace() */ - - - -#define NUM_TRACE_RECORDS ( 10000 ) -/* -** Thread to extract and print trace entries from the buffer. -*/ -static void PR_CALLBACK SampleTrace( void *arg ) -{ -#if defined(DEBUG) || defined(FORCE_NSPR_TRACE) - PRInt32 found, rc; - PRTraceEntry *foundEntries; - PRInt32 i; - - foundEntries = (PRTraceEntry *)PR_Malloc( NUM_TRACE_RECORDS * sizeof(PRTraceEntry)); - PR_ASSERT(foundEntries != NULL ); - - do - { - rc = PR_GetTraceEntries( foundEntries, NUM_TRACE_RECORDS, &found); - PR_LOG( lm, msgLevel, - ("SampleTrace: Lost Data: %ld found: %ld", rc, found )); - - if ( found != 0) - { - for ( i = 0 ; i < found; i++ ) - { - PR_LOG( lm, msgLevel, - ("SampleTrace, detail: Thread: %p, Time: %llX, UD0: %ld, UD1: %ld, UD2: %8.8ld", - (foundEntries +i)->thread, - (foundEntries +i)->time, - (foundEntries +i)->userData[0], - (foundEntries +i)->userData[1], - (foundEntries +i)->userData[2] )); - } - } - PR_Sleep(PR_MillisecondsToInterval(50)); - } - while( found != 0 && activeThreads >= 1 ); - - PR_Free( foundEntries ); - - PR_EnterMonitor(mon); - --activeThreads; - PR_Notify( mon ); - PR_ExitMonitor(mon); - - PR_LOG( lm, msgLevel, - ("SampleTrace(): exiting")); - -#endif - return; -} /* end RecordTrace() */ - -/* -** Basic trace test. -*/ -static void TraceTest( void ) -{ - PRInt32 i; - PRInt32 size; - PR_DEFINE_TRACE( th ); - PRThread *t1, *t2; - - PR_LOG( lm, msgLevel, - ("Begin TraceTest")); - - size = SMALL_TRACE_BUFSIZE; - PR_SET_TRACE_OPTION( PRTraceBufSize, &size ); - PR_GET_TRACE_OPTION( PRTraceBufSize, &i ); - - PR_CREATE_TRACE( th, "TraceTest", "tt2", "A description for the trace test" ); - PR_CREATE_TRACE( th, "TraceTest", "tt3", "A description for the trace test" ); - PR_CREATE_TRACE( th, "TraceTest", "tt4", "A description for the trace test" ); - PR_CREATE_TRACE( th, "TraceTest", "tt5", "A description for the trace test" ); - PR_CREATE_TRACE( th, "TraceTest", "tt6", "A description for the trace test" ); - PR_CREATE_TRACE( th, "TraceTest", "tt7", "A description for the trace test" ); - PR_CREATE_TRACE( th, "TraceTest", "tt8", "A description for the trace test" ); - - PR_CREATE_TRACE( th, "Trace Test", "tt0", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt1", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt2", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt3", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt4", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt5", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt6", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt7", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt8", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt9", "QName is Trace Test, not TraceTest" ); - PR_CREATE_TRACE( th, "Trace Test", "tt10", "QName is Trace Test, not TraceTest" ); - - - - activeThreads += 2; - t1 = PR_CreateThread(PR_USER_THREAD, - RecordTrace, NULL, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - PR_ASSERT(t1); - - t2 = PR_CreateThread(PR_USER_THREAD, - SampleTrace, 0, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - PR_ASSERT(t2); - - ListTraces(); - - PR_GET_TRACE_HANDLE_FROM_NAME( th, "TraceTest","tt1" ); - PR_ASSERT( th == hTrace ); - - PR_LOG( lm, msgLevel, - ("End TraceTest")); - return; -} /* end TraceTest() */ - - -/* -** Ordered lock test. -*/ -static void OrderedLockTest( void ) -{ - PR_LOG( lm, msgLevel, - ("Begin OrderedLockTest")); - - -} /* end OrderedLockTest() */ - - -int main(int argc, char **argv) -{ -#if defined(DEBUG) || defined(FORCE_NSPR_TRACE) - PRUint32 counter; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "hdv:"); - lm = PR_NewLogModule("Test"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'v': /* verbose mode */ - msgLevel = (PRLogModuleLevel)atol( opt->value); - break; - case 'h': /* help message */ - Help(); - help = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_CREATE_TRACE( hTrace, "TraceTest", "tt1", "A description for the trace test" ); - mon = PR_NewMonitor(); - PR_EnterMonitor( mon ); - - TraceTest(); - CounterTest(); - OrderedLockTest(); - - /* Wait for all threads to exit */ - while ( activeThreads > 0 ) { - if ( activeThreads == 1 ) - PR_SET_TRACE_OPTION( PRTraceStopRecording, NULL ); - PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); - PR_GET_COUNTER( counter, hCounter ); - } - PR_ExitMonitor( mon ); - - /* - ** Evaluate results - */ - PR_GET_COUNTER( counter, hCounter ); - if ( counter != 0 ) - { - failed = PR_TRUE; - PR_LOG( lm, msgLevel, - ("Expected counter == 0, found: %ld", counter)); - printf("FAIL\n"); - } - else - { - printf("PASS\n"); - } - - - PR_DESTROY_COUNTER( hCounter ); - - PR_DestroyMonitor( mon ); - - PR_TRACE( hTrace, TraceFlow, 0xfff,0,0,0,0,0,0); - PR_DESTROY_TRACE( hTrace ); -#else - printf("Test not defined\n"); -#endif - return 0; -} /* main() */ -/* end instrumt.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/intrio.c nspr-4.10.7/mozilla/nsprpub/pr/tests/intrio.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/intrio.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/intrio.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: intrio.c - * Purpose: testing i/o interrupts (see Bugzilla bug #31120) - */ - -#include "nspr.h" - -#include -#include -#include - -/* for synchronization between the main thread and iothread */ -static PRLock *lock; -static PRCondVar *cvar; -static PRBool iothread_ready; - -static void PR_CALLBACK AbortIO(void *arg) -{ - PRStatus rv; - PR_Sleep(PR_SecondsToInterval(2)); - rv = PR_Interrupt((PRThread*)arg); - PR_ASSERT(PR_SUCCESS == rv); -} /* AbortIO */ - -static void PR_CALLBACK IOThread(void *arg) -{ - PRFileDesc *sock, *newsock; - PRNetAddr addr; - - sock = PR_OpenTCPSocket(PR_AF_INET6); - if (sock == NULL) { - fprintf(stderr, "PR_OpenTCPSocket failed\n"); - exit(1); - } - memset(&addr, 0, sizeof(addr)); - if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_SetNetAddr failed\n"); - exit(1); - } - if (PR_Bind(sock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_Bind failed\n"); - exit(1); - } - if (PR_Listen(sock, 5) == PR_FAILURE) { - fprintf(stderr, "PR_Listen failed\n"); - exit(1); - } - /* tell the main thread that we are ready */ - PR_Lock(lock); - iothread_ready = PR_TRUE; - PR_NotifyCondVar(cvar); - PR_Unlock(lock); - newsock = PR_Accept(sock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (newsock != NULL) { - fprintf(stderr, "PR_Accept shouldn't have succeeded\n"); - exit(1); - } - if (PR_GetError() != PR_PENDING_INTERRUPT_ERROR) { - fprintf(stderr, "PR_Accept failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - printf("PR_Accept() is interrupted as expected\n"); - if (PR_Close(sock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } -} - -static void Test(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *iothread, *abortio; - - printf("A %s thread will be interrupted by a %s thread\n", - (scope1 == PR_LOCAL_THREAD ? "local" : "global"), - (scope2 == PR_LOCAL_THREAD ? "local" : "global")); - iothread_ready = PR_FALSE; - iothread = PR_CreateThread( - PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL, - scope1, PR_JOINABLE_THREAD, 0); - if (iothread == NULL) { - fprintf(stderr, "cannot create thread\n"); - exit(1); - } - PR_Lock(lock); - while (!iothread_ready) - PR_WaitCondVar(cvar, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(lock); - abortio = PR_CreateThread( - PR_USER_THREAD, AbortIO, iothread, PR_PRIORITY_NORMAL, - scope2, PR_JOINABLE_THREAD, 0); - if (abortio == NULL) { - fprintf(stderr, "cannot create thread\n"); - exit(1); - } - if (PR_JoinThread(iothread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - if (PR_JoinThread(abortio) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } -} - -int main(int argc, char **argv) -{ - PR_STDIO_INIT(); - lock = PR_NewLock(); - if (lock == NULL) { - fprintf(stderr, "PR_NewLock failed\n"); - exit(1); - } - cvar = PR_NewCondVar(lock); - if (cvar == NULL) { - fprintf(stderr, "PR_NewCondVar failed\n"); - exit(1); - } - /* test all four combinations */ - Test(PR_LOCAL_THREAD, PR_LOCAL_THREAD); - Test(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); - Test(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); - Test(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); - printf("PASSED\n"); - return 0; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/intrupt.c nspr-4.10.7/mozilla/nsprpub/pr/tests/intrupt.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/intrupt.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/intrupt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,330 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: intrupt.c - * Purpose: testing thread interrupts - */ - -#include "plgetopt.h" -#include "prcvar.h" -#include "prerror.h" -#include "prinit.h" -#include "prinrval.h" -#include "prio.h" -#include "prlock.h" -#include "prlog.h" -#include "prthread.h" -#include "prtypes.h" -#include "prnetdb.h" - -#include -#include - -#define DEFAULT_TCP_PORT 12500 - -static PRLock *ml = NULL; -static PRCondVar *cv = NULL; - -static PRBool passed = PR_TRUE; -static PRBool debug_mode = PR_FALSE; -static PRThreadScope thread_scope = PR_LOCAL_THREAD; - -static void PR_CALLBACK AbortCV(void *arg) -{ - PRStatus rv; - PRThread *me = PR_GetCurrentThread(); - - /* some other thread (main) is doing the interrupt */ - PR_Lock(ml); - rv = PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); - if (debug_mode) printf( "Expected interrupt on wait CV and "); - if (PR_FAILURE == rv) - { - if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) - { - if (debug_mode) printf("got it\n"); - } - else - { - if (debug_mode) printf("got random error\n"); - passed = PR_FALSE; - } - } - else - { - if (debug_mode) printf("got a successful completion\n"); - passed = PR_FALSE; - } - - rv = PR_WaitCondVar(cv, 10); - if (debug_mode) - { - printf( - "Expected success on wait CV and %s\n", - (PR_SUCCESS == rv) ? "got it" : "failed"); - } - passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE; - - /* interrupt myself, then clear */ - PR_Interrupt(me); - PR_ClearInterrupt(); - rv = PR_WaitCondVar(cv, 10); - if (debug_mode) - { - printf("Expected success on wait CV and "); - if (PR_FAILURE == rv) - { - printf( - "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ? - "got interrupted" : "a random failure"); - } - printf("got it\n"); - } - passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE; - - /* set, then wait - interrupt - then wait again */ - PR_Interrupt(me); - rv = PR_WaitCondVar(cv, 10); - if (debug_mode) printf( "Expected interrupt on wait CV and "); - if (PR_FAILURE == rv) - { - if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) - { - if (debug_mode) printf("got it\n"); - } - else - { - if (debug_mode) printf("failed\n"); - passed = PR_FALSE; - } - } - else - { - if (debug_mode) printf("got a successful completion\n"); - passed = PR_FALSE; - } - - rv = PR_WaitCondVar(cv, 10); - if (debug_mode) - { - printf( - "Expected success on wait CV and %s\n", - (PR_SUCCESS == rv) ? "got it" : "failed"); - } - passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE; - - PR_Unlock(ml); - -} /* AbortCV */ - -static void PR_CALLBACK AbortIO(void *arg) -{ - PRStatus rv; - PR_Sleep(PR_SecondsToInterval(2)); - rv = PR_Interrupt((PRThread*)arg); - PR_ASSERT(PR_SUCCESS == rv); -} /* AbortIO */ - -static void PR_CALLBACK AbortJoin(void *arg) -{ -} /* AbortJoin */ - -static void setup_listen_socket(PRFileDesc **listner, PRNetAddr *netaddr) -{ - PRStatus rv; - PRInt16 port = DEFAULT_TCP_PORT; - - *listner = PR_NewTCPSocket(); - PR_ASSERT(*listner != NULL); - memset(netaddr, 0, sizeof(*netaddr)); - (*netaddr).inet.ip = PR_htonl(PR_INADDR_ANY); - (*netaddr).inet.family = PR_AF_INET; - do - { - (*netaddr).inet.port = PR_htons(port); - rv = PR_Bind(*listner, netaddr); - port += 1; - PR_ASSERT(port < (DEFAULT_TCP_PORT + 10)); - } while (PR_FAILURE == rv); - - rv = PR_Listen(*listner, 5); - - if (PR_GetSockName(*listner, netaddr) < 0) { - if (debug_mode) printf("intrupt: ERROR - PR_GetSockName failed\n"); - passed = PR_FALSE; - return; - } - -} - -static void PR_CALLBACK IntrBlock(void *arg) -{ - PRStatus rv; - PRNetAddr netaddr; - PRFileDesc *listner; - - /* some other thread (main) is doing the interrupt */ - /* block the interrupt */ - PR_BlockInterrupt(); - PR_Lock(ml); - rv = PR_WaitCondVar(cv, PR_SecondsToInterval(4)); - PR_Unlock(ml); - if (debug_mode) - { - printf("Expected success on wait CV and "); - if (PR_FAILURE == rv) - { - printf( - "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ? - "got interrupted" : "got a random failure"); - } else - printf("got it\n"); - } - passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE; - - setup_listen_socket(&listner, &netaddr); - PR_UnblockInterrupt(); - if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL) - { - PRInt32 error = PR_GetError(); - if (debug_mode) printf("Expected interrupt on PR_Accept() and "); - if (PR_PENDING_INTERRUPT_ERROR == error) - { - if (debug_mode) printf("got it\n"); - } - else - { - if (debug_mode) printf("failed\n"); - passed = PR_FALSE; - } - } - else - { - if (debug_mode) printf("Failed to interrupt PR_Accept()\n"); - passed = PR_FALSE; - } - - (void)PR_Close(listner); listner = NULL; -} /* TestIntrBlock */ - -void PR_CALLBACK Intrupt(void *arg) -{ - PRStatus rv; - PRNetAddr netaddr; - PRFileDesc *listner; - PRThread *abortCV, *abortIO, *abortJoin, *intrBlock; - - ml = PR_NewLock(); - cv = PR_NewCondVar(ml); - - /* Part I */ - if (debug_mode) printf("Part I\n"); - abortCV = PR_CreateThread( - PR_USER_THREAD, AbortCV, 0, PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - - PR_Sleep(PR_SecondsToInterval(2)); - rv = PR_Interrupt(abortCV); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(abortCV); - PR_ASSERT(PR_SUCCESS == rv); - - /* Part II */ - if (debug_mode) printf("Part II\n"); - abortJoin = PR_CreateThread( - PR_USER_THREAD, AbortJoin, 0, PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - PR_Sleep(PR_SecondsToInterval(2)); - if (debug_mode) printf("Expecting to interrupt an exited thread "); - rv = PR_Interrupt(abortJoin); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(abortJoin); - PR_ASSERT(PR_SUCCESS == rv); - if (debug_mode) printf("and succeeded\n"); - - /* Part III */ - if (debug_mode) printf("Part III\n"); - setup_listen_socket(&listner, &netaddr); - abortIO = PR_CreateThread( - PR_USER_THREAD, AbortIO, PR_GetCurrentThread(), PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - - if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL) - { - PRInt32 error = PR_GetError(); - if (debug_mode) printf("Expected interrupt on PR_Accept() and "); - if (PR_PENDING_INTERRUPT_ERROR == error) - { - if (debug_mode) printf("got it\n"); - } - else - { - if (debug_mode) printf("failed\n"); - passed = PR_FALSE; - } - } - else - { - if (debug_mode) printf("Failed to interrupt PR_Accept()\n"); - passed = PR_FALSE; - } - - (void)PR_Close(listner); listner = NULL; - - rv = PR_JoinThread(abortIO); - PR_ASSERT(PR_SUCCESS == rv); - /* Part VI */ - if (debug_mode) printf("Part VI\n"); - intrBlock = PR_CreateThread( - PR_USER_THREAD, IntrBlock, 0, PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - - PR_Sleep(PR_SecondsToInterval(2)); - rv = PR_Interrupt(intrBlock); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(intrBlock); - PR_ASSERT(PR_SUCCESS == rv); - - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); -} /* Intrupt */ - -int main(int argc, char **argv) -{ - PRThread *intrupt; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dG"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'G': /* use global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - } - } - PL_DestroyOptState(opt); - PR_STDIO_INIT(); - intrupt = PR_CreateThread( - PR_USER_THREAD, Intrupt, NULL, PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - if (intrupt == NULL) { - fprintf(stderr, "cannot create thread\n"); - passed = PR_FALSE; - } else { - PRStatus rv; - rv = PR_JoinThread(intrupt); - PR_ASSERT(rv == PR_SUCCESS); - } - printf("%s\n", ((passed) ? "PASSED" : "FAILED")); - return ((passed) ? 0 : 1); -} /* main */ - -/* intrupt.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/ioconthr.c nspr-4.10.7/mozilla/nsprpub/pr/tests/ioconthr.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/ioconthr.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/ioconthr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This is a test for the io continuation thread machinery - * in pthreads. - */ - -#include "nspr.h" -#include - -int num_threads = 10; /* must be an even number */ -PRThreadScope thread_scope = PR_GLOBAL_THREAD; - -void ThreadFunc(void *arg) -{ - PRFileDesc *fd = (PRFileDesc *) arg; - char buf[1024]; - PRInt32 nbytes; - PRErrorCode err; - - nbytes = PR_Recv(fd, buf, sizeof(buf), 0, PR_SecondsToInterval(20)); - if (nbytes == -1) { - err = PR_GetError(); - if (err != PR_PENDING_INTERRUPT_ERROR) { - fprintf(stderr, "PR_Recv failed: (%d, %d)\n", - err, PR_GetOSError()); - PR_ProcessExit(1); - } - /* - * After getting an I/O interrupt, this thread must - * close the fd before it exits due to a limitation - * of our NT implementation. - */ - if (PR_Close(fd) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - PR_ProcessExit(1); - } - } else { - fprintf(stderr, "PR_Recv received %d bytes!?\n", nbytes); - PR_ProcessExit(1); - } -} - -int main(int argc, char **argv) -{ - PRFileDesc **fds; - PRThread **threads; - PRIntervalTime start, elapsed; - int index; - - fds = (PRFileDesc **) PR_MALLOC(2 * num_threads * sizeof(PRFileDesc *)); - PR_ASSERT(fds != NULL); - threads = (PRThread **) PR_MALLOC(num_threads * sizeof(PRThread *)); - PR_ASSERT(threads != NULL); - - for (index = 0; index < num_threads; index++) { - if (PR_NewTCPSocketPair(&fds[2 * index]) == PR_FAILURE) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - PR_ProcessExit(1); - } - threads[index] = PR_CreateThread( - PR_USER_THREAD, ThreadFunc, fds[2 * index], - PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 0); - if (NULL == threads[index]) { - fprintf(stderr, "PR_CreateThread failed\n"); - PR_ProcessExit(1); - } - } - - /* Let the threads block in PR_Recv */ - PR_Sleep(PR_SecondsToInterval(2)); - - printf("Interrupting the threads\n"); - fflush(stdout); - start = PR_IntervalNow(); - for (index = 0; index < num_threads; index++) { - if (PR_Interrupt(threads[index]) == PR_FAILURE) { - fprintf(stderr, "PR_Interrupt failed\n"); - PR_ProcessExit(1); - } - } - for (index = 0; index < num_threads; index++) { - if (PR_JoinThread(threads[index]) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - PR_ProcessExit(1); - } - } - elapsed = (PRIntervalTime)(PR_IntervalNow() - start); - printf("Threads terminated in %d milliseconds\n", - PR_IntervalToMilliseconds(elapsed)); - fflush(stdout); - - /* We are being very generous and allow 10 seconds. */ - if (elapsed >= PR_SecondsToInterval(10)) { - fprintf(stderr, "Interrupting threads took longer than 10 seconds!!\n"); - PR_ProcessExit(1); - } - - for (index = 0; index < num_threads; index++) { - /* fds[2 * index] was passed to and closed by threads[index]. */ - if (PR_Close(fds[2 * index + 1]) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - PR_ProcessExit(1); - } - } - PR_DELETE(threads); - PR_DELETE(fds); - printf("PASS\n"); - PR_Cleanup(); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/io_timeout.c nspr-4.10.7/mozilla/nsprpub/pr/tests/io_timeout.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/io_timeout.c 2012-03-06 13:14:26.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/io_timeout.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,256 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** Test socket IO timeouts -** -** -** -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include -#include "nspr.h" - -#define NUM_THREADS 1 -#define BASE_PORT 8000 -#define DEFAULT_ACCEPT_TIMEOUT 2 - -typedef struct threadInfo { - PRInt16 id; - PRInt16 accept_timeout; - PRLock *dead_lock; - PRCondVar *dead_cv; - PRInt32 *alive; -} threadInfo; - -PRIntn failed_already = 0; -PRIntn debug_mode = 0; - -#define LOCAL_SCOPE_STRING "LOCAL scope" -#define GLOBAL_SCOPE_STRING "GLOBAL scope" -#define GLOBAL_BOUND_SCOPE_STRING "GLOBAL_BOUND scope" - -void -thread_main(void *_info) -{ - threadInfo *info = (threadInfo *)_info; - PRNetAddr listenAddr; - PRNetAddr clientAddr; - PRFileDesc *listenSock = NULL; - PRFileDesc *clientSock; - PRStatus rv; - PRThreadScope tscope; - char *scope_str; - - - if (debug_mode) - printf("thread %d is alive\n", info->id); - tscope = PR_GetThreadScope(PR_GetCurrentThread()); - - switch(tscope) { - case PR_LOCAL_THREAD: - scope_str = LOCAL_SCOPE_STRING; - break; - case PR_GLOBAL_THREAD: - scope_str = GLOBAL_SCOPE_STRING; - break; - case PR_GLOBAL_BOUND_THREAD: - scope_str = GLOBAL_BOUND_SCOPE_STRING; - break; - default: - PR_ASSERT(!"Invalid thread scope"); - break; - } - printf("thread id %d, scope %s\n", info->id, scope_str); - - listenSock = PR_NewTCPSocket(); - if (!listenSock) { - if (debug_mode) - printf("unable to create listen socket\n"); - failed_already=1; - goto dead; - } - - listenAddr.inet.family = PR_AF_INET; - listenAddr.inet.port = PR_htons(BASE_PORT + info->id); - listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY); - rv = PR_Bind(listenSock, &listenAddr); - if (rv == PR_FAILURE) { - if (debug_mode) - printf("unable to bind\n"); - failed_already=1; - goto dead; - } - - rv = PR_Listen(listenSock, 4); - if (rv == PR_FAILURE) { - if (debug_mode) - printf("unable to listen\n"); - failed_already=1; - goto dead; - } - - if (debug_mode) - printf("thread %d going into accept for %d seconds\n", - info->id, info->accept_timeout + info->id); - - clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id)); - - if (clientSock == NULL) { - if (PR_GetError() == PR_IO_TIMEOUT_ERROR) { - if (debug_mode) { - printf("PR_Accept() timeout worked!\n"); - printf("TEST PASSED! PR_Accept() returned error %d\n", - PR_IO_TIMEOUT_ERROR); - } - } else { - if (debug_mode) - printf("TEST FAILED! PR_Accept() returned error %d\n", - PR_GetError()); - failed_already=1; - } - } else { - if (debug_mode) - printf ("TEST FAILED! PR_Accept() succeeded?\n"); - failed_already=1; - PR_Close(clientSock); - } - -dead: - if (listenSock) { - PR_Close(listenSock); - } - PR_Lock(info->dead_lock); - (*info->alive)--; - PR_NotifyCondVar(info->dead_cv); - PR_Unlock(info->dead_lock); - - if (debug_mode) - printf("thread %d is dead\n", info->id); - - PR_Free(info); -} - -void -thread_test(PRThreadScope scope, PRInt32 num_threads) -{ - PRInt32 index; - PRThread *thr; - PRLock *dead_lock; - PRCondVar *dead_cv; - PRInt32 alive; - - if (debug_mode) - printf("IO Timeout test started with %d threads\n", num_threads); - - dead_lock = PR_NewLock(); - dead_cv = PR_NewCondVar(dead_lock); - alive = num_threads; - - for (index = 0; index < num_threads; index++) { - threadInfo *info = (threadInfo *)PR_Malloc(sizeof(threadInfo)); - - info->id = index; - info->dead_lock = dead_lock; - info->dead_cv = dead_cv; - info->alive = &alive; - info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT; - - thr = PR_CreateThread( PR_USER_THREAD, - thread_main, - (void *)info, - PR_PRIORITY_NORMAL, - scope, - PR_UNJOINABLE_THREAD, - 0); - - if (!thr) { - printf("Failed to create thread, error = %d(%d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - - PR_Lock(dead_lock); - alive--; - PR_Unlock(dead_lock); - } - } - - PR_Lock(dead_lock); - while(alive) { - if (debug_mode) - printf("main loop awake; alive = %d\n", alive); - PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(dead_lock); - - PR_DestroyCondVar(dead_cv); - PR_DestroyLock(dead_lock); -} - -int main(int argc, char **argv) -{ - PRInt32 num_threads = 0; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name [-d] [-t ] - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dt:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 't': /* threads to involve */ - num_threads = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - if (0 == num_threads) - num_threads = NUM_THREADS; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0); - PR_STDIO_INIT(); - - printf("test with global bound thread\n"); - thread_test(PR_GLOBAL_BOUND_THREAD, num_threads); - - printf("test with local thread\n"); - thread_test(PR_LOCAL_THREAD, num_threads); - - printf("test with global thread\n"); - thread_test(PR_GLOBAL_THREAD, num_threads); - - PR_Cleanup(); - - if (failed_already) - return 1; - else - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/io_timeoutk.c nspr-4.10.7/mozilla/nsprpub/pr/tests/io_timeoutk.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/io_timeoutk.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/io_timeoutk.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** name io_timeoutk.c -** Description:Test socket IO timeouts (kernel level) -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include -#include "nspr.h" - -#define NUM_THREADS 1 -#define BASE_PORT 8000 -#define DEFAULT_ACCEPT_TIMEOUT 2 - -typedef struct threadInfo { - PRInt16 id; - PRInt16 accept_timeout; - PRLock *dead_lock; - PRCondVar *dead_cv; - PRInt32 *alive; -} threadInfo; - -PRIntn failed_already=0; -PRIntn debug_mode; - - -void -thread_main(void *_info) -{ - threadInfo *info = (threadInfo *)_info; - PRNetAddr listenAddr; - PRNetAddr clientAddr; - PRFileDesc *listenSock = NULL; - PRFileDesc *clientSock; - PRStatus rv; - - if (debug_mode) printf("thread %d is alive\n", info->id); - - listenSock = PR_NewTCPSocket(); - if (!listenSock) { - if (debug_mode) printf("unable to create listen socket\n"); - goto dead; - } - - listenAddr.inet.family = AF_INET; - listenAddr.inet.port = PR_htons(BASE_PORT + info->id); - listenAddr.inet.ip = PR_htonl(INADDR_ANY); - rv = PR_Bind(listenSock, &listenAddr); - if (rv == PR_FAILURE) { - if (debug_mode) printf("unable to bind\n"); - goto dead; - } - - rv = PR_Listen(listenSock, 4); - if (rv == PR_FAILURE) { - if (debug_mode) printf("unable to listen\n"); - goto dead; - } - - if (debug_mode) printf("thread %d going into accept for %d seconds\n", - info->id, info->accept_timeout + info->id); - - clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id)); - - if (clientSock == NULL) { - if (PR_GetError() == PR_IO_TIMEOUT_ERROR) - if (debug_mode) { - printf("PR_Accept() timeout worked!\n"); - printf("TEST FAILED! PR_Accept() returned error %d\n", - PR_GetError()); - } - else failed_already=1; - } else { - if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n"); - else failed_already=1; - PR_Close(clientSock); - } - -dead: - if (listenSock) { - PR_Close(listenSock); - } - PR_Lock(info->dead_lock); - (*info->alive)--; - PR_NotifyCondVar(info->dead_cv); - PR_Unlock(info->dead_lock); - - if (debug_mode) printf("thread %d is dead\n", info->id); -} - -void -thread_test(PRInt32 scope, PRInt32 num_threads) -{ - PRInt32 index; - PRThread *thr; - PRLock *dead_lock; - PRCondVar *dead_cv; - PRInt32 alive; - - if (debug_mode) printf("IO Timeout test started with %d threads\n", num_threads); - - dead_lock = PR_NewLock(); - dead_cv = PR_NewCondVar(dead_lock); - alive = num_threads; - - for (index = 0; index < num_threads; index++) { - threadInfo *info = (threadInfo *)malloc(sizeof(threadInfo)); - - info->id = index; - info->dead_lock = dead_lock; - info->dead_cv = dead_cv; - info->alive = &alive; - info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT; - - thr = PR_CreateThread( PR_USER_THREAD, - thread_main, - (void *)info, - PR_PRIORITY_NORMAL, - scope, - PR_UNJOINABLE_THREAD, - 0); - - if (!thr) { - PR_Lock(dead_lock); - alive--; - PR_Unlock(dead_lock); - } - } - - PR_Lock(dead_lock); - while(alive) { - if (debug_mode) printf("main loop awake; alive = %d\n", alive); - PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(dead_lock); -} - -int main(int argc, char **argv) -{ - PRInt32 num_threads; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - if (argc > 2) - num_threads = atoi(argv[2]); - else - num_threads = NUM_THREADS; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0); - PR_STDIO_INIT(); - - if (debug_mode) printf("kernel level test\n"); - thread_test(PR_GLOBAL_THREAD, num_threads); - - PR_Cleanup(); - - if(failed_already) - return 1; - else - return 0; - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/io_timeoutu.c nspr-4.10.7/mozilla/nsprpub/pr/tests/io_timeoutu.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/io_timeoutu.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/io_timeoutu.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,202 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -/* -** name io_timeoutu.c -** Description: Test socket IO timeouts (user level) -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include -#include "nspr.h" - -#define NUM_THREADS 1 -#define BASE_PORT 8000 -#define DEFAULT_ACCEPT_TIMEOUT 2 - -typedef struct threadInfo { - PRInt16 id; - PRInt16 accept_timeout; - PRLock *dead_lock; - PRCondVar *dead_cv; - PRInt32 *alive; -} threadInfo; -PRIntn failed_already=0; -PRIntn debug_mode; - -void -thread_main(void *_info) -{ - threadInfo *info = (threadInfo *)_info; - PRNetAddr listenAddr; - PRNetAddr clientAddr; - PRFileDesc *listenSock = NULL; - PRFileDesc *clientSock; - PRStatus rv; - - if (debug_mode) printf("thread %d is alive\n", info->id); - - listenSock = PR_NewTCPSocket(); - if (!listenSock) { - if (debug_mode) printf("unable to create listen socket\n"); - goto dead; - } - - listenAddr.inet.family = AF_INET; - listenAddr.inet.port = PR_htons(BASE_PORT + info->id); - listenAddr.inet.ip = PR_htonl(INADDR_ANY); - rv = PR_Bind(listenSock, &listenAddr); - if (rv == PR_FAILURE) { - if (debug_mode) printf("unable to bind\n"); - goto dead; - } - - rv = PR_Listen(listenSock, 4); - if (rv == PR_FAILURE) { - if (debug_mode) printf("unable to listen\n"); - goto dead; - } - - if (debug_mode) printf("thread %d going into accept for %d seconds\n", - info->id, info->accept_timeout + info->id); - - clientSock = PR_Accept( - listenSock, &clientAddr, PR_SecondsToInterval( - info->accept_timeout + info->id)); - - if (clientSock == NULL) { - if (PR_GetError() == PR_IO_TIMEOUT_ERROR) - if (debug_mode) { - printf("PR_Accept() timeout worked!\n"); - printf("TEST FAILED! PR_Accept() returned error %d\n", - } - PR_GetError()); - else failed_already=1; - } else { - if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n"); - else failed_already=1; - PR_Close(clientSock); - } - -dead: - if (listenSock) { - PR_Close(listenSock); - } - PR_Lock(info->dead_lock); - (*info->alive)--; - PR_NotifyCondVar(info->dead_cv); - PR_Unlock(info->dead_lock); - - if (debug_mode) printf("thread %d is dead\n", info->id); -} - -void -thread_test(PRInt32 scope, PRInt32 num_threads) -{ - PRInt32 index; - PRThread *thr; - PRLock *dead_lock; - PRCondVar *dead_cv; - PRInt32 alive; - - if (debug_mode) printf("IO Timeout test started with %d threads\n", num_threads); - - dead_lock = PR_NewLock(); - dead_cv = PR_NewCondVar(dead_lock); - alive = num_threads; - - for (index = 0; index < num_threads; index++) { - threadInfo *info = (threadInfo *)malloc(sizeof(threadInfo)); - - info->id = index; - info->dead_lock = dead_lock; - info->dead_cv = dead_cv; - info->alive = &alive; - info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT; - - thr = PR_CreateThread( PR_USER_THREAD, - thread_main, - (void *)info, - PR_PRIORITY_NORMAL, - scope, - PR_UNJOINABLE_THREAD, - 0); - - if (!thr) { - PR_Lock(dead_lock); - alive--; - PR_Unlock(dead_lock); - } - } - - PR_Lock(dead_lock); - while(alive) { - if (debug_mode) printf("main loop awake; alive = %d\n", alive); - PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(dead_lock); -} - -int main(int argc, char **argv) -{ - PRInt32 num_threads; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - if (argc > 2) - num_threads = atoi(argv[2]); - else - num_threads = NUM_THREADS; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0); - PR_STDIO_INIT(); - - if (debug_mode) printf("user level test\n"); - thread_test(PR_LOCAL_THREAD, num_threads); - - PR_Cleanup(); - if(failed_already) - return 1; - else - return 0; - - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/ipv6.c nspr-4.10.7/mozilla/nsprpub/pr/tests/ipv6.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/ipv6.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/ipv6.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,216 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prenv.h" -#include "prmem.h" -#include "prlink.h" -#include "prsystem.h" -#include "prnetdb.h" -#include "prprf.h" -#include "prvrsion.h" - -#include "plerror.h" -#include "plgetopt.h" -#include "obsolete/probslet.h" - -#include - -#define DNS_BUFFER 100 -#define ADDR_BUFFER 100 -#define HOST_BUFFER 1024 -#define PROTO_BUFFER 1500 - -#define NETADDR_SIZE(addr) \ - (PR_AF_INET == (addr)->raw.family ? \ - sizeof((addr)->inet) : sizeof((addr)->ipv6)) - -static PRFileDesc *err = NULL; - -static void Help(void) -{ - PR_fprintf(err, "Usage: [-V] [-h]\n"); - PR_fprintf(err, "\t Name of host to lookup (default: self)\n"); - PR_fprintf(err, "\t-V Display runtime version info (default: FALSE)\n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); -} /* Help */ - -static void DumpAddr(const PRNetAddr* address, const char *msg) -{ - PRUint32 *word = (PRUint32*)address; - PRUint32 addr_len = sizeof(PRNetAddr); - PR_fprintf(err, "%s[%d]\t", msg, NETADDR_SIZE(address)); - while (addr_len > 0) - { - PR_fprintf(err, " %08x", *word++); - addr_len -= sizeof(PRUint32); - } - PR_fprintf(err, "\n"); -} /* DumpAddr */ - -static PRStatus PrintAddress(const PRNetAddr* address) -{ - PRNetAddr translation; - char buffer[ADDR_BUFFER]; - PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); - if (PR_FAILURE == rv) PL_FPrintError(err, "PR_NetAddrToString"); - else - { - PR_fprintf(err, "\t%s\n", buffer); - memset(&translation, 0, sizeof(translation)); - rv = PR_StringToNetAddr(buffer, &translation); - if (PR_FAILURE == rv) PL_FPrintError(err, "PR_StringToNetAddr"); - else - { - PRSize addr_len = NETADDR_SIZE(address); - if (0 != memcmp(address, &translation, addr_len)) - { - PR_fprintf(err, "Address translations do not match\n"); - DumpAddr(address, "original"); - DumpAddr(&translation, "translate"); - rv = PR_FAILURE; - } - } - } - return rv; -} /* PrintAddress */ - -int main(int argc, char **argv) -{ - PRStatus rv; - PLOptStatus os; - PRHostEnt host; - PRProtoEnt proto; - const char *name = NULL; - PRBool failed = PR_FALSE, version = PR_FALSE; - PLOptState *opt = PL_CreateOptState(argc, argv, "Vh"); - - err = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: /* Name of host to lookup */ - name = opt->value; - break; - case 'V': /* Do version discovery */ - version = PR_TRUE; - break; - case 'h': /* user wants some guidance */ - default: - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - } - } - PL_DestroyOptState(opt); - - if (version) - { -#if defined(WINNT) -#define NSPR_LIB "libnspr4" -#else -#define NSPR_LIB "nspr4" -#endif - const PRVersionDescription *version_info; - char *nspr_path = PR_GetEnv("LD_LIBRARY_PATH"); - char *nspr_name = PR_GetLibraryName(nspr_path, NSPR_LIB); - PRLibrary *runtime = PR_LoadLibrary(nspr_name); - if (NULL == runtime) - PL_FPrintError(err, "PR_LoadLibrary"); - else - { - versionEntryPointType versionPoint = (versionEntryPointType) - PR_FindSymbol(runtime, "libVersionPoint"); - if (NULL == versionPoint) - PL_FPrintError(err, "PR_FindSymbol"); - else - { - char buffer[100]; - PRExplodedTime exploded; - version_info = versionPoint(); - (void)PR_fprintf(err, "Runtime library version information\n"); - PR_ExplodeTime( - version_info->buildTime, PR_GMTParameters, &exploded); - (void)PR_FormatTime( - buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded); - (void)PR_fprintf(err, " Build time: %s GMT\n", buffer); - (void)PR_fprintf( - err, " Build time: %s\n", version_info->buildTimeString); - (void)PR_fprintf( - err, " %s V%u.%u.%u (%s%s%s)\n", - version_info->description, - version_info->vMajor, - version_info->vMinor, - version_info->vPatch, - (version_info->beta ? " beta " : ""), - (version_info->debug ? " debug " : ""), - (version_info->special ? " special" : "")); - (void)PR_fprintf(err, " filename: %s\n", version_info->filename); - (void)PR_fprintf(err, " security: %s\n", version_info->security); - (void)PR_fprintf(err, " copyright: %s\n", version_info->copyright); - (void)PR_fprintf(err, " comment: %s\n", version_info->comment); - } - } - if (NULL != nspr_name) PR_FreeLibraryName(nspr_name); - } - - { - if (NULL == name) - { - char *me = (char*)PR_MALLOC(DNS_BUFFER); - rv = PR_GetSystemInfo(PR_SI_HOSTNAME, me, DNS_BUFFER); - if (PR_FAILURE == rv) - { - failed = PR_TRUE; - PL_FPrintError(err, "PR_GetSystemInfo"); - return 2; - } - name = me; /* just leak the storage */ - } - } - - { - char buffer[HOST_BUFFER]; - PR_fprintf(err, "Translating the name %s ...", name); - - rv = PR_GetHostByName(name, buffer, sizeof(buffer), &host); - if (PR_FAILURE == rv) - { - failed = PR_TRUE; - PL_FPrintError(err, "PR_GetHostByName"); - } - else - { - PRIntn index = 0; - PRNetAddr address; - memset(&address, 0, sizeof(PRNetAddr)); - PR_fprintf(err, "success .. enumerating results\n"); - do - { - index = PR_EnumerateHostEnt(index, &host, 0, &address); - if (index > 0) PrintAddress(&address); - else if (-1 == index) - { - failed = PR_TRUE; - PL_FPrintError(err, "PR_EnumerateHostEnt"); - } - } while (index > 0); - } - } - - - { - char buffer[PROTO_BUFFER]; - /* - ** Get Proto by name/number - */ - rv = PR_GetProtoByName("tcp", &buffer[1], sizeof(buffer) - 1, &proto); - rv = PR_GetProtoByNumber(6, &buffer[3], sizeof(buffer) - 3, &proto); - } - - return (failed) ? 1 : 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/join.c nspr-4.10.7/mozilla/nsprpub/pr/tests/join.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/join.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/join.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,220 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: dbmalloc1.c -** -** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions. -** -** Modification History: -** -** 19-May-97 AGarcia - separate the four join tests into different unit test modules. -** AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" -#include "prttools.h" - -#include "nspr.h" - -#include -#include -#include - -/*********************************************************************** -** PRIVATE FUNCTION: Test_Result -** DESCRIPTION: Used in conjunction with the regress tool, prints out the -** status of the test case. -** INPUTS: PASS/FAIL -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** -** RESTRICTIONS: -** None -** MEMORY: NA -** ALGORITHM: Determine what the status is and print accordingly. -** -***********************************************************************/ - - -static void Test_Result (int result) -{ - if (result == PASS) - printf ("PASS\n"); - else - printf ("FAIL\n"); - exit (1); -} - - -/* - Program to test joining of threads. Two threads are created. One - to be waited upon until it has started. The other to join after it has - completed. -*/ - - -static void PR_CALLBACK lowPriority(void *arg) -{ -} - -static void PR_CALLBACK highPriority(void *arg) -{ -} - -static void PR_CALLBACK unjoinable(void *arg) -{ - PR_Sleep(PR_INTERVAL_NO_TIMEOUT); -} - -void runTest(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *low,*high; - - /* create the low and high priority threads */ - - low = PR_CreateThread(PR_USER_THREAD, - lowPriority, 0, - PR_PRIORITY_LOW, - scope1, - PR_JOINABLE_THREAD, - 0); - if (!low) { - if (debug_mode) printf("\tcannot create low priority thread\n"); - else Test_Result(FAIL); - return; - } - - high = PR_CreateThread(PR_USER_THREAD, - highPriority, 0, - PR_PRIORITY_HIGH, - scope2, - PR_JOINABLE_THREAD, - 0); - if (!high) { - if (debug_mode) printf("\tcannot create high priority thread\n"); - else Test_Result(FAIL); - return; - } - - /* Do the joining for both threads */ - if (PR_JoinThread(low) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join low priority thread\n"); - else Test_Result (FAIL); - return; - } else { - if (debug_mode) printf("\tjoined low priority thread\n"); - } - if (PR_JoinThread(high) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join high priority thread\n"); - else Test_Result(FAIL); - return; - } else { - if (debug_mode) printf("\tjoined high priority thread\n"); - } -} - -void joinWithUnjoinable(void) -{ - PRThread *thread; - - /* create the unjoinable thread */ - - thread = PR_CreateThread(PR_USER_THREAD, - unjoinable, 0, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - if (!thread) { - if (debug_mode) printf("\tcannot create unjoinable thread\n"); - else Test_Result(FAIL); - return; - } - - if (PR_JoinThread(thread) == PR_SUCCESS) { - if (debug_mode) printf("\tsuccessfully joined with unjoinable thread?!\n"); - else Test_Result(FAIL); - return; - } else { - if (debug_mode) printf("\tcannot join with unjoinable thread, as expected\n"); - if (PR_GetError() != PR_INVALID_ARGUMENT_ERROR) { - if (debug_mode) printf("\tWrong error code\n"); - else Test_Result(FAIL); - return; - } - } - if (PR_Interrupt(thread) == PR_FAILURE) { - if (debug_mode) printf("\tcannot interrupt unjoinable thread\n"); - else Test_Result(FAIL); - return; - } else { - if (debug_mode) printf("\tinterrupted unjoinable thread\n"); - } -} - -static PRIntn PR_CALLBACK RealMain(int argc, char **argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - printf("User-User test\n"); - runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD); - printf("User-Kernel test\n"); - runTest(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); - printf("Kernel-User test\n"); - runTest(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); - printf("Kernel-Kernel test\n"); - runTest(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); - printf("Join with unjoinable thread\n"); - joinWithUnjoinable(); - - printf("PASSED\n"); - - return 0; -} - - - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/joinkk.c nspr-4.10.7/mozilla/nsprpub/pr/tests/joinkk.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/joinkk.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/joinkk.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: dbmalloc1.c -** -** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions. -** -** Modification History: -** -** 19-May-97 AGarcia - separate the four join tests into different unit test modules. -** AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; -/* - Program to test joining of threads. Two threads are created. One - to be waited upon until it has started. The other to join after it has - completed. -*/ - - -static void lowPriority(void *arg) -{ -} - -static void highPriority(void *arg) -{ -} - -void runTest(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *low,*high; - - /* create the low and high priority threads */ - - low = PR_CreateThread(PR_USER_THREAD, - lowPriority, 0, - PR_PRIORITY_LOW, - scope1, - PR_JOINABLE_THREAD, - 0); - if (!low) { - if (debug_mode) printf("\tcannot create low priority thread\n"); - else failed_already=1; - return; - } - - high = PR_CreateThread(PR_USER_THREAD, - highPriority, 0, - PR_PRIORITY_HIGH, - scope2, - PR_JOINABLE_THREAD, - 0); - if (!high) { - if (debug_mode) printf("\tcannot create high priority thread\n"); - else failed_already=1; - return; - } - - /* Do the joining for both threads */ - if (PR_JoinThread(low) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join low priority thread\n"); - else failed_already=1; - return; - } else { - if (debug_mode) printf("\tjoined low priority thread\n"); - } - if (PR_JoinThread(high) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join high priority thread\n"); - else failed_already=1; - return; - } else { - if (debug_mode) printf("\tjoined high priority thread\n"); - } -} - -static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - if (debug_mode) printf("Kernel-Kernel test\n"); - runTest(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); - - if(failed_already) - { - printf("FAIL\n"); - return 1; - } - else - { - printf("PASS\n"); - return 0; - } - -} - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/joinku.c nspr-4.10.7/mozilla/nsprpub/pr/tests/joinku.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/joinku.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/joinku.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: dbmalloc1.c -** -** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions. -** -** Modification History: -** -** 19-May-97 AGarcia - separate the four join tests into different unit test modules. -** AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - - -/* - Program to test joining of threads. Two threads are created. One - to be waited upon until it has started. The other to join after it has - completed. -*/ - - -static void lowPriority(void *arg) -{ -} - -static void highPriority(void *arg) -{ -} - -void runTest(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *low,*high; - - /* create the low and high priority threads */ - - low = PR_CreateThread(PR_USER_THREAD, - lowPriority, 0, - PR_PRIORITY_LOW, - scope1, - PR_JOINABLE_THREAD, - 0); - if (!low) { - if (debug_mode) printf("\tcannot create low priority thread\n"); - else failed_already=1; - return; - } - - high = PR_CreateThread(PR_USER_THREAD, - highPriority, 0, - PR_PRIORITY_HIGH, - scope2, - PR_JOINABLE_THREAD, - 0); - if (!high) { - if (debug_mode) printf("\tcannot create high priority thread\n"); - else failed_already=1; - return; - } - - /* Do the joining for both threads */ - if (PR_JoinThread(low) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join low priority thread\n"); - else failed_already=1; - return; - } else { - if (debug_mode) printf("\tjoined low priority thread\n"); - } - if (PR_JoinThread(high) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join high priority thread\n"); - else failed_already=1; - return; - } else { - if (debug_mode) printf("\tjoined high priority thread\n"); - } -} - -static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - /* main test */ - - if (debug_mode) printf("Kernel-User test\n"); - runTest(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); - - - if(failed_already) - { - printf("FAIL\n"); - return 1; - } - else - { - printf("PASS\n"); - return 0; - } - -} - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/joinuk.c nspr-4.10.7/mozilla/nsprpub/pr/tests/joinuk.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/joinuk.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/joinuk.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: joinuk.c -** -** Description: Join kernel - user -** -** Modification History: -** -** 19-May-97 AGarcia - separate the four join tests into different unit test modules. -** AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; -/* - Program to test joining of threads. Two threads are created. One - to be waited upon until it has started. The other to join after it has - completed. -*/ - - -static void lowPriority(void *arg) -{ -} - -static void highPriority(void *arg) -{ -} - -void runTest(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *low,*high; - - /* create the low and high priority threads */ - - low = PR_CreateThread(PR_USER_THREAD, - lowPriority, 0, - PR_PRIORITY_LOW, - scope1, - PR_JOINABLE_THREAD, - 0); - if (!low) { - if (debug_mode) printf("\tcannot create low priority thread\n"); - else failed_already=1; - return; - } - - high = PR_CreateThread(PR_USER_THREAD, - highPriority, 0, - PR_PRIORITY_HIGH, - scope2, - PR_JOINABLE_THREAD, - 0); - if (!high) { - if (debug_mode) printf("\tcannot create high priority thread\n"); - else failed_already=1; - return; - } - - /* Do the joining for both threads */ - if (PR_JoinThread(low) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join low priority thread\n"); - else failed_already=1; - return; - } else { - if (debug_mode) printf("\tjoined low priority thread\n"); - } - if (PR_JoinThread(high) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join high priority thread\n"); - else failed_already=1; - return; - } else { - if (debug_mode) printf("\tjoined high priority thread\n"); - } -} - -static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - /* main test */ - - if (debug_mode) printf("User-Kernel test\n"); - runTest(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); - - - if(failed_already) - { - printf("FAIL\n"); - return 1; - } else - { - printf("PASS\n"); - return 0; - } -} - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/joinuu.c nspr-4.10.7/mozilla/nsprpub/pr/tests/joinuu.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/joinuu.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/joinuu.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,155 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: dbmalloc1.c -** -** Description: Join tests user - user -** -** Modification History: -** -** 19-May-97 AGarcia - separate the four join tests into different unit test modules. -** AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - - -/* - Program to test joining of threads. Two threads are created. One - to be waited upon until it has started. The other to join after it has - completed. -*/ - - -static void lowPriority(void *arg) -{ -} - -static void highPriority(void *arg) -{ -} - -void runTest(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *low,*high; - - /* create the low and high priority threads */ - - low = PR_CreateThread(PR_USER_THREAD, - lowPriority, 0, - PR_PRIORITY_LOW, - scope1, - PR_JOINABLE_THREAD, - 0); - if (!low) { - if (debug_mode) printf("\tcannot create low priority thread\n"); - else failed_already=1; - return; - } - - high = PR_CreateThread(PR_USER_THREAD, - highPriority, 0, - PR_PRIORITY_HIGH, - scope2, - PR_JOINABLE_THREAD, - 0); - if (!high) { - if (debug_mode) printf("\tcannot create high priority thread\n"); - else failed_already=1; - return; - } - - /* Do the joining for both threads */ - if (PR_JoinThread(low) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join low priority thread\n"); - else failed_already=1; - return; - } else { - if (debug_mode) printf("\tjoined low priority thread\n"); - } - if (PR_JoinThread(high) == PR_FAILURE) { - if (debug_mode) printf("\tcannot join high priority thread\n"); - else failed_already=1; - return; - } else { - if (debug_mode) printf("\tjoined high priority thread\n"); - } -} - -static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - /* main test */ - if (debug_mode) printf("User-User test\n"); - runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD); - - if(failed_already) - { - printf("FAIL\n"); - return 1; - } else - { - printf("PASS\n"); - return 0; - } - - -} - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/layer.c nspr-4.10.7/mozilla/nsprpub/pr/tests/layer.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/layer.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/layer.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,434 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prprf.h" -#include "prlog.h" -#include "prnetdb.h" -#include "prthread.h" - -#include "plerror.h" -#include "plgetopt.h" -#include "prwin16.h" - -#include -#include - -/* -** Testing layering of I/O -** -** The layered server -** A thread that acts as a server. It creates a TCP listener with a dummy -** layer pushed on top. Then listens for incoming connections. Each connection -** request for connection will be layered as well, accept one request, echo -** it back and close. -** -** The layered client -** Pretty much what you'd expect. -*/ - -static PRFileDesc *logFile; -static PRDescIdentity identity; -static PRNetAddr server_address; - -static PRIOMethods myMethods; - -typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity; - -static PRIntn minor_iterations = 5; -static PRIntn major_iterations = 1; -static Verbosity verbosity = quiet; -static PRUint16 default_port = 12273; - -static PRFileDesc *PushLayer(PRFileDesc *stack) -{ - PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods); - PRStatus rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); - if (verbosity > quiet) - PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); - PR_ASSERT(PR_SUCCESS == rv); - return stack; -} /* PushLayer */ - -static PRFileDesc *PushNewLayers(PRFileDesc *stack) -{ - PRDescIdentity tmp_identity; - PRFileDesc *layer; - PRStatus rv; - - /* push a dummy layer */ - tmp_identity = PR_GetUniqueIdentity("Dummy 1"); - layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); - rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); - if (verbosity > quiet) - PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, - stack); - PR_ASSERT(PR_SUCCESS == rv); - - /* push a data procesing layer */ - layer = PR_CreateIOLayerStub(identity, &myMethods); - rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); - if (verbosity > quiet) - PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, - stack); - PR_ASSERT(PR_SUCCESS == rv); - - /* push another dummy layer */ - tmp_identity = PR_GetUniqueIdentity("Dummy 2"); - layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); - rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); - if (verbosity > quiet) - PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, - stack); - PR_ASSERT(PR_SUCCESS == rv); - return stack; -} /* PushLayer */ - -#if 0 -static PRFileDesc *PopLayer(PRFileDesc *stack) -{ - PRFileDesc *popped = PR_PopIOLayer(stack, identity); - if (verbosity > quiet) - PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack); - popped->dtor(popped); - - return stack; -} /* PopLayer */ -#endif - -static void PR_CALLBACK Client(void *arg) -{ - PRStatus rv; - PRUint8 buffer[100]; - PRIntn empty_flags = 0; - PRIntn bytes_read, bytes_sent; - PRFileDesc *stack = (PRFileDesc*)arg; - - /* Initialize the buffer so that Purify won't complain */ - memset(buffer, 0, sizeof(buffer)); - - rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(PR_SUCCESS == rv); - while (minor_iterations-- > 0) - { - bytes_sent = PR_Send( - stack, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(sizeof(buffer) == bytes_sent); - if (verbosity > chatty) - PR_fprintf(logFile, "Client sending %d bytes\n", bytes_sent); - bytes_read = PR_Recv( - stack, buffer, bytes_sent, empty_flags, PR_INTERVAL_NO_TIMEOUT); - if (verbosity > chatty) - PR_fprintf(logFile, "Client receiving %d bytes\n", bytes_read); - PR_ASSERT(bytes_read == bytes_sent); - } - - if (verbosity > quiet) - PR_fprintf(logFile, "Client shutting down stack\n"); - - rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); -} /* Client */ - -static void PR_CALLBACK Server(void *arg) -{ - PRStatus rv; - PRUint8 buffer[100]; - PRFileDesc *service; - PRUintn empty_flags = 0; - PRIntn bytes_read, bytes_sent; - PRFileDesc *stack = (PRFileDesc*)arg; - PRNetAddr client_address; - - service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT); - if (verbosity > quiet) - PR_fprintf(logFile, "Server accepting connection\n"); - - do - { - bytes_read = PR_Recv( - service, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); - if (0 != bytes_read) - { - if (verbosity > chatty) - PR_fprintf(logFile, "Server receiving %d bytes\n", bytes_read); - PR_ASSERT(bytes_read > 0); - bytes_sent = PR_Send( - service, buffer, bytes_read, empty_flags, PR_INTERVAL_NO_TIMEOUT); - if (verbosity > chatty) - PR_fprintf(logFile, "Server sending %d bytes\n", bytes_sent); - PR_ASSERT(bytes_read == bytes_sent); - } - - } while (0 != bytes_read); - - if (verbosity > quiet) - PR_fprintf(logFile, "Server shutting down and closing stack\n"); - rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); - -} /* Server */ - -static PRInt32 PR_CALLBACK MyRecv( - PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - char *b = (char*)buf; - PRFileDesc *lo = fd->lower; - PRInt32 rv, readin = 0, request = 0; - rv = lo->methods->recv(lo, &request, sizeof(request), flags, timeout); - if (verbosity > chatty) PR_fprintf( - logFile, "MyRecv sending permission for %d bytes\n", request); - if (0 < rv) - { - if (verbosity > chatty) PR_fprintf( - logFile, "MyRecv received permission request for %d bytes\n", request); - rv = lo->methods->send( - lo, &request, sizeof(request), flags, timeout); - if (0 < rv) - { - if (verbosity > chatty) PR_fprintf( - logFile, "MyRecv sending permission for %d bytes\n", request); - while (readin < request) - { - rv = lo->methods->recv( - lo, b + readin, amount - readin, flags, timeout); - if (rv <= 0) break; - if (verbosity > chatty) PR_fprintf( - logFile, "MyRecv received %d bytes\n", rv); - readin += rv; - } - rv = readin; - } - } - return rv; -} /* MyRecv */ - -static PRInt32 PR_CALLBACK MySend( - PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - PRFileDesc *lo = fd->lower; - const char *b = (const char*)buf; - PRInt32 rv, wroteout = 0, request; - if (verbosity > chatty) PR_fprintf( - logFile, "MySend asking permission to send %d bytes\n", amount); - rv = lo->methods->send(lo, &amount, sizeof(amount), flags, timeout); - if (0 < rv) - { - rv = lo->methods->recv( - lo, &request, sizeof(request), flags, timeout); - if (0 < rv) - { - PR_ASSERT(request == amount); - if (verbosity > chatty) PR_fprintf( - logFile, "MySend got permission to send %d bytes\n", request); - while (wroteout < request) - { - rv = lo->methods->send( - lo, b + wroteout, request - wroteout, flags, timeout); - if (rv <= 0) break; - if (verbosity > chatty) PR_fprintf( - logFile, "MySend wrote %d bytes\n", rv); - wroteout += rv; - } - rv = amount; - } - } - return rv; -} /* MySend */ - -static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta) -{ - PRIntn verbage = (PRIntn)verbosity + delta; - if (verbage < (PRIntn)silent) verbage = (PRIntn)silent; - else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy; - return (Verbosity)verbage; -} /* ChangeVerbosity */ - -int main(int argc, char **argv) -{ - PRStatus rv; - PRIntn mits; - PLOptStatus os; - PRFileDesc *client, *service; - PRFileDesc *client_stack, *service_stack; - PRNetAddr any_address; - const char *server_name = NULL; - const PRIOMethods *stubMethods; - PRThread *client_thread, *server_thread; - PRThreadScope thread_scope = PR_LOCAL_THREAD; - PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: - server_name = opt->value; - break; - case 'd': /* debug mode */ - if (verbosity < noisy) - verbosity = ChangeVerbosity(verbosity, 1); - break; - case 'q': /* debug mode */ - if (verbosity > silent) - verbosity = ChangeVerbosity(verbosity, -1); - break; - case 'G': /* use global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'C': /* number of threads waiting */ - major_iterations = atoi(opt->value); - break; - case 'c': /* number of client threads */ - minor_iterations = atoi(opt->value); - break; - case 'p': /* default port */ - default_port = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - PR_STDIO_INIT(); - - logFile = PR_GetSpecialFD(PR_StandardError); - - identity = PR_GetUniqueIdentity("Dummy"); - stubMethods = PR_GetDefaultIOMethods(); - - /* - ** The protocol we're going to implement is one where in order to initiate - ** a send, the sender must first solicit permission. Therefore, every - ** send is really a send - receive - send sequence. - */ - myMethods = *stubMethods; /* first get the entire batch */ - myMethods.recv = MyRecv; /* then override the ones we care about */ - myMethods.send = MySend; /* then override the ones we care about */ - - if (NULL == server_name) - rv = PR_InitializeNetAddr( - PR_IpAddrLoopback, default_port, &server_address); - else - { - rv = PR_StringToNetAddr(server_name, &server_address); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_InitializeNetAddr( - PR_IpAddrNull, default_port, &server_address); - } - PR_ASSERT(PR_SUCCESS == rv); - - /* one type w/o layering */ - - mits = minor_iterations; - while (major_iterations-- > 0) - { - if (verbosity > silent) - PR_fprintf(logFile, "Beginning non-layered test\n"); - client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); - service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); - rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); - - minor_iterations = mits; - server_thread = PR_CreateThread( - PR_USER_THREAD, Server, service, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != server_thread); - - client_thread = PR_CreateThread( - PR_USER_THREAD, Client, client, - PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != client_thread); - - rv = PR_JoinThread(client_thread); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(server_thread); - PR_ASSERT(PR_SUCCESS == rv); - - rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); - if (verbosity > silent) - PR_fprintf(logFile, "Ending non-layered test\n"); - - /* with layering */ - if (verbosity > silent) - PR_fprintf(logFile, "Beginning layered test\n"); - client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); - PushLayer(client); - service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); - PushLayer(service); - rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); - - minor_iterations = mits; - server_thread = PR_CreateThread( - PR_USER_THREAD, Server, service, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != server_thread); - - client_thread = PR_CreateThread( - PR_USER_THREAD, Client, client, - PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != client_thread); - - rv = PR_JoinThread(client_thread); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(server_thread); - PR_ASSERT(PR_SUCCESS == rv); - - rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); - /* with layering, using new style stack */ - if (verbosity > silent) - PR_fprintf(logFile, - "Beginning layered test with new style stack\n"); - client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); - client_stack = PR_CreateIOLayer(client); - PushNewLayers(client_stack); - service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); - service_stack = PR_CreateIOLayer(service); - PushNewLayers(service_stack); - rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); - - minor_iterations = mits; - server_thread = PR_CreateThread( - PR_USER_THREAD, Server, service_stack, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != server_thread); - - client_thread = PR_CreateThread( - PR_USER_THREAD, Client, client_stack, - PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != client_thread); - - rv = PR_JoinThread(client_thread); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(server_thread); - PR_ASSERT(PR_SUCCESS == rv); - - rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv); - if (verbosity > silent) - PR_fprintf(logFile, "Ending layered test\n"); - } - return 0; -} /* main */ - -/* layer.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/lazyinit.c nspr-4.10.7/mozilla/nsprpub/pr/tests/lazyinit.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/lazyinit.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/lazyinit.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: lazyinit.c -** Description: Testing lazy initialization -** -** Since you only get to initialize once, you have to rerun the test -** for each test case. The test cases are numbered. If you want to -** add more tests, take the next number and add it to the switch -** statement. -** -** This test is problematic on systems that don't support the notion -** of console output. The workarounds to emulate that feature include -** initializations themselves, which defeats the purpose here. -*/ - -#include "prcvar.h" -#include "prenv.h" -#include "prinit.h" -#include "prinrval.h" -#include "prio.h" -#include "prlock.h" -#include "prlog.h" -#include "prthread.h" -#include "prtypes.h" - -#include -#include - -static void PR_CALLBACK lazyEntry(void *arg) -{ - PR_ASSERT(NULL == arg); -} /* lazyEntry */ - - -int main(int argc, char **argv) -{ - PRUintn pdkey; - PRStatus status; - char *path = NULL; - PRDir *dir = NULL; - PRLock *ml = NULL; - PRCondVar *cv = NULL; - PRThread *thread = NULL; - PRIntervalTime interval = 0; - PRFileDesc *file, *udp, *tcp, *pair[2]; - PRIntn test; - - if ( argc < 2) - { - test = 0; - } - else - test = atoi(argv[1]); - - switch (test) - { - case 0: ml = PR_NewLock(); - break; - - case 1: interval = PR_SecondsToInterval(1); - break; - - case 2: thread = PR_CreateThread( - PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - break; - - case 3: file = PR_Open("/usr/tmp/", PR_RDONLY, 0); - break; - - case 4: udp = PR_NewUDPSocket(); - break; - - case 5: tcp = PR_NewTCPSocket(); - break; - - case 6: dir = PR_OpenDir("/usr/tmp/"); - break; - - case 7: (void)PR_NewThreadPrivateIndex(&pdkey, NULL); - break; - - case 8: path = PR_GetEnv("PATH"); - break; - - case 9: status = PR_NewTCPSocketPair(pair); - break; - - case 10: PR_SetConcurrency(2); - break; - - default: - printf( - "lazyinit: unrecognized command line argument: %s\n", - argv[1] ); - printf( "FAIL\n" ); - exit( 1 ); - break; - } /* switch() */ - return 0; -} /* Lazy */ - -/* lazyinit.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/libfilename.c nspr-4.10.7/mozilla/nsprpub/pr/tests/libfilename.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/libfilename.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/libfilename.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: libfilename.c -** -** Description: test PR_GetLibraryFilePathname. -** -***********************************************************************/ - -#include "nspr.h" -#include "pprio.h" -#include -#include -#include - -PRBool debug_mode = PR_FALSE; - -static PRStatus RunTest(const char *name, PRFuncPtr addr) -{ - char *pathname; - PRFileDesc *fd; - - pathname = PR_GetLibraryFilePathname(name, addr); - if (pathname == NULL) { - fprintf(stderr, "PR_GetLibraryFilePathname failed\n"); - /* we let this test pass if this function is not implemented */ - if (PR_GetError() == PR_NOT_IMPLEMENTED_ERROR) { - return PR_SUCCESS; - } - return PR_FAILURE; - } - - if (debug_mode) printf("Pathname is %s\n", pathname); - fd = PR_OpenFile(pathname, PR_RDONLY, 0); - if (fd == NULL) { - fprintf(stderr, "PR_Open failed: %d\n", (int)PR_GetError()); - return PR_FAILURE; - } - if (PR_Close(fd) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed: %d\n", (int)PR_GetError()); - return PR_FAILURE; - } - PR_Free(pathname); - return PR_SUCCESS; -} - -int main(int argc, char **argv) -{ - char *name; - PRFuncPtr addr; - PRLibrary *lib; - PRBool failed = PR_FALSE; - - if (argc >= 2 && strcmp(argv[1], "-d") == 0) { - debug_mode = PR_TRUE; - } - - /* First test a library that is implicitly linked. */ -#ifdef WINNT - name = PR_Malloc(strlen("libnspr4.dll")+1); - strcpy(name, "libnspr4.dll"); -#else - name = PR_GetLibraryName(NULL, "nspr4"); -#endif - addr = (PRFuncPtr)PR_GetTCPMethods()->close; - if (RunTest(name, addr) == PR_FAILURE) { - failed = PR_TRUE; - } - PR_FreeLibraryName(name); - - /* Next test a library that is dynamically loaded. */ - name = PR_GetLibraryName("dll", "my"); - if (debug_mode) printf("Loading library %s\n", name); - lib = PR_LoadLibrary(name); - if (!lib) { - fprintf(stderr, "PR_LoadLibrary failed\n"); - exit(1); - } - PR_FreeLibraryName(name); - name = PR_GetLibraryName(NULL, "my"); - addr = PR_FindFunctionSymbol(lib, "My_GetValue"); - if (RunTest(name, addr) == PR_FAILURE) { - failed = PR_TRUE; - } - PR_FreeLibraryName(name); - PR_UnloadLibrary(lib); - if (failed) { - printf("FAIL\n"); - return 1; - } - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/lltest.c nspr-4.10.7/mozilla/nsprpub/pr/tests/lltest.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/lltest.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/lltest.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,827 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** testll.c -- test suite for 64bit integer (longlong) operations -** -** Summary: testll [-d] | [-h] -** -** Where: -** -d set debug mode on; displays individual test failures -** -v verbose mode; displays progress in test, plus -d -** -h gives usage message. -** -** Description: -** lltest.c tests the functions defined in NSPR 2.0's prlong.h. -** -** Successive tests begin to depend on other LL functions working -** correctly. So, ... Do not change the order of the tests as run -** from main(). -** -** Caveats: -** Do not even begin to think that this is an exhaustive test! -** -** These tests try a little of everything, but not all boundary -** conditions and limits are tested. -** You want better coverage? ... Add it. -** -** --- -** Author: Lawrence Hardiman . -** --- -** Revision History: -** 01-Oct-1997. Original implementation. -** -*/ - -#include "nspr.h" -#include "plgetopt.h" - -/* --- Local Definitions --- */ -#define ReportProgress(m) if (verboseMode) PR_fprintf(output, (m)); - - -/* --- Global variables --- */ -static PRIntn failedAlready = 0; -static PRFileDesc* output = NULL; -static PRBool debugMode = PR_FALSE; -static PRBool verboseMode = PR_FALSE; - -/* -** Constants used in tests. -*/ -const PRInt64 bigZero = LL_INIT( 0, 0 ); -const PRInt64 bigOne = LL_INIT( 0, 1 ); -const PRInt64 bigTwo = LL_INIT( 0, 2 ); -const PRInt64 bigSixTeen = LL_INIT( 0, 16 ); -const PRInt64 bigThirtyTwo = LL_INIT( 0, 32 ); -const PRInt64 bigMinusOne = LL_INIT( 0xffffffff, 0xffffffff ); -const PRInt64 bigMinusTwo = LL_INIT( 0xffffffff, 0xfffffffe ); -const PRInt64 bigNumber = LL_INIT( 0x7fffffff, 0xffffffff ); -const PRInt64 bigMinusNumber = LL_INIT( 0x80000000, 0x00000001 ); -const PRInt64 bigMaxInt32 = LL_INIT( 0x00000000, 0x7fffffff ); -const PRInt64 big2To31 = LL_INIT( 0x00000000, 0x80000000 ); -const PRUint64 bigZeroFox = LL_INIT( 0x00000000, 0xffffffff ); -const PRUint64 bigFoxFox = LL_INIT( 0xffffffff, 0xffffffff ); -const PRUint64 bigFoxZero = LL_INIT( 0xffffffff, 0x00000000 ); -const PRUint64 bigEightZero = LL_INIT( 0x80000000, 0x00000000 ); -const PRUint64 big64K = LL_INIT( 0x00000000, 0x00010000 ); -const PRInt64 bigInt0 = LL_INIT( 0x01a00000, 0x00001000 ); -const PRInt64 bigInt1 = LL_INIT( 0x01a00000, 0x00001100 ); -const PRInt64 bigInt2 = LL_INIT( 0x01a00000, 0x00000100 ); -const PRInt64 bigInt3 = LL_INIT( 0x01a00001, 0x00001000 ); -const PRInt64 bigInt4 = LL_INIT( 0x01a00001, 0x00001100 ); -const PRInt64 bigInt5 = LL_INIT( 0x01a00001, 0x00000100 ); -const PRInt64 bigInt6 = LL_INIT( 0xb1a00000, 0x00001000 ); -const PRInt64 bigInt7 = LL_INIT( 0xb1a00000, 0x00001100 ); -const PRInt64 bigInt8 = LL_INIT( 0xb1a00000, 0x00000100 ); -const PRInt64 bigInt9 = LL_INIT( 0xb1a00001, 0x00001000 ); -const PRInt64 bigInt10 = LL_INIT( 0xb1a00001, 0x00001100 ); -const PRInt64 bigInt11 = LL_INIT( 0xb1a00001, 0x00000100 ); -const PRInt32 one = 1l; -const PRInt32 minusOne = -1l; -const PRInt32 sixteen = 16l; -const PRInt32 thirtyTwo = 32l; -const PRInt32 sixtyThree = 63l; - -/* -** SetFailed() -- Report individual test failure -** -*/ -static void -SetFailed( char *what, char *how ) -{ - failedAlready = 1; - if ( debugMode ) - PR_fprintf(output, "%s: failed: %s\n", what, how ); - return; -} - -static void -ResultFailed( char *what, char *how, PRInt64 expected, PRInt64 got) -{ - if ( debugMode) - { - SetFailed( what, how ); - PR_fprintf(output, "Expected: 0x%llx Got: 0x%llx\n", expected, got ); - } - return; -} - - -/* -** TestAssignment() -- Test the assignment -*/ -static void TestAssignment( void ) -{ - PRInt64 zero = LL_Zero(); - PRInt64 min = LL_MinInt(); - PRInt64 max = LL_MaxInt(); - if (!LL_EQ(zero, bigZero)) - SetFailed("LL_EQ(zero, bigZero)", "!="); - if (!LL_CMP(max, >, min)) - SetFailed("LL_CMP(max, >, min)", "!>"); -} - -/* -** TestComparisons() -- Test the longlong comparison operations -*/ -static void -TestComparisons( void ) -{ - ReportProgress("Testing Comparisons Operations\n"); - - /* test for zero */ - if ( !LL_IS_ZERO( bigZero )) - SetFailed( "LL_IS_ZERO", "Zero is not zero" ); - - if ( LL_IS_ZERO( bigOne )) - SetFailed( "LL_IS_ZERO", "One tests as zero" ); - - if ( LL_IS_ZERO( bigMinusOne )) - SetFailed( "LL_IS_ZERO", "Minus One tests as zero" ); - - /* test equal */ - if ( !LL_EQ( bigZero, bigZero )) - SetFailed( "LL_EQ", "zero EQ zero"); - - if ( !LL_EQ( bigOne, bigOne )) - SetFailed( "LL_EQ", "one EQ one" ); - - if ( !LL_EQ( bigNumber, bigNumber )) - SetFailed( "LL_EQ", "bigNumber EQ bigNumber" ); - - if ( !LL_EQ( bigMinusOne, bigMinusOne )) - SetFailed( "LL_EQ", "minus one EQ minus one"); - - if ( LL_EQ( bigZero, bigOne )) - SetFailed( "LL_EQ", "zero EQ one"); - - if ( LL_EQ( bigOne, bigZero )) - SetFailed( "LL_EQ", "one EQ zero" ); - - if ( LL_EQ( bigMinusOne, bigOne )) - SetFailed( "LL_EQ", "minus one EQ one"); - - if ( LL_EQ( bigNumber, bigOne )) - SetFailed( "LL_EQ", "bigNumber EQ one"); - - /* test not equal */ - if ( LL_NE( bigZero, bigZero )) - SetFailed( "LL_NE", "0 NE 0"); - - if ( LL_NE( bigOne, bigOne )) - SetFailed( "LL_NE", "1 NE 1"); - - if ( LL_NE( bigMinusOne, bigMinusOne )) - SetFailed( "LL_NE", "-1 NE -1"); - - if ( LL_NE( bigNumber, bigNumber )) - SetFailed( "LL_NE", "n NE n"); - - if ( LL_NE( bigMinusNumber, bigMinusNumber )) - SetFailed( "LL_NE", "-n NE -n"); - - if ( !LL_NE( bigZero, bigOne)) - SetFailed( "LL_NE", "0 NE 1"); - - if ( !LL_NE( bigOne, bigMinusNumber)) - SetFailed( "LL_NE", "1 NE -n"); - - /* Greater than or equal to zero */ - if ( !LL_GE_ZERO( bigZero )) - SetFailed( "LL_GE_ZERO", "0"); - - if ( !LL_GE_ZERO( bigOne )) - SetFailed( "LL_GE_ZERO", "1"); - - if ( !LL_GE_ZERO( bigNumber )) - SetFailed( "LL_GE_ZERO", "n"); - - if ( LL_GE_ZERO( bigMinusOne )) - SetFailed( "LL_GE_ZERO", "-1"); - - if ( LL_GE_ZERO( bigMinusNumber )) - SetFailed( "LL_GE_ZERO", "-n"); - - /* Algebraic Compare two values */ - if ( !LL_CMP( bigZero, ==, bigZero )) - SetFailed( "LL_CMP", "0 == 0"); - - if ( LL_CMP( bigZero, >, bigZero )) - SetFailed( "LL_CMP", "0 > 0"); - - if ( LL_CMP( bigZero, <, bigZero )) - SetFailed( "LL_CMP", "0 < 0"); - - if ( LL_CMP( bigNumber, <, bigOne )) - SetFailed( "LL_CMP", "n < 1"); - - if ( !LL_CMP( bigNumber, >, bigOne )) - SetFailed( "LL_CMP", "n <= 1"); - - if ( LL_CMP( bigOne, >, bigNumber )) - SetFailed( "LL_CMP", "1 > n"); - - if ( LL_CMP( bigMinusNumber, >, bigNumber )) - SetFailed( "LL_CMP", "-n > n"); - - if ( LL_CMP( bigNumber, !=, bigNumber)) - SetFailed( "LL_CMP", "n != n"); - - if ( !LL_CMP( bigMinusOne, >, bigMinusTwo )) - SetFailed( "LL_CMP", "-1 <= -2"); - - if ( !LL_CMP( bigMaxInt32, <, big2To31 )) - SetFailed( "LL_CMP", "Max 32-bit signed int >= 2^31"); - - /* Two positive numbers */ - if ( !LL_CMP( bigInt0, <=, bigInt0 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( !LL_CMP( bigInt0, <=, bigInt1 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( LL_CMP( bigInt0, <=, bigInt2 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( !LL_CMP( bigInt0, <=, bigInt3 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( !LL_CMP( bigInt0, <=, bigInt4 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( !LL_CMP( bigInt0, <=, bigInt5 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - /* Two negative numbers */ - if ( !LL_CMP( bigInt6, <=, bigInt6 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( !LL_CMP( bigInt6, <=, bigInt7 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( LL_CMP( bigInt6, <=, bigInt8 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( !LL_CMP( bigInt6, <=, bigInt9 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( !LL_CMP( bigInt6, <=, bigInt10 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( !LL_CMP( bigInt6, <=, bigInt11 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - /* One positive, one negative */ - if ( LL_CMP( bigInt0, <=, bigInt6 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( LL_CMP( bigInt0, <=, bigInt7 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - if ( LL_CMP( bigInt0, <=, bigInt8 )) - SetFailed( "LL_CMP", "LL_CMP(<=) failed"); - - /* Bitwise Compare two numbers */ - if ( !LL_UCMP( bigZero, ==, bigZero )) - SetFailed( "LL_UCMP", "0 == 0"); - - if ( LL_UCMP( bigZero, >, bigZero )) - SetFailed( "LL_UCMP", "0 > 0"); - - if ( LL_UCMP( bigZero, <, bigZero )) - SetFailed( "LL_UCMP", "0 < 0"); - - if ( LL_UCMP( bigNumber, <, bigOne )) - SetFailed( "LL_UCMP", "n < 1"); - - if ( !LL_UCMP( bigNumber, >, bigOne )) - SetFailed( "LL_UCMP", "n < 1"); - - if ( LL_UCMP( bigOne, >, bigNumber )) - SetFailed( "LL_UCMP", "1 > n"); - - if ( LL_UCMP( bigMinusNumber, <, bigNumber )) - SetFailed( "LL_UCMP", "-n < n"); - - /* Two positive numbers */ - if ( !LL_UCMP( bigInt0, <=, bigInt0 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt0, <=, bigInt1 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( LL_UCMP( bigInt0, <=, bigInt2 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt0, <=, bigInt3 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt0, <=, bigInt4 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt0, <=, bigInt5 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - /* Two negative numbers */ - if ( !LL_UCMP( bigInt6, <=, bigInt6 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt6, <=, bigInt7 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( LL_UCMP( bigInt6, <=, bigInt8 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt6, <=, bigInt9 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt6, <=, bigInt10 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt6, <=, bigInt11 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - /* One positive, one negative */ - if ( !LL_UCMP( bigInt0, <=, bigInt6 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt0, <=, bigInt7 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - if ( !LL_UCMP( bigInt0, <=, bigInt8 )) - SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); - - return; -} - -/* -** TestLogicalOperations() -- Tests for AND, OR, ... -** -*/ -static void -TestLogicalOperations( void ) -{ - PRUint64 result, result2; - - ReportProgress("Testing Logical Operations\n"); - - /* Test AND */ - LL_AND( result, bigZero, bigZero ); - if ( !LL_IS_ZERO( result )) - ResultFailed( "LL_AND", "0 & 0", bigZero, result ); - - LL_AND( result, bigOne, bigOne ); - if ( LL_IS_ZERO( result )) - ResultFailed( "LL_AND", "1 & 1", bigOne, result ); - - LL_AND( result, bigZero, bigOne ); - if ( !LL_IS_ZERO( result )) - ResultFailed( "LL_AND", "1 & 1", bigZero, result ); - - LL_AND( result, bigMinusOne, bigMinusOne ); - if ( !LL_UCMP( result, ==, bigMinusOne )) - ResultFailed( "LL_AND", "-1 & -1", bigMinusOne, result ); - - /* test OR */ - LL_OR( result, bigZero, bigZero ); - if ( !LL_IS_ZERO( result )) - ResultFailed( "LL_OR", "0 | 1", bigZero, result); - - LL_OR( result, bigZero, bigOne ); - if ( LL_IS_ZERO( result )) - ResultFailed( "LL_OR", "0 | 1", bigOne, result ); - - LL_OR( result, bigZero, bigMinusNumber ); - if ( !LL_UCMP( result, ==, bigMinusNumber )) - ResultFailed( "LL_OR", "0 | -n", bigMinusNumber, result); - - LL_OR( result, bigMinusNumber, bigZero ); - if ( !LL_UCMP( result, ==, bigMinusNumber )) - ResultFailed( "LL_OR", "-n | 0", bigMinusNumber, result ); - - /* test XOR */ - LL_XOR( result, bigZero, bigZero ); - if ( LL_UCMP( result, !=, bigZero )) - ResultFailed( "LL_XOR", "0 ^ 0", bigZero, result); - - LL_XOR( result, bigOne, bigZero ); - if ( LL_UCMP( result, !=, bigOne )) - ResultFailed( "LL_XOR", "1 ^ 0", bigZero, result ); - - LL_XOR( result, bigMinusNumber, bigZero ); - if ( LL_UCMP( result, !=, bigMinusNumber )) - ResultFailed( "LL_XOR", "-n ^ 0", bigMinusNumber, result ); - - LL_XOR( result, bigMinusNumber, bigMinusNumber ); - if ( LL_UCMP( result, !=, bigZero )) - ResultFailed( "LL_XOR", "-n ^ -n", bigMinusNumber, result); - - /* test OR2. */ - result = bigZero; - LL_OR2( result, bigOne ); - if ( LL_UCMP( result, !=, bigOne )) - ResultFailed( "LL_OR2", "(r=0) |= 1", bigOne, result); - - result = bigOne; - LL_OR2( result, bigNumber ); - if ( LL_UCMP( result, !=, bigNumber )) - ResultFailed( "LL_OR2", "(r=1) |= n", bigNumber, result); - - result = bigMinusNumber; - LL_OR2( result, bigMinusNumber ); - if ( LL_UCMP( result, !=, bigMinusNumber )) - ResultFailed( "LL_OR2", "(r=-n) |= -n", bigMinusNumber, result); - - /* test NOT */ - LL_NOT( result, bigMinusNumber); - LL_NOT( result2, result); - if ( LL_UCMP( result2, !=, bigMinusNumber )) - ResultFailed( "LL_NOT", "r != ~(~-n)", bigMinusNumber, result); - - /* test Negation */ - LL_NEG( result, bigMinusNumber ); - LL_NEG( result2, result ); - if ( LL_CMP( result2, !=, bigMinusNumber )) - ResultFailed( "LL_NEG", "r != -(-(-n))", bigMinusNumber, result); - - return; -} - - - -/* -** TestConversion() -- Test Conversion Operations -** -*/ -static void -TestConversion( void ) -{ - PRInt64 result; - PRInt64 resultU; - PRInt32 result32; - PRUint32 resultU32; - float resultF; - PRFloat64 resultD; - - ReportProgress("Testing Conversion Operations\n"); - - /* LL_L2I -- Convert to signed 32bit */ - LL_L2I(result32, bigOne ); - if ( result32 != one ) - SetFailed( "LL_L2I", "r != 1"); - - LL_L2I(result32, bigMinusOne ); - if ( result32 != minusOne ) - SetFailed( "LL_L2I", "r != -1"); - - /* LL_L2UI -- Convert 64bit to unsigned 32bit */ - LL_L2UI( resultU32, bigMinusOne ); - if ( resultU32 != (PRUint32) minusOne ) - SetFailed( "LL_L2UI", "r != -1"); - - LL_L2UI( resultU32, bigOne ); - if ( resultU32 != (PRUint32) one ) - SetFailed( "LL_L2UI", "r != 1"); - - /* LL_L2F -- Convert to 32bit floating point */ - LL_L2F( resultF, bigOne ); - if ( resultF != 1.0 ) - SetFailed( "LL_L2F", "r != 1.0"); - - LL_L2F( resultF, bigMinusOne ); - if ( resultF != -1.0 ) - SetFailed( "LL_L2F", "r != 1.0"); - - /* LL_L2D -- Convert to 64bit floating point */ - LL_L2D( resultD, bigOne ); - if ( resultD != 1.0L ) - SetFailed( "LL_L2D", "r != 1.0"); - - LL_L2D( resultD, bigMinusOne ); - if ( resultD != -1.0L ) - SetFailed( "LL_L2D", "r != -1.0"); - - /* LL_I2L -- Convert 32bit signed to 64bit signed */ - LL_I2L( result, one ); - if ( LL_CMP(result, !=, bigOne )) - SetFailed( "LL_I2L", "r != 1"); - - LL_I2L( result, minusOne ); - if ( LL_CMP(result, !=, bigMinusOne )) - SetFailed( "LL_I2L", "r != -1"); - - /* LL_UI2L -- Convert 32bit unsigned to 64bit unsigned */ - LL_UI2L( resultU, (PRUint32) one ); - if ( LL_CMP(resultU, !=, bigOne )) - SetFailed( "LL_UI2L", "r != 1"); - - /* [lth.] This did not behave as expected, but it is correct - */ - LL_UI2L( resultU, (PRUint32) minusOne ); - if ( LL_CMP(resultU, !=, bigZeroFox )) - ResultFailed( "LL_UI2L", "r != -1", bigZeroFox, resultU); - - /* LL_F2L -- Convert 32bit float to 64bit signed */ - LL_F2L( result, 1.0 ); - if ( LL_CMP(result, !=, bigOne )) - SetFailed( "LL_F2L", "r != 1"); - - LL_F2L( result, -1.0 ); - if ( LL_CMP(result, !=, bigMinusOne )) - SetFailed( "LL_F2L", "r != -1"); - - /* LL_D2L -- Convert 64bit Float to 64bit signed */ - LL_D2L( result, 1.0L ); - if ( LL_CMP(result, !=, bigOne )) - SetFailed( "LL_D2L", "r != 1"); - - LL_D2L( result, -1.0L ); - if ( LL_CMP(result, !=, bigMinusOne )) - SetFailed( "LL_D2L", "r != -1"); - - return; -} - -static void ShiftCompileOnly() -{ - /* - ** This function is only compiled, never called. - ** The real test is to see if it compiles w/o - ** warnings. This is no small feat, by the way. - */ - PRInt64 ia, ib; - PRUint64 ua, ub; - LL_SHR(ia, ib, 32); - LL_SHL(ia, ib, 32); - - LL_USHR(ua, ub, 32); - LL_ISHL(ia, 49, 32); - -} /* ShiftCompileOnly */ - - -/* -** TestShift() -- Test Shifting Operations -** -*/ -static void -TestShift( void ) -{ - static const PRInt64 largeTwoZero = LL_INIT( 0x00000002, 0x00000000 ); - PRInt64 result; - PRUint64 resultU; - - ReportProgress("Testing Shifting Operations\n"); - - /* LL_SHL -- Shift left algebraic */ - LL_SHL( result, bigOne, one ); - if ( LL_CMP( result, !=, bigTwo )) - ResultFailed( "LL_SHL", "r != 2", bigOne, result ); - - LL_SHL( result, bigTwo, thirtyTwo ); - if ( LL_CMP( result, !=, largeTwoZero )) - ResultFailed( "LL_SHL", "r != twoZero", largeTwoZero, result); - - /* LL_SHR -- Shift right algebraic */ - LL_SHR( result, bigFoxZero, thirtyTwo ); - if ( LL_CMP( result, !=, bigMinusOne )) - ResultFailed( "LL_SHR", "r != -1", bigMinusOne, result); - - LL_SHR( result, bigTwo, one ); - if ( LL_CMP( result, !=, bigOne )) - ResultFailed( "LL_SHR", "r != 1", bigOne, result); - - LL_SHR( result, bigFoxFox, thirtyTwo ); - if ( LL_CMP( result, !=, bigMinusOne )) - ResultFailed( "LL_SHR", "r != -1 (was ff,ff)", bigMinusOne, result); - - /* LL_USHR -- Logical shift right */ - LL_USHR( resultU, bigZeroFox, thirtyTwo ); - if ( LL_UCMP( resultU, !=, bigZero )) - ResultFailed( "LL_USHR", "r != 0 ", bigZero, result); - - LL_USHR( resultU, bigFoxFox, thirtyTwo ); - if ( LL_UCMP( resultU, !=, bigZeroFox )) - ResultFailed( "LL_USHR", "r != 0 ", bigZeroFox, result); - - /* LL_ISHL -- Shift a 32bit integer into a 64bit result */ - LL_ISHL( resultU, minusOne, thirtyTwo ); - if ( LL_UCMP( resultU, !=, bigFoxZero )) - ResultFailed( "LL_ISHL", "r != ff,00 ", bigFoxZero, result); - - LL_ISHL( resultU, one, sixtyThree ); - if ( LL_UCMP( resultU, !=, bigEightZero )) - ResultFailed( "LL_ISHL", "r != 80,00 ", bigEightZero, result); - - LL_ISHL( resultU, one, sixteen ); - if ( LL_UCMP( resultU, !=, big64K )) - ResultFailed( "LL_ISHL", "r != 64K ", big64K, resultU); - - return; -} - - -/* -** TestArithmetic() -- Test arithmetic operations. -** -*/ -static void -TestArithmetic( void ) -{ - PRInt64 largeVal = LL_INIT( 0x00000001, 0xffffffff ); - PRInt64 largeValPlusOne = LL_INIT( 0x00000002, 0x00000000 ); - PRInt64 largeValTimesTwo = LL_INIT( 0x00000003, 0xfffffffe ); - PRInt64 largeMultCand = LL_INIT( 0x00000000, 0x7fffffff ); - PRInt64 largeMinusMultCand = LL_INIT( 0xffffffff, 0x10000001 ); - PRInt64 largeMultCandx64K = LL_INIT( 0x00007fff, 0xffff0000 ); - PRInt64 largeNumSHL5 = LL_INIT( 0x0000001f, 0xffffffe0 ); - PRInt64 result, result2; - - /* Addition */ - LL_ADD( result, bigOne, bigOne ); - if ( LL_CMP( result, !=, bigTwo )) - ResultFailed( "LL_ADD", "r != 1 + 1", bigTwo, result); - - LL_ADD( result, bigMinusOne, bigOne ); - if ( LL_CMP( result, !=, bigZero )) - ResultFailed( "LL_ADD", "r != -1 + 1", bigOne, result); - - LL_ADD( result, largeVal, bigOne ); - if ( LL_CMP( result, !=, largeValPlusOne )) - ResultFailed( "LL_ADD", "lVP1 != lV + 1", largeValPlusOne, result); - - /* Subtraction */ - LL_SUB( result, bigOne, bigOne ); - if ( LL_CMP( result, !=, bigZero )) - ResultFailed( "LL_SUB", "r != 1 - 1", bigZero, result); - - LL_SUB( result, bigTwo, bigOne ); - if ( LL_CMP( result, !=, bigOne )) - ResultFailed( "LL_SUB", "r != 2 - 1", bigOne, result); - - LL_SUB( result, largeValPlusOne, bigOne ); - if ( LL_CMP( result, !=, largeVal )) - ResultFailed( "LL_SUB", "r != lVP1 - 1", largeVal, result); - - - /* Multiply */ - LL_MUL( result, largeVal, bigTwo ); - if ( LL_CMP( result, !=, largeValTimesTwo )) - ResultFailed( "LL_MUL", "r != lV*2", largeValTimesTwo, result); - - LL_MUL( result, largeMultCand, big64K ); - if ( LL_CMP( result, !=, largeMultCandx64K )) - ResultFailed( "LL_MUL", "r != lV*64K", largeMultCandx64K, result); - - LL_NEG( result2, largeMultCand ); - LL_MUL( result, largeMultCand, bigMinusOne ); - if ( LL_CMP( result, !=, result2 )) - ResultFailed( "LL_MUL", "r != -lMC", result2, result); - - LL_SHL( result2, bigZeroFox, 5); - LL_MUL( result, bigZeroFox, bigThirtyTwo ); - if ( LL_CMP( result, !=, largeNumSHL5 )) - ResultFailed( "LL_MUL", "r != 0f<<5", largeNumSHL5, result ); - - - - /* LL_DIV() Division */ - LL_DIV( result, bigOne, bigOne); - if ( LL_CMP( result, !=, bigOne )) - ResultFailed( "LL_DIV", "1 != 1", bigOne, result); - - LL_DIV( result, bigNumber, bigOne ); - if ( LL_CMP( result, !=, bigNumber )) - ResultFailed( "LL_DIV", "r != n / 1", bigNumber, result); - - LL_DIV( result, bigNumber, bigMinusOne ); - if ( LL_CMP( result, !=, bigMinusNumber )) - ResultFailed( "LL_DIV", "r != n / -1", bigMinusNumber, result); - - LL_DIV( result, bigMinusNumber, bigMinusOne ); - if ( LL_CMP( result, !=, bigNumber )) - ResultFailed( "LL_DIV", "r != -n / -1", bigNumber, result); - - LL_SHL( result2, bigZeroFox, 5 ); - LL_DIV( result, result2, bigOne ); - if ( LL_CMP( result, !=, result2 )) - ResultFailed( "LL_DIV", "0f<<5 != 0f<<5", result2, result); - - LL_SHL( result2, bigZeroFox, 5 ); - LL_NEG( result2, result2 ); - LL_DIV( result, result2, bigOne ); - if ( LL_CMP( result, !=, result2 )) - ResultFailed( "LL_DIV", "-0f<<5 != -0f<<5", result2, result); - - LL_SHL( result2, bigZeroFox, 17 ); - LL_DIV( result, result2, bigMinusOne ); - LL_NEG( result2, result2 ); - if ( LL_CMP( result, !=, result2 )) - ResultFailed( "LL_DIV", "-0f<<17 != -0f<<17", result2, result); - - - /* LL_MOD() Modulo Division */ - LL_ADD( result2, bigThirtyTwo, bigOne ); - LL_MOD( result, result2, bigSixTeen ); - if ( LL_CMP( result, !=, bigOne )) - ResultFailed( "LL_MOD", "r != 1", bigSixTeen, result); - - - LL_MUL( result2, bigZeroFox, bigThirtyTwo ); - LL_ADD( result2, result2, bigSixTeen); - LL_MOD( result, result2, bigThirtyTwo ); - if ( LL_CMP( result, !=, bigSixTeen )) - ResultFailed( "LL_MOD", "r != 16", bigSixTeen, result); - - /* LL_UDIVMOD */ - LL_DIV( result, bigOne, bigOne); - if ( LL_CMP( result, !=, bigOne )) - ResultFailed( "LL_DIV", "r != 16", bigSixTeen, result); - - - return; -} - -static void TestWellknowns(void) -{ - PRInt64 max = LL_MAXINT, min = LL_MININT, zero = LL_ZERO; - PRInt64 mmax = LL_MaxInt(), mmin = LL_MinInt(), mzero = LL_Zero(); - if (LL_NE(max, mmax)) - ResultFailed( "max, mmax", "max != mmax", max, mmax); - if (LL_NE(min, mmin)) - ResultFailed( "min, mmin", "min != mmin", max, mmin); - if (LL_NE(zero, mzero)) - ResultFailed( "zero, mzero", "zero != mzero", zero, mzero); -} /* TestWellknowns */ - -/* -** Initialize() -- Initialize the test case -** -** Parse command line options -** -*/ -static PRIntn -Initialize( PRIntn argc, char **argv ) -{ - PLOptState *opt = PL_CreateOptState(argc, argv, "dvh"); - PLOptStatus os; - - /* - ** Parse command line options - */ - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* set debug mode */ - debugMode = PR_TRUE; - break; - - case 'v': /* set verbose mode */ - verboseMode = PR_TRUE; - debugMode = PR_TRUE; - break; - - case 'h': /* user wants some guidance */ - default: - PR_fprintf(output, "You get help.\n"); - return(1); - } - } - PL_DestroyOptState(opt); - return(0); -} - -int main(int argc, char **argv) -{ - PR_STDIO_INIT(); - output = PR_GetSpecialFD(PR_StandardError); - - if ( Initialize( argc, argv )) - return(1); - - TestAssignment(); - TestComparisons(); - TestLogicalOperations(); - TestConversion(); - TestShift(); - TestArithmetic(); - TestWellknowns(); - - /* - ** That's all folks! - */ - if ( failedAlready ) - { - PR_fprintf(output, "FAIL\n");\ - } - else - { - PR_fprintf(output, "PASS\n");\ - } - return failedAlready; -} /* end main() */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/lock.c nspr-4.10.7/mozilla/nsprpub/pr/tests/lock.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/lock.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/lock.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,519 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: lock.c -** Purpose: test basic locking functions -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -** -** 11-Aug-97 LarryH. Win16 port of NSPR. -** - Added "PASS", "FAIL" messages on completion. -** - Change stack variables to static scope variables -** because of shadow-stack use by Win16 -** - Added PR_CALLBACK attribute to functions called by NSPR -** - Added command line arguments: -** - l to control the number of loops -** - c to control the number of CPUs. -** (was positional argv). -** -** -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prio.h" -#include "prcmon.h" -#include "prinit.h" -#include "prinrval.h" -#include "prprf.h" -#include "prlock.h" -#include "prlog.h" -#include "prmon.h" -#include "prmem.h" -#include "prthread.h" -#include "prtypes.h" - -#include "plstr.h" - -#include - -#if defined(XP_UNIX) -#include -#endif - -static PRIntn failed_already=0; -static PRFileDesc *std_err = NULL; -static PRBool verbosity = PR_FALSE; -static PRBool debug_mode = PR_FALSE; - -const static PRIntervalTime contention_interval = 50; - -typedef struct LockContentious_s { - PRLock *ml; - PRInt32 loops; - PRUint32 contender; - PRUint32 contentious; - PRIntervalTime overhead; - PRIntervalTime interval; -} LockContentious_t; - -typedef struct MonitorContentious_s { - PRMonitor *ml; - PRInt32 loops; - PRUint32 contender; - PRUint32 contentious; - PRIntervalTime overhead; - PRIntervalTime interval; -} MonitorContentious_t; - - -static PRIntervalTime Sleeper(PRUint32 loops) -{ - PRIntervalTime predicted = 0; - while (loops-- > 0) - { - predicted += contention_interval; - (void)PR_Sleep(contention_interval); - } - return predicted; -} /* Sleeper */ - -/* -** BASIC LOCKS -*/ -static PRIntervalTime MakeLock(PRUint32 loops) -{ - PRLock *ml = NULL; - while (loops-- > 0) - { - ml = PR_NewLock(); - PR_DestroyLock(ml); - ml = NULL; - } - return 0; -} /* MakeLock */ - -static PRIntervalTime NonContentiousLock(PRUint32 loops) -{ - PRLock *ml = NULL; - ml = PR_NewLock(); - while (loops-- > 0) - { - PR_Lock(ml); - PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(ml); - PR_Unlock(ml); - } - PR_DestroyLock(ml); - return 0; -} /* NonContentiousLock */ - -static void PR_CALLBACK LockContender(void *arg) -{ - LockContentious_t *contention = (LockContentious_t*)arg; - while (contention->loops-- > 0) - { - PR_Lock(contention->ml); - PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml); - contention->contender+= 1; - contention->overhead += contention->interval; - PR_Sleep(contention->interval); - PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml); - PR_Unlock(contention->ml); - } -} /* LockContender */ - -static PRIntervalTime ContentiousLock(PRUint32 loops) -{ - PRStatus status; - PRThread *thread = NULL; - LockContentious_t * contention; - PRIntervalTime rv, overhead, timein = PR_IntervalNow(); - - contention = PR_NEWZAP(LockContentious_t); - contention->loops = loops; - contention->overhead = 0; - contention->ml = PR_NewLock(); - contention->interval = contention_interval; - thread = PR_CreateThread( - PR_USER_THREAD, LockContender, contention, - PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - PR_ASSERT(thread != NULL); - - overhead = PR_IntervalNow() - timein; - - while (contention->loops-- > 0) - { - PR_Lock(contention->ml); - PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml); - contention->contentious+= 1; - contention->overhead += contention->interval; - PR_Sleep(contention->interval); - PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml); - PR_Unlock(contention->ml); - } - - timein = PR_IntervalNow(); - status = PR_JoinThread(thread); - PR_DestroyLock(contention->ml); - overhead += (PR_IntervalNow() - timein); - rv = overhead + contention->overhead; - if (verbosity) - PR_fprintf( - std_err, "Access ratio: %u to %u\n", - contention->contentious, contention->contender); - PR_Free(contention); - return rv; -} /* ContentiousLock */ - -/* -** MONITORS -*/ -static PRIntervalTime MakeMonitor(PRUint32 loops) -{ - PRMonitor *ml = NULL; - while (loops-- > 0) - { - ml = PR_NewMonitor(); - PR_DestroyMonitor(ml); - ml = NULL; - } - return 0; -} /* MakeMonitor */ - -static PRIntervalTime NonContentiousMonitor(PRUint32 loops) -{ - PRMonitor *ml = NULL; - ml = PR_NewMonitor(); - while (loops-- > 0) - { - PR_EnterMonitor(ml); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); - PR_ExitMonitor(ml); - } - PR_DestroyMonitor(ml); - return 0; -} /* NonContentiousMonitor */ - -static void PR_CALLBACK TryEntry(void *arg) -{ - PRMonitor *ml = (PRMonitor*)arg; - if (debug_mode) PR_fprintf(std_err, "Reentrant thread created\n"); - PR_EnterMonitor(ml); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); - if (debug_mode) PR_fprintf(std_err, "Reentrant thread acquired monitor\n"); - PR_ExitMonitor(ml); - if (debug_mode) PR_fprintf(std_err, "Reentrant thread released monitor\n"); -} /* TryEntry */ - -static PRIntervalTime ReentrantMonitor(PRUint32 loops) -{ - PRStatus status; - PRThread *thread; - PRMonitor *ml = PR_NewMonitor(); - if (debug_mode) PR_fprintf(std_err, "\nMonitor created for reentrant test\n"); - - PR_EnterMonitor(ml); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); - PR_EnterMonitor(ml); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); - if (debug_mode) PR_fprintf(std_err, "Monitor acquired twice\n"); - - thread = PR_CreateThread( - PR_USER_THREAD, TryEntry, ml, - PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - PR_ASSERT(thread != NULL); - PR_Sleep(PR_SecondsToInterval(1)); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); - - PR_ExitMonitor(ml); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); - if (debug_mode) PR_fprintf(std_err, "Monitor released first time\n"); - - PR_ExitMonitor(ml); - if (debug_mode) PR_fprintf(std_err, "Monitor released second time\n"); - - status = PR_JoinThread(thread); - if (debug_mode) PR_fprintf(std_err, - "Reentrant thread joined %s\n", - (status == PR_SUCCESS) ? "successfully" : "in error"); - - PR_DestroyMonitor(ml); - return 0; -} /* ReentrantMonitor */ - -static void PR_CALLBACK MonitorContender(void *arg) -{ - MonitorContentious_t *contention = (MonitorContentious_t*)arg; - while (contention->loops-- > 0) - { - PR_EnterMonitor(contention->ml); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); - contention->contender+= 1; - contention->overhead += contention->interval; - PR_Sleep(contention->interval); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); - PR_ExitMonitor(contention->ml); - } -} /* MonitorContender */ - -static PRUint32 ContentiousMonitor(PRUint32 loops) -{ - PRStatus status; - PRThread *thread = NULL; - MonitorContentious_t * contention; - PRIntervalTime rv, overhead, timein = PR_IntervalNow(); - - contention = PR_NEWZAP(MonitorContentious_t); - contention->loops = loops; - contention->overhead = 0; - contention->ml = PR_NewMonitor(); - contention->interval = contention_interval; - thread = PR_CreateThread( - PR_USER_THREAD, MonitorContender, contention, - PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - PR_ASSERT(thread != NULL); - - overhead = PR_IntervalNow() - timein; - - while (contention->loops-- > 0) - { - PR_EnterMonitor(contention->ml); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); - contention->contentious+= 1; - contention->overhead += contention->interval; - PR_Sleep(contention->interval); - PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); - PR_ExitMonitor(contention->ml); - } - - timein = PR_IntervalNow(); - status = PR_JoinThread(thread); - PR_DestroyMonitor(contention->ml); - overhead += (PR_IntervalNow() - timein); - rv = overhead + contention->overhead; - if (verbosity) - PR_fprintf( - std_err, "Access ratio: %u to %u\n", - contention->contentious, contention->contender); - PR_Free(contention); - return rv; -} /* ContentiousMonitor */ - -/* -** CACHED MONITORS -*/ -static PRIntervalTime NonContentiousCMonitor(PRUint32 loops) -{ - MonitorContentious_t contention; - while (loops-- > 0) - { - PR_CEnterMonitor(&contention); - PR_CExitMonitor(&contention); - } - return 0; -} /* NonContentiousCMonitor */ - -static void PR_CALLBACK Contender(void *arg) -{ - MonitorContentious_t *contention = (MonitorContentious_t*)arg; - while (contention->loops-- > 0) - { - PR_CEnterMonitor(contention); - contention->contender+= 1; - contention->overhead += contention->interval; - PR_Sleep(contention->interval); - PR_CExitMonitor(contention); - } -} /* Contender */ - -static PRIntervalTime ContentiousCMonitor(PRUint32 loops) -{ - PRStatus status; - PRThread *thread = NULL; - MonitorContentious_t * contention; - PRIntervalTime overhead, timein = PR_IntervalNow(); - - contention = PR_NEWZAP(MonitorContentious_t); - contention->ml = NULL; - contention->loops = loops; - contention->interval = contention_interval; - thread = PR_CreateThread( - PR_USER_THREAD, Contender, contention, - PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - PR_ASSERT(thread != NULL); - - overhead = PR_IntervalNow() - timein; - - while (contention->loops-- > 0) - { - PR_CEnterMonitor(contention); - contention->contentious+= 1; - contention->overhead += contention->interval; - PR_Sleep(contention->interval); - PR_CExitMonitor(contention); - } - - timein = PR_IntervalNow(); - status = PR_JoinThread(thread); - overhead += (PR_IntervalNow() - timein); - overhead += overhead + contention->overhead; - if (verbosity) - PR_fprintf( - std_err, "Access ratio: %u to %u\n", - contention->contentious, contention->contender); - PR_Free(contention); - return overhead; -} /* ContentiousCMonitor */ - -static PRIntervalTime Test( - const char* msg, PRUint32 (*test)(PRUint32 loops), - PRUint32 loops, PRIntervalTime overhead) -{ - /* - * overhead - overhead not measured by the test. - * duration - wall clock time it took to perform test. - * predicted - extra time test says should not be counted - * - * Time accountable to the test is duration - overhead - predicted - * All times are Intervals and accumulated for all iterations. - */ - PRFloat64 elapsed; - PRIntervalTime accountable, duration; - PRUintn spaces = PL_strlen(msg); - PRIntervalTime timeout, timein = PR_IntervalNow(); - PRIntervalTime predicted = test(loops); - timeout = PR_IntervalNow(); - duration = timeout - timein; - - if (debug_mode) - { - accountable = duration - predicted; - accountable -= overhead; - elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable); - PR_fprintf(PR_STDOUT, "%s:", msg); - while (spaces++ < 50) PR_fprintf(PR_STDOUT, " "); - if ((PRInt32)accountable < 0) - PR_fprintf(PR_STDOUT, "*****.** usecs/iteration\n"); - else - PR_fprintf(PR_STDOUT, "%8.2f usecs/iteration\n", elapsed/loops); - } - return duration; -} /* Test */ - -int main(int argc, char **argv) -{ - PRBool rv = PR_TRUE; - PRIntervalTime duration; - PRUint32 cpu, cpus = 2, loops = 100; - - - PR_STDIO_INIT(); - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - { - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Command line argument -l sets the number of loops. - Command line argument -c sets the number of cpus. - Usage: lock [-d] [-l ] [-c ] - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dvl:c:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'v': /* debug mode */ - verbosity = PR_TRUE; - break; - case 'l': /* number of loops */ - loops = atoi(opt->value); - break; - case 'c': /* number of cpus */ - cpus = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - } - - /* main test */ - PR_SetConcurrency(8); - - if (loops == 0) loops = 100; - if (debug_mode) - { - std_err = PR_STDERR; - PR_fprintf(std_err, "Lock: Using %d loops\n", loops); - } - - if (cpus == 0) cpus = 2; - if (debug_mode) PR_fprintf(std_err, "Lock: Using %d cpu(s)\n", cpus); - - (void)Sleeper(10); /* try filling in the caches */ - - for (cpu = 1; cpu <= cpus; ++cpu) - { - if (debug_mode) PR_fprintf(std_err, "\nLock: Using %d CPU(s)\n", cpu); - PR_SetConcurrency(cpu); - - duration = Test("Overhead of PR_Sleep", Sleeper, loops, 0); - duration = 0; - - (void)Test("Lock creation/deletion", MakeLock, loops, 0); - (void)Test("Lock non-contentious locking/unlocking", NonContentiousLock, loops, 0); - (void)Test("Lock contentious locking/unlocking", ContentiousLock, loops, duration); - (void)Test("Monitor creation/deletion", MakeMonitor, loops, 0); - (void)Test("Monitor non-contentious locking/unlocking", NonContentiousMonitor, loops, 0); - (void)Test("Monitor contentious locking/unlocking", ContentiousMonitor, loops, duration); - - (void)Test("Cached monitor non-contentious locking/unlocking", NonContentiousCMonitor, loops, 0); - (void)Test("Cached monitor contentious locking/unlocking", ContentiousCMonitor, loops, duration); - - (void)ReentrantMonitor(loops); - } - - if (debug_mode) - PR_fprintf( - std_err, "%s: test %s\n", "Lock(mutex) test", - ((rv) ? "passed" : "failed")); - else { - if (!rv) - failed_already=1; - } - - if(failed_already) - { - PR_fprintf(PR_STDOUT, "FAIL\n"); - return 1; - } - else - { - PR_fprintf(PR_STDOUT, "PASS\n"); - return 0; - } - -} /* main */ - -/* testlock.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/lockfile.c nspr-4.10.7/mozilla/nsprpub/pr/tests/lockfile.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/lockfile.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/lockfile.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,229 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: lockfile.c -** Purpose: test basic locking functions -** Just because this times stuff, don't think its a perforamnce -** test!!! -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prcmon.h" -#include "prerror.h" -#include "prinit.h" -#include "prinrval.h" -#include "prlock.h" -#include "prlog.h" -#include "prmon.h" -#include "prthread.h" -#include "prtypes.h" - -#include "private/pprio.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - -const static PRIntervalTime contention_interval = 50; - -typedef struct LockContentious_s { - PRLock *ml; - PRInt32 loops; - PRIntervalTime overhead; - PRIntervalTime interval; -} LockContentious_t; - -#define LOCKFILE "prlock.fil" - - - -static PRIntervalTime NonContentiousLock(PRInt32 loops) -{ - PRFileDesc *_lockfile; - while (loops-- > 0) - { - _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666); - if (!_lockfile) { - if (debug_mode) printf( - "could not create lockfile: %d [%d]\n", - PR_GetError(), PR_GetOSError()); - return PR_INTERVAL_NO_TIMEOUT; - } - PR_LockFile(_lockfile); - PR_UnlockFile(_lockfile); - PR_Close(_lockfile); - } - return 0; -} /* NonContentiousLock */ - -static void PR_CALLBACK LockContender(void *arg) -{ - LockContentious_t *contention = (LockContentious_t*)arg; - PRFileDesc *_lockfile; - while (contention->loops-- > 0) - { - _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666); - if (!_lockfile) { - if (debug_mode) printf( - "could not create lockfile: %d [%d]\n", - PR_GetError(), PR_GetOSError()); - break; - } - PR_LockFile(_lockfile); - PR_Sleep(contention->interval); - PR_UnlockFile(_lockfile); - PR_Close(_lockfile); - } - -} /* LockContender */ - -/* -** Win16 requires things passed to Threads not be on the stack -*/ -static LockContentious_t contention; - -static PRIntervalTime ContentiousLock(PRInt32 loops) -{ - PRStatus status; - PRThread *thread = NULL; - PRIntervalTime overhead, timein = PR_IntervalNow(); - - contention.loops = loops; - contention.overhead = 0; - contention.ml = PR_NewLock(); - contention.interval = contention_interval; - thread = PR_CreateThread( - PR_USER_THREAD, LockContender, &contention, - PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - PR_ASSERT(thread != NULL); - - overhead = PR_IntervalNow() - timein; - - while (contention.loops > 0) - { - PR_Lock(contention.ml); - contention.overhead += contention.interval; - PR_Sleep(contention.interval); - PR_Unlock(contention.ml); - } - - timein = PR_IntervalNow(); - status = PR_JoinThread(thread); - PR_DestroyLock(contention.ml); - overhead += (PR_IntervalNow() - timein); - return overhead + contention.overhead; -} /* ContentiousLock */ - -static PRIntervalTime Test( - const char* msg, PRIntervalTime (*test)(PRInt32 loops), - PRInt32 loops, PRIntervalTime overhead) -{ - /* - * overhead - overhead not measured by the test. - * duration - wall clock time it took to perform test. - * predicted - extra time test says should not be counted - * - * Time accountable to the test is duration - overhead - predicted - * All times are Intervals and accumulated for all iterations. - */ - PRFloat64 elapsed; - PRIntervalTime accountable, duration; - PRUintn spaces = strlen(msg); - PRIntervalTime timeout, timein = PR_IntervalNow(); - PRIntervalTime predicted = test(loops); - timeout = PR_IntervalNow(); - duration = timeout - timein; - accountable = duration - predicted; - accountable -= overhead; - elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable); - if (debug_mode) printf("%s:", msg); - while (spaces++ < 50) if (debug_mode) printf(" "); - if ((PRInt32)accountable < 0) { - if (debug_mode) printf("*****.** usecs/iteration\n"); - } else { - if (debug_mode) printf("%8.2f usecs/iteration\n", elapsed/loops); - } - return duration; -} /* Test */ - -int main(int argc, char **argv) -{ - PRIntervalTime duration; - PRUint32 cpu, cpus = 2; - PRInt32 loops = 100; - - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (argc > 1) loops = atoi(argv[1]); - if (loops == 0) loops = 100; - if (debug_mode) printf("Lock: Using %d loops\n", loops); - - cpus = (argc < 3) ? 2 : atoi(argv[2]); - if (cpus == 0) cpus = 2; - if (debug_mode) printf("Lock: Using %d cpu(s)\n", cpus); - - - for (cpu = 1; cpu <= cpus; ++cpu) - { - if (debug_mode) printf("\nLockFile: Using %d CPU(s)\n", cpu); - PR_SetConcurrency(cpu); - - duration = Test("LockFile non-contentious locking/unlocking", NonContentiousLock, loops, 0); - (void)Test("LockFile contentious locking/unlocking", ContentiousLock, loops, duration); - } - - PR_Delete(LOCKFILE); /* try to get rid of evidence */ - - if (debug_mode) printf("%s: test %s\n", "Lock(mutex) test", ((failed_already) ? "failed" : "passed")); - if(failed_already) - return 1; - else - return 0; -} /* main */ - -/* testlock.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/logfile.c nspr-4.10.7/mozilla/nsprpub/pr/tests/logfile.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/logfile.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/logfile.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * A regression test for bug 491441. NSPR should not crash on startup in - * PR_SetLogFile when the NSPR_LOG_MODULES and NSPR_LOG_FILE environment - * variables are set. - * - * This test could be extended to be a full-blown test for NSPR_LOG_FILE. - */ - -#include "prinit.h" -#include "prlog.h" - -#include -#include - -int main() -{ - PRLogModuleInfo *test_lm; - - if (putenv("NSPR_LOG_MODULES=all:5") != 0) { - fprintf(stderr, "putenv failed\n"); - exit(1); - } - if (putenv("NSPR_LOG_FILE=logfile.log") != 0) { - fprintf(stderr, "putenv failed\n"); - exit(1); - } - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - test_lm = PR_NewLogModule("test"); - PR_LOG(test_lm, PR_LOG_MIN, ("logfile: test log message")); - PR_Cleanup(); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/logger.c nspr-4.10.7/mozilla/nsprpub/pr/tests/logger.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/logger.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/logger.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: logger.c - * Description: test program for logging's basic functions - */ - -#include "prinit.h" -#include "prlog.h" -#include "prlock.h" -#include "prcvar.h" -#include "prthread.h" -#include "prinrval.h" - -#include - -/* lth. re-define PR_LOG() */ -#if 0 -#undef PR_LOG_TEST -#undef PR_LOG -#define PR_LOG_TEST(_module,_level) ((_module)->level <= (_level)) -#define PR_LOG(_module,_level,_args) \ - { \ - if (PR_LOG_TEST(_module,_level)) \ - PR_LogPrint _args ; \ - } -#endif - - -static void Error(const char* msg) -{ - printf("\t%s\n", msg); -} /* Error */ - -static void PR_CALLBACK forked(void *arg) -{ - PRIntn i; - PRLock *ml; - PRCondVar *cv; - - PR_LogPrint("%s logging creating mutex\n", (const char*)arg); - ml = PR_NewLock(); - PR_LogPrint("%s logging creating condition variable\n", (const char*)arg); - cv = PR_NewCondVar(ml); - - PR_LogPrint("%s waiting on condition timeout 10 times\n", (const char*)arg); - for (i = 0; i < 10; ++i) - { - PR_Lock(ml); - PR_WaitCondVar(cv, PR_SecondsToInterval(1)); - PR_Unlock(ml); - } - - PR_LogPrint("%s logging destroying condition variable\n", (const char*)arg); - PR_DestroyCondVar(cv); - PR_LogPrint("%s logging destroying mutex\n", (const char*)arg); - PR_DestroyLock(ml); - PR_LogPrint("%s forked thread exiting\n", (const char*)arg); -} - -static void UserLogStuff( void ) -{ - PRLogModuleInfo *myLM; - PRIntn i; - - myLM = PR_NewLogModule( "userStuff" ); - if (! myLM ) - { - printf("UserLogStuff(): can't create new log module\n" ); - return; - } - - PR_LOG( myLM, PR_LOG_NOTICE, ("Log a Notice %d\n", 1 )); - - for (i = 0; i < 10 ; i++ ) - { - PR_LOG( myLM, PR_LOG_DEBUG, ("Log Debug number: %d\n", i)); - PR_Sleep( 300 ); - } - -} /* end UserLogStuff() */ - -int main(int argc, char **argv) -{ - PRThread *thread; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (argc > 1) - { - if (!PR_SetLogFile(argv[1])) - { - Error("Access: Cannot create log file"); - goto exit; - } - } - - /* Start logging something here */ - PR_LogPrint("%s logging into %s\n", argv[0], argv[1]); - - PR_LogPrint("%s creating new thread\n", argv[0]); - - /* - ** Now change buffering. - */ - PR_SetLogBuffering( 65500 ); - thread = PR_CreateThread( - PR_USER_THREAD, forked, (void*)argv[0], PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - PR_LogPrint("%s joining thread\n", argv[0]); - - UserLogStuff(); - - PR_JoinThread(thread); - - PR_LogFlush(); - return 0; - -exit: - return -1; -} - -/* logger.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/makedir.c nspr-4.10.7/mozilla/nsprpub/pr/tests/makedir.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/makedir.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/makedir.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This test calls PR_MakeDir to create a bunch of directories - * with various mode bits. - */ - -#include "prio.h" - -#include -#include - -int main(int argc, char **argv) -{ - if (PR_MakeDir("tdir0400", 0400) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0200", 0200) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0100", 0100) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0500", 0500) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0600", 0600) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0300", 0300) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0700", 0700) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0640", 0640) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0660", 0660) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0644", 0644) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0664", 0664) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - if (PR_MakeDir("tdir0666", 0666) == PR_FAILURE) { - fprintf(stderr, "PR_MakeDir failed\n"); - exit(1); - } - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/Makefile.in nspr-4.10.7/mozilla/nsprpub/pr/tests/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/pr/tests/Makefile.in 2012-11-13 23:18:00.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,501 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -#! gmake - -MOD_DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -DIRS = dll - -CSRCS = \ - accept.c \ - acceptread.c \ - acceptreademu.c \ - addrstr.c \ - affinity.c \ - alarm.c \ - anonfm.c \ - append.c \ - atomic.c \ - attach.c \ - bigfile.c \ - bigfile2.c \ - bigfile3.c \ - cleanup.c \ - cltsrv.c \ - concur.c \ - cvar.c \ - cvar2.c \ - dceemu.c \ - dlltest.c \ - dtoa.c \ - env.c \ - errcodes.c \ - errset.c \ - exit.c \ - fdcach.c \ - fileio.c \ - foreign.c \ - forktest.c \ - formattm.c \ - fsync.c \ - getai.c \ - gethost.c \ - getproto.c \ - i2l.c \ - initclk.c \ - inrval.c \ - instrumt.c \ - intrio.c \ - intrupt.c \ - io_timeout.c \ - ioconthr.c \ - ipv6.c \ - join.c \ - joinkk.c \ - joinku.c \ - joinuk.c \ - joinuu.c \ - layer.c \ - lazyinit.c \ - libfilename.c \ - lltest.c \ - lock.c \ - lockfile.c \ - logfile.c \ - logger.c \ - makedir.c \ - mbcs.c \ - multiacc.c \ - multiwait.c \ - many_cv.c \ - nameshm1.c \ - nbconn.c \ - nblayer.c \ - nonblock.c \ - ntioto.c \ - ntoh.c \ - obsints.c \ - op_2long.c \ - op_excl.c \ - op_filnf.c \ - op_filok.c \ - op_noacc.c \ - op_nofil.c \ - openfile.c \ - parent.c \ - parsetm.c \ - peek.c \ - perf.c \ - pipeping.c \ - pipeping2.c \ - pipepong.c \ - pipepong2.c \ - pipeself.c \ - poll_er.c \ - poll_nm.c \ - poll_to.c \ - pollable.c \ - prftest.c \ - prftest1.c \ - prftest2.c \ - primblok.c \ - priotest.c \ - provider.c \ - prpoll.c \ - prpollml.c \ - pushtop.c \ - ranfile.c \ - randseed.c \ - reinit.c \ - rmdir.c \ - rwlocktest.c \ - sel_spd.c \ - selct_er.c \ - selct_nm.c \ - selct_to.c \ - select2.c \ - selintr.c \ - sem.c \ - sema.c \ - semaerr.c \ - semaerr1.c \ - semaping.c \ - semapong.c \ - sendzlf.c \ - server_test.c \ - servr_kk.c \ - servr_ku.c \ - servr_uk.c \ - servr_uu.c \ - short_thread.c \ - sigpipe.c \ - socket.c \ - sockopt.c \ - sockping.c \ - sockpong.c \ - sprintf.c \ - sproc_ch.c \ - sproc_p.c \ - stack.c \ - stdio.c \ - str2addr.c \ - strod.c \ - suspend.c \ - switch.c \ - system.c \ - testbit.c \ - testfile.c \ - thrpool_server.c \ - thrpool_client.c \ - threads.c \ - thruput.c \ - timemac.c \ - timetest.c \ - tmoacc.c \ - tmocon.c \ - tpd.c \ - vercheck.c \ - version.c \ - udpsrv.c \ - writev.c \ - xnotify.c \ - y2k.c \ - y2ktmo.c \ - zerolen.c \ - $(NULL) - -ifeq ($(OS_ARCH),WINCE) -CFLAGS += -FImozce_shunt.h -Zi -UDEBUG -DNDEBUG -LDOPTS += -link $(DIST)/lib/mozce_shunt.lib ws2.lib -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO -PDB:$(@:.exe=.pdb) -endif - -ifeq ($(OS_TARGET),OS2) -CSRCS += \ - sleep.c \ - stat.c \ - yield.c \ - $(NULL) -endif - -ifeq (,$(filter-out WINCE WINNT OS2,$(OS_ARCH))) -PROG_SUFFIX = .exe -DLL_SUFFIX = .dll -else -PROG_SUFFIX = -DLL_SUFFIX = -endif - -PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX))) - -TARGETS = $(PROGS) - -INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private - -ifeq ($(OS_ARCH), WINNT) -ifdef NS_USE_GCC - EXTRA_LIBS += -lwsock32 -else - EXTRA_LIBS += wsock32.lib - LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO - ifdef PROFILE - LDOPTS += -PROFILE -MAP - endif # profile -endif # NS_USE_GCC -endif - -ifeq ($(OS_ARCH),OS2) -EXTRA_LIBS = $(OS_LIBS) -LDOPTS = -Zomf -Zlinker /PM:VIO -Zlinker /ST:0x64000 -endif - -ifneq ($(OS_ARCH), WINNT) -# Use an absolute pathname as the runtime library path (for the -R -# or -rpath linker option or the LD_RUN_PATH environment variable). -ifeq (,$(patsubst /%,,$(DIST))) -# $(DIST) is already an absolute pathname. -ABSOLUTE_LIB_DIR = $(dist_libdir) -else -# $(DIST) is a relative pathname: prepend the current directory. -PWD = $(shell pwd) -ABSOLUTE_LIB_DIR = $(PWD)/$(dist_libdir) -endif -endif - -ifeq ($(OS_ARCH), IRIX) - ifeq ($(USE_CPLUS), 1) - CC = CC - endif - LDOPTS += -rpath $(ABSOLUTE_LIB_DIR) - ifdef NS_USE_GCC - LDOPTS += -Wl,-rdata_shared - else - LDOPTS += -rdata_shared - endif -# For 6.x machines, include this flag - ifeq ($(basename $(OS_RELEASE)),6) - ifndef NS_USE_GCC - ifeq ($(USE_N32),1) - LDOPTS += -n32 - else - LDOPTS += -32 - endif - - ifeq ($(USE_PTHREADS), 1) - ifeq ($(OS_RELEASE), 6.2) - LDOPTS += -Wl,-woff,85 - endif - endif - endif - endif -endif - -ifeq ($(OS_ARCH), OSF1) - ifeq ($(USE_CPLUS), 1) - CC = cxx - endif -# I haven't figured out how to pass -rpath to cc on OSF1 V3.2, so -# we do static linking. - ifeq (,$(filter-out V2.0 V3.2,$(OS_RELEASE))) - LIBNSPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a - LIBPLC = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).a - EXTRA_LIBS = -lc_r - else - LDOPTS += -rpath $(ABSOLUTE_LIB_DIR) - endif -endif - -ifeq ($(OS_ARCH), HP-UX) - LDOPTS += -z -Wl,+s,+b,$(ABSOLUTE_LIB_DIR) - ifeq ($(USE_64),1) - LDOPTS += +DD64 - endif - ifeq ($(USE_PTHREADS),1) - EXTRA_LIBS = $(LIBPTHREAD) - endif -endif - -# AIX -ifeq ($(OS_ARCH),AIX) - LDOPTS += -blibpath:$(ABSOLUTE_LIB_DIR):/usr/lib:/lib - ifneq ($(OS_ARCH)$(OS_RELEASE),AIX4.1) - LDOPTS += -brtl - EXTRA_LIBS = -ldl - endif -endif - -# Solaris -ifeq ($(OS_ARCH), SunOS) - ifdef NS_USE_GCC - LDOPTS += -Xlinker -R -Xlinker $(ABSOLUTE_LIB_DIR) - else - ifeq ($(USE_CPLUS), 1) - CC = CC - endif - LDOPTS += -R $(ABSOLUTE_LIB_DIR) - endif - - ifdef USE_PTHREADS - EXTRA_LIBS = -lpthread - endif -endif # SunOS - -ifeq (,$(filter-out Linux GNU GNU_%,$(OS_ARCH))) - LDOPTS += -Xlinker -rpath $(ABSOLUTE_LIB_DIR) - ifeq ($(USE_PTHREADS),1) - EXTRA_LIBS = -lpthread - endif -endif - -ifeq ($(OS_ARCH), SCOOS) -# SCO Unix needs to link against -lsocket again even though we -# already linked with these system libraries when we built libnspr.so. -EXTRA_LIBS = -lsocket -# This hardcodes in the executable programs the directory to find -# libnspr.so etc. at program startup. Equivalent to the -R or -rpath -# option for ld on other platforms. -export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR) -endif - -ifeq ($(OS_ARCH),OpenUNIX) -export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR) -ifeq ($(USE_PTHREADS),1) -LDOPTS += -pthread -endif -endif - -ifeq ($(OS_ARCH), UNIXWARE) -export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR) -endif - -ifeq ($(OS_ARCH),FreeBSD) -ifeq ($(USE_PTHREADS),1) -LDOPTS += -pthread -endif -LDOPTS += -Xlinker -R $(ABSOLUTE_LIB_DIR) -endif - -ifeq ($(OS_ARCH),OpenBSD) -ifeq ($(USE_PTHREADS),1) -LDOPTS += -pthread -endif -endif - -ifeq ($(OS_ARCH),BSD_OS) -ifneq ($(OS_RELEASE),1.1) -EXTRA_LIBS = -ldl -endif -endif - -ifeq ($(OS_ARCH),RISCOS) -EXTRA_LIBS = -ldl -endif - -ifeq ($(USE_PTHREADS),1) -LIBPTHREAD = -lpthread -ifeq ($(OS_ARCH),AIX) -LIBPTHREAD = -lpthreads -endif -ifeq (,$(filter-out FreeBSD OpenBSD BSD_OS QNX Darwin OpenUNIX,$(OS_ARCH))) -LIBPTHREAD = -endif -ifeq ($(OS_ARCH)$(basename $(OS_RELEASE)),HP-UXB.10) -LIBPTHREAD = -ldce -endif -endif - -ifeq ($(OS_TARGET),Android) -LIBPTHREAD = -XCFLAGS = $(OS_CFLAGS) -endif - -##################################################### -# -# The rules -# -##################################################### - -include $(topsrcdir)/config/rules.mk - -AIX_PRE_4_2 = 0 -ifeq ($(OS_ARCH),AIX) -ifeq ($(OS_RELEASE),4.1) -ifneq ($(USE_PTHREADS), 1) -#AIX_PRE_4_2 = 1 -endif -endif -endif - -ifeq ($(AIX_PRE_4_2),1) - -# AIX releases prior to 4.2 need a special two-step linking hack -# in order to both override the system select() and be able to -# get at the original system select(). -# -# We use a pattern rule in ns/nspr20/config/rules.mk to generate -# the .$(OBJ_SUFFIX) file from the .c source file, then do the -# two-step linking hack below. - -$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) - rm -f $@ $(AIX_TMP) - $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a - $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) - rm -f $(AIX_TMP) - -else - -# All platforms that are not AIX pre-4.2. - -$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) -ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) - link $(LDOPTS) $(EXTRA_LDOPTS) $< $(LIBPLC) $(LIBNSPR) $(EXTRA_LIBS) -out:$@ -ifdef MT - @if test -f $@.manifest; then \ - $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ - rm -f $@.manifest; \ - fi -endif -else - $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(EXTRA_LIBS) -o $@ -endif # WINNT -endif # AIX_PRE_4_2 - -export:: $(TARGETS) -clean:: - rm -f $(TARGETS) - -# The following tests call BSD socket functions, so they need to link -# with -lsocket on some platforms. -ifeq ($(OS_ARCH),SunOS) -ifeq ($(USE_IPV6),1) -$(OBJDIR)/gethost: $(OBJDIR)/gethost.o - $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) -lsocket $(EXTRA_LIBS) -o $@ -endif -$(OBJDIR)/prpoll: $(OBJDIR)/prpoll.o - $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) -lsocket $(EXTRA_LIBS) -o $@ -endif - -ifeq ($(USE_PTHREADS), 1) -$(OBJDIR)/attach: $(OBJDIR)/attach.o - $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ -$(OBJDIR)/foreign: $(OBJDIR)/foreign.o - $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ -$(OBJDIR)/provider: $(OBJDIR)/provider.o - $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ -$(OBJDIR)/socket: $(OBJDIR)/socket.o - $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ -$(OBJDIR)/testfile: $(OBJDIR)/testfile.o - $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ -endif - -# -# Run the test programs with no arguments -# -# Test output goes to the file pointed to by the environment variable -# NSPR_TEST_LOGFILE, if set, else to /dev/null -# -ECHO = echo -PROGRAMS = $(notdir $(PROGS)) -ifdef NSPR_TEST_LOGFILE -LOGFILE = $(NSPR_TEST_LOGFILE) -else -ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) -LOGFILE = nul -else -LOGFILE = /dev/null -endif -endif - -ifeq ($(OS_TARGET),Linux) -ECHO = /bin/echo -endif - -ALWAYS: - -runtests:: $(PROGS) ALWAYS - @$(ECHO) "\nNSPR Test Results - $(OBJDIR)\n" - @$(ECHO) "BEGIN\t\t\t`date`" - @$(ECHO) "NSPR_TEST_LOGFILE\t$(LOGFILE)\n" - @$(ECHO) "Test\t\t\tResult\n" - @cd $(OBJDIR); for i in $(PROGRAMS); do \ - $(ECHO) "$$i\c"; \ - ./$$i >> $(LOGFILE) 2>&1 ; \ - if [ 0 = $$? ] ; then \ - $(ECHO) "\t\t\tPassed"; \ - else \ - $(ECHO) "\t\t\tFAILED"; \ - fi; \ - done - @$(ECHO) "\nEND\t\t`date`\n" diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/many_cv.c nspr-4.10.7/mozilla/nsprpub/pr/tests/many_cv.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/many_cv.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/many_cv.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include "prprf.h" -#include "prthread.h" -#include "prcvar.h" -#include "prlock.h" -#include "prlog.h" -#include "prmem.h" - -#include "primpl.h" - -#include "plgetopt.h" - -#include - -static PRInt32 RandomNum(void) -{ - PRInt32 ran = rand() >> 16; - return ran; -} /* RandomNum */ - -static void Help(void) -{ - PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); - PR_fprintf(err, "many_cv usage: [-c n] [-l n] [-h]\n"); - PR_fprintf(err, "\t-c n Number of conditions per lock (default: 10)\n"); - PR_fprintf(err, "\t-l n Number of times to loop the test (default: 1)\n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); -} /* Help */ - -static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) -{ - PLOptStatus os; - PRIntn index, nl; - PRLock *ml = NULL; - PRCondVar **cv = NULL; - PRBool stats = PR_FALSE; - PRIntn nc, loops = 1, cvs = 10; - PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); - PLOptState *opt = PL_CreateOptState(argc, argv, "hsc:l:"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 's': /* number of CVs to association with lock */ - stats = PR_TRUE; - break; - case 'c': /* number of CVs to association with lock */ - cvs = atoi(opt->value); - break; - case 'l': /* number of times to run the tests */ - loops = atoi(opt->value); - break; - case 'h': /* user wants some guidance */ - default: - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - } - } - PL_DestroyOptState(opt); - - PR_fprintf(err, "Settings\n"); - PR_fprintf(err, "\tConditions / lock: %d\n", cvs); - PR_fprintf(err, "\tLoops to run test: %d\n", loops); - - ml = PR_NewLock(); - PR_ASSERT(NULL != ml); - - cv = (PRCondVar**)PR_CALLOC(sizeof(PRCondVar*) * cvs); - PR_ASSERT(NULL != cv); - - for (index = 0; index < cvs; ++index) - { - cv[index] = PR_NewCondVar(ml); - PR_ASSERT(NULL != cv[index]); - } - - for (index = 0; index < loops; ++index) - { - PR_Lock(ml); - for (nl = 0; nl < cvs; ++nl) - { - PRInt32 ran = RandomNum() % 8; - if (0 == ran) PR_NotifyAllCondVar(cv[nl]); - else for (nc = 0; nc < ran; ++nc) - PR_NotifyCondVar(cv[nl]); - } - PR_Unlock(ml); - } - - for (index = 0; index < cvs; ++index) - PR_DestroyCondVar(cv[index]); - - PR_DELETE(cv); - - PR_DestroyLock(ml); - - printf("PASS\n"); - - PT_FPrintStats(err, "\nPThread Statistics\n"); - return 0; -} - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/mbcs.c nspr-4.10.7/mozilla/nsprpub/pr/tests/mbcs.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/mbcs.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/mbcs.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,155 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: mbcs.c -** -** Synopsis: mbcs {dirName} -** -** where dirName is the directory to be traversed. dirName is required. -** -** Description: -** mbcs.c tests use of multi-byte characters, as would be passed to -** NSPR funtions by internationalized applications. -** -** mbcs.c, when run on any single-byte platform, should run correctly. -** In truth, running the mbcs test on a single-byte platform is -** really meaningless. mbcs.c, nor any NSPR library or test is not -** intended for use with any wide character set, including Unicode. -** mbcs.c should not be included in runtests.ksh because it requires -** extensive user intervention to set-up and run. -** -** mbcs.c should be run on a platform using some form of multi-byte -** characters. The initial platform for this test is a Japanese -** language Windows NT 4.0 machine. ... Thank you Noriko Hoshi. -** -** To run mbcs.c, the tester should create a directory tree containing -** some files in the same directory from which the test is run; i.e. -** the current working directory. The directory and files should be -** named such that when represented in the local multi-byte character -** set, one or more characters of the name is longer than a single -** byte. -** -*/ - -#include -#include -#include -#include -#include - -/* -** Test harness infrastructure -*/ -PRLogModuleInfo *lm; -PRLogModuleLevel msgLevel = PR_LOG_NONE; -PRIntn debug = 0; -PRUint32 failed_already = 0; -/* end Test harness infrastructure */ - -char *dirName = NULL; /* directory name to traverse */ - -/* -** Traverse directory -*/ -static void TraverseDirectory( unsigned char *dir ) -{ - PRDir *cwd; - PRDirEntry *dirEntry; - PRFileInfo info; - PRStatus rc; - PRInt32 err; - PRFileDesc *fd; - char nextDir[256]; - char file[256]; - - printf("Directory: %s\n", dir ); - cwd = PR_OpenDir( dir ); - if ( NULL == cwd ) { - printf("PR_OpenDir() failed on directory: %s, with error: %d, %d\n", - dir, PR_GetError(), PR_GetOSError()); - exit(1); - } - while( NULL != (dirEntry = PR_ReadDir( cwd, PR_SKIP_BOTH | PR_SKIP_HIDDEN ))) { - sprintf( file, "%s/%s", dir, dirEntry->name ); - rc = PR_GetFileInfo( file, &info ); - if ( PR_FAILURE == rc ) { - printf("PR_GetFileInfo() failed on file: %s, with error: %d, %d\n", - dirEntry->name, PR_GetError(), PR_GetOSError()); - exit(1); - } - if ( PR_FILE_FILE == info.type ) { - printf("File: %s \tsize: %ld\n", dirEntry->name, info.size ); - fd = PR_Open( file, PR_RDONLY, 0 ); - if ( NULL == fd ) { - printf("PR_Open() failed. Error: %ld, OSError: %ld\n", - PR_GetError(), PR_GetOSError()); - } - rc = PR_Close( fd ); - if ( PR_FAILURE == rc ) { - printf("PR_Close() failed. Error: %ld, OSError: %ld\n", - PR_GetError(), PR_GetOSError()); - } - } else if ( PR_FILE_DIRECTORY == info.type ) { - sprintf( nextDir, "%s/%s", dir, dirEntry->name ); - TraverseDirectory(nextDir); - } else { - printf("type is not interesting for file: %s\n", dirEntry->name ); - /* keep going */ - } - } - /* assume end-of-file, actually could be error */ - - rc = PR_CloseDir( cwd ); - if ( PR_FAILURE == rc ) { - printf("PR_CloseDir() failed on directory: %s, with error: %d, %d\n", - dir, PR_GetError(), PR_GetOSError()); - } - -} /* end TraverseDirectory() */ - -int main(int argc, char **argv) -{ - { /* get command line options */ - /* - ** Get command line options - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dv"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug */ - debug = 1; - msgLevel = PR_LOG_ERROR; - break; - case 'v': /* verbose mode */ - msgLevel = PR_LOG_DEBUG; - break; - default: - dirName = strdup(opt->value); - break; - } - } - PL_DestroyOptState(opt); - } /* end get command line options */ - - lm = PR_NewLogModule("Test"); /* Initialize logging */ - - - if ( dirName == NULL ) { - printf("you gotta specify a directory as an operand!\n"); - exit(1); - } - - TraverseDirectory( dirName ); - - if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); - return( (failed_already == PR_TRUE )? 1 : 0 ); -} /* main() */ -/* end template.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/multiacc.c nspr-4.10.7/mozilla/nsprpub/pr/tests/multiacc.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/multiacc.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/multiacc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,220 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: multiacc.c - * - * Description: - * This test creates multiple threads that accept on the - * same listening socket. - */ - -#include "nspr.h" - -#include -#include -#include - -#define NUM_SERVER_THREADS 10 - -static int num_server_threads = NUM_SERVER_THREADS; -static PRThreadScope thread_scope = PR_GLOBAL_THREAD; -static PRBool exit_flag = PR_FALSE; - -static void ServerThreadFunc(void *arg) -{ - PRFileDesc *listenSock = (PRFileDesc *) arg; - PRFileDesc *acceptSock; - PRErrorCode err; - PRStatus status; - - while (!exit_flag) { - acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (NULL == acceptSock) { - err = PR_GetError(); - if (PR_PENDING_INTERRUPT_ERROR == err) { - printf("server thread is interrupted\n"); - fflush(stdout); - continue; - } - fprintf(stderr, "PR_Accept failed: %d\n", err); - exit(1); - } - status = PR_Close(acceptSock); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } -} - -int main(int argc, char **argv) -{ - PRNetAddr serverAddr; - PRFileDesc *dummySock; - PRFileDesc *listenSock; - PRFileDesc *clientSock; - PRThread *dummyThread; - PRThread **serverThreads; - PRStatus status; - PRUint16 port; - int idx; - PRInt32 nbytes; - char buf[1024]; - - serverThreads = (PRThread **) - PR_Malloc(num_server_threads * sizeof(PRThread *)); - if (NULL == serverThreads) { - fprintf(stderr, "PR_Malloc failed\n"); - exit(1); - } - - /* - * Create a dummy listening socket and have the first - * (dummy) thread listen on it. This is to ensure that - * the first thread becomes the I/O continuation thread - * in the pthreads implementation (see ptio.c) and remains - * so throughout the test, so that we never have to - * recycle the I/O continuation thread. - */ - dummySock = PR_NewTCPSocket(); - if (NULL == dummySock) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - memset(&serverAddr, 0, sizeof(serverAddr)); - status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_InitializeNetAddr failed\n"); - exit(1); - } - status = PR_Bind(dummySock, &serverAddr); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Bind failed\n"); - exit(1); - } - status = PR_Listen(dummySock, 5); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Listen failed\n"); - exit(1); - } - - listenSock = PR_NewTCPSocket(); - if (NULL == listenSock) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - memset(&serverAddr, 0, sizeof(serverAddr)); - status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_InitializeNetAddr failed\n"); - exit(1); - } - status = PR_Bind(listenSock, &serverAddr); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Bind failed\n"); - exit(1); - } - status = PR_GetSockName(listenSock, &serverAddr); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_GetSockName failed\n"); - exit(1); - } - port = PR_ntohs(serverAddr.inet.port); - status = PR_Listen(listenSock, 5); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Listen failed\n"); - exit(1); - } - - printf("creating dummy thread\n"); - fflush(stdout); - dummyThread = PR_CreateThread(PR_USER_THREAD, - ServerThreadFunc, dummySock, PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - if (NULL == dummyThread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - printf("sleeping one second before creating server threads\n"); - fflush(stdout); - PR_Sleep(PR_SecondsToInterval(1)); - for (idx = 0; idx < num_server_threads; idx++) { - serverThreads[idx] = PR_CreateThread(PR_USER_THREAD, - ServerThreadFunc, listenSock, PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - if (NULL == serverThreads[idx]) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - } - - memset(&serverAddr, 0, sizeof(serverAddr)); - PR_InitializeNetAddr(PR_IpAddrLoopback, port, &serverAddr); - clientSock = PR_NewTCPSocket(); - if (NULL == clientSock) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - printf("sleeping one second before connecting\n"); - fflush(stdout); - PR_Sleep(PR_SecondsToInterval(1)); - status = PR_Connect(clientSock, &serverAddr, PR_INTERVAL_NO_TIMEOUT); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Connect failed\n"); - exit(1); - } - nbytes = PR_Read(clientSock, buf, sizeof(buf)); - if (nbytes != 0) { - fprintf(stderr, "expected 0 bytes but got %d bytes\n", nbytes); - exit(1); - } - status = PR_Close(clientSock); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - printf("sleeping one second before shutting down server threads\n"); - fflush(stdout); - PR_Sleep(PR_SecondsToInterval(1)); - - exit_flag = PR_TRUE; - status = PR_Interrupt(dummyThread); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Interrupt failed\n"); - exit(1); - } - status = PR_JoinThread(dummyThread); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - for (idx = 0; idx < num_server_threads; idx++) { - status = PR_Interrupt(serverThreads[idx]); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Interrupt failed\n"); - exit(1); - } - status = PR_JoinThread(serverThreads[idx]); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - } - PR_Free(serverThreads); - status = PR_Close(dummySock); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(listenSock); - if (PR_FAILURE == status) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/multiwait.c nspr-4.10.7/mozilla/nsprpub/pr/tests/multiwait.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/multiwait.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/multiwait.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,693 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prprf.h" -#include "prlog.h" -#include "prmem.h" -#include "pratom.h" -#include "prlock.h" -#include "prmwait.h" -#include "prclist.h" -#include "prerror.h" -#include "prinrval.h" -#include "prnetdb.h" -#include "prthread.h" - -#include "plstr.h" -#include "plerror.h" -#include "plgetopt.h" - -#include - -typedef struct Shared -{ - const char *title; - PRLock *list_lock; - PRWaitGroup *group; - PRIntervalTime timeout; -} Shared; - -typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity; - -static PRFileDesc *debug = NULL; -static PRInt32 desc_allocated = 0; -static PRUint16 default_port = 12273; -static enum Verbosity verbosity = quiet; -static PRInt32 ops_required = 1000, ops_done = 0; -static PRThreadScope thread_scope = PR_LOCAL_THREAD; -static PRIntn client_threads = 20, worker_threads = 2, wait_objects = 50; - -#if defined(DEBUG) -#define MW_ASSERT(_expr) \ - ((_expr)?((void)0):_MW_Assert(# _expr,__FILE__,__LINE__)) -static void _MW_Assert(const char *s, const char *file, PRIntn ln) -{ - if (NULL != debug) PL_FPrintError(debug, NULL); - PR_Assert(s, file, ln); -} /* _MW_Assert */ -#else -#define MW_ASSERT(_expr) -#endif - -static void PrintRecvDesc(PRRecvWait *desc, const char *msg) -{ - const char *tag[] = { - "PR_MW_INTERRUPT", "PR_MW_TIMEOUT", - "PR_MW_FAILURE", "PR_MW_SUCCESS", "PR_MW_PENDING"}; - PR_fprintf( - debug, "%s: PRRecvWait(@0x%x): {fd: 0x%x, outcome: %s, tmo: %u}\n", - msg, desc, desc->fd, tag[desc->outcome + 3], desc->timeout); -} /* PrintRecvDesc */ - -static Shared *MakeShared(const char *title) -{ - Shared *shared = PR_NEWZAP(Shared); - shared->group = PR_CreateWaitGroup(1); - shared->timeout = PR_SecondsToInterval(1); - shared->list_lock = PR_NewLock(); - shared->title = title; - return shared; -} /* MakeShared */ - -static void DestroyShared(Shared *shared) -{ - PRStatus rv; - if (verbosity > quiet) - PR_fprintf(debug, "%s: destroying group\n", shared->title); - rv = PR_DestroyWaitGroup(shared->group); - MW_ASSERT(PR_SUCCESS == rv); - PR_DestroyLock(shared->list_lock); - PR_DELETE(shared); -} /* DestroyShared */ - -static PRRecvWait *CreateRecvWait(PRFileDesc *fd, PRIntervalTime timeout) -{ - PRRecvWait *desc_out = PR_NEWZAP(PRRecvWait); - MW_ASSERT(NULL != desc_out); - - MW_ASSERT(NULL != fd); - desc_out->fd = fd; - desc_out->timeout = timeout; - desc_out->buffer.length = 120; - desc_out->buffer.start = PR_CALLOC(120); - - PR_AtomicIncrement(&desc_allocated); - - if (verbosity > chatty) - PrintRecvDesc(desc_out, "Allocated"); - return desc_out; -} /* CreateRecvWait */ - -static void DestroyRecvWait(PRRecvWait *desc_out) -{ - if (verbosity > chatty) - PrintRecvDesc(desc_out, "Destroying"); - PR_Close(desc_out->fd); - if (NULL != desc_out->buffer.start) - PR_DELETE(desc_out->buffer.start); - PR_Free(desc_out); - (void)PR_AtomicDecrement(&desc_allocated); -} /* DestroyRecvWait */ - -static void CancelGroup(Shared *shared) -{ - PRRecvWait *desc_out; - - if (verbosity > quiet) - PR_fprintf(debug, "%s Reclaiming wait descriptors\n", shared->title); - - do - { - desc_out = PR_CancelWaitGroup(shared->group); - if (NULL != desc_out) DestroyRecvWait(desc_out); - } while (NULL != desc_out); - - MW_ASSERT(0 == desc_allocated); - MW_ASSERT(PR_GROUP_EMPTY_ERROR == PR_GetError()); -} /* CancelGroup */ - -static void PR_CALLBACK ClientThread(void* arg) -{ - PRStatus rv; - PRInt32 bytes; - PRIntn empty_flags = 0; - PRNetAddr server_address; - unsigned char buffer[100]; - Shared *shared = (Shared*)arg; - PRFileDesc *server = PR_NewTCPSocket(); - if ((NULL == server) - && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) return; - MW_ASSERT(NULL != server); - - if (verbosity > chatty) - PR_fprintf(debug, "%s: Server socket @0x%x\n", shared->title, server); - - /* Initialize the buffer so that Purify won't complain */ - memset(buffer, 0, sizeof(buffer)); - - rv = PR_InitializeNetAddr(PR_IpAddrLoopback, default_port, &server_address); - MW_ASSERT(PR_SUCCESS == rv); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: Client opening connection\n", shared->title); - rv = PR_Connect(server, &server_address, PR_INTERVAL_NO_TIMEOUT); - - if (PR_FAILURE == rv) - { - if (verbosity > silent) PL_FPrintError(debug, "Client connect failed"); - return; - } - - while (ops_done < ops_required) - { - bytes = PR_Send( - server, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); - if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break; - MW_ASSERT(sizeof(buffer) == bytes); - if (verbosity > chatty) - PR_fprintf( - debug, "%s: Client sent %d bytes\n", - shared->title, sizeof(buffer)); - bytes = PR_Recv( - server, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); - if (verbosity > chatty) - PR_fprintf( - debug, "%s: Client received %d bytes\n", - shared->title, sizeof(buffer)); - if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break; - MW_ASSERT(sizeof(buffer) == bytes); - PR_Sleep(shared->timeout); - } - rv = PR_Close(server); - MW_ASSERT(PR_SUCCESS == rv); - -} /* ClientThread */ - -static void OneInThenCancelled(Shared *shared) -{ - PRStatus rv; - PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait); - - shared->timeout = PR_INTERVAL_NO_TIMEOUT; - - desc_in->fd = PR_NewTCPSocket(); - desc_in->timeout = shared->timeout; - - if (verbosity > chatty) PrintRecvDesc(desc_in, "Adding desc"); - - rv = PR_AddWaitFileDesc(shared->group, desc_in); - MW_ASSERT(PR_SUCCESS == rv); - - if (verbosity > chatty) PrintRecvDesc(desc_in, "Cancelling"); - rv = PR_CancelWaitFileDesc(shared->group, desc_in); - MW_ASSERT(PR_SUCCESS == rv); - - desc_out = PR_WaitRecvReady(shared->group); - MW_ASSERT(desc_out == desc_in); - MW_ASSERT(PR_MW_INTERRUPT == desc_out->outcome); - MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); - if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready"); - - rv = PR_Close(desc_in->fd); - MW_ASSERT(PR_SUCCESS == rv); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: destroying group\n", shared->title); - - PR_DELETE(desc_in); -} /* OneInThenCancelled */ - -static void OneOpOneThread(Shared *shared) -{ - PRStatus rv; - PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait); - - desc_in->fd = PR_NewTCPSocket(); - desc_in->timeout = shared->timeout; - - if (verbosity > chatty) PrintRecvDesc(desc_in, "Adding desc"); - - rv = PR_AddWaitFileDesc(shared->group, desc_in); - MW_ASSERT(PR_SUCCESS == rv); - desc_out = PR_WaitRecvReady(shared->group); - MW_ASSERT(desc_out == desc_in); - MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome); - MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError()); - if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready"); - - rv = PR_Close(desc_in->fd); - MW_ASSERT(PR_SUCCESS == rv); - - PR_DELETE(desc_in); -} /* OneOpOneThread */ - -static void ManyOpOneThread(Shared *shared) -{ - PRStatus rv; - PRIntn index; - PRRecvWait *desc_in; - PRRecvWait *desc_out; - - if (verbosity > quiet) - PR_fprintf(debug, "%s: adding %d descs\n", shared->title, wait_objects); - - for (index = 0; index < wait_objects; ++index) - { - desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout); - - rv = PR_AddWaitFileDesc(shared->group, desc_in); - MW_ASSERT(PR_SUCCESS == rv); - } - - while (ops_done < ops_required) - { - desc_out = PR_WaitRecvReady(shared->group); - MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome); - MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError()); - if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready/readding"); - rv = PR_AddWaitFileDesc(shared->group, desc_out); - MW_ASSERT(PR_SUCCESS == rv); - (void)PR_AtomicIncrement(&ops_done); - } - - CancelGroup(shared); -} /* ManyOpOneThread */ - -static void PR_CALLBACK SomeOpsThread(void *arg) -{ - PRRecvWait *desc_out; - PRStatus rv = PR_SUCCESS; - Shared *shared = (Shared*)arg; - do /* until interrupted */ - { - desc_out = PR_WaitRecvReady(shared->group); - if (NULL == desc_out) - { - MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); - if (verbosity > quiet) PR_fprintf(debug, "Aborted\n"); - break; - } - MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome); - MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError()); - if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready"); - - if (verbosity > chatty) PrintRecvDesc(desc_out, "Re-Adding"); - desc_out->timeout = shared->timeout; - rv = PR_AddWaitFileDesc(shared->group, desc_out); - PR_AtomicIncrement(&ops_done); - if (ops_done > ops_required) break; - } while (PR_SUCCESS == rv); - MW_ASSERT(PR_SUCCESS == rv); -} /* SomeOpsThread */ - -static void SomeOpsSomeThreads(Shared *shared) -{ - PRStatus rv; - PRThread **thread; - PRIntn index; - PRRecvWait *desc_in; - - thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads); - - /* Create some threads */ - - if (verbosity > quiet) - PR_fprintf(debug, "%s: creating threads\n", shared->title); - for (index = 0; index < worker_threads; ++index) - { - thread[index] = PR_CreateThread( - PR_USER_THREAD, SomeOpsThread, shared, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - } - - /* then create some operations */ - if (verbosity > quiet) - PR_fprintf(debug, "%s: creating desc\n", shared->title); - for (index = 0; index < wait_objects; ++index) - { - desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout); - rv = PR_AddWaitFileDesc(shared->group, desc_in); - MW_ASSERT(PR_SUCCESS == rv); - } - - if (verbosity > quiet) - PR_fprintf(debug, "%s: sleeping\n", shared->title); - while (ops_done < ops_required) PR_Sleep(shared->timeout); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: interrupting/joining threads\n", shared->title); - for (index = 0; index < worker_threads; ++index) - { - rv = PR_Interrupt(thread[index]); - MW_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(thread[index]); - MW_ASSERT(PR_SUCCESS == rv); - } - PR_DELETE(thread); - - CancelGroup(shared); -} /* SomeOpsSomeThreads */ - -static PRStatus ServiceRequest(Shared *shared, PRRecvWait *desc) -{ - PRInt32 bytes_out; - - if (verbosity > chatty) - PR_fprintf( - debug, "%s: Service received %d bytes\n", - shared->title, desc->bytesRecv); - - if (0 == desc->bytesRecv) goto quitting; - if ((-1 == desc->bytesRecv) - && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) goto aborted; - - bytes_out = PR_Send( - desc->fd, desc->buffer.start, desc->bytesRecv, 0, shared->timeout); - if (verbosity > chatty) - PR_fprintf( - debug, "%s: Service sent %d bytes\n", - shared->title, bytes_out); - - if ((-1 == bytes_out) - && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) goto aborted; - MW_ASSERT(bytes_out == desc->bytesRecv); - - return PR_SUCCESS; - -aborted: -quitting: - return PR_FAILURE; -} /* ServiceRequest */ - -static void PR_CALLBACK ServiceThread(void *arg) -{ - PRStatus rv = PR_SUCCESS; - PRRecvWait *desc_out = NULL; - Shared *shared = (Shared*)arg; - do /* until interrupted */ - { - if (NULL != desc_out) - { - desc_out->timeout = PR_INTERVAL_NO_TIMEOUT; - if (verbosity > chatty) - PrintRecvDesc(desc_out, "Service re-adding"); - rv = PR_AddWaitFileDesc(shared->group, desc_out); - MW_ASSERT(PR_SUCCESS == rv); - } - - desc_out = PR_WaitRecvReady(shared->group); - if (NULL == desc_out) - { - MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); - break; - } - - switch (desc_out->outcome) - { - case PR_MW_SUCCESS: - { - PR_AtomicIncrement(&ops_done); - if (verbosity > chatty) - PrintRecvDesc(desc_out, "Service ready"); - rv = ServiceRequest(shared, desc_out); - break; - } - case PR_MW_INTERRUPT: - MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); - rv = PR_FAILURE; /* if interrupted, then exit */ - break; - case PR_MW_TIMEOUT: - MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError()); - case PR_MW_FAILURE: - if (verbosity > silent) - PL_FPrintError(debug, "RecvReady failure"); - break; - default: - break; - } - } while (PR_SUCCESS == rv); - - if (NULL != desc_out) DestroyRecvWait(desc_out); - -} /* ServiceThread */ - -static void PR_CALLBACK EnumerationThread(void *arg) -{ - PRStatus rv; - PRIntn count; - PRRecvWait *desc; - Shared *shared = (Shared*)arg; - PRIntervalTime five_seconds = PR_SecondsToInterval(5); - PRMWaitEnumerator *enumerator = PR_CreateMWaitEnumerator(shared->group); - MW_ASSERT(NULL != enumerator); - - while (PR_SUCCESS == PR_Sleep(five_seconds)) - { - count = 0; - desc = NULL; - while (NULL != (desc = PR_EnumerateWaitGroup(enumerator, desc))) - { - if (verbosity > chatty) PrintRecvDesc(desc, shared->title); - count += 1; - } - if (verbosity > silent) - PR_fprintf(debug, - "%s Enumerated %d objects\n", shared->title, count); - } - - MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); - - - rv = PR_DestroyMWaitEnumerator(enumerator); - MW_ASSERT(PR_SUCCESS == rv); -} /* EnumerationThread */ - -static void PR_CALLBACK ServerThread(void *arg) -{ - PRStatus rv; - PRIntn index; - PRRecvWait *desc_in; - PRThread **worker_thread; - Shared *shared = (Shared*)arg; - PRFileDesc *listener, *service; - PRNetAddr server_address, client_address; - - worker_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads); - if (verbosity > quiet) - PR_fprintf(debug, "%s: Server creating worker_threads\n", shared->title); - for (index = 0; index < worker_threads; ++index) - { - worker_thread[index] = PR_CreateThread( - PR_USER_THREAD, ServiceThread, shared, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - } - - rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &server_address); - MW_ASSERT(PR_SUCCESS == rv); - - listener = PR_NewTCPSocket(); MW_ASSERT(NULL != listener); - if (verbosity > chatty) - PR_fprintf( - debug, "%s: Server listener socket @0x%x\n", - shared->title, listener); - rv = PR_Bind(listener, &server_address); MW_ASSERT(PR_SUCCESS == rv); - rv = PR_Listen(listener, 10); MW_ASSERT(PR_SUCCESS == rv); - while (ops_done < ops_required) - { - if (verbosity > quiet) - PR_fprintf(debug, "%s: Server accepting connection\n", shared->title); - service = PR_Accept(listener, &client_address, PR_INTERVAL_NO_TIMEOUT); - if (NULL == service) - { - if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) break; - PL_PrintError("Accept failed"); - MW_ASSERT(!"Accept failed"); - } - else - { - desc_in = CreateRecvWait(service, shared->timeout); - desc_in->timeout = PR_INTERVAL_NO_TIMEOUT; - if (verbosity > chatty) - PrintRecvDesc(desc_in, "Service adding"); - rv = PR_AddWaitFileDesc(shared->group, desc_in); - MW_ASSERT(PR_SUCCESS == rv); - } - } - - if (verbosity > quiet) - PR_fprintf(debug, "%s: Server interrupting worker_threads\n", shared->title); - for (index = 0; index < worker_threads; ++index) - { - rv = PR_Interrupt(worker_thread[index]); - MW_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(worker_thread[index]); - MW_ASSERT(PR_SUCCESS == rv); - } - PR_DELETE(worker_thread); - - PR_Close(listener); - - CancelGroup(shared); - -} /* ServerThread */ - -static void RealOneGroupIO(Shared *shared) -{ - /* - ** Create a server that listens for connections and then services - ** requests that come in over those connections. The server never - ** deletes a connection and assumes a basic RPC model of operation. - ** - ** Use worker_threads threads to service how every many open ports - ** there might be. - ** - ** Oh, ya. Almost forget. Create (some) clients as well. - */ - PRStatus rv; - PRIntn index; - PRThread *server_thread, *enumeration_thread, **client_thread; - - if (verbosity > quiet) - PR_fprintf(debug, "%s: creating server_thread\n", shared->title); - - server_thread = PR_CreateThread( - PR_USER_THREAD, ServerThread, shared, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: creating enumeration_thread\n", shared->title); - - enumeration_thread = PR_CreateThread( - PR_USER_THREAD, EnumerationThread, shared, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: snoozing before creating clients\n", shared->title); - PR_Sleep(5 * shared->timeout); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: creating client_threads\n", shared->title); - client_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * client_threads); - for (index = 0; index < client_threads; ++index) - { - client_thread[index] = PR_CreateThread( - PR_USER_THREAD, ClientThread, shared, - PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - } - - while (ops_done < ops_required) PR_Sleep(shared->timeout); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: interrupting/joining client_threads\n", shared->title); - for (index = 0; index < client_threads; ++index) - { - rv = PR_Interrupt(client_thread[index]); - MW_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(client_thread[index]); - MW_ASSERT(PR_SUCCESS == rv); - } - PR_DELETE(client_thread); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: interrupting/joining enumeration_thread\n", shared->title); - rv = PR_Interrupt(enumeration_thread); - MW_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(enumeration_thread); - MW_ASSERT(PR_SUCCESS == rv); - - if (verbosity > quiet) - PR_fprintf(debug, "%s: interrupting/joining server_thread\n", shared->title); - rv = PR_Interrupt(server_thread); - MW_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(server_thread); - MW_ASSERT(PR_SUCCESS == rv); -} /* RealOneGroupIO */ - -static void RunThisOne( - void (*func)(Shared*), const char *name, const char *test_name) -{ - Shared *shared; - if ((NULL == test_name) || (0 == PL_strcmp(name, test_name))) - { - if (verbosity > silent) - PR_fprintf(debug, "%s()\n", name); - shared = MakeShared(name); - ops_done = 0; - func(shared); /* run the test */ - MW_ASSERT(0 == desc_allocated); - DestroyShared(shared); - } -} /* RunThisOne */ - -static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta) -{ - PRIntn verbage = (PRIntn)verbosity; - return (Verbosity)(verbage += delta); -} /* ChangeVerbosity */ - -int main(int argc, char **argv) -{ - PLOptStatus os; - const char *test_name = NULL; - PLOptState *opt = PL_CreateOptState(argc, argv, "dqGc:o:p:t:w:"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: - test_name = opt->value; - break; - case 'd': /* debug mode */ - if (verbosity < noisy) - verbosity = ChangeVerbosity(verbosity, 1); - break; - case 'q': /* debug mode */ - if (verbosity > silent) - verbosity = ChangeVerbosity(verbosity, -1); - break; - case 'G': /* use global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'c': /* number of client threads */ - client_threads = atoi(opt->value); - break; - case 'o': /* operations to compelete */ - ops_required = atoi(opt->value); - break; - case 'p': /* default port */ - default_port = atoi(opt->value); - break; - case 't': /* number of threads waiting */ - worker_threads = atoi(opt->value); - break; - case 'w': /* number of wait objects */ - wait_objects = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (verbosity > 0) - debug = PR_GetSpecialFD(PR_StandardError); - - RunThisOne(OneInThenCancelled, "OneInThenCancelled", test_name); - RunThisOne(OneOpOneThread, "OneOpOneThread", test_name); - RunThisOne(ManyOpOneThread, "ManyOpOneThread", test_name); - RunThisOne(SomeOpsSomeThreads, "SomeOpsSomeThreads", test_name); - RunThisOne(RealOneGroupIO, "RealOneGroupIO", test_name); - return 0; -} /* main */ - -/* multwait.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/nameshm1.c nspr-4.10.7/mozilla/nsprpub/pr/tests/nameshm1.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/nameshm1.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/nameshm1.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,576 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: nameshm1.c -- Test Named Shared Memory -** -** Description: -** nameshm1 tests Named Shared Memory. nameshm1 performs two tests of -** named shared memory. -** -** The first test is a basic test. The basic test operates as a single -** process. The process exercises all the API elements of the facility. -** This test also attempts to write to all locations in the shared -** memory. -** -** The second test is a client-server test. The client-server test -** creates a new instance of nameshm1, passing the -C argument to the -** new process; this creates the client-side process. The server-side -** (the instance of nameshm1 created from the command line) and the -** client-side interact via inter-process semaphores to verify that the -** shared memory segment can be read and written by both sides in a -** synchronized maner. -** -** Note: Because this test runs in two processes, the log files created -** by the test are not in chronological sequence; makes it hard to read. -** As a temporary circumvention, I changed the definition(s) of the -** _PUT_LOG() macro in prlog.c to force a flushall(), or equivalent. -** This causes the log entries to be emitted in true chronological -** order. -** -** Synopsis: nameshm1 [options] [name] -** -** Options: -** -d Enables debug trace via PR_LOG() -** -v Enables verbose mode debug trace via PR_LOG() -** -w Causes the basic test to attempt to write to the segment -** mapped as read-only. When this option is specified, the -** test should crash with a seg-fault; this is a destructive -** test and is considered successful when it seg-faults. -** -** -C Causes nameshm1 to start as the client-side of a -** client-server pair of processes. Only the instance -** of nameshm1 operating as the server-side process should -** specify the -C option when creating the client-side process; -** the -C option should not be specified at the command line. -** The client-side uses the shared memory segment created by -** the server-side to communicate with the server-side -** process. -** -** -p Specify the number of iterations the client-server tests -** should perform. Default: 1000. -** -** -s Size, in KBytes (1024), of the shared memory segment. -** Default: (10 * 1024) -** -** -i Number of client-side iterations. Default: 3 -** -** name specifies the name of the shared memory segment to be used. -** Default: /tmp/xxxNSPRshm -** -** -** See also: prshm.h -** -** /lth. Aug-1999. -*/ - -#include -#include -#include -#include -#include - -#ifdef SYMBIAN -#define SEM_NAME1 "c:\\data\\nameshmSEM1" -#define SEM_NAME2 "c:\\data\\nameshmSEM2" -#define OPT_NAME "c:\\data\\xxxNSPRshm" -#define EXE_NAME "nspr_tests_nameshm1.exe" -#else -#define SEM_NAME1 "/tmp/nameshmSEM1" -#define SEM_NAME2 "/tmp/nameshmSEM2" -#define OPT_NAME "/tmp/xxxNSPRshm" -#define EXE_NAME "nameshm1" -#endif -#define SEM_MODE 0666 -#define SHM_MODE 0666 - -#define NameSize (1024) - -PRIntn debug = 0; -PRIntn failed_already = 0; -PRLogModuleLevel msgLevel = PR_LOG_NONE; -PRLogModuleInfo *lm; - -/* command line options */ -PRIntn optDebug = 0; -PRIntn optVerbose = 0; -PRUint32 optWriteRO = 0; /* test write to read-only memory. should crash */ -PRUint32 optClient = 0; -PRUint32 optCreate = 1; -PRUint32 optAttachRW = 1; -PRUint32 optAttachRO = 1; -PRUint32 optClose = 1; -PRUint32 optDelete = 1; -PRInt32 optPing = 1000; -PRUint32 optSize = (10 * 1024 ); -PRInt32 optClientIterations = 3; -char optName[NameSize] = OPT_NAME; - -char buf[1024] = ""; - - -static void BasicTest( void ) -{ - PRSharedMemory *shm; - char *addr; /* address of shared memory segment */ - PRUint32 i; - PRInt32 rc; - - PR_LOG( lm, msgLevel, - ( "nameshm1: Begin BasicTest" )); - - if ( PR_FAILURE == PR_DeleteSharedMemory( optName )) { - PR_LOG( lm, msgLevel, - ("nameshm1: Initial PR_DeleteSharedMemory() failed. No problem")); - } else - PR_LOG( lm, msgLevel, - ("nameshm1: Initial PR_DeleteSharedMemory() success")); - - - shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE ); - if ( NULL == shm ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Create: success: %p", shm )); - - addr = PR_AttachSharedMemory( shm , 0 ); - if ( NULL == addr ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Attach: success: %p", addr )); - - /* fill memory with i */ - for ( i = 0; i < optSize ; i++ ) - { - *(addr + i) = i; - } - - rc = PR_DetachSharedMemory( shm, addr ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Detach: success: " )); - - rc = PR_CloseSharedMemory( shm ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Close: success: " )); - - rc = PR_DeleteSharedMemory( optName ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Delete: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RW Delete: success: " )); - - PR_LOG( lm, msgLevel, - ("nameshm1: BasicTest(): Passed")); - - return; -} /* end BasicTest() */ - -static void ReadOnlyTest( void ) -{ - PRSharedMemory *shm; - char *roAddr; /* read-only address of shared memory segment */ - PRInt32 rc; - - PR_LOG( lm, msgLevel, - ( "nameshm1: Begin ReadOnlyTest" )); - - shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE); - if ( NULL == shm ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Create: success: %p", shm )); - - - roAddr = PR_AttachSharedMemory( shm , PR_SHM_READONLY ); - if ( NULL == roAddr ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Attach: success: %p", roAddr )); - - if ( optWriteRO ) - { - *roAddr = 0x00; /* write to read-only memory */ - failed_already = 1; - PR_LOG( lm, msgLevel, ("nameshm1: Wrote to read-only memory segment!")); - return; - } - - rc = PR_DetachSharedMemory( shm, roAddr ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Detach: success: " )); - - rc = PR_CloseSharedMemory( shm ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Close: success: " )); - - rc = PR_DeleteSharedMemory( optName ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Destroy: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: RO Destroy: success: " )); - - PR_LOG( lm, msgLevel, - ("nameshm1: ReadOnlyTest(): Passed")); - - return; -} /* end ReadOnlyTest() */ - -static void DoClient( void ) -{ - PRStatus rc; - PRSem *sem1, *sem2; - PRSharedMemory *shm; - PRUint32 *addr; - PRInt32 i; - - PR_LOG( lm, msgLevel, - ("nameshm1: DoClient(): Starting")); - - sem1 = PR_OpenSemaphore( SEM_NAME1, 0, 0, 0 ); - PR_ASSERT( sem1 ); - - sem2 = PR_OpenSemaphore( SEM_NAME2, 0, 0, 0 ); - PR_ASSERT( sem1 ); - - shm = PR_OpenSharedMemory( optName, optSize, 0, SHM_MODE ); - if ( NULL == shm ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: DoClient(): Create: Error: %ld. OSError: %ld", - PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: DoClient(): Create: success: %p", shm )); - - addr = PR_AttachSharedMemory( shm , 0 ); - if ( NULL == addr ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: DoClient(): Attach: Error: %ld. OSError: %ld", - PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: DoClient(): Attach: success: %p", addr )); - - PR_LOG( lm, msgLevel, - ( "Client found: %s", addr)); - - PR_Sleep(PR_SecondsToInterval(4)); - for ( i = 0 ; i < optPing ; i++ ) - { - rc = PR_WaitSemaphore( sem2 ); - PR_ASSERT( PR_FAILURE != rc ); - - (*addr)++; - PR_ASSERT( (*addr % 2) == 0 ); - if ( optVerbose ) - PR_LOG( lm, msgLevel, - ( "nameshm1: Client ping: %d, i: %d", *addr, i)); - - rc = PR_PostSemaphore( sem1 ); - PR_ASSERT( PR_FAILURE != rc ); - } - - rc = PR_CloseSemaphore( sem1 ); - PR_ASSERT( PR_FAILURE != rc ); - - rc = PR_CloseSemaphore( sem2 ); - PR_ASSERT( PR_FAILURE != rc ); - - rc = PR_DetachSharedMemory( shm, addr ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: DoClient(): Detach: Error: %ld. OSError: %ld", - PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: DoClient(): Detach: success: " )); - - rc = PR_CloseSharedMemory( shm ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: DoClient(): Close: Error: %ld. OSError: %ld", - PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: DoClient(): Close: success: " )); - - return; -} /* end DoClient() */ - -static void ClientServerTest( void ) -{ - PRStatus rc; - PRSem *sem1, *sem2; - PRProcess *proc; - PRInt32 exit_status; - PRSharedMemory *shm; - PRUint32 *addr; - PRInt32 i; - char *child_argv[8]; - char buf[24]; - - PR_LOG( lm, msgLevel, - ( "nameshm1: Begin ClientServerTest" )); - - rc = PR_DeleteSharedMemory( optName ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Destroy: failed. No problem")); - } else - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Destroy: success" )); - - - shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE); - if ( NULL == shm ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Create: success: %p", shm )); - - addr = PR_AttachSharedMemory( shm , 0 ); - if ( NULL == addr ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Attach: success: %p", addr )); - - sem1 = PR_OpenSemaphore( SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0 ); - PR_ASSERT( sem1 ); - - sem2 = PR_OpenSemaphore( SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 1 ); - PR_ASSERT( sem1 ); - - strcpy( (char*)addr, "FooBar" ); - - child_argv[0] = EXE_NAME; - child_argv[1] = "-C"; - child_argv[2] = "-p"; - sprintf( buf, "%d", optPing ); - child_argv[3] = buf; - child_argv[4] = optName; - child_argv[5] = NULL; - - proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); - PR_ASSERT( proc ); - - PR_Sleep( PR_SecondsToInterval(4)); - - *addr = 1; - for ( i = 0 ; i < optPing ; i++ ) - { - rc = PR_WaitSemaphore( sem1 ); - PR_ASSERT( PR_FAILURE != rc ); - - (*addr)++; - PR_ASSERT( (*addr % 2) == 1 ); - if ( optVerbose ) - PR_LOG( lm, msgLevel, - ( "nameshm1: Server pong: %d, i: %d", *addr, i)); - - - rc = PR_PostSemaphore( sem2 ); - PR_ASSERT( PR_FAILURE != rc ); - } - - rc = PR_WaitProcess( proc, &exit_status ); - PR_ASSERT( PR_FAILURE != rc ); - - rc = PR_CloseSemaphore( sem1 ); - PR_ASSERT( PR_FAILURE != rc ); - - rc = PR_CloseSemaphore( sem2 ); - PR_ASSERT( PR_FAILURE != rc ); - - rc = PR_DeleteSemaphore( SEM_NAME1 ); - PR_ASSERT( PR_FAILURE != rc ); - - rc = PR_DeleteSemaphore( SEM_NAME2 ); - PR_ASSERT( PR_FAILURE != rc ); - - rc = PR_DetachSharedMemory( shm, addr ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Detach: Error: %ld. OSError: %ld", - PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Detach: success: " )); - - rc = PR_CloseSharedMemory( shm ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Close: Error: %ld. OSError: %ld", - PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Close: success: " )); - - rc = PR_DeleteSharedMemory( optName ); - if ( PR_FAILURE == rc ) - { - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Destroy: Error: %ld. OSError: %ld", - PR_GetError(), PR_GetOSError())); - failed_already = 1; - return; - } - PR_LOG( lm, msgLevel, - ( "nameshm1: Server: Destroy: success" )); - - return; -} /* end ClientServerTest() */ - -int main(int argc, char **argv) -{ - { - /* - ** Get command line options - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "Cdvw:s:p:i:"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'v': /* debug mode */ - optVerbose = 1; - /* no break! fall into debug option */ - case 'd': /* debug mode */ - debug = 1; - msgLevel = PR_LOG_DEBUG; - break; - case 'w': /* try writing to memory mapped read-only */ - optWriteRO = 1; - break; - case 'C': - optClient = 1; - break; - case 's': - optSize = atol(opt->value) * 1024; - break; - case 'p': - optPing = atol(opt->value); - break; - case 'i': - optClientIterations = atol(opt->value); - break; - default: - strcpy( optName, opt->value ); - break; - } - } - PL_DestroyOptState(opt); - } - - lm = PR_NewLogModule("Test"); /* Initialize logging */ - - PR_LOG( lm, msgLevel, - ( "nameshm1: Starting" )); - - if ( optClient ) - { - DoClient(); - } else { - BasicTest(); - if ( failed_already != 0 ) - goto Finished; - ReadOnlyTest(); - if ( failed_already != 0 ) - goto Finished; - ClientServerTest(); - } - -Finished: - if ( debug ) printf("%s\n", (failed_already)? "FAIL" : "PASS" ); - return( (failed_already)? 1 : 0 ); -} /* main() */ -/* end instrumt.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/nbconn.c nspr-4.10.7/mozilla/nsprpub/pr/tests/nbconn.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/nbconn.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/nbconn.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,520 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * A test for nonblocking connect. Functions tested include PR_Connect, - * PR_Poll, and PR_GetConnectStatus. - * - * The test should be invoked with a host name, for example: - * nbconn www.netscape.com - * It will do a nonblocking connect to port 80 (HTTP) on that host, - * and when connected, issue the "GET /" HTTP command. - * - * You should run this test in three ways: - * 1. To a known web site, such as www.netscape.com. The HTML of the - * top-level page at the web site should be printed. - * 2. To a machine not running a web server at port 80. This test should - * fail. Ideally the error code should be PR_CONNECT_REFUSED_ERROR. - * But it is possible to return PR_UNKNOWN_ERROR on certain platforms. - * 3. To an unreachable machine, for example, a machine that is off line. - * The test should fail after the connect times out. Ideally the - * error code should be PR_IO_TIMEOUT_ERROR, but it is possible to - * return PR_UNKNOWN_ERROR on certain platforms. - */ - -#include "nspr.h" -#include "plgetopt.h" -#include -#include - -#define SERVER_MAX_BIND_COUNT 100 -#define DATA_BUF_SIZE 256 -#define TCP_SERVER_PORT 10000 -#define TCP_UNUSED_PORT 211 - -typedef struct Server_Param { - PRFileDesc *sp_fd; /* server port */ -} Server_Param; -static void PR_CALLBACK TCP_Server(void *arg); - -int _debug_on; -#define DPRINTF(arg) if (_debug_on) printf arg - -static PRIntn connection_success_test(); -static PRIntn connection_failure_test(); - -int main(int argc, char **argv) -{ - PRHostEnt he; - char buf[1024]; - PRNetAddr addr; - PRPollDesc pd; - PRStatus rv; - PRSocketOptionData optData; - const char *hostname = NULL; - PRIntn default_case, n, bytes_read, bytes_sent; - PRInt32 failed_already = 0; - - /* - * -d debug mode - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: /* debug mode */ - hostname = opt->value; - break; - case 'd': /* debug mode */ - _debug_on = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_STDIO_INIT(); - if (hostname) - default_case = 0; - else - default_case = 1; - - if (default_case) { - - /* - * In the default case the following tests are executed: - * 1. successful connection: a server thread accepts a connection - * from the main thread - * 2. unsuccessful connection: the main thread tries to connect to a - * nonexistent port and expects to get an error - */ - rv = connection_success_test(); - if (rv == 0) - rv = connection_failure_test(); - return rv; - } else { - PRFileDesc *sock; - - if (PR_GetHostByName(argv[1], buf, sizeof(buf), &he) == PR_FAILURE) { - printf( "Unknown host: %s\n", argv[1]); - exit(1); - } else { - printf( "host: %s\n", buf); - } - PR_EnumerateHostEnt(0, &he, 80, &addr); - - sock = PR_NewTCPSocket(); - optData.option = PR_SockOpt_Nonblocking; - optData.value.non_blocking = PR_TRUE; - PR_SetSocketOption(sock, &optData); - rv = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); - if (rv == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) { - printf( "Connect in progress\n"); - } - - pd.fd = sock; - pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; - n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (n == -1) { - printf( "PR_Poll failed\n"); - exit(1); - } - printf( "PR_Poll returns %d\n", n); - if (pd.out_flags & PR_POLL_READ) { - printf( "PR_POLL_READ\n"); - } - if (pd.out_flags & PR_POLL_WRITE) { - printf( "PR_POLL_WRITE\n"); - } - if (pd.out_flags & PR_POLL_EXCEPT) { - printf( "PR_POLL_EXCEPT\n"); - } - if (pd.out_flags & PR_POLL_ERR) { - printf( "PR_POLL_ERR\n"); - } - if (pd.out_flags & PR_POLL_NVAL) { - printf( "PR_POLL_NVAL\n"); - } - - if (PR_GetConnectStatus(&pd) == PR_SUCCESS) { - printf("PR_GetConnectStatus: connect succeeded\n"); - PR_Write(sock, "GET /\r\n\r\n", 9); - PR_Shutdown(sock, PR_SHUTDOWN_SEND); - pd.in_flags = PR_POLL_READ; - while (1) { - n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - printf( "poll returns %d\n", n); - n = PR_Read(sock, buf, sizeof(buf)); - printf( "read returns %d\n", n); - if (n <= 0) { - break; - } - PR_Write(PR_STDOUT, buf, n); - } - } else { - if (PR_GetError() == PR_IN_PROGRESS_ERROR) { - printf( "PR_GetConnectStatus: connect still in progress\n"); - exit(1); - } - printf( "PR_GetConnectStatus: connect failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - } - PR_Close(sock); - printf( "PASS\n"); - return 0; - - } -} - - -/* - * TCP Server - * Server Thread - * Accept a connection from the client and write some data - */ -static void PR_CALLBACK -TCP_Server(void *arg) -{ - Server_Param *sp = (Server_Param *) arg; - PRFileDesc *sockfd, *newsockfd; - char data_buf[DATA_BUF_SIZE]; - PRIntn rv, bytes_read; - - sockfd = sp->sp_fd; - if ((newsockfd = PR_Accept(sockfd, NULL, - PR_INTERVAL_NO_TIMEOUT)) == NULL) { - fprintf(stderr,"ERROR - PR_Accept failed: (%d,%d)\n", - PR_GetError(), PR_GetOSError()); - return; - } - bytes_read = 0; - while (bytes_read != DATA_BUF_SIZE) { - rv = PR_Read(newsockfd, data_buf + bytes_read , - DATA_BUF_SIZE - bytes_read); - if (rv < 0) { - fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - PR_Close(newsockfd); - return; - } - PR_ASSERT(rv != 0); - bytes_read += rv; - } - DPRINTF(("Bytes read from client - %d\n",bytes_read)); - rv = PR_Write(newsockfd, data_buf,DATA_BUF_SIZE); - if (rv < 0) { - fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - PR_Close(newsockfd); - return; - } - PR_ASSERT(rv == DATA_BUF_SIZE); - DPRINTF(("Bytes written to client - %d\n",rv)); - PR_Close(newsockfd); -} - - -/* - * test for successful connection using a non-blocking socket - */ -static PRIntn -connection_success_test() -{ - PRFileDesc *sockfd = NULL, *conn_fd = NULL; - PRNetAddr netaddr; - PRInt32 i, rv; - PRPollDesc pd; - PRSocketOptionData optData; - PRThread *thr = NULL; - Server_Param sp; - char send_buf[DATA_BUF_SIZE], recv_buf[DATA_BUF_SIZE]; - PRIntn default_case, n, bytes_read, bytes_sent; - PRIntn failed_already = 0; - - /* - * Create a tcp socket - */ - if ((sockfd = PR_NewTCPSocket()) == NULL) { - fprintf(stderr,"Error - PR_NewTCPSocket failed\n"); - failed_already=1; - goto def_exit; - } - memset(&netaddr, 0 , sizeof(netaddr)); - netaddr.inet.family = PR_AF_INET; - netaddr.inet.port = PR_htons(TCP_SERVER_PORT); - netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); - /* - * try a few times to bind server's address, if addresses are in - * use - */ - i = 0; - while (PR_Bind(sockfd, &netaddr) < 0) { - if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { - netaddr.inet.port += 2; - if (i++ < SERVER_MAX_BIND_COUNT) - continue; - } - fprintf(stderr,"ERROR - PR_Bind failed: (%d,%d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - - if (PR_Listen(sockfd, 32) < 0) { - fprintf(stderr,"ERROR - PR_Listen failed: (%d,%d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - - if (PR_GetSockName(sockfd, &netaddr) < 0) { - fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - if ((conn_fd = PR_NewTCPSocket()) == NULL) { - fprintf(stderr,"Error - PR_NewTCPSocket failed\n"); - failed_already=1; - goto def_exit; - } - optData.option = PR_SockOpt_Nonblocking; - optData.value.non_blocking = PR_TRUE; - PR_SetSocketOption(conn_fd, &optData); - rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT); - if (rv == PR_FAILURE) { - if (PR_GetError() == PR_IN_PROGRESS_ERROR) { - DPRINTF(("Connect in progress\n")); - } else { - fprintf(stderr,"Error - PR_Connect failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - } - /* - * Now create a thread to accept a connection - */ - sp.sp_fd = sockfd; - thr = PR_CreateThread(PR_USER_THREAD, TCP_Server, (void *)&sp, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - if (thr == NULL) { - fprintf(stderr,"Error - PR_CreateThread failed: (%d,%d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - DPRINTF(("Created TCP_Server thread [0x%x]\n",thr)); - pd.fd = conn_fd; - pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; - n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (n == -1) { - fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - if (PR_GetConnectStatus(&pd) == PR_SUCCESS) { - PRInt32 rv; - - DPRINTF(("Connection successful\n")); - - /* - * Write some data, read it back and check data integrity to - * make sure the connection is good - */ - pd.in_flags = PR_POLL_WRITE; - bytes_sent = 0; - memset(send_buf, 'a', DATA_BUF_SIZE); - while (bytes_sent != DATA_BUF_SIZE) { - rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (rv < 0) { - fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_WRITE)); - rv = PR_Write(conn_fd, send_buf + bytes_sent, - DATA_BUF_SIZE - bytes_sent); - if (rv < 0) { - fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - PR_ASSERT(rv > 0); - bytes_sent += rv; - } - DPRINTF(("Bytes written to server - %d\n",bytes_sent)); - PR_Shutdown(conn_fd, PR_SHUTDOWN_SEND); - pd.in_flags = PR_POLL_READ; - bytes_read = 0; - memset(recv_buf, 0, DATA_BUF_SIZE); - while (bytes_read != DATA_BUF_SIZE) { - rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (rv < 0) { - fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_READ)); - rv = PR_Read(conn_fd, recv_buf + bytes_read , - DATA_BUF_SIZE - bytes_read); - if (rv < 0) { - fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - PR_ASSERT(rv != 0); - bytes_read += rv; - } - DPRINTF(("Bytes read from server - %d\n",bytes_read)); - /* - * verify the data read - */ - if (memcmp(send_buf, recv_buf, DATA_BUF_SIZE) != 0) { - fprintf(stderr,"ERROR - data corruption\n"); - failed_already=1; - goto def_exit; - } - DPRINTF(("Data integrity verified\n")); - } else { - fprintf(stderr,"PR_GetConnectStatus: connect failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already = 1; - goto def_exit; - } -def_exit: - if (thr) { - PR_JoinThread(thr); - thr = NULL; - } - if (sockfd) { - PR_Close(sockfd); - sockfd = NULL; - } - if (conn_fd) { - PR_Close(conn_fd); - conn_fd = NULL; - } - if (failed_already) - return 1; - else - return 0; - -} - -/* - * test for connection to a nonexistent port using a non-blocking socket - */ -static PRIntn -connection_failure_test() -{ - PRFileDesc *sockfd = NULL, *conn_fd = NULL; - PRNetAddr netaddr; - PRInt32 i, rv; - PRPollDesc pd; - PRSocketOptionData optData; - PRIntn n, failed_already = 0; - - /* - * Create a tcp socket - */ - if ((sockfd = PR_NewTCPSocket()) == NULL) { - fprintf(stderr,"Error - PR_NewTCPSocket failed\n"); - failed_already=1; - goto def_exit; - } - memset(&netaddr, 0 , sizeof(netaddr)); - netaddr.inet.family = PR_AF_INET; - netaddr.inet.port = PR_htons(TCP_SERVER_PORT); - netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); - /* - * try a few times to bind server's address, if addresses are in - * use - */ - i = 0; - while (PR_Bind(sockfd, &netaddr) < 0) { - if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { - netaddr.inet.port += 2; - if (i++ < SERVER_MAX_BIND_COUNT) - continue; - } - fprintf(stderr,"ERROR - PR_Bind failed: (%d,%d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - - if (PR_GetSockName(sockfd, &netaddr) < 0) { - fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } -#ifdef AIX - /* - * On AIX, set to unused/reserved port - */ - netaddr.inet.port = PR_htons(TCP_UNUSED_PORT); -#endif - if ((conn_fd = PR_NewTCPSocket()) == NULL) { - fprintf(stderr,"Error - PR_NewTCPSocket failed\n"); - failed_already=1; - goto def_exit; - } - optData.option = PR_SockOpt_Nonblocking; - optData.value.non_blocking = PR_TRUE; - PR_SetSocketOption(conn_fd, &optData); - rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT); - if (rv == PR_FAILURE) { - DPRINTF(("PR_Connect to a non-listen port failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError())); - } else { - PR_ASSERT(rv == PR_SUCCESS); - fprintf(stderr,"Error - PR_Connect succeeded, expected to fail\n"); - failed_already=1; - goto def_exit; - } - pd.fd = conn_fd; - pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; - n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (n == -1) { - fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - goto def_exit; - } - if (PR_GetConnectStatus(&pd) == PR_SUCCESS) { - PRInt32 rv; - fprintf(stderr,"PR_GetConnectStatus succeeded, expected to fail\n"); - failed_already = 1; - goto def_exit; - } - rv = PR_GetError(); - DPRINTF(("Connection failed, successfully with PR_Error %d\n",rv)); -def_exit: - if (sockfd) { - PR_Close(sockfd); - sockfd = NULL; - } - if (conn_fd) { - PR_Close(conn_fd); - conn_fd = NULL; - } - if (failed_already) - return 1; - else - return 0; - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/nblayer.c nspr-4.10.7/mozilla/nsprpub/pr/tests/nblayer.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/nblayer.c 2012-03-06 13:14:27.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/nblayer.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,675 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prmem.h" -#include "prprf.h" -#include "prlog.h" -#include "prerror.h" -#include "prnetdb.h" -#include "prthread.h" - -#include "plerror.h" -#include "plgetopt.h" -#include "prwin16.h" - -#include -#include - -/* -** Testing layering of I/O -** -** The layered server -** A thread that acts as a server. It creates a TCP listener with a dummy -** layer pushed on top. Then listens for incoming connections. Each connection -** request for connection will be layered as well, accept one request, echo -** it back and close. -** -** The layered client -** Pretty much what you'd expect. -*/ - -static PRFileDesc *logFile; -static PRDescIdentity identity; -static PRNetAddr server_address; - -static PRIOMethods myMethods; - -typedef enum {rcv_get_debit, rcv_send_credit, rcv_data} RcvState; -typedef enum {xmt_send_debit, xmt_recv_credit, xmt_data} XmtState; - -struct PRFilePrivate -{ - RcvState rcvstate; - XmtState xmtstate; - PRInt32 rcvreq, rcvinprogress; - PRInt32 xmtreq, xmtinprogress; -}; - -typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity; - -static PRIntn minor_iterations = 5; -static PRIntn major_iterations = 1; -static Verbosity verbosity = quiet; -static PRUint16 default_port = 12273; - -static PRFileDesc *PushLayer(PRFileDesc *stack) -{ - PRStatus rv; - PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods); - layer->secret = PR_NEWZAP(PRFilePrivate); - rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); - PR_ASSERT(PR_SUCCESS == rv); - if (verbosity > quiet) - PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); - return stack; -} /* PushLayer */ - -static PRFileDesc *PopLayer(PRFileDesc *stack) -{ - PRFileDesc *popped = PR_PopIOLayer(stack, identity); - if (verbosity > quiet) - PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack); - PR_DELETE(popped->secret); - popped->dtor(popped); - return stack; -} /* PopLayer */ - -static void PR_CALLBACK Client(void *arg) -{ - PRStatus rv; - PRIntn mits; - PRInt32 ready; - PRUint8 buffer[100]; - PRPollDesc polldesc; - PRIntn empty_flags = 0; - PRIntn bytes_read, bytes_sent; - PRFileDesc *stack = (PRFileDesc*)arg; - - /* Initialize the buffer so that Purify won't complain */ - memset(buffer, 0, sizeof(buffer)); - - rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT); - if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError())) - { - if (verbosity > quiet) - PR_fprintf(logFile, "Client connect 'in progress'\n"); - do - { - polldesc.fd = stack; - polldesc.out_flags = 0; - polldesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; - ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); - if ((1 != ready) /* if not 1, then we're dead */ - || (0 == (polldesc.in_flags & polldesc.out_flags))) - { PR_ASSERT(!"Whoa!"); break; } - if (verbosity > quiet) - PR_fprintf( - logFile, "Client connect 'in progress' [0x%x]\n", - polldesc.out_flags); - rv = PR_GetConnectStatus(&polldesc); - if ((PR_FAILURE == rv) - && (PR_IN_PROGRESS_ERROR != PR_GetError())) break; - } while (PR_FAILURE == rv); - } - PR_ASSERT(PR_SUCCESS == rv); - if (verbosity > chatty) - PR_fprintf(logFile, "Client created connection\n"); - - for (mits = 0; mits < minor_iterations; ++mits) - { - bytes_sent = 0; - if (verbosity > quiet) - PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer)); - do - { - if (verbosity > chatty) - PR_fprintf( - logFile, "Client sending %d bytes\n", - sizeof(buffer) - bytes_sent); - ready = PR_Send( - stack, buffer + bytes_sent, sizeof(buffer) - bytes_sent, - empty_flags, PR_INTERVAL_NO_TIMEOUT); - if (verbosity > chatty) - PR_fprintf(logFile, "Client send status [%d]\n", ready); - if (0 < ready) bytes_sent += ready; - else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) - { - polldesc.fd = stack; - polldesc.out_flags = 0; - polldesc.in_flags = PR_POLL_WRITE; - ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); - if ((1 != ready) /* if not 1, then we're dead */ - || (0 == (polldesc.in_flags & polldesc.out_flags))) - { PR_ASSERT(!"Whoa!"); break; } - } - else break; - } while (bytes_sent < sizeof(buffer)); - PR_ASSERT(sizeof(buffer) == bytes_sent); - - bytes_read = 0; - do - { - if (verbosity > chatty) - PR_fprintf( - logFile, "Client receiving %d bytes\n", - bytes_sent - bytes_read); - ready = PR_Recv( - stack, buffer + bytes_read, bytes_sent - bytes_read, - empty_flags, PR_INTERVAL_NO_TIMEOUT); - if (verbosity > chatty) - PR_fprintf( - logFile, "Client receive status [%d]\n", ready); - if (0 < ready) bytes_read += ready; - else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) - { - polldesc.fd = stack; - polldesc.out_flags = 0; - polldesc.in_flags = PR_POLL_READ; - ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); - if ((1 != ready) /* if not 1, then we're dead */ - || (0 == (polldesc.in_flags & polldesc.out_flags))) - { PR_ASSERT(!"Whoa!"); break; } - } - else break; - } while (bytes_read < bytes_sent); - if (verbosity > chatty) - PR_fprintf(logFile, "Client received %d bytes\n", bytes_read); - PR_ASSERT(bytes_read == bytes_sent); - } - - if (verbosity > quiet) - PR_fprintf(logFile, "Client shutting down stack\n"); - - rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); -} /* Client */ - -static void PR_CALLBACK Server(void *arg) -{ - PRStatus rv; - PRInt32 ready; - PRUint8 buffer[100]; - PRFileDesc *service; - PRUintn empty_flags = 0; - struct PRPollDesc polldesc; - PRIntn bytes_read, bytes_sent; - PRFileDesc *stack = (PRFileDesc*)arg; - PRNetAddr client_address; - - do - { - if (verbosity > chatty) - PR_fprintf(logFile, "Server accepting connection\n"); - service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT); - if (verbosity > chatty) - PR_fprintf(logFile, "Server accept status [0x%p]\n", service); - if ((NULL == service) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) - { - polldesc.fd = stack; - polldesc.out_flags = 0; - polldesc.in_flags = PR_POLL_READ | PR_POLL_EXCEPT; - ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); - if ((1 != ready) /* if not 1, then we're dead */ - || (0 == (polldesc.in_flags & polldesc.out_flags))) - { PR_ASSERT(!"Whoa!"); break; } - } - } while (NULL == service); - PR_ASSERT(NULL != service); - - if (verbosity > quiet) - PR_fprintf(logFile, "Server accepting connection\n"); - - do - { - bytes_read = 0; - do - { - if (verbosity > chatty) - PR_fprintf( - logFile, "Server receiving %d bytes\n", - sizeof(buffer) - bytes_read); - ready = PR_Recv( - service, buffer + bytes_read, sizeof(buffer) - bytes_read, - empty_flags, PR_INTERVAL_NO_TIMEOUT); - if (verbosity > chatty) - PR_fprintf(logFile, "Server receive status [%d]\n", ready); - if (0 < ready) bytes_read += ready; - else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) - { - polldesc.fd = service; - polldesc.out_flags = 0; - polldesc.in_flags = PR_POLL_READ; - ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); - if ((1 != ready) /* if not 1, then we're dead */ - || (0 == (polldesc.in_flags & polldesc.out_flags))) - { PR_ASSERT(!"Whoa!"); break; } - } - else break; - } while (bytes_read < sizeof(buffer)); - - if (0 != bytes_read) - { - if (verbosity > chatty) - PR_fprintf(logFile, "Server received %d bytes\n", bytes_read); - PR_ASSERT(bytes_read > 0); - - bytes_sent = 0; - do - { - ready = PR_Send( - service, buffer + bytes_sent, bytes_read - bytes_sent, - empty_flags, PR_INTERVAL_NO_TIMEOUT); - if (0 < ready) - { - bytes_sent += ready; - } - else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) - { - polldesc.fd = service; - polldesc.out_flags = 0; - polldesc.in_flags = PR_POLL_WRITE; - ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); - if ((1 != ready) /* if not 1, then we're dead */ - || (0 == (polldesc.in_flags & polldesc.out_flags))) - { PR_ASSERT(!"Whoa!"); break; } - } - else break; - } while (bytes_sent < bytes_read); - PR_ASSERT(bytes_read == bytes_sent); - if (verbosity > chatty) - PR_fprintf(logFile, "Server sent %d bytes\n", bytes_sent); - } - } while (0 != bytes_read); - - if (verbosity > quiet) - PR_fprintf(logFile, "Server shutting down stack\n"); - rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); - -} /* Server */ - -static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd) -{ - PR_DELETE(fd->secret); /* manage my secret file object */ - return (PR_GetDefaultIOMethods())->close(fd); /* let him do all the work */ -} /* MyClose */ - -static PRInt16 PR_CALLBACK MyPoll( - PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) -{ - PRInt16 my_flags, new_flags; - PRFilePrivate *mine = (PRFilePrivate*)fd->secret; - if (0 != (PR_POLL_READ & in_flags)) - { - /* client thinks he's reading */ - switch (mine->rcvstate) - { - case rcv_send_credit: - my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE; - break; - case rcv_data: - case rcv_get_debit: - my_flags = in_flags; - default: break; - } - } - else if (0 != (PR_POLL_WRITE & in_flags)) - { - /* client thinks he's writing */ - switch (mine->xmtstate) - { - case xmt_recv_credit: - my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ; - break; - case xmt_send_debit: - case xmt_data: - my_flags = in_flags; - default: break; - } - } - else PR_ASSERT(!"How'd I get here?"); - new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags); - if (verbosity > chatty) - PR_fprintf( - logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n", - in_flags, my_flags, *out_flags, new_flags); - return new_flags; -} /* MyPoll */ - -static PRFileDesc * PR_CALLBACK MyAccept( - PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout) -{ - PRStatus rv; - PRFileDesc *newfd, *layer = fd; - PRFileDesc *newstack; - PRFilePrivate *newsecret; - - PR_ASSERT(fd != NULL); - PR_ASSERT(fd->lower != NULL); - - newstack = PR_NEW(PRFileDesc); - if (NULL == newstack) - { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - newsecret = PR_NEW(PRFilePrivate); - if (NULL == newsecret) - { - PR_DELETE(newstack); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - *newstack = *fd; /* make a copy of the accepting layer */ - *newsecret = *fd->secret; - newstack->secret = newsecret; - - newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout); - if (NULL == newfd) - { - PR_DELETE(newsecret); - PR_DELETE(newstack); - return NULL; - } - - /* this PR_PushIOLayer call cannot fail */ - rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); - PR_ASSERT(PR_SUCCESS == rv); - return newfd; /* that's it */ -} - -static PRInt32 PR_CALLBACK MyRecv( - PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - char *b; - PRInt32 rv; - PRFileDesc *lo = fd->lower; - PRFilePrivate *mine = (PRFilePrivate*)fd->secret; - - do - { - switch (mine->rcvstate) - { - case rcv_get_debit: - b = (char*)&mine->rcvreq; - mine->rcvreq = amount; - rv = lo->methods->recv( - lo, b + mine->rcvinprogress, - sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout); - if (0 == rv) goto closed; - if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; - mine->rcvinprogress += rv; /* accumulate the read */ - if (mine->rcvinprogress < sizeof(mine->rcvreq)) break; /* loop */ - mine->rcvstate = rcv_send_credit; - mine->rcvinprogress = 0; - case rcv_send_credit: - b = (char*)&mine->rcvreq; - rv = lo->methods->send( - lo, b + mine->rcvinprogress, - sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout); - if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; - mine->rcvinprogress += rv; /* accumulate the read */ - if (mine->rcvinprogress < sizeof(mine->rcvreq)) break; /* loop */ - mine->rcvstate = rcv_data; - mine->rcvinprogress = 0; - case rcv_data: - b = (char*)buf; - rv = lo->methods->recv( - lo, b + mine->rcvinprogress, - mine->rcvreq - mine->rcvinprogress, flags, timeout); - if (0 == rv) goto closed; - if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; - mine->rcvinprogress += rv; /* accumulate the read */ - if (mine->rcvinprogress < amount) break; /* loop */ - mine->rcvstate = rcv_get_debit; - mine->rcvinprogress = 0; - return mine->rcvreq; /* << -- that's it! */ - default: - break; - } - } while (-1 != rv); - return rv; -closed: - mine->rcvinprogress = 0; - mine->rcvstate = rcv_get_debit; - return 0; -} /* MyRecv */ - -static PRInt32 PR_CALLBACK MySend( - PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - char *b; - PRInt32 rv; - PRFileDesc *lo = fd->lower; - PRFilePrivate *mine = (PRFilePrivate*)fd->secret; - - do - { - switch (mine->xmtstate) - { - case xmt_send_debit: - b = (char*)&mine->xmtreq; - mine->xmtreq = amount; - rv = lo->methods->send( - lo, b - mine->xmtinprogress, - sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout); - if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; - mine->xmtinprogress += rv; - if (mine->xmtinprogress < sizeof(mine->xmtreq)) break; - mine->xmtstate = xmt_recv_credit; - mine->xmtinprogress = 0; - case xmt_recv_credit: - b = (char*)&mine->xmtreq; - rv = lo->methods->recv( - lo, b + mine->xmtinprogress, - sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout); - if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; - mine->xmtinprogress += rv; - if (mine->xmtinprogress < sizeof(mine->xmtreq)) break; - mine->xmtstate = xmt_data; - mine->xmtinprogress = 0; - case xmt_data: - b = (char*)buf; - rv = lo->methods->send( - lo, b + mine->xmtinprogress, - mine->xmtreq - mine->xmtinprogress, flags, timeout); - if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; - mine->xmtinprogress += rv; - if (mine->xmtinprogress < amount) break; - mine->xmtstate = xmt_send_debit; - mine->xmtinprogress = 0; - return mine->xmtreq; /* <<-- That's the one! */ - default: - break; - } - } while (-1 != rv); - return rv; -} /* MySend */ - -static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta) -{ - PRIntn verbage = (PRIntn)verbosity + delta; - if (verbage < (PRIntn)silent) verbage = (PRIntn)silent; - else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy; - return (Verbosity)verbage; -} /* ChangeVerbosity */ - -int main(int argc, char **argv) -{ - PRStatus rv; - PLOptStatus os; - PRFileDesc *client, *service; - PRNetAddr any_address; - const char *server_name = NULL; - const PRIOMethods *stubMethods; - PRThread *client_thread, *server_thread; - PRThreadScope thread_scope = PR_LOCAL_THREAD; - PRSocketOptionData socket_noblock, socket_nodelay; - PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: - server_name = opt->value; - break; - case 'd': /* debug mode */ - if (verbosity < noisy) - verbosity = ChangeVerbosity(verbosity, 1); - break; - case 'q': /* debug mode */ - if (verbosity > silent) - verbosity = ChangeVerbosity(verbosity, -1); - break; - case 'G': /* use global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'C': /* number of threads waiting */ - major_iterations = atoi(opt->value); - break; - case 'c': /* number of client threads */ - minor_iterations = atoi(opt->value); - break; - case 'p': /* default port */ - default_port = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - PR_STDIO_INIT(); - - logFile = PR_GetSpecialFD(PR_StandardError); - identity = PR_GetUniqueIdentity("Dummy"); - stubMethods = PR_GetDefaultIOMethods(); - - /* - ** The protocol we're going to implement is one where in order to initiate - ** a send, the sender must first solicit permission. Therefore, every - ** send is really a send - receive - send sequence. - */ - myMethods = *stubMethods; /* first get the entire batch */ - myMethods.accept = MyAccept; /* then override the ones we care about */ - myMethods.recv = MyRecv; /* then override the ones we care about */ - myMethods.send = MySend; /* then override the ones we care about */ - myMethods.close = MyClose; /* then override the ones we care about */ - myMethods.poll = MyPoll; /* then override the ones we care about */ - - if (NULL == server_name) - rv = PR_InitializeNetAddr( - PR_IpAddrLoopback, default_port, &server_address); - else - { - rv = PR_StringToNetAddr(server_name, &server_address); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_InitializeNetAddr( - PR_IpAddrNull, default_port, &server_address); - } - PR_ASSERT(PR_SUCCESS == rv); - - socket_noblock.value.non_blocking = PR_TRUE; - socket_noblock.option = PR_SockOpt_Nonblocking; - socket_nodelay.value.no_delay = PR_TRUE; - socket_nodelay.option = PR_SockOpt_NoDelay; - - /* one type w/o layering */ - - while (major_iterations-- > 0) - { - if (verbosity > silent) - PR_fprintf(logFile, "Beginning non-layered test\n"); - - client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); - service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); - - rv = PR_SetSocketOption(client, &socket_noblock); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_SetSocketOption(service, &socket_noblock); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_SetSocketOption(client, &socket_nodelay); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_SetSocketOption(service, &socket_nodelay); - PR_ASSERT(PR_SUCCESS == rv); - - rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); - - server_thread = PR_CreateThread( - PR_USER_THREAD, Server, service, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != server_thread); - - client_thread = PR_CreateThread( - PR_USER_THREAD, Client, client, - PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != client_thread); - - rv = PR_JoinThread(client_thread); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(server_thread); - PR_ASSERT(PR_SUCCESS == rv); - - rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); - if (verbosity > silent) - PR_fprintf(logFile, "Ending non-layered test\n"); - - /* with layering */ - if (verbosity > silent) - PR_fprintf(logFile, "Beginning layered test\n"); - client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); - service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); - - rv = PR_SetSocketOption(client, &socket_noblock); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_SetSocketOption(service, &socket_noblock); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_SetSocketOption(client, &socket_nodelay); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_SetSocketOption(service, &socket_nodelay); - PR_ASSERT(PR_SUCCESS == rv); - - PushLayer(client); - PushLayer(service); - - rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); - - server_thread = PR_CreateThread( - PR_USER_THREAD, Server, service, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != server_thread); - - client_thread = PR_CreateThread( - PR_USER_THREAD, Client, client, - PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 16 * 1024); - PR_ASSERT(NULL != client_thread); - - rv = PR_JoinThread(client_thread); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_JoinThread(server_thread); - PR_ASSERT(PR_SUCCESS == rv); - - rv = PR_Close(PopLayer(client)); PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Close(PopLayer(service)); PR_ASSERT(PR_SUCCESS == rv); - if (verbosity > silent) - PR_fprintf(logFile, "Ending layered test\n"); - } - return 0; -} /* main */ - -/* nblayer.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/nonblock.c nspr-4.10.7/mozilla/nsprpub/pr/tests/nonblock.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/nonblock.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/nonblock.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,225 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "prio.h" -#include "prerror.h" -#include "prlog.h" -#include "prprf.h" -#include "prnetdb.h" -#include "plerror.h" -#include "obsolete/probslet.h" - -#include -#include -#include - -#define NUMBER_ROUNDS 5 - -#if defined(WIN16) -/* -** Make win16 unit_time interval 300 milliseconds, others get 100 -*/ -#define UNIT_TIME 200 /* unit time in milliseconds */ -#elif defined(SYMBIAN) -#define UNIT_TIME 5000 /* unit time in milliseconds */ -#else -#define UNIT_TIME 100 /* unit time in milliseconds */ -#endif -#define CHUNK_SIZE 10 -#undef USE_PR_SELECT /* If defined, we use PR_Select. - * If not defined, use PR_Poll instead. */ - -#if defined(USE_PR_SELECT) -#include "pprio.h" -#endif - -static void PR_CALLBACK -clientThreadFunc(void *arg) -{ - PRUintn port = (PRUintn)arg; - PRFileDesc *sock; - PRNetAddr addr; - char buf[CHUNK_SIZE]; - int i; - PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME); - PRSocketOptionData optval; - PRStatus retVal; - PRInt32 nBytes; - - /* Initialize the buffer so that Purify won't complain */ - memset(buf, 0, sizeof(buf)); - - addr.inet.family = PR_AF_INET; - addr.inet.port = PR_htons((PRUint16)port); - addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip); - - /* time 1 */ - PR_Sleep(unitTime); - sock = PR_NewTCPSocket(); - optval.option = PR_SockOpt_Nonblocking; - optval.value.non_blocking = PR_TRUE; - PR_SetSocketOption(sock, &optval); - retVal = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); - if (retVal == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) { -#if !defined(USE_PR_SELECT) - PRPollDesc pd; - PRInt32 n; - fprintf(stderr, "connect: EWOULDBLOCK, good\n"); - pd.fd = sock; - pd.in_flags = PR_POLL_WRITE; - n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(n == 1); - PR_ASSERT(pd.out_flags == PR_POLL_WRITE); -#else - PR_fd_set writeSet; - PRInt32 n; - fprintf(stderr, "connect: EWOULDBLOCK, good\n"); - PR_FD_ZERO(&writeSet); - PR_FD_SET(sock, &writeSet); - n = PR_Select(0, NULL, &writeSet, NULL, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(n == 1); - PR_ASSERT(PR_FD_ISSET(sock, &writeSet)); -#endif - } - printf("client connected\n"); - fflush(stdout); - - /* time 4, 7, 11, etc. */ - for (i = 0; i < NUMBER_ROUNDS; i++) { - PR_Sleep(3 * unitTime); - nBytes = PR_Write(sock, buf, sizeof(buf)); - if (nBytes == -1) { - if (PR_GetError() == PR_WOULD_BLOCK_ERROR) { - fprintf(stderr, "write: EWOULDBLOCK\n"); - exit(1); - } else { - fprintf(stderr, "write: failed\n"); - } - } - printf("client sent %d bytes\n", nBytes); - fflush(stdout); - } - - PR_Close(sock); -} - -static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) -{ - PRFileDesc *listenSock, *sock; - PRUint16 listenPort; - PRNetAddr addr; - char buf[CHUNK_SIZE]; - PRThread *clientThread; - PRInt32 retVal; - PRSocketOptionData optval; - PRIntn i; - PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME); - - /* Create a listening socket */ - if ((listenSock = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - exit(1); - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - exit(1); - } - if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - exit(1); - } - listenPort = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - exit(1); - } - - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on port %hu\n\n", - listenPort); - printf("%s", buf); - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - exit(1); - } - - printf("client thread created.\n"); - - optval.option = PR_SockOpt_Nonblocking; - optval.value.non_blocking = PR_TRUE; - PR_SetSocketOption(listenSock, &optval); - /* time 0 */ - sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (sock != NULL || PR_GetError() != PR_WOULD_BLOCK_ERROR) { - PL_PrintError("First Accept\n"); - fprintf(stderr, "First PR_Accept() xxx\n" ); - exit(1); - } - printf("accept: EWOULDBLOCK, good\n"); - fflush(stdout); - /* time 2 */ - PR_Sleep(2 * unitTime); - sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (sock == NULL) { - PL_PrintError("Second Accept\n"); - fprintf(stderr, "Second PR_Accept() failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - printf("accept: succeeded, good\n"); - fflush(stdout); - PR_Close(listenSock); - - PR_SetSocketOption(sock, &optval); - - /* time 3, 5, 6, 8, etc. */ - for (i = 0; i < NUMBER_ROUNDS; i++) { - PR_Sleep(unitTime); - retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); - if (retVal != -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR) { - PL_PrintError("First Receive:\n"); - fprintf(stderr, "First PR_Recv: retVal: %ld, Error: %ld\n", - retVal, PR_GetError()); - exit(1); - } - printf("read: EWOULDBLOCK, good\n"); - fflush(stdout); - PR_Sleep(2 * unitTime); - retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); - if (retVal != CHUNK_SIZE) { - PL_PrintError("Second Receive:\n"); - fprintf(stderr, "Second PR_Recv: retVal: %ld, Error: %ld\n", - retVal, PR_GetError()); - exit(1); - } - printf("read: %d bytes, good\n", retVal); - fflush(stdout); - } - PR_Close(sock); - - printf("All tests finished\n"); - printf("PASS\n"); - return 0; -} - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/ntioto.c nspr-4.10.7/mozilla/nsprpub/pr/tests/ntioto.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/ntioto.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/ntioto.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,286 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: ntioto.c -** Description: -** This test, ntioto.c, was designed to reproduce a bug reported by NES -** on WindowsNT (fibers implementation). NSPR was asserting in ntio.c -** after PR_AcceptRead() had timed out. I/O performed subsequent to the -** call to PR_AcceptRead() could complete on a CPU other than the one -** on which it was started. The assert in ntio.c detected this, then -** asserted. -** -** Design: -** This test will fail with an assert in ntio.c if the problem it was -** designed to catch occurs. It returns 0 otherwise. -** -** The main() thread initializes and tears things down. A file is -** opened for writing; this file will be written to by AcceptThread() -** and JitterThread(). Main() creates a socket for reading, listens -** and binds the socket. -** -** ConnectThread() connects to the socket created by main, then polls -** the "state" variable. When state is AllDone, ConnectThread() exits. -** -** AcceptThread() calls PR_AcceptRead() on the socket. He fully expects -** it to time out. After the timeout, AccpetThread() interacts with -** JitterThread() via a common condition variable and the state -** variable. The two threads ping-pong back and forth, each thread -** writes the the file opened by main. This should provoke the -** condition reported by NES (if we didn't fix it). -** -** The failure is not solid. It may fail within a few ping-pongs between -** AcceptThread() and JitterThread() or may take a while. The default -** iteration count, jitter, is set by DEFAULT_JITTER. This may be -** modified at the command line with the -j option. -** -*/ - -#include -#include -#include -#include -#include - -/* -** Test harness infrastructure -*/ -PRLogModuleInfo *lm; -PRLogModuleLevel msgLevel = PR_LOG_NONE; -PRIntn debug = 0; -PRIntn verbose = 0; -PRUint32 failed_already = 0; -/* end Test harness infrastructure */ - -/* JITTER_DEFAULT: the number of times AcceptThread() and JitterThread() ping-pong */ -#define JITTER_DEFAULT 100000 -#define BASE_PORT 9867 - -PRIntervalTime timeout; -PRNetAddr listenAddr; -PRFileDesc *listenSock; -PRLock *ml; -PRCondVar *cv; -volatile enum { - RunJitter, - RunAcceptRead, - AllDone -} state = RunAcceptRead; -PRFileDesc *file1; -PRIntn iCounter = 0; -PRIntn jitter = JITTER_DEFAULT; -PRBool resume = PR_FALSE; - -/* -** Emit help text for this test -*/ -static void Help( void ) -{ - printf("Template: Help(): display your help message(s) here"); - exit(1); -} /* end Help() */ - - -/* -** static computation of PR_AcceptRead() buffer size. -*/ -#define ACCEPT_READ_DATASIZE 10 -#define ACCEPT_READ_BUFSIZE (PR_ACCEPT_READ_BUF_OVERHEAD + ACCEPT_READ_DATASIZE) - -static void AcceptThread(void *arg) -{ - PRIntn bytesRead; - char dataBuf[ACCEPT_READ_BUFSIZE]; - PRFileDesc *arSock; - PRNetAddr *arAddr; - - bytesRead = PR_AcceptRead( listenSock, - &arSock, - &arAddr, - dataBuf, - ACCEPT_READ_DATASIZE, - PR_SecondsToInterval(1)); - - if ( bytesRead == -1 && PR_GetError() == PR_IO_TIMEOUT_ERROR ) { - if ( debug ) printf("AcceptRead timed out\n"); - } else { - if ( debug ) printf("Oops! read: %d, error: %d\n", bytesRead, PR_GetError()); - } - - while( state != AllDone ) { - PR_Lock( ml ); - while( state != RunAcceptRead ) - PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT ); - if ( ++iCounter >= jitter ) - state = AllDone; - else - state = RunJitter; - if ( verbose ) printf("."); - PR_NotifyCondVar( cv ); - PR_Unlock( ml ); - PR_Write( file1, ".", 1 ); - } - - return; -} /* end AcceptThread() */ - -static void JitterThread(void *arg) -{ - while( state != AllDone ) { - PR_Lock( ml ); - while( state != RunJitter && state != AllDone ) - PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT ); - if ( state != AllDone) - state = RunAcceptRead; - if ( verbose ) printf("+"); - PR_NotifyCondVar( cv ); - PR_Unlock( ml ); - PR_Write( file1, "+", 1 ); - } - return; -} /* end Goofy() */ - -static void ConnectThread( void *arg ) -{ - PRStatus rv; - PRFileDesc *clientSock; - PRNetAddr serverAddress; - clientSock = PR_NewTCPSocket(); - - PR_ASSERT(clientSock); - - if ( resume ) { - if ( debug ) printf("pausing 3 seconds before connect\n"); - PR_Sleep( PR_SecondsToInterval(3)); - } - - memset(&serverAddress, 0, sizeof(serverAddress)); - rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddress); - PR_ASSERT( PR_SUCCESS == rv ); - rv = PR_Connect( clientSock, - &serverAddress, - PR_SecondsToInterval(1)); - PR_ASSERT( PR_SUCCESS == rv ); - - /* that's all we do. ... Wait for the acceptread() to timeout */ - while( state != AllDone ) - PR_Sleep( PR_SecondsToInterval(1)); - return; -} /* end ConnectThread() */ - - -int main(int argc, char **argv) -{ - PRThread *tJitter; - PRThread *tAccept; - PRThread *tConnect; - PRStatus rv; - /* This test if valid for WinNT only! */ - -#if !defined(WINNT) - return 0; -#endif - - { - /* - ** Get command line options - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "hdrvj:"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug */ - debug = 1; - msgLevel = PR_LOG_ERROR; - break; - case 'v': /* verbose mode */ - verbose = 1; - msgLevel = PR_LOG_DEBUG; - break; - case 'j': - jitter = atoi(opt->value); - if ( jitter == 0) - jitter = JITTER_DEFAULT; - break; - case 'r': - resume = PR_TRUE; - break; - case 'h': /* help message */ - Help(); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - } - - lm = PR_NewLogModule("Test"); /* Initialize logging */ - - /* set concurrency */ - PR_SetConcurrency( 4 ); - - /* setup thread synchronization mechanics */ - ml = PR_NewLock(); - cv = PR_NewCondVar( ml ); - - /* setup a tcp socket */ - memset(&listenAddr, 0, sizeof(listenAddr)); - rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr); - PR_ASSERT( PR_SUCCESS == rv ); - - listenSock = PR_NewTCPSocket(); - PR_ASSERT( listenSock ); - - rv = PR_Bind( listenSock, &listenAddr); - PR_ASSERT( PR_SUCCESS == rv ); - - rv = PR_Listen( listenSock, 5 ); - PR_ASSERT( PR_SUCCESS == rv ); - - /* open a file for writing, provoke bug */ - file1 = PR_Open("xxxTestFile", PR_CREATE_FILE | PR_RDWR, 666); - - /* create Connect thread */ - tConnect = PR_CreateThread( - PR_USER_THREAD, ConnectThread, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, 0 ); - PR_ASSERT( tConnect ); - - /* create jitter off thread */ - tJitter = PR_CreateThread( - PR_USER_THREAD, JitterThread, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, 0 ); - PR_ASSERT( tJitter ); - - /* create acceptread thread */ - tAccept = PR_CreateThread( - PR_USER_THREAD, AcceptThread, NULL, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, 0 ); - PR_ASSERT( tAccept ); - - /* wait for all threads to quit, then terminate gracefully */ - PR_JoinThread( tConnect ); - PR_JoinThread( tAccept ); - PR_JoinThread( tJitter ); - PR_Close( listenSock ); - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); - PR_Close( file1 ); - PR_Delete( "xxxTestFile"); - - /* test return and exit */ - if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); - return( (failed_already == PR_TRUE )? 1 : 0 ); -} /* main() */ -/* end ntioto.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/ntoh.c nspr-4.10.7/mozilla/nsprpub/pr/tests/ntoh.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/ntoh.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/ntoh.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * A test program for PR_htons, PR_ntohs, PR_htonl, PR_ntohl, - * PR_htonll, and PR_ntohll. - */ - -#include "prnetdb.h" - -#include -#include -#include - -/* Byte sequence in network byte order */ -static unsigned char bytes_n[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - -/* Integers in host byte order */ -static PRUint16 s_h = 0x0102; -static PRUint32 l_h = 0x01020304; -static PRUint64 ll_h = LL_INIT(0x01020304, 0x05060708); - -int main(int argc, char **argv) -{ - union { - PRUint16 s; - PRUint32 l; - PRUint64 ll; - unsigned char bytes[8]; - } un; - - un.s = s_h; - printf("%u %u\n", - un.bytes[0], un.bytes[1]); - un.s = PR_htons(un.s); - printf("%u %u\n", - un.bytes[0], un.bytes[1]); - if (memcmp(un.bytes, bytes_n, 2)) { - fprintf(stderr, "PR_htons failed\n"); - exit(1); - } - un.s = PR_ntohs(un.s); - printf("%u %u\n", - un.bytes[0], un.bytes[1]); - if (un.s != s_h) { - fprintf(stderr, "PR_ntohs failed\n"); - exit(1); - } - - un.l = l_h; - printf("%u %u %u %u\n", - un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]); - un.l = PR_htonl(un.l); - printf("%u %u %u %u\n", - un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]); - if (memcmp(un.bytes, bytes_n, 4)) { - fprintf(stderr, "PR_htonl failed\n"); - exit(1); - } - un.l = PR_ntohl(un.l); - printf("%u %u %u %u\n", - un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]); - if (un.l != l_h) { - fprintf(stderr, "PR_ntohl failed\n"); - exit(1); - } - - un.ll = ll_h; - printf("%u %u %u %u %u %u %u %u\n", - un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3], - un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]); - un.ll = PR_htonll(un.ll); - printf("%u %u %u %u %u %u %u %u\n", - un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3], - un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]); - if (memcmp(un.bytes, bytes_n, 8)) { - fprintf(stderr, "PR_htonll failed\n"); - exit(1); - } - un.ll = PR_ntohll(un.ll); - printf("%u %u %u %u %u %u %u %u\n", - un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3], - un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]); - if (LL_NE(un.ll, ll_h)) { - fprintf(stderr, "PR_ntohll failed\n"); - exit(1); - } - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/obsints.c nspr-4.10.7/mozilla/nsprpub/pr/tests/obsints.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/obsints.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/obsints.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Test: obsints.c - * - * Description: make sure that protypes.h defines the obsolete integer - * types intn, uintn, uint, int8, uint8, int16, uint16, int32, uint32, - * int64, and uint64. - */ - -#include - -#ifdef NO_NSPR_10_SUPPORT - -/* nothing to do */ -int main(int argc, char **argv) -{ - printf("PASS\n"); - return 0; -} - -#else /* NO_NSPR_10_SUPPORT */ - -#include "prtypes.h" /* which includes protypes.h */ - -int main(int argc, char **argv) -{ - /* - * Compilation fails if any of these integer types are not - * defined by protypes.h. - */ - intn in; - uintn uin; - uint ui; - int8 i8; - uint8 ui8; - int16 i16; - uint16 ui16; - int32 i32; - uint32 ui32; - int64 i64; - uint64 ui64; - - printf("PASS\n"); - return 0; -} - -#endif /* NO_NSPR_10_SUPPORT */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/op_2long.c nspr-4.10.7/mozilla/nsprpub/pr/tests/op_2long.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/op_2long.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/op_2long.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: op_2long.c -** -** Description: Test Program to verify the PR_NAME_TOO_LONG_ERROR -** -** Modification History: -** 03-June-97 AGarcia- Initial version -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "prinit.h" -#include "prmem.h" -#include "prio.h" -#include "prerror.h" -#include -#include "plerror.h" -#include "plgetopt.h" - -static PRFileDesc *t1; -PRIntn error_code; - -/* - * should exceed any system's maximum file name length - * Note: was set at 4096. This is legal on some unix (Linux 2.1+) platforms. - * - */ -#define TOO_LONG 5000 - -int main(int argc, char **argv) -{ - char nameTooLong[TOO_LONG]; - int i; - - /* Generate a really long pathname */ - for (i = 0; i < TOO_LONG - 1; i++) { - if (i % 10 == 0) { - nameTooLong[i] = '/'; - } else { - nameTooLong[i] = 'a'; - } - } - nameTooLong[TOO_LONG - 1] = 0; - - PR_STDIO_INIT(); - t1 = PR_Open(nameTooLong, PR_RDWR, 0666); - if (t1 == NULL) { - if (PR_GetError() == PR_NAME_TOO_LONG_ERROR) { - PL_PrintError("error code is"); - printf ("PASS\n"); - return 0; - } - else { - PL_PrintError("error code is"); - printf ("FAIL\n"); - return 1; - } - } - - else { - printf ("Test passed\n"); - return 0; - } - - - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/openfile.c nspr-4.10.7/mozilla/nsprpub/pr/tests/openfile.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/openfile.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/openfile.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This test calls PR_OpenFile to create a bunch of files - * with various file modes. - */ - -#include "prio.h" -#include "prerror.h" -#include "prinit.h" - -#include -#include - -#define TEMPLATE_FILE_NAME "template.txt" - -int main(int argc, char **argv) -{ - FILE *template; - char buf[32]; - PRInt32 nbytes; - PRFileDesc *fd; - - - /* Write in text mode. Let stdio deal with line endings. */ - template = fopen(TEMPLATE_FILE_NAME, "w"); - fputs("line 1\nline 2\n", template); - fclose(template); - - /* Read in binary mode */ - fd = PR_OpenFile(TEMPLATE_FILE_NAME, PR_RDONLY, 0666); - nbytes = PR_Read(fd, buf, sizeof(buf)); - PR_Close(fd); - PR_Delete(TEMPLATE_FILE_NAME); - - fd = PR_OpenFile("tfil0700.txt", PR_RDWR | PR_CREATE_FILE, 0700); - if (NULL == fd) { - fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - PR_Write(fd, buf, nbytes); - PR_Close(fd); - - fd = PR_OpenFile("tfil0500.txt", PR_RDWR | PR_CREATE_FILE, 0500); - if (NULL == fd) { - fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - PR_Write(fd, buf, nbytes); - PR_Close(fd); - - fd = PR_OpenFile("tfil0400.txt", PR_RDWR | PR_CREATE_FILE, 0400); - if (NULL == fd) { - fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - PR_Write(fd, buf, nbytes); - PR_Close(fd); - - fd = PR_OpenFile("tfil0644.txt", PR_RDWR | PR_CREATE_FILE, 0644); - if (NULL == fd) { - fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - PR_Write(fd, buf, nbytes); - PR_Close(fd); - - fd = PR_OpenFile("tfil0664.txt", PR_RDWR | PR_CREATE_FILE, 0664); - if (NULL == fd) { - fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - PR_Write(fd, buf, nbytes); - PR_Close(fd); - - fd = PR_OpenFile("tfil0660.txt", PR_RDWR | PR_CREATE_FILE, 0660); - if (NULL == fd) { - fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - PR_Write(fd, buf, nbytes); - PR_Close(fd); - - fd = PR_OpenFile("tfil0666.txt", PR_RDWR | PR_CREATE_FILE, 0666); - if (NULL == fd) { - fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - PR_Write(fd, buf, nbytes); - PR_Close(fd); - - fd = PR_OpenFile("tfil0640.txt", PR_RDWR | PR_CREATE_FILE, 0640); - if (NULL == fd) { - fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - PR_Write(fd, buf, nbytes); - PR_Close(fd); - - PR_Cleanup(); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/op_excl.c nspr-4.10.7/mozilla/nsprpub/pr/tests/op_excl.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/op_excl.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/op_excl.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: op_excl.c -** -** Description: Test Program to verify function of PR_EXCL open flag -** -** Modification History: -** 27-Oct-1999 lth. Initial version -***********************************************************************/ - -#include -#include -#include -#include - -/* -** Test harness infrastructure -*/ -PRLogModuleInfo *lm; -PRLogModuleLevel msgLevel = PR_LOG_NONE; -PRIntn debug = 0; -PRUint32 failed_already = 0; -/* end Test harness infrastructure */ -/* -** Emit help text for this test -*/ -static void Help( void ) -{ - printf("op_excl: Help"); - printf("op_excl [-d]"); - printf("-d enables debug messages"); - exit(1); -} /* end Help() */ - - - -int main(int argc, char **argv) -{ - PRFileDesc *fd; - PRStatus rv; - PRInt32 written; - char outBuf[] = "op_excl.c test file"; -#define OUT_SIZE sizeof(outBuf) -#define NEW_FILENAME "xxxExclNewFile" - - { - /* - ** Get command line options - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "hd"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug */ - debug = 1; - msgLevel = PR_LOG_ERROR; - break; - case 'h': /* help message */ - Help(); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - } - - lm = PR_NewLogModule("Test"); /* Initialize logging */ - - /* - ** First, open a file, PR_EXCL, we believe not to exist - */ - fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 ); - if ( NULL == fd ) { - if (debug) fprintf( stderr, "Open exclusive. Expected success, got failure\n"); - failed_already = 1; - goto Finished; - } - - written = PR_Write( fd, outBuf, OUT_SIZE ); - if ( OUT_SIZE != written ) { - if (debug) fprintf( stderr, "Write after open exclusive failed\n"); - failed_already = 1; - goto Finished; - } - - rv = PR_Close(fd); - if ( PR_FAILURE == rv ) { - if (debug) fprintf( stderr, "Close after open exclusive failed\n"); - failed_already = 1; - goto Finished; - } - - /* - ** Second, open the same file, PR_EXCL, expect it to fail - */ - fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 ); - if ( NULL != fd ) { - if (debug) fprintf( stderr, "Open exclusive. Expected failure, got success\n"); - failed_already = 1; - PR_Close(fd); - } - - rv = PR_Delete( NEW_FILENAME ); - if ( PR_FAILURE == rv ) { - if (debug) fprintf( stderr, "PR_Delete() failed\n"); - failed_already = 1; - } - -Finished: - if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); - return( (failed_already == PR_TRUE )? 1 : 0 ); -} /* main() */ -/* end op_excl.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/op_filnf.c nspr-4.10.7/mozilla/nsprpub/pr/tests/op_filnf.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/op_filnf.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/op_filnf.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: op_filnf.c -** -** Description: Test Program to verify the PR_FILE_NOT_FOUND_ERROR -** This test program also uses the TRUNCATE option -** -** Modification History: -** 03-June-97 AGarcia- Initial version -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "prinit.h" -#include "prmem.h" -#include "prio.h" -#include "prerror.h" -#include -#include "plgetopt.h" - -static PRFileDesc *t1; -PRIntn error_code; - -int main(int argc, char **argv) -{ - PR_STDIO_INIT(); - t1 = PR_Open("/usr/tmp/ttools/err03.tmp", PR_TRUNCATE | PR_RDWR, 0666); - if (t1 == NULL) { - if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) { - printf ("error code is %d \n", PR_GetError()); - printf ("PASS\n"); - return 0; - } - else { - printf ("error code is %d \n", PR_GetError()); - printf ("FAIL\n"); - return 1; - } - } - PR_Close(t1); - printf ("opened a file that should not exist\n"); - printf ("FAIL\n"); - return 1; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/op_filok.c nspr-4.10.7/mozilla/nsprpub/pr/tests/op_filok.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/op_filok.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/op_filok.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: op_filok.c -** -** Description: Test Program to verify the PR_Open finding an existing file. -** -** Modification History: -** 03-June-97 AGarcia- Initial version -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "prinit.h" -#include "prmem.h" -#include "prio.h" -#include "prerror.h" -#include - -static PRFileDesc *t1; - -int main(int argc, char **argv) -{ - PR_STDIO_INIT(); - - t1 = PR_Open(argv[0], PR_RDONLY, 0666); - - if (t1 == NULL) { - printf ("error code is %d \n", PR_GetError()); - printf ("File %s should be found\n", argv[0]); - return 1; - } else { - if (PR_Close(t1) == PR_SUCCESS) { - printf ("Test passed \n"); - return 0; - } else { - printf ("cannot close file\n"); - printf ("error code is %d\n", PR_GetError()); - return 1; - } - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/op_noacc.c nspr-4.10.7/mozilla/nsprpub/pr/tests/op_noacc.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/op_noacc.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/op_noacc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: op_noacc.c -** -** Description: Test Program to verify the PR_NO_ACCESS_RIGHTS_ERROR in PR_Open -** -** Modification History: -** 03-June-97 AGarcia- Initial version -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "prinit.h" -#include "prmem.h" -#include "prio.h" -#include "prerror.h" -#include -#include "plgetopt.h" - -static PRFileDesc *err01; -PRIntn error_code; - -int main(int argc, char **argv) -{ -#ifdef XP_PC - printf("op_noacc: Test not valid on MS-Windows.\n\tNo concept of 'mode' on Open() call\n"); - return(0); -#endif - - - PR_STDIO_INIT(); - err01 = PR_Open("err01.tmp", PR_CREATE_FILE | PR_RDWR, 0); - if (err01 == NULL) { - int error = PR_GetError(); - printf ("error code is %d\n", error); - if (error == PR_NO_ACCESS_RIGHTS_ERROR) { - printf ("PASS\n"); - return 0; - } - } - printf ("FAIL\n"); - return 1; -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/op_nofil.c nspr-4.10.7/mozilla/nsprpub/pr/tests/op_nofil.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/op_nofil.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/op_nofil.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: op_nofil.c -** -** Description: Test Program to verify the PR_FILE_NOT_FOUND_ERROR -** -** Modification History: -** 03-June-97 AGarcia- Initial version -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "prinit.h" -#include "prmem.h" -#include "prio.h" -#include "prerror.h" -#include -#include "plgetopt.h" - -/* - * A file name that cannot exist - */ -#define NO_SUCH_FILE "/no/such/file.tmp" - -static PRFileDesc *t1; - -int main(int argc, char **argv) -{ - PR_STDIO_INIT(); - t1 = PR_Open(NO_SUCH_FILE, PR_RDONLY, 0666); - if (t1 == NULL) { - if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) { - printf ("error code is PR_FILE_NOT_FOUND_ERROR, as expected\n"); - printf ("PASS\n"); - return 0; - } else { - printf ("error code is %d \n", PR_GetError()); - printf ("FAIL\n"); - return 1; - } - } - printf ("File %s exists on this machine!?\n", NO_SUCH_FILE); - if (PR_Close(t1) == PR_FAILURE) { - printf ("cannot close file\n"); - printf ("error code is %d \n", PR_GetError()); - } - printf ("FAIL\n"); - return 1; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/parent.c nspr-4.10.7/mozilla/nsprpub/pr/tests/parent.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/parent.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/parent.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** file: parent.c -** description: test the process machinery -*/ - -#include "prmem.h" -#include "prprf.h" -#include "prinit.h" -#include "prproces.h" -#include "prinrval.h" - -typedef struct Child -{ - const char *name; - char **argv; - PRProcess *process; - PRProcessAttr *attr; -} Child; - -/* for the default test 'cvar -c 2000' */ -static char *default_argv[] = {"cvar", "-c", "2000", NULL}; - -static void PrintUsage(void) -{ - PR_fprintf(PR_GetSpecialFD(PR_StandardError), - "Usage: parent [-d] child [options]\n"); -} - -int main(int argc, char **argv) -{ - PRStatus rv; - PRInt32 test_status = 1; - PRIntervalTime t_start, t_elapsed; - PRFileDesc *debug = NULL; - Child *child = PR_NEWZAP(Child); - - if (1 == argc) - { - /* no command-line arguments: run the default test */ - child->argv = default_argv; - } - else - { - argv += 1; /* don't care about our program name */ - while (*argv != NULL && argv[0][0] == '-') - { - if (argv[0][1] == 'd') - debug = PR_GetSpecialFD(PR_StandardError); - else - { - PrintUsage(); - return 2; /* not sufficient */ - } - argv += 1; - } - child->argv = argv; - } - - if (NULL == *child->argv) - { - PrintUsage(); - return 2; - } - - child->name = *child->argv; - if (NULL != debug) PR_fprintf(debug, "Forking %s\n", child->name); - - child->attr = PR_NewProcessAttr(); - PR_ProcessAttrSetStdioRedirect( - child->attr, PR_StandardOutput, - PR_GetSpecialFD(PR_StandardOutput)); - PR_ProcessAttrSetStdioRedirect( - child->attr, PR_StandardError, - PR_GetSpecialFD(PR_StandardError)); - - t_start = PR_IntervalNow(); - child->process = PR_CreateProcess( - child->name, child->argv, NULL, child->attr); - t_elapsed = (PRIntervalTime) (PR_IntervalNow() - t_start); - - PR_DestroyProcessAttr(child->attr); - - test_status = (NULL == child->process) ? 1 : 0; - if (NULL != debug) - { - PR_fprintf( - debug, "Child was %sforked\n", - (0 == test_status) ? "" : "NOT "); - if (0 == test_status) - PR_fprintf( - debug, "PR_CreateProcess took %lu microseconds\n", - PR_IntervalToMicroseconds(t_elapsed)); - } - - if (0 == test_status) - { - if (NULL != debug) PR_fprintf(debug, "Waiting for child to exit\n"); - rv = PR_WaitProcess(child->process, &test_status); - if (PR_SUCCESS == rv) - { - if (NULL != debug) - PR_fprintf( - debug, "Child exited %s\n", - (0 == test_status) ? "successfully" : "with error"); - } - else - { - test_status = 1; - if (NULL != debug) - PR_fprintf(debug, "PR_WaitProcess failed\n"); - } - } - PR_DELETE(child); - PR_Cleanup(); - return test_status; - -} /* main */ - -/* parent.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/parsetm.c nspr-4.10.7/mozilla/nsprpub/pr/tests/parsetm.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/parsetm.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/parsetm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This test program should eventually become a full-blown test for - * PR_ParseTimeString. Right now it just verifies that PR_ParseTimeString - * doesn't crash on an out-of-range time string (bug 480740). - */ - -#include "prtime.h" - -#include -#include -#include -#include - -PRBool debug_mode = PR_TRUE; - -static char *dayOfWeek[] = - { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; -static char *month[] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; - -static void PrintExplodedTime(const PRExplodedTime *et) { - PRInt32 totalOffset; - PRInt32 hourOffset, minOffset; - const char *sign; - - /* Print day of the week, month, day, hour, minute, and second */ - if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ", - dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, - et->tm_hour, et->tm_min, et->tm_sec); - - /* Print time zone */ - totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; - if (totalOffset == 0) { - if (debug_mode) printf("UTC "); - } else { - sign = "+"; - if (totalOffset < 0) { - totalOffset = -totalOffset; - sign = "-"; - } - hourOffset = totalOffset / 3600; - minOffset = (totalOffset % 3600) / 60; - if (debug_mode) - printf("%s%02ld%02ld ", sign, hourOffset, minOffset); - } - - /* Print year */ - if (debug_mode) printf("%hd", et->tm_year); -} - -int main(int argc, char **argv) -{ - PRTime ct; - PRExplodedTime et; - PRStatus rv; - char *sp1 = "Sat, 1 Jan 3001 00:00:00"; /* no time zone */ - char *sp2 = "Fri, 31 Dec 3000 23:59:60"; /* no time zone, not normalized */ - -#if _MSC_VER >= 1400 && !defined(WINCE) - /* Run this test in the US Pacific Time timezone. */ - _putenv_s("TZ", "PST8PDT"); - _tzset(); -#endif - - rv = PR_ParseTimeString(sp1, PR_FALSE, &ct); - printf("rv = %d\n", rv); - PR_ExplodeTime(ct, PR_GMTParameters, &et); - PrintExplodedTime(&et); - printf("\n"); - - rv = PR_ParseTimeString(sp2, PR_FALSE, &ct); - printf("rv = %d\n", rv); - PR_ExplodeTime(ct, PR_GMTParameters, &et); - PrintExplodedTime(&et); - printf("\n"); - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/peek.c nspr-4.10.7/mozilla/nsprpub/pr/tests/peek.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/peek.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/peek.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,360 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * A test case for the PR_MSG_PEEK flag of PR_Recv(). - * - * Test both blocking and non-blocking sockets. - */ - -#include "nspr.h" - -#include -#include -#include - -#define BUFFER_SIZE 1024 - -static int iterations = 10; - -/* - * In iteration i, recv_amount[i] is the number of bytes we - * wish to receive, and send_amount[i] is the number of bytes - * we actually send. Therefore, the number of elements in the - * recv_amount or send_amount array should equal to 'iterations'. - * For this test to pass we need to ensure that - * recv_amount[i] <= BUFFER_SIZE, - * send_amount[i] <= BUFFER_SIZE, - * send_amount[i] <= recv_amount[i]. - */ -static PRInt32 recv_amount[10] = { - 16, 128, 256, 1024, 512, 512, 128, 256, 32, 32}; -static PRInt32 send_amount[10] = { - 16, 64, 128, 1024, 512, 256, 128, 64, 16, 32}; - -/* Blocking I/O */ -static void ServerB(void *arg) -{ - PRFileDesc *listenSock = (PRFileDesc *) arg; - PRFileDesc *sock; - char buf[BUFFER_SIZE]; - PRInt32 nbytes; - int i; - int j; - - sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (NULL == sock) { - fprintf(stderr, "PR_Accept failed\n"); - exit(1); - } - - for (i = 0; i < iterations; i++) { - memset(buf, 0, sizeof(buf)); - nbytes = PR_Recv(sock, buf, recv_amount[i], - PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); - if (-1 == nbytes) { - fprintf(stderr, "PR_Recv failed\n"); - exit(1); - } - if (send_amount[i] != nbytes) { - fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); - exit(1); - } - for (j = 0; j < nbytes; j++) { - if (buf[j] != 2*i) { - fprintf(stderr, "byte %d should be %d but is %d\n", - j, 2*i, buf[j]); - exit(1); - } - } - fprintf(stderr, "server: peeked expected data\n"); - - memset(buf, 0, sizeof(buf)); - nbytes = PR_Recv(sock, buf, recv_amount[i], - PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); - if (-1 == nbytes) { - fprintf(stderr, "PR_Recv failed\n"); - exit(1); - } - if (send_amount[i] != nbytes) { - fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); - exit(1); - } - for (j = 0; j < nbytes; j++) { - if (buf[j] != 2*i) { - fprintf(stderr, "byte %d should be %d but is %d\n", - j, 2*i, buf[j]); - exit(1); - } - } - fprintf(stderr, "server: peeked expected data\n"); - - memset(buf, 0, sizeof(buf)); - nbytes = PR_Recv(sock, buf, recv_amount[i], - 0, PR_INTERVAL_NO_TIMEOUT); - if (-1 == nbytes) { - fprintf(stderr, "PR_Recv failed\n"); - exit(1); - } - if (send_amount[i] != nbytes) { - fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); - exit(1); - } - for (j = 0; j < nbytes; j++) { - if (buf[j] != 2*i) { - fprintf(stderr, "byte %d should be %d but is %d\n", - j, 2*i, buf[j]); - exit(1); - } - } - fprintf(stderr, "server: received expected data\n"); - - PR_Sleep(PR_SecondsToInterval(1)); - memset(buf, 2*i+1, send_amount[i]); - nbytes = PR_Send(sock, buf, send_amount[i], - 0, PR_INTERVAL_NO_TIMEOUT); - if (-1 == nbytes) { - fprintf(stderr, "PR_Send failed\n"); - exit(1); - } - if (send_amount[i] != nbytes) { - fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes); - exit(1); - } - } - if (PR_Close(sock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } -} - -/* Non-blocking I/O */ -static void ClientNB(void *arg) -{ - PRFileDesc *sock; - PRSocketOptionData opt; - PRUint16 port = (PRUint16) arg; - PRNetAddr addr; - char buf[BUFFER_SIZE]; - PRPollDesc pd; - PRInt32 npds; - PRInt32 nbytes; - int i; - int j; - - sock = PR_OpenTCPSocket(PR_AF_INET6); - if (NULL == sock) { - fprintf(stderr, "PR_OpenTCPSocket failed\n"); - exit(1); - } - opt.option = PR_SockOpt_Nonblocking; - opt.value.non_blocking = PR_TRUE; - if (PR_SetSocketOption(sock, &opt) == PR_FAILURE) { - fprintf(stderr, "PR_SetSocketOption failed\n"); - exit(1); - } - memset(&addr, 0, sizeof(addr)); - if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, port, &addr) - == PR_FAILURE) { - fprintf(stderr, "PR_SetNetAddr failed\n"); - exit(1); - } - if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { - if (PR_GetError() != PR_IN_PROGRESS_ERROR) { - fprintf(stderr, "PR_Connect failed\n"); - exit(1); - } - pd.fd = sock; - pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; - npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (-1 == npds) { - fprintf(stderr, "PR_Poll failed\n"); - exit(1); - } - if (1 != npds) { - fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); - exit(1); - } - if (PR_GetConnectStatus(&pd) == PR_FAILURE) { - fprintf(stderr, "PR_GetConnectStatus failed\n"); - exit(1); - } - } - - for (i = 0; i < iterations; i++) { - PR_Sleep(PR_SecondsToInterval(1)); - memset(buf, 2*i, send_amount[i]); - while ((nbytes = PR_Send(sock, buf, send_amount[i], - 0, PR_INTERVAL_NO_TIMEOUT)) == -1) { - if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { - fprintf(stderr, "PR_Send failed\n"); - exit(1); - } - pd.fd = sock; - pd.in_flags = PR_POLL_WRITE; - npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (-1 == npds) { - fprintf(stderr, "PR_Poll failed\n"); - exit(1); - } - if (1 != npds) { - fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); - exit(1); - } - } - if (send_amount[i] != nbytes) { - fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes); - exit(1); - } - - memset(buf, 0, sizeof(buf)); - while ((nbytes = PR_Recv(sock, buf, recv_amount[i], - PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT)) == -1) { - if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { - fprintf(stderr, "PR_Recv failed\n"); - exit(1); - } - pd.fd = sock; - pd.in_flags = PR_POLL_READ; - npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (-1 == npds) { - fprintf(stderr, "PR_Poll failed\n"); - exit(1); - } - if (1 != npds) { - fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); - exit(1); - } - } - if (send_amount[i] != nbytes) { - fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); - exit(1); - } - for (j = 0; j < nbytes; j++) { - if (buf[j] != 2*i+1) { - fprintf(stderr, "byte %d should be %d but is %d\n", - j, 2*i+1, buf[j]); - exit(1); - } - } - fprintf(stderr, "client: peeked expected data\n"); - - memset(buf, 0, sizeof(buf)); - nbytes = PR_Recv(sock, buf, recv_amount[i], - PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); - if (-1 == nbytes) { - fprintf(stderr, "PR_Recv failed\n"); - exit(1); - } - if (send_amount[i] != nbytes) { - fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); - exit(1); - } - for (j = 0; j < nbytes; j++) { - if (buf[j] != 2*i+1) { - fprintf(stderr, "byte %d should be %d but is %d\n", - j, 2*i+1, buf[j]); - exit(1); - } - } - fprintf(stderr, "client: peeked expected data\n"); - - memset(buf, 0, sizeof(buf)); - nbytes = PR_Recv(sock, buf, recv_amount[i], - 0, PR_INTERVAL_NO_TIMEOUT); - if (-1 == nbytes) { - fprintf(stderr, "PR_Recv failed\n"); - exit(1); - } - if (send_amount[i] != nbytes) { - fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); - exit(1); - } - for (j = 0; j < nbytes; j++) { - if (buf[j] != 2*i+1) { - fprintf(stderr, "byte %d should be %d but is %d\n", - j, 2*i+1, buf[j]); - exit(1); - } - } - fprintf(stderr, "client: received expected data\n"); - } - if (PR_Close(sock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } -} - -static void -RunTest(PRThreadScope scope, PRFileDesc *listenSock, PRUint16 port) -{ - PRThread *server, *client; - - server = PR_CreateThread(PR_USER_THREAD, ServerB, listenSock, - PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); - if (NULL == server) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - client = PR_CreateThread( - PR_USER_THREAD, ClientNB, (void *) port, - PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); - if (NULL == client) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - - if (PR_JoinThread(server) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - if (PR_JoinThread(client) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } -} - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock; - PRNetAddr addr; - PRUint16 port; - - listenSock = PR_OpenTCPSocket(PR_AF_INET6); - if (NULL == listenSock) { - fprintf(stderr, "PR_OpenTCPSocket failed\n"); - exit(1); - } - memset(&addr, 0, sizeof(addr)); - if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_SetNetAddr failed\n"); - exit(1); - } - if (PR_Bind(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_Bind failed\n"); - exit(1); - } - if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - exit(1); - } - port = PR_ntohs(addr.ipv6.port); - if (PR_Listen(listenSock, 5) == PR_FAILURE) { - fprintf(stderr, "PR_Listen failed\n"); - exit(1); - } - - fprintf(stderr, "Running the test with local threads\n"); - RunTest(PR_LOCAL_THREAD, listenSock, port); - fprintf(stderr, "Running the test with global threads\n"); - RunTest(PR_GLOBAL_THREAD, listenSock, port); - - if (PR_Close(listenSock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/perf.c nspr-4.10.7/mozilla/nsprpub/pr/tests/perf.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/perf.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/perf.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,442 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "plgetopt.h" - -#include -#include -#include - -int _debug_on = 0; -#define DPRINTF(arg) if (_debug_on) printf arg - -#include "obsolete/prsem.h" - -PRLock *lock; -PRMonitor *mon; -PRMonitor *mon2; - -#define DEFAULT_COUNT 1000 - -PRInt32 count; - -static void nop(int a, int b, int c) -{ -} - -static void LocalProcedureCall(void) -{ - PRInt32 i; - - for (i = 0; i < count; i++) { - nop(i, i, 5); - } -} - -static void DLLProcedureCall(void) -{ - PRInt32 i; - PRThreadState state; - PRThread *self = PR_GetCurrentThread(); - - for (i = 0; i < count; i++) { - state = PR_GetThreadState(self); - } -} - -static void Now(void) -{ - PRInt32 i; - PRTime time; - - for (i = 0; i < count; i++) { - time = PR_Now(); - } -} - -static void Interval(void) -{ - PRInt32 i; - PRIntervalTime time; - - for (i = 0; i < count; i++) { - time = PR_IntervalNow(); - } -} - -static void IdleLock(void) -{ - PRInt32 i; - - for (i = 0; i < count; i++) { - PR_Lock(lock); - PR_Unlock(lock); - } -} - -static void IdleMonitor(void) -{ - PRInt32 i; - - for (i = 0; i < count; i++) { - PR_EnterMonitor(mon); - PR_ExitMonitor(mon); - } -} - -static void IdleCMonitor(void) -{ - PRInt32 i; - - for (i = 0; i < count; i++) { - PR_CEnterMonitor((void*)7); - PR_CExitMonitor((void*)7); - } -} - -/************************************************************************/ - -static void PR_CALLBACK dull(void *arg) -{ -} - -static void CDThread(void) -{ - PRInt32 i; - int num_threads = count; - - /* - * Cannot create too many threads - */ - if (num_threads > 1000) - num_threads = 1000; - - for (i = 0; i < num_threads; i++) { - PRThread *t = PR_CreateThread(PR_USER_THREAD, - dull, 0, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - if (NULL == t) { - fprintf(stderr, "CDThread: cannot create thread %3d\n", i); - } else { - DPRINTF(("CDThread: created thread %3d \n",i)); - } - PR_Sleep(0); - } -} - -static int alive; -static int cxq; - -static void PR_CALLBACK CXReader(void *arg) -{ - PRInt32 i, n; - - PR_EnterMonitor(mon); - n = count / 2; - for (i = 0; i < n; i++) { - while (cxq == 0) { - DPRINTF(("CXReader: thread = 0x%lx waiting\n", - PR_GetCurrentThread())); - PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); - } - --cxq; - PR_Notify(mon); - } - PR_ExitMonitor(mon); - - PR_EnterMonitor(mon2); - --alive; - PR_Notify(mon2); - PR_ExitMonitor(mon2); - DPRINTF(("CXReader: thread = 0x%lx exiting\n", PR_GetCurrentThread())); -} - -static void PR_CALLBACK CXWriter(void *arg) -{ - PRInt32 i, n; - - PR_EnterMonitor(mon); - n = count / 2; - for (i = 0; i < n; i++) { - while (cxq == 1) { - DPRINTF(("CXWriter: thread = 0x%lx waiting\n", - PR_GetCurrentThread())); - PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); - } - ++cxq; - PR_Notify(mon); - } - PR_ExitMonitor(mon); - - PR_EnterMonitor(mon2); - --alive; - PR_Notify(mon2); - PR_ExitMonitor(mon2); - DPRINTF(("CXWriter: thread = 0x%lx exiting\n", PR_GetCurrentThread())); -} - -static void ContextSwitch(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *t1, *t2; - - PR_EnterMonitor(mon2); - alive = 2; - cxq = 0; - - t1 = PR_CreateThread(PR_USER_THREAD, - CXReader, 0, - PR_PRIORITY_NORMAL, - scope1, - PR_UNJOINABLE_THREAD, - 0); - if (NULL == t1) { - fprintf(stderr, "ContextSwitch: cannot create thread\n"); - } else { - DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n", - (scope1 == PR_GLOBAL_THREAD ? - "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"), - t1)); - } - t2 = PR_CreateThread(PR_USER_THREAD, - CXWriter, 0, - PR_PRIORITY_NORMAL, - scope2, - PR_UNJOINABLE_THREAD, - 0); - if (NULL == t2) { - fprintf(stderr, "ContextSwitch: cannot create thread\n"); - } else { - DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n", - (scope2 == PR_GLOBAL_THREAD ? - "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"), - t2)); - } - - /* Wait for both of the threads to exit */ - while (alive) { - PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); - } - PR_ExitMonitor(mon2); -} - -static void ContextSwitchUU(void) -{ - ContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD); -} - -static void ContextSwitchUK(void) -{ - ContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); -} - -static void ContextSwitchKU(void) -{ - ContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); -} - -static void ContextSwitchKK(void) -{ - ContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); -} - -/************************************************************************/ - -static void PR_CALLBACK SemaThread(void *argSema) -{ - PRSemaphore **sem = (PRSemaphore **)argSema; - PRInt32 i, n; - - n = count / 2; - for (i = 0; i < n; i++) { - DPRINTF(("SemaThread: thread = 0x%lx waiting on sem = 0x%lx\n", - PR_GetCurrentThread(), sem[0])); - PR_WaitSem(sem[0]); - DPRINTF(("SemaThread: thread = 0x%lx posting on sem = 0x%lx\n", - PR_GetCurrentThread(), sem[1])); - PR_PostSem(sem[1]); - } - - PR_EnterMonitor(mon2); - --alive; - PR_Notify(mon2); - PR_ExitMonitor(mon2); - DPRINTF(("SemaThread: thread = 0x%lx exiting\n", PR_GetCurrentThread())); -} - -static PRSemaphore *sem_set1[2]; -static PRSemaphore *sem_set2[2]; - -static void SemaContextSwitch(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *t1, *t2; - sem_set1[0] = PR_NewSem(1); - sem_set1[1] = PR_NewSem(0); - sem_set2[0] = sem_set1[1]; - sem_set2[1] = sem_set1[0]; - - PR_EnterMonitor(mon2); - alive = 2; - cxq = 0; - - t1 = PR_CreateThread(PR_USER_THREAD, - SemaThread, - sem_set1, - PR_PRIORITY_NORMAL, - scope1, - PR_UNJOINABLE_THREAD, - 0); - if (NULL == t1) { - fprintf(stderr, "SemaContextSwitch: cannot create thread\n"); - } else { - DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n", - (scope1 == PR_GLOBAL_THREAD ? - "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"), - t1)); - } - t2 = PR_CreateThread(PR_USER_THREAD, - SemaThread, - sem_set2, - PR_PRIORITY_NORMAL, - scope2, - PR_UNJOINABLE_THREAD, - 0); - if (NULL == t2) { - fprintf(stderr, "SemaContextSwitch: cannot create thread\n"); - } else { - DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n", - (scope2 == PR_GLOBAL_THREAD ? - "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"), - t2)); - } - - /* Wait for both of the threads to exit */ - while (alive) { - PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); - } - PR_ExitMonitor(mon2); - - PR_DestroySem(sem_set1[0]); - PR_DestroySem(sem_set1[1]); -} - -static void SemaContextSwitchUU(void) -{ - SemaContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD); -} - -static void SemaContextSwitchUK(void) -{ - SemaContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); -} - -static void SemaContextSwitchKU(void) -{ - SemaContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); -} - -static void SemaContextSwitchKK(void) -{ - SemaContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); -} - - -/************************************************************************/ - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow() - start; - d = (double)PR_IntervalToMicroseconds(stop); - - printf("%40s: %6.2f usec\n", msg, d / count); -} - -int main(int argc, char **argv) -{ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dc:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - case 'c': /* loop count */ - count = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (0 == count) count = DEFAULT_COUNT; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_BlockClockInterrupts(); - PR_UnblockClockInterrupts(); - PR_STDIO_INIT(); - - lock = PR_NewLock(); - mon = PR_NewMonitor(); - mon2 = PR_NewMonitor(); - - Measure(LocalProcedureCall, "local procedure call overhead"); - Measure(DLLProcedureCall, "DLL procedure call overhead"); - Measure(Now, "current calendar time"); - Measure(Interval, "interval time"); - Measure(IdleLock, "idle lock lock/unlock pair"); - Measure(IdleMonitor, "idle monitor entry/exit pair"); - Measure(IdleCMonitor, "idle cache monitor entry/exit pair"); - Measure(CDThread, "create/destroy thread pair"); - Measure(ContextSwitchUU, "context switch - user/user"); - Measure(ContextSwitchUK, "context switch - user/kernel"); - Measure(ContextSwitchKU, "context switch - kernel/user"); - Measure(ContextSwitchKK, "context switch - kernel/kernel"); - Measure(SemaContextSwitchUU, "sema context switch - user/user"); - Measure(SemaContextSwitchUK, "sema context switch - user/kernel"); - Measure(SemaContextSwitchKU, "sema context switch - kernel/user"); - Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel"); - - printf("--------------\n"); - printf("Adding 7 additional CPUs\n"); - - PR_SetConcurrency(8); - printf("--------------\n"); - - Measure(LocalProcedureCall, "local procedure call overhead"); - Measure(DLLProcedureCall, "DLL procedure call overhead"); - Measure(Now, "current calendar time"); - Measure(Interval, "interval time"); - Measure(IdleLock, "idle lock lock/unlock pair"); - Measure(IdleMonitor, "idle monitor entry/exit pair"); - Measure(IdleCMonitor, "idle cache monitor entry/exit pair"); - Measure(CDThread, "create/destroy thread pair"); - Measure(ContextSwitchUU, "context switch - user/user"); - Measure(ContextSwitchUK, "context switch - user/kernel"); - Measure(ContextSwitchKU, "context switch - kernel/user"); - Measure(ContextSwitchKK, "context switch - kernel/kernel"); - Measure(SemaContextSwitchUU, "sema context switch - user/user"); - Measure(SemaContextSwitchUK, "sema context switch - user/kernel"); - Measure(SemaContextSwitchKU, "sema context switch - kernel/user"); - Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel"); - - PR_DestroyLock(lock); - PR_DestroyMonitor(mon); - PR_DestroyMonitor(mon2); - - PR_Cleanup(); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/pipeping2.c nspr-4.10.7/mozilla/nsprpub/pr/tests/pipeping2.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/pipeping2.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/pipeping2.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: pipeping2.c - * - * Description: - * This test runs in conjunction with the pipepong2 test. - * This test creates two pipes and passes two pipe fd's - * to the pipepong2 test. Then this test writes "ping" to - * to the pipepong2 test and the pipepong2 test writes "pong" - * back. To run this pair of tests, just invoke pipeping2. - * - * Tested areas: process creation, pipes, file descriptor - * inheritance. - */ - -#include "prerror.h" -#include "prio.h" -#include "prproces.h" - -#include -#include -#include - -#define NUM_ITERATIONS 10 - -static char *child_argv[] = { "pipepong2", NULL }; - -int main(int argc, char **argv) -{ - PRFileDesc *in_pipe[2]; - PRFileDesc *out_pipe[2]; - PRStatus status; - PRProcess *process; - PRProcessAttr *attr; - char buf[1024]; - PRInt32 nBytes; - PRInt32 exitCode; - int idx; - - status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_CreatePipe failed\n"); - exit(1); - } - status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_CreatePipe failed\n"); - exit(1); - } - - status = PR_SetFDInheritable(in_pipe[0], PR_FALSE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - status = PR_SetFDInheritable(in_pipe[1], PR_TRUE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - status = PR_SetFDInheritable(out_pipe[0], PR_TRUE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - status = PR_SetFDInheritable(out_pipe[1], PR_FALSE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - - attr = PR_NewProcessAttr(); - if (attr == NULL) { - fprintf(stderr, "PR_NewProcessAttr failed\n"); - exit(1); - } - - status = PR_ProcessAttrSetInheritableFD(attr, out_pipe[0], "PIPE_READ"); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); - exit(1); - } - status = PR_ProcessAttrSetInheritableFD(attr, in_pipe[1], "PIPE_WRITE"); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); - exit(1); - } - - process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr); - if (process == NULL) { - fprintf(stderr, "PR_CreateProcess failed\n"); - exit(1); - } - PR_DestroyProcessAttr(attr); - status = PR_Close(out_pipe[0]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(in_pipe[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - - for (idx = 0; idx < NUM_ITERATIONS; idx++) { - strcpy(buf, "ping"); - printf("ping process: sending \"%s\"\n", buf); - nBytes = PR_Write(out_pipe[1], buf, 5); - if (nBytes == -1) { - fprintf(stderr, "PR_Write failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - memset(buf, 0, sizeof(buf)); - nBytes = PR_Read(in_pipe[0], buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed\n"); - exit(1); - } - printf("ping process: received \"%s\"\n", buf); - if (nBytes != 5) { - fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n", - nBytes); - exit(1); - } - if (strcmp(buf, "pong") != 0) { - fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", - buf); - exit(1); - } - } - - status = PR_Close(in_pipe[0]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(out_pipe[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_WaitProcess(process, &exitCode); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_WaitProcess failed\n"); - exit(1); - } - if (exitCode == 0) { - printf("PASS\n"); - return 0; - } else { - printf("FAIL\n"); - return 1; - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/pipeping.c nspr-4.10.7/mozilla/nsprpub/pr/tests/pipeping.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/pipeping.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/pipeping.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,158 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: pipeping.c - * - * Description: - * This test runs in conjunction with the pipepong test. - * This test creates two pipes and redirects the stdin and - * stdout of the pipepong test to the pipes. Then this - * test writes "ping" to the pipepong test and the pipepong - * test writes "pong" back. To run this pair of tests, - * just invoke pipeping. - * - * Tested areas: process creation, pipes, file descriptor - * inheritance, standard I/O redirection. - */ - -#include "prerror.h" -#include "prio.h" -#include "prproces.h" - -#include -#include -#include - -#ifdef XP_OS2 -static char *child_argv[] = { "pipepong.exe", NULL }; -#else -static char *child_argv[] = { "pipepong", NULL }; -#endif - -#define NUM_ITERATIONS 10 - -int main(int argc, char **argv) -{ - PRFileDesc *in_pipe[2]; - PRFileDesc *out_pipe[2]; - PRStatus status; - PRProcess *process; - PRProcessAttr *attr; - char buf[1024]; - PRInt32 nBytes; - PRInt32 exitCode; - int idx; - - status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_CreatePipe failed\n"); - exit(1); - } - status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_CreatePipe failed\n"); - exit(1); - } - - status = PR_SetFDInheritable(in_pipe[0], PR_FALSE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - status = PR_SetFDInheritable(in_pipe[1], PR_TRUE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - status = PR_SetFDInheritable(out_pipe[0], PR_TRUE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - status = PR_SetFDInheritable(out_pipe[1], PR_FALSE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - - attr = PR_NewProcessAttr(); - if (attr == NULL) { - fprintf(stderr, "PR_NewProcessAttr failed\n"); - exit(1); - } - - PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, out_pipe[0]); - PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, in_pipe[1]); - - process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr); - if (process == NULL) { - fprintf(stderr, "PR_CreateProcess failed\n"); - exit(1); - } - PR_DestroyProcessAttr(attr); - status = PR_Close(out_pipe[0]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(in_pipe[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - - for (idx = 0; idx < NUM_ITERATIONS; idx++) { - strcpy(buf, "ping"); - printf("ping process: sending \"%s\"\n", buf); - nBytes = PR_Write(out_pipe[1], buf, 5); - if (nBytes == -1) { - fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - exit(1); - } - memset(buf, 0, sizeof(buf)); - nBytes = PR_Read(in_pipe[0], buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - printf("ping process: received \"%s\"\n", buf); - if (nBytes != 5) { - fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n", - nBytes); - exit(1); - } - if (strcmp(buf, "pong") != 0) { - fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", - buf); - exit(1); - } - } - - status = PR_Close(in_pipe[0]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(out_pipe[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_WaitProcess(process, &exitCode); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_WaitProcess failed\n"); - exit(1); - } - if (exitCode == 0) { - printf("PASS\n"); - return 0; - } else { - printf("FAIL\n"); - return 1; - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/pipepong2.c nspr-4.10.7/mozilla/nsprpub/pr/tests/pipepong2.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/pipepong2.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/pipepong2.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: pipepong2.c - * - * Description: - * This test runs in conjunction with the pipeping2 test. - * The pipeping2 test creates two pipes and passes two - * pipe fd's to this test. Then the pipeping2 test writes - * "ping" to this test and this test writes "pong" back. - * To run this pair of tests, just invoke pipeping2. - * - * Tested areas: process creation, pipes, file descriptor - * inheritance. - */ - -#include "prerror.h" -#include "prio.h" - -#include -#include -#include - -#define NUM_ITERATIONS 10 - -int main(int argc, char **argv) -{ - PRFileDesc *pipe_read, *pipe_write; - PRStatus status; - char buf[1024]; - PRInt32 nBytes; - int idx; - - pipe_read = PR_GetInheritedFD("PIPE_READ"); - if (pipe_read == NULL) { - fprintf(stderr, "PR_GetInheritedFD failed\n"); - exit(1); - } - status = PR_SetFDInheritable(pipe_read, PR_FALSE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - pipe_write = PR_GetInheritedFD("PIPE_WRITE"); - if (pipe_write == NULL) { - fprintf(stderr, "PR_GetInheritedFD failed\n"); - exit(1); - } - status = PR_SetFDInheritable(pipe_write, PR_FALSE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - - for (idx = 0; idx < NUM_ITERATIONS; idx++) { - memset(buf, 0, sizeof(buf)); - nBytes = PR_Read(pipe_read, buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - printf("pong process: received \"%s\"\n", buf); - if (nBytes != 5) { - fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n", - nBytes); - exit(1); - } - if (strcmp(buf, "ping") != 0) { - fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n", - buf); - exit(1); - } - - strcpy(buf, "pong"); - printf("pong process: sending \"%s\"\n", buf); - nBytes = PR_Write(pipe_write, buf, 5); - if (nBytes == -1) { - fprintf(stderr, "PR_Write failed\n"); - exit(1); - } - } - - status = PR_Close(pipe_read); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(pipe_write); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/pipepong.c nspr-4.10.7/mozilla/nsprpub/pr/tests/pipepong.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/pipepong.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/pipepong.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: pipepong.c - * - * Description: - * This test runs in conjunction with the pipeping test. - * The pipeping test creates two pipes and redirects the - * stdin and stdout of this test to the pipes. Then the - * pipeping test writes "ping" to this test and this test - * writes "pong" back. Note that this test does not depend - * on NSPR at all. To run this pair of tests, just invoke - * pipeping. - * - * Tested areas: process creation, pipes, file descriptor - * inheritance, standard I/O redirection. - */ - -#include -#include -#include - -#define NUM_ITERATIONS 10 - -int main(int argc, char **argv) -{ - char buf[1024]; - size_t nBytes; - int idx; - - for (idx = 0; idx < NUM_ITERATIONS; idx++) { - memset(buf, 0, sizeof(buf)); - nBytes = fread(buf, 1, 5, stdin); - fprintf(stderr, "pong process: received \"%s\"\n", buf); - if (nBytes != 5) { - fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n", - nBytes); - exit(1); - } - if (strcmp(buf, "ping") != 0) { - fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n", - buf); - exit(1); - } - - strcpy(buf, "pong"); - fprintf(stderr, "pong process: sending \"%s\"\n", buf); - nBytes = fwrite(buf, 1, 5, stdout); - if (nBytes != 5) { - fprintf(stderr, "pong process: fwrite failed\n"); - exit(1); - } - fflush(stdout); - } - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/pipeself.c nspr-4.10.7/mozilla/nsprpub/pr/tests/pipeself.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/pipeself.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/pipeself.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,228 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: pipeself.c - * - * Description: - * This test has two threads communicating with each other using - * two unidirectional pipes. The primordial thread is the ping - * thread and the other thread is the pong thread. The ping - * thread writes "ping" to the pong thread and the pong thread - * writes "pong" back. - */ - -#include "prio.h" -#include "prerror.h" -#include "prthread.h" - -#include -#include -#include - -#define NUM_ITERATIONS 10 - -static PRFileDesc *ping_in, *ping_out; -static PRFileDesc *pong_in, *pong_out; - -static void PongThreadFunc(void *arg) -{ - char buf[1024]; - int idx; - PRInt32 nBytes; - PRStatus status; - - for (idx = 0; idx < NUM_ITERATIONS; idx++) { - memset(buf, 0, sizeof(buf)); - nBytes = PR_Read(pong_in, buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed\n"); - exit(1); - } - printf("pong thread: received \"%s\"\n", buf); - if (nBytes != 5) { - fprintf(stderr, "pong thread: expected 5 bytes but got %d bytes\n", - nBytes); - exit(1); - } - if (strcmp(buf, "ping") != 0) { - fprintf(stderr, "pong thread: expected \"ping\" but got \"%s\"\n", - buf); - exit(1); - } - strcpy(buf, "pong"); - printf("pong thread: sending \"%s\"\n", buf); - nBytes = PR_Write(pong_out, buf, 5); - if (nBytes == -1) { - fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - exit(1); - } - } - - status = PR_Close(pong_in); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(pong_out); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } -} - -int main(int argc, char **argv) -{ - PRStatus status; - PRThread *pongThread; - char buf[1024]; - PRInt32 nBytes; - int idx; - - status = PR_CreatePipe(&ping_in, &pong_out); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_CreatePipe failed\n"); - exit(1); - } - status = PR_CreatePipe(&pong_in, &ping_out); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_CreatePipe failed\n"); - exit(1); - } - - pongThread = PR_CreateThread(PR_USER_THREAD, PongThreadFunc, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (pongThread == NULL) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - - for (idx = 0; idx < NUM_ITERATIONS; idx++) { - strcpy(buf, "ping"); - printf("ping thread: sending \"%s\"\n", buf); - nBytes = PR_Write(ping_out, buf, 5); - if (nBytes == -1) { - fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - exit(1); - } - memset(buf, 0, sizeof(buf)); - nBytes = PR_Read(ping_in, buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed\n"); - exit(1); - } - printf("ping thread: received \"%s\"\n", buf); - if (nBytes != 5) { - fprintf(stderr, "ping thread: expected 5 bytes but got %d bytes\n", - nBytes); - exit(1); - } - if (strcmp(buf, "pong") != 0) { - fprintf(stderr, "ping thread: expected \"pong\" but got \"%s\"\n", - buf); - exit(1); - } - } - - status = PR_Close(ping_in); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(ping_out); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_JoinThread(pongThread); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - -#if defined(XP_UNIX) && !defined(SYMBIAN) - /* - * Test PR_Available for pipes - */ - status = PR_CreatePipe(&ping_in, &ping_out); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_CreatePipe failed\n"); - exit(1); - } - nBytes = PR_Write(ping_out, buf, 250); - if (nBytes == -1) { - fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - exit(1); - } - nBytes = PR_Available(ping_in); - if (nBytes < 0) { - fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - exit(1); - } else if (nBytes != 250) { - fprintf(stderr, "PR_Available: expected 250 bytes but got %d bytes\n", - nBytes); - exit(1); - } - printf("PR_Available: expected %d, got %d bytes\n",250, nBytes); - /* read some data */ - nBytes = PR_Read(ping_in, buf, 7); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed\n"); - exit(1); - } - /* check available data */ - nBytes = PR_Available(ping_in); - if (nBytes < 0) { - fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - exit(1); - } else if (nBytes != (250 - 7)) { - fprintf(stderr, "PR_Available: expected 243 bytes but got %d bytes\n", - nBytes); - exit(1); - } - printf("PR_Available: expected %d, got %d bytes\n",243, nBytes); - /* read all data */ - nBytes = PR_Read(ping_in, buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed\n"); - exit(1); - } else if (nBytes != 243) { - fprintf(stderr, "PR_Read failed: expected %d, got %d bytes\n", - 243, nBytes); - exit(1); - } - /* check available data */ - nBytes = PR_Available(ping_in); - if (nBytes < 0) { - fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - exit(1); - } else if (nBytes != 0) { - fprintf(stderr, "PR_Available: expected 0 bytes but got %d bytes\n", - nBytes); - exit(1); - } - printf("PR_Available: expected %d, got %d bytes\n", 0, nBytes); - - status = PR_Close(ping_in); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_Close(ping_out); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } -#endif /* XP_UNIX */ - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/pollable.c nspr-4.10.7/mozilla/nsprpub/pr/tests/pollable.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/pollable.c 2012-03-06 13:14:29.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/pollable.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * A test for the pollable events. - * - * A number of threads are in a ring configuration, each waiting on - * a pollable event that is set by its upstream neighbor. - */ - -#include "prinit.h" -#include "prio.h" -#include "prthread.h" -#include "prerror.h" -#include "prmem.h" -#include "prlog.h" -#include "prprf.h" - -#include "plgetopt.h" - -#include - -#define DEFAULT_THREADS 10 -#define DEFAULT_LOOPS 100 - -PRIntn numThreads = DEFAULT_THREADS; -PRIntn numIterations = DEFAULT_LOOPS; -PRIntervalTime dally = PR_INTERVAL_NO_WAIT; -PRFileDesc *debug_out = NULL; -PRBool debug_mode = PR_FALSE; -PRBool verbosity = PR_FALSE; - -typedef struct ThreadData { - PRFileDesc *event; - int index; - struct ThreadData *next; -} ThreadData; - -void ThreadRoutine(void *arg) -{ - ThreadData *data = (ThreadData *) arg; - PRIntn i; - PRPollDesc pd; - PRInt32 rv; - - pd.fd = data->event; - pd.in_flags = PR_POLL_READ; - - for (i = 0; i < numIterations; i++) { - rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (rv == -1) { - PR_fprintf(PR_STDERR, "PR_Poll failed\n"); - exit(1); - } - if (verbosity) { - PR_fprintf(debug_out, "thread %d awakened\n", data->index); - } - PR_ASSERT(rv != 0); - PR_ASSERT(pd.out_flags & PR_POLL_READ); - if (PR_WaitForPollableEvent(data->event) == PR_FAILURE) { - PR_fprintf(PR_STDERR, "consume event failed\n"); - exit(1); - } - if (dally != PR_INTERVAL_NO_WAIT) { - PR_Sleep(dally); - } - if (verbosity) { - PR_fprintf(debug_out, "thread %d posting event\n", data->index); - } - if (PR_SetPollableEvent(data->next->event) == PR_FAILURE) { - PR_fprintf(PR_STDERR, "post event failed\n"); - exit(1); - } - } -} - -static void Help(void) -{ - debug_out = PR_STDOUT; - - PR_fprintf( - debug_out, "Usage: pollable [-c n] [-t n] [-d] [-v] [-G] [-C n] [-D n]\n"); - PR_fprintf( - debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS); - PR_fprintf( - debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS); - PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n"); - PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n"); - PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n"); - PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n"); - PR_fprintf(debug_out, "-D n\tdally setting (msecs) (default: 0)\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - ThreadData selfData; - ThreadData *data; - PRThread **thread; - void *block; - PRIntn i; - PRIntervalTime timeStart, timeEnd; - PRPollDesc pd; - PRInt32 rv; - PRThreadScope thread_scope = PR_LOCAL_THREAD; - PRBool help = PR_FALSE; - PRUintn concurrency = 1; - PRUintn average; - PLOptStatus os; - PLOptState *opt; - - PR_STDIO_INIT(); - - opt = PL_CreateOptState(argc, argv, "hdvc:t:C:GD:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) { - continue; - } - switch (opt->option) { - case 'v': /* verbose mode */ - verbosity = PR_TRUE; - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'c': /* loop counter */ - numIterations = atoi(opt->value); - break; - case 't': /* thread limit */ - numThreads = atoi(opt->value); - break; - case 'C': /* Concurrency limit */ - concurrency = atoi(opt->value); - break; - case 'G': /* global threads only */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'D': /* dally */ - dally = PR_MillisecondsToInterval(atoi(opt->value)); - break; - case 'h': /* help message */ - Help(); - help = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (help) { - return 1; - } - - if (concurrency > 1) { - PR_SetConcurrency(concurrency); - } - - if (PR_TRUE == debug_mode) { - debug_out = PR_STDOUT; - PR_fprintf(debug_out, "Test parameters\n"); - PR_fprintf(debug_out, "\tThreads involved: %d\n", numThreads); - PR_fprintf(debug_out, "\tIteration limit: %d\n", numIterations); - PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency); - PR_fprintf(debug_out, "\tThread type: %s\n", - (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); - } - - /* - * Malloc a block of memory and divide it into data and thread. - */ - block = PR_MALLOC(numThreads * (sizeof(ThreadData) + sizeof(PRThread *))); - if (block == NULL) { - PR_fprintf(PR_STDERR, "cannot malloc, failed\n"); - exit(1); - } - data = (ThreadData *) block; - thread = (PRThread **) &data[numThreads]; - - /* Pollable event */ - selfData.event = PR_NewPollableEvent(); - if (selfData.event == NULL) { - PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - selfData.next = &data[0]; - for (i = 0; i < numThreads; i++) { - data[i].event = PR_NewPollableEvent(); - if (data[i].event == NULL) { - PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - data[i].index = i; - if (i != numThreads - 1) { - data[i].next = &data[i + 1]; - } else { - data[i].next = &selfData; - } - - thread[i] = PR_CreateThread(PR_USER_THREAD, - ThreadRoutine, &data[i], PR_PRIORITY_NORMAL, - thread_scope, PR_JOINABLE_THREAD, 0); - if (thread[i] == NULL) { - PR_fprintf(PR_STDERR, "cannot create thread\n"); - exit(1); - } - } - - timeStart = PR_IntervalNow(); - pd.fd = selfData.event; - pd.in_flags = PR_POLL_READ; - for (i = 0; i < numIterations; i++) { - if (dally != PR_INTERVAL_NO_WAIT) { - PR_Sleep(dally); - } - if (verbosity) { - PR_fprintf(debug_out, "main thread posting event\n"); - } - if (PR_SetPollableEvent(selfData.next->event) == PR_FAILURE) { - PR_fprintf(PR_STDERR, "set event failed\n"); - exit(1); - } - rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); - if (rv == -1) { - PR_fprintf(PR_STDERR, "wait failed\n"); - exit(1); - } - PR_ASSERT(rv != 0); - PR_ASSERT(pd.out_flags & PR_POLL_READ); - if (verbosity) { - PR_fprintf(debug_out, "main thread awakened\n"); - } - if (PR_WaitForPollableEvent(selfData.event) == PR_FAILURE) { - PR_fprintf(PR_STDERR, "consume event failed\n"); - exit(1); - } - } - timeEnd = PR_IntervalNow(); - - if (debug_mode) { - average = PR_IntervalToMicroseconds(timeEnd - timeStart) - / (numIterations * numThreads); - PR_fprintf(debug_out, "Average switch times %d usecs for %d threads\n", - average, numThreads); - } - - for (i = 0; i < numThreads; i++) { - if (PR_JoinThread(thread[i]) == PR_FAILURE) { - PR_fprintf(PR_STDERR, "join thread failed\n"); - exit(1); - } - PR_DestroyPollableEvent(data[i].event); - } - PR_DELETE(block); - PR_DestroyPollableEvent(selfData.event); - - PR_fprintf(PR_STDOUT, "PASSED\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/poll_er.c nspr-4.10.7/mozilla/nsprpub/pr/tests/poll_er.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/poll_er.c 2012-03-06 13:14:28.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/poll_er.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,210 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: prpoll_err.c -** -** Description: This program tests PR_Poll with sockets. -** error reporting operation is tested -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -#ifdef XP_BEOS -#include -int main() -{ - printf( "This test is not ported to the BeOS\n" ); - return 0; -} -#else - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "primpl.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - -static void -ClientThreadFunc(void *arg) -{ - PRFileDesc *badFD = (PRFileDesc *) arg; - /* - * Make the fd invalid - */ -#if defined(XP_UNIX) - close(PR_FileDesc2NativeHandle(badFD)); -#elif defined(XP_OS2) - soclose(PR_FileDesc2NativeHandle(badFD)); -#elif defined(WIN32) || defined(WIN16) - closesocket(PR_FileDesc2NativeHandle(badFD)); -#else -#error "Unknown architecture" -#endif -} - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock1, *listenSock2; - PRFileDesc *badFD; - PRUint16 listenPort1, listenPort2; - PRNetAddr addr; - char buf[128]; - PRPollDesc pds0[10], pds1[10], *pds, *other_pds; - PRIntn npds; - PRInt32 retVal; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (debug_mode) { - printf("This program tests PR_Poll with sockets.\n"); - printf("error reporting is tested.\n\n"); - } - - /* Create two listening sockets */ - if ((listenSock1 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = AF_INET; - addr.inet.ip = PR_htonl(INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort1 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock1, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - - if ((listenSock2 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = AF_INET; - addr.inet.ip = PR_htonl(INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort2 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock2, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu and %hu\n\n", - listenPort1, listenPort2); - if (debug_mode) printf("%s", buf); - - /* Set up the poll descriptor array */ - pds = pds0; - other_pds = pds1; - memset(pds, 0, sizeof(pds)); - pds[0].fd = listenSock1; - pds[0].in_flags = PR_POLL_READ; - pds[1].fd = listenSock2; - pds[1].in_flags = PR_POLL_READ; - npds = 2; - - - /* Testing bad fd */ - if (debug_mode) printf("PR_Poll should detect a bad file descriptor\n"); - if ((badFD = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a TCP socket\n"); - goto exit_now; - } - - pds[2].fd = badFD; - pds[2].in_flags = PR_POLL_READ; - npds = 3; - - if (PR_CreateThread(PR_USER_THREAD, ClientThreadFunc, - badFD, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0) == NULL) { - fprintf(stderr, "cannot create thread\n"); - exit(1); - } - - retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); - if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) { - fprintf(stderr, "Failed to detect the bad fd: " - "PR_Poll returns %d, out_flags is 0x%hx\n", - retVal, pds[2].out_flags); - failed_already=1; - goto exit_now; - } - if (debug_mode) printf("PR_Poll detected the bad fd. Test passed.\n\n"); - PR_Cleanup(); - goto exit_now; -exit_now: - if(failed_already) - return 1; - else - return 0; -} - -#endif /* XP_BEOS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/poll_nm.c nspr-4.10.7/mozilla/nsprpub/pr/tests/poll_nm.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/poll_nm.c 2012-03-06 13:14:29.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/poll_nm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,345 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: prpoll_norm.c -** -** Description: This program tests PR_Poll with sockets. -** Normal operation are tested -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prinit.h" -#include "prio.h" -#include "prlog.h" -#include "prprf.h" -#include "prnetdb.h" -#include "obsolete/probslet.h" - -#include "private/pprio.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - -#define NUM_ITERATIONS 5 - -static void PR_CALLBACK -clientThreadFunc(void *arg) -{ - PRUintn port = (PRUintn) arg; - PRFileDesc *sock; - PRNetAddr addr; - char buf[128]; - int i; - PRStatus sts; - PRInt32 n; - - addr.inet.family = PR_AF_INET; - addr.inet.port = PR_htons((PRUint16)port); - addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - memset(buf, 0, sizeof(buf)); - PR_snprintf(buf, sizeof(buf), "%hu", port); - - for (i = 0; i < NUM_ITERATIONS; i++) { - sock = PR_NewTCPSocket(); - PR_ASSERT(sock != NULL); - - sts = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(sts == PR_SUCCESS); - - n = PR_Write(sock, buf, sizeof(buf)); - PR_ASSERT(n >= 0); - - sts = PR_Close(sock); - PR_ASSERT(sts == PR_SUCCESS); - } -} - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL; - PRUint16 listenPort1, listenPort2; - PRNetAddr addr; - char buf[128]; - PRThread *clientThread; - PRPollDesc pds0[20], pds1[20], *pds, *other_pds; - PRIntn npds; - PRInt32 retVal; - PRIntn i, j; - PRSocketOptionData optval; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (debug_mode) { - printf("This program tests PR_Poll with sockets.\n"); - printf("Normal operation are tested.\n\n"); - } - - /* Create two listening sockets */ - if ((listenSock1 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - memset(&addr, 0, sizeof(addr)); - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort1 = PR_ntohs(addr.inet.port); - optval.option = PR_SockOpt_Nonblocking; - optval.value.non_blocking = PR_TRUE; - PR_SetSocketOption(listenSock1, &optval); - if (PR_Listen(listenSock1, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - - if ((listenSock2 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort2 = PR_ntohs(addr.inet.port); - PR_SetSocketOption(listenSock2, &optval); - if (PR_Listen(listenSock2, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu and %hu\n\n", - listenPort1, listenPort2); - if (debug_mode) printf("%s", buf); - - /* Set up the poll descriptor array */ - pds = pds0; - other_pds = pds1; - memset(pds, 0, sizeof(pds)); - pds[0].fd = listenSock1; - pds[0].in_flags = PR_POLL_READ; - pds[1].fd = listenSock2; - pds[1].in_flags = PR_POLL_READ; - /* Add some unused entries to test if they are ignored by PR_Poll() */ - memset(&pds[2], 0, sizeof(pds[2])); - memset(&pds[3], 0, sizeof(pds[3])); - memset(&pds[4], 0, sizeof(pds[4])); - npds = 5; - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort1, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - failed_already=1; - goto exit_now; - } - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort2, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - failed_already=1; - goto exit_now; - } - - if (debug_mode) { - printf("Two client threads are created. Each of them will\n"); - printf("send data to one of the two ports the server is listening on.\n"); - printf("The data they send is the port number. Each of them send\n"); - printf("the data five times, so you should see ten lines below,\n"); - printf("interleaved in an arbitrary order.\n"); - } - - /* two clients, three events per iteration: accept, read, close */ - i = 0; - while (i < 2 * 3 * NUM_ITERATIONS) { - PRPollDesc *tmp; - int nextIndex; - int nEvents = 0; - - retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(retVal != 0); /* no timeout */ - if (retVal == -1) { - fprintf(stderr, "PR_Poll failed\n"); - failed_already=1; - goto exit_now; - } - - nextIndex = 2; - /* the two listening sockets */ - for (j = 0; j < 2; j++) { - other_pds[j] = pds[j]; - PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 - && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); - if (pds[j].out_flags & PR_POLL_READ) { - PRFileDesc *sock; - - nEvents++; - sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT); - if (sock == NULL) { - fprintf(stderr, "PR_Accept() failed\n"); - failed_already=1; - goto exit_now; - } - other_pds[nextIndex].fd = sock; - other_pds[nextIndex].in_flags = PR_POLL_READ; - nextIndex++; - } else if (pds[j].out_flags & PR_POLL_ERR) { - fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); - failed_already=1; - goto exit_now; - } else if (pds[j].out_flags & PR_POLL_NVAL) { - fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n", - PR_FileDesc2NativeHandle(pds[j].fd)); - failed_already=1; - goto exit_now; - } - } - - for (j = 2; j < npds; j++) { - if (NULL == pds[j].fd) { - /* - * Keep the unused entries in the poll descriptor array - * for testing purposes. - */ - other_pds[nextIndex] = pds[j]; - nextIndex++; - continue; - } - - PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 - && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); - if (pds[j].out_flags & PR_POLL_READ) { - PRInt32 nAvail; - PRInt32 nRead; - - nEvents++; - nAvail = PR_Available(pds[j].fd); - nRead = PR_Read(pds[j].fd, buf, sizeof(buf)); - PR_ASSERT(nAvail == nRead); - if (nRead == -1) { - fprintf(stderr, "PR_Read() failed\n"); - failed_already=1; - goto exit_now; - } else if (nRead == 0) { - PR_Close(pds[j].fd); - continue; - } else { - /* Just to be safe */ - buf[127] = '\0'; - if (debug_mode) printf("The server received \"%s\" from a client\n", buf); - } - } else if (pds[j].out_flags & PR_POLL_ERR) { - fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); - failed_already=1; - goto exit_now; - } else if (pds[j].out_flags & PR_POLL_NVAL) { - fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n"); - failed_already=1; - goto exit_now; - } - other_pds[nextIndex] = pds[j]; - nextIndex++; - } - - PR_ASSERT(retVal == nEvents); - /* swap */ - tmp = pds; - pds = other_pds; - other_pds = tmp; - npds = nextIndex; - i += nEvents; - } - - if (debug_mode) printf("Tests passed\n"); - -exit_now: - - if (listenSock1) { - PR_Close(listenSock1); - } - if (listenSock2) { - PR_Close(listenSock2); - } - - PR_Cleanup(); - - if(failed_already) - return 1; - else - return 0; - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/poll_to.c nspr-4.10.7/mozilla/nsprpub/pr/tests/poll_to.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/poll_to.c 2012-03-06 13:14:29.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/poll_to.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: prpoll_to.c -** -** Description: This program tests PR_Poll with sockets. -** Timeout operation is tested -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prinit.h" -#include "prio.h" -#include "prlog.h" -#include "prprf.h" -#include "prnetdb.h" - -#include "private/pprio.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL; - PRUint16 listenPort1, listenPort2; - PRNetAddr addr; - char buf[128]; - PRPollDesc pds0[10], pds1[10], *pds, *other_pds; - PRIntn npds; - PRInt32 retVal; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (debug_mode) { - printf("This program tests PR_Poll with sockets.\n"); - printf("Timeout is tested.\n\n"); - } - - /* Create two listening sockets */ - if ((listenSock1 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - memset(&addr, 0, sizeof(addr)); - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - listenPort1 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock1, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - - if ((listenSock2 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - listenPort2 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock2, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - if (!debug_mode) failed_already=1; - goto exit_now; - } - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu and %hu\n\n", - listenPort1, listenPort2); - if (debug_mode) printf("%s", buf); - - /* Set up the poll descriptor array */ - pds = pds0; - other_pds = pds1; - memset(pds, 0, sizeof(pds)); - pds[0].fd = listenSock1; - pds[0].in_flags = PR_POLL_READ; - pds[1].fd = listenSock2; - pds[1].in_flags = PR_POLL_READ; - npds = 2; - - /* Testing timeout */ - if (debug_mode) printf("PR_Poll should time out in 5 seconds\n"); - retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5)); - if (retVal != 0) { - PR_snprintf(buf, sizeof(buf), - "PR_Poll should time out and return 0, but it returns %ld\n", - retVal); - fprintf(stderr, "%s", buf); - if (!debug_mode) failed_already=1; - goto exit_now; - } - if (debug_mode) printf("PR_Poll timed out. Test passed.\n\n"); - -exit_now: - - if (listenSock1) { - PR_Close(listenSock1); - } - if (listenSock2) { - PR_Close(listenSock2); - } - - PR_Cleanup(); - - if(failed_already) - return 1; - else - return 0; - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/prftest1.c nspr-4.10.7/mozilla/nsprpub/pr/tests/prftest1.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/prftest1.c 2012-03-06 13:14:29.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/prftest1.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prftest1.c -** Description: -** This is a simple test of the PR_snprintf() function defined -** in prprf.c. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" -#include "prttools.h" - -#include "prinit.h" -#include "prlong.h" -#include "prprf.h" - -#include - -#define BUF_SIZE 128 - -/*********************************************************************** -** PRIVATE FUNCTION: Test_Result -** DESCRIPTION: Used in conjunction with the regress tool, prints out the -** status of the test case. -** INPUTS: PASS/FAIL -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** -** RESTRICTIONS: -** None -** MEMORY: NA -** ALGORITHM: Determine what the status is and print accordingly. -** -***********************************************************************/ - - -static void Test_Result (int result) -{ - if (result == PASS) - printf ("PASS\n"); - else - printf ("FAIL\n"); -} - -int main(int argc, char **argv) -{ - PRInt16 i16; - PRIntn n; - PRInt32 i32; - PRInt64 i64; - char buf[BUF_SIZE]; - char answer[BUF_SIZE]; - int i; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - PR_STDIO_INIT(); - - i16 = -1; - n = -1; - i32 = -1; - LL_I2L(i64, i32); - - PR_snprintf(buf, BUF_SIZE, "%hx %x %lx %llx", i16, n, i32, i64); - strcpy(answer, "ffff "); - for (i = PR_BYTES_PER_INT * 2; i; i--) { - strcat(answer, "f"); - } - strcat(answer, " ffffffff ffffffffffffffff"); - - if (!strcmp(buf, answer)) { - if (debug_mode) printf("PR_snprintf test 1 passed\n"); - else Test_Result (PASS); - } else { - if (debug_mode) { - printf("PR_snprintf test 1 failed\n"); - printf("Converted string is %s\n", buf); - printf("Should be %s\n", answer); - } - else - Test_Result (FAIL); - } - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/prftest2.c nspr-4.10.7/mozilla/nsprpub/pr/tests/prftest2.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/prftest2.c 2012-03-06 13:14:29.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/prftest2.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: prftest2.c -** Description: -** This is a simple test of the PR_snprintf() function defined -** in prprf.c. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prlong.h" -#include "prinit.h" -#include "prprf.h" - -#include - -#define BUF_SIZE 128 - -PRIntn failed_already=0; -PRIntn debug_mode; - -int main(int argc, char **argv) -{ - PRInt16 i16; - PRIntn n; - PRInt32 i32; - PRInt64 i64; - char buf[BUF_SIZE]; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - - PR_STDIO_INIT(); - i16 = -32; - n = 30; - i32 = 64; - LL_I2L(i64, 333); - PR_snprintf(buf, BUF_SIZE, "%d %hd %lld %ld", n, i16, i64, i32); - if (!strcmp(buf, "30 -32 333 64")) { - if (debug_mode) printf("PR_snprintf test 2 passed\n"); - } else { - if (debug_mode) { - printf("PR_snprintf test 2 failed\n"); - printf("Converted string is %s\n", buf); - printf("Should be 30 -32 333 64\n"); - } - else failed_already=1; - } - if(failed_already) - { - printf("FAILED\n"); - return 1; - } - else - { - printf("PASSED\n"); - return 0; - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/prftest.c nspr-4.10.7/mozilla/nsprpub/pr/tests/prftest.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/prftest.c 2012-03-06 13:14:29.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/prftest.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: prftest.c - * Description: - * This is a simple test of the PR_snprintf() function defined - * in prprf.c. - */ - -#include "prlong.h" -#include "prprf.h" - -#include - -#define BUF_SIZE 128 - -int main(int argc, char **argv) -{ - PRInt16 i16; - PRIntn n; - PRInt32 i32; - PRInt64 i64; - char buf[BUF_SIZE]; - char answer[BUF_SIZE]; - int i, rv = 0; - - i16 = -1; - n = -1; - i32 = -1; - LL_I2L(i64, i32); - - PR_snprintf(buf, BUF_SIZE, "%hx %x %lx %llx", i16, n, i32, i64); - strcpy(answer, "ffff "); - for (i = PR_BYTES_PER_INT * 2; i; i--) { - strcat(answer, "f"); - } - strcat(answer, " ffffffff ffffffffffffffff"); - - if (!strcmp(buf, answer)) { - printf("PR_snprintf test 1 passed\n"); - } else { - printf("PR_snprintf test 1 failed\n"); - printf("Converted string is %s\n", buf); - printf("Should be %s\n", answer); - rv = 1; - } - - i16 = -32; - n = 30; - i32 = 64; - LL_I2L(i64, 333); - PR_snprintf(buf, BUF_SIZE, "%d %hd %lld %ld", n, i16, i64, i32); - if (!strcmp(buf, "30 -32 333 64")) { - printf("PR_snprintf test 2 passed\n"); - } else { - printf("PR_snprintf test 2 failed\n"); - printf("Converted string is %s\n", buf); - printf("Should be 30 -32 333 64\n"); - rv = 1; - } - - return rv; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/primblok.c nspr-4.10.7/mozilla/nsprpub/pr/tests/primblok.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/primblok.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/primblok.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: primblok.c - * Purpose: testing whether the primordial thread can block in a - * native blocking function without affecting the correct - * functioning of NSPR I/O functions (Bugzilla bug #30746) - */ - -#if !defined(WINNT) - -#include - -int main(int argc, char **argv) -{ - printf("This test is not relevant on this platform\n"); - return 0; -} - -#else /* WINNT */ - -#include "nspr.h" - -#include -#include -#include -#include - -#define TEST_FILE_NAME "primblok.dat" - -/* use InterlockedExchange to update this variable */ -static LONG iothread_done; - -static void PR_CALLBACK IOThread(void *arg) -{ - PRFileDesc *fd; - char buf[32]; - PRInt32 nbytes; - - /* Give the primordial thread one second to block */ - Sleep(1000); - - /* - * See if our PR_Write call will hang when the primordial - * thread is blocking in a native blocking function. - */ - fd = PR_Open(TEST_FILE_NAME, PR_WRONLY|PR_CREATE_FILE, 0666); - if (NULL == fd) { - fprintf(stderr, "PR_Open failed\n"); - exit(1); - } - memset(buf, 0xaf, sizeof(buf)); - fprintf(stderr, "iothread: calling PR_Write\n"); - nbytes = PR_Write(fd, buf, sizeof(buf)); - fprintf(stderr, "iothread: PR_Write returned\n"); - if (nbytes != sizeof(buf)) { - fprintf(stderr, "PR_Write returned %d\n", nbytes); - exit(1); - } - if (PR_Close(fd) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) { - fprintf(stderr, "PR_Delete failed\n"); - exit(1); - } - - /* Tell the main thread that we are done */ - InterlockedExchange(&iothread_done, 1); -} - -int main(int argc, char **argv) -{ - PRThread *iothread; - - /* Must be a global thread */ - iothread = PR_CreateThread( - PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (iothread == NULL) { - fprintf(stderr, "cannot create thread\n"); - exit(1); - } - - /* - * Block in a native blocking function. - * Give iothread 5 seconds to finish its task. - */ - Sleep(5000); - - /* - * Is iothread done or is it hung? - * - * I'm actually only interested in reading the value - * of iothread_done. I'm using InterlockedExchange as - * a thread-safe way to read iothread_done. - */ - if (InterlockedExchange(&iothread_done, 1) == 0) { - fprintf(stderr, "iothread is hung\n"); - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (PR_JoinThread(iothread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - printf("PASSED\n"); - return 0; -} /* main */ - -#endif /* WINNT */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/priotest.c nspr-4.10.7/mozilla/nsprpub/pr/tests/priotest.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/priotest.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/priotest.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: priotest.c - * Purpose: testing priorities - */ - -#include "prcmon.h" -#include "prinit.h" -#include "prinrval.h" -#include "prlock.h" -#include "prlog.h" -#include "prmon.h" -#include "prprf.h" -#include "prthread.h" -#include "prtypes.h" - -#include "plerror.h" -#include "plgetopt.h" - -#include -#include - -#define DEFAULT_DURATION 5 - -static PRBool failed = PR_FALSE; -static PRIntervalTime oneSecond; -static PRFileDesc *debug_out = NULL; -static PRBool debug_mode = PR_FALSE; - -static PRUint32 PerSecond(PRIntervalTime timein) -{ - PRUint32 loop = 0; - while (((PRIntervalTime)(PR_IntervalNow()) - timein) < oneSecond) - loop += 1; - return loop; -} /* PerSecond */ - -static void PR_CALLBACK Low(void *arg) -{ - PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg; - while (1) - { - t0 = PerSecond(PR_IntervalNow()); - *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8; - t3 = t2; t2 = t1; t1 = t0; - } -} /* Low */ - -static void PR_CALLBACK High(void *arg) -{ - PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg; - while (1) - { - PRIntervalTime timein = PR_IntervalNow(); - PR_Sleep(oneSecond >> 2); /* 0.25 seconds */ - t0 = PerSecond(timein); - *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8; - t3 = t2; t2 = t1; t1 = t0; - } -} /* High */ - -static void Help(void) -{ - PR_fprintf( - debug_out, "Usage: priotest [-d] [-c n]\n"); - PR_fprintf( - debug_out, "-c n\tduration of test in seconds (default: %d)\n", DEFAULT_DURATION); - PR_fprintf( - debug_out, "-d\tturn on debugging output (default: FALSE)\n"); -} /* Help */ - -static void RudimentaryTests(void) -{ - /* - ** Try some rudimentary tests like setting valid priority and - ** getting it back, or setting invalid priorities and getting - ** back a valid answer. - */ - PRThreadPriority priority; - PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT); - priority = PR_GetThreadPriority(PR_GetCurrentThread()); - failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority)) - ? PR_TRUE : PR_FALSE; - if (debug_mode && (PR_PRIORITY_URGENT != priority)) - { - PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n"); - } - - - PR_SetThreadPriority( - PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1)); - priority = PR_GetThreadPriority(PR_GetCurrentThread()); - failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority)) - ? PR_TRUE : PR_FALSE; - if (debug_mode && (PR_PRIORITY_FIRST != priority)) - { - PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n"); - } - - PR_SetThreadPriority( - PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1)); - priority = PR_GetThreadPriority(PR_GetCurrentThread()); - failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority)) - ? PR_TRUE : PR_FALSE; - if (debug_mode && (PR_PRIORITY_LAST != priority)) - { - PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n"); - } - -} /* RudimentataryTests */ - -static void CreateThreads(PRUint32 *lowCount, PRUint32 *highCount) -{ - (void)PR_CreateThread( - PR_USER_THREAD, Low, lowCount, PR_PRIORITY_LOW, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - (void)PR_CreateThread( - PR_USER_THREAD, High, highCount, PR_PRIORITY_HIGH, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); -} /* CreateThreads */ - -int main(int argc, char **argv) -{ - PLOptStatus os; - PRIntn duration = DEFAULT_DURATION; - PRUint32 totalCount, highCount = 0, lowCount = 0; - PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:"); - - debug_out = PR_STDOUT; - oneSecond = PR_SecondsToInterval(1); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'c': /* test duration */ - duration = atoi(opt->value); - break; - case 'h': /* help message */ - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - PR_STDIO_INIT(); - - if (duration == 0) duration = DEFAULT_DURATION; - - RudimentaryTests(); - - printf("Priority test: running for %d seconds\n\n", duration); - - (void)PerSecond(PR_IntervalNow()); - totalCount = PerSecond(PR_IntervalNow()); - - PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT); - - if (debug_mode) - { - PR_fprintf(debug_out, - "The high priority thread should get approximately three\n"); - PR_fprintf( debug_out, - "times what the low priority thread manages. A maximum of \n"); - PR_fprintf( debug_out, "%d cycles are available.\n\n", totalCount); - } - - duration = (duration + 4) / 5; - CreateThreads(&lowCount, &highCount); - while (duration--) - { - PRIntn loop = 5; - while (loop--) PR_Sleep(oneSecond); - if (debug_mode) - PR_fprintf(debug_out, "high : low :: %d : %d\n", highCount, lowCount); - } - - - PR_ProcessExit((failed) ? 1 : 0); - - PR_ASSERT(!"You can't get here -- but you did!"); - return 1; /* or here */ - -} /* main */ - -/* priotest.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/provider.c nspr-4.10.7/mozilla/nsprpub/pr/tests/provider.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/provider.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/provider.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1354 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * - * Notes: - * [1] lth. The call to Sleep() is a hack to get the test case to run - * on Windows 95. Without it, the test case fails with an error - * WSAECONNRESET following a recv() call. The error is caused by the - * server side thread termination without a shutdown() or closesocket() - * call. Windows docmunentation suggests that this is predicted - * behavior; that other platforms get away with it is ... serindipity. - * The test case should shutdown() or closesocket() before - * thread termination. I didn't have time to figure out where or how - * to do it. The Sleep() call inserts enough delay to allow the - * client side to recv() all his data before the server side thread - * terminates. Whew! ... - * - ** Modification History: - * 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. - * The debug mode will print all of the printfs associated with this test. - * The regress mode will be the default mode. Since the regress tool limits - * the output to a one line status:PASS or FAIL,all of the printf statements - * have been handled with an if (debug_mode) statement. - */ - -#include "prclist.h" -#include "prcvar.h" -#include "prerror.h" -#include "prinit.h" -#include "prinrval.h" -#include "prio.h" -#include "prlock.h" -#include "prlog.h" -#include "prtime.h" -#include "prmem.h" -#include "prnetdb.h" -#include "prprf.h" -#include "prthread.h" - -#include "pprio.h" -#include "primpl.h" - -#include "plstr.h" -#include "plerror.h" -#include "plgetopt.h" - -#include -#include - -#if defined(XP_UNIX) -#include -#endif - -/* -** This is the beginning of the test -*/ - -#define RECV_FLAGS 0 -#define SEND_FLAGS 0 -#define BUFFER_SIZE 1024 -#define DEFAULT_BACKLOG 5 -#define DEFAULT_PORT 13000 -#define DEFAULT_CLIENTS 1 -#define ALLOWED_IN_ACCEPT 1 -#define DEFAULT_CLIPPING 1000 -#define DEFAULT_WORKERS_MIN 1 -#define DEFAULT_WORKERS_MAX 1 -#define DEFAULT_SERVER "localhost" -#define DEFAULT_EXECUTION_TIME 10 -#define DEFAULT_CLIENT_TIMEOUT 4000 -#define DEFAULT_SERVER_TIMEOUT 4000 -#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGH - -typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t; - -static void PR_CALLBACK Worker(void *arg); -typedef struct CSPool_s CSPool_t; -typedef struct CSWorker_s CSWorker_t; -typedef struct CSServer_s CSServer_t; -typedef enum Verbosity -{ - TEST_LOG_ALWAYS, - TEST_LOG_ERROR, - TEST_LOG_WARNING, - TEST_LOG_NOTICE, - TEST_LOG_INFO, - TEST_LOG_STATUS, - TEST_LOG_VERBOSE -} Verbosity; - -static enum { - thread_nspr, thread_pthread, thread_sproc, thread_win32 -} thread_provider; - -static PRInt32 domain = AF_INET; -static PRInt32 protocol = 6; /* TCP */ -static PRFileDesc *debug_out = NULL; -static PRBool debug_mode = PR_FALSE; -static PRBool pthread_stats = PR_FALSE; -static Verbosity verbosity = TEST_LOG_ALWAYS; -static PRThreadScope thread_scope = PR_LOCAL_THREAD; - -struct CSWorker_s -{ - PRCList element; /* list of the server's workers */ - - PRThread *thread; /* this worker objects thread */ - CSServer_t *server; /* back pointer to server structure */ -}; - -struct CSPool_s -{ - PRCondVar *exiting; - PRCondVar *acceptComplete; - PRUint32 accepting, active, workers; -}; - -struct CSServer_s -{ - PRCList list; /* head of worker list */ - - PRLock *ml; - PRThread *thread; /* the main server thread */ - PRCondVar *stateChange; - - PRUint16 port; /* port we're listening on */ - PRUint32 backlog; /* size of our listener backlog */ - PRFileDesc *listener; /* the fd accepting connections */ - - CSPool_t pool; /* statistics on worker threads */ - CSState_t state; /* the server's state */ - struct /* controlling worker counts */ - { - PRUint32 minimum, maximum, accepting; - } workers; - - /* statistics */ - PRIntervalTime started, stopped; - PRUint32 operations, bytesTransferred; -}; - -typedef struct CSDescriptor_s -{ - PRInt32 size; /* size of transfer */ - char filename[60]; /* filename, null padded */ -} CSDescriptor_t; - -typedef struct CSClient_s -{ - PRLock *ml; - PRThread *thread; - PRCondVar *stateChange; - PRNetAddr serverAddress; - - CSState_t state; - - /* statistics */ - PRIntervalTime started, stopped; - PRUint32 operations, bytesTransferred; -} CSClient_t; - -#define TEST_LOG(l, p, a) \ - do { \ - if (debug_mode || (p <= verbosity)) printf a; \ - } while (0) - -PRLogModuleInfo *cltsrv_log_file = NULL; - -#define MY_ASSERT(_expr) \ - ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__)) - -#define TEST_ASSERT(_expr) \ - ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__)) - -static void _MY_Assert(const char *s, const char *file, PRIntn ln) -{ - PL_PrintError(NULL); - PR_Assert(s, file, ln); -} /* _MY_Assert */ - -static PRBool Aborted(PRStatus rv) -{ - return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ? - PR_TRUE : PR_FALSE; -} - -static void TimeOfDayMessage(const char *msg, PRThread* me) -{ - char buffer[100]; - PRExplodedTime tod; - PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod); - (void)PR_FormatTime(buffer, sizeof(buffer), "%H:%M:%S", &tod); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("%s(0x%p): %s\n", msg, me, buffer)); -} /* TimeOfDayMessage */ - - -static void PR_CALLBACK Client(void *arg) -{ - PRStatus rv; - PRIntn index; - char buffer[1024]; - PRFileDesc *fd = NULL; - PRUintn clipping = DEFAULT_CLIPPING; - CSClient_t *client = (CSClient_t*)arg; - PRThread *me = client->thread = PR_GetCurrentThread(); - CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); - PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT); - - - for (index = 0; index < sizeof(buffer); ++index) - buffer[index] = (char)index; - - client->started = PR_IntervalNow(); - - PR_Lock(client->ml); - client->state = cs_run; - PR_NotifyCondVar(client->stateChange); - PR_Unlock(client->ml); - - TimeOfDayMessage("Client started at", me); - - while (cs_run == client->state) - { - PRInt32 bytes, descbytes, filebytes, netbytes; - - (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer)); - TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, - ("\tClient(0x%p): connecting to server at %s\n", me, buffer)); - - fd = PR_Socket(domain, SOCK_STREAM, protocol); - TEST_ASSERT(NULL != fd); - rv = PR_Connect(fd, &client->serverAddress, timeout); - if (PR_FAILURE == rv) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): conection failed\n", me)); - goto aborted; - } - - memset(descriptor, 0, sizeof(*descriptor)); - descriptor->size = PR_htonl(descbytes = rand() % clipping); - PR_snprintf( - descriptor->filename, sizeof(descriptor->filename), - "CS%p%p-%p.dat", client->started, me, client->operations); - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes)); - bytes = PR_Send( - fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout); - if (sizeof(CSDescriptor_t) != bytes) - { - if (Aborted(PR_FAILURE)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): send descriptor timeout\n", me)); - goto retry; - } - } - TEST_ASSERT(sizeof(*descriptor) == bytes); - - netbytes = 0; - while (netbytes < descbytes) - { - filebytes = sizeof(buffer); - if ((descbytes - netbytes) < filebytes) - filebytes = descbytes - netbytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tClient(0x%p): sending %d bytes\n", me, filebytes)); - bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); - if (filebytes != bytes) - { - if (Aborted(PR_FAILURE)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): send data timeout\n", me)); - goto retry; - } - } - TEST_ASSERT(bytes == filebytes); - netbytes += bytes; - } - filebytes = 0; - while (filebytes < descbytes) - { - netbytes = sizeof(buffer); - if ((descbytes - filebytes) < netbytes) - netbytes = descbytes - filebytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tClient(0x%p): receiving %d bytes\n", me, netbytes)); - bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); - if (-1 == bytes) - { - if (Aborted(PR_FAILURE)) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): receive data aborted\n", me)); - goto aborted; - } - else if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): receive data timeout\n", me)); - else - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tClient(0x%p): receive error (%d, %d)\n", - me, PR_GetError(), PR_GetOSError())); - goto retry; - } - if (0 == bytes) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tClient(0x%p): unexpected end of stream\n", - PR_GetCurrentThread())); - break; - } - filebytes += bytes; - } - - rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); - if (Aborted(rv)) goto aborted; - TEST_ASSERT(PR_SUCCESS == rv); -retry: - (void)PR_Close(fd); fd = NULL; - TEST_LOG( - cltsrv_log_file, TEST_LOG_INFO, - ("\tClient(0x%p): disconnected from server\n", me)); - - PR_Lock(client->ml); - client->operations += 1; - client->bytesTransferred += 2 * descbytes; - rv = PR_WaitCondVar(client->stateChange, rand() % clipping); - PR_Unlock(client->ml); - if (Aborted(rv)) break; - } - -aborted: - client->stopped = PR_IntervalNow(); - - PR_ClearInterrupt(); - if (NULL != fd) rv = PR_Close(fd); - - PR_Lock(client->ml); - client->state = cs_exit; - PR_NotifyCondVar(client->stateChange); - PR_Unlock(client->ml); - PR_DELETE(descriptor); - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("\tClient(0x%p): stopped after %u operations and %u bytes\n", - PR_GetCurrentThread(), client->operations, client->bytesTransferred)); - -} /* Client */ - -static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server) -{ - PRStatus drv, rv; - char buffer[1024]; - PRFileDesc *file = NULL; - PRThread * me = PR_GetCurrentThread(); - PRInt32 bytes, descbytes, netbytes, filebytes = 0; - CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); - PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tProcessRequest(0x%p): receiving desciptor\n", me)); - bytes = PR_Recv( - fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout); - if (-1 == bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto exit; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tProcessRequest(0x%p): receive timeout\n", me)); - } - goto exit; - } - if (0 == bytes) - { - rv = PR_FAILURE; - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tProcessRequest(0x%p): unexpected end of file\n", me)); - goto exit; - } - descbytes = PR_ntohl(descriptor->size); - TEST_ASSERT(sizeof(*descriptor) == bytes); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", - me, descbytes, descriptor->filename)); - - file = PR_Open( - descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666); - if (NULL == file) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\tProcessRequest(0x%p): open file timeout\n", me)); - goto aborted; - } - } - TEST_ASSERT(NULL != file); - - filebytes = 0; - while (filebytes < descbytes) - { - netbytes = sizeof(buffer); - if ((descbytes - filebytes) < netbytes) - netbytes = descbytes - filebytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)); - bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); - if (-1 == bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): receive data timeout\n", me)); - goto aborted; - } - /* - * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED) - * on NT here. This is equivalent to ECONNRESET on Unix. - * -wtc - */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_WARNING, - ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", - me, PR_GetError(), PR_GetOSError())); - goto aborted; - } - if(0 == bytes) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_WARNING, - ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)); - rv = PR_FAILURE; - goto aborted; - } - filebytes += bytes; - netbytes = bytes; - /* The byte count for PR_Write should be positive */ - MY_ASSERT(netbytes > 0); - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes)); - bytes = PR_Write(file, buffer, netbytes); - if (netbytes != bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): write file timeout\n", me)); - goto aborted; - } - } - TEST_ASSERT(bytes > 0); - } - - PR_Lock(server->ml); - server->operations += 1; - server->bytesTransferred += filebytes; - PR_Unlock(server->ml); - - rv = PR_Close(file); file = NULL; - if (Aborted(rv)) goto aborted; - TEST_ASSERT(PR_SUCCESS == rv); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename)); - file = PR_Open(descriptor->filename, PR_RDONLY, 0); - if (NULL == file) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): open file timeout\n", - PR_GetCurrentThread())); - goto aborted; - } - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n", - me, PR_GetError(), PR_GetOSError())); - goto aborted; - } - TEST_ASSERT(NULL != file); - - netbytes = 0; - while (netbytes < descbytes) - { - filebytes = sizeof(buffer); - if ((descbytes - netbytes) < filebytes) - filebytes = descbytes - netbytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes)); - bytes = PR_Read(file, buffer, filebytes); - if (filebytes != bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): read file timeout\n", me)); - else - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", - me, PR_GetError(), PR_GetOSError())); - goto aborted; - } - TEST_ASSERT(bytes > 0); - netbytes += bytes; - filebytes = bytes; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes)); - bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); - if (filebytes != bytes) - { - rv = PR_FAILURE; - if (Aborted(rv)) goto aborted; - if (PR_IO_TIMEOUT_ERROR == PR_GetError()) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tProcessRequest(0x%p): send data timeout\n", me)); - goto aborted; - } - break; - } - TEST_ASSERT(bytes > 0); - } - - PR_Lock(server->ml); - server->bytesTransferred += filebytes; - PR_Unlock(server->ml); - - rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); - if (Aborted(rv)) goto aborted; - - rv = PR_Close(file); file = NULL; - if (Aborted(rv)) goto aborted; - TEST_ASSERT(PR_SUCCESS == rv); - -aborted: - PR_ClearInterrupt(); - if (NULL != file) PR_Close(file); - drv = PR_Delete(descriptor->filename); - TEST_ASSERT(PR_SUCCESS == drv); -exit: - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tProcessRequest(0x%p): Finished\n", me)); - - PR_DELETE(descriptor); - -#if defined(WIN95) - PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */ -#endif - return rv; -} /* ProcessRequest */ - -typedef void (*StartFn)(void*); -typedef struct StartObject -{ - StartFn start; - void *arg; -} StartObject; - -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) -#include "md/_pth.h" -#include - -static void *pthread_start(void *arg) -{ - StartObject *so = (StartObject*)arg; - StartFn start = so->start; - void *data = so->arg; - PR_Free(so); - start(data); - return NULL; -} /* pthread_start */ -#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ - -#if defined(IRIX) && !defined(_PR_PTHREADS) -#include -#include -static void sproc_start(void *arg, PRSize size) -{ - StartObject *so = (StartObject*)arg; - StartFn start = so->start; - void *data = so->arg; - PR_Free(so); - start(data); -} /* sproc_start */ -#endif /* defined(IRIX) && !defined(_PR_PTHREADS) */ - -#if defined(WIN32) -#include /* for _beginthreadex() */ - -static PRUintn __stdcall windows_start(void *arg) -{ - StartObject *so = (StartObject*)arg; - StartFn start = so->start; - void *data = so->arg; - PR_Free(so); - start(data); - return 0; -} /* windows_start */ -#endif /* defined(WIN32) */ - -static PRStatus JoinThread(PRThread *thread) -{ - PRStatus rv; - switch (thread_provider) - { - case thread_nspr: - rv = PR_JoinThread(thread); - break; - case thread_pthread: -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) - rv = PR_SUCCESS; - break; -#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ - case thread_win32: -#if defined(WIN32) - rv = PR_SUCCESS; - break; -#endif - default: - rv = PR_FAILURE; - break; - } - return rv; -} /* JoinThread */ - -static PRStatus NewThread( - StartFn start, void *arg, PRThreadPriority prio, PRThreadState state) -{ - PRStatus rv; - - switch (thread_provider) - { - case thread_nspr: - { - PRThread *thread = PR_CreateThread( - PR_USER_THREAD, start, arg, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, 0); - rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS; - } - break; - case thread_pthread: -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) - { - int rv; - pthread_t id; - pthread_attr_t tattr; - StartObject *start_object; - start_object = PR_NEW(StartObject); - PR_ASSERT(NULL != start_object); - start_object->start = start; - start_object->arg = arg; - - rv = _PT_PTHREAD_ATTR_INIT(&tattr); - PR_ASSERT(0 == rv); - - rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); - PR_ASSERT(0 == rv); - - rv = pthread_attr_setstacksize(&tattr, 64 * 1024); - PR_ASSERT(0 == rv); - - rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object); - (void)_PT_PTHREAD_ATTR_DESTROY(&tattr); - return (0 == rv) ? PR_SUCCESS : PR_FAILURE; - } -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - rv = PR_FAILURE; -#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ - break; - - case thread_sproc: -#if defined(IRIX) && !defined(_PR_PTHREADS) - { - PRInt32 pid; - StartObject *start_object; - start_object = PR_NEW(StartObject); - PR_ASSERT(NULL != start_object); - start_object->start = start; - start_object->arg = arg; - pid = sprocsp( - sproc_start, PR_SALL, start_object, NULL, 64 * 1024); - rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE; - } -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - rv = PR_FAILURE; -#endif /* defined(IRIX) && !defined(_PR_PTHREADS) */ - break; - case thread_win32: -#if defined(WIN32) - { - void *th; - PRUintn id; - StartObject *start_object; - start_object = PR_NEW(StartObject); - PR_ASSERT(NULL != start_object); - start_object->start = start; - start_object->arg = arg; - th = (void*)_beginthreadex( - NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */ - 0U, /* DWORD - initial thread stack size, in bytes */ - windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */ - start_object, /* LPVOID - argument for new thread */ - 0U, /*DWORD dwCreationFlags - creation flags */ - &id /* LPDWORD - pointer to returned thread identifier */ ); - - rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS; - } -#else - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - rv = PR_FAILURE; -#endif - break; - default: - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - rv = PR_FAILURE; - } - return rv; -} /* NewThread */ - -static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool) -{ - PRStatus rv; - CSWorker_t *worker = PR_NEWZAP(CSWorker_t); - worker->server = server; - PR_INIT_CLIST(&worker->element); - rv = NewThread( - Worker, worker, DEFAULT_SERVER_PRIORITY, PR_UNJOINABLE_THREAD); - if (PR_FAILURE == rv) PR_DELETE(worker); - - TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, - ("\tCreateWorker(0x%p): create new worker (0x%p)\n", - PR_GetCurrentThread(), worker->thread)); - - return rv; -} /* CreateWorker */ - -static void PR_CALLBACK Worker(void *arg) -{ - PRStatus rv; - PRNetAddr from; - PRFileDesc *fd = NULL; - CSWorker_t *worker = (CSWorker_t*)arg; - CSServer_t *server = worker->server; - CSPool_t *pool = &server->pool; - - PRThread *me = worker->thread = PR_GetCurrentThread(); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1)); - - PR_Lock(server->ml); - PR_APPEND_LINK(&worker->element, &server->list); - pool->workers += 1; /* define our existance */ - - while (cs_run == server->state) - { - while (pool->accepting >= server->workers.accepting) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tWorker(0x%p): waiting for accept slot[%d]\n", - me, pool->accepting)); - rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT); - if (Aborted(rv) || (cs_run != server->state)) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("\tWorker(0x%p): has been %s\n", - me, (Aborted(rv) ? "interrupted" : "stopped"))); - goto exit; - } - } - pool->accepting += 1; /* how many are really in accept */ - PR_Unlock(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\t\tWorker(0x%p): calling accept\n", me)); - fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT); - - PR_Lock(server->ml); - pool->accepting -= 1; - PR_NotifyCondVar(pool->acceptComplete); - - if ((NULL == fd) && Aborted(PR_FAILURE)) - { - if (NULL != server->listener) - { - PR_Close(server->listener); - server->listener = NULL; - } - goto exit; - } - - if (NULL != fd) - { - /* - ** Create another worker of the total number of workers is - ** less than the minimum specified or we have none left in - ** accept() AND we're not over the maximum. - ** This sort of presumes that the number allowed in accept - ** is at least as many as the minimum. Otherwise we'll keep - ** creating new threads and deleting them soon after. - */ - PRBool another = - ((pool->workers < server->workers.minimum) || - ((0 == pool->accepting) - && (pool->workers < server->workers.maximum))) ? - PR_TRUE : PR_FALSE; - pool->active += 1; - PR_Unlock(server->ml); - - if (another) (void)CreateWorker(server, pool); - - rv = ProcessRequest(fd, server); - if (PR_SUCCESS != rv) - TEST_LOG( - cltsrv_log_file, TEST_LOG_ERROR, - ("\t\tWorker(0x%p): server process ended abnormally\n", me)); - (void)PR_Close(fd); fd = NULL; - - PR_Lock(server->ml); - pool->active -= 1; - } - } - -exit: - PR_ClearInterrupt(); - PR_Unlock(server->ml); - - if (NULL != fd) - { - (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH); - (void)PR_Close(fd); - } - - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers)); - - PR_Lock(server->ml); - pool->workers -= 1; /* undefine our existance */ - PR_REMOVE_AND_INIT_LINK(&worker->element); - PR_NotifyCondVar(pool->exiting); - PR_Unlock(server->ml); - - PR_DELETE(worker); /* destruction of the "worker" object */ - -} /* Worker */ - -static void PR_CALLBACK Server(void *arg) -{ - PRStatus rv; - PRNetAddr serverAddress; - CSServer_t *server = (CSServer_t*)arg; - PRThread *me = server->thread = PR_GetCurrentThread(); - PRSocketOptionData sockOpt; - - server->listener = PR_Socket(domain, SOCK_STREAM, protocol); - - sockOpt.option = PR_SockOpt_Reuseaddr; - sockOpt.value.reuse_addr = PR_TRUE; - rv = PR_SetSocketOption(server->listener, &sockOpt); - TEST_ASSERT(PR_SUCCESS == rv); - - memset(&serverAddress, 0, sizeof(serverAddress)); - rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress); - - rv = PR_Bind(server->listener, &serverAddress); - TEST_ASSERT(PR_SUCCESS == rv); - - rv = PR_Listen(server->listener, server->backlog); - TEST_ASSERT(PR_SUCCESS == rv); - - server->started = PR_IntervalNow(); - TimeOfDayMessage("Server started at", me); - - PR_Lock(server->ml); - server->state = cs_run; - PR_NotifyCondVar(server->stateChange); - PR_Unlock(server->ml); - - /* - ** Create the first worker (actually, a thread that accepts - ** connections and then processes the work load as needed). - ** From this point on, additional worker threads are created - ** as they are needed by existing worker threads. - */ - rv = CreateWorker(server, &server->pool); - TEST_ASSERT(PR_SUCCESS == rv); - - /* - ** From here on this thread is merely hanging around as the contact - ** point for the main test driver. It's just waiting for the driver - ** to declare the test complete. - */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tServer(0x%p): waiting for state change\n", me)); - - PR_Lock(server->ml); - while ((cs_run == server->state) && !Aborted(rv)) - { - rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(server->ml); - PR_ClearInterrupt(); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_INFO, - ("\tServer(0x%p): shutting down workers\n", me)); - - /* - ** Get all the worker threads to exit. They know how to - ** clean up after themselves, so this is just a matter of - ** waiting for clorine in the pool to take effect. During - ** this stage we're ignoring interrupts. - */ - server->workers.minimum = server->workers.maximum = 0; - - PR_Lock(server->ml); - while (!PR_CLIST_IS_EMPTY(&server->list)) - { - PRCList *head = PR_LIST_HEAD(&server->list); - CSWorker_t *worker = (CSWorker_t*)head; - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker)); - rv = PR_Interrupt(worker->thread); - TEST_ASSERT(PR_SUCCESS == rv); - PR_REMOVE_AND_INIT_LINK(head); - } - - while (server->pool.workers > 0) - { - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("\tServer(0x%p): waiting for %u workers to exit\n", - me, server->pool.workers)); - (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT); - } - - server->state = cs_exit; - PR_NotifyCondVar(server->stateChange); - PR_Unlock(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("\tServer(0x%p): stopped after %u operations and %u bytes\n", - me, server->operations, server->bytesTransferred)); - - if (NULL != server->listener) PR_Close(server->listener); - server->stopped = PR_IntervalNow(); - -} /* Server */ - -static void WaitForCompletion(PRIntn execution) -{ - while (execution > 0) - { - PRIntn dally = (execution > 30) ? 30 : execution; - PR_Sleep(PR_SecondsToInterval(dally)); - if (pthread_stats) PT_FPrintStats(debug_out, "\nPThread Statistics\n"); - execution -= dally; - } -} /* WaitForCompletion */ - -static void Help(void) -{ - PR_fprintf(debug_out, "cltsrv test program usage:\n"); - PR_fprintf(debug_out, "\t-a threads allowed in accept (5)\n"); - PR_fprintf(debug_out, "\t-b backlock for listen (5)\n"); - PR_fprintf(debug_out, "\t-c number of clients to create (1)\n"); - PR_fprintf(debug_out, "\t-w minimal number of server threads (1)\n"); - PR_fprintf(debug_out, "\t-W maximum number of server threads (1)\n"); - PR_fprintf(debug_out, "\t-e duration of the test in seconds (10)\n"); - PR_fprintf(debug_out, "\t-s dsn name of server (localhost)\n"); - PR_fprintf(debug_out, "\t-G use GLOBAL threads (LOCAL)\n"); - PR_fprintf(debug_out, "\t-T thread provider ('n' | 'p' | 'w')(n)\n"); - PR_fprintf(debug_out, "\t-X use XTP as transport (TCP)\n"); - PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n"); - PR_fprintf(debug_out, "\t-v verbosity (accumulative) (0)\n"); - PR_fprintf(debug_out, "\t-p pthread statistics (FALSE)\n"); - PR_fprintf(debug_out, "\t-d debug mode (FALSE)\n"); - PR_fprintf(debug_out, "\t-h this message\n"); -} /* Help */ - -static Verbosity IncrementVerbosity(void) -{ - PRIntn verboge = (PRIntn)verbosity + 1; - return (Verbosity)verboge; -} /* IncrementVerbosity */ - -int main(int argc, char **argv) -{ - PRUintn index; - PRBool boolean; - CSClient_t *client; - PRStatus rv, joinStatus; - CSServer_t *server = NULL; - char *thread_type; - - PRUintn backlog = DEFAULT_BACKLOG; - PRUintn clients = DEFAULT_CLIENTS; - const char *serverName = DEFAULT_SERVER; - PRBool serverIsLocal = PR_TRUE; - PRUintn accepting = ALLOWED_IN_ACCEPT; - PRUintn workersMin = DEFAULT_WORKERS_MIN; - PRUintn workersMax = DEFAULT_WORKERS_MAX; - PRIntn execution = DEFAULT_EXECUTION_TIME; - - /* - * -G use global threads - * -a threads allowed in accept - * -b backlock for listen - * -c number of clients to create - * -w minimal number of server threads - * -W maximum number of server threads - * -e duration of the test in seconds - * -s dsn name of server (implies no server here) - * -v verbosity - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:w:W:e:s:T:vdhp"); - -#if defined(WIN32) - thread_provider = thread_win32; -#elif defined(_PR_PTHREADS) - thread_provider = thread_pthread; -#elif defined(IRIX) - thread_provider = thread_sproc; -#else - thread_provider = thread_nspr; -#endif - - debug_out = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'G': /* use global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'X': /* use XTP as transport */ - protocol = 36; - break; - case '6': /* Use IPv6 */ - domain = PR_AF_INET6; - break; - case 'a': /* the value for accepting */ - accepting = atoi(opt->value); - break; - case 'b': /* the value for backlock */ - backlog = atoi(opt->value); - break; - case 'T': /* the thread provider */ - if ('n' == *opt->value) thread_provider = thread_nspr; - else if ('p' == *opt->value) thread_provider = thread_pthread; - else if ('w' == *opt->value) thread_provider = thread_win32; - else {Help(); return 2; } - break; - case 'c': /* number of client threads */ - clients = atoi(opt->value); - break; - case 'w': /* minimum server worker threads */ - workersMin = atoi(opt->value); - break; - case 'W': /* maximum server worker threads */ - workersMax = atoi(opt->value); - break; - case 'e': /* program execution time in seconds */ - execution = atoi(opt->value); - break; - case 's': /* server's address */ - serverName = opt->value; - break; - case 'v': /* verbosity */ - verbosity = IncrementVerbosity(); - break; - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'p': /* pthread mode */ - pthread_stats = PR_TRUE; - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE; - if (0 == execution) execution = DEFAULT_EXECUTION_TIME; - if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX; - if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN; - if (0 == accepting) accepting = ALLOWED_IN_ACCEPT; - if (0 == backlog) backlog = DEFAULT_BACKLOG; - - if (workersMin > accepting) accepting = workersMin; - - PR_STDIO_INIT(); - TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread()); - - cltsrv_log_file = PR_NewLogModule("cltsrv_log"); - MY_ASSERT(NULL != cltsrv_log_file); - boolean = PR_SetLogFile("cltsrv.log"); - MY_ASSERT(boolean); - - if (serverIsLocal) - { - /* Establish the server */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_INFO, - ("main(0x%p): starting server\n", PR_GetCurrentThread())); - - server = PR_NEWZAP(CSServer_t); - PR_INIT_CLIST(&server->list); - server->state = cs_init; - server->ml = PR_NewLock(); - server->backlog = backlog; - server->port = DEFAULT_PORT; - server->workers.minimum = workersMin; - server->workers.maximum = workersMax; - server->workers.accepting = accepting; - server->stateChange = PR_NewCondVar(server->ml); - server->pool.exiting = PR_NewCondVar(server->ml); - server->pool.acceptComplete = PR_NewCondVar(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("main(0x%p): creating server thread\n", PR_GetCurrentThread())); - - rv = NewThread( - Server, server, PR_PRIORITY_HIGH, PR_JOINABLE_THREAD); - TEST_ASSERT(PR_SUCCESS == rv); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("main(0x%p): waiting for server init\n", PR_GetCurrentThread())); - - PR_Lock(server->ml); - while (server->state == cs_init) - PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("main(0x%p): server init complete (port #%d)\n", - PR_GetCurrentThread(), server->port)); - } - - if (clients != 0) - { - /* Create all of the clients */ - PRHostEnt host; - char buffer[BUFFER_SIZE]; - client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t)); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_VERBOSE, - ("main(0x%p): creating %d client threads\n", - PR_GetCurrentThread(), clients)); - - if (!serverIsLocal) - { - rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host); - if (PR_SUCCESS != rv) - { - PL_FPrintError(PR_STDERR, "PR_GetHostByName"); - return 2; - } - } - - for (index = 0; index < clients; ++index) - { - client[index].state = cs_init; - client[index].ml = PR_NewLock(); - if (serverIsLocal) - { - (void)PR_InitializeNetAddr( - PR_IpAddrLoopback, DEFAULT_PORT, - &client[index].serverAddress); - } - else - { - (void)PR_EnumerateHostEnt( - 0, &host, DEFAULT_PORT, &client[index].serverAddress); - } - client[index].stateChange = PR_NewCondVar(client[index].ml); - TEST_LOG( - cltsrv_log_file, TEST_LOG_INFO, - ("main(0x%p): creating client threads\n", PR_GetCurrentThread())); - rv = NewThread( - Client, &client[index], PR_PRIORITY_NORMAL, PR_JOINABLE_THREAD); - TEST_ASSERT(PR_SUCCESS == rv); - PR_Lock(client[index].ml); - while (cs_init == client[index].state) - PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(client[index].ml); - } - } - - /* Then just let them go at it for a bit */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("main(0x%p): waiting for execution interval (%d seconds)\n", - PR_GetCurrentThread(), execution)); - - WaitForCompletion(execution); - - TimeOfDayMessage("Shutting down", PR_GetCurrentThread()); - - if (clients != 0) - { - for (index = 0; index < clients; ++index) - { - TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, - ("main(0x%p): notifying client(0x%p) to stop\n", - PR_GetCurrentThread(), client[index].thread)); - - PR_Lock(client[index].ml); - if (cs_run == client[index].state) - { - client[index].state = cs_stop; - PR_Interrupt(client[index].thread); - while (cs_stop == client[index].state) - PR_WaitCondVar( - client[index].stateChange, PR_INTERVAL_NO_TIMEOUT); - } - PR_Unlock(client[index].ml); - - TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, - ("main(0x%p): joining client(0x%p)\n", - PR_GetCurrentThread(), client[index].thread)); - - joinStatus = JoinThread(client[index].thread); - TEST_ASSERT(PR_SUCCESS == joinStatus); - PR_DestroyCondVar(client[index].stateChange); - PR_DestroyLock(client[index].ml); - } - PR_DELETE(client); - } - - if (NULL != server) - { - /* All clients joined - retrieve the server */ - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("main(0x%p): notifying server(0x%p) to stop\n", - PR_GetCurrentThread(), server->thread)); - - PR_Lock(server->ml); - server->state = cs_stop; - PR_Interrupt(server->thread); - while (cs_exit != server->state) - PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(server->ml); - - TEST_LOG( - cltsrv_log_file, TEST_LOG_NOTICE, - ("main(0x%p): joining server(0x%p)\n", - PR_GetCurrentThread(), server->thread)); - joinStatus = JoinThread(server->thread); - TEST_ASSERT(PR_SUCCESS == joinStatus); - - PR_DestroyCondVar(server->stateChange); - PR_DestroyCondVar(server->pool.exiting); - PR_DestroyCondVar(server->pool.acceptComplete); - PR_DestroyLock(server->ml); - PR_DELETE(server); - } - - TEST_LOG( - cltsrv_log_file, TEST_LOG_ALWAYS, - ("main(0x%p): test complete\n", PR_GetCurrentThread())); - - if (thread_provider == thread_win32) - thread_type = "\nWin32 Thread Statistics\n"; - else if (thread_provider == thread_pthread) - thread_type = "\npthread Statistics\n"; - else if (thread_provider == thread_sproc) - thread_type = "\nsproc Statistics\n"; - else { - PR_ASSERT(thread_provider == thread_nspr); - thread_type = "\nPRThread Statistics\nn"; - } - - PT_FPrintStats(debug_out, thread_type); - - TimeOfDayMessage("Test exiting at", PR_GetCurrentThread()); - PR_Cleanup(); - return 0; -} /* main */ - -/* cltsrv.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/prpoll.c nspr-4.10.7/mozilla/nsprpub/pr/tests/prpoll.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/prpoll.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/prpoll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,351 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef WIN32 -#include -#endif - -#ifdef XP_UNIX -#include /* for close() */ -#endif - -#include "prinit.h" -#include "prio.h" -#include "prlog.h" -#include "prprf.h" -#include "prnetdb.h" - -#include "private/pprio.h" - -#define CLIENT_LOOPS 5 -#define BUF_SIZE 128 - -#include -#include -#include - -#ifdef WINCE - -int main(int argc, char **argv) -{ - fprintf(stderr, "Invalid/Broken Test for WinCE/WinMobile\n"); - exit(1); -} - -#else - -static void -clientThreadFunc(void *arg) -{ - PRUint16 port = (PRUint16) arg; - PRFileDesc *sock; - PRNetAddr addr; - char buf[BUF_SIZE]; - int i; - - addr.inet.family = PR_AF_INET; - addr.inet.port = PR_htons(port); - addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - PR_snprintf(buf, sizeof(buf), "%hu", port); - - for (i = 0; i < 5; i++) { - sock = PR_NewTCPSocket(); - PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); - - PR_Write(sock, buf, sizeof(buf)); - PR_Close(sock); - } -} - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock1, *listenSock2; - PRFileDesc *badFD; - PRUint16 listenPort1, listenPort2; - PRNetAddr addr; - char buf[BUF_SIZE]; - PRThread *clientThread; - PRPollDesc pds0[10], pds1[10], *pds, *other_pds; - PRIntn npds; - PRInt32 retVal; - PRInt32 rv; - PROsfd sd; - struct sockaddr_in saddr; - PRIntn saddr_len; - PRUint16 listenPort3; - PRFileDesc *socket_poll_fd; - PRIntn i, j; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - printf("This program tests PR_Poll with sockets.\n"); - printf("Timeout, error reporting, and normal operation are tested.\n\n"); - - /* Create two listening sockets */ - if ((listenSock1 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - exit(1); - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - exit(1); - } - if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - exit(1); - } - listenPort1 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock1, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - exit(1); - } - - if ((listenSock2 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - exit(1); - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - exit(1); - } - if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - exit(1); - } - listenPort2 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock2, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - exit(1); - } - /* Set up the poll descriptor array */ - pds = pds0; - other_pds = pds1; - memset(pds, 0, sizeof(pds)); - npds = 0; - pds[npds].fd = listenSock1; - pds[npds].in_flags = PR_POLL_READ; - npds++; - pds[npds].fd = listenSock2; - pds[npds].in_flags = PR_POLL_READ; - npds++; - - sd = socket(AF_INET, SOCK_STREAM, 0); - PR_ASSERT(sd >= 0); - memset((char *) &saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = htonl(INADDR_ANY); - saddr.sin_port = htons(0); - - rv = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr)); - PR_ASSERT(rv == 0); - saddr_len = sizeof(saddr); - rv = getsockname(sd, (struct sockaddr *) &saddr, &saddr_len); - PR_ASSERT(rv == 0); - listenPort3 = ntohs(saddr.sin_port); - - rv = listen(sd, 5); - PR_ASSERT(rv == 0); - pds[npds].fd = socket_poll_fd = PR_CreateSocketPollFd(sd); - PR_ASSERT(pds[npds].fd); - pds[npds].in_flags = PR_POLL_READ; - npds++; - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu, %hu and %hu\n\n", - listenPort1, listenPort2, listenPort3); - printf("%s", buf); - - /* Testing timeout */ - printf("PR_Poll should time out in 5 seconds\n"); - retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5)); - if (retVal != 0) { - PR_snprintf(buf, sizeof(buf), - "PR_Poll should time out and return 0, but it returns %ld\n", - retVal); - fprintf(stderr, "%s", buf); - exit(1); - } - printf("PR_Poll timed out. Test passed.\n\n"); - - /* Testing bad fd */ - printf("PR_Poll should detect a bad file descriptor\n"); - if ((badFD = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a TCP socket\n"); - exit(1); - } - - pds[npds].fd = badFD; - pds[npds].in_flags = PR_POLL_READ; - npds++; - PR_Close(badFD); /* make the fd bad */ -#if 0 - retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); - if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) { - fprintf(stderr, "Failed to detect the bad fd: " - "PR_Poll returns %d, out_flags is 0x%hx\n", - retVal, pds[npds - 1].out_flags); - exit(1); - } - printf("PR_Poll detected the bad fd. Test passed.\n\n"); -#endif - npds--; - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort1, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - exit(1); - } - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort2, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - exit(1); - } - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort3, - PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - exit(1); - } - - - printf("Three client threads are created. Each of them will\n"); - printf("send data to one of the three ports the server is listening on.\n"); - printf("The data they send is the port number. Each of them send\n"); - printf("the data five times, so you should see ten lines below,\n"); - printf("interleaved in an arbitrary order.\n"); - - /* 30 events total */ - i = 0; - while (i < 30) { - PRPollDesc *tmp; - int nextIndex; - int nEvents = 0; - - retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(retVal != 0); /* no timeout */ - if (retVal == -1) { - fprintf(stderr, "PR_Poll failed\n"); - exit(1); - } - - nextIndex = 3; - /* the three listening sockets */ - for (j = 0; j < 3; j++) { - other_pds[j] = pds[j]; - PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 - && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); - if (pds[j].out_flags & PR_POLL_READ) { - PRFileDesc *sock; - - nEvents++; - if (j == 2) { - PROsfd newsd; - newsd = accept(PR_FileDesc2NativeHandle(pds[j].fd), NULL, 0); - if (newsd == -1) { - fprintf(stderr, "accept() failed\n"); - exit(1); - } - other_pds[nextIndex].fd = PR_CreateSocketPollFd(newsd); - PR_ASSERT(other_pds[nextIndex].fd); - other_pds[nextIndex].in_flags = PR_POLL_READ; - } else { - sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT); - if (sock == NULL) { - fprintf(stderr, "PR_Accept() failed\n"); - exit(1); - } - other_pds[nextIndex].fd = sock; - other_pds[nextIndex].in_flags = PR_POLL_READ; - } - nextIndex++; - } else if (pds[j].out_flags & PR_POLL_ERR) { - fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); - exit(1); - } else if (pds[j].out_flags & PR_POLL_NVAL) { - fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n", - PR_FileDesc2NativeHandle(pds[j].fd)); - exit(1); - } - } - - for (j = 3; j < npds; j++) { - PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 - && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); - if (pds[j].out_flags & PR_POLL_READ) { - PRInt32 nBytes; - - nEvents++; - /* XXX: This call is a hack and should be fixed */ - if (PR_GetDescType(pds[j].fd) == (PRDescType) 0) { - nBytes = recv(PR_FileDesc2NativeHandle(pds[j].fd), buf, - sizeof(buf), 0); - if (nBytes == -1) { - fprintf(stderr, "recv() failed\n"); - exit(1); - } - printf("Server read %d bytes from native fd %d\n",nBytes, - PR_FileDesc2NativeHandle(pds[j].fd)); -#ifdef WIN32 - closesocket((SOCKET)PR_FileDesc2NativeHandle(pds[j].fd)); -#else - close(PR_FileDesc2NativeHandle(pds[j].fd)); -#endif - PR_DestroySocketPollFd(pds[j].fd); - } else { - nBytes = PR_Read(pds[j].fd, buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read() failed\n"); - exit(1); - } - PR_Close(pds[j].fd); - } - /* Just to be safe */ - buf[BUF_SIZE - 1] = '\0'; - printf("The server received \"%s\" from a client\n", buf); - } else if (pds[j].out_flags & PR_POLL_ERR) { - fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); - exit(1); - } else if (pds[j].out_flags & PR_POLL_NVAL) { - fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n"); - exit(1); - } else { - other_pds[nextIndex] = pds[j]; - nextIndex++; - } - } - - PR_ASSERT(retVal == nEvents); - /* swap */ - tmp = pds; - pds = other_pds; - other_pds = tmp; - npds = nextIndex; - i += nEvents; - } - PR_DestroySocketPollFd(socket_poll_fd); - - printf("All tests finished\n"); - PR_Cleanup(); - return 0; -} - - -#endif /* ifdef WINCE */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/prpollml.c nspr-4.10.7/mozilla/nsprpub/pr/tests/prpollml.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/prpollml.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/prpollml.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * This test exercises the code that allocates and frees the syspoll_list - * array of PRThread in the pthreads version. This test is intended to be - * run under Purify to verify that there is no memory leak. - */ - -#include "nspr.h" - -#include -#include -#include - -#ifdef SYMBIAN -#define POLL_DESC_COUNT 128 -#else -#define POLL_DESC_COUNT 256 /* This should be greater than the - * STACK_POLL_DESC_COUNT macro in - * ptio.c to cause syspoll_list to - * be created. */ -#endif - -static PRPollDesc pd[POLL_DESC_COUNT]; - -static void Test(void) -{ - int i; - PRInt32 rv; - PRIntervalTime timeout; - - timeout = PR_MillisecondsToInterval(10); - /* cause syspoll_list to grow */ - for (i = 1; i <= POLL_DESC_COUNT; i++) { - rv = PR_Poll(pd, i, timeout); - if (rv != 0) { - fprintf(stderr, - "PR_Poll should time out but returns %d (%d, %d)\n", - (int) rv, (int) PR_GetError(), (int) PR_GetOSError()); - exit(1); - } - } - /* syspoll_list should be large enough for all these */ - for (i = POLL_DESC_COUNT; i >= 1; i--) { - rv = PR_Poll(pd, i, timeout); - if (rv != 0) { - fprintf(stderr, "PR_Poll should time out but returns %d\n", - (int) rv); - exit(1); - } - } -} - -static void ThreadFunc(void *arg) -{ - Test(); -} - -int main(int argc, char **argv) -{ - int i; - PRThread *thread; - PRFileDesc *sock; - PRNetAddr addr; - - memset(&addr, 0, sizeof(addr)); - addr.inet.family = PR_AF_INET; - addr.inet.port = PR_htons(0); - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - for (i = 0; i < POLL_DESC_COUNT; i++) { - sock = PR_NewTCPSocket(); - if (sock == NULL) { - fprintf(stderr, "PR_NewTCPSocket failed (%d, %d)\n", - (int) PR_GetError(), (int) PR_GetOSError()); - fprintf(stderr, "Ensure the per process file descriptor limit " - "is greater than %d.", POLL_DESC_COUNT); - exit(1); - } - if (PR_Bind(sock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_Bind failed (%d, %d)\n", - (int) PR_GetError(), (int) PR_GetOSError()); - exit(1); - } - if (PR_Listen(sock, 5) == PR_FAILURE) { - fprintf(stderr, "PR_Listen failed (%d, %d)\n", - (int) PR_GetError(), (int) PR_GetOSError()); - exit(1); - } - - pd[i].fd = sock; - pd[i].in_flags = PR_POLL_READ; - } - - /* first run the test on the primordial thread */ - Test(); - - /* then run the test on all three kinds of threads */ - thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - if (NULL == thread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - if (PR_JoinThread(thread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (NULL == thread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - if (PR_JoinThread(thread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD, PR_JOINABLE_THREAD, 0); - if (NULL == thread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - if (PR_JoinThread(thread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - for (i = 0; i < POLL_DESC_COUNT; i++) { - if (PR_Close(pd[i].fd) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - } - PR_Cleanup(); - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/prselect.c nspr-4.10.7/mozilla/nsprpub/pr/tests/prselect.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/prselect.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/prselect.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,340 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1997 - Netscape Communications Corporation -** -** Name: prselect_err.c -** -** Description: tests PR_Select with sockets Error condition functions. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" -#include "prttools.h" - - -#include "prinit.h" -#include "prio.h" -#include "prlog.h" -#include "prprf.h" -#include "prerror.h" -#include "prnetdb.h" - -#include -#include -#include - -/*********************************************************************** -** PRIVATE FUNCTION: Test_Result -** DESCRIPTION: Used in conjunction with the regress tool, prints out the -** status of the test case. -** INPUTS: PASS/FAIL -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** -** RESTRICTIONS: -** None -** MEMORY: NA -** ALGORITHM: Determine what the status is and print accordingly. -** -***********************************************************************/ - - -static Test_Result (int result) -{ - if (result == PASS) - printf ("PASS\n"); - else - printf ("FAIL\n"); -} - -static void -clientThreadFunc(void *arg) -{ - PRUint16 port = (PRUint16) arg; - PRFileDesc *sock; - PRNetAddr addr; - char buf[128]; - int i; - - addr.inet.family = AF_INET; - addr.inet.port = PR_htons(port); - addr.inet.ip = PR_htonl(INADDR_LOOPBACK); - PR_snprintf(buf, sizeof(buf), "%hu", port); - - for (i = 0; i < 5; i++) { - sock = PR_NewTCPSocket(); - PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); - PR_Write(sock, buf, sizeof(buf)); - PR_Close(sock); - } -} - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock1, *listenSock2; - PRFileDesc *badFD; - PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds; - PRIntn nfds; - PRUint16 listenPort1, listenPort2; - PRNetAddr addr; - PR_fd_set readFdSet; - char buf[128]; - PRThread *clientThread; - PRInt32 retVal; - PRIntn i, j; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (debug_mode) { - printf("This program tests PR_Select with sockets. Timeout, error\n"); - printf("reporting, and normal operation are tested.\n\n"); - } - - /* Create two listening sockets */ - if ((listenSock1 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - if (!debug_mode) Test_Result(FAIL); - exit(1); - } - addr.inet.family = AF_INET; - addr.inet.ip = PR_htonl(INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - if (!debug_mode) Test_Result(FAIL); - exit(1); - } - if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - if (!debug_mode) Test_Result(FAIL); - exit(1); - } - listenPort1 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock1, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - if (!debug_mode) Test_Result(FAIL); - exit(1); - } - - if ((listenSock2 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - if (!debug_mode) Test_Result(FAIL); - exit(1); - } - addr.inet.family = AF_INET; - addr.inet.ip = PR_htonl(INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - if (!debug_mode) Test_Result(FAIL); - exit(1); - } - if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - if (!debug_mode) Test_Result(FAIL); - exit(1); - } - listenPort2 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock2, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - if (!debug_mode) Test_Result(FAIL); - exit(1); - } - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu and %hu\n\n", - listenPort1, listenPort2); - printf("%s", buf); - - /* Set up the fd set */ - PR_FD_ZERO(&readFdSet); - PR_FD_SET(listenSock1, &readFdSet); - PR_FD_SET(listenSock2, &readFdSet); - - /* Testing timeout */ - if (debug_mode) printf("PR_Select should time out in 5 seconds\n"); - retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, - PR_SecondsToInterval(5)); - if (retVal != 0) { - PR_snprintf(buf, sizeof(buf), - "PR_Select should time out and return 0, but it returns %ld\n", - retVal); - fprintf(stderr, "%s", buf); - if (retVal == -1) { - fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), - PR_GetOSError()); - if (!debug_mode) Test_Result(FAIL); - } - exit(1); - } - if (debug_mode) printf("PR_Select timed out. Test passed.\n\n"); - else Test_Result(PASS); - - /* Testing bad fd */ - printf("PR_Select should detect a bad file descriptor\n"); - if ((badFD = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a TCP socket\n"); - exit(1); - } - - PR_FD_SET(listenSock1, &readFdSet); - PR_FD_SET(listenSock2, &readFdSet); - PR_FD_SET(badFD, &readFdSet); - PR_Close(badFD); /* make the fd bad */ - retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, - PR_INTERVAL_NO_TIMEOUT); - if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) { - fprintf(stderr, "Failed to detect the bad fd: " - "PR_Select returns %d\n", retVal); - if (retVal == -1) { - fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), - PR_GetOSError()); - } - exit(1); - } - printf("PR_Select detected a bad fd. Test passed.\n\n"); - PR_FD_CLR(badFD, &readFdSet); - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort1, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - exit(1); - } - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort2, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - exit(1); - } - - printf("Two client threads are created. Each of them will\n"); - printf("send data to one of the two ports the server is listening on.\n"); - printf("The data they send is the port number. Each of them send\n"); - printf("the data five times, so you should see ten lines below,\n"); - printf("interleaved in an arbitrary order.\n"); - - /* set up the fd array */ - fds = fds0; - other_fds = fds1; - fds[0] = listenSock1; - fds[1] = listenSock2; - nfds = 2; - PR_FD_SET(listenSock1, &readFdSet); - PR_FD_SET(listenSock2, &readFdSet); - - /* 20 events total */ - i = 0; - while (i < 20) { - PRFileDesc **tmp; - int nextIndex; - int nEvents = 0; - - retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, - PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(retVal != 0); /* no timeout */ - if (retVal == -1) { - fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - exit(1); - } - - nextIndex = 2; - /* the two listening sockets */ - for (j = 0; j < 2; j++) { - other_fds[j] = fds[j]; - if (PR_FD_ISSET(fds[j], &readFdSet)) { - PRFileDesc *sock; - - nEvents++; - sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT); - if (sock == NULL) { - fprintf(stderr, "PR_Accept() failed\n"); - exit(1); - } - other_fds[nextIndex] = sock; - PR_FD_SET(sock, &readFdSet); - nextIndex++; - } - PR_FD_SET(fds[j], &readFdSet); - } - - for (j = 2; j < nfds; j++) { - if (PR_FD_ISSET(fds[j], &readFdSet)) { - PRInt32 nBytes; - - PR_FD_CLR(fds[j], &readFdSet); - nEvents++; - nBytes = PR_Read(fds[j], buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read() failed\n"); - exit(1); - } - /* Just to be safe */ - buf[127] = '\0'; - PR_Close(fds[j]); - printf("The server received \"%s\" from a client\n", buf); - } else { - PR_FD_SET(fds[j], &readFdSet); - other_fds[nextIndex] = fds[j]; - nextIndex++; - } - } - - PR_ASSERT(retVal == nEvents); - /* swap */ - tmp = fds; - fds = other_fds; - other_fds = tmp; - nfds = nextIndex; - i += nEvents; - } - - printf("All tests finished\n"); - PR_Cleanup(); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/prttools.h nspr-4.10.7/mozilla/nsprpub/pr/tests/prttools.h --- nspr-4.9.5/mozilla/nsprpub/pr/tests/prttools.h 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/prttools.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Used in Regress Tool */ -#define NOSTATUS 2 -#define PASS 1 -#define FAIL 0 - -PRIntn debug_mode=0; diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/pushtop.c nspr-4.10.7/mozilla/nsprpub/pr/tests/pushtop.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/pushtop.c 2012-09-28 14:21:22.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/pushtop.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* A regression test for bug 794316 */ - -#include -#include - -#include "prio.h" - -static PRIOMethods dummyMethods; - -int main() -{ - PRDescIdentity topId, middleId, bottomId; - PRFileDesc *top, *middle, *bottom; - PRFileDesc *fd; - - topId = PR_GetUniqueIdentity("top"); - middleId = PR_GetUniqueIdentity("middle"); - bottomId = PR_GetUniqueIdentity("bottom"); - - top = PR_CreateIOLayerStub(topId, &dummyMethods); - middle = PR_CreateIOLayerStub(middleId, &dummyMethods); - bottom = PR_CreateIOLayerStub(bottomId, &dummyMethods); - - fd = bottom; - PR_PushIOLayer(fd, PR_TOP_IO_LAYER, middle); - PR_PushIOLayer(fd, PR_TOP_IO_LAYER, top); - - top = fd; - middle = top->lower; - bottom = middle->lower; - - /* Verify that the higher pointers are correct. */ - if (middle->higher != top) { - fprintf(stderr, "middle->higher is wrong\n"); - fprintf(stderr, "FAILED\n"); - exit(1); - } - if (bottom->higher != middle) { - fprintf(stderr, "bottom->higher is wrong\n"); - fprintf(stderr, "FAILED\n"); - exit(1); - } - - top = PR_PopIOLayer(fd, topId); - top->dtor(top); - - middle = fd; - bottom = middle->lower; - - /* Verify that the higher pointer is correct. */ - if (bottom->higher != middle) { - fprintf(stderr, "bottom->higher is wrong\n"); - fprintf(stderr, "FAILED\n"); - exit(1); - } - - middle = PR_PopIOLayer(fd, middleId); - middle->dtor(middle); - if (fd->identity != bottomId) { - fprintf(stderr, "The bottom layer has the wrong identity\n"); - fprintf(stderr, "FAILED\n"); - exit(1); - } - fd->dtor(fd); - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/randseed.c nspr-4.10.7/mozilla/nsprpub/pr/tests/randseed.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/randseed.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/randseed.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: rngseed.c -** Description: -** Test NSPR's Random Number Seed generator -** -** Initial test: Just make sure it outputs some data. -** -** ... more? ... check some iterations to ensure it is random (no dupes) -** ... more? ... histogram distribution of random numbers -*/ - -#include "plgetopt.h" -#include "nspr.h" -#include "prrng.h" -#include -#include -#include - -/* -** Test harness infrastructure -*/ -PRLogModuleInfo *lm; -PRLogModuleLevel msgLevel = PR_LOG_NONE; -PRIntn debug = 0; -PRUint32 failed_already = 0; -/* end Test harness infrastructure */ - -PRIntn optRandCount = 30; -char buf[40]; -PRSize bufSize = sizeof(buf); -PRSize rSize; -PRIntn i; - -/* -** Emit help text for this test -*/ -static void Help( void ) -{ - printf("Template: Help(): display your help message(s) here"); - exit(1); -} /* end Help() */ - -static void PrintRand( void *buf, PRIntn size ) -{ - PRUint32 *rp = buf; - PRIntn i; - - printf("%4.4d--\n", size ); - while (size > 0 ) { - switch( size ) { - case 1 : - printf("%2.2X\n", *(rp++) ); - size -= 4; - break; - case 2 : - printf("%4.4X\n", *(rp++) ); - size -= 4; - break; - case 3 : - printf("%6.6X\n", *(rp++) ); - size -= 4; - break; - default: - while ( size >= 4) { - PRIntn i = 3; - do { - printf("%8.8X ", *(rp++) ); - size -= 4; - } while( i-- ); - i = 3; - printf("\n"); - } - break; - } /* end switch() */ - } /* end while() */ -} /* end PrintRand() */ - - -int main(int argc, char **argv) -{ - { - /* - ** Get command line options - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "hdv"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug */ - debug = 1; - msgLevel = PR_LOG_ERROR; - break; - case 'v': /* verbose mode */ - msgLevel = PR_LOG_DEBUG; - break; - case 'h': /* help message */ - Help(); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - } - - lm = PR_NewLogModule("Test"); /* Initialize logging */ - for ( i = 0; i < optRandCount ; i++ ) { - memset( buf, 0, bufSize ); - rSize = PR_GetRandomNoise( buf, bufSize ); - if (!rSize) { - fprintf(stderr, "Not implemented\n" ); - failed_already = PR_TRUE; - break; - } - if (debug) PrintRand( buf, rSize ); - } - - if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); - return( (failed_already == PR_TRUE )? 1 : 0 ); -} /* main() */ -/* end template.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/ranfile.c nspr-4.10.7/mozilla/nsprpub/pr/tests/ranfile.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/ranfile.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/ranfile.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,390 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Contact: AOF -** -** Name: ranfile.c -** -** Description: Test to hammer on various components of NSPR -** Modification History: -** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prinit.h" -#include "prthread.h" -#include "prlock.h" -#include "prcvar.h" -#include "prmem.h" -#include "prinrval.h" -#include "prio.h" - -#include -#include - -static PRIntn debug_mode = 0; -static PRIntn failed_already=0; -static PRThreadScope thread_scope = PR_LOCAL_THREAD; - -typedef enum {sg_go, sg_stop, sg_done} Action; -typedef enum {sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem; - -typedef struct Hammer_s { - PRLock *ml; - PRCondVar *cv; - PRUint32 id; - PRUint32 limit; - PRUint32 writes; - PRThread *thread; - PRIntervalTime timein; - Action action; - Problem problem; -} Hammer_t; - -#define DEFAULT_LIMIT 10 -#define DEFAULT_THREADS 2 -#define DEFAULT_LOOPS 1 - -static PRInt32 pageSize = 1024; -static const char* baseName = "./"; -static const char *programName = "Random File"; - -/*********************************************************************** -** PRIVATE FUNCTION: RandomNum -** DESCRIPTION: -** Generate a pseudo-random number -** INPUTS: None -** OUTPUTS: None -** RETURN: A pseudo-random unsigned number, 32-bits wide -** SIDE EFFECTS: -** Updates random seed (a static) -** RESTRICTIONS: -** None -** MEMORY: NA -** ALGORITHM: -** Uses the current interval timer value, promoted to a 64 bit -** float as a multiplier for a static residue (which begins -** as an uninitialized variable). The result is bits [16..48) -** of the product. Seed is then updated with the return value -** promoted to a float-64. -***********************************************************************/ -static PRUint32 RandomNum(void) -{ - PRUint32 rv; - PRUint64 shift; - static PRFloat64 seed = 0x58a9382; /* Just make sure it isn't 0! */ - PRFloat64 random = seed * (PRFloat64)PR_IntervalNow(); - LL_USHR(shift, *((PRUint64*)&random), 16); - LL_L2UI(rv, shift); - seed = (PRFloat64)rv; - return rv; -} /* RandomNum */ - -/*********************************************************************** -** PRIVATE FUNCTION: Thread -** DESCRIPTION: -** Hammer on the file I/O system -** INPUTS: A pointer to the thread's private data -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** Creates, accesses and deletes a file -** RESTRICTIONS: -** (Currently) must have file create permission in "/usr/tmp". -** MEMORY: NA -** ALGORITHM: -** This function is a root of a thread -** 1) Creates a (hopefully) unique file in /usr/tmp/ -** 2) Writes a zero to a random number of sequential pages -** 3) Closes the file -** 4) Reopens the file -** 5) Seeks to a random page within the file -** 6) Writes a one byte on that page -** 7) Repeat steps [5..6] for each page in the file -** 8) Close and delete the file -** 9) Repeat steps [1..8] until told to stop -** 10) Notify complete and return -***********************************************************************/ -static void PR_CALLBACK Thread(void *arg) -{ - PRUint32 index; - char filename[30]; - const char zero = 0; - PRFileDesc *file = NULL; - PRStatus rv = PR_SUCCESS; - Hammer_t *cd = (Hammer_t*)arg; - - (void)sprintf(filename, "%ssg%04ld.dat", baseName, cd->id); - - if (debug_mode) printf("Starting work on %s\n", filename); - - while (PR_TRUE) - { - PRUint32 bytes; - PRUint32 minor = (RandomNum() % cd->limit) + 1; - PRUint32 random = (RandomNum() % cd->limit) + 1; - PRUint32 pages = (RandomNum() % cd->limit) + 10; - while (minor-- > 0) - { - cd->problem = sg_okay; - if (cd->action != sg_go) goto finished; - cd->problem = sg_open; - file = PR_Open(filename, PR_RDWR|PR_CREATE_FILE, 0666); - if (file == NULL) goto finished; - for (index = 0; index < pages; index++) - { - cd->problem = sg_okay; - if (cd->action != sg_go) goto close; - cd->problem = sg_seek; - bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET); - if (bytes != pageSize * index) goto close; - cd->problem = sg_write; - bytes = PR_Write(file, &zero, sizeof(zero)); - if (bytes <= 0) goto close; - cd->writes += 1; - } - cd->problem = sg_close; - rv = PR_Close(file); - if (rv != PR_SUCCESS) goto purge; - - cd->problem = sg_okay; - if (cd->action != sg_go) goto purge; - - cd->problem = sg_open; - file = PR_Open(filename, PR_RDWR, 0666); - for (index = 0; index < pages; index++) - { - cd->problem = sg_okay; - if (cd->action != sg_go) goto close; - cd->problem = sg_seek; - bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET); - if (bytes != pageSize * index) goto close; - cd->problem = sg_write; - bytes = PR_Write(file, &zero, sizeof(zero)); - if (bytes <= 0) goto close; - cd->writes += 1; - random = (random + 511) % pages; - } - cd->problem = sg_close; - rv = PR_Close(file); - if (rv != PR_SUCCESS) goto purge; - cd->problem = sg_delete; - rv = PR_Delete(filename); - if (rv != PR_SUCCESS) goto finished; - } - } - -close: - (void)PR_Close(file); -purge: - (void)PR_Delete(filename); -finished: - PR_Lock(cd->ml); - cd->action = sg_done; - PR_NotifyCondVar(cd->cv); - PR_Unlock(cd->ml); - - if (debug_mode) printf("Ending work on %s\n", filename); - - return; -} /* Thread */ - -static Hammer_t hammer[100]; -static PRCondVar *cv; -/*********************************************************************** -** PRIVATE FUNCTION: main -** DESCRIPTION: -** Hammer on the file I/O system -** INPUTS: The usual argc and argv -** argv[0] - program name (not used) -** argv[1] - the number of times to execute the major loop -** argv[2] - the number of threads to toss into the batch -** argv[3] - the clipping number applied to randoms -** default values: loops = 2, threads = 10, limit = 57 -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** Creates, accesses and deletes lots of files -** RESTRICTIONS: -** (Currently) must have file create permission in "/usr/tmp". -** MEMORY: NA -** ALGORITHM: -** 1) Fork a "Thread()" -** 2) Wait for 'interleave' seconds -** 3) For [0..'threads') repeat [1..2] -** 4) Mark all objects to stop -** 5) Collect the threads, accumulating the results -** 6) For [0..'loops') repeat [1..5] -** 7) Print accumulated results and exit -** -** Characteristic output (from IRIX) -** Random File: Using loops = 2, threads = 10, limit = 57 -** Random File: [min [avg] max] writes/sec average -***********************************************************************/ -int main(int argc, char **argv) -{ - PRLock *ml; - PRUint32 id = 0; - int active, poll; - PRIntervalTime interleave; - PRIntervalTime duration = 0; - int limit = 0, loops = 0, threads = 0, times; - PRUint32 writes, writesMin = 0x7fffffff, writesTot = 0, durationTot = 0, writesMax = 0; - - const char *where[] = {"okay", "open", "close", "delete", "write", "seek"}; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'G': /* global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'l': /* limiting number */ - limit = atoi(opt->value); - break; - case 't': /* number of threads */ - threads = atoi(opt->value); - break; - case 'i': /* iteration counter */ - loops = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - interleave = PR_SecondsToInterval(10); - - ml = PR_NewLock(); - cv = PR_NewCondVar(ml); - - if (loops == 0) loops = DEFAULT_LOOPS; - if (limit == 0) limit = DEFAULT_LIMIT; - if (threads == 0) threads = DEFAULT_THREADS; - - if (debug_mode) printf( - "%s: Using loops = %d, threads = %d, limit = %d and %s threads\n", - programName, loops, threads, limit, - (thread_scope == PR_LOCAL_THREAD) ? "LOCAL" : "GLOBAL"); - - for (times = 0; times < loops; ++times) - { - if (debug_mode) printf("%s: Setting concurrency level to %d\n", programName, times + 1); - PR_SetConcurrency(times + 1); - for (active = 0; active < threads; active++) - { - hammer[active].ml = ml; - hammer[active].cv = cv; - hammer[active].id = id++; - hammer[active].writes = 0; - hammer[active].action = sg_go; - hammer[active].problem = sg_okay; - hammer[active].limit = (RandomNum() % limit) + 1; - hammer[active].timein = PR_IntervalNow(); - hammer[active].thread = PR_CreateThread( - PR_USER_THREAD, Thread, &hammer[active], - PR_GetThreadPriority(PR_GetCurrentThread()), - thread_scope, PR_JOINABLE_THREAD, 0); - - PR_Lock(ml); - PR_WaitCondVar(cv, interleave); /* start new ones slowly */ - PR_Unlock(ml); - } - - /* - * The last thread started has had the opportunity to run for - * 'interleave' seconds. Now gather them all back in. - */ - PR_Lock(ml); - for (poll = 0; poll < threads; poll++) - { - if (hammer[poll].action == sg_go) /* don't overwrite done */ - hammer[poll].action = sg_stop; /* ask him to stop */ - } - PR_Unlock(ml); - - while (active > 0) - { - for (poll = 0; poll < threads; poll++) - { - PR_Lock(ml); - while (hammer[poll].action < sg_done) - PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(ml); - - active -= 1; /* this is another one down */ - (void)PR_JoinThread(hammer[poll].thread); - hammer[poll].thread = NULL; - if (hammer[poll].problem == sg_okay) - { - duration = PR_IntervalToMilliseconds( - PR_IntervalNow() - hammer[poll].timein); - writes = hammer[poll].writes * 1000 / duration; - if (writes < writesMin) - writesMin = writes; - if (writes > writesMax) - writesMax = writes; - writesTot += hammer[poll].writes; - durationTot += duration; - } - else - if (debug_mode) printf( - "%s: test failed %s after %ld seconds\n", - programName, where[hammer[poll].problem], duration); - else failed_already=1; - } - } - } - if (debug_mode) printf( - "%s: [%ld [%ld] %ld] writes/sec average\n", - programName, writesMin, writesTot * 1000 / durationTot, writesMax); - - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); - - if (failed_already) - { - printf("FAIL\n"); - return 1; - } - else - { - printf("PASS\n"); - return 0; - } -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/README.TXT nspr-4.10.7/mozilla/nsprpub/pr/tests/README.TXT --- nspr-4.9.5/mozilla/nsprpub/pr/tests/README.TXT 2008-08-04 22:36:03.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/README.TXT 1970-01-01 00:00:00.000000000 +0000 @@ -1,407 +0,0 @@ -File: pr/tests/readme - -This document describes the test cases in the NSPR directory -pr/tests. - -===================================================================== -There is a sub-directory here: - -dll - sources for the .dll(.so) used by test dlltest.c - -===================================================================== -The individual files are described here. - -The script 'runtests.ksh' enumerates and runs test cases that are -expected to run on all platforms. - - -accept.c - Tests PR_Accept() and related socket functions. - -acceptread.c - Tests PR_AcceptRead() - -alarm.c - Tests alarm functions declared in obsolete/pralarm.h. - The alarm functions are obsolete, so is this test. - -atomic.c - Tests Atomic operations defined in pratom.h - -attach.c - Test PR_AttachThread() - Note: This is an NSPR private function. - -bigfile.c - Test 64bit file offset functions declared in prio.h - -bug1test.c - Demonstrates a bug on NT. - -cleanup.c - Tests PR_Cleanup() declared in prinit.h - -cltsrv.c - Tests many socket functions. - -concur.c - Tests threading functions and concurrent operations. - -cvar.c - Tests condition variables. - -cvar2.c - Tests condition variables. A rather abusive test. - -dbmalloc.c - Obsolete. Originally for testing debug builds of NSPR's malloc. - -dbmalloc1.c - Obsolete. Originally for testing debug builds of NSPR's malloc. - -dceemu.c - Tests special functions for DCE emulation. - -depend.c - Obsoltet. Tests early spec for library dependency. - -dlltest.c - Tests dynamic library functions. Used with dll/my.c - -dtoa.c - Tests conversions of double to string. - -exit.c - Tests PR_ProcessExit() declared in prinit.h - -fileio.c - Tests NSPR semaphores a bit of file i/o and threading - functions. - -foreign.c - Test auto-attach of a thread created by something other than - NSPR. - -forktest.c - Limited use. Tests unix fork() and related functions. - -fsync.c - Tests use of PR_Sync() declared in prio.h - -getproto.c - Tests socket functions PR_GetProtoByName(), etc. - -i2l.c - Tests LongLong functions for converting 32bit integer to 64bit - integer. - -initclk.c - Tests timing on minimal use of condition variable - -inrval.c - Tests interval timing functions. - -instrumt.c - Tests instrumentation functions. prcountr.h prtrace.h - -intrupt.c - Tests PR_Interrupt() - -ioconthr.c - Tests i/o continuation mechanism in pthreads. - -io_timeout.c - Test socket i/o timeouts. - -io_timeoutk.c - Obsolete. Subsumed in io_timeout.c - -io_timeoutu.c - Obsolete. Subsumed in io_timeout.c - -ipv6.c - Tests IPv6. IPv6 is not used by NSPR clients. - -join.c - Tests PR_JoinThread() - -joinkk.c - Tests PR_JoinThread() - -joinku.c - Tests PR_JoinThread() - -joinuk.c - Tests PR_JoinThread() - -joinuu.c - Tests PR_JoinThread() - -layer.c - Tests layered I/O. - -lazyinit.c - Tests implicit initialization. - -lltest.c - Tests LongLong (64bit integer) arithmentic and conversions. - -lock.c - Tests PR_Lock() in heavily threaded environment. - -lockfile.c - Test PR_Lockfile(). - -logger.c - Tests PR_LOG() - -makefile - The makefile that builds all the tests - -many_cv.c - Tests aquiring a large number of condition variables. - -multiwait.c - ??? - -nbconn.c - Test non-blocking connect. - -nblayer.c - Tests NSPR's layered I/O capability. - -nonblock.c - Tests operations on non-blocking socket. - -op_2long.c - Tests PR_Open() where filename is too long. - -op_filnf.c - Tests PR_Open() where filename is NotFound. - -op_filok.c - Tests PR_Open() where filename is accessable. - -op_noacc.c - Tests PR_Open() where file permissions are wrong. - Limited use. Windows has no concept of Unix style file permissions. - -op_nofil.c - Tests PR_Open() where filename does not exist. - -parent.c - Test parent/child process capability - -perf.c - Tests and measures context switch times for various thread - syncronization functions. - -pipeping.c - Tests inter-process pipes. Run with pipepong.c - -pipepong.c - Tests inter-process pipes. Run with pipeping.c - -pipeself.c - Tests inter-thread pipes. - -pollable.c - Tests pollable events. prio.h - -poll_er.c - Tests PR_Poll() where an error is expected. - -poll_nm.c - Tests PR_Poll() where normal operation is expected. - -poll_to.c - Tests PR_Poll() where timeout is expected. - -prftest.c - Tests printf-like formatting. - -prftest1.c - Obsolete. Subsumed in prftest.c - -prftest2.c - Obsolete. Subsumed in prftest.c - -priotest.c - Limited use. Tests NSPR thread dispatching priority. - -provider.c - -prpoll.c - Tests PR_Poll(). - -prselect.c - Obsolete. PR_Select() is obsolete. - -prttools.h - Unused file. - -ranfile.c - Tests random file access. - -readme - This file. - -runtests.ksh - A korn shell script that runs a set of tests that should run - on any of the NSPR supported platforms. - -runtests.pl - A perl script to run the test cases. This srcipt runs tests - common to all platforms and runs tests applicable to specific - platforms. Uses file runtests.txt to control execution. - -runtests.txt - Control file for perl script: runtests.pl - -rwlocktest.c - Tests Reader/Writer lock - -selct_er.c - Obsolete. PR_Select() is obsolete. - -selct_nm.c - Obsolete. PR_Select() is obsolete. - -selct_to.c - Obsolete. PR_Select() is obsolete. - -select2.c - Obsolete. PR_Select() is obsolete. - -sel_spd.c - Obsolete. PR_Select() is obsolete. - -sem.c - Obsolete. Semaphores are not supported. - -server_test.c - Tests sockets by simulating a server in loopback mode. - Makes its own client threads. - -servr_kk.c - Tests client/server sockets, threads using system threads. - -servr_ku.c - Tests client/server sockets, threads using system and user threads. - -servr_uk.c - Tests client/server sockets, threads using system and user threads. - -servr_uu.c - Tests client/server sockets, threads user threads. - -short_thread.c - Tests short-running threads. Useful for testing for race conditions. - -sigpipe.c - Tests NSPR's SIGPIPE handler. Unix only. - -sleep.c - Limited use. Tests sleep capability of platform. - -socket.c - Tests many socket functions. - -sockopt.c - Tests setting and getting socket options. - -sprintf.c - Tests sprintf. - -sproc_ch.c - Obsolete. Tests IRIX sproc-based threads. - -sproc_p.c - Obsolete. Tests IRIX sproc-based threads. - -stack.c - Test atomic stack operations. - -stat.c - Tests performance of getfileinfo() vs. stat() - -stdio.c - Tests NSPR's handling of stdin, stdout, stderr. - -strod.c - Tests formatting of double precision floating point. - -suspend.c - Private interfaces PR_SuspendAll(), PR_ResumeAll(), etc. - -switch.c - Tests thread switching - -system.c - Tests PR_GetSystemInfo() - -testbit.c - Tests bit arrays. - -testfile.c - Tests many file I/O functions. - -threads.c - Tests thread caching. - -thruput.c - Tests socket thruput. Must be run by hand as client/server. - Does not self terminate. - -time.c - Incomplete. Limited use. - -timemac.c - Test time and date functions. Originally for Mac. - -timetest.c - Tests time conversion over a wide range of dates. - -tmoacc.c - Server to tmocon.c and writev.c - Do not run it by itself. - -tmocon.c - Client thread to tmoacc.c - -tpd.c - Tests thread private data. - -udpsrv.c - Tests UDP socket functions. - -ut_ttools.h - unused file. - -version.c - Extract and print library version data. - -vercheck.c - Test PR_VersionCheck(). - -writev.c - Tests gather-write on a socket. Requires tmoacc.c - -xnotify.c - Tests cached monitors. - -yield.c - Limited use - -y2k.c - Test to verify NSPR's date functions as Y2K compliant. - -dll\Makefile - makefile for mygetval.c, mysetval.c - -dll\mygetval.c - Dynamic library test. See also dlltest.c - -dll\mysetval.c - Dynamic library test. See also dlltest.c diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/reinit.c nspr-4.10.7/mozilla/nsprpub/pr/tests/reinit.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/reinit.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/reinit.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* This test verifies that NSPR can be cleaned up and reinitialized. */ - -#include "nspr.h" -#include - -int main() -{ - PRStatus rv; - - fprintf(stderr, "Init 1\n"); - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - fprintf(stderr, "Cleanup 1\n"); - rv = PR_Cleanup(); - if (rv != PR_SUCCESS) { - fprintf(stderr, "FAIL\n"); - return 1; - } - - fprintf(stderr, "Init 2\n"); - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - fprintf(stderr, "Cleanup 2\n"); - rv = PR_Cleanup(); - if (rv != PR_SUCCESS) { - fprintf(stderr, "FAIL\n"); - return 1; - } - - fprintf(stderr, "PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/rmdir.c nspr-4.10.7/mozilla/nsprpub/pr/tests/rmdir.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/rmdir.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/rmdir.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: rmdir.c -** Description: Demonstrate bugzilla 80884. -** -** after fix to unix_errors.c, message should report correct -** failure of PR_Rmdir(). -** -** -** -*/ - -#include -#include -#include -#include -#include "plgetopt.h" - -#define DIRNAME "xxxBug80884/" -#define FILENAME "file80883" - -PRBool failed_already = PR_FALSE; -PRBool debug_mode = PR_FALSE; - -PRLogModuleInfo *lm; - -/* -** Help() -- print Usage information -*/ -static void Help( void ) { - fprintf(stderr, "template usage:\n" - "\t-d debug mode\n" - ); -} /* --- end Help() */ - -int main(int argc, char **argv) -{ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dh"); - PRFileDesc* fd; - PRErrorCode err; - - /* parse command line options */ - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) continue; - switch (opt->option) { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - lm = PR_NewLogModule( "testcase" ); - - (void) PR_MkDir( DIRNAME, 0777); - fd = PR_Open( DIRNAME FILENAME, PR_CREATE_FILE|PR_RDWR, 0666); - if (fd == 0) { - PRErrorCode err = PR_GetError(); - fprintf(stderr, "create file fails: %d: %s\n", err, - PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); - failed_already = PR_TRUE; - goto Finished; - } - - PR_Close(fd); - - if (PR_RmDir( DIRNAME ) == PR_SUCCESS) { - fprintf(stderr, "remove directory succeeds\n"); - failed_already = PR_TRUE; - goto Finished; - } - - err = PR_GetError(); - fprintf(stderr, "remove directory fails with: %d: %s\n", err, - PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); - - (void) PR_Delete( DIRNAME FILENAME); - (void) PR_RmDir( DIRNAME ); - - return 0; - -Finished: - if ( debug_mode ) printf("%s\n", ( failed_already ) ? "FAILED" : "PASS" ); - return( (failed_already)? 1 : 0 ); -} /* --- end main() */ -/* --- end template.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/runtests.pl nspr-4.10.7/mozilla/nsprpub/pr/tests/runtests.pl --- nspr-4.9.5/mozilla/nsprpub/pr/tests/runtests.pl 2012-09-28 05:25:00.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/runtests.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,370 +0,0 @@ -#!/usr/bin/perl -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -use POSIX qw(:sys_wait_h); -use POSIX qw(setsid); -use FileHandle; - -# Constants -$WINOS = "MSWin32"; - -$osname = $^O; - -use Cwd; -if ($osname =~ $WINOS) { - # Windows - require Win32::Process; - require Win32; -} - -# Get environment variables. -$output_file = $ENV{NSPR_TEST_LOGFILE}; -$timeout = $ENV{TEST_TIMEOUT}; - -$timeout = 0 if (!defined($timeout)); - -sub getTime { - ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(); - - $year = 1900 + $yearOffset; - - $theTime = sprintf("%04d-%02d-%02d %02d:%02d:%02d",$year,$month,$dayOfMonth,$hour,$minute,$second); - return $theTime; -} - -sub open_log { - - if (!defined($output_file)) { - print "No output file.\n"; - # null device - if ($osname =~ $WINOS) { - $output_file = "nul"; - } else { - $output_file = "/dev/null"; - } - } - - # use STDOUT for OF (to print summary of test results) - open(OF, ">&STDOUT") or die "Can't reuse STDOUT for OF\n"; - OF->autoflush; - # reassign STDOUT to $output_file (to print details of test results) - open(STDOUT, ">$output_file") or die "Can't open file $output_file for STDOUT\n"; - STDOUT->autoflush; - # redirect STDERR to STDOUT - open(STDERR, ">&STDOUT") or die "Can't redirect STDERR to STDOUT\n"; - STDERR->autoflush; - - # Print header test in summary - $now = getTime; - print OF "\nNSPR Test Results - tests\n"; - print OF "\nBEGIN\t\t\t$now\n"; - print OF "NSPR_TEST_LOGFILE\t$output_file\n"; - print OF "TEST_TIMEOUT\t$timeout\n\n"; - print OF "\nTest\t\t\tResult\n\n"; -} - -sub close_log { - # end of test marker in summary - $now = getTime; - print OF "END\t\t\t$now\n"; - - close(OF) or die "Can't close file OF\n"; - close(STDERR) or die "Can't close STDERR\n"; - close(STDOUT) or die "Can't close STDOUT\n"; -} - -sub print_begin { -$lprog = shift; - - # Summary output - print OF "$prog"; - # Full output - $now = getTime; - print "BEGIN TEST: $lprog ($now)\n\n"; -} - -sub print_end { -($lprog, $exit_status, $exit_signal, $exit_core) = @_; - - if (($exit_status == 0) && ($exit_signal == 0) && ($exit_core == 0)) { - $str_status = "Passed"; - } else { - $str_status = "FAILED"; - } - if ($exit_signal != 0) { - $str_signal = " - signal $exit_signal"; - } else { - $str_signal = ""; - } - if ($exit_core != 0) { - $str_core = " - core dumped"; - } else { - $str_core = ""; - } - $now = getTime; - # Full output - print "\nEND TEST: $lprog ($now)\n"; - print "TEST STATUS: $lprog = $str_status (exit status " . $exit_status . $str_signal . $str_core . ")\n"; - print "--------------------------------------------------\n\n"; - # Summary output - print OF "\t\t\t$str_status\n"; -} - -sub ux_start_prog { -# parameters: -$lprog = shift; # command to run - - # Create a process group for the child - # so we can kill all of it if needed - setsid or die "setsid failed: $!"; - # Start test program - exec("./$lprog"); - # We should not be here unless exec failed. - print "Faild to exec $lprog"; - exit 1 << 8; -} - -sub ux_wait_timeout { -# parameters: -$lpid = shift; # child process id -$ltimeout = shift; # timeout - - if ($ltimeout == 0) { - # No timeout: use blocking wait - $ret = waitpid($lpid,0); - # Exit and don't kill - $lstatus = $?; - $ltimeout = -1; - } else { - while ($ltimeout > 0) { - # Check status of child using non blocking wait - $ret = waitpid($lpid, WNOHANG); - if ($ret == 0) { - # Child still running - # print "Time left=$ltimeout\n"; - sleep 1; - $ltimeout--; - } else { - # Child has ended - $lstatus = $?; - # Exit the wait loop and don't kill - $ltimeout = -1; - } - } - } - - if ($ltimeout == 0) { - # we ran all the timeout: it's time to kill the child - print "Timeout ! Kill child process $lpid\n"; - # Kill the child process and group - kill(-9,$lpid); - $lstatus = 9; - } - - return $lstatus; -} - -sub ux_test_prog { -# parameters: -$prog = shift; # Program to test - - $child_pid = fork; - if ($child_pid == 0) { - # we are in the child process - print_begin($prog); - ux_start_prog($prog); - } else { - # we are in the parent process - $status = ux_wait_timeout($child_pid,$timeout); - # See Perlvar for documentation of $? - # exit status = $status >> 8 - # exit signal = $status & 127 (no signal = 0) - # core dump = $status & 128 (no core = 0) - print_end($prog, $status >> 8, $status & 127, $status & 128); - } - - return $status; -} - -sub win_path { -$lpath = shift; - - # MSYS drive letter = /c/ -> c:/ - $lpath =~ s/^\/(\w)\//$1:\//; - # Cygwin drive letter = /cygdrive/c/ -> c:/ - $lpath =~ s/^\/cygdrive\/(\w)\//$1:\//; - # replace / with \\ - $lpath =~ s/\//\\\\/g; - - return $lpath; -} - -sub win_ErrorReport{ - print Win32::FormatMessage( Win32::GetLastError() ); -} - -sub win_test_prog { -# parameters: -$prog = shift; # Program to test - - $status = 1; - $curdir = getcwd; - $curdir = win_path($curdir); - $prog_path = "$curdir\\$prog.exe"; - - print_begin($prog); - - Win32::Process::Create($ProcessObj, - "$prog_path", - "$prog", - 0, - NORMAL_PRIORITY_CLASS, - ".")|| die win_ErrorReport(); - $retwait = $ProcessObj->Wait($timeout * 1000); - - if ( $retwait == 0) { - # the prog didn't finish after the timeout: kill - $ProcessObj->Kill($status); - print "Timeout ! Process killed with exit status $status\n"; - } else { - # the prog finished before the timeout: get exit status - $ProcessObj->GetExitCode($status); - } - # There is no signal, no core on Windows - print_end($prog, $status, 0, 0); - - return $status -} - -# MAIN --------------- -@progs = ( -"accept", -"acceptread", -"acceptreademu", -"affinity", -"alarm", -"anonfm", -"atomic", -"attach", -"bigfile", -"cleanup", -"cltsrv", -"concur", -"cvar", -"cvar2", -"dlltest", -"dtoa", -"errcodes", -"exit", -"fdcach", -"fileio", -"foreign", -"formattm", -"fsync", -"gethost", -"getproto", -"i2l", -"initclk", -"inrval", -"instrumt", -"intrio", -"intrupt", -"io_timeout", -"ioconthr", -"join", -"joinkk", -"joinku", -"joinuk", -"joinuu", -"layer", -"lazyinit", -"libfilename", -"lltest", -"lock", -"lockfile", -"logfile", -"logger", -"many_cv", -"multiwait", -"nameshm1", -"nblayer", -"nonblock", -"ntioto", -"ntoh", -"op_2long", -"op_excl", -"op_filnf", -"op_filok", -"op_nofil", -"parent", -"parsetm", -"peek", -"perf", -"pipeping", -"pipeping2", -"pipeself", -"poll_nm", -"poll_to", -"pollable", -"prftest", -"primblok", -"provider", -"prpollml", -"pushtop", -"ranfile", -"randseed", -"reinit", -"rwlocktest", -"sel_spd", -"selct_er", -"selct_nm", -"selct_to", -"selintr", -"sema", -"semaerr", -"semaping", -"sendzlf", -"server_test", -"servr_kk", -"servr_uk", -"servr_ku", -"servr_uu", -"short_thread", -"sigpipe", -"socket", -"sockopt", -"sockping", -"sprintf", -"stack", -"stdio", -"str2addr", -"strod", -"switch", -"system", -"testbit", -"testfile", -"threads", -"timemac", -"timetest", -"tpd", -"udpsrv", -"vercheck", -"version", -"writev", -"xnotify", -"zerolen"); - -open_log; - -foreach $current_prog (@progs) { - if ($osname =~ $WINOS) { - win_test_prog($current_prog); - } else { - ux_test_prog($current_prog); - } -} - -close_log; diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/runtests.sh nspr-4.10.7/mozilla/nsprpub/pr/tests/runtests.sh --- nspr-4.9.5/mozilla/nsprpub/pr/tests/runtests.sh 2012-09-28 05:25:00.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/runtests.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,270 +0,0 @@ -#!/bin/sh -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# -# runtests.sh -# Bourne shell script for nspr tests -# - -SYSTEM_INFO=`uname -a` -OS_ARCH=`uname -s` - -if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "OS/2" ] -then - NULL_DEVICE=nul -else - NULL_DEVICE=/dev/null - FILE_D=`ulimit -n` - if [ $FILE_D -lt 512 ] - then - ulimit -n 512 - fi -fi - -# -# Irrevelant tests -# -#bug1test - used to demonstrate a bug on NT -#bigfile2 - requires 4Gig file creation. See BugZilla #5451 -#bigfile3 - requires 4Gig file creation. See BugZilla #5451 -#dbmalloc - obsolete; originally for testing debug version of nspr's malloc -#dbmalloc1 - obsolete; originally for testing debug version of nspr's malloc -#depend - obsolete; used to test a initial spec for library dependencies -#dceemu - used to tests special functions in NSPR for DCE emulation -#ipv6 - IPV6 not in use by NSPR clients -#mbcs - tests use of multi-byte charset for filenames. See BugZilla #25140 -#sproc_ch - obsolete; sproc-based tests for Irix -#sproc_p - obsolete; sproc-based tests for Irix -#io_timeoutk - obsolete; subsumed in io_timeout -#io_timeoutu - obsolete; subsumed in io_timeout -#prftest1 - obsolete; subsumed by prftest -#prftest2 - obsolete; subsumed by prftest -#prselect - obsolete; PR_Select is obsolete -#select2 - obsolete; PR_Select is obsolete -#sem - obsolete; PRSemaphore is obsolete -#stat - for OS2? -#suspend - private interfaces PR_SuspendAll, PR_ResumeAll, etc.. -#thruput - needs to be run manually as client/server -#time - used to measure time with native calls and nspr calls -#tmoacc - should be run with tmocon -#tmocon - should be run with tmoacc -#op_noacc - limited use -#yield - limited use for PR_Yield - -# -# Tests not run (but should) -# - -#forktest (failed on IRIX) -#nbconn - fails on some platforms -#poll_er - fails on some platforms? limited use? -#prpoll - the bad-FD test needs to be moved to a different test -#sleep - specific to OS/2 - -LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE} - -# -# Tests run on all platforms -# - -TESTS=" -accept -acceptread -acceptreademu -affinity -alarm -anonfm -atomic -attach -bigfile -cleanup -cltsrv -concur -cvar -cvar2 -dlltest -dtoa -errcodes -exit -fdcach -fileio -foreign -formattm -fsync -gethost -getproto -i2l -initclk -inrval -instrumt -intrio -intrupt -io_timeout -ioconthr -join -joinkk -joinku -joinuk -joinuu -layer -lazyinit -libfilename -lltest -lock -lockfile -logfile -logger -many_cv -multiwait -nameshm1 -nblayer -nonblock -ntioto -ntoh -op_2long -op_excl -op_filnf -op_filok -op_nofil -parent -parsetm -peek -perf -pipeping -pipeping2 -pipeself -poll_nm -poll_to -pollable -prftest -primblok -provider -prpollml -pushtop -ranfile -randseed -reinit -rwlocktest -sel_spd -selct_er -selct_nm -selct_to -selintr -sema -semaerr -semaping -sendzlf -server_test -servr_kk -servr_uk -servr_ku -servr_uu -short_thread -sigpipe -socket -sockopt -sockping -sprintf -stack -stdio -str2addr -strod -switch -system -testbit -testfile -threads -timemac -timetest -tpd -udpsrv -vercheck -version -writev -xnotify -zerolen" - -rval=0 - - -# -# When set, value of the environment variable TEST_TIMEOUT is the maximum -# time (secs) allowed for a test program beyond which it is terminated. -# If TEST_TIMEOUT is not set or if it's value is 0, then test programs -# don't timeout. -# -# Running runtests.ksh under MKS toolkit on NT, 95, 98 does not cause -# timeout detection correctly. For these platforms, do not attempt timeout -# test. (lth). -# -# - -OS_PLATFORM=`uname` -OBJDIR=`basename $PWD` -printf "\nNSPR Test Results - $OBJDIR\n\n" -printf "BEGIN\t\t\t`date`\n" -printf "NSPR_TEST_LOGFILE\t${LOGFILE}\n\n" -printf "Test\t\t\tResult\n\n" -if [ $OS_PLATFORM = "Windows_95" ] || [ $OS_PLATFORM = "Windows_98" ] || [ $OS_PLATFORM = "Windows_NT" ] || [ $OS_PLATFORM = "OS/2" ] ; then - for prog in $TESTS - do - printf "$prog" - printf "\nBEGIN TEST: $prog\n\n" >> ${LOGFILE} 2>&1 - ./$prog >> ${LOGFILE} 2>&1 - if [ 0 = $? ] ; then - printf "\t\t\tPassed\n"; - else - printf "\t\t\tFAILED\n"; - rval=1 - fi; - printf "\nEND TEST: $prog\n\n" >> ${LOGFILE} 2>&1 - done -else - for prog in $TESTS - do - printf "$prog" - printf "\nBEGIN TEST: $prog\n\n" >> ${LOGFILE} 2>&1 - export test_rval - ./$prog >> ${LOGFILE} 2>&1 & - test_pid=$! - sleep_pid=0 - if test -n "$TEST_TIMEOUT" && test "$TEST_TIMEOUT" -gt 0 - then - (sleep $TEST_TIMEOUT; kill $test_pid >/dev/null 2>&1 ) & - sleep_pid=$! - fi - wait $test_pid - test_rval=$? - [ $sleep_pid -eq 0 ] || kill $sleep_pid >/dev/null 2>&1 - if [ 0 = $test_rval ] ; then - printf "\t\t\tPassed\n"; - else - printf "\t\t\tFAILED\n"; - rval=1 - fi; - printf "\nEND TEST: $prog\n\n" >> ${LOGFILE} 2>&1 - done -fi; - -printf "END\t\t\t`date`\n" -exit $rval - - - - - - - - - - - - - - - - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/runy2ktests.ksh nspr-4.10.7/mozilla/nsprpub/pr/tests/runy2ktests.ksh --- nspr-4.9.5/mozilla/nsprpub/pr/tests/runy2ktests.ksh 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/runy2ktests.ksh 1970-01-01 00:00:00.000000000 +0000 @@ -1,237 +0,0 @@ -#!/bin/ksh -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# -# runy2ktests.ksh -# Set system clock to Y2K dates of interest and run the Y2K tests. -# Needs root/administrator privilege -# -# WARNING: Because this script needs to be run with root/administrator -# privilege, thorough understanding of the script and extreme -# caution are urged. -# - -# -# SECTION I -# Define variables -# - -SYSTEM_INFO=`uname -a` -OS_ARCH=`uname -s` -if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "Windows_95" ] -then - NULL_DEVICE=nul -else - NULL_DEVICE=/dev/null -fi - -# -# Test dates for NSPR Y2K tests -# -Y2KDATES=" 123123591998.55 - 090923591999.55 - 123123591999.55 - 022823592000.55 - 022923592000.55 - 123123592000.55" - -Y2KDATES_AIX=" 12312359.5598 - 09092359.5599 - 12312359.5599 - 02282359.5500 - 02292359.5500 - 12312359.5500" - -Y2KDATES_HPUX=" 123123591998 - 090923591999 - 123123591999 - 022823592000 - 022923592000 - 123123592000" - -Y2KDATES_MKS=" 1231235998.55 - 0909235999.55 - 1231235999.55 - 0228235900.55 - 0229235900.55 - 1231235900.55" - -# -# NSPR Y2K tests -# -Y2KTESTS=" -y2k \n -y2ktmo \n -y2k \n -../runtests.ksh" - -Y2KTESTS_HPUX=" -y2k \n -y2ktmo -l 60\n -y2k \n -../runtests.ksh" - -# -# SECTION II -# Define functions -# - -save_date() -{ - case $OS_ARCH in - AIX) - SAVED_DATE=`date "+%m%d%H%M.%S%y"` - ;; - HP-UX) - SAVED_DATE=`date "+%m%d%H%M%Y"` - ;; - Windows_NT) - SAVED_DATE=`date "+%m%d%H%M%y.%S"` - ;; - Windows_95) - SAVED_DATE=`date "+%m%d%H%M%y.%S"` - ;; - *) - SAVED_DATE=`date "+%m%d%H%M%Y.%S"` - ;; - esac -} - -set_date() -{ - case $OS_ARCH in - Windows_NT) -# -# The date command in MKS Toolkit releases 5.1 and 5.2 -# uses the current DST status for the date we want to -# set the system clock to. However, the DST status for -# that date may be different from the current DST status. -# We can work around this problem by invoking the date -# command with the same date twice. -# - date "$1" > $NULL_DEVICE - date "$1" > $NULL_DEVICE - ;; - *) - date "$1" > $NULL_DEVICE - ;; - esac -} - -restore_date() -{ - set_date "$SAVED_DATE" -} - -savedate() -{ - case $OS_ARCH in - AIX) - SAVED_DATE=`date "+%m%d%H%M.%S%y"` - ;; - HP-UX) - SAVED_DATE=`date "+%m%d%H%M%Y"` - ;; - Windows_NT) - SAVED_DATE=`date "+%m%d%H%M%y.%S"` - ;; - Windows_95) - SAVED_DATE=`date "+%m%d%H%M%y.%S"` - ;; - *) - SAVED_DATE=`date "+%m%d%H%M%Y.%S"` - ;; - esac -} - -set_y2k_test_parameters() -{ -# -# set dates -# - case $OS_ARCH in - AIX) - DATES=$Y2KDATES_AIX - ;; - HP-UX) - DATES=$Y2KDATES_HPUX - ;; - Windows_NT) - DATES=$Y2KDATES_MKS - ;; - Windows_95) - DATES=$Y2KDATES_MKS - ;; - *) - DATES=$Y2KDATES - ;; - esac - -# -# set tests -# - case $OS_ARCH in - HP-UX) - TESTS=$Y2KTESTS_HPUX - ;; - *) - TESTS=$Y2KTESTS - ;; - esac -} - -# -# runtests: -# - runs each test in $TESTS after setting the -# system clock to each date in $DATES -# - -runtests() -{ -for newdate in ${DATES} -do - set_date $newdate - echo $newdate - echo "BEGIN\t\t\t`date`" - echo "Date\t\t\t\t\tTest\t\t\tResult" - echo $TESTS | while read prog - do - echo "`date`\t\t\c" - echo "$prog\c" - ./$prog >> ${LOGFILE} 2>&1 - if [ 0 = $? ] ; then - echo "\t\t\tPassed"; - else - echo "\t\t\tFAILED"; - fi; - done - echo "END\t\t\t`date`\n" -done - -} - -# -# SECTION III -# Run tests -# - -LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE} -OBJDIR=`basename $PWD` -echo "\nNSPR Year 2000 Test Results - $OBJDIR\n" -echo "SYSTEM:\t\t\t${SYSTEM_INFO}" -echo "NSPR_TEST_LOGFILE:\t${LOGFILE}\n" - - -save_date - -# -# Run NSPR Y2k and standard tests -# - -set_y2k_test_parameters -runtests - -restore_date diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/rwlocktest.c nspr-4.10.7/mozilla/nsprpub/pr/tests/rwlocktest.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/rwlocktest.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/rwlocktest.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -/* - * - * RWLock tests - * - * Several threads are created to access and modify data arrays using - * PRRWLocks for synchronization. Two data arrays, array_A and array_B, are - * initialized with random data and a third array, array_C, is initialized - * with the sum of the first 2 arrays. - * - * Each one of the threads acquires a read lock to verify that the sum of - * the arrays A and B is equal to array C, and acquires a write lock to - * consistently update arrays A and B so that their is equal to array C. - * - */ - -#include "nspr.h" -#include "plgetopt.h" -#include "prrwlock.h" - -static int _debug_on; -static void rwtest(void *args); -static PRInt32 *array_A,*array_B,*array_C; -static void update_array(void); -static void check_array(void); - -typedef struct thread_args { - PRRWLock *rwlock; - PRInt32 loop_cnt; -} thread_args; - -PRFileDesc *output; -PRFileDesc *errhandle; - -#define DEFAULT_THREAD_CNT 4 -#define DEFAULT_LOOP_CNT 100 -#define TEST_ARRAY_SIZE 100 - -int main(int argc, char **argv) -{ - PRInt32 cnt; - PRStatus rc; - PRInt32 i; - - PRInt32 thread_cnt = DEFAULT_THREAD_CNT; - PRInt32 loop_cnt = DEFAULT_LOOP_CNT; - PRThread **threads; - thread_args *params; - PRRWLock *rwlock1; - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - case 't': /* thread count */ - thread_cnt = atoi(opt->value); - break; - case 'c': /* loop count */ - loop_cnt = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_SetConcurrency(4); - - output = PR_GetSpecialFD(PR_StandardOutput); - errhandle = PR_GetSpecialFD(PR_StandardError); - - rwlock1 = PR_NewRWLock(0,"Lock 1"); - if (rwlock1 == NULL) { - PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n", - PR_GetError()); - return 1; - } - - threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt); - params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt); - - /* - * allocate and initialize data arrays - */ - array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); - array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); - array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); - cnt = 0; - for (i=0; i < TEST_ARRAY_SIZE;i++) { - array_A[i] = cnt++; - array_B[i] = cnt++; - array_C[i] = array_A[i] + array_B[i]; - } - - if (_debug_on) - PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0], - thread_cnt, loop_cnt); - for(cnt = 0; cnt < thread_cnt; cnt++) { - PRThreadScope scope; - - params[cnt].rwlock = rwlock1; - params[cnt].loop_cnt = loop_cnt; - - /* - * create LOCAL and GLOBAL threads alternately - */ - if (cnt & 1) - scope = PR_LOCAL_THREAD; - else - scope = PR_GLOBAL_THREAD; - - threads[cnt] = PR_CreateThread(PR_USER_THREAD, - rwtest, ¶ms[cnt], - PR_PRIORITY_NORMAL, - scope, - PR_JOINABLE_THREAD, - 0); - if (threads[cnt] == NULL) { - PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n", - PR_GetError()); - PR_ProcessExit(2); - } - if (_debug_on) - PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0], - threads[cnt]); - } - - for(cnt = 0; cnt < thread_cnt; cnt++) { - rc = PR_JoinThread(threads[cnt]); - PR_ASSERT(rc == PR_SUCCESS); - - } - - PR_DELETE(threads); - PR_DELETE(params); - - PR_DELETE(array_A); - PR_DELETE(array_B); - PR_DELETE(array_C); - - PR_DestroyRWLock(rwlock1); - - - printf("PASS\n"); - return 0; -} - -static void rwtest(void *args) -{ - PRInt32 index; - thread_args *arg = (thread_args *) args; - - - for (index = 0; index < arg->loop_cnt; index++) { - - /* - * verify sum, update arrays and verify sum again - */ - - PR_RWLock_Rlock(arg->rwlock); - check_array(); - PR_RWLock_Unlock(arg->rwlock); - - PR_RWLock_Wlock(arg->rwlock); - update_array(); - PR_RWLock_Unlock(arg->rwlock); - - PR_RWLock_Rlock(arg->rwlock); - check_array(); - PR_RWLock_Unlock(arg->rwlock); - } - if (_debug_on) - PR_fprintf(output, - "Thread[0x%x] lock = 0x%x exiting\n", - PR_GetCurrentThread(), arg->rwlock); - -} - -static void check_array(void) -{ -PRInt32 i; - - for (i=0; i < TEST_ARRAY_SIZE;i++) - if (array_C[i] != (array_A[i] + array_B[i])) { - PR_fprintf(output, "Error - data check failed\n"); - PR_ProcessExit(1); - } -} - -static void update_array(void) -{ -PRInt32 i; - - for (i=0; i < TEST_ARRAY_SIZE;i++) { - array_A[i] += i; - array_B[i] -= i; - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/selct_er.c nspr-4.10.7/mozilla/nsprpub/pr/tests/selct_er.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/selct_er.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/selct_er.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,200 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1997 - Netscape Communications Corporation -** -** Name: prselect_err.c -** -** Description: tests PR_Select with sockets Error condition functions. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -#ifdef XP_BEOS -#include -int main() -{ - printf( "This test is not ported to the BeOS\n" ); - return 0; -} -#else - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "primpl.h" -#include "pprio.h" -#include "prnetdb.h" - -#include -#include -#include - - -PRIntn failed_already=0; -PRIntn debug_mode; - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock1, *listenSock2; - PRFileDesc *badFD; - PRUint16 listenPort1, listenPort2; - PRNetAddr addr; - PR_fd_set readFdSet; - char buf[128]; - PRInt32 retVal; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (debug_mode) { - printf("This program tests PR_Select with sockets. Error\n"); - printf("reporting operations are tested.\n\n"); - } - - /* Create two listening sockets */ - if ((listenSock1 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = AF_INET; - addr.inet.ip = PR_htonl(INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort1 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock1, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - - if ((listenSock2 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = AF_INET; - addr.inet.ip = PR_htonl(INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort2 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock2, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu and %hu\n\n", - listenPort1, listenPort2); - if (debug_mode) printf("%s", buf); - - /* Set up the fd set */ - PR_FD_ZERO(&readFdSet); - PR_FD_SET(listenSock1, &readFdSet); - PR_FD_SET(listenSock2, &readFdSet); - - - /* Testing bad fd */ - if (debug_mode) printf("PR_Select should detect a bad file descriptor\n"); - if ((badFD = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a TCP socket\n"); - failed_already=1; - goto exit_now; - } - - PR_FD_SET(badFD, &readFdSet); - /* - * Make the fd invalid - */ -#if defined(XP_UNIX) - close(PR_FileDesc2NativeHandle(badFD)); -#elif defined(XP_OS2) - soclose(PR_FileDesc2NativeHandle(badFD)); -#elif defined(WIN32) || defined(WIN16) - closesocket(PR_FileDesc2NativeHandle(badFD)); -#else -#error "Unknown architecture" -#endif - - retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, - PR_INTERVAL_NO_TIMEOUT); - if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) { - fprintf(stderr, "Failed to detect the bad fd: " - "PR_Select returns %d\n", retVal); - if (retVal == -1) { - fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), - PR_GetOSError()); - failed_already=1; - } - goto exit_now; - } - if (debug_mode) printf("PR_Select detected a bad fd. Test passed.\n\n"); - PR_FD_CLR(badFD, &readFdSet); - - PR_Cleanup(); - goto exit_now; -exit_now: - if(failed_already) - return 1; - else - return 0; - -} - -#endif /* XP_BEOS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/selct_nm.c nspr-4.10.7/mozilla/nsprpub/pr/tests/selct_nm.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/selct_nm.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/selct_nm.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,284 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1997 - Netscape Communications Corporation -** -** Name: prselect_norm.c -** -** Description: tests PR_Select with sockets - Normal operations. -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prinit.h" -#include "prio.h" -#include "prlog.h" -#include "prprf.h" -#include "prerror.h" -#include "prnetdb.h" - -#include "obsolete/probslet.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - -static void -clientThreadFunc(void *arg) -{ - PRUintn port = (PRUintn) arg; - PRFileDesc *sock; - PRNetAddr addr; - char buf[128]; - int i; - - addr.inet.family = PR_AF_INET; - addr.inet.port = PR_htons((PRUint16)port); - addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port); - - for (i = 0; i < 5; i++) { - sock = PR_NewTCPSocket(); - PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); - PR_Write(sock, buf, sizeof(buf)); - PR_Close(sock); - } -} - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock1, *listenSock2; - PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds; - PRIntn nfds; - PRUint16 listenPort1, listenPort2; - PRNetAddr addr; - PR_fd_set readFdSet; - char buf[128]; - PRThread *clientThread; - PRInt32 retVal; - PRIntn i, j; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (debug_mode) { - printf("This program tests PR_Select with sockets. \n"); - printf(" Normal operation are tested.\n\n"); - } - - /* Create two listening sockets */ - if ((listenSock1 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort1 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock1, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - - if ((listenSock2 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort2 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock2, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); -failed_already=1; - goto exit_now; - } - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu and %hu\n\n", - listenPort1, listenPort2); - if (debug_mode) printf("%s", buf); - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort1, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - failed_already=1; - goto exit_now; - } - - clientThread = PR_CreateThread(PR_USER_THREAD, - clientThreadFunc, (void *) listenPort2, - PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, 0); - if (clientThread == NULL) { - fprintf(stderr, "can't create thread\n"); - failed_already=1; - goto exit_now; - } - - if (debug_mode) { - printf("Two client threads are created. Each of them will\n"); - printf("send data to one of the two ports the server is listening on.\n"); - printf("The data they send is the port number. Each of them send\n"); - printf("the data five times, so you should see ten lines below,\n"); - printf("interleaved in an arbitrary order.\n"); - } - /* set up the fd array */ - fds = fds0; - other_fds = fds1; - fds[0] = listenSock1; - fds[1] = listenSock2; - nfds = 2; - /* Set up the fd set */ - PR_FD_ZERO(&readFdSet); - PR_FD_SET(listenSock1, &readFdSet); - PR_FD_SET(listenSock2, &readFdSet); - - /* 20 events total */ - i = 0; - while (i < 20) { - PRFileDesc **tmp; - int nextIndex; - int nEvents = 0; - - retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, - PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(retVal != 0); /* no timeout */ - if (retVal == -1) { - fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - failed_already=1; - goto exit_now; - } - - nextIndex = 2; - /* the two listening sockets */ - for (j = 0; j < 2; j++) { - other_fds[j] = fds[j]; - if (PR_FD_ISSET(fds[j], &readFdSet)) { - PRFileDesc *sock; - - nEvents++; - sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT); - if (sock == NULL) { - fprintf(stderr, "PR_Accept() failed\n"); - failed_already=1; - goto exit_now; - } - other_fds[nextIndex] = sock; - PR_FD_SET(sock, &readFdSet); - nextIndex++; - } - PR_FD_SET(fds[j], &readFdSet); - } - - for (j = 2; j < nfds; j++) { - if (PR_FD_ISSET(fds[j], &readFdSet)) { - PRInt32 nBytes; - - PR_FD_CLR(fds[j], &readFdSet); - nEvents++; - nBytes = PR_Read(fds[j], buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read() failed\n"); - failed_already=1; - goto exit_now; - } - /* Just to be safe */ - buf[127] = '\0'; - PR_Close(fds[j]); - if (debug_mode) printf("The server received \"%s\" from a client\n", buf); - } else { - PR_FD_SET(fds[j], &readFdSet); - other_fds[nextIndex] = fds[j]; - nextIndex++; - } - } - - PR_ASSERT(retVal == nEvents); - /* swap */ - tmp = fds; - fds = other_fds; - other_fds = tmp; - nfds = nextIndex; - i += nEvents; - } - - if (debug_mode) printf("Test passed\n"); - - PR_Cleanup(); - goto exit_now; -exit_now: - if(failed_already) - return 1; - else - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/selct_to.c nspr-4.10.7/mozilla/nsprpub/pr/tests/selct_to.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/selct_to.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/selct_to.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** 1997 - Netscape Communications Corporation -** -** Name: prselect_to.c -** -** Description: tests PR_Select with sockets. Time out functions -** -** Modification History: -** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prinit.h" -#include "prio.h" -#include "prlog.h" -#include "prprf.h" -#include "prnetdb.h" - -#include "obsolete/probslet.h" - -#include "prerror.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock1, *listenSock2; - PRUint16 listenPort1, listenPort2; - PRNetAddr addr; - PR_fd_set readFdSet; - char buf[128]; - PRInt32 retVal; - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (debug_mode) { - printf("This program tests PR_Select with sockets. Timeout \n"); - printf("operations are tested.\n\n"); - } - - /* Create two listening sockets */ - if ((listenSock1 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort1 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock1, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - - if ((listenSock2 = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Can't create a new TCP socket\n"); - failed_already=1; - goto exit_now; - } - addr.inet.family = PR_AF_INET; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - addr.inet.port = PR_htons(0); - if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "Can't bind socket\n"); - failed_already=1; - goto exit_now; - } - if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - failed_already=1; - goto exit_now; - } - listenPort2 = PR_ntohs(addr.inet.port); - if (PR_Listen(listenSock2, 5) == PR_FAILURE) { - fprintf(stderr, "Can't listen on a socket\n"); - failed_already=1; - goto exit_now; - } - PR_snprintf(buf, sizeof(buf), - "The server thread is listening on ports %hu and %hu\n\n", - listenPort1, listenPort2); - if (debug_mode) printf("%s", buf); - - /* Set up the fd set */ - PR_FD_ZERO(&readFdSet); - PR_FD_SET(listenSock1, &readFdSet); - PR_FD_SET(listenSock2, &readFdSet); - - /* Testing timeout */ - if (debug_mode) printf("PR_Select should time out in 5 seconds\n"); - retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, - PR_SecondsToInterval(5)); - if (retVal != 0) { - PR_snprintf(buf, sizeof(buf), - "PR_Select should time out and return 0, but it returns %ld\n", - retVal); - fprintf(stderr, "%s", buf); - if (retVal == -1) { - fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), - PR_GetOSError()); - failed_already=1; - } - goto exit_now; - } - if (debug_mode) printf("PR_Select timed out. Test passed.\n\n"); - - PR_Cleanup(); - -exit_now: - if(failed_already) - return 1; - else - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/select2.c nspr-4.10.7/mozilla/nsprpub/pr/tests/select2.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/select2.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/select2.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,322 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: select2.c -** -** Description: Measure PR_Select and Empty_Select performance. -** -** Modification History: -** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" -#include "prttools.h" -#include "primpl.h" - -#include -#include -#include -#if defined(OS2) -#include -#endif - -#define PORT 8000 -#define DEFAULT_COUNT 10 -PRInt32 count; - - -/*********************************************************************** -** PRIVATE FUNCTION: Test_Result -** DESCRIPTION: Used in conjunction with the regress tool, prints out the -** status of the test case. -** INPUTS: PASS/FAIL -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** -** RESTRICTIONS: -** None -** MEMORY: NA -** ALGORITHM: Determine what the status is and print accordingly. -** -***********************************************************************/ - - -static void Test_Result (int result) -{ - switch (result) - { - case PASS: - printf ("PASS\n"); - break; - case FAIL: - printf ("FAIL\n"); - break; - default: - printf ("NOSTATUS\n"); - break; - } -} - -static void EmptyPRSelect(void) -{ - PRInt32 index = count; - PRInt32 rv; - - for (; index--;) - rv = PR_Select(0, NULL, NULL, NULL, PR_INTERVAL_NO_WAIT); -} - -static void EmptyNativeSelect(void) -{ - PRInt32 rv; - PRInt32 index = count; - struct timeval timeout; - - timeout.tv_sec = timeout.tv_usec = 0; - for (; index--;) - rv = select(0, NULL, NULL, NULL, &timeout); -} - -static void PRSelectTest(void) -{ - PRFileDesc *listenSocket; - PRNetAddr serverAddr; - - if ( (listenSocket = PR_NewTCPSocket()) == NULL) { - if (debug_mode) printf("\tServer error creating listen socket\n"); - return; - } - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(INADDR_ANY); - - if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { - if (debug_mode) printf("\tServer error binding to server address\n"); - PR_Close(listenSocket); - return; - } - - if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { - if (debug_mode) printf("\tServer error listening to server socket\n"); - PR_Close(listenSocket); - return; - } - if (debug_mode) printf("Listening on port %d\n", PORT); - - { - PRFileDesc *newSock; - PRNetAddr rAddr; - PRInt32 loops = 0; - PR_fd_set rdset; - PRInt32 rv; - PRInt32 bytesRead; - char buf[11]; - - loops++; - - if (debug_mode) printf("Going into accept\n"); - - newSock = PR_Accept(listenSocket, - &rAddr, - PR_INTERVAL_NO_TIMEOUT); - - if (newSock) { - if (debug_mode) printf("Got connection!\n"); - } else { - if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError()); - else Test_Result (FAIL); - } - - PR_FD_ZERO(&rdset); - PR_FD_SET(newSock, &rdset); - - if (debug_mode) printf("Going into select \n"); - - rv = PR_Select(0, &rdset, 0, 0, PR_INTERVAL_NO_TIMEOUT); - - if (debug_mode) printf("return from select is %d\n", rv); - - if (PR_FD_ISSET(newSock, &rdset)) { - if (debug_mode) printf("I can't believe it- the socket is ready okay!\n"); - } else { - if (debug_mode) printf("Damn; the select test failed...\n"); - else Test_Result (FAIL); - } - - strcpy(buf, "XXXXXXXXXX"); - bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT); - buf[10] = '\0'; - - if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf); - - PR_Close(newSock); - } - -} - -#if defined(XP_UNIX) - -static void NativeSelectTest(void) -{ - PRFileDesc *listenSocket; - PRNetAddr serverAddr; - - if ( (listenSocket = PR_NewTCPSocket()) == NULL) { - if (debug_mode) printf("\tServer error creating listen socket\n"); - return; - } - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(INADDR_ANY); - - if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { - if (debug_mode) printf("\tServer error binding to server address\n"); - PR_Close(listenSocket); - return; - } - - if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { - if (debug_mode) printf("\tServer error listening to server socket\n"); - PR_Close(listenSocket); - return; - } - if (debug_mode) printf("Listening on port %d\n", PORT); - - { - PRIntn osfd; - char buf[11]; - fd_set rdset; - PRNetAddr rAddr; - PRFileDesc *newSock; - struct timeval timeout; - PRInt32 bytesRead, rv, loops = 0; - - loops++; - - if (debug_mode) printf("Going into accept\n"); - - newSock = PR_Accept(listenSocket, &rAddr, PR_INTERVAL_NO_TIMEOUT); - - if (newSock) { - if (debug_mode) printf("Got connection!\n"); - } else { - if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError()); - else Test_Result (FAIL); - } - - osfd = PR_FileDesc2NativeHandle(newSock); - FD_ZERO(&rdset); - FD_SET(osfd, &rdset); - - if (debug_mode) printf("Going into select \n"); - - - timeout.tv_sec = 2; timeout.tv_usec = 0; - rv = select(osfd + 1, &rdset, NULL, NULL, &timeout); - - if (debug_mode) printf("return from select is %d\n", rv); - - if (FD_ISSET(osfd, &rdset)) { - if (debug_mode) - printf("I can't believe it- the socket is ready okay!\n"); - } else { - if (debug_mode) printf("Damn; the select test failed...\n"); - else Test_Result (FAIL); - } - - strcpy(buf, "XXXXXXXXXX"); - bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT); - buf[10] = '\0'; - - if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf); - - PR_Close(newSock); - } - -} /* NativeSelectTest */ - -#endif /* defined(XP_UNIX) */ - -/************************************************************************/ - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - PRInt32 tot; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - tot = PR_IntervalToMilliseconds(stop-start); - - if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot); -} - -int main(int argc, char **argv) -{ - - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (argc > 2) { - count = atoi(argv[2]); - } else { - count = DEFAULT_COUNT; - } - -#if defined(XP_UNIX) - Measure(NativeSelectTest, "time to call 1 element select()"); -#endif - Measure(EmptyPRSelect, "time to call Empty PR_select()"); - Measure(EmptyNativeSelect, "time to call Empty select()"); - Measure(PRSelectTest, "time to call 1 element PR_select()"); - - if (!debug_mode) Test_Result (NOSTATUS); - PR_Cleanup(); - - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/selintr.c nspr-4.10.7/mozilla/nsprpub/pr/tests/selintr.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/selintr.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/selintr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Test whether classic NSPR's select() wrapper properly blocks - * the periodic SIGALRM clocks. On some platforms (such as - * HP-UX and SINIX) an interrupted select() system call is - * restarted with the originally specified timeout, ignoring - * the time that has elapsed. If a select() call is interrupted - * repeatedly, it will never time out. (See Bugzilla bug #39674.) - */ - -#if !defined(XP_UNIX) - -/* - * This test is applicable to Unix only. - */ - -int main() -{ - return 0; -} - -#else /* XP_UNIX */ - -#include "nspr.h" - -#include -#include -#ifdef SYMBIAN -#include -#endif - -int main(int argc, char **argv) -{ - struct timeval timeout; - int rv; - - PR_SetError(0, 0); /* force NSPR to initialize */ - PR_EnableClockInterrupts(); - - /* 2 seconds timeout */ - timeout.tv_sec = 2; - timeout.tv_usec = 0; - rv = select(1, NULL, NULL, NULL, &timeout); - printf("select returned %d\n", rv); - return 0; -} - -#endif /* XP_UNIX */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sel_spd.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sel_spd.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sel_spd.c 2012-03-06 13:14:30.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sel_spd.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,523 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Test the speed of select within NSPR - * - */ - -#include "nspr.h" -#include "prpriv.h" - -#include -#include -#include -#include -#ifdef SYMBIAN -#include -#endif - -#define PORT_BASE 19000 - -typedef struct timer_slot_t { - unsigned long d_connect; - unsigned long d_cl_data; - unsigned long d_sv_data; - unsigned long d_close; - unsigned long d_total; - unsigned long requests; -} timer_slot_t; - -static long _iterations = 5; -static long _client_data = 8192; - -#ifdef SYMBIAN -/* - * Symbian OS does not scale well specially the requirement for thread stack - * space and buffer allocation space. It is easy to get into a fragmented - * memory and not be able to allocate thread stack or client/server data - * buffer. - */ -static long _server_data = (8*1024); -static long _threads_max = 10, _threads = 10; -#else -static long _server_data = (128*1024); -static long _threads_max = 10, _threads = 10; -#endif - -static int verbose=0; -static PRMonitor *exit_cv; -static long _thread_exit_count; -static timer_slot_t *timer_data; -static PRThreadScope scope1, scope2; - -void tally_results(int); - -/* return the diff in microseconds */ -unsigned long _delta(PRIntervalTime *start, PRIntervalTime *stop) -{ - /* - * Will C do the right thing with unsigned arithemtic? - */ - return PR_IntervalToMicroseconds(*stop - *start); -} - -int _readn(PRFileDesc *sock, char *buf, int len) -{ - int rem; - int bytes; - - for (rem=len; rem; rem -= bytes) { - bytes = PR_Recv(sock, buf+len-rem, rem, 0, PR_INTERVAL_NO_TIMEOUT); - if (bytes <= 0) - return -1; - } - return len; -} - -void -_thread_exit(int id) -{ - PR_EnterMonitor(exit_cv); -#ifdef DEBUG - fprintf(stdout, "Thread %d EXIT\n", id); -#endif - - _thread_exit_count--; - if (_thread_exit_count == 0) { -#ifdef DEBUG - fprintf(stdout, "Thread %d EXIT triggered notify\n", id); -#endif - PR_Notify(exit_cv); - } - PR_ExitMonitor(exit_cv); -} - -void -_server_thread(void *arg_id) -{ - void _client_thread(void *); - PRThread *thread; - int *id = (int *)arg_id; - PRFileDesc *sock; - PRSocketOptionData sockopt; - PRNetAddr sa; - PRFileDesc * newsock; - char *data_buffer = NULL; - int data_buffer_size; - int index; - PRIntervalTime start, - connect_done, - read_done, - write_done, - close_done; - - -#ifdef DEBUG - fprintf(stdout, "server thread %d alive\n", *id); -#endif - - data_buffer_size = (_client_data>_server_data?_client_data:_server_data); - - if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL ) { - fprintf(stderr, "Error creating buffer in server thread %d\n", *id); - goto done; - } - - - if ( (sock = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Error creating socket in server thread %d\n", *id); - goto done; - } - - sockopt.option = PR_SockOpt_Reuseaddr; - sockopt.value.reuse_addr = PR_TRUE; - if ( PR_SetSocketOption(sock, &sockopt) == PR_FAILURE) { - fprintf(stderr, "Error setting socket option in server thread %d\n", *id); - goto done; - } - - memset(&sa, 0 , sizeof(sa)); - sa.inet.family = PR_AF_INET; - sa.inet.port = PR_htons(PORT_BASE + *id); - sa.inet.ip = PR_htonl(PR_INADDR_ANY); - - if ( PR_Bind(sock, &sa) < 0) { - fprintf(stderr, "Error binding socket in server thread %d errno = %d\n", *id, errno); - goto done; - } - - if ( PR_Listen(sock, 32) < 0 ) { - fprintf(stderr, "Error listening to socket in server thread %d\n", *id); - goto done; - } - - /* Tell the client to start */ - if ( (thread = PR_CreateThread(PR_USER_THREAD, - _client_thread, - id, - PR_PRIORITY_NORMAL, - scope2, - PR_UNJOINABLE_THREAD, - 0)) == NULL) - fprintf(stderr, "Error creating client thread %d\n", *id); - - for (index = 0; index< _iterations; index++) { - -#ifdef DEBUG - fprintf(stdout, "server thread %d loop %d\n", *id, index); -#endif - - start = PR_IntervalNow(); - - if ( (newsock = PR_Accept(sock, &sa, - PR_INTERVAL_NO_TIMEOUT)) == NULL) { - fprintf(stderr, "Error accepting connection %d in server thread %d\n", - index, *id); - goto done; - } -#ifdef DEBUG - fprintf(stdout, "server thread %d got connection %d\n", *id, newsock); -#endif - - - connect_done = PR_IntervalNow(); - - if ( _readn(newsock, data_buffer, _client_data) < _client_data) { - fprintf(stderr, "Error reading client data for iteration %d in server thread %d\n", index, *id ); - goto done; - } - -#ifdef DEBUG - fprintf(stdout, "server thread %d read %d bytes\n", *id, _client_data); -#endif - read_done = PR_IntervalNow(); - - if ( PR_Send(newsock, data_buffer, _server_data, 0, - PR_INTERVAL_NO_TIMEOUT) < _server_data) { - fprintf(stderr, "Error sending client data for iteration %d in server thread %d\n", index, *id ); - goto done; - } - -#ifdef DEBUG - fprintf(stdout, "server thread %d write %d bytes\n", *id, _server_data); -#endif - - write_done = PR_IntervalNow(); - - PR_Close(newsock); - - close_done = PR_IntervalNow(); - - timer_data[2*(*id)].d_connect += _delta(&start, &connect_done); - timer_data[2*(*id)].d_cl_data += _delta(&connect_done, &read_done); - timer_data[2*(*id)].d_sv_data += _delta(&read_done, &write_done); - timer_data[2*(*id)].d_close += _delta(&write_done, &close_done); - timer_data[2*(*id)].d_total += _delta(&start, &close_done); - timer_data[2*(*id)].requests++; - - -#ifdef DEBUG - fprintf(stdout, "server: %d %d %d %d %d\n", - _delta(&start, &connect_done), _delta(&connect_done, &read_done), - _delta(&read_done, &write_done), _delta(&write_done, &close_done), - _delta(&start, &close_done)); -#endif - } - -done: - if (data_buffer != NULL) PR_Free (data_buffer); - if (sock) PR_Close(sock); - _thread_exit(*id); - return; -} - -void -_client_thread(void *arg_id) -{ - int *id = (int *)arg_id; - int index; - PRNetAddr sa; - PRFileDesc *sock_h; - char *data_buffer = NULL; - int data_buffer_size; - int bytes; - PRIntervalTime start, - connect_done, - read_done, - write_done, - close_done; - PRStatus rv; - -#ifdef DEBUG - fprintf(stdout, "client thread %d alive\n", *id); -#endif - - data_buffer_size = (_client_data>_server_data?_client_data:_server_data); - - if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL) { - fprintf(stderr, "Error creating buffer in server thread %d\n", *id); - goto done; - } - - memset(&sa, 0 , sizeof(sa)); - rv = PR_InitializeNetAddr(PR_IpAddrLoopback, PORT_BASE + *id, &sa); - PR_ASSERT(PR_SUCCESS == rv); - - for (index = 0; index< _iterations; index++) { - -#ifdef DEBUG - fprintf(stdout, "client thread %d loop %d\n", *id, index); -#endif - - start = PR_IntervalNow(); - if ( (sock_h = PR_NewTCPSocket()) == NULL) { - fprintf(stderr, "Error creating socket %d in client thread %d\n", - index, *id); - goto done; - } - -#ifdef DEBUG - fprintf(stdout, "client thread %d socket created %d\n", *id, sock_h); -#endif - - if ( PR_Connect(sock_h, &sa, - PR_INTERVAL_NO_TIMEOUT) < 0) { - fprintf(stderr, "Error accepting connection %d in client thread %d\n", - index, *id); - goto done; - } - -#ifdef DEBUG - fprintf(stdout, "client thread %d socket connected %d\n", *id, sock_h); -#endif - - connect_done = PR_IntervalNow(); - if ( PR_Send(sock_h, data_buffer, _client_data, 0, - PR_INTERVAL_NO_TIMEOUT) < _client_data) { - fprintf(stderr, "Error sending client data for iteration %d in client thread %d\n", index, *id ); - goto done; - } - -#ifdef DEBUG - fprintf(stdout, "client thread %d socket wrote %d\n", *id, _client_data); -#endif - - write_done = PR_IntervalNow(); - if ( (bytes = _readn(sock_h, data_buffer, _server_data)) < _server_data) { - fprintf(stderr, "Error reading server data for iteration %d in client thread %d (read %d bytes)\n", index, *id, bytes ); - goto done; - } - -#ifdef DEBUG - fprintf(stdout, "client thread %d socket read %d\n", *id, _server_data); -#endif - - read_done = PR_IntervalNow(); - PR_Close(sock_h); - close_done = PR_IntervalNow(); - - timer_data[2*(*id)+1].d_connect += _delta(&start, &connect_done); - timer_data[2*(*id)+1].d_cl_data += _delta(&connect_done, &write_done); - timer_data[2*(*id)+1].d_sv_data += _delta(&write_done, &read_done); - timer_data[2*(*id)+1].d_close += _delta(&read_done, &close_done); - timer_data[2*(*id)+1].d_total += _delta(&start, &close_done); - timer_data[2*(*id)+1].requests++; - } -done: - if (data_buffer != NULL) PR_Free (data_buffer); - _thread_exit(*id); - - return; -} - -static -void do_work(void) -{ - int index; - - _thread_exit_count = _threads * 2; - for (index=0; index<_threads; index++) { - PRThread *thread; - int *id = (int *)PR_Malloc(sizeof(int)); - - *id = index; - - if ( (thread = PR_CreateThread(PR_USER_THREAD, - _server_thread, - id, - PR_PRIORITY_NORMAL, - scope1, - PR_UNJOINABLE_THREAD, - 0)) == NULL) - fprintf(stderr, "Error creating server thread %d\n", index); - } - - PR_EnterMonitor(exit_cv); - while (_thread_exit_count > 0) - PR_Wait(exit_cv, PR_INTERVAL_NO_TIMEOUT); - PR_ExitMonitor(exit_cv); - - fprintf(stdout, "TEST COMPLETE!\n"); - - tally_results(verbose); - -} - -static void do_workUU(void) -{ - scope1 = PR_LOCAL_THREAD; - scope2 = PR_LOCAL_THREAD; - do_work(); -} - -static void do_workUK(void) -{ - scope1 = PR_LOCAL_THREAD; - scope2 = PR_GLOBAL_THREAD; - do_work(); -} - -static void do_workKU(void) -{ - scope1 = PR_GLOBAL_THREAD; - scope2 = PR_LOCAL_THREAD; - do_work(); -} - -static void do_workKK(void) -{ - scope1 = PR_GLOBAL_THREAD; - scope2 = PR_GLOBAL_THREAD; - do_work(); -} - - - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - - printf("%40s: %6.2f usec\n", msg, d / _iterations); -} - - -int main(int argc, char **argv) -{ -#if defined(XP_UNIX) || defined(XP_OS2) - int opt; - PR_IMPORT_DATA(char *) optarg; -#endif - -#if defined(XP_UNIX) || defined(XP_OS2) - while ( (opt = getopt(argc, argv, "c:s:i:t:v")) != EOF) { - switch(opt) { - case 'i': - _iterations = atoi(optarg); - break; - case 't': - _threads_max = _threads = atoi(optarg); - break; - case 'c': - _client_data = atoi(optarg); - break; - case 's': - _server_data = atoi(optarg); - break; - case 'v': - verbose = 1; - break; - default: - break; - } - } -#endif - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - fprintf(stdout, "Running test for %d iterations with %d simultaneous threads.\n", - _iterations, _threads); - fprintf(stdout, "\tWill send %d bytes of client data and %d bytes of server data\n", - _client_data, _server_data); - - if ( (exit_cv = PR_NewMonitor()) == NULL) - fprintf(stderr, "Error creating monitor for exit cv\n"); - if ( (timer_data = (timer_slot_t *)PR_Malloc(2*_threads * sizeof(timer_slot_t))) == NULL) - fprintf(stderr, "error allocating thread time results array\n"); - memset(timer_data, 0 , 2*_threads*sizeof(timer_slot_t)); - - Measure(do_workUU, "select loop user/user"); - Measure(do_workUK, "select loop user/kernel"); - Measure(do_workKU, "select loop kernel/user"); - Measure(do_workKK, "select loop kernel/kernel"); - - - return 0; -} - -void -tally_results(int verbose) -{ - int index; - unsigned long tot_connect = 0; - unsigned long tot_cl_data = 0; - unsigned long tot_sv_data = 0; - unsigned long tot_close = 0; - unsigned long tot_all = 0; - unsigned long tot_requests = 0; - - fprintf(stdout, "Server results:\n\n"); - for (index=0; index<_threads_max*2; index+=2) { - - if (verbose) - fprintf(stdout, "server thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n", - index, timer_data[index].requests, timer_data[index].d_connect, - timer_data[index].d_cl_data, timer_data[index].d_sv_data, - timer_data[index].d_close, timer_data[index].d_total); - - tot_connect += timer_data[index].d_connect / _threads; - tot_cl_data += timer_data[index].d_cl_data / _threads; - tot_sv_data += timer_data[index].d_sv_data / _threads; - tot_close += timer_data[index].d_close / _threads; - tot_all += timer_data[index].d_total / _threads; - tot_requests += timer_data[index].requests / _threads; - } - fprintf(stdout, "----------\n"); - fprintf(stdout, "server per thread totals %u\t%u\t%u\t%u\t%u\n", - tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close); - fprintf(stdout, "server per thread elapsed time %u\n", tot_all); - fprintf(stdout, "----------\n"); - - tot_connect = tot_cl_data = tot_sv_data = tot_close = tot_all = tot_requests = 0; - fprintf(stdout, "Client results:\n\n"); - for (index=1; index<_threads_max*2; index+=2) { - - if (verbose) - fprintf(stdout, "client thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n", - index, timer_data[index].requests, timer_data[index].d_connect, - timer_data[index].d_cl_data, timer_data[index].d_sv_data, - timer_data[index].d_close, timer_data[index].d_total); - - tot_connect += timer_data[index].d_connect / _threads; - tot_cl_data += timer_data[index].d_cl_data / _threads; - tot_sv_data += timer_data[index].d_sv_data / _threads; - tot_close += timer_data[index].d_close / _threads; - tot_all += timer_data[index].d_total / _threads; - tot_requests += timer_data[index].requests / _threads; - } - fprintf(stdout, "----------\n"); - fprintf(stdout, "client per thread totals %u\t%u\t%u\t%u\t%u\n", - tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close); - fprintf(stdout, "client per thread elapsed time %u\n", tot_all); -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sema.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sema.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sema.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sema.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "plgetopt.h" - -#include - -#define SEM_NAME1 "/tmp/foo.sem" -#define SEM_NAME2 "/tmp/bar.sem" -#define SEM_MODE 0666 -#define ITERATIONS 1000 - -static PRBool debug_mode = PR_FALSE; -static PRIntn iterations = ITERATIONS; -static PRIntn counter; -static PRSem *sem1, *sem2; - -/* - * Thread 2 waits on semaphore 2 and posts to semaphore 1. - */ -void ThreadFunc(void *arg) -{ - PRIntn i; - - for (i = 0; i < iterations; i++) { - if (PR_WaitSemaphore(sem2) == PR_FAILURE) { - fprintf(stderr, "PR_WaitSemaphore failed\n"); - exit(1); - } - if (counter == 2*i+1) { - if (debug_mode) printf("thread 2: counter = %d\n", counter); - } else { - fprintf(stderr, "thread 2: counter should be %d but is %d\n", - 2*i+1, counter); - exit(1); - } - counter++; - if (PR_PostSemaphore(sem1) == PR_FAILURE) { - fprintf(stderr, "PR_PostSemaphore failed\n"); - exit(1); - } - } -} - -static void Help(void) -{ - fprintf(stderr, "sema test program usage:\n"); - fprintf(stderr, "\t-d debug mode (FALSE)\n"); - fprintf(stderr, "\t-c loop count (%d)\n", ITERATIONS); - fprintf(stderr, "\t-h this message\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PRThread *thred; - PRIntn i; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) continue; - switch (opt->option) { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'c': /* loop count */ - iterations = atoi(opt->value); - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) { - fprintf(stderr, "warning: removed semaphore %s left over " - "from previous run\n", SEM_NAME1); - } - if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) { - fprintf(stderr, "warning: removed semaphore %s left over " - "from previous run\n", SEM_NAME2); - } - - sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1); - if (NULL == sem1) { - fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0); - if (NULL == sem2) { - fprintf(stderr, "PR_OpenSemaphore failed\n"); - exit(1); - } - thred = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (NULL == thred) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - - /* - * Thread 1 waits on semaphore 1 and posts to semaphore 2. - */ - for (i = 0; i < iterations; i++) { - if (PR_WaitSemaphore(sem1) == PR_FAILURE) { - fprintf(stderr, "PR_WaitSemaphore failed\n"); - exit(1); - } - if (counter == 2*i) { - if (debug_mode) printf("thread 1: counter = %d\n", counter); - } else { - fprintf(stderr, "thread 1: counter should be %d but is %d\n", - 2*i, counter); - exit(1); - } - counter++; - if (PR_PostSemaphore(sem2) == PR_FAILURE) { - fprintf(stderr, "PR_PostSemaphore failed\n"); - exit(1); - } - } - - if (PR_JoinThread(thred) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - - if (PR_CloseSemaphore(sem1) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - } - if (PR_CloseSemaphore(sem2) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - } - if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) { - fprintf(stderr, "PR_DeleteSemaphore failed\n"); - } - if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) { - fprintf(stderr, "PR_DeleteSemaphore failed\n"); - } - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/semaerr1.c nspr-4.10.7/mozilla/nsprpub/pr/tests/semaerr1.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/semaerr1.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/semaerr1.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "plgetopt.h" - -#include - -#ifdef SYMBIAN -#define SEM_NAME1 "c:\\data\\foo.sem" -#define SEM_NAME2 "c:\\data\\bar.sem" -#else -#define SEM_NAME1 "/tmp/foo.sem" -#define SEM_NAME2 "/tmp/bar.sem" -#endif -#define SEM_MODE 0666 - -static PRBool debug_mode = PR_FALSE; - -static void Help(void) -{ - fprintf(stderr, "semaerr1 test program usage:\n"); - fprintf(stderr, "\t-d debug mode (FALSE)\n"); - fprintf(stderr, "\t-h this message\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dh"); - PRSem *sem; - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) continue; - switch (opt->option) { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - /* - * PR_SEM_CREATE|PR_SEM_EXCL should be able to - * create a nonexistent semaphore. - */ - (void) PR_DeleteSemaphore(SEM_NAME2); - sem = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0); - if (sem == NULL) { - fprintf(stderr, "PR_OpenSemaphore failed\n"); - exit(1); - } - if (PR_CloseSemaphore(sem) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - exit(1); - } - if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) { - fprintf(stderr, "PR_DeleteSemaphore failed\n"); - exit(1); - } - - /* - * Opening an existing semaphore with PR_SEM_CREATE|PR_SEM_EXCL. - * should fail with PR_FILE_EXISTS_ERROR. - */ - sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0); - if (sem != NULL) { - fprintf(stderr, "PR_OpenSemaphore should fail but succeeded\n"); - exit(1); - } - if (PR_GetError() != PR_FILE_EXISTS_ERROR) { - fprintf(stderr, "Expect %d but got %d\n", PR_FILE_EXISTS_ERROR, - PR_GetError()); - exit(1); - } - - /* - * Try again, with just PR_SEM_CREATE. This should succeed. - */ - sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0); - if (sem == NULL) { - fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - if (PR_CloseSemaphore(sem) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - exit(1); - } - - sem = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0); - if (sem == NULL) { - fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - if (PR_CloseSemaphore(sem) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - exit(1); - } - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/semaerr.c nspr-4.10.7/mozilla/nsprpub/pr/tests/semaerr.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/semaerr.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/semaerr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "plgetopt.h" - -#include - -#ifdef SYMBIAN -#define NO_SUCH_SEM_NAME "c:\\data\\nosuchsem.sem" -#define SEM_NAME1 "c:\\data\\foo.sem" -#define EXE_NAME "nspr_tests_semaerr1.exe" -#else -#define NO_SUCH_SEM_NAME "/tmp/nosuchsem.sem" -#define SEM_NAME1 "/tmp/foo.sem" -#define EXE_NAME "semaerr1" -#endif -#define SEM_MODE 0666 - -static PRBool debug_mode = PR_FALSE; - -static void Help(void) -{ - fprintf(stderr, "semaerr test program usage:\n"); - fprintf(stderr, "\t-d debug mode (FALSE)\n"); - fprintf(stderr, "\t-h this message\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dh"); - PRSem *sem; - char *child_argv[32]; - char **child_arg; - PRProcess *proc; - PRInt32 exit_code; - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) continue; - switch (opt->option) { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - /* - * Open a nonexistent semaphore without the PR_SEM_CREATE - * flag should fail with PR_FILE_NOT_FOUND_ERROR. - */ - (void) PR_DeleteSemaphore(NO_SUCH_SEM_NAME); - sem = PR_OpenSemaphore(NO_SUCH_SEM_NAME, 0, 0, 0); - if (NULL != sem) { - fprintf(stderr, "Opening nonexistent semaphore %s " - "without the PR_SEM_CREATE flag should fail " - "but succeeded\n", NO_SUCH_SEM_NAME); - exit(1); - } - if (PR_GetError() != PR_FILE_NOT_FOUND_ERROR) { - fprintf(stderr, "Expected error is %d but got (%d, %d)\n", - PR_FILE_NOT_FOUND_ERROR, PR_GetError(), PR_GetOSError()); - exit(1); - } - - /* - * Create a semaphore and let the another process - * try PR_SEM_CREATE and PR_SEM_CREATE|PR_SEM_EXCL. - */ - if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) { - fprintf(stderr, "warning: deleted semaphore %s from previous " - "run of the test\n", SEM_NAME1); - } - sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0); - if (sem == NULL) { - fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - child_arg = child_argv; - *child_arg++ = EXE_NAME; - if (debug_mode) { - *child_arg++ = "-d"; - } - *child_arg = NULL; - proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); - if (proc == NULL) { - fprintf(stderr, "PR_CreateProcess failed\n"); - exit(1); - } - if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) { - fprintf(stderr, "PR_WaitProcess failed\n"); - exit(1); - } - if (exit_code != 0) { - fprintf(stderr, "process semaerr1 failed\n"); - exit(1); - } - if (PR_CloseSemaphore(sem) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - exit(1); - } - if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) { - fprintf(stderr, "PR_DeleteSemaphore failed\n"); - exit(1); - } - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/semaping.c nspr-4.10.7/mozilla/nsprpub/pr/tests/semaping.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/semaping.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/semaping.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "plgetopt.h" - -#include - -#ifdef SYMBIAN -#define SHM_NAME "c:\\data\\counter" -#define SEM_NAME1 "c:\\data\\foo.sem" -#define SEM_NAME2 "c:\\data\\bar.sem" -#define EXE_NAME "nspr_tests_semapong.exe" -#else -#define SHM_NAME "/tmp/counter" -#define SEM_NAME1 "/tmp/foo.sem" -#define SEM_NAME2 "/tmp/bar.sem" -#define EXE_NAME "semapong" -#endif -#define SEM_MODE 0666 -#define SHM_MODE 0666 -#define ITERATIONS 1000 - -static PRBool debug_mode = PR_FALSE; -static PRIntn iterations = ITERATIONS; -static PRSem *sem1, *sem2; - -static void Help(void) -{ - fprintf(stderr, "semaping test program usage:\n"); - fprintf(stderr, "\t-d debug mode (FALSE)\n"); - fprintf(stderr, "\t-c loop count (%d)\n", ITERATIONS); - fprintf(stderr, "\t-h this message\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PRProcess *proc; - PRIntn i; - char *child_argv[32]; - char **child_arg; - char iterations_buf[32]; - PRSharedMemory *shm; - PRIntn *counter_addr; - PRInt32 exit_code; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) continue; - switch (opt->option) { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'c': /* loop count */ - iterations = atoi(opt->value); - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - if (PR_DeleteSharedMemory(SHM_NAME) == PR_SUCCESS) { - fprintf(stderr, "warning: removed shared memory %s left over " - "from previous run\n", SHM_NAME); - } - if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) { - fprintf(stderr, "warning: removed semaphore %s left over " - "from previous run\n", SEM_NAME1); - } - if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) { - fprintf(stderr, "warning: removed semaphore %s left over " - "from previous run\n", SEM_NAME2); - } - - shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), PR_SHM_CREATE, SHM_MODE); - if (NULL == shm) { - fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - counter_addr = PR_AttachSharedMemory(shm, 0); - if (NULL == counter_addr) { - fprintf(stderr, "PR_AttachSharedMemory failed\n"); - exit(1); - } - *counter_addr = 0; - sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1); - if (NULL == sem1) { - fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0); - if (NULL == sem2) { - fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - - child_arg = &child_argv[0]; - *child_arg++ = EXE_NAME; - if (debug_mode != PR_FALSE) { - *child_arg++ = "-d"; - } - if (iterations != ITERATIONS) { - *child_arg++ = "-c"; - PR_snprintf(iterations_buf, sizeof(iterations_buf), "%d", iterations); - *child_arg++ = iterations_buf; - } - *child_arg = NULL; - proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); - if (NULL == proc) { - fprintf(stderr, "PR_CreateProcess failed\n"); - exit(1); - } - - /* - * Process 1 waits on semaphore 1 and posts to semaphore 2. - */ - for (i = 0; i < iterations; i++) { - if (PR_WaitSemaphore(sem1) == PR_FAILURE) { - fprintf(stderr, "PR_WaitSemaphore failed\n"); - exit(1); - } - if (*counter_addr == 2*i) { - if (debug_mode) printf("process 1: counter = %d\n", *counter_addr); - } else { - fprintf(stderr, "process 1: counter should be %d but is %d\n", - 2*i, *counter_addr); - exit(1); - } - (*counter_addr)++; - if (PR_PostSemaphore(sem2) == PR_FAILURE) { - fprintf(stderr, "PR_PostSemaphore failed\n"); - exit(1); - } - } - if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) { - fprintf(stderr, "PR_DetachSharedMemory failed\n"); - exit(1); - } - if (PR_CloseSharedMemory(shm) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSharedMemory failed\n"); - exit(1); - } - if (PR_CloseSemaphore(sem1) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - } - if (PR_CloseSemaphore(sem2) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - } - - if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) { - fprintf(stderr, "PR_WaitProcess failed\n"); - exit(1); - } - if (exit_code != 0) { - fprintf(stderr, "process 2 failed with exit code %d\n", exit_code); - exit(1); - } - - if (PR_DeleteSharedMemory(SHM_NAME) == PR_FAILURE) { - fprintf(stderr, "PR_DeleteSharedMemory failed\n"); - } - if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) { - fprintf(stderr, "PR_DeleteSemaphore failed\n"); - } - if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) { - fprintf(stderr, "PR_DeleteSemaphore failed\n"); - } - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/semapong.c nspr-4.10.7/mozilla/nsprpub/pr/tests/semapong.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/semapong.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/semapong.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "plgetopt.h" - -#include - -#ifdef SYMBIAN -#define SHM_NAME "c:\\data\\counter" -#define SEM_NAME1 "c:\\data\\foo.sem" -#define SEM_NAME2 "c:\\data\\bar.sem" -#else -#define SHM_NAME "/tmp/counter" -#define SEM_NAME1 "/tmp/foo.sem" -#define SEM_NAME2 "/tmp/bar.sem" -#endif -#define ITERATIONS 1000 - -static PRBool debug_mode = PR_FALSE; -static PRIntn iterations = ITERATIONS; -static PRSem *sem1, *sem2; - -static void Help(void) -{ - fprintf(stderr, "semapong test program usage:\n"); - fprintf(stderr, "\t-d debug mode (FALSE)\n"); - fprintf(stderr, "\t-c loop count (%d)\n", ITERATIONS); - fprintf(stderr, "\t-h this message\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PRIntn i; - PRSharedMemory *shm; - PRIntn *counter_addr; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) continue; - switch (opt->option) { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'c': /* loop count */ - iterations = atoi(opt->value); - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), 0, 0666); - if (NULL == shm) { - fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - sem1 = PR_OpenSemaphore(SEM_NAME1, 0, 0, 0); - if (NULL == sem1) { - fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - sem2 = PR_OpenSemaphore(SEM_NAME2, 0, 0, 0); - if (NULL == sem2) { - fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - - counter_addr = PR_AttachSharedMemory(shm, 0); - if (NULL == counter_addr) { - fprintf(stderr, "PR_AttachSharedMemory failed\n"); - exit(1); - } - - /* - * Process 2 waits on semaphore 2 and posts to semaphore 1. - */ - for (i = 0; i < iterations; i++) { - if (PR_WaitSemaphore(sem2) == PR_FAILURE) { - fprintf(stderr, "PR_WaitSemaphore failed\n"); - exit(1); - } - if (*counter_addr == 2*i+1) { - if (debug_mode) printf("process 2: counter = %d\n", *counter_addr); - } else { - fprintf(stderr, "process 2: counter should be %d but is %d\n", - 2*i+1, *counter_addr); - exit(1); - } - (*counter_addr)++; - if (PR_PostSemaphore(sem1) == PR_FAILURE) { - fprintf(stderr, "PR_PostSemaphore failed\n"); - exit(1); - } - } - if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) { - fprintf(stderr, "PR_DetachSharedMemory failed\n"); - exit(1); - } - if (PR_CloseSharedMemory(shm) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSharedMemory failed\n"); - exit(1); - } - if (PR_CloseSemaphore(sem1) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - } - if (PR_CloseSemaphore(sem2) == PR_FAILURE) { - fprintf(stderr, "PR_CloseSemaphore failed\n"); - } - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sem.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sem.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sem.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sem.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: sem.c -** -** Description: Tests Semaphonre functions. -** -** Modification History: -** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include "prpriv.h" - -#include -#include -#include - -PRIntn failed_already=0; -PRIntn debug_mode; - -/* - Since we don't have stdin, stdout everywhere, we will fake - it with our in-memory buffers called stdin and stdout. -*/ - -#define SBSIZE 1024 - -#include "obsolete/prsem.h" - -static char stdinBuf[SBSIZE]; -static char stdoutBuf[SBSIZE]; - -static PRUintn stdinBufIdx = 0; -static PRUintn stdoutBufIdx = 0; -static PRStatus finalResult = PR_SUCCESS; - - -static size_t dread (PRUintn device, char *buf, size_t bufSize) -{ - PRUintn i; - - /* during first read call, initialize the stdinBuf buffer*/ - if (stdinBufIdx == 0) { - for (i=0; i 0); -} - -static void writer(void) -{ - PRUintn i = 0; - size_t nbytes; - - do { - (void) PR_WaitSem(fullBufs); - nbytes = buf[i].nbytes; - if (nbytes > 0) { - nbytes = dwrite(1, buf[i].data, nbytes); - PR_PostSem(emptyBufs); - i = (i + 1) % 2; - } - } while (nbytes > 0); -} - -int main(int argc, char **argv) -{ - PRThread *r; - - PR_STDIO_INIT(); - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - { - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - } - - /* main test */ - - emptyBufs = PR_NewSem(2); /* two empty buffers */ - - fullBufs = PR_NewSem(0); /* zero full buffers */ - - /* create the reader thread */ - - r = PR_CreateThread(PR_USER_THREAD, - reader, 0, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - - /* Do the writer operation in this thread */ - writer(); - - PR_DestroySem(emptyBufs); - PR_DestroySem(fullBufs); - - if (finalResult == PR_SUCCESS) { - if (debug_mode) printf("sem Test Passed.\n"); - } - else{ - if (debug_mode) printf("sem Test Failed.\n"); - failed_already=1; - } - PR_Cleanup(); - if(failed_already) - return 1; - else - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sendzlf.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sendzlf.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sendzlf.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sendzlf.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,214 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Test: sendzlf.c - * - * Description: send a zero-length file with PR_SendFile and - * PR_TransmitFile. - */ - -#define ZERO_LEN_FILE_NAME "zerolen.tmp" -#define HEADER_STR "Header" -#define HEADER_LEN 6 /* length of HEADER_STR, not counting the null byte */ -#define TRAILER_STR "Trailer" -#define TRAILER_LEN 7 /* length of TRAILER_STR, not counting the null byte */ - -#include "nspr.h" - -#include -#include -#include - -static void ClientThread(void *arg) -{ - PRFileDesc *sock; - PRNetAddr addr; - PRUint16 port = (PRUint16) arg; - char buf[1024]; - char *bufPtr; - PRInt32 nbytes; - PRInt32 ntotal; - PRInt32 nexpected; - - sock = PR_NewTCPSocket(); - if (NULL == sock) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_InitializeNetAddr failed\n"); - exit(1); - } - if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { - fprintf(stderr, "PR_Connect failed\n"); - exit(1); - } - ntotal = 0; - bufPtr = buf; - while ((nbytes = PR_Read(sock, bufPtr, sizeof(buf)-ntotal)) > 0) { - ntotal += nbytes; - bufPtr += nbytes; - } - if (-1 == nbytes) { - fprintf(stderr, "PR_Read failed\n"); - exit(1); - } - nexpected = HEADER_LEN+TRAILER_LEN+TRAILER_LEN+HEADER_LEN+HEADER_LEN; - if (ntotal != nexpected) { - fprintf(stderr, "total bytes read should be %d but is %d\n", - nexpected, ntotal); - exit(1); - } - if (memcmp(buf, HEADER_STR TRAILER_STR TRAILER_STR HEADER_STR HEADER_STR, - nexpected) != 0) { - fprintf(stderr, "wrong data is received\n"); - exit(1); - } - if (PR_Close(sock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } -} - -static void ServerThread(void *arg) -{ - PRFileDesc *listenSock = (PRFileDesc *) arg; - PRFileDesc *acceptSock; - PRFileDesc *file; - PRSendFileData sfd; - char header[1024], trailer[1024]; - PRInt32 nbytes; - - /* Create a zero-length file */ - file = PR_Open(ZERO_LEN_FILE_NAME, - PR_CREATE_FILE|PR_TRUNCATE|PR_RDWR, 0666); - if (NULL == file) { - fprintf(stderr, "PR_Open failed\n"); - exit(1); - } - sfd.fd = file; - sfd.file_offset = 0; - sfd.file_nbytes = 0; - memcpy(header, HEADER_STR, HEADER_LEN); - memcpy(trailer, TRAILER_STR, TRAILER_LEN); - sfd.header = header; - sfd.hlen = HEADER_LEN; - sfd.trailer = trailer; - sfd.tlen = TRAILER_LEN; - acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (NULL == acceptSock) { - fprintf(stderr, "PR_Accept failed\n"); - exit(1); - } - /* Send both header and trailer */ - nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - if (HEADER_LEN+TRAILER_LEN != nbytes) { - fprintf(stderr, "PR_SendFile should return %d but returned %d\n", - HEADER_LEN+TRAILER_LEN, nbytes); - exit(1); - } - /* Trailer only, no header */ - sfd.hlen = 0; - nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - if (TRAILER_LEN != nbytes) { - fprintf(stderr, "PR_SendFile should return %d but returned %d\n", - TRAILER_LEN, nbytes); - exit(1); - } - /* Header only, no trailer */ - sfd.hlen = HEADER_LEN; - sfd.tlen = 0; - nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - if (HEADER_LEN != nbytes) { - fprintf(stderr, "PR_SendFile should return %d but returned %d\n", - HEADER_LEN, nbytes); - exit(1); - } - /* Try PR_TransmitFile */ - nbytes = PR_TransmitFile(acceptSock, file, header, HEADER_LEN, - PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT); - if (HEADER_LEN != nbytes) { - fprintf(stderr, "PR_TransmitFile should return %d but returned %d\n", - HEADER_LEN, nbytes); - exit(1); - } - if (PR_Close(acceptSock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - if (PR_Close(file) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - if (PR_Delete(ZERO_LEN_FILE_NAME) == PR_FAILURE) { - fprintf(stderr, "PR_Delete failed\n"); - exit(1); - } -} - -int main(int argc, char **argv) -{ - PRFileDesc *listenSock; - PRThread *clientThread; - PRThread *serverThread; - PRNetAddr addr; - PRThreadScope scope = PR_GLOBAL_THREAD; - - listenSock = PR_NewTCPSocket(); - if (NULL == listenSock) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_InitializeNetAddr failed\n"); - exit(1); - } - if (PR_Bind(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_Bind failed\n"); - exit(1); - } - /* Find out what port number we are bound to. */ - if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - exit(1); - } - if (PR_Listen(listenSock, 5) == PR_FAILURE) { - fprintf(stderr, "PR_Listen failed\n"); - exit(1); - } - - clientThread = PR_CreateThread(PR_USER_THREAD, - ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)), - PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); - if (NULL == clientThread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - serverThread = PR_CreateThread(PR_USER_THREAD, - ServerThread, listenSock, - PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); - if (NULL == serverThread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - if (PR_JoinThread(clientThread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - if (PR_JoinThread(serverThread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - if (PR_Close(listenSock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/server_test.c nspr-4.10.7/mozilla/nsprpub/pr/tests/server_test.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/server_test.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/server_test.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,610 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** This server simulates a server running in loopback mode. -** -** The idea is that a single server is created. The server initially creates -** a number of worker threads. Then, with the server running, a number of -** clients are created which start requesting service from the server. -** -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include "pprthred.h" - -#include - -#define PORT 15004 -#define THREAD_STACKSIZE 0 - -#define PASS 0 -#define FAIL 1 -static int debug_mode = 0; - -static int _iterations = 1000; -static int _clients = 1; -static int _client_data = 250; -static int _server_data = (8*1024); - -static PRThreadScope ServerScope, ClientScope; - -#define SERVER "Server" -#define MAIN "Main" - -#define SERVER_STATE_STARTUP 0 -#define SERVER_STATE_READY 1 -#define SERVER_STATE_DYING 2 -#define SERVER_STATE_DEAD 4 -int ServerState; -PRLock *ServerStateCVLock; -PRCondVar *ServerStateCV; - -#undef DEBUGPRINTS -#ifdef DEBUGPRINTS -#define DPRINTF printf -#else -#define DPRINTF -#endif - - -/*********************************************************************** -** PRIVATE FUNCTION: Test_Result -** DESCRIPTION: Used in conjunction with the regress tool, prints out the -** status of the test case. -** INPUTS: PASS/FAIL -** OUTPUTS: None -** RETURN: None -** SIDE EFFECTS: -** -** RESTRICTIONS: -** None -** MEMORY: NA -** ALGORITHM: Determine what the status is and print accordingly. -** -***********************************************************************/ - - -static void Test_Result (int result) -{ - switch (result) - { - case PASS: - printf ("PASS\n"); - break; - case FAIL: - printf ("FAIL\n"); - break; - default: - break; - } -} - -static void do_work(void); - -/* --- Server state functions --------------------------------------------- */ -void -SetServerState(char *waiter, PRInt32 state) -{ - PR_Lock(ServerStateCVLock); - ServerState = state; - PR_NotifyCondVar(ServerStateCV); - - if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); - - PR_Unlock(ServerStateCVLock); -} - -int -WaitServerState(char *waiter, PRInt32 state) -{ - PRInt32 rv; - - PR_Lock(ServerStateCVLock); - - if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); - - while(!(ServerState & state)) - PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); - rv = ServerState; - - if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", - waiter, state, ServerState); - PR_Unlock(ServerStateCVLock); - - return rv; -} - -/* --- Server Functions ------------------------------------------- */ - -PRLock *workerThreadsLock; -PRInt32 workerThreads; -PRInt32 workerThreadsBusy; - -void -WorkerThreadFunc(void *_listenSock) -{ - PRFileDesc *listenSock = (PRFileDesc *)_listenSock; - PRInt32 bytesRead; - PRInt32 bytesWritten; - char *dataBuf; - char *sendBuf; - - if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", - _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); - dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); - if (!dataBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - - if (debug_mode) DPRINTF("\tServer worker thread running\n"); - - while(1) { - PRInt32 bytesToRead = _client_data; - PRInt32 bytesToWrite = _server_data; - PRFileDesc *newSock; - PRNetAddr *rAddr; - PRInt32 loops = 0; - - loops++; - - if (debug_mode) DPRINTF("\tServer thread going into accept\n"); - - bytesRead = PR_AcceptRead(listenSock, - &newSock, - &rAddr, - dataBuf, - bytesToRead, - PR_INTERVAL_NO_TIMEOUT); - - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); - continue; - } - - if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); - - PR_AtomicIncrement(&workerThreadsBusy); -#ifdef SYMBIAN - if (workerThreadsBusy == workerThreads && workerThreads<1) { -#else - if (workerThreadsBusy == workerThreads) { -#endif - PR_Lock(workerThreadsLock); - if (workerThreadsBusy == workerThreads) { - PRThread *WorkerThread; - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSock, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("Error creating client thread %d\n", workerThreads); - } else { - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); - } - } - PR_Unlock(workerThreadsLock); - } - - bytesToRead -= bytesRead; - while (bytesToRead) { - bytesRead = PR_Recv(newSock, - dataBuf, - bytesToRead, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); - continue; - } - if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); - } - - bytesWritten = PR_Send(newSock, - sendBuf, - bytesToWrite, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesWritten != _server_data) { - if (debug_mode) printf("\tError sending data to client (%d, %d)\n", - bytesWritten, PR_GetOSError()); - } else { - if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); - } - - PR_Close(newSock); - PR_AtomicDecrement(&workerThreadsBusy); - } -} - -PRFileDesc * -ServerSetup(void) -{ - PRFileDesc *listenSocket; - PRNetAddr serverAddr; - PRThread *WorkerThread; - - if ( (listenSocket = PR_NewTCPSocket()) == NULL) { - if (debug_mode) printf("\tServer error creating listen socket\n"); - else Test_Result(FAIL); - return NULL; - } - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); - - if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { - if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", - PR_GetOSError()); - else Test_Result(FAIL); - PR_Close(listenSocket); - return NULL; - } - - if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { - if (debug_mode) printf("\tServer error listening to server socket\n"); - else Test_Result(FAIL); - PR_Close(listenSocket); - - return NULL; - } - - /* Create Clients */ - workerThreads = 0; - workerThreadsBusy = 0; - - workerThreadsLock = PR_NewLock(); - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSocket, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("error creating working thread\n"); - PR_Close(listenSocket); - return NULL; - } - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); - - return listenSocket; -} - -/* The main server loop */ -void -ServerThreadFunc(void *unused) -{ - PRFileDesc *listenSocket; - - /* Do setup */ - listenSocket = ServerSetup(); - - if (!listenSocket) { - SetServerState(SERVER, SERVER_STATE_DEAD); - } else { - - if (debug_mode) DPRINTF("\tServer up\n"); - - /* Tell clients they can start now. */ - SetServerState(SERVER, SERVER_STATE_READY); - - /* Now wait for server death signal */ - WaitServerState(SERVER, SERVER_STATE_DYING); - - /* Cleanup */ - SetServerState(SERVER, SERVER_STATE_DEAD); - } -} - -/* --- Client Functions ------------------------------------------- */ - -PRInt32 numRequests; -PRInt32 numClients; -PRMonitor *clientMonitor; - -void -ClientThreadFunc(void *unused) -{ - PRNetAddr serverAddr; - PRFileDesc *clientSocket; - char *sendBuf; - char *recvBuf; - PRInt32 rv; - PRInt32 bytesNeeded; - - sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); - if (!recvBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - - while(numRequests > 0) { - - if ( (numRequests % 10) == 0 ) - if (debug_mode) printf("."); - if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); - - clientSocket = PR_NewTCPSocket(); - if (!clientSocket) { - if (debug_mode) printf("Client error creating socket: OS error %d\n", - PR_GetOSError()); - continue; - } - - if (debug_mode) DPRINTF("\tClient connecting\n"); - - rv = PR_Connect(clientSocket, - &serverAddr, - PR_INTERVAL_NO_TIMEOUT); - if (!clientSocket) { - if (debug_mode) printf("\tClient error connecting\n"); - continue; - } - - if (debug_mode) DPRINTF("\tClient connected\n"); - - rv = PR_Send(clientSocket, - sendBuf, - _client_data, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv != _client_data) { - if (debug_mode) printf("Client error sending data (%d)\n", rv); - PR_Close(clientSocket); - continue; - } - - if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); - - bytesNeeded = _server_data; - while(bytesNeeded) { - rv = PR_Recv(clientSocket, - recvBuf, - bytesNeeded, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv <= 0) { - if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", - rv, (_server_data - bytesNeeded), _server_data); - break; - } - if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); - bytesNeeded -= rv; - } - - PR_Close(clientSocket); - - PR_AtomicDecrement(&numRequests); - } - - PR_EnterMonitor(clientMonitor); - --numClients; - PR_Notify(clientMonitor); - PR_ExitMonitor(clientMonitor); - - PR_DELETE(sendBuf); - PR_DELETE(recvBuf); -} - -void -RunClients(void) -{ - PRInt32 index; - - numRequests = _iterations; - numClients = _clients; - clientMonitor = PR_NewMonitor(); - - for (index=0; index<_clients; index++) { - PRThread *clientThread; - - - clientThread = PR_CreateThread( - PR_USER_THREAD, - ClientThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ClientScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!clientThread) { - if (debug_mode) printf("\terror creating client thread %d\n", index); - } else - if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); - - } - - PR_EnterMonitor(clientMonitor); - while(numClients) - PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); - PR_ExitMonitor(clientMonitor); -} - -/* --- Main Function ---------------------------------------------- */ - -static -void do_work() -{ - PRThread *ServerThread; - PRInt32 state; - - SetServerState(MAIN, SERVER_STATE_STARTUP); - ServerThread = PR_CreateThread( - PR_USER_THREAD, - ServerThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ServerScope, - PR_JOINABLE_THREAD, - THREAD_STACKSIZE); - if (!ServerThread) { - if (debug_mode) printf("error creating main server thread\n"); - return; - } - - /* Wait for server to be ready */ - state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); - - if (!(state & SERVER_STATE_DEAD)) { - /* Run Test Clients */ - RunClients(); - - /* Send death signal to server */ - SetServerState(MAIN, SERVER_STATE_DYING); - } - - PR_JoinThread(ServerThread); -} - -static void do_workUU(void) -{ - ServerScope = PR_LOCAL_THREAD; - ClientScope = PR_LOCAL_THREAD; - do_work(); -} - -static void do_workUK(void) -{ - ServerScope = PR_LOCAL_THREAD; - ClientScope = PR_GLOBAL_THREAD; - do_work(); -} - -static void do_workKU(void) -{ - ServerScope = PR_GLOBAL_THREAD; - ClientScope = PR_LOCAL_THREAD; - do_work(); -} - -static void do_workKK(void) -{ - ServerScope = PR_GLOBAL_THREAD; - ClientScope = PR_GLOBAL_THREAD; - do_work(); -} - - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - - if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); -} - - -int main(int argc, char **argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ -#ifndef SYMBIAN - if (debug_mode) { - printf("Enter number of iterations: \n"); - scanf("%d", &_iterations); - printf("Enter number of clients : \n"); - scanf("%d", &_clients); - printf("Enter size of client data : \n"); - scanf("%d", &_client_data); - printf("Enter size of server data : \n"); - scanf("%d", &_server_data); - } - else -#endif - { - - _iterations = 10; - _clients = 1; - _client_data = 10; - _server_data = 10; - } - - if (debug_mode) { - printf("\n\n%d iterations with %d client threads.\n", - _iterations, _clients); - printf("Sending %d bytes of client data and %d bytes of server data\n", - _client_data, _server_data); - } - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - ServerStateCVLock = PR_NewLock(); - ServerStateCV = PR_NewCondVar(ServerStateCVLock); - - Measure(do_workUU, "server loop user/user"); - #if 0 - Measure(do_workUK, "server loop user/kernel"); - Measure(do_workKU, "server loop kernel/user"); - Measure(do_workKK, "server loop kernel/kernel"); - #endif - - PR_Cleanup(); - - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/servr_kk.c nspr-4.10.7/mozilla/nsprpub/pr/tests/servr_kk.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/servr_kk.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/servr_kk.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,588 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** This server simulates a server running in loopback mode. -** -** The idea is that a single server is created. The server initially creates -** a number of worker threads. Then, with the server running, a number of -** clients are created which start requesting service from the server. -** -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include "pprthred.h" - -#include - -#define PORT 15004 -#define THREAD_STACKSIZE 0 - -static int _iterations = 1000; -static int _clients = 1; -static int _client_data = 250; -static int _server_data = (8*1024); - -static PRThreadScope ServerScope, ClientScope; - -#define SERVER "Server" -#define MAIN "Main" - -#define SERVER_STATE_STARTUP 0 -#define SERVER_STATE_READY 1 -#define SERVER_STATE_DYING 2 -#define SERVER_STATE_DEAD 4 -int ServerState; -PRLock *ServerStateCVLock; -PRCondVar *ServerStateCV; - -#ifdef DEBUGPRINTS -#define DPRINTF printf -#else -#define DPRINTF -#endif - -PRIntn failed_already=0; -PRIntn debug_mode; -static void do_work(void); - -/* --- Server state functions --------------------------------------------- */ -void -SetServerState(char *waiter, PRInt32 state) -{ - PR_Lock(ServerStateCVLock); - ServerState = state; - PR_NotifyCondVar(ServerStateCV); - - if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); - - PR_Unlock(ServerStateCVLock); -} - -int -WaitServerState(char *waiter, PRInt32 state) -{ - PRInt32 rv; - - PR_Lock(ServerStateCVLock); - - if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); - - while(!(ServerState & state)) - PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); - rv = ServerState; - - if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", - waiter, state, ServerState); - PR_Unlock(ServerStateCVLock); - - return rv; -} - -/* --- Server Functions ------------------------------------------- */ - -PRLock *workerThreadsLock; -PRInt32 workerThreads; -PRInt32 workerThreadsBusy; - -void -WorkerThreadFunc(void *_listenSock) -{ - PRFileDesc *listenSock = (PRFileDesc *)_listenSock; - PRInt32 bytesRead; - PRInt32 bytesWritten; - char *dataBuf; - char *sendBuf; - - if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", - _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); - dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); - if (!dataBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - - if (debug_mode) DPRINTF("\tServer worker thread running\n"); - - while(1) { - PRInt32 bytesToRead = _client_data; - PRInt32 bytesToWrite = _server_data; - PRFileDesc *newSock; - PRNetAddr *rAddr; - PRInt32 loops = 0; - - loops++; - - if (debug_mode) DPRINTF("\tServer thread going into accept\n"); - - bytesRead = PR_AcceptRead(listenSock, - &newSock, - &rAddr, - dataBuf, - bytesToRead, - PR_INTERVAL_NO_TIMEOUT); - - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); - continue; - } - - if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); - - PR_AtomicIncrement(&workerThreadsBusy); -#ifdef SYMBIAN - if (workerThreadsBusy == workerThreads && workerThreads<1) { -#else - if (workerThreadsBusy == workerThreads) { -#endif - PR_Lock(workerThreadsLock); - if (workerThreadsBusy == workerThreads) { - PRThread *WorkerThread; - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSock, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("Error creating client thread %d\n", workerThreads); - } else { - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); - } - } - PR_Unlock(workerThreadsLock); - } - - bytesToRead -= bytesRead; - while (bytesToRead) { - bytesRead = PR_Recv(newSock, - dataBuf, - bytesToRead, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); - continue; - } - if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); - } - - bytesWritten = PR_Send(newSock, - sendBuf, - bytesToWrite, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesWritten != _server_data) { - if (debug_mode) printf("\tError sending data to client (%d, %d)\n", - bytesWritten, PR_GetOSError()); - } else { - if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); - } - - PR_Close(newSock); - PR_AtomicDecrement(&workerThreadsBusy); - } -} - -PRFileDesc * -ServerSetup(void) -{ - PRFileDesc *listenSocket; - PRSocketOptionData sockOpt; - PRNetAddr serverAddr; - PRThread *WorkerThread; - - if ( (listenSocket = PR_NewTCPSocket()) == NULL) { - if (debug_mode) printf("\tServer error creating listen socket\n"); - else failed_already=1; - return NULL; - } - - sockOpt.option = PR_SockOpt_Reuseaddr; - sockOpt.value.reuse_addr = PR_TRUE; - if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { - if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", - PR_GetOSError()); - else failed_already=1; - PR_Close(listenSocket); - return NULL; - } - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); - - if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { - if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", - PR_GetOSError()); - else failed_already=1; - PR_Close(listenSocket); - return NULL; - } - - if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { - if (debug_mode) printf("\tServer error listening to server socket\n"); - else failed_already=1; - PR_Close(listenSocket); - - return NULL; - } - - /* Create Clients */ - workerThreads = 0; - workerThreadsBusy = 0; - - workerThreadsLock = PR_NewLock(); - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSocket, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("error creating working thread\n"); - PR_Close(listenSocket); - return NULL; - } - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); - - return listenSocket; -} - -/* The main server loop */ -void -ServerThreadFunc(void *unused) -{ - PRFileDesc *listenSocket; - - /* Do setup */ - listenSocket = ServerSetup(); - - if (!listenSocket) { - SetServerState(SERVER, SERVER_STATE_DEAD); - } else { - - if (debug_mode) DPRINTF("\tServer up\n"); - - /* Tell clients they can start now. */ - SetServerState(SERVER, SERVER_STATE_READY); - - /* Now wait for server death signal */ - WaitServerState(SERVER, SERVER_STATE_DYING); - - /* Cleanup */ - SetServerState(SERVER, SERVER_STATE_DEAD); - } -} - -/* --- Client Functions ------------------------------------------- */ - -PRInt32 numRequests; -PRInt32 numClients; -PRMonitor *clientMonitor; - -void -ClientThreadFunc(void *unused) -{ - PRNetAddr serverAddr; - PRFileDesc *clientSocket; - char *sendBuf; - char *recvBuf; - PRInt32 rv; - PRInt32 bytesNeeded; - - sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); - if (!recvBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - - while(numRequests > 0) { - - if ( (numRequests % 10) == 0 ) - if (debug_mode) printf("."); - if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); - - clientSocket = PR_NewTCPSocket(); - if (!clientSocket) { - if (debug_mode) printf("Client error creating socket: OS error %d\n", - PR_GetOSError()); - continue; - } - - if (debug_mode) DPRINTF("\tClient connecting\n"); - - rv = PR_Connect(clientSocket, - &serverAddr, - PR_INTERVAL_NO_TIMEOUT); - if (!clientSocket) { - if (debug_mode) printf("\tClient error connecting\n"); - continue; - } - - if (debug_mode) DPRINTF("\tClient connected\n"); - - rv = PR_Send(clientSocket, - sendBuf, - _client_data, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv != _client_data) { - if (debug_mode) printf("Client error sending data (%d)\n", rv); - PR_Close(clientSocket); - continue; - } - - if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); - - bytesNeeded = _server_data; - while(bytesNeeded) { - rv = PR_Recv(clientSocket, - recvBuf, - bytesNeeded, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv <= 0) { - if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", - rv, (_server_data - bytesNeeded), _server_data); - break; - } - if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); - bytesNeeded -= rv; - } - - PR_Close(clientSocket); - - PR_AtomicDecrement(&numRequests); - } - - PR_EnterMonitor(clientMonitor); - --numClients; - PR_Notify(clientMonitor); - PR_ExitMonitor(clientMonitor); - - PR_DELETE(sendBuf); - PR_DELETE(recvBuf); -} - -void -RunClients(void) -{ - PRInt32 index; - - numRequests = _iterations; - numClients = _clients; - clientMonitor = PR_NewMonitor(); - - for (index=0; index<_clients; index++) { - PRThread *clientThread; - - - clientThread = PR_CreateThread( - PR_USER_THREAD, - ClientThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ClientScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!clientThread) { - if (debug_mode) printf("\terror creating client thread %d\n", index); - } else - if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); - - } - - PR_EnterMonitor(clientMonitor); - while(numClients) - PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); - PR_ExitMonitor(clientMonitor); -} - -/* --- Main Function ---------------------------------------------- */ - -static -void do_work() -{ - PRThread *ServerThread; - PRInt32 state; - - SetServerState(MAIN, SERVER_STATE_STARTUP); - ServerThread = PR_CreateThread( - PR_USER_THREAD, - ServerThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ServerScope, - PR_JOINABLE_THREAD, - THREAD_STACKSIZE); - if (!ServerThread) { - if (debug_mode) printf("error creating main server thread\n"); - return; - } - - /* Wait for server to be ready */ - state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); - - if (!(state & SERVER_STATE_DEAD)) { - /* Run Test Clients */ - RunClients(); - - /* Send death signal to server */ - SetServerState(MAIN, SERVER_STATE_DYING); - } - - PR_JoinThread(ServerThread); -} - -static void do_workUU(void) -{ - ServerScope = PR_LOCAL_THREAD; - ClientScope = PR_LOCAL_THREAD; - do_work(); -} - -static void do_workUK(void) -{ - ServerScope = PR_LOCAL_THREAD; - ClientScope = PR_GLOBAL_THREAD; - do_work(); -} - -static void do_workKU(void) -{ - ServerScope = PR_GLOBAL_THREAD; - ClientScope = PR_LOCAL_THREAD; - do_work(); -} - -static void do_workKK(void) -{ - ServerScope = PR_GLOBAL_THREAD; - ClientScope = PR_GLOBAL_THREAD; - do_work(); -} - - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - - if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); -} - - -int main(int argc, char **argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ -#ifndef SYMBIAN - if (debug_mode) { - printf("Enter number of iterations: \n"); - scanf("%d", &_iterations); - printf("Enter number of clients : \n"); - scanf("%d", &_clients); - printf("Enter size of client data : \n"); - scanf("%d", &_client_data); - printf("Enter size of server data : \n"); - scanf("%d", &_server_data); - } - else -#endif - { - _iterations = 7; - _clients = 7; - _client_data = 100; - _server_data = 100; - } - - if (debug_mode) { - printf("\n\n%d iterations with %d client threads.\n", - _iterations, _clients); - printf("Sending %d bytes of client data and %d bytes of server data\n", - _client_data, _server_data); - } - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - PR_SetThreadRecycleMode(64); - - ServerStateCVLock = PR_NewLock(); - ServerStateCV = PR_NewCondVar(ServerStateCVLock); - - - Measure(do_workKK, "server loop kernel/kernel"); - - PR_Cleanup(); - - if(failed_already) - return 1; - else - return 0; - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/servr_ku.c nspr-4.10.7/mozilla/nsprpub/pr/tests/servr_ku.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/servr_ku.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/servr_ku.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,568 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** This server simulates a server running in loopback mode. -** -** The idea is that a single server is created. The server initially creates -** a number of worker threads. Then, with the server running, a number of -** clients are created which start requesting service from the server. -** -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include "pprthred.h" - -#include - -#define PORT 15004 -#define THREAD_STACKSIZE 0 - -static int _iterations = 1000; -static int _clients = 1; -static int _client_data = 250; -static int _server_data = (8*1024); - -static PRThreadScope ServerScope, ClientScope; - -#define SERVER "Server" -#define MAIN "Main" - -#define SERVER_STATE_STARTUP 0 -#define SERVER_STATE_READY 1 -#define SERVER_STATE_DYING 2 -#define SERVER_STATE_DEAD 4 -int ServerState; -PRLock *ServerStateCVLock; -PRCondVar *ServerStateCV; - -#ifdef DEBUGPRINTS -#define DPRINTF printf -#else -#define DPRINTF -#endif - -PRIntn failed_already=0; -PRIntn debug_mode; - -static void do_work(void); - -/* --- Server state functions --------------------------------------------- */ -void -SetServerState(char *waiter, PRInt32 state) -{ - PR_Lock(ServerStateCVLock); - ServerState = state; - PR_NotifyCondVar(ServerStateCV); - - if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); - - PR_Unlock(ServerStateCVLock); -} - -int -WaitServerState(char *waiter, PRInt32 state) -{ - PRInt32 rv; - - PR_Lock(ServerStateCVLock); - - if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); - - while(!(ServerState & state)) - PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); - rv = ServerState; - - if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", - waiter, state, ServerState); - PR_Unlock(ServerStateCVLock); - - return rv; -} - -/* --- Server Functions ------------------------------------------- */ - -PRLock *workerThreadsLock; -PRInt32 workerThreads; -PRInt32 workerThreadsBusy; - -void -WorkerThreadFunc(void *_listenSock) -{ - PRFileDesc *listenSock = (PRFileDesc *)_listenSock; - PRInt32 bytesRead; - PRInt32 bytesWritten; - char *dataBuf; - char *sendBuf; - - if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", - _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); - dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); - if (!dataBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - - if (debug_mode) DPRINTF("\tServer worker thread running\n"); - - while(1) { - PRInt32 bytesToRead = _client_data; - PRInt32 bytesToWrite = _server_data; - PRFileDesc *newSock; - PRNetAddr *rAddr; - PRInt32 loops = 0; - - loops++; - - if (debug_mode) DPRINTF("\tServer thread going into accept\n"); - - bytesRead = PR_AcceptRead(listenSock, - &newSock, - &rAddr, - dataBuf, - bytesToRead, - PR_INTERVAL_NO_TIMEOUT); - - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); - continue; - } - - if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); - - PR_AtomicIncrement(&workerThreadsBusy); -#ifdef SYMBIAN - if (workerThreadsBusy == workerThreads && workerThreads<1) { -#else - if (workerThreadsBusy == workerThreads) { -#endif - PR_Lock(workerThreadsLock); - if (workerThreadsBusy == workerThreads) { - PRThread *WorkerThread; - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSock, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("Error creating client thread %d\n", workerThreads); - } else { - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); - } - } - PR_Unlock(workerThreadsLock); - } - - bytesToRead -= bytesRead; - while (bytesToRead) { - bytesRead = PR_Recv(newSock, - dataBuf, - bytesToRead, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); - continue; - } - if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); - } - - bytesWritten = PR_Send(newSock, - sendBuf, - bytesToWrite, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesWritten != _server_data) { - if (debug_mode) printf("\tError sending data to client (%d, %d)\n", - bytesWritten, PR_GetOSError()); - } else { - if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); - } - - PR_Close(newSock); - PR_AtomicDecrement(&workerThreadsBusy); - } -} - -PRFileDesc * -ServerSetup(void) -{ - PRFileDesc *listenSocket; - PRSocketOptionData sockOpt; - PRNetAddr serverAddr; - PRThread *WorkerThread; - - if ( (listenSocket = PR_NewTCPSocket()) == NULL) { - if (debug_mode) printf("\tServer error creating listen socket\n"); - else failed_already=1; - return NULL; - } - - sockOpt.option = PR_SockOpt_Reuseaddr; - sockOpt.value.reuse_addr = PR_TRUE; - if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { - if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", - PR_GetOSError()); - else failed_already=1; - PR_Close(listenSocket); - return NULL; - } - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); - - if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { - if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", - PR_GetOSError()); - else failed_already=1; - PR_Close(listenSocket); - return NULL; - } - - if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { - if (debug_mode) printf("\tServer error listening to server socket\n"); - else failed_already=1; - PR_Close(listenSocket); - - return NULL; - } - - /* Create Clients */ - workerThreads = 0; - workerThreadsBusy = 0; - - workerThreadsLock = PR_NewLock(); - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSocket, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("error creating working thread\n"); - PR_Close(listenSocket); - return NULL; - } - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); - - return listenSocket; -} - -/* The main server loop */ -void -ServerThreadFunc(void *unused) -{ - PRFileDesc *listenSocket; - - /* Do setup */ - listenSocket = ServerSetup(); - - if (!listenSocket) { - SetServerState(SERVER, SERVER_STATE_DEAD); - } else { - - if (debug_mode) DPRINTF("\tServer up\n"); - - /* Tell clients they can start now. */ - SetServerState(SERVER, SERVER_STATE_READY); - - /* Now wait for server death signal */ - WaitServerState(SERVER, SERVER_STATE_DYING); - - /* Cleanup */ - SetServerState(SERVER, SERVER_STATE_DEAD); - } -} - -/* --- Client Functions ------------------------------------------- */ - -PRInt32 numRequests; -PRInt32 numClients; -PRMonitor *clientMonitor; - -void -ClientThreadFunc(void *unused) -{ - PRNetAddr serverAddr; - PRFileDesc *clientSocket; - char *sendBuf; - char *recvBuf; - PRInt32 rv; - PRInt32 bytesNeeded; - - sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); - if (!recvBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - - while(numRequests > 0) { - - if ( (numRequests % 10) == 0 ) - if (debug_mode) printf("."); - if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); - - clientSocket = PR_NewTCPSocket(); - if (!clientSocket) { - if (debug_mode) printf("Client error creating socket: OS error %d\n", - PR_GetOSError()); - continue; - } - - if (debug_mode) DPRINTF("\tClient connecting\n"); - - rv = PR_Connect(clientSocket, - &serverAddr, - PR_INTERVAL_NO_TIMEOUT); - if (!clientSocket) { - if (debug_mode) printf("\tClient error connecting\n"); - continue; - } - - if (debug_mode) DPRINTF("\tClient connected\n"); - - rv = PR_Send(clientSocket, - sendBuf, - _client_data, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv != _client_data) { - if (debug_mode) printf("Client error sending data (%d)\n", rv); - PR_Close(clientSocket); - continue; - } - - if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); - - bytesNeeded = _server_data; - while(bytesNeeded) { - rv = PR_Recv(clientSocket, - recvBuf, - bytesNeeded, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv <= 0) { - if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", - rv, (_server_data - bytesNeeded), _server_data); - break; - } - if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); - bytesNeeded -= rv; - } - - PR_Close(clientSocket); - - PR_AtomicDecrement(&numRequests); - } - - PR_EnterMonitor(clientMonitor); - --numClients; - PR_Notify(clientMonitor); - PR_ExitMonitor(clientMonitor); - - PR_DELETE(sendBuf); - PR_DELETE(recvBuf); -} - -void -RunClients(void) -{ - PRInt32 index; - - numRequests = _iterations; - numClients = _clients; - clientMonitor = PR_NewMonitor(); - - for (index=0; index<_clients; index++) { - PRThread *clientThread; - - - clientThread = PR_CreateThread( - PR_USER_THREAD, - ClientThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ClientScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!clientThread) { - if (debug_mode) printf("\terror creating client thread %d\n", index); - } else - if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); - - } - - PR_EnterMonitor(clientMonitor); - while(numClients) - PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); - PR_ExitMonitor(clientMonitor); -} - -/* --- Main Function ---------------------------------------------- */ - -static -void do_work() -{ - PRThread *ServerThread; - PRInt32 state; - - SetServerState(MAIN, SERVER_STATE_STARTUP); - ServerThread = PR_CreateThread( - PR_USER_THREAD, - ServerThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ServerScope, - PR_JOINABLE_THREAD, - THREAD_STACKSIZE); - if (!ServerThread) { - if (debug_mode) printf("error creating main server thread\n"); - return; - } - - /* Wait for server to be ready */ - state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); - - if (!(state & SERVER_STATE_DEAD)) { - /* Run Test Clients */ - RunClients(); - - /* Send death signal to server */ - SetServerState(MAIN, SERVER_STATE_DYING); - } - - PR_JoinThread(ServerThread); -} - - -static void do_workKU(void) -{ - ServerScope = PR_GLOBAL_THREAD; - ClientScope = PR_LOCAL_THREAD; - do_work(); -} - - - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - - if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); -} - - -int main(int argc, char **argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ -#ifndef SYMBIAN - if (debug_mode) { - printf("Enter number of iterations: \n"); - scanf("%d", &_iterations); - printf("Enter number of clients : \n"); - scanf("%d", &_clients); - printf("Enter size of client data : \n"); - scanf("%d", &_client_data); - printf("Enter size of server data : \n"); - scanf("%d", &_server_data); - } - else -#endif - { - _iterations = 7; - _clients = 7; - _client_data = 100; - _server_data = 100; - } - - if (debug_mode) { - printf("\n\n%d iterations with %d client threads.\n", - _iterations, _clients); - printf("Sending %d bytes of client data and %d bytes of server data\n", - _client_data, _server_data); - } - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - PR_SetThreadRecycleMode(64); - - ServerStateCVLock = PR_NewLock(); - ServerStateCV = PR_NewCondVar(ServerStateCVLock); - - Measure(do_workKU, "server loop kernel/user"); - - PR_Cleanup(); - if(failed_already) - return 1; - else - return 0; - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/servr_uk.c nspr-4.10.7/mozilla/nsprpub/pr/tests/servr_uk.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/servr_uk.c 2012-03-06 13:14:31.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/servr_uk.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,570 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** This server simulates a server running in loopback mode. -** -** The idea is that a single server is created. The server initially creates -** a number of worker threads. Then, with the server running, a number of -** clients are created which start requesting service from the server. -** -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include "pprthred.h" - -#include - -#define PORT 15004 -#define THREAD_STACKSIZE 0 - -static int _iterations = 1000; -static int _clients = 1; -static int _client_data = 250; -static int _server_data = (8*1024); - -static PRThreadScope ServerScope, ClientScope; - -#define SERVER "Server" -#define MAIN "Main" - -#define SERVER_STATE_STARTUP 0 -#define SERVER_STATE_READY 1 -#define SERVER_STATE_DYING 2 -#define SERVER_STATE_DEAD 4 -int ServerState; -PRLock *ServerStateCVLock; -PRCondVar *ServerStateCV; - -#ifdef DEBUGPRINTS -#define DPRINTF printf -#else -#define DPRINTF -#endif - -PRIntn failed_already=0; -PRIntn debug_mode; - - - -static void do_work(void); - -/* --- Server state functions --------------------------------------------- */ -void -SetServerState(char *waiter, PRInt32 state) -{ - PR_Lock(ServerStateCVLock); - ServerState = state; - PR_NotifyCondVar(ServerStateCV); - - if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); - - PR_Unlock(ServerStateCVLock); -} - -int -WaitServerState(char *waiter, PRInt32 state) -{ - PRInt32 rv; - - PR_Lock(ServerStateCVLock); - - if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); - - while(!(ServerState & state)) - PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); - rv = ServerState; - - if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", - waiter, state, ServerState); - PR_Unlock(ServerStateCVLock); - - return rv; -} - -/* --- Server Functions ------------------------------------------- */ - -PRLock *workerThreadsLock; -PRInt32 workerThreads; -PRInt32 workerThreadsBusy; - -void -WorkerThreadFunc(void *_listenSock) -{ - PRFileDesc *listenSock = (PRFileDesc *)_listenSock; - PRInt32 bytesRead; - PRInt32 bytesWritten; - char *dataBuf; - char *sendBuf; - - if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", - _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); - dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); - if (!dataBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - - if (debug_mode) DPRINTF("\tServer worker thread running\n"); - - while(1) { - PRInt32 bytesToRead = _client_data; - PRInt32 bytesToWrite = _server_data; - PRFileDesc *newSock; - PRNetAddr *rAddr; - PRInt32 loops = 0; - - loops++; - - if (debug_mode) DPRINTF("\tServer thread going into accept\n"); - - bytesRead = PR_AcceptRead(listenSock, - &newSock, - &rAddr, - dataBuf, - bytesToRead, - PR_INTERVAL_NO_TIMEOUT); - - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); - continue; - } - - if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); - - PR_AtomicIncrement(&workerThreadsBusy); -#ifdef SYMBIAN - if (workerThreadsBusy == workerThreads && workerThreads<1) { -#else - if (workerThreadsBusy == workerThreads) { -#endif - PR_Lock(workerThreadsLock); - if (workerThreadsBusy == workerThreads) { - PRThread *WorkerThread; - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSock, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("Error creating client thread %d\n", workerThreads); - } else { - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); - } - } - PR_Unlock(workerThreadsLock); - } - - bytesToRead -= bytesRead; - while (bytesToRead) { - bytesRead = PR_Recv(newSock, - dataBuf, - bytesToRead, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); - continue; - } - if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); - } - - bytesWritten = PR_Send(newSock, - sendBuf, - bytesToWrite, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesWritten != _server_data) { - if (debug_mode) printf("\tError sending data to client (%d, %d)\n", - bytesWritten, PR_GetOSError()); - } else { - if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); - } - - PR_Close(newSock); - PR_AtomicDecrement(&workerThreadsBusy); - } -} - -PRFileDesc * -ServerSetup(void) -{ - PRFileDesc *listenSocket; - PRSocketOptionData sockOpt; - PRNetAddr serverAddr; - PRThread *WorkerThread; - - if ( (listenSocket = PR_NewTCPSocket()) == NULL) { - if (debug_mode) printf("\tServer error creating listen socket\n"); - else - return NULL; - } - - sockOpt.option = PR_SockOpt_Reuseaddr; - sockOpt.value.reuse_addr = PR_TRUE; - if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { - if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", - PR_GetOSError()); - else failed_already=1; - PR_Close(listenSocket); - return NULL; - } - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); - - if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { - if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", - PR_GetOSError()); - else failed_already=1; - PR_Close(listenSocket); - return NULL; - } - - if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { - if (debug_mode) printf("\tServer error listening to server socket\n"); - else failed_already=1; - PR_Close(listenSocket); - - return NULL; - } - - /* Create Clients */ - workerThreads = 0; - workerThreadsBusy = 0; - - workerThreadsLock = PR_NewLock(); - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSocket, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("error creating working thread\n"); - PR_Close(listenSocket); - return NULL; - } - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); - - return listenSocket; -} - -/* The main server loop */ -void -ServerThreadFunc(void *unused) -{ - PRFileDesc *listenSocket; - - /* Do setup */ - listenSocket = ServerSetup(); - - if (!listenSocket) { - SetServerState(SERVER, SERVER_STATE_DEAD); - } else { - - if (debug_mode) DPRINTF("\tServer up\n"); - - /* Tell clients they can start now. */ - SetServerState(SERVER, SERVER_STATE_READY); - - /* Now wait for server death signal */ - WaitServerState(SERVER, SERVER_STATE_DYING); - - /* Cleanup */ - SetServerState(SERVER, SERVER_STATE_DEAD); - } -} - -/* --- Client Functions ------------------------------------------- */ - -PRInt32 numRequests; -PRInt32 numClients; -PRMonitor *clientMonitor; - -void -ClientThreadFunc(void *unused) -{ - PRNetAddr serverAddr; - PRFileDesc *clientSocket; - char *sendBuf; - char *recvBuf; - PRInt32 rv; - PRInt32 bytesNeeded; - - sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); - if (!recvBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - - while(numRequests > 0) { - - if ( (numRequests % 10) == 0 ) - if (debug_mode) printf("."); - if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); - - clientSocket = PR_NewTCPSocket(); - if (!clientSocket) { - if (debug_mode) printf("Client error creating socket: OS error %d\n", - PR_GetOSError()); - continue; - } - - if (debug_mode) DPRINTF("\tClient connecting\n"); - - rv = PR_Connect(clientSocket, - &serverAddr, - PR_INTERVAL_NO_TIMEOUT); - if (!clientSocket) { - if (debug_mode) printf("\tClient error connecting\n"); - continue; - } - - if (debug_mode) DPRINTF("\tClient connected\n"); - - rv = PR_Send(clientSocket, - sendBuf, - _client_data, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv != _client_data) { - if (debug_mode) printf("Client error sending data (%d)\n", rv); - PR_Close(clientSocket); - continue; - } - - if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); - - bytesNeeded = _server_data; - while(bytesNeeded) { - rv = PR_Recv(clientSocket, - recvBuf, - bytesNeeded, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv <= 0) { - if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", - rv, (_server_data - bytesNeeded), _server_data); - break; - } - if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); - bytesNeeded -= rv; - } - - PR_Close(clientSocket); - - PR_AtomicDecrement(&numRequests); - } - - PR_EnterMonitor(clientMonitor); - --numClients; - PR_Notify(clientMonitor); - PR_ExitMonitor(clientMonitor); - - PR_DELETE(sendBuf); - PR_DELETE(recvBuf); -} - -void -RunClients(void) -{ - PRInt32 index; - - numRequests = _iterations; - numClients = _clients; - clientMonitor = PR_NewMonitor(); - - for (index=0; index<_clients; index++) { - PRThread *clientThread; - - - clientThread = PR_CreateThread( - PR_USER_THREAD, - ClientThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ClientScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!clientThread) { - if (debug_mode) printf("\terror creating client thread %d\n", index); - } else - if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); - - } - - PR_EnterMonitor(clientMonitor); - while(numClients) - PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); - PR_ExitMonitor(clientMonitor); -} - -/* --- Main Function ---------------------------------------------- */ - -static -void do_work() -{ - PRThread *ServerThread; - PRInt32 state; - - SetServerState(MAIN, SERVER_STATE_STARTUP); - ServerThread = PR_CreateThread( - PR_USER_THREAD, - ServerThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ServerScope, - PR_JOINABLE_THREAD, - THREAD_STACKSIZE); - if (!ServerThread) { - if (debug_mode) printf("error creating main server thread\n"); - return; - } - - /* Wait for server to be ready */ - state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); - - if (!(state & SERVER_STATE_DEAD)) { - /* Run Test Clients */ - RunClients(); - - /* Send death signal to server */ - SetServerState(MAIN, SERVER_STATE_DYING); - } - - PR_JoinThread(ServerThread); -} - - -static void do_workUK(void) -{ - ServerScope = PR_LOCAL_THREAD; - ClientScope = PR_GLOBAL_THREAD; - do_work(); -} - - - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - - if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); -} - - -int main(int argc, char **argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ -#ifndef SYMBIAN - if (debug_mode) { - printf("Enter number of iterations: \n"); - scanf("%d", &_iterations); - printf("Enter number of clients : \n"); - scanf("%d", &_clients); - printf("Enter size of client data : \n"); - scanf("%d", &_client_data); - printf("Enter size of server data : \n"); - scanf("%d", &_server_data); - } - else -#endif - { - _iterations = 7; - _clients = 7; - _client_data = 100; - _server_data = 100; - } - - if (debug_mode) { - printf("\n\n%d iterations with %d client threads.\n", - _iterations, _clients); - printf("Sending %d bytes of client data and %d bytes of server data\n", - _client_data, _server_data); - } - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - PR_SetThreadRecycleMode(64); - - ServerStateCVLock = PR_NewLock(); - ServerStateCV = PR_NewCondVar(ServerStateCVLock); - - Measure(do_workUK, "server loop user/kernel"); - - PR_Cleanup(); - - if(failed_already) - return 1; - else - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/servr_uu.c nspr-4.10.7/mozilla/nsprpub/pr/tests/servr_uu.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/servr_uu.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/servr_uu.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,569 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** This server simulates a server running in loopback mode. -** -** The idea is that a single server is created. The server initially creates -** a number of worker threads. Then, with the server running, a number of -** clients are created which start requesting service from the server. -** -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include "pprthred.h" - -#include - -#define PORT 15004 -#define THREAD_STACKSIZE 0 - -static int _iterations = 1000; -static int _clients = 1; -static int _client_data = 250; -static int _server_data = (8*1024); - -static PRThreadScope ServerScope, ClientScope; - -#define SERVER "Server" -#define MAIN "Main" - -#define SERVER_STATE_STARTUP 0 -#define SERVER_STATE_READY 1 -#define SERVER_STATE_DYING 2 -#define SERVER_STATE_DEAD 4 -int ServerState; -PRLock *ServerStateCVLock; -PRCondVar *ServerStateCV; - -#ifdef DEBUGPRINTS -#define DPRINTF printf -#else -#define DPRINTF -#endif - -PRIntn failed_already=0; -PRIntn debug_mode; - -static void do_work(void); - -/* --- Server state functions --------------------------------------------- */ -void -SetServerState(char *waiter, PRInt32 state) -{ - PR_Lock(ServerStateCVLock); - ServerState = state; - PR_NotifyCondVar(ServerStateCV); - - if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); - - PR_Unlock(ServerStateCVLock); -} - -int -WaitServerState(char *waiter, PRInt32 state) -{ - PRInt32 rv; - - PR_Lock(ServerStateCVLock); - - if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); - - while(!(ServerState & state)) - PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); - rv = ServerState; - - if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", - waiter, state, ServerState); - PR_Unlock(ServerStateCVLock); - - return rv; -} - -/* --- Server Functions ------------------------------------------- */ - -PRLock *workerThreadsLock; -PRInt32 workerThreads; -PRInt32 workerThreadsBusy; - -void -WorkerThreadFunc(void *_listenSock) -{ - PRFileDesc *listenSock = (PRFileDesc *)_listenSock; - PRInt32 bytesRead; - PRInt32 bytesWritten; - char *dataBuf; - char *sendBuf; - - if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", - _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); - dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); - if (!dataBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tServer could not malloc space!?\n"); - - if (debug_mode) DPRINTF("\tServer worker thread running\n"); - - while(1) { - PRInt32 bytesToRead = _client_data; - PRInt32 bytesToWrite = _server_data; - PRFileDesc *newSock; - PRNetAddr *rAddr; - PRInt32 loops = 0; - - loops++; - - if (debug_mode) DPRINTF("\tServer thread going into accept\n"); - - bytesRead = PR_AcceptRead(listenSock, - &newSock, - &rAddr, - dataBuf, - bytesToRead, - PR_INTERVAL_NO_TIMEOUT); - - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); - continue; - } - - if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); - - PR_AtomicIncrement(&workerThreadsBusy); -#ifdef SYMBIAN - if (workerThreadsBusy == workerThreads && workerThreads<1) { -#else - if (workerThreadsBusy == workerThreads) { -#endif - - PR_Lock(workerThreadsLock); - if (workerThreadsBusy == workerThreads) { - PRThread *WorkerThread; - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSock, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("Error creating client thread %d\n", workerThreads); - } else { - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); - } - } - PR_Unlock(workerThreadsLock); - } - - bytesToRead -= bytesRead; - while (bytesToRead) { - bytesRead = PR_Recv(newSock, - dataBuf, - bytesToRead, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesRead < 0) { - if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); - continue; - } - if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); - } - - bytesWritten = PR_Send(newSock, - sendBuf, - bytesToWrite, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (bytesWritten != _server_data) { - if (debug_mode) printf("\tError sending data to client (%d, %d)\n", - bytesWritten, PR_GetOSError()); - } else { - if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); - } - - PR_Close(newSock); - PR_AtomicDecrement(&workerThreadsBusy); - } -} - -PRFileDesc * -ServerSetup(void) -{ - PRFileDesc *listenSocket; - PRSocketOptionData sockOpt; - PRNetAddr serverAddr; - PRThread *WorkerThread; - - if ( (listenSocket = PR_NewTCPSocket()) == NULL) { - if (debug_mode) printf("\tServer error creating listen socket\n"); - else failed_already=1; - return NULL; - } - - sockOpt.option = PR_SockOpt_Reuseaddr; - sockOpt.value.reuse_addr = PR_TRUE; - if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { - if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", - PR_GetOSError()); - else failed_already=1; - PR_Close(listenSocket); - return NULL; - } - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); - - if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { - if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", - PR_GetOSError()); - else failed_already=1; - PR_Close(listenSocket); - return NULL; - } - - if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { - if (debug_mode) printf("\tServer error listening to server socket\n"); - else failed_already=1; - PR_Close(listenSocket); - - return NULL; - } - - /* Create Clients */ - workerThreads = 0; - workerThreadsBusy = 0; - - workerThreadsLock = PR_NewLock(); - - WorkerThread = PR_CreateThread( - PR_SYSTEM_THREAD, - WorkerThreadFunc, - listenSocket, - PR_PRIORITY_NORMAL, - ServerScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!WorkerThread) { - if (debug_mode) printf("error creating working thread\n"); - PR_Close(listenSocket); - return NULL; - } - PR_AtomicIncrement(&workerThreads); - if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); - - return listenSocket; -} - -/* The main server loop */ -void -ServerThreadFunc(void *unused) -{ - PRFileDesc *listenSocket; - - /* Do setup */ - listenSocket = ServerSetup(); - - if (!listenSocket) { - SetServerState(SERVER, SERVER_STATE_DEAD); - } else { - - if (debug_mode) DPRINTF("\tServer up\n"); - - /* Tell clients they can start now. */ - SetServerState(SERVER, SERVER_STATE_READY); - - /* Now wait for server death signal */ - WaitServerState(SERVER, SERVER_STATE_DYING); - - /* Cleanup */ - SetServerState(SERVER, SERVER_STATE_DEAD); - } -} - -/* --- Client Functions ------------------------------------------- */ - -PRInt32 numRequests; -PRInt32 numClients; -PRMonitor *clientMonitor; - -void -ClientThreadFunc(void *unused) -{ - PRNetAddr serverAddr; - PRFileDesc *clientSocket; - char *sendBuf; - char *recvBuf; - PRInt32 rv; - PRInt32 bytesNeeded; - - sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); - if (!sendBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); - if (!recvBuf) - if (debug_mode) printf("\tClient could not malloc space!?\n"); - - memset(&serverAddr, 0, sizeof(PRNetAddr)); - serverAddr.inet.family = PR_AF_INET; - serverAddr.inet.port = PR_htons(PORT); - serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - - while(numRequests > 0) { - - if ( (numRequests % 10) == 0 ) - if (debug_mode) printf("."); - if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); - - clientSocket = PR_NewTCPSocket(); - if (!clientSocket) { - if (debug_mode) printf("Client error creating socket: OS error %d\n", - PR_GetOSError()); - continue; - } - - if (debug_mode) DPRINTF("\tClient connecting\n"); - - rv = PR_Connect(clientSocket, - &serverAddr, - PR_INTERVAL_NO_TIMEOUT); - if (!clientSocket) { - if (debug_mode) printf("\tClient error connecting\n"); - continue; - } - - if (debug_mode) DPRINTF("\tClient connected\n"); - - rv = PR_Send(clientSocket, - sendBuf, - _client_data, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv != _client_data) { - if (debug_mode) printf("Client error sending data (%d)\n", rv); - PR_Close(clientSocket); - continue; - } - - if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); - - bytesNeeded = _server_data; - while(bytesNeeded) { - rv = PR_Recv(clientSocket, - recvBuf, - bytesNeeded, - 0, - PR_INTERVAL_NO_TIMEOUT); - if (rv <= 0) { - if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", - rv, (_server_data - bytesNeeded), _server_data); - break; - } - if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); - bytesNeeded -= rv; - } - - PR_Close(clientSocket); - - PR_AtomicDecrement(&numRequests); - } - - PR_EnterMonitor(clientMonitor); - --numClients; - PR_Notify(clientMonitor); - PR_ExitMonitor(clientMonitor); - - PR_DELETE(sendBuf); - PR_DELETE(recvBuf); -} - -void -RunClients(void) -{ - PRInt32 index; - - numRequests = _iterations; - numClients = _clients; - clientMonitor = PR_NewMonitor(); - - for (index=0; index<_clients; index++) { - PRThread *clientThread; - - - clientThread = PR_CreateThread( - PR_USER_THREAD, - ClientThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ClientScope, - PR_UNJOINABLE_THREAD, - THREAD_STACKSIZE); - - if (!clientThread) { - if (debug_mode) printf("\terror creating client thread %d\n", index); - } else - if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); - - } - - PR_EnterMonitor(clientMonitor); - while(numClients) - PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); - PR_ExitMonitor(clientMonitor); -} - -/* --- Main Function ---------------------------------------------- */ - -static -void do_work() -{ - PRThread *ServerThread; - PRInt32 state; - - SetServerState(MAIN, SERVER_STATE_STARTUP); - ServerThread = PR_CreateThread( - PR_USER_THREAD, - ServerThreadFunc, - NULL, - PR_PRIORITY_NORMAL, - ServerScope, - PR_JOINABLE_THREAD, - THREAD_STACKSIZE); - if (!ServerThread) { - if (debug_mode) printf("error creating main server thread\n"); - return; - } - - /* Wait for server to be ready */ - state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); - - if (!(state & SERVER_STATE_DEAD)) { - /* Run Test Clients */ - RunClients(); - - /* Send death signal to server */ - SetServerState(MAIN, SERVER_STATE_DYING); - } - - PR_JoinThread(ServerThread); -} - -static void do_workUU(void) -{ - ServerScope = PR_LOCAL_THREAD; - ClientScope = PR_LOCAL_THREAD; - do_work(); -} - - - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - - if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); -} - - -int main(int argc, char **argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ -#ifndef SYMBIAN - if (debug_mode) { - printf("Enter number of iterations: \n"); - scanf("%d", &_iterations); - printf("Enter number of clients : \n"); - scanf("%d", &_clients); - printf("Enter size of client data : \n"); - scanf("%d", &_client_data); - printf("Enter size of server data : \n"); - scanf("%d", &_server_data); - } - else -#endif - { - _iterations = 7; - _clients = 7; - _client_data = 100; - _server_data = 100; - } - - if (debug_mode) { - printf("\n\n%d iterations with %d client threads.\n", - _iterations, _clients); - printf("Sending %d bytes of client data and %d bytes of server data\n", - _client_data, _server_data); - } - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - PR_SetThreadRecycleMode(64); - - ServerStateCVLock = PR_NewLock(); - ServerStateCV = PR_NewCondVar(ServerStateCVLock); - - Measure(do_workUU, "server loop user/user"); - - PR_Cleanup(); - - if(failed_already) - return 1; - else - return 0; - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/short_thread.c nspr-4.10.7/mozilla/nsprpub/pr/tests/short_thread.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/short_thread.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/short_thread.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "nspr.h" -#include "plgetopt.h" - -/* - * Create a thread that exits right away; useful for testing race conditions in thread - * creation - */ - -int _debug_on = 0; -#define DPRINTF(arg) if (_debug_on) printf arg - -static void housecleaning(void *cur_time); - -int main (int argc, char **argv) -{ - static PRIntervalTime thread_start_time; - static PRThread *housekeeping_tid = NULL; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (( housekeeping_tid = - PR_CreateThread (PR_USER_THREAD, housecleaning, (void*)&thread_start_time, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0)) - == NULL ) { - fprintf(stderr, - "simple_test: Error - PR_CreateThread failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - exit( 1 ); - } - PR_Cleanup(); - return(0); -} - -static void -housecleaning (void *cur_time) -{ - DPRINTF(("Child Thread exiting\n")); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sigpipe.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sigpipe.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sigpipe.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sigpipe.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - ************************************************************************* - * - * Test: sigpipe.c - * - * Test the SIGPIPE handler in NSPR. This test applies to Unix only. - * - ************************************************************************* - */ - -#if !defined(XP_UNIX) && !defined(XP_OS2) - -int main(void) -{ - /* This test applies to Unix and OS/2. */ - return 0; -} - -#else /* XP_UNIX && OS/2 */ - -#include "nspr.h" - -#ifdef XP_OS2 -#define INCL_DOSQUEUES -#define INCL_DOSERRORS -#include -#endif - -#include -#include -#include - -static void Test(void *arg) -{ -#ifdef XP_OS2 - HFILE pipefd[2]; -#else - int pipefd[2]; -#endif - int rv; - char c = '\0'; - -#ifdef XP_OS2 - if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) { -#else - if (pipe(pipefd) == -1) { -#endif - fprintf(stderr, "cannot create pipe: %d\n", errno); - exit(1); - } - close(pipefd[0]); - - rv = write(pipefd[1], &c, 1); - if (rv != -1) { - fprintf(stderr, "write to broken pipe should have failed with EPIPE but returned %d\n", rv); - exit(1); - } -#ifdef SYMBIAN - /* Have mercy on the unknown 142 errno, it seems ok */ - if (errno != EPIPE && errno != 142) { -#else - if (errno != EPIPE) { -#endif - fprintf(stderr, "write to broken pipe failed but with wrong errno: %d\n", errno); - exit(1); - } - close(pipefd[1]); - printf("write to broken pipe failed with EPIPE, as expected\n"); -} - -int main(int argc, char **argv) -{ - PRThread *thread; - - /* This initializes NSPR. */ - PR_SetError(0, 0); - - thread = PR_CreateThread(PR_USER_THREAD, Test, NULL, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (thread == NULL) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - if (PR_JoinThread(thread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - Test(NULL); - - printf("PASSED\n"); - return 0; -} - -#endif /* XP_UNIX */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sleep.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sleep.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sleep.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sleep.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" - -#if defined(XP_UNIX) || defined(XP_OS2) - -#include - -#ifndef XP_OS2 -#include -#endif -#include - -#if defined(HAVE_SVID_GETTOD) -#define GTOD(_a) gettimeofday(_a) -#else -#define GTOD(_a) gettimeofday((_a), NULL) -#endif - -static PRIntn rv = 0; - -static void Other(void *unused) -{ - PRIntn didit = 0; - while (PR_SUCCESS == PR_Sleep(PR_MillisecondsToInterval(250))) - { - fprintf(stderr, "."); - didit += 1; - } - if (didit < 5) rv = 1; -} - -int main(int argc, char **argv) -{ - PRUint32 elapsed; - PRThread *thread; - struct timeval timein, timeout; - PRInt32 onePercent = 3000000UL / 100UL; - - fprintf (stderr, "First sleep will sleep 3 seconds.\n"); - fprintf (stderr, " sleep 1 begin\n"); - (void)GTOD(&timein); - sleep (3); - (void)GTOD(&timeout); - fprintf (stderr, " sleep 1 end\n"); - elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec); - elapsed += (timeout.tv_usec - timein.tv_usec); - fprintf(stderr, "elapsed %u usecs\n", elapsed); - if (labs(elapsed - 3000000UL) > onePercent) rv = 1; - - PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 100); - PR_STDIO_INIT(); - - fprintf (stderr, "Second sleep should do the same (does it?).\n"); - fprintf (stderr, " sleep 2 begin\n"); - (void)GTOD(&timein); - sleep (3); - (void)GTOD(&timeout); - fprintf (stderr, " sleep 2 end\n"); - elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec); - elapsed += (timeout.tv_usec - timein.tv_usec); - fprintf(stderr, "elapsed %u usecs\n", elapsed); - if (labs(elapsed - 3000000UL) > onePercent) rv = 1; - - fprintf (stderr, "What happens to other threads?\n"); - fprintf (stderr, "You should see dots every quarter second.\n"); - fprintf (stderr, "If you don't, you're probably running on classic NSPR.\n"); - thread = PR_CreateThread( - PR_USER_THREAD, Other, NULL, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - fprintf (stderr, " sleep 2 begin\n"); - (void)GTOD(&timein); - sleep (3); - (void)GTOD(&timeout); - fprintf (stderr, " sleep 2 end\n"); - PR_Interrupt(thread); - PR_JoinThread(thread); - elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec); - elapsed += (timeout.tv_usec - timein.tv_usec); - fprintf(stderr, "elapsed %u usecs\n", elapsed); - if (labs(elapsed - 3000000UL) > onePercent) rv = 1; - fprintf(stderr, "%s\n", (0 == rv) ? "PASSED" : "FAILED"); - return rv; -} - -#else /* defined(XP_UNIX) */ - -PRIntn main() -{ - return 2; -} - -#endif /* defined(XP_UNIX) */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/socket.c nspr-4.10.7/mozilla/nsprpub/pr/tests/socket.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/socket.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/socket.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2322 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: socket.c -** -** Description: Test socket functionality. -** -** Modification History: -*/ -#include "primpl.h" - -#include "plgetopt.h" - -#include -#include -#include -#ifdef XP_UNIX -#include -#endif -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) -#include -#endif - -#ifdef WIN32 -#include -#endif - -static int _debug_on = 0; -static int test_cancelio = 0; - -#include "obsolete/prsem.h" - -#ifdef XP_PC -#define mode_t int -#endif - -#define DPRINTF(arg) if (_debug_on) printf arg - -#ifdef XP_PC -char *TEST_DIR = "prdir"; -char *SMALL_FILE_NAME = "prsmallf"; -char *LARGE_FILE_NAME = "prlargef"; -#elif defined(SYMBIAN) -char *TEST_DIR = "c:\\data\\prsocket"; -char *SMALL_FILE_NAME = "c:\\data\\prsocket\\small_file"; -char *LARGE_FILE_NAME = "c:\\data\\prsocket\\large_file"; -#else -char *TEST_DIR = "/tmp/prsocket_test_dir"; -char *SMALL_FILE_NAME = "/tmp/prsocket_test_dir/small_file"; -char *LARGE_FILE_NAME = "/tmp/prsocket_test_dir/large_file"; -#endif -#define SMALL_FILE_SIZE (3 * 1024) /* 3 KB */ -#define SMALL_FILE_OFFSET_1 (512) -#define SMALL_FILE_LEN_1 (1 * 1024) /* 1 KB */ -#define SMALL_FILE_OFFSET_2 (75) -#define SMALL_FILE_LEN_2 (758) -#define SMALL_FILE_OFFSET_3 (1024) -#define SMALL_FILE_LEN_3 (SMALL_FILE_SIZE - SMALL_FILE_OFFSET_3) -#define SMALL_FILE_HEADER_SIZE (64) /* 64 bytes */ -#define SMALL_FILE_TRAILER_SIZE (128) /* 128 bytes */ - -#define LARGE_FILE_SIZE (3 * 1024 * 1024) /* 3 MB */ -#define LARGE_FILE_OFFSET_1 (0) -#define LARGE_FILE_LEN_1 (2 * 1024 * 1024) /* 2 MB */ -#define LARGE_FILE_OFFSET_2 (64) -#define LARGE_FILE_LEN_2 (1 * 1024 * 1024 + 75) -#define LARGE_FILE_OFFSET_3 (2 * 1024 * 1024 - 128) -#define LARGE_FILE_LEN_3 (LARGE_FILE_SIZE - LARGE_FILE_OFFSET_3) -#define LARGE_FILE_OFFSET_4 PR_GetPageSize() -#define LARGE_FILE_LEN_4 769 -#define LARGE_FILE_HEADER_SIZE (512) -#define LARGE_FILE_TRAILER_SIZE (64) - -#define BUF_DATA_SIZE (2 * 1024) -#define TCP_MESG_SIZE 1024 -/* - * set UDP datagram size small enough that datagrams sent to a port on the - * local host will not be lost - */ -#define UDP_DGRAM_SIZE 128 -#define NUM_TCP_CLIENTS 5 /* for a listen queue depth of 5 */ -#define NUM_UDP_CLIENTS 10 - -#ifdef SYMBIAN -#define NUM_TRANSMITFILE_CLIENTS 1 -#else -#define NUM_TRANSMITFILE_CLIENTS 4 -#endif - -#define NUM_TCP_CONNECTIONS_PER_CLIENT 5 -#define NUM_TCP_MESGS_PER_CONNECTION 10 -#define NUM_UDP_DATAGRAMS_PER_CLIENT 5 -#define TCP_SERVER_PORT 10000 -#define UDP_SERVER_PORT TCP_SERVER_PORT -#define SERVER_MAX_BIND_COUNT 100 - -#ifdef WINCE -#define perror(s) -#endif - -static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS; -static PRInt32 num_udp_clients = NUM_UDP_CLIENTS; -static PRInt32 num_transmitfile_clients = NUM_TRANSMITFILE_CLIENTS; -static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT; -static PRInt32 tcp_mesg_size = TCP_MESG_SIZE; -static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION; -static PRInt32 num_udp_datagrams_per_client = NUM_UDP_DATAGRAMS_PER_CLIENT; -static PRInt32 udp_datagram_size = UDP_DGRAM_SIZE; - -static PRInt32 thread_count; -PRUint16 server_domain = PR_AF_INET, client_domain = PR_AF_INET; - -/* an I/O layer that uses the emulated senfile method */ -static PRDescIdentity emuSendFileIdentity; -static PRIOMethods emuSendFileMethods; - -int failed_already=0; -typedef struct buffer { - char data[BUF_DATA_SIZE]; -} buffer; - -PRNetAddr tcp_server_addr, udp_server_addr; - -typedef struct Serve_Client_Param { - PRFileDesc *sockfd; /* socket to read from/write to */ - PRInt32 datalen; /* bytes of data transfered in each read/write */ -} Serve_Client_Param; - -typedef struct Server_Param { - PRSemaphore *addr_sem; /* sem to post on, after setting up the address */ - PRMonitor *exit_mon; /* monitor to signal on exit */ - PRInt32 *exit_counter; /* counter to decrement, before exit */ - PRInt32 datalen; /* bytes of data transfered in each read/write */ -} Server_Param; - - -typedef struct Client_Param { - PRNetAddr server_addr; - PRMonitor *exit_mon; /* monitor to signal on exit */ - PRInt32 *exit_counter; /* counter to decrement, before exit */ - PRInt32 datalen; - PRInt32 udp_connect; /* if set clients connect udp sockets */ -} Client_Param; - -/* the sendfile method in emuSendFileMethods */ -static PRInt32 PR_CALLBACK -emu_SendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - return PR_EmulateSendFile(sd, sfd, flags, timeout); -} - -/* the transmitfile method in emuSendFileMethods */ -static PRInt32 PR_CALLBACK -emu_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, const void *headers, - PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - PRSendFileData sfd; - - sfd.fd = fd; - sfd.file_offset = 0; - sfd.file_nbytes = 0; - sfd.header = headers; - sfd.hlen = hlen; - sfd.trailer = NULL; - sfd.tlen = 0; - return emu_SendFile(sd, &sfd, flags, timeout); -} - -/* - * readn - * read data from sockfd into buf - */ -static PRInt32 -readn(PRFileDesc *sockfd, char *buf, int len) -{ - int rem; - int bytes; - int offset = 0; - int err; - PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; - - if (test_cancelio) - timeout = PR_SecondsToInterval(2); - - for (rem=len; rem; offset += bytes, rem -= bytes) { - DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n", - PR_GetCurrentThread(), rem)); -retry: - bytes = PR_Recv(sockfd, buf + offset, rem, 0, - timeout); - DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n", - PR_GetCurrentThread(), bytes)); - if (bytes < 0) { -#ifdef WINNT - printf("PR_Recv: error = %d oserr = %d\n",(err = PR_GetError()), - PR_GetOSError()); - if ((test_cancelio) && (err == PR_IO_TIMEOUT_ERROR)) { - if (PR_NT_CancelIo(sockfd) != PR_SUCCESS) - printf("PR_NT_CancelIO: error = %d\n",PR_GetError()); - timeout = PR_INTERVAL_NO_TIMEOUT; - goto retry; - } -#endif - return -1; - } - } - return len; -} - -/* - * writen - * write data from buf to sockfd - */ -static PRInt32 -writen(PRFileDesc *sockfd, char *buf, int len) -{ - int rem; - int bytes; - int offset = 0; - - for (rem=len; rem; offset += bytes, rem -= bytes) { - DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n", - PR_GetCurrentThread(), rem)); - bytes = PR_Send(sockfd, buf + offset, rem, 0, - PR_INTERVAL_NO_TIMEOUT); - DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n", - PR_GetCurrentThread(), bytes)); - if (bytes <= 0) - return -1; - } - return len; -} - -/* - * Serve_Client - * Thread, started by the server, for serving a client connection. - * Reads data from socket and writes it back, unmodified, and - * closes the socket - */ -static void PR_CALLBACK -Serve_Client(void *arg) -{ - Serve_Client_Param *scp = (Serve_Client_Param *) arg; - PRFileDesc *sockfd; - buffer *in_buf; - PRInt32 bytes, j; - - sockfd = scp->sockfd; - bytes = scp->datalen; - in_buf = PR_NEW(buffer); - if (in_buf == NULL) { - fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); - failed_already=1; - goto exit; - } - - - for (j = 0; j < num_tcp_mesgs_per_connection; j++) { - /* - * Read data from client and send it back to the client unmodified - */ - if (readn(sockfd, in_buf->data, bytes) < bytes) { - fprintf(stderr,"prsocket_test: ERROR - Serve_Client:readn\n"); - failed_already=1; - goto exit; - } - /* Shutdown only RCV will cause error on Symbian OS */ -#if !defined(SYMBIAN) - /* - * shutdown reads, after the last read - */ - if (j == num_tcp_mesgs_per_connection - 1) - if (PR_Shutdown(sockfd, PR_SHUTDOWN_RCV) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); - } -#endif - DPRINTF(("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n",PR_GetCurrentThread(), - (*((int *) in_buf->data)))); - if (writen(sockfd, in_buf->data, bytes) < bytes) { - fprintf(stderr,"prsocket_test: ERROR - Serve_Client:writen\n"); - failed_already=1; - goto exit; - } - } - /* - * shutdown reads and writes - */ - if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); - failed_already=1; - } - -exit: - PR_Close(sockfd); - if (in_buf) { - PR_DELETE(in_buf); - } -} - -PRThread* create_new_thread(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize, PRInt32 index) -{ -PRInt32 native_thread = 0; - - PR_ASSERT(state == PR_UNJOINABLE_THREAD); -#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) - switch(index % 4) { - case 0: - scope = (PR_LOCAL_THREAD); - break; - case 1: - scope = (PR_GLOBAL_THREAD); - break; - case 2: - scope = (PR_GLOBAL_BOUND_THREAD); - break; - case 3: - native_thread = 1; - break; - default: - PR_ASSERT(!"Invalid scope"); - break; - } - if (native_thread) { -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) - pthread_t tid; - if (!pthread_create(&tid, NULL, (void * (*)(void *)) start, arg)) - return((PRThread *) tid); - else - return (NULL); -#else - HANDLE thandle; - unsigned tid; - - thandle = (HANDLE) _beginthreadex( - NULL, - stackSize, - (unsigned (__stdcall *)(void *))start, - arg, - 0, - &tid); - return((PRThread *) thandle); -#endif - } else { - return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); - } -#else - return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); -#endif -} - -/* - * TCP Server - * Server Thread - * Bind an address to a socket and listen for incoming connections - * Start a Serve_Client thread for each incoming connection. - */ -static void PR_CALLBACK -TCP_Server(void *arg) -{ - PRThread *t; - Server_Param *sp = (Server_Param *) arg; - Serve_Client_Param *scp; - PRFileDesc *sockfd, *newsockfd; - PRNetAddr netaddr; - PRInt32 i; - /* - * Create a tcp socket - */ - if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL) { - fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); - goto exit; - } - memset(&netaddr, 0 , sizeof(netaddr)); - - if (PR_SetNetAddr(PR_IpAddrAny, server_domain, TCP_SERVER_PORT, - &netaddr) == PR_FAILURE) { - fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); - goto exit; - } - /* - * try a few times to bind server's address, if addresses are in - * use - */ - i = 0; - - while (PR_Bind(sockfd, &netaddr) < 0) { - if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { - netaddr.inet.port += 2; - if (i++ < SERVER_MAX_BIND_COUNT) - continue; - } - fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); - perror("PR_Bind"); - failed_already=1; - goto exit; - } - - if (PR_Listen(sockfd, 32) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); - failed_already=1; - goto exit; - } - - if (PR_GetSockName(sockfd, &netaddr) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); - failed_already=1; - goto exit; - } - - DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", - netaddr.inet.ip, netaddr.inet.port)); - if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain, - PR_ntohs(PR_NetAddrInetPort(&netaddr)), - &tcp_server_addr) == PR_FAILURE) { - fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); - goto exit; - } - if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET)) - PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK), - &tcp_server_addr.ipv6.ip); - - /* - * Wake up parent thread because server address is bound and made - * available in the global variable 'tcp_server_addr' - */ - PR_PostSem(sp->addr_sem); - - for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) { - /* test both null and non-null 'addr' argument to PR_Accept */ - PRNetAddr *addrp = (i%2 ? &netaddr: NULL); - - DPRINTF(("TCP_Server: Accepting connection\n")); - if ((newsockfd = PR_Accept(sockfd, addrp, - PR_INTERVAL_NO_TIMEOUT)) == NULL) { - fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n"); - goto exit; - } - DPRINTF(("TCP_Server: Accepted connection\n")); - scp = PR_NEW(Serve_Client_Param); - if (scp == NULL) { - fprintf(stderr,"prsocket_test: PR_NEW failed\n"); - goto exit; - } - - /* - * Start a Serve_Client thread for each incoming connection - */ - scp->sockfd = newsockfd; - scp->datalen = sp->datalen; - - t = create_new_thread(PR_USER_THREAD, - Serve_Client, (void *)scp, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0, i); - if (t == NULL) { - fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); - failed_already=1; - goto exit; - } - DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t)); - } - -exit: - if (sockfd) { - PR_Close(sockfd); - } - - /* - * Decrement exit_counter and notify parent thread - */ - - PR_EnterMonitor(sp->exit_mon); - --(*sp->exit_counter); - PR_Notify(sp->exit_mon); - PR_ExitMonitor(sp->exit_mon); - DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread())); -} - -/* - * UDP Server - * Server Thread - * Bind an address to a socket, read data from clients and send data - * back to clients - */ -static void PR_CALLBACK -UDP_Server(void *arg) -{ - Server_Param *sp = (Server_Param *) arg; - PRFileDesc *sockfd; - buffer *in_buf; - PRNetAddr netaddr; - PRInt32 bytes, i, rv = 0; - - - bytes = sp->datalen; - /* - * Create a udp socket - */ - if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) { - fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n"); - failed_already=1; - return; - } - memset(&netaddr, 0 , sizeof(netaddr)); - if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT, - &netaddr) == PR_FAILURE) { - fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); - failed_already=1; - return; - } - /* - * try a few times to bind server's address, if addresses are in - * use - */ - i = 0; - while (PR_Bind(sockfd, &netaddr) < 0) { - if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { - netaddr.inet.port += 2; - if (i++ < SERVER_MAX_BIND_COUNT) - continue; - } - fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); - perror("PR_Bind"); - failed_already=1; - return; - } - - if (PR_GetSockName(sockfd, &netaddr) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); - failed_already=1; - return; - } - - DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", - netaddr.inet.ip, netaddr.inet.port)); - /* - * We can't use the IP address returned by PR_GetSockName in - * netaddr.inet.ip because netaddr.inet.ip is returned - * as 0 (= PR_INADDR_ANY). - */ - - if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain, - PR_ntohs(PR_NetAddrInetPort(&netaddr)), - &udp_server_addr) == PR_FAILURE) { - fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); - failed_already=1; - return; - } - if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET)) - PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK), - &udp_server_addr.ipv6.ip); - - /* - * Wake up parent thread because server address is bound and made - * available in the global variable 'udp_server_addr' - */ - PR_PostSem(sp->addr_sem); - - bytes = sp->datalen; - in_buf = PR_NEW(buffer); - if (in_buf == NULL) { - fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); - failed_already=1; - return; - } - /* - * Receive datagrams from clients and send them back, unmodified, to the - * clients - */ - memset(&netaddr, 0 , sizeof(netaddr)); - for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) { - DPRINTF(("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", - netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data, - in_buf->data[0])); - - rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, - PR_INTERVAL_NO_TIMEOUT); - DPRINTF(("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", - netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, - in_buf->data[0])); - if (rv != bytes) { - return; - } - rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr, - PR_INTERVAL_NO_TIMEOUT); - if (rv != bytes) { - return; - } - } - - PR_DELETE(in_buf); - PR_Close(sockfd); - - /* - * Decrement exit_counter and notify parent thread - */ - PR_EnterMonitor(sp->exit_mon); - --(*sp->exit_counter); - PR_Notify(sp->exit_mon); - PR_ExitMonitor(sp->exit_mon); - DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread())); -} - -/* - * TCP_Client - * Client Thread - * Connect to the server at the address specified in the argument. - * Fill in a buffer, write data to server, read it back and check - * for data corruption. - * Close the socket for server connection - */ -static void PR_CALLBACK -TCP_Client(void *arg) -{ - Client_Param *cp = (Client_Param *) arg; - PRFileDesc *sockfd; - buffer *in_buf, *out_buf; - union PRNetAddr netaddr; - PRInt32 bytes, i, j; - - - bytes = cp->datalen; - out_buf = PR_NEW(buffer); - if (out_buf == NULL) { - fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); - failed_already=1; - return; - } - in_buf = PR_NEW(buffer); - if (in_buf == NULL) { - fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); - failed_already=1; - return; - } - netaddr = cp->server_addr; - - for (i = 0; i < num_tcp_connections_per_client; i++) { - if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL) { - fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n"); - failed_already=1; - return; - } - if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ - fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - return; - } - for (j = 0; j < num_tcp_mesgs_per_connection; j++) { - /* - * fill in random data - */ - memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes); - /* - * write to server - */ -#ifdef WINNT - if (test_cancelio && (j == 0)) - PR_Sleep(PR_SecondsToInterval(12)); -#endif - if (writen(sockfd, out_buf->data, bytes) < bytes) { - fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n"); - failed_already=1; - return; - } - DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", - PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); - if (readn(sockfd, in_buf->data, bytes) < bytes) { - fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n"); - failed_already=1; - return; - } - /* - * verify the data read - */ - if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { - fprintf(stderr,"prsocket_test: ERROR - data corruption\n"); - failed_already=1; - return; - } - } - /* - * shutdown reads and writes - */ - if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); -#if defined(SYMBIAN) - if (EPIPE != errno) -#endif - failed_already=1; - } - PR_Close(sockfd); - } - - PR_DELETE(out_buf); - PR_DELETE(in_buf); - - /* - * Decrement exit_counter and notify parent thread - */ - - PR_EnterMonitor(cp->exit_mon); - --(*cp->exit_counter); - PR_Notify(cp->exit_mon); - PR_ExitMonitor(cp->exit_mon); - DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread())); -} - -/* - * UDP_Client - * Client Thread - * Create a socket and bind an address - * Communicate with the server at the address specified in the argument. - * Fill in a buffer, write data to server, read it back and check - * for data corruption. - * Close the socket - */ -static void PR_CALLBACK -UDP_Client(void *arg) -{ - Client_Param *cp = (Client_Param *) arg; - PRFileDesc *sockfd; - buffer *in_buf, *out_buf; - union PRNetAddr netaddr; - PRInt32 bytes, i, rv; - - - bytes = cp->datalen; - out_buf = PR_NEW(buffer); - if (out_buf == NULL) { - fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); - failed_already=1; - return; - } - in_buf = PR_NEW(buffer); - if (in_buf == NULL) { - fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); - failed_already=1; - return; - } - if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) { - fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n"); - failed_already=1; - return; - } - - /* - * bind an address for the client, let the system chose the port - * number - */ - memset(&netaddr, 0 , sizeof(netaddr)); - if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0, - &netaddr) == PR_FAILURE) { - fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); - failed_already=1; - return; - } - if (PR_Bind(sockfd, &netaddr) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); - perror("PR_Bind"); - return; - } - - if (PR_GetSockName(sockfd, &netaddr) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); - failed_already=1; - return; - } - - DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", - netaddr.inet.ip, netaddr.inet.port)); - - netaddr = cp->server_addr; - - if (cp->udp_connect) { - if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ - fprintf(stderr,"prsocket_test: PR_Connect failed\n"); - failed_already=1; - return; - } - } - - for (i = 0; i < num_udp_datagrams_per_client; i++) { - /* - * fill in random data - */ - DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n", - PR_GetCurrentThread(), out_buf->data, bytes)); - memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes); - /* - * write to server - */ - if (cp->udp_connect) - rv = PR_Send(sockfd, out_buf->data, bytes, 0, - PR_INTERVAL_NO_TIMEOUT); - else - rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr, - PR_INTERVAL_NO_TIMEOUT); - if (rv != bytes) { - return; - } - DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", - PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); - if (cp->udp_connect) - rv = PR_Recv(sockfd, in_buf->data, bytes, 0, - PR_INTERVAL_NO_TIMEOUT); - else - rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, - PR_INTERVAL_NO_TIMEOUT); - if (rv != bytes) { - return; - } - DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n", - PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data)))); - /* - * verify the data read - */ - if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { - fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n"); - failed_already=1; - return; - } - } - PR_Close(sockfd); - - PR_DELETE(in_buf); - PR_DELETE(out_buf); - - /* - * Decrement exit_counter and notify parent thread - */ - - PR_EnterMonitor(cp->exit_mon); - --(*cp->exit_counter); - PR_Notify(cp->exit_mon); - PR_ExitMonitor(cp->exit_mon); - PR_DELETE(cp); - DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread())); -} - -/* - * TCP_Socket_Client_Server_Test - concurrent server test - * - * One server and several clients are started - * Each client connects to the server and sends a chunk of data - * For each connection, server starts another thread to read the data - * from the client and send it back to the client, unmodified. - * Each client checks that data received from server is same as the - * data it sent to the server. - * - */ - -static PRInt32 -TCP_Socket_Client_Server_Test(void) -{ - int i; - PRThread *t; - PRSemaphore *server_sem; - Server_Param *sparamp; - Client_Param *cparamp; - PRMonitor *mon2; - PRInt32 datalen; - - - datalen = tcp_mesg_size; - thread_count = 0; - /* - * start the server thread - */ - sparamp = PR_NEW(Server_Param); - if (sparamp == NULL) { - fprintf(stderr,"prsocket_test: PR_NEW failed\n"); - failed_already=1; - return -1; - } - server_sem = PR_NewSem(0); - if (server_sem == NULL) { - fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); - failed_already=1; - return -1; - } - mon2 = PR_NewMonitor(); - if (mon2 == NULL) { - fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); - failed_already=1; - return -1; - } - PR_EnterMonitor(mon2); - - sparamp->addr_sem = server_sem; - sparamp->exit_mon = mon2; - sparamp->exit_counter = &thread_count; - sparamp->datalen = datalen; - t = PR_CreateThread(PR_USER_THREAD, - TCP_Server, (void *)sparamp, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - if (t == NULL) { - fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); - failed_already=1; - return -1; - } - DPRINTF(("Created TCP server = 0x%lx\n", t)); - thread_count++; - - /* - * wait till the server address is setup - */ - PR_WaitSem(server_sem); - - /* - * Now start a bunch of client threads - */ - - cparamp = PR_NEW(Client_Param); - if (cparamp == NULL) { - fprintf(stderr,"prsocket_test: PR_NEW failed\n"); - failed_already=1; - return -1; - } - cparamp->server_addr = tcp_server_addr; - cparamp->exit_mon = mon2; - cparamp->exit_counter = &thread_count; - cparamp->datalen = datalen; - for (i = 0; i < num_tcp_clients; i++) { - t = create_new_thread(PR_USER_THREAD, - TCP_Client, (void *) cparamp, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0, i); - if (t == NULL) { - fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); - failed_already=1; - return -1; - } - DPRINTF(("Created TCP client = 0x%lx\n", t)); - thread_count++; - } - /* Wait for server and client threads to exit */ - while (thread_count) { - PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); - DPRINTF(("TCP Server - thread_count = %d\n", thread_count)); - } - PR_ExitMonitor(mon2); - printf("%30s","TCP_Socket_Client_Server_Test:"); - printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l, - num_tcp_clients, num_tcp_connections_per_client); - printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":", - num_tcp_mesgs_per_connection, tcp_mesg_size); - - return 0; -} - -/* - * UDP_Socket_Client_Server_Test - iterative server test - * - * One server and several clients are started - * Each client connects to the server and sends a chunk of data - * For each connection, server starts another thread to read the data - * from the client and send it back to the client, unmodified. - * Each client checks that data received from server is same as the - * data it sent to the server. - * - */ - -static PRInt32 -UDP_Socket_Client_Server_Test(void) -{ - int i; - PRThread *t; - PRSemaphore *server_sem; - Server_Param *sparamp; - Client_Param *cparamp; - PRMonitor *mon2; - PRInt32 datalen; - PRInt32 udp_connect = 1; - - - datalen = udp_datagram_size; - thread_count = 0; - /* - * start the server thread - */ - sparamp = PR_NEW(Server_Param); - if (sparamp == NULL) { - fprintf(stderr,"prsocket_test: PR_NEW failed\n"); - failed_already=1; - return -1; - } - server_sem = PR_NewSem(0); - if (server_sem == NULL) { - fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); - failed_already=1; - return -1; - } - mon2 = PR_NewMonitor(); - if (mon2 == NULL) { - fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); - failed_already=1; - return -1; - } - PR_EnterMonitor(mon2); - - sparamp->addr_sem = server_sem; - sparamp->exit_mon = mon2; - sparamp->exit_counter = &thread_count; - sparamp->datalen = datalen; - DPRINTF(("Creating UDP server")); - t = PR_CreateThread(PR_USER_THREAD, - UDP_Server, (void *)sparamp, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - if (t == NULL) { - fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); - failed_already=1; - return -1; - } - thread_count++; - - /* - * wait till the server address is setup - */ - PR_WaitSem(server_sem); - - /* - * Now start a bunch of client threads - */ - - for (i = 0; i < num_udp_clients; i++) { - cparamp = PR_NEW(Client_Param); - if (cparamp == NULL) { - fprintf(stderr,"prsocket_test: PR_NEW failed\n"); - failed_already=1; - return -1; - } - cparamp->server_addr = udp_server_addr; - cparamp->exit_mon = mon2; - cparamp->exit_counter = &thread_count; - cparamp->datalen = datalen; - /* - * Cause every other client thread to connect udp sockets - */ - cparamp->udp_connect = udp_connect; - if (udp_connect) - udp_connect = 0; - else - udp_connect = 1; - DPRINTF(("Creating UDP client %d\n", i)); - t = PR_CreateThread(PR_USER_THREAD, - UDP_Client, (void *) cparamp, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - if (t == NULL) { - fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); - failed_already=1; - return -1; - } - thread_count++; - } - /* Wait for server and client threads to exit */ - while (thread_count) { - PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); - DPRINTF(("UDP Server - thread_count = %d\n", thread_count)); - } - PR_ExitMonitor(mon2); - printf("%30s","UDP_Socket_Client_Server_Test: "); - printf("%2ld Server %2ld Clients\n",1l, num_udp_clients); - printf("%30s %2ld datagrams_per_client %4ld bytes_per_datagram\n",":", - num_udp_datagrams_per_client, udp_datagram_size); - - return 0; -} - -static PRFileDesc *small_file_fd, *large_file_fd; -static void *small_file_addr, *small_file_header, *large_file_addr; -static void *small_file_trailer, *large_file_header, *large_file_trailer; -/* - * TransmitFile_Client - * Client Thread - */ -static void -TransmitFile_Client(void *arg) -{ - PRFileDesc *sockfd; - union PRNetAddr netaddr; - char *small_buf, *large_buf; - Client_Param *cp = (Client_Param *) arg; - PRInt32 rlen; - - small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE + - SMALL_FILE_TRAILER_SIZE); - if (small_buf == NULL) { - fprintf(stderr,"prsocket_test: failed to alloc buffer\n"); - failed_already=1; - return; - } - large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE + LARGE_FILE_HEADER_SIZE + - LARGE_FILE_TRAILER_SIZE); - if (large_buf == NULL) { - fprintf(stderr,"prsocket_test: failed to alloc buffer\n"); - failed_already=1; - return; - } - netaddr.inet.family = cp->server_addr.inet.family; - netaddr.inet.port = cp->server_addr.inet.port; - netaddr.inet.ip = cp->server_addr.inet.ip; - - if ((sockfd = PR_NewTCPSocket()) == NULL) { - fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); - failed_already=1; - return; - } - - if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ - fprintf(stderr,"prsocket_test: PR_Connect failed\n"); - failed_already=1; - return; - } - /* - * read the small file and verify the data - */ - if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE) - != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) { - fprintf(stderr, - "prsocket_test: TransmitFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - /* File transmission test can not be done because of large file's size */ - if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ - fprintf(stderr, - "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n"); - failed_already=1; - return; - } - if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE, - SMALL_FILE_SIZE) != 0) { - fprintf(stderr, - "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n"); - failed_already=1; - return; - } -#endif - /* - * read the large file and verify the data - */ - if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) { - fprintf(stderr, - "prsocket_test: TransmitFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) { - fprintf(stderr, - "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n"); - failed_already=1; - } -#endif - - - /* - * receive data from PR_SendFile - */ - /* - * case 1: small file with header and trailer - */ - rlen = SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE + - SMALL_FILE_TRAILER_SIZE; - if (readn(sockfd, small_buf, rlen) != rlen) { - fprintf(stderr, - "prsocket_test: SendFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ - fprintf(stderr, - "SendFile 1. ERROR - small file header corruption\n"); - failed_already=1; - return; - } - if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE, - SMALL_FILE_SIZE) != 0) { - fprintf(stderr, - "SendFile 1. ERROR - small file data corruption\n"); - failed_already=1; - return; - } - if (memcmp(small_file_trailer, - small_buf + SMALL_FILE_HEADER_SIZE + SMALL_FILE_SIZE, - SMALL_FILE_TRAILER_SIZE) != 0) { - fprintf(stderr, - "SendFile 1. ERROR - small file trailer corruption\n"); - failed_already=1; - return; - } -#endif - /* - * case 2: partial large file at zero offset, file with header and trailer - */ - rlen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE + - LARGE_FILE_TRAILER_SIZE; - if (readn(sockfd, large_buf, rlen) != rlen) { - fprintf(stderr, - "prsocket_test: SendFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ - fprintf(stderr, - "SendFile 2. ERROR - large file header corruption\n"); - failed_already=1; - return; - } - if (memcmp(large_file_addr, large_buf + LARGE_FILE_HEADER_SIZE, - LARGE_FILE_LEN_1) != 0) { - fprintf(stderr, - "SendFile 2. ERROR - large file data corruption\n"); - failed_already=1; - return; - } - if (memcmp(large_file_trailer, - large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_1, - LARGE_FILE_TRAILER_SIZE) != 0) { - fprintf(stderr, - "SendFile 2. ERROR - large file trailer corruption\n"); - failed_already=1; - return; - } -#endif - /* - * case 3: partial small file at non-zero offset, with header - */ - rlen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE; - if (readn(sockfd, small_buf, rlen) != rlen) { - fprintf(stderr, - "prsocket_test: SendFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ - fprintf(stderr, - "SendFile 3. ERROR - small file header corruption\n"); - failed_already=1; - return; - } - if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_1, - small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_1) != 0) { - fprintf(stderr, - "SendFile 3. ERROR - small file data corruption\n"); - failed_already=1; - return; - } -#endif - /* - * case 4: partial small file at non-zero offset, with trailer - */ - rlen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE; - if (readn(sockfd, small_buf, rlen) != rlen) { - fprintf(stderr, - "prsocket_test: SendFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_2, small_buf, - SMALL_FILE_LEN_2) != 0) { - fprintf(stderr, - "SendFile 4. ERROR - small file data corruption\n"); - failed_already=1; - return; - } - if (memcmp(small_file_trailer, small_buf + SMALL_FILE_LEN_2, - SMALL_FILE_TRAILER_SIZE) != 0) { - fprintf(stderr, - "SendFile 4. ERROR - small file trailer corruption\n"); - failed_already=1; - return; - } -#endif - /* - * case 5: partial large file at non-zero offset, file with header - */ - rlen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE; - if (readn(sockfd, large_buf, rlen) != rlen) { - fprintf(stderr, - "prsocket_test: SendFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ - fprintf(stderr, - "SendFile 5. ERROR - large file header corruption\n"); - failed_already=1; - return; - } - if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_2, - large_buf + LARGE_FILE_HEADER_SIZE, - LARGE_FILE_LEN_2) != 0) { - fprintf(stderr, - "SendFile 5. ERROR - large file data corruption\n"); - failed_already=1; - return; - } -#endif - /* - * case 6: partial small file at non-zero offset, with header - */ - rlen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE; - if (readn(sockfd, small_buf, rlen) != rlen) { - fprintf(stderr, - "prsocket_test: SendFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ - fprintf(stderr, - "SendFile 6. ERROR - small file header corruption\n"); - return; - } - if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_3, - small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_3) != 0) { -#if 0 - char *i, *j; - int k; - - i = (char *) small_file_addr + SMALL_FILE_OFFSET_3; - j = small_buf + SMALL_FILE_HEADER_SIZE; - k = SMALL_FILE_LEN_3; - while (k-- > 0) { - if (*i++ != *j++) - printf("i = %d j = %d\n", - (int) (i - ((char *) small_file_addr + SMALL_FILE_OFFSET_3)), - (int) (j - (small_buf + SMALL_FILE_HEADER_SIZE))); - } -#endif - fprintf(stderr, - "SendFile 6. ERROR - small file data corruption\n"); - failed_already=1; - return; - } -#endif - /* - * case 7: partial large file at non-zero offset, with header - */ - rlen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE; - if (readn(sockfd, large_buf, rlen) != rlen) { - fprintf(stderr, - "prsocket_test: SendFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ - fprintf(stderr, - "SendFile 7. ERROR - large file header corruption\n"); - failed_already=1; - return; - } - if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_3, - large_buf + LARGE_FILE_HEADER_SIZE, - LARGE_FILE_LEN_3) != 0) { - fprintf(stderr, - "SendFile 7. ERROR - large file data corruption\n"); - failed_already=1; - return; - } -#endif - /* - * case 8: partial large file at non-zero, page-aligned offset, with - * header and trailer - */ - rlen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE + - LARGE_FILE_TRAILER_SIZE; - if (readn(sockfd, large_buf, rlen) != rlen) { - fprintf(stderr, - "prsocket_test: SendFile_Client failed to receive file\n"); - failed_already=1; - return; - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ - fprintf(stderr, - "SendFile 2. ERROR - large file header corruption\n"); - failed_already=1; - return; - } - if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_4, - large_buf + LARGE_FILE_HEADER_SIZE, - LARGE_FILE_LEN_4) != 0) { - fprintf(stderr, - "SendFile 2. ERROR - large file data corruption\n"); - failed_already=1; - return; - } - if (memcmp(large_file_trailer, - large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_4, - LARGE_FILE_TRAILER_SIZE) != 0) { - fprintf(stderr, - "SendFile 2. ERROR - large file trailer corruption\n"); - failed_already=1; - return; - } -#endif - PR_DELETE(small_buf); - PR_DELETE(large_buf); - PR_Close(sockfd); - - - /* - * Decrement exit_counter and notify parent thread - */ - - PR_EnterMonitor(cp->exit_mon); - --(*cp->exit_counter); - PR_Notify(cp->exit_mon); - PR_ExitMonitor(cp->exit_mon); - DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread())); -} - -/* - * Serve_TransmitFile_Client - * Thread, started by the server, for serving a client connection. - * Trasmits a small file, with a header, and a large file, without - * a header - */ -static void -Serve_TransmitFile_Client(void *arg) -{ - Serve_Client_Param *scp = (Serve_Client_Param *) arg; - PRFileDesc *sockfd; - PRInt32 bytes; - PRFileDesc *local_small_file_fd=NULL; - PRFileDesc *local_large_file_fd=NULL; - PRSendFileData sfd; - PRInt32 slen; - - sockfd = scp->sockfd; - local_small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDONLY,0); - - if (local_small_file_fd == NULL) { - fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n", - SMALL_FILE_NAME); - failed_already=1; - goto done; - } - local_large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDONLY,0); - - if (local_large_file_fd == NULL) { - fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n", - LARGE_FILE_NAME); - failed_already=1; - goto done; - } - bytes = PR_TransmitFile(sockfd, local_small_file_fd, small_file_header, - SMALL_FILE_HEADER_SIZE, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - if (bytes != (SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE)) { - fprintf(stderr, - "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - bytes = PR_TransmitFile(sockfd, local_large_file_fd, NULL, 0, - PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT); - if (bytes != LARGE_FILE_SIZE) { - fprintf(stderr, - "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - - /* - * PR_SendFile test cases - */ - - /* - * case 1: small file with header and trailer - */ - sfd.fd = local_small_file_fd; - sfd.file_offset = 0; - sfd.file_nbytes = 0; - sfd.header = small_file_header; - sfd.hlen = SMALL_FILE_HEADER_SIZE; - sfd.trailer = small_file_trailer; - sfd.tlen = SMALL_FILE_TRAILER_SIZE; - bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - slen = SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE + - SMALL_FILE_TRAILER_SIZE; - if (bytes != slen) { - fprintf(stderr, - "socket: Error - 1. PR_SendFile send_size = %d, bytes sent = %d\n", - slen, bytes); - fprintf(stderr, - "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - - /* - * case 2: partial large file at zero offset, file with header and trailer - */ - sfd.fd = local_large_file_fd; - sfd.file_offset = 0; - sfd.file_nbytes = LARGE_FILE_LEN_1; - sfd.header = large_file_header; - sfd.hlen = LARGE_FILE_HEADER_SIZE; - sfd.trailer = large_file_trailer; - sfd.tlen = LARGE_FILE_TRAILER_SIZE; - bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - slen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE + - LARGE_FILE_TRAILER_SIZE; - if (bytes != slen) { - fprintf(stderr, - "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n", - slen, bytes); - fprintf(stderr, - "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - /* - * case 3: partial small file at non-zero offset, with header - */ - sfd.fd = local_small_file_fd; - sfd.file_offset = SMALL_FILE_OFFSET_1; - sfd.file_nbytes = SMALL_FILE_LEN_1; - sfd.header = small_file_header; - sfd.hlen = SMALL_FILE_HEADER_SIZE; - sfd.trailer = NULL; - sfd.tlen = 0; - bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - slen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE; - if (bytes != slen) { - fprintf(stderr, - "socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n", - slen, bytes); - fprintf(stderr, - "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - /* - * case 4: partial small file at non-zero offset, with trailer - */ - sfd.fd = local_small_file_fd; - sfd.file_offset = SMALL_FILE_OFFSET_2; - sfd.file_nbytes = SMALL_FILE_LEN_2; - sfd.header = NULL; - sfd.hlen = 0; - sfd.trailer = small_file_trailer; - sfd.tlen = SMALL_FILE_TRAILER_SIZE; - bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - slen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE; - if (bytes != slen) { - fprintf(stderr, - "socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n", - slen, bytes); - fprintf(stderr, - "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - /* - * case 5: partial large file at non-zero offset, file with header - */ - sfd.fd = local_large_file_fd; - sfd.file_offset = LARGE_FILE_OFFSET_2; - sfd.file_nbytes = LARGE_FILE_LEN_2; - sfd.header = large_file_header; - sfd.hlen = LARGE_FILE_HEADER_SIZE; - sfd.trailer = NULL; - sfd.tlen = 0; - bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - slen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE; - if (bytes != slen) { - fprintf(stderr, - "socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n", - slen, bytes); - fprintf(stderr, - "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - /* - * case 6: partial small file from non-zero offset till end of file, with header - */ - sfd.fd = local_small_file_fd; - sfd.file_offset = SMALL_FILE_OFFSET_3; - sfd.file_nbytes = 0; /* data from offset to end-of-file */ - sfd.header = small_file_header; - sfd.hlen = SMALL_FILE_HEADER_SIZE; - sfd.trailer = NULL; - sfd.tlen = 0; - bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - slen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE; - if (bytes != slen) { - fprintf(stderr, - "socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n", - slen, bytes); - fprintf(stderr, - "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - /* - * case 7: partial large file at non-zero offset till end-of-file, with header - */ - sfd.fd = local_large_file_fd; - sfd.file_offset = LARGE_FILE_OFFSET_3; - sfd.file_nbytes = 0; /* data until end-of-file */ - sfd.header = large_file_header; - sfd.hlen = LARGE_FILE_HEADER_SIZE; - sfd.trailer = NULL; - sfd.tlen = 0; - bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, - PR_INTERVAL_NO_TIMEOUT); - slen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE; - if (bytes != slen) { - fprintf(stderr, - "socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n", - slen, bytes); - fprintf(stderr, - "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } - /* - * case 8: partial large file at non-zero page-aligned offset, - * with header and trailer - */ - sfd.fd = local_large_file_fd; - sfd.file_offset = LARGE_FILE_OFFSET_4; - sfd.file_nbytes = LARGE_FILE_LEN_4; - sfd.header = large_file_header; - sfd.hlen = LARGE_FILE_HEADER_SIZE; - sfd.trailer = large_file_trailer; - sfd.tlen = LARGE_FILE_TRAILER_SIZE; - bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_CLOSE_SOCKET, - PR_INTERVAL_NO_TIMEOUT); - slen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE + - LARGE_FILE_TRAILER_SIZE; - if (bytes != slen) { - fprintf(stderr, - "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n", - slen, bytes); - fprintf(stderr, - "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - } -done: - if (local_small_file_fd != NULL) - PR_Close(local_small_file_fd); - if (local_large_file_fd != NULL) - PR_Close(local_large_file_fd); -} - -/* - * TransmitFile Server - * Server Thread - * Bind an address to a socket and listen for incoming connections - * Create worker threads to service clients - */ -static void -TransmitFile_Server(void *arg) -{ - PRThread **t = NULL; /* an array of PRThread pointers */ - Server_Param *sp = (Server_Param *) arg; - Serve_Client_Param *scp; - PRFileDesc *sockfd = NULL, *newsockfd; - PRNetAddr netaddr; - PRInt32 i; - - t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *)); - if (t == NULL) { - fprintf(stderr, "prsocket_test: run out of memory\n"); - failed_already=1; - goto exit; - } - /* - * Create a tcp socket - */ - if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) { - fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n"); - failed_already=1; - goto exit; - } - memset(&netaddr, 0 , sizeof(netaddr)); - netaddr.inet.family = PR_AF_INET; - netaddr.inet.port = PR_htons(TCP_SERVER_PORT); - netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); - /* - * try a few times to bind server's address, if addresses are in - * use - */ - i = 0; - while (PR_Bind(sockfd, &netaddr) < 0) { - if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { - netaddr.inet.port += 2; - if (i++ < SERVER_MAX_BIND_COUNT) - continue; - } - fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); - failed_already=1; - perror("PR_Bind"); - goto exit; - } - - if (PR_Listen(sockfd, 32) < 0) { - fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); - failed_already=1; - goto exit; - } - - if (PR_GetSockName(sockfd, &netaddr) < 0) { - fprintf(stderr, - "prsocket_test: ERROR - PR_GetSockName failed\n"); - failed_already=1; - goto exit; - } - - DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", - netaddr.inet.ip, netaddr.inet.port)); - tcp_server_addr.inet.family = netaddr.inet.family; - tcp_server_addr.inet.port = netaddr.inet.port; - tcp_server_addr.inet.ip = netaddr.inet.ip; - - /* - * Wake up parent thread because server address is bound and made - * available in the global variable 'tcp_server_addr' - */ - PR_PostSem(sp->addr_sem); - - for (i = 0; i < num_transmitfile_clients ; i++) { - /* test both null and non-null 'addr' argument to PR_Accept */ - PRNetAddr *addrp = (i%2 ? &netaddr: NULL); - - if ((newsockfd = PR_Accept(sockfd, addrp, - PR_INTERVAL_NO_TIMEOUT)) == NULL) { - fprintf(stderr, - "prsocket_test: ERROR - PR_Accept failed\n"); - failed_already=1; - goto exit; - } - /* test both regular and emulated PR_SendFile */ - if (i%2) { - PRFileDesc *layer = PR_CreateIOLayerStub( - emuSendFileIdentity, &emuSendFileMethods); - if (layer == NULL) { - fprintf(stderr, - "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n"); - failed_already=1; - goto exit; - } - if (PR_PushIOLayer(newsockfd, PR_TOP_IO_LAYER, layer) - == PR_FAILURE) { - fprintf(stderr, - "prsocket_test: ERROR - PR_PushIOLayer failed\n"); - failed_already=1; - goto exit; - } - } - scp = PR_NEW(Serve_Client_Param); - if (scp == NULL) { - fprintf(stderr,"prsocket_test: PR_NEW failed\n"); - failed_already=1; - goto exit; - } - - /* - * Start a Serve_Client thread for each incoming connection - */ - scp->sockfd = newsockfd; - scp->datalen = sp->datalen; - - t[i] = PR_CreateThread(PR_USER_THREAD, - Serve_TransmitFile_Client, (void *)scp, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0); - if (t[i] == NULL) { - fprintf(stderr, - "prsocket_test: PR_CreateThread failed\n"); - failed_already=1; - goto exit; - } - DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t)); - } - - /* - * Wait for all the worker threads to end, so that we know - * they are no longer using the small and large file fd's. - */ - - for (i = 0; i < num_transmitfile_clients; i++) { - PR_JoinThread(t[i]); - } - -exit: - if (t) { - PR_DELETE(t); - } - if (sockfd) { - PR_Close(sockfd); - } - - /* - * Decrement exit_counter and notify parent thread - */ - - PR_EnterMonitor(sp->exit_mon); - --(*sp->exit_counter); - PR_Notify(sp->exit_mon); - PR_ExitMonitor(sp->exit_mon); - DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread())); -} - -/* - * Socket_Misc_Test - test miscellaneous functions - * - */ -static PRInt32 -Socket_Misc_Test(void) -{ - PRIntn i, rv = 0, bytes, count, len; - PRThread *t; - PRSemaphore *server_sem; - Server_Param *sparamp; - Client_Param *cparamp; - PRMonitor *mon2; - PRInt32 datalen; - - /* - * We deliberately pick a buffer size that is not a nice multiple - * of 1024. - */ -#define TRANSMITFILE_BUF_SIZE (4 * 1024 - 11) - - typedef struct { - char data[TRANSMITFILE_BUF_SIZE]; - } file_buf; - file_buf *buf = NULL; - - /* - * create file(s) to be transmitted - */ - if ((PR_MkDir(TEST_DIR, 0777)) < 0) { - printf("prsocket_test failed to create dir %s\n",TEST_DIR); - failed_already=1; - return -1; - } - - small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777); - - if (small_file_fd == NULL) { - fprintf(stderr,"prsocket_test failed to create/open file %s\n", - SMALL_FILE_NAME); - failed_already=1; - rv = -1; - goto done; - } - buf = PR_NEW(file_buf); - if (buf == NULL) { - fprintf(stderr,"prsocket_test failed to allocate buffer\n"); - failed_already=1; - rv = -1; - goto done; - } - /* - * fill in random data - */ - for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) { - buf->data[i] = i; - } - count = 0; - do { - len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ? - TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count); - bytes = PR_Write(small_file_fd, buf->data, len); - if (bytes <= 0) { - fprintf(stderr, - "prsocket_test failed to write to file %s\n", - SMALL_FILE_NAME); - failed_already=1; - rv = -1; - goto done; - } - count += bytes; - } while (count < SMALL_FILE_SIZE); -#ifdef XP_UNIX - /* - * map the small file; used in checking for data corruption - */ - small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ, - MAP_SHARED, small_file_fd->secret->md.osfd, 0); - if (small_file_addr == (void *) -1) { - fprintf(stderr,"prsocket_test failed to mmap file %s\n", - SMALL_FILE_NAME); - failed_already=1; - rv = -1; - goto done; - } -#endif - /* - * header for small file - */ - small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE); - if (small_file_header == NULL) { - fprintf(stderr,"prsocket_test failed to malloc header file\n"); - failed_already=1; - rv = -1; - goto done; - } - memset(small_file_header, (int) PR_IntervalNow(), - SMALL_FILE_HEADER_SIZE); - /* - * trailer for small file - */ - small_file_trailer = PR_MALLOC(SMALL_FILE_TRAILER_SIZE); - if (small_file_trailer == NULL) { - fprintf(stderr,"prsocket_test failed to malloc header trailer\n"); - failed_already=1; - rv = -1; - goto done; - } - memset(small_file_trailer, (int) PR_IntervalNow(), - SMALL_FILE_TRAILER_SIZE); - /* - * setup large file - */ - large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777); - - if (large_file_fd == NULL) { - fprintf(stderr,"prsocket_test failed to create/open file %s\n", - LARGE_FILE_NAME); - failed_already=1; - rv = -1; - goto done; - } - /* - * fill in random data - */ - for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) { - buf->data[i] = i; - } - count = 0; - do { - len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ? - TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count); - bytes = PR_Write(large_file_fd, buf->data, len); - if (bytes <= 0) { - fprintf(stderr, - "prsocket_test failed to write to file %s: (%ld, %ld)\n", - LARGE_FILE_NAME, - PR_GetError(), PR_GetOSError()); - failed_already=1; - rv = -1; - goto done; - } - count += bytes; - } while (count < LARGE_FILE_SIZE); -#if defined(XP_UNIX) && !defined(SYMBIAN) - /* - * map the large file; used in checking for data corruption - */ - large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ, - MAP_SHARED, large_file_fd->secret->md.osfd, 0); - if (large_file_addr == (void *) -1) { - fprintf(stderr,"prsocket_test failed to mmap file %s\n", - LARGE_FILE_NAME); - failed_already=1; - rv = -1; - goto done; - } -#endif - /* - * header for large file - */ - large_file_header = PR_MALLOC(LARGE_FILE_HEADER_SIZE); - if (large_file_header == NULL) { - fprintf(stderr,"prsocket_test failed to malloc header file\n"); - failed_already=1; - rv = -1; - goto done; - } - memset(large_file_header, (int) PR_IntervalNow(), - LARGE_FILE_HEADER_SIZE); - /* - * trailer for large file - */ - large_file_trailer = PR_MALLOC(LARGE_FILE_TRAILER_SIZE); - if (large_file_trailer == NULL) { - fprintf(stderr,"prsocket_test failed to malloc header trailer\n"); - failed_already=1; - rv = -1; - goto done; - } - memset(large_file_trailer, (int) PR_IntervalNow(), - LARGE_FILE_TRAILER_SIZE); - - datalen = tcp_mesg_size; - thread_count = 0; - /* - * start the server thread - */ - sparamp = PR_NEW(Server_Param); - if (sparamp == NULL) { - fprintf(stderr,"prsocket_test: PR_NEW failed\n"); - failed_already=1; - rv = -1; - goto done; - } - server_sem = PR_NewSem(0); - if (server_sem == NULL) { - fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); - failed_already=1; - rv = -1; - goto done; - } - mon2 = PR_NewMonitor(); - if (mon2 == NULL) { - fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); - failed_already=1; - rv = -1; - goto done; - } - PR_EnterMonitor(mon2); - - sparamp->addr_sem = server_sem; - sparamp->exit_mon = mon2; - sparamp->exit_counter = &thread_count; - sparamp->datalen = datalen; - t = PR_CreateThread(PR_USER_THREAD, - TransmitFile_Server, (void *)sparamp, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - if (t == NULL) { - fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); - failed_already=1; - rv = -1; - goto done; - } - DPRINTF(("Created TCP server = 0x%x\n", t)); - thread_count++; - - /* - * wait till the server address is setup - */ - PR_WaitSem(server_sem); - - /* - * Now start a bunch of client threads - */ - - cparamp = PR_NEW(Client_Param); - if (cparamp == NULL) { - fprintf(stderr,"prsocket_test: PR_NEW failed\n"); - failed_already=1; - rv = -1; - goto done; - } - cparamp->server_addr = tcp_server_addr; - cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - cparamp->exit_mon = mon2; - cparamp->exit_counter = &thread_count; - cparamp->datalen = datalen; - for (i = 0; i < num_transmitfile_clients; i++) { - t = create_new_thread(PR_USER_THREAD, - TransmitFile_Client, (void *) cparamp, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0, i); - if (t == NULL) { - fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); - rv = -1; - failed_already=1; - goto done; - } - DPRINTF(("Created TransmitFile client = 0x%lx\n", t)); - thread_count++; - } - /* Wait for server and client threads to exit */ - while (thread_count) { - PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); - DPRINTF(("Socket_Misc_Test - thread_count = %d\n", thread_count)); - } - PR_ExitMonitor(mon2); -done: - if (buf) { - PR_DELETE(buf); - } -#if defined(XP_UNIX) && !defined(SYMBIAN) - munmap((char*)small_file_addr, SMALL_FILE_SIZE); - munmap((char*)large_file_addr, LARGE_FILE_SIZE); -#endif - PR_Close(small_file_fd); - PR_Close(large_file_fd); - if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) { - fprintf(stderr,"prsocket_test: failed to unlink file %s\n", - SMALL_FILE_NAME); - failed_already=1; - } - if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) { - fprintf(stderr,"prsocket_test: failed to unlink file %s\n", - LARGE_FILE_NAME); - failed_already=1; - } - if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) { - fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - failed_already=1; - } - - printf("%-29s%s","Socket_Misc_Test",":"); - printf("%2d Server %2d Clients\n",1, num_transmitfile_clients); - printf("%30s Sizes of Transmitted Files - %4d KB, %2d MB \n",":", - SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024)); - - - return rv; -} -/************************************************************************/ - -/* - * Test Socket NSPR APIs - */ - -int main(int argc, char **argv) -{ - /* - * -d debug mode - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - PR_SetConcurrency(4); - - emuSendFileIdentity = PR_GetUniqueIdentity("Emulated SendFile"); - emuSendFileMethods = *PR_GetDefaultIOMethods(); - emuSendFileMethods.transmitfile = emu_TransmitFile; - emuSendFileMethods.sendfile = emu_SendFile; - - /* - * run client-server test with TCP, Ipv4-Ipv4 - */ - printf("TCP Client/Server Test - IPv4/Ipv4\n"); - if (TCP_Socket_Client_Server_Test() < 0) { - printf("TCP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("TCP_Socket_Client_Server_Test Passed\n"); - /* - * client-server test, Ipv6-Ipv4 - */ - client_domain = PR_AF_INET6; - printf("TCP Client/Server Test - IPv6/Ipv4\n"); - if (TCP_Socket_Client_Server_Test() < 0) { - printf("TCP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("TCP_Socket_Client_Server_Test Passed\n"); - /* - * client-server test, Ipv4-Ipv6 - */ - client_domain = PR_AF_INET; - server_domain = PR_AF_INET6; - printf("TCP Client/Server Test - IPv4/Ipv6\n"); - if (TCP_Socket_Client_Server_Test() < 0) { - printf("TCP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("TCP_Socket_Client_Server_Test Passed\n"); - /* - * client-server test, Ipv6-Ipv6 - */ - client_domain = PR_AF_INET6; - server_domain = PR_AF_INET6; - printf("TCP Client/Server Test - IPv6/Ipv6\n"); - if (TCP_Socket_Client_Server_Test() < 0) { - printf("TCP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("TCP_Socket_Client_Server_Test Passed\n"); - test_cancelio = 0; - -#if defined(SYMBIAN) && !defined(__WINSCW__) - /* UDP tests only run on Symbian devices but not emulator */ - /* - * run client-server test with UDP, IPv4/IPv4 - */ - printf("UDP Client/Server Test - IPv4/Ipv4\n"); - client_domain = PR_AF_INET; - server_domain = PR_AF_INET; - if (UDP_Socket_Client_Server_Test() < 0) { - printf("UDP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("UDP_Socket_Client_Server_Test Passed\n"); - /* - * run client-server test with UDP, IPv6/IPv4 - */ - printf("UDP Client/Server Test - IPv6/Ipv4\n"); - client_domain = PR_AF_INET6; - server_domain = PR_AF_INET; - if (UDP_Socket_Client_Server_Test() < 0) { - printf("UDP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("UDP_Socket_Client_Server_Test Passed\n"); - /* - * run client-server test with UDP,IPv4-IPv6 - */ - printf("UDP Client/Server Test - IPv4/Ipv6\n"); - client_domain = PR_AF_INET; - server_domain = PR_AF_INET6; - if (UDP_Socket_Client_Server_Test() < 0) { - printf("UDP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("UDP_Socket_Client_Server_Test Passed\n"); - /* - * run client-server test with UDP,IPv6-IPv6 - */ - printf("UDP Client/Server Test - IPv6/Ipv6\n"); - client_domain = PR_AF_INET6; - server_domain = PR_AF_INET6; - if (UDP_Socket_Client_Server_Test() < 0) { - printf("UDP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("UDP_Socket_Client_Server_Test Passed\n"); -#endif - - /* - * Misc socket tests - including transmitfile, etc. - */ - - /* File transmission test can not be done in Symbian OS because of - * large file's size and the incomplete mmap() implementation. */ -#if !defined(WIN16) && !defined(SYMBIAN) - /* -** The 'transmit file' test does not run because -** transmit file is not implemented in NSPR yet. -** -*/ - if (Socket_Misc_Test() < 0) { - printf("Socket_Misc_Test failed\n"); - failed_already=1; - goto done; - } else - printf("Socket_Misc_Test passed\n"); - - /* - * run client-server test with TCP again to test - * recycling used sockets from PR_TransmitFile(). - */ - if (TCP_Socket_Client_Server_Test() < 0) { - printf("TCP_Socket_Client_Server_Test failed\n"); - goto done; - } else - printf("TCP_Socket_Client_Server_Test Passed\n"); -#endif - -done: - PR_Cleanup(); - if (failed_already) return 1; - else return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sockopt.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sockopt.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sockopt.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sockopt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "prio.h" -#include "prinit.h" -#include "prprf.h" -#include "obsolete/probslet.h" - -#include "plerror.h" - -static PRFileDesc *err = NULL; -static PRBool failed = PR_FALSE; - -static void Failed(const char *msg1, const char *msg2) -{ - if (NULL != msg1) PR_fprintf(err, "%s ", msg1); - PL_FPrintError(err, msg2); - failed = PR_TRUE; -} /* Failed */ - -static PRSockOption Incr(PRSockOption *option) -{ - PRIntn val = ((PRIntn)*option) + 1; - *option = (PRSockOption)val; - return (PRSockOption)val; -} /* Incr */ - -int main(int argc, char **argv) -{ - PRStatus rv; - PRFileDesc *udp = PR_NewUDPSocket(); - PRFileDesc *tcp = PR_NewTCPSocket(); - const char *tag[] = - { - "PR_SockOpt_Nonblocking", /* nonblocking io */ - "PR_SockOpt_Linger", /* linger on close if data present */ - "PR_SockOpt_Reuseaddr", /* allow local address reuse */ - "PR_SockOpt_Keepalive", /* keep connections alive */ - "PR_SockOpt_RecvBufferSize", /* send buffer size */ - "PR_SockOpt_SendBufferSize", /* receive buffer size */ - - "PR_SockOpt_IpTimeToLive", /* time to live */ - "PR_SockOpt_IpTypeOfService", /* type of service and precedence */ - - "PR_SockOpt_AddMember", /* add an IP group membership */ - "PR_SockOpt_DropMember", /* drop an IP group membership */ - "PR_SockOpt_McastInterface", /* multicast interface address */ - "PR_SockOpt_McastTimeToLive", /* multicast timetolive */ - "PR_SockOpt_McastLoopback", /* multicast loopback */ - - "PR_SockOpt_NoDelay", /* don't delay send to coalesce packets */ - "PR_SockOpt_MaxSegment", /* maximum segment size */ - "PR_SockOpt_Broadcast", /* Enable broadcast */ - "PR_SockOpt_Last" - }; - - err = PR_GetSpecialFD(PR_StandardError); - PR_STDIO_INIT(); - - if (NULL == udp) Failed("PR_NewUDPSocket()", NULL); - else if (NULL == tcp) Failed("PR_NewTCPSocket()", NULL); - else - { - PRSockOption option; - PRUint32 segment = 1024; - PRNetAddr addr; - - rv = PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr); - if (PR_FAILURE == rv) Failed("PR_InitializeNetAddr()", NULL); - rv = PR_Bind(udp, &addr); - if (PR_FAILURE == rv) Failed("PR_Bind()", NULL); - for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option)) - { - PRSocketOptionData data; - PRFileDesc *fd = tcp; - data.option = option; - switch (option) - { - case PR_SockOpt_Nonblocking: - data.value.non_blocking = PR_TRUE; - break; -#ifndef SYMBIAN - case PR_SockOpt_Linger: - data.value.linger.polarity = PR_TRUE; - data.value.linger.linger = PR_SecondsToInterval(2); - break; -#endif - case PR_SockOpt_Reuseaddr: - data.value.reuse_addr = PR_TRUE; - break; - case PR_SockOpt_Keepalive: - data.value.keep_alive = PR_TRUE; - break; - case PR_SockOpt_RecvBufferSize: - data.value.recv_buffer_size = segment; - break; - case PR_SockOpt_SendBufferSize: - data.value.send_buffer_size = segment; - break; -#ifndef SYMBIAN - case PR_SockOpt_IpTimeToLive: - data.value.ip_ttl = 64; - break; - case PR_SockOpt_IpTypeOfService: - data.value.tos = 0; - break; - case PR_SockOpt_McastTimeToLive: - fd = udp; - data.value.mcast_ttl = 4; - break; - case PR_SockOpt_McastLoopback: - fd = udp; - data.value.mcast_loopback = PR_TRUE; - break; -#endif - case PR_SockOpt_NoDelay: - data.value.no_delay = PR_TRUE; - break; -#ifndef WIN32 - case PR_SockOpt_MaxSegment: - data.value.max_segment = segment; - break; -#endif -#ifndef SYMBIAN - case PR_SockOpt_Broadcast: - fd = udp; - data.value.broadcast = PR_TRUE; - break; -#endif - default: continue; - } - - /* - * TCP_MAXSEG can only be read, not set - */ - if (option != PR_SockOpt_MaxSegment) { -#ifdef WIN32 - if (option != PR_SockOpt_McastLoopback) -#endif - { - rv = PR_SetSocketOption(fd, &data); - if (PR_FAILURE == rv) - Failed("PR_SetSocketOption()", tag[option]); - } - } - - rv = PR_GetSocketOption(fd, &data); - if (PR_FAILURE == rv) Failed("PR_GetSocketOption()", tag[option]); - } - PR_Close(udp); - PR_Close(tcp); - } - PR_fprintf(err, "%s\n", (failed) ? "FAILED" : "PASSED"); - return (failed) ? 1 : 0; -} /* main */ - -/* sockopt.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sockping.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sockping.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sockping.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sockping.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: sockping.c - * - * Description: - * This test runs in conjunction with the sockpong test. - * This test creates a socket pair and passes one socket - * to the sockpong test. Then this test writes "ping" to - * to the sockpong test and the sockpong test writes "pong" - * back. To run this pair of tests, just invoke sockping. - * - * Tested areas: process creation, socket pairs, file - * descriptor inheritance. - */ - -#include "prerror.h" -#include "prio.h" -#include "prproces.h" - -#include -#include -#include - -#define NUM_ITERATIONS 10 - -static char *child_argv[] = { "sockpong", NULL }; - -int main(int argc, char **argv) -{ - PRFileDesc *sock[2]; - PRStatus status; - PRProcess *process; - PRProcessAttr *attr; - char buf[1024]; - PRInt32 nBytes; - PRInt32 exitCode; - int idx; - - status = PR_NewTCPSocketPair(sock); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_NewTCPSocketPair failed\n"); - exit(1); - } - - status = PR_SetFDInheritable(sock[0], PR_FALSE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - status = PR_SetFDInheritable(sock[1], PR_TRUE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - - attr = PR_NewProcessAttr(); - if (attr == NULL) { - fprintf(stderr, "PR_NewProcessAttr failed\n"); - exit(1); - } - - status = PR_ProcessAttrSetInheritableFD(attr, sock[1], "SOCKET"); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); - exit(1); - } - - process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr); - if (process == NULL) { - fprintf(stderr, "PR_CreateProcess failed\n"); - exit(1); - } - PR_DestroyProcessAttr(attr); - status = PR_Close(sock[1]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - - for (idx = 0; idx < NUM_ITERATIONS; idx++) { - strcpy(buf, "ping"); - printf("ping process: sending \"%s\"\n", buf); - nBytes = PR_Write(sock[0], buf, 5); - if (nBytes == -1) { - fprintf(stderr, "PR_Write failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - memset(buf, 0, sizeof(buf)); - nBytes = PR_Read(sock[0], buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - printf("ping process: received \"%s\"\n", buf); - if (nBytes != 5) { - fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n", - nBytes); - exit(1); - } - if (strcmp(buf, "pong") != 0) { - fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", - buf); - exit(1); - } - } - - status = PR_Close(sock[0]); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - status = PR_WaitProcess(process, &exitCode); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_WaitProcess failed\n"); - exit(1); - } - if (exitCode == 0) { - printf("PASS\n"); - return 0; - } else { - printf("FAIL\n"); - return 1; - } -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sockpong.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sockpong.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sockpong.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sockpong.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: sockpong.c - * - * Description: - * This test runs in conjunction with the sockping test. - * The sockping test creates a socket pair and passes one - * socket to this test. Then the sockping test writes - * "ping" to this test and this test writes "pong" back. - * To run this pair of tests, just invoke sockping. - * - * Tested areas: process creation, socket pairs, file - * descriptor inheritance. - */ - -#include "prerror.h" -#include "prio.h" - -#include -#include -#include - -#define NUM_ITERATIONS 10 - -int main(int argc, char **argv) -{ - PRFileDesc *sock; - PRStatus status; - char buf[1024]; - PRInt32 nBytes; - int idx; - - sock = PR_GetInheritedFD("SOCKET"); - if (sock == NULL) { - fprintf(stderr, "PR_GetInheritedFD failed\n"); - exit(1); - } - status = PR_SetFDInheritable(sock, PR_FALSE); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_SetFDInheritable failed\n"); - exit(1); - } - - for (idx = 0; idx < NUM_ITERATIONS; idx++) { - memset(buf, 0, sizeof(buf)); - nBytes = PR_Read(sock, buf, sizeof(buf)); - if (nBytes == -1) { - fprintf(stderr, "PR_Read failed: (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - exit(1); - } - printf("pong process: received \"%s\"\n", buf); - if (nBytes != 5) { - fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n", - nBytes); - exit(1); - } - if (strcmp(buf, "ping") != 0) { - fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n", - buf); - exit(1); - } - - strcpy(buf, "pong"); - printf("pong process: sending \"%s\"\n", buf); - nBytes = PR_Write(sock, buf, 5); - if (nBytes == -1) { - fprintf(stderr, "PR_Write failed\n"); - exit(1); - } - } - - status = PR_Close(sock); - if (status == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sprintf.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sprintf.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sprintf.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sprintf.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,431 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: sprintf.c - * Description: - * This is a test program for the PR_snprintf() functions defined - * in prprf.c. This test program is based on ns/nspr/tests/sprintf.c, - * revision 1.10. - * Modification History: - * 20-May-1997 AGarcia replaced printf statment to return PASS\n. This is to be used by the - * regress tool parsing routine. - ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to - * recognize the return code from tha main program. - */ - -#include "prinit.h" -#include "prprf.h" -#include "prlog.h" -#include "prlong.h" -#include -#include -#include - -static char sbuf[20000]; - - -/* -** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf. -** Make sure the results are identical -*/ -static void test_i(char *pattern, int i) -{ - char *s; - char buf[200]; - int n; - - /* try all three routines */ - s = PR_smprintf(pattern, i); - PR_ASSERT(s != 0); - n = PR_snprintf(buf, sizeof(buf), pattern, i); - PR_ASSERT(n <= sizeof(buf)); - sprintf(sbuf, pattern, i); - - /* compare results */ - if ((strncmp(s, buf, sizeof(buf)) != 0) || - (strncmp(s, sbuf, sizeof(sbuf)) != 0)) { - fprintf(stderr, - "pattern='%s' i=%d\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", - pattern, i, s, buf, sbuf); - PR_smprintf_free(s); - exit(-1); - } - PR_smprintf_free(s); -} - -static void TestI(void) -{ - static int nums[] = { - 0, 1, -1, 10, -10, - 32767, -32768, - }; - static char *signs[] = { - "", - "0", "-", "+", " ", - "0-", "0+", "0 ", "-0", "-+", "- ", - "+0", "+-", "+ ", " 0", " -", " +", - "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +", - "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +", - "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -", - " 0-", " 0+", " -0", " -+", " +0", " +-", - "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-", - "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0", - "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0", - " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0", - }; - static char *precs[] = { - "", "3", "5", "43", - "7.3", "7.5", "7.11", "7.43", - }; - static char *formats[] = { - "d", "o", "x", "u", - "hd", "ho", "hx", "hu" - }; - int f, s, n, p; - char fmt[20]; - - for (f = 0; f < PR_ARRAY_SIZE(formats); f++) { - for (s = 0; s < PR_ARRAY_SIZE(signs); s++) { - for (p = 0; p < PR_ARRAY_SIZE(precs); p++) { - fmt[0] = '%'; - fmt[1] = 0; - if (signs[s]) strcat(fmt, signs[s]); - if (precs[p]) strcat(fmt, precs[p]); - if (formats[f]) strcat(fmt, formats[f]); - for (n = 0; n < PR_ARRAY_SIZE(nums); n++) { - test_i(fmt, nums[n]); - } - } - } - } -} - -/************************************************************************/ - -/* -** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf. -** Make sure the results are identical -*/ -static void test_l(char *pattern, char *spattern, PRInt32 l) -{ - char *s; - char buf[200]; - int n; - - /* try all three routines */ - s = PR_smprintf(pattern, l); - PR_ASSERT(s != 0); - n = PR_snprintf(buf, sizeof(buf), pattern, l); - PR_ASSERT(n <= sizeof(buf)); - sprintf(sbuf, spattern, l); - - /* compare results */ - if ((strncmp(s, buf, sizeof(buf)) != 0) || - (strncmp(s, sbuf, sizeof(sbuf)) != 0)) { - fprintf(stderr, - "pattern='%s' l=%ld\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", - pattern, l, s, buf, sbuf); - PR_smprintf_free(s); - exit(-1); - } - PR_smprintf_free(s); -} - -static void TestL(void) -{ - static PRInt32 nums[] = { - 0, - 1, - -1, - 10, - -10, - 32767, - -32768, - PR_INT32(0x7fffffff), /* 2147483647L */ - -1 - PR_INT32(0x7fffffff) /* -2147483648L */ - }; - static char *signs[] = { - "", - "0", "-", "+", " ", - "0-", "0+", "0 ", "-0", "-+", "- ", - "+0", "+-", "+ ", " 0", " -", " +", - "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +", - "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +", - "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -", - " 0-", " 0+", " -0", " -+", " +0", " +-", - "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-", - "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0", - "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0", - " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0", - }; - static char *precs[] = { - "", "3", "5", "43", - ".3", ".43", - "7.3", "7.5", "7.11", "7.43", - }; - static char *formats[] = { "ld", "lo", "lx", "lu" }; - -#if PR_BYTES_PER_INT == 4 - static char *sformats[] = { "d", "o", "x", "u" }; -#elif PR_BYTES_PER_LONG == 4 - static char *sformats[] = { "ld", "lo", "lx", "lu" }; -#else -#error Neither int nor long is 4 bytes on this platform -#endif - - int f, s, n, p; - char fmt[40], sfmt[40]; - - for (f = 0; f < PR_ARRAY_SIZE(formats); f++) { - for (s = 0; s < PR_ARRAY_SIZE(signs); s++) { - for (p = 0; p < PR_ARRAY_SIZE(precs); p++) { - fmt[0] = '%'; - fmt[1] = 0; - if (signs[s]) strcat(fmt, signs[s]); - if (precs[p]) strcat(fmt, precs[p]); - strcpy(sfmt, fmt); - if (formats[f]) strcat(fmt, formats[f]); - if (sformats[f]) strcat(sfmt, sformats[f]); - for (n = 0; n < PR_ARRAY_SIZE(nums); n++) { - test_l(fmt, sfmt, nums[n]); - } - } - } - } -} - -/************************************************************************/ - -/* -** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf. -** Make sure the results are identical -*/ -static void test_ll(char *pattern, char *spattern, PRInt64 l) -{ - char *s; - char buf[200]; - int n; - - /* try all three routines */ - s = PR_smprintf(pattern, l); - PR_ASSERT(s != 0); - n = PR_snprintf(buf, sizeof(buf), pattern, l); - PR_ASSERT(n <= sizeof(buf)); -#if defined(HAVE_LONG_LONG) - sprintf(sbuf, spattern, l); - - /* compare results */ - if ((strncmp(s, buf, sizeof(buf)) != 0) || - (strncmp(s, sbuf, sizeof(sbuf)) != 0)) { -#if PR_BYTES_PER_LONG == 8 -#define FORMAT_SPEC "%ld" -#elif defined(WIN16) -#define FORMAT_SPEC "%Ld" -#elif defined(WIN32) -#define FORMAT_SPEC "%I64d" -#else -#define FORMAT_SPEC "%lld" -#endif - fprintf(stderr, - "pattern='%s' ll=" FORMAT_SPEC "\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", - pattern, l, s, buf, sbuf); - printf("FAIL\n"); - PR_smprintf_free(s); - exit(-1); - } - PR_smprintf_free(s); -#else - /* compare results */ - if ((strncmp(s, buf, sizeof(buf)) != 0)) { - fprintf(stderr, - "pattern='%s'\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", - pattern, s, buf, sbuf); - printf("FAIL\n"); - PR_smprintf_free(s); - exit(-1); - } - PR_smprintf_free(s); -#endif -} - -static void TestLL(void) -{ - static PRInt64 nums[] = { - LL_INIT(0, 0), - LL_INIT(0, 1), - LL_INIT(0xffffffff, 0xffffffff), /* -1 */ - LL_INIT(0, 10), - LL_INIT(0xffffffff, 0xfffffff6), /* -10 */ - LL_INIT(0, 32767), - LL_INIT(0xffffffff, 0xffff8000), /* -32768 */ - LL_INIT(0, 0x7fffffff), /* 2147483647 */ - LL_INIT(0xffffffff, 0x80000000), /* -2147483648 */ - LL_INIT(0x7fffffff, 0xffffffff), /* 9223372036854775807 */ - LL_INIT(0x80000000, 0), /* -9223372036854775808 */ - PR_INT64(0), - PR_INT64(1), - PR_INT64(-1), - PR_INT64(10), - PR_INT64(-10), - PR_INT64(32767), - PR_INT64(-32768), - PR_INT64(2147483647), - PR_INT64(-2147483648), - PR_INT64(9223372036854775807), - PR_INT64(-9223372036854775808) - }; - - static char *signs[] = { - "", - "0", "-", "+", " ", - "0-", "0+", "0 ", "-0", "-+", "- ", - "+0", "+-", "+ ", " 0", " -", " +", - "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +", - "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +", - "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -", - " 0-", " 0+", " -0", " -+", " +0", " +-", - "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-", - "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0", - "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0", - " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0", - }; - static char *precs[] = { - "", "3", "5", "43", - ".3", ".43", - "7.3", "7.5", "7.11", "7.43", - }; - static char *formats[] = { "lld", "llo", "llx", "llu" }; - -#if PR_BYTES_PER_LONG == 8 - static char *sformats[] = { "ld", "lo", "lx", "lu" }; -#elif defined(WIN16) - /* Watcom uses the format string "%Ld" instead of "%lld". */ - static char *sformats[] = { "Ld", "Lo", "Lx", "Lu" }; -#elif defined(WIN32) - static char *sformats[] = { "I64d", "I64o", "I64x", "I64u" }; -#else - static char *sformats[] = { "lld", "llo", "llx", "llu" }; -#endif - - int f, s, n, p; - char fmt[40], sfmt[40]; - - for (f = 0; f < PR_ARRAY_SIZE(formats); f++) { - for (s = 0; s < PR_ARRAY_SIZE(signs); s++) { - for (p = 0; p < PR_ARRAY_SIZE(precs); p++) { - fmt[0] = '%'; - fmt[1] = 0; - if (signs[s]) strcat(fmt, signs[s]); - if (precs[p]) strcat(fmt, precs[p]); - strcpy(sfmt, fmt); - if (formats[f]) strcat(fmt, formats[f]); - if (sformats[f]) strcat(sfmt, sformats[f]); - for (n = 0; n < PR_ARRAY_SIZE(nums); n++) { - test_ll(fmt, sfmt, nums[n]); - } - } - } - } -} - -/************************************************************************/ - -/* -** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf. -** Make sure the results are identical -*/ -static void test_s(char *pattern, char *ss) -{ - char *s; - unsigned char before[8]; - char buf[200]; - unsigned char after[8]; - int n; - - memset(before, 0xBB, 8); - memset(after, 0xAA, 8); - - /* try all three routines */ - s = PR_smprintf(pattern, ss); - PR_ASSERT(s != 0); - n = PR_snprintf(buf, sizeof(buf), pattern, ss); - PR_ASSERT(n <= sizeof(buf)); - sprintf(sbuf, pattern, ss); - - for (n = 0; n < 8; n++) { - PR_ASSERT(before[n] == 0xBB); - PR_ASSERT(after[n] == 0xAA); - } - - /* compare results */ - if ((strncmp(s, buf, sizeof(buf)) != 0) || - (strncmp(s, sbuf, sizeof(sbuf)) != 0)) { - fprintf(stderr, - "pattern='%s' ss=%.20s\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", - pattern, ss, s, buf, sbuf); - printf("FAIL\n"); - PR_smprintf_free(s); - exit(-1); - } - PR_smprintf_free(s); -} - -static void TestS(void) -{ - static char *strs[] = { - "", - "a", - "abc", - "abcde", - "abcdefABCDEF", - "abcdefghijklmnopqrstuvwxyz0123456789!@#$" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$" - "abcdefghijklmnopqrstuvwxyz0123456789!@#$", - }; - /* '0' is not relevant to printing strings */ - static char *signs[] = { - "", - "-", "+", " ", - "-+", "- ", "+-", "+ ", " -", " +", - "-+ ", "- +", "+- ", "+ -", " -+", " +-", - }; - static char *precs[] = { - "", "3", "5", "43", - ".3", ".43", - "7.3", "7.5", "7.11", "7.43", - }; - static char *formats[] = { "s" }; - int f, s, n, p; - char fmt[40]; - - for (f = 0; f < PR_ARRAY_SIZE(formats); f++) { - for (s = 0; s < PR_ARRAY_SIZE(signs); s++) { - for (p = 0; p < PR_ARRAY_SIZE(precs); p++) { - fmt[0] = '%'; - fmt[1] = 0; - if (signs[s]) strcat(fmt+strlen(fmt), signs[s]); - if (precs[p]) strcat(fmt+strlen(fmt), precs[p]); - if (formats[f]) strcat(fmt+strlen(fmt), formats[f]); - for (n = 0; n < PR_ARRAY_SIZE(strs); n++) { - test_s(fmt, strs[n]); - } - } - } - } -} - -/************************************************************************/ - -int main(int argc, char **argv) -{ - PR_STDIO_INIT(); - TestI(); - TestL(); - TestLL(); - TestS(); - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sproc_ch.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sproc_ch.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sproc_ch.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sproc_ch.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Test sproc_ch.c - * - * The purpose of this test and the sproc_p.c test is to test the shutdown - * of all the IRIX sprocs in a program when one of them dies due to an error. - * - * There are three sprocs in this test: the parent, the child, and the - * grandchild. The parent and child sprocs never stop on their own. - * The grandchild sproc gets a segmentation fault and dies. You should - * You should use "ps" to see if the parent and child sprocs are killed - * after the grandchild dies. - */ - -#include "prinit.h" -#include - -#if !defined(IRIX) - -int main(int argc, char **argv) -{ - printf("This test applies to IRIX only.\n"); - return 0; -} - -#else /* IRIX */ - -#include "prthread.h" -#include -#include - -void SegFault(void *unused) -{ - int *p = 0; - - printf("The grandchild sproc has pid %d.\n", getpid()); - printf("The grandchild sproc will get a segmentation fault and die.\n"); - printf("The parent and child sprocs should be killed after the " - "grandchild sproc dies.\n"); - printf("Use 'ps' to make sure this is so.\n"); - fflush(stdout); - /* Force a segmentation fault */ - *p = 0; -} - -void NeverStops(void *unused) -{ - int i = 0; - - printf("The child sproc has pid %d.\n", getpid()); - printf("The child sproc won't stop on its own.\n"); - fflush(stdout); - - /* create the grandchild sproc */ - PR_CreateThread(PR_USER_THREAD, SegFault, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); - - while (1) { - i++; - } -} - -int main() -{ - int i= 0; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - printf("The parent sproc has pid %d.\n", getpid()); - printf("The parent sproc won't stop on its own.\n"); - fflush(stdout); - - /* create the child sproc */ - PR_CreateThread(PR_USER_THREAD, NeverStops, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); - - while (1) { - i++; - } - return 0; -} - -#endif /* IRIX */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/sproc_p.c nspr-4.10.7/mozilla/nsprpub/pr/tests/sproc_p.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/sproc_p.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/sproc_p.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Test sproc_p.c - * - * The purpose of this test and the sproc_ch.c test is to test the shutdown - * of all the IRIX sprocs in a program when one of them dies due to an error. - * - * In this test, the parent sproc gets a segmentation fault and dies. - * The child sproc never stops on its own. You should use "ps" to see if - * the child sproc is killed after the parent dies. - */ - -#include "prinit.h" -#include - -#if !defined(IRIX) - -int main(int argc, char **argv) -{ - printf("This test applies to IRIX only.\n"); - return 0; -} - -#else /* IRIX */ - -#include "prthread.h" -#include -#include - -void NeverStops(void *unused) -{ - int i = 0; - - printf("The child sproc has pid %d.\n", getpid()); - printf("The child sproc won't stop on its own.\n"); - fflush(stdout); - - /* I never stop */ - while (1) { - i++; - } -} - -int main() -{ - int *p = 0; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - printf("The parent sproc has pid %d.\n", getpid()); - printf("The parent sproc will first create a child sproc.\n"); - printf("Then the parent sproc will get a segmentation fault and die.\n"); - printf("The child sproc should be killed after the parent sproc dies.\n"); - printf("Use 'ps' to make sure this is so.\n"); - fflush(stdout); - - PR_CreateThread(PR_USER_THREAD, NeverStops, NULL, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); - - /* Force a segmentation fault */ - *p = 0; - return 0; -} - -#endif /* IRIX */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/stack.c nspr-4.10.7/mozilla/nsprpub/pr/tests/stack.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/stack.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/stack.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,280 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -/* - * - * Test atomic stack operations - * - * Two stacks are created and threads add data items (each containing - * one of the first n integers) to the first stack, remove data items - * from the first stack and add them to the second stack. The primordial - * thread compares the sum of the first n integers to the sum of the - * integers in the data items in the second stack. The test succeeds if - * they are equal. - */ - -#include "nspr.h" -#include "plgetopt.h" - -typedef struct _DataRecord { - PRInt32 data; - PRStackElem link; -} DataRecord; - -#define RECORD_LINK_PTR(lp) ((DataRecord*) ((char*) (lp) - offsetof(DataRecord,link))) - -#define MAX_THREAD_CNT 100 -#define DEFAULT_THREAD_CNT 4 -#define DEFAULT_DATA_CNT 100 -#define DEFAULT_LOOP_CNT 10000 - -/* - * sum of the first n numbers using the formula n*(n+1)/2 - */ -#define SUM_OF_NUMBERS(n) ((n & 1) ? (((n + 1)/2) * n) : ((n/2) * (n+1))) - -typedef struct stack_data { - PRStack *list1; - PRStack *list2; - PRInt32 initial_data_value; - PRInt32 data_cnt; - PRInt32 loops; -} stack_data; - -static void stackop(void *arg); - -static int _debug_on; - -PRFileDesc *output; -PRFileDesc *errhandle; - -int main(int argc, char **argv) -{ -#if !(defined(SYMBIAN) && defined(__WINS__)) - PRInt32 rv, cnt, sum; - DataRecord *Item; - PRStack *list1, *list2; - PRStackElem *node; - PRStatus rc; - - PRInt32 thread_cnt = DEFAULT_THREAD_CNT; - PRInt32 data_cnt = DEFAULT_DATA_CNT; - PRInt32 loops = DEFAULT_LOOP_CNT; - PRThread **threads; - stack_data *thread_args; - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:l:"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - case 't': /* thread count */ - thread_cnt = atoi(opt->value); - break; - case 'c': /* data count */ - data_cnt = atoi(opt->value); - break; - case 'l': /* loop count */ - loops = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_SetConcurrency(4); - - output = PR_GetSpecialFD(PR_StandardOutput); - errhandle = PR_GetSpecialFD(PR_StandardError); - list1 = PR_CreateStack("Stack_1"); - if (list1 == NULL) { - PR_fprintf(errhandle, "PR_CreateStack failed - error %d\n", - PR_GetError()); - return 1; - } - - list2 = PR_CreateStack("Stack_2"); - if (list2 == NULL) { - PR_fprintf(errhandle, "PR_CreateStack failed - error %d\n", - PR_GetError()); - return 1; - } - - - threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt); - thread_args = (stack_data *) PR_CALLOC(sizeof(stack_data) * thread_cnt); - - if (_debug_on) - PR_fprintf(output,"%s: thread_cnt = %d data_cnt = %d\n", argv[0], - thread_cnt, data_cnt); - for(cnt = 0; cnt < thread_cnt; cnt++) { - PRThreadScope scope; - - thread_args[cnt].list1 = list1; - thread_args[cnt].list2 = list2; - thread_args[cnt].loops = loops; - thread_args[cnt].data_cnt = data_cnt; - thread_args[cnt].initial_data_value = 1 + cnt * data_cnt; - - if (cnt & 1) - scope = PR_GLOBAL_THREAD; - else - scope = PR_LOCAL_THREAD; - - - threads[cnt] = PR_CreateThread(PR_USER_THREAD, - stackop, &thread_args[cnt], - PR_PRIORITY_NORMAL, - scope, - PR_JOINABLE_THREAD, - 0); - if (threads[cnt] == NULL) { - PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n", - PR_GetError()); - PR_ProcessExit(2); - } - if (_debug_on) - PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0], - threads[cnt]); - } - - for(cnt = 0; cnt < thread_cnt; cnt++) { - rc = PR_JoinThread(threads[cnt]); - PR_ASSERT(rc == PR_SUCCESS); - } - - node = PR_StackPop(list1); - /* - * list1 should be empty - */ - if (node != NULL) { - PR_fprintf(errhandle, "Error - Stack 1 not empty\n"); - PR_ASSERT(node == NULL); - PR_ProcessExit(4); - } - - cnt = data_cnt * thread_cnt; - sum = 0; - while (cnt-- > 0) { - node = PR_StackPop(list2); - /* - * There should be at least 'cnt' number of records - */ - if (node == NULL) { - PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n"); - PR_ProcessExit(3); - } - Item = RECORD_LINK_PTR(node); - sum += Item->data; - } - node = PR_StackPop(list2); - /* - * there should be exactly 'cnt' number of records - */ - if (node != NULL) { - PR_fprintf(errhandle, "Error - Stack 2 not empty\n"); - PR_ASSERT(node == NULL); - PR_ProcessExit(4); - } - PR_DELETE(threads); - PR_DELETE(thread_args); - - PR_DestroyStack(list1); - PR_DestroyStack(list2); - - if (sum == SUM_OF_NUMBERS(data_cnt * thread_cnt)) { - PR_fprintf(output, "%s successful\n", argv[0]); - PR_fprintf(output, "\t\tsum = 0x%x, expected = 0x%x\n", sum, - SUM_OF_NUMBERS(thread_cnt * data_cnt)); - return 0; - } else { - PR_fprintf(output, "%s failed: sum = 0x%x, expected = 0x%x\n", - argv[0], sum, - SUM_OF_NUMBERS(data_cnt * thread_cnt)); - return 2; - } -#endif -} - -static void stackop(void *thread_arg) -{ - PRInt32 val, cnt, index, loops; - DataRecord *Items, *Item; - PRStack *list1, *list2; - PRStackElem *node; - stack_data *arg = (stack_data *) thread_arg; - - val = arg->initial_data_value; - cnt = arg->data_cnt; - loops = arg->loops; - list1 = arg->list1; - list2 = arg->list2; - - /* - * allocate memory for the data records - */ - Items = (DataRecord *) PR_CALLOC(sizeof(DataRecord) * cnt); - PR_ASSERT(Items != NULL); - index = 0; - - if (_debug_on) - PR_fprintf(output, - "Thread[0x%x] init_val = %d cnt = %d data1 = 0x%x datan = 0x%x\n", - PR_GetCurrentThread(), val, cnt, &Items[0], &Items[cnt-1]); - - - /* - * add the data records to list1 - */ - while (cnt-- > 0) { - Items[index].data = val++; - PR_StackPush(list1, &Items[index].link); - index++; - } - - /* - * pop data records from list1 and add them back to list1 - * generates contention for the stack accesses - */ - while (loops-- > 0) { - cnt = arg->data_cnt; - while (cnt-- > 0) { - node = PR_StackPop(list1); - if (node == NULL) { - PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n"); - PR_ASSERT(node != NULL); - PR_ProcessExit(3); - } - PR_StackPush(list1, node); - } - } - /* - * remove the data records from list1 and add them to list2 - */ - cnt = arg->data_cnt; - while (cnt-- > 0) { - node = PR_StackPop(list1); - if (node == NULL) { - PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n"); - PR_ASSERT(node != NULL); - PR_ProcessExit(3); - } - PR_StackPush(list2, node); - } - if (_debug_on) - PR_fprintf(output, - "Thread[0x%x] init_val = %d cnt = %d exiting\n", - PR_GetCurrentThread(), val, cnt); - -} - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/stat.c nspr-4.10.7/mozilla/nsprpub/pr/tests/stat.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/stat.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/stat.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Program to test different ways to get file info; right now it - * only works for solaris and OS/2. - * - */ -#include "nspr.h" -#include "prpriv.h" -#include "prinrval.h" - -#include -#include -#include - -#ifdef XP_OS2 -#include -#include -#include -#endif - -#define DEFAULT_COUNT 100000 -PRInt32 count; - -#ifndef XP_PC -char *filename = "/etc/passwd"; -#else -char *filename = "..\\stat.c"; -#endif - -static void statPRStat(void) -{ - PRFileInfo finfo; - PRInt32 index = count; - - for (;index--;) { - PR_GetFileInfo(filename, &finfo); - } -} - -static void statStat(void) -{ - struct stat finfo; - PRInt32 index = count; - - for (;index--;) { - stat(filename, &finfo); - } -} - -/************************************************************************/ - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - PRInt32 tot; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - tot = PR_IntervalToMilliseconds(stop-start); - - printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot); -} - -int main(int argc, char **argv) -{ - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (argc > 1) { - count = atoi(argv[1]); - } else { - count = DEFAULT_COUNT; - } - - Measure(statPRStat, "time to call PR_GetFileInfo()"); - Measure(statStat, "time to call stat()"); - - PR_Cleanup(); -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/stdio.c nspr-4.10.7/mozilla/nsprpub/pr/tests/stdio.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/stdio.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/stdio.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: stdio.c - * Description: testing the "special" fds - * Modification History: - * 20-May-1997 AGarcia - Replace Test succeeded status with PASS. This is used by the - * regress tool parsing code. - ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to -** recognize the return code from tha main program. - */ - - -#include "prlog.h" -#include "prinit.h" -#include "prio.h" - -#include -#include - -static PRIntn PR_CALLBACK stdio(PRIntn argc, char **argv) -{ - PRInt32 rv; - - PRFileDesc *out = PR_GetSpecialFD(PR_StandardOutput); - PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); - - rv = PR_Write( - out, "This to standard out\n", - strlen("This to standard out\n")); - PR_ASSERT((PRInt32)strlen("This to standard out\n") == rv); - rv = PR_Write( - err, "This to standard err\n", - strlen("This to standard err\n")); - PR_ASSERT((PRInt32)strlen("This to standard err\n") == rv); - - return 0; - -} /* stdio */ - -int main(int argc, char **argv) -{ - PR_STDIO_INIT(); - return PR_Initialize(stdio, argc, argv, 0); -} /* main */ - - -/* stdio.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/str2addr.c nspr-4.10.7/mozilla/nsprpub/pr/tests/str2addr.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/str2addr.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/str2addr.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: str2addr.c - * Description: a test for PR_StringToNetAddr - */ - -#include "nspr.h" - -#include -#include - -/* Address string to convert */ -#define DEFAULT_IPV4_ADDR_STR "207.200.73.41" - -/* Expected conversion result, in network byte order */ -static unsigned char default_ipv4_addr[] = {207, 200, 73, 41}; - -int main(int argc, char **argv) -{ - PRNetAddr addr; - const char *addrStr; - unsigned char *bytes; - int idx; - - addrStr = DEFAULT_IPV4_ADDR_STR; - if (PR_StringToNetAddr(addrStr, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_StringToNetAddr failed\n"); - exit(1); - } - if (addr.inet.family != PR_AF_INET) { - fprintf(stderr, "addr.inet.family should be %d but is %d\n", - PR_AF_INET, addr.inet.family); - exit(1); - } - bytes = (unsigned char *) &addr.inet.ip; - for (idx = 0; idx < 4; idx++) { - if (bytes[idx] != default_ipv4_addr[idx]) { - fprintf(stderr, "byte %d of IPv4 addr should be %d but is %d\n", - idx, default_ipv4_addr[idx], bytes[idx]); - exit(1); - } - } - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/strod.c nspr-4.10.7/mozilla/nsprpub/pr/tests/strod.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/strod.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/strod.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prinit.h" -#include "prio.h" -#include "prprf.h" -#include "prdtoa.h" -#include "plgetopt.h" - -#include - -static void Help(void) -{ - PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); - PR_fprintf(err, "Usage: /.strod [-n n] [-l n] [-h]\n"); - PR_fprintf(err, "\t-n n Number to translate (default: 1234567890123456789)\n"); - PR_fprintf(err, "\t-l n Times to loop the test (default: 1)\n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); -} /* Help */ - -static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv) -{ - PLOptStatus os; - PRIntn loops = 1; - PRFloat64 answer; - const char *number = "1234567890123456789"; - PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); - PLOptState *opt = PL_CreateOptState(argc, argv, "hc:l:"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'n': /* number to translate */ - number = opt->value; - break; - case 'l': /* number of times to run the tests */ - loops = atoi(opt->value); - break; - case 'h': /* user wants some guidance */ - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_fprintf(err, "Settings\n"); - PR_fprintf(err, "\tNumber to translate %s\n", number); - PR_fprintf(err, "\tLoops to run test: %d\n", loops); - - while (loops--) - { - answer = PR_strtod(number, NULL); - PR_fprintf(err, "Translation = %20.0f\n", answer); - } - return 0; -} - - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/suspend.c nspr-4.10.7/mozilla/nsprpub/pr/tests/suspend.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/suspend.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/suspend.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifdef XP_BEOS -#include -int main() -{ - printf( "This test is not ported to the BeOS\n" ); - return 0; -} -#else - -#include "nspr.h" -#include "prpriv.h" -#include "prinrval.h" - -#include -#include -#include - -PRMonitor *mon; -PRInt32 count; -PRInt32 alive; - -#define SLEEP_TIME 4 /* secs */ - -void PR_CALLBACK -Level_2_Thread(void *arg) -{ - PR_Sleep(PR_MillisecondsToInterval(4 * 1000)); - printf("Level_2_Thread[0x%lx] exiting\n",PR_GetCurrentThread()); - return; -} - -void PR_CALLBACK -Level_1_Thread(void *arg) -{ - PRUint32 tmp = (PRUint32)arg; - PRThreadScope scope = (PRThreadScope) tmp; - PRThread *thr; - - thr = PR_CreateThreadGCAble(PR_USER_THREAD, - Level_2_Thread, - NULL, - PR_PRIORITY_HIGH, - scope, - PR_JOINABLE_THREAD, - 0); - - if (!thr) { - printf("Could not create thread!\n"); - } else { - printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n", - PR_GetCurrentThread(), - (scope == PR_GLOBAL_THREAD) ? - "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", - thr); - PR_JoinThread(thr); - } - PR_EnterMonitor(mon); - alive--; - PR_Notify(mon); - PR_ExitMonitor(mon); - printf("Thread[0x%lx] exiting\n",PR_GetCurrentThread()); -} - -static PRStatus PR_CALLBACK print_thread(PRThread *thread, int i, void *arg) -{ - PRInt32 words; - PRWord *registers; - - printf( - "\nprint_thread[0x%lx]: %-20s - i = %ld\n",thread, - (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ? - "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", i); - registers = PR_GetGCRegisters(thread, 0, (int *)&words); - if (registers) - printf("Registers R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n", - registers[0],registers[1],registers[2],registers[3]); - printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread)); - return PR_SUCCESS; -} - -static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *thr; - PRThread *me = PR_GetCurrentThread(); - int n; - PRInt32 words; - PRWord *registers; - - alive = 0; - mon = PR_NewMonitor(); - - alive = count; - for (n=0; n 1) { - count = atoi(argv[1]); - } else { - count = 5; - } - - printf("\n\n%20s%30s\n\n"," ","Suspend_Resume Test"); - CreateThreadsUU(); - CreateThreadsUK(); - CreateThreadsKU(); - CreateThreadsKK(); - PR_SetConcurrency(2); - - printf("\n%20s%30s\n\n"," ","Added 2nd CPU\n"); - - CreateThreadsUK(); - CreateThreadsKK(); - CreateThreadsUU(); - CreateThreadsKU(); - PR_Cleanup(); - - return 0; -} - -#endif /* XP_BEOS */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/switch.c nspr-4.10.7/mozilla/nsprpub/pr/tests/switch.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/switch.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/switch.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,237 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: switch.c -** Description: trying to time context switches -*/ - -#include "prinit.h" -#include "prcvar.h" -#include "prmem.h" -#include "prinrval.h" -#include "prlock.h" -#include "prlog.h" -#include "prthread.h" -#include "prprf.h" - -#include "plerror.h" -#include "plgetopt.h" - -#include "private/pprio.h" - -#include - -#define INNER_LOOPS 100 -#define DEFAULT_LOOPS 100 -#define DEFAULT_THREADS 10 - -static PRFileDesc *debug_out = NULL; -static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE; - -typedef struct Shared -{ - PRLock *ml; - PRCondVar *cv; - PRBool twiddle; - PRThread *thread; - struct Shared *next; -} Shared; - -static void Help(void) -{ - debug_out = PR_STDOUT; - - PR_fprintf( - debug_out, "Usage: >./switch [-c n] [-t n] [-d] [-v] [-G] [-C n]\n"); - PR_fprintf( - debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS); - PR_fprintf( - debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS); - PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n"); - PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n"); - PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n"); - PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n"); -} /* Help */ - -static void PR_CALLBACK Notified(void *arg) -{ - Shared *shared = (Shared*)arg; - PRStatus status = PR_SUCCESS; - while (PR_SUCCESS == status) - { - PR_Lock(shared->ml); - while (shared->twiddle && (PR_SUCCESS == status)) - status = PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT); - if (verbosity) PR_fprintf(debug_out, "+"); - shared->twiddle = PR_TRUE; - shared->next->twiddle = PR_FALSE; - PR_NotifyCondVar(shared->next->cv); - PR_Unlock(shared->ml); - } -} /* Notified */ - -static Shared home; -PRIntn PR_CALLBACK Switch(PRIntn argc, char **argv) -{ - PLOptStatus os; - PRStatus status; - PRBool help = PR_FALSE; - PRUintn concurrency = 1; - Shared *shared, *link; - PRIntervalTime timein, timeout; - PRThreadScope thread_scope = PR_LOCAL_THREAD; - PRUintn thread_count, inner_count, loop_count, average; - PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS; - PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'v': /* verbose mode */ - verbosity = PR_TRUE; - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'c': /* loop counter */ - loop_limit = atoi(opt->value); - break; - case 't': /* thread limit */ - thread_limit = atoi(opt->value); - break; - case 'C': /* Concurrency limit */ - concurrency = atoi(opt->value); - break; - case 'G': /* global threads only */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'h': /* help message */ - Help(); - help = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (help) return -1; - - if (PR_TRUE == debug_mode) - { - debug_out = PR_STDOUT; - PR_fprintf(debug_out, "Test parameters\n"); - PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit); - PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit); - PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency); - PR_fprintf( - debug_out, "\tThread type: %s\n", - (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); - } - - PR_SetConcurrency(concurrency); - - link = &home; - home.ml = PR_NewLock(); - home.cv = PR_NewCondVar(home.ml); - home.twiddle = PR_FALSE; - home.next = NULL; - - timeout = 0; - - for (thread_count = 1; thread_count <= thread_limit; ++thread_count) - { - shared = PR_NEWZAP(Shared); - - shared->ml = home.ml; - shared->cv = PR_NewCondVar(home.ml); - shared->twiddle = PR_TRUE; - shared->next = link; - link = shared; - - shared->thread = PR_CreateThread( - PR_USER_THREAD, Notified, shared, - PR_PRIORITY_HIGH, thread_scope, - PR_JOINABLE_THREAD, 0); - PR_ASSERT(shared->thread != NULL); - if (NULL == shared->thread) - failed = PR_TRUE; - } - - for (loop_count = 1; loop_count <= loop_limit; ++loop_count) - { - timein = PR_IntervalNow(); - for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count) - { - PR_Lock(home.ml); - home.twiddle = PR_TRUE; - shared->twiddle = PR_FALSE; - PR_NotifyCondVar(shared->cv); - while (home.twiddle) - { - status = PR_WaitCondVar(home.cv, PR_INTERVAL_NO_TIMEOUT); - if (PR_FAILURE == status) - failed = PR_TRUE; - } - PR_Unlock(home.ml); - } - timeout += (PR_IntervalNow() - timein); - } - - if (debug_mode) - { - average = PR_IntervalToMicroseconds(timeout) - / (INNER_LOOPS * loop_limit * thread_count); - PR_fprintf( - debug_out, "Average switch times %d usecs for %d threads\n", - average, thread_limit); - } - - link = shared; - for (thread_count = 1; thread_count <= thread_limit; ++thread_count) - { - if (&home == link) break; - status = PR_Interrupt(link->thread); - if (PR_SUCCESS != status) - { - failed = PR_TRUE; - if (debug_mode) - PL_FPrintError(debug_out, "Failed to interrupt"); - } - link = link->next; - } - - for (thread_count = 1; thread_count <= thread_limit; ++thread_count) - { - link = shared->next; - status = PR_JoinThread(shared->thread); - if (PR_SUCCESS != status) - { - failed = PR_TRUE; - if (debug_mode) - PL_FPrintError(debug_out, "Failed to join"); - } - PR_DestroyCondVar(shared->cv); - PR_DELETE(shared); - if (&home == link) break; - shared = link; - } - PR_DestroyCondVar(home.cv); - PR_DestroyLock(home.ml); - - PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n")); - return ((failed) ? 1 : 0); -} /* Switch */ - -int main(int argc, char **argv) -{ - PRIntn result; - PR_STDIO_INIT(); - result = PR_Initialize(Switch, argc, argv, 0); - return result; -} /* main */ - -/* switch.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/system.c nspr-4.10.7/mozilla/nsprpub/pr/tests/system.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/system.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/system.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prmem.h" -#include "prprf.h" -#include "prsystem.h" - -#include "plerror.h" - -static char *tag[] = -{ - "PR_SI_HOSTNAME", - "PR_SI_SYSNAME", - "PR_SI_RELEASE", - "PR_SI_ARCHITECTURE" -}; - -static PRSysInfo Incr(PRSysInfo *cmd) -{ - PRIntn tmp = (PRIntn)*cmd + 1; - *cmd = (PRSysInfo)tmp; - return (PRSysInfo)tmp; -} /* Incr */ - -int main(int argc, char **argv) -{ - PRStatus rv; - PRSysInfo cmd; - PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput); - - char *info = (char*)PR_Calloc(SYS_INFO_BUFFER_LENGTH, 1); - for (cmd = PR_SI_HOSTNAME; cmd <= PR_SI_ARCHITECTURE; Incr(&cmd)) - { - rv = PR_GetSystemInfo(cmd, info, SYS_INFO_BUFFER_LENGTH); - if (PR_SUCCESS == rv) PR_fprintf(output, "%s: %s\n", tag[cmd], info); - else PL_FPrintError(output, tag[cmd]); - } - PR_DELETE(info); - - PR_fprintf(output, "Host page size is %d\n", PR_GetPageSize()); - PR_fprintf(output, "Page shift is %d\n", PR_GetPageShift()); - PR_fprintf(output, "Memory map alignment is %ld\n", PR_GetMemMapAlignment()); - PR_fprintf(output, "Number of processors is: %d\n", PR_GetNumberOfProcessors()); - PR_fprintf(output, "Physical memory size is: %llu\n", PR_GetPhysicalMemorySize()); - - return 0; -} /* main */ - -/* system.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/testbit.c nspr-4.10.7/mozilla/nsprpub/pr/tests/testbit.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/testbit.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/testbit.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: lazyinit.c -** Description: Test the functions and macros declared in prbit.h -** -*/ - -#include "nspr.h" - -#define ErrorReport(x) { printf((x)); failed = 1; } - -prbitmap_t myMap[512/32] = { 0 }; - -PRInt32 rc; -PRInt32 i; -PRIntn failed = 0; - -int main(int argc, char **argv) -{ - /* - ** Test bitmap things. - */ - if ( PR_TEST_BIT( myMap, 0 )) - ErrorReport("Test 0.0: Failed\n"); - - if ( PR_TEST_BIT( myMap, 31 )) - ErrorReport("Test 0.1: Failed\n"); - - if ( PR_TEST_BIT( myMap, 128 )) - ErrorReport("Test 0.2: Failed\n"); - - if ( PR_TEST_BIT( myMap, 129 )) - ErrorReport("Test 0.3: Failed\n"); - - - PR_SET_BIT( myMap, 0 ); - if ( !PR_TEST_BIT( myMap, 0 )) - ErrorReport("Test 1.0: Failed\n"); - - PR_CLEAR_BIT( myMap, 0 ); - if ( PR_TEST_BIT( myMap, 0 )) - ErrorReport("Test 1.0.1: Failed\n"); - - PR_SET_BIT( myMap, 31 ); - if ( !PR_TEST_BIT( myMap, 31 )) - ErrorReport("Test 1.1: Failed\n"); - - PR_CLEAR_BIT( myMap, 31 ); - if ( PR_TEST_BIT( myMap, 31 )) - ErrorReport("Test 1.1.1: Failed\n"); - - PR_SET_BIT( myMap, 128 ); - if ( !PR_TEST_BIT( myMap, 128 )) - ErrorReport("Test 1.2: Failed\n"); - - PR_CLEAR_BIT( myMap, 128 ); - if ( PR_TEST_BIT( myMap, 128 )) - ErrorReport("Test 1.2.1: Failed\n"); - - PR_SET_BIT( myMap, 129 ); - if ( !PR_TEST_BIT( myMap, 129 )) - ErrorReport("Test 1.3: Failed\n"); - - PR_CLEAR_BIT( myMap, 129 ); - if ( PR_TEST_BIT( myMap, 129 )) - ErrorReport("Test 1.3.1: Failed\n"); - - - /* - ** Test Ceiling and Floor functions and macros - */ - if ((rc = PR_CeilingLog2(32)) != 5 ) - ErrorReport("Test 10.0: Failed\n"); - - if ((rc = PR_FloorLog2(32)) != 5 ) - ErrorReport("Test 10.1: Failed\n"); - - - /* - ** Evaluate results and exit - */ - if (failed) - { - printf("FAILED\n"); - return(1); - } - else - { - printf("PASSED\n"); - return(0); - } -} /* end main() */ -/* end testbit.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/testfile.c nspr-4.10.7/mozilla/nsprpub/pr/tests/testfile.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/testfile.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/testfile.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,961 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "prpriv.h" - -#include -#include -#include -#ifdef WIN32 -#include -#include -#endif -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) -#include -#endif -#ifdef SYMBIAN -#include -#endif - -#if defined(XP_OS2) -#define INCL_DOSFILEMGR -#include -#include -#include -#endif /* XP_OS2 */ - -static int _debug_on = 0; - -#ifdef WINCE -#define setbuf(x,y) -#endif - -#ifdef XP_WIN -#define mode_t int -#endif - -#define DPRINTF(arg) if (_debug_on) printf arg - -PRLock *lock; -PRMonitor *mon; -PRInt32 count; -int thread_count; - -#ifdef WIN16 -#define BUF_DATA_SIZE 256 * 120 -#else -#define BUF_DATA_SIZE 256 * 1024 -#endif - -#define NUM_RDWR_THREADS 10 -#define NUM_DIRTEST_THREADS 4 -#define CHUNK_SIZE 512 - -typedef struct buffer { - char data[BUF_DATA_SIZE]; -} buffer; - -typedef struct File_Rdwr_Param { - char *pathname; - char *buf; - int offset; - int len; -} File_Rdwr_Param; - -#ifdef XP_PC -#ifdef XP_OS2 -char *TEST_DIR = "prdir"; -#else -char *TEST_DIR = "C:\\temp\\prdir"; -#endif -char *FILE_NAME = "pr_testfile"; -char *HIDDEN_FILE_NAME = "hidden_pr_testfile"; -#else -#ifdef SYMBIAN -char *TEST_DIR = "c:\\data\\testfile_dir"; -#else -char *TEST_DIR = "/tmp/testfile_dir"; -#endif -char *FILE_NAME = "pr_testfile"; -char *HIDDEN_FILE_NAME = ".hidden_pr_testfile"; -#endif -buffer *in_buf, *out_buf; -char pathname[256], renamename[256]; -#ifdef WINCE -WCHAR wPathname[256]; -#endif -#define TMPDIR_LEN 64 -char testdir[TMPDIR_LEN]; -static PRInt32 PR_CALLBACK DirTest(void *argunused); -PRInt32 dirtest_failed = 0; - -PRThread* create_new_thread(PRThreadType type, - void (*start)(void *arg), - void *arg, - PRThreadPriority priority, - PRThreadScope scope, - PRThreadState state, - PRUint32 stackSize, PRInt32 index) -{ -PRInt32 native_thread = 0; - - PR_ASSERT(state == PR_UNJOINABLE_THREAD); - -#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) || defined(XP_OS2) - - switch(index % 4) { - case 0: - scope = (PR_LOCAL_THREAD); - break; - case 1: - scope = (PR_GLOBAL_THREAD); - break; - case 2: - scope = (PR_GLOBAL_BOUND_THREAD); - break; - case 3: - native_thread = 1; - break; - default: - PR_ASSERT(!"Invalid scope"); - break; - } - if (native_thread) { -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) - pthread_t tid; - if (!pthread_create(&tid, NULL, start, arg)) - return((PRThread *) tid); - else - return (NULL); -#elif defined(XP_OS2) - TID tid; - - tid = (TID)_beginthread((void(* _Optlink)(void*))start, - NULL, 32768, arg); - if (tid == -1) { - printf("_beginthread failed. errno %d\n", errno); - return (NULL); - } - else - return((PRThread *) tid); -#else - HANDLE thandle; - unsigned tid; - - thandle = (HANDLE) _beginthreadex( - NULL, - stackSize, - (unsigned (__stdcall *)(void *))start, - arg, - 0, - &tid); - return((PRThread *) thandle); -#endif - } else { - return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); - } -#else - return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); -#endif -} - -static void PR_CALLBACK File_Write(void *arg) -{ -PRFileDesc *fd_file; -File_Rdwr_Param *fp = (File_Rdwr_Param *) arg; -char *name, *buf; -int offset, len; - - setbuf(stdout, NULL); - name = fp->pathname; - buf = fp->buf; - offset = fp->offset; - len = fp->len; - - fd_file = PR_Open(name, PR_RDWR | PR_CREATE_FILE, 0777); - if (fd_file == NULL) { - printf("testfile failed to create/open file %s\n",name); - return; - } - if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { - printf("testfile failed to seek in file %s\n",name); - return; - } - if ((PR_Write(fd_file, buf, len)) < 0) { - printf("testfile failed to write to file %s\n",name); - return; - } - DPRINTF(("Write out_buf[0] = 0x%x\n",(*((int *) buf)))); - PR_Close(fd_file); - PR_DELETE(fp); - - PR_EnterMonitor(mon); - --thread_count; - PR_Notify(mon); - PR_ExitMonitor(mon); -} - -static void PR_CALLBACK File_Read(void *arg) -{ -PRFileDesc *fd_file; -File_Rdwr_Param *fp = (File_Rdwr_Param *) arg; -char *name, *buf; -int offset, len; - - setbuf(stdout, NULL); - name = fp->pathname; - buf = fp->buf; - offset = fp->offset; - len = fp->len; - - fd_file = PR_Open(name, PR_RDONLY, 0); - if (fd_file == NULL) { - printf("testfile failed to open file %s\n",name); - return; - } - if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { - printf("testfile failed to seek in file %s\n",name); - return; - } - if ((PR_Read(fd_file, buf, len)) < 0) { - printf("testfile failed to read to file %s\n",name); - return; - } - DPRINTF(("Read in_buf[0] = 0x%x\n",(*((int *) buf)))); - PR_Close(fd_file); - PR_DELETE(fp); - - PR_EnterMonitor(mon); - --thread_count; - PR_Notify(mon); - PR_ExitMonitor(mon); -} - - -static PRInt32 Misc_File_Tests(char *pathname) -{ -PRFileDesc *fd_file; -int len, rv = 0; -PRFileInfo file_info, file_info1; -char tmpname[1024]; - - setbuf(stdout, NULL); - /* - * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access - */ - - fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); - - if (fd_file == NULL) { - printf("testfile failed to create/open file %s\n",pathname); - return -1; - } - if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { - printf("testfile PR_GetFileInfo failed on file %s\n",pathname); - rv = -1; - goto cleanup; - } - if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) { - printf("testfile PR_Access failed on file %s\n",pathname); - rv = -1; - goto cleanup; - } - if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) { - printf("testfile PR_Access failed on file %s\n",pathname); - rv = -1; - goto cleanup; - } - if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) { - printf("testfile PR_Access failed on file %s\n",pathname); - rv = -1; - goto cleanup; - } - - - if (PR_GetFileInfo(pathname, &file_info) < 0) { - printf("testfile PR_GetFileInfo failed on file %s\n",pathname); - rv = -1; - goto cleanup; - } - if (file_info.type != PR_FILE_FILE) { - printf( - "testfile: Error - PR_GetFileInfo returned incorrect type for file %s\n", - pathname); - rv = -1; - goto cleanup; - } - if (file_info.size != 0) { - printf( - "testfile PR_GetFileInfo returned incorrect size (%d should be 0) for file %s\n", - file_info.size, pathname); - rv = -1; - goto cleanup; - } - file_info1 = file_info; - - len = PR_Available(fd_file); - if (len < 0) { - printf("testfile PR_Available failed on file %s\n",pathname); - rv = -1; - goto cleanup; - } else if (len != 0) { - printf( - "testfile PR_Available failed: expected/returned = %d/%d bytes\n", - 0, len); - rv = -1; - goto cleanup; - } - if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { - printf("testfile PR_GetFileInfo failed on file %s\n",pathname); - goto cleanup; - } - if (LL_NE(file_info.creationTime , file_info1.creationTime)) { - printf( - "testfile PR_GetFileInfo returned incorrect status-change time: %s\n", - pathname); - printf("ft = %lld, ft1 = %lld\n",file_info.creationTime, - file_info1.creationTime); - rv = -1; - goto cleanup; - } - len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); - if (len < 0) { - printf("testfile failed to write to file %s\n",pathname); - rv = -1; - goto cleanup; - } - if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { - printf("testfile PR_GetFileInfo failed on file %s\n",pathname); - goto cleanup; - } - if (file_info.size != CHUNK_SIZE) { - printf( - "testfile PR_GetFileInfo returned incorrect size (%d should be %d) for file %s\n", - file_info.size, CHUNK_SIZE, pathname); - rv = -1; - goto cleanup; - } - if (LL_CMP(file_info.modifyTime, < , file_info1.modifyTime)) { - printf( - "testfile PR_GetFileInfo returned incorrect modify time: %s\n", - pathname); - printf("ft = %lld, ft1 = %lld\n",file_info.modifyTime, - file_info1.modifyTime); - rv = -1; - goto cleanup; - } - - len = PR_Available(fd_file); - if (len < 0) { - printf("testfile PR_Available failed on file %s\n",pathname); - rv = -1; - goto cleanup; - } else if (len != 0) { - printf( - "testfile PR_Available failed: expected/returned = %d/%d bytes\n", - 0, len); - rv = -1; - goto cleanup; - } - - PR_Seek(fd_file, 0, PR_SEEK_SET); - len = PR_Available(fd_file); - if (len < 0) { - printf("testfile PR_Available failed on file %s\n",pathname); - rv = -1; - goto cleanup; - } else if (len != CHUNK_SIZE) { - printf( - "testfile PR_Available failed: expected/returned = %d/%d bytes\n", - CHUNK_SIZE, len); - rv = -1; - goto cleanup; - } - PR_Close(fd_file); - - strcpy(tmpname,pathname); - strcat(tmpname,".RENAMED"); - if (PR_FAILURE == PR_Rename(pathname, tmpname)) { - printf("testfile failed to rename file %s\n",pathname); - rv = -1; - goto cleanup; - } - - fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); - len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); - PR_Close(fd_file); - if (PR_SUCCESS == PR_Rename(pathname, tmpname)) { - printf("testfile renamed to existing file %s\n",pathname); - } - - if ((PR_Delete(tmpname)) < 0) { - printf("testfile failed to unlink file %s\n",tmpname); - rv = -1; - } - -cleanup: - if ((PR_Delete(pathname)) < 0) { - printf("testfile failed to unlink file %s\n",pathname); - rv = -1; - } - return rv; -} - - -static PRInt32 PR_CALLBACK FileTest(void) -{ -PRDir *fd_dir; -int i, offset, len, rv = 0; -PRThread *t; -PRThreadScope scope = PR_GLOBAL_THREAD; -File_Rdwr_Param *fparamp; - - /* - * Create Test dir - */ - if ((PR_MkDir(TEST_DIR, 0777)) < 0) { - printf("testfile failed to create dir %s\n",TEST_DIR); - return -1; - } - fd_dir = PR_OpenDir(TEST_DIR); - if (fd_dir == NULL) { - printf("testfile failed to open dir %s\n",TEST_DIR); - rv = -1; - goto cleanup; - } - - PR_CloseDir(fd_dir); - - strcat(pathname, TEST_DIR); - strcat(pathname, "/"); - strcat(pathname, FILE_NAME); - - in_buf = PR_NEW(buffer); - if (in_buf == NULL) { - printf( - "testfile failed to alloc buffer struct\n"); - rv = -1; - goto cleanup; - } - out_buf = PR_NEW(buffer); - if (out_buf == NULL) { - printf( - "testfile failed to alloc buffer struct\n"); - rv = -1; - goto cleanup; - } - - /* - * Start a bunch of writer threads - */ - offset = 0; - len = CHUNK_SIZE; - PR_EnterMonitor(mon); - for (i = 0; i < NUM_RDWR_THREADS; i++) { - fparamp = PR_NEW(File_Rdwr_Param); - if (fparamp == NULL) { - printf( - "testfile failed to alloc File_Rdwr_Param struct\n"); - rv = -1; - goto cleanup; - } - fparamp->pathname = pathname; - fparamp->buf = out_buf->data + offset; - fparamp->offset = offset; - fparamp->len = len; - memset(fparamp->buf, i, len); - - t = create_new_thread(PR_USER_THREAD, - File_Write, (void *)fparamp, - PR_PRIORITY_NORMAL, - scope, - PR_UNJOINABLE_THREAD, - 0, i); - offset += len; - } - thread_count = i; - /* Wait for writer threads to exit */ - while (thread_count) { - PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); - } - PR_ExitMonitor(mon); - - - /* - * Start a bunch of reader threads - */ - offset = 0; - len = CHUNK_SIZE; - PR_EnterMonitor(mon); - for (i = 0; i < NUM_RDWR_THREADS; i++) { - fparamp = PR_NEW(File_Rdwr_Param); - if (fparamp == NULL) { - printf( - "testfile failed to alloc File_Rdwr_Param struct\n"); - rv = -1; - goto cleanup; - } - fparamp->pathname = pathname; - fparamp->buf = in_buf->data + offset; - fparamp->offset = offset; - fparamp->len = len; - - t = create_new_thread(PR_USER_THREAD, - File_Read, (void *)fparamp, - PR_PRIORITY_NORMAL, - scope, - PR_UNJOINABLE_THREAD, - 0, i); - offset += len; - if ((offset + len) > BUF_DATA_SIZE) - break; - } - thread_count = i; - - /* Wait for reader threads to exit */ - while (thread_count) { - PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); - } - PR_ExitMonitor(mon); - - if (memcmp(in_buf->data, out_buf->data, offset) != 0) { - printf("File Test failed: file data corrupted\n"); - rv = -1; - goto cleanup; - } - - if ((PR_Delete(pathname)) < 0) { - printf("testfile failed to unlink file %s\n",pathname); - rv = -1; - goto cleanup; - } - - /* - * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access - */ - if (Misc_File_Tests(pathname) < 0) { - rv = -1; - } - -cleanup: - if ((PR_RmDir(TEST_DIR)) < 0) { - printf("testfile failed to rmdir %s\n", TEST_DIR); - rv = -1; - } - return rv; -} - -struct dirtest_arg { - PRMonitor *mon; - PRInt32 done; -}; - -static PRInt32 RunDirTest(void) -{ -int i; -PRThread *t; -PRMonitor *mon; -struct dirtest_arg thrarg; - - mon = PR_NewMonitor(); - if (!mon) { - printf("RunDirTest: Error - failed to create monitor\n"); - dirtest_failed = 1; - return -1; - } - thrarg.mon = mon; - - for (i = 0; i < NUM_DIRTEST_THREADS; i++) { - - thrarg.done= 0; - t = create_new_thread(PR_USER_THREAD, - DirTest, &thrarg, - PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, - PR_UNJOINABLE_THREAD, - 0, i); - if (!t) { - printf("RunDirTest: Error - failed to create thread\n"); - dirtest_failed = 1; - return -1; - } - PR_EnterMonitor(mon); - while (!thrarg.done) - PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); - PR_ExitMonitor(mon); - - } - PR_DestroyMonitor(mon); - return 0; -} - -static PRInt32 PR_CALLBACK DirTest(void *arg) -{ -struct dirtest_arg *tinfo = (struct dirtest_arg *) arg; -PRFileDesc *fd_file; -PRDir *fd_dir; -int i; -int path_len; -PRDirEntry *dirEntry; -PRFileInfo info; -PRInt32 num_files = 0; -#if defined(XP_PC) && defined(WIN32) -HANDLE hfile; -#endif - -#define FILES_IN_DIR 20 - - /* - * Create Test dir - */ - DPRINTF(("Creating test dir %s\n",TEST_DIR)); - if ((PR_MkDir(TEST_DIR, 0777)) < 0) { - printf( - "testfile failed to create dir %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - fd_dir = PR_OpenDir(TEST_DIR); - if (fd_dir == NULL) { - printf( - "testfile failed to open dirctory %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - - strcpy(pathname, TEST_DIR); - strcat(pathname, "/"); - strcat(pathname, FILE_NAME); - path_len = strlen(pathname); - - for (i = 0; i < FILES_IN_DIR; i++) { - - sprintf(pathname + path_len,"%d%s",i,""); - - DPRINTF(("Creating test file %s\n",pathname)); - - fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); - - if (fd_file == NULL) { - printf( - "testfile failed to create/open file %s [%d, %d]\n", - pathname, PR_GetError(), PR_GetOSError()); - return -1; - } - PR_Close(fd_file); - } -#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) - /* - * Create a hidden file - a platform-dependent operation - */ - strcpy(pathname, TEST_DIR); - strcat(pathname, "/"); - strcat(pathname, HIDDEN_FILE_NAME); -#if defined(XP_UNIX) || defined(XP_BEOS) - DPRINTF(("Creating hidden test file %s\n",pathname)); - fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); - - if (fd_file == NULL) { - printf( - "testfile failed to create/open hidden file %s [%d, %d]\n", - pathname, PR_GetError(), PR_GetOSError()); - return -1; - } - - PR_Close(fd_file); - -#elif defined(WINCE) - DPRINTF(("Creating hidden test file %s\n",pathname)); - MultiByteToWideChar(CP_ACP, 0, pathname, -1, wPathname, 256); - hfile = CreateFile(wPathname, GENERIC_READ, - FILE_SHARE_READ|FILE_SHARE_WRITE, - NULL, - CREATE_NEW, - FILE_ATTRIBUTE_HIDDEN, - NULL); - if (hfile == INVALID_HANDLE_VALUE) { - printf("testfile failed to create/open hidden file %s [0, %d]\n", - pathname, GetLastError()); - return -1; - } - CloseHandle(hfile); - -#elif defined(XP_PC) && defined(WIN32) - DPRINTF(("Creating hidden test file %s\n",pathname)); - hfile = CreateFile(pathname, GENERIC_READ, - FILE_SHARE_READ|FILE_SHARE_WRITE, - NULL, - CREATE_NEW, - FILE_ATTRIBUTE_HIDDEN, - NULL); - if (hfile == INVALID_HANDLE_VALUE) { - printf("testfile failed to create/open hidden file %s [0, %d]\n", - pathname, GetLastError()); - return -1; - } - CloseHandle(hfile); - -#elif defined(OS2) - DPRINTF(("Creating hidden test file %s\n",pathname)); - fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, (int)FILE_HIDDEN); - - if (fd_file == NULL) { - printf("testfile failed to create/open hidden file %s [%d, %d]\n", - pathname, PR_GetError(), PR_GetOSError()); - return -1; - } - PR_Close(fd_file); -#endif /* XP_UNIX */ - -#endif /* XP_UNIX || (XP_PC && WIN32) */ - - - if (PR_FAILURE == PR_CloseDir(fd_dir)) - { - printf( - "testfile failed to close dirctory %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - fd_dir = PR_OpenDir(TEST_DIR); - if (fd_dir == NULL) { - printf( - "testfile failed to reopen dirctory %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - - /* - * List all files, including hidden files - */ - DPRINTF(("Listing all files in directory %s\n",TEST_DIR)); -#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) - num_files = FILES_IN_DIR + 1; -#else - num_files = FILES_IN_DIR; -#endif - while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) { - num_files--; - strcpy(pathname, TEST_DIR); - strcat(pathname, "/"); - strcat(pathname, dirEntry->name); - DPRINTF(("\t%s\n",dirEntry->name)); - - if ((PR_GetFileInfo(pathname, &info)) < 0) { - printf( - "testfile failed to GetFileInfo file %s [%d, %d]\n", - pathname, PR_GetError(), PR_GetOSError()); - return -1; - } - - if (info.type != PR_FILE_FILE) { - printf( - "testfile incorrect fileinfo for file %s [%d, %d]\n", - pathname, PR_GetError(), PR_GetOSError()); - return -1; - } - } - if (num_files != 0) - { - printf( - "testfile failed to find all files in directory %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - - PR_CloseDir(fd_dir); - -#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) - - /* - * List all files, except hidden files - */ - - fd_dir = PR_OpenDir(TEST_DIR); - if (fd_dir == NULL) { - printf( - "testfile failed to reopen dirctory %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - - DPRINTF(("Listing non-hidden files in directory %s\n",TEST_DIR)); - while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_HIDDEN)) != NULL) { - DPRINTF(("\t%s\n",dirEntry->name)); - if (!strcmp(HIDDEN_FILE_NAME, dirEntry->name)) { - printf("testfile found hidden file %s\n", pathname); - return -1; - } - - } - /* - * Delete hidden file - */ - strcpy(pathname, TEST_DIR); - strcat(pathname, "/"); - strcat(pathname, HIDDEN_FILE_NAME); - if (PR_FAILURE == PR_Delete(pathname)) { - printf( - "testfile failed to delete hidden file %s [%d, %d]\n", - pathname, PR_GetError(), PR_GetOSError()); - return -1; - } - - PR_CloseDir(fd_dir); -#endif /* XP_UNIX || (XP_PC && WIN32) */ - - strcpy(renamename, TEST_DIR); - strcat(renamename, ".RENAMED"); - if (PR_FAILURE == PR_Rename(TEST_DIR, renamename)) { - printf( - "testfile failed to rename directory %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - - if (PR_FAILURE == PR_MkDir(TEST_DIR, 0777)) { - printf( - "testfile failed to recreate dir %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - if (PR_SUCCESS == PR_Rename(renamename, TEST_DIR)) { - printf( - "testfile renamed directory to existing name %s\n", - renamename); - return -1; - } - - if (PR_FAILURE == PR_RmDir(TEST_DIR)) { - printf( - "testfile failed to rmdir %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - - if (PR_FAILURE == PR_Rename(renamename, TEST_DIR)) { - printf( - "testfile failed to rename directory %s [%d, %d]\n", - renamename, PR_GetError(), PR_GetOSError()); - return -1; - } - fd_dir = PR_OpenDir(TEST_DIR); - if (fd_dir == NULL) { - printf( - "testfile failed to reopen directory %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - - strcpy(pathname, TEST_DIR); - strcat(pathname, "/"); - strcat(pathname, FILE_NAME); - path_len = strlen(pathname); - - for (i = 0; i < FILES_IN_DIR; i++) { - - sprintf(pathname + path_len,"%d%s",i,""); - - if (PR_FAILURE == PR_Delete(pathname)) { - printf( - "testfile failed to delete file %s [%d, %d]\n", - pathname, PR_GetError(), PR_GetOSError()); - return -1; - } - } - - PR_CloseDir(fd_dir); - - if (PR_FAILURE == PR_RmDir(TEST_DIR)) { - printf( - "testfile failed to rmdir %s [%d, %d]\n", - TEST_DIR, PR_GetError(), PR_GetOSError()); - return -1; - } - PR_EnterMonitor(tinfo->mon); - tinfo->done = 1; - PR_Notify(tinfo->mon); - PR_ExitMonitor(tinfo->mon); - - return 0; -} -/************************************************************************/ - -/* - * Test file and directory NSPR APIs - */ - -int main(int argc, char **argv) -{ -#ifdef WIN32 - PRUint32 len; -#endif -#if defined(XP_UNIX) || defined(XP_OS2) - int opt; - extern char *optarg; - extern int optind; -#endif -#if defined(XP_UNIX) || defined(XP_OS2) - while ((opt = getopt(argc, argv, "d")) != EOF) { - switch(opt) { - case 'd': - _debug_on = 1; - break; - default: - break; - } - } -#endif - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - mon = PR_NewMonitor(); - if (mon == NULL) { - printf("testfile: PR_NewMonitor failed\n"); - exit(2); - } -#ifdef WIN32 - -#ifdef WINCE - { - WCHAR tdir[TMPDIR_LEN]; - len = GetTempPath(TMPDIR_LEN, tdir); - if ((len > 0) && (len < (TMPDIR_LEN - 6))) { - /* - * enough space for prdir - */ - WideCharToMultiByte(CP_ACP, 0, tdir, -1, testdir, TMPDIR_LEN, 0, 0); - } - } -#else - len = GetTempPath(TMPDIR_LEN, testdir); -#endif /* WINCE */ - - if ((len > 0) && (len < (TMPDIR_LEN - 6))) { - /* - * enough space for prdir - */ - strcpy((testdir + len),"prdir"); - TEST_DIR = testdir; - printf("TEST_DIR = %s\n",TEST_DIR); - } -#endif /* WIN32 */ - - if (FileTest() < 0) { - printf("File Test failed\n"); - exit(2); - } - printf("File Test passed\n"); - if ((RunDirTest() < 0) || dirtest_failed) { - printf("Dir Test failed\n"); - exit(2); - } - printf("Dir Test passed\n"); - - PR_DestroyMonitor(mon); - PR_Cleanup(); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/threads.c nspr-4.10.7/mozilla/nsprpub/pr/tests/threads.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/threads.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/threads.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,203 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" -#include "prinrval.h" -#include "plgetopt.h" -#include "pprthred.h" -#include -#include -#include - -PRMonitor *mon; -PRInt32 count, iterations, alive; - -PRBool debug_mode = PR_FALSE, passed = PR_TRUE; - -void -PR_CALLBACK -ReallyDumbThread(void *arg) -{ - return; -} - -void -PR_CALLBACK -DumbThread(void *arg) -{ - PRInt32 tmp = (PRInt32)arg; - PRThreadScope scope = (PRThreadScope)tmp; - PRThread *thr; - - thr = PR_CreateThread(PR_USER_THREAD, - ReallyDumbThread, - NULL, - PR_PRIORITY_NORMAL, - scope, - PR_JOINABLE_THREAD, - 0); - - if (!thr) { - if (debug_mode) { - printf("Could not create really dumb thread (%d, %d)!\n", - PR_GetError(), PR_GetOSError()); - } - passed = PR_FALSE; - } else { - PR_JoinThread(thr); - } - PR_EnterMonitor(mon); - alive--; - PR_Notify(mon); - PR_ExitMonitor(mon); -} - -static void CreateThreads(PRThreadScope scope1, PRThreadScope scope2) -{ - PRThread *thr; - int n; - - alive = 0; - mon = PR_NewMonitor(); - - alive = count; - for (n=0; noption) - { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'c': /* loop counter */ - count = atoi(opt->value); - break; - case 'i': /* loop counter */ - iterations = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - } - - if (0 == count) count = 50; - if (0 == iterations) iterations = 10; - - if (debug_mode) - { - printf("\ -** Tests lots of thread creations. \n\ -** Create %ld native threads %ld times. \n\ -** Create %ld user threads %ld times \n", iterations,count,iterations,count); - } - - for (index=0; index -#include -#include -#ifdef XP_UNIX -#include -#endif -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) -#include -#endif - -#ifdef WIN32 -#include -#endif - -static int _debug_on = 0; -static int server_port = -1; -static char *program_name = NULL; - -#include "obsolete/prsem.h" - -#ifdef XP_PC -#define mode_t int -#endif - -#define DPRINTF(arg) if (_debug_on) printf arg - -#define BUF_DATA_SIZE (2 * 1024) -#define TCP_MESG_SIZE 1024 -#define NUM_TCP_CLIENTS 10 /* for a listen queue depth of 5 */ - -#define NUM_TCP_CONNECTIONS_PER_CLIENT 10 -#define NUM_TCP_MESGS_PER_CONNECTION 10 -#define TCP_SERVER_PORT 10000 - -static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS; -static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT; -static PRInt32 tcp_mesg_size = TCP_MESG_SIZE; -static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION; - -int failed_already=0; - -typedef struct buffer { - char data[BUF_DATA_SIZE]; -} buffer; - -PRNetAddr tcp_server_addr, udp_server_addr; - -typedef struct Client_Param { - PRNetAddr server_addr; - PRMonitor *exit_mon; /* monitor to signal on exit */ - PRInt32 *exit_counter; /* counter to decrement, before exit */ - PRInt32 datalen; -} Client_Param; - -/* - * readn - * read data from sockfd into buf - */ -static PRInt32 -readn(PRFileDesc *sockfd, char *buf, int len) -{ - int rem; - int bytes; - int offset = 0; - PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; - - for (rem=len; rem; offset += bytes, rem -= bytes) { - DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n", - PR_GetCurrentThread(), rem)); - bytes = PR_Recv(sockfd, buf + offset, rem, 0, - timeout); - DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n", - PR_GetCurrentThread(), bytes)); - if (bytes < 0) { - return -1; - } - } - return len; -} - -/* - * writen - * write data from buf to sockfd - */ -static PRInt32 -writen(PRFileDesc *sockfd, char *buf, int len) -{ - int rem; - int bytes; - int offset = 0; - - for (rem=len; rem; offset += bytes, rem -= bytes) { - DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n", - PR_GetCurrentThread(), rem)); - bytes = PR_Send(sockfd, buf + offset, rem, 0, - PR_INTERVAL_NO_TIMEOUT); - DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n", - PR_GetCurrentThread(), bytes)); - if (bytes <= 0) - return -1; - } - return len; -} - -/* - * TCP_Client - * Client job - * Connect to the server at the address specified in the argument. - * Fill in a buffer, write data to server, read it back and check - * for data corruption. - * Close the socket for server connection - */ -static void PR_CALLBACK -TCP_Client(void *arg) -{ - Client_Param *cp = (Client_Param *) arg; - PRFileDesc *sockfd; - buffer *in_buf, *out_buf; - union PRNetAddr netaddr; - PRInt32 bytes, i, j; - - - DPRINTF(("TCP client started\n")); - bytes = cp->datalen; - out_buf = PR_NEW(buffer); - if (out_buf == NULL) { - fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name); - failed_already=1; - return; - } - in_buf = PR_NEW(buffer); - if (in_buf == NULL) { - fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name); - failed_already=1; - return; - } - netaddr.inet.family = cp->server_addr.inet.family; - netaddr.inet.port = cp->server_addr.inet.port; - netaddr.inet.ip = cp->server_addr.inet.ip; - - for (i = 0; i < num_tcp_connections_per_client; i++) { - if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) { - fprintf(stderr,"%s: PR_OpenTCPSocket failed\n", program_name); - failed_already=1; - return; - } - - DPRINTF(("TCP client connecting to server:%d\n", server_port)); - if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ - fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n", - PR_GetError(), PR_GetOSError()); - failed_already=1; - return; - } - for (j = 0; j < num_tcp_mesgs_per_connection; j++) { - /* - * fill in random data - */ - memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes); - /* - * write to server - */ - if (writen(sockfd, out_buf->data, bytes) < bytes) { - fprintf(stderr,"%s: ERROR - TCP_Client:writen\n", program_name); - failed_already=1; - return; - } - /* - DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", - PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); - */ - if (readn(sockfd, in_buf->data, bytes) < bytes) { - fprintf(stderr,"%s: ERROR - TCP_Client:readn\n", program_name); - failed_already=1; - return; - } - /* - * verify the data read - */ - if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { - fprintf(stderr,"%s: ERROR - data corruption\n", program_name); - failed_already=1; - return; - } - } - /* - * shutdown reads and writes - */ - if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { - fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name); - failed_already=1; - } - PR_Close(sockfd); - } - - PR_DELETE(out_buf); - PR_DELETE(in_buf); - - /* - * Decrement exit_counter and notify parent thread - */ - - PR_EnterMonitor(cp->exit_mon); - --(*cp->exit_counter); - PR_Notify(cp->exit_mon); - PR_ExitMonitor(cp->exit_mon); - DPRINTF(("TCP_Client exiting\n")); -} - -/* - * TCP_Socket_Client_Server_Test - concurrent server test - * - * Each client connects to the server and sends a chunk of data - * For each connection, server reads the data - * from the client and sends it back to the client, unmodified. - * Each client checks that data received from server is same as the - * data it sent to the server. - * - */ - -static PRInt32 -TCP_Socket_Client_Server_Test(void) -{ - int i; - Client_Param *cparamp; - PRMonitor *mon2; - PRInt32 datalen; - PRInt32 connections = 0; - PRThread *thr; - - datalen = tcp_mesg_size; - connections = 0; - - mon2 = PR_NewMonitor(); - if (mon2 == NULL) { - fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name); - failed_already=1; - return -1; - } - - /* - * Start client jobs - */ - cparamp = PR_NEW(Client_Param); - if (cparamp == NULL) { - fprintf(stderr,"%s: PR_NEW failed\n", program_name); - failed_already=1; - return -1; - } - cparamp->server_addr.inet.family = PR_AF_INET; - cparamp->server_addr.inet.port = PR_htons(server_port); - cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); - cparamp->exit_mon = mon2; - cparamp->exit_counter = &connections; - cparamp->datalen = datalen; - for (i = 0; i < num_tcp_clients; i++) { - thr = PR_CreateThread(PR_USER_THREAD, TCP_Client, (void *)cparamp, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); - if (NULL == thr) { - fprintf(stderr,"%s: PR_CreateThread failed\n", program_name); - failed_already=1; - return -1; - } - PR_EnterMonitor(mon2); - connections++; - PR_ExitMonitor(mon2); - DPRINTF(("Created TCP client = 0x%lx\n", thr)); - } - /* Wait for client jobs to exit */ - PR_EnterMonitor(mon2); - while (0 != connections) { - PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); - DPRINTF(("Client job count = %d\n", connections)); - } - PR_ExitMonitor(mon2); - printf("%30s","TCP_Socket_Client_Server_Test:"); - printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l, - num_tcp_clients, num_tcp_connections_per_client); - printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":", - num_tcp_mesgs_per_connection, tcp_mesg_size); - - PR_DELETE(cparamp); - return 0; -} - -/************************************************************************/ - -int main(int argc, char **argv) -{ - /* - * -d debug mode - */ - PLOptStatus os; - PLOptState *opt; - program_name = argv[0]; - - opt = PL_CreateOptState(argc, argv, "dp:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - case 'p': - server_port = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - PR_SetConcurrency(4); - - TCP_Socket_Client_Server_Test(); - - PR_Cleanup(); - if (failed_already) - return 1; - else - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/thrpool_server.c nspr-4.10.7/mozilla/nsprpub/pr/tests/thrpool_server.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/thrpool_server.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/thrpool_server.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,572 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: thrpool.c -** -** Description: Test threadpool functionality. -** -** Modification History: -*/ -#include "primpl.h" - -#include "plgetopt.h" - -#include -#include -#include -#ifdef XP_UNIX -#include -#endif -#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) -#include -#endif - -/* for getcwd */ -#if defined(XP_UNIX) || defined (XP_OS2) || defined(XP_BEOS) -#include -#elif defined(XP_PC) -#include -#endif - -#ifdef WIN32 -#include -#endif - -static int _debug_on = 0; -static char *program_name = NULL; -static void serve_client_write(void *arg); - -#include "obsolete/prsem.h" - -#ifdef XP_PC -#define mode_t int -#endif - -#define DPRINTF(arg) if (_debug_on) printf arg - - -#define BUF_DATA_SIZE (2 * 1024) -#define TCP_MESG_SIZE 1024 -#define NUM_TCP_CLIENTS 10 /* for a listen queue depth of 5 */ - - -#define NUM_TCP_CONNECTIONS_PER_CLIENT 10 -#define NUM_TCP_MESGS_PER_CONNECTION 10 -#define TCP_SERVER_PORT 10000 -#define SERVER_MAX_BIND_COUNT 100 - -#ifdef WINCE -char *getcwd(char *buf, size_t size) -{ - wchar_t wpath[MAX_PATH]; - _wgetcwd(wpath, MAX_PATH); - WideCharToMultiByte(CP_ACP, 0, wpath, -1, buf, size, 0, 0); -} - -#define perror(s) -#endif - -static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS; -static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT; -static PRInt32 tcp_mesg_size = TCP_MESG_SIZE; -static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION; -static void TCP_Server_Accept(void *arg); - - -int failed_already=0; -typedef struct buffer { - char data[BUF_DATA_SIZE]; -} buffer; - - -typedef struct Server_Param { - PRJobIoDesc iod; /* socket to read from/write to */ - PRInt32 datalen; /* bytes of data transfered in each read/write */ - PRNetAddr netaddr; - PRMonitor *exit_mon; /* monitor to signal on exit */ - PRInt32 *job_counterp; /* counter to decrement, before exit */ - PRInt32 conn_counter; /* counter to decrement, before exit */ - PRThreadPool *tp; -} Server_Param; - -typedef struct Serve_Client_Param { - PRJobIoDesc iod; /* socket to read from/write to */ - PRInt32 datalen; /* bytes of data transfered in each read/write */ - PRMonitor *exit_mon; /* monitor to signal on exit */ - PRInt32 *job_counterp; /* counter to decrement, before exit */ - PRThreadPool *tp; -} Serve_Client_Param; - -typedef struct Session { - PRJobIoDesc iod; /* socket to read from/write to */ - buffer *in_buf; - PRInt32 bytes; - PRInt32 msg_num; - PRInt32 bytes_read; - PRMonitor *exit_mon; /* monitor to signal on exit */ - PRInt32 *job_counterp; /* counter to decrement, before exit */ - PRThreadPool *tp; -} Session; - -static void -serve_client_read(void *arg) -{ - Session *sp = (Session *) arg; - int rem; - int bytes; - int offset; - PRFileDesc *sockfd; - char *buf; - PRJob *jobp; - - PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; - - sockfd = sp->iod.socket; - buf = sp->in_buf->data; - - PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection); - PR_ASSERT(sp->bytes_read < sp->bytes); - - offset = sp->bytes_read; - rem = sp->bytes - offset; - bytes = PR_Recv(sockfd, buf + offset, rem, 0, timeout); - if (bytes < 0) { - return; - } - sp->bytes_read += bytes; - sp->iod.timeout = PR_SecondsToInterval(60); - if (sp->bytes_read < sp->bytes) { - jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp, - PR_FALSE); - PR_ASSERT(NULL != jobp); - return; - } - PR_ASSERT(sp->bytes_read == sp->bytes); - DPRINTF(("serve_client: read complete, msg(%d) \n", sp->msg_num)); - - sp->iod.timeout = PR_SecondsToInterval(60); - jobp = PR_QueueJob_Write(sp->tp, &sp->iod, serve_client_write, sp, - PR_FALSE); - PR_ASSERT(NULL != jobp); - - return; -} - -static void -serve_client_write(void *arg) -{ - Session *sp = (Session *) arg; - int bytes; - PRFileDesc *sockfd; - char *buf; - PRJob *jobp; - - sockfd = sp->iod.socket; - buf = sp->in_buf->data; - - PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection); - - bytes = PR_Send(sockfd, buf, sp->bytes, 0, PR_INTERVAL_NO_TIMEOUT); - PR_ASSERT(bytes == sp->bytes); - - if (bytes < 0) { - return; - } - DPRINTF(("serve_client: write complete, msg(%d) \n", sp->msg_num)); - sp->msg_num++; - if (sp->msg_num < num_tcp_mesgs_per_connection) { - sp->bytes_read = 0; - sp->iod.timeout = PR_SecondsToInterval(60); - jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp, - PR_FALSE); - PR_ASSERT(NULL != jobp); - return; - } - - DPRINTF(("serve_client: read/write complete, msg(%d) \n", sp->msg_num)); - if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { - fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name); - } - - PR_Close(sockfd); - PR_EnterMonitor(sp->exit_mon); - --(*sp->job_counterp); - PR_Notify(sp->exit_mon); - PR_ExitMonitor(sp->exit_mon); - - PR_DELETE(sp->in_buf); - PR_DELETE(sp); - - return; -} - -/* - * Serve_Client - * Thread, started by the server, for serving a client connection. - * Reads data from socket and writes it back, unmodified, and - * closes the socket - */ -static void PR_CALLBACK -Serve_Client(void *arg) -{ - Serve_Client_Param *scp = (Serve_Client_Param *) arg; - buffer *in_buf; - Session *sp; - PRJob *jobp; - - sp = PR_NEW(Session); - sp->iod = scp->iod; - - in_buf = PR_NEW(buffer); - if (in_buf == NULL) { - fprintf(stderr,"%s: failed to alloc buffer struct\n",program_name); - failed_already=1; - return; - } - - sp->in_buf = in_buf; - sp->bytes = scp->datalen; - sp->msg_num = 0; - sp->bytes_read = 0; - sp->tp = scp->tp; - sp->exit_mon = scp->exit_mon; - sp->job_counterp = scp->job_counterp; - - sp->iod.timeout = PR_SecondsToInterval(60); - jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp, - PR_FALSE); - PR_ASSERT(NULL != jobp); - PR_DELETE(scp); -} - -static void -print_stats(void *arg) -{ - Server_Param *sp = (Server_Param *) arg; - PRThreadPool *tp = sp->tp; - PRInt32 counter; - PRJob *jobp; - - PR_EnterMonitor(sp->exit_mon); - counter = (*sp->job_counterp); - PR_ExitMonitor(sp->exit_mon); - - printf("PRINT_STATS: #client connections = %d\n",counter); - - - jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(500), - print_stats, sp, PR_FALSE); - - PR_ASSERT(NULL != jobp); -} - -static int job_counter = 0; -/* - * TCP Server - * Server binds an address to a socket, starts a client process and - * listens for incoming connections. - * Each client connects to the server and sends a chunk of data - * Starts a Serve_Client job for each incoming connection, to read - * the data from the client and send it back to the client, unmodified. - * Each client checks that data received from server is same as the - * data it sent to the server. - * Finally, the threadpool is shutdown - */ -static void PR_CALLBACK -TCP_Server(void *arg) -{ - PRThreadPool *tp = (PRThreadPool *) arg; - Server_Param *sp; - PRFileDesc *sockfd; - PRNetAddr netaddr; - PRMonitor *sc_mon; - PRJob *jobp; - int i; - PRStatus rval; - - /* - * Create a tcp socket - */ - if ((sockfd = PR_NewTCPSocket()) == NULL) { - fprintf(stderr,"%s: PR_NewTCPSocket failed\n", program_name); - return; - } - memset(&netaddr, 0 , sizeof(netaddr)); - netaddr.inet.family = PR_AF_INET; - netaddr.inet.port = PR_htons(TCP_SERVER_PORT); - netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); - /* - * try a few times to bind server's address, if addresses are in - * use - */ - i = 0; - while (PR_Bind(sockfd, &netaddr) < 0) { - if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { - netaddr.inet.port += 2; - if (i++ < SERVER_MAX_BIND_COUNT) - continue; - } - fprintf(stderr,"%s: ERROR - PR_Bind failed\n", program_name); - perror("PR_Bind"); - failed_already=1; - return; - } - - if (PR_Listen(sockfd, 32) < 0) { - fprintf(stderr,"%s: ERROR - PR_Listen failed\n", program_name); - failed_already=1; - return; - } - - if (PR_GetSockName(sockfd, &netaddr) < 0) { - fprintf(stderr,"%s: ERROR - PR_GetSockName failed\n", program_name); - failed_already=1; - return; - } - - DPRINTF(( - "TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", - netaddr.inet.ip, netaddr.inet.port)); - - sp = PR_NEW(Server_Param); - if (sp == NULL) { - fprintf(stderr,"%s: PR_NEW failed\n", program_name); - failed_already=1; - return; - } - sp->iod.socket = sockfd; - sp->iod.timeout = PR_SecondsToInterval(60); - sp->datalen = tcp_mesg_size; - sp->exit_mon = sc_mon; - sp->job_counterp = &job_counter; - sp->conn_counter = 0; - sp->tp = tp; - sp->netaddr = netaddr; - - /* create and cancel an io job */ - jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp, - PR_FALSE); - PR_ASSERT(NULL != jobp); - rval = PR_CancelJob(jobp); - PR_ASSERT(PR_SUCCESS == rval); - - /* - * create the client process - */ - { -#define MAX_ARGS 4 - char *argv[MAX_ARGS + 1]; - int index = 0; - char port[32]; - char path[1024 + sizeof("/thrpool_client")]; - - getcwd(path, sizeof(path)); - - (void)strcat(path, "/thrpool_client"); -#ifdef XP_PC - (void)strcat(path, ".exe"); -#endif - argv[index++] = path; - sprintf(port,"%d",PR_ntohs(netaddr.inet.port)); - if (_debug_on) - { - argv[index++] = "-d"; - argv[index++] = "-p"; - argv[index++] = port; - argv[index++] = NULL; - } else { - argv[index++] = "-p"; - argv[index++] = port; - argv[index++] = NULL; - } - PR_ASSERT(MAX_ARGS >= (index - 1)); - - DPRINTF(("creating client process %s ...\n", path)); - if (PR_FAILURE == PR_CreateProcessDetached(path, argv, NULL, NULL)) { - fprintf(stderr, - "thrpool_server: ERROR - PR_CreateProcessDetached failed\n"); - failed_already=1; - return; - } - } - - sc_mon = PR_NewMonitor(); - if (sc_mon == NULL) { - fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name); - failed_already=1; - return; - } - - sp->iod.socket = sockfd; - sp->iod.timeout = PR_SecondsToInterval(60); - sp->datalen = tcp_mesg_size; - sp->exit_mon = sc_mon; - sp->job_counterp = &job_counter; - sp->conn_counter = 0; - sp->tp = tp; - sp->netaddr = netaddr; - - /* create and cancel a timer job */ - jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(5000), - print_stats, sp, PR_FALSE); - PR_ASSERT(NULL != jobp); - rval = PR_CancelJob(jobp); - PR_ASSERT(PR_SUCCESS == rval); - - DPRINTF(("TCP_Server: Accepting connections \n")); - - jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp, - PR_FALSE); - PR_ASSERT(NULL != jobp); - return; -} - -static void -TCP_Server_Accept(void *arg) -{ - Server_Param *sp = (Server_Param *) arg; - PRThreadPool *tp = sp->tp; - Serve_Client_Param *scp; - PRFileDesc *newsockfd; - PRJob *jobp; - - if ((newsockfd = PR_Accept(sp->iod.socket, &sp->netaddr, - PR_INTERVAL_NO_TIMEOUT)) == NULL) { - fprintf(stderr,"%s: ERROR - PR_Accept failed\n", program_name); - failed_already=1; - goto exit; - } - scp = PR_NEW(Serve_Client_Param); - if (scp == NULL) { - fprintf(stderr,"%s: PR_NEW failed\n", program_name); - failed_already=1; - goto exit; - } - - /* - * Start a Serve_Client job for each incoming connection - */ - scp->iod.socket = newsockfd; - scp->iod.timeout = PR_SecondsToInterval(60); - scp->datalen = tcp_mesg_size; - scp->exit_mon = sp->exit_mon; - scp->job_counterp = sp->job_counterp; - scp->tp = sp->tp; - - PR_EnterMonitor(sp->exit_mon); - (*sp->job_counterp)++; - PR_ExitMonitor(sp->exit_mon); - jobp = PR_QueueJob(tp, Serve_Client, scp, - PR_FALSE); - - PR_ASSERT(NULL != jobp); - DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", jobp)); - - /* - * single-threaded update; no lock needed - */ - sp->conn_counter++; - if (sp->conn_counter < - (num_tcp_clients * num_tcp_connections_per_client)) { - jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp, - PR_FALSE); - PR_ASSERT(NULL != jobp); - return; - } - jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(500), - print_stats, sp, PR_FALSE); - - PR_ASSERT(NULL != jobp); - DPRINTF(("TCP_Server: Created print_stats timer job = 0x%lx\n", jobp)); - -exit: - PR_EnterMonitor(sp->exit_mon); - /* Wait for server jobs to finish */ - while (0 != *sp->job_counterp) { - PR_Wait(sp->exit_mon, PR_INTERVAL_NO_TIMEOUT); - DPRINTF(("TCP_Server: conn_counter = %d\n", - *sp->job_counterp)); - } - - PR_ExitMonitor(sp->exit_mon); - if (sp->iod.socket) { - PR_Close(sp->iod.socket); - } - PR_DestroyMonitor(sp->exit_mon); - printf("%30s","TCP_Socket_Client_Server_Test:"); - printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l, - num_tcp_clients, num_tcp_connections_per_client); - printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":", - num_tcp_mesgs_per_connection, tcp_mesg_size); - - DPRINTF(("%s: calling PR_ShutdownThreadPool\n", program_name)); - PR_ShutdownThreadPool(sp->tp); - PR_DELETE(sp); -} - -/************************************************************************/ - -#define DEFAULT_INITIAL_THREADS 4 -#define DEFAULT_MAX_THREADS 100 -#define DEFAULT_STACKSIZE (512 * 1024) - -int main(int argc, char **argv) -{ - PRInt32 initial_threads = DEFAULT_INITIAL_THREADS; - PRInt32 max_threads = DEFAULT_MAX_THREADS; - PRInt32 stacksize = DEFAULT_STACKSIZE; - PRThreadPool *tp = NULL; - PRStatus rv; - PRJob *jobp; - - /* - * -d debug mode - */ - PLOptStatus os; - PLOptState *opt; - - program_name = argv[0]; - opt = PL_CreateOptState(argc, argv, "d"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - _debug_on = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - PR_SetConcurrency(4); - - tp = PR_CreateThreadPool(initial_threads, max_threads, stacksize); - if (NULL == tp) { - printf("PR_CreateThreadPool failed\n"); - failed_already=1; - goto done; - } - jobp = PR_QueueJob(tp, TCP_Server, tp, PR_TRUE); - rv = PR_JoinJob(jobp); - PR_ASSERT(PR_SUCCESS == rv); - - DPRINTF(("%s: calling PR_JoinThreadPool\n", program_name)); - rv = PR_JoinThreadPool(tp); - PR_ASSERT(PR_SUCCESS == rv); - DPRINTF(("%s: returning from PR_JoinThreadPool\n", program_name)); - -done: - PR_Cleanup(); - if (failed_already) return 1; - else return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/thruput.c nspr-4.10.7/mozilla/nsprpub/pr/tests/thruput.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/thruput.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/thruput.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,379 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: thruput.c -** Description: Test server's throughput capability comparing various -** implmentation strategies. -** -** Note: Requires a server machine and an aribitrary number of -** clients to bang on it. Trust the numbers on the server -** more than those being displayed by the various clients. -*/ - -#include "prerror.h" -#include "prinrval.h" -#include "prinit.h" -#include "prio.h" -#include "prlock.h" -#include "prmem.h" -#include "prnetdb.h" -#include "prprf.h" -#include "prthread.h" -#include "pprio.h" -#include "plerror.h" -#include "plgetopt.h" - -#define ADDR_BUFFER 100 -#define PORT_NUMBER 51877 -#define SAMPLING_INTERVAL 10 -#define BUFFER_SIZE (32 * 1024) - -static PRInt32 domain = PR_AF_INET; -static PRInt32 protocol = 6; /* TCP */ -static PRFileDesc *err = NULL; -static PRIntn concurrency = 1; -static PRInt32 xport_buffer = -1; -static PRUint32 initial_streams = 1; -static PRInt32 buffer_size = BUFFER_SIZE; -static PRThreadScope thread_scope = PR_LOCAL_THREAD; - -typedef struct Shared -{ - PRLock *ml; - PRUint32 sampled; - PRUint32 threads; - PRIntervalTime timein; - PRNetAddr server_address; -} Shared; - -static Shared *shared = NULL; - -static PRStatus PrintAddress(const PRNetAddr* address) -{ - char buffer[ADDR_BUFFER]; - PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); - if (PR_SUCCESS == rv) - PR_fprintf(err, "%s:%u\n", buffer, PR_ntohs(address->inet.port)); - else PL_FPrintError(err, "PR_NetAddrToString"); - return rv; -} /* PrintAddress */ - - -static void PR_CALLBACK Clientel(void *arg) -{ - PRStatus rv; - PRFileDesc *xport; - PRInt32 bytes, sampled; - PRIntervalTime now, interval; - PRBool do_display = PR_FALSE; - Shared *shared = (Shared*)arg; - char *buffer = (char*)PR_Malloc(buffer_size); - PRNetAddr *server_address = &shared->server_address; - PRIntervalTime connect_timeout = PR_SecondsToInterval(5); - PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL); - - PR_fprintf(err, "Client connecting to "); - (void)PrintAddress(server_address); - - do - { - xport = PR_Socket(domain, PR_SOCK_STREAM, protocol); - if (NULL == xport) - { - PL_FPrintError(err, "PR_Socket"); - return; - } - - if (xport_buffer != -1) - { - PRSocketOptionData data; - data.option = PR_SockOpt_RecvBufferSize; - data.value.recv_buffer_size = (PRSize)xport_buffer; - rv = PR_SetSocketOption(xport, &data); - if (PR_FAILURE == rv) - PL_FPrintError(err, "PR_SetSocketOption - ignored"); - data.option = PR_SockOpt_SendBufferSize; - data.value.send_buffer_size = (PRSize)xport_buffer; - rv = PR_SetSocketOption(xport, &data); - if (PR_FAILURE == rv) - PL_FPrintError(err, "PR_SetSocketOption - ignored"); - } - - rv = PR_Connect(xport, server_address, connect_timeout); - if (PR_FAILURE == rv) - { - PL_FPrintError(err, "PR_Connect"); - if (PR_IO_TIMEOUT_ERROR != PR_GetError()) - PR_Sleep(connect_timeout); - PR_Close(xport); /* delete it and start over */ - } - } while (PR_FAILURE == rv); - - do - { - bytes = PR_Recv( - xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT); - PR_Lock(shared->ml); - now = PR_IntervalNow(); - shared->sampled += bytes; - interval = now - shared->timein; - if (interval > sampling_interval) - { - sampled = shared->sampled; - shared->timein = now; - shared->sampled = 0; - do_display = PR_TRUE; - } - PR_Unlock(shared->ml); - - if (do_display) - { - PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval); - PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate); - do_display = PR_FALSE; - } - - } while (bytes > 0); -} /* Clientel */ - -static void Client(const char *server_name) -{ - PRStatus rv; - PRHostEnt host; - char buffer[PR_NETDB_BUF_SIZE]; - PRIntervalTime dally = PR_SecondsToInterval(60); - PR_fprintf(err, "Translating the name %s\n", server_name); - rv = PR_GetHostByName(server_name, buffer, sizeof(buffer), &host); - if (PR_FAILURE == rv) - PL_FPrintError(err, "PR_GetHostByName"); - else - { - if (PR_EnumerateHostEnt( - 0, &host, PORT_NUMBER, &shared->server_address) < 0) - PL_FPrintError(err, "PR_EnumerateHostEnt"); - else - { - do - { - shared->threads += 1; - (void)PR_CreateThread( - PR_USER_THREAD, Clientel, shared, - PR_PRIORITY_NORMAL, thread_scope, - PR_UNJOINABLE_THREAD, 8 * 1024); - if (shared->threads == initial_streams) - { - PR_Sleep(dally); - initial_streams += 1; - } - } while (PR_TRUE); - } - } -} - -static void PR_CALLBACK Servette(void *arg) -{ - PRInt32 bytes, sampled; - PRIntervalTime now, interval; - PRBool do_display = PR_FALSE; - PRFileDesc *client = (PRFileDesc*)arg; - char *buffer = (char*)PR_Malloc(buffer_size); - PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL); - - if (xport_buffer != -1) - { - PRStatus rv; - PRSocketOptionData data; - data.option = PR_SockOpt_RecvBufferSize; - data.value.recv_buffer_size = (PRSize)xport_buffer; - rv = PR_SetSocketOption(client, &data); - if (PR_FAILURE == rv) - PL_FPrintError(err, "PR_SetSocketOption - ignored"); - data.option = PR_SockOpt_SendBufferSize; - data.value.send_buffer_size = (PRSize)xport_buffer; - rv = PR_SetSocketOption(client, &data); - if (PR_FAILURE == rv) - PL_FPrintError(err, "PR_SetSocketOption - ignored"); - } - - do - { - bytes = PR_Send( - client, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT); - - PR_Lock(shared->ml); - now = PR_IntervalNow(); - shared->sampled += bytes; - interval = now - shared->timein; - if (interval > sampling_interval) - { - sampled = shared->sampled; - shared->timein = now; - shared->sampled = 0; - do_display = PR_TRUE; - } - PR_Unlock(shared->ml); - - if (do_display) - { - PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval); - PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate); - do_display = PR_FALSE; - } - } while (bytes > 0); -} /* Servette */ - -static void Server(void) -{ - PRStatus rv; - PRNetAddr server_address, client_address; - PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol); - - if (NULL == xport) - { - PL_FPrintError(err, "PR_Socket"); - return; - } - - rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER, &server_address); - if (PR_FAILURE == rv) PL_FPrintError(err, "PR_InitializeNetAddr"); - else - { - rv = PR_Bind(xport, &server_address); - if (PR_FAILURE == rv) PL_FPrintError(err, "PR_Bind"); - else - { - PRFileDesc *client; - rv = PR_Listen(xport, 10); - PR_fprintf(err, "Server listening on "); - (void)PrintAddress(&server_address); - do - { - client = PR_Accept( - xport, &client_address, PR_INTERVAL_NO_TIMEOUT); - if (NULL == client) PL_FPrintError(err, "PR_Accept"); - else - { - PR_fprintf(err, "Server accepting from "); - (void)PrintAddress(&client_address); - shared->threads += 1; - (void)PR_CreateThread( - PR_USER_THREAD, Servette, client, - PR_PRIORITY_NORMAL, thread_scope, - PR_UNJOINABLE_THREAD, 8 * 1024); - } - } while (PR_TRUE); - - } - } -} /* Server */ - -static void Help(void) -{ - PR_fprintf(err, "Usage: [-h] []\n"); - PR_fprintf(err, "\t-s Initial # of connections (default: 1)\n"); - PR_fprintf(err, "\t-C Set 'concurrency' (default: 1)\n"); - PR_fprintf(err, "\t-b Client buffer size (default: 32k)\n"); - PR_fprintf(err, "\t-B Transport recv/send buffer size (default: sys)\n"); - PR_fprintf(err, "\t-G Use GLOBAL threads (default: LOCAL)\n"); - PR_fprintf(err, "\t-X Use XTP transport (default: TCP)\n"); - PR_fprintf(err, "\t-6 Use IPv6 (default: IPv4)\n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); - PR_fprintf(err, "\t DNS name of server\n"); - PR_fprintf(err, "\t\tIf is not specified, this host will be\n"); - PR_fprintf(err, "\t\tthe server and not act as a client.\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PLOptStatus os; - const char *server_name = NULL; - PLOptState *opt = PL_CreateOptState(argc, argv, "hGX6C:b:s:B:"); - - err = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: /* Name of server */ - server_name = opt->value; - break; - case 'G': /* Globular threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'X': /* Use XTP as the transport */ - protocol = 36; - break; - case '6': /* Use IPv6 */ - domain = PR_AF_INET6; - break; - case 's': /* initial_streams */ - initial_streams = atoi(opt->value); - break; - case 'C': /* concurrency */ - concurrency = atoi(opt->value); - break; - case 'b': /* buffer size */ - buffer_size = 1024 * atoi(opt->value); - break; - case 'B': /* buffer size */ - xport_buffer = 1024 * atoi(opt->value); - break; - case 'h': /* user wants some guidance */ - default: - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - } - } - PL_DestroyOptState(opt); - - shared = PR_NEWZAP(Shared); - shared->ml = PR_NewLock(); - - PR_fprintf(err, - "This machine is %s\n", - (NULL == server_name) ? "the SERVER" : "a CLIENT"); - - PR_fprintf(err, - "Transport being used is %s\n", - (6 == protocol) ? "TCP" : "XTP"); - - if (PR_GLOBAL_THREAD == thread_scope) - { - if (1 != concurrency) - { - PR_fprintf(err, " **Concurrency > 1 and GLOBAL threads!?!?\n"); - PR_fprintf(err, " **Ignoring concurrency\n"); - concurrency = 1; - } - } - - if (1 != concurrency) - { - PR_SetConcurrency(concurrency); - PR_fprintf(err, "Concurrency set to %u\n", concurrency); - } - - PR_fprintf(err, - "All threads will be %s\n", - (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); - - PR_fprintf(err, "Client buffer size will be %u\n", buffer_size); - - if (-1 != xport_buffer) - PR_fprintf( - err, "Transport send & receive buffer size will be %u\n", xport_buffer); - - - if (NULL == server_name) Server(); - else Client(server_name); - - return 0; -} /* main */ - -/* thruput.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/time.c nspr-4.10.7/mozilla/nsprpub/pr/tests/time.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/time.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/time.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,169 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Program to test different ways to get the time; right now it is tuned - * only for solaris. - * solaris results (100000 iterations): - * time to get time with time(): 4.63 usec avg, 463 msec total - * time to get time with gethrtime(): 2.17 usec avg, 217 msec total - * time to get time with gettimeofday(): 1.25 usec avg, 125 msec total - * - * - */ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include "prpriv.h" -#include "prinrval.h" - -#include -#include -#include -#include - -#define DEFAULT_COUNT 100000 -PRInt32 count; - -time_t itime; -hrtime_t ihrtime; - -void -ftime_init() -{ - itime = time(NULL); - ihrtime = gethrtime(); -} - -time_t -ftime() -{ - hrtime_t now = gethrtime(); - - return itime + ((now - ihrtime) / 1000000000ll); -} - -static void timeTime(void) -{ - PRInt32 index = count; - time_t rv; - - for (;index--;) - rv = time(NULL); -} - -static void timeGethrtime(void) -{ - PRInt32 index = count; - time_t rv; - - for (;index--;) - rv = ftime(); -} - -static void timeGettimeofday(void) -{ - PRInt32 index = count; - time_t rv; - struct timeval tp; - - for (;index--;) - rv = gettimeofday(&tp, NULL); -} - -static void timePRTime32(void) -{ - PRInt32 index = count; - PRInt32 rv32; - PRTime q; - PRTime rv; - - LL_I2L(q, 1000000); - - for (;index--;) { - rv = PR_Now(); - LL_DIV(rv, rv, q); - LL_L2I(rv32, rv); - } -} - -static void timePRTime64(void) -{ - PRInt32 index = count; - PRTime rv; - - for (;index--;) - rv = PR_Now(); -} - -/************************************************************************/ - -static void Measure(void (*func)(void), const char *msg) -{ - PRIntervalTime start, stop; - double d; - PRInt32 tot; - - start = PR_IntervalNow(); - (*func)(); - stop = PR_IntervalNow(); - - d = (double)PR_IntervalToMicroseconds(stop - start); - tot = PR_IntervalToMilliseconds(stop-start); - - if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot); -} - -int main(int argc, char **argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - - if (argc > 1) { - count = atoi(argv[1]); - } else { - count = DEFAULT_COUNT; - } - - ftime_init(); - - Measure(timeTime, "time to get time with time()"); - Measure(timeGethrtime, "time to get time with gethrtime()"); - Measure(timeGettimeofday, "time to get time with gettimeofday()"); - Measure(timePRTime32, "time to get time with PR_Time() (32bit)"); - Measure(timePRTime64, "time to get time with PR_Time() (64bit)"); - - PR_Cleanup(); - return 0; -} - - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/timemac.c nspr-4.10.7/mozilla/nsprpub/pr/tests/timemac.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/timemac.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/timemac.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * file: timemac.c - * description: test time and date routines on the Mac - */ -#include -#include "prinit.h" -#include "prtime.h" - - -static char *dayOfWeek[] = - { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; -static char *month[] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; - -static void printExplodedTime(const PRExplodedTime *et) { - PRInt32 totalOffset; - PRInt32 hourOffset, minOffset; - const char *sign; - - /* Print day of the week, month, day, hour, minute, and second */ - printf( "%s %s %ld %02ld:%02ld:%02ld ", - dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, - et->tm_hour, et->tm_min, et->tm_sec); - - /* Print time zone */ - totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; - if (totalOffset == 0) { - printf("UTC "); - } else { - sign = ""; - if (totalOffset < 0) { - totalOffset = -totalOffset; - sign = "-"; - } - hourOffset = totalOffset / 3600; - minOffset = (totalOffset % 3600) / 60; - printf("%s%02ld%02ld ", sign, hourOffset, minOffset); - } - - /* Print year */ - printf("%d", et->tm_year); -} - -int main(int argc, char** argv) -{ - PR_STDIO_INIT(); - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - - /* - ************************************************************* - ** - ** Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime - ** on the current time - ** - ************************************************************* - */ - - { - PRTime t1, t2; - PRExplodedTime et; - - printf("*********************************************\n"); - printf("** **\n"); - printf("** Testing PR_Now(), PR_ExplodeTime, and **\n"); - printf("** PR_ImplodeTime on the current time **\n"); - printf("** **\n"); - printf("*********************************************\n\n"); - t1 = PR_Now(); - - /* First try converting to UTC */ - - PR_ExplodeTime(t1, PR_GMTParameters, &et); - if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) { - printf("ERROR: UTC has nonzero gmt or dst offset.\n"); - return 1; - } - printf("Current UTC is "); - printExplodedTime(&et); - printf("\n"); - - t2 = PR_ImplodeTime(&et); - if (LL_NE(t1, t2)) { - printf("ERROR: Explode and implode are NOT inverse.\n"); - return 1; - } - - /* Next, try converting to local (US Pacific) time */ - - PR_ExplodeTime(t1, PR_LocalTimeParameters, &et); - printf("Current local time is "); - printExplodedTime(&et); - printf("\n"); - printf("GMT offset is %ld, DST offset is %ld\n", - et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset); - t2 = PR_ImplodeTime(&et); - if (LL_NE(t1, t2)) { - printf("ERROR: Explode and implode are NOT inverse.\n"); - return 1; - } - } - - printf("Please examine the results\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/timetest.c nspr-4.10.7/mozilla/nsprpub/pr/tests/timetest.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/timetest.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/timetest.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,739 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * file: timetest.c - * description: test time and date routines - */ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prinit.h" -#include "prtime.h" -#include "prprf.h" - -#include -#include -#include - -int failed_already=0; -PRBool debug_mode = PR_FALSE; - -static char *dayOfWeek[] = - { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; -static char *month[] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; - -static void PrintExplodedTime(const PRExplodedTime *et) { - PRInt32 totalOffset; - PRInt32 hourOffset, minOffset; - const char *sign; - - /* Print day of the week, month, day, hour, minute, and second */ - if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ", - dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, - et->tm_hour, et->tm_min, et->tm_sec); - - /* Print time zone */ - totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; - if (totalOffset == 0) { - if (debug_mode) printf("UTC "); - } else { - sign = "+"; - if (totalOffset < 0) { - totalOffset = -totalOffset; - sign = "-"; - } - hourOffset = totalOffset / 3600; - minOffset = (totalOffset % 3600) / 60; - if (debug_mode) - printf("%s%02ld%02ld ", sign, hourOffset, minOffset); - } - - /* Print year */ - if (debug_mode) printf("%hd", et->tm_year); -} - -static int ExplodedTimeIsEqual(const PRExplodedTime *et1, - const PRExplodedTime *et2) -{ - if (et1->tm_usec == et2->tm_usec && - et1->tm_sec == et2->tm_sec && - et1->tm_min == et2->tm_min && - et1->tm_hour == et2->tm_hour && - et1->tm_mday == et2->tm_mday && - et1->tm_month == et2->tm_month && - et1->tm_year == et2->tm_year && - et1->tm_wday == et2->tm_wday && - et1->tm_yday == et2->tm_yday && - et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset && - et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) { - return 1; - } else { - return 0; - } -} - -static void -testParseTimeString(PRTime t) -{ - PRExplodedTime et; - PRTime t2; - char timeString[128]; - char buf[128]; - PRInt32 totalOffset; - PRInt32 hourOffset, minOffset; - const char *sign; - PRInt64 usec_per_sec; - - /* Truncate the microsecond part of PRTime */ - LL_I2L(usec_per_sec, PR_USEC_PER_SEC); - LL_DIV(t, t, usec_per_sec); - LL_MUL(t, t, usec_per_sec); - - PR_ExplodeTime(t, PR_LocalTimeParameters, &et); - - /* Print day of the week, month, day, hour, minute, and second */ - PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ", - dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday, - et.tm_hour, et.tm_min, et.tm_sec); - /* Print time zone */ - totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset; - if (totalOffset == 0) { - strcat(timeString, "GMT "); /* I wanted to use "UTC" here, but - * PR_ParseTimeString doesn't - * understand "UTC". */ - } else { - sign = "+"; - if (totalOffset < 0) { - totalOffset = -totalOffset; - sign = "-"; - } - hourOffset = totalOffset / 3600; - minOffset = (totalOffset % 3600) / 60; - PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset); - strcat(timeString, buf); - } - /* Print year */ - PR_snprintf(buf, 128, "%hd", et.tm_year); - strcat(timeString, buf); - - if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) { - fprintf(stderr, "PR_ParseTimeString() failed\n"); - exit(1); - } - if (LL_NE(t, t2)) { - fprintf(stderr, "PR_ParseTimeString() incorrect\n"); - PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n", - t, t2, timeString); - fprintf(stderr, "%s\n", buf); - exit(1); - } -} - -int main(int argc, char** argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt; - - PR_STDIO_INIT(); - opt = PL_CreateOptState(argc, argv, "d"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - - /* Testing zero PRTime (the epoch) */ - { - PRTime t; - PRExplodedTime et; - - LL_I2L(t, 0); - if (debug_mode) printf("The NSPR epoch is:\n"); - PR_ExplodeTime(t, PR_LocalTimeParameters, &et); - PrintExplodedTime(&et); - if (debug_mode) printf("\n"); - PR_ExplodeTime(t, PR_GMTParameters, &et); - PrintExplodedTime(&et); - if (debug_mode) printf("\n\n"); - testParseTimeString(t); - } - - /* - ************************************************************* - ** - ** Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime - ** on the current time - ** - ************************************************************* - */ - - { - PRTime t1, t2; - PRExplodedTime et; - - if (debug_mode) { - printf("*********************************************\n"); - printf("** **\n"); - printf("** Testing PR_Now(), PR_ExplodeTime, and **\n"); - printf("** PR_ImplodeTime on the current time **\n"); - printf("** **\n"); - printf("*********************************************\n\n"); - } - t1 = PR_Now(); - - /* First try converting to UTC */ - - PR_ExplodeTime(t1, PR_GMTParameters, &et); - if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) { - if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n"); - else failed_already=1; - return 1; - } - if (debug_mode) printf("Current UTC is "); - PrintExplodedTime(&et); - if (debug_mode) printf("\n"); - - t2 = PR_ImplodeTime(&et); - if (LL_NE(t1, t2)) { - if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n"); - else printf("FAIL\n"); - return 1; - } - - /* Next, try converting to local (US Pacific) time */ - - PR_ExplodeTime(t1, PR_LocalTimeParameters, &et); - if (debug_mode) printf("Current local time is "); - PrintExplodedTime(&et); - if (debug_mode) printf("\n"); - if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n", - et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset); - t2 = PR_ImplodeTime(&et); - if (LL_NE(t1, t2)) { - if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n"); - return 1; - } - - if (debug_mode) printf("Please examine the results\n"); - testParseTimeString(t1); - } - - - /* - ******************************************* - ** - ** Testing PR_NormalizeTime() - ** - ******************************************* - */ - - /* July 4, 2001 is Wednesday */ - { - PRExplodedTime et; - - if (debug_mode) { - printf("\n"); - printf("**********************************\n"); - printf("** **\n"); - printf("** Testing PR_NormalizeTime() **\n"); - printf("** **\n"); - printf("**********************************\n\n"); - } - et.tm_year = 2001; - et.tm_month = 7 - 1; - et.tm_mday = 4; - et.tm_hour = 0; - et.tm_min = 0; - et.tm_sec = 0; - et.tm_usec = 0; - et.tm_params = PR_GMTParameters(&et); - - PR_NormalizeTime(&et, PR_GMTParameters); - - if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]); - if (et.tm_wday == 3) { - if (debug_mode) printf("PASS\n"); - } else { - if (debug_mode) printf("ERROR: It should be Wednesday\n"); - else failed_already=1; - return 1; - } - testParseTimeString(PR_ImplodeTime(&et)); - - /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */ - et.tm_year = 1997; - et.tm_month = 6 - 1; - et.tm_mday = 12; - et.tm_hour = 23; - et.tm_min = 0; - et.tm_sec = 0; - et.tm_usec = 0; - et.tm_params.tp_gmt_offset = -8 * 3600; - et.tm_params.tp_dst_offset = 0; - - PR_NormalizeTime(&et, PR_USPacificTimeParameters); - - if (debug_mode) { - printf("Thu Jun 12, 1997 23:00:00 PST is "); - } - PrintExplodedTime(&et); - if (debug_mode) printf(".\n"); - if (et.tm_wday == 5) { - if (debug_mode) printf("PASS\n"); - } else { - if (debug_mode) printf("ERROR: It should be Friday\n"); - else failed_already=1; - return 1; - } - testParseTimeString(PR_ImplodeTime(&et)); - - /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */ - et.tm_year = 1997; - et.tm_month = 2 - 1; - et.tm_mday = 14; - et.tm_hour = 0; - et.tm_min = 0; - et.tm_sec = 0; - et.tm_usec = 0; - et.tm_params.tp_gmt_offset = -8 * 3600; - et.tm_params.tp_dst_offset = 3600; - - PR_NormalizeTime(&et, PR_USPacificTimeParameters); - - if (debug_mode) { - printf("Fri Feb 14, 1997 00:00:00 PDT is "); - } - PrintExplodedTime(&et); - if (debug_mode) printf(".\n"); - if (et.tm_wday == 4) { - if (debug_mode) printf("PASS\n"); - } else { - if (debug_mode) printf("ERROR: It should be Thursday\n"); - else failed_already=1; - return 1; - } - testParseTimeString(PR_ImplodeTime(&et)); - - /* What time is Nov. 7, 1996, 18:29:23 PDT? */ - et.tm_year = 1996; - et.tm_month = 11 - 1; - et.tm_mday = 7; - et.tm_hour = 18; - et.tm_min = 29; - et.tm_sec = 23; - et.tm_usec = 0; - et.tm_params.tp_gmt_offset = -8 * 3600; /* PDT */ - et.tm_params.tp_dst_offset = 3600; - - PR_NormalizeTime(&et, PR_LocalTimeParameters); - if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is "); - PrintExplodedTime(&et); - if (debug_mode) printf(".\n"); - testParseTimeString(PR_ImplodeTime(&et)); - - /* What time is Oct. 7, 1995, 18:29:23 PST? */ - et.tm_year = 1995; - et.tm_month = 10 - 1; - et.tm_mday = 7; - et.tm_hour = 18; - et.tm_min = 29; - et.tm_sec = 23; - et.tm_params.tp_gmt_offset = -8 * 3600; /* PST */ - et.tm_params.tp_dst_offset = 0; - - PR_NormalizeTime(&et, PR_LocalTimeParameters); - if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is "); - PrintExplodedTime(&et); - if (debug_mode) printf(".\n"); - testParseTimeString(PR_ImplodeTime(&et)); - - if (debug_mode) printf("Please examine the results\n"); - } - - /* - ************************************************************** - ** - ** Testing range of years - ** - ************************************************************** - */ - - { - PRExplodedTime et1, et2; - PRTime ttt; - PRTime secs; - - if (debug_mode) { - printf("\n"); - printf("***************************************\n"); - printf("** **\n"); - printf("** Testing range of years **\n"); - printf("** **\n"); - printf("***************************************\n\n"); - } - /* April 4, 1917 GMT */ - et1.tm_usec = 0; - et1.tm_sec = 0; - et1.tm_min = 0; - et1.tm_hour = 0; - et1.tm_mday = 4; - et1.tm_month = 4 - 1; - et1.tm_year = 1917; - et1.tm_params = PR_GMTParameters(&et1); - PR_NormalizeTime(&et1, PR_LocalTimeParameters); - secs = PR_ImplodeTime(&et1); - if (LL_GE_ZERO(secs)) { - if (debug_mode) - printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n"); - failed_already = 1; - return 1; - } - PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2); - if (!ExplodedTimeIsEqual(&et1, &et2)) { - if (debug_mode) - printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n"); - failed_already=1; - return 1; - } - ttt = PR_ImplodeTime(&et1); - testParseTimeString( ttt ); - - if (debug_mode) printf("Test passed for April 4, 1917\n"); - - /* July 4, 2050 */ - et1.tm_usec = 0; - et1.tm_sec = 0; - et1.tm_min = 0; - et1.tm_hour = 0; - et1.tm_mday = 4; - et1.tm_month = 7 - 1; - et1.tm_year = 2050; - et1.tm_params = PR_GMTParameters(&et1); - PR_NormalizeTime(&et1, PR_LocalTimeParameters); - secs = PR_ImplodeTime(&et1); - if (!LL_GE_ZERO(secs)) { - if (debug_mode) - printf("ERROR: July 4, 2050 GMT returns a negative second count\n"); - failed_already = 1; - return 1; - } - PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2); - if (!ExplodedTimeIsEqual(&et1, &et2)) { - if (debug_mode) - printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n"); - failed_already=1; - return 1; - } - testParseTimeString(PR_ImplodeTime(&et1)); - - if (debug_mode) printf("Test passed for July 4, 2050\n"); - - } - - /* - ************************************************************** - ** - ** Stress test - * - ** Go through four years, starting from - ** 00:00:00 PST Jan. 1, 2005, incrementing - ** every 10 minutes. - ** - ************************************************************** - */ - - { - PRExplodedTime et, et1, et2; - PRInt64 usecPer10Min; - int day, hour, min; - PRTime usecs; - int dstInEffect = 0; - - if (debug_mode) { - printf("\n"); - printf("*******************************************************\n"); - printf("** **\n"); - printf("** Stress test Pacific Time **\n"); - printf("** Starting from midnight Jan. 1, 2005 PST, **\n"); - printf("** going through four years in 10-minute increment **\n"); - printf("** **\n"); - printf("*******************************************************\n\n"); - } - LL_I2L(usecPer10Min, 600000000L); - - /* 00:00:00 PST Jan. 1, 2005 */ - et.tm_usec = 0; - et.tm_sec = 0; - et.tm_min = 0; - et.tm_hour = 0; - et.tm_mday = 1; - et.tm_month = 0; - et.tm_year = 2005; - et.tm_params.tp_gmt_offset = -8 * 3600; - et.tm_params.tp_dst_offset = 0; - usecs = PR_ImplodeTime(&et); - - for (day = 0; day < 4 * 365 + 1; day++) { - for (hour = 0; hour < 24; hour++) { - for (min = 0; min < 60; min += 10) { - LL_ADD(usecs, usecs, usecPer10Min); - PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1); - - et2 = et; - et2.tm_usec += 600000000L; - PR_NormalizeTime(&et2, PR_USPacificTimeParameters); - - if (!ExplodedTimeIsEqual(&et1, &et2)) { - printf("ERROR: componentwise comparison failed\n"); - PrintExplodedTime(&et1); - printf("\n"); - PrintExplodedTime(&et2); - printf("\n"); - failed_already=1; - return 1; - } - - if (LL_NE(usecs, PR_ImplodeTime(&et1))) { - printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); - PrintExplodedTime(&et1); - printf("\n"); - failed_already=1; - return 1; - } - testParseTimeString(usecs); - - if (!dstInEffect && et1.tm_params.tp_dst_offset) { - dstInEffect = 1; - if (debug_mode) { - printf("DST changeover from "); - PrintExplodedTime(&et); - printf(" to "); - PrintExplodedTime(&et1); - printf(".\n"); - } - } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { - dstInEffect = 0; - if (debug_mode) { - printf("DST changeover from "); - PrintExplodedTime(&et); - printf(" to "); - PrintExplodedTime(&et1); - printf(".\n"); - } - } - - et = et1; - } - } - } - if (debug_mode) printf("Test passed\n"); - } - - - /* Same stress test, but with PR_LocalTimeParameters */ - - { - PRExplodedTime et, et1, et2; - PRInt64 usecPer10Min; - int day, hour, min; - PRTime usecs; - int dstInEffect = 0; - - if (debug_mode) { - printf("\n"); - printf("*******************************************************\n"); - printf("** **\n"); - printf("** Stress test Local Time **\n"); - printf("** Starting from midnight Jan. 1, 2005 PST, **\n"); - printf("** going through four years in 10-minute increment **\n"); - printf("** **\n"); - printf("*******************************************************\n\n"); - } - - LL_I2L(usecPer10Min, 600000000L); - - /* 00:00:00 PST Jan. 1, 2005 */ - et.tm_usec = 0; - et.tm_sec = 0; - et.tm_min = 0; - et.tm_hour = 0; - et.tm_mday = 1; - et.tm_month = 0; - et.tm_year = 2005; - et.tm_params.tp_gmt_offset = -8 * 3600; - et.tm_params.tp_dst_offset = 0; - usecs = PR_ImplodeTime(&et); - - for (day = 0; day < 4 * 365 + 1; day++) { - for (hour = 0; hour < 24; hour++) { - for (min = 0; min < 60; min += 10) { - LL_ADD(usecs, usecs, usecPer10Min); - PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1); - - et2 = et; - et2.tm_usec += 600000000L; - PR_NormalizeTime(&et2, PR_LocalTimeParameters); - - if (!ExplodedTimeIsEqual(&et1, &et2)) { - printf("ERROR: componentwise comparison failed\n"); - PrintExplodedTime(&et1); - printf("\n"); - PrintExplodedTime(&et2); - printf("\n"); - return 1; - } - - if (LL_NE(usecs, PR_ImplodeTime(&et1))) { - printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); - PrintExplodedTime(&et1); - printf("\n"); - failed_already=1; - return 1; - } - testParseTimeString(usecs); - - if (!dstInEffect && et1.tm_params.tp_dst_offset) { - dstInEffect = 1; - if (debug_mode) { - printf("DST changeover from "); - PrintExplodedTime(&et); - printf(" to "); - PrintExplodedTime(&et1); - printf(".\n"); - } - } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { - dstInEffect = 0; - if (debug_mode) { - printf("DST changeover from "); - PrintExplodedTime(&et); - printf(" to "); - PrintExplodedTime(&et1); - printf(".\n"); - } - } - - et = et1; - } - } - } - if (debug_mode) printf("Test passed\n"); - } - - /* Same stress test, but with PR_LocalTimeParameters and going backward */ - - { - PRExplodedTime et, et1, et2; - PRInt64 usecPer10Min; - int day, hour, min; - PRTime usecs; - int dstInEffect = 0; - - if (debug_mode) { - printf("\n"); - printf("*******************************************************\n"); - printf("** **\n"); - printf("** Stress test Local Time **\n"); - printf("** Starting from midnight Jan. 1, 2009 PST, **\n"); - printf("** going back four years in 10-minute increment **\n"); - printf("** **\n"); - printf("*******************************************************\n\n"); - } - - LL_I2L(usecPer10Min, 600000000L); - - /* 00:00:00 PST Jan. 1, 2009 */ - et.tm_usec = 0; - et.tm_sec = 0; - et.tm_min = 0; - et.tm_hour = 0; - et.tm_mday = 1; - et.tm_month = 0; - et.tm_year = 2009; - et.tm_params.tp_gmt_offset = -8 * 3600; - et.tm_params.tp_dst_offset = 0; - usecs = PR_ImplodeTime(&et); - - for (day = 0; day < 4 * 365 + 1; day++) { - for (hour = 0; hour < 24; hour++) { - for (min = 0; min < 60; min += 10) { - LL_SUB(usecs, usecs, usecPer10Min); - PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1); - - et2 = et; - et2.tm_usec -= 600000000L; - PR_NormalizeTime(&et2, PR_LocalTimeParameters); - - if (!ExplodedTimeIsEqual(&et1, &et2)) { - printf("ERROR: componentwise comparison failed\n"); - PrintExplodedTime(&et1); - printf("\n"); - PrintExplodedTime(&et2); - printf("\n"); - return 1; - } - - if (LL_NE(usecs, PR_ImplodeTime(&et1))) { - printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); - PrintExplodedTime(&et1); - printf("\n"); - failed_already=1; - return 1; - } - testParseTimeString(usecs); - - if (!dstInEffect && et1.tm_params.tp_dst_offset) { - dstInEffect = 1; - if (debug_mode) { - printf("DST changeover from "); - PrintExplodedTime(&et); - printf(" to "); - PrintExplodedTime(&et1); - printf(".\n"); - } - } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { - dstInEffect = 0; - if (debug_mode) { - printf("DST changeover from "); - PrintExplodedTime(&et); - printf(" to "); - PrintExplodedTime(&et1); - printf(".\n"); - } - } - - et = et1; - } - } - } - } - - if (failed_already) return 1; - else return 0; - -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/tmoacc.c nspr-4.10.7/mozilla/nsprpub/pr/tests/tmoacc.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/tmoacc.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/tmoacc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,296 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" - -#include -#include - -#include "plerror.h" -#include "plgetopt.h" - -#define BASE_PORT 9867 -#define DEFAULT_THREADS 1 -#define DEFAULT_BACKLOG 10 -#define DEFAULT_TIMEOUT 10 -#define RANDOM_RANGE 100 /* should be significantly smaller than RAND_MAX */ - -typedef enum {running, stopped} Status; - -typedef struct Shared -{ - PRLock *ml; - PRCondVar *cv; - PRBool passed; - PRBool random; - PRFileDesc *debug; - PRIntervalTime timeout; - PRFileDesc *listenSock; - Status status; -} Shared; - -static PRIntervalTime Timeout(const Shared *shared) -{ - PRIntervalTime timeout = shared->timeout; - if (shared->random) - { - PRIntervalTime half = timeout >> 1; /* one half of the interval */ - PRIntervalTime quarter = half >> 1; /* one quarter of the interval */ - /* something in [0..timeout / 2) */ - PRUint32 random = (rand() % RANDOM_RANGE) * half / RANDOM_RANGE; - timeout = (3 * quarter) + random; /* [75..125)% */ - } - return timeout; -} /* Timeout */ - -static void Accept(void *arg) -{ - PRStatus rv; - char *buffer = NULL; - PRNetAddr clientAddr; - Shared *shared = (Shared*)arg; - PRInt32 recv_length = 0, flags = 0; - PRFileDesc *clientSock; - PRIntn toread, byte, bytes, loop = 0; - struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor; - - do - { - PRUint32 checksum = 0; - if (NULL != shared->debug) - PR_fprintf(shared->debug, "[%d]accepting ... ", loop++); - clientSock = PR_Accept( - shared->listenSock, &clientAddr, Timeout(shared)); - if (clientSock != NULL) - { - if (NULL != shared->debug) - PR_fprintf(shared->debug, "reading length ... "); - bytes = PR_Recv( - clientSock, &descriptor, sizeof(descriptor), - flags, Timeout(shared)); - if (sizeof(descriptor) == bytes) - { - /* and, before doing something stupid ... */ - descriptor.length = PR_ntohl(descriptor.length); - descriptor.checksum = PR_ntohl(descriptor.checksum); - if (NULL != shared->debug) - PR_fprintf(shared->debug, "%d bytes ... ", descriptor.length); - toread = descriptor.length; - if (recv_length < descriptor.length) - { - if (NULL != buffer) PR_DELETE(buffer); - buffer = (char*)PR_MALLOC(descriptor.length); - recv_length = descriptor.length; - } - for (toread = descriptor.length; toread > 0; toread -= bytes) - { - bytes = PR_Recv( - clientSock, &buffer[descriptor.length - toread], - toread, flags, Timeout(shared)); - if (-1 == bytes) - { - if (NULL != shared->debug) - PR_fprintf(shared->debug, "read data failed..."); - bytes = 0; - } - } - } - else if (NULL != shared->debug) - { - PR_fprintf(shared->debug, "read desciptor failed..."); - descriptor.length = -1; - } - if (NULL != shared->debug) - PR_fprintf(shared->debug, "closing"); - rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH); - if ((PR_FAILURE == rv) && (NULL != shared->debug)) - { - PR_fprintf(shared->debug, " failed"); - shared->passed = PR_FALSE; - } - rv = PR_Close(clientSock); - if (PR_FAILURE == rv) if (NULL != shared->debug) - { - PR_fprintf(shared->debug, " failed"); - shared->passed = PR_FALSE; - } - if (descriptor.length > 0) - { - for (byte = 0; byte < descriptor.length; ++byte) - { - PRUint32 overflow = checksum & 0x80000000; - checksum = (checksum << 1); - if (0x00000000 != overflow) checksum += 1; - checksum += buffer[byte]; - } - if ((descriptor.checksum != checksum) && (NULL != shared->debug)) - { - PR_fprintf(shared->debug, " ... data mismatch"); - shared->passed = PR_FALSE; - } - } - else if (0 == descriptor.length) - { - PR_Lock(shared->ml); - shared->status = stopped; - PR_NotifyCondVar(shared->cv); - PR_Unlock(shared->ml); - } - if (NULL != shared->debug) - PR_fprintf(shared->debug, "\n"); - } - else - { - if (PR_PENDING_INTERRUPT_ERROR != PR_GetError()) - { - if (NULL != shared->debug) PL_PrintError("Accept"); - shared->passed = PR_FALSE; - } - } - } while (running == shared->status); - if (NULL != buffer) PR_DELETE(buffer); -} /* Accept */ - -PRIntn Tmoacc(PRIntn argc, char **argv) -{ - PRStatus rv; - PRIntn exitStatus; - PRIntn index; - Shared *shared; - PLOptStatus os; - PRThread **thread; - PRNetAddr listenAddr; - PRSocketOptionData sockOpt; - PRIntn timeout = DEFAULT_TIMEOUT; - PRIntn threads = DEFAULT_THREADS; - PRIntn backlog = DEFAULT_BACKLOG; - PRThreadScope thread_scope = PR_LOCAL_THREAD; - - PLOptState *opt = PL_CreateOptState(argc, argv, "dGb:t:T:R"); - - shared = PR_NEWZAP(Shared); - - shared->debug = NULL; - shared->passed = PR_TRUE; - shared->random = PR_TRUE; - shared->status = running; - shared->ml = PR_NewLock(); - shared->cv = PR_NewCondVar(shared->ml); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - shared->debug = PR_GetSpecialFD(PR_StandardError); - break; - case 'G': /* use global threads */ - thread_scope = PR_GLOBAL_THREAD; - break; - case 'b': /* size of listen backlog */ - backlog = atoi(opt->value); - break; - case 't': /* number of threads doing accept */ - threads = atoi(opt->value); - break; - case 'T': /* timeout used for network operations */ - timeout = atoi(opt->value); - break; - case 'R': /* randomize the timeout values */ - shared->random = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - if (0 == threads) threads = DEFAULT_THREADS; - if (0 == backlog) backlog = DEFAULT_BACKLOG; - if (0 == timeout) timeout = DEFAULT_TIMEOUT; - - PR_STDIO_INIT(); - memset(&listenAddr, 0, sizeof(listenAddr)); - rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr); - PR_ASSERT(PR_SUCCESS == rv); - - shared->timeout = PR_SecondsToInterval(timeout); - - /* First bind to the socket */ - shared->listenSock = PR_NewTCPSocket(); - if (shared->listenSock) - { - sockOpt.option = PR_SockOpt_Reuseaddr; - sockOpt.value.reuse_addr = PR_TRUE; - rv = PR_SetSocketOption(shared->listenSock, &sockOpt); - PR_ASSERT(PR_SUCCESS == rv); - rv = PR_Bind(shared->listenSock, &listenAddr); - if (rv != PR_FAILURE) - { - rv = PR_Listen(shared->listenSock, threads + backlog); - if (PR_SUCCESS == rv) - { - thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*)); - for (index = 0; index < threads; ++index) - { - thread[index] = PR_CreateThread( - PR_USER_THREAD, Accept, shared, - PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 0); - PR_ASSERT(NULL != thread[index]); - } - - PR_Lock(shared->ml); - while (shared->status == running) - PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(shared->ml); - for (index = 0; index < threads; ++index) - { - rv = PR_Interrupt(thread[index]); - PR_ASSERT(PR_SUCCESS== rv); - rv = PR_JoinThread(thread[index]); - PR_ASSERT(PR_SUCCESS== rv); - } - PR_DELETE(thread); - } - else - { - if (shared->debug) PL_PrintError("Listen"); - shared->passed = PR_FALSE; - } - } - else - { - if (shared->debug) PL_PrintError("Bind"); - shared->passed = PR_FALSE; - } - - PR_Close(shared->listenSock); - } - else - { - if (shared->debug) PL_PrintError("Create"); - shared->passed = PR_FALSE; - } - - PR_DestroyCondVar(shared->cv); - PR_DestroyLock(shared->ml); - - PR_fprintf( - PR_GetSpecialFD(PR_StandardError), "%s\n", - ((shared->passed) ? "PASSED" : "FAILED")); - - exitStatus = (shared->passed) ? 0 : 1; - PR_DELETE(shared); - return exitStatus; -} - -int main(int argc, char **argv) -{ - return (PR_VersionCheck(PR_VERSION)) ? - PR_Initialize(Tmoacc, argc, argv, 4) : -1; -} /* main */ - -/* tmoacc */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/tmocon.c nspr-4.10.7/mozilla/nsprpub/pr/tests/tmocon.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/tmocon.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/tmocon.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,378 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*********************************************************************** -** -** Name: tmocon.c -** -** Description: test client socket connection. -** -** Modification History: -** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. -** The debug mode will print all of the printfs associated with this test. -** The regress mode will be the default mode. Since the regress tool limits -** the output to a one line status:PASS or FAIL,all of the printf statements -** have been handled with an if (debug_mode) statement. -***********************************************************************/ - -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "nspr.h" -#include "pprio.h" - -#include "plerror.h" -#include "plgetopt.h" - -#include -#include -#include - -/* for getcwd */ -#if defined(XP_UNIX) || defined (XP_OS2) || defined(XP_BEOS) -#include -#elif defined(XP_PC) -#include -#endif - -#ifdef WINCE -#include -char *getcwd(char *buf, size_t size) -{ - wchar_t wpath[MAX_PATH]; - _wgetcwd(wpath, MAX_PATH); - WideCharToMultiByte(CP_ACP, 0, wpath, -1, buf, size, 0, 0); -} -#endif - -#define BASE_PORT 9867 - -#define DEFAULT_DALLY 1 -#define DEFAULT_THREADS 1 -#define DEFAULT_TIMEOUT 10 -#define DEFAULT_MESSAGES 100 -#define DEFAULT_MESSAGESIZE 100 - -static PRFileDesc *debug_out = NULL; - -typedef struct Shared -{ - PRBool random; - PRBool failed; - PRBool intermittant; - PRIntn debug; - PRInt32 messages; - PRIntervalTime dally; - PRIntervalTime timeout; - PRInt32 message_length; - PRNetAddr serverAddress; -} Shared; - -static PRIntervalTime Timeout(const Shared *shared) -{ - PRIntervalTime timeout = shared->timeout; - if (shared->random) - { - PRIntervalTime quarter = timeout >> 2; /* one quarter of the interval */ - PRUint32 random = rand() % quarter; /* something in[0..timeout / 4) */ - timeout = (((3 * quarter) + random) >> 2) + quarter; /* [75..125)% */ - } - return timeout; -} /* Timeout */ - -static void CauseTimeout(const Shared *shared) -{ - if (shared->intermittant) PR_Sleep(Timeout(shared)); -} /* CauseTimeout */ - -static PRStatus MakeReceiver(Shared *shared) -{ - PRStatus rv = PR_FAILURE; - if (PR_IsNetAddrType(&shared->serverAddress, PR_IpAddrLoopback)) - { - char *argv[3]; - char path[1024 + sizeof("/tmoacc")]; - - getcwd(path, sizeof(path)); - - (void)strcat(path, "/tmoacc"); -#ifdef XP_PC - (void)strcat(path, ".exe"); -#endif - argv[0] = path; - if (shared->debug > 0) - { - argv[1] = "-d"; - argv[2] = NULL; - } - else argv[1] = NULL; - if (shared->debug > 1) - PR_fprintf(debug_out, " creating accept process %s ...", path); - fflush(stdout); - rv = PR_CreateProcessDetached(path, argv, NULL, NULL); - if (PR_SUCCESS == rv) - { - if (shared->debug > 1) - PR_fprintf(debug_out, " wait 5 seconds"); - if (shared->debug > 1) - PR_fprintf(debug_out, " before connecting to accept process ..."); - fflush(stdout); - PR_Sleep(PR_SecondsToInterval(5)); - return rv; - } - shared->failed = PR_TRUE; - if (shared->debug > 0) - PL_FPrintError(debug_out, "PR_CreateProcessDetached failed"); - } - return rv; -} /* MakeReceiver */ - -static void Connect(void *arg) -{ - PRStatus rv; - char *buffer = NULL; - PRFileDesc *clientSock; - Shared *shared = (Shared*)arg; - PRInt32 loop, bytes, flags = 0; - struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor; - debug_out = (0 == shared->debug) ? NULL : PR_GetSpecialFD(PR_StandardError); - - buffer = (char*)PR_MALLOC(shared->message_length); - - for (bytes = 0; bytes < shared->message_length; ++bytes) - buffer[bytes] = (char)bytes; - - descriptor.checksum = 0; - for (bytes = 0; bytes < shared->message_length; ++bytes) - { - PRUint32 overflow = descriptor.checksum & 0x80000000; - descriptor.checksum = (descriptor.checksum << 1); - if (0x00000000 != overflow) descriptor.checksum += 1; - descriptor.checksum += buffer[bytes]; - } - descriptor.checksum = PR_htonl(descriptor.checksum); - - for (loop = 0; loop < shared->messages; ++loop) - { - if (shared->debug > 1) - PR_fprintf(debug_out, "[%d]socket ... ", loop); - clientSock = PR_NewTCPSocket(); - if (clientSock) - { - /* - * We need to slow down the rate of generating connect requests, - * otherwise the listen backlog queue on the accept side may - * become full and we will get connection refused or timeout - * error. - */ - - PR_Sleep(shared->dally); - if (shared->debug > 1) - { - char buf[128]; - PR_NetAddrToString(&shared->serverAddress, buf, sizeof(buf)); - PR_fprintf(debug_out, "connecting to %s ... ", buf); - } - rv = PR_Connect( - clientSock, &shared->serverAddress, Timeout(shared)); - if (PR_SUCCESS == rv) - { - PRInt32 descriptor_length = (loop < (shared->messages - 1)) ? - shared->message_length : 0; - descriptor.length = PR_htonl(descriptor_length); - if (shared->debug > 1) - PR_fprintf( - debug_out, "sending %d bytes ... ", descriptor_length); - CauseTimeout(shared); /* might cause server to timeout */ - bytes = PR_Send( - clientSock, &descriptor, sizeof(descriptor), - flags, Timeout(shared)); - if (bytes != sizeof(descriptor)) - { - shared->failed = PR_TRUE; - if (shared->debug > 0) - PL_FPrintError(debug_out, "PR_Send failed"); - } - if (0 != descriptor_length) - { - CauseTimeout(shared); - bytes = PR_Send( - clientSock, buffer, descriptor_length, - flags, Timeout(shared)); - if (bytes != descriptor_length) - { - shared->failed = PR_TRUE; - if (shared->debug > 0) - PL_FPrintError(debug_out, "PR_Send failed"); - } - } - if (shared->debug > 1) PR_fprintf(debug_out, "closing ... "); - rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH); - rv = PR_Close(clientSock); - if (shared->debug > 1) - { - if (PR_SUCCESS == rv) PR_fprintf(debug_out, "\n"); - else PL_FPrintError(debug_out, "shutdown failed"); - } - } - else - { - if (shared->debug > 1) PL_FPrintError(debug_out, "connect failed"); - PR_Close(clientSock); - if ((loop == 0) && (PR_GetError() == PR_CONNECT_REFUSED_ERROR)) - { - if (MakeReceiver(shared) == PR_FAILURE) break; - } - else - { - if (shared->debug > 1) PR_fprintf(debug_out, " exiting\n"); - break; - } - } - } - else - { - shared->failed = PR_TRUE; - if (shared->debug > 0) PL_FPrintError(debug_out, "create socket"); - break; - } - } - - PR_DELETE(buffer); -} /* Connect */ - -int Tmocon(int argc, char **argv) -{ - /* - * USAGE - * -d turn on debugging output (default = off) - * -v turn on verbose output (default = off) - * -h dns name of host serving the connection (default = self) - * -i dally intermittantly to cause timeouts (default = off) - * -m number of messages to send (default = 100) - * -s size of each message (default = 100) - * -t number of threads sending (default = 1) - * -G use global threads (default = local) - * -T timeout on I/O operations (seconds) (default = 10) - * -D dally between connect requests (seconds)(default = 0) - * -R randomize the dally types around 'T' (default = no) - */ - - PRStatus rv; - int exitStatus; - PLOptStatus os; - Shared *shared = NULL; - PRThread **thread = NULL; - PRIntn index, threads = DEFAULT_THREADS; - PRThreadScope thread_scope = PR_LOCAL_THREAD; - PRInt32 dally = DEFAULT_DALLY, timeout = DEFAULT_TIMEOUT; - PLOptState *opt = PL_CreateOptState(argc, argv, "divGRh:m:s:t:T:D:"); - - shared = PR_NEWZAP(Shared); - - shared->debug = 0; - shared->failed = PR_FALSE; - shared->random = PR_FALSE; - shared->messages = DEFAULT_MESSAGES; - shared->message_length = DEFAULT_MESSAGESIZE; - - PR_STDIO_INIT(); - memset(&shared->serverAddress, 0, sizeof(shared->serverAddress)); - rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &shared->serverAddress); - PR_ASSERT(PR_SUCCESS == rv); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': - if (0 == shared->debug) shared->debug = 1; - break; - case 'v': - if (0 == shared->debug) shared->debug = 2; - break; - case 'i': - shared->intermittant = PR_TRUE; - break; - case 'R': - shared->random = PR_TRUE; - break; - case 'G': - thread_scope = PR_GLOBAL_THREAD; - break; - case 'h': /* the value for backlock */ - { - PRIntn es = 0; - PRHostEnt host; - char buffer[1024]; - (void)PR_GetHostByName( - opt->value, buffer, sizeof(buffer), &host); - es = PR_EnumerateHostEnt( - es, &host, BASE_PORT, &shared->serverAddress); - PR_ASSERT(es > 0); - } - break; - case 'm': /* number of messages to send */ - shared->messages = atoi(opt->value); - break; - case 't': /* number of threads sending */ - threads = atoi(opt->value); - break; - case 'D': /* dally time between transmissions */ - dally = atoi(opt->value); - break; - case 'T': /* timeout on I/O operations */ - timeout = atoi(opt->value); - break; - case 's': /* total size of each message */ - shared->message_length = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (0 == timeout) timeout = DEFAULT_TIMEOUT; - if (0 == threads) threads = DEFAULT_THREADS; - if (0 == shared->messages) shared->messages = DEFAULT_MESSAGES; - if (0 == shared->message_length) shared->message_length = DEFAULT_MESSAGESIZE; - - shared->dally = PR_SecondsToInterval(dally); - shared->timeout = PR_SecondsToInterval(timeout); - - thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*)); - - for (index = 0; index < threads; ++index) - thread[index] = PR_CreateThread( - PR_USER_THREAD, Connect, shared, - PR_PRIORITY_NORMAL, thread_scope, - PR_JOINABLE_THREAD, 0); - for (index = 0; index < threads; ++index) - rv = PR_JoinThread(thread[index]); - - PR_DELETE(thread); - - PR_fprintf( - PR_GetSpecialFD(PR_StandardError), "%s\n", - ((shared->failed) ? "FAILED" : "PASSED")); - exitStatus = (shared->failed) ? 1 : 0; - PR_DELETE(shared); - return exitStatus; -} - -int main(int argc, char **argv) -{ - return (PR_VersionCheck(PR_VERSION)) ? - PR_Initialize(Tmocon, argc, argv, 4) : -1; -} /* main */ - -/* tmocon.c */ - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/tpd.c nspr-4.10.7/mozilla/nsprpub/pr/tests/tpd.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/tpd.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/tpd.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,298 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* -** File: tpd.c -** Description: Exercising the thread private data bailywick. -*/ - -#include "prmem.h" -#include "prinit.h" -#include "prlog.h" -#include "prprf.h" -#include "prthread.h" -#include "prtypes.h" - -#include "private/pprio.h" - -#include "plgetopt.h" - -static PRUintn key[128]; -static PRIntn debug = 0; -static PRBool failed = PR_FALSE; -static PRBool should = PR_TRUE; -static PRBool did = PR_TRUE; -static PRFileDesc *fout = NULL; - -static void PrintProgress(PRIntn line) -{ - failed = failed || (should && !did); - failed = failed || (!should && did); - if (debug > 0) - { -#if defined(WIN16) - printf( - "@ line %d destructor should%s have been called and was%s\n", - line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); -#else - PR_fprintf( - fout, "@ line %d destructor should%s have been called and was%s\n", - line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); -#endif - } -} /* PrintProgress */ - -static void MyAssert(const char *expr, const char *file, PRIntn line) -{ - if (debug > 0) - (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line); -} /* MyAssert */ - -#define MY_ASSERT(_expr) \ - ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__)) - - -static void PR_CALLBACK Destructor(void *data) -{ - MY_ASSERT(NULL != data); - if (should) did = PR_TRUE; - else failed = PR_TRUE; - /* - * We don't actually free the storage since it's actually allocated - * on the stack. Normally, this would not be the case and this is - * the opportunity to free whatever. - PR_Free(data); - */ -} /* Destructor */ - -static void PR_CALLBACK Thread(void *null) -{ - void *pd; - PRStatus rv; - PRUintn keys; - char *key_string[] = { - "Key #0", "Key #1", "Key #2", "Key #3", - "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; - - did = should = PR_FALSE; - for (keys = 0; keys < 8; ++keys) - { - pd = PR_GetThreadPrivate(key[keys]); - MY_ASSERT(NULL == pd); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 4; keys < 8; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], key_string[keys]); - MY_ASSERT(PR_FAILURE == rv); - } - PrintProgress(__LINE__); - - did = PR_FALSE; should = PR_TRUE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = PR_FALSE; should = PR_TRUE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], NULL); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], NULL); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 8; keys < 127; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = PR_FALSE; should = PR_TRUE; - for (keys = 8; keys < 127; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], NULL); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 8; keys < 127; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], NULL); - MY_ASSERT(PR_SUCCESS == rv); - } - - /* put in keys and leave them there for thread exit */ - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - did = PR_FALSE; should = PR_TRUE; - -} /* Thread */ - -static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv) -{ - void *pd; - PRStatus rv; - PRUintn keys; - PRThread *thread; - char *key_string[] = { - "Key #0", "Key #1", "Key #2", "Key #3", - "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; - - fout = PR_STDOUT; - - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 0; keys < 8; ++keys) - { - pd = PR_GetThreadPrivate(key[keys]); - MY_ASSERT(NULL == pd); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - for (keys = 4; keys < 8; ++keys) - key[keys] = 4096; /* set to invalid value */ - did = should = PR_FALSE; - for (keys = 4; keys < 8; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], key_string[keys]); - MY_ASSERT(PR_FAILURE == rv); - } - PrintProgress(__LINE__); - - did = PR_FALSE; should = PR_TRUE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], key_string[keys]); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = PR_FALSE; should = PR_TRUE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], NULL); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 0; keys < 4; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], NULL); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 8; keys < 127; ++keys) - { - rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); - MY_ASSERT(PR_SUCCESS == rv); - rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = PR_FALSE; should = PR_TRUE; - for (keys = 8; keys < 127; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], NULL); - MY_ASSERT(PR_SUCCESS == rv); - } - PrintProgress(__LINE__); - - did = should = PR_FALSE; - for (keys = 8; keys < 127; ++keys) - { - rv = PR_SetThreadPrivate(key[keys], NULL); - MY_ASSERT(PR_SUCCESS == rv); - } - - thread = PR_CreateThread( - PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - - (void)PR_JoinThread(thread); - - PrintProgress(__LINE__); - -#if defined(WIN16) - printf( - "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); -#else - (void)PR_fprintf( - fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); -#endif - - return 0; - -} /* Tpd */ - -int main(int argc, char **argv) -{ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dl:r:"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - PR_STDIO_INIT(); - return PR_Initialize(Tpd, argc, argv, 0); -} /* main */ - -/* tpd.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/udpsrv.c nspr-4.10.7/mozilla/nsprpub/pr/tests/udpsrv.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/udpsrv.c 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/udpsrv.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,530 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/******************************************************************* -** udpsrc.c -- Test basic function of UDP server -** -** udpsrv operates on the same machine with program udpclt. -** udpsrv is the server side of a udp sockets application. -** udpclt is the client side of a udp sockets application. -** -** The test is designed to assist developers in porting/debugging -** the UDP socket functions of NSPR. -** -** This test is not a stress test. -** -** main() starts two threads: UDP_Server() and UDP_Client(); -** main() uses PR_JoinThread() to wait for the threads to complete. -** -** UDP_Server() does repeated recvfrom()s from a socket. -** He detects an EOF condition set by UDP_Client(). For each -** packet received by UDP_Server(), he checks its content for -** expected content, then sends the packet back to UDP_Client(). -** -** UDP_Client() sends packets to UDP_Server() using sendto() -** he recieves packets back from the server via recvfrom(). -** After he sends enough packets containing UDP_AMOUNT_TO_WRITE -** bytes of data, he sends an EOF message. -** -** The test issues a pass/fail message at end. -** -** Notes: -** The variable "_debug_on" can be set to 1 to cause diagnostic -** messages related to client/server synchronization. Useful when -** the test hangs. -** -** Error messages are written to stdout. -** -******************************************************************** -*/ -/* --- include files --- */ -#include "nspr.h" -#include "prpriv.h" - -#include "plgetopt.h" -#include "prttools.h" - -#include -#include -#include -#include - -#ifdef XP_PC -#define mode_t int -#endif - -#define UDP_BUF_SIZE 4096 -#define UDP_DGRAM_SIZE 128 -#define UDP_AMOUNT_TO_WRITE (PRInt32)((UDP_DGRAM_SIZE * 1000l) +1) -#define NUM_UDP_CLIENTS 1 -#define NUM_UDP_DATAGRAMS_PER_CLIENT 5 -#define UDP_SERVER_PORT 9050 -#define UDP_CLIENT_PORT 9053 -#define MY_INADDR PR_INADDR_ANY -#define PEER_INADDR PR_INADDR_LOOPBACK - -#define UDP_TIMEOUT 400000 -/* #define UDP_TIMEOUT PR_INTERVAL_NO_TIMEOUT */ - -/* --- static data --- */ -static PRIntn _debug_on = 0; -static PRBool passed = PR_TRUE; -static PRUint32 cltBytesRead = 0; -static PRUint32 srvBytesRead = 0; -static PRFileDesc *output = NULL; - -/* --- static function declarations --- */ -#define DPRINTF(arg) if (_debug_on) PR_fprintf(output, arg) - - - -/******************************************************************* -** ListNetAddr() -- Display the Net Address on stdout -** -** Description: displays the component parts of a PRNetAddr struct -** -** Arguments: address of PRNetAddr structure to display -** -** Returns: void -** -** Notes: -** -******************************************************************** -*/ -void ListNetAddr( char *msg, PRNetAddr *na ) -{ - char mbuf[256]; - - sprintf( mbuf, "ListNetAddr: %s family: %d, port: %d, ip: %8.8X\n", - msg, na->inet.family, PR_ntohs( na->inet.port), PR_ntohl(na->inet.ip) ); -#if 0 - DPRINTF( mbuf ); -#endif -} /* --- end ListNetAddr() --- */ - -/******************************************************************** -** UDP_Server() -- Test a UDP server application -** -** Description: The Server side of a UDP Client/Server application. -** -** Arguments: none -** -** Returns: void -** -** Notes: -** -** -******************************************************************** -*/ -static void PR_CALLBACK UDP_Server( void *arg ) -{ - static char svrBuf[UDP_BUF_SIZE]; - PRFileDesc *svrSock; - PRInt32 rv; - PRNetAddr netaddr; - PRBool bound = PR_FALSE; - PRBool endOfInput = PR_FALSE; - PRInt32 numBytes = UDP_DGRAM_SIZE; - - DPRINTF("udpsrv: UDP_Server(): starting\n" ); - - /* --- Create the socket --- */ - DPRINTF("udpsrv: UDP_Server(): Creating UDP Socket\n" ); - svrSock = PR_NewUDPSocket(); - if ( svrSock == NULL ) - { - passed = PR_FALSE; - if (debug_mode) - PR_fprintf(output, - "udpsrv: UDP_Server(): PR_NewUDPSocket() returned NULL\n" ); - return; - } - - /* --- Initialize the sockaddr_in structure --- */ - memset( &netaddr, 0, sizeof( netaddr )); - netaddr.inet.family = PR_AF_INET; - netaddr.inet.port = PR_htons( UDP_SERVER_PORT ); - netaddr.inet.ip = PR_htonl( MY_INADDR ); - - /* --- Bind the socket --- */ - while ( !bound ) - { - DPRINTF("udpsrv: UDP_Server(): Binding socket\n" ); - rv = PR_Bind( svrSock, &netaddr ); - if ( rv < 0 ) - { - if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR ) - { - if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \ - PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n"); - PR_Sleep( PR_MillisecondsToInterval( 2000 )); - continue; - } - else - { - passed = PR_FALSE; - if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \ - PR_Bind(): failed: %ld with error: %ld\n", - rv, PR_GetError() ); - PR_Close( svrSock ); - return; - } - } - else - bound = PR_TRUE; - } - ListNetAddr( "UDP_Server: after bind", &netaddr ); - - /* --- Recv the socket --- */ - while( !endOfInput ) - { - DPRINTF("udpsrv: UDP_Server(): RecvFrom() socket\n" ); - rv = PR_RecvFrom( svrSock, svrBuf, numBytes, 0, &netaddr, UDP_TIMEOUT ); - if ( rv == -1 ) - { - passed = PR_FALSE; - if (debug_mode) - PR_fprintf(output, - "udpsrv: UDP_Server(): PR_RecvFrom(): failed with error: %ld\n", - PR_GetError() ); - PR_Close( svrSock ); - return; - } - ListNetAddr( "UDP_Server after RecvFrom", &netaddr ); - - srvBytesRead += rv; - - if ( svrBuf[0] == 'E' ) - { - DPRINTF("udpsrv: UDP_Server(): EOF on input detected\n" ); - endOfInput = PR_TRUE; - } - - /* --- Send the socket --- */ - DPRINTF("udpsrv: UDP_Server(): SendTo(): socket\n" ); - rv = PR_SendTo( svrSock, svrBuf, rv, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT ); - if ( rv == -1 ) - { - passed = PR_FALSE; - if (debug_mode) - PR_fprintf(output, - "udpsrv: UDP_Server(): PR_SendTo(): failed with error: %ld\n", - PR_GetError() ); - PR_Close( svrSock ); - return; - } - ListNetAddr( "UDP_Server after SendTo", &netaddr ); - } - - /* --- Close the socket --- */ - DPRINTF("udpsrv: UDP_Server(): Closing socket\n" ); - rv = PR_Close( svrSock ); - if ( rv != PR_SUCCESS ) - { - passed = PR_FALSE; - if (debug_mode) - PR_fprintf(output, - "udpsrv: UDP_Server(): PR_Close(): failed to close socket\n" ); - return; - } - - DPRINTF("udpsrv: UDP_Server(): Normal end\n" ); -} /* --- end UDP_Server() --- */ - - -static char cltBuf[UDP_BUF_SIZE]; -static char cltBufin[UDP_BUF_SIZE]; -/******************************************************************** -** UDP_Client() -- Test a UDP client application -** -** Description: -** -** Arguments: -** -** -** Returns: -** 0 -- Successful execution -** 1 -- Test failed. -** -** Notes: -** -** -******************************************************************** -*/ -static void PR_CALLBACK UDP_Client( void *arg ) -{ - PRFileDesc *cltSock; - PRInt32 rv; - PRBool bound = PR_FALSE; - PRNetAddr netaddr; - PRNetAddr netaddrx; - PRBool endOfInput = PR_FALSE; - PRInt32 numBytes = UDP_DGRAM_SIZE; - PRInt32 writeThisMany = UDP_AMOUNT_TO_WRITE; - int i; - - - DPRINTF("udpsrv: UDP_Client(): starting\n" ); - - /* --- Create the socket --- */ - cltSock = PR_NewUDPSocket(); - if ( cltSock == NULL ) - { - passed = PR_FALSE; - if (debug_mode) - PR_fprintf(output, - "udpsrv: UDP_Client(): PR_NewUDPSocket() returned NULL\n" ); - return; - } - - /* --- Initialize the sockaddr_in structure --- */ - memset( &netaddr, 0, sizeof( netaddr )); - netaddr.inet.family = PR_AF_INET; - netaddr.inet.ip = PR_htonl( MY_INADDR ); - netaddr.inet.port = PR_htons( UDP_CLIENT_PORT ); - - /* --- Initialize the write buffer --- */ - for ( i = 0; i < UDP_BUF_SIZE ; i++ ) - cltBuf[i] = i; - - /* --- Bind the socket --- */ - while ( !bound ) - { - DPRINTF("udpsrv: UDP_Client(): Binding socket\n" ); - rv = PR_Bind( cltSock, &netaddr ); - if ( rv < 0 ) - { - if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR ) - { - if (debug_mode) - PR_fprintf(output, - "udpsrv: UDP_Client(): PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n"); - PR_Sleep( PR_MillisecondsToInterval( 2000 )); - continue; - } - else - { - passed = PR_FALSE; - if (debug_mode) - PR_fprintf(output, - "udpsrv: UDP_Client(): PR_Bind(): failed: %ld with error: %ld\n", - rv, PR_GetError() ); - PR_Close( cltSock ); - return; - } - } - else - bound = PR_TRUE; - } - ListNetAddr( "UDP_Client after Bind", &netaddr ); - - /* --- Initialize the sockaddr_in structure --- */ - memset( &netaddr, 0, sizeof( netaddr )); - netaddr.inet.family = PR_AF_INET; - netaddr.inet.ip = PR_htonl( PEER_INADDR ); - netaddr.inet.port = PR_htons( UDP_SERVER_PORT ); - - /* --- send and receive packets until no more data left */ - while( !endOfInput ) - { - /* - ** Signal EOF in the data stream on the last packet - */ - if ( writeThisMany <= UDP_DGRAM_SIZE ) - { - DPRINTF("udpsrv: UDP_Client(): Send EOF packet\n" ); - cltBuf[0] = 'E'; - endOfInput = PR_TRUE; - } - - /* --- SendTo the socket --- */ - if ( writeThisMany > UDP_DGRAM_SIZE ) - numBytes = UDP_DGRAM_SIZE; - else - numBytes = writeThisMany; - writeThisMany -= numBytes; - { - char mbuf[256]; - sprintf( mbuf, "udpsrv: UDP_Client(): write_this_many: %d, numbytes: %d\n", - writeThisMany, numBytes ); - DPRINTF( mbuf ); - } - - DPRINTF("udpsrv: UDP_Client(): SendTo(): socket\n" ); - rv = PR_SendTo( cltSock, cltBuf, numBytes, 0, &netaddr, UDP_TIMEOUT ); - if ( rv == -1 ) - { - passed = PR_FALSE; - if (debug_mode) - PR_fprintf(output, - "udpsrv: UDP_Client(): PR_SendTo(): failed with error: %ld\n", - PR_GetError() ); - PR_Close( cltSock ); - return; - } - ListNetAddr( "UDP_Client after SendTo", &netaddr ); - - /* --- RecvFrom the socket --- */ - memset( cltBufin, 0, UDP_BUF_SIZE ); - DPRINTF("udpsrv: UDP_Client(): RecvFrom(): socket\n" ); - rv = PR_RecvFrom( cltSock, cltBufin, numBytes, 0, &netaddrx, UDP_TIMEOUT ); - if ( rv == -1 ) - { - passed = PR_FALSE; - if (debug_mode) PR_fprintf(output, - "udpsrv: UDP_Client(): PR_RecvFrom(): failed with error: %ld\n", - PR_GetError() ); - PR_Close( cltSock ); - return; - } - ListNetAddr( "UDP_Client after RecvFrom()", &netaddr ); - cltBytesRead += rv; - - /* --- verify buffer --- */ - for ( i = 0; i < rv ; i++ ) - { - if ( cltBufin[i] != i ) - { - /* --- special case, end of input --- */ - if ( endOfInput && i == 0 && cltBufin[0] == 'E' ) - continue; - passed = PR_FALSE; - if (debug_mode) PR_fprintf(output, - "udpsrv: UDP_Client(): return data mismatch\n" ); - PR_Close( cltSock ); - return; - } - } - if (debug_mode) PR_fprintf(output, "."); - } - - /* --- Close the socket --- */ - DPRINTF("udpsrv: UDP_Server(): Closing socket\n" ); - rv = PR_Close( cltSock ); - if ( rv != PR_SUCCESS ) - { - passed = PR_FALSE; - if (debug_mode) PR_fprintf(output, - "udpsrv: UDP_Client(): PR_Close(): failed to close socket\n" ); - return; - } - DPRINTF("udpsrv: UDP_Client(): ending\n" ); -} /* --- end UDP_Client() --- */ - -/******************************************************************** -** main() -- udpsrv -** -** arguments: -** -** Returns: -** 0 -- Successful execution -** 1 -- Test failed. -** -** Description: -** -** Standard test case setup. -** -** Calls the function UDP_Server() -** -******************************************************************** -*/ - -int main(int argc, char **argv) -{ - PRThread *srv, *clt; -/* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d -v - */ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dv"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = 1; - break; - case 'v': /* verbose mode */ - _debug_on = 1; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - PR_STDIO_INIT(); - output = PR_STDERR; - - PR_SetConcurrency(4); - - /* - ** Create the Server thread - */ - DPRINTF( "udpsrv: Creating Server Thread\n" ); - srv = PR_CreateThread( PR_USER_THREAD, - UDP_Server, - (void *) 0, - PR_PRIORITY_LOW, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0 ); - if ( srv == NULL ) - { - if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" ); - passed = PR_FALSE; - } - - /* - ** Give the Server time to Start - */ - DPRINTF( "udpsrv: Pausing to allow Server to start\n" ); - PR_Sleep( PR_MillisecondsToInterval(200) ); - - /* - ** Create the Client thread - */ - DPRINTF( "udpsrv: Creating Client Thread\n" ); - clt = PR_CreateThread( PR_USER_THREAD, - UDP_Client, - (void *) 0, - PR_PRIORITY_LOW, - PR_LOCAL_THREAD, - PR_JOINABLE_THREAD, - 0 ); - if ( clt == NULL ) - { - if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" ); - passed = PR_FALSE; - } - - /* - ** - */ - DPRINTF("udpsrv: Waiting to join Server & Client Threads\n" ); - PR_JoinThread( srv ); - PR_JoinThread( clt ); - - /* - ** Evaluate test results - */ - if (debug_mode) PR_fprintf(output, "\n\nudpsrv: main(): cltBytesRead(%ld), \ - srvBytesRead(%ld), expected(%ld)\n", - cltBytesRead, srvBytesRead, UDP_AMOUNT_TO_WRITE ); - if ( cltBytesRead != srvBytesRead || cltBytesRead != UDP_AMOUNT_TO_WRITE ) - { - passed = PR_FALSE; - } - PR_Cleanup(); - if ( passed ) - return 0; - else - return 1; -} /* --- end main() --- */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/ut_ttools.h nspr-4.10.7/mozilla/nsprpub/pr/tests/ut_ttools.h --- nspr-4.9.5/mozilla/nsprpub/pr/tests/ut_ttools.h 2012-03-06 13:14:32.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/ut_ttools.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Used in Regress Tool */ -#define NOSTATUS 2 -#define PASS 1 -#define FAIL 0 - -PRIntn debug_mode=0; diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/vercheck.c nspr-4.10.7/mozilla/nsprpub/pr/tests/vercheck.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/vercheck.c 2012-11-22 01:14:00.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/vercheck.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * File: vercheck.c - * - * Description: - * This test tests the PR_VersionCheck() function. The - * compatible_version and incompatible_version arrays - * need to be updated for each patch or release. - * - * Tested areas: library version compatibility check. - */ - -#include "prinit.h" - -#include -#include - -/* - * This release (4.9.5) is backward compatible with the - * 4.0.x, 4.1.x, 4.2.x, 4.3.x, 4.4.x, 4.5.x, 4.6.x, 4.7.x, - * 4.8.x, 4.9, 4.9.1, 4.9.2, 4.9.3, and 4.9.4 releases. - * It, of course, is compatible with itself. - */ -static char *compatible_version[] = { - "4.0", "4.0.1", "4.1", "4.1.1", "4.1.2", "4.1.3", - "4.2", "4.2.1", "4.2.2", "4.3", "4.4", "4.4.1", - "4.5", "4.5.1", - "4.6", "4.6.1", "4.6.2", "4.6.3", "4.6.4", "4.6.5", - "4.6.6", "4.6.7", "4.6.8", - "4.7", "4.7.1", "4.7.2", "4.7.3", "4.7.4", "4.7.5", - "4.7.6", - "4.8", "4.8.1", "4.8.2", "4.8.3", "4.8.4", "4.8.5", - "4.8.6", "4.8.7", "4.8.8", "4.8.9", - "4.9", "4.9.1", "4.9.2", "4.9.3", "4.9.4", PR_VERSION -}; - -/* - * This release is not backward compatible with the old - * NSPR 2.1 and 3.x releases. - * - * Any release is incompatible with future releases and - * patches. - */ -static char *incompatible_version[] = { - "2.1 19980529", - "3.0", "3.0.1", - "3.1", "3.1.1", "3.1.2", "3.1.3", - "3.5", "3.5.1", - "4.9.6", - "4.10", "4.10.1", - "10.0", "11.1", "12.14.20" -}; - -int main(int argc, char **argv) -{ - int idx; - int num_compatible = sizeof(compatible_version) / sizeof(char *); - int num_incompatible = sizeof(incompatible_version) / sizeof(char *); - - printf("NSPR release %s:\n", PR_VERSION); - for (idx = 0; idx < num_compatible; idx++) { - if (PR_VersionCheck(compatible_version[idx]) == PR_FALSE) { - fprintf(stderr, "Should be compatible with version %s\n", - compatible_version[idx]); - exit(1); - } - printf("Compatible with version %s\n", compatible_version[idx]); - } - - for (idx = 0; idx < num_incompatible; idx++) { - if (PR_VersionCheck(incompatible_version[idx]) == PR_TRUE) { - fprintf(stderr, "Should be incompatible with version %s\n", - incompatible_version[idx]); - exit(1); - } - printf("Incompatible with version %s\n", incompatible_version[idx]); - } - - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/version.c nspr-4.10.7/mozilla/nsprpub/pr/tests/version.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/version.c 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/version.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prprf.h" -#include "prlink.h" -#include "prvrsion.h" - -#include "plerror.h" -#include "plgetopt.h" - -PR_IMPORT(const PRVersionDescription *) libVersionPoint(void); - -int main(int argc, char **argv) -{ - PRIntn rv = 1; - PLOptStatus os; - PRIntn verbosity = 0; - PRLibrary *runtime = NULL; - const char *library_name = NULL; - const PRVersionDescription *version_info; - char buffer[100]; - PRExplodedTime exploded; - PLOptState *opt = PL_CreateOptState(argc, argv, "d"); - - PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: /* fully qualified library name */ - library_name = opt->value; - break; - case 'd': /* verbodity */ - verbosity += 1; - break; - default: - PR_fprintf(err, "Usage: version [-d] {fully qualified library name}\n"); - return 2; /* but not a lot else */ - } - } - PL_DestroyOptState(opt); - - if (NULL != library_name) - { - runtime = PR_LoadLibrary(library_name); - if (NULL == runtime) { - PL_FPrintError(err, "PR_LoadLibrary"); - return 3; - } else { - versionEntryPointType versionPoint = (versionEntryPointType) - PR_FindSymbol(runtime, "libVersionPoint"); - if (NULL == versionPoint) { - PL_FPrintError(err, "PR_FindSymbol"); - return 4; - } - version_info = versionPoint(); - } - } else - version_info = libVersionPoint(); /* NSPR's version info */ - - (void)PR_fprintf(err, "Runtime library version information\n"); - PR_ExplodeTime( - version_info->buildTime, PR_GMTParameters, &exploded); - (void)PR_FormatTime( - buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded); - (void)PR_fprintf(err, " Build time: %s GMT\n", buffer); - (void)PR_fprintf( - err, " Build time: %s\n", version_info->buildTimeString); - (void)PR_fprintf( - err, " %s V%u.%u.%u (%s%s%s)\n", - version_info->description, - version_info->vMajor, - version_info->vMinor, - version_info->vPatch, - (version_info->beta ? " beta " : ""), - (version_info->debug ? " debug " : ""), - (version_info->special ? " special" : "")); - (void)PR_fprintf(err, " filename: %s\n", version_info->filename); - (void)PR_fprintf(err, " security: %s\n", version_info->security); - (void)PR_fprintf(err, " copyright: %s\n", version_info->copyright); - (void)PR_fprintf(err, " comment: %s\n", version_info->comment); - rv = 0; - return rv; -} - -/* version.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/writev.c nspr-4.10.7/mozilla/nsprpub/pr/tests/writev.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/writev.c 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/writev.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,197 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nspr.h" - -#include "plgetopt.h" - -#include -#include - - -#ifndef IOV_MAX -#define IOV_MAX 16 -#endif - -#define BASE_PORT 9867 - -int PR_CALLBACK Writev(int argc, char **argv) -{ - - PRStatus rv; - PRNetAddr serverAddr; - PRFileDesc *clientSock, *debug = NULL; - - char *buffer = NULL; - PRIOVec *iov = NULL; - PRBool passed = PR_TRUE; - PRIntervalTime timein, elapsed, timeout; - PRIntervalTime tmo_min = 0x7fffffff, tmo_max = 0, tmo_elapsed = 0; - PRInt32 tmo_counted = 0, iov_index, loop, bytes, number_fragments; - PRInt32 message_length = 100, fragment_length = 100, messages = 100; - struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor; - - /* - * USAGE - * -h dns name of host serving the connection (default = self) - * -m number of messages to send (default = 100) - * -s size of each message (default = 100) - * -f size of each message fragment (default = 100) - */ - - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dh:m:s:f:"); - - PR_STDIO_INIT(); - rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddr); - PR_ASSERT(PR_SUCCESS == rv); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'h': /* the remote host */ - { - PRIntn es = 0; - PRHostEnt host; - char buffer[1024]; - (void)PR_GetHostByName(opt->value, buffer, sizeof(buffer), &host); - es = PR_EnumerateHostEnt(es, &host, BASE_PORT, &serverAddr); - PR_ASSERT(es > 0); - } - break; - case 'd': /* debug mode */ - debug = PR_GetSpecialFD(PR_StandardError); - break; - case 'm': /* number of messages to send */ - messages = atoi(opt->value); - break; - case 's': /* total size of each message */ - message_length = atoi(opt->value); - break; - case 'f': /* size of each message fragment */ - fragment_length = atoi(opt->value); - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - buffer = (char*)malloc(message_length); - - number_fragments = (message_length + fragment_length - 1) / fragment_length + 1; - while (IOV_MAX < number_fragments) - { - fragment_length = message_length / (IOV_MAX - 2); - number_fragments = (message_length + fragment_length - 1) / - fragment_length + 1; - if (NULL != debug) PR_fprintf(debug, - "Too many fragments - reset fragment length to %ld\n", fragment_length); - } - iov = (PRIOVec*)malloc(number_fragments * sizeof(PRIOVec)); - - iov[0].iov_base = (char*)&descriptor; - iov[0].iov_len = sizeof(descriptor); - for (iov_index = 1; iov_index < number_fragments; ++iov_index) - { - iov[iov_index].iov_base = buffer + (iov_index - 1) * fragment_length; - iov[iov_index].iov_len = fragment_length; - } - - for (bytes = 0; bytes < message_length; ++bytes) - buffer[bytes] = (char)bytes; - - timeout = PR_SecondsToInterval(1); - - for (loop = 0; loop < messages; ++loop) - { - if (NULL != debug) - PR_fprintf(debug, "[%d]socket ... ", loop); - clientSock = PR_NewTCPSocket(); - if (clientSock) - { - timein = PR_IntervalNow(); - if (NULL != debug) - PR_fprintf(debug, "connecting ... "); - rv = PR_Connect(clientSock, &serverAddr, timeout); - if (PR_SUCCESS == rv) - { - descriptor.checksum = 0; - descriptor.length = (loop < (messages - 1)) ? message_length : 0; - if (0 == descriptor.length) number_fragments = 1; - else - for (iov_index = 0; iov_index < descriptor.length; ++iov_index) - { - PRUint32 overflow = descriptor.checksum & 0x80000000; - descriptor.checksum = (descriptor.checksum << 1); - if (0x00000000 != overflow) descriptor.checksum += 1; - descriptor.checksum += buffer[iov_index]; - } - if (NULL != debug) PR_fprintf( - debug, "sending %d bytes ... ", descriptor.length); - - /* then, at the last moment ... */ - descriptor.length = PR_ntohl(descriptor.length); - descriptor.checksum = PR_ntohl(descriptor.checksum); - - bytes = PR_Writev(clientSock, iov, number_fragments, timeout); - if (NULL != debug) - PR_fprintf(debug, "closing ... "); - rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH); - rv = PR_Close(clientSock); - if (NULL != debug) PR_fprintf( - debug, "%s\n", ((PR_SUCCESS == rv) ? "good" : "bad")); - elapsed = PR_IntervalNow() - timein; - if (elapsed < tmo_min) tmo_min = elapsed; - else if (elapsed > tmo_max) tmo_max = elapsed; - tmo_elapsed += elapsed; - tmo_counted += 1; - } - else - { - if (NULL != debug) PR_fprintf( - debug, "failed - retrying (%d, %d)\n", - PR_GetError(), PR_GetOSError()); - PR_Close(clientSock); - } - } - else if (NULL != debug) - { - PR_fprintf(debug, "unable to create client socket\n"); - passed = PR_FALSE; - } - } - if (NULL != debug) { - if (0 == tmo_counted) { - PR_fprintf(debug, "No connection made\n"); - } else { - PR_fprintf( - debug, "\nTimings: %d [%d] %d (microseconds)\n", - PR_IntervalToMicroseconds(tmo_min), - PR_IntervalToMicroseconds(tmo_elapsed / tmo_counted), - PR_IntervalToMicroseconds(tmo_max)); - } - } - - PR_DELETE(buffer); - PR_DELETE(iov); - - PR_fprintf( - PR_GetSpecialFD(PR_StandardError), - "%s\n", (passed) ? "PASSED" : "FAILED"); - return (passed) ? 0 : 1; -} - -int main(int argc, char **argv) -{ - return (PR_VersionCheck(PR_VERSION)) ? - PR_Initialize(Writev, argc, argv, 4) : -1; -} /* main */ - -/* writev.c */ - - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/xnotify.c nspr-4.10.7/mozilla/nsprpub/pr/tests/xnotify.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/xnotify.c 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/xnotify.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,357 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "plerror.h" -#include "plgetopt.h" - -#include "prinit.h" -#include "prprf.h" -#include "prio.h" -#include "prcvar.h" -#include "prmon.h" -#include "prcmon.h" -#include "prlock.h" -#include "prerror.h" -#include "prinit.h" -#include "prinrval.h" -#include "prthread.h" - -static PRLock *ml = NULL; -static PRIntervalTime base; -static PRFileDesc *err = NULL; - -typedef struct CMonShared -{ - PRInt32 o1, o2; -} CMonShared; - -typedef struct MonShared -{ - PRMonitor *o1, *o2; -} MonShared; - -typedef struct LockShared -{ - PRLock *o1, *o2; - PRCondVar *cv1, *cv2; -} LockShared; - -static void LogNow(const char *msg, PRStatus rv) -{ - PRIntervalTime now = PR_IntervalNow(); - PR_Lock(ml); - PR_fprintf(err, "%6ld: %s", (now - base), msg); - if (PR_FAILURE == rv) PL_FPrintError(err, " "); - else PR_fprintf(err, "\n"); - PR_Unlock(ml); -} /* LogNow */ - -static void Help(void) -{ - PR_fprintf(err, "Usage: [-[d][l][m][c]] [-h]\n"); - PR_fprintf(err, "\t-d debug mode (default: FALSE)\n"); - PR_fprintf(err, "\t-l test with locks (default: FALSE)\n"); - PR_fprintf(err, "\t-m tests with monitors (default: FALSE)\n"); - PR_fprintf(err, "\t-c tests with cmonitors (default: FALSE)\n"); - PR_fprintf(err, "\t-h help\n"); -} /* Help */ - -static void PR_CALLBACK T2CMon(void *arg) -{ - PRStatus rv; - CMonShared *shared = (CMonShared*)arg; - - PR_CEnterMonitor(&shared->o1); - LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS); - rv = PR_CWait(&shared->o1, PR_SecondsToInterval(5)); - if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv); - else LogNow("T2 wait failed on o1", rv); - - rv = PR_CNotify(&shared->o1); - if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv); - else LogNow("T2 notify on o1 failed", rv); - - PR_CExitMonitor(&shared->o1); -} /* T2CMon */ - -static void PR_CALLBACK T3CMon(void *arg) -{ - PRStatus rv; - CMonShared *shared = (CMonShared*)arg; - - PR_CEnterMonitor(&shared->o2); - LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS); - rv = PR_CWait(&shared->o2, PR_SecondsToInterval(5)); - if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv); - else LogNow("T3 wait failed on o2", rv); - rv = PR_CNotify(&shared->o2); - LogNow("T3 notify on o2", rv); - PR_CExitMonitor(&shared->o2); - -} /* T3CMon */ - -static CMonShared sharedCM; - -static void T1CMon(void) -{ - PRStatus rv; - PRThread *t2, *t3; - - PR_fprintf(err, "\n**********************************\n"); - PR_fprintf(err, " CACHED MONITORS\n"); - PR_fprintf(err, "**********************************\n"); - - base = PR_IntervalNow(); - - PR_CEnterMonitor(&sharedCM.o1); - LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS); - rv = PR_CWait(&sharedCM.o1, PR_SecondsToInterval(3)); - if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv); - else LogNow("T1 wait on o1 failed", rv); - PR_CExitMonitor(&sharedCM.o1); - - LogNow("T1 creating T2", PR_SUCCESS); - t2 = PR_CreateThread( - PR_USER_THREAD, T2CMon, &sharedCM, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - - LogNow("T1 creating T3", PR_SUCCESS); - t3 = PR_CreateThread( - PR_USER_THREAD, T3CMon, &sharedCM, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - - PR_CEnterMonitor(&sharedCM.o2); - LogNow("T1 waiting forever on o2", PR_SUCCESS); - rv = PR_CWait(&sharedCM.o2, PR_INTERVAL_NO_TIMEOUT); - if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv); - else LogNow("T1 wait on o2 failed", rv); - PR_CExitMonitor(&sharedCM.o2); - - (void)PR_JoinThread(t2); - (void)PR_JoinThread(t3); - -} /* T1CMon */ - -static void PR_CALLBACK T2Mon(void *arg) -{ - PRStatus rv; - MonShared *shared = (MonShared*)arg; - - PR_EnterMonitor(shared->o1); - LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS); - rv = PR_Wait(shared->o1, PR_SecondsToInterval(5)); - if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv); - else LogNow("T2 wait failed on o1", rv); - - rv = PR_Notify(shared->o1); - if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv); - else LogNow("T2 notify on o1 failed", rv); - - PR_ExitMonitor(shared->o1); -} /* T2Mon */ - -static void PR_CALLBACK T3Mon(void *arg) -{ - PRStatus rv; - MonShared *shared = (MonShared*)arg; - - PR_EnterMonitor(shared->o2); - LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS); - rv = PR_Wait(shared->o2, PR_SecondsToInterval(5)); - if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv); - else LogNow("T3 wait failed on o2", rv); - rv = PR_Notify(shared->o2); - LogNow("T3 notify on o2", rv); - PR_ExitMonitor(shared->o2); - -} /* T3Mon */ - -static MonShared sharedM; -static void T1Mon(void) -{ - PRStatus rv; - PRThread *t2, *t3; - - PR_fprintf(err, "\n**********************************\n"); - PR_fprintf(err, " MONITORS\n"); - PR_fprintf(err, "**********************************\n"); - - sharedM.o1 = PR_NewMonitor(); - sharedM.o2 = PR_NewMonitor(); - - base = PR_IntervalNow(); - - PR_EnterMonitor(sharedM.o1); - LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS); - rv = PR_Wait(sharedM.o1, PR_SecondsToInterval(3)); - if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv); - else LogNow("T1 wait on o1 failed", rv); - PR_ExitMonitor(sharedM.o1); - - LogNow("T1 creating T2", PR_SUCCESS); - t2 = PR_CreateThread( - PR_USER_THREAD, T2Mon, &sharedM, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - - LogNow("T1 creating T3", PR_SUCCESS); - t3 = PR_CreateThread( - PR_USER_THREAD, T3Mon, &sharedM, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - - PR_EnterMonitor(sharedM.o2); - LogNow("T1 waiting forever on o2", PR_SUCCESS); - rv = PR_Wait(sharedM.o2, PR_INTERVAL_NO_TIMEOUT); - if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv); - else LogNow("T1 wait on o2 failed", rv); - PR_ExitMonitor(sharedM.o2); - - (void)PR_JoinThread(t2); - (void)PR_JoinThread(t3); - - PR_DestroyMonitor(sharedM.o1); - PR_DestroyMonitor(sharedM.o2); - -} /* T1Mon */ - -static void PR_CALLBACK T2Lock(void *arg) -{ - PRStatus rv; - LockShared *shared = (LockShared*)arg; - - PR_Lock(shared->o1); - LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS); - rv = PR_WaitCondVar(shared->cv1, PR_SecondsToInterval(5)); - if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv); - else LogNow("T2 wait failed on o1", rv); - - rv = PR_NotifyCondVar(shared->cv1); - if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv); - else LogNow("T2 notify on o1 failed", rv); - - PR_Unlock(shared->o1); -} /* T2Lock */ - -static void PR_CALLBACK T3Lock(void *arg) -{ - PRStatus rv; - LockShared *shared = (LockShared*)arg; - - PR_Lock(shared->o2); - LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS); - rv = PR_WaitCondVar(shared->cv2, PR_SecondsToInterval(5)); - if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv); - else LogNow("T3 wait failed on o2", rv); - rv = PR_NotifyCondVar(shared->cv2); - LogNow("T3 notify on o2", rv); - PR_Unlock(shared->o2); - -} /* T3Lock */ - -/* -** Make shared' a static variable for Win16 -*/ -static LockShared sharedL; - -static void T1Lock(void) -{ - PRStatus rv; - PRThread *t2, *t3; - sharedL.o1 = PR_NewLock(); - sharedL.o2 = PR_NewLock(); - sharedL.cv1 = PR_NewCondVar(sharedL.o1); - sharedL.cv2 = PR_NewCondVar(sharedL.o2); - - PR_fprintf(err, "\n**********************************\n"); - PR_fprintf(err, " LOCKS\n"); - PR_fprintf(err, "**********************************\n"); - - base = PR_IntervalNow(); - - PR_Lock(sharedL.o1); - LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS); - rv = PR_WaitCondVar(sharedL.cv1, PR_SecondsToInterval(3)); - if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv); - else LogNow("T1 wait on o1 failed", rv); - PR_Unlock(sharedL.o1); - - LogNow("T1 creating T2", PR_SUCCESS); - t2 = PR_CreateThread( - PR_USER_THREAD, T2Lock, &sharedL, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - - LogNow("T1 creating T3", PR_SUCCESS); - t3 = PR_CreateThread( - PR_USER_THREAD, T3Lock, &sharedL, PR_PRIORITY_NORMAL, - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - - PR_Lock(sharedL.o2); - LogNow("T1 waiting forever on o2", PR_SUCCESS); - rv = PR_WaitCondVar(sharedL.cv2, PR_INTERVAL_NO_TIMEOUT); - if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv); - else LogNow("T1 wait on o2 failed", rv); - PR_Unlock(sharedL.o2); - - (void)PR_JoinThread(t2); - (void)PR_JoinThread(t3); - - PR_DestroyLock(sharedL.o1); - PR_DestroyLock(sharedL.o2); - PR_DestroyCondVar(sharedL.cv1); - PR_DestroyCondVar(sharedL.cv2); -} /* T1Lock */ - -static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) -{ - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dhlmc"); - PRBool locks = PR_FALSE, monitors = PR_FALSE, cmonitors = PR_FALSE; - - err = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode (noop) */ - break; - case 'l': /* locks */ - locks = PR_TRUE; - break; - case 'm': /* monitors */ - monitors = PR_TRUE; - break; - case 'c': /* cached monitors */ - cmonitors = PR_TRUE; - break; - case 'h': /* needs guidance */ - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - ml = PR_NewLock(); - if (locks) T1Lock(); - if (monitors) T1Mon(); - if (cmonitors) T1CMon(); - - PR_DestroyLock(ml); - - PR_fprintf(err, "Done!\n"); - return 0; -} /* main */ - - -int main(int argc, char **argv) -{ - PRIntn rv; - - PR_STDIO_INIT(); - rv = PR_Initialize(RealMain, argc, argv, 0); - return rv; -} /* main */ -/* xnotify.c */ diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/y2k.c nspr-4.10.7/mozilla/nsprpub/pr/tests/y2k.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/y2k.c 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/y2k.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,786 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * file: y2k.c - * description: Test for y2k compliance for NSPR. - * - * Sep 1999. lth. Added "Sun" specified dates to the test data. - */ -/*********************************************************************** -** Includes -***********************************************************************/ -/* Used to get the command line option */ -#include "plgetopt.h" - -#include "prinit.h" -#include "prtime.h" -#include "prprf.h" -#include "prlog.h" - -#include -#include -#include - -#define PRINT_DETAILS - -int failed_already=0; -PRBool debug_mode = PR_FALSE; - -static char *dayOfWeek[] = - { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; -static char *month[] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; - -PRLogModuleInfo *lm; - -static void PrintExplodedTime(const PRExplodedTime *et) { - PRInt32 totalOffset; - PRInt32 hourOffset, minOffset; - const char *sign; - - /* Print day of the week, month, day, hour, minute, and second */ - printf("%s %s %2ld %02ld:%02ld:%02ld ", - dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, - et->tm_hour, et->tm_min, et->tm_sec); - - /* Print year */ - printf("%hd ", et->tm_year); - - /* Print time zone */ - totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; - if (totalOffset == 0) { - printf("UTC "); - } else { - sign = "+"; - if (totalOffset < 0) { - totalOffset = -totalOffset; - sign = "-"; - } - hourOffset = totalOffset / 3600; - minOffset = (totalOffset % 3600) / 60; - printf("%s%02ld%02ld ", sign, hourOffset, minOffset); - } -#ifdef PRINT_DETAILS - printf("{%d, %d, %d, %d, %d, %d, %d, %d, %d, { %d, %d}}\n",et->tm_usec, - et->tm_sec, - et->tm_min, - et->tm_hour, - et->tm_mday, - et->tm_month, - et->tm_year, - et->tm_wday, - et->tm_yday, - et->tm_params.tp_gmt_offset, - et->tm_params.tp_dst_offset); -#endif -} - -static int ExplodedTimeIsEqual(const PRExplodedTime *et1, - const PRExplodedTime *et2) -{ - if (et1->tm_usec == et2->tm_usec && - et1->tm_sec == et2->tm_sec && - et1->tm_min == et2->tm_min && - et1->tm_hour == et2->tm_hour && - et1->tm_mday == et2->tm_mday && - et1->tm_month == et2->tm_month && - et1->tm_year == et2->tm_year && - et1->tm_wday == et2->tm_wday && - et1->tm_yday == et2->tm_yday && - et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset && - et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) { - return 1; - } else { - return 0; - } -} - -/* - * TEST 1: TestExplodeImplodeTime - * Description: - * For each given timestamp T (a PRTime value), call PR_ExplodeTime - * with GMT, US Pacific, and local time parameters. Compare the - * resulting calendar (exploded) time values with the expected - * values. - * - * Note: the expected local time values depend on the local time - * zone. The local time values stored in this test are for the US - * Pacific Time Zone. If you are running this test in a different - * time zone, you need to modify the values in the localt array. - * An example is provided below. - * - * Call PR_ImplodeTime for each of the exploded values and compare - * the resulting PRTime values with the original input. - * - * This test is run for the values of time T corresponding to the - * following dates: - * - 12/31/99 - before 2000 - * - 01/01/00 - after 2000 - * - Leap year - Feb 29, 2000 - * - March 1st, 2001 (after 1 year) - * - March 1st, 2005 (after second leap year) - * - 09/09/99 (used by some programs as an end of file marker) - * - * Call PR_Now, convert to calendar time using PR_ExplodeTime and - * manually check the result for correctness. The time should match - * the system clock. - * - * Tested functions: PR_Now, PR_ExplodeTime, PR_ImplodeTime, - * PR_LocalTimeParameters, PR_GMTParameters. - */ - -static PRTime prt[] = { - LL_INIT(220405, 2133125120), /* 946634400000000 */ - LL_INIT(220425, 2633779200), /* 946720800000000 */ - LL_INIT(221612, 2107598848), /* 951818400000000 */ - LL_INIT(228975, 663398400), /* 983440800000000 */ - LL_INIT(258365, 1974568960), /* 1109671200000000 */ - LL_INIT(218132, 1393788928), /* 936871200000000 */ - /* Sun's dates follow */ - LL_INIT( 213062, 4077979648 ), /* Dec 31 1998 10:00:00 */ - LL_INIT( 218152, 1894443008 ), /* Sep 10 1999 10:00:00 */ - LL_INIT( 221592, 1606944768 ), /* Feb 28 2000 10:00:00 */ - LL_INIT( 227768, 688924672 ), /* Dec 31 2000 10:00:00 */ - LL_INIT( 227788, 1189578752 ), /* Jan 1 2001 10:00:00 */ -}; - -static PRExplodedTime gmt[] = { - { 0, 0, 0, 10, 31, 11, 1999, 5, 364, {0, 0}}, /* 1999/12/31 10:00:00 GMT */ - { 0, 0, 0, 10, 1, 0, 2000, 6, 0, {0, 0}}, /* 2000/01/01 10:00:00 GMT */ - { 0, 0, 0, 10, 29, 1, 2000, 2, 59, {0, 0}}, /* 2000/02/29 10:00:00 GMT */ - { 0, 0, 0, 10, 1, 2, 2001, 4, 59, {0, 0}}, /* 2001/3/1 10:00:00 GMT */ - { 0, 0, 0, 10, 1, 2, 2005, 2, 59, {0, 0}}, /* 2005/3/1 10:00:00 GMT */ - { 0, 0, 0, 10, 9, 8, 1999, 4, 251, {0, 0}}, /* 1999/9/9 10:00:00 GMT */ - /* Sun's dates follow */ - { 0, 0, 0, 10, 31, 11, 1998, 4, 364, {0, 0}}, /* 12/31/1998 10:00:00 GMT */ - { 0, 0, 0, 10, 10, 8, 1999, 5, 252, {0, 0}}, /* 9/10/1999 10:00:00 GMT */ - { 0, 0, 0, 10, 28, 1, 2000, 1, 58, {0, 0}}, /* 2/28/2000 10:00:00 GMT */ - { 0, 0, 0, 10, 31, 11, 2000, 0, 365, {0, 0}}, /* 12/31/2000 10:00:00 GMT */ - { 0, 0, 0, 10, 1, 0, 2001, 1, 0, {0, 0}} /* 1/1/2001 10:00:00 GMT */ -}; - -static PRExplodedTime uspt[] = { -{ 0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST */ -{ 0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */ -{ 0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */ -{ 0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */ -{ 0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */ -{ 0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}}, /* 1999/9/9 3:00:00 PDT */ - /* Sun's dates follow */ - { 0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}}, /* 12/31/1998 00:00:00 GMT */ - { 0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}}, /* 9/10/1999 00:00:00 GMT */ - { 0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}}, /* 2/28/2000 00:00:00 GMT */ - { 0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}}, /* 12/31/2000 00:00:00 GMT */ - { 0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}} /* 1/1/2001 00:00:00 GMT */ -}; - -/* - * This test assumes that we are in US Pacific Time Zone. - * If you are running this test in a different time zone, - * you need to modify the localt array and fill in the - * expected results. The localt array for US Eastern Time - * Zone is provided as an example. - */ -static PRExplodedTime localt[] = { -{ 0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST */ -{ 0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */ -{ 0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */ -{ 0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */ -{ 0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */ -{ 0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}}, /* 1999/9/9 3:00:00 PDT */ - /* Sun's dates follow */ - { 0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}}, /* 12/31/1998 00:00:00 GMT */ - { 0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}}, /* 9/10/1999 00:00:00 GMT */ - { 0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}}, /* 2/28/2000 00:00:00 GMT */ - { 0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}}, /* 12/31/2000 00:00:00 GMT */ - { 0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}} /* 1/1/2001 00:00:00 GMT */ -}; - -#ifdef US_EASTERN_TIME -static PRExplodedTime localt[] = { -{ 0, 0, 0, 5, 31, 11, 1999, 5, 364, {-18000, 0}}, /* 1999/12/31 2:00:00 EST */ -{ 0, 0, 0, 5, 1, 0, 2000, 6, 0, {-18000, 0}}, /* 2000/01/01 2:00:00 EST */ -{ 0, 0, 0, 5, 29, 1, 2000, 2, 59, {-18000, 0}}, /* 2000/02/29 2:00:00 EST */ -{ 0, 0, 0, 5, 1, 2, 2001, 4, 59, {-18000, 0}}, /* 2001/3/1 2:00:00 EST */ -{ 0, 0, 0, 5, 1, 2, 2005, 2, 59, {-18000, 0}}, /* 2005/3/1 2:00:00 EST */ -{ 0, 0, 0, 6, 9, 8, 1999, 4, 251, {-18000, 3600}}, /* 1999/9/9 3:00:00 EDT */ - /* Sun's dates follow */ - { 0, 0, 0, 5, 31, 11, 1998, 4, 364, {-18000 0}}, /* 12/31/1998 00:00:00 GMT */ - { 0, 0, 0, 6, 10, 8, 1999, 5, 252, {-18000 3600}}, /* 9/10/1999 00:00:00 GMT */ - { 0, 0, 0, 5, 28, 1, 2000, 1, 58, {-18000 0}}, /* 2/28/2000 00:00:00 GMT */ - { 0, 0, 0, 5, 31, 11, 2000, 0, 365, {-18000 0}}, /* 12/31/2000 00:00:00 GMT */ - { 0, 0, 0, 5, 1, 0, 2001, 1, 0, {-18000 0}} /* 1/1/2001 00:00:00 GMT */ -}; -#endif - -static PRStatus TestExplodeImplodeTime(void) -{ - PRTime prt_tmp; - PRTime now; - int idx; - int array_size = sizeof(prt) / sizeof(PRTime); - PRExplodedTime et_tmp; - char buf[1024]; - - for (idx = 0; idx < array_size; idx++) { - PR_snprintf(buf, sizeof(buf), "%lld", prt[idx]); - if (debug_mode) printf("Time stamp %s\n", buf); - PR_ExplodeTime(prt[idx], PR_GMTParameters, &et_tmp); - if (!ExplodedTimeIsEqual(&et_tmp, &gmt[idx])) { - fprintf(stderr, "GMT not equal\n"); - PrintExplodedTime(&et_tmp); - PrintExplodedTime(&gmt[idx]); - exit(1); - } - prt_tmp = PR_ImplodeTime(&et_tmp); - if (LL_NE(prt_tmp, prt[idx])) { - fprintf(stderr, "PRTime not equal\n"); - exit(1); - } - if (debug_mode) { - printf("GMT: "); - PrintExplodedTime(&et_tmp); - printf("\n"); - } - - PR_ExplodeTime(prt[idx], PR_USPacificTimeParameters, &et_tmp); - if (!ExplodedTimeIsEqual(&et_tmp, &uspt[idx])) { - fprintf(stderr, "US Pacific Time not equal\n"); - PrintExplodedTime(&et_tmp); - PrintExplodedTime(&uspt[idx]); - exit(1); - } - prt_tmp = PR_ImplodeTime(&et_tmp); - if (LL_NE(prt_tmp, prt[idx])) { - fprintf(stderr, "PRTime not equal\n"); - exit(1); - } - if (debug_mode) { - printf("US Pacific Time: "); - PrintExplodedTime(&et_tmp); - printf("\n"); - } - - PR_ExplodeTime(prt[idx], PR_LocalTimeParameters, &et_tmp); - if (!ExplodedTimeIsEqual(&et_tmp, &localt[idx])) { - fprintf(stderr, "not equal\n"); - PrintExplodedTime(&et_tmp); - PrintExplodedTime(&localt[idx]); - exit(1); - } - prt_tmp = PR_ImplodeTime(&et_tmp); - if (LL_NE(prt_tmp, prt[idx])) { - fprintf(stderr, "not equal\n"); - exit(1); - } - if (debug_mode) { - printf("Local time:"); - PrintExplodedTime(&et_tmp); - printf("\n\n"); - } - } - - now = PR_Now(); - PR_ExplodeTime(now, PR_GMTParameters, &et_tmp); - printf("Current GMT is "); - PrintExplodedTime(&et_tmp); - printf("\n"); - prt_tmp = PR_ImplodeTime(&et_tmp); - if (LL_NE(prt_tmp, now)) { - fprintf(stderr, "not equal\n"); - exit(1); - } - PR_ExplodeTime(now, PR_USPacificTimeParameters, &et_tmp); - printf("Current US Pacific Time is "); - PrintExplodedTime(&et_tmp); - printf("\n"); - prt_tmp = PR_ImplodeTime(&et_tmp); - if (LL_NE(prt_tmp, now)) { - fprintf(stderr, "not equal\n"); - exit(1); - } - PR_ExplodeTime(now, PR_LocalTimeParameters, &et_tmp); - printf("Current local time is "); - PrintExplodedTime(&et_tmp); - printf("\n"); - prt_tmp = PR_ImplodeTime(&et_tmp); - if (LL_NE(prt_tmp, now)) { - fprintf(stderr, "not equal\n"); - exit(1); - } - printf("Please verify the results\n\n"); - - if (debug_mode) printf("Test 1 passed\n"); - return PR_SUCCESS; -} -/* End of Test 1: TestExplodeImplodeTime */ - -/* - * Test 2: Normalize Time - */ - -/* - * time increment for addition to PRExplodeTime - */ -typedef struct time_increment { - PRInt32 ti_usec; - PRInt32 ti_sec; - PRInt32 ti_min; - PRInt32 ti_hour; -} time_increment_t; - -/* - * Data for testing PR_Normalize - * Add the increment to base_time, normalize it to GMT and US Pacific - * Time zone. - */ -typedef struct normalize_test_data { - PRExplodedTime base_time; - time_increment_t increment; - PRExplodedTime expected_gmt_time; - PRExplodedTime expected_uspt_time; -} normalize_test_data_t; - - -/* - * Test data - the base time values cover dates of interest including y2k - 1, - * y2k + 1, y2k leap year, y2k leap date + 1year, - * y2k leap date + 4 years - */ -normalize_test_data_t normalize_test_array[] = { - /*usec sec min hour mday mo year wday yday {gmtoff, dstoff }*/ - - /* Fri 12/31/1999 19:32:48 PST */ - {{0, 48, 32, 19, 31, 11, 1999, 5, 364, { -28800, 0}}, - {0, 0, 30, 20}, - {0, 48, 2, 0, 2, 0, 2000, 0, 1, { 0, 0}}, /*Sun Jan 2 00:02:48 UTC 2000*/ - {0, 48, 2, 16, 1, 0, 2000, 6, 0, { -28800, 0}},/* Sat Jan 1 16:02:48 - PST 2000*/ - }, - /* Fri 99-12-31 23:59:02 GMT */ - {{0, 2, 59, 23, 31, 11, 1999, 5, 364, { 0, 0}}, - {0, 0, 45, 0}, - {0, 2, 44, 0, 1, 0, 2000, 6, 0, { 0, 0}},/* Sat Jan 1 00:44:02 UTC 2000*/ - {0, 2, 44, 16, 31, 11, 1999, 5, 364, { -28800, 0}}/*Fri Dec 31 16:44:02 - PST 1999*/ - }, - /* 99-12-25 12:00:00 GMT */ - {{0, 0, 0, 12, 25, 11, 1999, 6, 358, { 0, 0}}, - {0, 0, 0, 364 * 24}, - {0, 0, 0, 12, 23, 11, 2000, 6, 357, { 0, 0}},/*Sat Dec 23 12:00:00 - 2000 UTC*/ - {0, 0, 0, 4, 23, 11, 2000, 6, 357, { -28800, 0}}/*Sat Dec 23 04:00:00 - 2000 -0800*/ - }, - /* 00-01-1 00:00:00 PST */ - {{0, 0, 0, 0, 1, 0, 2000, 6, 0, { -28800, 0}}, - {0, 0, 0, 48}, - {0, 0, 0, 8, 3, 0, 2000, 1, 2, { 0, 0}},/*Mon Jan 3 08:00:00 2000 UTC*/ - {0, 0, 0, 0, 3, 0, 2000, 1, 2, { -28800, 0}}/*Mon Jan 3 00:00:00 2000 - -0800*/ - }, - /* 00-01-10 12:00:00 PST */ - {{0, 0, 0, 12, 10, 0, 2000, 1, 9, { -28800, 0}}, - {0, 0, 0, 364 * 5 * 24}, - {0, 0, 0, 20, 3, 0, 2005, 1, 2, { 0, 0}},/*Mon Jan 3 20:00:00 2005 UTC */ - {0, 0, 0, 12, 3, 0, 2005, 1, 2, { -28800, 0}}/*Mon Jan 3 12:00:00 - 2005 -0800*/ - }, - /* 00-02-28 15:39 GMT */ - {{0, 0, 39, 15, 28, 1, 2000, 1, 58, { 0, 0}}, - {0, 0, 0, 24}, - {0, 0, 39, 15, 29, 1, 2000, 2, 59, { 0, 0}}, /*Tue Feb 29 15:39:00 2000 - UTC*/ - {0, 0, 39, 7, 29, 1, 2000, 2, 59, { -28800, 0}}/*Tue Feb 29 07:39:00 - 2000 -0800*/ - }, - /* 01-03-01 12:00 PST */ - {{0, 0, 0, 12, 3, 0, 2001, 3, 2, { -28800, 0}},/*Wed Jan 3 12:00:00 - -0800 2001*/ - {0, 30, 30,45}, - {0, 30, 30, 17, 5, 0, 2001, 5, 4, { 0, 0}}, /*Fri Jan 5 17:30:30 2001 - UTC*/ - {0, 30, 30, 9, 5, 0, 2001, 5, 4, { -28800, 0}} /*Fri Jan 5 09:30:30 - 2001 -0800*/ - }, - /* 2004-04-26 12:00 GMT */ - {{0, 0, 0, 20, 3, 0, 2001, 3, 2, { 0, 0}}, - {0, 0, 30,0}, - {0, 0, 30, 20, 3, 0, 2001, 3, 2, { 0, 0}},/*Wed Jan 3 20:30:00 2001 UTC*/ - {0, 0, 30, 12, 3, 0, 2001, 3, 2, { -28800, 0}}/*Wed Jan 3 12:30:00 - 2001 -0800*/ - }, - /* 99-09-09 00:00 GMT */ - {{0, 0, 0, 0, 9, 8, 1999, 4, 251, { 0, 0}}, - {0, 0, 0, 12}, - {0, 0, 0, 12, 9, 8, 1999, 4, 251, { 0, 0}},/*Thu Sep 9 12:00:00 1999 UTC*/ - {0, 0, 0, 5, 9, 8, 1999, 4, 251, { -28800, 3600}}/*Thu Sep 9 05:00:00 - 1999 -0700*/ - } -}; - -void add_time_increment(PRExplodedTime *et1, time_increment_t *it) -{ - et1->tm_usec += it->ti_usec; - et1->tm_sec += it->ti_sec; - et1->tm_min += it->ti_min; - et1->tm_hour += it->ti_hour; -} - -/* -** TestNormalizeTime() -- Test PR_NormalizeTime() -** For each data item, add the time increment to the base_time and then -** normalize it for GMT and local time zones. This test assumes that -** the local time zone is the Pacific Time Zone. The normalized values -** should match the expected values in the data item. -** -*/ -PRStatus TestNormalizeTime(void) -{ -int idx, count; -normalize_test_data_t *itemp; -time_increment_t *itp; - - count = sizeof(normalize_test_array)/sizeof(normalize_test_array[0]); - for (idx = 0; idx < count; idx++) { - itemp = &normalize_test_array[idx]; - if (debug_mode) { - printf("%2d. %15s",idx +1,"Base time: "); - PrintExplodedTime(&itemp->base_time); - printf("\n"); - } - itp = &itemp->increment; - if (debug_mode) { - printf("%20s %2d hrs %2d min %3d sec\n","Add",itp->ti_hour, - itp->ti_min, itp->ti_sec); - } - add_time_increment(&itemp->base_time, &itemp->increment); - PR_NormalizeTime(&itemp->base_time, PR_LocalTimeParameters); - if (debug_mode) { - printf("%19s","PST time: "); - PrintExplodedTime(&itemp->base_time); - printf("\n"); - } - if (!ExplodedTimeIsEqual(&itemp->base_time, - &itemp->expected_uspt_time)) { - printf("PR_NormalizeTime failed\n"); - if (debug_mode) - PrintExplodedTime(&itemp->expected_uspt_time); - return PR_FAILURE; - } - PR_NormalizeTime(&itemp->base_time, PR_GMTParameters); - if (debug_mode) { - printf("%19s","GMT time: "); - PrintExplodedTime(&itemp->base_time); - printf("\n"); - } - - if (!ExplodedTimeIsEqual(&itemp->base_time, - &itemp->expected_gmt_time)) { - printf("PR_NormalizeTime failed\n"); - return PR_FAILURE; - } - } - return PR_SUCCESS; -} - - -/* -** ParseTest. Structure defining a string time and a matching exploded time -** -*/ -typedef struct ParseTest -{ - char *sDate; /* string to be converted using PR_ParseTimeString() */ - PRExplodedTime et; /* expected result of the conversion */ -} ParseTest; - -static ParseTest parseArray[] = -{ - /* |<----- expected result ------------------------------------------->| */ - /* "string to test" usec sec min hour day mo year wday julian {gmtoff, dstoff }*/ - { "Thursday 1 Jan 1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "1 Jan 1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "1-Jan-1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "01-Jan-1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "January 1, 1970", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "January 1, 1970 00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "January 01, 1970 00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "January 01 1970 00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "January 01 1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "01-01-1970", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "01/01/1970", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "01/01/70", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "01/01/70 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "70/01/01 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "70/1/1 00:00:", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "00:00 Thursday, January 1, 1970",{ 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "1-Jan-70 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "70-01-01 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - { "70/01/01 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, - - /* 31-Dec-1969 */ - { "Wed 31 Dec 1969 00:00:00", { 000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0 }}}, - { "31 Dec 1969 00:00:00", { 000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0 }}}, - { "12/31/69 00:00:00", { 000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0 }}}, - { "12/31/1969 00:00:00", { 000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0 }}}, - { "12-31-69 00:00:00", { 000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0 }}}, - { "12-31-1969 00:00:00", { 000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0 }}}, - { "69-12-31 00:00:00", { 000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0 }}}, - { "69/12/31 00:00:00", { 000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0 }}}, - - /* "Sun". 31-Dec-1998 (?) */ - { "Thu 31 Dec 1998 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, - { "12/31/98 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, - { "12/31/1998 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, - { "12-31-98 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, - { "12-31-1998 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, - { "98-12-31 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, - { "98/12/31 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, - - /* 09-Sep-1999. Interesting because of its use as an eof marker? */ - { "09 Sep 1999 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, - { "9/9/99 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, - { "9/9/1999 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, - { "9-9-99 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, - { "9-9-1999 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, - { "09-09-99 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, - { "09-09-1999 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, - { "99-09-09 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, - - /* "Sun". 10-Sep-1999. Because Sun said so. */ - { "10 Sep 1999 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, - { "9/10/99 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, - { "9/10/1999 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, - { "9-10-99 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, - { "9-10-1999 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, - { "09-10-99 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, - { "09-10-1999 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, - { "99-09-10 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, - - /* 31-Dec-1999 */ - { "31 Dec 1999 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, - { "12/31/99 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, - { "12/31/1999 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, - { "12-31-99 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, - { "12-31-1999 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, - { "99-12-31 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, - { "99/12/31 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, - - /* 01-Jan-2000 */ - { "01 Jan 2000 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, - { "1/1/00 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, - { "1/1/2000 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, - { "1-1-00 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, - { "1-1-2000 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, - { "01-01-00 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, - { "Saturday 01-01-2000 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, - - /* "Sun". 28-Feb-2000 */ - { "28 Feb 2000 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, - { "2/28/00 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, - { "2/28/2000 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, - { "2-28-00 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, - { "2-28-2000 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, - { "02-28-00 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, - { "02-28-2000 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, - - /* 29-Feb-2000 */ - { "29 Feb 2000 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, - { "2/29/00 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, - { "2/29/2000 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, - { "2-29-00 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, - { "2-29-2000 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, - { "02-29-00 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, - { "02-29-2000 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, - - /* 01-Mar-2000 */ - { "01 Mar 2000 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, - { "3/1/00 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, - { "3/1/2000 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, - { "3-1-00 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, - { "03-01-00 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, - { "03-01-2000 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, - - /* "Sun". 31-Dec-2000 */ - { "31 Dec 2000 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, - { "12/31/00 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, - { "12/31/2000 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, - { "12-31-00 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, - { "12-31-2000 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, - { "00-12-31 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, - { "00/12/31 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, - - /* "Sun". 01-Jan-2001 */ - { "01 Jan 2001 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, - { "1/1/01 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, - { "1/1/2001 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, - { "1-1-01 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, - { "1-1-2001 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, - { "01-01-01 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, - { "Saturday 01-01-2001 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, - - /* 01-Mar-2001 */ - { "01 Mar 2001 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, - { "3/1/01 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, - { "3/1/2001 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, - { "3-1-01 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, - { "3-1-2001 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, - { "03-01-01 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, - { "03-01-2001 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, - - /* 29-Feb-2004 */ - { "29 Feb 2004 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, - { "2/29/04 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, - { "2/29/2004 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, - { "2-29-04 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, - { "2-29-2004 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, - - /* 01-Mar-2004 */ - { "01 Mar 2004 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, - { "3/1/04 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, - { "3/1/2004 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, - { "3-1-04 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, - { "3-1-2004 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, - { "03-01-04 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, - { "03-01-2004 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, - - /* 01-Mar-2005 */ - { "01 Mar 2005 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, - { "3/1/05 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, - { "3/1/2005 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, - { "3-1-05 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, - { "3-1-2005 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, - { "03-01-05 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, - { "03-01-2005 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, - - /* last element. string must be null */ - { NULL } -}; /* end array of ParseTest */ - -/* -** TestParseTime() -- Test PR_ParseTimeString() for y2k compliance -** -** TestParseTime() loops thru the array parseArray. For each element in -** the array, he calls PR_ParseTimeString() with sDate as the conversion -** argument. The result (ct) is then converted to a PRExplodedTime structure -** and compared with the exploded time value (parseArray[n].et) in the -** array element; if equal, the element passes the test. -** -** The array parseArray[] contains entries that are interesting to the -** y2k problem. -** -** -*/ -static PRStatus TestParseTime( void ) -{ - ParseTest *ptp = parseArray; - PRTime ct; - PRExplodedTime cet; - char *sp = ptp->sDate; - PRStatus rc; - PRStatus rv = PR_SUCCESS; - - while ( sp != NULL) - { - rc = PR_ParseTimeString( sp, PR_FALSE, &ct ); - if ( PR_FAILURE == rc ) - { - printf("TestParseTime(): PR_ParseTimeString() failed to convert: %s\n", sp ); - rv = PR_FAILURE; - failed_already = 1; - } - else - { - PR_ExplodeTime( ct, PR_LocalTimeParameters , &cet ); - - if ( !ExplodedTimeIsEqual( &cet, &ptp->et )) - { - printf("TestParseTime(): Exploded time compare failed: %s\n", sp ); - if ( debug_mode ) - { - PrintExplodedTime( &cet ); - printf("\n"); - PrintExplodedTime( &ptp->et ); - printf("\n"); - } - - rv = PR_FAILURE; - failed_already = 1; - } - } - - /* point to next element in array, keep going */ - ptp++; - sp = ptp->sDate; - } /* end while() */ - - return( rv ); -} /* end TestParseTime() */ - -int main(int argc, char** argv) -{ - /* The command line argument: -d is used to determine if the test is being run - in debug mode. The regress tool requires only one line output:PASS or FAIL. - All of the printfs associated with this test has been handled with a if (debug_mode) - test. - Usage: test_name -d - */ - PLOptStatus os; - PLOptState *opt; - - PR_STDIO_INIT(); - opt = PL_CreateOptState(argc, argv, "d"); - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - /* main test */ - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - lm = PR_NewLogModule("test"); - - if ( PR_FAILURE == TestExplodeImplodeTime()) - { - PR_LOG( lm, PR_LOG_ERROR, - ("TestExplodeImplodeTime() failed")); - } - else - printf("Test 1: Calendar Time Test passed\n"); - - if ( PR_FAILURE == TestNormalizeTime()) - { - PR_LOG( lm, PR_LOG_ERROR, - ("TestNormalizeTime() failed")); - } - else - printf("Test 2: Normalize Time Test passed\n"); - - if ( PR_FAILURE == TestParseTime()) - { - PR_LOG( lm, PR_LOG_ERROR, - ("TestParseTime() failed")); - } - else - printf("Test 3: Parse Time Test passed\n"); - - if (failed_already) - return 1; - else - return 0; -} /* end main() y2k.c */ - diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/y2ktmo.c nspr-4.10.7/mozilla/nsprpub/pr/tests/y2ktmo.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/y2ktmo.c 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/y2ktmo.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,550 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Test: y2ktmo - * - * Description: - * This test tests the interval time facilities in NSPR for Y2K - * compliance. All the functions that take a timeout argument - * are tested: PR_Sleep, socket I/O (PR_Accept is taken as a - * representative), PR_Poll, PR_WaitCondVar, PR_Wait, and - * PR_CWait. A thread of each thread scope (local, global, and - * global bound) is created to call each of these functions. - * The test should be started at the specified number of seconds - * (called the lead time) before a Y2K rollover test date. The - * timeout values for these threads will span over the rollover - * date by at least the specified number of seconds. For - * example, if the lead time is 5 seconds, the test should - * be started at time (D - 5), where D is a rollover date, and - * the threads will time out at or after time (D + 5). The - * timeout values for the threads are spaced one second apart. - * - * When a thread times out, it calls PR_IntervalNow() to verify - * that it did wait for the specified time. In addition, it - * calls a platform-native function to verify the actual elapsed - * time again, to rule out the possibility that PR_IntervalNow() - * is broken. We allow the actual elapsed time to deviate from - * the specified timeout by a certain tolerance (in milliseconds). - */ - -#include "nspr.h" -#include "plgetopt.h" - -#include -#include -#include -#if defined(XP_UNIX) -#include /* for gettimeofday */ -#endif -#if defined(WIN32) -#if defined(WINCE) -#include -#else -#include -#include /* for _ftime */ -#endif -#endif - -#define DEFAULT_LEAD_TIME_SECS 5 -#define DEFAULT_TOLERANCE_MSECS 500 - -static PRBool debug_mode = PR_FALSE; -static PRInt32 lead_time_secs = DEFAULT_LEAD_TIME_SECS; -static PRInt32 tolerance_msecs = DEFAULT_TOLERANCE_MSECS; -static PRIntervalTime start_time; -static PRIntervalTime tolerance; - -#if defined(XP_UNIX) -static struct timeval start_time_tv; -#endif -#if defined(WIN32) -#if defined(WINCE) -static DWORD start_time_tick; -#else -static struct _timeb start_time_tb; -#endif -#endif - -static void SleepThread(void *arg) -{ - PRIntervalTime timeout = (PRIntervalTime) arg; - PRIntervalTime elapsed; -#if defined(XP_UNIX) || defined(WIN32) - PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); - PRInt32 elapsed_msecs; -#endif -#if defined(XP_UNIX) - struct timeval end_time_tv; -#endif -#if defined(WIN32) && !defined(WINCE) - struct _timeb end_time_tb; -#endif - - if (PR_Sleep(timeout) == PR_FAILURE) { - fprintf(stderr, "PR_Sleep failed\n"); - exit(1); - } - elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); - if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#if defined(XP_UNIX) - gettimeofday(&end_time_tv, NULL); - elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) - + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; -#endif -#if defined(WIN32) -#if defined(WINCE) - elapsed_msecs = GetTickCount() - start_time_tick; -#else - _ftime(&end_time_tb); - elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) - + (end_time_tb.millitm - start_time_tb.millitm); -#endif -#endif -#if defined(XP_UNIX) || defined(WIN32) - if (elapsed_msecs + tolerance_msecs < timeout_msecs - || elapsed_msecs > timeout_msecs + tolerance_msecs) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#endif - if (debug_mode) { - fprintf(stderr, "Sleep thread (scope %d) done\n", - PR_GetThreadScope(PR_GetCurrentThread())); - } -} - -static void AcceptThread(void *arg) -{ - PRIntervalTime timeout = (PRIntervalTime) arg; - PRIntervalTime elapsed; -#if defined(XP_UNIX) || defined(WIN32) - PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); - PRInt32 elapsed_msecs; -#endif -#if defined(XP_UNIX) - struct timeval end_time_tv; -#endif -#if defined(WIN32) && !defined(WINCE) - struct _timeb end_time_tb; -#endif - PRFileDesc *sock; - PRNetAddr addr; - PRFileDesc *accepted; - - sock = PR_NewTCPSocket(); - if (sock == NULL) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - memset(&addr, 0, sizeof(addr)); - addr.inet.family = PR_AF_INET; - addr.inet.port = 0; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - if (PR_Bind(sock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_Bind failed\n"); - exit(1); - } - if (PR_Listen(sock, 5) == PR_FAILURE) { - fprintf(stderr, "PR_Listen failed\n"); - exit(1); - } - accepted = PR_Accept(sock, NULL, timeout); - if (accepted != NULL || PR_GetError() != PR_IO_TIMEOUT_ERROR) { - fprintf(stderr, "PR_Accept did not time out\n"); - exit(1); - } - elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); - if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#if defined(XP_UNIX) - gettimeofday(&end_time_tv, NULL); - elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) - + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; -#endif -#if defined(WIN32) -#if defined(WINCE) - elapsed_msecs = GetTickCount() - start_time_tick; -#else - _ftime(&end_time_tb); - elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) - + (end_time_tb.millitm - start_time_tb.millitm); -#endif -#endif -#if defined(XP_UNIX) || defined(WIN32) - if (elapsed_msecs + tolerance_msecs < timeout_msecs - || elapsed_msecs > timeout_msecs + tolerance_msecs) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#endif - if (PR_Close(sock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - if (debug_mode) { - fprintf(stderr, "Accept thread (scope %d) done\n", - PR_GetThreadScope(PR_GetCurrentThread())); - } -} - -static void PollThread(void *arg) -{ - PRIntervalTime timeout = (PRIntervalTime) arg; - PRIntervalTime elapsed; -#if defined(XP_UNIX) || defined(WIN32) - PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); - PRInt32 elapsed_msecs; -#endif -#if defined(XP_UNIX) - struct timeval end_time_tv; -#endif -#if defined(WIN32) && !defined(WINCE) - struct _timeb end_time_tb; -#endif - PRFileDesc *sock; - PRNetAddr addr; - PRPollDesc pd; - PRIntn rv; - - sock = PR_NewTCPSocket(); - if (sock == NULL) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - memset(&addr, 0, sizeof(addr)); - addr.inet.family = PR_AF_INET; - addr.inet.port = 0; - addr.inet.ip = PR_htonl(PR_INADDR_ANY); - if (PR_Bind(sock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_Bind failed\n"); - exit(1); - } - if (PR_Listen(sock, 5) == PR_FAILURE) { - fprintf(stderr, "PR_Listen failed\n"); - exit(1); - } - pd.fd = sock; - pd.in_flags = PR_POLL_READ; - rv = PR_Poll(&pd, 1, timeout); - if (rv != 0) { - fprintf(stderr, "PR_Poll did not time out\n"); - exit(1); - } - elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); - if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#if defined(XP_UNIX) - gettimeofday(&end_time_tv, NULL); - elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) - + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; -#endif -#if defined(WIN32) -#if defined(WINCE) - elapsed_msecs = GetTickCount() - start_time_tick; -#else - _ftime(&end_time_tb); - elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) - + (end_time_tb.millitm - start_time_tb.millitm); -#endif -#endif -#if defined(XP_UNIX) || defined(WIN32) - if (elapsed_msecs + tolerance_msecs < timeout_msecs - || elapsed_msecs > timeout_msecs + tolerance_msecs) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#endif - if (PR_Close(sock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - if (debug_mode) { - fprintf(stderr, "Poll thread (scope %d) done\n", - PR_GetThreadScope(PR_GetCurrentThread())); - } -} - -static void WaitCondVarThread(void *arg) -{ - PRIntervalTime timeout = (PRIntervalTime) arg; - PRIntervalTime elapsed; -#if defined(XP_UNIX) || defined(WIN32) - PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); - PRInt32 elapsed_msecs; -#endif -#if defined(XP_UNIX) - struct timeval end_time_tv; -#endif -#if defined(WIN32) && !defined(WINCE) - struct _timeb end_time_tb; -#endif - PRLock *ml; - PRCondVar *cv; - - ml = PR_NewLock(); - if (ml == NULL) { - fprintf(stderr, "PR_NewLock failed\n"); - exit(1); - } - cv = PR_NewCondVar(ml); - if (cv == NULL) { - fprintf(stderr, "PR_NewCondVar failed\n"); - exit(1); - } - PR_Lock(ml); - PR_WaitCondVar(cv, timeout); - PR_Unlock(ml); - elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); - if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#if defined(XP_UNIX) - gettimeofday(&end_time_tv, NULL); - elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) - + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; -#endif -#if defined(WIN32) -#if defined(WINCE) - elapsed_msecs = GetTickCount() - start_time_tick; -#else - _ftime(&end_time_tb); - elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) - + (end_time_tb.millitm - start_time_tb.millitm); -#endif -#endif -#if defined(XP_UNIX) || defined(WIN32) - if (elapsed_msecs + tolerance_msecs < timeout_msecs - || elapsed_msecs > timeout_msecs + tolerance_msecs) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#endif - PR_DestroyCondVar(cv); - PR_DestroyLock(ml); - if (debug_mode) { - fprintf(stderr, "wait cond var thread (scope %d) done\n", - PR_GetThreadScope(PR_GetCurrentThread())); - } -} - -static void WaitMonitorThread(void *arg) -{ - PRIntervalTime timeout = (PRIntervalTime) arg; - PRIntervalTime elapsed; -#if defined(XP_UNIX) || defined(WIN32) - PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); - PRInt32 elapsed_msecs; -#endif -#if defined(XP_UNIX) - struct timeval end_time_tv; -#endif -#if defined(WIN32) && !defined(WINCE) - struct _timeb end_time_tb; -#endif - PRMonitor *mon; - - mon = PR_NewMonitor(); - if (mon == NULL) { - fprintf(stderr, "PR_NewMonitor failed\n"); - exit(1); - } - PR_EnterMonitor(mon); - PR_Wait(mon, timeout); - PR_ExitMonitor(mon); - elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); - if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#if defined(XP_UNIX) - gettimeofday(&end_time_tv, NULL); - elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) - + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; -#endif -#if defined(WIN32) -#if defined(WINCE) - elapsed_msecs = GetTickCount() - start_time_tick; -#else - _ftime(&end_time_tb); - elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) - + (end_time_tb.millitm - start_time_tb.millitm); -#endif -#endif -#if defined(XP_UNIX) || defined(WIN32) - if (elapsed_msecs + tolerance_msecs < timeout_msecs - || elapsed_msecs > timeout_msecs + tolerance_msecs) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#endif - PR_DestroyMonitor(mon); - if (debug_mode) { - fprintf(stderr, "wait monitor thread (scope %d) done\n", - PR_GetThreadScope(PR_GetCurrentThread())); - } -} - -static void WaitCMonitorThread(void *arg) -{ - PRIntervalTime timeout = (PRIntervalTime) arg; - PRIntervalTime elapsed; -#if defined(XP_UNIX) || defined(WIN32) - PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); - PRInt32 elapsed_msecs; -#endif -#if defined(XP_UNIX) - struct timeval end_time_tv; -#endif -#if defined(WIN32) && !defined(WINCE) - struct _timeb end_time_tb; -#endif - int dummy; - - PR_CEnterMonitor(&dummy); - PR_CWait(&dummy, timeout); - PR_CExitMonitor(&dummy); - elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); - if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#if defined(XP_UNIX) - gettimeofday(&end_time_tv, NULL); - elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) - + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; -#endif -#if defined(WIN32) -#if defined(WINCE) - elapsed_msecs = GetTickCount() - start_time_tick; -#else - _ftime(&end_time_tb); - elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) - + (end_time_tb.millitm - start_time_tb.millitm); -#endif -#endif -#if defined(XP_UNIX) || defined(WIN32) - if (elapsed_msecs + tolerance_msecs < timeout_msecs - || elapsed_msecs > timeout_msecs + tolerance_msecs) { - fprintf(stderr, "timeout wrong\n"); - exit(1); - } -#endif - if (debug_mode) { - fprintf(stderr, "wait cached monitor thread (scope %d) done\n", - PR_GetThreadScope(PR_GetCurrentThread())); - } -} - -typedef void (*NSPRThreadFunc)(void*); - -static NSPRThreadFunc threadFuncs[] = { - SleepThread, AcceptThread, PollThread, - WaitCondVarThread, WaitMonitorThread, WaitCMonitorThread}; - -static PRThreadScope threadScopes[] = { - PR_LOCAL_THREAD, PR_GLOBAL_THREAD, PR_GLOBAL_BOUND_THREAD}; - -static void Help(void) -{ - fprintf(stderr, "y2ktmo test program usage:\n"); - fprintf(stderr, "\t-d debug mode (FALSE)\n"); - fprintf(stderr, "\t-l lead time (%d)\n", - DEFAULT_LEAD_TIME_SECS); - fprintf(stderr, "\t-t tolerance (%d)\n", - DEFAULT_TOLERANCE_MSECS); - fprintf(stderr, "\t-h this message\n"); -} /* Help */ - -int main(int argc, char **argv) -{ - PRThread **threads; - int num_thread_funcs = sizeof(threadFuncs)/sizeof(NSPRThreadFunc); - int num_thread_scopes = sizeof(threadScopes)/sizeof(PRThreadScope); - int i, j; - int idx; - PRInt32 secs; - PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dl:t:h"); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { - if (PL_OPT_BAD == os) continue; - switch (opt->option) { - case 'd': /* debug mode */ - debug_mode = PR_TRUE; - break; - case 'l': /* lead time */ - lead_time_secs = atoi(opt->value); - break; - case 't': /* tolerance */ - tolerance_msecs = atoi(opt->value); - break; - case 'h': - default: - Help(); - return 2; - } - } - PL_DestroyOptState(opt); - - if (debug_mode) { - fprintf(stderr, "lead time: %d secs\n", lead_time_secs); - fprintf(stderr, "tolerance: %d msecs\n", tolerance_msecs); - } - - start_time = PR_IntervalNow(); -#if defined(XP_UNIX) - gettimeofday(&start_time_tv, NULL); -#endif -#if defined(WIN32) -#ifdef WINCE - start_time_tick = GetTickCount(); -#else - _ftime(&start_time_tb); -#endif -#endif - tolerance = PR_MillisecondsToInterval(tolerance_msecs); - - threads = PR_Malloc( - num_thread_scopes * num_thread_funcs * sizeof(PRThread*)); - if (threads == NULL) { - fprintf(stderr, "PR_Malloc failed\n"); - exit(1); - } - - /* start to time out 5 seconds after a rollover date */ - secs = lead_time_secs + 5; - idx = 0; - for (i = 0; i < num_thread_scopes; i++) { - for (j = 0; j < num_thread_funcs; j++) { - threads[idx] = PR_CreateThread(PR_USER_THREAD, threadFuncs[j], - (void*)PR_SecondsToInterval(secs), PR_PRIORITY_NORMAL, - threadScopes[i], PR_JOINABLE_THREAD, 0); - if (threads[idx] == NULL) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - secs++; - idx++; - } - } - for (idx = 0; idx < num_thread_scopes*num_thread_funcs; idx++) { - if (PR_JoinThread(threads[idx]) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - } - PR_Free(threads); - printf("PASS\n"); - return 0; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/pr/tests/yield.c nspr-4.10.7/mozilla/nsprpub/pr/tests/yield.c --- nspr-4.9.5/mozilla/nsprpub/pr/tests/yield.c 2012-03-06 13:14:33.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/pr/tests/yield.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include -#include "prthread.h" -#include "prinit.h" -#ifndef XP_OS2 -#include "private/pprmisc.h" -#include -#else -#include "primpl.h" -#include -#endif - -#define THREADS 10 - - -void -threadmain(void *_id) -{ - int id = (int)_id; - int index; - - printf("thread %d alive\n", id); - for (index=0; index<10; index++) { - printf("thread %d yielding\n", id); - PR_Sleep(0); - printf("thread %d awake\n", id); - } - printf("thread %d dead\n", id); - -} - -int main(int argc, char **argv) -{ - int index; - PRThread *a[THREADS]; - - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 5); - PR_STDIO_INIT(); - - for (index=0; index - -int main(int argc, char **argv) -{ - printf("PASS\n"); - return 0; -} - -#else /* XP_UNIX */ - -#include "nspr.h" -#include "private/pprio.h" - -#include -#include -#include -#include -#include - -static void ClientThread(void *arg) -{ - PRFileDesc *sock; - PRNetAddr addr; - PRUint16 port = (PRUint16) arg; - char buf[1024]; - PRInt32 nbytes; - - sock = PR_NewTCPSocket(); - if (NULL == sock) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_InitializeNetAddr failed\n"); - exit(1); - } - if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { - fprintf(stderr, "PR_Connect failed\n"); - exit(1); - } - /* - * Sleep 5 seconds to force the server thread to get EAGAIN. - */ - if (PR_Sleep(PR_SecondsToInterval(5)) == PR_FAILURE) { - fprintf(stderr, "PR_Sleep failed\n"); - exit(1); - } - /* - * Then start reading. - */ - while ((nbytes = PR_Read(sock, buf, sizeof(buf))) > 0) { - /* empty loop body */ - } - if (-1 == nbytes) { - fprintf(stderr, "PR_Read failed\n"); - exit(1); - } - if (PR_Close(sock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } -} - -int main() -{ - PRFileDesc *listenSock; - PRFileDesc *acceptSock; - int osfd; - PRThread *clientThread; - PRNetAddr addr; - char buf[1024]; - PRInt32 nbytes; - PRIOVec iov; -#ifdef SYMBIAN - int loopcount=0; -#endif - - memset(buf, 0, sizeof(buf)); /* Initialize the buffer. */ - listenSock = PR_NewTCPSocket(); - if (NULL == listenSock) { - fprintf(stderr, "PR_NewTCPSocket failed\n"); - exit(1); - } - if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_InitializeNetAddr failed\n"); - exit(1); - } - if (PR_Bind(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_Bind failed\n"); - exit(1); - } - /* Find out what port number we are bound to. */ - if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { - fprintf(stderr, "PR_GetSockName failed\n"); - exit(1); - } - if (PR_Listen(listenSock, 5) == PR_FAILURE) { - fprintf(stderr, "PR_Listen failed\n"); - exit(1); - } - - /* - * First test PR_Writev. - */ - clientThread = PR_CreateThread(PR_USER_THREAD, - ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)), - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (NULL == clientThread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } - acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (NULL == acceptSock) { - fprintf(stderr, "PR_Accept failed\n"); - exit(1); - } - osfd = PR_FileDesc2NativeHandle(acceptSock); - while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) { - /* empty loop body */ -#ifdef SYMBIAN - if (loopcount++>64) break; -#endif - } - if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) { - fprintf(stderr, "write failed\n"); - exit(1); - } - iov.iov_base = buf; - iov.iov_len = 0; - printf("calling PR_Writev with a zero-length buffer\n"); - fflush(stdout); - nbytes = PR_Writev(acceptSock, &iov, 1, PR_INTERVAL_NO_TIMEOUT); - if (nbytes != 0) { - fprintf(stderr, "PR_Writev should return 0 but returns %d\n", nbytes); - exit(1); - } - if (PR_Close(acceptSock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - if (PR_JoinThread(clientThread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - - /* - * Then test PR_Write. - */ - clientThread = PR_CreateThread(PR_USER_THREAD, - ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)), - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (NULL == clientThread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } -#ifdef SYMBIAN - loopcount = 0; -#endif - acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (NULL == acceptSock) { - fprintf(stderr, "PR_Accept failed\n"); - exit(1); - } - osfd = PR_FileDesc2NativeHandle(acceptSock); - while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) { - /* empty loop body */ -#ifdef SYMBIAN - if (loopcount++>64) break; -#endif - } - if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) { - fprintf(stderr, "write failed\n"); - exit(1); - } - printf("calling PR_Write with a zero-length buffer\n"); - fflush(stdout); - nbytes = PR_Write(acceptSock, buf, 0); - if (nbytes != 0) { - fprintf(stderr, "PR_Write should return 0 but returns %d\n", nbytes); - exit(1); - } - if (PR_Close(acceptSock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - if (PR_JoinThread(clientThread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - - /* - * Finally test PR_Send. - */ - clientThread = PR_CreateThread(PR_USER_THREAD, - ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)), - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (NULL == clientThread) { - fprintf(stderr, "PR_CreateThread failed\n"); - exit(1); - } -#ifdef SYMBIAN - loopcount = 0; -#endif - acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); - if (NULL == acceptSock) { - fprintf(stderr, "PR_Accept failed\n"); - exit(1); - } - osfd = PR_FileDesc2NativeHandle(acceptSock); - while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) { - /* empty loop body */ -#ifdef SYMBIAN - if (loopcount++>64) break; -#endif - } - if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) { - fprintf(stderr, "write failed\n"); - exit(1); - } - printf("calling PR_Send with a zero-length buffer\n"); - fflush(stdout); - nbytes = PR_Send(acceptSock, buf, 0, 0, PR_INTERVAL_NO_TIMEOUT); - if (nbytes != 0) { - fprintf(stderr, "PR_Send should return 0 but returns %d\n", nbytes); - exit(1); - } - if (PR_Close(acceptSock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - if (PR_JoinThread(clientThread) == PR_FAILURE) { - fprintf(stderr, "PR_JoinThread failed\n"); - exit(1); - } - - if (PR_Close(listenSock) == PR_FAILURE) { - fprintf(stderr, "PR_Close failed\n"); - exit(1); - } - printf("PASS\n"); - return 0; -} - -#endif /* XP_UNIX */ diff -Nru nspr-4.9.5/mozilla/nsprpub/tools/.cvsignore nspr-4.10.7/mozilla/nsprpub/tools/.cvsignore --- nspr-4.9.5/mozilla/nsprpub/tools/.cvsignore 2001-05-12 05:12:57.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/tools/.cvsignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Makefile diff -Nru nspr-4.9.5/mozilla/nsprpub/tools/httpget.c nspr-4.10.7/mozilla/nsprpub/tools/httpget.c --- nspr-4.9.5/mozilla/nsprpub/tools/httpget.c 2012-03-06 13:14:34.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/tools/httpget.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,433 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -/* - * Author: Wan-Teh Chang - * - * Given an HTTP URL, httpget uses the GET method to fetch the file. - * The fetched file is written to stdout by default, or can be - * saved in an output file. - * - * This is a single-threaded program. - */ - -#include "prio.h" -#include "prnetdb.h" -#include "prlog.h" -#include "prerror.h" -#include "prprf.h" -#include "prinit.h" - -#include -#include -#include /* for atoi */ - -#define FCOPY_BUFFER_SIZE (16 * 1024) -#define INPUT_BUFFER_SIZE 1024 -#define LINE_SIZE 512 -#define HOST_SIZE 256 -#define PORT_SIZE 32 -#define PATH_SIZE 512 - -/* - * A buffer for storing the excess input data for ReadLine. - * The data in the buffer starts from (including) the element pointed to - * by inputHead, and ends just before (not including) the element pointed - * to by inputTail. The buffer is empty if inputHead == inputTail. - */ - -static char inputBuf[INPUT_BUFFER_SIZE]; -/* - * inputBufEnd points just past the end of inputBuf - */ -static char *inputBufEnd = inputBuf + sizeof(inputBuf); -static char *inputHead = inputBuf; -static char *inputTail = inputBuf; - -static PRBool endOfStream = PR_FALSE; - -/* - * ReadLine -- - * - * Read in a line of text, terminated by CRLF or LF, from fd into buf. - * The terminating CRLF or LF is included (always as '\n'). The text - * in buf is terminated by a null byte. The excess bytes are stored in - * inputBuf for use in the next ReadLine call or FetchFile call. - * Returns the number of bytes in buf. 0 means end of stream. Returns - * -1 if read fails. - */ - -PRInt32 ReadLine(PRFileDesc *fd, char *buf, PRUint32 bufSize) -{ - char *dst = buf; - char *bufEnd = buf + bufSize; /* just past the end of buf */ - PRBool lineFound = PR_FALSE; - char *crPtr = NULL; /* points to the CR ('\r') character */ - PRInt32 nRead; - -loop: - PR_ASSERT(inputBuf <= inputHead && inputHead <= inputTail - && inputTail <= inputBufEnd); - while (lineFound == PR_FALSE && inputHead != inputTail - && dst < bufEnd - 1) { - if (*inputHead == '\r') { - crPtr = dst; - } else if (*inputHead == '\n') { - lineFound = PR_TRUE; - if (crPtr == dst - 1) { - dst--; - } - } - *(dst++) = *(inputHead++); - } - if (lineFound == PR_TRUE || dst == bufEnd - 1 || endOfStream == PR_TRUE) { - *dst = '\0'; - return dst - buf; - } - - /* - * The input buffer should be empty now - */ - PR_ASSERT(inputHead == inputTail); - - nRead = PR_Read(fd, inputBuf, sizeof(inputBuf)); - if (nRead == -1) { - *dst = '\0'; - return -1; - } else if (nRead == 0) { - endOfStream = PR_TRUE; - *dst = '\0'; - return dst - buf; - } - inputHead = inputBuf; - inputTail = inputBuf + nRead; - goto loop; -} - -PRInt32 DrainInputBuffer(char *buf, PRUint32 bufSize) -{ - PRInt32 nBytes = inputTail - inputHead; - - if (nBytes == 0) { - if (endOfStream) { - return -1; - } else { - return 0; - } - } - if ((PRInt32) bufSize < nBytes) { - nBytes = bufSize; - } - memcpy(buf, inputHead, nBytes); - inputHead += nBytes; - return nBytes; -} - -PRStatus FetchFile(PRFileDesc *in, PRFileDesc *out) -{ - char buf[FCOPY_BUFFER_SIZE]; - PRInt32 nBytes; - - while ((nBytes = DrainInputBuffer(buf, sizeof(buf))) > 0) { - if (PR_Write(out, buf, nBytes) != nBytes) { - fprintf(stderr, "httpget: cannot write to file\n"); - return PR_FAILURE; - } - } - if (nBytes < 0) { - /* Input buffer is empty and end of stream */ - return PR_SUCCESS; - } - while ((nBytes = PR_Read(in, buf, sizeof(buf))) > 0) { - if (PR_Write(out, buf, nBytes) != nBytes) { - fprintf(stderr, "httpget: cannot write to file\n"); - return PR_FAILURE; - } - } - if (nBytes < 0) { - fprintf(stderr, "httpget: cannot read from socket\n"); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -PRStatus FastFetchFile(PRFileDesc *in, PRFileDesc *out, PRUint32 size) -{ - PRInt32 nBytes; - PRFileMap *outfMap; - void *addr; - char *start; - PRUint32 rem; - PRUint32 bytesToRead; - PRStatus rv; - PRInt64 sz64; - - LL_UI2L(sz64, size); - outfMap = PR_CreateFileMap(out, sz64, PR_PROT_READWRITE); - PR_ASSERT(outfMap); - addr = PR_MemMap(outfMap, LL_ZERO, size); - if (addr == NULL) { - fprintf(stderr, "cannot memory-map file: (%d, %d)\n", PR_GetError(), - PR_GetOSError()); - - PR_CloseFileMap(outfMap); - return PR_FAILURE; - } - start = (char *) addr; - rem = size; - while ((nBytes = DrainInputBuffer(start, rem)) > 0) { - start += nBytes; - rem -= nBytes; - } - if (nBytes < 0) { - /* Input buffer is empty and end of stream */ - return PR_SUCCESS; - } - bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE; - while (rem > 0 && (nBytes = PR_Read(in, start, bytesToRead)) > 0) { - start += nBytes; - rem -= nBytes; - bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE; - } - if (nBytes < 0) { - fprintf(stderr, "httpget: cannot read from socket\n"); - return PR_FAILURE; - } - rv = PR_MemUnmap(addr, size); - PR_ASSERT(rv == PR_SUCCESS); - rv = PR_CloseFileMap(outfMap); - PR_ASSERT(rv == PR_SUCCESS); - return PR_SUCCESS; -} - -PRStatus ParseURL(char *url, char *host, PRUint32 hostSize, - char *port, PRUint32 portSize, char *path, PRUint32 pathSize) -{ - char *start, *end; - char *dst; - char *hostEnd; - char *portEnd; - char *pathEnd; - - if (strncmp(url, "http", 4)) { - fprintf(stderr, "httpget: the protocol must be http\n"); - return PR_FAILURE; - } - if (strncmp(url + 4, "://", 3) || url[7] == '\0') { - fprintf(stderr, "httpget: malformed URL: %s\n", url); - return PR_FAILURE; - } - - start = end = url + 7; - dst = host; - hostEnd = host + hostSize; - while (*end && *end != ':' && *end != '/') { - if (dst == hostEnd - 1) { - fprintf(stderr, "httpget: host name too long\n"); - return PR_FAILURE; - } - *(dst++) = *(end++); - } - *dst = '\0'; - - if (*end == '\0') { - PR_snprintf(port, portSize, "%d", 80); - PR_snprintf(path, pathSize, "%s", "/"); - return PR_SUCCESS; - } - - if (*end == ':') { - end++; - dst = port; - portEnd = port + portSize; - while (*end && *end != '/') { - if (dst == portEnd - 1) { - fprintf(stderr, "httpget: port number too long\n"); - return PR_FAILURE; - } - *(dst++) = *(end++); - } - *dst = '\0'; - if (*end == '\0') { - PR_snprintf(path, pathSize, "%s", "/"); - return PR_SUCCESS; - } - } else { - PR_snprintf(port, portSize, "%d", 80); - } - - dst = path; - pathEnd = path + pathSize; - while (*end) { - if (dst == pathEnd - 1) { - fprintf(stderr, "httpget: file pathname too long\n"); - return PR_FAILURE; - } - *(dst++) = *(end++); - } - *dst = '\0'; - return PR_SUCCESS; -} - -void PrintUsage(void) { - fprintf(stderr, "usage: httpget url\n" - " httpget -o outputfile url\n" - " httpget url -o outputfile\n"); -} - -int main(int argc, char **argv) -{ - PRHostEnt hostentry; - char buf[PR_NETDB_BUF_SIZE]; - PRNetAddr addr; - PRFileDesc *socket = NULL, *file = NULL; - PRIntn cmdSize; - char host[HOST_SIZE]; - char port[PORT_SIZE]; - char path[PATH_SIZE]; - char line[LINE_SIZE]; - int exitStatus = 0; - PRBool endOfHeader = PR_FALSE; - char *url; - char *fileName = NULL; - PRUint32 fileSize; - - if (argc != 2 && argc != 4) { - PrintUsage(); - exit(1); - } - - if (argc == 2) { - /* - * case 1: httpget url - */ - url = argv[1]; - } else { - if (strcmp(argv[1], "-o") == 0) { - /* - * case 2: httpget -o outputfile url - */ - fileName = argv[2]; - url = argv[3]; - } else { - /* - * case 3: httpget url -o outputfile - */ - url = argv[1]; - if (strcmp(argv[2], "-o") != 0) { - PrintUsage(); - exit(1); - } - fileName = argv[3]; - } - } - - if (ParseURL(url, host, sizeof(host), port, sizeof(port), - path, sizeof(path)) == PR_FAILURE) { - exit(1); - } - - if (PR_GetHostByName(host, buf, sizeof(buf), &hostentry) - == PR_FAILURE) { - fprintf(stderr, "httpget: unknown host name: %s\n", host); - exit(1); - } - - addr.inet.family = PR_AF_INET; - addr.inet.port = PR_htons((short) atoi(port)); - addr.inet.ip = *((PRUint32 *) hostentry.h_addr_list[0]); - - socket = PR_NewTCPSocket(); - if (socket == NULL) { - fprintf(stderr, "httpget: cannot create new tcp socket\n"); - exit(1); - } - - if (PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { - fprintf(stderr, "httpget: cannot connect to http server\n"); - exitStatus = 1; - goto done; - } - - if (fileName == NULL) { - file = PR_STDOUT; - } else { - file = PR_Open(fileName, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, - 00777); - if (file == NULL) { - fprintf(stderr, "httpget: cannot open file %s: (%d, %d)\n", - fileName, PR_GetError(), PR_GetOSError()); - exitStatus = 1; - goto done; - } - } - - cmdSize = PR_snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n", path); - PR_ASSERT(cmdSize == (PRIntn) strlen("GET HTTP/1.0\r\n\r\n") - + (PRIntn) strlen(path)); - if (PR_Write(socket, buf, cmdSize) != cmdSize) { - fprintf(stderr, "httpget: cannot write to http server\n"); - exitStatus = 1; - goto done; - } - - if (ReadLine(socket, line, sizeof(line)) <= 0) { - fprintf(stderr, "httpget: cannot read line from http server\n"); - exitStatus = 1; - goto done; - } - - /* HTTP response: 200 == OK */ - if (strstr(line, "200") == NULL) { - fprintf(stderr, "httpget: %s\n", line); - exitStatus = 1; - goto done; - } - - while (ReadLine(socket, line, sizeof(line)) > 0) { - if (line[0] == '\n') { - endOfHeader = PR_TRUE; - break; - } - if (strncmp(line, "Content-Length", 14) == 0 - || strncmp(line, "Content-length", 14) == 0) { - char *p = line + 14; - - while (*p == ' ' || *p == '\t') { - p++; - } - if (*p != ':') { - continue; - } - p++; - while (*p == ' ' || *p == '\t') { - p++; - } - fileSize = 0; - while ('0' <= *p && *p <= '9') { - fileSize = 10 * fileSize + (*p - '0'); - p++; - } - } - } - if (endOfHeader == PR_FALSE) { - fprintf(stderr, "httpget: cannot read line from http server\n"); - exitStatus = 1; - goto done; - } - - if (fileName == NULL || fileSize == 0) { - FetchFile(socket, file); - } else { - FastFetchFile(socket, file, fileSize); - } - -done: - if (socket) PR_Close(socket); - if (file) PR_Close(file); - PR_Cleanup(); - return exitStatus; -} diff -Nru nspr-4.9.5/mozilla/nsprpub/tools/Makefile.in nspr-4.10.7/mozilla/nsprpub/tools/Makefile.in --- nspr-4.9.5/mozilla/nsprpub/tools/Makefile.in 2012-11-13 23:18:00.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/tools/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,184 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#! gmake - -MOD_DEPTH = .. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(MOD_DEPTH)/config/autoconf.mk - -include $(topsrcdir)/config/config.mk - -ifeq ($(OS_TARGET), WIN16) -OS_CFLAGS = $(OS_EXE_CFLAGS) -endif - - -DIRS = - -CSRCS = \ - httpget.c \ - tail.c \ - $(NULL) - -ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) -PROG_SUFFIX = .exe -else -PROG_SUFFIX = -endif - -PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX))) - -TARGETS = $(PROGS) - -INCLUDES = -I$(dist_includedir) - -NSPR_VERSION = 3 - -# Setting the variables LDOPTS and LIBPR. We first initialize -# them to the default values, then adjust them for some platforms. -LDOPTS = -L$(dist_libdir) -LIBPR = -lnspr$(NSPR_VERSION) -LIBPLC = -lplc$(NSPR_VERSION) - -ifeq ($(OS_ARCH), WINNT) -ifeq ($(OS_TARGET), WIN16) - LIBPR = $(dist_libdir)/nspr$(NSPR_VERSION).lib - LIBPLC= $(dist_libdir)/plc$(NSPR_VERSION).lib -else -LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO -LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).$(LIB_SUFFIX) -LIBPLC= $(dist_libdir)/libplc$(NSPR_VERSION).$(LIB_SUFFIX) -endif -endif - -ifeq ($(OS_ARCH),OS2) -LDOPTS += -Zomf -Zlinker /PM:VIO -endif - -ifneq ($(OS_ARCH), WINNT) -PWD = $(shell pwd) -endif - -ifeq ($(OS_ARCH), IRIX) -LDOPTS += -rpath $(PWD)/$(dist_libdir) -endif - -ifeq ($(OS_ARCH), OSF1) -LDOPTS += -rpath $(PWD)/$(dist_libdir) -lpthread -endif - -ifeq ($(OS_ARCH), HP-UX) -LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir) -endif - -# AIX -ifeq ($(OS_ARCH),AIX) -LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib -LIBPR = -lnspr$(NSPR_VERSION)_shr -LIBPLC = -lplc$(NSPR_VERSION)_shr -endif - -# Solaris -ifeq ($(OS_ARCH), SunOS) -ifdef NS_USE_GCC -LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir) -else -LDOPTS += -R $(PWD)/$(dist_libdir) -endif - -# SunOS 5.5 needs to link with -lpthread, even though we already -# linked with this system library when we built libnspr.so. -ifeq ($(OS_RELEASE), 5.5) -ifdef USE_PTHREADS -EXTRA_LIBS = -lpthread -endif -endif -endif # SunOS - -ifeq ($(OS_ARCH), SCOOS) -# SCO Unix needs to link against -lsocket again even though we -# already linked with these system libraries when we built libnspr.so. -EXTRA_LIBS = -lsocket -# This hardcodes in the executable programs the directory to find -# libnspr.so etc. at program startup. Equivalent to the -R or -rpath -# option for ld on other platforms. -export LD_RUN_PATH = $(PWD)/$(dist_libdir) -endif - -##################################################### -# -# The rules -# -##################################################### - -include $(topsrcdir)/config/rules.mk - -AIX_PRE_4_2 = 0 -ifeq ($(OS_ARCH),AIX) -ifneq ($(OS_RELEASE),4.2) -ifneq ($(USE_PTHREADS), 1) -#AIX_PRE_4_2 = 1 -endif -endif -endif - -ifeq ($(AIX_PRE_4_2),1) - -# AIX releases prior to 4.2 need a special two-step linking hack -# in order to both override the system select() and be able to -# get at the original system select(). -# -# We use a pattern rule in ns/nspr20/config/rules.mk to generate -# the .$(OBJ_SUFFIX) file from the .c source file, then do the -# two-step linking hack below. - -$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) - rm -f $@ $(AIX_TMP) - $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(NSPR_VERSION).a - $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) - rm -f $(AIX_TMP) - -else - -# All platforms that are not AIX pre-4.2. - -$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) - @$(MAKE_OBJDIR) -ifeq ($(OS_ARCH), WINNT) -ifeq ($(OS_TARGET),WIN16) - echo system windows >w16link - echo option map >>w16link - echo option stack=10K >>w16link - echo option heapsize=32K >>w16link - echo debug $(DEBUGTYPE) all >>w16link - echo name $@ >>w16link - echo file >>w16link - echo $< >>w16link - echo library >>w16link - echo $(LIBPR), >>w16link - echo $(LIBPLC), >>w16link - echo winsock.lib >>w16link - wlink @w16link. -else - link $(LDOPTS) $< $(LIBPR) $(LIBPLC) wsock32.lib -out:$@ -endif -else -ifeq ($(OS_ARCH),OS2) - $(LINK) $(LDOPTS) $< $(LIBPR) $(LIBPLC) $(OS_LIBS) $(EXTRA_LIBS) -o $@ -else - $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPLC) $(EXTRA_LIBS) -o $@ -endif -endif -endif - -export:: $(TARGETS) -clean:: - rm -f $(TARGETS) - diff -Nru nspr-4.9.5/mozilla/nsprpub/tools/tail.c nspr-4.10.7/mozilla/nsprpub/tools/tail.c --- nspr-4.9.5/mozilla/nsprpub/tools/tail.c 2012-03-06 13:14:34.000000000 +0000 +++ nspr-4.10.7/mozilla/nsprpub/tools/tail.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prio.h" -#include "prprf.h" -#include "prinit.h" -#include "prthread.h" -#include "prinrval.h" - -#include "plerror.h" -#include "plgetopt.h" - -#include - -#define BUFFER_SIZE 500 - -static PRFileDesc *out = NULL, *err = NULL; - -static void Help(void) -{ - PR_fprintf(err, "Usage: tail [-n ] [-f] [-h] \n"); - PR_fprintf(err, "\t-t Dally time in milliseconds\n"); - PR_fprintf(err, "\t-n Number of bytes before \n"); - PR_fprintf(err, "\t-f Follow the \n"); - PR_fprintf(err, "\t-h This message and nothing else\n"); -} /* Help */ - -PRIntn main(PRIntn argc, char **argv) -{ - PRIntn rv = 0; - PLOptStatus os; - PRStatus status; - PRFileDesc *file; - PRFileInfo fileInfo; - PRIntervalTime dally; - char buffer[BUFFER_SIZE]; - PRBool follow = PR_FALSE; - const char *filename = NULL; - PRUint32 position = 0, seek = 0, time = 0; - PLOptState *opt = PL_CreateOptState(argc, argv, "hfn:"); - - out = PR_GetSpecialFD(PR_StandardOutput); - err = PR_GetSpecialFD(PR_StandardError); - - while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) - { - if (PL_OPT_BAD == os) continue; - switch (opt->option) - { - case 0: /* it's the filename */ - filename = opt->value; - break; - case 'n': /* bytes before end of file */ - seek = atoi(opt->value); - break; - case 't': /* dally time */ - time = atoi(opt->value); - break; - case 'f': /* follow the end of file */ - follow = PR_TRUE; - break; - case 'h': /* user wants some guidance */ - Help(); /* so give him an earful */ - return 2; /* but not a lot else */ - break; - default: - break; - } - } - PL_DestroyOptState(opt); - - if (0 == time) time = 1000; - dally = PR_MillisecondsToInterval(time); - - if (NULL == filename) - { - (void)PR_fprintf(out, "Input file not specified\n"); - rv = 1; goto done; - } - file = PR_Open(filename, PR_RDONLY, 0); - if (NULL == file) - { - PL_FPrintError(err, "File cannot be opened for reading"); - return 1; - } - - status = PR_GetOpenFileInfo(file, &fileInfo); - if (PR_FAILURE == status) - { - PL_FPrintError(err, "Cannot acquire status of file"); - rv = 1; goto done; - } - if (seek > 0) - { - if (seek > fileInfo.size) seek = 0; - position = PR_Seek(file, (fileInfo.size - seek), PR_SEEK_SET); - if (-1 == (PRInt32)position) - PL_FPrintError(err, "Cannot seek to starting position"); - } - - do - { - while (position < fileInfo.size) - { - PRInt32 read, bytes = fileInfo.size - position; - if (bytes > sizeof(buffer)) bytes = sizeof(buffer); - read = PR_Read(file, buffer, bytes); - if (read != bytes) - PL_FPrintError(err, "Cannot read to eof"); - position += read; - PR_Write(out, buffer, read); - } - - if (follow) - { - PR_Sleep(dally); - status = PR_GetOpenFileInfo(file, &fileInfo); - if (PR_FAILURE == status) - { - PL_FPrintError(err, "Cannot acquire status of file"); - rv = 1; goto done; - } - } - } while (follow); - -done: - PR_Close(file); - - return rv; -} /* main */ - -/* tail.c */ diff -Nru nspr-4.9.5/nspr/admin/explode.pl nspr-4.10.7/nspr/admin/explode.pl --- nspr-4.9.5/nspr/admin/explode.pl 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/admin/explode.pl 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,43 @@ +#!/bin/perl +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# ----------------------------------------------------------------- +# +# explode.pl -- Unpack .jar files into bin, lib, include directories +# +# syntax: perl explode.pl +# +# Description: +# explode.pl unpacks the .jar files created by the NSPR build +# procedure. +# +# Suggested use: After copying the platform directories to +# /s/b/c/nspr20/. CD to /s/b/c/nspr20/ and +# run explode.pl. This will unpack the jar files into bin, lib, +# include directories. +# +# ----------------------------------------------------------------- + +@dirs = `ls -d *.OBJ*`; + +foreach $dir (@dirs) { + chop($dir); + if (-l $dir) { + print "Skipping symbolic link $dir\n"; + next; + } + print "Unzipping $dir/mdbinary.jar\n"; + system ("unzip", "-o", "$dir/mdbinary.jar", + "-d", "$dir"); + system ("rm", "-rf", "$dir/META-INF"); + mkdir "$dir/include", 0755; + print "Unzipping $dir/mdheader.jar\n"; + system ("unzip", "-o", "-aa", + "$dir/mdheader.jar", + "-d", "$dir/include"); + system ("rm", "-rf", "$dir/include/META-INF"); +} +# --- end explode.pl ---------------------------------------------- diff -Nru nspr-4.9.5/nspr/admin/makeTargetDirs.sh nspr-4.10.7/nspr/admin/makeTargetDirs.sh --- nspr-4.9.5/nspr/admin/makeTargetDirs.sh 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/admin/makeTargetDirs.sh 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,47 @@ +#!/bin/sh +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# ----------------------------------------------------------------- +# makeTargetDirs.sh -- Create target directories for building NSPR +# +# syntax: makeTargetDirs.sh +# +# Description: +# makeTargetDirs.sh creates a set of directories intended for use +# with NSPR's autoconf based build system. +# +# The enumerated directories are the same as those built for NSPR +# 4.1.1. Adjust as needed. +# +# ----------------------------------------------------------------- + +mkdir AIX4.3_64_DBG.OBJ +mkdir AIX4.3_64_OPT.OBJ +mkdir AIX4.3_DBG.OBJ +mkdir AIX4.3_OPT.OBJ +mkdir HP-UXB.11.00_64_DBG.OBJ +mkdir HP-UXB.11.00_64_OPT.OBJ +mkdir HP-UXB.11.00_DBG.OBJ +mkdir HP-UXB.11.00_OPT.OBJ +mkdir IRIX6.5_n32_PTH_DBG.OBJ +mkdir IRIX6.5_n32_PTH_OPT.OBJ +mkdir Linux2.2_x86_glibc_PTH_DBG.OBJ +mkdir Linux2.2_x86_glibc_PTH_OPT.OBJ +mkdir Linux2.4_x86_glibc_PTH_DBG.OBJ +mkdir Linux2.4_x86_glibc_PTH_OPT.OBJ +mkdir OSF1V4.0D_DBG.OBJ +mkdir OSF1V4.0D_OPT.OBJ +mkdir SunOS5.6_DBG.OBJ +mkdir SunOS5.6_OPT.OBJ +mkdir SunOS5.7_64_DBG.OBJ +mkdir SunOS5.7_64_OPT.OBJ +mkdir WIN954.0_DBG.OBJ +mkdir WIN954.0_DBG.OBJD +mkdir WIN954.0_OPT.OBJ +mkdir WINNT4.0_DBG.OBJ +mkdir WINNT4.0_DBG.OBJD +mkdir WINNT4.0_OPT.OBJ +# --- end makeTargetDirs.sh --------------------------------------- diff -Nru nspr-4.9.5/nspr/admin/symlinks.sh nspr-4.10.7/nspr/admin/symlinks.sh --- nspr-4.9.5/nspr/admin/symlinks.sh 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/admin/symlinks.sh 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,43 @@ +#!/bin/sh +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# ----------------------------------------------------------------- +# symlinks.sh -- create links from NSPR builds +# +# syntax: symlinks.sh +# +# Description: +# symlinks.sh creates some symbolic links for NSPR build targets +# that are not actually build, but for which there are NSPR +# binaries suitable for running on the intended target. ... got +# that? +# +# Suggested use: After copying NSPR binaries to +# /s/b/c/nspr20/ run symlinks.sh to create the links +# for all supported platforms. +# +# The symlinks in this script correspond to the NSPR 4.1.1 +# release. Adjust as necessary. +# +# ----------------------------------------------------------------- + +ln -s SunOS5.6_DBG.OBJ SunOS5.7_DBG.OBJ +ln -s SunOS5.6_OPT.OBJ SunOS5.7_OPT.OBJ + +ln -s SunOS5.6_DBG.OBJ SunOS5.8_DBG.OBJ +ln -s SunOS5.6_OPT.OBJ SunOS5.8_OPT.OBJ + +ln -s SunOS5.7_64_DBG.OBJ SunOS5.8_64_DBG.OBJ +ln -s SunOS5.7_64_OPT.OBJ SunOS5.8_64_OPT.OBJ + +ln -s OSF1V4.0D_DBG.OBJ OSF1V5.0_DBG.OBJ +ln -s OSF1V4.0D_OPT.OBJ OSF1V5.0_OPT.OBJ + +ln -s WINNT4.0_DBG.OBJ WINNT5.0_DBG.OBJ +ln -s WINNT4.0_DBG.OBJD WINNT5.0_DBG.OBJD +ln -s WINNT4.0_OPT.OBJ WINNT5.0_OPT.OBJ +# --- end symlinks.sh --------------------------------------------- + diff -Nru nspr-4.9.5/nspr/build/autoconf/config.guess nspr-4.10.7/nspr/build/autoconf/config.guess --- nspr-4.9.5/nspr/build/autoconf/config.guess 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/build/autoconf/config.guess 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1420 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-02-12' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2014 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -Nru nspr-4.9.5/nspr/build/autoconf/config.sub nspr-4.10.7/nspr/build/autoconf/config.sub --- nspr-4.9.5/nspr/build/autoconf/config.sub 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/build/autoconf/config.sub 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1795 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-01-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2014 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 \ + | or1k | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -android*) + os=-android + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or1k-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + *-android*|*-linuxandroid*) + vendor=linux- + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -Nru nspr-4.9.5/nspr/build/autoconf/install-sh nspr-4.10.7/nspr/build/autoconf/install-sh --- nspr-4.9.5/nspr/build/autoconf/install-sh 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/build/autoconf/install-sh 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,123 @@ +#!/bin/sh +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +# +# install - install a program, script, or datafile +# This comes from X11R5; it is not part of GNU. +# +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" + +instcmd="$mvprog" +chmodcmd="" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +fi + +if [ x"$dst" = x ] +then + echo "install: no destination specified" + exit 1 +fi + + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + +if [ -d $dst ] +then + dst="$dst"/`basename $src` +fi + +# Make a temp file name in the proper directory. + +dstdir=`dirname $dst` +dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + +$doit $instcmd $src $dsttmp + +# and set any options; do chmod last to preserve setuid bits + +if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi +if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi +if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi +if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi + +# Now rename the file to the real destination. + +$doit $rmcmd $dst +$doit $mvcmd $dsttmp $dst + + +exit 0 diff -Nru nspr-4.9.5/nspr/build/autoconf/patches/config.sub.patch nspr-4.10.7/nspr/build/autoconf/patches/config.sub.patch --- nspr-4.9.5/nspr/build/autoconf/patches/config.sub.patch 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/build/autoconf/patches/config.sub.patch 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +--- config.sub.orig 2014-03-09 18:34:03 -0700 ++++ config.sub 2014-03-14 19:49:48 -0700 +@@ -115,7 +115,7 @@ + # Here we must recognize all the valid KERNEL-OS combinations. + maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` + case $maybe_os in +- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ ++ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ +@@ -123,10 +123,6 @@ + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; +- android-linux) +- os=-linux-android +- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown +- ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] +@@ -1367,7 +1363,7 @@ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ +- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ ++ | -mingw32* | -mingw64* | -linux-gnu* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ +@@ -1508,6 +1504,9 @@ + ;; + -nacl*) + ;; ++ -android*) ++ os=-android ++ ;; + -none) + ;; + *) +@@ -1777,6 +1776,9 @@ + -vos*) + vendor=stratus + ;; ++ *-android*|*-linuxandroid*) ++ vendor=linux- ++ ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; diff -Nru nspr-4.9.5/nspr/build/autoconf/README nspr-4.10.7/nspr/build/autoconf/README --- nspr-4.9.5/nspr/build/autoconf/README 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/build/autoconf/README 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,5 @@ +The config.guess and config.sub scripts were downloaded from +http://git.savannah.gnu.org/cgit/config.git/tree/config.guess?id=6947a35648e577c2e3a12d5c88d488c6ea94e1c0 +http://git.savannah.gnu.org/cgit/config.git/tree/config.sub?id=6947a35648e577c2e3a12d5c88d488c6ea94e1c0 + +Our private patches are in the patches/ directory. diff -Nru nspr-4.9.5/nspr/build/cygwin-wrapper nspr-4.10.7/nspr/build/cygwin-wrapper --- nspr-4.9.5/nspr/build/cygwin-wrapper 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/build/cygwin-wrapper 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,79 @@ +#!/bin/sh +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# +# Stupid wrapper to avoid win32 dospath/cygdrive issues +# Try not to spawn programs from within this file. If the stuff in here looks royally +# confusing, see bug: http://bugzilla.mozilla.org/show_bug.cgi?id=206643 +# and look at the older versions of this file that are easier to read, but +# do basically the same thing +# + +prog=$1 +shift +if test -z "$prog"; then + exit 0 +fi + +# If $CYGDRIVE_MOUNT was not set in configure, give $mountpoint the results of mount -p +mountpoint=$CYGDRIVE_MOUNT +if test -z "$mountpoint"; then + mountpoint=`mount -p` + if test -z "$mountpoint"; then + print "Cannot determine cygwin mount points. Exiting" + exit 1 + fi +fi + +# Delete everything but "/cygdrive" (or other mountpoint) from mount=`mount -p` +mountpoint=${mountpoint#*/} +mountpoint=/${mountpoint%%[!A-Za-z0-9_]*} +mountpoint=${mountpoint%/} + +args="" +up="" +if test "${prog}" = "-up"; then + up=1 + prog=${1} + shift +fi + +process=1 + +# Convert the mountpoint in parameters to Win32 filenames +# For instance: /cygdrive/c/foo -> c:/foo +for i in "${@}" +do + if test "${i}" = "-wrap"; then + process=1 + else + if test "${i}" = "-nowrap"; then + process= + else + if test -n "${process}"; then + if test -n "${up}"; then + pathname=${i#-I[a-zA-Z]:/} + if ! test "${pathname}" = "${i}"; then + no_i=${i#-I} + driveletter=${no_i%%:*} + i=-I${mountpoint}/${driveletter}/${pathname} + fi + else + eval 'leader=${i%%'${mountpoint}'/[a-zA-Z]/*}' + if ! test "${leader}" = "${i}"; then + eval 'pathname=${i#'${leader}${mountpoint}'/[a-zA-Z]/}' + eval 'no_mountpoint=${i#'${leader}${mountpoint}'/}' + driveletter=${no_mountpoint%%/*} + i=${leader}${driveletter}:/${pathname} + fi + fi + fi + + args="${args} ${i}" + fi + fi +done + +exec $prog $args diff -Nru nspr-4.9.5/nspr/build/win32/pgomerge.py nspr-4.10.7/nspr/build/win32/pgomerge.py --- nspr-4.9.5/nspr/build/win32/pgomerge.py 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/build/win32/pgomerge.py 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,44 @@ +#!/usr/bin/python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Usage: pgomerge.py +# Gathers .pgc files from dist/bin and merges them into +# $PWD/$basename.pgd using pgomgr, then deletes them. +# No errors if any of these files don't exist. + +import sys, os, os.path, subprocess +if not sys.platform == "win32": + raise Exception("This script was only meant for Windows.") + +def MergePGOFiles(basename, pgddir, pgcdir): + """Merge pgc files produced from an instrumented binary + into the pgd file for the second pass of profile-guided optimization + with MSVC. |basename| is the name of the DLL or EXE without the + extension. |pgddir| is the path that contains .pgd + (should be the objdir it was built in). |pgcdir| is the path + containing basename!N.pgc files, which is probably dist/bin. + Calls pgomgr to merge each pgc file into the pgd, then deletes + the pgc files.""" + if not os.path.isdir(pgddir) or not os.path.isdir(pgcdir): + return + pgdfile = os.path.abspath(os.path.join(pgddir, basename + ".pgd")) + if not os.path.isfile(pgdfile): + return + for file in os.listdir(pgcdir): + if file.startswith(basename+"!") and file.endswith(".pgc"): + try: + pgcfile = os.path.normpath(os.path.join(pgcdir, file)) + subprocess.call(['pgomgr', '-merge', + pgcfile, + pgdfile]) + os.remove(pgcfile) + except OSError: + pass + +if __name__ == '__main__': + if len(sys.argv) != 3: + print >>sys.stderr, "Usage: pgomerge.py " + sys.exit(1) + MergePGOFiles(sys.argv[1], os.getcwd(), sys.argv[2]) diff -Nru nspr-4.9.5/nspr/config/autoconf.mk.in nspr-4.10.7/nspr/config/autoconf.mk.in --- nspr-4.9.5/nspr/config/autoconf.mk.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/autoconf.mk.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,148 @@ +# -*- Mode: Makefile -*- +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +INCLUDED_AUTOCONF_MK = 1 +USE_AUTOCONF = 1 +@SHELL_OVERRIDE@ +MOZILLA_CLIENT = @MOZILLA_CLIENT@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +includedir = @includedir@ +libdir = @libdir@ +datarootdir = @datarootdir@ +datadir = @datadir@ + +dist_prefix = @dist_prefix@ +dist_bindir = @dist_bindir@ +dist_includedir = @dist_includedir@ +dist_libdir = @dist_libdir@ + +DIST = $(dist_prefix) + +RELEASE_OBJDIR_NAME = @RELEASE_OBJDIR_NAME@ +OBJDIR_NAME = @OBJDIR_NAME@ +OBJDIR = @OBJDIR@ +# We do magic with OBJ_SUFFIX in config.mk, the following ensures we don't +# manually use it before config.mk inclusion +OBJ_SUFFIX = $(error config/config.mk needs to be included before using OBJ_SUFFIX) +_OBJ_SUFFIX = @OBJ_SUFFIX@ +LIB_SUFFIX = @LIB_SUFFIX@ +DLL_SUFFIX = @DLL_SUFFIX@ +ASM_SUFFIX = @ASM_SUFFIX@ +MOD_NAME = @NSPR_MODNAME@ + +MOD_MAJOR_VERSION = @MOD_MAJOR_VERSION@ +MOD_MINOR_VERSION = @MOD_MINOR_VERSION@ +MOD_PATCH_VERSION = @MOD_PATCH_VERSION@ + +LIBNSPR = @LIBNSPR@ +LIBPLC = @LIBPLC@ + +CROSS_COMPILE = @CROSS_COMPILE@ +MOZ_OPTIMIZE = @MOZ_OPTIMIZE@ +MOZ_DEBUG = @MOZ_DEBUG@ +MOZ_DEBUG_SYMBOLS = @MOZ_DEBUG_SYMBOLS@ + +USE_CPLUS = @USE_CPLUS@ +USE_IPV6 = @USE_IPV6@ +USE_N32 = @USE_N32@ +USE_X32 = @USE_X32@ +USE_64 = @USE_64@ +ENABLE_STRIP = @ENABLE_STRIP@ + +USE_PTHREADS = @USE_PTHREADS@ +USE_BTHREADS = @USE_BTHREADS@ +PTHREADS_USER = @USE_USER_PTHREADS@ +CLASSIC_NSPR = @USE_NSPR_THREADS@ + +AS = @AS@ +ASFLAGS = @ASFLAGS@ +CC = @CC@ +CCC = @CXX@ +NS_USE_GCC = @GNU_CC@ +GCC_USE_GNU_LD = @GCC_USE_GNU_LD@ +MSC_VER = @MSC_VER@ +AR = @AR@ +AR_FLAGS = @AR_FLAGS@ +LD = @LD@ +RANLIB = @RANLIB@ +PERL = @PERL@ +RC = @RC@ +RCFLAGS = @RCFLAGS@ +STRIP = @STRIP@ +NSINSTALL = @NSINSTALL@ +FILTER = @FILTER@ +IMPLIB = @IMPLIB@ +CYGWIN_WRAPPER = @CYGWIN_WRAPPER@ +MT = @MT@ + +OS_CPPFLAGS = @CPPFLAGS@ +OS_CFLAGS = $(OS_CPPFLAGS) @CFLAGS@ $(DSO_CFLAGS) +OS_CXXFLAGS = $(OS_CPPFLAGS) @CXXFLAGS@ $(DSO_CFLAGS) +OS_LIBS = @OS_LIBS@ +OS_LDFLAGS = @LDFLAGS@ +OS_DLLFLAGS = @OS_DLLFLAGS@ +DLLFLAGS = @DLLFLAGS@ +EXEFLAGS = @EXEFLAGS@ +OPTIMIZER = @OPTIMIZER@ + +PROFILE_GEN_CFLAGS = @PROFILE_GEN_CFLAGS@ +PROFILE_GEN_LDFLAGS = @PROFILE_GEN_LDFLAGS@ +PROFILE_USE_CFLAGS = @PROFILE_USE_CFLAGS@ +PROFILE_USE_LDFLAGS = @PROFILE_USE_LDFLAGS@ + +MKSHLIB = @MKSHLIB@ +WRAP_LDFLAGS = @WRAP_LDFLAGS@ +DSO_CFLAGS = @DSO_CFLAGS@ +DSO_LDOPTS = @DSO_LDOPTS@ + +RESOLVE_LINK_SYMBOLS = @RESOLVE_LINK_SYMBOLS@ + +HOST_CC = @HOST_CC@ +HOST_CFLAGS = @HOST_CFLAGS@ +HOST_LDFLAGS = @HOST_LDFLAGS@ + +DEFINES = @DEFINES@ @DEFS@ + +MDCPUCFG_H = @MDCPUCFG_H@ +PR_MD_CSRCS = @PR_MD_CSRCS@ +PR_MD_ASFILES = @PR_MD_ASFILES@ +PR_MD_ARCH_DIR = @PR_MD_ARCH_DIR@ +CPU_ARCH = @CPU_ARCH@ + +OS_TARGET = @OS_TARGET@ +OS_ARCH = @OS_ARCH@ +OS_RELEASE = @OS_RELEASE@ +OS_TEST = @OS_TEST@ + +NOSUCHFILE = @NOSUCHFILE@ +AIX_LINK_OPTS = @AIX_LINK_OPTS@ +MOZ_OBJFORMAT = @MOZ_OBJFORMAT@ +ULTRASPARC_LIBRARY = @ULTRASPARC_LIBRARY@ + +OBJECT_MODE = @OBJECT_MODE@ +ifdef OBJECT_MODE +export OBJECT_MODE +endif + +VISIBILITY_FLAGS = @VISIBILITY_FLAGS@ +WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCLUDES@ + +MACOSX_DEPLOYMENT_TARGET = @MACOSX_DEPLOYMENT_TARGET@ +ifdef MACOSX_DEPLOYMENT_TARGET +export MACOSX_DEPLOYMENT_TARGET +endif + +MACOS_SDK_DIR = @MACOS_SDK_DIR@ + +SYMBIAN_SDK_DIR = @SYMBIAN_SDK_DIR@ + +NEXT_ROOT = @NEXT_ROOT@ +ifdef NEXT_ROOT +export NEXT_ROOT +endif diff -Nru nspr-4.9.5/nspr/config/config.mk nspr-4.10.7/nspr/config/config.mk --- nspr-4.9.5/nspr/config/config.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/config.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,169 @@ +#! gmake +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Configuration information for building in the NSPR source module + +# Define an include-at-most-once-flag +NSPR_CONFIG_MK = 1 + +# +# The variable definitions in this file are inputs to NSPR's +# build system. This file, if present, is included at the +# beginning of config.mk. +# +# For example: +# +# MOZ_OPTIMIZE=1 +# USE_PTHREADS=1 +# NS_USE_GCC= +# +ifndef topsrcdir +topsrcdir=$(MOD_DEPTH) +endif + +ifndef srcdir +srcdir=. +endif + +NFSPWD = $(MOD_DEPTH)/config/nfspwd + +CFLAGS = $(VISIBILITY_FLAGS) $(CC_ONLY_FLAGS) $(OPTIMIZER)\ + $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS) +CCCFLAGS = $(VISIBILITY_FLAGS) $(CCC_ONLY_FLAGS) $(OPTIMIZER)\ + $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS) +# For purify +NOMD_CFLAGS = $(CC_ONLY_FLAGS) $(OPTIMIZER) $(NOMD_OS_CFLAGS)\ + $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS) +NOMD_CCFLAGS = $(CCC_ONLY_FLAGS) $(OPTIMIZER) $(NOMD_OS_CFLAGS)\ + $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS) + +LDFLAGS = $(OS_LDFLAGS) + +# Enable profile-guided optimization +ifndef NO_PROFILE_GUIDED_OPTIMIZE +ifdef MOZ_PROFILE_GENERATE +CFLAGS += $(PROFILE_GEN_CFLAGS) +LDFLAGS += $(PROFILE_GEN_LDFLAGS) +DLLFLAGS += $(PROFILE_GEN_LDFLAGS) +ifeq (WINNT,$(OS_ARCH)) +AR_FLAGS += -LTCG +endif +endif # MOZ_PROFILE_GENERATE + +ifdef MOZ_PROFILE_USE +CFLAGS += $(PROFILE_USE_CFLAGS) +LDFLAGS += $(PROFILE_USE_LDFLAGS) +DLLFLAGS += $(PROFILE_USE_LDFLAGS) +ifeq (WINNT,$(OS_ARCH)) +AR_FLAGS += -LTCG +endif +endif # MOZ_PROFILE_USE +endif # NO_PROFILE_GUIDED_OPTIMIZE + +define MAKE_OBJDIR +if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi +endef + +LINK_DLL = $(LD) $(OS_DLLFLAGS) $(DLLFLAGS) + +ifeq ($(OS_ARCH),Darwin) +PWD := $(shell pwd) +endif + +ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2, $(OS_ARCH))) +INSTALL = $(NSINSTALL) +else +ifeq ($(NSDISTMODE),copy) +# copy files, but preserve source mtime +INSTALL = $(NSINSTALL) -t +else +ifeq ($(NSDISTMODE),absolute_symlink) +# install using absolute symbolic links +ifeq ($(OS_ARCH),Darwin) +INSTALL = $(NSINSTALL) -L $(PWD) +else +INSTALL = $(NSINSTALL) -L `$(NFSPWD)` +endif +else +# install using relative symbolic links +INSTALL = $(NSINSTALL) -R +endif +endif +endif # (WINNT || OS2) && !CROSS_COMPILE + +DEPENDENCIES = $(OBJDIR)/.md + +ifdef BUILD_DEBUG_GC +DEFINES += -DDEBUG_GC +endif + +GARBAGE += $(DEPENDENCIES) core $(wildcard core.[0-9]*) + +DIST_GARBAGE += Makefile + +#################################################################### +# +# The NSPR-specific configuration +# +#################################################################### + +DEFINES += -DFORCE_PR_LOG + +ifeq ($(_PR_NO_CLOCK_TIMER),1) +DEFINES += -D_PR_NO_CLOCK_TIMER +endif + +ifeq ($(USE_PTHREADS), 1) +DEFINES += -D_PR_PTHREADS -UHAVE_CVAR_BUILT_ON_SEM +endif + +ifeq ($(PTHREADS_USER), 1) +DEFINES += -DPTHREADS_USER -UHAVE_CVAR_BUILT_ON_SEM +endif + +ifeq ($(USE_IPV6),1) +DEFINES += -D_PR_INET6 +endif + +ifeq ($(MOZ_UNICODE),1) +DEFINES += -DMOZ_UNICODE +endif + +#################################################################### +# +# Configuration for the release process +# +#################################################################### + +MDIST = /m/dist +ifeq ($(OS_ARCH),WINNT) +MDIST = //helium/dist +MDIST_DOS = $(subst /,\\,$(MDIST)) +endif + +# RELEASE_DIR is ns/dist/ + +RELEASE_DIR = $(MOD_DEPTH)/dist/release/$(MOD_NAME) + +RELEASE_INCLUDE_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/include +RELEASE_BIN_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/bin +RELEASE_LIB_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/lib + +# autoconf.mk sets OBJ_SUFFIX to an error to avoid use before including +# this file +OBJ_SUFFIX := $(_OBJ_SUFFIX) + +# PGO builds with GCC build objects with instrumentation in a first pass, +# then objects optimized, without instrumentation, in a second pass. If +# we overwrite the ojects from the first pass with those from the second, +# we end up not getting instrumentation data for better optimization on +# incremental builds. As a consequence, we use a different object suffix +# for the first pass. +ifdef MOZ_PROFILE_GENERATE +ifdef NS_USE_GCC +OBJ_SUFFIX := i_o +endif +endif diff -Nru nspr-4.9.5/nspr/config/.cvsignore nspr-4.10.7/nspr/config/.cvsignore --- nspr-4.9.5/nspr/config/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,11 @@ +nfspwd +revdepth +my_config.mk +my_overrides.mk +autoconf.mk +nsprincl.mk +nsprincl.sh +now +Makefile +nsinstall +nspr-config diff -Nru nspr-4.9.5/nspr/config/gcc_hidden.h nspr-4.10.7/nspr/config/gcc_hidden.h --- nspr-4.9.5/nspr/config/gcc_hidden.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/gcc_hidden.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,6 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Begin all files as hidden visibility */ +#pragma GCC visibility push(hidden) diff -Nru nspr-4.9.5/nspr/config/libc_r.h nspr-4.10.7/nspr/config/libc_r.h --- nspr-4.9.5/nspr/config/libc_r.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/libc_r.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* libc_r.h -- macros, defines, etc. to make using reentrant libc calls */ +/* a bit easier. This was initially done for AIX pthreads, */ +/* but should be usable for anyone... */ + +/* Most of these use locally defined space instead of static library space. */ +/* Because of this, we use the _INIT_R to declare/allocate space (stack), */ +/* and the plain routines to actually do it..._WARNING_: avoid allocating */ +/* memory wherever possible. Memory allocation is fairly expensive, at */ +/* least on AIX...use arrays instead (which allocate from the stack.) */ +/* I know the names are a bit strange, but I wanted to be fairly certain */ +/* that we didn't have any namespace corruption...in general, the inits are */ +/* R__INIT_R(), and the actual calls are R__R(). */ + +#ifndef _LIBC_R_H +#define _LIBC_R_H + +/************/ +/* strtok */ +/************/ +#define R_STRTOK_INIT_R() \ + char *r_strtok_r=NULL + +#define R_STRTOK_R(return,source,delim) \ + return=strtok_r(source,delim,&r_strtok_r) + +#define R_STRTOK_NORET_R(source,delim) \ + strtok_r(source,delim,&r_strtok_r) + +/**************/ +/* strerror */ +/**************/ +#define R_MAX_STRERROR_LEN_R 8192 /* Straight from limits.h */ + +#define R_STRERROR_INIT_R() \ + char r_strerror_r[R_MAX_STRERROR_LEN_R] + +#define R_STRERROR_R(val) \ + strerror_r(val,r_strerror_r,R_MAX_STRERROR_LEN_R) + +/*****************/ +/* time things */ +/*****************/ +#define R_ASCTIME_INIT_R() \ + char r_asctime_r[26] + +#define R_ASCTIME_R(val) \ + asctime_r(val,r_asctime_r) + +#define R_CTIME_INIT_R() \ + char r_ctime_r[26] + +#define R_CTIME_R(val) \ + ctime_r(val,r_ctime_r) + +#define R_GMTIME_INIT_R() \ + struct tm r_gmtime_r + +#define R_GMTIME_R(time) \ + gmtime_r(time,&r_gmtime_r) + +#define R_LOCALTIME_INIT_R() \ + struct tm r_localtime_r + +#define R_LOCALTIME_R(val) \ + localtime_r(val,&r_localtime_r) + +/***********/ +/* crypt */ +/***********/ +#include +#define R_CRYPT_INIT_R() \ + CRYPTD r_cryptd_r; \ + bzero(&r_cryptd_r,sizeof(CRYPTD)) + +#define R_CRYPT_R(pass,salt) \ + crypt_r(pass,salt,&r_cryptd_r) + +/**************/ +/* pw stuff */ +/**************/ +#define R_MAX_PW_LEN_R 1024 +/* The following must be after the last declaration, but */ +/* before the first bit of code... */ +#define R_GETPWNAM_INIT_R(pw_ptr) \ + struct passwd r_getpwnam_pw_r; \ + char r_getpwnam_line_r[R_MAX_PW_LEN_R]; \ + pw_ptr = &r_getpwnam_pw_r + +#define R_GETPWNAM_R(name) \ + getpwnam_r(name,&r_getpwnam_pw_r,r_getpwnam_line_r,R_MAX_PW_LEN_R) + +/*******************/ +/* gethost stuff */ +/*******************/ +#define R_GETHOSTBYADDR_INIT_R() \ + struct hostent r_gethostbyaddr_r; \ + struct hostent_data r_gethostbyaddr_data_r + +#define R_GETHOSTBYADDR_R(addr,len,type,xptr_ent) \ + bzero(&r_gethostbyaddr_r,sizeof(struct hostent)); \ + bzero(&r_gethostbyaddr_data_r,sizeof(struct hostent_data)); \ + xptr_ent = &r_gethostbyaddr_r; \ + if (gethostbyaddr_r(addr,len,type, \ + &r_gethostbyaddr_r,&r_gethostbyaddr_data_r) == -1) { \ + xptr_ent = NULL; \ + } + +#define R_GETHOSTBYNAME_INIT_R() \ + struct hostent r_gethostbyname_r; \ + struct hostent_data r_gethostbyname_data_r + +#define R_GETHOSTBYNAME_R(name,xptr_ent) \ + bzero(&r_gethostbyname_r,sizeof(struct hostent)); \ + bzero(&r_gethostbyname_data_r,sizeof(struct hostent_data)); \ + xptr_ent = &r_gethostbyname_r; \ + if (gethostbyname_r(name, \ + &r_gethostbyname_r,&r_gethostbyname_data_r) == -1) { \ + xptr_ent = NULL; \ + } + +#endif /* _LIBC_R_H */ diff -Nru nspr-4.9.5/nspr/config/Makefile.in nspr-4.10.7/nspr/config/Makefile.in --- nspr-4.9.5/nspr/config/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,124 @@ +#! gmake +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MOD_DEPTH = .. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +# Indicate that this directory builds build tools. +INTERNAL_TOOLS = 1 + +# For sanity's sake, we compile nsinstall without the wrapped system +# headers, so that we can use it to set up the wrapped system headers. +VISIBILITY_FLAGS = + +# autoconf.mk must be deleted last (from the top-level directory) +# because it is included by every makefile. +DIST_GARBAGE = nsprincl.mk nsprincl.sh nspr-config nspr.pc + +RELEASE_BINS = nspr-config + +include $(topsrcdir)/config/config.mk + +CSRCS = now.c + +# This version hasn't been ported for us; the one in mozilla/config has +ifneq ($(OS_ARCH),OS2) +CSRCS += nsinstall.c + +PLSRCS = nfspwd.pl +endif + +ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2,$(OS_ARCH))) +PROG_SUFFIX = .exe +else +PROG_SUFFIX = +endif + +# Temporary workaround to disable the generation of +# library build time because now.c uses the 'long long' +# data type that's not available on some platforms. +ifeq (,$(filter-out QNX SCOOS UNIXWARE,$(OS_ARCH))) +DEFINES += -DOMIT_LIB_BUILD_TIME +endif + +ifeq ($(OS_ARCH), IRIX) + ifeq ($(basename $(OS_RELEASE)),6) + ifndef NS_USE_GCC + ifeq ($(USE_N32),1) + XLDOPTS += -n32 -Wl,-woff,85 + else + ifeq ($(USE_64),1) + XLDOPTS += -64 + else + XLDOPTS += -32 + endif + endif + endif + endif +endif + +ifeq ($(OS_ARCH), HP-UX) + ifeq ($(USE_64),1) + XLDOPTS += +DD64 + endif +endif + +ifeq ($(OS_ARCH), OS2) +XCFLAGS = $(OS_CFLAGS) +endif + +include $(topsrcdir)/config/rules.mk + +PROGS = $(OBJDIR)/now$(PROG_SUFFIX) + +ifeq (,$(CROSS_COMPILE)$(filter-out OS2 WINNT,$(OS_ARCH))) +TARGETS = $(PROGS) +else +ifeq (,$(filter-out SYMBIAN WINCE,$(OS_ARCH))) +TARGETS = $(PROGS) +else +PROGS += $(OBJDIR)/nsinstall$(PROG_SUFFIX) +TARGETS = $(PROGS) $(PLSRCS:.pl=) +endif +endif + +OUTOPTION = -o # end of the line +ifeq (,$(filter-out WINNT WIN95 WINCE,$(OS_TARGET))) +ifndef NS_USE_GCC +OUTOPTION = -Fe +endif +endif + +# Redefine MAKE_OBJDIR for just this directory +define MAKE_OBJDIR +if test ! -d $(@D); then rm -rf $(@D); mkdir $(@D); else true; fi +endef + +export:: $(TARGETS) + rm -f $(dist_bindir)/nspr-config + +ifdef WRAP_SYSTEM_INCLUDES +export:: + if test ! -d system_wrappers; then mkdir system_wrappers; fi + $(PERL) $(srcdir)/make-system-wrappers.pl system_wrappers < $(srcdir)/system-headers + $(INSTALL) system_wrappers $(dist_includedir) +endif + +$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) + $(CC) $(XCFLAGS) $< $(LDFLAGS) $(XLDOPTS) $(OUTOPTION)$@ + +install:: nspr.m4 + $(NSINSTALL) -D $(DESTDIR)$(datadir)/aclocal + $(NSINSTALL) -t -m 0644 $< $(DESTDIR)$(datadir)/aclocal + +install:: nspr.pc + $(NSINSTALL) -D $(DESTDIR)$(libdir)/pkgconfig + $(NSINSTALL) -t -m 0644 $< $(DESTDIR)$(libdir)/pkgconfig diff -Nru nspr-4.9.5/nspr/config/make-system-wrappers.pl nspr-4.10.7/nspr/config/make-system-wrappers.pl --- nspr-4.9.5/nspr/config/make-system-wrappers.pl 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/make-system-wrappers.pl 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,26 @@ +#!/usr/bin/perl +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +$output_dir = shift; + +while () { + chomp; + if (-e "$output_dir/$_") { + next; + } + + if (/(.*)\/[^\/*]/) { + mkdir "$output_dir/$1"; + } + + open OUT, ">$output_dir/$_"; + print OUT "#pragma GCC system_header\n"; # suppress include_next warning + print OUT "#pragma GCC visibility push(default)\n"; + print OUT "#include_next \<$_\>\n"; + print OUT "#pragma GCC visibility pop\n"; + close OUT; +} + diff -Nru nspr-4.9.5/nspr/config/nfspwd.pl nspr-4.10.7/nspr/config/nfspwd.pl --- nspr-4.9.5/nspr/config/nfspwd.pl 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/nfspwd.pl 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,18 @@ +#! perl +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +require "fastcwd.pl"; + +$_ = &fastcwd; +if (m@^/[uh]/@o || s@^/tmp_mnt/@/@o) { + print("$_\n"); +} elsif ((($user, $rest) = m@^/usr/people/(\w+)/(.*)@o) + && readlink("/u/$user") eq "/usr/people/$user") { + print("/u/$user/$rest\n"); +} else { + chop($host = `hostname`); + print("/h/$host$_\n"); +} diff -Nru nspr-4.9.5/nspr/config/now.c nspr-4.10.7/nspr/config/now.c --- nspr-4.9.5/nspr/config/now.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/now.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include + +int main(int argc, char **argv) +{ +#if defined(OMIT_LIB_BUILD_TIME) + /* + * Some platforms don't have any 64-bit integer type + * such as 'long long'. Because we can't use NSPR's + * PR_snprintf in this program, it is difficult to + * print a static initializer for PRInt64 (a struct). + * So we print nothing. The makefiles that build the + * shared libraries will detect the empty output string + * of this program and omit the library build time + * in PRVersionDescription. + */ +#elif defined(_MSC_VER) + __int64 now; + time_t sec; + + sec = time(NULL); + now = (1000000i64) * sec; + fprintf(stdout, "%I64d", now); +#else + long long now; + time_t sec; + + sec = time(NULL); + now = (1000000LL) * sec; + fprintf(stdout, "%lld", now); +#endif + + return 0; +} /* main */ + +/* now.c */ diff -Nru nspr-4.9.5/nspr/config/nsinstall.c nspr-4.10.7/nspr/config/nsinstall.c --- nspr-4.9.5/nspr/config/nsinstall.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/nsinstall.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,525 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Netscape portable install command. +** +** Brendan Eich, 7/20/95 +*/ +#include /* OSF/1 requires this before grp.h, so put it first */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef USE_REENTRANT_LIBC +#include "libc_r.h" +#endif /* USE_REENTRANT_LIBC */ + +#include "pathsub.h" + +#define HAVE_FCHMOD + +#if defined(BEOS) +#undef HAVE_FCHMOD +#endif + +/* + * Does getcwd() take NULL as the first argument and malloc + * the result buffer? + */ +#if !defined(DARWIN) +#define GETCWD_CAN_MALLOC +#endif + +#if defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) +#include +#endif + +#if defined(SCO) || defined(UNIXWARE) +#if !defined(S_ISLNK) && defined(S_IFLNK) +#define S_ISLNK(a) (((a) & S_IFMT) == S_IFLNK) +#endif +#endif + +#ifdef QNX +#define d_ino d_stat.st_ino +#endif + +static void +usage(void) +{ + fprintf(stderr, + "usage: %s [-C cwd] [-L linkprefix] [-m mode] [-o owner] [-g group]\n" + " %*s [-DdltR] file [file ...] directory\n", + program, (int)strlen(program), ""); + exit(2); +} + +static int +mkdirs(char *path, mode_t mode) +{ + char *cp; + struct stat sb; + int res; + + while (*path == '/' && path[1] == '/') + path++; + for (cp = strrchr(path, '/'); cp && cp != path && cp[-1] == '/'; cp--) + ; + if (cp && cp != path) { + *cp = '\0'; + if ((stat(path, &sb) < 0 || !S_ISDIR(sb.st_mode)) && + mkdirs(path, mode) < 0) { + return -1; + } + *cp = '/'; + } + res = mkdir(path, mode); + if ((res != 0) && (errno == EEXIST)) + return 0; + else + return res; +} + +static uid_t +touid(char *owner) +{ + struct passwd *pw; + uid_t uid; + char *cp; + + pw = getpwnam(owner); + if (pw) + return pw->pw_uid; + uid = strtol(owner, &cp, 0); + if (uid == 0 && cp == owner) + fail("cannot find uid for %s", owner); + return uid; +} + +static gid_t +togid(char *group) +{ + struct group *gr; + gid_t gid; + char *cp; + + gr = getgrnam(group); + if (gr) + return gr->gr_gid; + gid = strtol(group, &cp, 0); + if (gid == 0 && cp == group) + fail("cannot find gid for %s", group); + return gid; +} + +int +main(int argc, char **argv) +{ + int onlydir, dodir, dolink, dorelsymlink, dotimes, opt, len, lplen, tdlen, bnlen, exists, fromfd, tofd, cc, wc; + mode_t mode = 0755; + char *linkprefix, *owner, *group, *cp, *cwd, *todir, *toname, *name, *base, *linkname, *bp, buf[BUFSIZ]; + uid_t uid; + gid_t gid; + struct stat sb, tosb; + struct utimbuf utb; + + program = argv[0]; + cwd = linkname = linkprefix = owner = group = 0; + onlydir = dodir = dolink = dorelsymlink = dotimes = lplen = 0; + + while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) { + switch (opt) { + case 'C': + cwd = optarg; + break; + case 'D': + onlydir = 1; + break; + case 'd': + dodir = 1; + break; + case 'l': + dolink = 1; + break; + case 'L': + linkprefix = optarg; + lplen = strlen(linkprefix); + dolink = 1; + break; + case 'R': + dolink = dorelsymlink = 1; + break; + case 'm': + mode = strtoul(optarg, &cp, 8); + if (mode == 0 && cp == optarg) + usage(); + break; + case 'o': + owner = optarg; + break; + case 'g': + group = optarg; + break; + case 't': + dotimes = 1; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + if (argc < 2 - onlydir) + usage(); + + todir = argv[argc-1]; + if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) && + mkdirs(todir, 0777) < 0) { + fail("cannot make directory %s", todir); + } + if (onlydir) + return 0; + + if (!cwd) { +#ifdef GETCWD_CAN_MALLOC + cwd = getcwd(0, PATH_MAX); +#else + cwd = malloc(PATH_MAX + 1); + cwd = getcwd(cwd, PATH_MAX); +#endif + } + xchdir(todir); +#ifdef GETCWD_CAN_MALLOC + todir = getcwd(0, PATH_MAX); +#else + todir = malloc(PATH_MAX + 1); + todir = getcwd(todir, PATH_MAX); +#endif + xchdir(cwd); + tdlen = strlen(todir); + + uid = owner ? touid(owner) : -1; + gid = group ? togid(group) : -1; + + while (--argc > 0) { + name = *argv++; + len = strlen(name); + base = xbasename(name); + bnlen = strlen(base); + toname = (char*)xmalloc(tdlen + 1 + bnlen + 1); + sprintf(toname, "%s/%s", todir, base); + exists = (lstat(toname, &tosb) == 0); + + if (dodir) { + /* -d means create a directory, always */ + if (exists && !S_ISDIR(tosb.st_mode)) { + (void) unlink(toname); + exists = 0; + } + if (!exists && mkdir(toname, mode) < 0) + fail("cannot make directory %s", toname); + if ((owner || group) && chown(toname, uid, gid) < 0) + fail("cannot change owner of %s", toname); + } else if (dolink) { + if (*name == '/') { + /* source is absolute pathname, link to it directly */ + linkname = 0; + } else { + if (linkprefix) { + /* -L implies -l and prefixes names with a $cwd arg. */ + len += lplen + 1; + linkname = (char*)xmalloc(len + 1); + sprintf(linkname, "%s/%s", linkprefix, name); + } else if (dorelsymlink) { + /* Symlink the relative path from todir to source name. */ + linkname = (char*)xmalloc(PATH_MAX); + + if (*todir == '/') { + /* todir is absolute: skip over common prefix. */ + lplen = relatepaths(todir, cwd, linkname); + strcpy(linkname + lplen, name); + } else { + /* todir is named by a relative path: reverse it. */ + reversepath(todir, name, len, linkname); + xchdir(cwd); + } + + len = strlen(linkname); + } + name = linkname; + } + + /* Check for a pre-existing symlink with identical content. */ + if (exists && + (!S_ISLNK(tosb.st_mode) || + readlink(toname, buf, sizeof buf) != len || + strncmp(buf, name, len) != 0)) { + (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); + exists = 0; + } + if (!exists && symlink(name, toname) < 0) + fail("cannot make symbolic link %s", toname); +#ifdef HAVE_LCHOWN + if ((owner || group) && lchown(toname, uid, gid) < 0) + fail("cannot change owner of %s", toname); +#endif + + if (linkname) { + free(linkname); + linkname = 0; + } + } else { + /* Copy from name to toname, which might be the same file. */ + fromfd = open(name, O_RDONLY); + if (fromfd < 0 || fstat(fromfd, &sb) < 0) + fail("cannot access %s", name); + if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0)) + (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); + tofd = open(toname, O_CREAT | O_WRONLY, 0666); + if (tofd < 0) + fail("cannot create %s", toname); + + bp = buf; + while ((cc = read(fromfd, bp, sizeof buf)) > 0) { + while ((wc = write(tofd, bp, cc)) > 0) { + if ((cc -= wc) == 0) + break; + bp += wc; + } + if (wc < 0) + fail("cannot write to %s", toname); + } + if (cc < 0) + fail("cannot read from %s", name); + + if (ftruncate(tofd, sb.st_size) < 0) + fail("cannot truncate %s", toname); + if (dotimes) { + utb.actime = sb.st_atime; + utb.modtime = sb.st_mtime; + if (utime(toname, &utb) < 0) + fail("cannot set times of %s", toname); + } +#ifdef HAVE_FCHMOD + if (fchmod(tofd, mode) < 0) +#else + if (chmod(toname, mode) < 0) +#endif + fail("cannot change mode of %s", toname); + if ((owner || group) && fchown(tofd, uid, gid) < 0) + fail("cannot change owner of %s", toname); + + /* Must check for delayed (NFS) write errors on close. */ + if (close(tofd) < 0) + fail("cannot write to %s", toname); + close(fromfd); + } + + free(toname); + } + + free(cwd); + free(todir); + return 0; +} + +/* +** Pathname subroutines. +** +** Brendan Eich, 8/29/95 +*/ + +char *program; + +void +fail(char *format, ...) +{ + int error; + va_list ap; + +#ifdef USE_REENTRANT_LIBC + R_STRERROR_INIT_R(); +#endif + + error = errno; + fprintf(stderr, "%s: ", program); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + if (error) + +#ifdef USE_REENTRANT_LIBC + R_STRERROR_R(errno); + fprintf(stderr, ": %s", r_strerror_r); +#else + fprintf(stderr, ": %s", strerror(errno)); +#endif + + putc('\n', stderr); + exit(1); +} + +char * +getcomponent(char *path, char *name) +{ + if (*path == '\0') + return 0; + if (*path == '/') { + *name++ = '/'; + } else { + do { + *name++ = *path++; + } while (*path != '/' && *path != '\0'); + } + *name = '\0'; + while (*path == '/') + path++; + return path; +} + +#ifdef UNIXWARE_READDIR_BUFFER_TOO_SMALL +/* Sigh. The static buffer in Unixware's readdir is too small. */ +struct dirent * readdir(DIR *d) +{ + static struct dirent *buf = NULL; +#define MAX_PATH_LEN 1024 + + + if(buf == NULL) + buf = (struct dirent *) malloc(sizeof(struct dirent) + MAX_PATH_LEN) +; + return(readdir_r(d, buf)); +} +#endif + +char * +ino2name(ino_t ino, char *dir) +{ + DIR *dp; + struct dirent *ep; + char *name; + + dp = opendir(".."); + if (!dp) + fail("cannot read parent directory"); + for (;;) { + if (!(ep = readdir(dp))) + fail("cannot find current directory"); + if (ep->d_ino == ino) + break; + } + name = xstrdup(ep->d_name); + closedir(dp); + return name; +} + +void * +xmalloc(size_t size) +{ + void *p = malloc(size); + if (!p) + fail("cannot allocate %u bytes", size); + return p; +} + +char * +xstrdup(char *s) +{ + return strcpy((char*)xmalloc(strlen(s) + 1), s); +} + +char * +xbasename(char *path) +{ + char *cp; + + while ((cp = strrchr(path, '/')) && cp[1] == '\0') + *cp = '\0'; + if (!cp) return path; + return cp + 1; +} + +void +xchdir(char *dir) +{ + if (chdir(dir) < 0) + fail("cannot change directory to %s", dir); +} + +int +relatepaths(char *from, char *to, char *outpath) +{ + char *cp, *cp2; + int len; + char buf[NAME_MAX]; + + assert(*from == '/' && *to == '/'); + for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++) + if (*cp == '\0') + break; + while (cp[-1] != '/') + cp--, cp2--; + if (cp - 1 == to) { + /* closest common ancestor is /, so use full pathname */ + len = strlen(strcpy(outpath, to)); + if (outpath[len] != '/') { + outpath[len++] = '/'; + outpath[len] = '\0'; + } + } else { + len = 0; + while ((cp2 = getcomponent(cp2, buf)) != 0) { + strcpy(outpath + len, "../"); + len += 3; + } + while ((cp = getcomponent(cp, buf)) != 0) { + sprintf(outpath + len, "%s/", buf); + len += strlen(outpath + len); + } + } + return len; +} + +void +reversepath(char *inpath, char *name, int len, char *outpath) +{ + char *cp, *cp2; + char buf[NAME_MAX]; + struct stat sb; + + cp = strcpy(outpath + PATH_MAX - (len + 1), name); + cp2 = inpath; + while ((cp2 = getcomponent(cp2, buf)) != 0) { + if (strcmp(buf, ".") == 0) + continue; + if (strcmp(buf, "..") == 0) { + if (stat(".", &sb) < 0) + fail("cannot stat current directory"); + name = ino2name(sb.st_ino, ".."); + len = strlen(name); + cp -= len + 1; + strcpy(cp, name); + cp[len] = '/'; + free(name); + xchdir(".."); + } else { + cp -= 3; + strncpy(cp, "../", 3); + xchdir(buf); + } + } + strcpy(outpath, cp); +} diff -Nru nspr-4.9.5/nspr/config/nspr-config.in nspr-4.10.7/nspr/config/nspr-config.in --- nspr-4.9.5/nspr/config/nspr-config.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/nspr-config.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,147 @@ +#!/bin/sh +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +prefix=@prefix@ + +major_version=@MOD_MAJOR_VERSION@ +minor_version=@MOD_MINOR_VERSION@ +patch_version=@MOD_PATCH_VERSION@ + +usage() +{ + cat <&2 +fi + +lib_nspr=yes +lib_plc=yes +lib_plds=yes + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + ;; + --prefix) + echo_prefix=yes + ;; + --exec-prefix=*) + exec_prefix=$optarg + ;; + --exec-prefix) + echo_exec_prefix=yes + ;; + --includedir=*) + includedir=$optarg + ;; + --includedir) + echo_includedir=yes + ;; + --libdir=*) + libdir=$optarg + ;; + --libdir) + echo_libdir=yes + ;; + --version) + echo ${major_version}.${minor_version}.${patch_version} + ;; + --cflags) + echo_cflags=yes + ;; + --libs) + echo_libs=yes + ;; + nspr) + lib_nspr=yes + ;; + plc) + lib_plc=yes + ;; + plds) + lib_plds=yes + ;; + *) + usage 1 1>&2 + ;; + esac + shift +done + +# Set variables that may be dependent upon other variables +if test -z "$exec_prefix"; then + exec_prefix=@exec_prefix@ +fi +if test -z "$includedir"; then + includedir=@includedir@ +fi +if test -z "$libdir"; then + libdir=@libdir@ +fi + +if test "$echo_prefix" = "yes"; then + echo $prefix +fi + +if test "$echo_exec_prefix" = "yes"; then + echo $exec_prefix +fi + +if test "$echo_includedir" = "yes"; then + echo $includedir +fi + +if test "$echo_libdir" = "yes"; then + echo $libdir +fi + +if test "$echo_cflags" = "yes"; then + echo -I$includedir +fi + +if test "$echo_libs" = "yes"; then + libdirs=-L$libdir + if test -n "$lib_plds"; then + libdirs="$libdirs -lplds${major_version}" + fi + if test -n "$lib_plc"; then + libdirs="$libdirs -lplc${major_version}" + fi + if test -n "$lib_nspr"; then + libdirs="$libdirs -lnspr${major_version}" + fi + os_ldflags="@LDFLAGS@" + for i in $os_ldflags ; do + if echo $i | grep \^-L >/dev/null; then + libdirs="$libdirs $i" + fi + done + echo $libdirs @OS_LIBS@ +fi + diff -Nru nspr-4.9.5/nspr/config/nsprincl.mk.in nspr-4.10.7/nspr/config/nsprincl.mk.in --- nspr-4.9.5/nspr/config/nsprincl.mk.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/nsprincl.mk.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,9 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Include in Makefiles to define NSPR variables + +NSPR_VERSION = @NSPR_VERSION@ +NSPR_LIB = -lnspr@NSPR_VERSION@ +NSPR_EXTRA_LIBS = @EXTRA_LIBS@ diff -Nru nspr-4.9.5/nspr/config/nsprincl.sh.in nspr-4.10.7/nspr/config/nsprincl.sh.in --- nspr-4.9.5/nspr/config/nsprincl.sh.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/nsprincl.sh.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,9 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Include in shell scripts to define NSPR variables + +NSPR_VERSION=@NSPR_VERSION@ +NSPR_LIB=-lnspr$NSPR_VERSION +NSPR_EXTRA_LIBS="@EXTRA_LIBS@" diff -Nru nspr-4.9.5/nspr/config/nspr.m4 nspr-4.10.7/nspr/config/nspr.m4 --- nspr-4.9.5/nspr/config/nspr.m4 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/nspr.m4 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,82 @@ +# -*- tab-width: 4; -*- +# Configure paths for NSPR +# Public domain - Chris Seawood 2001-04-05 +# Based upon gtk.m4 (also PD) by Owen Taylor + +dnl AM_PATH_NSPR([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for NSPR, and define NSPR_CFLAGS and NSPR_LIBS +AC_DEFUN([AM_PATH_NSPR], +[dnl + +AC_ARG_WITH(nspr-prefix, + [ --with-nspr-prefix=PFX Prefix where NSPR is installed], + nspr_config_prefix="$withval", + nspr_config_prefix="") + +AC_ARG_WITH(nspr-exec-prefix, + [ --with-nspr-exec-prefix=PFX + Exec prefix where NSPR is installed], + nspr_config_exec_prefix="$withval", + nspr_config_exec_prefix="") + + if test -n "$nspr_config_exec_prefix"; then + nspr_config_args="$nspr_config_args --exec-prefix=$nspr_config_exec_prefix" + if test -z "$NSPR_CONFIG"; then + NSPR_CONFIG=$nspr_config_exec_prefix/bin/nspr-config + fi + fi + if test -n "$nspr_config_prefix"; then + nspr_config_args="$nspr_config_args --prefix=$nspr_config_prefix" + if test -z "$NSPR_CONFIG"; then + NSPR_CONFIG=$nspr_config_prefix/bin/nspr-config + fi + fi + + unset ac_cv_path_NSPR_CONFIG + AC_PATH_PROG(NSPR_CONFIG, nspr-config, no) + min_nspr_version=ifelse([$1], ,4.0.0,$1) + AC_MSG_CHECKING(for NSPR - version >= $min_nspr_version) + + no_nspr="" + if test "$NSPR_CONFIG" = "no"; then + no_nspr="yes" + else + NSPR_CFLAGS=`$NSPR_CONFIG $nspr_config_args --cflags` + NSPR_LIBS=`$NSPR_CONFIG $nspr_config_args --libs` + + nspr_config_major_version=`$NSPR_CONFIG $nspr_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + nspr_config_minor_version=`$NSPR_CONFIG $nspr_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + nspr_config_micro_version=`$NSPR_CONFIG $nspr_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + min_nspr_major_version=`echo $min_nspr_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + min_nspr_minor_version=`echo $min_nspr_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + min_nspr_micro_version=`echo $min_nspr_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "$nspr_config_major_version" -ne "$min_nspr_major_version"; then + no_nspr="yes" + elif test "$nspr_config_major_version" -eq "$min_nspr_major_version" && + test "$nspr_config_minor_version" -lt "$min_nspr_minor_version"; then + no_nspr="yes" + elif test "$nspr_config_major_version" -eq "$min_nspr_major_version" && + test "$nspr_config_minor_version" -eq "$min_nspr_minor_version" && + test "$nspr_config_micro_version" -lt "$min_nspr_micro_version"; then + no_nspr="yes" + fi + fi + + if test -z "$no_nspr"; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + fi + + + AC_SUBST(NSPR_CFLAGS) + AC_SUBST(NSPR_LIBS) + +]) diff -Nru nspr-4.9.5/nspr/config/nspr.pc.in nspr-4.10.7/nspr/config/nspr.pc.in --- nspr-4.9.5/nspr/config/nspr.pc.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/nspr.pc.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: NSPR +Description: The Netscape Portable Runtime +Version: @MOD_MAJOR_VERSION@.@MOD_MINOR_VERSION@.@MOD_PATCH_VERSION@ +Libs: -L@libdir@ -lplds@MOD_MAJOR_VERSION@ -lplc@MOD_MAJOR_VERSION@ -lnspr@MOD_MAJOR_VERSION@ +Cflags: -I@includedir@ diff -Nru nspr-4.9.5/nspr/config/pathsub.h nspr-4.10.7/nspr/config/pathsub.h --- nspr-4.9.5/nspr/config/pathsub.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/pathsub.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef pathsub_h___ +#define pathsub_h___ +/* +** Pathname subroutines. +** +** Brendan Eich, 8/29/95 +*/ +#include +#include + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +/* + * Just prevent stupidity + */ +#undef NAME_MAX +#define NAME_MAX 256 + +extern char *program; + +extern void fail(char *format, ...); +extern char *getcomponent(char *path, char *name); +extern char *ino2name(ino_t ino, char *dir); +extern void *xmalloc(size_t size); +extern char *xstrdup(char *s); +extern char *xbasename(char *path); +extern void xchdir(char *dir); + +/* Relate absolute pathnames from and to returning the result in outpath. */ +extern int relatepaths(char *from, char *to, char *outpath); + +/* XXX changes current working directory -- caveat emptor */ +extern void reversepath(char *inpath, char *name, int len, char *outpath); + +#endif /* pathsub_h___ */ diff -Nru nspr-4.9.5/nspr/config/prdepend.h nspr-4.10.7/nspr/config/prdepend.h --- nspr-4.9.5/nspr/config/prdepend.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/prdepend.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,13 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * A dummy header file that is a dependency for all the object files. + * Used to force a full recompilation of NSPR in Mozilla's Tinderbox + * depend builds. See comments in rules.mk. + */ + +#error "Do not include this header file." + diff -Nru nspr-4.9.5/nspr/config/rules.mk nspr-4.10.7/nspr/config/rules.mk --- nspr-4.9.5/nspr/config/rules.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/rules.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,522 @@ +#! gmake +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +################################################################################ +# We used to have a 4 pass build process. Now we do everything in one pass. +# +# export - Create generated headers and stubs. Publish public headers to +# dist//include. +# Create libraries. Publish libraries to dist//lib. +# Create programs. +# +# libs - obsolete. Now a synonym of "export". +# +# all - the default makefile target. Now a synonym of "export". +# +# install - Install headers, libraries, and programs on the system. +# +# Parameters to this makefile (set these before including): +# +# a) +# TARGETS -- the target to create +# (defaults to $LIBRARY $PROGRAM) +# b) +# DIRS -- subdirectories for make to recurse on +# (the 'all' rule builds $TARGETS $DIRS) +# c) +# CSRCS -- .c files to compile +# (used to define $OBJS) +# d) +# PROGRAM -- the target program name to create from $OBJS +# ($OBJDIR automatically prepended to it) +# e) +# LIBRARY -- the target library name to create from $OBJS +# ($OBJDIR automatically prepended to it) +# +################################################################################ + +ifndef topsrcdir +topsrcdir=$(MOD_DEPTH) +endif + +ifndef srcdir +srcdir=. +endif + +ifndef NSPR_CONFIG_MK +include $(topsrcdir)/config/config.mk +endif + +ifdef USE_AUTOCONF +ifdef CROSS_COMPILE +ifdef INTERNAL_TOOLS +CC=$(HOST_CC) +CCC=$(HOST_CXX) +CFLAGS=$(HOST_CFLAGS) +CXXFLAGS=$(HOST_CXXFLAGS) +LDFLAGS=$(HOST_LDFLAGS) +endif +endif +endif + +# +# This makefile contains rules for building the following kinds of +# libraries: +# - LIBRARY: a static (archival) library +# - SHARED_LIBRARY: a shared (dynamic link) library +# - IMPORT_LIBRARY: an import library, used only on Windows and OS/2 +# +# The names of these libraries can be generated by simply specifying +# LIBRARY_NAME and LIBRARY_VERSION. +# + +ifdef LIBRARY_NAME +ifeq (,$(filter-out WINNT WINCE OS2,$(OS_ARCH))) + +# +# Win95 and OS/2 require library names conforming to the 8.3 rule. +# other platforms do not. +# +ifeq (,$(filter-out WIN95 WINCE WINMO OS2,$(OS_TARGET))) +LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX) +SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) +IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX) +SHARED_LIB_PDB = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).pdb +else +LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX) +SHARED_LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) +IMPORT_LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX) +SHARED_LIB_PDB = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).pdb +endif + +else + +LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX) +ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1) +SHARED_LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_shr.a +else +ifdef MKSHLIB +SHARED_LIBRARY = $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) +endif +endif + +endif +endif + +ifndef TARGETS +ifeq (,$(filter-out WINNT WINCE OS2,$(OS_ARCH))) +TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) +ifdef MOZ_DEBUG_SYMBOLS +ifdef MSC_VER +ifneq (,$(filter-out 1100 1200,$(MSC_VER))) +TARGETS += $(SHARED_LIB_PDB) +endif +endif +endif +else +TARGETS = $(LIBRARY) $(SHARED_LIBRARY) +endif +endif + +# +# OBJS is the list of object files. It can be constructed by +# specifying CSRCS (list of C source files) and ASFILES (list +# of assembly language source files). +# + +ifndef OBJS +OBJS = $(addprefix $(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \ + $(addprefix $(OBJDIR)/,$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))) +endif + +ALL_TRASH = $(TARGETS) $(OBJS) $(RES) $(filter-out . .., $(OBJDIR)) LOGS TAGS $(GARBAGE) \ + $(NOSUCHFILE) \ + $(OBJS:.$(OBJ_SUFFIX)=.i_o) \ + so_locations + +ifndef RELEASE_LIBS_DEST +RELEASE_LIBS_DEST = $(RELEASE_LIB_DIR) +endif + +define MAKE_IN_DIR + $(MAKE) -C $(dir) $@ + +endef # do not remove the blank line! + +ifdef DIRS +LOOP_OVER_DIRS = $(foreach dir,$(DIRS),$(MAKE_IN_DIR)) +endif + +################################################################################ + +all:: export + +export:: + +$(LOOP_OVER_DIRS) + +libs:: export + +clean:: + rm -rf $(OBJS) $(RES) so_locations $(NOSUCHFILE) $(GARBAGE) + +$(LOOP_OVER_DIRS) + +clobber:: + rm -rf $(OBJS) $(RES) $(TARGETS) $(filter-out . ..,$(OBJDIR)) $(GARBAGE) so_locations $(NOSUCHFILE) + +$(LOOP_OVER_DIRS) + +realclean clobber_all:: + rm -rf $(wildcard *.OBJ *.OBJD) dist $(ALL_TRASH) + +$(LOOP_OVER_DIRS) + +distclean:: + rm -rf $(wildcard *.OBJ *.OBJD) dist $(ALL_TRASH) $(DIST_GARBAGE) + +$(LOOP_OVER_DIRS) + +install:: $(RELEASE_BINS) $(RELEASE_HEADERS) $(RELEASE_LIBS) +ifdef RELEASE_BINS + $(NSINSTALL) -t -m 0755 $(RELEASE_BINS) $(DESTDIR)$(bindir) +endif +ifdef RELEASE_HEADERS + $(NSINSTALL) -t -m 0644 $(RELEASE_HEADERS) $(DESTDIR)$(includedir)/$(include_subdir) +endif +ifdef RELEASE_LIBS + $(NSINSTALL) -t -m 0755 $(RELEASE_LIBS) $(DESTDIR)$(libdir)/$(lib_subdir) +endif + +$(LOOP_OVER_DIRS) + +release:: export +ifdef RELEASE_BINS + @echo "Copying executable programs and scripts to release directory" + @if test -z "$(BUILD_NUMBER)"; then \ + echo "BUILD_NUMBER must be defined"; \ + false; \ + else \ + true; \ + fi + @if test ! -d $(RELEASE_BIN_DIR); then \ + rm -rf $(RELEASE_BIN_DIR); \ + $(NSINSTALL) -D $(RELEASE_BIN_DIR);\ + else \ + true; \ + fi + cp $(RELEASE_BINS) $(RELEASE_BIN_DIR) +endif +ifdef RELEASE_LIBS + @echo "Copying libraries to release directory" + @if test -z "$(BUILD_NUMBER)"; then \ + echo "BUILD_NUMBER must be defined"; \ + false; \ + else \ + true; \ + fi + @if test ! -d $(RELEASE_LIBS_DEST); then \ + rm -rf $(RELEASE_LIBS_DEST); \ + $(NSINSTALL) -D $(RELEASE_LIBS_DEST);\ + else \ + true; \ + fi + cp $(RELEASE_LIBS) $(RELEASE_LIBS_DEST) +endif +ifdef RELEASE_HEADERS + @echo "Copying header files to release directory" + @if test -z "$(BUILD_NUMBER)"; then \ + echo "BUILD_NUMBER must be defined"; \ + false; \ + else \ + true; \ + fi + @if test ! -d $(RELEASE_HEADERS_DEST); then \ + rm -rf $(RELEASE_HEADERS_DEST); \ + $(NSINSTALL) -D $(RELEASE_HEADERS_DEST);\ + else \ + true; \ + fi + cp $(RELEASE_HEADERS) $(RELEASE_HEADERS_DEST) +endif + +$(LOOP_OVER_DIRS) + +alltags: + rm -f TAGS tags + find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs etags -a + find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs ctags -a + +$(NFSPWD): + cd $(@D); $(MAKE) $(@F) + +$(PROGRAM): $(OBJS) + @$(MAKE_OBJDIR) +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) +ifdef MOZ_PROFILE_USE +# In the second pass, we need to merge the pgc files into the pgd file. +# The compiler would do this for us automatically if they were in the right +# place, but they're in dist/bin. + python $(topsrcdir)/build/win32/pgomerge.py \ + $(notdir $(PROGRAM:.exe=)) $(DIST)/bin +endif # MOZ_PROFILE_USE + $(CC) $(OBJS) -Fe$@ -link $(LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) +ifdef MT + @if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ + rm -f $@.manifest; \ + fi +endif # MSVC with manifest tool +ifdef MOZ_PROFILE_GENERATE +# touch it a few seconds into the future to work around FAT's +# 2-second granularity + touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink +endif # MOZ_PROFILE_GENERATE +else # WINNT && !GCC + $(CC) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS) $(WRAP_LDFLAGS) +endif # WINNT && !GCC +ifdef ENABLE_STRIP + $(STRIP) $@ +endif + +$(LIBRARY): $(OBJS) + @$(MAKE_OBJDIR) + rm -f $@ + $(AR) $(AR_FLAGS) $(OBJS) $(AR_EXTRA_ARGS) + $(RANLIB) $@ + +ifeq ($(OS_TARGET), OS2) +$(IMPORT_LIBRARY): $(MAPFILE) + rm -f $@ + $(IMPLIB) $@ $(MAPFILE) +else +ifeq (,$(filter-out WIN95 WINCE WINMO,$(OS_TARGET))) +# PDBs and import libraries need to depend on the shared library to +# order dependencies properly. +$(IMPORT_LIBRARY): $(SHARED_LIBRARY) +$(SHARED_LIB_PDB): $(SHARED_LIBRARY) +endif +endif + +$(SHARED_LIBRARY): $(OBJS) $(RES) $(MAPFILE) + @$(MAKE_OBJDIR) + rm -f $@ +ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1) + echo "#!" > $(OBJDIR)/lib$(LIBRARY_NAME)_syms + nm -B -C -g $(OBJS) \ + | awk '/ [T,D] / {print $$3}' \ + | sed -e 's/^\.//' \ + | sort -u >> $(OBJDIR)/lib$(LIBRARY_NAME)_syms + $(LD) $(XCFLAGS) -o $@ $(OBJS) -bE:$(OBJDIR)/lib$(LIBRARY_NAME)_syms \ + -bM:SRE -bnoentry $(OS_LIBS) $(EXTRA_LIBS) +else # AIX 4.1 +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) +ifdef MOZ_PROFILE_USE + python $(topsrcdir)/build/win32/pgomerge.py \ + $(notdir $(SHARED_LIBRARY:.$(DLL_SUFFIX)=)) $(DIST)/bin +endif # MOZ_PROFILE_USE + $(LINK_DLL) -MAP $(DLLBASE) $(DLL_LIBS) $(EXTRA_LIBS) $(OBJS) $(RES) +ifdef MT + @if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;2; \ + rm -f $@.manifest; \ + fi +endif # MSVC with manifest tool +ifdef MOZ_PROFILE_GENERATE + touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink +endif # MOZ_PROFILE_GENERATE +else # WINNT && !GCC + $(MKSHLIB) $(OBJS) $(RES) $(LDFLAGS) $(WRAP_LDFLAGS) $(EXTRA_LIBS) +endif # WINNT && !GCC +endif # AIX 4.1 +ifdef ENABLE_STRIP + $(STRIP) $@ +endif + +################################################################################ + +ifdef MOZ_PROFILE_USE +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) +# When building with PGO, we have to make sure to re-link +# in the MOZ_PROFILE_USE phase if we linked in the +# MOZ_PROFILE_GENERATE phase. We'll touch this pgo.relink +# file in the link rule in the GENERATE phase to indicate +# that we need a relink. +$(SHARED_LIBRARY): pgo.relink + +$(PROGRAM): pgo.relink + +endif # WINNT && !GCC +endif # MOZ_PROFILE_USE + +ifneq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE)) +ifdef NS_USE_GCC +# Force rebuilding libraries and programs in both passes because each +# pass uses different object files. +$(PROGRAM) $(SHARED_LIBRARY) $(LIBRARY): FORCE +.PHONY: FORCE +endif +endif + +################################################################################ + +ifdef MOZ_PROFILE_GENERATE +# Clean up profiling data during PROFILE_GENERATE phase +export:: +ifeq ($(OS_ARCH)_$(NS_USE_GCC), WINNT_) + $(foreach pgd,$(wildcard *.pgd),pgomgr -clear $(pgd);) +else +ifdef NS_USE_GCC + -$(RM) *.gcda +endif +endif +endif + +################################################################################ + +ifeq ($(OS_ARCH),WINNT) +$(RES): $(RESNAME) + @$(MAKE_OBJDIR) +# The resource compiler does not understand the -U option. +ifdef NS_USE_GCC + $(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) -o $@ $< +else + $(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES) -Fo$@ $< +endif # GCC + @echo $(RES) finished +endif + +$(MAPFILE): $(LIBRARY_NAME).def + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH),SunOS) + grep -v ';-' $< | \ + sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ +endif +ifeq ($(OS_ARCH),OS2) + echo LIBRARY $(LIBRARY_NAME)$(LIBRARY_VERSION) INITINSTANCE TERMINSTANCE > $@ + echo PROTMODE >> $@ + echo CODE LOADONCALL MOVEABLE DISCARDABLE >> $@ + echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@ + echo EXPORTS >> $@ + grep -v ';+' $< | grep -v ';-' | \ + sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,\([\t ]*\),\1_,' | \ + awk 'BEGIN {ord=1;} { print($$0 " @" ord " RESIDENTNAME"); ord++;}' >> $@ + $(ADD_TO_DEF_FILE) +endif + +# +# Translate source filenames to absolute paths. This is required for +# debuggers under Windows and OS/2 to find source files automatically. +# + +ifeq (,$(filter-out AIX OS2,$(OS_ARCH))) +NEED_ABSOLUTE_PATH = 1 +endif + +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) +NEED_ABSOLUTE_PATH = 1 +endif + +ifdef NEED_ABSOLUTE_PATH +# The quotes allow absolute paths to contain spaces. +pr_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))" +endif + +$(OBJDIR)/%.$(OBJ_SUFFIX): %.cpp + @$(MAKE_OBJDIR) +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + $(CCC) -Fo$@ -c $(CCCFLAGS) $(call pr_abspath,$<) +else +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINCE) + $(CCC) -Fo$@ -c $(CCCFLAGS) $< +else +ifdef NEED_ABSOLUTE_PATH + $(CCC) -o $@ -c $(CCCFLAGS) $(call pr_abspath,$<) +else + $(CCC) -o $@ -c $(CCCFLAGS) $< +endif +endif +endif + +WCCFLAGS1 = $(subst /,\\,$(CFLAGS)) +WCCFLAGS2 = $(subst -I,-i=,$(WCCFLAGS1)) +WCCFLAGS3 = $(subst -D,-d,$(WCCFLAGS2)) +$(OBJDIR)/%.$(OBJ_SUFFIX): %.c + @$(MAKE_OBJDIR) +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + $(CC) -Fo$@ -c $(CFLAGS) $(call pr_abspath,$<) +else +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINCE) + $(CC) -Fo$@ -c $(CFLAGS) $< +else +ifdef NEED_ABSOLUTE_PATH + $(CC) -o $@ -c $(CFLAGS) $(call pr_abspath,$<) +else + $(CC) -o $@ -c $(CFLAGS) $< +endif +endif +endif + + +$(OBJDIR)/%.$(OBJ_SUFFIX): %.s + @$(MAKE_OBJDIR) + $(AS) -o $@ $(ASFLAGS) -c $< + +%.i: %.c + $(CC) -C -E $(CFLAGS) $< > $*.i + +%: %.pl + rm -f $@; cp $< $@; chmod +x $@ + +# +# HACK ALERT +# +# The only purpose of this rule is to pass Mozilla's Tinderbox depend +# builds (http://tinderbox.mozilla.org/showbuilds.cgi). Mozilla's +# Tinderbox builds NSPR continuously as part of the Mozilla client. +# Because NSPR's make depend is not implemented, whenever we change +# an NSPR header file, the depend build does not recompile the NSPR +# files that depend on the header. +# +# This rule makes all the objects depend on a dummy header file. +# Touch this dummy header file to force the depend build to recompile +# everything. +# +# This rule should be removed when make depend is implemented. +# + +DUMMY_DEPEND_H = $(topsrcdir)/config/prdepend.h + +$(filter $(OBJDIR)/%.$(OBJ_SUFFIX),$(OBJS)): $(OBJDIR)/%.$(OBJ_SUFFIX): $(DUMMY_DEPEND_H) + +# END OF HACK + +################################################################################ +# Special gmake rules. +################################################################################ + +# +# Disallow parallel builds with MSVC < 8 since it can't open the PDB file in +# parallel. +# +ifeq (,$(filter-out 1200 1300 1310,$(MSC_VER))) +.NOTPARALLEL: +endif + +# +# Re-define the list of default suffixes, so gmake won't have to churn through +# hundreds of built-in suffix rules for stuff we don't need. +# +.SUFFIXES: +.SUFFIXES: .a .$(OBJ_SUFFIX) .c .cpp .s .h .i .pl + +# +# Fake targets. Always run these rules, even if a file/directory with that +# name already exists. +# +.PHONY: all alltags clean export install libs realclean release + +# +# List the target pattern of an implicit rule as a dependency of the +# special target .PRECIOUS to preserve intermediate files made by +# implicit rules whose target patterns match that file's name. +# (See GNU Make documentation, Edition 0.51, May 1996, Sec. 10.4, +# p. 107.) +# +.PRECIOUS: $(OBJDIR)/%.$(OBJ_SUFFIX) diff -Nru nspr-4.9.5/nspr/config/system-headers nspr-4.10.7/nspr/config/system-headers --- nspr-4.9.5/nspr/config/system-headers 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/config/system-headers 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,172 @@ +Aliases.h +arpa/inet.h +assert.h +bsd/libc.h +bsd/syscall.h +bstring.h +builtin.h +c_asm.h +cf.h +CFBundle.h +CFData.h +CFDictionary.h +CFString.h +CFURL.h +CodeFragments.h +commdlg.h +crt_externs.h +crypt.h +ctype.h +descrip.h +Devices.h +direct.h +dirent.h +dlfcn.h +dl.h +DriverServices.h +dvidef.h +errno.h +Errors.h +Events.h +fcntl.h +fibdef.h +files.h +Files.h +float.h +Folders.h +Gestalt.h +getopt.h +grp.h +ia64/sys/inline.h +ifaddrs.h +image.h +ints.h +iodef.h +io.h +iostream.h +kernel/OS.h +lib$routines.h +limits.h +loader.h +locale.h +LowMem.h +MacErrors.h +machine/builtins.h +machine/clock.h +machine/endian.h +machine/inline.h +mach/mach_init.h +mach/mach_host.h +mach-o/dyld.h +MacTypes.h +Math64.h +math.h +mbstring.h +memory.h +MixedMode.h +model.h +mswsock.h +Multiprocessing.h +mutex.h +netdb.h +net/if.h +netinet/in.h +netinet/in_systm.h +netinet/tcp.h +OpenTptInternet.h +OpenTransport.h +os2.h +OS.h +osreldate.h +OSUtils.h +poll.h +PPCToolbox.h +Processes.h +process.h +pthread.h +pwd.h +QDOffscreen.h +Resources.h +rld_interface.h +rpc/types.h +semaphore.h +setjmp.h +share.h +signal.h +ssdef.h +starlet.h +stat.h +stdarg.h +stddef.h +stdio.h +stdlib.h +string.h +stropts.h +stsdef.h +support/SupportDefs.h +support/TLS.h +synch.h +sys/atomic_op.h +syscall.h +sys/cfgodm.h +sys/file.h +sys/filio.h +sys/immu.h +sys/ioctl.h +sys/ipc.h +sys/ldr.h +sys/locking.h +sys/lwp.h +sys/mman.h +sys/mpctl.h +sys/param.h +sys/pda.h +sys/poll.h +sys/prctl.h +sys/priv.h +sys/procfs.h +sys/pstat.h +sys/regset.h +sys/resource.h +sys/sched.h +sys/select.h +sys/sem.h +sys/sendfile.h +sys/shm.h +sys/socket.h +sys/stack.h +sys/stat.h +sys/statvfs.h +sys/syscall.h +sys/sysctl.h +sys/sysmp.h +sys/syssgi.h +sys/systeminfo.h +sys/timeb.h +sys/time.h +sys/times.h +sys/types.h +sys/ucontext.h +sys/uio.h +sys/utsname.h +sys/wait.h +task.h +TextUtils.h +thread.h +time.h +Timer.h +types.h +Types.h +ucontext.h +ucx$inetdef.h +ulocks.h +unistd.h +unix.h +unixlib.h +utime.h +wchar.h +winbase.h +win/compobj.h +windef.h +windows.h +winsock.h diff -Nru nspr-4.9.5/nspr/configure nspr-4.10.7/nspr/configure --- nspr-4.9.5/nspr/configure 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/configure 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,9966 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="pr/include/nspr.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +MT +NEXT_ROOT +SYMBIAN_SDK_DIR +MACOS_SDK_DIR +WRAP_SYSTEM_INCLUDES +VISIBILITY_FLAGS +CYGWIN_WRAPPER +OS_DLLFLAGS +EXEFLAGS +DLLFLAGS +RCFLAGS +RC +OPTIMIZER +NSINSTALL +RELEASE_OBJDIR_NAME +OBJDIR_NAME +OBJDIR +ULTRASPARC_LIBRARY +MOZ_OBJFORMAT +NOSUCHFILE +AIX_LINK_OPTS +RESOLVE_LINK_SYMBOLS +OS_LIBS +PROFILE_USE_LDFLAGS +PROFILE_USE_CFLAGS +PROFILE_GEN_LDFLAGS +PROFILE_GEN_CFLAGS +IMPLIB +FILTER +ASFLAGS +AR_FLAGS +DEFINES +MACOSX_DEPLOYMENT_TARGET +OS_TEST +OS_RELEASE +OS_ARCH +OS_TARGET +DSO_LDOPTS +DSO_CFLAGS +MKSHLIB +WRAP_LDFLAGS +ASM_SUFFIX +DLL_SUFFIX +LIB_SUFFIX +OBJ_SUFFIX +CPU_ARCH +PR_MD_ARCH_DIR +PR_MD_ASFILES +PR_MD_CSRCS +MDCPUCFG_H +NSPR_MODNAME +MOD_PATCH_VERSION +MOD_MINOR_VERSION +MOD_MAJOR_VERSION +LIBPLC +LIBNSPR +USE_NSPR_THREADS +USE_USER_PTHREADS +USE_BTHREADS +USE_PTHREADS +ENABLE_STRIP +OBJECT_MODE +USE_64 +USE_X32 +USE_N32 +USE_IPV6 +USE_CPLUS +MOZ_DEBUG_SYMBOLS +MOZ_DEBUG +MOZ_OPTIMIZE +CROSS_COMPILE +MSC_VER +GCC_USE_GNU_LD +GNU_CC +HOST_LDFLAGS +HOST_CFLAGS +MOZILLA_CLIENT +SHELL_OVERRIDE +CCACHE +EGREP +GREP +PERL +CPP +HOST_CC +WINDRES +STRIP +LD +AS +AR +RANLIB +ac_ct_CXX +CXXFLAGS +CXX +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +WHOAMI +dist_libdir +dist_includedir +dist_bindir +dist_prefix +CC +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_android_ndk +with_android_toolchain +with_android_version +with_android_platform +with_gonk +with_dist_prefix +with_dist_bindir +with_dist_includedir +with_dist_libdir +with_mozilla +enable_optimize +enable_debug +enable_debug_symbols +enable_win32_target +enable_symbian_target +enable_debug_rtl +enable_static_rtl +enable_n32 +enable_x32 +enable_64bit +enable_mdupdate +enable_cplus +with_arm_kuser +with_macos_sdk +enable_macos_target +enable_os2_high_mem +enable_thumb2 +with_thumb +with_thumb_interwork +with_arch +with_fpu +with_float_abi +with_soft_float +with_symbian_sdk +with_ccache +enable_strip +with_pthreads +enable_user_pthreads +enable_nspr_threads +with_bthreads +enable_ipv6 +enable_wrap_malloc +with_wrap_malloc +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-optimize=OPT Enable code optimizations (ie. -O2) + --enable-debug=DBG Enable debugging (using compiler flags DBG) + --enable-debug-symbols=DBG Enable debugging symbols + (using compiler flags DBG) + --enable-win32-target=\$t + Specify win32 flavor. (WIN95 or WINNT) + --enable-symbian-target=\$t + Specify symbian flavor. (WINSCW or GCCE) + --enable-debug-rtl Use the MSVC debug runtime library + --enable-static-rtl Use the MSVC static runtime library + --enable-n32 Enable n32 ABI support (IRIX only) + --enable-x32 Enable x32 ABI support (x86_64 only) + --enable-64bit Enable 64-bit support (on certain platforms) + --enable-mdupdate Enable use of certain compilers' mdupdate feature + --enable-cplus Enable some c++ api routines + --enable-macos-target=VER + Set the minimum MacOS version needed at runtime + 10.2 for ppc, 10.4 for x86 + --disable-os2-high-mem Disable high-memory support on OS/2 + + --enable-strip Enable stripping of shared libs and programs + --enable-user-pthreads Build using userland pthreads + --enable-nspr-threads Build using classic nspr threads + --enable-ipv6 Compile ipv6 support + --enable-wrap-malloc Wrap malloc calls (gnu linker only) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-android-ndk=DIR + location where the Android NDK can be found + --with-android-toolchain=DIR + location of the Android toolchain + --with-android-version=VER + Android platform version, default 5 for arm, 9 for x86/mips + --with-android-platform=DIR + location of platform dir + --with-gonk=DIR location of gonk dir + --with-dist-prefix=DIST_PREFIX + place build files in DIST_PREFIX dist + --with-dist-bindir=DIR build execuatables in DIR DIST_PREFIX/bin + --with-dist-includedir=DIR + build include files in DIR DIST_PREFIX/include/nspr + --with-dist-libdir=DIR build library files in DIR DIST_PREFIX/lib + --with-mozilla Compile NSPR with Mozilla support + --with-arm-kuser Use kuser helpers (Linux/ARM only) + (Requires kernel 2.6.13 or later) + --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only) + --with-thumb[=yes|no|toolchain-default] + Use Thumb instruction set (-mthumb) + --with-thumb-interwork[=yes|no|toolchain-default] + Use Thumb/ARM instuctions interwork (-mthumb-interwork) + --with-arch=[type|toolchain-default] + Use specific CPU features (-march=type) + --with-fpu=[type|toolchain-default] + Use specific FPU type (-mfpu=type) + --with-float-abi=[type|toolchain-default] + Use specific arm float ABI (-mfloat-abi=type) + --with-soft-float[=yes|no|toolchain-default] + Use soft float library (-msoft-float) + --with-symbian-sdk=SYMBIAN_SDK_DIR + The path to the Symbian SDK + --with-ccache=path/to/ccache + Enable compiling with ccache + --with-pthreads Use system pthreads library as thread subsystem + --with-bthreads Use system bthreads library as thread subsystem + (BeOS only) + --with-wrap-malloc=SHAREDLIB Location of malloc wrapper library + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_aux_dir= +for ac_dir in ${srcdir}/build/autoconf "$srcdir"/${srcdir}/build/autoconf; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in ${srcdir}/build/autoconf \"$srcdir\"/${srcdir}/build/autoconf" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +MOD_MAJOR_VERSION=4 +MOD_MINOR_VERSION=10 +MOD_PATCH_VERSION=7 +NSPR_MODNAME=nspr20 +_HAVE_PTHREADS= +USE_PTHREADS= +USE_USER_PTHREADS= +USE_NSPR_THREADS= +USE_N32= +USE_X32= +USE_64= +USE_CPLUS= +USE_IPV6= +USE_MDUPDATE= +_MACOSX_DEPLOYMENT_TARGET= +_OPTIMIZE_FLAGS=-O +_DEBUG_FLAGS=-g +MOZ_DEBUG=1 +MOZ_OPTIMIZE= +OBJDIR='$(OBJDIR_NAME)' +OBJDIR_NAME=. +OBJDIR_SUFFIX=OBJ +NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall' +NOSUCHFILE=/no-such-file +LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)' +LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)' +CYGWIN_WRAPPER= +MACOS_SDK_DIR= +NEXT_ROOT= +MT= +MOZ_OS2_HIGH_MEMORY=1 +PROFILE_GEN_CFLAGS= +PROFILE_GEN_LDFLAGS= +PROFILE_USE_CFLAGS= +PROFILE_USE_LDFLAGS= + +RESOLVE_LINK_SYMBOLS= + +CFLAGS="${CFLAGS=}" +CXXFLAGS="${CXXFLAGS=}" +LDFLAGS="${LDFLAGS=}" +DLLFLAGS="${DLLFLAGS=}" +HOST_CFLAGS="${HOST_CFLAGS=}" +HOST_LDFLAGS="${HOST_LDFLAGS=}" + +case "$target" in +*-cygwin*|*-mingw*|*-msys*) + # Check to see if we are really running in a msvc environemnt + _WIN32_MSVC= + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break +done + + cat > conftest.c </dev/null | grep COMPILER) +EOF + if test -n "$dummy"; then + _WIN32_MSVC=1 + CXX=$CC + fi + rm -f conftest.c + ;; +*-mks*) + _WIN32_MSVC=1 + ;; +esac + +if test -n "$_WIN32_MSVC"; then + SKIP_PATH_CHECKS=1 + SKIP_COMPILER_CHECKS=1 + SKIP_LIBRARY_CHECKS=1 +fi + + + +# Check whether --with-android-ndk was given. +if test "${with_android_ndk+set}" = set; then : + withval=$with_android_ndk; android_ndk=$withval +fi + + + +# Check whether --with-android-toolchain was given. +if test "${with_android_toolchain+set}" = set; then : + withval=$with_android_toolchain; android_toolchain=$withval +fi + + +case "$target_cpu" in +arm) + android_version=5 + ;; +i?86|mipsel) + android_version=9 + ;; +esac + + +# Check whether --with-android-version was given. +if test "${with_android_version+set}" = set; then : + withval=$with_android_version; android_version=$withval +fi + + + +# Check whether --with-android-platform was given. +if test "${with_android_platform+set}" = set; then : + withval=$with_android_platform; android_platform=$withval +fi + + +case "$target" in +arm-linux*-android*|*-linuxandroid*) + android_tool_prefix="arm-linux-androideabi" + ;; +i?86-*android*) + android_tool_prefix="i686-linux-android" + ;; +mipsel-*android*) + android_tool_prefix="mipsel-linux-android" + ;; +*) + android_tool_prefix="$target_os" + ;; +esac + + + +# Check whether --with-gonk was given. +if test "${with_gonk+set}" = set; then : + withval=$with_gonk; gonkdir=$withval +fi + + +if test -n "$gonkdir" ; then + + if test -z "$HOST_CPPFLAGS" ; then + HOST_CPPFLAGS=" " + fi + if test -z "$HOST_CFLAGS" ; then + HOST_CFLAGS=" " + fi + if test -z "$HOST_CXXFLAGS" ; then + HOST_CXXFLAGS=" " + fi + if test -z "$HOST_LDFLAGS" ; then + HOST_LDFLAGS=" " + fi + + $as_echo "#define ANDROID 1" >>confdefs.h + +else +case "$target" in +*-android*|*-linuxandroid*) + if test -z "$android_ndk" ; then + as_fn_error $? "You must specify --with-android-ndk=/path/to/ndk when targeting Android." "$LINENO" 5 + fi + + if test -z "$android_toolchain" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for android toolchain directory" >&5 +$as_echo_n "checking for android toolchain directory... " >&6; } + + kernel_name=`uname -s | tr "[:upper:]" "[:lower:]"` + + case "$target_cpu" in + arm) + target_name=arm-linux-androideabi-4.4.3 + ;; + i?86) + target_name=x86-4.4.3 + ;; + mipsel) + target_name=mipsel-linux-android-4.4.3 + ;; + esac + android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86 + + if test -d "$android_toolchain" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $android_toolchain" >&5 +$as_echo "$android_toolchain" >&6; } + else + as_fn_error $? "not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain." "$LINENO" 5 + fi + fi + + if test -z "$android_platform" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for android platform directory" >&5 +$as_echo_n "checking for android platform directory... " >&6; } + + case "$target_cpu" in + arm) + target_name=arm + ;; + i?86) + target_name=x86 + ;; + mipsel) + target_name=mips + ;; + esac + + android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name" + + if test -d "$android_platform" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $android_platform" >&5 +$as_echo "$android_platform" >&6; } + else + as_fn_error $? "not found. You have to specify --with-android-platform=/path/to/ndk/platform." "$LINENO" 5 + fi + fi + + case "$target_cpu" in + i?86) + if ! test -e "$android_toolchain"/bin/"$android_tool_prefix"-gcc; then + android_tool_prefix="i686-android-linux" + fi + ;; + esac + + AS="$android_toolchain"/bin/"$android_tool_prefix"-as + CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc + CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++ + CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp + LD="$android_toolchain"/bin/"$android_tool_prefix"-ld + AR="$android_toolchain"/bin/"$android_tool_prefix"-ar + RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib + STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip + + CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS" + CFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CFLAGS" + CXXFLAGS="-mandroid -I$android_platform/usr/include -fpic -fno-short-enums -fno-exceptions $CXXFLAGS" + LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform $LDFLAGS" + + if test -z "$HOST_CPPFLAGS" ; then + HOST_CPPFLAGS=" " + fi + if test -z "$HOST_CFLAGS" ; then + HOST_CFLAGS=" " + fi + if test -z "$HOST_CXXFLAGS" ; then + HOST_CXXFLAGS=" " + fi + if test -z "$HOST_LDFLAGS" ; then + HOST_LDFLAGS=" " + fi + + $as_echo "#define ANDROID 1" >>confdefs.h + + ;; +esac +fi + +dist_prefix='${MOD_DEPTH}/dist' +dist_bindir='${dist_prefix}/bin' +dist_includedir='${dist_prefix}/include/nspr' +dist_libdir='${dist_prefix}/lib' +if test "${includedir}" = '${prefix}/include'; then + includedir='${prefix}/include/nspr' +fi + + +# Check whether --with-dist-prefix was given. +if test "${with_dist_prefix+set}" = set; then : + withval=$with_dist_prefix; dist_prefix=$withval +fi + + + +# Check whether --with-dist-bindir was given. +if test "${with_dist_bindir+set}" = set; then : + withval=$with_dist_bindir; dist_bindir=$withval +fi + + + +# Check whether --with-dist-includedir was given. +if test "${with_dist_includedir+set}" = set; then : + withval=$with_dist_includedir; dist_includedir=$withval +fi + + + +# Check whether --with-dist-libdir was given. +if test "${with_dist_libdir+set}" = set; then : + withval=$with_dist_libdir; dist_libdir=$withval +fi + + + + + + + + +# Check whether --with-mozilla was given. +if test "${with_mozilla+set}" = set; then : + withval=$with_mozilla; if test "$withval" = "yes"; then + $as_echo "#define MOZILLA_CLIENT 1" >>confdefs.h + + MOZILLA_CLIENT=1 + else + MOZILLA_CLIENT= + fi +else + if test -n "$MOZILLA_CLIENT"; then + $as_echo "#define MOZILLA_CLIENT 1" >>confdefs.h + + fi +fi + + +# Check whether --enable-optimize was given. +if test "${enable_optimize+set}" = set; then : + enableval=$enable_optimize; if test "$enableval" != "no"; then + MOZ_OPTIMIZE=1 + if test -n "$enableval" -a "$enableval" != "yes"; then + _OPTIMIZE_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` + _SAVE_OPTIMIZE_FLAGS=$_OPTIMIZE_FLAGS + fi + else + MOZ_OPTIMIZE= + fi +fi + + +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; if test "$enableval" != "no"; then + MOZ_DEBUG=1 + MOZ_DEBUG_SYMBOLS=1 + if test -n "$enableval" -a "$enableval" != "yes"; then + _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` + _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS + fi + else + MOZ_DEBUG= + fi +else + MOZ_DEBUG_SYMBOLS=1 +fi + + +# Check whether --enable-debug-symbols was given. +if test "${enable_debug_symbols+set}" = set; then : + enableval=$enable_debug_symbols; if test "$enableval" != "no"; then + MOZ_DEBUG_SYMBOLS=1 + if test -n "$enableval" -a "$enableval" != "yes"; then + if test -z "$_SAVE_DEBUG_FLAGS"; then + _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` + _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS + else + as_fn_error $? "--enable-debug-symbols flags cannot be used with --enable-debug flags" "$LINENO" 5 + fi + fi + else + MOZ_DEBUG_SYMBOLS= + fi +fi + + +# Check whether --enable-win32-target was given. +if test "${enable_win32_target+set}" = set; then : + enableval=$enable_win32_target; OS_TARGET=`echo $enableval | tr a-z A-Z` +fi + + +# Check whether --enable-symbian-target was given. +if test "${enable_symbian_target+set}" = set; then : + enableval=$enable_symbian_target; OS_TARGET=`echo $enableval | tr a-z A-Z` +fi + + +# Check whether --enable-debug-rtl was given. +if test "${enable_debug_rtl+set}" = set; then : + enableval=$enable_debug_rtl; if test "$enableval" = "yes"; then + USE_DEBUG_RTL=1 + else + USE_DEBUG_RTL=0 + fi +fi + + +# Check whether --enable-static-rtl was given. +if test "${enable_static_rtl+set}" = set; then : + enableval=$enable_static_rtl; if test "$enableval" = "yes"; then + USE_STATIC_RTL=1 + fi +fi + + +# Check whether --enable-n32 was given. +if test "${enable_n32+set}" = set; then : + enableval=$enable_n32; if test "$enableval" = "yes"; then + USE_N32=1 + else if test "$enableval" = "no"; then + USE_N32= + fi + fi +fi + + +# Check whether --enable-x32 was given. +if test "${enable_x32+set}" = set; then : + enableval=$enable_x32; if test "$enableval" = "yes"; then + USE_X32=1 + else if test "$enableval" = "no"; then + USE_X32= + fi + fi +fi + + +# Check whether --enable-64bit was given. +if test "${enable_64bit+set}" = set; then : + enableval=$enable_64bit; if test "$enableval" = "yes"; then + USE_64=1 + fi +fi + + +# Check whether --enable-mdupdate was given. +if test "${enable_mdupdate+set}" = set; then : + enableval=$enable_mdupdate; if test "$enableval" = "yes"; then + USE_MDUPDATE=1 + fi +fi + + +# Check whether --enable-cplus was given. +if test "${enable_cplus+set}" = set; then : + enableval=$enable_cplus; if test "$enableval" = "yes"; then + USE_CPLUS=1 + fi +fi + + + +# Check whether --with-arm-kuser was given. +if test "${with_arm_kuser+set}" = set; then : + withval=$with_arm_kuser; if test "$withval" = "yes"; then + $as_echo "#define _PR_ARM_KUSER 1" >>confdefs.h + + fi +fi + + + +# Check whether --with-macos-sdk was given. +if test "${with_macos_sdk+set}" = set; then : + withval=$with_macos_sdk; MACOS_SDK_DIR=$withval +fi + + +# Check whether --enable-macos-target was given. +if test "${enable_macos_target+set}" = set; then : + enableval=$enable_macos_target; _MACOSX_DEPLOYMENT_TARGET=$enableval +fi + + +case "$target" in + +*-aix*) + case "${target_os}" in + aix3.2*) + USE_NSPR_THREADS=1 + ;; + *) + USE_PTHREADS=1 + ;; + esac + ;; + +esac + +if test -z "$CC"; then + case "$target" in + + *-aix*) + if test -z "$USE_NSPR_THREADS"; then + CC=xlc_r + else + CC=xlc + fi + ;; + + *-hpux*) + CC=cc + ;; + + *-irix*) + CC=cc + ;; + + *-osf*) + CC=cc + ;; + + *-solaris*) + CC=cc + ;; + + esac +fi + +if test -z "$CXX"; then + case "$target" in + + *-aix*) + if test -z "$USE_NSPR_THREADS"; then + CXX=xlC_r + else + CXX=xlC + fi + ;; + + *-hpux*) + case "${target_os}" in + hpux10.30) + CXX=aCC + ;; + hpux11.*) + CXX=aCC + ;; + *) + CXX=CC + ;; + esac + ;; + + *-irix*) + CXX=CC + ;; + + *-osf*) + CXX=cxx + ;; + + *-solaris*) + CXX=CC + ;; + + esac +fi + +if test -z "$SKIP_PATH_CHECKS"; then + # Extract the first word of "$WHOAMI whoami", so it can be a program name with args. +set dummy $WHOAMI whoami; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_WHOAMI+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $WHOAMI in + [\\/]* | ?:[\\/]*) + ac_cv_path_WHOAMI="$WHOAMI" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_WHOAMI="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_WHOAMI" && ac_cv_path_WHOAMI="echo not_whoami" + ;; +esac +fi +WHOAMI=$ac_cv_path_WHOAMI +if test -n "$WHOAMI"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WHOAMI" >&5 +$as_echo "$WHOAMI" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi + +if test -n "$MOZ_DEBUG"; then + $as_echo "#define DEBUG 1" >>confdefs.h + + DEFINES="$DEFINES -UNDEBUG" + + case "${target_os}" in + beos*) + DEFINES="$DEFINES -DDEBUG_${USER}" + ;; + mks*|cygwin*|mingw*|msys*|os2*) + DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`" + ;; + *) + DEFINES="$DEFINES -DDEBUG_`$WHOAMI`" + ;; + esac +else + $as_echo "#define NDEBUG 1" >>confdefs.h + + DEFINES="$DEFINES -UDEBUG" +fi + +if test -z "$SKIP_COMPILER_CHECKS"; then +if test "$target" != "$host"; then + echo "cross compiling from $host to $target" + cross_compiling=yes + + case "$build:$target" in + powerpc-apple-darwin8*:i?86-apple-darwin*) + _SAVE_CFLAGS=$CFLAGS + _SAVE_CXXFLAGS=$CXXFLAGS + CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CFLAGS" + CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS" + ;; + *:arm*-apple-darwin*) + _SAVE_CFLAGS=$CFLAGS + _SAVE_CXXFLAGS=$CXXFLAGS + CFLAGS="-isysroot $MACOS_SDK_DIR $CFLAGS" + CXXFLAGS="-isysroot $MACOS_SDK_DIR $CXXFLAGS" + ;; + esac + + for ac_prog in $CC "${target_alias}-gcc" "${target}-gcc" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break +done +test -n "$CC" || CC="echo" + + unset ac_cv_prog_CC + fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +if test "$target" != "$host"; then + if test -n "$USE_CPLUS"; then + for ac_prog in $CXX "${target_alias}-g++" "${target}-g++" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break +done +test -n "$CXX" || CXX="echo" + + unset ac_cv_prog_CXX + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + fi + + case "$build:$target" in + powerpc-apple-darwin8*:i?86-apple-darwin*|*:arm*-apple-darwin*) + CFLAGS=$_SAVE_CFLAGS + CXXFLAGS=$_SAVE_CXXFLAGS + ;; + esac + + for ac_prog in $RANLIB "${target_alias}-ranlib" "${target}-ranlib" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$RANLIB" && break +done +test -n "$RANLIB" || RANLIB="echo" + + for ac_prog in $AR "${target_alias}-ar" "${target}-ar" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break +done +test -n "$AR" || AR="echo" + + for ac_prog in $AS "${target_alias}-as" "${target}-as" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AS" && break +done +test -n "$AS" || AS="echo" + + for ac_prog in $LD "${target_alias}-ld" "${target}-ld" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LD"; then + ac_cv_prog_LD="$LD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LD="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LD=$ac_cv_prog_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$LD" && break +done +test -n "$LD" || LD="echo" + + for ac_prog in $STRIP "${target_alias}-strip" "${target}-strip" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$STRIP" && break +done +test -n "$STRIP" || STRIP="echo" + + for ac_prog in $WINDRES "${target_alias}-windres" "${target}-windres" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$WINDRES"; then + ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_WINDRES="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +WINDRES=$ac_cv_prog_WINDRES +if test -n "$WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 +$as_echo "$WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$WINDRES" && break +done +test -n "$WINDRES" || WINDRES="echo" + + + _SAVE_CC="$CC" + _SAVE_CFLAGS="$CFLAGS" + _SAVE_LDFLAGS="$LDFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $host compiler" >&5 +$as_echo_n "checking for $host compiler... " >&6; } + for ac_prog in $HOST_CC gcc cc /usr/ucb/cc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HOST_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HOST_CC"; then + ac_cv_prog_HOST_CC="$HOST_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HOST_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +HOST_CC=$ac_cv_prog_HOST_CC +if test -n "$HOST_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HOST_CC" >&5 +$as_echo "$HOST_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$HOST_CC" && break +done +test -n "$HOST_CC" || HOST_CC="""" + + if test -z "$HOST_CC"; then + as_fn_error $? "no acceptable cc found in \$PATH" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HOST_CC" >&5 +$as_echo "$HOST_CC" >&6; } + if test -z "$HOST_CFLAGS"; then + HOST_CFLAGS="$CFLAGS" + fi + if test -z "$HOST_LDFLAGS"; then + HOST_LDFLAGS="$LDFLAGS" + fi + + CC="$HOST_CC" + CFLAGS="$HOST_CFLAGS" + LDFLAGS="$HOST_LDFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works" >&5 +$as_echo_n "checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works... " >&6; } + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + as_fn_error $? "installation or configuration problem: $host compiler $HOST_CC cannot create executables." "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + CC=$_SAVE_CC + CFLAGS=$_SAVE_CFLAGS + LDFLAGS=$_SAVE_LDFLAGS +else + if test -n "$USE_CPLUS"; then + if test "$CC" = "cl" -a -z "$CXX"; then + CXX=$CC + else + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + fi + fi + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + for ac_prog in as +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $AS in + [\\/]* | ?:[\\/]*) + ac_cv_path_AS="$AS" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_AS="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +AS=$ac_cv_path_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AS" && break +done +test -n "$AS" || AS="$CC" + + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_AR="$AR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +AR=$ac_cv_path_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break +done +test -n "$AR" || AR="echo not_ar" + + for ac_prog in ld link +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LD in + [\\/]* | ?:[\\/]*) + ac_cv_path_LD="$LD" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LD="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +LD=$ac_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$LD" && break +done +test -n "$LD" || LD="echo not_ld" + + for ac_prog in strip +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $STRIP in + [\\/]* | ?:[\\/]*) + ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_STRIP="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +STRIP=$ac_cv_path_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$STRIP" && break +done +test -n "$STRIP" || STRIP="echo not_strip" + + for ac_prog in windres +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $WINDRES in + [\\/]* | ?:[\\/]*) + ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_WINDRES="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +WINDRES=$ac_cv_path_WINDRES +if test -n "$WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 +$as_echo "$WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$WINDRES" && break +done +test -n "$WINDRES" || WINDRES="echo not_windres" + + if test -z "$HOST_CC"; then + HOST_CC="$CC" + fi + if test -z "$HOST_CFLAGS"; then + HOST_CFLAGS="$CFLAGS" + fi +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +if test "$GCC" = "yes"; then + GNU_CC=1 +fi +if test "$GXX" = "yes"; then + GNU_CXX=1 +fi +if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then + GNU_AS=1 +fi +rm -f a.out + +case "$build:$target" in + i?86-apple-darwin*:powerpc-apple-darwin*) + cross_compiling=yes + ;; +esac + +if test "$cross_compiling" = "yes"; then + CROSS_COMPILE=1 +else + CROSS_COMPILE= +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc -pipe support" >&5 +$as_echo_n "checking for gcc -pipe support... " >&6; } +if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then + echo '#include ' > dummy-hello.c + echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c + ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5 + cat dummy-hello.s | ${AS} -o dummy-hello.S - 2>&5 + if test $? = 0; then + _res_as_stdin="yes" + else + _res_as_stdin="no" + fi + if test "$_res_as_stdin" = "yes"; then + _SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -pipe" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main () +{ +printf("Hello World\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + _res_gcc_pipe="yes" +else + _res_gcc_pipe="no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$_SAVE_CFLAGS + fi + if test "$_res_as_stdin" = "yes" && test "$_res_gcc_pipe" = "yes"; then + _res="yes"; + CFLAGS="$CFLAGS -pipe" + CXXFLAGS="$CXXFLAGS -pipe" + else + _res="no" + fi + rm -f dummy-hello.c dummy-hello.s dummy-hello.S dummy-hello a.out + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_res" >&5 +$as_echo "$_res" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +_SAVE_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler supports -fprofile-generate" >&5 +$as_echo_n "checking whether C compiler supports -fprofile-generate... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + PROFILE_GEN_CFLAGS="-fprofile-generate" + result="yes" +else + result="no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5 +$as_echo "$result" >&6; } + +if test $result = "yes"; then + PROFILE_GEN_LDFLAGS="-fprofile-generate" + PROFILE_USE_CFLAGS="-fprofile-use -fprofile-correction -Wcoverage-mismatch" + PROFILE_USE_LDFLAGS="-fprofile-use" +fi + +CFLAGS="$_SAVE_CFLAGS" + +if test "$GNU_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for visibility(hidden) attribute" >&5 +$as_echo_n "checking for visibility(hidden) attribute... " >&6; } +if ${ac_cv_visibility_hidden+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c </dev/null 2>&1; then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + ac_cv_visibility_hidden=yes + fi + fi + rm -f conftest.cs + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_visibility_hidden" >&5 +$as_echo "$ac_cv_visibility_hidden" >&6; } + if test "$ac_cv_visibility_hidden" = "yes"; then + $as_echo "#define HAVE_VISIBILITY_HIDDEN_ATTRIBUTE 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for visibility pragma support" >&5 +$as_echo_n "checking for visibility pragma support... " >&6; } +if ${ac_cv_visibility_pragma+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c </dev/null 2>&1; then + if grep '\.hidden.*foo_hidden' conftest.s >/dev/null; then + if ! grep '\.hidden.*foo_default' conftest.s > /dev/null; then + ac_cv_visibility_pragma=yes + fi + fi + fi + rm -f conftest.cs + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_visibility_pragma" >&5 +$as_echo "$ac_cv_visibility_pragma" >&6; } + if test "$ac_cv_visibility_pragma" = "yes"; then + $as_echo "#define HAVE_VISIBILITY_PRAGMA 1" >>confdefs.h + + # To work around a build problem on Linux x86-64 (Bugzilla bug + # 293438), we use the -fvisibility=hidden flag. This flag is less + # optimal than #pragma GCC visibility push(hidden) because the flag + # assumes that symbols defined outside the current source file have + # the default visibility. This has the advantage that we don't need + # to wrap system header files, but has the disadvantage that calls + # to hidden symbols defined in other source files cannot be + # optimized by the compiler. The -fvisibility=hidden flag does + # hide and export symbols correctly. + #VISIBILITY_FLAGS='-I$(dist_includedir)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' + #WRAP_SYSTEM_INCLUDES=1 + VISIBILITY_FLAGS="-fvisibility=hidden" + WRAP_SYSTEM_INCLUDES= + fi + fi +fi # GNU_CC + +fi # SKIP_COMPILER_CHECKS + +if test -z "$SKIP_PATH_CHECKS"; then + for ac_prog in perl5 perl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PERL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PERL=$ac_cv_path_PERL +if test -n "$PERL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 +$as_echo "$PERL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PERL" && break +done +test -n "$PERL" || PERL="echo not_perl" + +elif test -z "$PERL"; then + PERL=perl +fi + +OBJ_SUFFIX=o +LIB_SUFFIX=a +DLL_SUFFIX=so +ASM_SUFFIX=s +MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@' +PR_MD_ASFILES= +PR_MD_CSRCS= +PR_MD_ARCH_DIR=unix +AR_FLAGS='cr $@' +AS='$(CC)' +ASFLAGS='$(CFLAGS)' + +if test -n "$CROSS_COMPILE"; then + OS_ARCH=`echo $target_os | sed -e 's|/|_|g'` + OS_RELEASE= + OS_TEST="${target_cpu}" + case "${target_os}" in + linux*) OS_ARCH=Linux ;; + solaris*) OS_ARCH=SunOS OS_RELEASE=5 ;; + mingw*) OS_ARCH=WINNT CPU_ARCH=x86 ;; + darwin*) OS_ARCH=Darwin ;; + riscos*) OS_ARCH=RISCOS ;; + esac +else + OS_ARCH=`uname -s | sed -e 's|/|_|g'` + OS_RELEASE=`uname -r` + OS_TEST=`uname -m` +fi + +if test "$OS_ARCH" = "IRIX64"; then + OS_ARCH=IRIX +fi + +if test "$OS_ARCH" = "AIX"; then + OS_RELEASE=`uname -v`.`uname -r` +fi + +if test "$OS_ARCH" = "FreeBSD"; then + OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'` +fi + +if test "$OS_ARCH" = "Linux"; then + OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'` + OS_RELEASE=`echo $OS_RELEASE | awk -F\. '{ print $1 "." $2 }'` +fi + +####################################################################### +# Master "Core Components" macros for getting the OS target # +####################################################################### + +# +# Note: OS_TARGET should be specified on the command line for gmake. +# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built. +# The difference between the Win95 target and the WinNT target is that +# the WinNT target uses Windows NT specific features not available +# in Windows 95. The Win95 target will run on Windows NT, but (supposedly) +# at lesser performance (the Win95 target uses threads; the WinNT target +# uses fibers). +# +# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no +# cross-compilation. +# + +# +# The following hack allows one to build on a WIN95 machine (as if +# s/he were cross-compiling on a WINNT host for a WIN95 target). +# It also accomodates for MKS's uname.exe. If you never intend +# to do development on a WIN95 machine, you don't need this hack. +# +case "$OS_ARCH" in +Windows_95) + OS_ARCH=Windows_NT + OS_TARGET=WIN95 + ;; +Windows_98) + OS_ARCH=Windows_NT + OS_TARGET=WIN95 + ;; +CYGWIN_9*|CYGWIN_ME*) + OS_ARCH='CYGWIN_NT-4.0' + OS_TARGET=WIN95 + ;; +OS_2) + OS_ARCH=OS2 + OS_TARGET=OS2 + ;; +esac + +# +# On WIN32, we also define the variable CPU_ARCH. +# + +case "$OS_ARCH" in +Windows_NT) +# +# If uname -s returns "Windows_NT", we assume that we are using +# the uname.exe in MKS toolkit. +# +# The -r option of MKS uname only returns the major version number. +# So we need to use its -v option to get the minor version number. +# Moreover, it doesn't have the -p option, so we need to use uname -m. +# + OS_ARCH=WINNT + OS_MINOR_RELEASE=`uname -v` + if test "$OS_MINOR_RELEASE" = "00"; then + OS_MINOR_RELEASE=0 + fi + OS_RELEASE="${OS_RELEASE}.${OS_MINOR_RELEASE}" + CPU_ARCH=`uname -m` + # + # MKS's uname -m returns "586" on a Pentium machine. + # + if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then + CPU_ARCH=x86 + fi + ;; +CYGWIN_NT*|MINGW*_NT*|MSYS_NT*) +# +# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using +# the uname.exe in the Cygwin tools. +# If uname -s returns "MINGW32_NT-5.1", we assume that we are using +# the uname.exe in the MSYS tools. +# If uname -s returns "MSYS_NT-6.3", we assume that we are using +# the uname.exe in the MSYS2 tools. +# + OS_RELEASE=`expr $OS_ARCH : '.*NT-\(.*\)'` + OS_ARCH=WINNT + CPU_ARCH=`uname -m` + # + # Cygwin's uname -m returns "i686" on a Pentium Pro machine. + # + if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then + CPU_ARCH=x86 + fi + ;; +esac + +if test -n "$MOZILLA_CLIENT" && test "$OS_ARCH" = "WINNT"; then + OS_TARGET=WIN95 + if test -n "$MOZ_DEBUG" -a -z "$USE_DEBUG_RTL"; then + USE_DEBUG_RTL=1 + fi +fi +if test -z "$OS_TARGET"; then + OS_TARGET=$OS_ARCH +fi +if test "$OS_TARGET" = "WIN95"; then + OS_RELEASE="4.0" +fi +OS_CONFIG="${OS_TARGET}${OS_RELEASE}" + +# Check whether --enable-os2-high-mem was given. +if test "${enable_os2_high_mem+set}" = set; then : + enableval=$enable_os2_high_mem; if test "$enableval" = "no"; then + MOZ_OS2_HIGH_MEMORY= + else + MOZ_OS2_HIGH_MEMORY=1 + fi +fi + + + +MOZ_ALIGN=toolchain-default + +case "$target" in +arm*-android*|arm*-linuxandroid*) + MOZ_THUMB=yes + MOZ_ARCH=armv7-a + MOZ_FPU=vfp + MOZ_FLOAT_ABI=softfp + MOZ_SOFT_FLOAT=yes + MOZ_ALIGN=no + ;; +arm*-*) + if test -n "$MOZ_PLATFORM_MAEMO"; then + MOZ_THUMB=no + MOZ_ARCH=armv7-a + MOZ_FLOAT_ABI=softfp + fi + if test "$MOZ_PLATFORM_MAEMO" = 6; then + MOZ_THUMB=yes + fi + ;; +esac + +# Check whether --enable-thumb2 was given. +if test "${enable_thumb2+set}" = set; then : + enableval=$enable_thumb2; MOZ_THUMB=$enableval +fi + + + +# Check whether --with-thumb was given. +if test "${with_thumb+set}" = set; then : + withval=$with_thumb; if test -z "$GNU_CC"; then + as_fn_error $? "--with-thumb is not supported on non-GNU toolchain-defaults" "$LINENO" 5 + fi + MOZ_THUMB=$withval +fi + + + +# Check whether --with-thumb-interwork was given. +if test "${with_thumb_interwork+set}" = set; then : + withval=$with_thumb_interwork; if test -z "$GNU_CC"; then + as_fn_error $? "--with-thumb-interwork is not supported on non-GNU toolchain-defaults" "$LINENO" 5 + fi + MOZ_THUMB_INTERWORK=$withval +fi + + + +# Check whether --with-arch was given. +if test "${with_arch+set}" = set; then : + withval=$with_arch; if test -z "$GNU_CC"; then + as_fn_error $? "--with-arch is not supported on non-GNU toolchain-defaults" "$LINENO" 5 + fi + MOZ_ARCH=$withval +fi + + + +# Check whether --with-fpu was given. +if test "${with_fpu+set}" = set; then : + withval=$with_fpu; if test -z "$GNU_CC"; then + as_fn_error $? "--with-fpu is not supported on non-GNU toolchain-defaults" "$LINENO" 5 + fi + MOZ_FPU=$withval +fi + + + +# Check whether --with-float-abi was given. +if test "${with_float_abi+set}" = set; then : + withval=$with_float_abi; if test -z "$GNU_CC"; then + as_fn_error $? "--with-float-abi is not supported on non-GNU toolchain-defaults" "$LINENO" 5 + fi + MOZ_FLOAT_ABI=$withval +fi + + + +# Check whether --with-soft-float was given. +if test "${with_soft_float+set}" = set; then : + withval=$with_soft_float; if test -z "$GNU_CC"; then + as_fn_error $? "--with-soft-float is not supported on non-GNU toolchain-defaults" "$LINENO" 5 + fi + MOZ_SOFT_FLOAT=$withval +fi + + +case "$MOZ_ARCH" in +toolchain-default|"") + arch_flag="" + ;; +*) + arch_flag="-march=$MOZ_ARCH" + ;; +esac + +case "$MOZ_THUMB" in +yes) + MOZ_THUMB2=1 + thumb_flag="-mthumb" + ;; +no) + MOZ_THUMB2= + thumb_flag="-marm" + ;; +*) + _SAVE_CFLAGS="$CFLAGS" + CFLAGS="$arch_flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return sizeof(__thumb2__); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + MOZ_THUMB2=1 +else + MOZ_THUMB2= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$_SAVE_CFLAGS" + thumb_flag="" + ;; +esac + +case "$MOZ_THUMB_INTERWORK" in +yes) + thumb_interwork_flag="-mthumb-interwork" + ;; +no) + thumb_interwork_flag="-mno-thumb-interwork" + ;; +*) # toolchain-default + thumb_interwork_flag="" + ;; +esac + +case "$MOZ_FPU" in +toolchain-default|"") + fpu_flag="" + ;; +*) + fpu_flag="-mfpu=$MOZ_FPU" + ;; +esac + +case "$MOZ_FLOAT_ABI" in +toolchain-default|"") + float_abi_flag="" + ;; +*) + float_abi_flag="-mfloat-abi=$MOZ_FLOAT_ABI" + ;; +esac + +case "$MOZ_SOFT_FLOAT" in +yes) + soft_float_flag="-msoft-float" + ;; +no) + soft_float_flag="-mno-soft-float" + ;; +*) # toolchain-default + soft_float_flag="" + ;; +esac + +case "$MOZ_ALIGN" in +toolchain-default|"") + align_flag="" + ;; +no) + align_flag="-mno-unaligned-access" + ;; +yes) + align_flag="-munaligned-access" + ;; +*) + align_flag="" + ;; +esac + +if test -n "$align_flag"; then + _SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $align_flag" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether alignment flag ($align_flag) is supported" >&5 +$as_echo_n "checking whether alignment flag ($align_flag) is supported... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + align_flag="" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$_SAVE_CFLAGS" +fi + +all_flags=`echo $arch_flag $thumb_flag $thumb_interwork_flag $fpu_flag $float_abi_flag $soft_float_flag $align_flag` +if test -n "$all_flags"; then + _SAVE_CFLAGS="$CFLAGS" + CFLAGS="$all_flags" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the chosen combination of compiler flags ($all_flags) works" >&5 +$as_echo_n "checking whether the chosen combination of compiler flags ($all_flags) works... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + as_fn_error $? "no" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + CFLAGS="$_SAVE_CFLAGS $all_flags" + CXXFLAGS="$CXXFLAGS $all_flags" + ASFLAGS="$ASFLAGS $all_flags" + if test -n "$thumb_flag"; then + LDFLAGS="$LDFLAGS $thumb_flag" + fi +fi + +case "$host" in +*-mingw*|*-msys*) + NSINSTALL=nsinstall + ;; +*-cygwin*|*-mks*) + NSINSTALL='$(CYGWIN_WRAPPER) nsinstall' + if test `echo "${PATH}" | grep -c \;` = 0; then + CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper' + fi + ;; +*-beos*) + HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE" + ;; +*os2*) + ;; +*) + HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX" + ;; +esac + +case "$target" in + +*-aix*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define AIX 1" >>confdefs.h + + $as_echo "#define SYSV 1" >>confdefs.h + + DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_fn_c_check_header_mongrel "$LINENO" "sys/atomic_op.h" "ac_cv_header_sys_atomic_op_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_atomic_op_h" = xyes; then : + $as_echo "#define AIX_HAVE_ATOMIC_OP_H 1" >>confdefs.h + +fi + + + case "${target_os}" in + aix3.2*) + $as_echo "#define AIX_RENAME_SELECT 1" >>confdefs.h + + $as_echo "#define _PR_NO_LARGE_FILES 1" >>confdefs.h + + AIX_LINK_OPTS='-bnso -berok' + PR_MD_ASFILES=os_AIX.s + ;; + aix4.1*) + $as_echo "#define AIX_TIMERS 1" >>confdefs.h + + $as_echo "#define _PR_NO_LARGE_FILES 1" >>confdefs.h + + $as_echo "#define AIX4_1 1" >>confdefs.h + + MKSHLIB= + DSO_LDOPTS= + AIX_LINK_OPTS='-bnso -berok' + LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)_shr' + LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)_shr' + ;; + aix4.2*) + $as_echo "#define AIX_TIMERS 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_OFF64_T 1" >>confdefs.h + + AIX_LINK_OPTS='-brtl -bnso -berok' + ;; + aix4.3*) + $as_echo "#define AIX_TIMERS 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_OFF64_T 1" >>confdefs.h + + $as_echo "#define AIX4_3_PLUS 1" >>confdefs.h + + $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h + + $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h + + USE_IPV6=1 + AIX_LINK_OPTS='-brtl -bnso -berok' + ;; + *) + $as_echo "#define AIX_TIMERS 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_OFF64_T 1" >>confdefs.h + + $as_echo "#define AIX4_3_PLUS 1" >>confdefs.h + + $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h + + $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h + + USE_IPV6=1 + AIX_LINK_OPTS='-brtl -bnso -berok' + ;; + esac + CFLAGS="$CFLAGS -qro -qroconst" + AIX_WRAP='$(DIST)/lib/aixwrap.o' + AIX_TMP='./_aix_tmp.o' + if test -n "$USE_64"; then + MDCPUCFG_H=_aix64.cfg + OBJECT_MODE=64 + else + MDCPUCFG_H=_aix32.cfg + fi + PR_MD_CSRCS=aix.c + RESOLVE_LINK_SYMBOLS=1 + ;; + +*-beos*) + $as_echo "#define XP_BEOS 1" >>confdefs.h + + $as_echo "#define BeOS 1" >>confdefs.h + + $as_echo "#define BEOS 1" >>confdefs.h + + $as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + DSO_LDOPTS=-nostart + MDCPUCFG_H=_beos.cfg + USE_BTHREADS=1 + PR_MD_ARCH_DIR=beos + RESOLVE_LINK_SYMBOLS=1 + case "${target_cpu}" in + i*86) + _OPTIMIZE_FLAGS=-O2 + _DEBUG_FLAGS='-gdwarf-2 -O0' + MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@' + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr in -lbind" >&5 +$as_echo_n "checking for gethostbyaddr in -lbind... " >&6; } +if ${ac_cv_lib_bind_gethostbyaddr+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbind $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyaddr (); +int +main () +{ +return gethostbyaddr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_bind_gethostbyaddr=yes +else + ac_cv_lib_bind_gethostbyaddr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_gethostbyaddr" >&5 +$as_echo "$ac_cv_lib_bind_gethostbyaddr" >&6; } +if test "x$ac_cv_lib_bind_gethostbyaddr" = xyes; then : + OS_LIBS="$OS_LIBS -lbind -lsocket" +fi + + ;; + powerpc) + CC=mwcc + CCC=mwcc + LD=mwld + DSO_LDOPTS='-xms -export pragma -init _init_routine_ -term _term_routine_ -lroot -lnet /boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o /boot/develop/lib/ppc/start_dyn.o' + _OPTIMIZE_FLAGS=-O2 + _DEBUG_FLAGS='-g -O0' + ;; + esac + ;; + +*-bsdi*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define BSDI 1" >>confdefs.h + + $as_echo "#define NEED_BSDREGEX 1" >>confdefs.h + + + CFLAGS="$CFLAGS -Wall -Wno-format" + CXXFLAGS="$CXXFLAGS -Wall -Wno-format" + + if echo "$OS_TEST" | grep -c 86 >/dev/null; then + CPU_ARCH=x86 + elif echo "$OS_TEST" | grep -c sparc >/dev/null; then + CPU_ARCH=sparc + fi + + MDCPUCFG_H=_bsdi.cfg + PR_MD_CSRCS=bsdi.c + + DSO_LDOPTS=-r + + case "$target_os" in + bsdi1.1*) + $as_echo "#define _PR_BSDI_JMPBUF_IS_ARRAY 1" >>confdefs.h + + $as_echo "#define _PR_STAT_HAS_ONLY_ST_ATIME 1" >>confdefs.h + + $as_echo "#define _PR_NEED_H_ERRNO 1" >>confdefs.h + + MKSHLIB= + DSO_CFLAGS= + DSO_LDOPTS= + ;; + + bsdi2.1*) + $as_echo "#define _PR_TIMESPEC_HAS_TS_SEC 1" >>confdefs.h + + $as_echo "#define _PR_BSDI_JMPBUF_IS_ARRAY 1" >>confdefs.h + + $as_echo "#define HAVE_DLL 1" >>confdefs.h + + $as_echo "#define USE_DLFCN 1" >>confdefs.h + + $as_echo "#define _PR_STAT_HAS_ST_ATIMESPEC 1" >>confdefs.h + + PR_MD_ASFILES=os_BSD_OS_386_2.s + ;; + + bsdi4.* | bsdi5.*) + $as_echo "#define _PR_SELECT_CONST_TIMEVAL 1" >>confdefs.h + + $as_echo "#define _PR_BSDI_JMPBUF_IS_STRUCT 1" >>confdefs.h + + $as_echo "#define HAVE_DLL 1" >>confdefs.h + + $as_echo "#define USE_DLFCN 1" >>confdefs.h + + $as_echo "#define _PR_STAT_HAS_ST_ATIMESPEC 1" >>confdefs.h + + MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)' + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-shared -Wl,-soname,$(@:$(OBJDIR)/%.so=%.so)' + STRIP="$STRIP -d" + case "$target_os" in + bsdi4.2* | bsdi4.3* | bsdi5.*) + $as_echo "#define _PR_HAVE_GETPROTO_R 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_GETPROTO_R_POINTER 1" >>confdefs.h + + ;; + esac + ;; + *) + $as_echo "#define _PR_SELECT_CONST_TIMEVAL 1" >>confdefs.h + + $as_echo "#define _PR_BSDI_JMPBUF_IS_STRUCT 1" >>confdefs.h + + $as_echo "#define HAVE_DLL 1" >>confdefs.h + + $as_echo "#define USE_DLFCN 1" >>confdefs.h + + $as_echo "#define _PR_STAT_HAS_ST_ATIMESPEC 1" >>confdefs.h + + ;; + esac + + ;; + +*-darwin*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define DARWIN 1" >>confdefs.h + + $as_echo "#define HAVE_BSD_FLOCK 1" >>confdefs.h + + $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h + + AS='$(CC) -x assembler-with-cpp' + CFLAGS="$CFLAGS -Wall -fno-common" + case "${target_cpu}" in + arm*) + CPU_ARCH=arm + ;; + i*86*|x86_64) + if test -n "$USE_64"; then + CPU_ARCH=x86_64 + else + CPU_ARCH=i386 + fi + ;; + *) + CPU_ARCH=ppc + ;; + esac + if test "`echo $CC | grep -c '\-arch '`" = "0"; then + CC="$CC -arch $CPU_ARCH" + fi + ac_fn_c_check_header_mongrel "$LINENO" "crt_externs.h" "ac_cv_header_crt_externs_h" "$ac_includes_default" +if test "x$ac_cv_header_crt_externs_h" = xyes; then : + +fi + + + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names' + _OPTIMIZE_FLAGS=-O2 + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + STRIP="$STRIP -x -S" + DLL_SUFFIX=dylib + USE_PTHREADS=1 + MDCPUCFG_H=_darwin.cfg + PR_MD_CSRCS=darwin.c + PR_MD_ASFILES=os_Darwin.s + + # Add Mac OS X support for loading CFM & CFBundle plugins + if test -f "${MACOS_SDK_DIR}/System/Library/Frameworks/Carbon.framework/Carbon"; then + $as_echo "#define XP_MACOSX 1" >>confdefs.h + + OS_TARGET=MacOSX + + if test -n "$_MACOSX_DEPLOYMENT_TARGET" ; then + export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET + elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then + case "${target_cpu}" in + powerpc*) + export MACOSX_DEPLOYMENT_TARGET=10.2 + ;; + i*86*) + export MACOSX_DEPLOYMENT_TARGET=10.4 + ;; + esac + fi + + + if test "$MACOS_SDK_DIR"; then + + if test ! -d "$MACOS_SDK_DIR"; then + as_fn_error $? "SDK not found. When using --with-macos-sdk, you must +specify a valid SDK. SDKs are installed when the optional cross-development +tools are selected during the Xcode/Developer Tools installation." "$LINENO" 5 + fi + + + CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'` + GCC_VERSION_FULL=`echo $CC_VERSION | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'` + GCC_VERSION=`echo $GCC_VERSION_FULL | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'` + + GCC_VERSION_MAJOR=`echo $GCC_VERSION_FULL | $PERL -pe 's/(^\d*).*/$1/;'` + if test "$GCC_VERSION_MAJOR" -lt "4" ; then + SDK_C_FRAMEWORK="-F${MACOS_SDK_DIR}/System/Library/Frameworks" + if test -d "${MACOS_SDK_DIR}/Library/Frameworks" ; then + SDK_C_FRAMEWORK="$SDK_C_FRAMEWORK -F${MACOS_SDK_DIR}/Library/Frameworks" + fi + + SDK_C_INCLUDE="-isystem ${MACOS_SDK_DIR}/usr/include/gcc/darwin/${GCC_VERSION} -isystem ${MACOS_SDK_DIR}/usr/include ${SDK_C_FRAMEWORK}" + + CFLAGS="$CFLAGS -nostdinc ${SDK_C_INCLUDE}" + + CPP="$CPP -nostdinc ${SDK_C_INCLUDE}" + + + HOST_DARWIN_MAJOR=`echo "$build_os" | sed -E -e 's/^darwin([0-9]+).*$/\1/'` + + if test "$HOST_DARWIN_MAJOR" -lt 9 ; then + MACOS_SDK_LIBS="-L${MACOS_SDK_DIR}/usr/lib/gcc/darwin -L${MACOS_SDK_DIR}/usr/lib/gcc/darwin/${GCC_VERSION_FULL} -L${MACOS_SDK_DIR}/usr/lib ${SDK_C_FRAMEWORK}" + else + MACOS_SDK_LIBS="-Wl,-syslibroot,${MACOS_SDK_DIR}" + fi + + LDFLAGS="${MACOS_SDK_LIBS} $LDFLAGS" + export NEXT_ROOT=$MACOS_SDK_DIR + + if test -n "$CROSS_COMPILE" ; then + HOST_CC="NEXT_ROOT= $HOST_CC" + HOST_CXX="NEXT_ROOT= $HOST_CXX" + fi + else + CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}" + + CPP="$CPP -isysroot ${MACOS_SDK_DIR}" + + if test "$GCC_VERSION_FULL" != "4.0.0" ; then + LDFLAGS="$LDFLAGS -isysroot ${MACOS_SDK_DIR}" + else + LDFLAGS="$LDFLAGS -Wl,-syslibroot,${MACOS_SDK_DIR}" + fi + fi + fi + fi + ;; + +*-dgux*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define _PR_LOCAL_THREADS_ONLY 1" >>confdefs.h + + $as_echo "#define SVR4 1" >>confdefs.h + + $as_echo "#define SYSV 1" >>confdefs.h + + $as_echo "#define DGUX 1" >>confdefs.h + + $as_echo "#define _DGUX_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX4A_DRAFT6_SOURCE 1" >>confdefs.h + + DSO_LDOPTS=-G + _OPTIMIZE_FLAGS=-O2 + _DEBUG_FLAGS= + MDCPUCFG_H=_dgux.cfg + PR_MD_CSRCS=dgux.c + ;; + +*-freebsd*) + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + fi + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define FREEBSD 1" >>confdefs.h + + $as_echo "#define HAVE_BSD_FLOCK 1" >>confdefs.h + + $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h + + CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall" + MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf` + if test "$MOZ_OBJFORMAT" = "elf"; then + DLL_SUFFIX=so + else + DLL_SUFFIX=so.1.0 + fi + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' + MDCPUCFG_H=_freebsd.cfg + PR_MD_CSRCS=freebsd.c + ;; + +*-hpux*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define HPUX 1" >>confdefs.h + + $as_echo "#define _HPUX_SOURCE 1" >>confdefs.h + + # OSF1 and HPUX report the POLLHUP event for a socket when the + # shutdown(SHUT_WR) operation is called for the remote end, even though + # the socket is still writeable. Use select(), instead of poll(), to + # workaround this problem. + $as_echo "#define _PR_POLL_WITH_SELECT 1" >>confdefs.h + + $as_echo "#define _USE_BIG_FDS 1" >>confdefs.h + + DSO_LDOPTS='-b +h $(notdir $@)' + PR_MD_CSRCS=hpux.c + if test "$OS_TEST" = "ia64"; then + DLL_SUFFIX=so + DSO_LDOPTS="$DSO_LDOPTS +b '\$\$ORIGIN'" + CPU_ARCH_TAG=_$OS_TEST + if test -z "$USE_64"; then + COMPILER_TAG=_32 + fi + PR_MD_ASFILES=os_HPUX_ia64.s + else + $as_echo "#define hppa 1" >>confdefs.h + + DLL_SUFFIX=sl + PR_MD_ASFILES=os_HPUX.s + fi + if test -n "$USE_64"; then + MDCPUCFG_H=_hpux64.cfg + else + MDCPUCFG_H=_hpux32.cfg + fi + if test -z "$GNU_CC"; then + CC="$CC -Ae" + CXX="$CXX -ext" + DSO_CFLAGS=+Z + else + DSO_CFLAGS=-fPIC + ASFLAGS="$ASFLAGS -x assembler-with-cpp" + fi + + if test -n "$MOZILLA_CLIENT"; then + DEFAULT_IMPL_STRATEGY=_EMU + fi + + if echo "$OS_RELEASE" | grep ^A.09 >/dev/null; then + $as_echo "#define _PR_NEED_H_ERRNO 1" >>confdefs.h + + $as_echo "#define HPUX9 1" >>confdefs.h + + DEFAULT_IMPL_STRATEGY=_EMU + USE_NSPR_THREADS=1 + fi + + if echo "$OS_RELEASE" | egrep '^(A.09|B.10)' >/dev/null; then + $as_echo "#define _PR_NO_LARGE_FILES 1" >>confdefs.h + + fi + + if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then + $as_echo "#define _PR_NEED_H_ERRNO 1" >>confdefs.h + + fi + + if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then + $as_echo "#define HAVE_INT_LOCALTIME_R 1" >>confdefs.h + + fi + + if echo "$OS_RELEASE" | egrep '^(B.10.30|B.11)' >/dev/null; then + $as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h + + fi + + # HP-UX 11i v2 (B.11.23) or higher + + case "$OS_RELEASE" in + [C-Z]*|B.[2-9]*|B.1[2-9]*|B.11.[3-9]*|B.11.2[3-9]*) + USE_IPV6=1 + ;; + esac + + + if test "$OS_RELEASE" = "B.10.01"; then + $as_echo "#define HPUX10 1" >>confdefs.h + + DEFAULT_IMPL_STRATEGY=_EMU + fi + + if test "$OS_RELEASE" = "B.10.10"; then + $as_echo "#define HPUX10 1" >>confdefs.h + + $as_echo "#define HPUX10_10 1" >>confdefs.h + + DEFAULT_IMPL_STRATEGY=_PTH + fi + + if test "$OS_RELEASE" = "B.10.20"; then + $as_echo "#define HPUX10 1" >>confdefs.h + + $as_echo "#define HPUX10_20 1" >>confdefs.h + + if test -z "$GNU_CC"; then + CFLAGS="$CFLAGS +DAportable +DS1.1" + CXXFLAGS="$CXXFLAGS +DAportable +DS1.1" + fi + DEFAULT_IMPL_STRATEGY=_PTH + fi + + if test "$OS_RELEASE" = "B.10.30"; then + $as_echo "#define HPUX10 1" >>confdefs.h + + $as_echo "#define HPUX10_30 1" >>confdefs.h + + if test -z "$GNU_CC"; then + CFLAGS="$CFLAGS +DAportable +DS1.1" + CXXFLAGS="$CXXFLAGS +DAportable +DS1.1" + fi + DEFAULT_IMPL_STRATEGY=_PTH + fi + + if echo "$OS_RELEASE" | grep ^B.11 >/dev/null; then + $as_echo "#define HPUX10 1" >>confdefs.h + + $as_echo "#define HPUX11 1" >>confdefs.h + + $as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_OFF64_T 1" >>confdefs.h + + $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h + + if test -z "$GNU_CC"; then + if test -z "$USE_64"; then + if test "$OS_TEST" = "ia64"; then + CFLAGS="$CFLAGS +DD32" + CXXFLAGS="$CXXFLAGS +DD32" + else + CFLAGS="$CFLAGS +DAportable +DS2.0" + CXXFLAGS="$CXXFLAGS +DAportable +DS2.0" + fi + else + if test "$OS_TEST" = "ia64"; then + CFLAGS="$CFLAGS +DD64" + CXXFLAGS="$CXXFLAGS +DD64" + else + CFLAGS="$CFLAGS +DA2.0W +DS2.0" + CXXFLAGS="$CXXFLAGS +DA2.0W +DS2.0" + fi + fi + fi + DEFAULT_IMPL_STRATEGY=_PTH + fi + + if test "$DEFAULT_IMPL_STRATEGY" = "_EMU"; then + USE_NSPR_THREADS=1 + USE_PTHREADS= + USE_USER_PTHREADS= + elif test "$DEFAULT_IMPL_STRATEGY" = "_PTH"; then + USE_PTHREADS=1 + if test "$USE_NSPR_THREADS"; then + USE_PTHREADS= + fi + if test "$USE_USER_PTHREADS"; then + USE_PTHREADS= + fi + fi + ;; + +*-irix*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define IRIX 1" >>confdefs.h + + $as_echo "#define SVR4 1" >>confdefs.h + + $as_echo "#define _SGI_MP_SOURCE 1" >>confdefs.h + + $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h + + PR_MD_CSRCS=irix.c + PR_MD_ASFILES=os_Irix.s + MKSHLIB='$(LD) $(DSO_LDOPTS) -rdata_shared -shared -soname $(notdir $@) -o $@' + STRIP="$STRIP -f" + RESOLVE_LINK_SYMBOLS=1 + if test -n "$USE_64"; then + MDCPUCFG_H=_irix64.cfg + else + MDCPUCFG_H=_irix32.cfg + fi + case "${target_os}" in + irix6*) + $as_echo "#define IRIX6 1" >>confdefs.h + + USE_PTHREADS=1 + USE_N32=1 + COMPILER_TAG=_n32 + IMPL_STRATEGY=_PTH + ;; + irix5*) + $as_echo "#define IRIX5 1" >>confdefs.h + + USE_NSPR_THREADS=1 + ;; + *) + USE_PTHREADS=1 + USE_N32=1 + ;; + esac + if test "$GNU_CC"; then + AS='$(CC) -Wp,-P -x assembler-with-cpp -D_ASM -mips2 $(INCLUDES)' + CFLAGS="$CFLAGS -Wall -Wno-format" + _OPTIMIZE_FLAGS="-O6" + else + if test -n "$USE_N32"; then + AS='as -D_ASM $(INCLUDES) -n32' + else + AS='as -D_ASM $(INCLUDES)' + fi + CFLAGS="$CFLAGS -fullwarn -xansi" + if test "$USE_N32"; then + _OPTIMIZE_FLAGS="-O -OPT:Olimit=4000" + else + _OPTIMIZE_FLAGS="-O -Olimit 4000" + fi + if test "$USE_MDUPDATE"; then + CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)" + fi + case "${target}" in + *-irix6.*) + CFLAGS="$CFLAGS -multigot" + DSO_LDOPTS="-no_unresolved" + if test "$USE_N32"; then + CFLAGS="$CFLAGS -n32 -woff 1209" + DSO_LDOPTS="$DSO_LDOPTS -n32" + else + if test "$USE_64"; then + CFLAGS="$CFLAGS -64" + else + CFLAGS="$CFLAGS -32" + fi + fi + ;; + *) + CFLAGS="$CFLAGS -xgot" + ;; + esac + fi + if test "${target_os}" = "irix5.3"; then + $as_echo "#define IRIX5_3 1" >>confdefs.h + + fi + case "${target_os}" in + irix6.5) + if test -z "$GNU_CC"; then + CFLAGS="$CFLAGS -mips3" + fi + $as_echo "#define _PR_HAVE_GETPROTO_R 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_GETPROTO_R_POINTER 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_SGI_PRDA_PROCMASK 1" >>confdefs.h + + ;; + irix5*) + ;; + *) + $as_echo "#define _PR_HAVE_SGI_PRDA_PROCMASK 1" >>confdefs.h + + ;; + esac + ;; + +*-linux*|*-gnu*|*-k*bsd*-gnu|*-android*|*-linuxandroid*) + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + IMPL_STRATEGY=_PTH + fi + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h + + case "${target}" in + *-android*|*-linuxandroid*) + OS_TARGET=Android + $as_echo "#define LINUX 1" >>confdefs.h + + ;; + *-linux*) + $as_echo "#define LINUX 1" >>confdefs.h + + ;; + esac + CFLAGS="$CFLAGS -Wall" + CXXFLAGS="$CXXFLAGS -Wall" + MDCPUCFG_H=_linux.cfg + PR_MD_CSRCS=linux.c + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' + _OPTIMIZE_FLAGS=-O2 + _DEBUG_FLAGS="-g -fno-inline" # most people on linux use gcc/gdb, and that + # combo is not yet good at debugging inlined + # functions (even when using DWARF2 as the + # debugging format) + COMPILER_TAG=_glibc + if echo "$OS_TEST" | grep -c 86 >/dev/null; then + CPU_ARCH=x86 + else + CPU_ARCH=$OS_TEST + fi + CPU_ARCH_TAG=_${CPU_ARCH} + case "${target_cpu}" in + alpha) + $as_echo "#define _ALPHA_ 1" >>confdefs.h + + $as_echo "#define __alpha 1" >>confdefs.h + + CFLAGS="$CFLAGS -mieee" + CXXFLAGS="$CXXFLAGS -mieee" + ;; + i*86) + $as_echo "#define i386 1" >>confdefs.h + + PR_MD_ASFILES=os_Linux_x86.s + ;; + ia64) + PR_MD_ASFILES=os_Linux_ia64.s + ;; + x86_64) + if test -n "$USE_64"; then + PR_MD_ASFILES=os_Linux_x86_64.s + elif test -n "$USE_X32"; then + PR_MD_ASFILES=os_Linux_x86_64.s + CC="$CC -mx32" + CXX="$CXX -mx32" + else + $as_echo "#define i386 1" >>confdefs.h + + PR_MD_ASFILES=os_Linux_x86.s + CC="$CC -m32" + CXX="$CXX -m32" + fi + ;; + ppc|powerpc) + PR_MD_ASFILES=os_Linux_ppc.s + ;; + powerpc64) + if test -n "$USE_64"; then + CC="$CC -m64" + CXX="$CXX -m64" + else + PR_MD_ASFILES=os_Linux_ppc.s + fi + ;; + m68k) + CFLAGS="$CFLAGS -m68020-60" + CXXFLAGS="$CXXFLAGS -m68020-60" + ;; + esac + ;; + +*-mingw*|*-msys*|*-cygwin*|*-mks*) + $as_echo "#define XP_PC 1" >>confdefs.h + + $as_echo "#define WIN32 1" >>confdefs.h + + PR_MD_ARCH_DIR=windows + RESOLVE_LINK_SYMBOLS=1 + + if test -n "$GNU_CC"; then + CC="$CC -mwindows" + CXX="$CXX -mwindows" + DLL_SUFFIX=dll + MKSHLIB='$(CC) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(IMPORT_LIBRARY) $(DLLBASE) -o $(subst $(OBJDIR)/,,$(SHARED_LIBRARY))' + RC=$WINDRES + # Use temp file for windres (bug 213281) + RCFLAGS='-O coff --use-temp-file' + else + LD=link + AR='lib -NOLOGO -OUT:"$@"' + AR_FLAGS= + RANLIB='echo not_ranlib' + STRIP='echo not_strip' + RC=rc.exe + GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb' + OBJ_SUFFIX=obj + LIB_SUFFIX=lib + DLL_SUFFIX=dll + + # Determine compiler version + + _MSVC_VER_FILTER='s|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p' + + CC_VERSION=`"${CC}" -v 2>&1 | sed -ne "$_MSVC_VER_FILTER"` + _CC_MAJOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $1 }'` + _CC_MINOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $2 }'` + _CC_RELEASE=`echo ${CC_VERSION} | awk -F\. '{ print $3 }'` + _CC_BUILD=`echo ${CC_VERSION} | awk -F\. '{ print $4 }'` + MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION} + + if test "$_CC_MAJOR_VERSION" -eq "14"; then + if test $_CC_RELEASE -gt 50727; then + _USE_DYNAMICBASE=1 + elif test $_CC_BUILD -ge 762; then + _USE_DYNAMICBASE=1 + fi + $as_echo "#define _CRT_SECURE_NO_DEPRECATE 1" >>confdefs.h + + $as_echo "#define _CRT_NONSTDC_NO_DEPRECATE 1" >>confdefs.h + + elif test $_CC_MAJOR_VERSION -ge 15; then + _USE_DYNAMICBASE=1 + $as_echo "#define _CRT_SECURE_NO_WARNINGS 1" >>confdefs.h + + $as_echo "#define _CRT_NONSTDC_NO_WARNINGS 1" >>confdefs.h + + fi + + if test -n "$_USE_DYNAMICBASE"; then + DLLFLAGS="$DLLFLAGS -DYNAMICBASE" + fi + + # Ensure that mt is Microsoft (R) Manifest Tool and not magnetic + # tape manipulation utility (or something else) + if test "$MSC_VER" -ge "1400"; then + + _MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p' + + + MSMT_TOOL=`mt 2>&1|grep 'Microsoft (R) Manifest Tool'` + if test -n "$MSMT_TOOL"; then + MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"` + if test -z "$MSMANIFEST_TOOL_VERSION"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unknown version of the Microsoft (R) Manifest Tool." >&5 +$as_echo "$as_me: WARNING: Unknown version of the Microsoft (R) Manifest Tool." >&2;} + fi + MT=mt + unset MSMT_TOOL + else + as_fn_error $? "Microsoft (R) Manifest Tool must be in your \$PATH." "$LINENO" 5 + fi + fi + + CFLAGS="$CFLAGS -W3 -nologo -GF -Gy" + DLLFLAGS="$DLLFLAGS -OUT:\"\$@\"" + _DEBUG_FLAGS=-Zi + _OPTIMIZE_FLAGS=-O2 + + PROFILE_GEN_CFLAGS="-GL" + PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT" + PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952" + PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE" + + if test "$MSC_VER" -ge "1800"; then + CFLAGS="$CFLAGS -FS" + PROFILE_GEN_CFLAGS="$PROFILE_GEN_CFLAGS -Gw" + PROFILE_USE_CFLAGS="$PROFILE_USE_CFLAGS -Gw" + fi + + if test -z "$MOZ_OPTIMIZE"; then + CFLAGS="$CFLAGS -Od" + fi + + if test "$USE_DEBUG_RTL" = 1; then + if test -n "$USE_STATIC_RTL"; then + CFLAGS="$CFLAGS -MTd" + else + CFLAGS="$CFLAGS -MDd" + fi + else + if test -n "$USE_STATIC_RTL"; then + CFLAGS="$CFLAGS -MT" + else + CFLAGS="$CFLAGS -MD" + fi + fi + + if test -n "$MOZ_DEBUG"; then + $as_echo "#define _DEBUG 1" >>confdefs.h + + else + DEFINES="$DEFINES -U_DEBUG" + fi + + if test -n "$MOZ_DEBUG_SYMBOLS"; then + if test -n "$MOZ_OPTIMIZE"; then + DLLFLAGS="$DLLFLAGS -DEBUG -OPT:REF" + LDFLAGS="$LDFLAGS -DEBUG -OPT:REF" + else + DLLFLAGS="$DLLFLAGS -DEBUG" + LDFLAGS="$LDFLAGS -DEBUG" + fi + fi + + OS_DLLFLAGS="-nologo -DLL -SUBSYSTEM:WINDOWS" + if test "$MSC_VER" -le "1200" -a -z "$MOZ_DEBUG_SYMBOLS"; then + OS_DLLFLAGS="$OS_DLLFLAGS -PDB:NONE" + fi + + if test "$OS_TARGET" = "WINNT"; then + CFLAGS="$CFLAGS -GT" + LIBNSPR='$(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' + LIBPLC='$(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' + else + LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' + LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' + fi + fi # GNU_CC + + if test -n "$USE_STATIC_TLS"; then + $as_echo "#define _PR_USE_STATIC_TLS 1" >>confdefs.h + + fi + + if test "$OS_TARGET" = "WINNT"; then + $as_echo "#define WINNT 1" >>confdefs.h + + else + $as_echo "#define WIN95 1" >>confdefs.h + + # undefine WINNT as some versions of mingw gcc define it by default + DEFINES="$DEFINES -UWINNT" + $as_echo "#define _PR_GLOBAL_THREADS_ONLY 1" >>confdefs.h + + fi + + if test "$CPU_ARCH" = "x86"; then + CPU_ARCH_TAG= + else + CPU_ARCH_TAG=$CPU_ARCH + fi + + if test "$USE_DEBUG_RTL" = 1; then + OBJDIR_SUFFIX=OBJD + fi + + case "$OS_TARGET" in + WINNT) + MDCPUCFG_H=_winnt.cfg + ;; + WIN95) + MDCPUCFG_H=_win95.cfg + ;; + *) + as_fn_error $? "Missing OS_TARGET for ${target}. Use --enable-win32-target to set." "$LINENO" 5 + ;; + esac + + case "$target_cpu" in + i*86) + if test -n "$USE_64"; then + $as_echo "#define _AMD64_ 1" >>confdefs.h + + else + $as_echo "#define _X86_ 1" >>confdefs.h + + if test -z "$GNU_CC" -a "$MSC_VER" -ge "1700"; then + CFLAGS="$CFLAGS -arch:IA32" + fi + fi + ;; + x86_64) + $as_echo "#define _AMD64_ 1" >>confdefs.h + + USE_64=1 + ;; + ia64) + $as_echo "#define _IA64_ 1" >>confdefs.h + + USE_64=1 + ;; + *) + $as_echo "#define _CPU_ARCH_NOT_DEFINED 1" >>confdefs.h + + ;; + esac + ;; + +*-netbsd*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define NETBSD 1" >>confdefs.h + + $as_echo "#define HAVE_BSD_FLOCK 1" >>confdefs.h + + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + fi + MDCPUCFG_H=_netbsd.cfg + PR_MD_CSRCS=netbsd.c + + DSO_CFLAGS='-fPIC -DPIC' + CFLAGS="$CFLAGS -ansi -Wall" + CXXFLAGS="$CXXFLAGS -ansi -Wall" + MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)' + + if test -z "$OBJECT_FMT"; then + if echo __ELF__ | ${CC-cc} -E - | grep -q __ELF__ 2>/dev/null; then + OBJECT_FMT=a.out + DLL_SUFFIX=so.1.0 + DSO_LDOPTS='-shared' + else + OBJECT_FMT=ELF + DLL_SUFFIX=so + DSO_LDOPTS='-shared -Wl,-soname,$(notdir $@)' + fi + fi + + if test "$LIBRUNPATH"; then + DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH" + fi + ;; + +*-nto*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define NTO 1" >>confdefs.h + + $as_echo "#define _QNX_SOURCE 1" >>confdefs.h + + $as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h + + MDCPUCFG_H=_nto.cfg + PR_MD_CSRCS=nto.c + MKSHLIB='$(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(notdir $@) -o $@' + DSO_CFLAGS=-fPIC + DSO_LDOPTS=-shared + OS_LIBS="$OS_LIBS -lsocket" + _OPTIMIZE_FLAGS="-O1" + _DEBUG_FLAGS="-gstabs" + ;; + +*-openbsd*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define OPENBSD 1" >>confdefs.h + + $as_echo "#define HAVE_BSD_FLOCK 1" >>confdefs.h + + $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h + + CFLAGS="$CFLAGS -ansi -Wall" + CXXFLAGS="$CXXFLAGS -ansi -Wall" + DLL_SUFFIX=so.1.0 + DSO_CFLAGS=-fPIC + MDCPUCFG_H=_openbsd.cfg + PR_MD_CSRCS=openbsd.c + OS_LIBS="-lc" + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + fi + DSO_LDOPTS='-shared -fPIC' + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + ;; + +*-osf*) + SHELL_OVERRIDE="SHELL = /usr/bin/ksh" + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define OSF1 1" >>confdefs.h + + $as_echo "#define _REENTRANT 1" >>confdefs.h + + # OSF1 and HPUX report the POLLHUP event for a socket when the + # shutdown(SHUT_WR) operation is called for the remote end, even though + # the socket is still writeable. Use select(), instead of poll(), to + # workaround this problem. + $as_echo "#define _PR_POLL_WITH_SELECT 1" >>confdefs.h + + + if echo "$OS_RELEASE" | egrep -c '(V2.0|V3.2)' 2>/dev/null ; then + USE_NSPR_THREADS=1 + fi + + if test -z "$GNU_CC"; then + CC="$CC -std1 -ieee_with_inexact" + if test "$OS_RELEASE" != "V2.0"; then + CC="$CC -readonly_strings" + fi + _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000" + ac_fn_c_check_header_mongrel "$LINENO" "machine/builtins.h" "ac_cv_header_machine_builtins_h" "$ac_includes_default" +if test "x$ac_cv_header_machine_builtins_h" = xyes; then : + $as_echo "#define OSF1_HAVE_MACHINE_BUILTINS_H 1" >>confdefs.h + +fi + + + else + CFLAGS="$CFLAGS -mieee" + CXXFLAGS="$CXXFLAGS -mieee" + fi + + if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then + $as_echo "#define HAVE_INT_LOCALTIME_R 1" >>confdefs.h + + else + $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h + + $as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h + + fi + if echo $OS_RELEASE | grep -c V4.0 >/dev/null; then + $as_echo "#define OSF1V4_MAP_PRIVATE_BUG 1" >>confdefs.h + + fi + DSO_LDOPTS='-shared -all -expect_unresolved "*" -soname $(notdir $@)' + MDCPUCFG_H=_osf1.cfg + PR_MD_CSRCS=osf1.c + ;; + +*-qnx*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define QNX 1" >>confdefs.h + + $as_echo "#define _PR_NEED_H_ERRNO 1" >>confdefs.h + + USE_NSPR_THREADS=1 + MDCPUCFG_H=_qnx.cfg + PR_MD_CSRCS=qnx.c + ;; + +*-riscos*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define RISCOS 1" >>confdefs.h + + $as_echo "#define _PR_NEED_H_ERRNO 1" >>confdefs.h + + USE_PTHREADS=1 + MDCPUCFG_H=_riscos.cfg + PR_MD_CSRCS=riscos.c + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + ;; + +*-*-sco*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define SCO 1" >>confdefs.h + + $as_echo "#define sco 1" >>confdefs.h + + $as_echo "#define SYSV 1" >>confdefs.h + + $as_echo "#define _SVID3 1" >>confdefs.h + + $as_echo "#define _PR_NEED_H_ERRNO 1" >>confdefs.h + + CC='cc -b elf -KPIC' + CXX='$(NSDEPTH)/build/hcpp CC +.cpp +w' + USE_NSPR_THREADS=1 + CPU_ARCH=x86 + DSO_LDOPTS='-b elf -G' + MDCPUCFG_H=_scoos.cfg + PR_MD_SRCS=scoos.c + ;; + +*-solaris*) + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + fi + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define SVR4 1" >>confdefs.h + + $as_echo "#define SYSV 1" >>confdefs.h + + $as_echo "#define __svr4 1" >>confdefs.h + + $as_echo "#define __svr4__ 1" >>confdefs.h + + $as_echo "#define SOLARIS 1" >>confdefs.h + + $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h + + CPU_ARCH=`uname -p` + MDCPUCFG_H=_solaris.cfg + PR_MD_CSRCS=solaris.c + LD=/usr/ccs/bin/ld + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + RESOLVE_LINK_SYMBOLS=1 + case "${OS_RELEASE}" in + 5.8|5.9) + ;; + *) + # It is safe to use the -Bdirect linker flag on Solaris 10 or later. + USE_B_DIRECT=1 + ;; + esac + if test -n "$GNU_CC"; then + DSO_CFLAGS=-fPIC + if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then + GCC_USE_GNU_LD=1 + fi + DSO_LDOPTS='-shared -Wl,-h,$(notdir $@),-z,combreloc,-z,defs,-z,ignore' + if test -n "$USE_B_DIRECT"; then + DSO_LDOPTS="$DSO_LDOPTS,-Bdirect" + fi + else + DSO_CFLAGS=-KPIC + DSO_LDOPTS='-G -h $(notdir $@) -z combreloc -z defs -z ignore' + if test -n "$USE_B_DIRECT"; then + DSO_LDOPTS="$DSO_LDOPTS -Bdirect" + fi + fi + if test -n "$GNU_CC"; then + CFLAGS="$CFLAGS -Wall" + CXXFLAGS="$CXXFLAGS -Wall" + if test -n "$USE_MDUPDATE"; then + CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)" + CXXFLAGS="$CXXFLAGS -MDupdate \$(DEPENDENCIES)" + fi + GCC_AS=`$CC -print-prog-name=as` + if test "`echo | $GCC_AS -v 2>&1 | grep -c GNU`" != "0"; then + GNU_AS=1 + fi + else + CFLAGS="$CFLAGS -xstrconst" + CXXFLAGS="$CXXFLAGS -Qoption cg -xstrconst -features=tmplife" + if test -z "$MOZ_OPTIMIZE"; then + CFLAGS="$CFLAGS -xs" + CXXFLAGS="$CXXFLAGS -xs" + fi + _OPTIMIZE_FLAGS=-xO4 + fi + if test -z "$GNU_AS"; then + ASFLAGS="$ASFLAGS -Wa,-P" + fi + if test -n "$USE_64"; then + if test -n "$GNU_CC"; then + CC="$CC -m64" + CXX="$CXX -m64" + else + if test "$OS_TEST" = "i86pc"; then + CC="$CC -xarch=amd64" + CXX="$CXX -xarch=amd64" + else + CC="$CC -xarch=v9" + CXX="$CXX -xarch=v9" + fi + fi + fi + if test "$OS_TEST" = "i86pc"; then + if test -z "$USE_64"; then + $as_echo "#define i386 1" >>confdefs.h + + fi + CPU_ARCH_TAG=_$OS_TEST + # The default debug format, DWARF (-g), is not supported by gcc + # on i386-ANY-sysv4/solaris, but the stabs format is. It is + # assumed that the Solaris assembler /usr/ccs/bin/as is used. + # If your gcc uses GNU as, you do not need the -Wa,-s option. + if test -n "$MOZ_DEBUG" && test -n "$GNU_CC"; then + _DEBUG_FLAGS=-gstabs + if test -z "$GNU_AS"; then + _DEBUG_FLAGS="$_DEBUG_FLAGS -Wa,-s" + fi + fi + fi + case "${target_os}" in + solaris2.3*) + $as_echo "#define _PR_NO_LARGE_FILES 1" >>confdefs.h + + ;; + solaris2.4*) + $as_echo "#define _PR_NO_LARGE_FILES 1" >>confdefs.h + + ;; + solaris2.5*) + $as_echo "#define SOLARIS2_5 1" >>confdefs.h + + ;; + *) + $as_echo "#define _PR_HAVE_OFF64_T 1" >>confdefs.h + + # The lfcompile64(5) man page on Solaris 2.6 says: + # For applications that do not wish to conform to the POSIX or + # X/Open specifications, the 64-bit transitional interfaces + # are available by default. No compile-time flags need to be + # set. + # But gcc 2.7.2.x fails to define _LARGEFILE64_SOURCE by default. + # The native compiler, gcc 2.8.x, and egcs don't have this problem. + if test -n "$GNU_CC"; then + $as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h + + fi + ;; + esac + case "${target_os}" in + solaris2.3*) + ;; + solaris2.4*) + ;; + solaris2.5*) + ;; + solaris2.6*) + ;; + solaris2.7*) + ;; + *) + # Solaris 8 or higher has IPv6. + $as_echo "#define _PR_INET6 1" >>confdefs.h + + ;; + esac + if test "$CPU_ARCH" = "sparc"; then + # 64-bit Solaris SPARC requires V9 architecture, so the following + # is not needed. + if test -z "$USE_64"; then + ULTRASPARC_LIBRARY=nspr_flt + fi + fi + # Purify requires that binaries linked against nspr also + # be linked against -lrt (or -lposix4) so add it to OS_LIBS + _rev=`uname -r` + _librt=`echo $_rev 5.6 | awk '{ if ($1 > $2) print "-lrt"; else print "-lposix4" }'` + OS_LIBS="$OS_LIBS $_librt" + ;; + +*-sco-sysv5*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define UNIXWARE 1" >>confdefs.h + + $as_echo "#define SVR4 1" >>confdefs.h + + $as_echo "#define SYSV 1" >>confdefs.h + + USE_NSPR_THREADS=1 + if echo $OS_RELEASE | grep -c 2.1 2>/dev/null; then + $as_echo "#define _PR_NO_LARGE_FILES 1" >>confdefs.h + + CC='$(NSDEPTH)/build/hcc cc' + CXX='$(NSDEPTH)/build/hcpp CC' + MDCPUCFG_H=_unixware.cfg + else + $as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_OFF64_T 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_SOCKADDR_LEN 1" >>confdefs.h + + MDCPUCFG_H=_unixware7.cfg + fi + PR_MD_CSRCS=unixware.c + DSO_LDOPTS=-G + CPU_ARCH=x86 + ;; + +*-symbian*) + +# Check whether --with-symbian-sdk was given. +if test "${with_symbian_sdk+set}" = set; then : + withval=$with_symbian_sdk; SYMBIAN_SDK_DIR=$withval +fi + + + echo ----------------------------------------------------------------------------- + echo Building with Symbian SDK in: $SYMBIAN_SDK_DIR + echo ----------------------------------------------------------------------------- + + $as_echo "#define XP_UNIX 1" >>confdefs.h + + $as_echo "#define SYMBIAN 1" >>confdefs.h + + $as_echo "#define __arm__ 1" >>confdefs.h + + $as_echo "#define __SYMBIAN32__ 1" >>confdefs.h + + $as_echo "#define _UNICODE 1" >>confdefs.h + + $as_echo "#define NDEBUG 1" >>confdefs.h + + $as_echo "#define __SUPPORT_CPP_EXCEPTIONS__ 1" >>confdefs.h + + $as_echo "#define MOZ_STDERR_TO_STDOUT 1" >>confdefs.h + + $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h + + $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h + + USE_PTHREADS=1 + LIB_SUFFIX=lib + DLL_SUFFIX=dll + MKSHLIB= + DSO_LDOPTS= + DSO_CFLAGS= + VISIBILITY_FLAGS= + MDCPUCFG_H=_symbian.cfg + PR_MD_CSRCS=symbian.c + NSINSTALL=nsinstall + RANLIB='echo no ranlib ' + CPU_ARCH=ARM + OS_ARCH=SYMBIAN + OS_EXE_CFLAGS="$OS_EXE_CFLAGS -D__EXE__" + CFLAGS="$CFLAGS -MD -nostdinc" + SYMBIAN_SYS_INCLUDE="-I$SYMBIAN_SDK_DIR/Epoc32/include/variant -I$SYMBIAN_SDK_DIR/Epoc32/include -I$SYMBIAN_SDK_DIR/Epoc32/include/stdapis" + echo ------------------------------------------------------- + echo SYMBIAN_SYS_INCLUDE is: $SYMBIAN_SYS_INCLUDE + echo ------------------------------------------------------- + case "$OS_TARGET" in + WINSCW) + CC=mwccsym2.exe + CXX=mwccsym2.exe + LD=mwldsym2.exe + AR=mwldsym2.exe + WINSCW_LD_DIR="\$(SYMBIAN_SDK_DIR)/EPOC32/RELEASE/WINSCW/UDEB" + CFLAGS="$CFLAGS -O0 -inline off -wchar_t off -align 4 -warnings on -w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostderr -gccdep -cwd source -i- -I\$(VPATH)" + SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include Symbian_OS_v9.2.hrh" + AR_FLAGS="-library -msgstyle gcc -stdlib -subsystem windows -noimplib -o \$@" + $as_echo "#define _DEBUG 1" >>confdefs.h + + $as_echo "#define __CW32__ 1" >>confdefs.h + + $as_echo "#define __WINS__ 1" >>confdefs.h + + $as_echo "#define __WINSCW__ 1" >>confdefs.h + + DEFINES="$DEFINES -U_WIN32" + ;; + GCCE) + CFLAGS="$CFLAGS -Wall -Wno-unknown-pragmas -fexceptions -march=armv5t -mapcs -pipe -x c -msoft-float" + CXXFLAGS="$CXXFLAGS $CFLAGS -Wno-ctor-dtor-privacy" + SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include $SYMBIAN_SDK_DIR/EPOC32/INCLUDE/GCCE/GCCE.h" + $as_echo "#define __GCCE__ 1" >>confdefs.h + + $as_echo "#define __EABI__ 1" >>confdefs.h + + DEFINES="$DEFINES -D__PRODUCT_INCLUDE__=$SYMBIAN_SDK_DIR/Epoc32/include/variant/Symbian_OS_v9.2.hrh" + ;; + *) + as_fn_error $? "Missing OS_TARGET for ${target}. Set --enable-symbian-target to with 'WINSCW' or 'GCCE'." "$LINENO" 5 + ;; + esac + CFLAGS="$CFLAGS ${SYMBIAN_SYS_INCLUDE}" + ;; + +*-os2*) + $as_echo "#define XP_OS2 1" >>confdefs.h + + $as_echo "#define XP_PC 1" >>confdefs.h + + $as_echo "#define BSD_SELECT 1" >>confdefs.h + + $as_echo "#define TCPV40HDRS 1" >>confdefs.h + + LIB_SUFFIX=lib + DLL_SUFFIX=dll + RC=rc.exe + PR_MD_ARCH_DIR=os2 + PROG_SUFFIX=.exe + NSINSTALL=nsinstall + MDCPUCFG_H=_os2.cfg + RESOLVE_LINK_SYMBOLS=1 + + $as_echo "#define OS2 1" >>confdefs.h + + AR=emxomfar + AR_FLAGS='r $@' + CFLAGS="$CFLAGS -Wall -Zomf" + CXXFLAGS="$CFLAGS -Wall -Zomf" + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + DSO_CFLAGS= + DSO_LDOPTS='-Zomf -Zdll' + LDFLAGS='-Zmap' + _OPTIMIZE_FLAGS="-O2 -s" + _DEBUG_FLAGS="-g -fno-inline" + if test -n "$MOZ_OPTIMIZE"; then + DSO_LDOPTS="$DSO_LDOPTS -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA" + fi + IMPLIB='emximp -o' + FILTER='emxexp -o' + if test -n "$MOZ_OS2_HIGH_MEMORY"; then + LDFLAGS="$LDFLAGS -Zhigh-mem" + $as_echo "#define MOZ_OS2_HIGH_MEMORY 1" >>confdefs.h + + fi + + # GCC for OS/2 currently predefines these, but we don't want them + DEFINES="$DEFINES -Uunix -U__unix -U__unix__" + ;; + +*) + $as_echo "#define XP_UNIX 1" >>confdefs.h + + ;; + +esac + +if test -z "$SKIP_LIBRARY_CHECKS"; then + + + +case $target in +*-darwin*|*-beos*|*-os2*) + ;; +*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + OS_LIBS="-ldl $OS_LIBS" +fi + + +fi + + ;; +esac + + + + +if test $ac_cv_c_compiler_gnu = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 +$as_echo_n "checking whether $CC needs -traditional... " >&6; } +if ${ac_cv_prog_gcc_traditional+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_pattern="Autoconf.*'x'" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 +$as_echo "$ac_cv_prog_gcc_traditional" >&6; } + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +_SAVE_LIBS="$LIBS" +LIBS="$LIBS $OS_LIBS" +for ac_func in dladdr gettid lchown setpriority strerror syscall +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +LIBS="$_SAVE_LIBS" + + + +# Check whether --with-ccache was given. +if test "${with_ccache+set}" = set; then : + withval=$with_ccache; CCACHE=$withval +else + CCACHE="no" +fi + + +if test "$CCACHE" != "no"; then + if test -n "$CCACHE"; then + if test "$CCACHE" = "yes"; then + CCACHE= + else + if test ! -e "$CCACHE"; then + as_fn_error $? "$CCACHE not found" "$LINENO" 5 + fi + fi + fi + for ac_prog in $CCACHE ccache +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_CCACHE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $CCACHE in + [\\/]* | ?:[\\/]*) + ac_cv_path_CCACHE="$CCACHE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_CCACHE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +CCACHE=$ac_cv_path_CCACHE +if test -n "$CCACHE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCACHE" >&5 +$as_echo "$CCACHE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CCACHE" && break +done + + if test -z "$CCACHE" -o "$CCACHE" = ":"; then + as_fn_error $? "ccache not found" "$LINENO" 5 + elif test -x "$CCACHE"; then + CC="$CCACHE $CC" + CXX="$CCACHE $CXX" + else + as_fn_error $? "$CCACHE is not executable" "$LINENO" 5 + fi +fi + +# Check whether --enable-strip was given. +if test "${enable_strip+set}" = set; then : + enableval=$enable_strip; if test "$enableval" = "yes"; then + ENABLE_STRIP=1 + fi +fi + + +case "${target_os}" in +hpux*) +if test -z "$GNU_CC"; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for +Olit support" >&5 +$as_echo_n "checking for +Olit support... " >&6; } +if ${ac_cv_hpux_usable_olit_option+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_hpux_usable_olit_option=no + rm -f conftest* + echo 'int main() { return 0; }' | cat > conftest.c + ${CC-cc} ${CFLAGS} +Olit=all -o conftest conftest.c > conftest.out 2>&1 + if test $? -eq 0; then + if test -z "`egrep -i '(unrecognize|unknown)' conftest.out`"; then + ac_cv_hpux_usable_olit_option=yes + fi + fi + rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_hpux_usable_olit_option" >&5 +$as_echo "$ac_cv_hpux_usable_olit_option" >&6; } + + if test "$ac_cv_hpux_usable_olit_option" = "yes"; then + CFLAGS="$CFLAGS +Olit=all" + CXXFLAGS="$CXXFLAGS +Olit=all" + else + CFLAGS="$CFLAGS +ESlit" + CXXFLAGS="$CXXFLAGS +ESlit" + fi +fi +;; +esac + +case "$target_os" in +darwin*) + _HAVE_PTHREADS=1 + ;; +*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthreads" >&5 +$as_echo_n "checking for pthread_create in -lpthreads... " >&6; } +if ${ac_cv_lib_pthreads_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthreads $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthreads_pthread_create=yes +else + ac_cv_lib_pthreads_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_create" >&5 +$as_echo "$ac_cv_lib_pthreads_pthread_create" >&6; } +if test "x$ac_cv_lib_pthreads_pthread_create" = xyes; then : + _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +$as_echo_n "checking for pthread_create in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_pthread_create=yes +else + ac_cv_lib_pthread_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : + _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc_r" >&5 +$as_echo_n "checking for pthread_create in -lc_r... " >&6; } +if ${ac_cv_lib_c_r_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc_r $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_r_pthread_create=yes +else + ac_cv_lib_c_r_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_create" >&5 +$as_echo "$ac_cv_lib_c_r_pthread_create" >&6; } +if test "x$ac_cv_lib_c_r_pthread_create" = xyes; then : + _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc" >&5 +$as_echo_n "checking for pthread_create in -lc... " >&6; } +if ${ac_cv_lib_c_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_pthread_create=yes +else + ac_cv_lib_c_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_pthread_create" >&5 +$as_echo "$ac_cv_lib_c_pthread_create" >&6; } +if test "x$ac_cv_lib_c_pthread_create" = xyes; then : + _HAVE_PTHREADS=1 + +fi + + +fi + + +fi + + +fi + + ;; +esac + + +# Check whether --with-pthreads was given. +if test "${with_pthreads+set}" = set; then : + withval=$with_pthreads; if test "$withval" = "yes"; then + if test -n "$_HAVE_PTHREADS"; then + USE_PTHREADS=1 + USE_USER_PTHREADS= + USE_NSPR_THREADS= + else + as_fn_error $? " --with-pthreads specified for a system without pthread support " "$LINENO" 5; + fi + else + USE_PTHREADS= + _PTHREAD_LDFLAGS= + fi +else + if test -n "$_HAVE_PTHREADS" && test -z "$USE_USER_PTHREADS" && test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + USE_USER_PTHREADS= + USE_NSPR_THREADS= + fi +fi + + +# Check whether --enable-user-pthreads was given. +if test "${enable_user_pthreads+set}" = set; then : + enableval=$enable_user_pthreads; if test "$enableval" = "yes"; then + if test -n "$_HAVE_PTHREADS"; then + USE_PTHREADS= + USE_USER_PTHREADS=1 + USE_NSPR_THREADS= + else + as_fn_error $? " --enable-user-pthreads specified for a system without pthread support " "$LINENO" 5; + fi + fi +fi + + +# Check whether --enable-nspr-threads was given. +if test "${enable_nspr_threads+set}" = set; then : + enableval=$enable_nspr_threads; if test "$enableval" = "yes"; then + USE_PTHREADS= + USE_USER_PTHREADS= + USE_NSPR_THREADS=1 + fi +fi + + +case "$target" in +*-beos*) + +# Check whether --with-bthreads was given. +if test "${with_bthreads+set}" = set; then : + withval=$with_bthreads; if test "$withval" = "yes"; then + USE_BTHREADS=1 + USE_USER_PTHREADS= + USE_PTHREADS= + fi +fi + + ;; +esac + +fi # SKIP_LIBRARY_CHECKS + +# Check whether --enable-ipv6 was given. +if test "${enable_ipv6+set}" = set; then : + enableval=$enable_ipv6; if test "$enableval" = "yes"; then + USE_IPV6=1 + else + USE_IPV6= + fi +fi + + +if test -n "$USE_PTHREADS"; then + rm -f conftest* + ac_cv_have_dash_pthread=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -pthread" >&5 +$as_echo_n "checking whether ${CC-cc} accepts -pthread... " >&6; } + echo 'int main() { return 0; }' | cat > conftest.c + ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1 + if test $? -eq 0; then + if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthread`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then + ac_cv_have_dash_pthread=yes + case "$target_os" in + freebsd*) +# Freebsd doesn't use -pthread for compiles, it uses them for linking + ;; + *) + CFLAGS="$CFLAGS -pthread" + CXXFLAGS="$CXXFLAGS -pthread" + ;; + esac + fi + fi + rm -f conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_dash_pthread" >&5 +$as_echo "$ac_cv_have_dash_pthread" >&6; } + + ac_cv_have_dash_pthreads=no + if test "$ac_cv_have_dash_pthread" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-cc} accepts -pthreads" >&5 +$as_echo_n "checking whether ${CC-cc} accepts -pthreads... " >&6; } + echo 'int main() { return 0; }' | cat > conftest.c + ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1 + if test $? -eq 0; then + if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthreads`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then + ac_cv_have_dash_pthreads=yes + CFLAGS="$CFLAGS -pthreads" + CXXFLAGS="$CXXFLAGS -pthreads" + fi + fi + rm -f conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_dash_pthreads" >&5 +$as_echo "$ac_cv_have_dash_pthreads" >&6; } + fi + + case "$target" in + *-solaris*) + if test "$ac_cv_have_dash_pthreads" = "yes"; then + _PTHREAD_LDFLAGS= + fi + ;; + *-freebsd*) + $as_echo "#define _REENTRANT 1" >>confdefs.h + + $as_echo "#define _THREAD_SAFE 1" >>confdefs.h + + if test "$ac_cv_have_dash_pthread" = "yes"; then + _PTHREAD_LDFLAGS="-pthread" + else + _PTHREAD_LDFLAGS="-lc_r" + fi + ;; + *-netbsd*) + if test "$ac_cv_have_dash_pthread" = "yes"; then + _PTHREAD_LDFLAGS="-pthread" + fi + ;; + *-bsdi*) + $as_echo "#define _THREAD_SAFE 1" >>confdefs.h + + if test "$ac_cv_have_dash_pthread" = "yes"; then + _PTHREAD_LDFLAGS= + fi + ;; + *-openbsd*) + if test "$ac_cv_have_dash_pthread" = "yes"; then + _PTHREAD_LDFLAGS=-pthread + fi + ;; + *-linux*|*-gnu*|*-k*bsd*-gnu) + $as_echo "#define _REENTRANT 1" >>confdefs.h + + ;; + esac + +else + if test -n "$USE_USER_PTHREADS"; then + USE_PTHREADS= + USE_NSPR_THREADS= + else + _PTHREAD_LDFLAGS= + fi +fi + +case "$target" in +*-aix*) + if test -n "$USE_NSPR_THREADS"; then + $as_echo "#define _PR_LOCAL_THREADS_ONLY 1" >>confdefs.h + + fi + case "$target_os" in + aix4.1*) + if test -z "$USE_PTHREADS"; then + $as_echo "#define AIX_RENAME_SELECT 1" >>confdefs.h + + fi + ;; + aix4.2*) + if test -z "$USE_NSPR_THREADS"; then + $as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h + + fi + ;; + aix4.3*) + if test -z "$USE_NSPR_THREADS"; then + $as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h + + fi + if test -n "$USE_PTHREADS"; then + $as_echo "#define _PR_HAVE_THREADSAFE_GETHOST 1" >>confdefs.h + + fi + ;; + *) + if test -z "$USE_NSPR_THREADS"; then + $as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h + + fi + if test -n "$USE_PTHREADS"; then + $as_echo "#define _PR_HAVE_THREADSAFE_GETHOST 1" >>confdefs.h + + fi + ;; + esac + ;; +*-bsdi*) + if test -n "$USE_PTHREADS"; then + $as_echo "#define _PR_NEED_PTHREAD_INIT 1" >>confdefs.h + + fi + ;; +*-freebsd*) + if test -n "$USE_NSPR_THREADS"; then + $as_echo "#define _PR_LOCAL_THREADS_ONLY 1" >>confdefs.h + + fi + ;; +*-hpux*) + if test -n "$USE_NSPR_THREADS"; then + $as_echo "#define _PR_LOCAL_THREADS_ONLY 1" >>confdefs.h + + fi + if test "$USE_PTHREADS"; then + if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then + $as_echo "#define _REENTRANT 1" >>confdefs.h + + $as_echo "#define _PR_DCETHREADS 1" >>confdefs.h + + else + cat >>confdefs.h <<_ACEOF +#define _POSIX_C_SOURCE 199506L +_ACEOF + + $as_echo "#define _PR_HAVE_THREADSAFE_GETHOST 1" >>confdefs.h + + fi + fi + if test "$USE_USER_PTHREADS"; then + cat >>confdefs.h <<_ACEOF +#define _POSIX_C_SOURCE 199506L +_ACEOF + + fi + ;; +*-irix*) + if test "${target_os}" = "irix6.5"; then + if test -n "$USE_PTHREADS"; then + $as_echo "#define _PR_HAVE_GETHOST_R 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_GETHOST_R_POINTER 1" >>confdefs.h + + fi + fi + ;; +*-linux*|*-gnu*|*-k*bsd*-gnu) + if test -n "$USE_NSPR_THREADS"; then + $as_echo "#define _PR_LOCAL_THREADS_ONLY 1" >>confdefs.h + + fi + ;; +*-mingw*|*-msys*|*-cygwin*|*-mks*|*-os2*|*-beos*) + USE_PTHREADS= + _PTHREAD_LDFLAGS= + USE_USER_PTHREADS= + ;; +*-netbsd*|*-openbsd*) + if test -n "$USE_NSPR_THREADS"; then + $as_echo "#define _PR_LOCAL_THREADS_ONLY 1" >>confdefs.h + + fi + ;; +*-osf*) + if test -n "$USE_NSPR_THREADS"; then + $as_echo "#define _PR_LOCAL_THREADS_ONLY 1" >>confdefs.h + + fi + if test -n "$USE_PTHREADS"; then + if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then + : + else + $as_echo "#define _PR_HAVE_THREADSAFE_GETHOST 1" >>confdefs.h + + fi + fi + ;; +*-solaris*) + if test -n "$USE_NSPR_THREADS"; then + $as_echo "#define _PR_LOCAL_THREADS_ONLY 1" >>confdefs.h + + fi + if test -n "$USE_PTHREADS"; then + $as_echo "#define _REENTRANT 1" >>confdefs.h + + $as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h + + if test "$OS_TEST" = "i86pc"; then + if test -n "$USE_64"; then + PR_MD_ASFILES=os_SunOS_x86_64.s + else + PR_MD_ASFILES=os_SunOS_x86.s + fi + else + if test -n "$USE_64"; then + PR_MD_ASFILES=os_SunOS_sparcv9.s + fi + fi + fi + ;; +*-nto*) + if test -n "$USE_PTHREADS"; then + $as_echo "#define _PR_HAVE_GETHOST_R 1" >>confdefs.h + + $as_echo "#define _PR_HAVE_GETHOST_R_POINTER 1" >>confdefs.h + + fi + ;; +esac + +OS_LIBS="$_PTHREAD_LDFLAGS $OS_LIBS" + +if test -n "$_SAVE_OPTIMIZE_FLAGS"; then + _OPTIMIZE_FLAGS="$_SAVE_OPTIMIZE_FLAGS" +fi + +if test -n "$_SAVE_DEBUG_FLAGS"; then + _DEBUG_FLAGS="$_SAVE_DEBUG_FLAGS" +fi + +if test -n "$MOZ_OPTIMIZE"; then + CFLAGS="$CFLAGS $_OPTIMIZE_FLAGS" + CXXFLAGS="$CXXFLAGS $_OPTIMIZE_FLAGS" +fi + +if test -n "$MOZ_DEBUG_SYMBOLS"; then + CFLAGS="$CFLAGS $_DEBUG_FLAGS" + CXXFLAGS="$CXXFLAGS $_DEBUG_FLAGS" +fi + +if test -n "$MOZ_OPTIMIZE"; then + OBJDIR_TAG=_OPT +else + OBJDIR_TAG=_DBG +fi + +if test -n "$USE_64"; then + COMPILER_TAG=_64 +fi + +RELEASE_OBJDIR_NAME="${OS_CONFIG}${CPU_ARCH_TAG}${COMPILER_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}.${OBJDIR_SUFFIX}" + +case "$target_os" in +cygwin*|mks*) + CC="\$(CYGWIN_WRAPPER) $CC" + CXX="\$(CYGWIN_WRAPPER) $CXX" + RC="\$(CYGWIN_WRAPPER) $RC" + ;; +esac + +# Check whether --enable-wrap-malloc was given. +if test "${enable_wrap_malloc+set}" = set; then : + enableval=$enable_wrap_malloc; if test "$enableval" = "yes"; then + _WRAP_MALLOC=1 + fi +fi + + +if test -n "$_WRAP_MALLOC"; then + if test -n "$GNU_CC"; then + WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=malloc,--wrap=calloc,--wrap=valloc,--wrap=free,--wrap=realloc,--wrap=memalign" + WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=__builtin_new,--wrap=__builtin_vec_new,--wrap=__builtin_delete,--wrap=__builtin_vec_delete" + WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=strdup,--wrap=strndup" + WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=posix_memalign,--wrap=malloc_usable_size" + else + as_fn_error $? "--enable-wrap-malloc is not supported for non-GNU toolchains" "$LINENO" 5 + fi +fi + + +# Check whether --with-wrap-malloc was given. +if test "${with_wrap_malloc+set}" = set; then : + withval=$with_wrap_malloc; WRAP_LDFLAGS="${WRAP_LDFLAGS} $withval" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +MAKEFILES=" + Makefile + config/Makefile + config/autoconf.mk + config/nsprincl.mk + config/nsprincl.sh + config/nspr-config + config/nspr.pc + lib/Makefile + lib/ds/Makefile + lib/libc/Makefile + lib/libc/include/Makefile + lib/libc/src/Makefile + lib/tests/Makefile + pkg/Makefile + pr/Makefile + pr/include/Makefile + pr/include/md/Makefile + pr/include/obsolete/Makefile + pr/include/private/Makefile + pr/src/Makefile + pr/src/io/Makefile + pr/src/linking/Makefile + pr/src/malloc/Makefile + pr/src/md/Makefile + pr/src/md/${PR_MD_ARCH_DIR}/Makefile + pr/src/memory/Makefile + pr/src/misc/Makefile + pr/src/threads/Makefile + pr/tests/Makefile + pr/tests/dll/Makefile +" + +if test "$OS_TARGET" = "Linux"; then + MAKEFILES="$MAKEFILES + pkg/linux/Makefile + " +elif test "$OS_TARGET" = "SunOS"; then + MAKEFILES="$MAKEFILES + pkg/solaris/Makefile + pkg/solaris/SUNWpr/Makefile + pkg/solaris/SUNWprd/Makefile + " +fi + +if test -z "$USE_PTHREADS" && test -z "$USE_BTHREADS"; then + MAKEFILES="$MAKEFILES + pr/src/threads/combined/Makefile + " +elif test -n "$USE_PTHREADS"; then + MAKEFILES="$MAKEFILES + pr/src/pthreads/Makefile + " +elif test -n "$USE_BTHREADS"; then + MAKEFILES="$MAKEFILES + pr/src/bthreads/Makefile + " +fi + +if test -n "$USE_CPLUS"; then + MAKEFILES="$MAKEFILES + pr/src/cplus/Makefile + pr/src/cplus/tests/Makefile + " +fi + +echo $MAKEFILES > unallmakefiles + +ac_config_files="$ac_config_files $MAKEFILES" + +ac_config_commands="$ac_config_commands default" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "$MAKEFILES") CONFIG_FILES="$CONFIG_FILES $MAKEFILES" ;; + "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "default":C) chmod +x config/nspr-config ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff -Nru nspr-4.9.5/nspr/configure.in nspr-4.10.7/nspr/configure.in --- nspr-4.9.5/nspr/configure.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/configure.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,3217 @@ +dnl -*- Mode: Autoconf; tab-width: 4; indent-tabs-mode: nil; -*- +dnl +dnl This Source Code Form is subject to the terms of the Mozilla Public +dnl License, v. 2.0. If a copy of the MPL was not distributed with this +dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. + +AC_PREREQ(2.61) +AC_INIT +AC_CONFIG_SRCDIR([pr/include/nspr.h]) + +AC_CONFIG_AUX_DIR(${srcdir}/build/autoconf) +AC_CANONICAL_TARGET + +dnl ======================================================== +dnl = Defaults +dnl ======================================================== +MOD_MAJOR_VERSION=4 +MOD_MINOR_VERSION=10 +MOD_PATCH_VERSION=7 +NSPR_MODNAME=nspr20 +_HAVE_PTHREADS= +USE_PTHREADS= +USE_USER_PTHREADS= +USE_NSPR_THREADS= +USE_N32= +USE_X32= +USE_64= +USE_CPLUS= +USE_IPV6= +USE_MDUPDATE= +_MACOSX_DEPLOYMENT_TARGET= +_OPTIMIZE_FLAGS=-O +_DEBUG_FLAGS=-g +MOZ_DEBUG=1 +MOZ_OPTIMIZE= +OBJDIR='$(OBJDIR_NAME)' +OBJDIR_NAME=. +OBJDIR_SUFFIX=OBJ +NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall' +NOSUCHFILE=/no-such-file +LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)' +LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)' +CYGWIN_WRAPPER= +MACOS_SDK_DIR= +NEXT_ROOT= +MT= +MOZ_OS2_HIGH_MEMORY=1 +PROFILE_GEN_CFLAGS= +PROFILE_GEN_LDFLAGS= +PROFILE_USE_CFLAGS= +PROFILE_USE_LDFLAGS= + +dnl Link in libraries necessary to resolve all symbols for shared libs +RESOLVE_LINK_SYMBOLS= + +dnl ======================================================== +dnl = +dnl = Dont change the following lines. Doing so breaks: +dnl = +dnl = CFLAGS="-foo" ./configure +dnl = +dnl ======================================================== +CFLAGS="${CFLAGS=}" +CXXFLAGS="${CXXFLAGS=}" +LDFLAGS="${LDFLAGS=}" +DLLFLAGS="${DLLFLAGS=}" +HOST_CFLAGS="${HOST_CFLAGS=}" +HOST_LDFLAGS="${HOST_LDFLAGS=}" + +case "$target" in +*-cygwin*|*-mingw*|*-msys*) + # Check to see if we are really running in a msvc environemnt + _WIN32_MSVC= + AC_CHECK_PROGS(CC, cl) + cat > conftest.c </dev/null | grep COMPILER) +EOF + if test -n "$dummy"; then + _WIN32_MSVC=1 + CXX=$CC + fi + rm -f conftest.c + ;; +*-mks*) + _WIN32_MSVC=1 + ;; +esac + +if test -n "$_WIN32_MSVC"; then + SKIP_PATH_CHECKS=1 + SKIP_COMPILER_CHECKS=1 + SKIP_LIBRARY_CHECKS=1 +fi + +dnl ======================================================== +dnl = Android uses a very custom (hacky) toolchain; we need to do this +dnl = here, so that the compiler checks can succeed +dnl ======================================================== + +AC_ARG_WITH(android-ndk, +[ --with-android-ndk=DIR + location where the Android NDK can be found], + android_ndk=$withval) + +AC_ARG_WITH(android-toolchain, +[ --with-android-toolchain=DIR + location of the Android toolchain], + android_toolchain=$withval) + +dnl The default android_version is different for each target cpu. +case "$target_cpu" in +arm) + android_version=5 + ;; +i?86|mipsel) + android_version=9 + ;; +esac + +AC_ARG_WITH(android-version, +[ --with-android-version=VER + Android platform version, default 5 for arm, 9 for x86/mips], + android_version=$withval) + +AC_ARG_WITH(android-platform, +[ --with-android-platform=DIR + location of platform dir], + android_platform=$withval) + +case "$target" in +arm-linux*-android*|*-linuxandroid*) + android_tool_prefix="arm-linux-androideabi" + ;; +i?86-*android*) + android_tool_prefix="i686-linux-android" + ;; +mipsel-*android*) + android_tool_prefix="mipsel-linux-android" + ;; +*) + android_tool_prefix="$target_os" + ;; +esac + +dnl ======================================================== +dnl = Gonk is a fork of Android used for Mozilla's B2G project. +dnl = Configuration is done largely by the top level config +dnl = and the specified gonk directory doesn't matter here. +dnl ======================================================== + +AC_ARG_WITH(gonk, +[ --with-gonk=DIR location of gonk dir], + gonkdir=$withval) + +if test -n "$gonkdir" ; then + dnl Most things are directly configured by env vars when building for gonk + + dnl prevent cross compile section from using these flags as host flags + if test -z "$HOST_CPPFLAGS" ; then + HOST_CPPFLAGS=" " + fi + if test -z "$HOST_CFLAGS" ; then + HOST_CFLAGS=" " + fi + if test -z "$HOST_CXXFLAGS" ; then + HOST_CXXFLAGS=" " + fi + if test -z "$HOST_LDFLAGS" ; then + HOST_LDFLAGS=" " + fi + + AC_DEFINE(ANDROID) +else +case "$target" in +*-android*|*-linuxandroid*) + if test -z "$android_ndk" ; then + AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.]) + fi + + if test -z "$android_toolchain" ; then + AC_MSG_CHECKING([for android toolchain directory]) + + kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"` + + case "$target_cpu" in + arm) + target_name=arm-linux-androideabi-4.4.3 + ;; + i?86) + target_name=x86-4.4.3 + ;; + mipsel) + target_name=mipsel-linux-android-4.4.3 + ;; + esac + android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86 + + if test -d "$android_toolchain" ; then + AC_MSG_RESULT([$android_toolchain]) + else + AC_MSG_ERROR([not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain.]) + fi + fi + + if test -z "$android_platform" ; then + AC_MSG_CHECKING([for android platform directory]) + + case "$target_cpu" in + arm) + target_name=arm + ;; + i?86) + target_name=x86 + ;; + mipsel) + target_name=mips + ;; + esac + + android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name" + + if test -d "$android_platform" ; then + AC_MSG_RESULT([$android_platform]) + else + AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.]) + fi + fi + + dnl Old NDK support. If minimum requirement is changed to NDK r8b, + dnl please remove this. + case "$target_cpu" in + i?86) + if ! test -e "$android_toolchain"/bin/"$android_tool_prefix"-gcc; then + dnl Old NDK toolchain name + android_tool_prefix="i686-android-linux" + fi + ;; + esac + + dnl set up compilers + AS="$android_toolchain"/bin/"$android_tool_prefix"-as + CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc + CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++ + CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp + LD="$android_toolchain"/bin/"$android_tool_prefix"-ld + AR="$android_toolchain"/bin/"$android_tool_prefix"-ar + RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib + STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip + + CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS" + CFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CFLAGS" + CXXFLAGS="-mandroid -I$android_platform/usr/include -fpic -fno-short-enums -fno-exceptions $CXXFLAGS" + LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform $LDFLAGS" + + dnl prevent cross compile section from using these flags as host flags + if test -z "$HOST_CPPFLAGS" ; then + HOST_CPPFLAGS=" " + fi + if test -z "$HOST_CFLAGS" ; then + HOST_CFLAGS=" " + fi + if test -z "$HOST_CXXFLAGS" ; then + HOST_CXXFLAGS=" " + fi + if test -z "$HOST_LDFLAGS" ; then + HOST_LDFLAGS=" " + fi + + AC_DEFINE(ANDROID) + ;; +esac +fi + +dnl ======================================================== +dnl = +dnl = Check options that may affect the compiler +dnl = +dnl ======================================================== +dist_prefix='${MOD_DEPTH}/dist' +dist_bindir='${dist_prefix}/bin' +dist_includedir='${dist_prefix}/include/nspr' +dist_libdir='${dist_prefix}/lib' +dnl If the --includedir option was not specified, add '/nspr' to autoconf's +dnl default value of includedir. +if test "${includedir}" = '${prefix}/include'; then + includedir='${prefix}/include/nspr' +fi + +AC_ARG_WITH(dist-prefix, + [ --with-dist-prefix=DIST_PREFIX + place build files in DIST_PREFIX [dist]], + dist_prefix=$withval) + +AC_ARG_WITH(dist-bindir, + [ --with-dist-bindir=DIR build execuatables in DIR [DIST_PREFIX/bin]], + dist_bindir=$withval) + +AC_ARG_WITH(dist-includedir, + [ --with-dist-includedir=DIR + build include files in DIR [DIST_PREFIX/include/nspr]], + dist_includedir=$withval) + +AC_ARG_WITH(dist-libdir, + [ --with-dist-libdir=DIR build library files in DIR [DIST_PREFIX/lib]], + dist_libdir=$withval) + +AC_SUBST(dist_prefix) +AC_SUBST(dist_bindir) +AC_SUBST(dist_includedir) +AC_SUBST(dist_libdir) + +dnl Check if NSPR is being compiled for Mozilla +dnl Let --with-arg override environment setting +dnl +AC_ARG_WITH(mozilla, + [ --with-mozilla Compile NSPR with Mozilla support], + [ if test "$withval" = "yes"; then + AC_DEFINE(MOZILLA_CLIENT) + MOZILLA_CLIENT=1 + else + MOZILLA_CLIENT= + fi], + [ if test -n "$MOZILLA_CLIENT"; then + AC_DEFINE(MOZILLA_CLIENT) + fi]) + +AC_ARG_ENABLE(optimize, + [ --enable-optimize[=OPT] Enable code optimizations (ie. -O2) ], + [ if test "$enableval" != "no"; then + MOZ_OPTIMIZE=1 + if test -n "$enableval" -a "$enableval" != "yes"; then + _OPTIMIZE_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` + _SAVE_OPTIMIZE_FLAGS=$_OPTIMIZE_FLAGS + fi + else + MOZ_OPTIMIZE= + fi ]) + +AC_ARG_ENABLE(debug, + [ --enable-debug[=DBG] Enable debugging (using compiler flags DBG)], + [ if test "$enableval" != "no"; then + MOZ_DEBUG=1 + MOZ_DEBUG_SYMBOLS=1 + if test -n "$enableval" -a "$enableval" != "yes"; then + _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` + _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS + fi + else + MOZ_DEBUG= + fi ], + MOZ_DEBUG_SYMBOLS=1) + +AC_ARG_ENABLE(debug-symbols, + [ --enable-debug-symbols[=DBG] Enable debugging symbols + (using compiler flags DBG)], + [ if test "$enableval" != "no"; then + MOZ_DEBUG_SYMBOLS=1 + if test -n "$enableval" -a "$enableval" != "yes"; then + if test -z "$_SAVE_DEBUG_FLAGS"; then + _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'` + _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS + else + AC_MSG_ERROR([--enable-debug-symbols flags cannot be used with --enable-debug flags]) + fi + fi + else + MOZ_DEBUG_SYMBOLS= + fi ]) + +AC_ARG_ENABLE(win32-target, + [ --enable-win32-target=\$t + Specify win32 flavor. (WIN95 or WINNT)], + OS_TARGET=`echo $enableval | tr a-z A-Z`) + +AC_ARG_ENABLE(symbian-target, + [ --enable-symbian-target=\$t + Specify symbian flavor. (WINSCW or GCCE)], + OS_TARGET=`echo $enableval | tr a-z A-Z`) + +AC_ARG_ENABLE(debug-rtl, + [ --enable-debug-rtl Use the MSVC debug runtime library], + [ if test "$enableval" = "yes"; then + USE_DEBUG_RTL=1 + else + USE_DEBUG_RTL=0 + fi ]) + +AC_ARG_ENABLE(static-rtl, + [ --enable-static-rtl Use the MSVC static runtime library], + [ if test "$enableval" = "yes"; then + USE_STATIC_RTL=1 + fi ]) + +AC_ARG_ENABLE(n32, + [ --enable-n32 Enable n32 ABI support (IRIX only)], + [ if test "$enableval" = "yes"; then + USE_N32=1 + else if test "$enableval" = "no"; then + USE_N32= + fi + fi ]) + +AC_ARG_ENABLE(x32, + [ --enable-x32 Enable x32 ABI support (x86_64 only)], + [ if test "$enableval" = "yes"; then + USE_X32=1 + else if test "$enableval" = "no"; then + USE_X32= + fi + fi ]) + +AC_ARG_ENABLE(64bit, + [ --enable-64bit Enable 64-bit support (on certain platforms)], + [ if test "$enableval" = "yes"; then + USE_64=1 + fi ]) + +AC_ARG_ENABLE(mdupdate, + [ --enable-mdupdate Enable use of certain compilers' mdupdate feature], + [ if test "$enableval" = "yes"; then + USE_MDUPDATE=1 + fi ]) + +AC_ARG_ENABLE(cplus, + [ --enable-cplus Enable some c++ api routines], + [ if test "$enableval" = "yes"; then + USE_CPLUS=1 + fi]) + +AC_ARG_WITH(arm-kuser, + [ --with-arm-kuser Use kuser helpers (Linux/ARM only) + (Requires kernel 2.6.13 or later)], + [ if test "$withval" = "yes"; then + AC_DEFINE(_PR_ARM_KUSER) + fi ]) + +dnl ======================================================== +dnl = Mac OS X SDK support +dnl ======================================================== +AC_ARG_WITH(macos-sdk, + [ --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)], + MACOS_SDK_DIR=$withval) + +AC_ARG_ENABLE(macos-target, + [ --enable-macos-target=VER + Set the minimum MacOS version needed at runtime + [10.2 for ppc, 10.4 for x86]], + [_MACOSX_DEPLOYMENT_TARGET=$enableval]) + +dnl ======================================================== +dnl = +dnl = Set the threading model +dnl = +dnl ======================================================== +case "$target" in + +*-aix*) + case "${target_os}" in + aix3.2*) + USE_NSPR_THREADS=1 + ;; + *) + USE_PTHREADS=1 + ;; + esac + ;; + +esac + +dnl ======================================================== +dnl = +dnl = Set the default C compiler +dnl = +dnl ======================================================== +if test -z "$CC"; then + case "$target" in + + *-aix*) + if test -z "$USE_NSPR_THREADS"; then + CC=xlc_r + else + CC=xlc + fi + ;; + + *-hpux*) + CC=cc + ;; + + *-irix*) + CC=cc + ;; + + *-osf*) + CC=cc + ;; + + *-solaris*) + CC=cc + ;; + + esac +fi + +dnl ======================================================== +dnl = +dnl = Set the default C++ compiler +dnl = +dnl ======================================================== +if test -z "$CXX"; then + case "$target" in + + *-aix*) + if test -z "$USE_NSPR_THREADS"; then + CXX=xlC_r + else + CXX=xlC + fi + ;; + + *-hpux*) + case "${target_os}" in + hpux10.30) + CXX=aCC + ;; + hpux11.*) + CXX=aCC + ;; + *) + CXX=CC + ;; + esac + ;; + + *-irix*) + CXX=CC + ;; + + *-osf*) + CXX=cxx + ;; + + *-solaris*) + CXX=CC + ;; + + esac +fi + +if test -z "$SKIP_PATH_CHECKS"; then + AC_PATH_PROG(WHOAMI, $WHOAMI whoami, echo not_whoami) +fi + +if test -n "$MOZ_DEBUG"; then + AC_DEFINE(DEBUG) + DEFINES="$DEFINES -UNDEBUG" + + case "${target_os}" in + beos*) + DEFINES="$DEFINES -DDEBUG_${USER}" + ;; + mks*|cygwin*|mingw*|msys*|os2*) + DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`" + ;; + *) + DEFINES="$DEFINES -DDEBUG_`$WHOAMI`" + ;; + esac +else + AC_DEFINE(NDEBUG) + DEFINES="$DEFINES -UDEBUG" +fi + +if test -z "$SKIP_COMPILER_CHECKS"; then +dnl ======================================================== +dnl Checks for compilers. +dnl ======================================================== +if test "$target" != "$host"; then + echo "cross compiling from $host to $target" + cross_compiling=yes + + case "$build:$target" in + powerpc-apple-darwin8*:i?86-apple-darwin*) + dnl The Darwin cross compiler doesn't necessarily point itself at a + dnl root that has libraries for the proper architecture, it defaults + dnl to the system root. The libraries in the system root on current + dnl versions of PPC OS X 10.4 aren't fat, so these target compiler + dnl checks will fail. Fake a working SDK in that case. + _SAVE_CFLAGS=$CFLAGS + _SAVE_CXXFLAGS=$CXXFLAGS + CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CFLAGS" + CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS" + ;; + *:arm*-apple-darwin*) + dnl The arm compiler doesn't appear to know about its root by default, + dnl so explicitly pass it one here. Later on we'll put this in CFLAGS + dnl anyway. + _SAVE_CFLAGS=$CFLAGS + _SAVE_CXXFLAGS=$CXXFLAGS + CFLAGS="-isysroot $MACOS_SDK_DIR $CFLAGS" + CXXFLAGS="-isysroot $MACOS_SDK_DIR $CXXFLAGS" + ;; + esac + + AC_CHECK_PROGS(CC, $CC "${target_alias}-gcc" "${target}-gcc", echo) + unset ac_cv_prog_CC + dnl Now exit the conditional block to invoke AC_PROG_CC. +fi + +dnl In the latest versions of autoconf, AC_PROG_CC is a one-shot macro, +dnl declared with AC_DEFUN_ONCE. So it must not be expanded inside a +dnl conditional block. Invoke AC_PROG_CC outside any conditional block +dnl and before invoking AC_TRY_COMPILE (which requires AC_PROG_CC). +AC_PROG_CC + +dnl Reenter the conditional blocks after invoking AC_PROG_CC. +if test "$target" != "$host"; then + if test -n "$USE_CPLUS"; then + AC_CHECK_PROGS(CXX, $CXX "${target_alias}-g++" "${target}-g++", echo) + unset ac_cv_prog_CXX + AC_PROG_CXX + fi + + case "$build:$target" in + powerpc-apple-darwin8*:i?86-apple-darwin*|*:arm*-apple-darwin*) + dnl Revert the changes made above. From this point on, the target + dnl compiler will never be used without applying the SDK to CFLAGS + dnl (see --with-macos-sdk below). + CFLAGS=$_SAVE_CFLAGS + CXXFLAGS=$_SAVE_CXXFLAGS + ;; + esac + + AC_CHECK_PROGS(RANLIB, $RANLIB "${target_alias}-ranlib" "${target}-ranlib", echo) + AC_CHECK_PROGS(AR, $AR "${target_alias}-ar" "${target}-ar", echo) + AC_CHECK_PROGS(AS, $AS "${target_alias}-as" "${target}-as", echo) + AC_CHECK_PROGS(LD, $LD "${target_alias}-ld" "${target}-ld", echo) + AC_CHECK_PROGS(STRIP, $STRIP "${target_alias}-strip" "${target}-strip", echo) + AC_CHECK_PROGS(WINDRES, $WINDRES "${target_alias}-windres" "${target}-windres", echo) + + _SAVE_CC="$CC" + _SAVE_CFLAGS="$CFLAGS" + _SAVE_LDFLAGS="$LDFLAGS" + + AC_MSG_CHECKING([for $host compiler]) + AC_CHECK_PROGS(HOST_CC, $HOST_CC gcc cc /usr/ucb/cc, "") + if test -z "$HOST_CC"; then + AC_MSG_ERROR([no acceptable cc found in \$PATH]) + fi + AC_MSG_RESULT([$HOST_CC]) + if test -z "$HOST_CFLAGS"; then + HOST_CFLAGS="$CFLAGS" + fi + if test -z "$HOST_LDFLAGS"; then + HOST_LDFLAGS="$LDFLAGS" + fi + + CC="$HOST_CC" + CFLAGS="$HOST_CFLAGS" + LDFLAGS="$HOST_LDFLAGS" + + AC_MSG_CHECKING([whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works]) + AC_TRY_COMPILE([], [return 0;], + [AC_MSG_RESULT([yes])], + [AC_MSG_ERROR([installation or configuration problem: $host compiler $HOST_CC cannot create executables.])] ) + + CC=$_SAVE_CC + CFLAGS=$_SAVE_CFLAGS + LDFLAGS=$_SAVE_LDFLAGS +else + if test -n "$USE_CPLUS"; then + if test "$CC" = "cl" -a -z "$CXX"; then + CXX=$CC + else + AC_PROG_CXX + fi + fi + AC_PROG_RANLIB + AC_PATH_PROGS(AS, as, $CC) + AC_PATH_PROGS(AR, ar, echo not_ar) + AC_PATH_PROGS(LD, ld link, echo not_ld) + AC_PATH_PROGS(STRIP, strip, echo not_strip) + AC_PATH_PROGS(WINDRES, windres, echo not_windres) + if test -z "$HOST_CC"; then + HOST_CC="$CC" + fi + if test -z "$HOST_CFLAGS"; then + HOST_CFLAGS="$CFLAGS" + fi +fi + +AC_PROG_CPP + +if test "$GCC" = "yes"; then + GNU_CC=1 +fi +if test "$GXX" = "yes"; then + GNU_CXX=1 +fi +if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then + GNU_AS=1 +fi +rm -f a.out + +case "$build:$target" in + i?86-apple-darwin*:powerpc-apple-darwin*) + dnl cross_compiling will have erroneously been set to "no" in this + dnl case, because the x86 build host is able to run ppc code in a + dnl translated environment, making a cross compiler appear native. + cross_compiling=yes + ;; +esac + +if test "$cross_compiling" = "yes"; then + CROSS_COMPILE=1 +else + CROSS_COMPILE= +fi + +dnl ======================================================== +dnl Check for gcc -pipe support +dnl ======================================================== +AC_MSG_CHECKING([for gcc -pipe support]) +if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then + echo '#include ' > dummy-hello.c + echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c + ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5 + cat dummy-hello.s | ${AS} -o dummy-hello.S - 2>&5 + if test $? = 0; then + _res_as_stdin="yes" + else + _res_as_stdin="no" + fi + if test "$_res_as_stdin" = "yes"; then + _SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -pipe" + AC_TRY_COMPILE( [ #include ], + [printf("Hello World\n");], + [_res_gcc_pipe="yes"], + [_res_gcc_pipe="no"] ) + CFLAGS=$_SAVE_CFLAGS + fi + if test "$_res_as_stdin" = "yes" && test "$_res_gcc_pipe" = "yes"; then + _res="yes"; + CFLAGS="$CFLAGS -pipe" + CXXFLAGS="$CXXFLAGS -pipe" + else + _res="no" + fi + rm -f dummy-hello.c dummy-hello.s dummy-hello.S dummy-hello a.out + AC_MSG_RESULT([$_res]) +else + AC_MSG_RESULT([no]) +fi + +dnl ======================================================== +dnl Profile guided optimization +dnl ======================================================== +dnl Test for profiling options +dnl Under gcc 3.4+, use -fprofile-generate/-fprofile-use + +_SAVE_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction" + +AC_MSG_CHECKING([whether C compiler supports -fprofile-generate]) +AC_TRY_COMPILE([], [return 0;], + [ PROFILE_GEN_CFLAGS="-fprofile-generate" + result="yes" ], result="no") +AC_MSG_RESULT([$result]) + +if test $result = "yes"; then + PROFILE_GEN_LDFLAGS="-fprofile-generate" + PROFILE_USE_CFLAGS="-fprofile-use -fprofile-correction -Wcoverage-mismatch" + PROFILE_USE_LDFLAGS="-fprofile-use" +fi + +CFLAGS="$_SAVE_CFLAGS" + +dnl =============================================================== +dnl Check for .hidden assembler directive and visibility attribute. +dnl Borrowed from glibc configure.in +dnl =============================================================== +if test "$GNU_CC"; then + AC_CACHE_CHECK(for visibility(hidden) attribute, + ac_cv_visibility_hidden, + [cat > conftest.c </dev/null 2>&1; then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + ac_cv_visibility_hidden=yes + fi + fi + rm -f conftest.[cs] + ]) + if test "$ac_cv_visibility_hidden" = "yes"; then + AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE) + AC_CACHE_CHECK(for visibility pragma support, + ac_cv_visibility_pragma, + [cat > conftest.c </dev/null 2>&1; then + if grep '\.hidden.*foo_hidden' conftest.s >/dev/null; then + if ! grep '\.hidden.*foo_default' conftest.s > /dev/null; then + ac_cv_visibility_pragma=yes + fi + fi + fi + rm -f conftest.[cs] + ]) + if test "$ac_cv_visibility_pragma" = "yes"; then + AC_DEFINE(HAVE_VISIBILITY_PRAGMA) + # To work around a build problem on Linux x86-64 (Bugzilla bug + # 293438), we use the -fvisibility=hidden flag. This flag is less + # optimal than #pragma GCC visibility push(hidden) because the flag + # assumes that symbols defined outside the current source file have + # the default visibility. This has the advantage that we don't need + # to wrap system header files, but has the disadvantage that calls + # to hidden symbols defined in other source files cannot be + # optimized by the compiler. The -fvisibility=hidden flag does + # hide and export symbols correctly. + #VISIBILITY_FLAGS='-I$(dist_includedir)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' + #WRAP_SYSTEM_INCLUDES=1 + VISIBILITY_FLAGS="-fvisibility=hidden" + WRAP_SYSTEM_INCLUDES= + fi + fi +fi # GNU_CC + +fi # SKIP_COMPILER_CHECKS + +dnl ======================================================== +dnl Checks for programs. +dnl ======================================================== +if test -z "$SKIP_PATH_CHECKS"; then + AC_PATH_PROGS(PERL, perl5 perl, echo not_perl) +elif test -z "$PERL"; then + PERL=perl +fi + +dnl ======================================================== +dnl Default platform specific options +dnl ======================================================== +OBJ_SUFFIX=o +LIB_SUFFIX=a +DLL_SUFFIX=so +ASM_SUFFIX=s +MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@' +PR_MD_ASFILES= +PR_MD_CSRCS= +PR_MD_ARCH_DIR=unix +AR_FLAGS='cr $@' +AS='$(CC)' +ASFLAGS='$(CFLAGS)' + +if test -n "$CROSS_COMPILE"; then + OS_ARCH=`echo $target_os | sed -e 's|/|_|g'` + OS_RELEASE= + OS_TEST="${target_cpu}" + case "${target_os}" in + linux*) OS_ARCH=Linux ;; + solaris*) OS_ARCH=SunOS OS_RELEASE=5 ;; + mingw*) OS_ARCH=WINNT CPU_ARCH=x86 ;; + darwin*) OS_ARCH=Darwin ;; + riscos*) OS_ARCH=RISCOS ;; + esac +else + OS_ARCH=`uname -s | sed -e 's|/|_|g'` + OS_RELEASE=`uname -r` + OS_TEST=`uname -m` +fi + +if test "$OS_ARCH" = "IRIX64"; then + OS_ARCH=IRIX +fi + +if test "$OS_ARCH" = "AIX"; then + OS_RELEASE=`uname -v`.`uname -r` +fi + +if test "$OS_ARCH" = "FreeBSD"; then + OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'` +fi + +if test "$OS_ARCH" = "Linux"; then + OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'` + OS_RELEASE=`echo $OS_RELEASE | awk -F\. '{ print $1 "." $2 }'` +fi + +####################################################################### +# Master "Core Components" macros for getting the OS target # +####################################################################### + +# +# Note: OS_TARGET should be specified on the command line for gmake. +# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built. +# The difference between the Win95 target and the WinNT target is that +# the WinNT target uses Windows NT specific features not available +# in Windows 95. The Win95 target will run on Windows NT, but (supposedly) +# at lesser performance (the Win95 target uses threads; the WinNT target +# uses fibers). +# +# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no +# cross-compilation. +# + +# +# The following hack allows one to build on a WIN95 machine (as if +# s/he were cross-compiling on a WINNT host for a WIN95 target). +# It also accomodates for MKS's uname.exe. If you never intend +# to do development on a WIN95 machine, you don't need this hack. +# +case "$OS_ARCH" in +Windows_95) + OS_ARCH=Windows_NT + OS_TARGET=WIN95 + ;; +Windows_98) + OS_ARCH=Windows_NT + OS_TARGET=WIN95 + ;; +CYGWIN_9*|CYGWIN_ME*) + OS_ARCH='CYGWIN_NT-4.0' + OS_TARGET=WIN95 + ;; +OS_2) + OS_ARCH=OS2 + OS_TARGET=OS2 + ;; +esac + +# +# On WIN32, we also define the variable CPU_ARCH. +# + +case "$OS_ARCH" in +Windows_NT) +# +# If uname -s returns "Windows_NT", we assume that we are using +# the uname.exe in MKS toolkit. +# +# The -r option of MKS uname only returns the major version number. +# So we need to use its -v option to get the minor version number. +# Moreover, it doesn't have the -p option, so we need to use uname -m. +# + OS_ARCH=WINNT + OS_MINOR_RELEASE=`uname -v` + if test "$OS_MINOR_RELEASE" = "00"; then + OS_MINOR_RELEASE=0 + fi + OS_RELEASE="${OS_RELEASE}.${OS_MINOR_RELEASE}" + CPU_ARCH=`uname -m` + # + # MKS's uname -m returns "586" on a Pentium machine. + # + if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then + CPU_ARCH=x86 + fi + ;; +CYGWIN_NT*|MINGW*_NT*|MSYS_NT*) +# +# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using +# the uname.exe in the Cygwin tools. +# If uname -s returns "MINGW32_NT-5.1", we assume that we are using +# the uname.exe in the MSYS tools. +# If uname -s returns "MSYS_NT-6.3", we assume that we are using +# the uname.exe in the MSYS2 tools. +# + OS_RELEASE=`expr $OS_ARCH : '.*NT-\(.*\)'` + OS_ARCH=WINNT + CPU_ARCH=`uname -m` + # + # Cygwin's uname -m returns "i686" on a Pentium Pro machine. + # + if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then + CPU_ARCH=x86 + fi + ;; +esac + +if test -n "$MOZILLA_CLIENT" && test "$OS_ARCH" = "WINNT"; then + OS_TARGET=WIN95 + if test -n "$MOZ_DEBUG" -a -z "$USE_DEBUG_RTL"; then + USE_DEBUG_RTL=1 + fi +fi +if test -z "$OS_TARGET"; then + OS_TARGET=$OS_ARCH +fi +if test "$OS_TARGET" = "WIN95"; then + OS_RELEASE="4.0" +fi +OS_CONFIG="${OS_TARGET}${OS_RELEASE}" + +dnl ======================================================== +dnl Enable high-memory support on OS/2 by default. +dnl ======================================================== +AC_ARG_ENABLE(os2-high-mem, + [ --disable-os2-high-mem Disable high-memory support on OS/2], + [ if test "$enableval" = "no"; then + MOZ_OS2_HIGH_MEMORY= + else + MOZ_OS2_HIGH_MEMORY=1 + fi ]) + +dnl ======================================================== +dnl = ARM toolchain tweaks +dnl ======================================================== + +dnl Defaults +MOZ_ALIGN=toolchain-default + +case "$target" in +arm*-android*|arm*-linuxandroid*) + MOZ_THUMB=yes + MOZ_ARCH=armv7-a + MOZ_FPU=vfp + MOZ_FLOAT_ABI=softfp + MOZ_SOFT_FLOAT=yes + MOZ_ALIGN=no + ;; +arm*-*) + if test -n "$MOZ_PLATFORM_MAEMO"; then + MOZ_THUMB=no + MOZ_ARCH=armv7-a + MOZ_FLOAT_ABI=softfp + fi + if test "$MOZ_PLATFORM_MAEMO" = 6; then + MOZ_THUMB=yes + fi + ;; +esac + +dnl Kept for compatibility with some buildbot mozconfig +AC_ARG_ENABLE(thumb2, [], MOZ_THUMB=$enableval) + +AC_ARG_WITH(thumb, +[ --with-thumb[[=yes|no|toolchain-default]]] +[ Use Thumb instruction set (-mthumb)], + if test -z "$GNU_CC"; then + AC_MSG_ERROR([--with-thumb is not supported on non-GNU toolchain-defaults]) + fi + MOZ_THUMB=$withval) + +AC_ARG_WITH(thumb-interwork, +[ --with-thumb-interwork[[=yes|no|toolchain-default]] + Use Thumb/ARM instuctions interwork (-mthumb-interwork)], + if test -z "$GNU_CC"; then + AC_MSG_ERROR([--with-thumb-interwork is not supported on non-GNU toolchain-defaults]) + fi + MOZ_THUMB_INTERWORK=$withval) + +AC_ARG_WITH(arch, +[ --with-arch=[[type|toolchain-default]] + Use specific CPU features (-march=type)], + if test -z "$GNU_CC"; then + AC_MSG_ERROR([--with-arch is not supported on non-GNU toolchain-defaults]) + fi + MOZ_ARCH=$withval) + +AC_ARG_WITH(fpu, +[ --with-fpu=[[type|toolchain-default]] + Use specific FPU type (-mfpu=type)], + if test -z "$GNU_CC"; then + AC_MSG_ERROR([--with-fpu is not supported on non-GNU toolchain-defaults]) + fi + MOZ_FPU=$withval) + +AC_ARG_WITH(float-abi, +[ --with-float-abi=[[type|toolchain-default]] + Use specific arm float ABI (-mfloat-abi=type)], + if test -z "$GNU_CC"; then + AC_MSG_ERROR([--with-float-abi is not supported on non-GNU toolchain-defaults]) + fi + MOZ_FLOAT_ABI=$withval) + +AC_ARG_WITH(soft-float, +[ --with-soft-float[[=yes|no|toolchain-default]] + Use soft float library (-msoft-float)], + if test -z "$GNU_CC"; then + AC_MSG_ERROR([--with-soft-float is not supported on non-GNU toolchain-defaults]) + fi + MOZ_SOFT_FLOAT=$withval) + +case "$MOZ_ARCH" in +toolchain-default|"") + arch_flag="" + ;; +*) + arch_flag="-march=$MOZ_ARCH" + ;; +esac + +case "$MOZ_THUMB" in +yes) + MOZ_THUMB2=1 + thumb_flag="-mthumb" + ;; +no) + MOZ_THUMB2= + thumb_flag="-marm" + ;; +*) + _SAVE_CFLAGS="$CFLAGS" + CFLAGS="$arch_flag" + AC_TRY_COMPILE([],[return sizeof(__thumb2__);], + MOZ_THUMB2=1, + MOZ_THUMB2=) + CFLAGS="$_SAVE_CFLAGS" + thumb_flag="" + ;; +esac + +case "$MOZ_THUMB_INTERWORK" in +yes) + thumb_interwork_flag="-mthumb-interwork" + ;; +no) + thumb_interwork_flag="-mno-thumb-interwork" + ;; +*) # toolchain-default + thumb_interwork_flag="" + ;; +esac + +case "$MOZ_FPU" in +toolchain-default|"") + fpu_flag="" + ;; +*) + fpu_flag="-mfpu=$MOZ_FPU" + ;; +esac + +case "$MOZ_FLOAT_ABI" in +toolchain-default|"") + float_abi_flag="" + ;; +*) + float_abi_flag="-mfloat-abi=$MOZ_FLOAT_ABI" + ;; +esac + +case "$MOZ_SOFT_FLOAT" in +yes) + soft_float_flag="-msoft-float" + ;; +no) + soft_float_flag="-mno-soft-float" + ;; +*) # toolchain-default + soft_float_flag="" + ;; +esac + +case "$MOZ_ALIGN" in +toolchain-default|"") + align_flag="" + ;; +no) + align_flag="-mno-unaligned-access" + ;; +yes) + align_flag="-munaligned-access" + ;; +*) + align_flag="" + ;; +esac + +if test -n "$align_flag"; then + _SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $align_flag" + AC_MSG_CHECKING(whether alignment flag ($align_flag) is supported) + AC_TRY_COMPILE([],[],,align_flag="") + CFLAGS="$_SAVE_CFLAGS" +fi + +dnl Use echo to avoid accumulating space characters +all_flags=`echo $arch_flag $thumb_flag $thumb_interwork_flag $fpu_flag $float_abi_flag $soft_float_flag $align_flag` +if test -n "$all_flags"; then + _SAVE_CFLAGS="$CFLAGS" + CFLAGS="$all_flags" + AC_MSG_CHECKING(whether the chosen combination of compiler flags ($all_flags) works) + AC_TRY_COMPILE([],[return 0;], + AC_MSG_RESULT([yes]), + AC_MSG_ERROR([no])) + + CFLAGS="$_SAVE_CFLAGS $all_flags" + CXXFLAGS="$CXXFLAGS $all_flags" + ASFLAGS="$ASFLAGS $all_flags" + if test -n "$thumb_flag"; then + LDFLAGS="$LDFLAGS $thumb_flag" + fi +fi + +dnl ======================================================== +dnl Override of system specific host options +dnl ======================================================== +case "$host" in +*-mingw*|*-msys*) + NSINSTALL=nsinstall + ;; +*-cygwin*|*-mks*) + NSINSTALL='$(CYGWIN_WRAPPER) nsinstall' + if test `echo "${PATH}" | grep -c \;` = 0; then + CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper' + fi + ;; +*-beos*) + HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE" + ;; +*os2*) + ;; +*) + HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX" + ;; +esac + +dnl ======================================================== +dnl Override of system specific target options +dnl ======================================================== +case "$target" in + +*-aix*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(AIX) + AC_DEFINE(SYSV) + DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib' + AC_CHECK_HEADER(sys/atomic_op.h, AC_DEFINE(AIX_HAVE_ATOMIC_OP_H)) + case "${target_os}" in + aix3.2*) + AC_DEFINE(AIX_RENAME_SELECT) + AC_DEFINE(_PR_NO_LARGE_FILES) + AIX_LINK_OPTS='-bnso -berok' + PR_MD_ASFILES=os_AIX.s + ;; + aix4.1*) + AC_DEFINE(AIX_TIMERS) + AC_DEFINE(_PR_NO_LARGE_FILES) + AC_DEFINE(AIX4_1) + MKSHLIB= + DSO_LDOPTS= + AIX_LINK_OPTS='-bnso -berok' + LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)_shr' + LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)_shr' + ;; + aix4.2*) + AC_DEFINE(AIX_TIMERS) + AC_DEFINE(_PR_HAVE_OFF64_T) + AIX_LINK_OPTS='-brtl -bnso -berok' + ;; + aix4.3*) + AC_DEFINE(AIX_TIMERS) + AC_DEFINE(_PR_HAVE_OFF64_T) + AC_DEFINE(AIX4_3_PLUS) + AC_DEFINE(HAVE_SOCKLEN_T) + AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) + USE_IPV6=1 + AIX_LINK_OPTS='-brtl -bnso -berok' + ;; + *) + AC_DEFINE(AIX_TIMERS) + AC_DEFINE(_PR_HAVE_OFF64_T) + AC_DEFINE(AIX4_3_PLUS) + AC_DEFINE(HAVE_SOCKLEN_T) + AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) + USE_IPV6=1 + AIX_LINK_OPTS='-brtl -bnso -berok' + ;; + esac + CFLAGS="$CFLAGS -qro -qroconst" + AIX_WRAP='$(DIST)/lib/aixwrap.o' + AIX_TMP='./_aix_tmp.o' + if test -n "$USE_64"; then + MDCPUCFG_H=_aix64.cfg + OBJECT_MODE=64 + else + MDCPUCFG_H=_aix32.cfg + fi + PR_MD_CSRCS=aix.c + RESOLVE_LINK_SYMBOLS=1 + ;; + +*-beos*) + AC_DEFINE(XP_BEOS) + AC_DEFINE(BeOS) + AC_DEFINE(BEOS) + AC_DEFINE(_POSIX_SOURCE) + DSO_LDOPTS=-nostart + MDCPUCFG_H=_beos.cfg + USE_BTHREADS=1 + PR_MD_ARCH_DIR=beos + RESOLVE_LINK_SYMBOLS=1 + case "${target_cpu}" in + i*86) + _OPTIMIZE_FLAGS=-O2 + _DEBUG_FLAGS='-gdwarf-2 -O0' + MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@' + AC_CHECK_LIB(bind, gethostbyaddr, [OS_LIBS="$OS_LIBS -lbind -lsocket"]) + ;; + powerpc) + CC=mwcc + CCC=mwcc + LD=mwld + DSO_LDOPTS='-xms -export pragma -init _init_routine_ -term _term_routine_ -lroot -lnet /boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o /boot/develop/lib/ppc/start_dyn.o' + _OPTIMIZE_FLAGS=-O2 + _DEBUG_FLAGS='-g -O0' + ;; + esac + ;; + +*-bsdi*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(BSDI) + AC_DEFINE(NEED_BSDREGEX) + + CFLAGS="$CFLAGS -Wall -Wno-format" + CXXFLAGS="$CXXFLAGS -Wall -Wno-format" + + if echo "$OS_TEST" | grep -c 86 >/dev/null; then + CPU_ARCH=x86 + elif echo "$OS_TEST" | grep -c sparc >/dev/null; then + CPU_ARCH=sparc + fi + + MDCPUCFG_H=_bsdi.cfg + PR_MD_CSRCS=bsdi.c + + DSO_LDOPTS=-r + + case "$target_os" in + bsdi1.1*) + AC_DEFINE(_PR_BSDI_JMPBUF_IS_ARRAY) + AC_DEFINE(_PR_STAT_HAS_ONLY_ST_ATIME) + AC_DEFINE(_PR_NEED_H_ERRNO) + MKSHLIB= + DSO_CFLAGS= + DSO_LDOPTS= + ;; + + bsdi2.1*) + AC_DEFINE(_PR_TIMESPEC_HAS_TS_SEC) + AC_DEFINE(_PR_BSDI_JMPBUF_IS_ARRAY) + AC_DEFINE(HAVE_DLL) + AC_DEFINE(USE_DLFCN) + AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC) + PR_MD_ASFILES=os_BSD_OS_386_2.s + ;; + + bsdi4.* | bsdi5.*) + AC_DEFINE(_PR_SELECT_CONST_TIMEVAL) + AC_DEFINE(_PR_BSDI_JMPBUF_IS_STRUCT) + AC_DEFINE(HAVE_DLL) + AC_DEFINE(USE_DLFCN) + AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC) + MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)' + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-shared -Wl,-soname,$(@:$(OBJDIR)/%.so=%.so)' + STRIP="$STRIP -d" + case "$target_os" in + bsdi4.2* | bsdi4.3* | bsdi5.*) + AC_DEFINE(_PR_HAVE_GETPROTO_R) + AC_DEFINE(_PR_HAVE_GETPROTO_R_POINTER) + ;; + esac + ;; + *) + AC_DEFINE(_PR_SELECT_CONST_TIMEVAL) + AC_DEFINE(_PR_BSDI_JMPBUF_IS_STRUCT) + AC_DEFINE(HAVE_DLL) + AC_DEFINE(USE_DLFCN) + AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC) + ;; + esac + + ;; + +*-darwin*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(DARWIN) + AC_DEFINE(HAVE_BSD_FLOCK) + AC_DEFINE(HAVE_SOCKLEN_T) + AS='$(CC) -x assembler-with-cpp' + CFLAGS="$CFLAGS -Wall -fno-common" + case "${target_cpu}" in + arm*) + CPU_ARCH=arm + ;; + i*86*|x86_64) + if test -n "$USE_64"; then + CPU_ARCH=x86_64 + else + CPU_ARCH=i386 + fi + ;; + *) + CPU_ARCH=ppc + ;; + esac + if test "`echo $CC | grep -c '\-arch '`" = "0"; then + CC="$CC -arch $CPU_ARCH" + fi + AC_CHECK_HEADER(crt_externs.h) + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names' + _OPTIMIZE_FLAGS=-O2 + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + STRIP="$STRIP -x -S" + DLL_SUFFIX=dylib + USE_PTHREADS=1 + MDCPUCFG_H=_darwin.cfg + PR_MD_CSRCS=darwin.c + PR_MD_ASFILES=os_Darwin.s + + # Add Mac OS X support for loading CFM & CFBundle plugins + if test -f "${MACOS_SDK_DIR}/System/Library/Frameworks/Carbon.framework/Carbon"; then + AC_DEFINE(XP_MACOSX) + OS_TARGET=MacOSX + + if test -n "$_MACOSX_DEPLOYMENT_TARGET" ; then + dnl Use the specified value + export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET + elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then + dnl No value specified on the command line or in the environment, + dnl use the lesser of the library's minimum or the architecture's + dnl minimum. + case "${target_cpu}" in + powerpc*) + dnl Architecture minimum 10.2 + export MACOSX_DEPLOYMENT_TARGET=10.2 + ;; + i*86*) + dnl Architecture minimum 10.4 + export MACOSX_DEPLOYMENT_TARGET=10.4 + ;; + esac + fi + + dnl MACOS_SDK_DIR will be set to the SDK location whenever one is + dnl in use. NEXT_ROOT will be set and exported if it's needed for + dnl ld. + + if test "$MACOS_SDK_DIR"; then + dnl Sync this section with the one in Mozilla's top level. + + if test ! -d "$MACOS_SDK_DIR"; then + AC_MSG_ERROR([SDK not found. When using --with-macos-sdk, you must +specify a valid SDK. SDKs are installed when the optional cross-development +tools are selected during the Xcode/Developer Tools installation.]) + fi + + changequote(,) + CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'` + GCC_VERSION_FULL=`echo $CC_VERSION | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'` + GCC_VERSION=`echo $GCC_VERSION_FULL | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'` + changequote([,]) + GCC_VERSION_MAJOR=`echo $GCC_VERSION_FULL | $PERL -pe 's/(^\d*).*/$1/;'` + if test "$GCC_VERSION_MAJOR" -lt "4" ; then + SDK_C_FRAMEWORK="-F${MACOS_SDK_DIR}/System/Library/Frameworks" + if test -d "${MACOS_SDK_DIR}/Library/Frameworks" ; then + SDK_C_FRAMEWORK="$SDK_C_FRAMEWORK -F${MACOS_SDK_DIR}/Library/Frameworks" + fi + + SDK_C_INCLUDE="-isystem ${MACOS_SDK_DIR}/usr/include/gcc/darwin/${GCC_VERSION} -isystem ${MACOS_SDK_DIR}/usr/include ${SDK_C_FRAMEWORK}" + + CFLAGS="$CFLAGS -nostdinc ${SDK_C_INCLUDE}" + + dnl CPP needs to be set for AC_CHECK_HEADER. + CPP="$CPP -nostdinc ${SDK_C_INCLUDE}" + + changequote(,) + HOST_DARWIN_MAJOR=`echo "$build_os" | sed -E -e 's/^darwin([0-9]+).*$/\1/'` + changequote([,]) + if test "$HOST_DARWIN_MAJOR" -lt 9 ; then + dnl The build host is running Tiger (10.4) or earlier. + dnl ld support for -syslibroot is compiler-agnostic, but + dnl only available on Tiger and later. On Tiger and + dnl earlier build hosts, just rely on NEXT_ROOT, because + dnl it's not been shown to cause any problems. + MACOS_SDK_LIBS="-L${MACOS_SDK_DIR}/usr/lib/gcc/darwin -L${MACOS_SDK_DIR}/usr/lib/gcc/darwin/${GCC_VERSION_FULL} -L${MACOS_SDK_DIR}/usr/lib ${SDK_C_FRAMEWORK}" + else + dnl The build host is running Leopard (10.5) or later. + dnl With NEXT_ROOT set, the linker will still not apply + dnl it when resolving dependencies. This causes problems + dnl on Leopard, where an SDK depends on frameworks which + dnl were present in earlier OS releases (and the associated + dnl SDK) but not in Leopard. -syslibroot does not have + dnl this problem, but it results in harmless warnings when + dnl NEXT_ROOT is set. NEXT_ROOT needs to remain set even + dnl on Leopard because the compiler uses it too. + MACOS_SDK_LIBS="-Wl,-syslibroot,${MACOS_SDK_DIR}" + fi + + LDFLAGS="${MACOS_SDK_LIBS} $LDFLAGS" + export NEXT_ROOT=$MACOS_SDK_DIR + + if test -n "$CROSS_COMPILE" ; then + dnl NEXT_ROOT will be in the environment, but it + dnl shouldn't be set for the build host. HOST_CXX is + dnl presently unused. + HOST_CC="NEXT_ROOT= $HOST_CC" + HOST_CXX="NEXT_ROOT= $HOST_CXX" + fi + else + dnl gcc >= 4.0 uses different paths than above, but knows + dnl how to find them itself. + CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}" + + dnl CPP needs to be set for AC_CHECK_HEADER. + CPP="$CPP -isysroot ${MACOS_SDK_DIR}" + + dnl If gcc >= 4.0.0, we're guaranteed to be on Tiger, which + dnl has an ld that supports -syslibroot. Don't set + dnl NEXT_ROOT because it will be ignored and cause + dnl warnings when -syslibroot is specified. + if test "$GCC_VERSION_FULL" != "4.0.0" ; then + dnl gcc > 4.0.0 will pass -syslibroot to ld automatically + dnl based on the -isysroot it receives. + LDFLAGS="$LDFLAGS -isysroot ${MACOS_SDK_DIR}" + else + dnl gcc 4.0.0 doesn't pass -syslibroot to ld, it needs + dnl to be explicit. + LDFLAGS="$LDFLAGS -Wl,-syslibroot,${MACOS_SDK_DIR}" + fi + fi + fi + fi + ;; + +*-dgux*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(_PR_LOCAL_THREADS_ONLY) + AC_DEFINE(SVR4) + AC_DEFINE(SYSV) + AC_DEFINE(DGUX) + AC_DEFINE(_DGUX_SOURCE) + AC_DEFINE(_POSIX4A_DRAFT6_SOURCE) + DSO_LDOPTS=-G + _OPTIMIZE_FLAGS=-O2 + _DEBUG_FLAGS= + MDCPUCFG_H=_dgux.cfg + PR_MD_CSRCS=dgux.c + ;; + +*-freebsd*) + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + fi + AC_DEFINE(XP_UNIX) + AC_DEFINE(FREEBSD) + AC_DEFINE(HAVE_BSD_FLOCK) + AC_DEFINE(HAVE_SOCKLEN_T) + CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall" + MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf` + if test "$MOZ_OBJFORMAT" = "elf"; then + DLL_SUFFIX=so + else + DLL_SUFFIX=so.1.0 + fi + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' + MDCPUCFG_H=_freebsd.cfg + PR_MD_CSRCS=freebsd.c + ;; + +*-hpux*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(HPUX) + AC_DEFINE(_HPUX_SOURCE) + # OSF1 and HPUX report the POLLHUP event for a socket when the + # shutdown(SHUT_WR) operation is called for the remote end, even though + # the socket is still writeable. Use select(), instead of poll(), to + # workaround this problem. + AC_DEFINE(_PR_POLL_WITH_SELECT) + AC_DEFINE(_USE_BIG_FDS) + DSO_LDOPTS='-b +h $(notdir $@)' + PR_MD_CSRCS=hpux.c + if test "$OS_TEST" = "ia64"; then + DLL_SUFFIX=so + DSO_LDOPTS="$DSO_LDOPTS +b '\$\$ORIGIN'" + CPU_ARCH_TAG=_$OS_TEST + if test -z "$USE_64"; then + COMPILER_TAG=_32 + fi + PR_MD_ASFILES=os_HPUX_ia64.s + else + AC_DEFINE(hppa) + DLL_SUFFIX=sl + PR_MD_ASFILES=os_HPUX.s + fi + if test -n "$USE_64"; then + MDCPUCFG_H=_hpux64.cfg + else + MDCPUCFG_H=_hpux32.cfg + fi + if test -z "$GNU_CC"; then + CC="$CC -Ae" + CXX="$CXX -ext" + DSO_CFLAGS=+Z + else + DSO_CFLAGS=-fPIC + ASFLAGS="$ASFLAGS -x assembler-with-cpp" + fi + + if test -n "$MOZILLA_CLIENT"; then + DEFAULT_IMPL_STRATEGY=_EMU + fi + + if echo "$OS_RELEASE" | grep ^A.09 >/dev/null; then + AC_DEFINE(_PR_NEED_H_ERRNO) + AC_DEFINE(HPUX9) + DEFAULT_IMPL_STRATEGY=_EMU + USE_NSPR_THREADS=1 + fi + + if echo "$OS_RELEASE" | egrep '^(A.09|B.10)' >/dev/null; then + AC_DEFINE(_PR_NO_LARGE_FILES) + fi + + if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then + AC_DEFINE(_PR_NEED_H_ERRNO) + fi + + if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then + AC_DEFINE(HAVE_INT_LOCALTIME_R) + fi + + if echo "$OS_RELEASE" | egrep '^(B.10.30|B.11)' >/dev/null; then + AC_DEFINE(HAVE_POINTER_LOCALTIME_R) + fi + + # HP-UX 11i v2 (B.11.23) or higher + changequote(<<,>>) + case "$OS_RELEASE" in + [C-Z]*|B.[2-9]*|B.1[2-9]*|B.11.[3-9]*|B.11.2[3-9]*) + USE_IPV6=1 + ;; + esac + changequote([,]) + + if test "$OS_RELEASE" = "B.10.01"; then + AC_DEFINE(HPUX10) + DEFAULT_IMPL_STRATEGY=_EMU + fi + + if test "$OS_RELEASE" = "B.10.10"; then + AC_DEFINE(HPUX10) + AC_DEFINE(HPUX10_10) + DEFAULT_IMPL_STRATEGY=_PTH + fi + + if test "$OS_RELEASE" = "B.10.20"; then + AC_DEFINE(HPUX10) + AC_DEFINE(HPUX10_20) + if test -z "$GNU_CC"; then + CFLAGS="$CFLAGS +DAportable +DS1.1" + CXXFLAGS="$CXXFLAGS +DAportable +DS1.1" + fi + DEFAULT_IMPL_STRATEGY=_PTH + fi + + if test "$OS_RELEASE" = "B.10.30"; then + AC_DEFINE(HPUX10) + AC_DEFINE(HPUX10_30) + if test -z "$GNU_CC"; then + CFLAGS="$CFLAGS +DAportable +DS1.1" + CXXFLAGS="$CXXFLAGS +DAportable +DS1.1" + fi + DEFAULT_IMPL_STRATEGY=_PTH + fi + + if echo "$OS_RELEASE" | grep ^B.11 >/dev/null; then + AC_DEFINE(HPUX10) + AC_DEFINE(HPUX11) + AC_DEFINE(_LARGEFILE64_SOURCE) + AC_DEFINE(_PR_HAVE_OFF64_T) + AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) + if test -z "$GNU_CC"; then + if test -z "$USE_64"; then + if test "$OS_TEST" = "ia64"; then + CFLAGS="$CFLAGS +DD32" + CXXFLAGS="$CXXFLAGS +DD32" + else + CFLAGS="$CFLAGS +DAportable +DS2.0" + CXXFLAGS="$CXXFLAGS +DAportable +DS2.0" + fi + else + if test "$OS_TEST" = "ia64"; then + CFLAGS="$CFLAGS +DD64" + CXXFLAGS="$CXXFLAGS +DD64" + else + CFLAGS="$CFLAGS +DA2.0W +DS2.0" + CXXFLAGS="$CXXFLAGS +DA2.0W +DS2.0" + fi + fi + fi + DEFAULT_IMPL_STRATEGY=_PTH + fi + + if test "$DEFAULT_IMPL_STRATEGY" = "_EMU"; then + USE_NSPR_THREADS=1 + USE_PTHREADS= + USE_USER_PTHREADS= + elif test "$DEFAULT_IMPL_STRATEGY" = "_PTH"; then + USE_PTHREADS=1 + if test "$USE_NSPR_THREADS"; then + USE_PTHREADS= + fi + if test "$USE_USER_PTHREADS"; then + USE_PTHREADS= + fi + fi + ;; + +*-irix*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(IRIX) + AC_DEFINE(SVR4) + AC_DEFINE(_SGI_MP_SOURCE) + AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) + PR_MD_CSRCS=irix.c + PR_MD_ASFILES=os_Irix.s + MKSHLIB='$(LD) $(DSO_LDOPTS) -rdata_shared -shared -soname $(notdir $@) -o $@' + STRIP="$STRIP -f" + RESOLVE_LINK_SYMBOLS=1 + if test -n "$USE_64"; then + MDCPUCFG_H=_irix64.cfg + else + MDCPUCFG_H=_irix32.cfg + fi + case "${target_os}" in + irix6*) + AC_DEFINE(IRIX6) + USE_PTHREADS=1 + USE_N32=1 + COMPILER_TAG=_n32 + IMPL_STRATEGY=_PTH + ;; + irix5*) + AC_DEFINE(IRIX5) + USE_NSPR_THREADS=1 + ;; + *) + USE_PTHREADS=1 + USE_N32=1 + ;; + esac + if test "$GNU_CC"; then + dnl + dnl If we are using gcc with native binutils, we need to + dnl suppress the + dnl #lineno "filename" num num + dnl lines, which confuse IRIX native as. Add -Wp,-P to the + dnl gcc command line, which passes -P to the preprocessor. + dnl + AS='$(CC) -Wp,-P -x assembler-with-cpp -D_ASM -mips2 $(INCLUDES)' + CFLAGS="$CFLAGS -Wall -Wno-format" + _OPTIMIZE_FLAGS="-O6" + else + if test -n "$USE_N32"; then + AS='as -D_ASM $(INCLUDES) -n32' + else + AS='as -D_ASM $(INCLUDES)' + fi + CFLAGS="$CFLAGS -fullwarn -xansi" + if test "$USE_N32"; then + _OPTIMIZE_FLAGS="-O -OPT:Olimit=4000" + else + _OPTIMIZE_FLAGS="-O -Olimit 4000" + fi + if test "$USE_MDUPDATE"; then + CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)" + fi + case "${target}" in + *-irix6.*) + CFLAGS="$CFLAGS -multigot" + DSO_LDOPTS="-no_unresolved" + if test "$USE_N32"; then + CFLAGS="$CFLAGS -n32 -woff 1209" + DSO_LDOPTS="$DSO_LDOPTS -n32" + else + if test "$USE_64"; then + CFLAGS="$CFLAGS -64" + else + CFLAGS="$CFLAGS -32" + fi + fi + ;; + *) + CFLAGS="$CFLAGS -xgot" + ;; + esac + fi + if test "${target_os}" = "irix5.3"; then + AC_DEFINE(IRIX5_3) + fi + case "${target_os}" in + irix6.5) + if test -z "$GNU_CC"; then + CFLAGS="$CFLAGS -mips3" + fi + AC_DEFINE(_PR_HAVE_GETPROTO_R) + AC_DEFINE(_PR_HAVE_GETPROTO_R_POINTER) + AC_DEFINE(_PR_HAVE_SGI_PRDA_PROCMASK) + ;; + irix5*) + ;; + *) + AC_DEFINE(_PR_HAVE_SGI_PRDA_PROCMASK) + ;; + esac + ;; + +*-linux*|*-gnu*|*-k*bsd*-gnu|*-android*|*-linuxandroid*) + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + IMPL_STRATEGY=_PTH + fi + AC_DEFINE(XP_UNIX) + AC_DEFINE(_GNU_SOURCE) + AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) + case "${target}" in + *-android*|*-linuxandroid*) + OS_TARGET=Android + AC_DEFINE(LINUX) + ;; + *-linux*) + AC_DEFINE(LINUX) + ;; + esac + CFLAGS="$CFLAGS -Wall" + CXXFLAGS="$CXXFLAGS -Wall" + MDCPUCFG_H=_linux.cfg + PR_MD_CSRCS=linux.c + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' + _OPTIMIZE_FLAGS=-O2 + _DEBUG_FLAGS="-g -fno-inline" # most people on linux use gcc/gdb, and that + # combo is not yet good at debugging inlined + # functions (even when using DWARF2 as the + # debugging format) + COMPILER_TAG=_glibc + if echo "$OS_TEST" | grep -c 86 >/dev/null; then + CPU_ARCH=x86 + else + CPU_ARCH=$OS_TEST + fi + CPU_ARCH_TAG=_${CPU_ARCH} + case "${target_cpu}" in + alpha) + AC_DEFINE(_ALPHA_) + AC_DEFINE(__alpha) + CFLAGS="$CFLAGS -mieee" + CXXFLAGS="$CXXFLAGS -mieee" + ;; + i*86) + AC_DEFINE(i386) + PR_MD_ASFILES=os_Linux_x86.s + ;; + ia64) + PR_MD_ASFILES=os_Linux_ia64.s + ;; + x86_64) + if test -n "$USE_64"; then + PR_MD_ASFILES=os_Linux_x86_64.s + elif test -n "$USE_X32"; then + PR_MD_ASFILES=os_Linux_x86_64.s + CC="$CC -mx32" + CXX="$CXX -mx32" + else + AC_DEFINE(i386) + PR_MD_ASFILES=os_Linux_x86.s + CC="$CC -m32" + CXX="$CXX -m32" + fi + ;; + ppc|powerpc) + PR_MD_ASFILES=os_Linux_ppc.s + ;; + powerpc64) + if test -n "$USE_64"; then + CC="$CC -m64" + CXX="$CXX -m64" + else + PR_MD_ASFILES=os_Linux_ppc.s + fi + ;; + m68k) + CFLAGS="$CFLAGS -m68020-60" + CXXFLAGS="$CXXFLAGS -m68020-60" + ;; + esac + ;; + +*-mingw*|*-msys*|*-cygwin*|*-mks*) + AC_DEFINE(XP_PC) + AC_DEFINE(WIN32) + PR_MD_ARCH_DIR=windows + RESOLVE_LINK_SYMBOLS=1 + + if test -n "$GNU_CC"; then + CC="$CC -mwindows" + CXX="$CXX -mwindows" + DLL_SUFFIX=dll + MKSHLIB='$(CC) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(IMPORT_LIBRARY) $(DLLBASE) -o $(subst $(OBJDIR)/,,$(SHARED_LIBRARY))' + RC=$WINDRES + # Use temp file for windres (bug 213281) + RCFLAGS='-O coff --use-temp-file' + else + LD=link + AR='lib -NOLOGO -OUT:"$@"' + AR_FLAGS= + RANLIB='echo not_ranlib' + STRIP='echo not_strip' + RC=rc.exe + GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb' + OBJ_SUFFIX=obj + LIB_SUFFIX=lib + DLL_SUFFIX=dll + + # Determine compiler version + changequote(,) + _MSVC_VER_FILTER='s|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p' + changequote([,]) + CC_VERSION=`"${CC}" -v 2>&1 | sed -ne "$_MSVC_VER_FILTER"` + _CC_MAJOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $1 }'` + _CC_MINOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $2 }'` + _CC_RELEASE=`echo ${CC_VERSION} | awk -F\. '{ print $3 }'` + _CC_BUILD=`echo ${CC_VERSION} | awk -F\. '{ print $4 }'` + MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION} + + if test "$_CC_MAJOR_VERSION" -eq "14"; then + dnl -DYNAMICBASE is only supported on VC8SP1 or newer, + dnl so be very specific here! + dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762 + if test $_CC_RELEASE -gt 50727; then + _USE_DYNAMICBASE=1 + elif test $_CC_BUILD -ge 762; then + _USE_DYNAMICBASE=1 + fi + AC_DEFINE(_CRT_SECURE_NO_DEPRECATE) + AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE) + elif test $_CC_MAJOR_VERSION -ge 15; then + _USE_DYNAMICBASE=1 + AC_DEFINE(_CRT_SECURE_NO_WARNINGS) + AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS) + fi + + if test -n "$_USE_DYNAMICBASE"; then + DLLFLAGS="$DLLFLAGS -DYNAMICBASE" + fi + + # Ensure that mt is Microsoft (R) Manifest Tool and not magnetic + # tape manipulation utility (or something else) + if test "$MSC_VER" -ge "1400"; then + changequote(,) + _MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p' + changequote([,]) + + MSMT_TOOL=`mt 2>&1|grep 'Microsoft (R) Manifest Tool'` + if test -n "$MSMT_TOOL"; then + MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"` + if test -z "$MSMANIFEST_TOOL_VERSION"; then + AC_MSG_WARN([Unknown version of the Microsoft (R) Manifest Tool.]) + fi + MT=mt + unset MSMT_TOOL + else + AC_MSG_ERROR([Microsoft (R) Manifest Tool must be in your \$PATH.]) + fi + fi + + CFLAGS="$CFLAGS -W3 -nologo -GF -Gy" + DLLFLAGS="$DLLFLAGS -OUT:\"\$@\"" + _DEBUG_FLAGS=-Zi + _OPTIMIZE_FLAGS=-O2 + + PROFILE_GEN_CFLAGS="-GL" + PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT" + PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952" + PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE" + + if test "$MSC_VER" -ge "1800"; then + dnl Visual C++ 2013 requires -FS when parallel building with + dnl make -jN. If not specified, compiler sometimes emits C1041 + dnl error. + CFLAGS="$CFLAGS -FS" + dnl -Gw can benefit when using linker optimization on PGO. + dnl http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx + PROFILE_GEN_CFLAGS="$PROFILE_GEN_CFLAGS -Gw" + PROFILE_USE_CFLAGS="$PROFILE_USE_CFLAGS -Gw" + fi + + if test -z "$MOZ_OPTIMIZE"; then + CFLAGS="$CFLAGS -Od" + fi + + if test "$USE_DEBUG_RTL" = 1; then + if test -n "$USE_STATIC_RTL"; then + CFLAGS="$CFLAGS -MTd" + else + CFLAGS="$CFLAGS -MDd" + fi + else + if test -n "$USE_STATIC_RTL"; then + CFLAGS="$CFLAGS -MT" + else + CFLAGS="$CFLAGS -MD" + fi + fi + + if test -n "$MOZ_DEBUG"; then + AC_DEFINE(_DEBUG) + else + DEFINES="$DEFINES -U_DEBUG" + fi + + if test -n "$MOZ_DEBUG_SYMBOLS"; then + if test -n "$MOZ_OPTIMIZE"; then + DLLFLAGS="$DLLFLAGS -DEBUG -OPT:REF" + LDFLAGS="$LDFLAGS -DEBUG -OPT:REF" + else + DLLFLAGS="$DLLFLAGS -DEBUG" + LDFLAGS="$LDFLAGS -DEBUG" + fi + fi + + OS_DLLFLAGS="-nologo -DLL -SUBSYSTEM:WINDOWS" + if test "$MSC_VER" -le "1200" -a -z "$MOZ_DEBUG_SYMBOLS"; then + OS_DLLFLAGS="$OS_DLLFLAGS -PDB:NONE" + fi + + if test "$OS_TARGET" = "WINNT"; then + CFLAGS="$CFLAGS -GT" + LIBNSPR='$(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' + LIBPLC='$(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' + else + LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' + LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)' + fi + fi # GNU_CC + + if test -n "$USE_STATIC_TLS"; then + AC_DEFINE(_PR_USE_STATIC_TLS) + fi + + if test "$OS_TARGET" = "WINNT"; then + AC_DEFINE(WINNT) + else + AC_DEFINE(WIN95) + # undefine WINNT as some versions of mingw gcc define it by default + DEFINES="$DEFINES -UWINNT" + AC_DEFINE(_PR_GLOBAL_THREADS_ONLY) + fi + + if test "$CPU_ARCH" = "x86"; then + CPU_ARCH_TAG= + else + CPU_ARCH_TAG=$CPU_ARCH + fi + + if test "$USE_DEBUG_RTL" = 1; then + OBJDIR_SUFFIX=OBJD + fi + + case "$OS_TARGET" in + WINNT) + MDCPUCFG_H=_winnt.cfg + ;; + WIN95) + MDCPUCFG_H=_win95.cfg + ;; + *) + AC_MSG_ERROR([Missing OS_TARGET for ${target}. Use --enable-win32-target to set.]) + ;; + esac + + case "$target_cpu" in + i*86) + if test -n "$USE_64"; then + AC_DEFINE(_AMD64_) + else + AC_DEFINE(_X86_) + if test -z "$GNU_CC" -a "$MSC_VER" -ge "1700"; then + dnl Visual C++ 2012 defaults to -arch:SSE2. Use -arch:IA32 + dnl to avoid requiring SSE2. + CFLAGS="$CFLAGS -arch:IA32" + fi + fi + ;; + x86_64) + AC_DEFINE(_AMD64_) + USE_64=1 + ;; + ia64) + AC_DEFINE(_IA64_) + USE_64=1 + ;; + *) + AC_DEFINE(_CPU_ARCH_NOT_DEFINED) + ;; + esac + ;; + +*-netbsd*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(NETBSD) + AC_DEFINE(HAVE_BSD_FLOCK) + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + fi + MDCPUCFG_H=_netbsd.cfg + PR_MD_CSRCS=netbsd.c + + DSO_CFLAGS='-fPIC -DPIC' + CFLAGS="$CFLAGS -ansi -Wall" + CXXFLAGS="$CXXFLAGS -ansi -Wall" + MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)' + + if test -z "$OBJECT_FMT"; then + if echo __ELF__ | ${CC-cc} -E - | grep -q __ELF__ 2>/dev/null; then + OBJECT_FMT=a.out + DLL_SUFFIX=so.1.0 + DSO_LDOPTS='-shared' + else + OBJECT_FMT=ELF + DLL_SUFFIX=so + DSO_LDOPTS='-shared -Wl,-soname,$(notdir $@)' + fi + fi + + if test "$LIBRUNPATH"; then + DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH" + fi + ;; + +*-nto*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(NTO) + AC_DEFINE(_QNX_SOURCE) + AC_DEFINE(HAVE_POINTER_LOCALTIME_R) + MDCPUCFG_H=_nto.cfg + PR_MD_CSRCS=nto.c + MKSHLIB='$(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(notdir $@) -o $@' + DSO_CFLAGS=-fPIC + DSO_LDOPTS=-shared + OS_LIBS="$OS_LIBS -lsocket" + _OPTIMIZE_FLAGS="-O1" + _DEBUG_FLAGS="-gstabs" + ;; + +*-openbsd*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(OPENBSD) + AC_DEFINE(HAVE_BSD_FLOCK) + AC_DEFINE(HAVE_SOCKLEN_T) + CFLAGS="$CFLAGS -ansi -Wall" + CXXFLAGS="$CXXFLAGS -ansi -Wall" + DLL_SUFFIX=so.1.0 + DSO_CFLAGS=-fPIC + MDCPUCFG_H=_openbsd.cfg + PR_MD_CSRCS=openbsd.c + OS_LIBS="-lc" + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + fi + DSO_LDOPTS='-shared -fPIC' + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + ;; + +*-osf*) + SHELL_OVERRIDE="SHELL = /usr/bin/ksh" + AC_DEFINE(XP_UNIX) + AC_DEFINE(OSF1) + AC_DEFINE(_REENTRANT) + # OSF1 and HPUX report the POLLHUP event for a socket when the + # shutdown(SHUT_WR) operation is called for the remote end, even though + # the socket is still writeable. Use select(), instead of poll(), to + # workaround this problem. + AC_DEFINE(_PR_POLL_WITH_SELECT) + + if echo "$OS_RELEASE" | egrep -c '(V2.0|V3.2)' 2>/dev/null ; then + USE_NSPR_THREADS=1 + fi + + if test -z "$GNU_CC"; then + CC="$CC -std1 -ieee_with_inexact" + if test "$OS_RELEASE" != "V2.0"; then + CC="$CC -readonly_strings" + fi + _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000" + AC_CHECK_HEADER(machine/builtins.h, AC_DEFINE(OSF1_HAVE_MACHINE_BUILTINS_H)) + else + CFLAGS="$CFLAGS -mieee" + CXXFLAGS="$CXXFLAGS -mieee" + fi + + if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then + AC_DEFINE(HAVE_INT_LOCALTIME_R) + else + AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) + AC_DEFINE(HAVE_POINTER_LOCALTIME_R) + fi + if echo $OS_RELEASE | grep -c V4.0 >/dev/null; then + AC_DEFINE(OSF1V4_MAP_PRIVATE_BUG) + fi + DSO_LDOPTS='-shared -all -expect_unresolved "*" -soname $(notdir $@)' + MDCPUCFG_H=_osf1.cfg + PR_MD_CSRCS=osf1.c + ;; + +*-qnx*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(QNX) + AC_DEFINE(_PR_NEED_H_ERRNO) + USE_NSPR_THREADS=1 + MDCPUCFG_H=_qnx.cfg + PR_MD_CSRCS=qnx.c + ;; + +*-riscos*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(RISCOS) + AC_DEFINE(_PR_NEED_H_ERRNO) + USE_PTHREADS=1 + MDCPUCFG_H=_riscos.cfg + PR_MD_CSRCS=riscos.c + DSO_CFLAGS=-fPIC + DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)' + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + ;; + +*-*-sco*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(SCO) + AC_DEFINE(sco) + AC_DEFINE(SYSV) + AC_DEFINE(_SVID3) + AC_DEFINE(_PR_NEED_H_ERRNO) + CC='cc -b elf -KPIC' + CXX='$(NSDEPTH)/build/hcpp CC +.cpp +w' + USE_NSPR_THREADS=1 + CPU_ARCH=x86 + DSO_LDOPTS='-b elf -G' + MDCPUCFG_H=_scoos.cfg + PR_MD_SRCS=scoos.c + ;; + +*-solaris*) + if test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + fi + AC_DEFINE(XP_UNIX) + AC_DEFINE(SVR4) + AC_DEFINE(SYSV) + AC_DEFINE(__svr4) + AC_DEFINE(__svr4__) + AC_DEFINE(SOLARIS) + AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) + CPU_ARCH=`uname -p` + MDCPUCFG_H=_solaris.cfg + PR_MD_CSRCS=solaris.c + LD=/usr/ccs/bin/ld + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + RESOLVE_LINK_SYMBOLS=1 + case "${OS_RELEASE}" in + 5.8|5.9) + ;; + *) + # It is safe to use the -Bdirect linker flag on Solaris 10 or later. + USE_B_DIRECT=1 + ;; + esac + if test -n "$GNU_CC"; then + DSO_CFLAGS=-fPIC + if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then + GCC_USE_GNU_LD=1 + fi + DSO_LDOPTS='-shared -Wl,-h,$(notdir $@),-z,combreloc,-z,defs,-z,ignore' + if test -n "$USE_B_DIRECT"; then + DSO_LDOPTS="$DSO_LDOPTS,-Bdirect" + fi + else + DSO_CFLAGS=-KPIC + DSO_LDOPTS='-G -h $(notdir $@) -z combreloc -z defs -z ignore' + if test -n "$USE_B_DIRECT"; then + DSO_LDOPTS="$DSO_LDOPTS -Bdirect" + fi + fi + if test -n "$GNU_CC"; then + CFLAGS="$CFLAGS -Wall" + CXXFLAGS="$CXXFLAGS -Wall" + if test -n "$USE_MDUPDATE"; then + CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)" + CXXFLAGS="$CXXFLAGS -MDupdate \$(DEPENDENCIES)" + fi + GCC_AS=`$CC -print-prog-name=as` + if test "`echo | $GCC_AS -v 2>&1 | grep -c GNU`" != "0"; then + GNU_AS=1 + fi + else + CFLAGS="$CFLAGS -xstrconst" + CXXFLAGS="$CXXFLAGS -Qoption cg -xstrconst -features=tmplife" + if test -z "$MOZ_OPTIMIZE"; then + CFLAGS="$CFLAGS -xs" + CXXFLAGS="$CXXFLAGS -xs" + fi + _OPTIMIZE_FLAGS=-xO4 + fi + if test -z "$GNU_AS"; then + ASFLAGS="$ASFLAGS -Wa,-P" + fi + if test -n "$USE_64"; then + if test -n "$GNU_CC"; then + CC="$CC -m64" + CXX="$CXX -m64" + else + if test "$OS_TEST" = "i86pc"; then + CC="$CC -xarch=amd64" + CXX="$CXX -xarch=amd64" + else + CC="$CC -xarch=v9" + CXX="$CXX -xarch=v9" + fi + fi + fi + if test "$OS_TEST" = "i86pc"; then + if test -z "$USE_64"; then + AC_DEFINE(i386) + fi + CPU_ARCH_TAG=_$OS_TEST + # The default debug format, DWARF (-g), is not supported by gcc + # on i386-ANY-sysv4/solaris, but the stabs format is. It is + # assumed that the Solaris assembler /usr/ccs/bin/as is used. + # If your gcc uses GNU as, you do not need the -Wa,-s option. + if test -n "$MOZ_DEBUG" && test -n "$GNU_CC"; then + _DEBUG_FLAGS=-gstabs + if test -z "$GNU_AS"; then + _DEBUG_FLAGS="$_DEBUG_FLAGS -Wa,-s" + fi + fi + fi + case "${target_os}" in + solaris2.3*) + AC_DEFINE(_PR_NO_LARGE_FILES) + ;; + solaris2.4*) + AC_DEFINE(_PR_NO_LARGE_FILES) + ;; + solaris2.5*) + AC_DEFINE(SOLARIS2_5) + ;; + *) + AC_DEFINE(_PR_HAVE_OFF64_T) + # The lfcompile64(5) man page on Solaris 2.6 says: + # For applications that do not wish to conform to the POSIX or + # X/Open specifications, the 64-bit transitional interfaces + # are available by default. No compile-time flags need to be + # set. + # But gcc 2.7.2.x fails to define _LARGEFILE64_SOURCE by default. + # The native compiler, gcc 2.8.x, and egcs don't have this problem. + if test -n "$GNU_CC"; then + AC_DEFINE(_LARGEFILE64_SOURCE) + fi + ;; + esac + case "${target_os}" in + solaris2.3*) + ;; + solaris2.4*) + ;; + solaris2.5*) + ;; + solaris2.6*) + ;; + solaris2.7*) + ;; + *) + # Solaris 8 or higher has IPv6. + AC_DEFINE(_PR_INET6) + ;; + esac + if test "$CPU_ARCH" = "sparc"; then + # 64-bit Solaris SPARC requires V9 architecture, so the following + # is not needed. + if test -z "$USE_64"; then + ULTRASPARC_LIBRARY=nspr_flt + fi + fi + # Purify requires that binaries linked against nspr also + # be linked against -lrt (or -lposix4) so add it to OS_LIBS + _rev=`uname -r` + _librt=`echo $_rev 5.6 | awk '{ if ($1 > $2) print "-lrt"; else print "-lposix4" }'` + OS_LIBS="$OS_LIBS $_librt" + ;; + +*-sco-sysv5*) + AC_DEFINE(XP_UNIX) + AC_DEFINE(UNIXWARE) + AC_DEFINE(SVR4) + AC_DEFINE(SYSV) + USE_NSPR_THREADS=1 + if echo $OS_RELEASE | grep -c 2.1 2>/dev/null; then + AC_DEFINE(_PR_NO_LARGE_FILES) + CC='$(NSDEPTH)/build/hcc cc' + CXX='$(NSDEPTH)/build/hcpp CC' + MDCPUCFG_H=_unixware.cfg + else + AC_DEFINE(_LARGEFILE64_SOURCE) + AC_DEFINE(_PR_HAVE_OFF64_T) + AC_DEFINE(_PR_HAVE_SOCKADDR_LEN) + MDCPUCFG_H=_unixware7.cfg + fi + PR_MD_CSRCS=unixware.c + DSO_LDOPTS=-G + CPU_ARCH=x86 + ;; + +*-symbian*) + AC_ARG_WITH(symbian-sdk, + [ --with-symbian-sdk=SYMBIAN_SDK_DIR + The path to the Symbian SDK], + SYMBIAN_SDK_DIR=$withval) + + echo ----------------------------------------------------------------------------- + echo Building with Symbian SDK in: $SYMBIAN_SDK_DIR + echo ----------------------------------------------------------------------------- + + AC_DEFINE(XP_UNIX) + AC_DEFINE(SYMBIAN) + AC_DEFINE(__arm__) + AC_DEFINE(__SYMBIAN32__) + AC_DEFINE(_UNICODE) + AC_DEFINE(NDEBUG) + AC_DEFINE(__SUPPORT_CPP_EXCEPTIONS__) + AC_DEFINE(MOZ_STDERR_TO_STDOUT) + AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) + AC_DEFINE(HAVE_SOCKLEN_T) + USE_PTHREADS=1 + LIB_SUFFIX=lib + DLL_SUFFIX=dll + MKSHLIB= + DSO_LDOPTS= + DSO_CFLAGS= + VISIBILITY_FLAGS= + MDCPUCFG_H=_symbian.cfg + PR_MD_CSRCS=symbian.c + NSINSTALL=nsinstall + RANLIB='echo no ranlib ' + CPU_ARCH=ARM + OS_ARCH=SYMBIAN + OS_EXE_CFLAGS="$OS_EXE_CFLAGS -D__EXE__" + CFLAGS="$CFLAGS -MD -nostdinc" + SYMBIAN_SYS_INCLUDE="-I$SYMBIAN_SDK_DIR/Epoc32/include/variant -I$SYMBIAN_SDK_DIR/Epoc32/include -I$SYMBIAN_SDK_DIR/Epoc32/include/stdapis" + echo ------------------------------------------------------- + echo SYMBIAN_SYS_INCLUDE is: $SYMBIAN_SYS_INCLUDE + echo ------------------------------------------------------- + case "$OS_TARGET" in + WINSCW) + CC=mwccsym2.exe + CXX=mwccsym2.exe + LD=mwldsym2.exe + AR=mwldsym2.exe + WINSCW_LD_DIR="\$(SYMBIAN_SDK_DIR)/EPOC32/RELEASE/WINSCW/UDEB" + CFLAGS="$CFLAGS -O0 -inline off -wchar_t off -align 4 -warnings on -w nohidevirtual,nounusedexpr -msgstyle gcc -enum int -str pool -exc ms -trigraphs on -nostderr -gccdep -cwd source -i- -I\$(VPATH)" + SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include Symbian_OS_v9.2.hrh" + AR_FLAGS="-library -msgstyle gcc -stdlib -subsystem windows -noimplib -o \$@" + AC_DEFINE(_DEBUG) + AC_DEFINE(__CW32__) + AC_DEFINE(__WINS__) + AC_DEFINE(__WINSCW__) + DEFINES="$DEFINES -U_WIN32" + ;; + GCCE) + CFLAGS="$CFLAGS -Wall -Wno-unknown-pragmas -fexceptions -march=armv5t -mapcs -pipe -x c -msoft-float" + CXXFLAGS="$CXXFLAGS $CFLAGS -Wno-ctor-dtor-privacy" + SYMBIAN_SYS_INCLUDE="$SYMBIAN_SYS_INCLUDE -include $SYMBIAN_SDK_DIR/EPOC32/INCLUDE/GCCE/GCCE.h" + AC_DEFINE(__GCCE__) + AC_DEFINE(__EABI__) + DEFINES="$DEFINES -D__PRODUCT_INCLUDE__=$SYMBIAN_SDK_DIR/Epoc32/include/variant/Symbian_OS_v9.2.hrh" + ;; + *) + AC_MSG_ERROR([Missing OS_TARGET for ${target}. Set --enable-symbian-target to with 'WINSCW' or 'GCCE'.]) + ;; + esac + CFLAGS="$CFLAGS ${SYMBIAN_SYS_INCLUDE}" + ;; + +*-os2*) + AC_DEFINE(XP_OS2) + AC_DEFINE(XP_PC) + AC_DEFINE(BSD_SELECT) + AC_DEFINE(TCPV40HDRS) + LIB_SUFFIX=lib + DLL_SUFFIX=dll + RC=rc.exe + PR_MD_ARCH_DIR=os2 + PROG_SUFFIX=.exe + NSINSTALL=nsinstall + MDCPUCFG_H=_os2.cfg + RESOLVE_LINK_SYMBOLS=1 + + AC_DEFINE(OS2) + AR=emxomfar + AR_FLAGS='r $@' + CFLAGS="$CFLAGS -Wall -Zomf" + CXXFLAGS="$CFLAGS -Wall -Zomf" + MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@' + DSO_CFLAGS= + DSO_LDOPTS='-Zomf -Zdll' + LDFLAGS='-Zmap' + _OPTIMIZE_FLAGS="-O2 -s" + _DEBUG_FLAGS="-g -fno-inline" + if test -n "$MOZ_OPTIMIZE"; then + DSO_LDOPTS="$DSO_LDOPTS -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA" + fi + IMPLIB='emximp -o' + FILTER='emxexp -o' + if test -n "$MOZ_OS2_HIGH_MEMORY"; then + LDFLAGS="$LDFLAGS -Zhigh-mem" + AC_DEFINE(MOZ_OS2_HIGH_MEMORY) + fi + + # GCC for OS/2 currently predefines these, but we don't want them + DEFINES="$DEFINES -Uunix -U__unix -U__unix__" + ;; + +*) + AC_DEFINE(XP_UNIX) + ;; + +esac + +if test -z "$SKIP_LIBRARY_CHECKS"; then +dnl ======================================================== +dnl Check for system libraries +dnl ======================================================== + + +dnl We don't want anything to link with libdl even if it's present on OS X, +dnl since it's not used and not part of the default installation. +dnl The same goes for BeOS. +dnl OS/2 has dlfcn in libc. + +case $target in +*-darwin*|*-beos*|*-os2*) + ;; +*) + AC_CHECK_LIB(dl, dlopen, + [AC_CHECK_HEADER(dlfcn.h, + OS_LIBS="-ldl $OS_LIBS")]) + ;; +esac + + +dnl ======================================================== +dnl Check for system header files. +dnl ======================================================== + +dnl ======================================================== +dnl Check for typedefs and structs +dnl ======================================================== + +dnl ======================================================== +dnl Checks for library functions. +dnl ======================================================== +AC_PROG_GCC_TRADITIONAL +_SAVE_LIBS="$LIBS" +LIBS="$LIBS $OS_LIBS" +AC_CHECK_FUNCS(dladdr gettid lchown setpriority strerror syscall) +LIBS="$_SAVE_LIBS" + +dnl ======================================================== +dnl Check options +dnl ======================================================== + +dnl ====================================================== +dnl = Enable compiling with ccache +dnl ====================================================== +AC_ARG_WITH(ccache, +[ --with-ccache[=path/to/ccache] + Enable compiling with ccache], + CCACHE=$withval, CCACHE="no") + +if test "$CCACHE" != "no"; then + if test -n "$CCACHE"; then + if test "$CCACHE" = "yes"; then + CCACHE= + else + if test ! -e "$CCACHE"; then + AC_MSG_ERROR([$CCACHE not found]) + fi + fi + fi + AC_PATH_PROGS(CCACHE, $CCACHE ccache) + if test -z "$CCACHE" -o "$CCACHE" = ":"; then + AC_MSG_ERROR([ccache not found]) + elif test -x "$CCACHE"; then + CC="$CCACHE $CC" + CXX="$CCACHE $CXX" + else + AC_MSG_ERROR([$CCACHE is not executable]) + fi +fi + +dnl ======================================================== +dnl = +dnl = --enable-strip +dnl = +dnl = Enable stripping of libs and executables +dnl = +dnl ======================================================== +AC_ARG_ENABLE(strip, + [ --enable-strip Enable stripping of shared libs and programs], + [ if test "$enableval" = "yes"; then + ENABLE_STRIP=1 + fi ]) + +dnl Check for hpux options +case "${target_os}" in +hpux*) +if test -z "$GNU_CC"; then + + AC_CACHE_CHECK(for +Olit support, + ac_cv_hpux_usable_olit_option, + dnl since aCC doesn't throw an error on invalid options, + dnl we have to test this the hard way + [ac_cv_hpux_usable_olit_option=no + rm -f conftest* + echo 'int main() { return 0; }' | cat > conftest.c + ${CC-cc} ${CFLAGS} +Olit=all -o conftest conftest.c > conftest.out 2>&1 + if test $? -eq 0; then + if test -z "`egrep -i '(unrecognize|unknown)' conftest.out`"; then + ac_cv_hpux_usable_olit_option=yes + fi + fi + rm -f conftest* + ]) + + if test "$ac_cv_hpux_usable_olit_option" = "yes"; then + CFLAGS="$CFLAGS +Olit=all" + CXXFLAGS="$CXXFLAGS +Olit=all" + else + CFLAGS="$CFLAGS +ESlit" + CXXFLAGS="$CXXFLAGS +ESlit" + fi +fi +;; +esac + +case "$target_os" in +darwin*) + _HAVE_PTHREADS=1 + ;; +*) + AC_CHECK_LIB(pthreads, pthread_create, + _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads", + AC_CHECK_LIB(pthread, pthread_create, + _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread", + AC_CHECK_LIB(c_r, pthread_create, + _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r", + AC_CHECK_LIB(c, pthread_create, + _HAVE_PTHREADS=1 + ) + ) + ) + ) + ;; +esac + +AC_ARG_WITH(pthreads, + [ --with-pthreads Use system pthreads library as thread subsystem], + [ if test "$withval" = "yes"; then + if test -n "$_HAVE_PTHREADS"; then + USE_PTHREADS=1 + USE_USER_PTHREADS= + USE_NSPR_THREADS= + else + AC_MSG_ERROR([ --with-pthreads specified for a system without pthread support ]); + fi + else + USE_PTHREADS= + _PTHREAD_LDFLAGS= + fi], + [ if test -n "$_HAVE_PTHREADS" && test -z "$USE_USER_PTHREADS" && test -z "$USE_NSPR_THREADS"; then + USE_PTHREADS=1 + USE_USER_PTHREADS= + USE_NSPR_THREADS= + fi]) + +AC_ARG_ENABLE(user-pthreads, + [ --enable-user-pthreads Build using userland pthreads], + [ if test "$enableval" = "yes"; then + if test -n "$_HAVE_PTHREADS"; then + USE_PTHREADS= + USE_USER_PTHREADS=1 + USE_NSPR_THREADS= + else + AC_MSG_ERROR([ --enable-user-pthreads specified for a system without pthread support ]); + fi + fi]) + +AC_ARG_ENABLE(nspr-threads, + [ --enable-nspr-threads Build using classic nspr threads], + [ if test "$enableval" = "yes"; then + USE_PTHREADS= + USE_USER_PTHREADS= + USE_NSPR_THREADS=1 + fi]) + +case "$target" in +*-beos*) + AC_ARG_WITH(bthreads, + [ --with-bthreads Use system bthreads library as thread subsystem + (BeOS only)], + [ if test "$withval" = "yes"; then + USE_BTHREADS=1 + USE_USER_PTHREADS= + USE_PTHREADS= + fi]) + ;; +esac + +fi # SKIP_LIBRARY_CHECKS + +AC_ARG_ENABLE(ipv6, + [ --enable-ipv6 Compile ipv6 support], + [ if test "$enableval" = "yes"; then + USE_IPV6=1 + else + USE_IPV6= + fi]) + +if test -n "$USE_PTHREADS"; then + dnl See if -pthread is supported. + rm -f conftest* + ac_cv_have_dash_pthread=no + AC_MSG_CHECKING(whether ${CC-cc} accepts -pthread) + echo 'int main() { return 0; }' | cat > conftest.c + ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1 + if test $? -eq 0; then + if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthread`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then + ac_cv_have_dash_pthread=yes + case "$target_os" in + freebsd*) +# Freebsd doesn't use -pthread for compiles, it uses them for linking + ;; + *) + CFLAGS="$CFLAGS -pthread" + CXXFLAGS="$CXXFLAGS -pthread" + ;; + esac + fi + fi + rm -f conftest* + AC_MSG_RESULT($ac_cv_have_dash_pthread) + + dnl + dnl See if -pthreads is supported. + dnl + ac_cv_have_dash_pthreads=no + if test "$ac_cv_have_dash_pthread" = "no"; then + AC_MSG_CHECKING(whether ${CC-cc} accepts -pthreads) + echo 'int main() { return 0; }' | cat > conftest.c + ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1 + if test $? -eq 0; then + if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthreads`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then + ac_cv_have_dash_pthreads=yes + CFLAGS="$CFLAGS -pthreads" + CXXFLAGS="$CXXFLAGS -pthreads" + fi + fi + rm -f conftest* + AC_MSG_RESULT($ac_cv_have_dash_pthreads) + fi + + case "$target" in + *-solaris*) + if test "$ac_cv_have_dash_pthreads" = "yes"; then + _PTHREAD_LDFLAGS= + fi + ;; + *-freebsd*) + AC_DEFINE(_REENTRANT) + AC_DEFINE(_THREAD_SAFE) + dnl -pthread links in -lc_r, so don't specify it explicitly. + if test "$ac_cv_have_dash_pthread" = "yes"; then + _PTHREAD_LDFLAGS="-pthread" + else + _PTHREAD_LDFLAGS="-lc_r" + fi + ;; + *-netbsd*) + if test "$ac_cv_have_dash_pthread" = "yes"; then + _PTHREAD_LDFLAGS="-pthread" + fi + ;; + *-bsdi*) + AC_DEFINE(_THREAD_SAFE) + dnl -pthread links in -lc_r, so don't specify it explicitly. + if test "$ac_cv_have_dash_pthread" = "yes"; then + _PTHREAD_LDFLAGS= + fi + ;; + *-openbsd*) + if test "$ac_cv_have_dash_pthread" = "yes"; then + _PTHREAD_LDFLAGS=-pthread + fi + ;; + *-linux*|*-gnu*|*-k*bsd*-gnu) + AC_DEFINE(_REENTRANT) + ;; + esac + +else + if test -n "$USE_USER_PTHREADS"; then + USE_PTHREADS= + USE_NSPR_THREADS= + else + _PTHREAD_LDFLAGS= + fi +fi +dnl Special thread exceptions + +case "$target" in +*-aix*) + if test -n "$USE_NSPR_THREADS"; then + AC_DEFINE(_PR_LOCAL_THREADS_ONLY) + fi + case "$target_os" in + aix4.1*) + if test -z "$USE_PTHREADS"; then + AC_DEFINE(AIX_RENAME_SELECT) + fi + ;; + aix4.2*) + if test -z "$USE_NSPR_THREADS"; then + AC_DEFINE(HAVE_POINTER_LOCALTIME_R) + fi + ;; + aix4.3*) + if test -z "$USE_NSPR_THREADS"; then + AC_DEFINE(HAVE_POINTER_LOCALTIME_R) + fi + if test -n "$USE_PTHREADS"; then + AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST) + fi + ;; + *) + if test -z "$USE_NSPR_THREADS"; then + AC_DEFINE(HAVE_POINTER_LOCALTIME_R) + fi + if test -n "$USE_PTHREADS"; then + AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST) + fi + ;; + esac + ;; +*-bsdi*) + if test -n "$USE_PTHREADS"; then + AC_DEFINE(_PR_NEED_PTHREAD_INIT) + fi + ;; +*-freebsd*) + if test -n "$USE_NSPR_THREADS"; then + AC_DEFINE(_PR_LOCAL_THREADS_ONLY) + fi + ;; +*-hpux*) + if test -n "$USE_NSPR_THREADS"; then + AC_DEFINE(_PR_LOCAL_THREADS_ONLY) + fi + if test "$USE_PTHREADS"; then + if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then + AC_DEFINE(_REENTRANT) + AC_DEFINE(_PR_DCETHREADS) + else + AC_DEFINE_UNQUOTED(_POSIX_C_SOURCE,199506L) + AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST) + fi + fi + if test "$USE_USER_PTHREADS"; then + AC_DEFINE_UNQUOTED(_POSIX_C_SOURCE,199506L) + fi + ;; +*-irix*) + if test "${target_os}" = "irix6.5"; then + if test -n "$USE_PTHREADS"; then + AC_DEFINE(_PR_HAVE_GETHOST_R) + AC_DEFINE(_PR_HAVE_GETHOST_R_POINTER) + fi + fi + ;; +*-linux*|*-gnu*|*-k*bsd*-gnu) + if test -n "$USE_NSPR_THREADS"; then + AC_DEFINE(_PR_LOCAL_THREADS_ONLY) + fi + ;; +*-mingw*|*-msys*|*-cygwin*|*-mks*|*-os2*|*-beos*) + dnl win32, os2 & beos cannot use pthreads + USE_PTHREADS= + _PTHREAD_LDFLAGS= + USE_USER_PTHREADS= + ;; +*-netbsd*|*-openbsd*) + if test -n "$USE_NSPR_THREADS"; then + AC_DEFINE(_PR_LOCAL_THREADS_ONLY) + fi + ;; +*-osf*) + if test -n "$USE_NSPR_THREADS"; then + AC_DEFINE(_PR_LOCAL_THREADS_ONLY) + fi + if test -n "$USE_PTHREADS"; then + if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then + : + else + AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST) + fi + fi + ;; +*-solaris*) + if test -n "$USE_NSPR_THREADS"; then + AC_DEFINE(_PR_LOCAL_THREADS_ONLY) + fi + if test -n "$USE_PTHREADS"; then + AC_DEFINE(_REENTRANT) + AC_DEFINE(HAVE_POINTER_LOCALTIME_R) + if test "$OS_TEST" = "i86pc"; then + if test -n "$USE_64"; then + PR_MD_ASFILES=os_SunOS_x86_64.s + else + PR_MD_ASFILES=os_SunOS_x86.s + fi + else + if test -n "$USE_64"; then + PR_MD_ASFILES=os_SunOS_sparcv9.s + fi + fi + fi + ;; +*-nto*) + if test -n "$USE_PTHREADS"; then + AC_DEFINE(_PR_HAVE_GETHOST_R) + AC_DEFINE(_PR_HAVE_GETHOST_R_POINTER) + fi + ;; +esac + +OS_LIBS="$_PTHREAD_LDFLAGS $OS_LIBS" + +dnl If the user passed in arg to --enable-optimize or --enable-debug, +dnl make sure that we use it. +if test -n "$_SAVE_OPTIMIZE_FLAGS"; then + _OPTIMIZE_FLAGS="$_SAVE_OPTIMIZE_FLAGS" +fi + +if test -n "$_SAVE_DEBUG_FLAGS"; then + _DEBUG_FLAGS="$_SAVE_DEBUG_FLAGS" +fi + +if test -n "$MOZ_OPTIMIZE"; then + CFLAGS="$CFLAGS $_OPTIMIZE_FLAGS" + CXXFLAGS="$CXXFLAGS $_OPTIMIZE_FLAGS" +fi + +if test -n "$MOZ_DEBUG_SYMBOLS"; then + CFLAGS="$CFLAGS $_DEBUG_FLAGS" + CXXFLAGS="$CXXFLAGS $_DEBUG_FLAGS" +fi + +if test -n "$MOZ_OPTIMIZE"; then + OBJDIR_TAG=_OPT +else + OBJDIR_TAG=_DBG +fi + +if test -n "$USE_64"; then + COMPILER_TAG=_64 +fi + +RELEASE_OBJDIR_NAME="${OS_CONFIG}${CPU_ARCH_TAG}${COMPILER_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}.${OBJDIR_SUFFIX}" + +dnl ======================================================== +dnl Use cygwin wrapper for win32 builds, except MSYS/MinGW +dnl ======================================================== +case "$target_os" in +cygwin*|mks*) + CC="\$(CYGWIN_WRAPPER) $CC" + CXX="\$(CYGWIN_WRAPPER) $CXX" + RC="\$(CYGWIN_WRAPPER) $RC" + ;; +esac + +dnl ======================================================== +dnl = Use malloc wrapper lib +dnl ======================================================== +AC_ARG_ENABLE(wrap-malloc, +[ --enable-wrap-malloc Wrap malloc calls (gnu linker only)], +[ if test "$enableval" = "yes"; then + _WRAP_MALLOC=1 + fi ]) + +if test -n "$_WRAP_MALLOC"; then + if test -n "$GNU_CC"; then + WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=malloc,--wrap=calloc,--wrap=valloc,--wrap=free,--wrap=realloc,--wrap=memalign" + WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=__builtin_new,--wrap=__builtin_vec_new,--wrap=__builtin_delete,--wrap=__builtin_vec_delete" + WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=strdup,--wrap=strndup" + WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=posix_memalign,--wrap=malloc_usable_size" + else + AC_MSG_ERROR([--enable-wrap-malloc is not supported for non-GNU toolchains]) + fi +fi + +dnl ======================================================== +dnl = Location of malloc wrapper lib +dnl ======================================================== +AC_ARG_WITH(wrap-malloc, +[ --with-wrap-malloc=SHAREDLIB Location of malloc wrapper library], + WRAP_LDFLAGS="${WRAP_LDFLAGS} $withval") + +dnl ======================================================== +dnl Substitution of found variables. +dnl ======================================================== +AC_SUBST(SHELL_OVERRIDE) + +AC_SUBST(MOZILLA_CLIENT) +AC_SUBST(CC) +AC_SUBST(CXX) +AC_SUBST(CFLAGS) +AC_SUBST(CXXFLAGS) +AC_SUBST(CPPFLAGS) +AC_SUBST(HOST_CC) +AC_SUBST(HOST_CFLAGS) +AC_SUBST(LDFLAGS) +AC_SUBST(HOST_LDFLAGS) +AC_SUBST(GNU_CC) +AC_SUBST(GCC_USE_GNU_LD) +AC_SUBST(MSC_VER) +AC_SUBST(CROSS_COMPILE) + +AC_SUBST(MOZ_OPTIMIZE) +AC_SUBST(MOZ_DEBUG) +AC_SUBST(MOZ_DEBUG_SYMBOLS) + +AC_SUBST(USE_CPLUS) +AC_SUBST(USE_IPV6) +AC_SUBST(USE_N32) +AC_SUBST(USE_X32) +AC_SUBST(USE_64) +AC_SUBST(OBJECT_MODE) +AC_SUBST(ENABLE_STRIP) + +AC_SUBST(USE_PTHREADS) +AC_SUBST(USE_BTHREADS) +AC_SUBST(USE_USER_PTHREADS) +AC_SUBST(USE_NSPR_THREADS) + +AC_SUBST(LIBNSPR) +AC_SUBST(LIBPLC) + +AC_SUBST(MOD_MAJOR_VERSION) +AC_SUBST(MOD_MINOR_VERSION) +AC_SUBST(MOD_PATCH_VERSION) +AC_SUBST(NSPR_MODNAME) +AC_SUBST(MDCPUCFG_H) +AC_SUBST(PR_MD_CSRCS) +AC_SUBST(PR_MD_ASFILES) +AC_SUBST(PR_MD_ARCH_DIR) +AC_SUBST(CPU_ARCH) + +AC_SUBST(OBJ_SUFFIX) +AC_SUBST(LIB_SUFFIX) +AC_SUBST(DLL_SUFFIX) +AC_SUBST(ASM_SUFFIX) +AC_SUBST(WRAP_LDFLAGS) +AC_SUBST(MKSHLIB) +AC_SUBST(DSO_CFLAGS) +AC_SUBST(DSO_LDOPTS) + +AC_SUBST(OS_TARGET) +AC_SUBST(OS_ARCH) +AC_SUBST(OS_RELEASE) +AC_SUBST(OS_TEST) +AC_SUBST(MACOSX_DEPLOYMENT_TARGET) + +AC_SUBST(DEFINES) +AC_SUBST(DEFS) +AC_SUBST(AR) +AC_SUBST(AR_FLAGS) +AC_SUBST(AS) +AC_SUBST(ASFLAGS) +AC_SUBST(LD) +AC_SUBST(RANLIB) +AC_SUBST(PERL) +AC_SUBST(STRIP) +AC_SUBST(FILTER) +AC_SUBST(IMPLIB) + +AC_SUBST(PROFILE_GEN_CFLAGS) +AC_SUBST(PROFILE_GEN_LDFLAGS) +AC_SUBST(PROFILE_USE_CFLAGS) +AC_SUBST(PROFILE_USE_LDFLAGS) + +AC_SUBST(OS_LIBS) +AC_SUBST(RESOLVE_LINK_SYMBOLS) +AC_SUBST(AIX_LINK_OPTS) +AC_SUBST(NOSUCHFILE) +AC_SUBST(MOZ_OBJFORMAT) +AC_SUBST(ULTRASPARC_LIBRARY) + +AC_SUBST(OBJDIR) +AC_SUBST(OBJDIR_NAME) +AC_SUBST(RELEASE_OBJDIR_NAME) +AC_SUBST(NSINSTALL) +AC_SUBST(OPTIMIZER) +AC_SUBST(RC) +AC_SUBST(RCFLAGS) +AC_SUBST(DLLFLAGS) +AC_SUBST(EXEFLAGS) +AC_SUBST(OS_DLLFLAGS) +AC_SUBST(CYGWIN_WRAPPER) +AC_SUBST(VISIBILITY_FLAGS) +AC_SUBST(WRAP_SYSTEM_INCLUDES) +AC_SUBST(MACOS_SDK_DIR) +AC_SUBST(SYMBIAN_SDK_DIR) +AC_SUBST(NEXT_ROOT) +AC_SUBST(MT) + +dnl ======================================================== +dnl Generate output files. +dnl ======================================================== +MAKEFILES=" + Makefile + config/Makefile + config/autoconf.mk + config/nsprincl.mk + config/nsprincl.sh + config/nspr-config + config/nspr.pc + lib/Makefile + lib/ds/Makefile + lib/libc/Makefile + lib/libc/include/Makefile + lib/libc/src/Makefile + lib/tests/Makefile + pkg/Makefile + pr/Makefile + pr/include/Makefile + pr/include/md/Makefile + pr/include/obsolete/Makefile + pr/include/private/Makefile + pr/src/Makefile + pr/src/io/Makefile + pr/src/linking/Makefile + pr/src/malloc/Makefile + pr/src/md/Makefile + pr/src/md/${PR_MD_ARCH_DIR}/Makefile + pr/src/memory/Makefile + pr/src/misc/Makefile + pr/src/threads/Makefile + pr/tests/Makefile + pr/tests/dll/Makefile +" + +if test "$OS_TARGET" = "Linux"; then + MAKEFILES="$MAKEFILES + pkg/linux/Makefile + " +elif test "$OS_TARGET" = "SunOS"; then + MAKEFILES="$MAKEFILES + pkg/solaris/Makefile + pkg/solaris/SUNWpr/Makefile + pkg/solaris/SUNWprd/Makefile + " +fi + +if test -z "$USE_PTHREADS" && test -z "$USE_BTHREADS"; then + MAKEFILES="$MAKEFILES + pr/src/threads/combined/Makefile + " +elif test -n "$USE_PTHREADS"; then + MAKEFILES="$MAKEFILES + pr/src/pthreads/Makefile + " +elif test -n "$USE_BTHREADS"; then + MAKEFILES="$MAKEFILES + pr/src/bthreads/Makefile + " +fi + +if test -n "$USE_CPLUS"; then + MAKEFILES="$MAKEFILES + pr/src/cplus/Makefile + pr/src/cplus/tests/Makefile + " +fi + +echo $MAKEFILES > unallmakefiles + +AC_CONFIG_FILES([$MAKEFILES]) +AC_CONFIG_COMMANDS([default], [chmod +x config/nspr-config]) +AC_OUTPUT diff -Nru nspr-4.9.5/nspr/.cvsignore nspr-4.10.7/nspr/.cvsignore --- nspr-4.9.5/nspr/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,5 @@ +Makefile +config-defs.h +config.cache +config.log +config.status diff -Nru nspr-4.9.5/nspr/.hg_archival.txt nspr-4.10.7/nspr/.hg_archival.txt --- nspr-4.9.5/nspr/.hg_archival.txt 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/.hg_archival.txt 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,4 @@ +repo: a4b34919bf34db2ee22acbbc305693c8980b6dc6 +node: 0f03651116c5b34ba48b5a5cd31234303d9806b6 +branch: default +tag: NSPR_4_10_7_RTM diff -Nru nspr-4.9.5/nspr/.hgignore nspr-4.10.7/nspr/.hgignore --- nspr-4.9.5/nspr/.hgignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/.hgignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,5 @@ +syntax: glob +*~ +*OPT.OBJ/* +*DBG.OBJ/* +*DBG.OBJD/* diff -Nru nspr-4.9.5/nspr/lib/.cvsignore nspr-4.10.7/nspr/lib/.cvsignore --- nspr-4.9.5/nspr/lib/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/lib/ds/.cvsignore nspr-4.10.7/nspr/lib/ds/.cvsignore --- nspr-4.9.5/nspr/lib/ds/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,2 @@ +Makefile +_pl_bld.h diff -Nru nspr-4.9.5/nspr/lib/ds/Makefile.in nspr-4.10.7/nspr/lib/ds/Makefile.in --- nspr-4.9.5/nspr/lib/ds/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,151 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include + +CSRCS = \ + plarena.c \ + plhash.c \ + plvrsion.c \ + $(NULL) + +HEADERS = \ + plarenas.h \ + plarena.h \ + plhash.h \ + $(NULL) + +HEADERS := $(addprefix $(srcdir)/, $(HEADERS)) + +ifeq ($(OS_ARCH), WINNT) +RES=$(OBJDIR)/plds.res +RESNAME=plds.rc +endif # WINNT + +ifeq ($(OS_ARCH), AIX) +ifeq ($(CLASSIC_NSPR),1) +OS_LIBS = -lc +else +OS_LIBS = -lc_r +endif +endif + +ifeq ($(OS_ARCH),IRIX) +OS_LIBS = -lc +endif + +ifeq ($(OS_ARCH),SunOS) +OS_LIBS = -lc +MAPFILE = $(OBJDIR)/pldsmap.sun +GARBAGE += $(MAPFILE) +ifdef NS_USE_GCC +ifdef GCC_USE_GNU_LD +MKSHLIB += -Wl,--version-script,$(MAPFILE) +else +MKSHLIB += -Wl,-M,$(MAPFILE) +endif +else +MKSHLIB += -M $(MAPFILE) +endif +# The -R '$ORIGIN' linker option instructs this library to search for its +# dependencies in the same directory where it resides. +MKSHLIB += -R '$$ORIGIN' +endif + +ifeq ($(OS_ARCH),OS2) +MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def +GARBAGE += $(MAPFILE) +MKSHLIB += $(MAPFILE) +endif + +EXTRA_LIBS = $(LIBNSPR) + +# On SCOOS, we can't link with extra libraries when +# we build a shared library. If we do so, the linker doesn't +# complain, but we would run into weird problems at run-time. +# Therefore on these platforms, we link just the .o files. +ifeq ($(OS_ARCH),SCOOS) +EXTRA_LIBS = +endif + +ifdef RESOLVE_LINK_SYMBOLS +EXTRA_LIBS += $(OS_LIBS) +endif + +LIBRARY_NAME = plds +LIBRARY_VERSION = $(MOD_MAJOR_VERSION) + +RELEASE_HEADERS = $(HEADERS) +RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR) +RELEASE_LIBS = $(TARGETS) + +include $(topsrcdir)/config/rules.mk + +# +# Version information generation (begin) +# +ECHO = echo +TINC = $(OBJDIR)/_pl_bld.h +PROD = $(notdir $(SHARED_LIBRARY)) +NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now +SH_DATE = $(shell date "+%Y-%m-%d %T") +SH_NOW = $(shell $(NOW)) + +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + SUF = i64 +else + SUF = LL +endif + +GARBAGE += $(TINC) + +$(TINC): + @$(MAKE_OBJDIR) + @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC) + @if test ! -z "$(SH_NOW)"; then \ + $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \ + else \ + true; \ + fi + @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) + + +$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC) +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $< +else + $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< +endif +# +# Version information generation (end) +# + +# +# The Client build wants the shared libraries in $(dist_bindir), +# so we also install them there. +# + +export:: $(TARGETS) + $(INSTALL) -m 444 $(HEADERS) $(dist_includedir) + $(INSTALL) -m 444 $(TARGETS) $(dist_libdir) +ifdef SHARED_LIBRARY +ifeq ($(OS_ARCH),HP-UX) + $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir) + $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir) +else + $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir) +endif +endif diff -Nru nspr-4.9.5/nspr/lib/ds/plarena.c nspr-4.10.7/nspr/lib/ds/plarena.c --- nspr-4.9.5/nspr/lib/ds/plarena.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/plarena.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,442 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Lifetime-based fast allocation, inspired by much prior art, including + * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes" + * David R. Hanson, Software -- Practice and Experience, Vol. 20(1). + */ +#include +#include +#include "plarena.h" +#include "prmem.h" +#include "prbit.h" +#include "prlog.h" +#include "prlock.h" +#include "prinit.h" + +static PLArena *arena_freelist; + +#ifdef PL_ARENAMETER +static PLArenaStats *arena_stats_list; + +#define COUNT(pool,what) (pool)->stats.what++ +#else +#define COUNT(pool,what) /* nothing */ +#endif + +#define PL_ARENA_DEFAULT_ALIGN sizeof(double) + +static PRLock *arenaLock; +static PRCallOnceType once; +static const PRCallOnceType pristineCallOnce; + +/* +** InitializeArenas() -- Initialize arena operations. +** +** InitializeArenas() is called exactly once and only once from +** LockArena(). This function creates the arena protection +** lock: arenaLock. +** +** Note: If the arenaLock cannot be created, InitializeArenas() +** fails quietly, returning only PR_FAILURE. This percolates up +** to the application using the Arena API. He gets no arena +** from PL_ArenaAllocate(). It's up to him to fail gracefully +** or recover. +** +*/ +static PRStatus InitializeArenas( void ) +{ + PR_ASSERT( arenaLock == NULL ); + arenaLock = PR_NewLock(); + if ( arenaLock == NULL ) + return PR_FAILURE; + else + return PR_SUCCESS; +} /* end ArenaInitialize() */ + +static PRStatus LockArena( void ) +{ + PRStatus rc = PR_CallOnce( &once, InitializeArenas ); + + if ( PR_FAILURE != rc ) + PR_Lock( arenaLock ); + return(rc); +} /* end LockArena() */ + +static void UnlockArena( void ) +{ + PR_Unlock( arenaLock ); + return; +} /* end UnlockArena() */ + +PR_IMPLEMENT(void) PL_InitArenaPool( + PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align) +{ + /* + * Look-up table of PR_BITMASK(PR_CeilingLog2(align)) values for + * align = 1 to 32. + */ + static const PRUint8 pmasks[33] = { + 0, /* not used */ + 0, 1, 3, 3, 7, 7, 7, 7,15,15,15,15,15,15,15,15, /* 1 ... 16 */ + 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31}; /* 17 ... 32 */ + + if (align == 0) + align = PL_ARENA_DEFAULT_ALIGN; + + if (align < sizeof(pmasks)/sizeof(pmasks[0])) + pool->mask = pmasks[align]; + else + pool->mask = PR_BITMASK(PR_CeilingLog2(align)); + + pool->first.next = NULL; + pool->first.base = pool->first.avail = pool->first.limit = + (PRUword)PL_ARENA_ALIGN(pool, &pool->first + 1); + pool->current = &pool->first; + /* + * Compute the net size so that each arena's gross size is |size|. + * sizeof(PLArena) + pool->mask is the header and alignment slop + * that PL_ArenaAllocate adds to the net size. + */ + if (size > sizeof(PLArena) + pool->mask) + pool->arenasize = size - (sizeof(PLArena) + pool->mask); + else + pool->arenasize = size; +#ifdef PL_ARENAMETER + memset(&pool->stats, 0, sizeof pool->stats); + pool->stats.name = strdup(name); + pool->stats.next = arena_stats_list; + arena_stats_list = &pool->stats; +#endif +} + + +/* +** PL_ArenaAllocate() -- allocate space from an arena pool +** +** Description: PL_ArenaAllocate() allocates space from an arena +** pool. +** +** First, try to satisfy the request from arenas starting at +** pool->current. +** +** If there is not enough space in the arena pool->current, try +** to claim an arena, on a first fit basis, from the global +** freelist (arena_freelist). +** +** If no arena in arena_freelist is suitable, then try to +** allocate a new arena from the heap. +** +** Returns: pointer to allocated space or NULL +** +** Notes: The original implementation had some difficult to +** solve bugs; the code was difficult to read. Sometimes it's +** just easier to rewrite it. I did that. larryh. +** +** See also: bugzilla: 45343. +** +*/ + +PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb) +{ + PLArena *a; + char *rp; /* returned pointer */ + + PR_ASSERT((nb & pool->mask) == 0); + + nb = (PRUword)PL_ARENA_ALIGN(pool, nb); /* force alignment */ + + /* attempt to allocate from arenas at pool->current */ + { + a = pool->current; + do { + if ( nb <= a->limit - a->avail ) { + pool->current = a; + rp = (char *)a->avail; + a->avail += nb; + return rp; + } + } while( NULL != (a = a->next) ); + } + + /* attempt to allocate from arena_freelist */ + { + PLArena *p; /* previous pointer, for unlinking from freelist */ + + /* lock the arena_freelist. Make access to the freelist MT-Safe */ + if ( PR_FAILURE == LockArena()) + return(0); + + for ( a = arena_freelist, p = NULL; a != NULL ; p = a, a = a->next ) { + if ( nb <= a->limit - a->base ) { + if ( p == NULL ) + arena_freelist = a->next; + else + p->next = a->next; + UnlockArena(); + a->avail = a->base; + rp = (char *)a->avail; + a->avail += nb; + /* the newly allocated arena is linked after pool->current + * and becomes pool->current */ + a->next = pool->current->next; + pool->current->next = a; + pool->current = a; + if ( NULL == pool->first.next ) + pool->first.next = a; + return(rp); + } + } + UnlockArena(); + } + + /* attempt to allocate from the heap */ + { + PRUint32 sz = PR_MAX(pool->arenasize, nb); + if (PR_UINT32_MAX - sz < sizeof *a + pool->mask) { + a = NULL; + } else { + sz += sizeof *a + pool->mask; /* header and alignment slop */ + a = (PLArena*)PR_MALLOC(sz); + } + if ( NULL != a ) { + a->limit = (PRUword)a + sz; + a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1); + PL_MAKE_MEM_NOACCESS((void*)a->avail, a->limit - a->avail); + rp = (char *)a->avail; + a->avail += nb; + /* the newly allocated arena is linked after pool->current + * and becomes pool->current */ + a->next = pool->current->next; + pool->current->next = a; + pool->current = a; + if ( NULL == pool->first.next ) + pool->first.next = a; + PL_COUNT_ARENA(pool,++); + COUNT(pool, nmallocs); + return(rp); + } + } + + /* we got to here, and there's no memory to allocate */ + return(NULL); +} /* --- end PL_ArenaAllocate() --- */ + +PR_IMPLEMENT(void *) PL_ArenaGrow( + PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr) +{ + void *newp; + + PL_ARENA_ALLOCATE(newp, pool, size + incr); + if (newp) + memcpy(newp, p, size); + return newp; +} + +static void ClearArenaList(PLArena *a, PRInt32 pattern) +{ + + for (; a; a = a->next) { + PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); + a->avail = a->base; + PL_CLEAR_UNUSED_PATTERN(a, pattern); + PL_MAKE_MEM_NOACCESS((void*)a->avail, a->limit - a->avail); + } +} + +PR_IMPLEMENT(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern) +{ + ClearArenaList(pool->first.next, pattern); +} + +/* + * Free tail arenas linked after head, which may not be the true list head. + * Reset pool->current to point to head in case it pointed at a tail arena. + */ +static void FreeArenaList(PLArenaPool *pool, PLArena *head, PRBool reallyFree) +{ + PLArena **ap, *a; + + ap = &head->next; + a = *ap; + if (!a) + return; + +#ifdef DEBUG + ClearArenaList(a, PL_FREE_PATTERN); +#endif + + if (reallyFree) { + do { + *ap = a->next; + PL_CLEAR_ARENA(a); + PL_COUNT_ARENA(pool,--); + PR_DELETE(a); + } while ((a = *ap) != 0); + } else { + /* Insert the whole arena chain at the front of the freelist. */ + do { + PL_MAKE_MEM_NOACCESS((void*)(*ap)->base, + (*ap)->limit - (*ap)->base); + ap = &(*ap)->next; + } while (*ap); + LockArena(); + *ap = arena_freelist; + arena_freelist = a; + head->next = 0; + UnlockArena(); + } + + pool->current = head; +} + +PR_IMPLEMENT(void) PL_ArenaRelease(PLArenaPool *pool, char *mark) +{ + PLArena *a; + + for (a = &pool->first; a; a = a->next) { + if (PR_UPTRDIFF(mark, a->base) <= PR_UPTRDIFF(a->avail, a->base)) { + a->avail = (PRUword)PL_ARENA_ALIGN(pool, mark); + FreeArenaList(pool, a, PR_FALSE); + return; + } + } +} + +PR_IMPLEMENT(void) PL_FreeArenaPool(PLArenaPool *pool) +{ + FreeArenaList(pool, &pool->first, PR_FALSE); + COUNT(pool, ndeallocs); +} + +PR_IMPLEMENT(void) PL_FinishArenaPool(PLArenaPool *pool) +{ + FreeArenaList(pool, &pool->first, PR_TRUE); +#ifdef PL_ARENAMETER + { + PLArenaStats *stats, **statsp; + + if (pool->stats.name) + PR_DELETE(pool->stats.name); + for (statsp = &arena_stats_list; (stats = *statsp) != 0; + statsp = &stats->next) { + if (stats == &pool->stats) { + *statsp = stats->next; + return; + } + } + } +#endif +} + +PR_IMPLEMENT(void) PL_CompactArenaPool(PLArenaPool *ap) +{ +} + +PR_IMPLEMENT(void) PL_ArenaFinish(void) +{ + PLArena *a, *next; + + for (a = arena_freelist; a; a = next) { + next = a->next; + PR_DELETE(a); + } + arena_freelist = NULL; + + if (arenaLock) { + PR_DestroyLock(arenaLock); + arenaLock = NULL; + } + once = pristineCallOnce; +} + +PR_IMPLEMENT(size_t) PL_SizeOfArenaPoolExcludingPool( + const PLArenaPool *pool, PLMallocSizeFn mallocSizeOf) +{ + /* + * The first PLArena is within |pool|, so don't measure it. Subsequent + * PLArenas are separate and must be measured. + */ + size_t size = 0; + const PLArena *arena = pool->first.next; + while (arena) { + size += mallocSizeOf(arena); + arena = arena->next; + } + return size; +} + +#ifdef PL_ARENAMETER +PR_IMPLEMENT(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb) +{ + pool->stats.nallocs++; + pool->stats.nbytes += nb; + if (nb > pool->stats.maxalloc) + pool->stats.maxalloc = nb; + pool->stats.variance += nb * nb; +} + +PR_IMPLEMENT(void) PL_ArenaCountInplaceGrowth( + PLArenaPool *pool, PRUint32 size, PRUint32 incr) +{ + pool->stats.ninplace++; +} + +PR_IMPLEMENT(void) PL_ArenaCountGrowth( + PLArenaPool *pool, PRUint32 size, PRUint32 incr) +{ + pool->stats.ngrows++; + pool->stats.nbytes += incr; + pool->stats.variance -= size * size; + size += incr; + if (size > pool->stats.maxalloc) + pool->stats.maxalloc = size; + pool->stats.variance += size * size; +} + +PR_IMPLEMENT(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark) +{ + pool->stats.nreleases++; +} + +PR_IMPLEMENT(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark) +{ + pool->stats.nfastrels++; +} + +#include +#include + +PR_IMPLEMENT(void) PL_DumpArenaStats(FILE *fp) +{ + PLArenaStats *stats; + double mean, variance; + + for (stats = arena_stats_list; stats; stats = stats->next) { + if (stats->nallocs != 0) { + mean = (double)stats->nbytes / stats->nallocs; + variance = fabs(stats->variance / stats->nallocs - mean * mean); + } else { + mean = variance = 0; + } + + fprintf(fp, "\n%s allocation statistics:\n", stats->name); + fprintf(fp, " number of arenas: %u\n", stats->narenas); + fprintf(fp, " number of allocations: %u\n", stats->nallocs); + fprintf(fp, " number of free arena reclaims: %u\n", stats->nreclaims); + fprintf(fp, " number of malloc calls: %u\n", stats->nmallocs); + fprintf(fp, " number of deallocations: %u\n", stats->ndeallocs); + fprintf(fp, " number of allocation growths: %u\n", stats->ngrows); + fprintf(fp, " number of in-place growths: %u\n", stats->ninplace); + fprintf(fp, "number of released allocations: %u\n", stats->nreleases); + fprintf(fp, " number of fast releases: %u\n", stats->nfastrels); + fprintf(fp, " total bytes allocated: %u\n", stats->nbytes); + fprintf(fp, " mean allocation size: %g\n", mean); + fprintf(fp, " standard deviation: %g\n", sqrt(variance)); + fprintf(fp, " maximum allocation size: %u\n", stats->maxalloc); + } +} +#endif /* PL_ARENAMETER */ diff -Nru nspr-4.9.5/nspr/lib/ds/plarena.h nspr-4.10.7/nspr/lib/ds/plarena.h --- nspr-4.9.5/nspr/lib/ds/plarena.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/plarena.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,253 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef plarena_h___ +#define plarena_h___ +/* + * Lifetime-based fast allocation, inspired by much prior art, including + * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes" + * David R. Hanson, Software -- Practice and Experience, Vol. 20(1). + * + * Also supports LIFO allocation (PL_ARENA_MARK/PL_ARENA_RELEASE). + */ +#include "prtypes.h" +#include "plarenas.h" + +PR_BEGIN_EXTERN_C + +typedef struct PLArena PLArena; + +struct PLArena { + PLArena *next; /* next arena for this lifetime */ + PRUword base; /* aligned base address, follows this header */ + PRUword limit; /* one beyond last byte in arena */ + PRUword avail; /* points to next available byte */ +}; + +#ifdef PL_ARENAMETER +typedef struct PLArenaStats PLArenaStats; + +struct PLArenaStats { + PLArenaStats *next; /* next in arenaStats list */ + char *name; /* name for debugging */ + PRUint32 narenas; /* number of arenas in pool */ + PRUint32 nallocs; /* number of PL_ARENA_ALLOCATE() calls */ + PRUint32 nreclaims; /* number of reclaims from freeArenas */ + PRUint32 nmallocs; /* number of malloc() calls */ + PRUint32 ndeallocs; /* number of lifetime deallocations */ + PRUint32 ngrows; /* number of PL_ARENA_GROW() calls */ + PRUint32 ninplace; /* number of in-place growths */ + PRUint32 nreleases; /* number of PL_ARENA_RELEASE() calls */ + PRUint32 nfastrels; /* number of "fast path" releases */ + PRUint32 nbytes; /* total bytes allocated */ + PRUint32 maxalloc; /* maximum allocation size in bytes */ + PRFloat64 variance; /* size variance accumulator */ +}; +#endif + +struct PLArenaPool { + PLArena first; /* first arena in pool list */ + PLArena *current; /* arena from which to allocate space */ + PRUint32 arenasize; /* net exact size of a new arena */ + PRUword mask; /* alignment mask (power-of-2 - 1) */ +#ifdef PL_ARENAMETER + PLArenaStats stats; +#endif +}; + +/* + * WARNING: The PL_MAKE_MEM_ macros are for internal use by NSPR. Do NOT use + * them in your code. + * + * NOTE: Valgrind support to be added. + * + * The PL_MAKE_MEM_ macros are modeled after the MOZ_MAKE_MEM_ macros in + * Mozilla's mfbt/MemoryChecking.h. Only AddressSanitizer is supported now. + * + * Provides a common interface to the ASan (AddressSanitizer) and Valgrind + * functions used to mark memory in certain ways. In detail, the following + * three macros are provided: + * + * PL_MAKE_MEM_NOACCESS - Mark memory as unsafe to access (e.g. freed) + * PL_MAKE_MEM_UNDEFINED - Mark memory as accessible, with content undefined + * PL_MAKE_MEM_DEFINED - Mark memory as accessible, with content defined + * + * With Valgrind in use, these directly map to the three respective Valgrind + * macros. With ASan in use, the NOACCESS macro maps to poisoning the memory, + * while the UNDEFINED/DEFINED macros unpoison memory. + * + * With no memory checker available, all macros expand to the empty statement. + */ + +/* WARNING: PL_SANITIZE_ADDRESS is for internal use by this header. Do NOT + * define or test this macro in your code. + */ +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define PL_SANITIZE_ADDRESS 1 +#endif +#elif defined(__SANITIZE_ADDRESS__) +#define PL_SANITIZE_ADDRESS 1 +#endif + +#if defined(PL_SANITIZE_ADDRESS) + +/* These definitions are usually provided through the + * sanitizer/asan_interface.h header installed by ASan. + * See https://code.google.com/p/address-sanitizer/wiki/ManualPoisoning + */ + +void __asan_poison_memory_region(void const volatile *addr, size_t size); +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); + +#define PL_MAKE_MEM_NOACCESS(addr, size) \ + __asan_poison_memory_region((addr), (size)) + +#define PL_MAKE_MEM_UNDEFINED(addr, size) \ + __asan_unpoison_memory_region((addr), (size)) + +#define PL_MAKE_MEM_DEFINED(addr, size) \ + __asan_unpoison_memory_region((addr), (size)) + +#else + +#define PL_MAKE_MEM_NOACCESS(addr, size) +#define PL_MAKE_MEM_UNDEFINED(addr, size) +#define PL_MAKE_MEM_DEFINED(addr, size) + +#endif + +/* + * If the including .c file uses only one power-of-2 alignment, it may define + * PL_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions + * per ALLOCATE and GROW. + */ +#ifdef PL_ARENA_CONST_ALIGN_MASK +#define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + PL_ARENA_CONST_ALIGN_MASK) \ + & ~PL_ARENA_CONST_ALIGN_MASK) + +#define PL_INIT_ARENA_POOL(pool, name, size) \ + PL_InitArenaPool(pool, name, size, PL_ARENA_CONST_ALIGN_MASK + 1) +#else +#define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + (pool)->mask) & ~(pool)->mask) +#endif + +#define PL_ARENA_ALLOCATE(p, pool, nb) \ + PR_BEGIN_MACRO \ + PLArena *_a = (pool)->current; \ + PRUint32 _nb = PL_ARENA_ALIGN(pool, nb); \ + PRUword _p = _a->avail; \ + PRUword _q = _p + _nb; \ + if (_q > _a->limit) { \ + _p = (PRUword)PL_ArenaAllocate(pool, _nb); \ + } else { \ + _a->avail = _q; \ + } \ + p = (void *)_p; \ + PL_MAKE_MEM_UNDEFINED(p, nb); \ + PL_ArenaCountAllocation(pool, nb); \ + PR_END_MACRO + +#define PL_ARENA_GROW(p, pool, size, incr) \ + PR_BEGIN_MACRO \ + PLArena *_a = (pool)->current; \ + PRUint32 _incr = PL_ARENA_ALIGN(pool, incr); \ + PRUword _p = _a->avail; \ + PRUword _q = _p + _incr; \ + if (_p == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \ + _q <= _a->limit) { \ + PL_MAKE_MEM_UNDEFINED((unsigned char *)(p) + size, incr); \ + _a->avail = _q; \ + PL_ArenaCountInplaceGrowth(pool, size, incr); \ + } else { \ + p = PL_ArenaGrow(pool, p, size, incr); \ + } \ + PL_ArenaCountGrowth(pool, size, incr); \ + PR_END_MACRO + +#define PL_ARENA_MARK(pool) ((void *) (pool)->current->avail) +#define PR_UPTRDIFF(p,q) ((PRUword)(p) - (PRUword)(q)) + +#define PL_CLEAR_UNUSED_PATTERN(a, pattern) \ + PR_BEGIN_MACRO \ + PR_ASSERT((a)->avail <= (a)->limit); \ + PL_MAKE_MEM_UNDEFINED((void*)(a)->avail, (a)->limit - (a)->avail); \ + memset((void*)(a)->avail, (pattern), (a)->limit - (a)->avail); \ + PR_END_MACRO +#ifdef DEBUG +#define PL_FREE_PATTERN 0xDA +#define PL_CLEAR_UNUSED(a) PL_CLEAR_UNUSED_PATTERN((a), PL_FREE_PATTERN) +#define PL_CLEAR_ARENA(a) \ + PR_BEGIN_MACRO \ + PL_MAKE_MEM_UNDEFINED((void*)(a), (a)->limit - (PRUword)(a)); \ + memset((void*)(a), PL_FREE_PATTERN, (a)->limit - (PRUword)(a)); \ + PR_END_MACRO +#else +#define PL_CLEAR_UNUSED(a) +#define PL_CLEAR_ARENA(a) +#endif + +#define PL_ARENA_RELEASE(pool, mark) \ + PR_BEGIN_MACRO \ + char *_m = (char *)(mark); \ + PLArena *_a = (pool)->current; \ + if (PR_UPTRDIFF(_m, _a->base) <= PR_UPTRDIFF(_a->avail, _a->base)) { \ + _a->avail = (PRUword)PL_ARENA_ALIGN(pool, _m); \ + PL_CLEAR_UNUSED(_a); \ + PL_MAKE_MEM_NOACCESS((void*)_a->avail, _a->limit - _a->avail); \ + PL_ArenaCountRetract(pool, _m); \ + } else { \ + PL_ArenaRelease(pool, _m); \ + } \ + PL_ArenaCountRelease(pool, _m); \ + PR_END_MACRO + +#ifdef PL_ARENAMETER +#define PL_COUNT_ARENA(pool,op) ((pool)->stats.narenas op) +#else +#define PL_COUNT_ARENA(pool,op) +#endif + +#define PL_ARENA_DESTROY(pool, a, pnext) \ + PR_BEGIN_MACRO \ + PL_COUNT_ARENA(pool,--); \ + if ((pool)->current == (a)) (pool)->current = &(pool)->first; \ + *(pnext) = (a)->next; \ + PL_CLEAR_ARENA(a); \ + free(a); \ + (a) = 0; \ + PR_END_MACRO + +#ifdef PL_ARENAMETER + +#include + +PR_EXTERN(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb); + +PR_EXTERN(void) PL_ArenaCountInplaceGrowth( + PLArenaPool *pool, PRUint32 size, PRUint32 incr); + +PR_EXTERN(void) PL_ArenaCountGrowth( + PLArenaPool *pool, PRUint32 size, PRUint32 incr); + +PR_EXTERN(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark); + +PR_EXTERN(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark); + +PR_EXTERN(void) PL_DumpArenaStats(FILE *fp); + +#else /* !PL_ARENAMETER */ + +#define PL_ArenaCountAllocation(ap, nb) /* nothing */ +#define PL_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */ +#define PL_ArenaCountGrowth(ap, size, incr) /* nothing */ +#define PL_ArenaCountRelease(ap, mark) /* nothing */ +#define PL_ArenaCountRetract(ap, mark) /* nothing */ + +#endif /* !PL_ARENAMETER */ + +PR_END_EXTERN_C + +#endif /* plarena_h___ */ diff -Nru nspr-4.9.5/nspr/lib/ds/plarenas.h nspr-4.10.7/nspr/lib/ds/plarenas.h --- nspr-4.9.5/nspr/lib/ds/plarenas.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/plarenas.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef PLARENAS_H +#define PLARENAS_H + +PR_BEGIN_EXTERN_C + +typedef struct PLArenaPool PLArenaPool; + +/* +** Initialize an arena pool with the given name for debugging and metering, +** with a minimum gross size per arena of size bytes. The net size per arena +** is smaller than the gross size by a header of four pointers plus any +** necessary padding for alignment. +** +** Note: choose a gross size that's a power of two to avoid the heap allocator +** rounding the size up. +**/ +PR_EXTERN(void) PL_InitArenaPool( + PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align); + +/* +** Finish using arenas, freeing all memory associated with them. +**/ +PR_EXTERN(void) PL_ArenaFinish(void); + +/* +** Free the arenas in pool. The user may continue to allocate from pool +** after calling this function. There is no need to call PL_InitArenaPool() +** again unless PL_FinishArenaPool(pool) has been called. +**/ +PR_EXTERN(void) PL_FreeArenaPool(PLArenaPool *pool); + +/* +** Free the arenas in pool and finish using it altogether. +**/ +PR_EXTERN(void) PL_FinishArenaPool(PLArenaPool *pool); + +/* +** Compact all of the arenas in a pool so that no space is wasted. +** NOT IMPLEMENTED. Do not use. +**/ +PR_EXTERN(void) PL_CompactArenaPool(PLArenaPool *pool); + +/* +** Friend functions used by the PL_ARENA_*() macros. +** +** WARNING: do not call these functions directly. Always use the +** PL_ARENA_*() macros. +**/ +PR_EXTERN(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb); + +PR_EXTERN(void *) PL_ArenaGrow( + PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr); + +PR_EXTERN(void) PL_ArenaRelease(PLArenaPool *pool, char *mark); + +/* +** memset contents of all arenas in pool to pattern +*/ +PR_EXTERN(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern); + +/* +** A function like malloc_size() or malloc_usable_size() that measures the +** size of a heap block. +*/ +typedef size_t (*PLMallocSizeFn)(const void *ptr); + +/* +** Measure all memory used by a PLArenaPool, excluding the PLArenaPool +** structure. +*/ +PR_EXTERN(size_t) PL_SizeOfArenaPoolExcludingPool( + const PLArenaPool *pool, PLMallocSizeFn mallocSizeOf); + +PR_END_EXTERN_C + +#endif /* PLARENAS_H */ diff -Nru nspr-4.9.5/nspr/lib/ds/plds.def nspr-4.10.7/nspr/lib/ds/plds.def --- nspr-4.9.5/nspr/lib/ds/plds.def 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/plds.def 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,60 @@ +;+# +;+# This Source Code Form is subject to the terms of the Mozilla Public +;+# License, v. 2.0. If a copy of the MPL was not distributed with this +;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. +;+# +;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS +;+# 1. For all unix platforms, the string ";-" means "remove this line" +;+# 2. For all unix platforms, the string " DATA " will be removed from any +;+# line on which it occurs. +;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. +;+# On AIX, lines containing ";+" will be removed. +;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. +;+# 5. For all unix platforms, after the above processing has taken place, +;+# all characters after the first ";" on the line will be removed. +;+# And for AIX, the first ";" will also be removed. +;+# This file is passed directly to windows. Since ';' is a comment, all UNIX +;+# directives are hidden behind ";", ";+", and ";-" +;+NSPR_4.0 { +;+ global: +LIBRARY plds4 ;- +EXPORTS ;- +PL_ArenaAllocate; +PL_ArenaFinish; +PL_ArenaGrow; +PL_ArenaRelease; +PL_CompactArenaPool; +PL_CompareStrings; +PL_CompareValues; +PL_FinishArenaPool; +PL_FreeArenaPool; +PL_HashString; +PL_HashTableAdd; +PL_HashTableDestroy; +PL_HashTableDump; +PL_HashTableEnumerateEntries; +PL_HashTableLookup; +PL_HashTableRawAdd; +PL_HashTableRawLookup; +PL_HashTableRawRemove; +PL_HashTableRemove; +PL_InitArenaPool; +PL_NewHashTable; +libVersionPoint; +;+ local: *; +;+}; +;+ +;+NSPR_4.1 { +;+ global: +PL_HashTableLookupConst; +PL_HashTableRawLookupConst; +;+} NSPR_4.0; +;+ +;+NSPR_4.8.5 { +;+ global: +PL_ClearArenaPool; +;+} NSPR_4.1; +;+NSPR_4.9.6 { +;+ global: +PL_SizeOfArenaPoolExcludingPool; +;+} NSPR_4.8.5; diff -Nru nspr-4.9.5/nspr/lib/ds/plds.rc nspr-4.10.7/nspr/lib/ds/plds.rc --- nspr-4.9.5/nspr/lib/ds/plds.rc 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/plds.rc 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include + +#define MY_LIBNAME "plds" +#define MY_FILEDESCRIPTION "PLDS Library" + +#define STRINGIZE(x) #x +#define STRINGIZE2(x) STRINGIZE(x) +#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR) + +#ifdef _DEBUG +#define MY_DEBUG_STR " (debug)" +#define MY_FILEFLAGS_1 VS_FF_DEBUG +#else +#define MY_DEBUG_STR "" +#define MY_FILEFLAGS_1 0x0L +#endif +#if PR_BETA +#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE +#else +#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 +#endif + +#ifdef WINNT +#define MY_FILEOS VOS_NT_WINDOWS32 +#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR +#else +#define MY_FILEOS VOS__WINDOWS32 +#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Version-information resource +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 + PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS MY_FILEFLAGS_2 + FILEOS MY_FILEOS + FILETYPE VFT_DLL + FILESUBTYPE 0x0L // not used + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" // Lang=US English, CharSet=Unicode + BEGIN + VALUE "CompanyName", "Mozilla Foundation\0" + VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" + VALUE "FileVersion", PR_VERSION "\0" + VALUE "InternalName", MY_INTERNAL_NAME "\0" + VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" + VALUE "ProductName", "Netscape Portable Runtime\0" + VALUE "ProductVersion", PR_VERSION "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff -Nru nspr-4.9.5/nspr/lib/ds/plhash.c nspr-4.10.7/nspr/lib/ds/plhash.c --- nspr-4.9.5/nspr/lib/ds/plhash.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/plhash.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,483 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * PL hash table package. + */ +#include "plhash.h" +#include "prbit.h" +#include "prlog.h" +#include "prmem.h" +#include "prtypes.h" +#include +#include + +/* Compute the number of buckets in ht */ +#define NBUCKETS(ht) (1 << (PL_HASH_BITS - (ht)->shift)) + +/* The smallest table has 16 buckets */ +#define MINBUCKETSLOG2 4 +#define MINBUCKETS (1 << MINBUCKETSLOG2) + +/* Compute the maximum entries given n buckets that we will tolerate, ~90% */ +#define OVERLOADED(n) ((n) - ((n) >> 3)) + +/* Compute the number of entries below which we shrink the table by half */ +#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0) + +/* +** Stubs for default hash allocator ops. +*/ +static void * PR_CALLBACK +DefaultAllocTable(void *pool, PRSize size) +{ + return PR_MALLOC(size); +} + +static void PR_CALLBACK +DefaultFreeTable(void *pool, void *item) +{ + PR_Free(item); +} + +static PLHashEntry * PR_CALLBACK +DefaultAllocEntry(void *pool, const void *key) +{ + return PR_NEW(PLHashEntry); +} + +static void PR_CALLBACK +DefaultFreeEntry(void *pool, PLHashEntry *he, PRUintn flag) +{ + if (flag == HT_FREE_ENTRY) + PR_Free(he); +} + +static PLHashAllocOps defaultHashAllocOps = { + DefaultAllocTable, DefaultFreeTable, + DefaultAllocEntry, DefaultFreeEntry +}; + +PR_IMPLEMENT(PLHashTable *) +PL_NewHashTable(PRUint32 n, PLHashFunction keyHash, + PLHashComparator keyCompare, PLHashComparator valueCompare, + const PLHashAllocOps *allocOps, void *allocPriv) +{ + PLHashTable *ht; + PRSize nb; + + if (n <= MINBUCKETS) { + n = MINBUCKETSLOG2; + } else { + n = PR_CeilingLog2(n); + if ((PRInt32)n < 0) + return 0; + } + + if (!allocOps) allocOps = &defaultHashAllocOps; + + ht = (PLHashTable*)((*allocOps->allocTable)(allocPriv, sizeof *ht)); + if (!ht) + return 0; + memset(ht, 0, sizeof *ht); + ht->shift = PL_HASH_BITS - n; + n = 1 << n; + nb = n * sizeof(PLHashEntry *); + ht->buckets = (PLHashEntry**)((*allocOps->allocTable)(allocPriv, nb)); + if (!ht->buckets) { + (*allocOps->freeTable)(allocPriv, ht); + return 0; + } + memset(ht->buckets, 0, nb); + + ht->keyHash = keyHash; + ht->keyCompare = keyCompare; + ht->valueCompare = valueCompare; + ht->allocOps = allocOps; + ht->allocPriv = allocPriv; + return ht; +} + +PR_IMPLEMENT(void) +PL_HashTableDestroy(PLHashTable *ht) +{ + PRUint32 i, n; + PLHashEntry *he, *next; + const PLHashAllocOps *allocOps = ht->allocOps; + void *allocPriv = ht->allocPriv; + + n = NBUCKETS(ht); + for (i = 0; i < n; i++) { + for (he = ht->buckets[i]; he; he = next) { + next = he->next; + (*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY); + } + } +#ifdef DEBUG + memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]); +#endif + (*allocOps->freeTable)(allocPriv, ht->buckets); +#ifdef DEBUG + memset(ht, 0xDB, sizeof *ht); +#endif + (*allocOps->freeTable)(allocPriv, ht); +} + +/* +** Multiplicative hash, from Knuth 6.4. +*/ +#define GOLDEN_RATIO 0x9E3779B9U /* 2/(1+sqrt(5))*(2^32) */ + +PR_IMPLEMENT(PLHashEntry **) +PL_HashTableRawLookup(PLHashTable *ht, PLHashNumber keyHash, const void *key) +{ + PLHashEntry *he, **hep, **hep0; + PLHashNumber h; + +#ifdef HASHMETER + ht->nlookups++; +#endif + h = keyHash * GOLDEN_RATIO; + h >>= ht->shift; + hep = hep0 = &ht->buckets[h]; + while ((he = *hep) != 0) { + if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) { + /* Move to front of chain if not already there */ + if (hep != hep0) { + *hep = he->next; + he->next = *hep0; + *hep0 = he; + } + return hep0; + } + hep = &he->next; +#ifdef HASHMETER + ht->nsteps++; +#endif + } + return hep; +} + +/* +** Same as PL_HashTableRawLookup but doesn't reorder the hash entries. +*/ +PR_IMPLEMENT(PLHashEntry **) +PL_HashTableRawLookupConst(PLHashTable *ht, PLHashNumber keyHash, + const void *key) +{ + PLHashEntry *he, **hep; + PLHashNumber h; + +#ifdef HASHMETER + ht->nlookups++; +#endif + h = keyHash * GOLDEN_RATIO; + h >>= ht->shift; + hep = &ht->buckets[h]; + while ((he = *hep) != 0) { + if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) { + break; + } + hep = &he->next; +#ifdef HASHMETER + ht->nsteps++; +#endif + } + return hep; +} + +PR_IMPLEMENT(PLHashEntry *) +PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep, + PLHashNumber keyHash, const void *key, void *value) +{ + PRUint32 i, n; + PLHashEntry *he, *next, **oldbuckets; + PRSize nb; + + /* Grow the table if it is overloaded */ + n = NBUCKETS(ht); + if (ht->nentries >= OVERLOADED(n)) { + oldbuckets = ht->buckets; + nb = 2 * n * sizeof(PLHashEntry *); + ht->buckets = (PLHashEntry**) + ((*ht->allocOps->allocTable)(ht->allocPriv, nb)); + if (!ht->buckets) { + ht->buckets = oldbuckets; + return 0; + } + memset(ht->buckets, 0, nb); +#ifdef HASHMETER + ht->ngrows++; +#endif + ht->shift--; + + for (i = 0; i < n; i++) { + for (he = oldbuckets[i]; he; he = next) { + next = he->next; + hep = PL_HashTableRawLookup(ht, he->keyHash, he->key); + PR_ASSERT(*hep == 0); + he->next = 0; + *hep = he; + } + } +#ifdef DEBUG + memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); +#endif + (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); + hep = PL_HashTableRawLookup(ht, keyHash, key); + } + + /* Make a new key value entry */ + he = (*ht->allocOps->allocEntry)(ht->allocPriv, key); + if (!he) + return 0; + he->keyHash = keyHash; + he->key = key; + he->value = value; + he->next = *hep; + *hep = he; + ht->nentries++; + return he; +} + +PR_IMPLEMENT(PLHashEntry *) +PL_HashTableAdd(PLHashTable *ht, const void *key, void *value) +{ + PLHashNumber keyHash; + PLHashEntry *he, **hep; + + keyHash = (*ht->keyHash)(key); + hep = PL_HashTableRawLookup(ht, keyHash, key); + if ((he = *hep) != 0) { + /* Hit; see if values match */ + if ((*ht->valueCompare)(he->value, value)) { + /* key,value pair is already present in table */ + return he; + } + if (he->value) + (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE); + he->value = value; + return he; + } + return PL_HashTableRawAdd(ht, hep, keyHash, key, value); +} + +PR_IMPLEMENT(void) +PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he) +{ + PRUint32 i, n; + PLHashEntry *next, **oldbuckets; + PRSize nb; + + *hep = he->next; + (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY); + + /* Shrink table if it's underloaded */ + n = NBUCKETS(ht); + if (--ht->nentries < UNDERLOADED(n)) { + oldbuckets = ht->buckets; + nb = n * sizeof(PLHashEntry*) / 2; + ht->buckets = (PLHashEntry**)( + (*ht->allocOps->allocTable)(ht->allocPriv, nb)); + if (!ht->buckets) { + ht->buckets = oldbuckets; + return; + } + memset(ht->buckets, 0, nb); +#ifdef HASHMETER + ht->nshrinks++; +#endif + ht->shift++; + + for (i = 0; i < n; i++) { + for (he = oldbuckets[i]; he; he = next) { + next = he->next; + hep = PL_HashTableRawLookup(ht, he->keyHash, he->key); + PR_ASSERT(*hep == 0); + he->next = 0; + *hep = he; + } + } +#ifdef DEBUG + memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); +#endif + (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); + } +} + +PR_IMPLEMENT(PRBool) +PL_HashTableRemove(PLHashTable *ht, const void *key) +{ + PLHashNumber keyHash; + PLHashEntry *he, **hep; + + keyHash = (*ht->keyHash)(key); + hep = PL_HashTableRawLookup(ht, keyHash, key); + if ((he = *hep) == 0) + return PR_FALSE; + + /* Hit; remove element */ + PL_HashTableRawRemove(ht, hep, he); + return PR_TRUE; +} + +PR_IMPLEMENT(void *) +PL_HashTableLookup(PLHashTable *ht, const void *key) +{ + PLHashNumber keyHash; + PLHashEntry *he, **hep; + + keyHash = (*ht->keyHash)(key); + hep = PL_HashTableRawLookup(ht, keyHash, key); + if ((he = *hep) != 0) { + return he->value; + } + return 0; +} + +/* +** Same as PL_HashTableLookup but doesn't reorder the hash entries. +*/ +PR_IMPLEMENT(void *) +PL_HashTableLookupConst(PLHashTable *ht, const void *key) +{ + PLHashNumber keyHash; + PLHashEntry *he, **hep; + + keyHash = (*ht->keyHash)(key); + hep = PL_HashTableRawLookupConst(ht, keyHash, key); + if ((he = *hep) != 0) { + return he->value; + } + return 0; +} + +/* +** Iterate over the entries in the hash table calling func for each +** entry found. Stop if "f" says to (return value & PR_ENUMERATE_STOP). +** Return a count of the number of elements scanned. +*/ +PR_IMPLEMENT(int) +PL_HashTableEnumerateEntries(PLHashTable *ht, PLHashEnumerator f, void *arg) +{ + PLHashEntry *he, **hep; + PRUint32 i, nbuckets; + int rv, n = 0; + PLHashEntry *todo = 0; + + nbuckets = NBUCKETS(ht); + for (i = 0; i < nbuckets; i++) { + hep = &ht->buckets[i]; + while ((he = *hep) != 0) { + rv = (*f)(he, n, arg); + n++; + if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) { + *hep = he->next; + if (rv & HT_ENUMERATE_REMOVE) { + he->next = todo; + todo = he; + } + } else { + hep = &he->next; + } + if (rv & HT_ENUMERATE_STOP) { + goto out; + } + } + } + +out: + hep = &todo; + while ((he = *hep) != 0) { + PL_HashTableRawRemove(ht, hep, he); + } + return n; +} + +#ifdef HASHMETER +#include +#include + +PR_IMPLEMENT(void) +PL_HashTableDumpMeter(PLHashTable *ht, PLHashEnumerator dump, FILE *fp) +{ + double mean, variance; + PRUint32 nchains, nbuckets; + PRUint32 i, n, maxChain, maxChainLen; + PLHashEntry *he; + + variance = 0; + nchains = 0; + maxChainLen = 0; + nbuckets = NBUCKETS(ht); + for (i = 0; i < nbuckets; i++) { + he = ht->buckets[i]; + if (!he) + continue; + nchains++; + for (n = 0; he; he = he->next) + n++; + variance += n * n; + if (n > maxChainLen) { + maxChainLen = n; + maxChain = i; + } + } + mean = (double)ht->nentries / nchains; + variance = fabs(variance / nchains - mean * mean); + + fprintf(fp, "\nHash table statistics:\n"); + fprintf(fp, " number of lookups: %u\n", ht->nlookups); + fprintf(fp, " number of entries: %u\n", ht->nentries); + fprintf(fp, " number of grows: %u\n", ht->ngrows); + fprintf(fp, " number of shrinks: %u\n", ht->nshrinks); + fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps + / ht->nlookups); + fprintf(fp, "mean hash chain length: %g\n", mean); + fprintf(fp, " standard deviation: %g\n", sqrt(variance)); + fprintf(fp, " max hash chain length: %u\n", maxChainLen); + fprintf(fp, " max hash chain: [%u]\n", maxChain); + + for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++) + if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT) + break; +} +#endif /* HASHMETER */ + +PR_IMPLEMENT(int) +PL_HashTableDump(PLHashTable *ht, PLHashEnumerator dump, FILE *fp) +{ + int count; + + count = PL_HashTableEnumerateEntries(ht, dump, fp); +#ifdef HASHMETER + PL_HashTableDumpMeter(ht, dump, fp); +#endif + return count; +} + +PR_IMPLEMENT(PLHashNumber) +PL_HashString(const void *key) +{ + PLHashNumber h; + const PRUint8 *s; + + h = 0; + for (s = (const PRUint8*)key; *s; s++) + h = PR_ROTATE_LEFT32(h, 4) ^ *s; + return h; +} + +PR_IMPLEMENT(int) +PL_CompareStrings(const void *v1, const void *v2) +{ + return strcmp((const char*)v1, (const char*)v2) == 0; +} + +PR_IMPLEMENT(int) +PL_CompareValues(const void *v1, const void *v2) +{ + return v1 == v2; +} diff -Nru nspr-4.9.5/nspr/lib/ds/plhash.h nspr-4.10.7/nspr/lib/ds/plhash.h --- nspr-4.9.5/nspr/lib/ds/plhash.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/plhash.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef plhash_h___ +#define plhash_h___ +/* + * API to portable hash table code. + */ +#include +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +typedef struct PLHashEntry PLHashEntry; +typedef struct PLHashTable PLHashTable; +typedef PRUint32 PLHashNumber; +#define PL_HASH_BITS 32 /* Number of bits in PLHashNumber */ +typedef PLHashNumber (PR_CALLBACK *PLHashFunction)(const void *key); +typedef PRIntn (PR_CALLBACK *PLHashComparator)(const void *v1, const void *v2); + +typedef PRIntn (PR_CALLBACK *PLHashEnumerator)(PLHashEntry *he, PRIntn i, void *arg); + +/* Flag bits in PLHashEnumerator's return value */ +#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */ +#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */ +#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */ +#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */ + +typedef struct PLHashAllocOps { + void * (PR_CALLBACK *allocTable)(void *pool, PRSize size); + void (PR_CALLBACK *freeTable)(void *pool, void *item); + PLHashEntry * (PR_CALLBACK *allocEntry)(void *pool, const void *key); + void (PR_CALLBACK *freeEntry)(void *pool, PLHashEntry *he, PRUintn flag); +} PLHashAllocOps; + +#define HT_FREE_VALUE 0 /* just free the entry's value */ +#define HT_FREE_ENTRY 1 /* free value and entire entry */ + +struct PLHashEntry { + PLHashEntry *next; /* hash chain linkage */ + PLHashNumber keyHash; /* key hash function result */ + const void *key; /* ptr to opaque key */ + void *value; /* ptr to opaque value */ +}; + +struct PLHashTable { + PLHashEntry **buckets; /* vector of hash buckets */ + PRUint32 nentries; /* number of entries in table */ + PRUint32 shift; /* multiplicative hash shift */ + PLHashFunction keyHash; /* key hash function */ + PLHashComparator keyCompare; /* key comparison function */ + PLHashComparator valueCompare; /* value comparison function */ + const PLHashAllocOps *allocOps; /* allocation operations */ + void *allocPriv; /* allocation private data */ +#ifdef HASHMETER + PRUint32 nlookups; /* total number of lookups */ + PRUint32 nsteps; /* number of hash chains traversed */ + PRUint32 ngrows; /* number of table expansions */ + PRUint32 nshrinks; /* number of table contractions */ +#endif +}; + +/* + * Create a new hash table. + * If allocOps is null, use default allocator ops built on top of malloc(). + */ +PR_EXTERN(PLHashTable *) +PL_NewHashTable(PRUint32 numBuckets, PLHashFunction keyHash, + PLHashComparator keyCompare, PLHashComparator valueCompare, + const PLHashAllocOps *allocOps, void *allocPriv); + +PR_EXTERN(void) +PL_HashTableDestroy(PLHashTable *ht); + +/* Higher level access methods */ +PR_EXTERN(PLHashEntry *) +PL_HashTableAdd(PLHashTable *ht, const void *key, void *value); + +PR_EXTERN(PRBool) +PL_HashTableRemove(PLHashTable *ht, const void *key); + +PR_EXTERN(void *) +PL_HashTableLookup(PLHashTable *ht, const void *key); + +PR_EXTERN(void *) +PL_HashTableLookupConst(PLHashTable *ht, const void *key); + +PR_EXTERN(PRIntn) +PL_HashTableEnumerateEntries(PLHashTable *ht, PLHashEnumerator f, void *arg); + +/* General-purpose C string hash function. */ +PR_EXTERN(PLHashNumber) +PL_HashString(const void *key); + +/* Compare strings using strcmp(), return true if equal. */ +PR_EXTERN(PRIntn) +PL_CompareStrings(const void *v1, const void *v2); + +/* Stub function just returns v1 == v2 */ +PR_EXTERN(PRIntn) +PL_CompareValues(const void *v1, const void *v2); + +/* Low level access methods */ +PR_EXTERN(PLHashEntry **) +PL_HashTableRawLookup(PLHashTable *ht, PLHashNumber keyHash, const void *key); + +PR_EXTERN(PLHashEntry **) +PL_HashTableRawLookupConst(PLHashTable *ht, PLHashNumber keyHash, + const void *key); + +PR_EXTERN(PLHashEntry *) +PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep, PLHashNumber keyHash, + const void *key, void *value); + +PR_EXTERN(void) +PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he); + +/* This can be trivially implemented using PL_HashTableEnumerateEntries. */ +PR_EXTERN(PRIntn) +PL_HashTableDump(PLHashTable *ht, PLHashEnumerator dump, FILE *fp); + +PR_END_EXTERN_C + +#endif /* plhash_h___ */ diff -Nru nspr-4.9.5/nspr/lib/ds/plvrsion.c nspr-4.10.7/nspr/lib/ds/plvrsion.c --- nspr-4.9.5/nspr/lib/ds/plvrsion.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/ds/plvrsion.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include "prvrsion.h" + +/************************************************************************/ +/**************************IDENTITY AND VERSIONING***********************/ +/************************************************************************/ +#include "_pl_bld.h" +#if !defined(_BUILD_TIME) +#ifdef HAVE_LONG_LONG +#define _BUILD_TIME 0 +#else +#define _BUILD_TIME {0, 0} +#endif +#endif +#if !defined(_BUILD_STRING) +#define _BUILD_STRING "" +#endif +#if !defined(_PRODUCTION) +#define _PRODUCTION "" +#endif +#if defined(DEBUG) +#define _DEBUG_STRING " (debug)" +#else +#define _DEBUG_STRING "" +#endif + +/* + * A trick to expand the PR_VMAJOR macro before concatenation. + */ +#define CONCAT(x, y) x ## y +#define CONCAT2(x, y) CONCAT(x, y) +#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplds, PR_VMAJOR) + +PRVersionDescription VERSION_DESC_NAME = +{ + /* version */ 2, /* this is the only one supported */ + /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */ + /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */ + /* vMajor */ PR_VMAJOR, /* NSPR's version number */ + /* vMinor */ PR_VMINOR, /* and minor version */ + /* vPatch */ PR_VPATCH, /* and patch */ + /* beta */ PR_BETA, /* beta build boolean */ +#if defined(DEBUG) + /* debug */ PR_TRUE, /* a debug build */ +#else + /* debug */ PR_FALSE, /* an optomized build */ +#endif + /* special */ PR_FALSE, /* they're all special, but ... */ + /* filename */ _PRODUCTION, /* the produced library name */ + /* description */ "Portable runtime", /* what we are */ + /* security */ "N/A", /* not applicable here */ + /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved", + /* comment */ "http://www.mozilla.org/MPL/", + /* specialString */ "" +}; + +#ifdef XP_UNIX + +/* + * Version information for the 'ident' and 'what commands + * + * NOTE: the first component of the concatenated rcsid string + * must not end in a '$' to prevent rcs keyword substitution. + */ +static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING + " " _BUILD_STRING " $"; +static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING + " " _BUILD_STRING; + +#endif /* XP_UNIX */ + +PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint() +{ +#ifdef XP_UNIX + /* + * Add dummy references to rcsid and sccsid to prevent them + * from being optimized away as unused variables. + */ + const char *dummy; + + dummy = rcsid; + dummy = sccsid; +#endif + return &VERSION_DESC_NAME; +} /* versionEntryPointType */ + +/* plvrsion.c */ + diff -Nru nspr-4.9.5/nspr/lib/libc/.cvsignore nspr-4.10.7/nspr/lib/libc/.cvsignore --- nspr-4.9.5/nspr/lib/libc/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/lib/libc/include/.cvsignore nspr-4.10.7/nspr/lib/libc/include/.cvsignore --- nspr-4.9.5/nspr/lib/libc/include/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/include/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/lib/libc/include/Makefile.in nspr-4.10.7/nspr/lib/libc/include/Makefile.in --- nspr-4.9.5/nspr/lib/libc/include/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/include/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,24 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk +include $(topsrcdir)/config/config.mk + +HEADERS = $(wildcard $(srcdir)/*.h) + +RELEASE_HEADERS = $(HEADERS) +RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR) + +include $(topsrcdir)/config/rules.mk + +export:: $(HEADERS) + $(INSTALL) -m 444 $(HEADERS) $(dist_includedir) diff -Nru nspr-4.9.5/nspr/lib/libc/include/plbase64.h nspr-4.10.7/nspr/lib/libc/include/plbase64.h --- nspr-4.9.5/nspr/lib/libc/include/plbase64.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/include/plbase64.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _plbase64_h +#define _plbase64_h + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* + * PL_Base64Encode + * + * This routine encodes the data pointed to by the "src" parameter using the + * base64 algorithm, and returns a pointer to the result. If the "srclen" + * parameter is not zero, it specifies the length of the source data. If it + * is zero, the source data is assumed to be null-terminated, and PL_strlen + * is used to determine the source length. If the "dest" parameter is not + * null, it is assumed to point to a buffer of sufficient size (which may be + * calculated: ((srclen + 2)/3)*4) into which the encoded data is placed + * (without any termination). If the "dest" parameter is null, a buffer is + * allocated from the heap to hold the encoded data, and the result *will* + * be terminated with an extra null character. It is the caller's + * responsibility to free the result when it is allocated. A null is returned + * if the allocation fails. + * + * NOTE: when calculating ((srclen + 2)/3)*4), first ensure that + * srclen <= (PR_UINT32_MAX/4) * 3 + * to avoid PRUint32 overflow. + */ + +PR_EXTERN(char *) +PL_Base64Encode +( + const char *src, + PRUint32 srclen, + char *dest +); + +/* + * PL_Base64Decode + * + * This routine decodes the data pointed to by the "src" parameter using + * the base64 algorithm, and returns a pointer to the result. The source + * may either include or exclude any trailing '=' characters. If the + * "srclen" parameter is not zero, it specifies the length of the source + * data. If it is zero, PL_strlen will be used to determine the source + * length. If the "dest" parameter is not null, it is assumed to point to + * a buffer of sufficient size (which may be calculated: (srclen * 3)/4 + * when srclen includes the '=' characters) into which the decoded data + * is placed (without any termination). If the "dest" parameter is null, + * a buffer is allocated from the heap to hold the decoded data, and the + * result *will* be terminated with an extra null character. It is the + * caller's responsibility to free the result when it is allocated. A null + * is retuned if the allocation fails, or if the source is not well-coded. + * + * NOTE: when calculating (srclen * 3)/4, first ensure that + * srclen <= PR_UINT32_MAX/3 + * to avoid PRUint32 overflow. Alternatively, calculate + * (srclen/4) * 3 + ((srclen%4) * 3)/4 + * which is equivalent but doesn't overflow for any value of srclen. + */ + +PR_EXTERN(char *) +PL_Base64Decode +( + const char *src, + PRUint32 srclen, + char *dest +); + +PR_END_EXTERN_C + +#endif /* _plbase64_h */ diff -Nru nspr-4.9.5/nspr/lib/libc/include/plerror.h nspr-4.10.7/nspr/lib/libc/include/plerror.h --- nspr-4.9.5/nspr/lib/libc/include/plerror.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/include/plerror.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: plerror.h +** Description: Simple routine to print translate the calling thread's +** error numbers and print them. +*/ + +#if defined(PLERROR_H) +#else +#define PLERROR_H + +#include "prio.h" +#include "prtypes.h" + +PR_BEGIN_EXTERN_C +/* +** Print the messages to "syserr" prepending 'msg' if not NULL. +*/ +PR_EXTERN(void) PL_PrintError(const char *msg); + +/* +** Print the messages to specified output file prepending 'msg' if not NULL. +*/ +PR_EXTERN(void) PL_FPrintError(PRFileDesc *output, const char *msg); + +PR_END_EXTERN_C + +#endif /* defined(PLERROR_H) */ + +/* plerror.h */ diff -Nru nspr-4.9.5/nspr/lib/libc/include/plgetopt.h nspr-4.10.7/nspr/lib/libc/include/plgetopt.h --- nspr-4.9.5/nspr/lib/libc/include/plgetopt.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/include/plgetopt.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: plgetopt.h +** Description: utilities to parse argc/argv +*/ + +#if defined(PLGETOPT_H_) +#else +#define PLGETOPT_H_ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +typedef struct PLOptionInternal PLOptionInternal; + +typedef enum +{ + PL_OPT_OK, /* all's well with the option */ + PL_OPT_EOL, /* end of options list */ + PL_OPT_BAD /* invalid option (and value) */ +} PLOptStatus; + +typedef struct PLLongOpt +{ + const char * longOptName; /* long option name string */ + PRIntn longOption; /* value put in PLOptState for this option. */ + PRBool valueRequired; /* If option name not followed by '=', */ + /* value is the next argument from argv. */ +} PLLongOpt; + +typedef struct PLOptState +{ + char option; /* the name of the option */ + const char *value; /* the value of that option | NULL */ + + PLOptionInternal *internal; /* private processing state */ + + PRIntn longOption; /* value from PLLongOpt put here */ + PRIntn longOptIndex; /* index into caller's array of PLLongOpts */ +} PLOptState; + +/* + * PL_CreateOptState + * + * The argument "options" points to a string of single-character option + * names. Option names that may have an option argument value must be + * followed immediately by a ':' character. + */ +PR_EXTERN(PLOptState*) PL_CreateOptState( + PRIntn argc, char **argv, const char *options); + +/* + * PL_CreateLongOptState + * + * Alternative to PL_CreateOptState. + * Allows caller to specify BOTH a string of single-character option names, + * AND an array of structures describing "long" (keyword) option names. + * The array is terminated by a structure in which longOptName is NULL. + * Long option values (arguments) may always be given as "--name=value". + * If PLLongOpt.valueRequired is not PR_FALSE, and the option name was not + * followed by '=' then the next argument from argv is taken as the value. + */ +PR_EXTERN(PLOptState*) PL_CreateLongOptState( + PRIntn argc, char **argv, const char *options, + const PLLongOpt *longOpts); +/* + * PL_DestroyOptState + * + * Call this to destroy the PLOptState returned from PL_CreateOptState or + * PL_CreateLongOptState. + */ +PR_EXTERN(void) PL_DestroyOptState(PLOptState *opt); + +/* + * PL_GetNextOpt + * + * When this function returns PL_OPT_OK, + * - opt->option will hold the single-character option name that was parsed, + * or zero. + * When opt->option is zero, the token parsed was either a "long" (keyword) + * option or a positional parameter. + * For a positional parameter, + * - opt->longOptIndex will contain -1, and + * - opt->value will point to the positional parameter string. + * For a long option name, + * - opt->longOptIndex will contain the non-negative index of the + * PLLongOpt structure in the caller's array of PLLongOpt structures + * corresponding to the long option name, and + * For a single-character or long option, + * - opt->longOption will contain the value of the single-character option + * name, or the value of the longOption from the PLLongOpt structure + * for that long option. See notes below. + * - opt->value will point to the argument option string, or will + * be NULL if option does not require argument. If option requires + * argument but it is not provided, PL_OPT_BAD is returned. + * When opt->option is non-zero, + * - opt->longOptIndex will be -1 + * When this function returns PL_OPT_EOL, or PL_OPT_BAD, the contents of + * opt are undefined. + * + * Notes: It is possible to ignore opt->option, and always look at + * opt->longOption instead. opt->longOption will contain the same value + * as opt->option for single-character option names, and will contain the + * value of longOption from the PLLongOpt structure for long option names. + * This means that it is possible to equivalence long option names to + * single character names by giving the longOption in the PLLongOpt struct + * the same value as the single-character option name. + * For long options that are NOT intended to be equivalent to any single- + * character option, the longOption value should be chosen to not match + * any possible single character name. It might be advisable to choose + * longOption values greater than 0xff for such long options. + */ +PR_EXTERN(PLOptStatus) PL_GetNextOpt(PLOptState *opt); + +PR_END_EXTERN_C + +#endif /* defined(PLGETOPT_H_) */ + +/* plgetopt.h */ + diff -Nru nspr-4.9.5/nspr/lib/libc/include/plstr.h nspr-4.10.7/nspr/lib/libc/include/plstr.h --- nspr-4.9.5/nspr/lib/libc/include/plstr.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/include/plstr.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,437 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _plstr_h +#define _plstr_h + +/* + * plstr.h + * + * This header file exports the API to the NSPR portable library or string- + * handling functions. + * + * This API was not designed as an "optimal" or "ideal" string library; it + * was based on the good ol' unix string.3 functions, and was written to + * + * 1) replace the libc functions, for cross-platform consistency, + * 2) complete the API on platforms lacking common functions (e.g., + * strcase*), and + * 3) to implement some obvious "closure" functions that I've seen + * people hacking around in our code. + * + * Point number three largely means that most functions have an "strn" + * limited-length version, and all comparison routines have a non-case- + * sensitive version available. + */ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C +/* + * PL_strlen + * + * Returns the length of the provided string, not including the trailing '\0'. + */ + +PR_EXTERN(PRUint32) +PL_strlen(const char *str); + +/* + * PL_strnlen + * + * Returns the length of the provided string, not including the trailing '\0', + * up to the indicated maximum. The string will not be examined beyond the + * maximum; if no terminating '\0' is found, the maximum will be returned. + */ + +PR_EXTERN(PRUint32) +PL_strnlen(const char *str, PRUint32 max); + +/* + * PL_strcpy + * + * Copies the source string, up to and including the trailing '\0', into the + * destination buffer. It does not (can not) verify that the destination + * buffer is large enough. It returns the "dest" argument. + */ + +PR_EXTERN(char *) +PL_strcpy(char *dest, const char *src); + +/* + * PL_strncpy + * + * Copies the source string into the destination buffer, up to and including + * the trailing '\0' or up to and including the max'th character, whichever + * comes first. It does not (can not) verify that the destination buffer is + * large enough. If the source string is longer than the maximum length, + * the result will *not* be null-terminated (JLRU). + */ + +PR_EXTERN(char *) +PL_strncpy(char *dest, const char *src, PRUint32 max); + +/* + * PL_strncpyz + * + * Copies the source string into the destination buffer, up to and including + * the trailing '\0' or up but not including the max'th character, whichever + * comes first. It does not (can not) verify that the destination buffer is + * large enough. The destination string is always terminated with a '\0', + * unlike the traditional libc implementation. It returns the "dest" argument. + * + * NOTE: If you call this with a source "abcdefg" and a max of 5, the + * destination will end up with "abcd\0" (i.e., its strlen length will be 4)! + * + * This means you can do this: + * + * char buffer[ SOME_SIZE ]; + * PL_strncpyz(buffer, src, sizeof(buffer)); + * + * and the result will be properly terminated. + */ + +PR_EXTERN(char *) +PL_strncpyz(char *dest, const char *src, PRUint32 max); + +/* + * PL_strdup + * + * Returns a pointer to a malloc'd extent of memory containing a duplicate + * of the argument string. The size of the allocated extent is one greater + * than the length of the argument string, because of the terminator. A + * null argument, like a zero-length argument, will result in a pointer to + * a one-byte extent containing the null value. This routine returns null + * upon malloc failure. + */ + +PR_EXTERN(char *) +PL_strdup(const char *s); + +/* + * PL_strfree + * + * Free memory allocated by PL_strdup + */ + +PR_EXTERN(void) +PL_strfree(char *s); + +/* + * PL_strndup + * + * Returns a pointer to a malloc'd extent of memory containing a duplicate + * of the argument string, up to the maximum specified. If the argument + * string has a length greater than the value of the specified maximum, the + * return value will be a pointer to an extent of memory of length one + * greater than the maximum specified. A null string, a zero-length string, + * or a zero maximum will all result in a pointer to a one-byte extent + * containing the null value. This routine returns null upon malloc failure. + */ + +PR_EXTERN(char *) +PL_strndup(const char *s, PRUint32 max); + +/* + * PL_strcat + * + * Appends a copy of the string pointed to by the second argument to the + * end of the string pointed to by the first. The destination buffer is + * not (can not be) checked for sufficient size. A null destination + * argument returns null; otherwise, the first argument is returned. + */ + +PR_EXTERN(char *) +PL_strcat(char *dst, const char *src); + +/* + * PL_strncat + * + * Appends a copy of the string pointed to by the second argument, up to + * the maximum size specified, to the end of the string pointed to by the + * first. The destination buffer is not (can not be) checked for sufficient + * size. A null destination argument returns null; otherwise, the first + * argument is returned. If the maximum size limits the copy, then the + * result will *not* be null-terminated (JLRU). A null destination + * returns null; otherwise, the destination argument is returned. + */ + +PR_EXTERN(char *) +PL_strncat(char *dst, const char *src, PRUint32 max); + +/* + * PL_strcatn + * + * Appends a copy of the string pointed to by the third argument, to the + * end of the string pointed to by the first. The second argument specifies + * the maximum size of the destination buffer, including the null termination. + * If the existing string in dst is longer than the max, no action is taken. + * The resulting string will be null-terminated. A null destination returns + * null; otherwise, the destination argument is returned. + */ + +PR_EXTERN(char *) +PL_strcatn(char *dst, PRUint32 max, const char *src); + +/* + * PL_strcmp + * + * Returns an integer, the sign of which -- positive, zero, or negative -- + * reflects the lexical sorting order of the two strings indicated. The + * result is positive if the first string comes after the second. The + * NSPR implementation is not i18n. + */ + +PR_EXTERN(PRIntn) +PL_strcmp(const char *a, const char *b); + +/* + * PL_strncmp + * + * Returns an integer, the sign of which -- positive, zero, or negative -- + * reflects the lexical sorting order of the two strings indicated, up to + * the maximum specified. The result is positive if the first string comes + * after the second. The NSPR implementation is not i18n. If the maximum + * is zero, only the existance or non-existance (pointer is null) of the + * strings is compared. + */ + +PR_EXTERN(PRIntn) +PL_strncmp(const char *a, const char *b, PRUint32 max); + +/* + * PL_strcasecmp + * + * Returns an integer, the sign of which -- positive, zero or negative -- + * reflects the case-insensitive lexical sorting order of the two strings + * indicated. The result is positive if the first string comes after the + * second. The NSPR implementation is not i18n. + */ + +PR_EXTERN(PRIntn) +PL_strcasecmp(const char *a, const char *b); + +/* + * PL_strncasecmp + * + * Returns an integer, the sign of which -- positive, zero or negative -- + * reflects the case-insensitive lexical sorting order of the first n characters + * of the two strings indicated. The result is positive if the first string comes + * after the second. The NSPR implementation is not i18n. + */ + +PR_EXTERN(PRIntn) +PL_strncasecmp(const char *a, const char *b, PRUint32 max); + +/* + * PL_strchr + * + * Returns a pointer to the first instance of the specified character in the + * provided string. It returns null if the character is not found, or if the + * provided string is null. The character may be the null character. + */ + +PR_EXTERN(char *) +PL_strchr(const char *s, char c); + +/* + * PL_strrchr + * + * Returns a pointer to the last instance of the specified character in the + * provided string. It returns null if the character is not found, or if the + * provided string is null. The character may be the null character. + */ + +PR_EXTERN(char *) +PL_strrchr(const char *s, char c); + +/* + * PL_strnchr + * + * Returns a pointer to the first instance of the specified character within the + * first n characters of the provided string. It returns null if the character + * is not found, or if the provided string is null. The character may be the + * null character. + */ + +PR_EXTERN(char *) +PL_strnchr(const char *s, char c, PRUint32 n); + +/* + * PL_strnrchr + * + * Returns a pointer to the last instance of the specified character within the + * first n characters of the provided string. It returns null if the character is + * not found, or if the provided string is null. The character may be the null + * character. + */ + +PR_EXTERN(char *) +PL_strnrchr(const char *s, char c, PRUint32 n); + +/* + * NOTE: Looking for strcasechr, strcaserchr, strncasechr, or strncaserchr? + * Use strpbrk, strprbrk, strnpbrk or strnprbrk. + */ + +/* + * PL_strpbrk + * + * Returns a pointer to the first instance in the first string of any character + * (not including the terminating null character) of the second string. It returns + * null if either string is null. + */ + +PR_EXTERN(char *) +PL_strpbrk(const char *s, const char *list); + +/* + * PL_strprbrk + * + * Returns a pointer to the last instance in the first string of any character + * (not including the terminating null character) of the second string. It returns + * null if either string is null. + */ + +PR_EXTERN(char *) +PL_strprbrk(const char *s, const char *list); + +/* + * PL_strnpbrk + * + * Returns a pointer to the first instance (within the first n characters) of any + * character (not including the terminating null character) of the second string. + * It returns null if either string is null. + */ + +PR_EXTERN(char *) +PL_strnpbrk(const char *s, const char *list, PRUint32 n); + +/* + * PL_strnprbrk + * + * Returns a pointer to the last instance (within the first n characters) of any + * character (not including the terminating null character) of the second string. + * It returns null if either string is null. + */ + +PR_EXTERN(char *) +PL_strnprbrk(const char *s, const char *list, PRUint32 n); + +/* + * PL_strstr + * + * Returns a pointer to the first instance of the little string within the + * big one. It returns null if either string is null. + */ + +PR_EXTERN(char *) +PL_strstr(const char *big, const char *little); + +/* + * PL_strrstr + * + * Returns a pointer to the last instance of the little string within the big one. + * It returns null if either string is null. + */ + +PR_EXTERN(char *) +PL_strrstr(const char *big, const char *little); + +/* + * PL_strnstr + * + * Returns a pointer to the first instance of the little string within the first + * n characters of the big one. It returns null if either string is null. It + * returns null if the length of the little string is greater than n. + */ + +PR_EXTERN(char *) +PL_strnstr(const char *big, const char *little, PRUint32 n); + +/* + * PL_strnrstr + * + * Returns a pointer to the last instance of the little string within the first + * n characters of the big one. It returns null if either string is null. It + * returns null if the length of the little string is greater than n. + */ + +PR_EXTERN(char *) +PL_strnrstr(const char *big, const char *little, PRUint32 max); + +/* + * PL_strcasestr + * + * Returns a pointer to the first instance of the little string within the big one, + * ignoring case. It returns null if either string is null. + */ + +PR_EXTERN(char *) +PL_strcasestr(const char *big, const char *little); + +/* + * PL_strcaserstr + * + * Returns a pointer to the last instance of the little string within the big one, + * ignoring case. It returns null if either string is null. + */ + +PR_EXTERN(char *) +PL_strcaserstr(const char *big, const char *little); + +/* + * PL_strncasestr + * + * Returns a pointer to the first instance of the little string within the first + * n characters of the big one, ignoring case. It returns null if either string is + * null. It returns null if the length of the little string is greater than n. + */ + +PR_EXTERN(char *) +PL_strncasestr(const char *big, const char *little, PRUint32 max); + +/* + * PL_strncaserstr + * + * Returns a pointer to the last instance of the little string within the first + * n characters of the big one, ignoring case. It returns null if either string is + * null. It returns null if the length of the little string is greater than n. + */ + +PR_EXTERN(char *) +PL_strncaserstr(const char *big, const char *little, PRUint32 max); + +/* + * PL_strtok_r + * + * Splits the string s1 into tokens, separated by one or more characters + * from the separator string s2. The argument lasts points to a + * user-supplied char * pointer in which PL_strtok_r stores information + * for it to continue scanning the same string. + * + * In the first call to PL_strtok_r, s1 points to a string and the value + * of *lasts is ignored. PL_strtok_r returns a pointer to the first + * token, writes '\0' into the character following the first token, and + * updates *lasts. + * + * In subsequent calls, s1 is null and lasts must stay unchanged from the + * previous call. The separator string s2 may be different from call to + * call. PL_strtok_r returns a pointer to the next token in s1. When no + * token remains in s1, PL_strtok_r returns null. + */ + +PR_EXTERN(char *) +PL_strtok_r(char *s1, const char *s2, char **lasts); + +/* + * Things not (yet?) included: strspn/strcspn, strsep. + * memchr, memcmp, memcpy, memccpy, index, rindex, bcmp, bcopy, bzero. + * Any and all i18n/l10n stuff. + */ + +PR_END_EXTERN_C + +#endif /* _plstr_h */ diff -Nru nspr-4.9.5/nspr/lib/libc/include/README nspr-4.10.7/nspr/lib/libc/include/README --- nspr-4.9.5/nspr/lib/libc/include/README 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/include/README 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,7 @@ +NSPR 2.0 libc functions +----------------------- + +Last edited: AOF 04 March 1997 + +This directory contains the API for various libc-types of functions. + diff -Nru nspr-4.9.5/nspr/lib/libc/Makefile.in nspr-4.10.7/nspr/lib/libc/Makefile.in --- nspr-4.9.5/nspr/lib/libc/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,24 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +export NSPR20=1 + +include $(topsrcdir)/config/config.mk + +DIRS = include src + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/lib/libc/README nspr-4.10.7/nspr/lib/libc/README --- nspr-4.9.5/nspr/lib/libc/README 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/README 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,20 @@ +NSPR 2.0 libc functions +----------------------- + +Last edited: AOF 04 March 1997 + +This directory contains various libc-types of functions. All functions in +this directory are platform independent, thread friendly (both safe and +efficient). They are contributed from various sources, though the contri- +butions are monitored by the NSPR group (mailto:freier). + +All API items exported by these functions will contain the same three +character prefix, "PL_" (Portable Library). Internal function names +that are not exported (static) are of little concern, though some caution +must be used on those elements that are 'extern' but not really intended +to be part of the API. Those should all have a prefix of "_PL_" (is that +legal?). + +The responsibility for contributions in this area are distributed among +all interested parties. + diff -Nru nspr-4.9.5/nspr/lib/libc/src/base64.c nspr-4.10.7/nspr/lib/libc/src/base64.c --- nspr-4.9.5/nspr/lib/libc/src/base64.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/base64.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,416 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plbase64.h" +#include "prlog.h" /* For PR_NOT_REACHED */ +#include "prmem.h" /* for malloc / PR_MALLOC */ + +#include /* for strlen */ + +static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static void +encode3to4 +( + const unsigned char *src, + unsigned char *dest +) +{ + PRUint32 b32 = (PRUint32)0; + PRIntn i, j = 18; + + for( i = 0; i < 3; i++ ) + { + b32 <<= 8; + b32 |= (PRUint32)src[i]; + } + + for( i = 0; i < 4; i++ ) + { + dest[i] = base[ (PRUint32)((b32>>j) & 0x3F) ]; + j -= 6; + } + + return; +} + +static void +encode2to4 +( + const unsigned char *src, + unsigned char *dest +) +{ + dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ]; + dest[1] = base[ (PRUint32)(((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)) ]; + dest[2] = base[ (PRUint32)((src[1] & 0x0F) << 2) ]; + dest[3] = (unsigned char)'='; + return; +} + +static void +encode1to4 +( + const unsigned char *src, + unsigned char *dest +) +{ + dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ]; + dest[1] = base[ (PRUint32)((src[0] & 0x03) << 4) ]; + dest[2] = (unsigned char)'='; + dest[3] = (unsigned char)'='; + return; +} + +static void +encode +( + const unsigned char *src, + PRUint32 srclen, + unsigned char *dest +) +{ + while( srclen >= 3 ) + { + encode3to4(src, dest); + src += 3; + dest += 4; + srclen -= 3; + } + + switch( srclen ) + { + case 2: + encode2to4(src, dest); + break; + case 1: + encode1to4(src, dest); + break; + case 0: + break; + default: + PR_NOT_REACHED("coding error"); + } + + return; +} + +/* + * PL_Base64Encode + * + * If the destination argument is NULL, a return buffer is + * allocated, and the data therein will be null-terminated. + * If the destination argument is not NULL, it is assumed to + * be of sufficient size, and the contents will not be null- + * terminated by this routine. + * + * Returns null if the allocation fails. + */ + +PR_IMPLEMENT(char *) +PL_Base64Encode +( + const char *src, + PRUint32 srclen, + char *dest +) +{ + if( 0 == srclen ) + { + size_t len = strlen(src); + srclen = len; + /* Detect truncation. */ + if( srclen != len ) + { + return (char *)0; + } + } + + if( (char *)0 == dest ) + { + PRUint32 destlen; + /* Ensure all PRUint32 values stay within range. */ + if( srclen > (PR_UINT32_MAX/4) * 3 ) + { + return (char *)0; + } + destlen = ((srclen + 2)/3) * 4; + dest = (char *)PR_MALLOC(destlen + 1); + if( (char *)0 == dest ) + { + return (char *)0; + } + dest[ destlen ] = (char)0; /* null terminate */ + } + + encode((const unsigned char *)src, srclen, (unsigned char *)dest); + return dest; +} + +static PRInt32 +codetovalue +( + unsigned char c +) +{ + if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') ) + { + return (PRInt32)(c - (unsigned char)'A'); + } + else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') ) + { + return ((PRInt32)(c - (unsigned char)'a') +26); + } + else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') ) + { + return ((PRInt32)(c - (unsigned char)'0') +52); + } + else if( (unsigned char)'+' == c ) + { + return (PRInt32)62; + } + else if( (unsigned char)'/' == c ) + { + return (PRInt32)63; + } + else + { + return -1; + } +} + +static PRStatus +decode4to3 +( + const unsigned char *src, + unsigned char *dest +) +{ + PRUint32 b32 = (PRUint32)0; + PRInt32 bits; + PRIntn i; + + for( i = 0; i < 4; i++ ) + { + bits = codetovalue(src[i]); + if( bits < 0 ) + { + return PR_FAILURE; + } + + b32 <<= 6; + b32 |= bits; + } + + dest[0] = (unsigned char)((b32 >> 16) & 0xFF); + dest[1] = (unsigned char)((b32 >> 8) & 0xFF); + dest[2] = (unsigned char)((b32 ) & 0xFF); + + return PR_SUCCESS; +} + +static PRStatus +decode3to2 +( + const unsigned char *src, + unsigned char *dest +) +{ + PRUint32 b32 = (PRUint32)0; + PRInt32 bits; + PRUint32 ubits; + + bits = codetovalue(src[0]); + if( bits < 0 ) + { + return PR_FAILURE; + } + + b32 = (PRUint32)bits; + b32 <<= 6; + + bits = codetovalue(src[1]); + if( bits < 0 ) + { + return PR_FAILURE; + } + + b32 |= (PRUint32)bits; + b32 <<= 4; + + bits = codetovalue(src[2]); + if( bits < 0 ) + { + return PR_FAILURE; + } + + ubits = (PRUint32)bits; + b32 |= (ubits >> 2); + + dest[0] = (unsigned char)((b32 >> 8) & 0xFF); + dest[1] = (unsigned char)((b32 ) & 0xFF); + + return PR_SUCCESS; +} + +static PRStatus +decode2to1 +( + const unsigned char *src, + unsigned char *dest +) +{ + PRUint32 b32; + PRUint32 ubits; + PRInt32 bits; + + bits = codetovalue(src[0]); + if( bits < 0 ) + { + return PR_FAILURE; + } + + ubits = (PRUint32)bits; + b32 = (ubits << 2); + + bits = codetovalue(src[1]); + if( bits < 0 ) + { + return PR_FAILURE; + } + + ubits = (PRUint32)bits; + b32 |= (ubits >> 4); + + dest[0] = (unsigned char)b32; + + return PR_SUCCESS; +} + +static PRStatus +decode +( + const unsigned char *src, + PRUint32 srclen, + unsigned char *dest +) +{ + PRStatus rv; + + while( srclen >= 4 ) + { + rv = decode4to3(src, dest); + if( PR_SUCCESS != rv ) + { + return PR_FAILURE; + } + + src += 4; + dest += 3; + srclen -= 4; + } + + switch( srclen ) + { + case 3: + rv = decode3to2(src, dest); + break; + case 2: + rv = decode2to1(src, dest); + break; + case 1: + rv = PR_FAILURE; + break; + case 0: + rv = PR_SUCCESS; + break; + default: + PR_NOT_REACHED("coding error"); + } + + return rv; +} + +/* + * PL_Base64Decode + * + * If the destination argument is NULL, a return buffer is + * allocated and the data therein will be null-terminated. + * If the destination argument is not null, it is assumed + * to be of sufficient size, and the data will not be null- + * terminated by this routine. + * + * Returns null if the allocation fails, or if the source string is + * not well-formed. + */ + +PR_IMPLEMENT(char *) +PL_Base64Decode +( + const char *src, + PRUint32 srclen, + char *dest +) +{ + PRStatus status; + PRBool allocated = PR_FALSE; + + if( (char *)0 == src ) + { + return (char *)0; + } + + if( 0 == srclen ) + { + size_t len = strlen(src); + srclen = len; + /* Detect truncation. */ + if( srclen != len ) + { + return (char *)0; + } + } + + if( srclen && (0 == (srclen & 3)) ) + { + if( (char)'=' == src[ srclen-1 ] ) + { + if( (char)'=' == src[ srclen-2 ] ) + { + srclen -= 2; + } + else + { + srclen -= 1; + } + } + } + + if( (char *)0 == dest ) + { + /* The following computes ((srclen * 3) / 4) without overflow. */ + PRUint32 destlen = (srclen / 4) * 3 + ((srclen % 4) * 3) / 4; + dest = (char *)PR_MALLOC(destlen + 1); + if( (char *)0 == dest ) + { + return (char *)0; + } + dest[ destlen ] = (char)0; /* null terminate */ + allocated = PR_TRUE; + } + + status = decode((const unsigned char *)src, srclen, (unsigned char *)dest); + if( PR_SUCCESS != status ) + { + if( PR_TRUE == allocated ) + { + PR_DELETE(dest); + } + + return (char *)0; + } + + return dest; +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/.cvsignore nspr-4.10.7/nspr/lib/libc/src/.cvsignore --- nspr-4.9.5/nspr/lib/libc/src/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,2 @@ +Makefile +_pl_bld.h diff -Nru nspr-4.9.5/nspr/lib/libc/src/Makefile.in nspr-4.10.7/nspr/lib/libc/src/Makefile.in --- nspr-4.9.5/nspr/lib/libc/src/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,152 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +INCLUDES = -I$(dist_includedir) + +CSRCS =\ + plvrsion.c \ + strlen.c \ + strcpy.c \ + strdup.c \ + strcase.c \ + strcat.c \ + strcmp.c \ + strchr.c \ + strpbrk.c \ + strstr.c \ + strtok.c \ + base64.c \ + plerror.c \ + plgetopt.c \ + $(NULL) + +LIBRARY_NAME = plc +LIBRARY_VERSION = $(MOD_MAJOR_VERSION) + +RELEASE_LIBS = $(TARGETS) + +ifeq ($(OS_ARCH),WINNT) +RES=$(OBJDIR)/plc.res +RESNAME=plc.rc +endif # WINNT + +ifeq ($(OS_ARCH), AIX) +ifeq ($(CLASSIC_NSPR),1) +OS_LIBS = -lc +else +OS_LIBS = -lc_r +endif +endif + +ifeq ($(OS_ARCH),IRIX) +OS_LIBS = -lc +endif + +ifeq ($(OS_ARCH),SunOS) +OS_LIBS = -lc +MAPFILE = $(OBJDIR)/plcmap.sun +GARBAGE += $(MAPFILE) +ifdef NS_USE_GCC +ifdef GCC_USE_GNU_LD +MKSHLIB += -Wl,--version-script,$(MAPFILE) +else +MKSHLIB += -Wl,-M,$(MAPFILE) +endif +else +MKSHLIB += -M $(MAPFILE) +endif +# The -R '$ORIGIN' linker option instructs this library to search for its +# dependencies in the same directory where it resides. +MKSHLIB += -R '$$ORIGIN' +endif + +ifeq ($(OS_ARCH),OS2) +MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def +GARBAGE += $(MAPFILE) +MKSHLIB += $(MAPFILE) +endif + +EXTRA_LIBS = $(LIBNSPR) + +# On SCOOS, we can't link with extra libraries when +# we build a shared library. If we do so, the linker doesn't +# complain, but we would run into weird problems at run-time. +# Therefore on these platforms, we link just the .o files. +ifeq ($(OS_ARCH),SCOOS) +EXTRA_LIBS = +endif + +ifdef RESOLVE_LINK_SYMBOLS +EXTRA_LIBS += $(OS_LIBS) +endif + +include $(topsrcdir)/config/rules.mk + +# +# Version information generation (begin) +# +ECHO = echo +TINC = $(OBJDIR)/_pl_bld.h +PROD = $(notdir $(SHARED_LIBRARY)) +NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now +SH_DATE = $(shell date "+%Y-%m-%d %T") +SH_NOW = $(shell $(NOW)) + +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + SUF = i64 +else + SUF = LL +endif + +GARBAGE += $(TINC) + +$(TINC): + @$(MAKE_OBJDIR) + @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC) + @if test ! -z "$(SH_NOW)"; then \ + $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \ + else \ + true; \ + fi + @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) + + +$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC) +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $< +else + $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< +endif +# +# Version information generation (end) +# + +# +# The Client build wants the shared libraries in $(dist_bindir), +# so we also install them there. +# + +export:: $(TARGETS) + $(INSTALL) -m 444 $(TARGETS) $(dist_libdir) +ifdef SHARED_LIBRARY +ifeq ($(OS_ARCH),HP-UX) + $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir) + $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir) +else + $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir) +endif +endif diff -Nru nspr-4.9.5/nspr/lib/libc/src/plc.def nspr-4.10.7/nspr/lib/libc/src/plc.def --- nspr-4.9.5/nspr/lib/libc/src/plc.def 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/plc.def 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,72 @@ +;+# +;+# This Source Code Form is subject to the terms of the Mozilla Public +;+# License, v. 2.0. If a copy of the MPL was not distributed with this +;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. +;+# +;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS +;+# 1. For all unix platforms, the string ";-" means "remove this line" +;+# 2. For all unix platforms, the string " DATA " will be removed from any +;+# line on which it occurs. +;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. +;+# On AIX, lines containing ";+" will be removed. +;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. +;+# 5. For all unix platforms, after the above processing has taken place, +;+# all characters after the first ";" on the line will be removed. +;+# And for AIX, the first ";" will also be removed. +;+# This file is passed directly to windows. Since ';' is a comment, all UNIX +;+# directives are hidden behind ";", ";+", and ";-" +;+NSPR_4.0 { +;+ global: +LIBRARY plc4 ;- +EXPORTS ;- +PL_Base64Decode; +PL_Base64Encode; +PL_CreateOptState; +PL_DestroyOptState; +PL_FPrintError; +PL_GetNextOpt; +PL_PrintError; +PL_strcasecmp; +PL_strcaserstr; +PL_strcasestr; +PL_strcat; +PL_strcatn; +PL_strchr; +PL_strcmp; +PL_strcpy; +PL_strdup; +PL_strfree; +PL_strlen; +PL_strncasecmp; +PL_strncaserstr; +PL_strncasestr; +PL_strncat; +PL_strnchr; +PL_strncmp; +PL_strncpy; +PL_strncpyz; +PL_strndup; +PL_strnlen; +PL_strnpbrk; +PL_strnprbrk; +PL_strnrchr; +PL_strnrstr; +PL_strnstr; +PL_strpbrk; +PL_strprbrk; +PL_strrchr; +PL_strrstr; +PL_strstr; +libVersionPoint; +;+ local: *; +;+}; +;+ +;+NSPR_4.2 { +;+ global: +PL_strtok_r; +;+} NSPR_4.0; +;+ +;+NSPR_4.7 { +;+ global: +PL_CreateLongOptState; +;+} NSPR_4.2; diff -Nru nspr-4.9.5/nspr/lib/libc/src/plc.rc nspr-4.10.7/nspr/lib/libc/src/plc.rc --- nspr-4.9.5/nspr/lib/libc/src/plc.rc 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/plc.rc 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "prinit.h" +#include + +#define MY_LIBNAME "plc" +#define MY_FILEDESCRIPTION "PLC Library" + +#define STRINGIZE(x) #x +#define STRINGIZE2(x) STRINGIZE(x) +#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR) + +#ifdef _DEBUG +#define MY_DEBUG_STR " (debug)" +#define MY_FILEFLAGS_1 VS_FF_DEBUG +#else +#define MY_DEBUG_STR "" +#define MY_FILEFLAGS_1 0x0L +#endif +#if PR_BETA +#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE +#else +#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 +#endif + +#ifdef WINNT +#define MY_FILEOS VOS_NT_WINDOWS32 +#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR +#else +#define MY_FILEOS VOS__WINDOWS32 +#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Version-information resource +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 + PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS MY_FILEFLAGS_2 + FILEOS MY_FILEOS + FILETYPE VFT_DLL + FILESUBTYPE 0x0L // not used + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" // Lang=US English, CharSet=Unicode + BEGIN + VALUE "CompanyName", "Mozilla Foundation\0" + VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" + VALUE "FileVersion", PR_VERSION "\0" + VALUE "InternalName", MY_INTERNAL_NAME "\0" + VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" + VALUE "ProductName", "Netscape Portable Runtime\0" + VALUE "ProductVersion", PR_VERSION "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff -Nru nspr-4.9.5/nspr/lib/libc/src/plerror.c nspr-4.10.7/nspr/lib/libc/src/plerror.c --- nspr-4.9.5/nspr/lib/libc/src/plerror.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/plerror.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File:plerror.c +** Description: Simple routine to print translate the calling thread's +** error numbers and print them to "syserr". +*/ + +#include "plerror.h" + +#include "prprf.h" +#include "prerror.h" + +PR_IMPLEMENT(void) PL_FPrintError(PRFileDesc *fd, const char *msg) +{ +PRErrorCode error = PR_GetError(); +PRInt32 oserror = PR_GetOSError(); +const char *name = PR_ErrorToName(error); + + if (NULL != msg) PR_fprintf(fd, "%s: ", msg); + if (NULL == name) + PR_fprintf( + fd, " (%d)OUT OF RANGE, oserror = %d\n", error, oserror); + else + PR_fprintf( + fd, "%s(%d), oserror = %d\n", + name, error, oserror); +} /* PL_FPrintError */ + +PR_IMPLEMENT(void) PL_PrintError(const char *msg) +{ + static PRFileDesc *fd = NULL; + if (NULL == fd) fd = PR_GetSpecialFD(PR_StandardError); + PL_FPrintError(fd, msg); +} /* PL_PrintError */ + +/* plerror.c */ diff -Nru nspr-4.9.5/nspr/lib/libc/src/plgetopt.c nspr-4.10.7/nspr/lib/libc/src/plgetopt.c --- nspr-4.9.5/nspr/lib/libc/src/plgetopt.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/plgetopt.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,248 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: plgetopt.c +** Description: utilities to parse argc/argv +*/ + +#include "prmem.h" +#include "prlog.h" +#include "prerror.h" +#include "plstr.h" +#include "plgetopt.h" + +#include + +static char static_Nul = 0; + +struct PLOptionInternal +{ + const char *options; /* client options list specification */ + PRIntn argc; /* original number of arguments */ + char **argv; /* vector of pointers to arguments */ + PRIntn xargc; /* which one we're processing now */ + const char *xargv; /* where within *argv[xargc] */ + PRIntn minus; /* do we already have the '-'? */ + const PLLongOpt *longOpts; /* Caller's array */ + PRBool endOfOpts; /* have reached a "--" argument */ + PRIntn optionsLen; /* is strlen(options) */ +}; + +/* +** Create the state in which to parse the tokens. +** +** argc the sum of the number of options and their values +** argv the options and their values +** options vector of single character options w/ | w/o ': +*/ +PR_IMPLEMENT(PLOptState*) PL_CreateOptState( + PRIntn argc, char **argv, const char *options) +{ + return PL_CreateLongOptState( argc, argv, options, NULL); +} /* PL_CreateOptState */ + +PR_IMPLEMENT(PLOptState*) PL_CreateLongOptState( + PRIntn argc, char **argv, const char *options, + const PLLongOpt *longOpts) +{ + PLOptState *opt = NULL; + PLOptionInternal *internal; + + if (NULL == options) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return opt; + } + + opt = PR_NEWZAP(PLOptState); + if (NULL == opt) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return opt; + } + + internal = PR_NEW(PLOptionInternal); + if (NULL == internal) + { + PR_DELETE(opt); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + opt->option = 0; + opt->value = NULL; + opt->internal = internal; + opt->longOption = 0; + opt->longOptIndex = -1; + + internal->argc = argc; + internal->argv = argv; + internal->xargc = 0; + internal->xargv = &static_Nul; + internal->minus = 0; + internal->options = options; + internal->longOpts = longOpts; + internal->endOfOpts = PR_FALSE; + internal->optionsLen = PL_strlen(options); + + return opt; +} /* PL_CreateLongOptState */ + +/* +** Destroy object created by CreateOptState() +*/ +PR_IMPLEMENT(void) PL_DestroyOptState(PLOptState *opt) +{ + PR_DELETE(opt->internal); + PR_DELETE(opt); +} /* PL_DestroyOptState */ + +PR_IMPLEMENT(PLOptStatus) PL_GetNextOpt(PLOptState *opt) +{ + PLOptionInternal *internal = opt->internal; + + opt->longOption = 0; + opt->longOptIndex = -1; + /* + ** If the current xarg points to nul, advance to the next + ** element of the argv vector. If the vector index is equal + ** to argc, we're out of arguments, so return an EOL. + ** Note whether the first character of the new argument is + ** a '-' and skip by it if it is. + */ + while (0 == *internal->xargv) + { + internal->xargc += 1; + if (internal->xargc >= internal->argc) + { + opt->option = 0; + opt->value = NULL; + return PL_OPT_EOL; + } + internal->xargv = internal->argv[internal->xargc]; + internal->minus = 0; + if (!internal->endOfOpts && ('-' == *internal->xargv)) + { + internal->minus++; + internal->xargv++; /* and consume */ + if ('-' == *internal->xargv && internal->longOpts) + { + internal->minus++; + internal->xargv++; + if (0 == *internal->xargv) + { + internal->endOfOpts = PR_TRUE; + } + } + } + } + + /* + ** If we already have a '-' or '--' in hand, xargv points to the next + ** option. See if we can find a match in the list of possible + ** options supplied. + */ + if (internal->minus == 2) + { + char * foundEqual = strchr(internal->xargv,'='); + PRIntn optNameLen = foundEqual ? (foundEqual - internal->xargv) : + strlen(internal->xargv); + const PLLongOpt *longOpt = internal->longOpts; + PLOptStatus result = PL_OPT_BAD; + + opt->option = 0; + opt->value = NULL; + + for (; longOpt->longOptName; ++longOpt) + { + if (strncmp(longOpt->longOptName, internal->xargv, optNameLen)) + continue; /* not a possible match */ + if (strlen(longOpt->longOptName) != optNameLen) + continue; /* not a match */ + /* option name match */ + opt->longOptIndex = longOpt - internal->longOpts; + opt->longOption = longOpt->longOption; + /* value is part of the current argv[] element if = was found */ + /* note: this sets value even for long options that do not + * require option if specified as --long=value */ + if (foundEqual) + { + opt->value = foundEqual + 1; + } + else if (longOpt->valueRequired) + { + /* value is the next argv[] element, if any */ + if (internal->xargc + 1 < internal->argc) + { + opt->value = internal->argv[++(internal->xargc)]; + } + /* missing value */ + else + { + break; /* return PL_OPT_BAD */ + } + } + result = PL_OPT_OK; + break; + } + internal->xargv = &static_Nul; /* consume this */ + return result; + } + if (internal->minus) + { + PRIntn cop; + PRIntn eoo = internal->optionsLen; + for (cop = 0; cop < eoo; ++cop) + { + if (internal->options[cop] == *internal->xargv) + { + opt->option = *internal->xargv++; + opt->longOption = opt->option & 0xff; + /* + ** if options indicates that there's an associated + ** value, it must be provided, either as part of this + ** argv[] element or as the next one + */ + if (':' == internal->options[cop + 1]) + { + /* value is part of the current argv[] element */ + if (0 != *internal->xargv) + { + opt->value = internal->xargv; + } + /* value is the next argv[] element, if any */ + else if (internal->xargc + 1 < internal->argc) + { + opt->value = internal->argv[++(internal->xargc)]; + } + /* missing value */ + else + { + return PL_OPT_BAD; + } + + internal->xargv = &static_Nul; + internal->minus = 0; + } + else + opt->value = NULL; + return PL_OPT_OK; + } + } + internal->xargv += 1; /* consume that option */ + return PL_OPT_BAD; + } + + /* + ** No '-', so it must be a standalone value. The option is nul. + */ + opt->value = internal->argv[internal->xargc]; + internal->xargv = &static_Nul; + opt->option = 0; + return PL_OPT_OK; +} /* PL_GetNextOpt */ + +/* plgetopt.c */ diff -Nru nspr-4.9.5/nspr/lib/libc/src/plvrsion.c nspr-4.10.7/nspr/lib/libc/src/plvrsion.c --- nspr-4.9.5/nspr/lib/libc/src/plvrsion.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/plvrsion.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include "prvrsion.h" + +/************************************************************************/ +/**************************IDENTITY AND VERSIONING***********************/ +/************************************************************************/ +#include "_pl_bld.h" +#if !defined(_BUILD_TIME) +#ifdef HAVE_LONG_LONG +#define _BUILD_TIME 0 +#else +#define _BUILD_TIME {0, 0} +#endif +#endif +#if !defined(_BUILD_STRING) +#define _BUILD_STRING "" +#endif +#if !defined(_PRODUCTION) +#define _PRODUCTION "" +#endif +#if defined(DEBUG) +#define _DEBUG_STRING " (debug)" +#else +#define _DEBUG_STRING "" +#endif + +/* + * A trick to expand the PR_VMAJOR macro before concatenation. + */ +#define CONCAT(x, y) x ## y +#define CONCAT2(x, y) CONCAT(x, y) +#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplc, PR_VMAJOR) + +PRVersionDescription VERSION_DESC_NAME = +{ + /* version */ 2, /* this is the only one supported */ + /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */ + /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */ + /* vMajor */ PR_VMAJOR, /* NSPR's version number */ + /* vMinor */ PR_VMINOR, /* and minor version */ + /* vPatch */ PR_VPATCH, /* and patch */ + /* beta */ PR_BETA, /* beta build boolean */ +#if defined(DEBUG) + /* debug */ PR_TRUE, /* a debug build */ +#else + /* debug */ PR_FALSE, /* an optomized build */ +#endif + /* special */ PR_FALSE, /* they're all special, but ... */ + /* filename */ _PRODUCTION, /* the produced library name */ + /* description */ "Portable runtime", /* what we are */ + /* security */ "N/A", /* not applicable here */ + /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved", + /* comment */ "http://www.mozilla.org/MPL/", + /* specialString */ "" +}; + +#ifdef XP_UNIX + +/* + * Version information for the 'ident' and 'what commands + * + * NOTE: the first component of the concatenated rcsid string + * must not end in a '$' to prevent rcs keyword substitution. + */ +static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING + " " _BUILD_STRING " $"; +static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING + " " _BUILD_STRING; + +#endif /* XP_UNIX */ + +PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint() +{ +#ifdef XP_UNIX + /* + * Add dummy references to rcsid and sccsid to prevent them + * from being optimized away as unused variables. + */ + const char *dummy; + + dummy = rcsid; + dummy = sccsid; +#endif + return &VERSION_DESC_NAME; +} /* versionEntryPointType */ + +/* plvrsion.c */ + diff -Nru nspr-4.9.5/nspr/lib/libc/src/README nspr-4.10.7/nspr/lib/libc/src/README --- nspr-4.9.5/nspr/lib/libc/src/README 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/README 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,20 @@ +NSPR 2.0 libc functions +----------------------- + +Last edited: AOF 04 March 1997 + +This directory contains various libc-types of functions. All functions in +this directory are platform independent, thread friendly (both safe and +efficient). They are contributed from various sources, though the contri- +butions are monitored by the NSPR group (mailto:freier). + +All API items exported by these functions will contain the same three +character prefix, "PL_" (Portable Library). Internal function names +that are not exported (static) are of little concern, though some caution +must be used on those elements that are 'extern' but not really intended +to be part of the API. Those should all have a prefix of "_PL_" (is that +legal?). + +The responsibility for contributions in this area are distributed among +all interested parties. + diff -Nru nspr-4.9.5/nspr/lib/libc/src/strcase.c nspr-4.10.7/nspr/lib/libc/src/strcase.c --- nspr-4.9.5/nspr/lib/libc/src/strcase.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strcase.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include + +static const unsigned char uc[] = +{ + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + ' ', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '{', '|', '}', '~', '\177', + 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207, + 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217, + 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227, + 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237, + 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247, + 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257, + 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, + 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, + 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307, + 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317, + 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327, + 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, + 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347, + 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357, + 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, + 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377 +}; + +PR_IMPLEMENT(PRIntn) +PL_strcasecmp(const char *a, const char *b) +{ + const unsigned char *ua = (const unsigned char *)a; + const unsigned char *ub = (const unsigned char *)b; + + if( ((const char *)0 == a) || (const char *)0 == b ) + return (PRIntn)(a-b); + + while( (uc[*ua] == uc[*ub]) && ('\0' != *a) ) + { + a++; + ua++; + ub++; + } + + return (PRIntn)(uc[*ua] - uc[*ub]); +} + +PR_IMPLEMENT(PRIntn) +PL_strncasecmp(const char *a, const char *b, PRUint32 max) +{ + const unsigned char *ua = (const unsigned char *)a; + const unsigned char *ub = (const unsigned char *)b; + + if( ((const char *)0 == a) || (const char *)0 == b ) + return (PRIntn)(a-b); + + while( max && (uc[*ua] == uc[*ub]) && ('\0' != *a) ) + { + a++; + ua++; + ub++; + max--; + } + + if( 0 == max ) return (PRIntn)0; + + return (PRIntn)(uc[*ua] - uc[*ub]); +} + +PR_IMPLEMENT(char *) +PL_strcasestr(const char *big, const char *little) +{ + PRUint32 ll; + + if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; + if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; + + ll = strlen(little); + + for( ; *big; big++ ) + /* obvious improvement available here */ + if( 0 == PL_strncasecmp(big, little, ll) ) + return (char *)big; + + return (char *)0; +} + +PR_IMPLEMENT(char *) +PL_strcaserstr(const char *big, const char *little) +{ + const char *p; + PRUint32 bl, ll; + + if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; + if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; + + bl = strlen(big); + ll = strlen(little); + if( bl < ll ) return (char *)0; + p = &big[ bl - ll ]; + + for( ; p >= big; p-- ) + /* obvious improvement available here */ + if( 0 == PL_strncasecmp(p, little, ll) ) + return (char *)p; + + return (char *)0; +} + +PR_IMPLEMENT(char *) +PL_strncasestr(const char *big, const char *little, PRUint32 max) +{ + PRUint32 ll; + + if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; + if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; + + ll = strlen(little); + if( ll > max ) return (char *)0; + max -= ll; + max++; + + for( ; max && *big; big++, max-- ) + /* obvious improvement available here */ + if( 0 == PL_strncasecmp(big, little, ll) ) + return (char *)big; + + return (char *)0; +} + +PR_IMPLEMENT(char *) +PL_strncaserstr(const char *big, const char *little, PRUint32 max) +{ + const char *p; + PRUint32 ll; + + if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; + if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; + + ll = strlen(little); + + for( p = big; max && *p; p++, max-- ) + ; + + p -= ll; + if( p < big ) return (char *)0; + + for( ; p >= big; p-- ) + /* obvious improvement available here */ + if( 0 == PL_strncasecmp(p, little, ll) ) + return (char *)p; + + return (char *)0; +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strcat.c nspr-4.10.7/nspr/lib/libc/src/strcat.c --- nspr-4.9.5/nspr/lib/libc/src/strcat.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strcat.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include + +PR_IMPLEMENT(char *) +PL_strcat(char *dest, const char *src) +{ + if( ((char *)0 == dest) || ((const char *)0 == src) ) + return dest; + + return strcat(dest, src); +} + +PR_IMPLEMENT(char *) +PL_strncat(char *dest, const char *src, PRUint32 max) +{ + char *rv; + + if( ((char *)0 == dest) || ((const char *)0 == src) || (0 == max) ) + return dest; + + for( rv = dest; *dest; dest++ ) + ; + + (void)PL_strncpy(dest, src, max); + return rv; +} + +PR_IMPLEMENT(char *) +PL_strcatn(char *dest, PRUint32 max, const char *src) +{ + char *rv; + PRUint32 dl; + + if( ((char *)0 == dest) || ((const char *)0 == src) ) + return dest; + + for( rv = dest, dl = 0; *dest; dest++, dl++ ) + ; + + if( max <= dl ) return rv; + (void)PL_strncpyz(dest, src, max-dl); + + return rv; +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strchr.c nspr-4.10.7/nspr/lib/libc/src/strchr.c --- nspr-4.9.5/nspr/lib/libc/src/strchr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strchr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include + +PR_IMPLEMENT(char *) +PL_strchr(const char *s, char c) +{ + if( (const char *)0 == s ) return (char *)0; + + return strchr(s, c); +} + +PR_IMPLEMENT(char *) +PL_strrchr(const char *s, char c) +{ + if( (const char *)0 == s ) return (char *)0; + + return strrchr(s, c); +} + +PR_IMPLEMENT(char *) +PL_strnchr(const char *s, char c, PRUint32 n) +{ + if( (const char *)0 == s ) return (char *)0; + + for( ; n && *s; s++, n-- ) + if( *s == c ) + return (char *)s; + + if( ((char)0 == c) && (n > 0) && ((char)0 == *s) ) return (char *)s; + + return (char *)0; +} + +PR_IMPLEMENT(char *) +PL_strnrchr(const char *s, char c, PRUint32 n) +{ + const char *p; + + if( (const char *)0 == s ) return (char *)0; + + for( p = s; n && *p; p++, n-- ) + ; + + if( ((char)0 == c) && (n > 0) && ((char)0 == *p) ) return (char *)p; + + for( p--; p >= s; p-- ) + if( *p == c ) + return (char *)p; + + return (char *)0; +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strcmp.c nspr-4.10.7/nspr/lib/libc/src/strcmp.c --- nspr-4.9.5/nspr/lib/libc/src/strcmp.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strcmp.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include + +PR_IMPLEMENT(PRIntn) +PL_strcmp(const char *a, const char *b) +{ + if( ((const char *)0 == a) || (const char *)0 == b ) + return (PRIntn)(a-b); + + return (PRIntn)strcmp(a, b); +} + +PR_IMPLEMENT(PRIntn) +PL_strncmp(const char *a, const char *b, PRUint32 max) +{ + if( ((const char *)0 == a) || (const char *)0 == b ) + return (PRIntn)(a-b); + + return (PRIntn)strncmp(a, b, (size_t)max); +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strcpy.c nspr-4.10.7/nspr/lib/libc/src/strcpy.c --- nspr-4.9.5/nspr/lib/libc/src/strcpy.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strcpy.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include + +PR_IMPLEMENT(char *) +PL_strcpy(char *dest, const char *src) +{ + if( ((char *)0 == dest) || ((const char *)0 == src) ) return (char *)0; + + return strcpy(dest, src); +} + +PR_IMPLEMENT(char *) +PL_strncpy(char *dest, const char *src, PRUint32 max) +{ + char *rv; + + if( (char *)0 == dest ) return (char *)0; + if( (const char *)0 == src ) return (char *)0; + + for( rv = dest; max && ((*dest = *src) != 0); dest++, src++, max-- ) + ; + +#ifdef JLRU + /* XXX I (wtc) think the -- and ++ operators should be postfix. */ + while( --max ) + *++dest = '\0'; +#endif /* JLRU */ + + return rv; +} + +PR_IMPLEMENT(char *) +PL_strncpyz(char *dest, const char *src, PRUint32 max) +{ + char *rv; + + if( (char *)0 == dest ) return (char *)0; + if( (const char *)0 == src ) return (char *)0; + if( 0 == max ) return (char *)0; + + for( rv = dest, max--; max && ((*dest = *src) != 0); dest++, src++, max-- ) + ; + + *dest = '\0'; + + return rv; +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strdup.c nspr-4.10.7/nspr/lib/libc/src/strdup.c --- nspr-4.9.5/nspr/lib/libc/src/strdup.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strdup.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include "prmem.h" +#include + +PR_IMPLEMENT(char *) +PL_strdup(const char *s) +{ + char *rv; + size_t n; + + if( (const char *)0 == s ) + s = ""; + + n = strlen(s) + 1; + + rv = (char *)malloc(n); + if( (char *)0 == rv ) return rv; + + (void)memcpy(rv, s, n); + + return rv; +} + +PR_IMPLEMENT(void) +PL_strfree(char *s) +{ + free(s); +} + +PR_IMPLEMENT(char *) +PL_strndup(const char *s, PRUint32 max) +{ + char *rv; + size_t l; + + if( (const char *)0 == s ) + s = ""; + + l = PL_strnlen(s, max); + + rv = (char *)malloc(l+1); + if( (char *)0 == rv ) return rv; + + (void)memcpy(rv, s, l); + rv[l] = '\0'; + + return rv; +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strlen.c nspr-4.10.7/nspr/lib/libc/src/strlen.c --- nspr-4.9.5/nspr/lib/libc/src/strlen.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strlen.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include "prtypes.h" +#include "prlog.h" +#include + +PR_IMPLEMENT(PRUint32) +PL_strlen(const char *str) +{ + size_t l; + + if( (const char *)0 == str ) return 0; + + l = strlen(str); + + /* error checking in case we have a 64-bit platform -- make sure + * we don't have ultra long strings that overflow an int32 + */ + if( sizeof(PRUint32) < sizeof(size_t) ) + { + if( l > PR_INT32_MAX ) + PR_Assert("l <= PR_INT32_MAX", __FILE__, __LINE__); + } + + return (PRUint32)l; +} + +PR_IMPLEMENT(PRUint32) +PL_strnlen(const char *str, PRUint32 max) +{ + register const char *s; + + if( (const char *)0 == str ) return 0; + for( s = str; max && *s; s++, max-- ) + ; + + return (PRUint32)(s - str); +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strpbrk.c nspr-4.10.7/nspr/lib/libc/src/strpbrk.c --- nspr-4.9.5/nspr/lib/libc/src/strpbrk.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strpbrk.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include + +PR_IMPLEMENT(char *) +PL_strpbrk(const char *s, const char *list) +{ + if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0; + + return strpbrk(s, list); +} + +PR_IMPLEMENT(char *) +PL_strprbrk(const char *s, const char *list) +{ + const char *p; + const char *r; + + if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0; + + for( r = s; *r; r++ ) + ; + + for( r--; r >= s; r-- ) + for( p = list; *p; p++ ) + if( *r == *p ) + return (char *)r; + + return (char *)0; +} + +PR_IMPLEMENT(char *) +PL_strnpbrk(const char *s, const char *list, PRUint32 max) +{ + const char *p; + + if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0; + + for( ; max && *s; s++, max-- ) + for( p = list; *p; p++ ) + if( *s == *p ) + return (char *)s; + + return (char *)0; +} + +PR_IMPLEMENT(char *) +PL_strnprbrk(const char *s, const char *list, PRUint32 max) +{ + const char *p; + const char *r; + + if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0; + + for( r = s; max && *r; r++, max-- ) + ; + + for( r--; r >= s; r-- ) + for( p = list; *p; p++ ) + if( *r == *p ) + return (char *)r; + + return (char *)0; +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strstr.c nspr-4.10.7/nspr/lib/libc/src/strstr.c --- nspr-4.9.5/nspr/lib/libc/src/strstr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strstr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include + +PR_IMPLEMENT(char *) +PL_strstr(const char *big, const char *little) +{ + if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; + if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; + + return strstr(big, little); +} + +PR_IMPLEMENT(char *) +PL_strrstr(const char *big, const char *little) +{ + const char *p; + size_t ll; + size_t bl; + + if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; + if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; + + ll = strlen(little); + bl = strlen(big); + if( bl < ll ) return (char *)0; + p = &big[ bl - ll ]; + + for( ; p >= big; p-- ) + if( *little == *p ) + if( 0 == strncmp(p, little, ll) ) + return (char *)p; + + return (char *)0; +} + +PR_IMPLEMENT(char *) +PL_strnstr(const char *big, const char *little, PRUint32 max) +{ + size_t ll; + + if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; + if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; + + ll = strlen(little); + if( ll > (size_t)max ) return (char *)0; + max -= (PRUint32)ll; + max++; + + for( ; max && *big; big++, max-- ) + if( *little == *big ) + if( 0 == strncmp(big, little, ll) ) + return (char *)big; + + return (char *)0; +} + +PR_IMPLEMENT(char *) +PL_strnrstr(const char *big, const char *little, PRUint32 max) +{ + const char *p; + size_t ll; + + if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0; + if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0; + + ll = strlen(little); + + for( p = big; max && *p; p++, max-- ) + ; + + p -= ll; + if( p < big ) return (char *)0; + + for( ; p >= big; p-- ) + if( *little == *p ) + if( 0 == strncmp(p, little, ll) ) + return (char *)p; + + return (char *)0; +} diff -Nru nspr-4.9.5/nspr/lib/libc/src/strtok.c nspr-4.10.7/nspr/lib/libc/src/strtok.c --- nspr-4.9.5/nspr/lib/libc/src/strtok.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/libc/src/strtok.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" + +PR_IMPLEMENT(char *) +PL_strtok_r(char *s1, const char *s2, char **lasts) +{ + const char *sepp; + int c, sc; + char *tok; + + if( s1 == NULL ) + { + if( *lasts == NULL ) + return NULL; + + s1 = *lasts; + } + + for( ; (c = *s1) != 0; s1++ ) + { + for( sepp = s2 ; (sc = *sepp) != 0 ; sepp++ ) + { + if( c == sc ) + break; + } + if( sc == 0 ) + break; + } + + if( c == 0 ) + { + *lasts = NULL; + return NULL; + } + + tok = s1++; + + for( ; (c = *s1) != 0; s1++ ) + { + for( sepp = s2; (sc = *sepp) != 0; sepp++ ) + { + if( c == sc ) + { + *s1++ = '\0'; + *lasts = s1; + return tok; + } + } + } + *lasts = NULL; + return tok; +} diff -Nru nspr-4.9.5/nspr/lib/Makefile.in nspr-4.10.7/nspr/lib/Makefile.in --- nspr-4.9.5/nspr/lib/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,24 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = .. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +export NSPR20=1 + +include $(topsrcdir)/config/config.mk + +DIRS = ds libc + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/lib/prstreams/.cvsignore nspr-4.10.7/nspr/lib/prstreams/.cvsignore --- nspr-4.9.5/nspr/lib/prstreams/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/lib/prstreams/Makefile.in nspr-4.10.7/nspr/lib/prstreams/Makefile.in --- nspr-4.9.5/nspr/lib/prstreams/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,148 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +ifeq ($(OS_ARCH), IRIX) + ifneq ($(OS_RELEASE),5.3) + CCC_ONLY_FLAGS += -exceptions + endif +endif + +ifeq ($(OS_ARCH), BeOS) + CFLAGS += -frtti -fexceptions +endif + +INCLUDES = -I$(dist_includedir) + +HEADERS = $(wildcard $(srcdir)/*.h) + +CSRCS = \ + plvrsion.c \ + $(NULL) + +CXXSRCS = \ + prstrms.cpp \ + $(NULL) + +OBJS = $(addprefix $(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)) $(CXXSRCS:.cpp=.$(OBJ_SUFFIX))) + +ifeq ($(OS_ARCH), WINNT) + RES=$(OBJDIR)/prstrms.res + RESNAME=prstrms.rc + OS_LIBS = user32.lib +else + ifeq ($(OS_ARCH),OS2) + OS_LIBS = -lstdcpp + else + ifeq ($(OS_ARCH), AIX) + ifeq ($(OS_RELEASE), 4.1) + ifeq ($(CLASSIC_NSPR),1) + OS_LIBS += -lC -lc + else + OS_LIBS += -lC_r -lc_r + endif + else + # makeC++SharedLib(_r) is in either /usr/lpp/xlC/bin + # or /usr/ibmcxx/bin. + ifeq ($(CLASSIC_NSPR),1) + MKSHLIB = makeC++SharedLib -p 0 + else + MKSHLIB = makeC++SharedLib_r -p 0 + endif + OS_LIBS += -ldl + endif + endif + endif +endif + +ifeq ($(OS_ARCH),BeOS) + OS_LIBS = -lstdc++.r4 +endif + +ifeq ($(OS_ARCH), UNIXWARE) + OS_LIBS += -lC +endif + +EXTRA_LIBS = $(LIBNSPR) + +# On SCOOS, we can't link with extra libraries when +# we build a shared library. If we do so, the linker doesn't +# complain, but we would run into weird problems at run-time. +# Therefore on these platforms, we link just the object files. +ifeq ($(OS_ARCH),SCOOS) + EXTRA_LIBS = +endif + +ifdef RESOLVE_LINK_SYMBOLS +EXTRA_LIBS += $(OS_LIBS) +endif + +LIBRARY_NAME = prstrms +LIBRARY_VERSION = $(MOD_MAJOR_VERSION) + +RELEASE_HEADERS = $(HEADERS) +RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR) +RELEASE_LIBS = $(TARGETS) + +include $(topsrcdir)/config/rules.mk + +# +# Version information generation (begin) +# +ECHO = echo +TINC = $(OBJDIR)/_pl_bld.h +PROD = $(notdir $(SHARED_LIBRARY)) +NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now +SH_DATE = $(shell date "+%Y-%m-%d %T") +SH_NOW = $(shell $(NOW)) + +ifeq ($(OS_ARCH), WINNT) + SUF = i64 +else + SUF = LL +endif + +$(TINC): + @$(MAKE_OBJDIR) + @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC) + @if test ! -z "$(SH_NOW)"; then \ + $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \ + else \ + true; \ + fi + @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) + + +$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC) +ifeq ($(OS_ARCH), WINNT) + $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< +else + $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< +endif +# +# Version information generation (end) +# + +export:: $(TARGETS) $(HEADERS) + $(INSTALL) -m 444 $(HEADERS) $(dist_includedir) + $(INSTALL) -m 444 $(TARGETS) $(dist_libdir) +ifeq ($(OS_ARCH),OS2) + $(INSTALL) -m 444 $(TARGETS) $(dist_bindir) +endif +ifeq ($(OS_ARCH),HP-UX) +ifdef SHARED_LIBRARY + $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir) +endif +endif diff -Nru nspr-4.9.5/nspr/lib/prstreams/plvrsion.c nspr-4.10.7/nspr/lib/prstreams/plvrsion.c --- nspr-4.9.5/nspr/lib/prstreams/plvrsion.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/plvrsion.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include "prvrsion.h" + +/************************************************************************/ +/**************************IDENTITY AND VERSIONING***********************/ +/************************************************************************/ +#include "_pl_bld.h" +#if !defined(_BUILD_TIME) +#ifdef HAVE_LONG_LONG +#define _BUILD_TIME 0 +#else +#define _BUILD_TIME {0, 0} +#endif +#endif +#if !defined(_BUILD_STRING) +#define _BUILD_STRING "" +#endif +#if !defined(_PRODUCTION) +#define _PRODUCTION "" +#endif +#if defined(DEBUG) +#define _DEBUG_STRING " (debug)" +#else +#define _DEBUG_STRING "" +#endif + +/* + * A trick to expand the PR_VMAJOR macro before concatenation. + */ +#define CONCAT(x, y) x ## y +#define CONCAT2(x, y) CONCAT(x, y) +#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libprstrms, PR_VMAJOR) + +PRVersionDescription VERSION_DESC_NAME = +{ + /* version */ 2, /* this is the only one supported */ + /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */ + /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */ + /* vMajor */ PR_VMAJOR, /* NSPR's version number */ + /* vMinor */ PR_VMINOR, /* and minor version */ + /* vPatch */ PR_VPATCH, /* and patch */ + /* beta */ PR_BETA, /* beta build boolean */ +#if defined(DEBUG) + /* debug */ PR_TRUE, /* a debug build */ +#else + /* debug */ PR_FALSE, /* an optomized build */ +#endif + /* special */ PR_FALSE, /* they're all special, but ... */ + /* filename */ _PRODUCTION, /* the produced library name */ + /* description */ "Portable runtime", /* what we are */ + /* security */ "N/A", /* not applicable here */ + /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved", + /* comment */ "http://www.mozilla.org/MPL/", + /* specialString */ "" +}; + +#ifdef XP_UNIX + +/* + * Version information for the 'ident' and 'what commands + * + * NOTE: the first component of the concatenated rcsid string + * must not end in a '$' to prevent rcs keyword substitution. + */ +static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING + " " _BUILD_STRING " $"; +static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING + " " _BUILD_STRING; + +#endif /* XP_UNIX */ + +PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint() +{ +#ifdef XP_UNIX + /* + * Add dummy references to rcsid and sccsid to prevent them + * from being optimized away as unused variables. + */ + const char *dummy; + + dummy = rcsid; + dummy = sccsid; +#endif + return &VERSION_DESC_NAME; +} /* versionEntryPointType */ + +/* plvrsion.c */ + diff -Nru nspr-4.9.5/nspr/lib/prstreams/prstrms.cpp nspr-4.10.7/nspr/lib/prstreams/prstrms.cpp --- nspr-4.9.5/nspr/lib/prstreams/prstrms.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/prstrms.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,516 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Robin J. Maxwell 11-22-96 + * Fredrik Roubert 2010-07-23 + * Matt Austern 2010-07-23 + */ + +#include "prstrms.h" + +#include +#include +#include +#include + +using std::ios_base; +using std::iostream; +using std::istream; +using std::nothrow; +using std::ostream; +using std::streambuf; +using std::streamsize; + + +PRfilebuf::PRfilebuf(): + _fd(NULL), + _opened(false), + _allocated(false), + _unbuffered(false), + _user_buf(false), + _buf_base(NULL), + _buf_end(NULL) { } + + +PRfilebuf::PRfilebuf(PRFileDesc *fd): + _fd(fd), + _opened(false), + _allocated(false), + _unbuffered(false), + _user_buf(false), + _buf_base(NULL), + _buf_end(NULL) { } + + +PRfilebuf::PRfilebuf(PRFileDesc *fd, char_type *ptr, streamsize len): + _fd(fd), + _opened(false), + _allocated(false), + _unbuffered(false), + _user_buf(false), + _buf_base(NULL), + _buf_end(NULL) +{ + setbuf(ptr, len); +} + + +PRfilebuf::~PRfilebuf() +{ + if (_opened) { + close(); + } else { + sync(); + } + if (_allocated) { + delete _buf_base; + } +} + + +PRfilebuf *PRfilebuf::open( + const char *name, ios_base::openmode flags, PRIntn mode) +{ + if (_fd != NULL) { + return NULL; // Error if already open. + } + + // Translate flags argument. + PRIntn prflags = 0; + bool ate = (flags & ios_base::ate) != 0; + flags &= ~(ios_base::ate | ios_base::binary); + + // TODO: The flag PR_CREATE_FILE should probably be used for the cases + // (out), (out|app), (out|trunc) and (in|out|trunc) as the C++ standard + // specifies that these cases should open files 'as if by using fopen with + // "w"'. But adding that flag here will cause the unit test to leave files + // behind after running (which might or might not be an error in the unit + // test) so the matter needs further investigation before any changes are + // made. The old prstreams implementation used the non-standard flag + // ios::nocreate to control the use of PR_CREATE_FILE. + + if (flags == (ios_base::out)) { + prflags = PR_WRONLY | PR_TRUNCATE; + } else if (flags == (ios_base::out | ios_base::app)) { + prflags = PR_RDWR | PR_APPEND; + } else if (flags == (ios_base::out | ios_base::trunc)) { + prflags = PR_WRONLY | PR_TRUNCATE; + } else if (flags == (ios_base::in)) { + prflags = PR_RDONLY; + } else if (flags == (ios_base::in | ios_base::out)) { + prflags = PR_RDWR; + } else if (flags == (ios_base::in | ios_base::out | ios_base::trunc)) { + prflags = PR_RDWR | PR_TRUNCATE; + } else { + return NULL; // Unrecognized flag combination. + } + + if ((_fd = PR_Open(name, prflags, mode)) == NULL) { + return NULL; + } + + _opened = true; + + if (ate && + seekoff(0, ios_base::end, flags) == pos_type(traits_type::eof())) { + close(); + return NULL; + } + + return this; +} + + +PRfilebuf *PRfilebuf::attach(PRFileDesc *fd) +{ + if (_fd != NULL) { + return NULL; // Error if already open. + } + + _opened = false; + _fd = fd; + return this; +} + + +PRfilebuf *PRfilebuf::close() +{ + if (_fd == NULL) + return NULL; + + int status = sync(); + + if (PR_Close(_fd) == PR_FAILURE || + traits_type::eq_int_type(status, traits_type::eof())) { + return NULL; + } + + _fd = NULL; + return this; +} + + +streambuf *PRfilebuf::setbuf(char_type *ptr, streamsize len) +{ + if (is_open() && _buf_end) { + return NULL; + } + + if (!ptr || len <= 0) { + _unbuffered = true; + } else { + setb(ptr, ptr + len, false); + } + + return this; +} + + +streambuf::pos_type PRfilebuf::seekoff( + off_type offset, ios_base::seekdir dir, ios_base::openmode /*flags*/) +{ + if (PR_GetDescType(_fd) != PR_DESC_FILE) { + return traits_type::eof(); + } + + PRSeekWhence whence; + PRInt64 pos; + + switch (dir) { + case ios_base::beg: whence = PR_SEEK_SET; break; + case ios_base::cur: whence = PR_SEEK_CUR; break; + case ios_base::end: whence = PR_SEEK_END; break; + default: + return traits_type::eof(); // This should never happen. + } + + if (traits_type::eq_int_type(sync(), traits_type::eof())) { + return traits_type::eof(); + } + + if ((pos = PR_Seek64(_fd, offset, whence)) == -1) { + return traits_type::eof(); + } + + return pos; +} + + +int PRfilebuf::sync() +{ + if (_fd == NULL) { + return traits_type::eof(); + } + + if (!_unbuffered) { + // Sync write area. + PRInt32 waiting; + if ((waiting = pptr() - pbase()) != 0) { + PRInt32 nout; + if ((nout = PR_Write(_fd, pbase(), waiting)) != waiting) { + if (nout > 0) { + // Should set _pptr -= nout. + pbump(-nout); + memmove(pbase(), pbase() + nout, waiting - nout); + } + return traits_type::eof(); + } + } + setp(NULL, NULL); // Empty put area. + + if (PR_GetDescType(_fd) == PR_DESC_FILE) { + // Sockets can't seek; don't need this. + PROffset64 avail; + if ((avail = in_avail()) > 0) { + if (PR_Seek64(_fd, -avail, PR_SEEK_CUR) != -1) { + return traits_type::eof(); + } + } + } + setg(NULL, NULL, NULL); // Empty get area. + } + + return 0; +} + + +streambuf::int_type PRfilebuf::underflow() +{ + PRInt32 count; + char_type byte; + + if (gptr() != NULL && gptr() < egptr()) { + return traits_type::to_int_type(*gptr()); + } + + // Make sure there is a reserve area. + if (!_unbuffered && _buf_base == NULL && !allocate()) { + return traits_type::eof(); + } + + // Sync before new buffer created below. + if (traits_type::eq_int_type(sync(), traits_type::eof())) { + return traits_type::eof(); + } + + if (_unbuffered) { + if (PR_Read(_fd, &byte, 1) <= 0) { + return traits_type::eof(); + } + + return traits_type::to_int_type(byte); + } + + if ((count = PR_Read(_fd, _buf_base, _buf_end - _buf_base)) <= 0) { + return traits_type::eof(); // Reached EOF. + } + + setg(_buf_base, _buf_base, _buf_base + count); + return traits_type::to_int_type(*gptr()); +} + + +streambuf::int_type PRfilebuf::overflow(int_type c) +{ + // Make sure there is a reserve area. + if (!_unbuffered && _buf_base == NULL && !allocate()) { + return traits_type::eof(); + } + + // Sync before new buffer created below. + if (traits_type::eq_int_type(sync(), traits_type::eof())) { + return traits_type::eof(); + } + + if (!_unbuffered) { + setp(_buf_base, _buf_end); + } + + if (!traits_type::eq_int_type(c, traits_type::eof())) { + // Extract the byte to be written. + // (Required on big-endian architectures.) + char_type byte = traits_type::to_char_type(c); + if (!_unbuffered && pptr() < epptr()) { // Guard against recursion. + return sputc(byte); + } else { + if (PR_Write(_fd, &byte, 1) != 1) { + return traits_type::eof(); + } + } + } + + return traits_type::not_eof(c); +} + + +bool PRfilebuf::allocate() +{ + char_type *buf = new(nothrow) char_type[BUFSIZ]; + if (buf == NULL) { + return false; + } + + setb(buf, buf + BUFSIZ, true); + return true; +} + + +void PRfilebuf::setb(char_type *buf_base, char_type *buf_end, bool user_buf) +{ + if (_buf_base && !_user_buf) { + delete[] _buf_base; + } + + _buf_base = buf_base; + _buf_end = buf_end; + _user_buf = user_buf; +} + + +PRifstream::PRifstream(): + istream(NULL), + _filebuf() +{ + init(&_filebuf); +} + + +PRifstream::PRifstream(PRFileDesc *fd): + istream(NULL), + _filebuf(fd) +{ + init(&_filebuf); +} + + +PRifstream::PRifstream(PRFileDesc *fd, char_type *ptr, streamsize len): + istream(NULL), + _filebuf(fd, ptr, len) +{ + init(&_filebuf); +} + + +PRifstream::PRifstream(const char *name, openmode flags, PRIntn mode): + istream(NULL), + _filebuf() +{ + init(&_filebuf); + if (!_filebuf.open(name, flags | in, mode)) { + setstate(failbit); + } +} + + +PRifstream::~PRifstream() { } + + +void PRifstream::open(const char *name, openmode flags, PRIntn mode) +{ + if (is_open() || !_filebuf.open(name, flags | in, mode)) { + setstate(failbit); + } +} + + +void PRifstream::attach(PRFileDesc *fd) +{ + if (!_filebuf.attach(fd)) { + setstate(failbit); + } +} + + +void PRifstream::close() +{ + if (_filebuf.close() == NULL) { + setstate(failbit); + } +} + + +PRofstream::PRofstream(): + ostream(NULL), + _filebuf() +{ + init(&_filebuf); +} + + +PRofstream::PRofstream(PRFileDesc *fd): + ostream(NULL), + _filebuf(fd) +{ + init(&_filebuf); +} + + +PRofstream::PRofstream(PRFileDesc *fd, char_type *ptr, streamsize len): + ostream(NULL), + _filebuf(fd, ptr, len) +{ + init(&_filebuf); +} + + +PRofstream::PRofstream(const char *name, openmode flags, PRIntn mode): + ostream(NULL), + _filebuf() +{ + init(&_filebuf); + if (!_filebuf.open(name, flags | out, mode)) { + setstate(failbit); + } +} + + +PRofstream::~PRofstream() { } + + +void PRofstream::open(const char *name, openmode flags, PRIntn mode) +{ + if (is_open() || !_filebuf.open(name, flags | out, mode)) { + setstate(failbit); + } +} + + +void PRofstream::attach(PRFileDesc *fd) +{ + if (!_filebuf.attach(fd)) { + setstate(failbit); + } +} + + +void PRofstream::close() +{ + if (_filebuf.close() == NULL) { + setstate(failbit); + } +} + + +PRfstream::PRfstream(): + iostream(NULL), + _filebuf() +{ + init(&_filebuf); +} + + +PRfstream::PRfstream(PRFileDesc *fd): + iostream(NULL), + _filebuf(fd) +{ + init(&_filebuf); +} + + +PRfstream::PRfstream(PRFileDesc *fd, char_type *ptr, streamsize len): + iostream(NULL), + _filebuf(fd, ptr, len) +{ + init(&_filebuf); +} + + +PRfstream::PRfstream(const char *name, openmode flags, PRIntn mode): + iostream(NULL), + _filebuf() +{ + init(&_filebuf); + if (!_filebuf.open(name, flags | in | out, mode)) { + setstate(failbit); + } +} + + +PRfstream::~PRfstream() { } + + +void PRfstream::open(const char *name, openmode flags, PRIntn mode) +{ + if (is_open() || !_filebuf.open(name, flags | in | out, mode)) { + setstate(failbit); + } +} + + +void PRfstream::attach(PRFileDesc *fd) +{ + if (!_filebuf.attach(fd)) { + setstate(failbit); + } +} + + +void PRfstream::close() +{ + if (_filebuf.close() == NULL) { + setstate(failbit); + } +} diff -Nru nspr-4.9.5/nspr/lib/prstreams/prstrms.h nspr-4.10.7/nspr/lib/prstreams/prstrms.h --- nspr-4.9.5/nspr/lib/prstreams/prstrms.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/prstrms.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Robin J. Maxwell 11-22-96 + * Fredrik Roubert 2010-07-23 + * Matt Austern 2010-07-23 + */ + +#ifndef _PRSTRMS_H +#define _PRSTRMS_H + +#include +#include +#include +#include + +#include "prio.h" + +#ifdef _MSC_VER +// http://support.microsoft.com/kb/q168958/ +class PR_IMPLEMENT(std::_Mutex); +class PR_IMPLEMENT(std::ios_base); +#endif + + +class PR_IMPLEMENT(PRfilebuf): public std::streambuf +{ +public: + PRfilebuf(); + PRfilebuf(PRFileDesc *fd); + PRfilebuf(PRFileDesc *fd, char_type *ptr, std::streamsize len); + virtual ~PRfilebuf(); + + bool is_open() const { return _fd != NULL; } + + PRfilebuf *open( + const char *name, + std::ios_base::openmode flags, + PRIntn mode); + PRfilebuf *attach(PRFileDesc *fd); + PRfilebuf *close(); + +protected: + virtual std::streambuf *setbuf(char_type *ptr, std::streamsize len); + virtual pos_type seekoff( + off_type offset, + std::ios_base::seekdir dir, + std::ios_base::openmode flags); + virtual pos_type seekpos( + pos_type pos, + std::ios_base::openmode flags) { + return seekoff(pos, std::ios_base::beg, flags); + } + virtual int sync(); + virtual int_type underflow(); + virtual int_type overflow(int_type c = traits_type::eof()); + + // TODO: Override pbackfail(), showmanyc(), uflow(), xsgetn(), and xsputn(). + +private: + bool allocate(); + void setb(char_type *buf_base, char_type *buf_end, bool user_buf); + + PRFileDesc *_fd; + bool _opened; + bool _allocated; + bool _unbuffered; + bool _user_buf; + char_type *_buf_base; + char_type *_buf_end; +}; + + +class PR_IMPLEMENT(PRifstream): public std::istream +{ +public: + PRifstream(); + PRifstream(PRFileDesc *fd); + PRifstream(PRFileDesc *fd, char_type *ptr, std::streamsize len); + PRifstream(const char *name, openmode flags = in, PRIntn mode = 0); + virtual ~PRifstream(); + + PRfilebuf *rdbuf() const { return &_filebuf; } + bool is_open() const { return _filebuf.is_open(); } + + void open(const char *name, openmode flags = in, PRIntn mode = 0); + void attach(PRFileDesc *fd); + void close(); + +private: + mutable PRfilebuf _filebuf; +}; + + +class PR_IMPLEMENT(PRofstream): public std::ostream +{ +public: + PRofstream(); + PRofstream(PRFileDesc *fd); + PRofstream(PRFileDesc *fd, char_type *ptr, std::streamsize len); + PRofstream(const char *name, openmode flags = out, PRIntn mode = 0); + virtual ~PRofstream(); + + PRfilebuf *rdbuf() const { return &_filebuf; } + bool is_open() const { return _filebuf.is_open(); } + + void open(const char *name, openmode flags = out, PRIntn mode = 0); + void attach(PRFileDesc *fd); + void close(); + +private: + mutable PRfilebuf _filebuf; +}; + + +class PR_IMPLEMENT(PRfstream): public std::iostream +{ +public: + PRfstream(); + PRfstream(PRFileDesc *fd); + PRfstream(PRFileDesc *fd, char_type *ptr, std::streamsize len); + PRfstream(const char *name, openmode flags = in | out, PRIntn mode = 0); + virtual ~PRfstream(); + + PRfilebuf *rdbuf() const { return &_filebuf; } + bool is_open() const { return _filebuf.is_open(); } + + void open(const char *name, openmode flags = in | out, PRIntn mode = 0); + void attach(PRFileDesc *fd); + void close(); + +private: + mutable PRfilebuf _filebuf; +}; + + +#endif /* _PRSTRMS_H */ diff -Nru nspr-4.9.5/nspr/lib/prstreams/prstrms.rc nspr-4.10.7/nspr/lib/prstreams/prstrms.rc --- nspr-4.9.5/nspr/lib/prstreams/prstrms.rc 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/prstrms.rc 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include + +#define MY_LIBNAME "prstrms" +#define MY_FILEDESCRIPTION "PRSTRMS Library" + +#define STRINGIZE(x) #x +#define STRINGIZE2(x) STRINGIZE(x) +#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR) + +#ifdef _DEBUG +#define MY_DEBUG_STR " (debug)" +#define MY_FILEFLAGS_1 VS_FF_DEBUG +#else +#define MY_DEBUG_STR "" +#define MY_FILEFLAGS_1 0x0L +#endif +#if PR_BETA +#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE +#else +#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 +#endif + +#ifdef WINNT +#define MY_FILEOS VOS_NT_WINDOWS32 +#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR +#else +#define MY_FILEOS VOS__WINDOWS32 +#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Version-information resource +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 + PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS MY_FILEFLAGS_2 + FILEOS MY_FILEOS + FILETYPE VFT_DLL + FILESUBTYPE 0x0L // not used + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" // Lang=US English, CharSet=Unicode + BEGIN + VALUE "CompanyName", "Mozilla Foundation\0" + VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" + VALUE "FileVersion", PR_VERSION "\0" + VALUE "InternalName", MY_INTERNAL_NAME "\0" + VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" + VALUE "ProductName", "Netscape Portable Runtime\0" + VALUE "ProductVersion", PR_VERSION "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff -Nru nspr-4.9.5/nspr/lib/prstreams/tests/testprstrm/.cvsignore nspr-4.10.7/nspr/lib/prstreams/tests/testprstrm/.cvsignore --- nspr-4.9.5/nspr/lib/prstreams/tests/testprstrm/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/tests/testprstrm/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/lib/prstreams/tests/testprstrm/Makefile.in nspr-4.10.7/nspr/lib/prstreams/tests/testprstrm/Makefile.in --- nspr-4.9.5/nspr/lib/prstreams/tests/testprstrm/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/tests/testprstrm/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,168 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CXXSRCS = \ + testprstrm.cpp \ + $(NULL) + +OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX))) + +ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) +PROG_SUFFIX = .exe +else +PROG_SUFFIX = +endif + +PROGS = $(addprefix $(OBJDIR)/, $(CXXSRCS:.cpp=$(PROG_SUFFIX))) + +TARGETS = $(PROGS) $(OBJS) + +INCLUDES = -I$(dist_includedir) + +# Setting the variables LDOPTS and LIBPR. We first initialize +# them to the default values, then adjust them for some platforms. +LDOPTS = -L$(dist_libdir) +LIBPR = -lnspr$(MOD_MAJOR_VERSION) +LIBPRSTRMS = -lprstrms$(MOD_MAJOR_VERSION) + +ifeq ($(OS_ARCH), WINNT) + LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO + ifeq ($(OS_TARGET), WIN95) + LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + LIBPRSTRMS = $(dist_libdir)/prstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + else + LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + LIBPRSTRMS = $(dist_libdir)/libprstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + endif +endif + +ifeq ($(OS_ARCH),OS2) +LDOPTS += -Zomf -Zlinker /PM:VIO -lstdcpp +endif + +ifneq ($(OS_ARCH), WINNT) +PWD = $(shell pwd) +endif + +ifeq ($(OS_ARCH), IRIX) +LDOPTS += -rpath $(PWD)/$(dist_libdir) +endif + +ifeq ($(OS_ARCH), OSF1) +LDOPTS += -rpath $(PWD)/$(dist_libdir) +endif + +ifeq ($(OS_ARCH), HP-UX) +LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir) +endif + +# AIX +ifeq ($(OS_ARCH),AIX) +LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib +ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1) +LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr +LIBPRSTRMS = -lprstrms$(MOD_MAJOR_VERSION)_shr +else +LDOPTS += -brtl +EXTRA_LIBS = -ldl +endif +endif + +# Solaris +ifeq ($(OS_ARCH), SunOS) +ifdef NS_USE_GCC +LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir) +else +LDOPTS += -R $(PWD)/$(dist_libdir) +# CC on SunOS 5.5.x needs to link with -lpthread even though we already +# linked with this system library when we built libnspr.so. +ifdef USE_PTHREADS +EXTRA_LIBS = -lpthread +endif # USE_PTHREADS +endif # NS_USE_GCC +endif # SunOS + +ifeq ($(OS_ARCH), SCOOS) +# SCO Unix needs to link against -lsocket again even though we +# already linked with these system libraries when we built libnspr.so. +EXTRA_LIBS = -lsocket +# This hardcodes in the executable programs the directory to find +# libnspr.so etc. at program startup. Equivalent to the -R or -rpath +# option for ld on other platforms. +export LD_RUN_PATH = $(PWD)/$(dist_libdir) +endif + +ifeq ($(OS_ARCH), UNIXWARE) +export LD_RUN_PATH = $(PWD)/$(dist_libdir) +endif + +##################################################### +# +# The rules +# +##################################################### + +include $(topsrcdir)/config/rules.mk + +AIX_PRE_4_2 = 0 +ifeq ($(OS_ARCH),AIX) +ifneq ($(OS_RELEASE),4.2) +ifneq ($(USE_PTHREADS), 1) +#AIX_PRE_4_2 = 1 +endif +endif +endif + +ifeq ($(AIX_PRE_4_2),1) + +# AIX releases prior to 4.2 need a special two-step linking hack +# in order to both override the system select() and be able to +# get at the original system select(). +# +# We use a pattern rule in ns/nspr20/config/rules.mk to generate +# the .$(OBJ_SUFFIX) file from the .c source file, then do the +# two-step linking hack below. + +$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) + rm -f $@ $(AIX_TMP) + $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a + $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) + rm -f $(AIX_TMP) + +else + +# All platforms that are not AIX pre-4.2. + +$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH), WINNT) + link $(LDOPTS) $< $(LIBPR) $(LIBPRSTRMS) ws2_32.lib -out:$@ +else +ifeq ($(OS_ARCH),OS2) + $(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPR) $(LIBPRSTRMS) $(OS_LIBS) $(EXTRA_LIBS) +else + $(CCC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPRSTRMS) $(EXTRA_LIBS) -o $@ +endif +endif +endif + +export:: $(TARGETS) +clean:: + rm -f $(TARGETS) + +testlinker: + echo $(LINK) diff -Nru nspr-4.9.5/nspr/lib/prstreams/tests/testprstrm/testprstrm.cpp nspr-4.10.7/nspr/lib/prstreams/tests/testprstrm/testprstrm.cpp --- nspr-4.9.5/nspr/lib/prstreams/tests/testprstrm/testprstrm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/prstreams/tests/testprstrm/testprstrm.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prstrms.h" + +#include "prinit.h" +#include "prio.h" +#include "prthread.h" + +#include +#include + +#ifdef XP_UNIX +#include +#endif + +using std::cout; +using std::endl; +using std::ios; + +const unsigned int MaxCnt = 1; + +typedef struct threadarg { + const char *mytag; +} threadarg; + +void threadwork(threadarg *arg); + +void +threadmain(void *mytag) +{ + threadarg arg; + + arg.mytag = static_cast(mytag); + + threadwork(&arg); +} + +void +threadwork(threadarg *arg) +{ + unsigned int i; + + char fname1[256]; + char fname2[256]; + + strcpy(fname1, arg->mytag); + strcpy(fname2, arg->mytag); + strcat(fname2, "2"); + PR_Delete(fname1); + PR_Delete(fname2); + + PRfilebuf *fb[MaxCnt]; + PRifstream *ifs[MaxCnt]; + PRofstream *ofs[MaxCnt]; + int mode = 0; +#ifdef XP_UNIX + mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; +#endif + + // + // Allocate a bunch + cout << "Testing unused filebufs ----------------" << endl; + for (i=0; i < MaxCnt; i++){ + fb[i] = new PRfilebuf; + } + // Delete them + for (i=0; i < MaxCnt; i++){ + delete fb[i]; + } + cout << "Unused filebufs complete ---------------" << endl; + + // + // Allocate a bunch + cout << "Testing unused ifstream -----------------" << endl; + for (i=0; i < MaxCnt; i++){ + ifs[i] = new PRifstream; + } + // + // Delete them + for (i=0; i < MaxCnt; i++){ + delete ifs[i]; + } + cout << "Unused ifstream complete ----------------" << endl; + // + // Allocate a bunch + cout << "Testing unused ofstream -----------------" << endl; + for (i=0; i < MaxCnt; i++){ + ofs[i] = new PRofstream; + } + for (i=0; i < MaxCnt; i++){ + *(ofs[i]) << "A"; // Write a bit + delete ofs[i]; // Delete it. + } + cout << "Unused ofstream complete ----------------" << endl; + + cout << "Testing use of ofstream 1 (extra filebuf allocated) ---------" << endl; + PRofstream *aos = new PRofstream(fname1, ios::out|ios::ate, mode); + for (i=0; i < MaxCnt; i++){ + for (int j=0; j < 8192; j++) + *aos << "AaBbCcDdEeFfGg" << endl; + fb[i] = new PRfilebuf; // Allocate as we go to hack at the heap + } + // + // Delete the extra foo we allocated + for (i=0; i < MaxCnt; i++){ + delete fb[i]; + } + aos->flush(); // Explicit flush + delete aos; + cout << "Testing use of ofstream 1 complete (extra filebuf deleted) --" << endl; + cout << "Testing use of ofstream 2 (extra filebuf allocated) ---------" << endl; + PRofstream *aos2 = new PRofstream(fname2, ios::out, mode); + + for (i=0; i < MaxCnt; i++){ + *aos2 << "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; + } + // Force flushing in the dtor + delete aos2; + cout << "Testing use of ofstream 2 complete (extra filebuf deleted) --" << endl; + char line[1024]; + cout << "Testing use of ifstream 1 (stack allocation) -------------" << endl; + PRifstream ais(fname1); + for (i=0; i < MaxCnt; i++){ + ais >> line; + } + cout << "Testing use of ifstream 1 complete -----------------------" << endl; + cout << "Testing use of ifstream 2 ----------------------" << endl; + PRifstream *ais2 = new PRifstream(fname2); + char achar; + for (i=0; i < MaxCnt*10; i++){ + *ais2 >> achar; + } + delete ais2; + cout << "Testing use of ifstream 2 complete -------------" << endl; +} + +#define STACKSIZE 1024*1024 +int +main() +{ + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 256); + threadmain(const_cast("TestFile")); + PRThread *thr1 = PR_CreateThread(PR_SYSTEM_THREAD, + threadmain, + const_cast("TestFile1"), + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + STACKSIZE); + PRThread *thr2 = PR_CreateThread(PR_SYSTEM_THREAD, + threadmain, + const_cast("TestFile2"), + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + STACKSIZE); + PRThread *thr3 = PR_CreateThread(PR_SYSTEM_THREAD, + threadmain, + const_cast("TestFile3"), + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + STACKSIZE); + PR_JoinThread(thr1); + PR_JoinThread(thr2); + PR_JoinThread(thr3); + return 0; +} diff -Nru nspr-4.9.5/nspr/lib/tests/arena.c nspr-4.10.7/nspr/lib/tests/arena.c --- nspr-4.9.5/nspr/lib/tests/arena.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/tests/arena.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,369 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: arena.c +** Description: Testing arenas +** +*/ + +#include +#include +#include +#include "nspr.h" +#include "plarena.h" +#include "plgetopt.h" + +PRLogModuleInfo *tLM; +PRIntn threadCount = 0; +PRMonitor *tMon; +PRBool failed_already = PR_FALSE; + +/* Arguments from the command line with default values */ +PRIntn debug_mode = 0; +PRIntn poolMin = 4096; +PRIntn poolMax = (100 * 4096); +PRIntn arenaMin = 40; +PRIntn arenaMax = (100 * 40); +PRIntn stressIterations = 15; +PRIntn maxAlloc = (1024 * 1024); +PRIntn stressThreads = 4; + +void DumpAll( void ) +{ + return; +} + +/* +** Test Arena allocation. +*/ +static void ArenaAllocate( void ) +{ + PLArenaPool ap; + void *ptr; + PRInt32 i; + + PL_InitArenaPool( &ap, "AllocArena", 2048, sizeof(double)); + PR_LOG( tLM, PR_LOG_DEBUG, ("AA, InitPool -- Pool: %p. first: %p, current: %p, size: %d", + &ap, ap.first, ap.current, ap.arenasize )); + + for( i = 0; i < 150; i++ ) + { + PL_ARENA_ALLOCATE( ptr, &ap, 512 ); + PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", + &ap, ap.first, ap.current, ap.arenasize )); + PR_LOG( tLM, PR_LOG_DEBUG,( + "AA -- Pool: %p. alloc: %p ", &ap, ptr )); + } + + PL_FreeArenaPool( &ap ); + + for( i = 0; i < 221; i++ ) + { + PL_ARENA_ALLOCATE( ptr, &ap, 512 ); + PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d", + &ap, ap.first, ap.current, ap.arenasize )); + PR_LOG( tLM, PR_LOG_DEBUG,( + "AA -- Pool: %p. alloc: %p ", &ap, ptr )); + } + + PL_FreeArenaPool( &ap ); + + return; +} /* end ArenaGrow() */ +/* +** Test Arena grow. +*/ +static void ArenaGrow( void ) +{ + PLArenaPool ap; + void *ptr; + PRInt32 i; + + PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double)); + PL_ARENA_ALLOCATE( ptr, &ap, 512 ); + + PR_LOG( tLM, PR_LOG_DEBUG, ("Before growth -- Pool: %p. alloc: %p ", &ap, ptr )); + + for( i = 0; i < 10; i++ ) + { + PL_ARENA_GROW( ptr, &ap, 512, 7000 ); + PR_LOG( tLM, PR_LOG_DEBUG, ("After growth -- Pool: %p. alloc: %p ", &ap, ptr )); + } + + + return; +} /* end ArenaGrow() */ + + +/* +** Test arena Mark and Release. +*/ +static void MarkAndRelease( void ) +{ + PLArenaPool ap; + void *ptr = NULL; + void *mark0, *mark1; + PRIntn i; + + PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double)); + mark0 = PL_ARENA_MARK( &ap ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("mark0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m0: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark0 )); + + for( i = 0; i < 201; i++ ) + { + PL_ARENA_ALLOCATE( ptr, &ap, 512 ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr )); + } + + mark1 = PL_ARENA_MARK( &ap ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("mark1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m1: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark1 )); + + + for( i = 0; i < 225; i++ ) + { + PL_ARENA_ALLOCATE( ptr, &ap, 512 ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr )); + } + + PL_ARENA_RELEASE( &ap, mark1 ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("Release-1: %p -- Pool: %p. first: %p, current: %p, size: %d", + mark1, &ap, ap.first, ap.current, ap.arenasize )); + + for( i = 0; i < 20; i++ ) + { + PL_ARENA_ALLOCATE( ptr, &ap, 512 ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr )); + } + + PL_ARENA_RELEASE( &ap, mark1 ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("Release-1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr )); + + PL_ARENA_RELEASE( &ap, mark0 ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("Release-0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr )); + + PL_FreeArenaPool( &ap ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("Free. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr )); + + PL_FinishArenaPool( &ap ); + PR_LOG( tLM, PR_LOG_DEBUG, + ("Finish. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", + &ap, ap.first.next, ap.current, ap.arenasize, ptr )); + + return; +} /* end MarkAndRelease() */ + +/* +** RandSize() returns a random number in the range +** min..max, rounded to the next doubleword +** +*/ +static PRIntn RandSize( PRIntn min, PRIntn max ) +{ + PRIntn sz = (rand() % (max -min)) + min + sizeof(double); + + sz &= ~sizeof(double)-1; + + return(sz); +} + + +/* +** StressThread() +** A bunch of these beat on individual arenas +** This tests the free_list protection. +** +*/ +static void PR_CALLBACK StressThread( void *arg ) +{ + PLArenaPool ap; + PRIntn i; + PRIntn sz; + void *ptr; + PRThread *tp = PR_GetCurrentThread(); + + PR_LOG( tLM, PR_LOG_DEBUG, ("Stress Thread %p started\n", PR_GetCurrentThread())); + PL_InitArenaPool( &ap, "TheArena", RandSize( poolMin, poolMax), sizeof(double)); + + for ( i = 0; i < stressIterations; i++ ) + { + PRIntn allocated = 0; + + while ( allocated < maxAlloc ) + { + sz = RandSize( arenaMin, arenaMax ); + PL_ARENA_ALLOCATE( ptr, &ap, sz ); + if ( ptr == NULL ) + { + PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated)); + break; + } + allocated += sz; + } + PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp)); + PL_FreeArenaPool( &ap ); + } + PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp)); + PL_FinishArenaPool( &ap ); + PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp)); + + /* That's all folks! let's quit */ + PR_EnterMonitor(tMon); + threadCount--; + PR_Notify(tMon); + PR_ExitMonitor(tMon); + return; +} + +/* +** Stress() +** Flog the hell out of arenas multi-threaded. +** Do NOT pass an individual arena to another thread. +** +*/ +static void Stress( void ) +{ + PRThread *tt; + PRIntn i; + + tMon = PR_NewMonitor(); + + for ( i = 0 ; i < stressThreads ; i++ ) + { + PR_EnterMonitor(tMon); + tt = PR_CreateThread(PR_USER_THREAD, + StressThread, + NULL, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + threadCount++; + PR_ExitMonitor(tMon); + } + + /* Wait for all threads to exit */ + PR_EnterMonitor(tMon); + while ( threadCount != 0 ) + { + PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT); + } + PR_ExitMonitor(tMon); + PR_DestroyMonitor(tMon); + + return; +} /* end Stress() */ + +/* +** EvaluateResults() +** uses failed_already to display results and set program +** exit code. +*/ +static PRIntn EvaluateResults(void) +{ + PRIntn rc = 0; + + if ( failed_already == PR_TRUE ) + { + PR_LOG( tLM, PR_LOG_DEBUG, ("FAIL\n")); + rc =1; + } + else + { + PR_LOG( tLM, PR_LOG_DEBUG, ("PASS\n")); + } + return(rc); +} /* EvaluateResults() */ + +void Help( void ) +{ + printf("arena [options]\n"); + printf("where options are:\n"); + printf("-p minimum size of an arena pool. Default(%d)\n", poolMin); + printf("-P maximum size of an arena pool. Default(%d)\n", poolMax); + printf("-a minimum size of an arena allocation. Default(%d)\n", arenaMin); + printf("-A maximum size of an arena allocation. Default(%d)\n", arenaMax); + printf("-i number of iterations in a stress thread. Default(%d)\n", stressIterations); + printf("-s maximum allocation for a single stress thread. Default(%d)\n", maxAlloc); + printf("-t number of stress threads. Default(%d)\n", stressThreads ); + printf("-d enable debug mode\n"); + printf("\n"); + exit(1); +} + +PRIntn main(PRIntn argc, char *argv[]) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dhp:P:a:A:i:s:t:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'a': /* arena Min size */ + arenaMin = atol( opt->value ); + break; + case 'A': /* arena Max size */ + arenaMax = atol( opt->value ); + break; + case 'p': /* pool Min size */ + poolMin = atol( opt->value ); + break; + case 'P': /* pool Max size */ + poolMax = atol( opt->value ); + break; + case 'i': /* Iterations in stress tests */ + stressIterations = atol( opt->value ); + break; + case 's': /* storage to get per iteration */ + maxAlloc = atol( opt->value ); + break; + case 't': /* Number of stress threads to create */ + stressThreads = atol( opt->value ); + break; + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'h': /* help */ + default: + Help(); + } /* end switch() */ + } /* end while() */ + PL_DestroyOptState(opt); + + srand( (unsigned)time( NULL ) ); /* seed random number generator */ + tLM = PR_NewLogModule("testcase"); + + +#if 0 + ArenaAllocate(); + ArenaGrow(); +#endif + + MarkAndRelease(); + + Stress(); + + return(EvaluateResults()); +} /* end main() */ + +/* arena.c */ diff -Nru nspr-4.9.5/nspr/lib/tests/base64t.c nspr-4.10.7/nspr/lib/tests/base64t.c --- nspr-4.9.5/nspr/lib/tests/base64t.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/tests/base64t.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,3015 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plbase64.h" +#include "plstr.h" +#include "nspr.h" + +#include + +static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* PL_Base64Encode, single characters */ +PRBool test_001(void) +{ + PRUint32 a, b; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char result[ 8 ]; + char *rv; + + printf("Test 001 (PL_Base64Encode, single characters) ..."); fflush(stdout); + + plain[1] = plain[2] = plain[3] = (unsigned char)0; + cypher[2] = cypher[3] = (unsigned char)'='; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + + for( b = 0; b < 4; b++ ) + { + plain[0] = (unsigned char)(a * 4 + b); + cypher[1] = base[(b * 16)]; + + rv = PL_Base64Encode((char *)plain, 1, result); + if( rv != result ) + { + printf("FAIL\n\t(%d, %d): return value\n", a, b); + return PR_FALSE; + } + + if( 0 != PL_strncmp((char *)cypher, result, 4) ) + { + printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.4s.\"\n", + a, b, cypher, result); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, double characters */ +PRBool test_002(void) +{ + PRUint32 a, b, c, d; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char result[ 8 ]; + char *rv; + + printf("Test 002 (PL_Base64Encode, double characters) ..."); fflush(stdout); + + plain[2] = plain[3] = (unsigned char)0; + cypher[3] = (unsigned char)'='; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + cypher[2] = base[d*4]; + + rv = PL_Base64Encode((char *)plain, 2, result); + if( rv != result ) + { + printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d); + return PR_FALSE; + } + + if( 0 != PL_strncmp((char *)cypher, result, 4) ) + { + printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n", + a, b, c, d, cypher, result); + return PR_FALSE; + } + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, triple characters */ +PRBool test_003(void) +{ + PRUint32 a, b, c, d, e, f; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char result[ 8 ]; + char *rv; + + printf("Test 003 (PL_Base64Encode, triple characters) ..."); fflush(stdout); + + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + for( e = 0; e < 4; e++ ) + { + cypher[2] = base[d*4 + e]; + for( f = 0; f < 64; f++ ) + { + plain[2] = e * 64 + f; + cypher[3] = base[f]; + + rv = PL_Base64Encode((char *)plain, 3, result); + if( rv != result ) + { + printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): return value\n", a, b, c, d, e, f); + return PR_FALSE; + } + + if( 0 != PL_strncmp((char *)cypher, result, 4) ) + { + printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n", + a, b, c, d, e, f, cypher, result); + return PR_FALSE; + } + } + } + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + + static struct + { + const char *plaintext; + const char *cyphertext; + } array[] = + { + /* Cyphertexts generated with uuenview 0.5.13 */ + { " ", "IA==" }, + { ".", "Lg==" }, + { "/", "Lw==" }, + { "C", "Qw==" }, + { "H", "SA==" }, + { "S", "Uw==" }, + { "^", "Xg==" }, + { "a", "YQ==" }, + { "o", "bw==" }, + { "t", "dA==" }, + + { "AB", "QUI=" }, + { "AH", "QUg=" }, + { "AQ", "QVE=" }, + { "BD", "QkQ=" }, + { "CR", "Q1I=" }, + { "CS", "Q1M=" }, + { "DB", "REI=" }, + { "DC", "REM=" }, + { "EK", "RUs=" }, + { "ET", "RVQ=" }, + { "IM", "SU0=" }, + { "JR", "SlI=" }, + { "LO", "TE8=" }, + { "LW", "TFc=" }, + { "ML", "TUw=" }, + { "SB", "U0I=" }, + { "TO", "VE8=" }, + { "VS", "VlM=" }, + { "WP", "V1A=" }, + /* legitimate two-letter words */ + { "ad", "YWQ=" }, + { "ah", "YWg=" }, + { "am", "YW0=" }, + { "an", "YW4=" }, + { "as", "YXM=" }, + { "at", "YXQ=" }, + { "ax", "YXg=" }, + { "be", "YmU=" }, + { "by", "Ynk=" }, + { "do", "ZG8=" }, + { "go", "Z28=" }, + { "he", "aGU=" }, + { "hi", "aGk=" }, + { "if", "aWY=" }, + { "in", "aW4=" }, + { "is", "aXM=" }, + { "it", "aXQ=" }, + { "me", "bWU=" }, + { "my", "bXk=" }, + { "no", "bm8=" }, + { "of", "b2Y=" }, + { "on", "b24=" }, + { "or", "b3I=" }, + { "ox", "b3g=" }, + { "so", "c28=" }, + { "to", "dG8=" }, + { "up", "dXA=" }, + { "us", "dXM=" }, + { "we", "d2U=" }, + /* all three-letter entries in /usr/dict/words */ + { "1st", "MXN0" }, + { "2nd", "Mm5k" }, + { "3rd", "M3Jk" }, + { "4th", "NHRo" }, + { "5th", "NXRo" }, + { "6th", "NnRo" }, + { "7th", "N3Ro" }, + { "8th", "OHRo" }, + { "9th", "OXRo" }, + { "AAA", "QUFB" }, + { "AAU", "QUFV" }, + { "ABA", "QUJB" }, + { "abc", "YWJj" }, + { "Abe", "QWJl" }, + { "Abo", "QWJv" }, + { "ace", "YWNl" }, + { "ACM", "QUNN" }, + { "ACS", "QUNT" }, + { "act", "YWN0" }, + { "Ada", "QWRh" }, + { "add", "YWRk" }, + { "ado", "YWRv" }, + { "aft", "YWZ0" }, + { "age", "YWdl" }, + { "ago", "YWdv" }, + { "aid", "YWlk" }, + { "ail", "YWls" }, + { "aim", "YWlt" }, + { "air", "YWly" }, + { "ala", "YWxh" }, + { "alb", "YWxi" }, + { "ale", "YWxl" }, + { "Ali", "QWxp" }, + { "all", "YWxs" }, + { "alp", "YWxw" }, + { "A&M", "QSZN" }, + { "AMA", "QU1B" }, + { "ami", "YW1p" }, + { "amp", "YW1w" }, + { "Amy", "QW15" }, + { "amy", "YW15" }, + { "ana", "YW5h" }, + { "and", "YW5k" }, + { "ani", "YW5p" }, + { "Ann", "QW5u" }, + { "ant", "YW50" }, + { "any", "YW55" }, + { "A&P", "QSZQ" }, + { "ape", "YXBl" }, + { "Apr", "QXBy" }, + { "APS", "QVBT" }, + { "apt", "YXB0" }, + { "arc", "YXJj" }, + { "are", "YXJl" }, + { "ark", "YXJr" }, + { "arm", "YXJt" }, + { "art", "YXJ0" }, + { "a's", "YSdz" }, + { "ash", "YXNo" }, + { "ask", "YXNr" }, + { "ass", "YXNz" }, + { "ate", "YXRl" }, + { "Aug", "QXVn" }, + { "auk", "YXVr" }, + { "Ave", "QXZl" }, + { "awe", "YXdl" }, + { "awl", "YXds" }, + { "awn", "YXdu" }, + { "axe", "YXhl" }, + { "aye", "YXll" }, + { "bad", "YmFk" }, + { "bag", "YmFn" }, + { "bah", "YmFo" }, + { "bam", "YmFt" }, + { "ban", "YmFu" }, + { "bar", "YmFy" }, + { "bat", "YmF0" }, + { "bay", "YmF5" }, + { "bed", "YmVk" }, + { "bee", "YmVl" }, + { "beg", "YmVn" }, + { "bel", "YmVs" }, + { "Ben", "QmVu" }, + { "bet", "YmV0" }, + { "bey", "YmV5" }, + { "bib", "Ymli" }, + { "bid", "Ymlk" }, + { "big", "Ymln" }, + { "bin", "Ymlu" }, + { "bit", "Yml0" }, + { "biz", "Yml6" }, + { "BMW", "Qk1X" }, + { "boa", "Ym9h" }, + { "bob", "Ym9i" }, + { "bog", "Ym9n" }, + { "bon", "Ym9u" }, + { "boo", "Ym9v" }, + { "bop", "Ym9w" }, + { "bow", "Ym93" }, + { "box", "Ym94" }, + { "boy", "Ym95" }, + { "b's", "Yidz" }, + { "BTL", "QlRM" }, + { "BTU", "QlRV" }, + { "bub", "YnVi" }, + { "bud", "YnVk" }, + { "bug", "YnVn" }, + { "bum", "YnVt" }, + { "bun", "YnVu" }, + { "bus", "YnVz" }, + { "but", "YnV0" }, + { "buy", "YnV5" }, + { "bye", "Ynll" }, + { "cab", "Y2Fi" }, + { "Cal", "Q2Fs" }, + { "cam", "Y2Ft" }, + { "can", "Y2Fu" }, + { "cap", "Y2Fw" }, + { "car", "Y2Fy" }, + { "cat", "Y2F0" }, + { "caw", "Y2F3" }, + { "CBS", "Q0JT" }, + { "CDC", "Q0RD" }, + { "CEQ", "Q0VR" }, + { "chi", "Y2hp" }, + { "CIA", "Q0lB" }, + { "cit", "Y2l0" }, + { "cod", "Y29k" }, + { "cog", "Y29n" }, + { "col", "Y29s" }, + { "con", "Y29u" }, + { "coo", "Y29v" }, + { "cop", "Y29w" }, + { "cos", "Y29z" }, + { "cot", "Y290" }, + { "cow", "Y293" }, + { "cox", "Y294" }, + { "coy", "Y295" }, + { "CPA", "Q1BB" }, + { "cpu", "Y3B1" }, + { "CRT", "Q1JU" }, + { "cry", "Y3J5" }, + { "c's", "Yydz" }, + { "cub", "Y3Vi" }, + { "cud", "Y3Vk" }, + { "cue", "Y3Vl" }, + { "cup", "Y3Vw" }, + { "cur", "Y3Vy" }, + { "cut", "Y3V0" }, + { "dab", "ZGFi" }, + { "dad", "ZGFk" }, + { "dam", "ZGFt" }, + { "Dan", "RGFu" }, + { "Dar", "RGFy" }, + { "day", "ZGF5" }, + { "Dec", "RGVj" }, + { "Dee", "RGVl" }, + { "Del", "RGVs" }, + { "den", "ZGVu" }, + { "Des", "RGVz" }, + { "dew", "ZGV3" }, + { "dey", "ZGV5" }, + { "did", "ZGlk" }, + { "die", "ZGll" }, + { "dig", "ZGln" }, + { "dim", "ZGlt" }, + { "din", "ZGlu" }, + { "dip", "ZGlw" }, + { "Dis", "RGlz" }, + { "DNA", "RE5B" }, + { "DOD", "RE9E" }, + { "doe", "ZG9l" }, + { "dog", "ZG9n" }, + { "don", "ZG9u" }, + { "dot", "ZG90" }, + { "Dow", "RG93" }, + { "dry", "ZHJ5" }, + { "d's", "ZCdz" }, + { "dub", "ZHVi" }, + { "dud", "ZHVk" }, + { "due", "ZHVl" }, + { "dug", "ZHVn" }, + { "dun", "ZHVu" }, + { "dye", "ZHll" }, + { "ear", "ZWFy" }, + { "eat", "ZWF0" }, + { "ebb", "ZWJi" }, + { "EDT", "RURU" }, + { "eel", "ZWVs" }, + { "eft", "ZWZ0" }, + { "e.g", "ZS5n" }, + { "egg", "ZWdn" }, + { "ego", "ZWdv" }, + { "eke", "ZWtl" }, + { "Eli", "RWxp" }, + { "elk", "ZWxr" }, + { "ell", "ZWxs" }, + { "elm", "ZWxt" }, + { "Ely", "RWx5" }, + { "end", "ZW5k" }, + { "Eng", "RW5n" }, + { "EPA", "RVBB" }, + { "era", "ZXJh" }, + { "ere", "ZXJl" }, + { "erg", "ZXJn" }, + { "err", "ZXJy" }, + { "e's", "ZSdz" }, + { "EST", "RVNU" }, + { "eta", "ZXRh" }, + { "etc", "ZXRj" }, + { "Eva", "RXZh" }, + { "eve", "ZXZl" }, + { "ewe", "ZXdl" }, + { "eye", "ZXll" }, + { "FAA", "RkFB" }, + { "fad", "ZmFk" }, + { "fag", "ZmFn" }, + { "fan", "ZmFu" }, + { "far", "ZmFy" }, + { "fat", "ZmF0" }, + { "fay", "ZmF5" }, + { "FBI", "RkJJ" }, + { "FCC", "RkND" }, + { "FDA", "RkRB" }, + { "Feb", "RmVi" }, + { "fed", "ZmVk" }, + { "fee", "ZmVl" }, + { "few", "ZmV3" }, + { "fib", "Zmli" }, + { "fig", "Zmln" }, + { "fin", "Zmlu" }, + { "fir", "Zmly" }, + { "fit", "Zml0" }, + { "fix", "Zml4" }, + { "Flo", "Rmxv" }, + { "flu", "Zmx1" }, + { "fly", "Zmx5" }, + { "FMC", "Rk1D" }, + { "fob", "Zm9i" }, + { "foe", "Zm9l" }, + { "fog", "Zm9n" }, + { "fop", "Zm9w" }, + { "for", "Zm9y" }, + { "fox", "Zm94" }, + { "FPC", "RlBD" }, + { "fro", "ZnJv" }, + { "fry", "ZnJ5" }, + { "f's", "Zidz" }, + { "FTC", "RlRD" }, + { "fum", "ZnVt" }, + { "fun", "ZnVu" }, + { "fur", "ZnVy" }, + { "gab", "Z2Fi" }, + { "gad", "Z2Fk" }, + { "gag", "Z2Fn" }, + { "gal", "Z2Fs" }, + { "gam", "Z2Ft" }, + { "GAO", "R0FP" }, + { "gap", "Z2Fw" }, + { "gar", "Z2Fy" }, + { "gas", "Z2Fz" }, + { "gay", "Z2F5" }, + { "gee", "Z2Vl" }, + { "gel", "Z2Vs" }, + { "gem", "Z2Vt" }, + { "get", "Z2V0" }, + { "gig", "Z2ln" }, + { "Gil", "R2ls" }, + { "gin", "Z2lu" }, + { "GMT", "R01U" }, + { "GNP", "R05Q" }, + { "gnu", "Z251" }, + { "Goa", "R29h" }, + { "gob", "Z29i" }, + { "god", "Z29k" }, + { "gog", "Z29n" }, + { "GOP", "R09Q" }, + { "got", "Z290" }, + { "GPO", "R1BP" }, + { "g's", "Zydz" }, + { "GSA", "R1NB" }, + { "gum", "Z3Vt" }, + { "gun", "Z3Vu" }, + { "Gus", "R3Vz" }, + { "gut", "Z3V0" }, + { "guy", "Z3V5" }, + { "gym", "Z3lt" }, + { "gyp", "Z3lw" }, + { "had", "aGFk" }, + { "Hal", "SGFs" }, + { "ham", "aGFt" }, + { "Han", "SGFu" }, + { "hap", "aGFw" }, + { "hat", "aGF0" }, + { "haw", "aGF3" }, + { "hay", "aGF5" }, + { "hem", "aGVt" }, + { "hen", "aGVu" }, + { "her", "aGVy" }, + { "hew", "aGV3" }, + { "hex", "aGV4" }, + { "hey", "aGV5" }, + { "hid", "aGlk" }, + { "him", "aGlt" }, + { "hip", "aGlw" }, + { "his", "aGlz" }, + { "hit", "aGl0" }, + { "hob", "aG9i" }, + { "hoc", "aG9j" }, + { "hoe", "aG9l" }, + { "hog", "aG9n" }, + { "hoi", "aG9p" }, + { "Hom", "SG9t" }, + { "hop", "aG9w" }, + { "hot", "aG90" }, + { "how", "aG93" }, + { "hoy", "aG95" }, + { "h's", "aCdz" }, + { "hub", "aHVi" }, + { "hue", "aHVl" }, + { "hug", "aHVn" }, + { "huh", "aHVo" }, + { "hum", "aHVt" }, + { "Hun", "SHVu" }, + { "hut", "aHV0" }, + { "Ian", "SWFu" }, + { "IBM", "SUJN" }, + { "Ibn", "SWJu" }, + { "ICC", "SUND" }, + { "ice", "aWNl" }, + { "icy", "aWN5" }, + { "I'd", "SSdk" }, + { "Ida", "SWRh" }, + { "i.e", "aS5l" }, + { "iii", "aWlp" }, + { "Ike", "SWtl" }, + { "ill", "aWxs" }, + { "I'm", "SSdt" }, + { "imp", "aW1w" }, + { "Inc", "SW5j" }, + { "ink", "aW5r" }, + { "inn", "aW5u" }, + { "ion", "aW9u" }, + { "Ira", "SXJh" }, + { "ire", "aXJl" }, + { "irk", "aXJr" }, + { "IRS", "SVJT" }, + { "i's", "aSdz" }, + { "Ito", "SXRv" }, + { "ITT", "SVRU" }, + { "ivy", "aXZ5" }, + { "jab", "amFi" }, + { "jag", "amFn" }, + { "jam", "amFt" }, + { "Jan", "SmFu" }, + { "jar", "amFy" }, + { "jaw", "amF3" }, + { "jay", "amF5" }, + { "Jed", "SmVk" }, + { "jet", "amV0" }, + { "Jew", "SmV3" }, + { "jig", "amln" }, + { "Jim", "Smlt" }, + { "job", "am9i" }, + { "Joe", "Sm9l" }, + { "jog", "am9n" }, + { "Jon", "Sm9u" }, + { "jot", "am90" }, + { "joy", "am95" }, + { "j's", "aidz" }, + { "jug", "anVn" }, + { "jut", "anV0" }, + { "Kay", "S2F5" }, + { "keg", "a2Vn" }, + { "ken", "a2Vu" }, + { "key", "a2V5" }, + { "kid", "a2lk" }, + { "Kim", "S2lt" }, + { "kin", "a2lu" }, + { "kit", "a2l0" }, + { "k's", "aydz" }, + { "lab", "bGFi" }, + { "lac", "bGFj" }, + { "lad", "bGFk" }, + { "lag", "bGFn" }, + { "lam", "bGFt" }, + { "Lao", "TGFv" }, + { "lap", "bGFw" }, + { "law", "bGF3" }, + { "lax", "bGF4" }, + { "lay", "bGF5" }, + { "lea", "bGVh" }, + { "led", "bGVk" }, + { "lee", "bGVl" }, + { "leg", "bGVn" }, + { "Len", "TGVu" }, + { "Leo", "TGVv" }, + { "let", "bGV0" }, + { "Lev", "TGV2" }, + { "Lew", "TGV3" }, + { "lew", "bGV3" }, + { "lid", "bGlk" }, + { "lie", "bGll" }, + { "lim", "bGlt" }, + { "Lin", "TGlu" }, + { "lip", "bGlw" }, + { "lit", "bGl0" }, + { "Liz", "TGl6" }, + { "lob", "bG9i" }, + { "log", "bG9n" }, + { "lop", "bG9w" }, + { "Los", "TG9z" }, + { "lot", "bG90" }, + { "Lou", "TG91" }, + { "low", "bG93" }, + { "loy", "bG95" }, + { "l's", "bCdz" }, + { "LSI", "TFNJ" }, + { "Ltd", "THRk" }, + { "LTV", "TFRW" }, + { "lug", "bHVn" }, + { "lux", "bHV4" }, + { "lye", "bHll" }, + { "Mac", "TWFj" }, + { "mad", "bWFk" }, + { "Mae", "TWFl" }, + { "man", "bWFu" }, + { "Mao", "TWFv" }, + { "map", "bWFw" }, + { "mar", "bWFy" }, + { "mat", "bWF0" }, + { "maw", "bWF3" }, + { "Max", "TWF4" }, + { "max", "bWF4" }, + { "may", "bWF5" }, + { "MBA", "TUJB" }, + { "Meg", "TWVn" }, + { "Mel", "TWVs" }, + { "men", "bWVu" }, + { "met", "bWV0" }, + { "mew", "bWV3" }, + { "mid", "bWlk" }, + { "mig", "bWln" }, + { "min", "bWlu" }, + { "MIT", "TUlU" }, + { "mix", "bWl4" }, + { "mob", "bW9i" }, + { "Moe", "TW9l" }, + { "moo", "bW9v" }, + { "mop", "bW9w" }, + { "mot", "bW90" }, + { "mow", "bW93" }, + { "MPH", "TVBI" }, + { "Mrs", "TXJz" }, + { "m's", "bSdz" }, + { "mud", "bXVk" }, + { "mug", "bXVn" }, + { "mum", "bXVt" }, + { "nab", "bmFi" }, + { "nag", "bmFn" }, + { "Nan", "TmFu" }, + { "nap", "bmFw" }, + { "Nat", "TmF0" }, + { "nay", "bmF5" }, + { "NBC", "TkJD" }, + { "NBS", "TkJT" }, + { "NCO", "TkNP" }, + { "NCR", "TkNS" }, + { "Ned", "TmVk" }, + { "nee", "bmVl" }, + { "net", "bmV0" }, + { "new", "bmV3" }, + { "nib", "bmli" }, + { "NIH", "TklI" }, + { "nil", "bmls" }, + { "nip", "bmlw" }, + { "nit", "bml0" }, + { "NNE", "Tk5F" }, + { "NNW", "Tk5X" }, + { "nob", "bm9i" }, + { "nod", "bm9k" }, + { "non", "bm9u" }, + { "nor", "bm9y" }, + { "not", "bm90" }, + { "Nov", "Tm92" }, + { "now", "bm93" }, + { "NRC", "TlJD" }, + { "n's", "bidz" }, + { "NSF", "TlNG" }, + { "nun", "bnVu" }, + { "nut", "bnV0" }, + { "NYC", "TllD" }, + { "NYU", "TllV" }, + { "oaf", "b2Fm" }, + { "oak", "b2Fr" }, + { "oar", "b2Fy" }, + { "oat", "b2F0" }, + { "Oct", "T2N0" }, + { "odd", "b2Rk" }, + { "ode", "b2Rl" }, + { "off", "b2Zm" }, + { "oft", "b2Z0" }, + { "ohm", "b2ht" }, + { "oil", "b2ls" }, + { "old", "b2xk" }, + { "one", "b25l" }, + { "opt", "b3B0" }, + { "orb", "b3Ji" }, + { "ore", "b3Jl" }, + { "Orr", "T3Jy" }, + { "o's", "bydz" }, + { "Ott", "T3R0" }, + { "our", "b3Vy" }, + { "out", "b3V0" }, + { "ova", "b3Zh" }, + { "owe", "b3dl" }, + { "owl", "b3ds" }, + { "own", "b3du" }, + { "pad", "cGFk" }, + { "pal", "cGFs" }, + { "Pam", "UGFt" }, + { "pan", "cGFu" }, + { "pap", "cGFw" }, + { "par", "cGFy" }, + { "pat", "cGF0" }, + { "paw", "cGF3" }, + { "pax", "cGF4" }, + { "pay", "cGF5" }, + { "Paz", "UGF6" }, + { "PBS", "UEJT" }, + { "PDP", "UERQ" }, + { "pea", "cGVh" }, + { "pee", "cGVl" }, + { "peg", "cGVn" }, + { "pen", "cGVu" }, + { "pep", "cGVw" }, + { "per", "cGVy" }, + { "pet", "cGV0" }, + { "pew", "cGV3" }, + { "PhD", "UGhE" }, + { "phi", "cGhp" }, + { "pie", "cGll" }, + { "pig", "cGln" }, + { "pin", "cGlu" }, + { "pip", "cGlw" }, + { "pit", "cGl0" }, + { "ply", "cGx5" }, + { "pod", "cG9k" }, + { "Poe", "UG9l" }, + { "poi", "cG9p" }, + { "pol", "cG9s" }, + { "pop", "cG9w" }, + { "pot", "cG90" }, + { "pow", "cG93" }, + { "ppm", "cHBt" }, + { "pro", "cHJv" }, + { "pry", "cHJ5" }, + { "p's", "cCdz" }, + { "psi", "cHNp" }, + { "PTA", "UFRB" }, + { "pub", "cHVi" }, + { "PUC", "UFVD" }, + { "pug", "cHVn" }, + { "pun", "cHVu" }, + { "pup", "cHVw" }, + { "pus", "cHVz" }, + { "put", "cHV0" }, + { "PVC", "UFZD" }, + { "QED", "UUVE" }, + { "q's", "cSdz" }, + { "qua", "cXVh" }, + { "quo", "cXVv" }, + { "Rae", "UmFl" }, + { "rag", "cmFn" }, + { "raj", "cmFq" }, + { "ram", "cmFt" }, + { "ran", "cmFu" }, + { "rap", "cmFw" }, + { "rat", "cmF0" }, + { "raw", "cmF3" }, + { "ray", "cmF5" }, + { "RCA", "UkNB" }, + { "R&D", "UiZE" }, + { "reb", "cmVi" }, + { "red", "cmVk" }, + { "rep", "cmVw" }, + { "ret", "cmV0" }, + { "rev", "cmV2" }, + { "Rex", "UmV4" }, + { "rho", "cmhv" }, + { "rib", "cmli" }, + { "rid", "cmlk" }, + { "rig", "cmln" }, + { "rim", "cmlt" }, + { "Rio", "Umlv" }, + { "rip", "cmlw" }, + { "RNA", "Uk5B" }, + { "rob", "cm9i" }, + { "rod", "cm9k" }, + { "roe", "cm9l" }, + { "Ron", "Um9u" }, + { "rot", "cm90" }, + { "row", "cm93" }, + { "Roy", "Um95" }, + { "RPM", "UlBN" }, + { "r's", "cidz" }, + { "rub", "cnVi" }, + { "rue", "cnVl" }, + { "rug", "cnVn" }, + { "rum", "cnVt" }, + { "run", "cnVu" }, + { "rut", "cnV0" }, + { "rye", "cnll" }, + { "sac", "c2Fj" }, + { "sad", "c2Fk" }, + { "sag", "c2Fn" }, + { "Sal", "U2Fs" }, + { "Sam", "U2Ft" }, + { "San", "U2Fu" }, + { "Sao", "U2Fv" }, + { "sap", "c2Fw" }, + { "sat", "c2F0" }, + { "saw", "c2F3" }, + { "sax", "c2F4" }, + { "say", "c2F5" }, + { "Sci", "U2Np" }, + { "SCM", "U0NN" }, + { "sea", "c2Vh" }, + { "sec", "c2Vj" }, + { "see", "c2Vl" }, + { "sen", "c2Vu" }, + { "seq", "c2Vx" }, + { "set", "c2V0" }, + { "sew", "c2V3" }, + { "sex", "c2V4" }, + { "she", "c2hl" }, + { "Shu", "U2h1" }, + { "shy", "c2h5" }, + { "sib", "c2li" }, + { "sic", "c2lj" }, + { "sin", "c2lu" }, + { "sip", "c2lw" }, + { "sir", "c2ly" }, + { "sis", "c2lz" }, + { "sit", "c2l0" }, + { "six", "c2l4" }, + { "ski", "c2tp" }, + { "sky", "c2t5" }, + { "sly", "c2x5" }, + { "sob", "c29i" }, + { "Soc", "U29j" }, + { "sod", "c29k" }, + { "Sol", "U29s" }, + { "son", "c29u" }, + { "sop", "c29w" }, + { "sou", "c291" }, + { "sow", "c293" }, + { "soy", "c295" }, + { "spa", "c3Bh" }, + { "spy", "c3B5" }, + { "Sri", "U3Jp" }, + { "s's", "cydz" }, + { "SSE", "U1NF" }, + { "SST", "U1NU" }, + { "SSW", "U1NX" }, + { "Stu", "U3R1" }, + { "sub", "c3Vi" }, + { "sud", "c3Vk" }, + { "sue", "c3Vl" }, + { "sum", "c3Vt" }, + { "sun", "c3Vu" }, + { "sup", "c3Vw" }, + { "Sus", "U3Vz" }, + { "tab", "dGFi" }, + { "tad", "dGFk" }, + { "tag", "dGFn" }, + { "tam", "dGFt" }, + { "tan", "dGFu" }, + { "tao", "dGFv" }, + { "tap", "dGFw" }, + { "tar", "dGFy" }, + { "tat", "dGF0" }, + { "tau", "dGF1" }, + { "tax", "dGF4" }, + { "tea", "dGVh" }, + { "Ted", "VGVk" }, + { "ted", "dGVk" }, + { "tee", "dGVl" }, + { "Tel", "VGVs" }, + { "ten", "dGVu" }, + { "the", "dGhl" }, + { "thy", "dGh5" }, + { "tic", "dGlj" }, + { "tid", "dGlk" }, + { "tie", "dGll" }, + { "til", "dGls" }, + { "Tim", "VGlt" }, + { "tin", "dGlu" }, + { "tip", "dGlw" }, + { "tit", "dGl0" }, + { "TNT", "VE5U" }, + { "toe", "dG9l" }, + { "tog", "dG9n" }, + { "Tom", "VG9t" }, + { "ton", "dG9u" }, + { "too", "dG9v" }, + { "top", "dG9w" }, + { "tor", "dG9y" }, + { "tot", "dG90" }, + { "tow", "dG93" }, + { "toy", "dG95" }, + { "TRW", "VFJX" }, + { "try", "dHJ5" }, + { "t's", "dCdz" }, + { "TTL", "VFRM" }, + { "TTY", "VFRZ" }, + { "tub", "dHVi" }, + { "tug", "dHVn" }, + { "tum", "dHVt" }, + { "tun", "dHVu" }, + { "TVA", "VFZB" }, + { "TWA", "VFdB" }, + { "two", "dHdv" }, + { "TWX", "VFdY" }, + { "ugh", "dWdo" }, + { "UHF", "VUhG" }, + { "Uri", "VXJp" }, + { "urn", "dXJu" }, + { "U.S", "VS5T" }, + { "u's", "dSdz" }, + { "USA", "VVNB" }, + { "USC", "VVND" }, + { "use", "dXNl" }, + { "USN", "VVNO" }, + { "van", "dmFu" }, + { "vat", "dmF0" }, + { "vee", "dmVl" }, + { "vet", "dmV0" }, + { "vex", "dmV4" }, + { "VHF", "VkhG" }, + { "via", "dmlh" }, + { "vie", "dmll" }, + { "vii", "dmlp" }, + { "vis", "dmlz" }, + { "viz", "dml6" }, + { "von", "dm9u" }, + { "vow", "dm93" }, + { "v's", "didz" }, + { "WAC", "V0FD" }, + { "wad", "d2Fk" }, + { "wag", "d2Fn" }, + { "wah", "d2Fo" }, + { "wan", "d2Fu" }, + { "war", "d2Fy" }, + { "was", "d2Fz" }, + { "wax", "d2F4" }, + { "way", "d2F5" }, + { "web", "d2Vi" }, + { "wed", "d2Vk" }, + { "wee", "d2Vl" }, + { "Wei", "V2Vp" }, + { "wet", "d2V0" }, + { "who", "d2hv" }, + { "why", "d2h5" }, + { "wig", "d2ln" }, + { "win", "d2lu" }, + { "wit", "d2l0" }, + { "woe", "d29l" }, + { "wok", "d29r" }, + { "won", "d29u" }, + { "woo", "d29v" }, + { "wop", "d29w" }, + { "wow", "d293" }, + { "wry", "d3J5" }, + { "w's", "dydz" }, + { "x's", "eCdz" }, + { "yah", "eWFo" }, + { "yak", "eWFr" }, + { "yam", "eWFt" }, + { "yap", "eWFw" }, + { "yaw", "eWF3" }, + { "yea", "eWVh" }, + { "yen", "eWVu" }, + { "yet", "eWV0" }, + { "yin", "eWlu" }, + { "yip", "eWlw" }, + { "yon", "eW9u" }, + { "you", "eW91" }, + { "yow", "eW93" }, + { "y's", "eSdz" }, + { "yuh", "eXVo" }, + { "zag", "emFn" }, + { "Zan", "WmFu" }, + { "zap", "emFw" }, + { "Zen", "WmVu" }, + { "zig", "emln" }, + { "zip", "emlw" }, + { "Zoe", "Wm9l" }, + { "zoo", "em9v" }, + { "z's", "eidz" }, + /* the false rumors file */ + { "\"So when I die, the first thing I will see in heaven is a score list?\"", + "IlNvIHdoZW4gSSBkaWUsIHRoZSBmaXJzdCB0aGluZyBJIHdpbGwgc2VlIGluIGhlYXZlbiBpcyBhIHNjb3JlIGxpc3Q/Ig==" }, + { "1st Law of Hacking: leaving is much more difficult than entering.", + "MXN0IExhdyBvZiBIYWNraW5nOiBsZWF2aW5nIGlzIG11Y2ggbW9yZSBkaWZmaWN1bHQgdGhhbiBlbnRlcmluZy4=" }, + { "2nd Law of Hacking: first in, first out.", + "Mm5kIExhdyBvZiBIYWNraW5nOiBmaXJzdCBpbiwgZmlyc3Qgb3V0Lg==" }, + { "3rd Law of Hacking: the last blow counts most.", + "M3JkIExhdyBvZiBIYWNraW5nOiB0aGUgbGFzdCBibG93IGNvdW50cyBtb3N0Lg==" }, + { "4th Law of Hacking: you will find the exit at the entrance.", + "NHRoIExhdyBvZiBIYWNraW5nOiB5b3Ugd2lsbCBmaW5kIHRoZSBleGl0IGF0IHRoZSBlbnRyYW5jZS4=" }, + { "A chameleon imitating a mail daemon often delivers scrolls of fire.", + "QSBjaGFtZWxlb24gaW1pdGF0aW5nIGEgbWFpbCBkYWVtb24gb2Z0ZW4gZGVsaXZlcnMgc2Nyb2xscyBvZiBmaXJlLg==" }, + { "A cockatrice corpse is guaranteed to be untainted!", + "QSBjb2NrYXRyaWNlIGNvcnBzZSBpcyBndWFyYW50ZWVkIHRvIGJlIHVudGFpbnRlZCE=" }, + { "A dead cockatrice is just a dead lizard.", + "QSBkZWFkIGNvY2thdHJpY2UgaXMganVzdCBhIGRlYWQgbGl6YXJkLg==" }, + { "A dragon is just a snake that ate a scroll of fire.", + "QSBkcmFnb24gaXMganVzdCBhIHNuYWtlIHRoYXQgYXRlIGEgc2Nyb2xsIG9mIGZpcmUu" }, + { "A fading corridor enlightens your insight.", + "QSBmYWRpbmcgY29ycmlkb3IgZW5saWdodGVucyB5b3VyIGluc2lnaHQu" }, + { "A glowing potion is too hot to drink.", + "QSBnbG93aW5nIHBvdGlvbiBpcyB0b28gaG90IHRvIGRyaW5rLg==" }, + { "A good amulet may protect you against guards.", + "QSBnb29kIGFtdWxldCBtYXkgcHJvdGVjdCB5b3UgYWdhaW5zdCBndWFyZHMu" }, + { "A lizard corpse is a good thing to turn undead.", + "QSBsaXphcmQgY29ycHNlIGlzIGEgZ29vZCB0aGluZyB0byB0dXJuIHVuZGVhZC4=" }, + { "A long worm can be defined recursively. So how should you attack it?", + "QSBsb25nIHdvcm0gY2FuIGJlIGRlZmluZWQgcmVjdXJzaXZlbHkuIFNvIGhvdyBzaG91bGQgeW91IGF0dGFjayBpdD8=" }, + { "A monstrous mind is a toy forever.", + "QSBtb25zdHJvdXMgbWluZCBpcyBhIHRveSBmb3JldmVyLg==" }, + { "A nymph will be very pleased if you call her by her real name: Lorelei.", + "QSBueW1waCB3aWxsIGJlIHZlcnkgcGxlYXNlZCBpZiB5b3UgY2FsbCBoZXIgYnkgaGVyIHJlYWwgbmFtZTogTG9yZWxlaS4=" }, + { "A ring of dungeon master control is a great find.", + "QSByaW5nIG9mIGR1bmdlb24gbWFzdGVyIGNvbnRyb2wgaXMgYSBncmVhdCBmaW5kLg==" }, + { "A ring of extra ring finger is useless if not enchanted.", + "QSByaW5nIG9mIGV4dHJhIHJpbmcgZmluZ2VyIGlzIHVzZWxlc3MgaWYgbm90IGVuY2hhbnRlZC4=" }, + { "A rope may form a trail in a maze.", + "QSByb3BlIG1heSBmb3JtIGEgdHJhaWwgaW4gYSBtYXplLg==" }, + { "A staff may recharge if you drop it for awhile.", + "QSBzdGFmZiBtYXkgcmVjaGFyZ2UgaWYgeW91IGRyb3AgaXQgZm9yIGF3aGlsZS4=" }, + { "A visit to the Zoo is very educational; you meet interesting animals.", + "QSB2aXNpdCB0byB0aGUgWm9vIGlzIHZlcnkgZWR1Y2F0aW9uYWw7IHlvdSBtZWV0IGludGVyZXN0aW5nIGFuaW1hbHMu" }, + { "A wand of deaf is a more dangerous weapon than a wand of sheep.", + "QSB3YW5kIG9mIGRlYWYgaXMgYSBtb3JlIGRhbmdlcm91cyB3ZWFwb24gdGhhbiBhIHdhbmQgb2Ygc2hlZXAu" }, + { "A wand of vibration might bring the whole cave crashing about your ears.", + "QSB3YW5kIG9mIHZpYnJhdGlvbiBtaWdodCBicmluZyB0aGUgd2hvbGUgY2F2ZSBjcmFzaGluZyBhYm91dCB5b3VyIGVhcnMu" }, + { "A winner never quits. A quitter never wins.", + "QSB3aW5uZXIgbmV2ZXIgcXVpdHMuIEEgcXVpdHRlciBuZXZlciB3aW5zLg==" }, + { "A wish? Okay, make me a fortune cookie!", + "QSB3aXNoPyBPa2F5LCBtYWtlIG1lIGEgZm9ydHVuZSBjb29raWUh" }, + { "Afraid of mimics? Try to wear a ring of true seeing.", + "QWZyYWlkIG9mIG1pbWljcz8gVHJ5IHRvIHdlYXIgYSByaW5nIG9mIHRydWUgc2VlaW5nLg==" }, + { "All monsters are created evil, but some are more evil than others.", + "QWxsIG1vbnN0ZXJzIGFyZSBjcmVhdGVkIGV2aWwsIGJ1dCBzb21lIGFyZSBtb3JlIGV2aWwgdGhhbiBvdGhlcnMu" }, + { "Always attack a floating eye from behind!", + "QWx3YXlzIGF0dGFjayBhIGZsb2F0aW5nIGV5ZSBmcm9tIGJlaGluZCE=" }, + { "An elven cloak is always the height of fashion.", + "QW4gZWx2ZW4gY2xvYWsgaXMgYWx3YXlzIHRoZSBoZWlnaHQgb2YgZmFzaGlvbi4=" }, + { "Any small object that is accidentally dropped will hide under a larger object.", + "QW55IHNtYWxsIG9iamVjdCB0aGF0IGlzIGFjY2lkZW50YWxseSBkcm9wcGVkIHdpbGwgaGlkZSB1bmRlciBhIGxhcmdlciBvYmplY3Qu" }, + { "Balrogs do not appear above level 20.", + "QmFscm9ncyBkbyBub3QgYXBwZWFyIGFib3ZlIGxldmVsIDIwLg==" }, + { "Banana peels work especially well against Keystone Kops.", + "QmFuYW5hIHBlZWxzIHdvcmsgZXNwZWNpYWxseSB3ZWxsIGFnYWluc3QgS2V5c3RvbmUgS29wcy4=" }, + { "Be careful when eating bananas. Monsters might slip on the peels.", + "QmUgY2FyZWZ1bCB3aGVuIGVhdGluZyBiYW5hbmFzLiBNb25zdGVycyBtaWdodCBzbGlwIG9uIHRoZSBwZWVscy4=" }, + { "Better leave the dungeon; otherwise you might get hurt badly.", + "QmV0dGVyIGxlYXZlIHRoZSBkdW5nZW9uOyBvdGhlcndpc2UgeW91IG1pZ2h0IGdldCBodXJ0IGJhZGx5Lg==" }, + { "Beware of the potion of nitroglycerin -- it's not for the weak of heart.", + "QmV3YXJlIG9mIHRoZSBwb3Rpb24gb2Ygbml0cm9nbHljZXJpbiAtLSBpdCdzIG5vdCBmb3IgdGhlIHdlYWsgb2YgaGVhcnQu" }, + { "Beware: there's always a chance that your wand explodes as you try to zap it!", + "QmV3YXJlOiB0aGVyZSdzIGFsd2F5cyBhIGNoYW5jZSB0aGF0IHlvdXIgd2FuZCBleHBsb2RlcyBhcyB5b3UgdHJ5IHRvIHphcCBpdCE=" }, + { "Beyond the 23rd level lies a happy retirement in a room of your own.", + "QmV5b25kIHRoZSAyM3JkIGxldmVsIGxpZXMgYSBoYXBweSByZXRpcmVtZW50IGluIGEgcm9vbSBvZiB5b3VyIG93bi4=" }, + { "Changing your suit without dropping your sword? You must be kidding!", + "Q2hhbmdpbmcgeW91ciBzdWl0IHdpdGhvdXQgZHJvcHBpbmcgeW91ciBzd29yZD8gWW91IG11c3QgYmUga2lkZGluZyE=" }, + { "Cockatrices might turn themselves to stone faced with a mirror.", + "Q29ja2F0cmljZXMgbWlnaHQgdHVybiB0aGVtc2VsdmVzIHRvIHN0b25lIGZhY2VkIHdpdGggYSBtaXJyb3Iu" }, + { "Consumption of home-made food is strictly forbidden in this dungeon.", + "Q29uc3VtcHRpb24gb2YgaG9tZS1tYWRlIGZvb2QgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIGluIHRoaXMgZHVuZ2Vvbi4=" }, + { "Dark room? Your chance to develop your photographs!", + "RGFyayByb29tPyBZb3VyIGNoYW5jZSB0byBkZXZlbG9wIHlvdXIgcGhvdG9ncmFwaHMh" }, + { "Dark rooms are not *completely* dark: just wait and let your eyes adjust...", + "RGFyayByb29tcyBhcmUgbm90ICpjb21wbGV0ZWx5KiBkYXJrOiBqdXN0IHdhaXQgYW5kIGxldCB5b3VyIGV5ZXMgYWRqdXN0Li4u" }, + { "David London sez, \"Hey guys, *WIELD* a lizard corpse against a cockatrice!\"", + "RGF2aWQgTG9uZG9uIHNleiwgIkhleSBndXlzLCAqV0lFTEQqIGEgbGl6YXJkIGNvcnBzZSBhZ2FpbnN0IGEgY29ja2F0cmljZSEi" }, + { "Death is just life's way of telling you you've been fired.", + "RGVhdGggaXMganVzdCBsaWZlJ3Mgd2F5IG9mIHRlbGxpbmcgeW91IHlvdSd2ZSBiZWVuIGZpcmVkLg==" }, + { "Demi-gods don't need any help from the gods.", + "RGVtaS1nb2RzIGRvbid0IG5lZWQgYW55IGhlbHAgZnJvbSB0aGUgZ29kcy4=" }, + { "Demons *HATE* Priests and Priestesses.", + "RGVtb25zICpIQVRFKiBQcmllc3RzIGFuZCBQcmllc3Rlc3Nlcy4=" }, + { "Didn't you forget to pay?", + "RGlkbid0IHlvdSBmb3JnZXQgdG8gcGF5Pw==" }, + { "Didn't your mother tell you not to eat food off the floor?", + "RGlkbid0IHlvdXIgbW90aGVyIHRlbGwgeW91IG5vdCB0byBlYXQgZm9vZCBvZmYgdGhlIGZsb29yPw==" }, + { "Direct a direct hit on your direct opponent, directing in the right direction.", + "RGlyZWN0IGEgZGlyZWN0IGhpdCBvbiB5b3VyIGRpcmVjdCBvcHBvbmVudCwgZGlyZWN0aW5nIGluIHRoZSByaWdodCBkaXJlY3Rpb24u" }, + { "Do you want to make more money? Sure, we all do! Join the Fort Ludios guard!", + "RG8geW91IHdhbnQgdG8gbWFrZSBtb3JlIG1vbmV5PyBTdXJlLCB3ZSBhbGwgZG8hIEpvaW4gdGhlIEZvcnQgTHVkaW9zIGd1YXJkIQ==" }, + { "Don't eat too much: you might start hiccoughing!", + "RG9uJ3QgZWF0IHRvbyBtdWNoOiB5b3UgbWlnaHQgc3RhcnQgaGljY291Z2hpbmch" }, + { "Don't play hack at your work; your boss might hit you!", + "RG9uJ3QgcGxheSBoYWNrIGF0IHlvdXIgd29yazsgeW91ciBib3NzIG1pZ2h0IGhpdCB5b3Uh" }, + { "Don't tell a soul you found a secret door, otherwise it isn't a secret anymore.", + "RG9uJ3QgdGVsbCBhIHNvdWwgeW91IGZvdW5kIGEgc2VjcmV0IGRvb3IsIG90aGVyd2lzZSBpdCBpc24ndCBhIHNlY3JldCBhbnltb3JlLg==" }, + { "Drinking potions of booze may land you in jail if you are under 21.", + "RHJpbmtpbmcgcG90aW9ucyBvZiBib296ZSBtYXkgbGFuZCB5b3UgaW4gamFpbCBpZiB5b3UgYXJlIHVuZGVyIDIxLg==" }, + { "Drop your vanity and get rid of your jewels! Pickpockets about!", + "RHJvcCB5b3VyIHZhbml0eSBhbmQgZ2V0IHJpZCBvZiB5b3VyIGpld2VscyEgUGlja3BvY2tldHMgYWJvdXQh" }, + { "Eat 10 cloves of garlic and keep all humans at a two-square distance.", + "RWF0IDEwIGNsb3ZlcyBvZiBnYXJsaWMgYW5kIGtlZXAgYWxsIGh1bWFucyBhdCBhIHR3by1zcXVhcmUgZGlzdGFuY2Uu" }, + { "Eels hide under mud. Use a unicorn to clear the water and make them visible.", + "RWVscyBoaWRlIHVuZGVyIG11ZC4gVXNlIGEgdW5pY29ybiB0byBjbGVhciB0aGUgd2F0ZXIgYW5kIG1ha2UgdGhlbSB2aXNpYmxlLg==" }, + { "Engrave your wishes with a wand of wishing.", + "RW5ncmF2ZSB5b3VyIHdpc2hlcyB3aXRoIGEgd2FuZCBvZiB3aXNoaW5nLg==" }, + { "Eventually you will come to admire the swift elegance of a retreating nymph.", + "RXZlbnR1YWxseSB5b3Ugd2lsbCBjb21lIHRvIGFkbWlyZSB0aGUgc3dpZnQgZWxlZ2FuY2Ugb2YgYSByZXRyZWF0aW5nIG55bXBoLg==" }, + { "Ever heard hissing outside? I *knew* you hadn't!", + "RXZlciBoZWFyZCBoaXNzaW5nIG91dHNpZGU/IEkgKmtuZXcqIHlvdSBoYWRuJ3Qh" }, + { "Ever lifted a dragon corpse?", + "RXZlciBsaWZ0ZWQgYSBkcmFnb24gY29ycHNlPw==" }, + { "Ever seen a leocrotta dancing the tengu?", + "RXZlciBzZWVuIGEgbGVvY3JvdHRhIGRhbmNpbmcgdGhlIHRlbmd1Pw==" }, + { "Ever seen your weapon glow plaid?", + "RXZlciBzZWVuIHlvdXIgd2VhcG9uIGdsb3cgcGxhaWQ/" }, + { "Ever tamed a shopkeeper?", + "RXZlciB0YW1lZCBhIHNob3BrZWVwZXI/" }, + { "Ever tried digging through a Vault Guard?", + "RXZlciB0cmllZCBkaWdnaW5nIHRocm91Z2ggYSBWYXVsdCBHdWFyZD8=" }, + { "Ever tried enchanting a rope?", + "RXZlciB0cmllZCBlbmNoYW50aW5nIGEgcm9wZT8=" }, + { "Floating eyes can't stand Hawaiian shirts.", + "RmxvYXRpbmcgZXllcyBjYW4ndCBzdGFuZCBIYXdhaWlhbiBzaGlydHMu" }, + { "For any remedy there is a misery.", + "Rm9yIGFueSByZW1lZHkgdGhlcmUgaXMgYSBtaXNlcnku" }, + { "Giant bats turn into giant vampires.", + "R2lhbnQgYmF0cyB0dXJuIGludG8gZ2lhbnQgdmFtcGlyZXMu" }, + { "Good day for overcoming obstacles. Try a steeplechase.", + "R29vZCBkYXkgZm9yIG92ZXJjb21pbmcgb2JzdGFjbGVzLiBUcnkgYSBzdGVlcGxlY2hhc2Uu" }, + { "Half Moon tonight. (At least it's better than no Moon at all.)", + "SGFsZiBNb29uIHRvbmlnaHQuIChBdCBsZWFzdCBpdCdzIGJldHRlciB0aGFuIG5vIE1vb24gYXQgYWxsLik=" }, + { "Help! I'm being held prisoner in a fortune cookie factory!", + "SGVscCEgSSdtIGJlaW5nIGhlbGQgcHJpc29uZXIgaW4gYSBmb3J0dW5lIGNvb2tpZSBmYWN0b3J5IQ==" }, + { "Housecats have nine lives, kittens only one.", + "SG91c2VjYXRzIGhhdmUgbmluZSBsaXZlcywga2l0dGVucyBvbmx5IG9uZS4=" }, + { "How long can you tread water?", + "SG93IGxvbmcgY2FuIHlvdSB0cmVhZCB3YXRlcj8=" }, + { "Hungry? There is an abundance of food on the next level.", + "SHVuZ3J5PyBUaGVyZSBpcyBhbiBhYnVuZGFuY2Ugb2YgZm9vZCBvbiB0aGUgbmV4dCBsZXZlbC4=" }, + { "I guess you've never hit a mail daemon with the Amulet of Yendor...", + "SSBndWVzcyB5b3UndmUgbmV2ZXIgaGl0IGEgbWFpbCBkYWVtb24gd2l0aCB0aGUgQW11bGV0IG9mIFllbmRvci4uLg==" }, + { "If you are the shopkeeper, you can take things for free.", + "SWYgeW91IGFyZSB0aGUgc2hvcGtlZXBlciwgeW91IGNhbiB0YWtlIHRoaW5ncyBmb3IgZnJlZS4=" }, + { "If you can't learn to do it well, learn to enjoy doing it badly.", + "SWYgeW91IGNhbid0IGxlYXJuIHRvIGRvIGl0IHdlbGwsIGxlYXJuIHRvIGVuam95IGRvaW5nIGl0IGJhZGx5Lg==" }, + { "If you thought the Wizard was bad, just wait till you meet the Warlord!", + "SWYgeW91IHRob3VnaHQgdGhlIFdpemFyZCB3YXMgYmFkLCBqdXN0IHdhaXQgdGlsbCB5b3UgbWVldCB0aGUgV2FybG9yZCE=" }, + { "If you turn blind, don't expect your dog to be turned into a seeing-eye dog.", + "SWYgeW91IHR1cm4gYmxpbmQsIGRvbid0IGV4cGVjdCB5b3VyIGRvZyB0byBiZSB0dXJuZWQgaW50byBhIHNlZWluZy1leWUgZG9nLg==" }, + { "If you want to feel great, you must eat something real big.", + "SWYgeW91IHdhbnQgdG8gZmVlbCBncmVhdCwgeW91IG11c3QgZWF0IHNvbWV0aGluZyByZWFsIGJpZy4=" }, + { "If you want to float, you'd better eat a floating eye.", + "SWYgeW91IHdhbnQgdG8gZmxvYXQsIHlvdSdkIGJldHRlciBlYXQgYSBmbG9hdGluZyBleWUu" }, + { "If your ghost kills a player, it increases your score.", + "SWYgeW91ciBnaG9zdCBraWxscyBhIHBsYXllciwgaXQgaW5jcmVhc2VzIHlvdXIgc2NvcmUu" }, + { "Increase mindpower: Tame your own ghost!", + "SW5jcmVhc2UgbWluZHBvd2VyOiBUYW1lIHlvdXIgb3duIGdob3N0IQ==" }, + { "It furthers one to see the great man.", + "SXQgZnVydGhlcnMgb25lIHRvIHNlZSB0aGUgZ3JlYXQgbWFuLg==" }, + { "It's easy to overlook a monster in a wood.", + "SXQncyBlYXN5IHRvIG92ZXJsb29rIGEgbW9uc3RlciBpbiBhIHdvb2Qu" }, + { "Just below any trapdoor there may be another one. Just keep falling!", + "SnVzdCBiZWxvdyBhbnkgdHJhcGRvb3IgdGhlcmUgbWF5IGJlIGFub3RoZXIgb25lLiBKdXN0IGtlZXAgZmFsbGluZyE=" }, + { "Katanas are very sharp; watch you don't cut yourself.", + "S2F0YW5hcyBhcmUgdmVyeSBzaGFycDsgd2F0Y2ggeW91IGRvbid0IGN1dCB5b3Vyc2VsZi4=" }, + { "Keep a clear mind: quaff clear potions.", + "S2VlcCBhIGNsZWFyIG1pbmQ6IHF1YWZmIGNsZWFyIHBvdGlvbnMu" }, + { "Kicking the terminal doesn't hurt the monsters.", + "S2lja2luZyB0aGUgdGVybWluYWwgZG9lc24ndCBodXJ0IHRoZSBtb25zdGVycy4=" }, + { "Killer bees keep appearing till you kill their queen.", + "S2lsbGVyIGJlZXMga2VlcCBhcHBlYXJpbmcgdGlsbCB5b3Uga2lsbCB0aGVpciBxdWVlbi4=" }, + { "Killer bunnies can be tamed with carrots only.", + "S2lsbGVyIGJ1bm5pZXMgY2FuIGJlIHRhbWVkIHdpdGggY2Fycm90cyBvbmx5Lg==" }, + { "Latest news? Put `rec.games.roguelike.nethack' in your .newsrc!", + "TGF0ZXN0IG5ld3M/IFB1dCBgcmVjLmdhbWVzLnJvZ3VlbGlrZS5uZXRoYWNrJyBpbiB5b3VyIC5uZXdzcmMh" }, + { "Learn how to spell. Play NetHack!", + "TGVhcm4gaG93IHRvIHNwZWxsLiBQbGF5IE5ldEhhY2sh" }, + { "Leprechauns hide their gold in a secret room.", + "TGVwcmVjaGF1bnMgaGlkZSB0aGVpciBnb2xkIGluIGEgc2VjcmV0IHJvb20u" }, + { "Let your fingers do the walking on the yulkjhnb keys.", + "TGV0IHlvdXIgZmluZ2VycyBkbyB0aGUgd2Fsa2luZyBvbiB0aGUgeXVsa2pobmIga2V5cy4=" }, + { "Let's face it: this time you're not going to win.", + "TGV0J3MgZmFjZSBpdDogdGhpcyB0aW1lIHlvdSdyZSBub3QgZ29pbmcgdG8gd2luLg==" }, + { "Let's have a party, drink a lot of booze.", + "TGV0J3MgaGF2ZSBhIHBhcnR5LCBkcmluayBhIGxvdCBvZiBib296ZS4=" }, + { "Liquor sellers do not drink; they hate to see you twice.", + "TGlxdW9yIHNlbGxlcnMgZG8gbm90IGRyaW5rOyB0aGV5IGhhdGUgdG8gc2VlIHlvdSB0d2ljZS4=" }, + { "Lunar eclipse tonight. May as well quit now!", + "THVuYXIgZWNsaXBzZSB0b25pZ2h0LiBNYXkgYXMgd2VsbCBxdWl0IG5vdyE=" }, + { "Meeting your own ghost decreases your luck considerably!", + "TWVldGluZyB5b3VyIG93biBnaG9zdCBkZWNyZWFzZXMgeW91ciBsdWNrIGNvbnNpZGVyYWJseSE=" }, + { "Money to invest? Take it to the local branch of the Magic Memory Vault!", + "TW9uZXkgdG8gaW52ZXN0PyBUYWtlIGl0IHRvIHRoZSBsb2NhbCBicmFuY2ggb2YgdGhlIE1hZ2ljIE1lbW9yeSBWYXVsdCE=" }, + { "Monsters come from nowhere to hit you everywhere.", + "TW9uc3RlcnMgY29tZSBmcm9tIG5vd2hlcmUgdG8gaGl0IHlvdSBldmVyeXdoZXJlLg==" }, + { "Monsters sleep because you are boring, not because they ever get tired.", + "TW9uc3RlcnMgc2xlZXAgYmVjYXVzZSB5b3UgYXJlIGJvcmluZywgbm90IGJlY2F1c2UgdGhleSBldmVyIGdldCB0aXJlZC4=" }, + { "Most monsters prefer minced meat. That's why they are hitting you!", + "TW9zdCBtb25zdGVycyBwcmVmZXIgbWluY2VkIG1lYXQuIFRoYXQncyB3aHkgdGhleSBhcmUgaGl0dGluZyB5b3Uh" }, + { "Most of the bugs in NetHack are on the floor.", + "TW9zdCBvZiB0aGUgYnVncyBpbiBOZXRIYWNrIGFyZSBvbiB0aGUgZmxvb3Iu" }, + { "Much ado Nothing Happens.", + "TXVjaCBhZG8gTm90aGluZyBIYXBwZW5zLg==" }, + { "Multi-player NetHack is a myth.", + "TXVsdGktcGxheWVyIE5ldEhhY2sgaXMgYSBteXRoLg==" }, + { "NetHack is addictive. Too late, you're already hooked.", + "TmV0SGFjayBpcyBhZGRpY3RpdmUuIFRvbyBsYXRlLCB5b3UncmUgYWxyZWFkeSBob29rZWQu" }, + { "Never ask a shopkeeper for a price list.", + "TmV2ZXIgYXNrIGEgc2hvcGtlZXBlciBmb3IgYSBwcmljZSBsaXN0Lg==" }, + { "Never burn a tree, unless you like getting whacked with a +5 shovel.", + "TmV2ZXIgYnVybiBhIHRyZWUsIHVubGVzcyB5b3UgbGlrZSBnZXR0aW5nIHdoYWNrZWQgd2l0aCBhICs1IHNob3ZlbC4=" }, + { "Never eat with glowing hands!", + "TmV2ZXIgZWF0IHdpdGggZ2xvd2luZyBoYW5kcyE=" }, + { "Never mind the monsters hitting you: they just replace the charwomen.", + "TmV2ZXIgbWluZCB0aGUgbW9uc3RlcnMgaGl0dGluZyB5b3U6IHRoZXkganVzdCByZXBsYWNlIHRoZSBjaGFyd29tZW4u" }, + { "Never play leapfrog with a unicorn.", + "TmV2ZXIgcGxheSBsZWFwZnJvZyB3aXRoIGEgdW5pY29ybi4=" }, + { "Never step on a cursed engraving.", + "TmV2ZXIgc3RlcCBvbiBhIGN1cnNlZCBlbmdyYXZpbmcu" }, + { "Never swim with a camera: there's nothing to take pictures of.", + "TmV2ZXIgc3dpbSB3aXRoIGEgY2FtZXJhOiB0aGVyZSdzIG5vdGhpbmcgdG8gdGFrZSBwaWN0dXJlcyBvZi4=" }, + { "Never teach your pet rust monster to fetch.", + "TmV2ZXIgdGVhY2ggeW91ciBwZXQgcnVzdCBtb25zdGVyIHRvIGZldGNoLg==" }, + { "Never trust a random generator in magic fields.", + "TmV2ZXIgdHJ1c3QgYSByYW5kb20gZ2VuZXJhdG9yIGluIG1hZ2ljIGZpZWxkcy4=" }, + { "Never use a wand of death.", + "TmV2ZXIgdXNlIGEgd2FuZCBvZiBkZWF0aC4=" }, + { "No level contains two shops. The maze is no level. So...", + "Tm8gbGV2ZWwgY29udGFpbnMgdHdvIHNob3BzLiBUaGUgbWF6ZSBpcyBubyBsZXZlbC4gU28uLi4=" }, + { "No part of this fortune may be reproduced, stored in a retrieval system, ...", + "Tm8gcGFydCBvZiB0aGlzIGZvcnR1bmUgbWF5IGJlIHJlcHJvZHVjZWQsIHN0b3JlZCBpbiBhIHJldHJpZXZhbCBzeXN0ZW0sIC4uLg==" }, + { "Not all rumors are as misleading as this one.", + "Tm90IGFsbCBydW1vcnMgYXJlIGFzIG1pc2xlYWRpbmcgYXMgdGhpcyBvbmUu" }, + { "Nymphs and nurses like beautiful rings.", + "TnltcGhzIGFuZCBudXJzZXMgbGlrZSBiZWF1dGlmdWwgcmluZ3Mu" }, + { "Nymphs are blondes. Are you a gentleman?", + "TnltcGhzIGFyZSBibG9uZGVzLiBBcmUgeW91IGEgZ2VudGxlbWFuPw==" }, + { "Offering a unicorn a worthless piece of glass might prove to be fatal!", + "T2ZmZXJpbmcgYSB1bmljb3JuIGEgd29ydGhsZXNzIHBpZWNlIG9mIGdsYXNzIG1pZ2h0IHByb3ZlIHRvIGJlIGZhdGFsIQ==" }, + { "Old hackers never die: young ones do.", + "T2xkIGhhY2tlcnMgbmV2ZXIgZGllOiB5b3VuZyBvbmVzIGRvLg==" }, + { "One has to leave shops before closing time.", + "T25lIGhhcyB0byBsZWF2ZSBzaG9wcyBiZWZvcmUgY2xvc2luZyB0aW1lLg==" }, + { "One homunculus a day keeps the doctor away.", + "T25lIGhvbXVuY3VsdXMgYSBkYXkga2VlcHMgdGhlIGRvY3RvciBhd2F5Lg==" }, + { "One level further down somebody is getting killed, right now.", + "T25lIGxldmVsIGZ1cnRoZXIgZG93biBzb21lYm9keSBpcyBnZXR0aW5nIGtpbGxlZCwgcmlnaHQgbm93Lg==" }, + { "Only a wizard can use a magic whistle.", + "T25seSBhIHdpemFyZCBjYW4gdXNlIGEgbWFnaWMgd2hpc3RsZS4=" }, + { "Only adventurers of evil alignment think of killing their dog.", + "T25seSBhZHZlbnR1cmVycyBvZiBldmlsIGFsaWdubWVudCB0aGluayBvZiBraWxsaW5nIHRoZWlyIGRvZy4=" }, + { "Only chaotic evils kill sleeping monsters.", + "T25seSBjaGFvdGljIGV2aWxzIGtpbGwgc2xlZXBpbmcgbW9uc3RlcnMu" }, + { "Only real trappers escape traps.", + "T25seSByZWFsIHRyYXBwZXJzIGVzY2FwZSB0cmFwcy4=" }, + { "Only real wizards can write scrolls.", + "T25seSByZWFsIHdpemFyZHMgY2FuIHdyaXRlIHNjcm9sbHMu" }, + { "Operation OVERKILL has started now.", + "T3BlcmF0aW9uIE9WRVJLSUxMIGhhcyBzdGFydGVkIG5vdy4=" }, + { "PLEASE ignore previous rumor.", + "UExFQVNFIGlnbm9yZSBwcmV2aW91cyBydW1vci4=" }, + { "Polymorph into an ettin; meet your opponents face to face to face.", + "UG9seW1vcnBoIGludG8gYW4gZXR0aW47IG1lZXQgeW91ciBvcHBvbmVudHMgZmFjZSB0byBmYWNlIHRvIGZhY2Uu" }, + { "Praying will frighten demons.", + "UHJheWluZyB3aWxsIGZyaWdodGVuIGRlbW9ucy4=" }, + { "Row (3x) that boat gently down the stream, Charon (4x), death is but a dream.", + "Um93ICgzeCkgdGhhdCBib2F0IGdlbnRseSBkb3duIHRoZSBzdHJlYW0sIENoYXJvbiAoNHgpLCBkZWF0aCBpcyBidXQgYSBkcmVhbS4=" }, + { "Running is good for your legs.", + "UnVubmluZyBpcyBnb29kIGZvciB5b3VyIGxlZ3Mu" }, + { "Screw up your courage! You've screwed up everything else.", + "U2NyZXcgdXAgeW91ciBjb3VyYWdlISBZb3UndmUgc2NyZXdlZCB1cCBldmVyeXRoaW5nIGVsc2Uu" }, + { "Seepage? Leaky pipes? Rising damp? Summon the plumber!", + "U2VlcGFnZT8gTGVha3kgcGlwZXM/IFJpc2luZyBkYW1wPyBTdW1tb24gdGhlIHBsdW1iZXIh" }, + { "Segmentation fault (core dumped).", + "U2VnbWVudGF0aW9uIGZhdWx0IChjb3JlIGR1bXBlZCku" }, + { "Shopkeepers sometimes die from old age.", + "U2hvcGtlZXBlcnMgc29tZXRpbWVzIGRpZSBmcm9tIG9sZCBhZ2Uu" }, + { "Some mazes (especially small ones) have no solutions, says man 6 maze.", + "U29tZSBtYXplcyAoZXNwZWNpYWxseSBzbWFsbCBvbmVzKSBoYXZlIG5vIHNvbHV0aW9ucywgc2F5cyBtYW4gNiBtYXplLg==" }, + { "Some questions the Sphynx asks just *don't* have any answers.", + "U29tZSBxdWVzdGlvbnMgdGhlIFNwaHlueCBhc2tzIGp1c3QgKmRvbid0KiBoYXZlIGFueSBhbnN3ZXJzLg==" }, + { "Sometimes \"mu\" is the answer.", + "U29tZXRpbWVzICJtdSIgaXMgdGhlIGFuc3dlci4=" }, + { "Sorry, no fortune this time. Better luck next cookie!", + "U29ycnksIG5vIGZvcnR1bmUgdGhpcyB0aW1lLiBCZXR0ZXIgbHVjayBuZXh0IGNvb2tpZSE=" }, + { "Spare your scrolls of make-edible until it's really necessary!", + "U3BhcmUgeW91ciBzY3JvbGxzIG9mIG1ha2UtZWRpYmxlIHVudGlsIGl0J3MgcmVhbGx5IG5lY2Vzc2FyeSE=" }, + { "Suddenly, the dungeon will collapse...", + "U3VkZGVubHksIHRoZSBkdW5nZW9uIHdpbGwgY29sbGFwc2UuLi4=" }, + { "Taming a mail daemon may cause a system security violation.", + "VGFtaW5nIGEgbWFpbCBkYWVtb24gbWF5IGNhdXNlIGEgc3lzdGVtIHNlY3VyaXR5IHZpb2xhdGlvbi4=" }, + { "The crowd was so tough, the Stooges won't play the Dungeon anymore, nyuk nyuk.", + "VGhlIGNyb3dkIHdhcyBzbyB0b3VnaCwgdGhlIFN0b29nZXMgd29uJ3QgcGxheSB0aGUgRHVuZ2VvbiBhbnltb3JlLCBueXVrIG55dWsu" }, + { "The leprechauns hide their treasure in a small hidden room.", + "VGhlIGxlcHJlY2hhdW5zIGhpZGUgdGhlaXIgdHJlYXN1cmUgaW4gYSBzbWFsbCBoaWRkZW4gcm9vbS4=" }, + { "The longer the wand the better.", + "VGhlIGxvbmdlciB0aGUgd2FuZCB0aGUgYmV0dGVyLg==" }, + { "The magic word is \"XYZZY\".", + "VGhlIG1hZ2ljIHdvcmQgaXMgIlhZWlpZIi4=" }, + { "The meek shall inherit your bones files.", + "VGhlIG1lZWsgc2hhbGwgaW5oZXJpdCB5b3VyIGJvbmVzIGZpbGVzLg==" }, + { "The mines are dark and deep, and I have levels to go before I sleep.", + "VGhlIG1pbmVzIGFyZSBkYXJrIGFuZCBkZWVwLCBhbmQgSSBoYXZlIGxldmVscyB0byBnbyBiZWZvcmUgSSBzbGVlcC4=" }, + { "The use of dynamite is dangerous.", + "VGhlIHVzZSBvZiBkeW5hbWl0ZSBpcyBkYW5nZXJvdXMu" }, + { "There are no worms in the UNIX version.", + "VGhlcmUgYXJlIG5vIHdvcm1zIGluIHRoZSBVTklYIHZlcnNpb24u" }, + { "There is a trap on this level!", + "VGhlcmUgaXMgYSB0cmFwIG9uIHRoaXMgbGV2ZWwh" }, + { "They say that Demogorgon, Asmodeus, Orcus, Yeenoghu & Juiblex is no law firm.", + "VGhleSBzYXkgdGhhdCBEZW1vZ29yZ29uLCBBc21vZGV1cywgT3JjdXMsIFllZW5vZ2h1ICYgSnVpYmxleCBpcyBubyBsYXcgZmlybS4=" }, + { "They say that Geryon has an evil twin, beware!", + "VGhleSBzYXkgdGhhdCBHZXJ5b24gaGFzIGFuIGV2aWwgdHdpbiwgYmV3YXJlIQ==" }, + { "They say that Medusa would make a terrible pet.", + "VGhleSBzYXkgdGhhdCBNZWR1c2Egd291bGQgbWFrZSBhIHRlcnJpYmxlIHBldC4=" }, + { "They say that NetHack bugs are Seldon planned.", + "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGJ1Z3MgYXJlIFNlbGRvbiBwbGFubmVkLg==" }, + { "They say that NetHack comes in 256 flavors.", + "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGNvbWVzIGluIDI1NiBmbGF2b3JzLg==" }, + { "They say that NetHack is just a computer game.", + "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIGp1c3QgYSBjb21wdXRlciBnYW1lLg==" }, + { "They say that NetHack is more than just a computer game.", + "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIG1vcmUgdGhhbiBqdXN0IGEgY29tcHV0ZXIgZ2FtZS4=" }, + { "They say that NetHack is never what it used to be.", + "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIG5ldmVyIHdoYXQgaXQgdXNlZCB0byBiZS4=" }, + { "They say that a baby dragon is too small to hurt or help you.", + "VGhleSBzYXkgdGhhdCBhIGJhYnkgZHJhZ29uIGlzIHRvbyBzbWFsbCB0byBodXJ0IG9yIGhlbHAgeW91Lg==" }, + { "They say that a black pudding is simply a brown pudding gone bad.", + "VGhleSBzYXkgdGhhdCBhIGJsYWNrIHB1ZGRpbmcgaXMgc2ltcGx5IGEgYnJvd24gcHVkZGluZyBnb25lIGJhZC4=" }, + { "They say that a black sheep has 3 bags full of wool.", + "VGhleSBzYXkgdGhhdCBhIGJsYWNrIHNoZWVwIGhhcyAzIGJhZ3MgZnVsbCBvZiB3b29sLg==" }, + { "They say that a blank scroll is like a blank check.", + "VGhleSBzYXkgdGhhdCBhIGJsYW5rIHNjcm9sbCBpcyBsaWtlIGEgYmxhbmsgY2hlY2su" }, + { "They say that a cat named Morris has nine lives.", + "VGhleSBzYXkgdGhhdCBhIGNhdCBuYW1lZCBNb3JyaXMgaGFzIG5pbmUgbGl2ZXMu" }, + { "They say that a desperate shopper might pay any price in a shop.", + "VGhleSBzYXkgdGhhdCBhIGRlc3BlcmF0ZSBzaG9wcGVyIG1pZ2h0IHBheSBhbnkgcHJpY2UgaW4gYSBzaG9wLg==" }, + { "They say that a diamond dog is everybody's best friend.", + "VGhleSBzYXkgdGhhdCBhIGRpYW1vbmQgZG9nIGlzIGV2ZXJ5Ym9keSdzIGJlc3QgZnJpZW5kLg==" }, + { "They say that a dwarf lord can carry a pick-axe because his armor is light.", + "VGhleSBzYXkgdGhhdCBhIGR3YXJmIGxvcmQgY2FuIGNhcnJ5IGEgcGljay1heGUgYmVjYXVzZSBoaXMgYXJtb3IgaXMgbGlnaHQu" }, + { "They say that a floating eye can defeat Medusa.", + "VGhleSBzYXkgdGhhdCBhIGZsb2F0aW5nIGV5ZSBjYW4gZGVmZWF0IE1lZHVzYS4=" }, + { "They say that a fortune only has 1 line and you can't read between it.", + "VGhleSBzYXkgdGhhdCBhIGZvcnR1bmUgb25seSBoYXMgMSBsaW5lIGFuZCB5b3UgY2FuJ3QgcmVhZCBiZXR3ZWVuIGl0Lg==" }, + { "They say that a fortune only has 1 line, but you can read between it.", + "VGhleSBzYXkgdGhhdCBhIGZvcnR1bmUgb25seSBoYXMgMSBsaW5lLCBidXQgeW91IGNhbiByZWFkIGJldHdlZW4gaXQu" }, + { "They say that a fountain looks nothing like a regularly erupting geyser.", + "VGhleSBzYXkgdGhhdCBhIGZvdW50YWluIGxvb2tzIG5vdGhpbmcgbGlrZSBhIHJlZ3VsYXJseSBlcnVwdGluZyBnZXlzZXIu" }, + { "They say that a gold doubloon is worth more than its weight in gold.", + "VGhleSBzYXkgdGhhdCBhIGdvbGQgZG91Ymxvb24gaXMgd29ydGggbW9yZSB0aGFuIGl0cyB3ZWlnaHQgaW4gZ29sZC4=" }, + { "They say that a grid bug won't pay a shopkeeper for zapping you in a shop.", + "VGhleSBzYXkgdGhhdCBhIGdyaWQgYnVnIHdvbid0IHBheSBhIHNob3BrZWVwZXIgZm9yIHphcHBpbmcgeW91IGluIGEgc2hvcC4=" }, + { "They say that a gypsy could tell your fortune for a price.", + "VGhleSBzYXkgdGhhdCBhIGd5cHN5IGNvdWxkIHRlbGwgeW91ciBmb3J0dW5lIGZvciBhIHByaWNlLg==" }, + { "They say that a hacker named Alice once level teleported by using a mirror.", + "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBBbGljZSBvbmNlIGxldmVsIHRlbGVwb3J0ZWQgYnkgdXNpbmcgYSBtaXJyb3Iu" }, + { "They say that a hacker named David once slew a giant with a sling and a rock.", + "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBEYXZpZCBvbmNlIHNsZXcgYSBnaWFudCB3aXRoIGEgc2xpbmcgYW5kIGEgcm9jay4=" }, + { "They say that a hacker named Dorothy once rode a fog cloud to Oz.", + "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBEb3JvdGh5IG9uY2Ugcm9kZSBhIGZvZyBjbG91ZCB0byBPei4=" }, + { "They say that a hacker named Mary once lost a white sheep in the mazes.", + "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBNYXJ5IG9uY2UgbG9zdCBhIHdoaXRlIHNoZWVwIGluIHRoZSBtYXplcy4=" }, + { "They say that a helm of brilliance is not to be taken lightly.", + "VGhleSBzYXkgdGhhdCBhIGhlbG0gb2YgYnJpbGxpYW5jZSBpcyBub3QgdG8gYmUgdGFrZW4gbGlnaHRseS4=" }, + { "They say that a hot dog and a hell hound are the same thing.", + "VGhleSBzYXkgdGhhdCBhIGhvdCBkb2cgYW5kIGEgaGVsbCBob3VuZCBhcmUgdGhlIHNhbWUgdGhpbmcu" }, + { "They say that a lamp named Aladdin's Lamp contains a djinni with 3 wishes.", + "VGhleSBzYXkgdGhhdCBhIGxhbXAgbmFtZWQgQWxhZGRpbidzIExhbXAgY29udGFpbnMgYSBkamlubmkgd2l0aCAzIHdpc2hlcy4=" }, + { "They say that a large dog named Lassie will lead you to the amulet.", + "VGhleSBzYXkgdGhhdCBhIGxhcmdlIGRvZyBuYW1lZCBMYXNzaWUgd2lsbCBsZWFkIHlvdSB0byB0aGUgYW11bGV0Lg==" }, + { "They say that a long sword is not a light sword.", + "VGhleSBzYXkgdGhhdCBhIGxvbmcgc3dvcmQgaXMgbm90IGEgbGlnaHQgc3dvcmQu" }, + { "They say that a manes won't mince words with you.", + "VGhleSBzYXkgdGhhdCBhIG1hbmVzIHdvbid0IG1pbmNlIHdvcmRzIHdpdGggeW91Lg==" }, + { "They say that a mind is a terrible thing to waste.", + "VGhleSBzYXkgdGhhdCBhIG1pbmQgaXMgYSB0ZXJyaWJsZSB0aGluZyB0byB3YXN0ZS4=" }, + { "They say that a plain nymph will only wear a wire ring in one ear.", + "VGhleSBzYXkgdGhhdCBhIHBsYWluIG55bXBoIHdpbGwgb25seSB3ZWFyIGEgd2lyZSByaW5nIGluIG9uZSBlYXIu" }, + { "They say that a plumed hat could be a previously used crested helmet.", + "VGhleSBzYXkgdGhhdCBhIHBsdW1lZCBoYXQgY291bGQgYmUgYSBwcmV2aW91c2x5IHVzZWQgY3Jlc3RlZCBoZWxtZXQu" }, + { "They say that a potion of oil is difficult to grasp.", + "VGhleSBzYXkgdGhhdCBhIHBvdGlvbiBvZiBvaWwgaXMgZGlmZmljdWx0IHRvIGdyYXNwLg==" }, + { "They say that a potion of yogurt is a cancelled potion of sickness.", + "VGhleSBzYXkgdGhhdCBhIHBvdGlvbiBvZiB5b2d1cnQgaXMgYSBjYW5jZWxsZWQgcG90aW9uIG9mIHNpY2tuZXNzLg==" }, + { "They say that a purple worm is not a baby purple dragon.", + "VGhleSBzYXkgdGhhdCBhIHB1cnBsZSB3b3JtIGlzIG5vdCBhIGJhYnkgcHVycGxlIGRyYWdvbi4=" }, + { "They say that a quivering blob tastes different than a gelatinous cube.", + "VGhleSBzYXkgdGhhdCBhIHF1aXZlcmluZyBibG9iIHRhc3RlcyBkaWZmZXJlbnQgdGhhbiBhIGdlbGF0aW5vdXMgY3ViZS4=" }, + { "They say that a runed broadsword named Stormbringer attracts vortices.", + "VGhleSBzYXkgdGhhdCBhIHJ1bmVkIGJyb2Fkc3dvcmQgbmFtZWQgU3Rvcm1icmluZ2VyIGF0dHJhY3RzIHZvcnRpY2VzLg==" }, + { "They say that a scroll of summoning has other names.", + "VGhleSBzYXkgdGhhdCBhIHNjcm9sbCBvZiBzdW1tb25pbmcgaGFzIG90aGVyIG5hbWVzLg==" }, + { "They say that a shaman can bestow blessings but usually doesn't.", + "VGhleSBzYXkgdGhhdCBhIHNoYW1hbiBjYW4gYmVzdG93IGJsZXNzaW5ncyBidXQgdXN1YWxseSBkb2Vzbid0Lg==" }, + { "They say that a shaman will bless you for an eye of newt and wing of bat.", + "VGhleSBzYXkgdGhhdCBhIHNoYW1hbiB3aWxsIGJsZXNzIHlvdSBmb3IgYW4gZXllIG9mIG5ld3QgYW5kIHdpbmcgb2YgYmF0Lg==" }, + { "They say that a shimmering gold shield is not a polished silver shield.", + "VGhleSBzYXkgdGhhdCBhIHNoaW1tZXJpbmcgZ29sZCBzaGllbGQgaXMgbm90IGEgcG9saXNoZWQgc2lsdmVyIHNoaWVsZC4=" }, + { "They say that a spear will hit a neo-otyugh. (Do YOU know what that is?)", + "VGhleSBzYXkgdGhhdCBhIHNwZWFyIHdpbGwgaGl0IGEgbmVvLW90eXVnaC4gKERvIFlPVSBrbm93IHdoYXQgdGhhdCBpcz8p" }, + { "They say that a spotted dragon is the ultimate shape changer.", + "VGhleSBzYXkgdGhhdCBhIHNwb3R0ZWQgZHJhZ29uIGlzIHRoZSB1bHRpbWF0ZSBzaGFwZSBjaGFuZ2VyLg==" }, + { "They say that a stethoscope is no good if you can only hear your heartbeat.", + "VGhleSBzYXkgdGhhdCBhIHN0ZXRob3Njb3BlIGlzIG5vIGdvb2QgaWYgeW91IGNhbiBvbmx5IGhlYXIgeW91ciBoZWFydGJlYXQu" }, + { "They say that a succubus named Suzy will sometimes warn you of danger.", + "VGhleSBzYXkgdGhhdCBhIHN1Y2N1YnVzIG5hbWVkIFN1enkgd2lsbCBzb21ldGltZXMgd2FybiB5b3Ugb2YgZGFuZ2VyLg==" }, + { "They say that a wand of cancellation is not like a wand of polymorph.", + "VGhleSBzYXkgdGhhdCBhIHdhbmQgb2YgY2FuY2VsbGF0aW9uIGlzIG5vdCBsaWtlIGEgd2FuZCBvZiBwb2x5bW9ycGgu" }, + { "They say that a wood golem named Pinocchio would be easy to control.", + "VGhleSBzYXkgdGhhdCBhIHdvb2QgZ29sZW0gbmFtZWQgUGlub2NjaGlvIHdvdWxkIGJlIGVhc3kgdG8gY29udHJvbC4=" }, + { "They say that after killing a dragon it's time for a change of scenery.", + "VGhleSBzYXkgdGhhdCBhZnRlciBraWxsaW5nIGEgZHJhZ29uIGl0J3MgdGltZSBmb3IgYSBjaGFuZ2Ugb2Ygc2NlbmVyeS4=" }, + { "They say that an amulet of strangulation is worse than ring around the collar.", + "VGhleSBzYXkgdGhhdCBhbiBhbXVsZXQgb2Ygc3RyYW5ndWxhdGlvbiBpcyB3b3JzZSB0aGFuIHJpbmcgYXJvdW5kIHRoZSBjb2xsYXIu" }, + { "They say that an attic is the best place to hide your toys.", + "VGhleSBzYXkgdGhhdCBhbiBhdHRpYyBpcyB0aGUgYmVzdCBwbGFjZSB0byBoaWRlIHlvdXIgdG95cy4=" }, + { "They say that an axe named Cleaver once belonged to a hacker named Beaver.", + "VGhleSBzYXkgdGhhdCBhbiBheGUgbmFtZWQgQ2xlYXZlciBvbmNlIGJlbG9uZ2VkIHRvIGEgaGFja2VyIG5hbWVkIEJlYXZlci4=" }, + { "They say that an eye of newt and a wing of bat are double the trouble.", + "VGhleSBzYXkgdGhhdCBhbiBleWUgb2YgbmV3dCBhbmQgYSB3aW5nIG9mIGJhdCBhcmUgZG91YmxlIHRoZSB0cm91YmxlLg==" }, + { "They say that an incubus named Izzy sometimes makes women feel sensitive.", + "VGhleSBzYXkgdGhhdCBhbiBpbmN1YnVzIG5hbWVkIEl6enkgc29tZXRpbWVzIG1ha2VzIHdvbWVuIGZlZWwgc2Vuc2l0aXZlLg==" }, + { "They say that an opulent throne room is rarely a place to wish you'd be in.", + "VGhleSBzYXkgdGhhdCBhbiBvcHVsZW50IHRocm9uZSByb29tIGlzIHJhcmVseSBhIHBsYWNlIHRvIHdpc2ggeW91J2QgYmUgaW4u" }, + { "They say that an unlucky hacker once had a nose bleed at an altar and died.", + "VGhleSBzYXkgdGhhdCBhbiB1bmx1Y2t5IGhhY2tlciBvbmNlIGhhZCBhIG5vc2UgYmxlZWQgYXQgYW4gYWx0YXIgYW5kIGRpZWQu" }, + { "They say that and they say this but they never say never, never!", + "VGhleSBzYXkgdGhhdCBhbmQgdGhleSBzYXkgdGhpcyBidXQgdGhleSBuZXZlciBzYXkgbmV2ZXIsIG5ldmVyIQ==" }, + { "They say that any quantum mechanic knows that speed kills.", + "VGhleSBzYXkgdGhhdCBhbnkgcXVhbnR1bSBtZWNoYW5pYyBrbm93cyB0aGF0IHNwZWVkIGtpbGxzLg==" }, + { "They say that applying a unicorn horn means you've missed the point.", + "VGhleSBzYXkgdGhhdCBhcHBseWluZyBhIHVuaWNvcm4gaG9ybiBtZWFucyB5b3UndmUgbWlzc2VkIHRoZSBwb2ludC4=" }, + { "They say that blue stones are radioactive, beware.", + "VGhleSBzYXkgdGhhdCBibHVlIHN0b25lcyBhcmUgcmFkaW9hY3RpdmUsIGJld2FyZS4=" }, + { "They say that building a dungeon is a team effort.", + "VGhleSBzYXkgdGhhdCBidWlsZGluZyBhIGR1bmdlb24gaXMgYSB0ZWFtIGVmZm9ydC4=" }, + { "They say that chaotic characters never get a kick out of altars.", + "VGhleSBzYXkgdGhhdCBjaGFvdGljIGNoYXJhY3RlcnMgbmV2ZXIgZ2V0IGEga2ljayBvdXQgb2YgYWx0YXJzLg==" }, + { "They say that collapsing a dungeon often creates a panic.", + "VGhleSBzYXkgdGhhdCBjb2xsYXBzaW5nIGEgZHVuZ2VvbiBvZnRlbiBjcmVhdGVzIGEgcGFuaWMu" }, + { "They say that counting your eggs before they hatch shows that you care.", + "VGhleSBzYXkgdGhhdCBjb3VudGluZyB5b3VyIGVnZ3MgYmVmb3JlIHRoZXkgaGF0Y2ggc2hvd3MgdGhhdCB5b3UgY2FyZS4=" }, + { "They say that dipping a bag of tricks in a fountain won't make it an icebox.", + "VGhleSBzYXkgdGhhdCBkaXBwaW5nIGEgYmFnIG9mIHRyaWNrcyBpbiBhIGZvdW50YWluIHdvbid0IG1ha2UgaXQgYW4gaWNlYm94Lg==" }, + { "They say that dipping an eel and brown mold in hot water makes bouillabaisse.", + "VGhleSBzYXkgdGhhdCBkaXBwaW5nIGFuIGVlbCBhbmQgYnJvd24gbW9sZCBpbiBob3Qgd2F0ZXIgbWFrZXMgYm91aWxsYWJhaXNzZS4=" }, + { "They say that donating a doubloon is extremely pious charity.", + "VGhleSBzYXkgdGhhdCBkb25hdGluZyBhIGRvdWJsb29uIGlzIGV4dHJlbWVseSBwaW91cyBjaGFyaXR5Lg==" }, + { "They say that eating royal jelly attracts grizzly owlbears.", + "VGhleSBzYXkgdGhhdCBlYXRpbmcgcm95YWwgamVsbHkgYXR0cmFjdHMgZ3JpenpseSBvd2xiZWFycy4=" }, + { "They say that eggs, pancakes and juice are just a mundane breakfast.", + "VGhleSBzYXkgdGhhdCBlZ2dzLCBwYW5jYWtlcyBhbmQganVpY2UgYXJlIGp1c3QgYSBtdW5kYW5lIGJyZWFrZmFzdC4=" }, + { "They say that everyone knows why Medusa stands alone in the dark.", + "VGhleSBzYXkgdGhhdCBldmVyeW9uZSBrbm93cyB3aHkgTWVkdXNhIHN0YW5kcyBhbG9uZSBpbiB0aGUgZGFyay4=" }, + { "They say that everyone wanted rec.games.hack to undergo a name change.", + "VGhleSBzYXkgdGhhdCBldmVyeW9uZSB3YW50ZWQgcmVjLmdhbWVzLmhhY2sgdG8gdW5kZXJnbyBhIG5hbWUgY2hhbmdlLg==" }, + { "They say that finding a winning strategy is a deliberate move on your part.", + "VGhleSBzYXkgdGhhdCBmaW5kaW5nIGEgd2lubmluZyBzdHJhdGVneSBpcyBhIGRlbGliZXJhdGUgbW92ZSBvbiB5b3VyIHBhcnQu" }, + { "They say that finding worthless glass is worth something.", + "VGhleSBzYXkgdGhhdCBmaW5kaW5nIHdvcnRobGVzcyBnbGFzcyBpcyB3b3J0aCBzb21ldGhpbmcu" }, + { "They say that fortune cookies are food for thought.", + "VGhleSBzYXkgdGhhdCBmb3J0dW5lIGNvb2tpZXMgYXJlIGZvb2QgZm9yIHRob3VnaHQu" }, + { "They say that gold is only wasted on a pet dragon.", + "VGhleSBzYXkgdGhhdCBnb2xkIGlzIG9ubHkgd2FzdGVkIG9uIGEgcGV0IGRyYWdvbi4=" }, + { "They say that good things come to those that wait.", + "VGhleSBzYXkgdGhhdCBnb29kIHRoaW5ncyBjb21lIHRvIHRob3NlIHRoYXQgd2FpdC4=" }, + { "They say that greased objects will slip out of monsters' hands.", + "VGhleSBzYXkgdGhhdCBncmVhc2VkIG9iamVjdHMgd2lsbCBzbGlwIG91dCBvZiBtb25zdGVycycgaGFuZHMu" }, + { "They say that if you can't spell then you'll wish you had a spell book.", + "VGhleSBzYXkgdGhhdCBpZiB5b3UgY2FuJ3Qgc3BlbGwgdGhlbiB5b3UnbGwgd2lzaCB5b3UgaGFkIGEgc3BlbGwgYm9vay4=" }, + { "They say that if you live by the sword, you'll die by the sword.", + "VGhleSBzYXkgdGhhdCBpZiB5b3UgbGl2ZSBieSB0aGUgc3dvcmQsIHlvdSdsbCBkaWUgYnkgdGhlIHN3b3JkLg==" }, + { "They say that if you play like a monster you'll have a better game.", + "VGhleSBzYXkgdGhhdCBpZiB5b3UgcGxheSBsaWtlIGEgbW9uc3RlciB5b3UnbGwgaGF2ZSBhIGJldHRlciBnYW1lLg==" }, + { "They say that if you sleep with a demon you might awake with a headache.", + "VGhleSBzYXkgdGhhdCBpZiB5b3Ugc2xlZXAgd2l0aCBhIGRlbW9uIHlvdSBtaWdodCBhd2FrZSB3aXRoIGEgaGVhZGFjaGUu" }, + { "They say that if you step on a crack you could break your mother's back.", + "VGhleSBzYXkgdGhhdCBpZiB5b3Ugc3RlcCBvbiBhIGNyYWNrIHlvdSBjb3VsZCBicmVhayB5b3VyIG1vdGhlcidzIGJhY2su" }, + { "They say that if you're invisible you can still be heard!", + "VGhleSBzYXkgdGhhdCBpZiB5b3UncmUgaW52aXNpYmxlIHlvdSBjYW4gc3RpbGwgYmUgaGVhcmQh" }, + { "They say that if you're lucky you can feel the runes on a scroll.", + "VGhleSBzYXkgdGhhdCBpZiB5b3UncmUgbHVja3kgeW91IGNhbiBmZWVsIHRoZSBydW5lcyBvbiBhIHNjcm9sbC4=" }, + { "They say that in the big picture gold is only small change.", + "VGhleSBzYXkgdGhhdCBpbiB0aGUgYmlnIHBpY3R1cmUgZ29sZCBpcyBvbmx5IHNtYWxsIGNoYW5nZS4=" }, + { "They say that in the dungeon it's not what you know that really matters.", + "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiBpdCdzIG5vdCB3aGF0IHlvdSBrbm93IHRoYXQgcmVhbGx5IG1hdHRlcnMu" }, + { "They say that in the dungeon moon rocks are really dilithium crystals.", + "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiBtb29uIHJvY2tzIGFyZSByZWFsbHkgZGlsaXRoaXVtIGNyeXN0YWxzLg==" }, + { "They say that in the dungeon the boorish customer is never right.", + "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB0aGUgYm9vcmlzaCBjdXN0b21lciBpcyBuZXZlciByaWdodC4=" }, + { "They say that in the dungeon you don't need a watch to tell time.", + "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3UgZG9uJ3QgbmVlZCBhIHdhdGNoIHRvIHRlbGwgdGltZS4=" }, + { "They say that in the dungeon you need something old, new, burrowed and blue.", + "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3UgbmVlZCBzb21ldGhpbmcgb2xkLCBuZXcsIGJ1cnJvd2VkIGFuZCBibHVlLg==" }, + { "They say that in the dungeon you should always count your blessings.", + "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3Ugc2hvdWxkIGFsd2F5cyBjb3VudCB5b3VyIGJsZXNzaW5ncy4=" }, + { "They say that iron golem plate mail isn't worth wishing for.", + "VGhleSBzYXkgdGhhdCBpcm9uIGdvbGVtIHBsYXRlIG1haWwgaXNuJ3Qgd29ydGggd2lzaGluZyBmb3Iu" }, + { "They say that it takes four quarterstaffs to make one staff.", + "VGhleSBzYXkgdGhhdCBpdCB0YWtlcyBmb3VyIHF1YXJ0ZXJzdGFmZnMgdG8gbWFrZSBvbmUgc3RhZmYu" }, + { "They say that it's not over till the fat ladies sing.", + "VGhleSBzYXkgdGhhdCBpdCdzIG5vdCBvdmVyIHRpbGwgdGhlIGZhdCBsYWRpZXMgc2luZy4=" }, + { "They say that it's not over till the fat lady shouts `Off with its head'.", + "VGhleSBzYXkgdGhhdCBpdCdzIG5vdCBvdmVyIHRpbGwgdGhlIGZhdCBsYWR5IHNob3V0cyBgT2ZmIHdpdGggaXRzIGhlYWQnLg==" }, + { "They say that kicking a heavy statue is really a dumb move.", + "VGhleSBzYXkgdGhhdCBraWNraW5nIGEgaGVhdnkgc3RhdHVlIGlzIHJlYWxseSBhIGR1bWIgbW92ZS4=" }, + { "They say that kicking a valuable gem doesn't seem to make sense.", + "VGhleSBzYXkgdGhhdCBraWNraW5nIGEgdmFsdWFibGUgZ2VtIGRvZXNuJ3Qgc2VlbSB0byBtYWtlIHNlbnNlLg==" }, + { "They say that leprechauns know Latin and you should too.", + "VGhleSBzYXkgdGhhdCBsZXByZWNoYXVucyBrbm93IExhdGluIGFuZCB5b3Ugc2hvdWxkIHRvby4=" }, + { "They say that minotaurs get lost outside of the mazes.", + "VGhleSBzYXkgdGhhdCBtaW5vdGF1cnMgZ2V0IGxvc3Qgb3V0c2lkZSBvZiB0aGUgbWF6ZXMu" }, + { "They say that most trolls are born again.", + "VGhleSBzYXkgdGhhdCBtb3N0IHRyb2xscyBhcmUgYm9ybiBhZ2Fpbi4=" }, + { "They say that naming your cat Garfield will make you more attractive.", + "VGhleSBzYXkgdGhhdCBuYW1pbmcgeW91ciBjYXQgR2FyZmllbGQgd2lsbCBtYWtlIHlvdSBtb3JlIGF0dHJhY3RpdmUu" }, + { "They say that no one knows everything about everything in the dungeon.", + "VGhleSBzYXkgdGhhdCBubyBvbmUga25vd3MgZXZlcnl0aGluZyBhYm91dCBldmVyeXRoaW5nIGluIHRoZSBkdW5nZW9uLg==" }, + { "They say that no one plays NetHack just for the fun of it.", + "VGhleSBzYXkgdGhhdCBubyBvbmUgcGxheXMgTmV0SGFjayBqdXN0IGZvciB0aGUgZnVuIG9mIGl0Lg==" }, + { "They say that no one really subscribes to rec.games.roguelike.nethack.", + "VGhleSBzYXkgdGhhdCBubyBvbmUgcmVhbGx5IHN1YnNjcmliZXMgdG8gcmVjLmdhbWVzLnJvZ3VlbGlrZS5uZXRoYWNrLg==" }, + { "They say that no one will admit to starting a rumor.", + "VGhleSBzYXkgdGhhdCBubyBvbmUgd2lsbCBhZG1pdCB0byBzdGFydGluZyBhIHJ1bW9yLg==" }, + { "They say that nurses sometimes carry scalpels and never use them.", + "VGhleSBzYXkgdGhhdCBudXJzZXMgc29tZXRpbWVzIGNhcnJ5IHNjYWxwZWxzIGFuZCBuZXZlciB1c2UgdGhlbS4=" }, + { "They say that once you've met one wizard you've met them all.", + "VGhleSBzYXkgdGhhdCBvbmNlIHlvdSd2ZSBtZXQgb25lIHdpemFyZCB5b3UndmUgbWV0IHRoZW0gYWxsLg==" }, + { "They say that one troll is worth 10,000 newts.", + "VGhleSBzYXkgdGhhdCBvbmUgdHJvbGwgaXMgd29ydGggMTAsMDAwIG5ld3RzLg==" }, + { "They say that only David can find the zoo!", + "VGhleSBzYXkgdGhhdCBvbmx5IERhdmlkIGNhbiBmaW5kIHRoZSB6b28h" }, + { "They say that only angels play their harps for their pets.", + "VGhleSBzYXkgdGhhdCBvbmx5IGFuZ2VscyBwbGF5IHRoZWlyIGhhcnBzIGZvciB0aGVpciBwZXRzLg==" }, + { "They say that only big spenders carry gold.", + "VGhleSBzYXkgdGhhdCBvbmx5IGJpZyBzcGVuZGVycyBjYXJyeSBnb2xkLg==" }, + { "They say that orc shamans are healthy, wealthy and wise.", + "VGhleSBzYXkgdGhhdCBvcmMgc2hhbWFucyBhcmUgaGVhbHRoeSwgd2VhbHRoeSBhbmQgd2lzZS4=" }, + { "They say that playing NetHack is like walking into a death trap.", + "VGhleSBzYXkgdGhhdCBwbGF5aW5nIE5ldEhhY2sgaXMgbGlrZSB3YWxraW5nIGludG8gYSBkZWF0aCB0cmFwLg==" }, + { "They say that problem breathing is best treated by a proper diet.", + "VGhleSBzYXkgdGhhdCBwcm9ibGVtIGJyZWF0aGluZyBpcyBiZXN0IHRyZWF0ZWQgYnkgYSBwcm9wZXIgZGlldC4=" }, + { "They say that quaffing many potions of levitation can give you a headache.", + "VGhleSBzYXkgdGhhdCBxdWFmZmluZyBtYW55IHBvdGlvbnMgb2YgbGV2aXRhdGlvbiBjYW4gZ2l2ZSB5b3UgYSBoZWFkYWNoZS4=" }, + { "They say that queen bees get that way by eating royal jelly.", + "VGhleSBzYXkgdGhhdCBxdWVlbiBiZWVzIGdldCB0aGF0IHdheSBieSBlYXRpbmcgcm95YWwgamVsbHku" }, + { "They say that reading a scare monster scroll is the same as saying Elbereth.", + "VGhleSBzYXkgdGhhdCByZWFkaW5nIGEgc2NhcmUgbW9uc3RlciBzY3JvbGwgaXMgdGhlIHNhbWUgYXMgc2F5aW5nIEVsYmVyZXRoLg==" }, + { "They say that real hackers always are controlled.", + "VGhleSBzYXkgdGhhdCByZWFsIGhhY2tlcnMgYWx3YXlzIGFyZSBjb250cm9sbGVkLg==" }, + { "They say that real hackers never sleep.", + "VGhleSBzYXkgdGhhdCByZWFsIGhhY2tlcnMgbmV2ZXIgc2xlZXAu" }, + { "They say that shopkeepers are insured by Croesus himself!", + "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBhcmUgaW5zdXJlZCBieSBDcm9lc3VzIGhpbXNlbGYh" }, + { "They say that shopkeepers never carry more than 20 gold pieces, at night.", + "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBuZXZlciBjYXJyeSBtb3JlIHRoYW4gMjAgZ29sZCBwaWVjZXMsIGF0IG5pZ2h0Lg==" }, + { "They say that shopkeepers never sell blessed potions of invisibility.", + "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBuZXZlciBzZWxsIGJsZXNzZWQgcG90aW9ucyBvZiBpbnZpc2liaWxpdHku" }, + { "They say that soldiers wear kid gloves and silly helmets.", + "VGhleSBzYXkgdGhhdCBzb2xkaWVycyB3ZWFyIGtpZCBnbG92ZXMgYW5kIHNpbGx5IGhlbG1ldHMu" }, + { "They say that some Kops are on the take.", + "VGhleSBzYXkgdGhhdCBzb21lIEtvcHMgYXJlIG9uIHRoZSB0YWtlLg==" }, + { "They say that some guards' palms can be greased.", + "VGhleSBzYXkgdGhhdCBzb21lIGd1YXJkcycgcGFsbXMgY2FuIGJlIGdyZWFzZWQu" }, + { "They say that some monsters may kiss your boots to stop your drum playing.", + "VGhleSBzYXkgdGhhdCBzb21lIG1vbnN0ZXJzIG1heSBraXNzIHlvdXIgYm9vdHMgdG8gc3RvcCB5b3VyIGRydW0gcGxheWluZy4=" }, + { "They say that sometimes you can be the hit of the party when playing a horn.", + "VGhleSBzYXkgdGhhdCBzb21ldGltZXMgeW91IGNhbiBiZSB0aGUgaGl0IG9mIHRoZSBwYXJ0eSB3aGVuIHBsYXlpbmcgYSBob3JuLg==" }, + { "They say that the NetHack gods generally welcome your sacrifices.", + "VGhleSBzYXkgdGhhdCB0aGUgTmV0SGFjayBnb2RzIGdlbmVyYWxseSB3ZWxjb21lIHlvdXIgc2FjcmlmaWNlcy4=" }, + { "They say that the Three Rings are named Vilya, Nenya and Narya.", + "VGhleSBzYXkgdGhhdCB0aGUgVGhyZWUgUmluZ3MgYXJlIG5hbWVkIFZpbHlhLCBOZW55YSBhbmQgTmFyeWEu" }, + { "They say that the Wizard of Yendor has a death wish.", + "VGhleSBzYXkgdGhhdCB0aGUgV2l6YXJkIG9mIFllbmRvciBoYXMgYSBkZWF0aCB3aXNoLg==" }, + { "They say that the `hair of the dog' is sometimes an effective remedy.", + "VGhleSBzYXkgdGhhdCB0aGUgYGhhaXIgb2YgdGhlIGRvZycgaXMgc29tZXRpbWVzIGFuIGVmZmVjdGl2ZSByZW1lZHku" }, + { "They say that the best time to save your game is now before its too late.", + "VGhleSBzYXkgdGhhdCB0aGUgYmVzdCB0aW1lIHRvIHNhdmUgeW91ciBnYW1lIGlzIG5vdyBiZWZvcmUgaXRzIHRvbyBsYXRlLg==" }, + { "They say that the biggest obstacle in NetHack is your mind.", + "VGhleSBzYXkgdGhhdCB0aGUgYmlnZ2VzdCBvYnN0YWNsZSBpbiBOZXRIYWNrIGlzIHlvdXIgbWluZC4=" }, + { "They say that the gods are angry when they hit you with objects.", + "VGhleSBzYXkgdGhhdCB0aGUgZ29kcyBhcmUgYW5ncnkgd2hlbiB0aGV5IGhpdCB5b3Ugd2l0aCBvYmplY3RzLg==" }, + { "They say that the priesthood are specially favored by the gods.", + "VGhleSBzYXkgdGhhdCB0aGUgcHJpZXN0aG9vZCBhcmUgc3BlY2lhbGx5IGZhdm9yZWQgYnkgdGhlIGdvZHMu" }, + { "They say that the way to make a unicorn happy is to give it what it wants.", + "VGhleSBzYXkgdGhhdCB0aGUgd2F5IHRvIG1ha2UgYSB1bmljb3JuIGhhcHB5IGlzIHRvIGdpdmUgaXQgd2hhdCBpdCB3YW50cy4=" }, + { "They say that there are no black or white stones, only gray.", + "VGhleSBzYXkgdGhhdCB0aGVyZSBhcmUgbm8gYmxhY2sgb3Igd2hpdGUgc3RvbmVzLCBvbmx5IGdyYXku" }, + { "They say that there are no skeletons hence there are no skeleton keys.", + "VGhleSBzYXkgdGhhdCB0aGVyZSBhcmUgbm8gc2tlbGV0b25zIGhlbmNlIHRoZXJlIGFyZSBubyBza2VsZXRvbiBrZXlzLg==" }, + { "They say that there is a clever rogue in every hacker just dying to escape.", + "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBhIGNsZXZlciByb2d1ZSBpbiBldmVyeSBoYWNrZXIganVzdCBkeWluZyB0byBlc2NhcGUu" }, + { "They say that there is no such thing as free advice.", + "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBubyBzdWNoIHRoaW5nIGFzIGZyZWUgYWR2aWNlLg==" }, + { "They say that there is only one way to win at NetHack.", + "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBvbmx5IG9uZSB3YXkgdG8gd2luIGF0IE5ldEhhY2su" }, + { "They say that there once was a fearsome chaotic samurai named Luk No.", + "VGhleSBzYXkgdGhhdCB0aGVyZSBvbmNlIHdhcyBhIGZlYXJzb21lIGNoYW90aWMgc2FtdXJhaSBuYW1lZCBMdWsgTm8u" }, + { "They say that there was a time when cursed holy water wasn't water.", + "VGhleSBzYXkgdGhhdCB0aGVyZSB3YXMgYSB0aW1lIHdoZW4gY3Vyc2VkIGhvbHkgd2F0ZXIgd2Fzbid0IHdhdGVyLg==" }, + { "They say that there's no point in crying over a gray ooze.", + "VGhleSBzYXkgdGhhdCB0aGVyZSdzIG5vIHBvaW50IGluIGNyeWluZyBvdmVyIGEgZ3JheSBvb3plLg==" }, + { "They say that there's only hope left after you've opened Pandora's box.", + "VGhleSBzYXkgdGhhdCB0aGVyZSdzIG9ubHkgaG9wZSBsZWZ0IGFmdGVyIHlvdSd2ZSBvcGVuZWQgUGFuZG9yYSdzIGJveC4=" }, + { "They say that trapdoors should always be marked `Caution: Trap Door'.", + "VGhleSBzYXkgdGhhdCB0cmFwZG9vcnMgc2hvdWxkIGFsd2F5cyBiZSBtYXJrZWQgYENhdXRpb246IFRyYXAgRG9vcicu" }, + { "They say that using an amulet of change isn't a difficult operation.", + "VGhleSBzYXkgdGhhdCB1c2luZyBhbiBhbXVsZXQgb2YgY2hhbmdlIGlzbid0IGEgZGlmZmljdWx0IG9wZXJhdGlvbi4=" }, + { "They say that water walking boots are better if you are fast like Hermes.", + "VGhleSBzYXkgdGhhdCB3YXRlciB3YWxraW5nIGJvb3RzIGFyZSBiZXR0ZXIgaWYgeW91IGFyZSBmYXN0IGxpa2UgSGVybWVzLg==" }, + { "They say that when you wear a circular amulet you might resemble a troll.", + "VGhleSBzYXkgdGhhdCB3aGVuIHlvdSB3ZWFyIGEgY2lyY3VsYXIgYW11bGV0IHlvdSBtaWdodCByZXNlbWJsZSBhIHRyb2xsLg==" }, + { "They say that when you're hungry you can get a pizza in 30 moves or it's free.", + "VGhleSBzYXkgdGhhdCB3aGVuIHlvdSdyZSBodW5ncnkgeW91IGNhbiBnZXQgYSBwaXp6YSBpbiAzMCBtb3ZlcyBvciBpdCdzIGZyZWUu" }, + { "They say that when your god is angry you should try another one.", + "VGhleSBzYXkgdGhhdCB3aGVuIHlvdXIgZ29kIGlzIGFuZ3J5IHlvdSBzaG91bGQgdHJ5IGFub3RoZXIgb25lLg==" }, + { "They say that wielding a unicorn horn takes strength.", + "VGhleSBzYXkgdGhhdCB3aWVsZGluZyBhIHVuaWNvcm4gaG9ybiB0YWtlcyBzdHJlbmd0aC4=" }, + { "They say that with speed boots you never worry about hit and run accidents.", + "VGhleSBzYXkgdGhhdCB3aXRoIHNwZWVkIGJvb3RzIHlvdSBuZXZlciB3b3JyeSBhYm91dCBoaXQgYW5kIHJ1biBhY2NpZGVudHMu" }, + { "They say that you can defeat a killer bee with a unicorn horn.", + "VGhleSBzYXkgdGhhdCB5b3UgY2FuIGRlZmVhdCBhIGtpbGxlciBiZWUgd2l0aCBhIHVuaWNvcm4gaG9ybi4=" }, + { "They say that you can only cross the River Styx in Charon's boat.", + "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkgY3Jvc3MgdGhlIFJpdmVyIFN0eXggaW4gQ2hhcm9uJ3MgYm9hdC4=" }, + { "They say that you can only kill a lich once and then you'd better be careful.", + "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkga2lsbCBhIGxpY2ggb25jZSBhbmQgdGhlbiB5b3UnZCBiZXR0ZXIgYmUgY2FyZWZ1bC4=" }, + { "They say that you can only wish for things you've already had.", + "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkgd2lzaCBmb3IgdGhpbmdzIHlvdSd2ZSBhbHJlYWR5IGhhZC4=" }, + { "They say that you can train a cat by talking gently to it.", + "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRyYWluIGEgY2F0IGJ5IHRhbGtpbmcgZ2VudGx5IHRvIGl0Lg==" }, + { "They say that you can train a dog by talking firmly to it.", + "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRyYWluIGEgZG9nIGJ5IHRhbGtpbmcgZmlybWx5IHRvIGl0Lg==" }, + { "They say that you can trust your gold with the king.", + "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRydXN0IHlvdXIgZ29sZCB3aXRoIHRoZSBraW5nLg==" }, + { "They say that you can't wipe your greasy bare hands on a blank scroll.", + "VGhleSBzYXkgdGhhdCB5b3UgY2FuJ3Qgd2lwZSB5b3VyIGdyZWFzeSBiYXJlIGhhbmRzIG9uIGEgYmxhbmsgc2Nyb2xsLg==" }, + { "They say that you cannot trust scrolls of rumor.", + "VGhleSBzYXkgdGhhdCB5b3UgY2Fubm90IHRydXN0IHNjcm9sbHMgb2YgcnVtb3Iu" }, + { "They say that you could fall head over heels for an energy vortex.", + "VGhleSBzYXkgdGhhdCB5b3UgY291bGQgZmFsbCBoZWFkIG92ZXIgaGVlbHMgZm9yIGFuIGVuZXJneSB2b3J0ZXgu" }, + { "They say that you need a key in order to open locked doors.", + "VGhleSBzYXkgdGhhdCB5b3UgbmVlZCBhIGtleSBpbiBvcmRlciB0byBvcGVuIGxvY2tlZCBkb29ycy4=" }, + { "They say that you need a mirror to notice a mimic in an antique shop.", + "VGhleSBzYXkgdGhhdCB5b3UgbmVlZCBhIG1pcnJvciB0byBub3RpY2UgYSBtaW1pYyBpbiBhbiBhbnRpcXVlIHNob3Au" }, + { "They say that you really can use a pick-axe unless you really can't.", + "VGhleSBzYXkgdGhhdCB5b3UgcmVhbGx5IGNhbiB1c2UgYSBwaWNrLWF4ZSB1bmxlc3MgeW91IHJlYWxseSBjYW4ndC4=" }, + { "They say that you should always store your tools in the cellar.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGFsd2F5cyBzdG9yZSB5b3VyIHRvb2xzIGluIHRoZSBjZWxsYXIu" }, + { "They say that you should be careful while climbing the ladder to success.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGJlIGNhcmVmdWwgd2hpbGUgY2xpbWJpbmcgdGhlIGxhZGRlciB0byBzdWNjZXNzLg==" }, + { "They say that you should call your armor `rustproof'.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGNhbGwgeW91ciBhcm1vciBgcnVzdHByb29mJy4=" }, + { "They say that you should name your dog Spuds to have a cool pet.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5hbWUgeW91ciBkb2cgU3B1ZHMgdG8gaGF2ZSBhIGNvb2wgcGV0Lg==" }, + { "They say that you should name your weapon after your first monster kill.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5hbWUgeW91ciB3ZWFwb24gYWZ0ZXIgeW91ciBmaXJzdCBtb25zdGVyIGtpbGwu" }, + { "They say that you should never introduce a rope golem to a succubus.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIGludHJvZHVjZSBhIHJvcGUgZ29sZW0gdG8gYSBzdWNjdWJ1cy4=" }, + { "They say that you should never sleep near invisible ring wraiths.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIHNsZWVwIG5lYXIgaW52aXNpYmxlIHJpbmcgd3JhaXRocy4=" }, + { "They say that you should never try to leave the dungeon with a bag of gems.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIHRyeSB0byBsZWF2ZSB0aGUgZHVuZ2VvbiB3aXRoIGEgYmFnIG9mIGdlbXMu" }, + { "They say that you should remove your armor before sitting on a throne.", + "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIHJlbW92ZSB5b3VyIGFybW9yIGJlZm9yZSBzaXR0aW5nIG9uIGEgdGhyb25lLg==" }, + { "This fortune cookie is copy protected.", + "VGhpcyBmb3J0dW5lIGNvb2tpZSBpcyBjb3B5IHByb3RlY3RlZC4=" }, + { "This fortune cookie is the property of Fortune Cookies, Inc.", + "VGhpcyBmb3J0dW5lIGNvb2tpZSBpcyB0aGUgcHJvcGVydHkgb2YgRm9ydHVuZSBDb29raWVzLCBJbmMu" }, + { "Tired? Try a scroll of charging on yourself.", + "VGlyZWQ/IFRyeSBhIHNjcm9sbCBvZiBjaGFyZ2luZyBvbiB5b3Vyc2VsZi4=" }, + { "To achieve the next higher rating, you need 3 more points.", + "VG8gYWNoaWV2ZSB0aGUgbmV4dCBoaWdoZXIgcmF0aW5nLCB5b3UgbmVlZCAzIG1vcmUgcG9pbnRzLg==" }, + { "To reach heaven, escape the dungeon while wearing a ring of levitation.", + "VG8gcmVhY2ggaGVhdmVuLCBlc2NhcGUgdGhlIGR1bmdlb24gd2hpbGUgd2VhcmluZyBhIHJpbmcgb2YgbGV2aXRhdGlvbi4=" }, + { "Tourists wear shirts loud enough to wake the dead.", + "VG91cmlzdHMgd2VhciBzaGlydHMgbG91ZCBlbm91Z2ggdG8gd2FrZSB0aGUgZGVhZC4=" }, + { "Try calling your katana Moulinette.", + "VHJ5IGNhbGxpbmcgeW91ciBrYXRhbmEgTW91bGluZXR0ZS4=" }, + { "Ulch! That meat was painted!", + "VWxjaCEgVGhhdCBtZWF0IHdhcyBwYWludGVkIQ==" }, + { "Unfortunately, this message was left intentionally blank.", + "VW5mb3J0dW5hdGVseSwgdGhpcyBtZXNzYWdlIHdhcyBsZWZ0IGludGVudGlvbmFsbHkgYmxhbmsu" }, + { "Using a morning star in the evening has no effect.", + "VXNpbmcgYSBtb3JuaW5nIHN0YXIgaW4gdGhlIGV2ZW5pbmcgaGFzIG5vIGVmZmVjdC4=" }, + { "Want a hint? Zap a wand of make invisible on your weapon!", + "V2FudCBhIGhpbnQ/IFphcCBhIHdhbmQgb2YgbWFrZSBpbnZpc2libGUgb24geW91ciB3ZWFwb24h" }, + { "Want to ascend in a hurry? Apply at Gizmonic Institute.", + "V2FudCB0byBhc2NlbmQgaW4gYSBodXJyeT8gQXBwbHkgYXQgR2l6bW9uaWMgSW5zdGl0dXRlLg==" }, + { "Wanted: shopkeepers. Send a scroll of mail to Mage of Yendor/Level 35/Dungeon.", + "V2FudGVkOiBzaG9wa2VlcGVycy4gU2VuZCBhIHNjcm9sbCBvZiBtYWlsIHRvIE1hZ2Ugb2YgWWVuZG9yL0xldmVsIDM1L0R1bmdlb24u" }, + { "Warning: fortune reading can be hazardous to your health.", + "V2FybmluZzogZm9ydHVuZSByZWFkaW5nIGNhbiBiZSBoYXphcmRvdXMgdG8geW91ciBoZWFsdGgu" }, + { "We have new ways of detecting treachery...", + "V2UgaGF2ZSBuZXcgd2F5cyBvZiBkZXRlY3RpbmcgdHJlYWNoZXJ5Li4u" }, + { "Wet towels make great weapons!", + "V2V0IHRvd2VscyBtYWtlIGdyZWF0IHdlYXBvbnMh" }, + { "What a pity, you cannot read it!", + "V2hhdCBhIHBpdHksIHlvdSBjYW5ub3QgcmVhZCBpdCE=" }, + { "When a piercer drops in on you, you will be tempted to hit the ceiling!", + "V2hlbiBhIHBpZXJjZXIgZHJvcHMgaW4gb24geW91LCB5b3Ugd2lsbCBiZSB0ZW1wdGVkIHRvIGhpdCB0aGUgY2VpbGluZyE=" }, + { "When in a maze follow the right wall and you will never get lost.", + "V2hlbiBpbiBhIG1hemUgZm9sbG93IHRoZSByaWdodCB3YWxsIGFuZCB5b3Ugd2lsbCBuZXZlciBnZXQgbG9zdC4=" }, + { "When you have a key, you don't have to wait for the guard.", + "V2hlbiB5b3UgaGF2ZSBhIGtleSwgeW91IGRvbid0IGhhdmUgdG8gd2FpdCBmb3IgdGhlIGd1YXJkLg==" }, + { "Why are you wasting time reading fortunes?", + "V2h5IGFyZSB5b3Ugd2FzdGluZyB0aW1lIHJlYWRpbmcgZm9ydHVuZXM/" }, + { "Wish for a master key and open the Magic Memory Vault!", + "V2lzaCBmb3IgYSBtYXN0ZXIga2V5IGFuZCBvcGVuIHRoZSBNYWdpYyBNZW1vcnkgVmF1bHQh" }, + { "Wizard expects every monster to do its duty.", + "V2l6YXJkIGV4cGVjdHMgZXZlcnkgbW9uc3RlciB0byBkbyBpdHMgZHV0eS4=" }, + { "Wow! You could've had a potion of fruit juice!", + "V293ISBZb3UgY291bGQndmUgaGFkIGEgcG90aW9uIG9mIGZydWl0IGp1aWNlIQ==" }, + { "Yet Another Silly Message (YASM).", + "WWV0IEFub3RoZXIgU2lsbHkgTWVzc2FnZSAoWUFTTSku" }, + { "You are destined to be misled by a fortune.", + "WW91IGFyZSBkZXN0aW5lZCB0byBiZSBtaXNsZWQgYnkgYSBmb3J0dW5lLg==" }, + { "You can get a genuine Amulet of Yendor by doing the following: --More--", + "WW91IGNhbiBnZXQgYSBnZW51aW5lIEFtdWxldCBvZiBZZW5kb3IgYnkgZG9pbmcgdGhlIGZvbGxvd2luZzogLS1Nb3JlLS0=" }, + { "You can protect yourself from black dragons by doing the following: --More--", + "WW91IGNhbiBwcm90ZWN0IHlvdXJzZWxmIGZyb20gYmxhY2sgZHJhZ29ucyBieSBkb2luZyB0aGUgZm9sbG93aW5nOiAtLU1vcmUtLQ==" }, + { "You can't get by the snake.", + "WW91IGNhbid0IGdldCBieSB0aGUgc25ha2Uu" }, + { "You feel like someone is pulling your leg.", + "WW91IGZlZWwgbGlrZSBzb21lb25lIGlzIHB1bGxpbmcgeW91ciBsZWcu" }, + { "You have to outwit the Sphynx or pay her.", + "WW91IGhhdmUgdG8gb3V0d2l0IHRoZSBTcGh5bnggb3IgcGF5IGhlci4=" }, + { "You hear the fortune cookie's hissing!", + "WW91IGhlYXIgdGhlIGZvcnR1bmUgY29va2llJ3MgaGlzc2luZyE=" }, + { "You may get rich selling letters, but beware of being blackmailed!", + "WW91IG1heSBnZXQgcmljaCBzZWxsaW5nIGxldHRlcnMsIGJ1dCBiZXdhcmUgb2YgYmVpbmcgYmxhY2ttYWlsZWQh" }, + { "You offend Shai-Hulud by sheathing your crysknife without having drawn blood.", + "WW91IG9mZmVuZCBTaGFpLUh1bHVkIGJ5IHNoZWF0aGluZyB5b3VyIGNyeXNrbmlmZSB3aXRob3V0IGhhdmluZyBkcmF3biBibG9vZC4=" }, + { "You swallowed the fortune!", + "WW91IHN3YWxsb3dlZCB0aGUgZm9ydHVuZSE=" }, + { "You want to regain strength? Two levels ahead is a guesthouse!", + "WW91IHdhbnQgdG8gcmVnYWluIHN0cmVuZ3RoPyBUd28gbGV2ZWxzIGFoZWFkIGlzIGEgZ3Vlc3Rob3VzZSE=" }, + { "You will encounter a tall, dark, and gruesome creature...", + "WW91IHdpbGwgZW5jb3VudGVyIGEgdGFsbCwgZGFyaywgYW5kIGdydWVzb21lIGNyZWF0dXJlLi4u" }, + + { "The End", "VGhlIEVuZA==" } + }; + +/* PL_Base64Encode, random strings */ +PRBool test_004(void) +{ + int i; + char result[ 4096 ]; + + printf("Test 004 (PL_Base64Encode, random strings) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 plen = PL_strlen(array[i].plaintext); + PRUint32 clen = ((plen + 2)/3)*4; + + char *rv = PL_Base64Encode(array[i].plaintext, plen, result); + + if( rv != result ) + { + printf("FAIL\n\t(%d): return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strncmp(result, array[i].cyphertext, clen) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", + i, array[i].plaintext, array[i].cyphertext, clen, result); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, single characters, malloc */ +PRBool test_005(void) +{ + PRUint32 a, b; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char *rv; + + printf("Test 005 (PL_Base64Encode, single characters, malloc) ..."); fflush(stdout); + + plain[1] = plain[2] = plain[3] = (unsigned char)0; + cypher[2] = cypher[3] = (unsigned char)'='; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + + for( b = 0; b < 4; b++ ) + { + plain[0] = (unsigned char)(a * 4 + b); + cypher[1] = base[(b * 16)]; + + rv = PL_Base64Encode((char *)plain, 1, (char *)0); + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d, %d): no return value\n", a, b); + return PR_FALSE; + } + + if( 0 != PL_strcmp((char *)cypher, rv) ) + { + printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n", + a, b, cypher, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, double characters, malloc */ +PRBool test_006(void) +{ + PRUint32 a, b, c, d; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char *rv; + + printf("Test 006 (PL_Base64Encode, double characters, malloc) ..."); fflush(stdout); + + plain[2] = plain[3] = (unsigned char)0; + cypher[3] = (unsigned char)'='; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + cypher[2] = base[d*4]; + + rv = PL_Base64Encode((char *)plain, 2, (char *)0); + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d); + return PR_FALSE; + } + + if( 0 != PL_strcmp((char *)cypher, rv) ) + { + printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n", + a, b, c, d, cypher, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, triple characters, malloc */ +PRBool test_007(void) +{ + PRUint32 a, b, c, d, e, f; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char *rv; + + printf("Test 007 (PL_Base64Encode, triple characters, malloc) ..."); fflush(stdout); + + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + for( e = 0; e < 4; e++ ) + { + cypher[2] = base[d*4 + e]; + for( f = 0; f < 64; f++ ) + { + plain[2] = e * 64 + f; + cypher[3] = base[f]; + + rv = PL_Base64Encode((char *)plain, 3, (char *)0); + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): no return value\n", a, b, c, d, e, f); + return PR_FALSE; + } + + if( 0 != PL_strcmp((char *)cypher, rv) ) + { + printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n", + a, b, c, d, e, f, cypher, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + } + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, random strings, malloc */ +PRBool test_008(void) +{ + int i; + + printf("Test 008 (PL_Base64Encode, random strings, malloc) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 plen = PL_strlen(array[i].plaintext); + PRUint32 clen = ((plen + 2)/3)*4; + + char *rv = PL_Base64Encode(array[i].plaintext, plen, (char *)0); + + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d): no return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strcmp(rv, array[i].cyphertext) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", + i, array[i].plaintext, array[i].cyphertext, rv); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, single characters */ +PRBool test_009(void) +{ + PRUint32 a, b; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char result[ 8 ]; + char *rv; + + printf("Test 009 (PL_Base64Decode, single characters, equals) ..."); fflush(stdout); + + plain[1] = plain[2] = plain[3] = (unsigned char)0; + cypher[2] = cypher[3] = (unsigned char)'='; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + + for( b = 0; b < 4; b++ ) + { + plain[0] = (unsigned char)(a * 4 + b); + cypher[1] = base[(b * 16)]; + + rv = PL_Base64Decode((char *)cypher, 4, result); + if( rv != result ) + { + printf("FAIL\n\t(%d, %d): return value\n", a, b); + return PR_FALSE; + } + + if( 0 != PL_strncmp((char *)plain, result, 1) ) + { + printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.1s.\"\n", + a, b, plain, result); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, single characters */ +PRBool test_010(void) +{ + PRUint32 a, b; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char result[ 8 ]; + char *rv; + + printf("Test 010 (PL_Base64Decode, single characters, no equals) ..."); fflush(stdout); + + plain[1] = plain[2] = plain[3] = (unsigned char)0; + cypher[2] = cypher[3] = (unsigned char)0; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + + for( b = 0; b < 4; b++ ) + { + plain[0] = (unsigned char)(a * 4 + b); + cypher[1] = base[(b * 16)]; + + rv = PL_Base64Decode((char *)cypher, 2, result); + if( rv != result ) + { + printf("FAIL\n\t(%d, %d): return value\n", a, b); + return PR_FALSE; + } + + if( 0 != PL_strncmp((char *)plain, result, 1) ) + { + printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.1s.\"\n", + a, b, plain, result); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, double characters */ +PRBool test_011(void) +{ + PRUint32 a, b, c, d; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char result[ 8 ]; + char *rv; + + printf("Test 011 (PL_Base64Decode, double characters, equals) ..."); fflush(stdout); + + plain[2] = plain[3] = (unsigned char)0; + cypher[3] = (unsigned char)'='; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + cypher[2] = base[d*4]; + + rv = PL_Base64Decode((char *)cypher, 4, result); + if( rv != result ) + { + printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d); + return PR_FALSE; + } + + if( 0 != PL_strncmp((char *)plain, result, 2) ) + { + printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.2s.\"\n", + a, b, c, d, plain, result); + return PR_FALSE; + } + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, double characters */ +PRBool test_012(void) +{ + PRUint32 a, b, c, d; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char result[ 8 ]; + char *rv; + + printf("Test 012 (PL_Base64Decode, double characters, no equals) ..."); fflush(stdout); + + plain[2] = plain[3] = (unsigned char)0; + cypher[3] = (unsigned char)0; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + cypher[2] = base[d*4]; + + rv = PL_Base64Decode((char *)cypher, 3, result); + if( rv != result ) + { + printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d); + return PR_FALSE; + } + + if( 0 != PL_strncmp((char *)plain, result, 2) ) + { + printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.2s.\"\n", + a, b, c, d, cypher, result); + return PR_FALSE; + } + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, triple characters */ +PRBool test_013(void) +{ + PRUint32 a, b, c, d, e, f; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char result[ 8 ]; + char *rv; + + printf("Test 013 (PL_Base64Decode, triple characters) ..."); fflush(stdout); + + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + for( e = 0; e < 4; e++ ) + { + cypher[2] = base[d*4 + e]; + for( f = 0; f < 64; f++ ) + { + plain[2] = e * 64 + f; + cypher[3] = base[f]; + + rv = PL_Base64Decode((char *)cypher, 4, result); + if( rv != result ) + { + printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): return value\n", a, b, c, d, e, f); + return PR_FALSE; + } + + if( 0 != PL_strncmp((char *)plain, result, 3) ) + { + printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.3s.\"\n", + a, b, c, d, e, f, plain, result); + return PR_FALSE; + } + } + } + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, random strings */ +PRBool test_014(void) +{ + int i; + char result[ 4096 ]; + + printf("Test 014 (PL_Base64Decode, random strings, equals) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 clen = PL_strlen(array[i].cyphertext); + PRUint32 plen = (clen * 3) / 4; + + char *rv = PL_Base64Decode(array[i].cyphertext, clen, result); + + if( rv != result ) + { + printf("FAIL\n\t(%d): return value\n", i); + return PR_FALSE; + } + + if( 0 == (clen & 3) ) + { + if( '=' == array[i].cyphertext[clen-1] ) + { + if( '=' == array[i].cyphertext[clen-2] ) + { + plen -= 2; + } + else + { + plen -= 1; + } + } + } + + if( 0 != PL_strncmp(result, array[i].plaintext, plen) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", + i, array[i].cyphertext, array[i].plaintext, plen, result); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, random strings */ +PRBool test_015(void) +{ + int i; + char buffer[ 4096 ]; + char result[ 4096 ]; + char *rv; + + printf("Test 015 (PL_Base64Decode, random strings, no equals) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 clen, plen; + + PL_strcpy(buffer, array[i].cyphertext); + clen = PL_strlen(buffer); + + if( 0 == (clen & 3) ) + { + if( '=' == buffer[clen-1] ) + { + if( '=' == buffer[clen-2] ) + { + buffer[clen-2] = buffer[clen-1] = (char)0; + clen -= 2; + } + else + { + buffer[clen-1] = (char)0; + clen -= 1; + } + } + } + + plen = (clen * 3) / 4; + + rv = PL_Base64Decode(buffer, clen, result); + + if( rv != result ) + { + printf("FAIL\n\t(%d): return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strncmp(result, array[i].plaintext, plen) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", + i, array[i].cyphertext, array[i].plaintext, plen, result); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, single characters, malloc */ +PRBool test_016(void) +{ + PRUint32 a, b; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char *rv; + + printf("Test 016 (PL_Base64Decode, single characters, equals, malloc) ..."); fflush(stdout); + + plain[1] = plain[2] = plain[3] = (unsigned char)0; + cypher[2] = cypher[3] = (unsigned char)'='; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + + for( b = 0; b < 4; b++ ) + { + plain[0] = (unsigned char)(a * 4 + b); + cypher[1] = base[(b * 16)]; + + rv = PL_Base64Decode((char *)cypher, 4, (char *)0); + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d, %d): no return value\n", a, b); + return PR_FALSE; + } + + if( 0 != PL_strcmp((char *)plain, rv) ) + { + printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n", + a, b, plain, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, single characters, malloc */ +PRBool test_017(void) +{ + PRUint32 a, b; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char *rv; + + printf("Test 017 (PL_Base64Decode, single characters, no equals, malloc) ..."); fflush(stdout); + + plain[1] = plain[2] = plain[3] = (unsigned char)0; + cypher[2] = cypher[3] = (unsigned char)0; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + + for( b = 0; b < 4; b++ ) + { + plain[0] = (unsigned char)(a * 4 + b); + cypher[1] = base[(b * 16)]; + + rv = PL_Base64Decode((char *)cypher, 2, (char *)0); + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d, %d): no return value\n", a, b); + return PR_FALSE; + } + + if( 0 != PL_strcmp((char *)plain, rv) ) + { + printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n", + a, b, plain, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, double characters, malloc */ +PRBool test_018(void) +{ + PRUint32 a, b, c, d; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char *rv; + + printf("Test 018 (PL_Base64Decode, double characters, equals, malloc) ..."); fflush(stdout); + + plain[2] = plain[3] = (unsigned char)0; + cypher[3] = (unsigned char)'='; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + cypher[2] = base[d*4]; + + rv = PL_Base64Decode((char *)cypher, 4, (char *)0); + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d); + return PR_FALSE; + } + + if( 0 != PL_strcmp((char *)plain, rv) ) + { + printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n", + a, b, c, d, plain, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, double characters, malloc */ +PRBool test_019(void) +{ + PRUint32 a, b, c, d; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char *rv; + + printf("Test 019 (PL_Base64Decode, double characters, no equals, malloc) ..."); fflush(stdout); + + plain[2] = plain[3] = (unsigned char)0; + cypher[3] = (unsigned char)0; + cypher[4] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + cypher[2] = base[d*4]; + + rv = PL_Base64Decode((char *)cypher, 3, (char *)0); + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d); + return PR_FALSE; + } + + if( 0 != PL_strcmp((char *)plain, rv) ) + { + printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n", + a, b, c, d, cypher, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, triple characters, malloc */ +PRBool test_020(void) +{ + PRUint32 a, b, c, d, e, f; + unsigned char plain[ 4 ]; + unsigned char cypher[ 5 ]; + char *rv; + + printf("Test 020 (PL_Base64Decode, triple characters, malloc) ..."); fflush(stdout); + + cypher[4] = (unsigned char)0; + plain[3] = (unsigned char)0; + + for( a = 0; a < 64; a++ ) + { + cypher[0] = base[a]; + for( b = 0; b < 4; b++ ) + { + plain[0] = (a*4) + b; + for( c = 0; c < 16; c++ ) + { + cypher[1] = base[b*16 + c]; + for( d = 0; d < 16; d++ ) + { + plain[1] = c*16 + d; + for( e = 0; e < 4; e++ ) + { + cypher[2] = base[d*4 + e]; + for( f = 0; f < 64; f++ ) + { + plain[2] = e * 64 + f; + cypher[3] = base[f]; + + rv = PL_Base64Decode((char *)cypher, 4, (char *)0); + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): no return value\n", a, b, c, d, e, f); + return PR_FALSE; + } + + if( 0 != PL_strcmp((char *)plain, rv) ) + { + printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.3s.\"\n", + a, b, c, d, e, f, plain, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + } + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, random strings, malloc */ +PRBool test_021(void) +{ + int i; + + printf("Test 021 (PL_Base64Decode, random strings, equals, malloc) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 clen = PL_strlen(array[i].cyphertext); + + char *rv = PL_Base64Decode(array[i].cyphertext, clen, (char *)0); + + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d): no return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strcmp(rv, array[i].plaintext) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", + i, array[i].cyphertext, array[i].plaintext, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, random strings, malloc */ +PRBool test_022(void) +{ + int i; + char buffer[ 4096 ]; + char *rv; + + printf("Test 022 (PL_Base64Decode, random strings, no equals, malloc) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 clen; + + PL_strcpy(buffer, array[i].cyphertext); + clen = PL_strlen(buffer); + + if( 0 == (clen & 3) ) + { + if( '=' == buffer[clen-1] ) + { + if( '=' == buffer[clen-2] ) + { + buffer[clen-2] = buffer[clen-1] = (char)0; + clen -= 2; + } + else + { + buffer[clen-1] = (char)0; + clen -= 1; + } + } + } + + rv = PL_Base64Decode(buffer, clen, (char *)0); + + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d): no return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strcmp(rv, array[i].plaintext) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", + i, array[i].cyphertext, array[i].plaintext, rv); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, random strings */ +PRBool test_023(void) +{ + int i; + char result[ 4096 ]; + + printf("Test 023 (PL_Base64Encode, random strings, strlen) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 plen = PL_strlen(array[i].plaintext); + PRUint32 clen = ((plen + 2)/3)*4; + + char *rv = PL_Base64Encode(array[i].plaintext, 0, result); + + if( rv != result ) + { + printf("FAIL\n\t(%d): return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strncmp(result, array[i].cyphertext, clen) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", + i, array[i].plaintext, array[i].cyphertext, clen, result); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, random strings, malloc */ +PRBool test_024(void) +{ + int i; + + printf("Test 024 (PL_Base64Encode, random strings, malloc, strlen) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 plen = PL_strlen(array[i].plaintext); + PRUint32 clen = ((plen + 2)/3)*4; + + char *rv = PL_Base64Encode(array[i].plaintext, 0, (char *)0); + + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d): no return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strcmp(rv, array[i].cyphertext) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", + i, array[i].plaintext, array[i].cyphertext, rv); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, random strings */ +PRBool test_025(void) +{ + int i; + char result[ 4096 ]; + + printf("Test 025 (PL_Base64Decode, random strings, equals, strlen) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 clen = PL_strlen(array[i].cyphertext); + PRUint32 plen = (clen * 3) / 4; + + char *rv = PL_Base64Decode(array[i].cyphertext, 0, result); + + if( rv != result ) + { + printf("FAIL\n\t(%d): return value\n", i); + return PR_FALSE; + } + + if( 0 == (clen & 3) ) + { + if( '=' == array[i].cyphertext[clen-1] ) + { + if( '=' == array[i].cyphertext[clen-2] ) + { + plen -= 2; + } + else + { + plen -= 1; + } + } + } + + if( 0 != PL_strncmp(result, array[i].plaintext, plen) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", + i, array[i].cyphertext, array[i].plaintext, plen, result); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, random strings */ +PRBool test_026(void) +{ + int i; + char buffer[ 4096 ]; + char result[ 4096 ]; + char *rv; + + printf("Test 026 (PL_Base64Decode, random strings, no equals, strlen) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 clen, plen; + + PL_strcpy(buffer, array[i].cyphertext); + clen = PL_strlen(buffer); + + if( 0 == (clen & 3) ) + { + if( '=' == buffer[clen-1] ) + { + if( '=' == buffer[clen-2] ) + { + buffer[clen-2] = buffer[clen-1] = (char)0; + clen -= 2; + } + else + { + buffer[clen-1] = (char)0; + clen -= 1; + } + } + } + + plen = (clen * 3) / 4; + + rv = PL_Base64Decode(buffer, 0, result); + + if( rv != result ) + { + printf("FAIL\n\t(%d): return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strncmp(result, array[i].plaintext, plen) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n", + i, array[i].cyphertext, array[i].plaintext, plen, result); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Decode, random strings, malloc */ +PRBool test_027(void) +{ + int i; + + printf("Test 027 (PL_Base64Decode, random strings, equals, malloc, strlen) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 clen = PL_strlen(array[i].cyphertext); + + char *rv = PL_Base64Decode(array[i].cyphertext, 0, (char *)0); + + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d): no return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strcmp(rv, array[i].plaintext) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", + i, array[i].cyphertext, array[i].plaintext, rv); + PR_DELETE(rv); + return PR_FALSE; + } + + PR_DELETE(rv); + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_Base64Encode, random strings, malloc */ +PRBool test_028(void) +{ + int i; + char buffer[ 4096 ]; + char *rv; + + printf("Test 028 (PL_Base64Decode, random strings, no equals, malloc, strlen) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRUint32 clen; + + PL_strcpy(buffer, array[i].cyphertext); + clen = PL_strlen(buffer); + + if( 0 == (clen & 3) ) + { + if( '=' == buffer[clen-1] ) + { + if( '=' == buffer[clen-2] ) + { + buffer[clen-2] = buffer[clen-1] = (char)0; + clen -= 2; + } + else + { + buffer[clen-1] = (char)0; + clen -= 1; + } + } + } + + rv = PL_Base64Decode(buffer, 0, (char *)0); + + if( (char *)0 == rv ) + { + printf("FAIL\n\t(%d): no return value\n", i); + return PR_FALSE; + } + + if( 0 != PL_strcmp(rv, array[i].plaintext) ) + { + printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n", + i, array[i].cyphertext, array[i].plaintext, rv); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +int +main +( + int argc, + char *argv[] +) +{ + printf("Testing the Portable Library base64 functions:\n"); + printf("(warning: the \"triple characters\" tests are slow)\n"); + + if( 1 + && test_001() + && test_002() + && test_003() + && test_004() + && test_005() + && test_006() + && test_007() + && test_008() + && test_009() + && test_010() + && test_011() + && test_012() + && test_013() + && test_014() + && test_015() + && test_016() + && test_017() + && test_018() + && test_019() + && test_020() + && test_021() + && test_022() + && test_023() + && test_024() + && test_025() + && test_026() + && test_027() + && test_028() + ) + { + printf("Suite passed.\n"); + return 0; + } + else + { + printf("Suite failed.\n"); + return 1; + } + + /*NOTREACHED*/ +} diff -Nru nspr-4.9.5/nspr/lib/tests/.cvsignore nspr-4.10.7/nspr/lib/tests/.cvsignore --- nspr-4.9.5/nspr/lib/tests/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/tests/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/lib/tests/getopt.c nspr-4.10.7/nspr/lib/tests/getopt.c --- nspr-4.9.5/nspr/lib/tests/getopt.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/tests/getopt.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,44 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include +#include + +#include "nspr.h" +#include "plgetopt.h" + + + +static const PLLongOpt optArray[] = { + { "longa", 'a' , PR_TRUE }, + { "longb", 'b' , PR_TRUE }, + { "longc", 'c' , PR_FALSE }, + { "longd", 'd' | 0x100, PR_TRUE }, + { "longe", 'e' | 0x100, PR_FALSE }, + { NULL, } +}; + +int +main(int argc, char **argv) +{ + PLOptState *opt; + PLOptStatus ostat; + + opt = PL_CreateLongOptState(argc, argv, "a:b:c", optArray); + + while (PL_OPT_OK == (ostat = PL_GetNextOpt(opt))) { + if (opt->option == 0 && opt->longOptIndex < 0) + printf("Positional parameter: \"%s\"\n", opt->value); + else + printf("%s option: %x (\'%c\', index %d), argument: \"%s\"\n", + (ostat == PL_OPT_BAD) ? "BAD" : "GOOD", + opt->longOption, opt->option ? opt->option : ' ', + opt->longOptIndex, opt->value); + + } + printf("last result was %s\n", (ostat == PL_OPT_BAD) ? "BAD" : "EOL"); + PL_DestroyOptState(opt); + return 0; +} diff -Nru nspr-4.9.5/nspr/lib/tests/Makefile.in nspr-4.10.7/nspr/lib/tests/Makefile.in --- nspr-4.9.5/nspr/lib/tests/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/tests/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,178 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CSRCS = \ + arena.c \ + base64t.c \ + getopt.c \ + string.c + +ifeq (,$(filter-out WINCE WINNT OS2,$(OS_ARCH))) +CSRCS += arena.c +endif + +ifeq (,$(filter-out WINCE WINNT OS2,$(OS_ARCH))) +PROG_SUFFIX = .exe +else +PROG_SUFFIX = +endif + +PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX))) + +TARGETS = $(PROGS) $(OBJS) + +INCLUDES = -I$(dist_includedir) + +# Setting the variables LDOPTS and LIBPR. We first initialize +# them to the default values, then adjust them for some platforms. +LDOPTS = -L$(dist_libdir) +LIBPR = -lnspr$(MOD_MAJOR_VERSION) +LIBPLC = -lplc$(MOD_MAJOR_VERSION) +LIBPLDS = -lplds$(MOD_MAJOR_VERSION) + +ifeq (,$(filter-out WINCE WINNT, $(OS_ARCH))) + LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO + ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET))) + LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + LIBPLC= $(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + LIBPLDS= $(dist_libdir)/plds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + else + LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + LIBPLC= $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + LIBPLDS= $(dist_libdir)/libplds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + endif +endif + +ifeq ($(OS_ARCH),OS2) +LDOPTS += -Zomf -Zlinker /PM:VIO +endif + +ifneq ($(OS_ARCH), WINNT) +PWD = $(shell pwd) +endif + +ifeq ($(OS_ARCH), IRIX) +LDOPTS += -rpath $(PWD)/$(dist_libdir) +endif + +ifeq ($(OS_ARCH), Linux) + ifeq ($(OS_RELEASE), 1.2) + EXTRA_LIBS = -ldl + else + LDOPTS += -Xlinker -rpath $(PWD)/$(dist_libdir) + ifeq ($(USE_PTHREADS),1) + EXTRA_LIBS = -lpthread + endif + endif +endif + +ifeq (,$(filter-out OpenBSD,$(OS_ARCH))) + ifeq ($(USE_PTHREADS),1) + EXTRA_LIBS = -lpthread + endif +endif + +ifeq ($(OS_ARCH), OSF1) +LDOPTS += -rpath $(PWD)/$(dist_libdir) -lpthread +endif + +ifeq ($(OS_ARCH), HP-UX) +LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir) +endif + +# AIX +ifeq ($(OS_ARCH),AIX) +LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib +LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr +LIBPLC = -lplc$(MOD_MAJOR_VERSION)_shr +endif + +# Solaris +ifeq ($(OS_ARCH), SunOS) +ifdef NS_USE_GCC +LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir) +else +LDOPTS += -R $(PWD)/$(dist_libdir) +endif + +# SunOS 5.5 needs to link with -lpthread, even though we already +# linked with this system library when we built libnspr.so. +ifeq ($(OS_RELEASE), 5.5) +ifdef USE_PTHREADS +EXTRA_LIBS = -lpthread +endif +endif +endif # SunOS + +##################################################### +# +# The rules +# +##################################################### + +include $(topsrcdir)/config/rules.mk + +AIX_PRE_4_2 = 0 +ifeq ($(OS_ARCH),AIX) +ifneq ($(OS_RELEASE),4.2) +ifneq ($(USE_PTHREADS), 1) +#AIX_PRE_4_2 = 1 +endif +endif +endif + +ifeq ($(AIX_PRE_4_2),1) + +# AIX releases prior to 4.2 need a special two-step linking hack +# in order to both override the system select() and be able to +# get at the original system select(). +# +# We use a pattern rule in ns/nspr20/config/rules.mk to generate +# the .$(OBJ_SUFFIX) file from the .c source file, then do the +# two-step linking hack below. + +$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) + rm -f $@ $(AIX_TMP) + $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a + $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) + rm -f $(AIX_TMP) + +else + +# All platforms that are not AIX pre-4.2. + +$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) + +ifeq ($(OS_ARCH), WINNT) + link $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) ws2_32.lib -out:$@ +else +ifeq ($(OS_ARCH), WINCE) + $(LD) $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) ws2.lib -out:$@ +else +ifeq ($(OS_ARCH),OS2) + $(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS) +else + $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPLDS) $(LIBPR) $(EXTRA_LIBS) -o $@ +endif +endif +endif +endif + +export:: $(TARGETS) +clean:: + rm -f $(TARGETS) diff -Nru nspr-4.9.5/nspr/lib/tests/string.c nspr-4.10.7/nspr/lib/tests/string.c --- nspr-4.9.5/nspr/lib/tests/string.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/lib/tests/string.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,3084 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plstr.h" +#include "nspr.h" + +#include + +/* PL_strlen */ +PRBool test_001(void) +{ + static struct + { + const char *str; + PRUint32 len; + } array[] = + { + { (const char *)0, 0 }, + { "", 0 }, + { "a", 1 }, + { "abcdefg", 7 }, + { "abcdefg\0hijk", 7 } + }; + + int i; + + printf("Test 001 (PL_strlen) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + if( PL_strlen(array[i].str) != array[i].len ) + { + printf("FAIL (%d: %s->%d, %d)\n", i, + array[i].str ? array[i].str : "(null)", + PL_strlen(array[i].str), array[i].len); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strnlen */ +PRBool test_002(void) +{ + static struct + { + const char *str; + PRUint32 max; + PRUint32 len; + } array[] = + { + { (const char *)0, 0, 0 }, + { (const char *)0, 12, 0 }, + { "", 0, 0 }, + { "", 12, 0 }, + { "a", 0, 0 }, + { "a", 1, 1 }, + { "a", 12, 1 }, + { "abcdefg", 0, 0 }, + { "abcdefg", 1, 1 }, + { "abcdefg", 7, 7 }, + { "abcdefg", 12, 7 }, + { "abcdefg\0hijk", 0, 0 }, + { "abcdefg\0hijk", 1, 1 }, + { "abcdefg\0hijk", 7, 7 }, + { "abcdefg\0hijk", 12, 7 }, + }; + + int i; + + printf("Test 002 (PL_strnlen) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + if( PL_strnlen(array[i].str, array[i].max) != array[i].len ) + { + printf("FAIL (%d: %s,%d->%d, %d)\n", i, + array[i].str ? array[i].str : "(null)", array[i].max, + PL_strnlen(array[i].str, array[i].max), array[i].len); + return PR_FALSE; + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strcpy */ +PRBool test_003(void) +{ + static char buffer[ 1024 ]; + + static struct + { + const char *str; + char *dest; + char *rv; + PRBool comp; + } array[] = + { + { (const char *)0, (char *)0, (char *)0, PR_FALSE }, + { (const char *)0, buffer, (char *)0, PR_FALSE }, + { "", (char *)0, (char *)0, PR_FALSE }, + { "", buffer, buffer, PR_TRUE }, + { "a", (char *)0, (char *)0, PR_FALSE }, + { "a", buffer, buffer, PR_TRUE }, + { "abcdefg", (char *)0, (char *)0, PR_FALSE }, + { "abcdefg", buffer, buffer, PR_TRUE }, + { "wxyz\0abcdefg", (char *)0, (char *)0, PR_FALSE }, + { "wxyz\0abcdefg", buffer, buffer, PR_TRUE } + }; + + int i; + + printf("Test 003 (PL_strcpy) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv; + const char *a = array[i].str; + const char *b = (const char *)array[i].dest; + + rv = PL_strcpy(array[i].dest, array[i].str); + if( array[i].rv != rv ) + { + printf("FAIL %d: (0x%x, %s)->0x%x\n", i, array[i].dest, + array[i].str ? array[i].str : "(null)", rv); + return PR_FALSE; + } + + if( array[i].comp ) + { + while( 1 ) + { + if( *a != *b ) + { + printf("FAIL %d: %s->%.32s\n", i, + array[i].str ? array[i].str : "(null)", + array[i].dest ? array[i].dest : "(null)"); + return PR_FALSE; + } + + if( (char)0 == *a ) break; + + a++; + b++; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strncpy */ +PRBool test_004(void) +{ + static char buffer[ 1024 ]; + + static struct + { + const char *str; + PRUint32 len; + char *dest; + char *rv; + PRBool comp; + const char *result; + PRBool nulled; + } array[] = + { + { (const char *)0, 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { (const char *)0, 0, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { (const char *)0, 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { (const char *)0, 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { (const char *)0, 1, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { (const char *)0, 7, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, + { "", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "", 1, buffer, buffer, PR_TRUE, "", PR_TRUE }, + { "", 7, buffer, buffer, PR_TRUE, "", PR_TRUE }, + { "a", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "a", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, + { "a", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "a", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "b", 1, buffer, buffer, PR_TRUE, "b", PR_FALSE }, + { "c", 7, buffer, buffer, PR_TRUE, "c", PR_TRUE }, + { "de", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "de", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, + { "de", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "de", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "fg", 1, buffer, buffer, PR_TRUE, "f", PR_FALSE }, + { "hi", 7, buffer, buffer, PR_TRUE, "hi", PR_TRUE }, + { "jklmnopq", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "jklmnopq", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, + { "jklmnopq", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "jklmnopq", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "rstuvwxy", 1, buffer, buffer, PR_TRUE, "r", PR_FALSE }, + { "zABCDEFG", 7, buffer, buffer, PR_TRUE, "zABCDEF", PR_FALSE }, + { "a\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "a\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, + { "a\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "a\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "b\0XXX", 1, buffer, buffer, PR_TRUE, "b", PR_FALSE }, + { "c\0XXX", 7, buffer, buffer, PR_TRUE, "c", PR_TRUE }, + { "de\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "de\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, + { "de\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "de\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "fg\0XXX", 1, buffer, buffer, PR_TRUE, "f", PR_FALSE }, + { "hi\0XXX", 7, buffer, buffer, PR_TRUE, "hi", PR_TRUE }, + { "jklmnopq\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "jklmnopq\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE }, + { "jklmnopq\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "jklmnopq\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE }, + { "rstuvwxy\0XXX", 1, buffer, buffer, PR_TRUE, "r", PR_FALSE }, + { "zABCDEFG\0XXX", 7, buffer, buffer, PR_TRUE, "zABCDEF", PR_FALSE }, + }; + + int i; + + printf("Test 004 (PL_strncpy) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv; + int j; + + for( j = 0; j < sizeof(buffer); j++ ) + buffer[j] = '-'; + + rv = PL_strncpy(array[i].dest, array[i].str, array[i].len); + if( array[i].rv != rv ) + { + printf("FAIL %d: (0x%x, %s, %lu)->0x%x\n", i, array[i].dest, + array[i].str ? array[i].str : "(null)", array[i].len, rv); + return PR_FALSE; + } + + if( array[i].comp ) + { + const char *a = array[i].result; + const char *b = array[i].dest; + + while( *a ) + { + if( *a != *b ) + { + printf("FAIL %d: %s != %.32s\n", i, + array[i].result, array[i].dest); + return PR_FALSE; + } + + a++; + b++; + } + + if( array[i].nulled ) + { + if( *b != '\0' ) + { + printf("FAIL %d: not terminated\n", i); + return PR_FALSE; + } + } + else + { + if( *b != '-' ) + { + printf("FAIL %d: overstepped\n", i); + return PR_FALSE; + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strncpyz */ +PRBool test_005(void) +{ + static char buffer[ 1024 ]; + + static struct + { + const char *str; + PRUint32 len; + char *dest; + char *rv; + PRBool comp; + const char *result; + } array[] = + { + { (const char *)0, 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { (const char *)0, 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { (const char *)0, 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { (const char *)0, 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { (const char *)0, 1, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { (const char *)0, 7, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { "", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { "", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "", 1, buffer, buffer, PR_TRUE, "" }, + { "", 7, buffer, buffer, PR_TRUE, "" }, + { "a", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "a", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { "a", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "a", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "b", 1, buffer, buffer, PR_TRUE, "" }, + { "c", 7, buffer, buffer, PR_TRUE, "c" }, + { "de", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "de", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { "de", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "de", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "fg", 1, buffer, buffer, PR_TRUE, "" }, + { "hi", 7, buffer, buffer, PR_TRUE, "hi" }, + { "jklmnopq", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "jklmnopq", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { "jklmnopq", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "jklmnopq", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "rstuvwxy", 1, buffer, buffer, PR_TRUE, "" }, + { "zABCDEFG", 7, buffer, buffer, PR_TRUE, "zABCDE" }, + { "a\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "a\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { "a\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "a\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "b\0XXX", 1, buffer, buffer, PR_TRUE, "" }, + { "c\0XXX", 7, buffer, buffer, PR_TRUE, "c" }, + { "de\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "de\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { "de\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "de\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "fg\0XXX", 1, buffer, buffer, PR_TRUE, "" }, + { "hi\0XXX", 7, buffer, buffer, PR_TRUE, "hi" }, + { "jklmnopq\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "jklmnopq\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 }, + { "jklmnopq\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "jklmnopq\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 }, + { "rstuvwxy\0XXX", 1, buffer, buffer, PR_TRUE, "" }, + { "zABCDEFG\0XXX", 7, buffer, buffer, PR_TRUE, "zABCDE" }, + }; + + int i; + + printf("Test 005 (PL_strncpyz) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv; + int j; + + for( j = 0; j < sizeof(buffer); j++ ) + buffer[j] = '-'; + + rv = PL_strncpyz(array[i].dest, array[i].str, array[i].len); + if( array[i].rv != rv ) + { + printf("FAIL %d: (0x%x, %s, %lu)->0x%x\n", i, array[i].dest, + array[i].str ? array[i].str : "(null)", array[i].len, rv); + return PR_FALSE; + } + + if( array[i].comp ) + { + const char *a = array[i].result; + const char *b = array[i].dest; + + while( 1 ) + { + if( *a != *b ) + { + printf("FAIL %d: %s != %.32s\n", i, + array[i].result, array[i].dest); + return PR_FALSE; + } + + if( (char)0 == *a ) break; + + a++; + b++; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strdup */ +PRBool test_006(void) +{ + static const char *array[] = + { + (const char *)0, + "", + "a", + "abcdefg" + }; + + int i; + + printf("Test 006 (PL_strdup) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strdup(array[i]); + + if( (char *)0 == rv ) + { + printf("FAIL %d: 0x%x -> 0\n", i, array[i]); + return PR_FALSE; + } + + if( (const char *)0 == array[i] ) + { + if( (char)0 != *rv ) + { + printf("FAIL %d: (const char *)0 -> %.32s\n", i, rv); + return PR_FALSE; + } + } + else + { + const char *a = array[i]; + const char *b = (const char *)rv; + + while( 1 ) + { + if( *a != *b ) + { + printf("FAIL %d: %s != %.32s\n", i, array[i], rv); + return PR_FALSE; + } + + if( (char)0 == *a ) break; + + a++; + b++; + } + + } + PL_strfree(rv); + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strndup */ +PRBool test_007(void) +{ + static struct + { + const char *str; + PRUint32 len; + const char *result; + } array[] = + { + { (const char *)0, 0, "" }, + { (const char *)0, 1, "" }, + { (const char *)0, 7, "" }, + { "", 0, "" }, + { "", 1, "" }, + { "", 7, "" }, + { "a", 0, "" }, + { "a", 1, "a" }, + { "a", 7, "a" }, + { "ab", 0, "" }, + { "ab", 1, "a" }, + { "ab", 7, "ab" }, + { "abcdefg", 0, "" }, + { "abcdefg", 1, "a" }, + { "abcdefg", 7, "abcdefg" }, + { "abcdefghijk", 0, "" }, + { "abcdefghijk", 1, "a" }, + { "abcdefghijk", 7, "abcdefg" }, + { "abcdef\0ghijk", 0, "" }, + { "abcdef\0ghijk", 1, "a" }, + { "abcdef\0ghijk", 7, "abcdef" } + }; + + int i; + + printf("Test 007 (PL_strndup) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strndup(array[i].str, array[i].len); + const char *a; + const char *b; + + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%lu -> 0\n", i, + array[i].str ? array[i].str : "(null)", array[i].len); + return PR_FALSE; + } + + a = array[i].result; + b = (const char *)rv; + + while( 1 ) + { + if( *a != *b ) + { + printf("FAIL %d: %s != %.32s\n", i, array[i].result, rv); + return PR_FALSE; + } + + if( (char)0 == *a ) break; + + a++; + b++; + } + + free(rv); + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strcat */ +PRBool test_008(void) +{ + static struct + { + const char *first; + const char *second; + const char *result; + } array[] = + { + { (const char *)0, (const char *)0, (const char *)0 }, + { (const char *)0, "xyz", (const char *)0 }, + { "", (const char *)0, "" }, + { "", "", "" }, + { "ab", "", "ab" }, + { "cd", "ef", "cdef" }, + { "gh\0X", "", "gh" }, + { "ij\0X", "kl", "ijkl" }, + { "mn\0X", "op\0X", "mnop" }, + { "qr", "st\0X", "qrst" }, + { "uv\0X", "wx\0X", "uvwx" } + }; + + int i; + + printf("Test 008 (PL_strcat) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char buffer[ 1024 ]; + int j; + char *rv; + + for( j = 0; j < sizeof(buffer); j++ ) + buffer[j] = '-'; + + if( (const char *)0 != array[i].first ) + (void)PL_strcpy(buffer, array[i].first); + + rv = PL_strcat(((const char *)0 == array[i].first) ? (char *)0 : buffer, + array[i].second); + + if( (const char *)0 == array[i].result ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s+%s -> %.32s, not zero\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s+%s -> null, not %s\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].result); + return PR_FALSE; + } + else + { + const char *a = array[i].result; + const char *b = (const char *)rv; + + while( 1 ) + { + if( *a != *b ) + { + printf("FAIL %d: %s+%s -> %.32s, not %s\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + rv, array[i].result); + return PR_FALSE; + } + + if( (char)0 == *a ) break; + + a++; + b++; + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strncat */ +PRBool test_009(void) +{ + static struct + { + const char *first; + const char *second; + PRUint32 length; + PRBool nulled; + const char *result; + } array[] = + { + { (const char *)0, (const char *)0, 0, PR_FALSE, (const char *)0 }, + { (const char *)0, (const char *)0, 1, PR_FALSE, (const char *)0 }, + { (const char *)0, (const char *)0, 7, PR_FALSE, (const char *)0 }, + { (const char *)0, "", 0, PR_FALSE, (const char *)0 }, + { (const char *)0, "", 1, PR_FALSE, (const char *)0 }, + { (const char *)0, "", 7, PR_FALSE, (const char *)0 }, + { (const char *)0, "stuff", 0, PR_FALSE, (const char *)0 }, + { (const char *)0, "stuff", 1, PR_FALSE, (const char *)0 }, + { (const char *)0, "stuff", 7, PR_FALSE, (const char *)0 }, + { "", (const char *)0, 0, PR_TRUE, "" }, + { "", (const char *)0, 1, PR_TRUE, "" }, + { "", (const char *)0, 7, PR_TRUE, "" }, + { "", "", 0, PR_TRUE, "" }, + { "", "", 1, PR_TRUE, "" }, + { "", "", 7, PR_TRUE, "" }, + { "", "abcdefgh", 0, PR_TRUE, "" }, + { "", "abcdefgh", 1, PR_FALSE, "a" }, + { "", "abcdefgh", 7, PR_FALSE, "abcdefg" }, + { "xyz", (const char *)0, 0, PR_TRUE, "xyz" }, + { "xyz", (const char *)0, 1, PR_TRUE, "xyz" }, + { "xyz", (const char *)0, 7, PR_TRUE, "xyz" }, + { "xyz", "", 0, PR_TRUE, "xyz" }, + { "xyz", "", 1, PR_TRUE, "xyz" }, + { "xyz", "", 7, PR_TRUE, "xyz" }, + { "xyz", "abcdefgh", 0, PR_TRUE, "xyz" }, + { "xyz", "abcdefgh", 1, PR_FALSE, "xyza" }, + { "xyz", "abcdefgh", 7, PR_FALSE, "xyzabcdefg" } + }; + + int i; + + printf("Test 009 (PL_strncat) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char buffer[ 1024 ]; + int j; + char *rv; + + for( j = 0; j < sizeof(buffer); j++ ) + buffer[j] = '-'; + + if( (const char *)0 != array[i].first ) + (void)PL_strcpy(buffer, array[i].first); + + rv = PL_strncat(((const char *)0 == array[i].first) ? (char *)0 : buffer, + array[i].second, array[i].length); + + if( (const char *)0 == array[i].result ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s+%s/%lu -> %.32s, not zero\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].length, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s+%s/%lu -> null, not %s\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].length, array[i].result); + return PR_FALSE; + } + else + { + const char *a = array[i].result; + const char *b = (const char *)rv; + + while( *a ) + { + if( *a != *b ) + { + printf("FAIL %d: %s+%s/%lu -> %.32s, not %s\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].length, rv, array[i].result); + return PR_FALSE; + } + + a++; + b++; + } + + if( array[i].nulled ) + { + if( (char)0 != *b ) + { + printf("FAIL %d: %s+%s/%lu -> not nulled\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].length); + return PR_FALSE; + } + } + else + { + if( (char)0 == *b ) + { + printf("FAIL %d: %s+%s/%lu -> overrun\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].length); + return PR_FALSE; + } + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strcatn */ +PRBool test_010(void) +{ + static struct + { + const char *first; + const char *second; + PRUint32 length; + const char *result; + } array[] = + { + { (const char *)0, (const char *)0, 0, (const char *)0 }, + { (const char *)0, (const char *)0, 1, (const char *)0 }, + { (const char *)0, (const char *)0, 7, (const char *)0 }, + { (const char *)0, "", 0, (const char *)0 }, + { (const char *)0, "", 1, (const char *)0 }, + { (const char *)0, "", 7, (const char *)0 }, + { (const char *)0, "stuff", 0, (const char *)0 }, + { (const char *)0, "stuff", 1, (const char *)0 }, + { (const char *)0, "stuff", 7, (const char *)0 }, + { "", (const char *)0, 0, "" }, + { "", (const char *)0, 1, "" }, + { "", (const char *)0, 7, "" }, + { "", "", 0, "" }, + { "", "", 1, "" }, + { "", "", 7, "" }, + { "", "abcdefgh", 0, "" }, + { "", "abcdefgh", 1, "" }, + { "", "abcdefgh", 7, "abcdef" }, + { "xyz", (const char *)0, 0, "xyz" }, + { "xyz", (const char *)0, 1, "xyz" }, + { "xyz", (const char *)0, 7, "xyz" }, + { "xyz", "", 0, "xyz" }, + { "xyz", "", 1, "xyz" }, + { "xyz", "", 7, "xyz" }, + { "xyz", "abcdefgh", 0, "xyz" }, + { "xyz", "abcdefgh", 1, "xyz" }, + { "xyz", "abcdefgh", 7, "xyzabc" } + }; + + int i; + + printf("Test 010 (PL_strcatn) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char buffer[ 1024 ]; + int j; + char *rv; + + for( j = 0; j < sizeof(buffer); j++ ) + buffer[j] = '-'; + + if( (const char *)0 != array[i].first ) + (void)PL_strcpy(buffer, array[i].first); + + rv = PL_strcatn(((const char *)0 == array[i].first) ? (char *)0 : buffer, + array[i].length, array[i].second); + + if( (const char *)0 == array[i].result ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s+%s/%lu -> %.32s, not zero\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].length, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s+%s/%lu -> null, not %s\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].length, array[i].result); + return PR_FALSE; + } + else + { + const char *a = array[i].result; + const char *b = (const char *)rv; + + while( 1 ) + { + if( *a != *b ) + { + printf("FAIL %d: %s+%s/%lu -> %.32s, not %s\n", i, + array[i].first ? array[i].first : "(null)", + array[i].second ? array[i].second : "(null)", + array[i].length, rv, array[i].result); + return PR_FALSE; + } + + if( (char)0 == *a ) break; + + a++; + b++; + } + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strcmp */ +PRBool test_011(void) +{ + static struct + { + const char *one; + const char *two; + PRIntn sign; + } array[] = + { + { (const char *)0, (const char *)0, 0 }, + { (const char *)0, "word", -1 }, + { "word", (const char *)0, 1 }, + { "word", "word", 0 }, + { "aZYXVUT", "bZYXVUT", -1 }, + { "aZYXVUT", "bAAAAAA", -1 }, + { "a", "aa", -1 }, + { "a", "a", 0 }, + { "a", "A", 1 }, + { "aaaaa", "baaaa", -1 }, + { "aaaaa", "abaaa", -1 }, + { "aaaaa", "aabaa", -1 }, + { "aaaaa", "aaaba", -1 }, + { "aaaaa", "aaaab", -1 }, + { "bZYXVUT", "aZYXVUT", 1 }, + { "bAAAAAA", "aZYXVUT", 1 }, + { "aa", "a", 1 }, + { "A", "a", -1 }, + { "baaaa", "aaaaa", 1 }, + { "abaaa", "aaaaa", 1 }, + { "aabaa", "aaaaa", 1 }, + { "aaaba", "aaaaa", 1 }, + { "aaaab", "aaaaa", 1 }, + { "word", "Word", 1 }, + { "word", "wOrd", 1 }, + { "word", "woRd", 1 }, + { "word", "worD", 1 }, + { "WORD", "wORD", -1 }, + { "WORD", "WoRD", -1 }, + { "WORD", "WOrD", -1 }, + { "WORD", "WORd", -1 } + }; + + int i; + + printf("Test 011 (PL_strcmp) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRIntn rv = PL_strcmp(array[i].one, array[i].two); + + switch( array[i].sign ) + { + case -1: + if( rv < 0 ) continue; + break; + case 1: + if( rv > 0 ) continue; + break; + case 0: + if( 0 == rv ) continue; + break; + default: + PR_NOT_REACHED("static data inconsistancy"); + break; + } + + printf("FAIL %d: %s-%s -> %d, not %d\n", i, + array[i].one ? array[i].one : "(null)", + array[i].two ? array[i].two : "(null)", + rv, array[i].sign); + return PR_FALSE; + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strncmp */ +PRBool test_012(void) +{ + static struct + { + const char *one; + const char *two; + PRUint32 max; + PRIntn sign; + } array[] = + { + { (const char *)0, (const char *)0, 0, 0 }, + { (const char *)0, (const char *)0, 1, 0 }, + { (const char *)0, (const char *)0, 4, 0 }, + { (const char *)0, "word", 0, -1 }, + { (const char *)0, "word", 1, -1 }, + { (const char *)0, "word", 4, -1 }, + { "word", (const char *)0, 0, 1 }, + { "word", (const char *)0, 1, 1 }, + { "word", (const char *)0, 4, 1 }, + { "word", "word", 0, 0 }, + { "word", "word", 1, 0 }, + { "word", "word", 3, 0 }, + { "word", "word", 5, 0 }, + { "aZYXVUT", "bZYXVUT", 0, 0 }, + { "aZYXVUT", "bZYXVUT", 1, -1 }, + { "aZYXVUT", "bZYXVUT", 4, -1 }, + { "aZYXVUT", "bZYXVUT", 9, -1 }, + { "aZYXVUT", "bAAAAAA", 0, 0 }, + { "aZYXVUT", "bAAAAAA", 1, -1 }, + { "aZYXVUT", "bAAAAAA", 4, -1 }, + { "aZYXVUT", "bAAAAAA", 5, -1 }, + { "a", "aa", 0, 0 }, + { "a", "aa", 1, 0 }, + { "a", "aa", 4, -1 }, + { "a", "a", 0, 0 }, + { "a", "a", 1, 0 }, + { "a", "a", 4, 0 }, + { "a", "A", 0, 0 }, + { "a", "A", 1, 1 }, + { "a", "A", 4, 1 }, + { "aaaaa", "baaaa", 0, 0 }, + { "aaaaa", "baaaa", 1, -1 }, + { "aaaaa", "baaaa", 4, -1 }, + { "aaaaa", "abaaa", 0, 0 }, + { "aaaaa", "abaaa", 1, 0 }, + { "aaaaa", "abaaa", 4, -1 }, + { "aaaaa", "aabaa", 0, 0 }, + { "aaaaa", "aabaa", 1, 0 }, + { "aaaaa", "aabaa", 4, -1 }, + { "aaaaa", "aaaba", 0, 0 }, + { "aaaaa", "aaaba", 1, 0 }, + { "aaaaa", "aaaba", 4, -1 }, + { "aaaaa", "aaaab", 0, 0 }, + { "aaaaa", "aaaab", 1, 0 }, + { "aaaaa", "aaaab", 4, 0 }, + { "bZYXVUT", "aZYXVUT", 0, 0 }, + { "bZYXVUT", "aZYXVUT", 1, 1 }, + { "bZYXVUT", "aZYXVUT", 4, 1 }, + { "bAAAAAA", "aZYXVUT", 0, 0 }, + { "bAAAAAA", "aZYXVUT", 1, 1 }, + { "bAAAAAA", "aZYXVUT", 4, 1 }, + { "aa", "a", 0, 0 }, + { "aa", "a", 1, 0 }, + { "aa", "a", 4, 1 }, + { "A", "a", 0, 0 }, + { "A", "a", 1, -1 }, + { "A", "a", 4, -1 }, + { "baaaa", "aaaaa", 0, 0 }, + { "baaaa", "aaaaa", 1, 1 }, + { "baaaa", "aaaaa", 4, 1 }, + { "abaaa", "aaaaa", 0, 0 }, + { "abaaa", "aaaaa", 1, 0 }, + { "abaaa", "aaaaa", 4, 1 }, + { "aabaa", "aaaaa", 0, 0 }, + { "aabaa", "aaaaa", 1, 0 }, + { "aabaa", "aaaaa", 4, 1 }, + { "aaaba", "aaaaa", 0, 0 }, + { "aaaba", "aaaaa", 1, 0 }, + { "aaaba", "aaaaa", 4, 1 }, + { "aaaab", "aaaaa", 0, 0 }, + { "aaaab", "aaaaa", 1, 0 }, + { "aaaab", "aaaaa", 4, 0 }, + { "word", "Word", 0, 0 }, + { "word", "Word", 1, 1 }, + { "word", "Word", 3, 1 }, + { "word", "wOrd", 0, 0 }, + { "word", "wOrd", 1, 0 }, + { "word", "wOrd", 3, 1 }, + { "word", "woRd", 0, 0 }, + { "word", "woRd", 1, 0 }, + { "word", "woRd", 3, 1 }, + { "word", "worD", 0, 0 }, + { "word", "worD", 1, 0 }, + { "word", "worD", 3, 0 }, + { "WORD", "wORD", 0, 0 }, + { "WORD", "wORD", 1, -1 }, + { "WORD", "wORD", 3, -1 }, + { "WORD", "WoRD", 0, 0 }, + { "WORD", "WoRD", 1, 0 }, + { "WORD", "WoRD", 3, -1 }, + { "WORD", "WOrD", 0, 0 }, + { "WORD", "WOrD", 1, 0 }, + { "WORD", "WOrD", 3, -1 }, + { "WORD", "WORd", 0, 0 }, + { "WORD", "WORd", 1, 0 }, + { "WORD", "WORd", 3, 0 } + + }; + + int i; + + printf("Test 012 (PL_strncmp) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRIntn rv = PL_strncmp(array[i].one, array[i].two, array[i].max); + + switch( array[i].sign ) + { + case -1: + if( rv < 0 ) continue; + break; + case 1: + if( rv > 0 ) continue; + break; + case 0: + if( 0 == rv ) continue; + break; + default: + PR_NOT_REACHED("static data inconsistancy"); + break; + } + + printf("FAIL %d: %s-%s/%ld -> %d, not %d\n", i, + array[i].one ? array[i].one : "(null)", + array[i].two ? array[i].two : "(null)", + array[i].max, rv, array[i].sign); + return PR_FALSE; + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strcasecmp */ +PRBool test_013(void) +{ + static struct + { + const char *one; + const char *two; + PRIntn sign; + } array[] = + { + { (const char *)0, (const char *)0, 0 }, + { (const char *)0, "word", -1 }, + { "word", (const char *)0, 1 }, + { "word", "word", 0 }, + { "aZYXVUT", "bZYXVUT", -1 }, + { "aZYXVUT", "bAAAAAA", -1 }, + { "a", "aa", -1 }, + { "a", "a", 0 }, + { "a", "A", 0 }, + { "aaaaa", "baaaa", -1 }, + { "aaaaa", "abaaa", -1 }, + { "aaaaa", "aabaa", -1 }, + { "aaaaa", "aaaba", -1 }, + { "aaaaa", "aaaab", -1 }, + { "bZYXVUT", "aZYXVUT", 1 }, + { "bAAAAAA", "aZYXVUT", 1 }, + { "aa", "a", 1 }, + { "A", "a", 0 }, + { "baaaa", "aaaaa", 1 }, + { "abaaa", "aaaaa", 1 }, + { "aabaa", "aaaaa", 1 }, + { "aaaba", "aaaaa", 1 }, + { "aaaab", "aaaaa", 1 }, + { "word", "Word", 0 }, + { "word", "wOrd", 0 }, + { "word", "woRd", 0 }, + { "word", "worD", 0 }, + { "WORD", "wORD", 0 }, + { "WORD", "WoRD", 0 }, + { "WORD", "WOrD", 0 }, + { "WORD", "WORd", 0 } + }; + + int i; + + printf("Test 013 (PL_strcasecmp) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRIntn rv = PL_strcasecmp(array[i].one, array[i].two); + + switch( array[i].sign ) + { + case -1: + if( rv < 0 ) continue; + break; + case 1: + if( rv > 0 ) continue; + break; + case 0: + if( 0 == rv ) continue; + break; + default: + PR_NOT_REACHED("static data inconsistancy"); + break; + } + + printf("FAIL %d: %s-%s -> %d, not %d\n", i, + array[i].one ? array[i].one : "(null)", + array[i].two ? array[i].two : "(null)", + rv, array[i].sign); + return PR_FALSE; + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strncasecmp */ +PRBool test_014(void) +{ + static struct + { + const char *one; + const char *two; + PRUint32 max; + PRIntn sign; + } array[] = + { + { (const char *)0, (const char *)0, 0, 0 }, + { (const char *)0, (const char *)0, 1, 0 }, + { (const char *)0, (const char *)0, 4, 0 }, + { (const char *)0, "word", 0, -1 }, + { (const char *)0, "word", 1, -1 }, + { (const char *)0, "word", 4, -1 }, + { "word", (const char *)0, 0, 1 }, + { "word", (const char *)0, 1, 1 }, + { "word", (const char *)0, 4, 1 }, + { "word", "word", 0, 0 }, + { "word", "word", 1, 0 }, + { "word", "word", 3, 0 }, + { "word", "word", 5, 0 }, + { "aZYXVUT", "bZYXVUT", 0, 0 }, + { "aZYXVUT", "bZYXVUT", 1, -1 }, + { "aZYXVUT", "bZYXVUT", 4, -1 }, + { "aZYXVUT", "bZYXVUT", 9, -1 }, + { "aZYXVUT", "bAAAAAA", 0, 0 }, + { "aZYXVUT", "bAAAAAA", 1, -1 }, + { "aZYXVUT", "bAAAAAA", 4, -1 }, + { "aZYXVUT", "bAAAAAA", 5, -1 }, + { "a", "aa", 0, 0 }, + { "a", "aa", 1, 0 }, + { "a", "aa", 4, -1 }, + { "a", "a", 0, 0 }, + { "a", "a", 1, 0 }, + { "a", "a", 4, 0 }, + { "a", "A", 0, 0 }, + { "a", "A", 1, 0 }, + { "a", "A", 4, 0 }, + { "aaaaa", "baaaa", 0, 0 }, + { "aaaaa", "baaaa", 1, -1 }, + { "aaaaa", "baaaa", 4, -1 }, + { "aaaaa", "abaaa", 0, 0 }, + { "aaaaa", "abaaa", 1, 0 }, + { "aaaaa", "abaaa", 4, -1 }, + { "aaaaa", "aabaa", 0, 0 }, + { "aaaaa", "aabaa", 1, 0 }, + { "aaaaa", "aabaa", 4, -1 }, + { "aaaaa", "aaaba", 0, 0 }, + { "aaaaa", "aaaba", 1, 0 }, + { "aaaaa", "aaaba", 4, -1 }, + { "aaaaa", "aaaab", 0, 0 }, + { "aaaaa", "aaaab", 1, 0 }, + { "aaaaa", "aaaab", 4, 0 }, + { "bZYXVUT", "aZYXVUT", 0, 0 }, + { "bZYXVUT", "aZYXVUT", 1, 1 }, + { "bZYXVUT", "aZYXVUT", 4, 1 }, + { "bAAAAAA", "aZYXVUT", 0, 0 }, + { "bAAAAAA", "aZYXVUT", 1, 1 }, + { "bAAAAAA", "aZYXVUT", 4, 1 }, + { "aa", "a", 0, 0 }, + { "aa", "a", 1, 0 }, + { "aa", "a", 4, 1 }, + { "A", "a", 0, 0 }, + { "A", "a", 1, 0 }, + { "A", "a", 4, 0 }, + { "baaaa", "aaaaa", 0, 0 }, + { "baaaa", "aaaaa", 1, 1 }, + { "baaaa", "aaaaa", 4, 1 }, + { "abaaa", "aaaaa", 0, 0 }, + { "abaaa", "aaaaa", 1, 0 }, + { "abaaa", "aaaaa", 4, 1 }, + { "aabaa", "aaaaa", 0, 0 }, + { "aabaa", "aaaaa", 1, 0 }, + { "aabaa", "aaaaa", 4, 1 }, + { "aaaba", "aaaaa", 0, 0 }, + { "aaaba", "aaaaa", 1, 0 }, + { "aaaba", "aaaaa", 4, 1 }, + { "aaaab", "aaaaa", 0, 0 }, + { "aaaab", "aaaaa", 1, 0 }, + { "aaaab", "aaaaa", 4, 0 }, + { "word", "Word", 0, 0 }, + { "word", "Word", 1, 0 }, + { "word", "Word", 3, 0 }, + { "word", "wOrd", 0, 0 }, + { "word", "wOrd", 1, 0 }, + { "word", "wOrd", 3, 0 }, + { "word", "woRd", 0, 0 }, + { "word", "woRd", 1, 0 }, + { "word", "woRd", 3, 0 }, + { "word", "worD", 0, 0 }, + { "word", "worD", 1, 0 }, + { "word", "worD", 3, 0 }, + { "WORD", "wORD", 0, 0 }, + { "WORD", "wORD", 1, 0 }, + { "WORD", "wORD", 3, 0 }, + { "WORD", "WoRD", 0, 0 }, + { "WORD", "WoRD", 1, 0 }, + { "WORD", "WoRD", 3, 0 }, + { "WORD", "WOrD", 0, 0 }, + { "WORD", "WOrD", 1, 0 }, + { "WORD", "WOrD", 3, 0 }, + { "WORD", "WORd", 0, 0 }, + { "WORD", "WORd", 1, 0 }, + { "WORD", "WORd", 3, 0 } + }; + + int i; + + printf("Test 014 (PL_strncasecmp) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + PRIntn rv = PL_strncasecmp(array[i].one, array[i].two, array[i].max); + + switch( array[i].sign ) + { + case -1: + if( rv < 0 ) continue; + break; + case 1: + if( rv > 0 ) continue; + break; + case 0: + if( 0 == rv ) continue; + break; + default: + PR_NOT_REACHED("static data inconsistancy"); + break; + } + + printf("FAIL %d: %s-%s/%ld -> %d, not %d\n", i, + array[i].one ? array[i].one : "(null)", + array[i].two ? array[i].two : "(null)", + array[i].max, rv, array[i].sign); + return PR_FALSE; + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strchr */ +PRBool test_015(void) +{ + static struct + { + const char *str; + char chr; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, 'a', PR_FALSE, 0 }, + { (const char *)0, '\0', PR_FALSE, 0 }, + { "abcdefg", 'a', PR_TRUE, 0 }, + { "abcdefg", 'b', PR_TRUE, 1 }, + { "abcdefg", 'c', PR_TRUE, 2 }, + { "abcdefg", 'd', PR_TRUE, 3 }, + { "abcdefg", 'e', PR_TRUE, 4 }, + { "abcdefg", 'f', PR_TRUE, 5 }, + { "abcdefg", 'g', PR_TRUE, 6 }, + { "abcdefg", 'h', PR_FALSE, 0 }, + { "abcdefg", '\0', PR_TRUE, 7 }, + { "abcdefg", 'A', PR_FALSE, 0 }, + { "abcdefg", 'B', PR_FALSE, 0 }, + { "abcdefg", 'C', PR_FALSE, 0 }, + { "abcdefg", 'D', PR_FALSE, 0 }, + { "abcdefg", 'E', PR_FALSE, 0 }, + { "abcdefg", 'F', PR_FALSE, 0 }, + { "abcdefg", 'G', PR_FALSE, 0 }, + { "abcdefg", 'H', PR_FALSE, 0 }, + { "abcdefgabcdefg", 'a', PR_TRUE, 0 }, + { "abcdefgabcdefg", 'b', PR_TRUE, 1 }, + { "abcdefgabcdefg", 'c', PR_TRUE, 2 }, + { "abcdefgabcdefg", 'd', PR_TRUE, 3 }, + { "abcdefgabcdefg", 'e', PR_TRUE, 4 }, + { "abcdefgabcdefg", 'f', PR_TRUE, 5 }, + { "abcdefgabcdefg", 'g', PR_TRUE, 6 }, + { "abcdefgabcdefg", 'h', PR_FALSE, 0 }, + { "abcdefgabcdefg", '\0', PR_TRUE, 14 } + }; + + int i; + + printf("Test 015 (PL_strchr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strchr(array[i].str, array[i].chr); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%c -> %.32s, not zero\n", i, array[i].str, + array[i].chr, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%c -> null, not +%lu\n", i, array[i].str, + array[i].chr, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%c -> 0x%x, not 0x%x+%lu\n", i, array[i].str, + array[i].chr, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strrchr */ +PRBool test_016(void) +{ + static struct + { + const char *str; + char chr; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, 'a', PR_FALSE, 0 }, + { (const char *)0, '\0', PR_FALSE, 0 }, + { "abcdefg", 'a', PR_TRUE, 0 }, + { "abcdefg", 'b', PR_TRUE, 1 }, + { "abcdefg", 'c', PR_TRUE, 2 }, + { "abcdefg", 'd', PR_TRUE, 3 }, + { "abcdefg", 'e', PR_TRUE, 4 }, + { "abcdefg", 'f', PR_TRUE, 5 }, + { "abcdefg", 'g', PR_TRUE, 6 }, + { "abcdefg", 'h', PR_FALSE, 0 }, + { "abcdefg", '\0', PR_TRUE, 7 }, + { "abcdefg", 'A', PR_FALSE, 0 }, + { "abcdefg", 'B', PR_FALSE, 0 }, + { "abcdefg", 'C', PR_FALSE, 0 }, + { "abcdefg", 'D', PR_FALSE, 0 }, + { "abcdefg", 'E', PR_FALSE, 0 }, + { "abcdefg", 'F', PR_FALSE, 0 }, + { "abcdefg", 'G', PR_FALSE, 0 }, + { "abcdefg", 'H', PR_FALSE, 0 }, + { "abcdefgabcdefg", 'a', PR_TRUE, 7 }, + { "abcdefgabcdefg", 'b', PR_TRUE, 8 }, + { "abcdefgabcdefg", 'c', PR_TRUE, 9 }, + { "abcdefgabcdefg", 'd', PR_TRUE, 10 }, + { "abcdefgabcdefg", 'e', PR_TRUE, 11 }, + { "abcdefgabcdefg", 'f', PR_TRUE, 12 }, + { "abcdefgabcdefg", 'g', PR_TRUE, 13 }, + { "abcdefgabcdefg", 'h', PR_FALSE, 0 }, + { "abcdefgabcdefg", '\0', PR_TRUE, 14 } + }; + + int i; + + printf("Test 016 (PL_strrchr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strrchr(array[i].str, array[i].chr); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%c -> %.32s, not zero\n", i, array[i].str, + array[i].chr, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%c -> null, not +%lu\n", i, array[i].str, + array[i].chr, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%c -> 0x%x, not 0x%x+%lu\n", i, array[i].str, + array[i].chr, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strnchr */ +PRBool test_017(void) +{ + static struct + { + const char *str; + char chr; + PRUint32 max; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, 'a', 2, PR_FALSE, 0 }, + { (const char *)0, '\0', 2, PR_FALSE, 0 }, + { "abcdefg", 'a', 5, PR_TRUE, 0 }, + { "abcdefg", 'b', 5, PR_TRUE, 1 }, + { "abcdefg", 'c', 5, PR_TRUE, 2 }, + { "abcdefg", 'd', 5, PR_TRUE, 3 }, + { "abcdefg", 'e', 5, PR_TRUE, 4 }, + { "abcdefg", 'f', 5, PR_FALSE, 0 }, + { "abcdefg", 'g', 5, PR_FALSE, 0 }, + { "abcdefg", 'h', 5, PR_FALSE, 0 }, + { "abcdefg", '\0', 5, PR_FALSE, 0 }, + { "abcdefg", '\0', 15, PR_TRUE, 7 }, + { "abcdefg", 'A', 5, PR_FALSE, 0 }, + { "abcdefg", 'B', 5, PR_FALSE, 0 }, + { "abcdefg", 'C', 5, PR_FALSE, 0 }, + { "abcdefg", 'D', 5, PR_FALSE, 0 }, + { "abcdefg", 'E', 5, PR_FALSE, 0 }, + { "abcdefg", 'F', 5, PR_FALSE, 0 }, + { "abcdefg", 'G', 5, PR_FALSE, 0 }, + { "abcdefg", 'H', 5, PR_FALSE, 0 }, + { "abcdefgabcdefg", 'a', 10, PR_TRUE, 0 }, + { "abcdefgabcdefg", 'b', 10, PR_TRUE, 1 }, + { "abcdefgabcdefg", 'c', 10, PR_TRUE, 2 }, + { "abcdefgabcdefg", 'd', 10, PR_TRUE, 3 }, + { "abcdefgabcdefg", 'e', 10, PR_TRUE, 4 }, + { "abcdefgabcdefg", 'f', 10, PR_TRUE, 5 }, + { "abcdefgabcdefg", 'g', 10, PR_TRUE, 6 }, + { "abcdefgabcdefg", 'h', 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", '\0', 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", '\0', 14, PR_FALSE, 0 }, + { "abcdefgabcdefg", '\0', 15, PR_TRUE, 14 } + }; + + int i; + + printf("Test 017 (PL_strnchr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strnchr(array[i].str, array[i].chr, array[i].max); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%c/%lu -> %.32s, not zero\n", i, array[i].str, + array[i].chr, array[i].max, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%c/%lu -> null, not +%lu\n", i, array[i].str, + array[i].chr, array[i].max, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%c/%lu -> 0x%x, not 0x%x+%lu\n", i, array[i].str, + array[i].chr, array[i].max, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strnrchr */ +PRBool test_018(void) +{ + static struct + { + const char *str; + char chr; + PRUint32 max; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, 'a', 2, PR_FALSE, 0 }, + { (const char *)0, '\0', 2, PR_FALSE, 0 }, + { "abcdefg", 'a', 5, PR_TRUE, 0 }, + { "abcdefg", 'b', 5, PR_TRUE, 1 }, + { "abcdefg", 'c', 5, PR_TRUE, 2 }, + { "abcdefg", 'd', 5, PR_TRUE, 3 }, + { "abcdefg", 'e', 5, PR_TRUE, 4 }, + { "abcdefg", 'f', 5, PR_FALSE, 0 }, + { "abcdefg", 'g', 5, PR_FALSE, 0 }, + { "abcdefg", 'h', 5, PR_FALSE, 0 }, + { "abcdefg", '\0', 5, PR_FALSE, 0 }, + { "abcdefg", '\0', 15, PR_TRUE, 7 }, + { "abcdefg", 'A', 5, PR_FALSE, 0 }, + { "abcdefg", 'B', 5, PR_FALSE, 0 }, + { "abcdefg", 'C', 5, PR_FALSE, 0 }, + { "abcdefg", 'D', 5, PR_FALSE, 0 }, + { "abcdefg", 'E', 5, PR_FALSE, 0 }, + { "abcdefg", 'F', 5, PR_FALSE, 0 }, + { "abcdefg", 'G', 5, PR_FALSE, 0 }, + { "abcdefg", 'H', 5, PR_FALSE, 0 }, + { "abcdefgabcdefg", 'a', 10, PR_TRUE, 7 }, + { "abcdefgabcdefg", 'b', 10, PR_TRUE, 8 }, + { "abcdefgabcdefg", 'c', 10, PR_TRUE, 9 }, + { "abcdefgabcdefg", 'd', 10, PR_TRUE, 3 }, + { "abcdefgabcdefg", 'e', 10, PR_TRUE, 4 }, + { "abcdefgabcdefg", 'f', 10, PR_TRUE, 5 }, + { "abcdefgabcdefg", 'g', 10, PR_TRUE, 6 }, + { "abcdefgabcdefg", 'h', 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", '\0', 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", '\0', 14, PR_FALSE, 0 }, + { "abcdefgabcdefg", '\0', 15, PR_TRUE, 14 } + }; + + int i; + + printf("Test 018 (PL_strnrchr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strnrchr(array[i].str, array[i].chr, array[i].max); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%c/%lu -> %.32s, not zero\n", i, array[i].str, + array[i].chr, array[i].max, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%c/%lu -> null, not +%lu\n", i, array[i].str, + array[i].chr, array[i].max, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%c/%lu -> 0x%x, not 0x%x+%lu\n", i, array[i].str, + array[i].chr, array[i].max, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strpbrk */ +PRBool test_019(void) +{ + static struct + { + const char *str; + const char *chrs; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, PR_FALSE, 0 }, + { (const char *)0, "abc", PR_FALSE, 0 }, + { "abc", (const char *)0, PR_FALSE, 0 }, + { "abcdefg", "", PR_FALSE, 0 }, + { "", "aeiou", PR_FALSE, 0 }, + { "abcdefg", "ae", PR_TRUE, 0 }, + { "abcdefg", "ei", PR_TRUE, 4 }, + { "abcdefg", "io", PR_FALSE, 0 }, + { "abcdefg", "bcd", PR_TRUE, 1 }, + { "abcdefg", "cbd", PR_TRUE, 1 }, + { "abcdefg", "dbc", PR_TRUE, 1 }, + { "abcdefg", "ghi", PR_TRUE, 6 }, + { "abcdefg", "AE", PR_FALSE, 0 }, + { "abcdefg", "EI", PR_FALSE, 0 }, + { "abcdefg", "IO", PR_FALSE, 0 }, + { "abcdefg", "BCD", PR_FALSE, 0 }, + { "abcdefg", "CBD", PR_FALSE, 0 }, + { "abcdefg", "DBC", PR_FALSE, 0 }, + { "abcdefg", "GHI", PR_FALSE, 0 }, + { "abcdefgabcdefg", "ae", PR_TRUE, 0 }, + { "abcdefgabcdefg", "ei", PR_TRUE, 4 }, + { "abcdefgabcdefg", "io", PR_FALSE, 0 }, + { "abcdefgabcdefg", "bcd", PR_TRUE, 1 }, + { "abcdefgabcdefg", "cbd", PR_TRUE, 1 }, + { "abcdefgabcdefg", "dbc", PR_TRUE, 1 }, + { "abcdefgabcdefg", "ghi", PR_TRUE, 6 }, + { "abcdefgabcdefg", "AE", PR_FALSE, 0 }, + { "abcdefgabcdefg", "EI", PR_FALSE, 0 }, + { "abcdefgabcdefg", "IO", PR_FALSE, 0 }, + { "abcdefgabcdefg", "BCD", PR_FALSE, 0 }, + { "abcdefgabcdefg", "CBD", PR_FALSE, 0 }, + { "abcdefgabcdefg", "DBC", PR_FALSE, 0 }, + { "abcdefgabcdefg", "GHI", PR_FALSE, 0 } + }; + + int i; + + printf("Test 019 (PL_strpbrk) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strpbrk(array[i].str, array[i].chrs); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s -> null, not +%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strprbrk */ +PRBool test_020(void) +{ + static struct + { + const char *str; + const char *chrs; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, PR_FALSE, 0 }, + { (const char *)0, "abc", PR_FALSE, 0 }, + { "abc", (const char *)0, PR_FALSE, 0 }, + { "abcdefg", "", PR_FALSE, 0 }, + { "", "aeiou", PR_FALSE, 0 }, + { "abcdefg", "ae", PR_TRUE, 4 }, + { "abcdefg", "ei", PR_TRUE, 4 }, + { "abcdefg", "io", PR_FALSE, 0 }, + { "abcdefg", "bcd", PR_TRUE, 3 }, + { "abcdefg", "cbd", PR_TRUE, 3 }, + { "abcdefg", "dbc", PR_TRUE, 3 }, + { "abcdefg", "ghi", PR_TRUE, 6 }, + { "abcdefg", "AE", PR_FALSE, 0 }, + { "abcdefg", "EI", PR_FALSE, 0 }, + { "abcdefg", "IO", PR_FALSE, 0 }, + { "abcdefg", "BCD", PR_FALSE, 0 }, + { "abcdefg", "CBD", PR_FALSE, 0 }, + { "abcdefg", "DBC", PR_FALSE, 0 }, + { "abcdefg", "GHI", PR_FALSE, 0 }, + { "abcdefgabcdefg", "ae", PR_TRUE, 11 }, + { "abcdefgabcdefg", "ei", PR_TRUE, 11 }, + { "abcdefgabcdefg", "io", PR_FALSE, 0 }, + { "abcdefgabcdefg", "bcd", PR_TRUE, 10 }, + { "abcdefgabcdefg", "cbd", PR_TRUE, 10 }, + { "abcdefgabcdefg", "dbc", PR_TRUE, 10 }, + { "abcdefgabcdefg", "ghi", PR_TRUE, 13 }, + { "abcdefgabcdefg", "AE", PR_FALSE, 0 }, + { "abcdefgabcdefg", "EI", PR_FALSE, 0 }, + { "abcdefgabcdefg", "IO", PR_FALSE, 0 }, + { "abcdefgabcdefg", "BCD", PR_FALSE, 0 }, + { "abcdefgabcdefg", "CBD", PR_FALSE, 0 }, + { "abcdefgabcdefg", "DBC", PR_FALSE, 0 }, + { "abcdefgabcdefg", "GHI", PR_FALSE, 0 } + }; + + int i; + + printf("Test 020 (PL_strprbrk) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strprbrk(array[i].str, array[i].chrs); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s -> null, not +%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strnpbrk */ +PRBool test_021(void) +{ + static struct + { + const char *str; + const char *chrs; + PRUint32 max; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, 3, PR_FALSE, 0 }, + { (const char *)0, "abc", 3, PR_FALSE, 0 }, + { "abc", (const char *)0, 3, PR_FALSE, 0 }, + { "abcdefg", "", 3, PR_FALSE, 0 }, + { "", "aeiou", 3, PR_FALSE, 0 }, + { "abcdefg", "ae", 0, PR_FALSE, 0 }, + { "abcdefg", "ae", 1, PR_TRUE, 0 }, + { "abcdefg", "ae", 4, PR_TRUE, 0 }, + { "abcdefg", "ae", 5, PR_TRUE, 0 }, + { "abcdefg", "ae", 6, PR_TRUE, 0 }, + { "abcdefg", "ei", 4, PR_FALSE, 0 }, + { "abcdefg", "io", 10, PR_FALSE, 0 }, + { "abcdefg", "bcd", 2, PR_TRUE, 1 }, + { "abcdefg", "cbd", 2, PR_TRUE, 1 }, + { "abcdefg", "dbc", 2, PR_TRUE, 1 }, + { "abcdefg", "ghi", 6, PR_FALSE, 0 }, + { "abcdefg", "ghi", 7, PR_TRUE, 6 }, + { "abcdefg", "AE", 9, PR_FALSE, 0 }, + { "abcdefg", "EI", 9, PR_FALSE, 0 }, + { "abcdefg", "IO", 9, PR_FALSE, 0 }, + { "abcdefg", "BCD", 9, PR_FALSE, 0 }, + { "abcdefg", "CBD", 9, PR_FALSE, 0 }, + { "abcdefg", "DBC", 9, PR_FALSE, 0 }, + { "abcdefg", "GHI", 9, PR_FALSE, 0 }, + { "abcdefgabcdefg", "ae", 10, PR_TRUE, 0 }, + { "abcdefgabcdefg", "ei", 10, PR_TRUE, 4 }, + { "abcdefgabcdefg", "io", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "bcd", 10, PR_TRUE, 1 }, + { "abcdefgabcdefg", "cbd", 10, PR_TRUE, 1 }, + { "abcdefgabcdefg", "dbc", 10, PR_TRUE, 1 }, + { "abcdefgabcdefg", "ghi", 10, PR_TRUE, 6 }, + { "abcdefgabcdefg", "AE", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "EI", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "IO", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "BCD", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "CBD", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "DBC", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "GHI", 10, PR_FALSE, 0 } + }; + + int i; + + printf("Test 021 (PL_strnpbrk) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strnpbrk(array[i].str, array[i].chrs, array[i].max); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + array[i].max, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s/%lu -> null, not +%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + array[i].max, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + array[i].max, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strnprbrk */ +PRBool test_022(void) +{ + static struct + { + const char *str; + const char *chrs; + PRUint32 max; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, 3, PR_FALSE, 0 }, + { (const char *)0, "abc", 3, PR_FALSE, 0 }, + { "abc", (const char *)0, 3, PR_FALSE, 0 }, + { "abcdefg", "", 3, PR_FALSE, 0 }, + { "", "aeiou", 3, PR_FALSE, 0 }, + { "abcdefg", "ae", 0, PR_FALSE, 0 }, + { "abcdefg", "ae", 1, PR_TRUE, 0 }, + { "abcdefg", "ae", 4, PR_TRUE, 0 }, + { "abcdefg", "ae", 5, PR_TRUE, 4 }, + { "abcdefg", "ae", 6, PR_TRUE, 4 }, + { "abcdefg", "ei", 4, PR_FALSE, 0 }, + { "abcdefg", "io", 10, PR_FALSE, 0 }, + { "abcdefg", "bcd", 2, PR_TRUE, 1 }, + { "abcdefg", "cbd", 2, PR_TRUE, 1 }, + { "abcdefg", "dbc", 2, PR_TRUE, 1 }, + { "abcdefg", "bcd", 3, PR_TRUE, 2 }, + { "abcdefg", "cbd", 3, PR_TRUE, 2 }, + { "abcdefg", "dbc", 3, PR_TRUE, 2 }, + { "abcdefg", "bcd", 5, PR_TRUE, 3 }, + { "abcdefg", "cbd", 5, PR_TRUE, 3 }, + { "abcdefg", "dbc", 5, PR_TRUE, 3 }, + { "abcdefg", "bcd", 15, PR_TRUE, 3 }, + { "abcdefg", "cbd", 15, PR_TRUE, 3 }, + { "abcdefg", "dbc", 15, PR_TRUE, 3 }, + { "abcdefg", "ghi", 6, PR_FALSE, 0 }, + { "abcdefg", "ghi", 7, PR_TRUE, 6 }, + { "abcdefg", "AE", 9, PR_FALSE, 0 }, + { "abcdefg", "EI", 9, PR_FALSE, 0 }, + { "abcdefg", "IO", 9, PR_FALSE, 0 }, + { "abcdefg", "BCD", 9, PR_FALSE, 0 }, + { "abcdefg", "CBD", 9, PR_FALSE, 0 }, + { "abcdefg", "DBC", 9, PR_FALSE, 0 }, + { "abcdefg", "GHI", 9, PR_FALSE, 0 }, + { "abcdefgabcdefg", "ae", 10, PR_TRUE, 7 }, + { "abcdefgabcdefg", "ei", 10, PR_TRUE, 4 }, + { "abcdefgabcdefg", "io", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "bcd", 10, PR_TRUE, 9 }, + { "abcdefgabcdefg", "cbd", 10, PR_TRUE, 9 }, + { "abcdefgabcdefg", "dbc", 10, PR_TRUE, 9 }, + { "abcdefgabcdefg", "ghi", 10, PR_TRUE, 6 }, + { "abcdefgabcdefg", "AE", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "EI", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "IO", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "BCD", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "CBD", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "DBC", 10, PR_FALSE, 0 }, + { "abcdefgabcdefg", "GHI", 10, PR_FALSE, 0 } + }; + + int i; + + printf("Test 022 (PL_strnprbrk) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strnprbrk(array[i].str, array[i].chrs, array[i].max); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + array[i].max, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s/%lu -> null, not +%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + array[i].max, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].chrs ? array[i].chrs : "(null)", + array[i].max, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strstr */ +PRBool test_023(void) +{ + static struct + { + const char *str; + const char *sub; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, PR_FALSE, 0 }, + { (const char *)0, "blah", PR_FALSE, 0 }, + { "blah-de-blah", (const char *)0, PR_FALSE, 0 }, + { "blah-de-blah", "blah", PR_TRUE, 0 }, + { "", "blah", PR_FALSE, 0 }, + { "blah-de-blah", "", PR_FALSE, 0 }, + { "abcdefg", "a", PR_TRUE, 0 }, + { "abcdefg", "c", PR_TRUE, 2 }, + { "abcdefg", "e", PR_TRUE, 4 }, + { "abcdefg", "g", PR_TRUE, 6 }, + { "abcdefg", "i", PR_FALSE, 0 }, + { "abcdefg", "ab", PR_TRUE, 0 }, + { "abcdefg", "cd", PR_TRUE, 2 }, + { "abcdefg", "ef", PR_TRUE, 4 }, + { "abcdefg", "gh", PR_FALSE, 0 }, + { "abcdabc", "bc", PR_TRUE, 1 }, + { "abcdefg", "abcdefg", PR_TRUE, 0 }, + { "abcdefgabcdefg", "a", PR_TRUE, 0 }, + { "abcdefgabcdefg", "c", PR_TRUE, 2 }, + { "abcdefgabcdefg", "e", PR_TRUE, 4 }, + { "abcdefgabcdefg", "g", PR_TRUE, 6 }, + { "abcdefgabcdefg", "i", PR_FALSE, 0 }, + { "abcdefgabcdefg", "ab", PR_TRUE, 0 }, + { "abcdefgabcdefg", "cd", PR_TRUE, 2 }, + { "abcdefgabcdefg", "ef", PR_TRUE, 4 }, + { "abcdefgabcdefg", "gh", PR_FALSE, 0 }, + { "abcdabcabcdabc", "bc", PR_TRUE, 1 }, + { "abcdefgabcdefg", "abcdefg", PR_TRUE, 0 }, + { "ABCDEFG", "a", PR_FALSE, 0 }, + { "ABCDEFG", "c", PR_FALSE, 0 }, + { "ABCDEFG", "e", PR_FALSE, 0 }, + { "ABCDEFG", "g", PR_FALSE, 0 }, + { "ABCDEFG", "i", PR_FALSE, 0 }, + { "ABCDEFG", "ab", PR_FALSE, 0 }, + { "ABCDEFG", "cd", PR_FALSE, 0 }, + { "ABCDEFG", "ef", PR_FALSE, 0 }, + { "ABCDEFG", "gh", PR_FALSE, 0 }, + { "ABCDABC", "bc", PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "a", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "c", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "e", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "g", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ab", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "cd", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ef", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", PR_FALSE, 0 } + }; + + int i; + + printf("Test 023 (PL_strstr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strstr(array[i].str, array[i].sub); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].str, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strrstr */ +PRBool test_024(void) +{ + static struct + { + const char *str; + const char *sub; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, PR_FALSE, 0 }, + { (const char *)0, "blah", PR_FALSE, 0 }, + { "blah-de-blah", (const char *)0, PR_FALSE, 0 }, + { "blah-de-blah", "blah", PR_TRUE, 8 }, + { "", "blah", PR_FALSE, 0 }, + { "blah-de-blah", "", PR_FALSE, 0 }, + { "abcdefg", "a", PR_TRUE, 0 }, + { "abcdefg", "c", PR_TRUE, 2 }, + { "abcdefg", "e", PR_TRUE, 4 }, + { "abcdefg", "g", PR_TRUE, 6 }, + { "abcdefg", "i", PR_FALSE, 0 }, + { "abcdefg", "ab", PR_TRUE, 0 }, + { "abcdefg", "cd", PR_TRUE, 2 }, + { "abcdefg", "ef", PR_TRUE, 4 }, + { "abcdefg", "gh", PR_FALSE, 0 }, + { "abcdabc", "bc", PR_TRUE, 5 }, + { "abcdefg", "abcdefg", PR_TRUE, 0 }, + { "abcdefgabcdefg", "a", PR_TRUE, 7 }, + { "abcdefgabcdefg", "c", PR_TRUE, 9 }, + { "abcdefgabcdefg", "e", PR_TRUE, 11 }, + { "abcdefgabcdefg", "g", PR_TRUE, 13 }, + { "abcdefgabcdefg", "i", PR_FALSE, 0 }, + { "abcdefgabcdefg", "ab", PR_TRUE, 7 }, + { "abcdefgabcdefg", "cd", PR_TRUE, 9 }, + { "abcdefgabcdefg", "ef", PR_TRUE, 11 }, + { "abcdefgabcdefg", "gh", PR_FALSE, 0 }, + { "abcdabcabcdabc", "bc", PR_TRUE, 12 }, + { "abcdefgabcdefg", "abcdefg", PR_TRUE, 7 }, + { "ABCDEFG", "a", PR_FALSE, 0 }, + { "ABCDEFG", "c", PR_FALSE, 0 }, + { "ABCDEFG", "e", PR_FALSE, 0 }, + { "ABCDEFG", "g", PR_FALSE, 0 }, + { "ABCDEFG", "i", PR_FALSE, 0 }, + { "ABCDEFG", "ab", PR_FALSE, 0 }, + { "ABCDEFG", "cd", PR_FALSE, 0 }, + { "ABCDEFG", "ef", PR_FALSE, 0 }, + { "ABCDEFG", "gh", PR_FALSE, 0 }, + { "ABCDABC", "bc", PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "a", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "c", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "e", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "g", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ab", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "cd", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ef", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", PR_FALSE, 0 } + }; + + int i; + + printf("Test 024 (PL_strrstr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strrstr(array[i].str, array[i].sub); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].str, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strnstr */ +PRBool test_025(void) +{ + static struct + { + const char *str; + const char *sub; + PRUint32 max; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, 12, PR_FALSE, 0 }, + { (const char *)0, "blah", 12, PR_FALSE, 0 }, + { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 0, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 2, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 3, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 4, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 5, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 12, PR_TRUE, 0 }, + { "", "blah", 12, PR_FALSE, 0 }, + { "blah-de-blah", "", 12, PR_FALSE, 0 }, + { "abcdefg", "a", 5, PR_TRUE, 0 }, + { "abcdefg", "c", 5, PR_TRUE, 2 }, + { "abcdefg", "e", 5, PR_TRUE, 4 }, + { "abcdefg", "g", 5, PR_FALSE, 0 }, + { "abcdefg", "i", 5, PR_FALSE, 0 }, + { "abcdefg", "ab", 5, PR_TRUE, 0 }, + { "abcdefg", "cd", 5, PR_TRUE, 2 }, + { "abcdefg", "ef", 5, PR_FALSE, 0 }, + { "abcdefg", "gh", 5, PR_FALSE, 0 }, + { "abcdabc", "bc", 5, PR_TRUE, 1 }, + { "abcdabc", "bc", 6, PR_TRUE, 1 }, + { "abcdabc", "bc", 7, PR_TRUE, 1 }, + { "abcdefg", "abcdefg", 6, PR_FALSE, 0 }, + { "abcdefg", "abcdefg", 7, PR_TRUE, 0 }, + { "abcdefg", "abcdefg", 8, PR_TRUE, 0 }, + { "abcdefgabcdefg", "a", 12, PR_TRUE, 0 }, + { "abcdefgabcdefg", "c", 12, PR_TRUE, 2 }, + { "abcdefgabcdefg", "e", 12, PR_TRUE, 4 }, + { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 }, + { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 }, + { "abcdefgabcdefg", "ab", 12, PR_TRUE, 0 }, + { "abcdefgabcdefg", "cd", 12, PR_TRUE, 2 }, + { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 }, + { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 }, + { "abcdabcabcdabc", "bc", 5, PR_TRUE, 1 }, + { "abcdabcabcdabc", "bc", 6, PR_TRUE, 1 }, + { "abcdabcabcdabc", "bc", 7, PR_TRUE, 1 }, + { "abcdefgabcdefg", "abcdefg", 6, PR_FALSE, 0 }, + { "abcdefgabcdefg", "abcdefg", 7, PR_TRUE, 0 }, + { "abcdefgabcdefg", "abcdefg", 8, PR_TRUE, 0 }, + { "ABCDEFG", "a", 5, PR_FALSE, 0 }, + { "ABCDEFG", "c", 5, PR_FALSE, 0 }, + { "ABCDEFG", "e", 5, PR_FALSE, 0 }, + { "ABCDEFG", "g", 5, PR_FALSE, 0 }, + { "ABCDEFG", "i", 5, PR_FALSE, 0 }, + { "ABCDEFG", "ab", 5, PR_FALSE, 0 }, + { "ABCDEFG", "cd", 5, PR_FALSE, 0 }, + { "ABCDEFG", "ef", 5, PR_FALSE, 0 }, + { "ABCDEFG", "gh", 5, PR_FALSE, 0 }, + { "ABCDABC", "bc", 5, PR_FALSE, 0 }, + { "ABCDABC", "bc", 6, PR_FALSE, 0 }, + { "ABCDABC", "bc", 7, PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", 7, PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", 8, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "a", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "c", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "e", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "g", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ab", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "cd", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ef", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", 5, PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", 6, PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", 7, PR_FALSE, }, + { "ABCDEFGABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", 7, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", 8, PR_FALSE, 0 } + }; + + int i; + + printf("Test 025 (PL_strnstr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strnstr(array[i].str, array[i].sub, array[i].max); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, array[i].str, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strnrstr */ +PRBool test_026(void) +{ + static struct + { + const char *str; + const char *sub; + PRUint32 max; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, 12, PR_FALSE, 0 }, + { (const char *)0, "blah", 12, PR_FALSE, 0 }, + { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 0, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 2, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 3, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 4, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 5, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 11, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 12, PR_TRUE, 8 }, + { "blah-de-blah", "blah", 13, PR_TRUE, 8 }, + { "", "blah", 12, PR_FALSE, 0 }, + { "blah-de-blah", "", 12, PR_FALSE, 0 }, + { "abcdefg", "a", 5, PR_TRUE, 0 }, + { "abcdefg", "c", 5, PR_TRUE, 2 }, + { "abcdefg", "e", 5, PR_TRUE, 4 }, + { "abcdefg", "g", 5, PR_FALSE, 0 }, + { "abcdefg", "i", 5, PR_FALSE, 0 }, + { "abcdefg", "ab", 5, PR_TRUE, 0 }, + { "abcdefg", "cd", 5, PR_TRUE, 2 }, + { "abcdefg", "ef", 5, PR_FALSE, 0 }, + { "abcdefg", "gh", 5, PR_FALSE, 0 }, + { "abcdabc", "bc", 5, PR_TRUE, 1 }, + { "abcdabc", "bc", 6, PR_TRUE, 1 }, + { "abcdabc", "bc", 7, PR_TRUE, 5 }, + { "abcdefg", "abcdefg", 6, PR_FALSE, 0 }, + { "abcdefg", "abcdefg", 7, PR_TRUE, 0 }, + { "abcdefg", "abcdefg", 8, PR_TRUE, 0 }, + { "abcdefgabcdefg", "a", 12, PR_TRUE, 7 }, + { "abcdefgabcdefg", "c", 12, PR_TRUE, 9 }, + { "abcdefgabcdefg", "e", 12, PR_TRUE, 11 }, + { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 }, + { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 }, + { "abcdefgabcdefg", "ab", 12, PR_TRUE, 7 }, + { "abcdefgabcdefg", "cd", 12, PR_TRUE, 9 }, + { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 }, + { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 }, + { "abcdabcabcdabc", "bc", 12, PR_TRUE, 8 }, + { "abcdabcabcdabc", "bc", 13, PR_TRUE, 8 }, + { "abcdabcabcdabc", "bc", 14, PR_TRUE, 12 }, + { "abcdefgabcdefg", "abcdefg", 13, PR_TRUE, 0 }, + { "abcdefgabcdefg", "abcdefg", 14, PR_TRUE, 7 }, + { "abcdefgabcdefg", "abcdefg", 15, PR_TRUE, 7 }, + { "ABCDEFG", "a", 5, PR_FALSE, 0 }, + { "ABCDEFG", "c", 5, PR_FALSE, 0 }, + { "ABCDEFG", "e", 5, PR_FALSE, 0 }, + { "ABCDEFG", "g", 5, PR_FALSE, 0 }, + { "ABCDEFG", "i", 5, PR_FALSE, 0 }, + { "ABCDEFG", "ab", 5, PR_FALSE, 0 }, + { "ABCDEFG", "cd", 5, PR_FALSE, 0 }, + { "ABCDEFG", "ef", 5, PR_FALSE, 0 }, + { "ABCDEFG", "gh", 5, PR_FALSE, 0 }, + { "ABCDABC", "bc", 5, PR_FALSE, 0 }, + { "ABCDABC", "bc", 6, PR_FALSE, 0 }, + { "ABCDABC", "bc", 7, PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", 7, PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", 8, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "a", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "c", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "e", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "g", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ab", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "cd", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ef", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", 12, PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", 13, PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", 14, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", 13, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", 14, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", 15, PR_FALSE, 0 } + }; + + int i; + + printf("Test 026 (PL_strnrstr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strnrstr(array[i].str, array[i].sub, array[i].max); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, array[i].str, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strcasestr */ +PRBool test_027(void) +{ + static struct + { + const char *str; + const char *sub; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, PR_FALSE, 0 }, + { (const char *)0, "blah", PR_FALSE, 0 }, + { "blah-de-blah", (const char *)0, PR_FALSE, 0 }, + { "blah-de-blah", "blah", PR_TRUE, 0 }, + { "", "blah", PR_FALSE, 0 }, + { "blah-de-blah", "", PR_FALSE, 0 }, + { "abcdefg", "a", PR_TRUE, 0 }, + { "abcdefg", "c", PR_TRUE, 2 }, + { "abcdefg", "e", PR_TRUE, 4 }, + { "abcdefg", "g", PR_TRUE, 6 }, + { "abcdefg", "i", PR_FALSE, 0 }, + { "abcdefg", "ab", PR_TRUE, 0 }, + { "abcdefg", "cd", PR_TRUE, 2 }, + { "abcdefg", "ef", PR_TRUE, 4 }, + { "abcdefg", "gh", PR_FALSE, 0 }, + { "abcdabc", "bc", PR_TRUE, 1 }, + { "abcdefg", "abcdefg", PR_TRUE, 0 }, + { "abcdefgabcdefg", "a", PR_TRUE, 0 }, + { "abcdefgabcdefg", "c", PR_TRUE, 2 }, + { "abcdefgabcdefg", "e", PR_TRUE, 4 }, + { "abcdefgabcdefg", "g", PR_TRUE, 6 }, + { "abcdefgabcdefg", "i", PR_FALSE, 0 }, + { "abcdefgabcdefg", "ab", PR_TRUE, 0 }, + { "abcdefgabcdefg", "cd", PR_TRUE, 2 }, + { "abcdefgabcdefg", "ef", PR_TRUE, 4 }, + { "abcdefgabcdefg", "gh", PR_FALSE, 0 }, + { "abcdabcabcdabc", "bc", PR_TRUE, 1 }, + { "abcdefgabcdefg", "abcdefg", PR_TRUE, 0 }, + { "ABCDEFG", "a", PR_TRUE, 0 }, + { "ABCDEFG", "c", PR_TRUE, 2 }, + { "ABCDEFG", "e", PR_TRUE, 4 }, + { "ABCDEFG", "g", PR_TRUE, 6 }, + { "ABCDEFG", "i", PR_FALSE, 0 }, + { "ABCDEFG", "ab", PR_TRUE, 0 }, + { "ABCDEFG", "cd", PR_TRUE, 2 }, + { "ABCDEFG", "ef", PR_TRUE, 4 }, + { "ABCDEFG", "gh", PR_FALSE, 0 }, + { "ABCDABC", "bc", PR_TRUE, 1 }, + { "ABCDEFG", "abcdefg", PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "a", PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "c", PR_TRUE, 2 }, + { "ABCDEFGABCDEFG", "e", PR_TRUE, 4 }, + { "ABCDEFGABCDEFG", "g", PR_TRUE, 6 }, + { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ab", PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "cd", PR_TRUE, 2 }, + { "ABCDEFGABCDEFG", "ef", PR_TRUE, 4 }, + { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", PR_TRUE, 1 }, + { "ABCDEFGABCDEFG", "abcdefg", PR_TRUE, 0 } + }; + + int i; + + printf("Test 027 (PL_strcasestr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strcasestr(array[i].str, array[i].sub); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].str, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strcaserstr */ +PRBool test_028(void) +{ + static struct + { + const char *str; + const char *sub; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, PR_FALSE, 0 }, + { (const char *)0, "blah", PR_FALSE, 0 }, + { "blah-de-blah", (const char *)0, PR_FALSE, 0 }, + { "blah-de-blah", "blah", PR_TRUE, 8 }, + { "", "blah", PR_FALSE, 0 }, + { "blah-de-blah", "", PR_FALSE, 0 }, + { "abcdefg", "a", PR_TRUE, 0 }, + { "abcdefg", "c", PR_TRUE, 2 }, + { "abcdefg", "e", PR_TRUE, 4 }, + { "abcdefg", "g", PR_TRUE, 6 }, + { "abcdefg", "i", PR_FALSE, 0 }, + { "abcdefg", "ab", PR_TRUE, 0 }, + { "abcdefg", "cd", PR_TRUE, 2 }, + { "abcdefg", "ef", PR_TRUE, 4 }, + { "abcdefg", "gh", PR_FALSE, 0 }, + { "abcdabc", "bc", PR_TRUE, 5 }, + { "abcdefg", "abcdefg", PR_TRUE, 0 }, + { "abcdefgabcdefg", "a", PR_TRUE, 7 }, + { "abcdefgabcdefg", "c", PR_TRUE, 9 }, + { "abcdefgabcdefg", "e", PR_TRUE, 11 }, + { "abcdefgabcdefg", "g", PR_TRUE, 13 }, + { "abcdefgabcdefg", "i", PR_FALSE, 0 }, + { "abcdefgabcdefg", "ab", PR_TRUE, 7 }, + { "abcdefgabcdefg", "cd", PR_TRUE, 9 }, + { "abcdefgabcdefg", "ef", PR_TRUE, 11 }, + { "abcdefgabcdefg", "gh", PR_FALSE, 0 }, + { "abcdabcabcdabc", "bc", PR_TRUE, 12 }, + { "abcdefgabcdefg", "abcdefg", PR_TRUE, 7 }, + { "ABCDEFG", "a", PR_TRUE, 0 }, + { "ABCDEFG", "c", PR_TRUE, 2 }, + { "ABCDEFG", "e", PR_TRUE, 4 }, + { "ABCDEFG", "g", PR_TRUE, 6 }, + { "ABCDEFG", "i", PR_FALSE, 0 }, + { "ABCDEFG", "ab", PR_TRUE, 0 }, + { "ABCDEFG", "cd", PR_TRUE, 2 }, + { "ABCDEFG", "ef", PR_TRUE, 4 }, + { "ABCDEFG", "gh", PR_FALSE, 0 }, + { "ABCDABC", "bc", PR_TRUE, 5 }, + { "ABCDEFG", "abcdefg", PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "a", PR_TRUE, 7 }, + { "ABCDEFGABCDEFG", "c", PR_TRUE, 9 }, + { "ABCDEFGABCDEFG", "e", PR_TRUE, 11 }, + { "ABCDEFGABCDEFG", "g", PR_TRUE, 13 }, + { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ab", PR_TRUE, 7 }, + { "ABCDEFGABCDEFG", "cd", PR_TRUE, 9 }, + { "ABCDEFGABCDEFG", "ef", PR_TRUE, 11 }, + { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", PR_TRUE, 12 }, + { "ABCDEFGABCDEFG", "abcdefg", PR_TRUE, 7 } + }; + + int i; + + printf("Test 028 (PL_strcaserstr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strcaserstr(array[i].str, array[i].sub); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].str, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strncasestr */ +PRBool test_029(void) +{ + static struct + { + const char *str; + const char *sub; + PRUint32 max; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, 12, PR_FALSE, 0 }, + { (const char *)0, "blah", 12, PR_FALSE, 0 }, + { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 0, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 2, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 3, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 4, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 5, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 12, PR_TRUE, 0 }, + { "", "blah", 12, PR_FALSE, 0 }, + { "blah-de-blah", "", 12, PR_FALSE, 0 }, + { "abcdefg", "a", 5, PR_TRUE, 0 }, + { "abcdefg", "c", 5, PR_TRUE, 2 }, + { "abcdefg", "e", 5, PR_TRUE, 4 }, + { "abcdefg", "g", 5, PR_FALSE, 0 }, + { "abcdefg", "i", 5, PR_FALSE, 0 }, + { "abcdefg", "ab", 5, PR_TRUE, 0 }, + { "abcdefg", "cd", 5, PR_TRUE, 2 }, + { "abcdefg", "ef", 5, PR_FALSE, 0 }, + { "abcdefg", "gh", 5, PR_FALSE, 0 }, + { "abcdabc", "bc", 5, PR_TRUE, 1 }, + { "abcdabc", "bc", 6, PR_TRUE, 1 }, + { "abcdabc", "bc", 7, PR_TRUE, 1 }, + { "abcdefg", "abcdefg", 6, PR_FALSE, 0 }, + { "abcdefg", "abcdefg", 7, PR_TRUE, 0 }, + { "abcdefg", "abcdefg", 8, PR_TRUE, 0 }, + { "abcdefgabcdefg", "a", 12, PR_TRUE, 0 }, + { "abcdefgabcdefg", "c", 12, PR_TRUE, 2 }, + { "abcdefgabcdefg", "e", 12, PR_TRUE, 4 }, + { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 }, + { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 }, + { "abcdefgabcdefg", "ab", 12, PR_TRUE, 0 }, + { "abcdefgabcdefg", "cd", 12, PR_TRUE, 2 }, + { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 }, + { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 }, + { "abcdabcabcdabc", "bc", 5, PR_TRUE, 1 }, + { "abcdabcabcdabc", "bc", 6, PR_TRUE, 1 }, + { "abcdabcabcdabc", "bc", 7, PR_TRUE, 1 }, + { "abcdefgabcdefg", "abcdefg", 6, PR_FALSE, 0 }, + { "abcdefgabcdefg", "abcdefg", 7, PR_TRUE, 0 }, + { "abcdefgabcdefg", "abcdefg", 8, PR_TRUE, 0 }, + { "ABCDEFG", "a", 5, PR_TRUE, 0 }, + { "ABCDEFG", "c", 5, PR_TRUE, 2 }, + { "ABCDEFG", "e", 5, PR_TRUE, 4 }, + { "ABCDEFG", "g", 5, PR_FALSE, 0 }, + { "ABCDEFG", "i", 5, PR_FALSE, 0 }, + { "ABCDEFG", "ab", 5, PR_TRUE, 0 }, + { "ABCDEFG", "cd", 5, PR_TRUE, 2 }, + { "ABCDEFG", "ef", 5, PR_FALSE, 0 }, + { "ABCDEFG", "gh", 5, PR_FALSE, 0 }, + { "ABCDABC", "bc", 5, PR_TRUE, 1 }, + { "ABCDABC", "bc", 6, PR_TRUE, 1 }, + { "ABCDABC", "bc", 7, PR_TRUE, 1 }, + { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", 7, PR_TRUE, 0 }, + { "ABCDEFG", "abcdefg", 8, PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "a", 12, PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "c", 12, PR_TRUE, 2 }, + { "ABCDEFGABCDEFG", "e", 12, PR_TRUE, 4 }, + { "ABCDEFGABCDEFG", "g", 12, PR_TRUE, 6 }, + { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ab", 12, PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "cd", 12, PR_TRUE, 2 }, + { "ABCDEFGABCDEFG", "ef", 12, PR_TRUE, 4 }, + { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", 5, PR_TRUE, 1 }, + { "ABCDABCABCDABC", "bc", 6, PR_TRUE, 1 }, + { "ABCDABCABCDABC", "bc", 7, PR_TRUE, 1 }, + { "ABCDEFGABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", 7, PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", 8, PR_TRUE, 0 } + }; + + int i; + + printf("Test 029 (PL_strncasestr) ..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strncasestr(array[i].str, array[i].sub, array[i].max); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, array[i].str, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strncaserstr */ +PRBool test_030(void) +{ + static struct + { + const char *str; + const char *sub; + PRUint32 max; + PRBool ret; + PRUint32 off; + } array[] = + { + { (const char *)0, (const char *)0, 12, PR_FALSE, 0 }, + { (const char *)0, "blah", 12, PR_FALSE, 0 }, + { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 0, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 2, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 3, PR_FALSE, 0 }, + { "blah-de-blah", "blah", 4, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 5, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 11, PR_TRUE, 0 }, + { "blah-de-blah", "blah", 12, PR_TRUE, 8 }, + { "blah-de-blah", "blah", 13, PR_TRUE, 8 }, + { "", "blah", 12, PR_FALSE, 0 }, + { "blah-de-blah", "", 12, PR_FALSE, 0 }, + { "abcdefg", "a", 5, PR_TRUE, 0 }, + { "abcdefg", "c", 5, PR_TRUE, 2 }, + { "abcdefg", "e", 5, PR_TRUE, 4 }, + { "abcdefg", "g", 5, PR_FALSE, 0 }, + { "abcdefg", "i", 5, PR_FALSE, 0 }, + { "abcdefg", "ab", 5, PR_TRUE, 0 }, + { "abcdefg", "cd", 5, PR_TRUE, 2 }, + { "abcdefg", "ef", 5, PR_FALSE, 0 }, + { "abcdefg", "gh", 5, PR_FALSE, 0 }, + { "abcdabc", "bc", 5, PR_TRUE, 1 }, + { "abcdabc", "bc", 6, PR_TRUE, 1 }, + { "abcdabc", "bc", 7, PR_TRUE, 5 }, + { "abcdefg", "abcdefg", 6, PR_FALSE, 0 }, + { "abcdefg", "abcdefg", 7, PR_TRUE, 0 }, + { "abcdefg", "abcdefg", 8, PR_TRUE, 0 }, + { "abcdefgabcdefg", "a", 12, PR_TRUE, 7 }, + { "abcdefgabcdefg", "c", 12, PR_TRUE, 9 }, + { "abcdefgabcdefg", "e", 12, PR_TRUE, 11 }, + { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 }, + { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 }, + { "abcdefgabcdefg", "ab", 12, PR_TRUE, 7 }, + { "abcdefgabcdefg", "cd", 12, PR_TRUE, 9 }, + { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 }, + { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 }, + { "abcdabcabcdabc", "bc", 12, PR_TRUE, 8 }, + { "abcdabcabcdabc", "bc", 13, PR_TRUE, 8 }, + { "abcdabcabcdabc", "bc", 14, PR_TRUE, 12 }, + { "abcdefgabcdefg", "abcdefg", 13, PR_TRUE, 0 }, + { "abcdefgabcdefg", "abcdefg", 14, PR_TRUE, 7 }, + { "abcdefgabcdefg", "abcdefg", 15, PR_TRUE, 7 }, + { "ABCDEFG", "a", 5, PR_TRUE, 0 }, + { "ABCDEFG", "c", 5, PR_TRUE, 2 }, + { "ABCDEFG", "e", 5, PR_TRUE, 4 }, + { "ABCDEFG", "g", 5, PR_FALSE, 0 }, + { "ABCDEFG", "i", 5, PR_FALSE, 0 }, + { "ABCDEFG", "ab", 5, PR_TRUE, 0 }, + { "ABCDEFG", "cd", 5, PR_TRUE, 2 }, + { "ABCDEFG", "ef", 5, PR_FALSE, 0 }, + { "ABCDEFG", "gh", 5, PR_FALSE, 0 }, + { "ABCDABC", "bc", 5, PR_TRUE, 1 }, + { "ABCDABC", "bc", 6, PR_TRUE, 1 }, + { "ABCDABC", "bc", 7, PR_TRUE, 5 }, + { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 }, + { "ABCDEFG", "abcdefg", 7, PR_TRUE, 0 }, + { "ABCDEFG", "abcdefg", 8, PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "a", 12, PR_TRUE, 7 }, + { "ABCDEFGABCDEFG", "c", 12, PR_TRUE, 9 }, + { "ABCDEFGABCDEFG", "e", 12, PR_TRUE, 11 }, + { "ABCDEFGABCDEFG", "g", 12, PR_TRUE, 6 }, + { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 }, + { "ABCDEFGABCDEFG", "ab", 12, PR_TRUE, 7 }, + { "ABCDEFGABCDEFG", "cd", 12, PR_TRUE, 9 }, + { "ABCDEFGABCDEFG", "ef", 12, PR_TRUE, 4 }, + { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 }, + { "ABCDABCABCDABC", "bc", 12, PR_TRUE, 8 }, + { "ABCDABCABCDABC", "bc", 13, PR_TRUE, 8 }, + { "ABCDABCABCDABC", "bc", 14, PR_TRUE, 12 }, + { "ABCDEFGABCDEFG", "abcdefg", 13, PR_TRUE, 0 }, + { "ABCDEFGABCDEFG", "abcdefg", 14, PR_TRUE, 7 }, + { "ABCDEFGABCDEFG", "abcdefg", 15, PR_TRUE, 7 } + }; + + int i; + + printf("Test 030 (PL_strncaserstr)..."); fflush(stdout); + + for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ ) + { + char *rv = PL_strncaserstr(array[i].str, array[i].sub, array[i].max); + + if( PR_FALSE == array[i].ret ) + { + if( (char *)0 != rv ) + { + printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, rv); + return PR_FALSE; + } + } + else + { + if( (char *)0 == rv ) + { + printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, array[i].str, array[i].off); + return PR_FALSE; + } + + if( &array[i].str[ array[i].off ] != rv ) + { + printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i, + array[i].str ? array[i].str : "(null)", + array[i].sub ? array[i].sub : "(null)", + array[i].max, rv, array[i].str, array[i].off); + return PR_FALSE; + } + } + } + + printf("PASS\n"); + return PR_TRUE; +} + +/* PL_strtok_r */ +PRBool test_031(void) +{ + static const char *tokens[] = { + "wtc", "relyea", "nelsonb", "jpierre", "nicolson", + "ian.mcgreer", "kirk.erickson", "sonja.mirtitsch", "mhein" + }; + + static const char *seps[] = { + ", ", ",", " ", "\t", ",,,", " ,", " ", " \t\t", "," + }; + + static const char s2[] = ", \t"; + + char string[ 1024 ]; + char *s1; + char *token; + char *lasts; + unsigned int i; + + printf("Test 031 (PL_strtok_r) ..."); fflush(stdout); + + /* Build the string. */ + string[0] = '\0'; + for( i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++ ) + { + PL_strcat(string, tokens[i]); + PL_strcat(string, seps[i]); + } + + /* Scan the string for tokens. */ + i = 0; + s1 = string; + while( (token = PL_strtok_r(s1, s2, &lasts)) != NULL) + { + if( PL_strcmp(token, tokens[i]) != 0 ) + { + printf("FAIL wrong token scanned\n"); + return PR_FALSE; + } + i++; + s1 = NULL; + } + if( i != sizeof(tokens)/sizeof(tokens[0]) ) + { + printf("FAIL wrong number of tokens scanned\n"); + return PR_FALSE; + } + + printf("PASS\n"); + return PR_TRUE; +} + +int +main +( + int argc, + char *argv[] +) +{ + printf("Testing the Portable Library string functions:\n"); + + if( 1 + && test_001() + && test_001() + && test_002() + && test_003() + && test_004() + && test_005() + && test_006() + && test_007() + && test_008() + && test_009() + && test_010() + && test_011() + && test_012() + && test_013() + && test_014() + && test_015() + && test_016() + && test_017() + && test_018() + && test_019() + && test_020() + && test_021() + && test_022() + && test_023() + && test_024() + && test_025() + && test_026() + && test_027() + && test_028() + && test_029() + && test_030() + && test_031() + ) + { + printf("Suite passed.\n"); + return 0; + } + else + { + printf("Suite failed.\n"); + return 1; + } + + /*NOTREACHED*/ +} diff -Nru nspr-4.9.5/nspr/LICENSE nspr-4.10.7/nspr/LICENSE --- nspr-4.9.5/nspr/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/LICENSE 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff -Nru nspr-4.9.5/nspr/Makefile.in nspr-4.10.7/nspr/Makefile.in --- nspr-4.9.5/nspr/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,118 @@ +#! gmake + +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +MOD_DEPTH = . +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +DIRS = config pr lib + +ifdef MOZILLA_CLIENT +# Make nsinstall use absolute symlinks by default for Mozilla OSX builds +# http://bugzilla.mozilla.org/show_bug.cgi?id=193164 +ifeq ($(OS_ARCH),Darwin) +ifndef NSDISTMODE +NSDISTMODE=absolute_symlink +export NSDISTMODE +endif +endif +endif + +DIST_GARBAGE = config.cache config.log config.status + +all:: config.status export + +include $(topsrcdir)/config/rules.mk + +config.status:: configure +ifeq ($(OS_ARCH),WINNT) + sh $(srcdir)/configure --no-create --no-recursion +else + ./config.status --recheck && ./config.status +endif + +# +# The -ll option of zip converts CR LF to LF. +# +ifeq ($(OS_ARCH),WINNT) +ZIP_ASCII_OPT = -ll +endif + +# Delete config/autoconf.mk last because it is included by every makefile. +distclean:: + @echo "cd pr/tests; $(MAKE) $@" + @$(MAKE) -C pr/tests $@ + rm -f config/autoconf.mk + rm -f `cat unallmakefiles` unallmakefiles + +release:: + echo $(BUILD_NUMBER) > $(RELEASE_DIR)/$(BUILD_NUMBER)/version.df + @if test -f imports.df; then \ + echo "cp -f imports.df $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df"; \ + cp -f imports.df $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df; \ + else \ + echo "echo > $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df"; \ + echo > $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df; \ + fi + cd $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \ + rm -rf META-INF; mkdir META-INF; cd META-INF; \ + echo "Manifest-Version: 1.0" > MANIFEST.MF; \ + echo "" >> MANIFEST.MF; \ + cd ..; rm -f mdbinary.jar; zip -r mdbinary.jar META-INF bin lib; \ + rm -rf META-INF; \ + cd include; \ + rm -rf META-INF; mkdir META-INF; cd META-INF; \ + echo "Manifest-Version: 1.0" > MANIFEST.MF; \ + echo "" >> MANIFEST.MF; \ + cd ..; rm -f mdheader.jar; zip $(ZIP_ASCII_OPT) -r mdheader.jar *; \ + rm -rf META-INF +ifeq ($(OS_ARCH),WINNT) + @if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); then \ + rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ + echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)"; \ + mkdir -p $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ + fi + @if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); then \ + rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ + echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)"; \ + mkdir -p $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ + fi +else + @if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); then \ + rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ + echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)"; \ + $(NSINSTALL) -D $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ + chmod 775 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ + fi + @if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); then \ + rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ + echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)"; \ + $(NSINSTALL) -D $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ + chmod 775 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ + fi +endif + cd $(RELEASE_DIR)/$(BUILD_NUMBER); \ + cp -f version.df imports.df $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \ + chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/version.df; \ + chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/imports.df; \ + cd $(OBJDIR_NAME); \ + cp -f mdbinary.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ + chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)/mdbinary.jar; \ + cd include; \ + cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \ + chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)/mdheader.jar + +package: + @echo "cd pkg; $(MAKE) publish" + $(MAKE) -C pkg publish + +depend: + @echo "NSPR20 has no dependencies. Skipped." diff -Nru nspr-4.9.5/nspr/pkg/linux/Makefile.in nspr-4.10.7/nspr/pkg/linux/Makefile.in --- nspr-4.9.5/nspr/pkg/linux/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/linux/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,80 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +NAME = sun-nspr +ifndef RPM_RELEASE +RPM_RELEASE = 1 +endif +TOPDIR = /usr/src/redhat +VERSION = `grep PR_VERSION $(dist_includedir)/prinit.h \ + | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'` + +SPECFILE = $(NAME).spec + +include $(MOD_DEPTH)/config/autoconf.mk + +# Force i386 for non 64 bit build +ifneq ($(USE_64),1) + RPMTARGET = "--target=i386" + RPMLIBDIR = lib +else + RPMLIBDIR = lib64 +endif + +publish: + $(MAKE) clean + mkdir -p SOURCES SRPMS RPMS BUILD + (cd $(dist_libdir) && tar cphf - libnspr4.so libplds4.so libplc4.so) \ + | (mkdir -p opt/sun/private/$(RPMLIBDIR) && cd opt/sun/private/$(RPMLIBDIR) && tar xvfBp -) + (cd $(dist_includedir) && tar cphf - .) \ + | (mkdir -p opt/sun/private/include/nspr && cd opt/sun/private/include/nspr && tar xvfBp -) + (cd opt/sun/private/include/nspr && \ + rm -rf md) + tar czvf SOURCES/$(NAME)-$(VERSION).tar.gz opt + echo "%define name $(NAME)" >$(SPECFILE) + echo "%define version $(VERSION)" >>$(SPECFILE) + echo "%define release $(RPM_RELEASE)" >>$(SPECFILE) + echo "%define buildroot `pwd`/$(NAME)-root" >>$(SPECFILE) + echo "%define _topdir `pwd`" >>$(SPECFILE) + echo "%define _unpackaged_files_terminate_build 0" >>$(SPECFILE) + cat $(srcdir)/$(NAME).spec >>$(SPECFILE) + echo "" >>$(SPECFILE) + echo "%files" >>$(SPECFILE) + echo "%defattr(-,root,root)" >>$(SPECFILE) + echo "%dir /opt" >>$(SPECFILE) + echo "%dir /opt/sun" >>$(SPECFILE) + echo "%dir /opt/sun/private" >>$(SPECFILE) + echo "%dir /opt/sun/private/$(RPMLIBDIR)" >>$(SPECFILE) + find opt \( -name "*.so" \) | sed -e "s-^-/-" >>$(SPECFILE) + echo "" >>$(SPECFILE) + echo "%files devel" >>$(SPECFILE) + echo "%defattr(-,root,root)" >>$(SPECFILE) + echo "%dir /opt" >>$(SPECFILE) + echo "%dir /opt/sun" >>$(SPECFILE) + echo "%dir /opt/sun/private" >>$(SPECFILE) + echo "%dir /opt/sun/private/include" >>$(SPECFILE) + echo "%dir /opt/sun/private/include/nspr" >>$(SPECFILE) + echo "%dir /opt/sun/private/include/nspr/obsolete" >>$(SPECFILE) + echo "%dir /opt/sun/private/include/nspr/private" >>$(SPECFILE) + find opt -type f \( -name "*.h" \) \ + | sed -e "s-^-/-" >>$(SPECFILE) + rpmbuild $(RPMTARGET) -bb $(SPECFILE) + +clean: + rm -rf $(TOPDIR)/BUILD/$(NAME) + rm -rf SOURCES SRPMS RPMS BUILD + rm -rf RPMS SRPMS opt + rm -f $(NAME)-$(VERSION).tar.gz diff -Nru nspr-4.9.5/nspr/pkg/linux/sun-nspr.spec nspr-4.10.7/nspr/pkg/linux/sun-nspr.spec --- nspr-4.9.5/nspr/pkg/linux/sun-nspr.spec 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/linux/sun-nspr.spec 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,49 @@ +Summary: Netscape Portable Runtime +Name: %{name} +Vendor: Sun Microsystems, Inc. +Version: %{version} +Release: %{release} +Copyright: Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Also under other license(s) as shown at the Description field. +Distribution: Sun Java(TM) Enterprise System +URL: http://www.sun.com +Group: System Environment/Base +Source: %{name}-%{version}.tar.gz +ExclusiveOS: Linux +BuildRoot: /var/tmp/%{name}-root + +%description + +NSPR provides platform independence for non-GUI operating system +facilities. These facilities include threads, thread synchronization, +normal file and network I/O, interval timing and calendar time, basic +memory management (malloc and free) and shared library linking. + +See: http://www.mozilla.org/projects/nspr/about-nspr.html + +This Source Code Form is subject to the terms of the Mozilla Public +License, v. 2.0. If a copy of the MPL was not distributed with this +file, You can obtain one at http://mozilla.org/MPL/2.0/. + +%package devel +Summary: Development Libraries for the Netscape Portable Runtime +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Header files for doing development with the Netscape Portable Runtime. + +Under "MPL/GPL" license. + +%prep +%setup -c + +%build + +%install +rm -rf $RPM_BUILD_ROOT +mkdir $RPM_BUILD_ROOT +cd $RPM_BUILD_ROOT +tar xvzf $RPM_SOURCE_DIR/%{name}-%{version}.tar.gz + +%clean +rm -rf $RPM_BUILD_ROOT diff -Nru nspr-4.9.5/nspr/pkg/Makefile.in nspr-4.10.7/nspr/pkg/Makefile.in --- nspr-4.9.5/nspr/pkg/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,29 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = .. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +DIRS = +ifeq ($(OS_TARGET),Linux) +DIRS = linux +endif +ifeq ($(OS_TARGET),SunOS) +DIRS = solaris +endif + +publish:: + +$(LOOP_OVER_DIRS) + +include $(topsrcdir)/config/rules.mk diff -Nru nspr-4.9.5/nspr/pkg/solaris/bld_awk_pkginfo.ksh nspr-4.10.7/nspr/pkg/solaris/bld_awk_pkginfo.ksh --- nspr-4.9.5/nspr/pkg/solaris/bld_awk_pkginfo.ksh 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/bld_awk_pkginfo.ksh 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,109 @@ +#!/usr/bin/ksh -p +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# +# Simple script which builds the awk_pkginfo awk script. This awk script +# is used to convert the pkginfo.tmpl files into pkginfo files +# for the build. +# + +usage() +{ + cat <<-EOF +usage: bld_awk_pkginfo -p -m -o [-v ] +EOF +} + +# +# Awk strings +# +# two VERSION patterns: one for Dewey decimal, one for Dewey plus ,REV=n +# the first has one '=' the second has two or more '=' +# +VERSION1="VERSION=[^=]*$" +VERSION2="VERSION=[^=]*=.*$" +PRODVERS="^SUNW_PRODVERS=" +ARCH='ARCH=\"ISA\"' + +# +# parse command line +# +mach="" +prodver="" +awk_script="" +version="NSPRVERS" + +while getopts o:p:m:v: c +do + case $c in + o) + awk_script=$OPTARG + ;; + m) + mach=$OPTARG + ;; + p) + prodver=$OPTARG + ;; + v) + version=$OPTARG + ;; + \?) + usage + exit 1 + ;; + esac +done + +if [[ ( -z $prodver ) || ( -z $mach ) || ( -z $awk_script ) ]] +then + usage + exit 1 +fi + +if [[ -f $awk_script ]] +then + rm -f $awk_script +fi + +# +# Build REV= field based on date +# +rev=$(date "+%Y.%m.%d.%H.%M") + +# +# Build awk script which will process all the +# pkginfo.tmpl files. +# +# the first VERSION pattern is replaced with a leading quotation mark +# +rm -f $awk_script +cat << EOF > $awk_script +/$VERSION1/ { + sub(/\=[^=]*$/,"=\"$rev\"") + print + next + } +/$VERSION2/ { + sub(/\=[^=]*$/,"=$rev\"") + sub(/NSPRVERS/,"$version") + print + next + } +/$PRODVERS/ { + printf "SUNW_PRODVERS=\"%s\"\n", "$prodver" + next + } +/$ARCH/ { + printf "ARCH=\"%s\"\n", "$mach" + next + } +{ print } +EOF diff -Nru nspr-4.9.5/nspr/pkg/solaris/common_files/copyright nspr-4.10.7/nspr/pkg/solaris/common_files/copyright --- nspr-4.9.5/nspr/pkg/solaris/common_files/copyright 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/common_files/copyright 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,6 @@ +Copyright 2005 Sun Microsystems, Inc. All rights reserved. +Use is subject to license terms. + +This Source Code Form is subject to the terms of the Mozilla Public +License, v. 2.0. If a copy of the MPL was not distributed with this +file, You can obtain one at http://mozilla.org/MPL/2.0/. diff -Nru nspr-4.9.5/nspr/pkg/solaris/Makefile.com nspr-4.10.7/nspr/pkg/solaris/Makefile.com --- nspr-4.9.5/nspr/pkg/solaris/Makefile.com 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/Makefile.com 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,37 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +MACH = $(shell mach) + +PUBLISH_ROOT = $(DIST) +ifeq ($(MOD_DEPTH),../..) +ROOT = ROOT +else +ROOT = $(subst ../../,,$(MOD_DEPTH))/ROOT +endif + +PKGARCHIVE = $(dist_prefix)/pkgarchive +DATAFILES = copyright +FILES = $(DATAFILES) pkginfo + +PACKAGE = $(shell basename `pwd`) + +PRODUCT_VERSION = $(shell grep PR_VERSION $(dist_includedir)/prinit.h \ + | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') + +LN = /usr/bin/ln +CP = /usr/bin/cp + +CLOBBERFILES = $(FILES) + +include $(topsrcdir)/config/rules.mk + +# vim: ft=make diff -Nru nspr-4.9.5/nspr/pkg/solaris/Makefile-devl.com nspr-4.10.7/nspr/pkg/solaris/Makefile-devl.com --- nspr-4.9.5/nspr/pkg/solaris/Makefile-devl.com 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/Makefile-devl.com 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,34 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +MACH = $(shell mach) + +PUBLISH_ROOT = $(DIST) +ifeq ($(MOD_DEPTH),../..) +ROOT = ROOT +else +ROOT = $(subst ../../,,$(MOD_DEPTH))/ROOT +endif + +PKGARCHIVE = $(dist_prefix)/pkgarchive +DATAFILES = copyright +FILES = $(DATAFILES) pkginfo + +PACKAGE = $(shell basename `pwd`) + +PRODUCT_VERSION = "$(MOD_VERSION).$(MOD_MINOR).$(MOD_PATCH)$(MOD_BETA)" +LN = /usr/bin/ln + +CLOBBERFILES = $(FILES) + +include $(topsrcdir)/config/rules.mk + +# vim: ft=make diff -Nru nspr-4.9.5/nspr/pkg/solaris/Makefile-devl.targ nspr-4.10.7/nspr/pkg/solaris/Makefile-devl.targ --- nspr-4.9.5/nspr/pkg/solaris/Makefile-devl.targ 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/Makefile-devl.targ 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,34 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +include $(srcdir)/../proto64.mk + +pkginfo: pkginfo.tmpl ../awk_pkginfo + $(RM) $@; nawk -f ../awk_pkginfo $(srcdir)/$@.tmpl > $@ + +pkg: $(PKGARCHIVE) + cat $(srcdir)/prototype | sed $(sed_proto64) > prototype + cp $(srcdir)/depend . + pkgmk -f prototype -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE) + +$(PKGARCHIVE): + [ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE) + +$(DATAFILES): %: $(srcdir)/../common_files/% + $(RM) $@; cp $(srcdir)/../common_files/$@ $@ + +$(MACHDATAFILES): %: $(srcdir)/../common_files/%_$(MACH) + $(RM) $@; cp $(srcdir)/../common_files/$@_$(MACH) $@ + +clobber clean:: + -$(RM) $(CLOBBERFILES) $(CLEANFILES) + +.PHONY: pkg diff -Nru nspr-4.9.5/nspr/pkg/solaris/Makefile.in nspr-4.10.7/nspr/pkg/solaris/Makefile.in --- nspr-4.9.5/nspr/pkg/solaris/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,89 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +abs_dist_libdir := $(shell (cd $(dist_libdir);pwd)) +abs_dist_includedir := $(shell (cd $(dist_includedir);pwd)) + +%: %.ksh + $(RM) $@ + cp $< $@ + chmod +x $@ + +DIRS = \ + SUNWpr \ + SUNWprd + +include $(srcdir)/Makefile.com + +PROTO = \ + $(ROOT) \ + $(ROOT)/usr/lib/mps \ + $(ROOT)/usr/include/mps + +ifeq ($(MACH), sparc) + PROTO += $(ROOT)/usr/lib/mps/cpu/sparcv8plus +endif + +ifeq ($(USE_64), 1) +ifeq ($(MACH), sparc) +# Sparc + PROTO += $(ROOT)/usr/lib/mps/sparcv9 +else +# AMD64 + PROTO += $(ROOT)/usr/lib/mps/amd64 +endif + abs_dist64_libdir = $(abs_dist_libdir) + abs_dist32_libdir = $(shell echo $(abs_dist_libdir) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g") + abs_dist64_includedir = $(abs_dist_includedir) + abs_dist32_includedir = $(shell echo $(abs_dist_includedir) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g") +else + abs_dist32_libdir = $(abs_dist_libdir) + abs_dist64_libdir = $(shell echo $(abs_dist_libdir) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g") + abs_dist32_includedir = $(abs_dist_includedir) + abs_dist64_includedir = $(shell echo $(abs_dist_includedir) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g") +endif + +awk_pkginfo: bld_awk_pkginfo + ./bld_awk_pkginfo -m $(MACH) -p "$(PRODUCT_VERSION)" -o $@ -v $(PRODUCT_VERSION) + +all:: awk_pkginfo $(PROTO) +publish: awk_pkginfo $(PROTO) + +$(LOOP_OVER_DIRS) + +clean clobber:: + $(RM) awk_pkginfo bld_awk_pkginfo + $(RM) -r $(ROOT) + +$(ROOT): + mkdir -p $@ + +$(ROOT)/usr/lib/mps/sparcv9: + mkdir -p $@ + $(CP) -r $(abs_dist64_libdir)/*.so $@ +$(ROOT)/usr/lib/mps/amd64: + mkdir -p $@ + $(CP) -r $(abs_dist64_libdir)/*.so $@ +$(ROOT)/usr/lib/mps: + mkdir -p $@ + $(CP) -r $(abs_dist32_libdir)/*.so $@ +$(ROOT)/usr/lib/mps/cpu/sparcv8plus: + mkdir -p $@ + $(CP) -r $(abs_dist32_libdir)/cpu/sparcv8plus/*.so $@ +$(ROOT)/usr/include/mps: + mkdir -p $@ + $(CP) -r $(abs_dist32_includedir)/* $@ diff -Nru nspr-4.9.5/nspr/pkg/solaris/Makefile.targ nspr-4.10.7/nspr/pkg/solaris/Makefile.targ --- nspr-4.9.5/nspr/pkg/solaris/Makefile.targ 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/Makefile.targ 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,32 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +include $(srcdir)/../proto64.mk + +pkginfo: pkginfo.tmpl ../awk_pkginfo + $(RM) $@; nawk -f ../awk_pkginfo $< > $@ + +pkg: $(PKGARCHIVE) prototype_$(MACH) + cp $(srcdir)/prototype_com . + cat $(srcdir)/prototype_$(MACH) | sed $(sed_proto64) > prototype_$(MACH) + cp $(srcdir)/depend . + pkgmk -f prototype_$(MACH) -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE) + +$(PKGARCHIVE): + [ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE) + +$(DATAFILES): %: $(srcdir)/../common_files/% + $(RM) $@; cp $(srcdir)/../common_files/$@ $@ + +clobber clean:: + -$(RM) $(CLOBBERFILES) $(CLEANFILES) + +.PHONY: pkg diff -Nru nspr-4.9.5/nspr/pkg/solaris/proto64.mk nspr-4.10.7/nspr/pkg/solaris/proto64.mk --- nspr-4.9.5/nspr/pkg/solaris/proto64.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/proto64.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,18 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +ifeq ($(USE_64), 1) + # Remove 64 tag + sed_proto64='s/\#64\#//g' +else + # Strip 64 lines + sed_proto64='/\#64\#/d' +endif diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWpr/depend nspr-4.10.7/nspr/pkg/solaris/SUNWpr/depend --- nspr-4.9.5/nspr/pkg/solaris/SUNWpr/depend 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWpr/depend 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,32 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# $Id$ +# +# This package information file defines software dependencies associated +# with the pkg. You can define three types of pkg dependencies with this file: +# P indicates a prerequisite for installation +# I indicates an incompatible package +# R indicates a reverse dependency +# see pkginfo(4), PKG parameter +# see pkginfo(4), NAME parameter +# see pkginfo(4), VERSION parameter +# see pkginfo(4), ARCH parameter +# +# () +# () +# ... +# +# ... + +P SUNWcar Core Architecture, (Root) +P SUNWkvm Core Architecture, (Kvm) +P SUNWcsr Core Solaris, (Root) +P SUNWcsu Core Solaris, (Usr) +P SUNWcsd Core Solaris Devices +P SUNWcsl Core Solaris Libraries diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWpr/Makefile.in nspr-4.10.7/nspr/pkg/solaris/SUNWpr/Makefile.in --- nspr-4.9.5/nspr/pkg/solaris/SUNWpr/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWpr/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,26 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(srcdir)/../Makefile.com + +DATAFILES += + +all:: $(FILES) +publish:: all pkg + +include $(srcdir)/../Makefile.targ diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWpr/pkginfo.tmpl nspr-4.10.7/nspr/pkg/solaris/SUNWpr/pkginfo.tmpl --- nspr-4.9.5/nspr/pkg/solaris/SUNWpr/pkginfo.tmpl 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWpr/pkginfo.tmpl 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,38 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWpr" +NAME="Netscape Portable Runtime" +ARCH="ISA" +VERSION="NSPRVERS,REV=0.0.0" +SUNW_PRODNAME="Netscape Portable Runtime" +SUNW_PRODVERS="NSPRVERS" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Netscape Portable Runtime Interface" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +#VSTOCK="" +#ISTATES="" +#RSTATES='' +#ULIMIT="" +#ORDER="" +#PSTAMP="" +#INTONLY="" diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWpr/prototype_com nspr-4.10.7/nspr/pkg/solaris/SUNWpr/prototype_com --- nspr-4.9.5/nspr/pkg/solaris/SUNWpr/prototype_com 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWpr/prototype_com 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,39 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search # where to find pkg objects +#!include # include another 'prototype' file +#!default # default used if not specified on entry +#!= # puts parameter in pkg environment + +# packaging files +i copyright +i pkginfo +i depend +# +# source locations relative to the prototype file +# +# SUNWpr +# +d none usr 755 root sys +d none usr/lib 755 root bin +d none usr/lib/mps 755 root bin +d none usr/lib/mps/secv1 755 root bin +f none usr/lib/mps/libnspr4.so 755 root bin +f none usr/lib/mps/libplc4.so 755 root bin +f none usr/lib/mps/libplds4.so 755 root bin +s none usr/lib/mps/secv1/libnspr4.so=../libnspr4.so +s none usr/lib/mps/secv1/libplc4.so=../libplc4.so +s none usr/lib/mps/secv1/libplds4.so=../libplds4.so diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWpr/prototype_i386 nspr-4.10.7/nspr/pkg/solaris/SUNWpr/prototype_i386 --- nspr-4.9.5/nspr/pkg/solaris/SUNWpr/prototype_i386 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWpr/prototype_i386 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,45 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search # where to find pkg objects +#!include # include another 'prototype' file +#!default # default used if not specified on entry +#!= # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are i386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWpr +# +#64#s none usr/lib/mps/64=amd64 +#64#s none usr/lib/mps/secv1/64=amd64 +#64#d none usr/lib/mps/amd64 755 root bin +#64#d none usr/lib/mps/secv1/amd64 755 root bin +#64#f none usr/lib/mps/amd64/libnspr4.so 755 root bin +#64#f none usr/lib/mps/amd64/libplc4.so 755 root bin +#64#f none usr/lib/mps/amd64/libplds4.so 755 root bin +#64#s none usr/lib/mps/secv1/amd64/libnspr4.so=../../amd64/libnspr4.so +#64#s none usr/lib/mps/secv1/amd64/libplc4.so=../../amd64/libplc4.so +#64#s none usr/lib/mps/secv1/amd64/libplds4.so=../../amd64/libplds4.so + diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWpr/prototype_sparc nspr-4.10.7/nspr/pkg/solaris/SUNWpr/prototype_sparc --- nspr-4.9.5/nspr/pkg/solaris/SUNWpr/prototype_sparc 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWpr/prototype_sparc 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search # where to find pkg objects +#!include # include another 'prototype' file +#!default # default used if not specified on entry +#!= # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWpr +# +d none usr/lib/mps/cpu 755 root bin +d none usr/lib/mps/cpu/sparcv8plus 755 root bin +d none usr/lib/mps/secv1/cpu 755 root bin +d none usr/lib/mps/secv1/cpu/sparcv8plus 755 root bin +f none usr/lib/mps/cpu/sparcv8plus/libnspr_flt4.so 755 root bin +s none usr/lib/mps/secv1/cpu/sparcv8plus/libnspr_flt4.so=../../../cpu/sparcv8plus/libnspr_flt4.so +#64#s none usr/lib/mps/64=sparcv9 +#64#s none usr/lib/mps/secv1/64=sparcv9 +#64#d none usr/lib/mps/sparcv9 755 root bin +#64#d none usr/lib/mps/secv1/sparcv9 755 root bin +#64#f none usr/lib/mps/sparcv9/libnspr4.so 755 root bin +#64#f none usr/lib/mps/sparcv9/libplc4.so 755 root bin +#64#f none usr/lib/mps/sparcv9/libplds4.so 755 root bin +#64#s none usr/lib/mps/secv1/sparcv9/libnspr4.so=../../sparcv9/libnspr4.so +#64#s none usr/lib/mps/secv1/sparcv9/libplc4.so=../../sparcv9/libplc4.so +#64#s none usr/lib/mps/secv1/sparcv9/libplds4.so=../../sparcv9/libplds4.so + diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWprd/depend nspr-4.10.7/nspr/pkg/solaris/SUNWprd/depend --- nspr-4.9.5/nspr/pkg/solaris/SUNWprd/depend 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWprd/depend 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,27 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# $Id$ +# +# This package information file defines software dependencies associated +# with the pkg. You can define three types of pkg dependencies with this file: +# P indicates a prerequisite for installation +# I indicates an incompatible package +# R indicates a reverse dependency +# see pkginfo(4), PKG parameter +# see pkginfo(4), NAME parameter +# see pkginfo(4), VERSION parameter +# see pkginfo(4), ARCH parameter +# +# () +# () +# ... +# +# ... + +P SUNWpr Netscape Portable Runtime diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWprd/Makefile.in nspr-4.10.7/nspr/pkg/solaris/SUNWprd/Makefile.in --- nspr-4.9.5/nspr/pkg/solaris/SUNWprd/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWprd/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,26 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(srcdir)/../Makefile-devl.com + +DATAFILES += + +all:: $(FILES) +publish:: all pkg + +include $(srcdir)/../Makefile-devl.targ diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWprd/pkginfo.tmpl nspr-4.10.7/nspr/pkg/solaris/SUNWprd/pkginfo.tmpl --- nspr-4.9.5/nspr/pkg/solaris/SUNWprd/pkginfo.tmpl 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWprd/pkginfo.tmpl 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,38 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWprd" +NAME="Netscape Portable Runtime Development" +ARCH="ISA" +VERSION="NSPRVERS,REV=0.0.0" +SUNW_PRODNAME="Netscape Portable Runtime Development" +SUNW_PRODVERS="NSPRVERS" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Netscape Portable Runtime Interface Files for Development" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +#VSTOCK="" +#ISTATES="" +#RSTATES='' +#ULIMIT="" +#ORDER="" +#PSTAMP="" +#INTONLY="" diff -Nru nspr-4.9.5/nspr/pkg/solaris/SUNWprd/prototype nspr-4.10.7/nspr/pkg/solaris/SUNWprd/prototype --- nspr-4.9.5/nspr/pkg/solaris/SUNWprd/prototype 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pkg/solaris/SUNWprd/prototype 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,89 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#ident "$Id$" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search # where to find pkg objects +#!include # include another 'prototype' file +#!default # default used if not specified on entry +#!= # puts parameter in pkg environment + +# packaging files +i copyright +i pkginfo +i depend +# +# source locations relative to .h 0644 root bine prototype file +# +# SUNWprd +# +d none usr 0755 root sys +d none usr/include 0755 root bin +d none usr/include/mps 0755 root bin +d none usr/include/mps/obsolete 0755 root bin +d none usr/include/mps/private 0755 root bin +f none usr/include/mps/obsolete/pralarm.h 0644 root bin +f none usr/include/mps/obsolete/probslet.h 0644 root bin +f none usr/include/mps/obsolete/protypes.h 0644 root bin +f none usr/include/mps/obsolete/prsem.h 0644 root bin +f none usr/include/mps/prcpucfg.h 0644 root bin +f none usr/include/mps/nspr.h 0644 root bin +f none usr/include/mps/pratom.h 0644 root bin +f none usr/include/mps/prbit.h 0644 root bin +f none usr/include/mps/prclist.h 0644 root bin +f none usr/include/mps/prcmon.h 0644 root bin +f none usr/include/mps/prcountr.h 0644 root bin +f none usr/include/mps/prcvar.h 0644 root bin +f none usr/include/mps/prdtoa.h 0644 root bin +f none usr/include/mps/prenv.h 0644 root bin +f none usr/include/mps/prerr.h 0644 root bin +f none usr/include/mps/prerror.h 0644 root bin +f none usr/include/mps/prinet.h 0644 root bin +f none usr/include/mps/prinit.h 0644 root bin +f none usr/include/mps/prinrval.h 0644 root bin +f none usr/include/mps/prio.h 0644 root bin +f none usr/include/mps/pripcsem.h 0644 root bin +f none usr/include/mps/private/pprio.h 0644 root bin +f none usr/include/mps/private/pprthred.h 0644 root bin +f none usr/include/mps/private/prpriv.h 0644 root bin +f none usr/include/mps/prlink.h 0644 root bin +f none usr/include/mps/prlock.h 0644 root bin +f none usr/include/mps/prlog.h 0644 root bin +f none usr/include/mps/prlong.h 0644 root bin +f none usr/include/mps/prmem.h 0644 root bin +f none usr/include/mps/prmon.h 0644 root bin +f none usr/include/mps/prmwait.h 0644 root bin +f none usr/include/mps/prnetdb.h 0644 root bin +f none usr/include/mps/prolock.h 0644 root bin +f none usr/include/mps/prpdce.h 0644 root bin +f none usr/include/mps/prprf.h 0644 root bin +f none usr/include/mps/prproces.h 0644 root bin +f none usr/include/mps/prrng.h 0644 root bin +f none usr/include/mps/prrwlock.h 0644 root bin +f none usr/include/mps/prshm.h 0644 root bin +f none usr/include/mps/prshma.h 0644 root bin +f none usr/include/mps/prsystem.h 0644 root bin +f none usr/include/mps/prthread.h 0644 root bin +f none usr/include/mps/prtime.h 0644 root bin +f none usr/include/mps/prtpool.h 0644 root bin +f none usr/include/mps/prtrace.h 0644 root bin +f none usr/include/mps/prtypes.h 0644 root bin +f none usr/include/mps/prvrsion.h 0644 root bin +f none usr/include/mps/prwin16.h 0644 root bin +f none usr/include/mps/plarenas.h 0644 root bin +f none usr/include/mps/plarena.h 0644 root bin +f none usr/include/mps/plbase64.h 0644 root bin +f none usr/include/mps/plerror.h 0644 root bin +f none usr/include/mps/plgetopt.h 0644 root bin +f none usr/include/mps/plhash.h 0644 root bin +f none usr/include/mps/plstr.h 0644 root bin diff -Nru nspr-4.9.5/nspr/pr/.cvsignore nspr-4.10.7/nspr/pr/.cvsignore --- nspr-4.9.5/nspr/pr/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/include/.cvsignore nspr-4.10.7/nspr/pr/include/.cvsignore --- nspr-4.9.5/nspr/pr/include/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/include/gencfg.c nspr-4.10.7/nspr/pr/include/gencfg.c --- nspr-4.9.5/nspr/pr/include/gencfg.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/gencfg.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,265 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#if defined(sgi) +#ifndef IRIX + error - IRIX is not defined +#endif +#endif + +#if defined(__sun) +#ifndef SOLARIS + error - SOLARIS is not defined +#endif +#endif + +#if defined(__hpux) +#ifndef HPUX + error - HPUX is not defined +#endif +#endif + +#if defined(__alpha) +#if !(defined(_WIN32)) && !(defined(OSF1)) && !(defined(__linux)) && !(defined(__FreeBSD__)) + error - None of OSF1, _WIN32, __linux, or __FreeBSD__ is defined +#endif +#endif + +#if defined(_IBMR2) +#ifndef AIX + error - AIX is not defined +#endif +#endif + +#if defined(linux) +#ifndef LINUX + error - LINUX is not defined +#endif +#endif + +#if defined(bsdi) +#ifndef BSDI + error - BSDI is not defined +#endif +#endif + +#if defined(M_UNIX) +#ifndef SCO + error - SCO is not defined +#endif +#endif +#if !defined(M_UNIX) && defined(_USLC_) +#ifndef UNIXWARE + error - UNIXWARE is not defined +#endif +#endif + +#if defined(__APPLE__) +#ifndef DARWIN + error - DARWIN is not defined +#endif +#endif + +/************************************************************************/ + +/* Generate cpucfg.h */ + +#ifdef XP_PC +#ifdef WIN32 +#define INT64 _PRInt64 +#else +#define INT64 long +#endif +#else +#if defined(HPUX) || defined(SCO) || defined(UNIXWARE) +#define INT64 long +#else +#define INT64 long long +#endif +#endif + +struct align_short { + char c; + short a; +}; +struct align_int { + char c; + int a; +}; +struct align_long { + char c; + long a; +}; +struct align_PRInt64 { + char c; + INT64 a; +}; +struct align_fakelonglong { + char c; + struct { + long hi, lo; + } a; +}; +struct align_float { + char c; + float a; +}; +struct align_double { + char c; + double a; +}; +struct align_pointer { + char c; + void *a; +}; + +#define ALIGN_OF(type) \ + (((char*)&(((struct align_##type *)0)->a)) - ((char*)0)) + +int bpb; + +/* Used if shell doesn't support redirection. By default, assume it does. */ +FILE *stream; + +static int Log2(int n) +{ + int log2 = 0; + + if (n & (n-1)) + log2++; + if (n >> 16) + log2 += 16, n >>= 16; + if (n >> 8) + log2 += 8, n >>= 8; + if (n >> 4) + log2 += 4, n >>= 4; + if (n >> 2) + log2 += 2, n >>= 2; + if (n >> 1) + log2++; + return log2; +} + +/* We assume that int's are 32 bits */ +static void do64(void) +{ + union { + int i; + char c[4]; + } u; + + u.i = 0x01020304; + if (u.c[0] == 0x01) { + fprintf(stream, "#undef IS_LITTLE_ENDIAN\n"); + fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n"); + } else { + fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n"); + fprintf(stream, "#undef IS_BIG_ENDIAN\n\n"); + } +} + +static void do32(void) +{ + union { + long i; + char c[4]; + } u; + + u.i = 0x01020304; + if (u.c[0] == 0x01) { + fprintf(stream, "#undef IS_LITTLE_ENDIAN\n"); + fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n"); + } else { + fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n"); + fprintf(stream, "#undef IS_BIG_ENDIAN\n\n"); + } +} + +/* +** Concievably this could actually be used; but there is lots of code out +** there with and's and shift's in it that assumes a byte is 8 bits, so +** forget about porting THIS code to those non 8 bit byte machines. +*/ +static void BitsPerByte(void) +{ + bpb = 8; +} + +int main(int argc, char **argv) +{ + BitsPerByte(); + + /* If we got a command line argument, try to use it as the stream. */ + ++argv; + if(*argv) { + if(!(stream = fopen ( *argv, "wt" ))) { + fprintf(stderr, "Could not write to output file %s.\n", *argv); + return 1; + } + } else { + stream = stdout; + } + + fprintf(stream, "#ifndef nspr_cpucfg___\n"); + fprintf(stream, "#define nspr_cpucfg___\n\n"); + + fprintf(stream, "/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n"); + + if (sizeof(long) == 8) { + do64(); + } else { + do32(); + } + fprintf(stream, "#define PR_BYTES_PER_BYTE %d\n", sizeof(char)); + fprintf(stream, "#define PR_BYTES_PER_SHORT %d\n", sizeof(short)); + fprintf(stream, "#define PR_BYTES_PER_INT %d\n", sizeof(int)); + fprintf(stream, "#define PR_BYTES_PER_INT64 %d\n", 8); + fprintf(stream, "#define PR_BYTES_PER_LONG %d\n", sizeof(long)); + fprintf(stream, "#define PR_BYTES_PER_FLOAT %d\n", sizeof(float)); + fprintf(stream, "#define PR_BYTES_PER_DOUBLE %d\n\n", sizeof(double)); + + fprintf(stream, "#define PR_BITS_PER_BYTE %d\n", bpb); + fprintf(stream, "#define PR_BITS_PER_SHORT %d\n", bpb * sizeof(short)); + fprintf(stream, "#define PR_BITS_PER_INT %d\n", bpb * sizeof(int)); + fprintf(stream, "#define PR_BITS_PER_INT64 %d\n", bpb * 8); + fprintf(stream, "#define PR_BITS_PER_LONG %d\n", bpb * sizeof(long)); + fprintf(stream, "#define PR_BITS_PER_FLOAT %d\n", bpb * sizeof(float)); + fprintf(stream, "#define PR_BITS_PER_DOUBLE %d\n\n", + bpb * sizeof(double)); + + fprintf(stream, "#define PR_BITS_PER_BYTE_LOG2 %d\n", Log2(bpb)); + fprintf(stream, "#define PR_BITS_PER_SHORT_LOG2 %d\n", + Log2(bpb * sizeof(short))); + fprintf(stream, "#define PR_BITS_PER_INT_LOG2 %d\n", + Log2(bpb * sizeof(int))); + fprintf(stream, "#define PR_BITS_PER_INT64_LOG2 %d\n", 6); + fprintf(stream, "#define PR_BITS_PER_LONG_LOG2 %d\n", + Log2(bpb * sizeof(long))); + fprintf(stream, "#define PR_BITS_PER_FLOAT_LOG2 %d\n", + Log2(bpb * sizeof(float))); + fprintf(stream, "#define PR_BITS_PER_DOUBLE_LOG2 %d\n\n", + Log2(bpb * sizeof(double))); + + fprintf(stream, "#define PR_ALIGN_OF_SHORT %d\n", ALIGN_OF(short)); + fprintf(stream, "#define PR_ALIGN_OF_INT %d\n", ALIGN_OF(int)); + fprintf(stream, "#define PR_ALIGN_OF_LONG %d\n", ALIGN_OF(long)); + if (sizeof(INT64) < 8) { + /* this machine doesn't actually support PRInt64's */ + fprintf(stream, "#define PR_ALIGN_OF_INT64 %d\n", + ALIGN_OF(fakelonglong)); + } else { + fprintf(stream, "#define PR_ALIGN_OF_INT64 %d\n", ALIGN_OF(PRInt64)); + } + fprintf(stream, "#define PR_ALIGN_OF_FLOAT %d\n", ALIGN_OF(float)); + fprintf(stream, "#define PR_ALIGN_OF_DOUBLE %d\n", ALIGN_OF(double)); + fprintf(stream, "#define PR_ALIGN_OF_POINTER %d\n\n", ALIGN_OF(pointer)); + + fprintf(stream, "#endif /* nspr_cpucfg___ */\n"); + fclose(stream); + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/include/Makefile.in nspr-4.10.7/nspr/pr/include/Makefile.in --- nspr-4.9.5/nspr/pr/include/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,27 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +DIRS = md private obsolete + +include $(topsrcdir)/config/config.mk + +HEADERS = $(wildcard $(srcdir)/*.h) + +RELEASE_HEADERS = $(HEADERS) +RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR) + +include $(topsrcdir)/config/rules.mk + +export:: $(RELEASE_HEADERS) + $(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir) diff -Nru nspr-4.9.5/nspr/pr/include/md/_aix32.cfg nspr-4.10.7/nspr/pr/include/md/_aix32.cfg --- nspr-4.9.5/nspr/pr/include/md/_aix32.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_aix32.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef AIX +#define AIX +#endif + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +/* used by protypes.h only */ +#define _PR_AIX_HAVE_BSD_INT_TYPES + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_aix64.cfg nspr-4.10.7/nspr/pr/include/md/_aix64.cfg --- nspr-4.9.5/nspr/pr/include/md/_aix64.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_aix64.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef AIX +#define AIX +#endif + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 8 + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +/* used by protypes.h only */ +#define _PR_AIX_HAVE_BSD_INT_TYPES + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_aix.h nspr-4.10.7/nspr/pr/include/md/_aix.h --- nspr-4.9.5/nspr/pr/include/md/_aix.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_aix.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,225 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_aix_defs_h___ +#define nspr_aix_defs_h___ + +#include +#if defined(_PR_PTHREADS) || defined(PTHREADS_USER) +#include +#endif + +/* + * To pick up fd_set and the poll events. + */ +#include +#include + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "aix" +#define _PR_SI_SYSNAME "AIX" +#define _PR_SI_ARCHITECTURE "rs6000" +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE (2*65536L) +#define _MD_MINIMUM_STACK_SIZE (2*65536L) +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#define NEED_TIME_R +#undef HAVE_STACK_GROWING_UP +#undef HAVE_WEAK_IO_SYMBOLS +#undef HAVE_WEAK_MALLOC_SYMBOLS +#define HAVE_DLL +#define USE_DLFCN +#define _PR_HAVE_SOCKADDR_LEN +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_STAT_HAS_ONLY_ST_ATIME +#ifdef _PR_INET6 +#define _PR_HAVE_INET_NTOP +#define _PR_HAVE_GETHOSTBYNAME2 +#ifdef _AIX51 /* AIX 4.3.3 does not have AI_NUMERICHOST. */ +#define _PR_HAVE_GETADDRINFO +#endif +#endif +#define _PR_HAVE_SYSV_SEMAPHORES +#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY +#define _PR_ACCEPT_INHERIT_NONBLOCK + +/* Timer operations */ +#if defined(AIX_TIMERS) +#define _MD_INTERVAL_INIT() + +extern PRIntervalTime _MD_AixGetInterval(void); +#define _MD_GET_INTERVAL _MD_AixGetInterval + +extern PRIntervalTime _MD_AixIntervalPerSec(void); +#define _MD_INTERVAL_PER_SEC _MD_AixIntervalPerSec + +#else /* defined(AIX_TIMERS) */ +#define _MD_INTERVAL_USE_GTOD +#endif /* defined(AIX_TIMERS) */ + +#ifdef AIX_HAVE_ATOMIC_OP_H +/* The atomic operations */ +#include +#define _PR_HAVE_ATOMIC_OPS +#ifndef IS_64 +#define _PR_HAVE_ATOMIC_CAS +#endif +#define _MD_INIT_ATOMIC() +#define _MD_ATOMIC_INCREMENT(val) ((PRInt32)fetch_and_add((atomic_p)val, 1) + 1) +#define _MD_ATOMIC_ADD(ptr, val) ((PRInt32)fetch_and_add((atomic_p)ptr, val) + val) +#define _MD_ATOMIC_DECREMENT(val) ((PRInt32)fetch_and_add((atomic_p)val, -1) - 1) +#define _MD_ATOMIC_SET(val, newval) _AIX_AtomicSet(val, newval) +#endif /* AIX_HAVE_ATOMIC_OP_H */ + +#define USE_SETJMP + +#include + +#define _MD_GET_SP(_t) (_t)->md.jb[3] +#define _MD_SET_THR_SP(_t, _sp) ((_t)->md.jb[3] = (int) (_sp - 2 * 64)) +#define PR_NUM_GCREGS _JBLEN + +#define CONTEXT(_th) ((_th)->md.jb) +#define SAVE_CONTEXT(_th) _setjmp(CONTEXT(_th)) +#define GOTO_CONTEXT(_th) _longjmp(CONTEXT(_th), 1) + +#ifdef PTHREADS_USER +#include "_nspr_pthread.h" +#else + +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + *status = PR_TRUE; \ + if (setjmp(CONTEXT(_thread))) { \ + (*_main)(); \ + } \ + _MD_GET_SP(_thread) = (int) (_sp - 2 * 64); \ + PR_END_MACRO + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!setjmp(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + longjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + jmp_buf jb; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#if !defined(_PR_PTHREADS) +#define _MD_INIT_LOCKS() +#endif + +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) +#endif /* PTHREADS_USER */ + +#ifdef AIX_RENAME_SELECT +#define _MD_SELECT select +#define _MD_POLL poll +#endif + +extern void _MD_aix_map_sendfile_error(int err); + +#endif /* nspr_aix_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_beos.cfg nspr-4.10.7/nspr/pr/include/md/_beos.cfg --- nspr-4.9.5/nspr/pr/include/md/_beos.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_beos.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_BEOS +#define XP_BEOS +#undef XP_UNIX +#endif + +#ifndef BEOS +#define BEOS +#endif + +#define PR_AF_INET6 5 /* same as AF_INET6 */ + +#ifdef __powerpc__ +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#else +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#endif + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +/* + * XXX These two macros need to be investigated for different architectures. + */ +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_beos.h nspr-4.10.7/nspr/pr/include/md/_beos.h --- nspr-4.9.5/nspr/pr/include/md/_beos.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_beos.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,583 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_beos_defs_h___ +#define nspr_beos_defs_h___ + +#include "prtypes.h" +#include "prio.h" +#include "prthread.h" +#include "prproces.h" +#include "prmem.h" +#include "obsolete/prsem.h" +#include + +#include +#include +#include + +/* + * Internal configuration macros + */ + +#ifdef BONE_VERSION +#define _PR_HAVE_SOCKADDR_LEN +#define HAVE_NETINET_TCP_H +#endif + +#define PR_LINKER_ARCH "beos" +#define _PR_SI_SYSNAME "BEOS" +#ifdef __powerpc__ +#define _PR_SI_ARCHITECTURE "ppc" +#else +#define _PR_SI_ARCHITECTURE "x86" +#endif +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#undef HAVE_STACK_GROWING_UP +#define HAVE_DLL +#define _PR_NO_CLOCK_TIMER + +/* + * The Atomic operations + */ + +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC _MD_AtomicInit +#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement +#define _MD_ATOMIC_ADD _MD_AtomicAdd +#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement +#define _MD_ATOMIC_SET _MD_AtomicSet + +#define HAVE_CVAR_BUILT_ON_SEM +#define _PR_GLOBAL_THREADS_ONLY +#define _PR_BTHREADS +#define _PR_NEED_FAKE_POLL +#define _PR_HAVE_PEEK_BUFFER +#define _PR_PEEK_BUFFER_MAX (16 * 1024) +#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) 1 +#define _PR_CONNECT_DOES_NOT_BIND +#define _PR_HAVE_O_APPEND + +/* Define threading functions and objects as native BeOS */ +struct _MDThread { + thread_id tid; /* BeOS thread handle */ + sem_id joinSem; /* sems used to synchronzie joining */ + PRBool is_joining; /* TRUE if someone is currently waiting to + join this thread */ +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +/* + * Lock and Semaphore related definitions + */ + +struct _MDLock { + sem_id semaphoreID; + int32 benaphoreCount; +}; + +struct _MDCVar { + sem_id sem1; + sem_id sem2; + int16 count; +}; + +struct _MDSemaphore { + sem_id sid; +}; + +/* +** CPU-related definitions +*/ +struct _MDCPU { + int8 unused; +}; + +/* +** Process-related definitions +*/ +struct _MDProcess { + pid_t pid; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* +** File- and directory-related definitions +*/ + +#ifndef BONE_VERSION +#define BE_SOCK_SHUTDOWN_READ 0x01 +#define BE_SOCK_SHUTDOWN_WRITE 0x02 +#endif + +struct _MDFileDesc { + PRInt32 osfd; + PRInt32 sock_state; + PRBool accepted_socket; + PRNetAddr peer_addr; +#ifndef BONE_VERSION + PRBool connectValueValid; + int connectReturnValue; + int connectReturnError; +#endif +}; + +struct _MDDir { + DIR *d; +}; + +#define PR_DIRECTORY_SEPARATOR '/' +#define PR_DIRECTORY_SEPARATOR_STR "/" +#define PR_PATH_SEPARATOR ':' +#define PR_PATH_SEPARATOR_STR ":" + +#define GETTIMEOFDAY(tp) gettimeofday((tp), NULL) + +/* --- Memory-mapped files stuff --- not implemented on BeOS */ + +struct _MDFileMap { + PRInt8 unused; +}; + +/* + * Network related definitions. + */ + +#ifndef BONE_VERSION +#define IPPROTO_IP 0 +#define AF_UNIX 2 +#define TCP_NODELAY SO_NONBLOCK +#define SO_LINGER -1 +#define SO_ERROR 4 +#endif + +#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 + +#ifndef BONE_VERSION +/* these aren't actually used. if they are, we're screwed */ +struct protoent { + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ + int p_proto; /* protocol # */ +}; + +struct protoent* getprotobyname(const char* name); +struct protoent* getprotobynumber(int number); +#endif + +/* + * malloc() related definitions. + */ + +#undef _PR_OVERRIDE_MALLOC + +/* Miscellaneous */ + +#define _MD_ERRNO() (errno) + +#define _MD_CLEANUP_BEFORE_EXIT _MD_cleanup_before_exit +#define _MD_EXIT _MD_exit + +#define _MD_GET_ENV getenv +#define _MD_PUT_ENV putenv + +#define _MD_EARLY_INIT _MD_early_init +#define _MD_FINAL_INIT _MD_final_init +#define _MD_EARLY_CLEANUP() + +/* CPU Stuff */ + +#define _MD_INIT_CPUS _MD_init_cpus +#define _MD_WAKEUP_CPUS _MD_wakeup_cpus +#define _MD_START_INTERRUPTS _MD_start_interrupts +#define _MD_STOP_INTERRUPTS _MD_stop_interrupts +#define _MD_DISABLE_CLOCK_INTERRUPTS _MD_disable_clock_interrupts +#define _MD_BLOCK_CLOCK_INTERRUPTS _MD_block_clock_interrupts +#define _MD_UNBLOCK_CLOCK_INTERRUPTS _MD_unblock_clock_interrupts +#define _MD_CLOCK_INTERRUPT _MD_clock_interrupt +#define _MD_INIT_STACK _MD_init_stack +#define _MD_CLEAR_STACK _MD_clear_stack +// #define _MD_GET_INTSOFF _MD_get_intsoff +// #define _MD_SET_INTSOFF _MD_set_intsoff +#define _MD_CURRENT_CPU _MD_current_cpu +#define _MD_SET_CURRENT_CPU _MD_set_current_cpu +#define _MD_INIT_RUNNING_CPU _MD_init_running_cpu +#define _MD_PAUSE_CPU _MD_pause_cpu + +/* Thread stuff */ + +#define _MD_CURRENT_THREAD() PR_GetCurrentThread() +// #define _MD_GET_ATTACHED_THREAD _MD_get_attached_thread +#define _MD_LAST_THREAD _MD_last_thread +#define _MD_SET_CURRENT_THREAD _MD_set_current_THREAD +#define _MD_SET_LAST_THREAD _MD_set_last_thread +#define _MD_INIT_THREAD _MD_init_thread +#define _MD_EXIT_THREAD _MD_exit_thread +#define _MD_INIT_ATTACHED_THREAD _MD_init_attached_thread + +#define _MD_SUSPEND_THREAD _MD_suspend_thread +#define _MD_RESUME_THREAD _MD_resume_thread +#define _MD_SUSPEND_CPU _MD_suspend_cpu +#define _MD_RESUME_CPU _MD_resume_cpu +#define _MD_BEGIN_SUSPEND_ALL _MD_begin_suspend_all +#define _MD_END_SUSPEND_ALL _MD_end_suspend_all +#define _MD_BEGIN_RESUME_ALL _MD_begin_resume_all +#define _MD_END_RESUME_ALL _MD_end_resume_all + +#define _MD_GET_SP _MD_get_sp + +#define _MD_CLEAN_THREAD _MD_clean_thread +#define _MD_CREATE_PRIMORDIAL_USER_THREAD _MD_create_primordial_user_thread +#define _MD_CREATE_USER_THREAD _MD_create_user_thread +#define _MD_INIT_PRIMORDIAL_THREAD _MD_init_primordial_thread +#define _MD_CREATE_THREAD _MD_create_thread +#define _MD_YIELD _MD_yield +#define _MD_SET_PRIORITY _MD_set_priority + +#define _MD_SUSPENDALL _MD_suspendall +#define _MD_RESUMEALL _MD_resumeall + +#define _MD_SWITCH_CONTEXT _MD_switch_context +#define _MD_RESTORE_CONTEXT _MD_restore_context + +#define _MD_WAIT _MD_wait +#define _MD_WAKEUP_WAITER _MD_wakeup_waiter + +#define _MD_SETTHREADAFFINITYMASK _MD_setthreadaffinitymask +#define _MD_GETTHREADAFFINITYMASK _MD_getthreadaffinitymask + +/* Thread Synchronization */ + +#define _MD_INIT_LOCKS _MD_init_locks +#define _MD_NEW_LOCK _MD_new_lock +#define _MD_FREE_LOCK _MD_free_lock +#define _MD_LOCK _MD_lock +#define _MD_TEST_AND_LOCK _MD_test_and_lock +#define _MD_UNLOCK _MD_unlock +#define _MD_IOQ_LOCK _MD_ioq_lock +#define _MD_IOQ_UNLOCK _MD_ioq_unlock +#define _MD_NEW_SEM _MD_new_sem +#define _MD_DESTROY_SEM _MD_destroy_sem +#define _MD_TIMED_WAIT_SEM _MD_timed_wait_sem +#define _MD_WAIT_SEM _MD_wait_sem +#define _MD_POST_SEM _MD_post_sem +// #define _MD_NEW_CV _MD_new_cv +// #define _MD_FREE_CV _MD_free_cv +// #define _MD_WAIT_CV _MD_wait_cv +// #define _MD_NOTIFY_CV _MD_notify_cv +// #define _MD_NOTIFYALL_CV _MD_notifyall_cv + +/* File I/O */ + +/* don't need any I/O initializations */ +#define _MD_INIT_IO() +#define _MD_INIT_FILEDESC(fd) + +#define _MD_OPEN_DIR _MD_open_dir +#define _MD_READ_DIR _MD_read_dir +#define _MD_CLOSE_DIR _MD_close_dir +#define _MD_MAKE_NONBLOCK _MD_make_nonblock +#define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable +#define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable +#define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable +#define _MD_OPEN _MD_open +#define _MD_OPEN_FILE _MD_open +#define _MD_CLOSE_FILE _MD_close_file +#define _MD_READ _MD_read +#define _MD_WRITE _MD_write +#define _MD_WRITEV _MD_writev +#define _MD_LSEEK _MD_lseek +#define _MD_LSEEK64 _MD_lseek64 +#define _MD_FSYNC _MD_fsync +#define _MD_DELETE _MD_delete +#define _MD_GETFILEINFO _MD_getfileinfo +#define _MD_GETFILEINFO64 _MD_getfileinfo64 +#define _MD_GETOPENFILEINFO _MD_getopenfileinfo +#define _MD_GETOPENFILEINFO64 _MD_getopenfileinfo64 +#define _MD_RENAME _MD_rename +#define _MD_ACCESS _MD_access +#define _MD_STAT stat +#define _MD_MKDIR _MD_mkdir +#define _MD_MAKE_DIR _MD_mkdir +#define _MD_RMDIR _MD_rmdir +#define _MD_PR_POLL _MD_pr_poll + +/* Network I/O */ + +#define _MD_CLOSE_SOCKET _MD_close_socket +#define _MD_CONNECT _MD_connect +#define _MD_ACCEPT _MD_accept +#define _MD_BIND _MD_bind +#define _MD_LISTEN _MD_listen +#define _MD_SHUTDOWN _MD_shutdown +#define _MD_RECV _MD_recv +#define _MD_SEND _MD_send +#define _MD_ACCEPT_READ _MD_accept_read +#define _MD_GETSOCKNAME _MD_getsockname +#define _MD_GETPEERNAME _MD_getpeername +#define _MD_GETSOCKOPT _MD_getsockopt +#define _MD_SETSOCKOPT _MD_setsockopt +#define _MD_RECVFROM _MD_recvfrom +#define _MD_SENDTO _MD_sendto +#define _MD_SOCKETPAIR _MD_socketpair +#define _MD_SOCKET _MD_socket +#define _MD_SOCKETAVAILABLE _MD_socketavailable +#define _MD_PIPEAVAILABLE _MD_socketavailable + +#define _MD_GET_SOCKET_ERROR() (errno) +#define _MD_GETHOSTNAME _MD_gethostname + +#define _MD_SELECT select + +/* Process management */ + +#define _MD_CREATE_PROCESS _MD_create_process +#define _MD_DETACH_PROCESS _MD_detach_process +#define _MD_WAIT_PROCESS _MD_wait_process +#define _MD_KILL_PROCESS _MD_kill_process + +/* Atomic data operations */ + +// #define _MD_INIT_ATOMIC _MD_init_atomic +// #define _MD_ATOMIC_INCREMENT _MD_atomic_increment +// #define _MD_ATOMIC_DECREMENT _MD_atomic_decrement +// #define _MD_ATOMIC_SET _MD_atomic_set + +/* memory management */ + +#define _MD_INIT_SEGS _MD_init_segs +#define _MD_ALLOC_SEGMENT _MD_alloc_segment +#define _MD_FREE_SEGMENT _MD_free_segment + +/* Memory mapped file I/O */ + +#define _MD_CREATE_FILE_MAP _MD_create_file_map +#define _MD_GET_MEM_MAP_ALIGNMENT _MD_get_mem_map_alignment +#define _MD_MEM_MAP _MD_mem_map +#define _MD_MEM_UNMAP _MD_mem_unmap +#define _MD_CLOSE_FILE_MAP _MD_close_file_map + +/* Time related */ + +#define _MD_NOW _MD_now +#define _MD_INTERVAL_INIT _MD_interval_init +#define _MD_GET_INTERVAL _MD_get_interval +#define _MD_INTERVAL_PER_SEC _MD_interval_per_sec + +/* File locking */ + +#define _MD_LOCKFILE _MD_lockfile +#define _MD_TLOCKFILE _MD_tlockfile +#define _MD_UNLOCKFILE _MD_unlockfile + +/** + * Prototypes for machine dependent function implementations. (Too bad + * NSPR's MD system blows so much that we have to reiterate every stinking + * thing we implement here in our MD header file.) + */ + +/* Miscellaneous */ + +NSPR_API(void) _MD_cleanup_before_exit(void); +NSPR_API(void) _MD_exit(PRIntn status); + +NSPR_API(char*) _MD_get_env(const char *name); +NSPR_API(PRIntn) _MD_put_env(const char *name); + +NSPR_API(void) _MD_early_init(void); +NSPR_API(void) _MD_final_init(void); + +/* CPU Stuff */ + +NSPR_API(void) _MD_init_cpus(); +NSPR_API(void) _MD_wakeup_cpus(); +NSPR_API(void) _MD_start_interrupts(void); +NSPR_API(void) _MD_stop_interrupts(void); +NSPR_API(void) _MD_disable_clock_interrupts(void); +NSPR_API(void) _MD_block_clock_interrupts(void); +NSPR_API(void) _MD_unblock_clock_interrupts(void); +NSPR_API(void) _MD_clock_interrupt(void); +// NSPR_API(void) _MD_init_stack(PRThreadStack *ts, PRIntn redzone); +// NSPR_API(void) _MD_clear_stack(PRThreadStack* ts); +// NSPR_API(PRInt32) _MD_get_intsoff(void); +// NSPR_API(void) _MD_set_intsoff(PRInt32 _val); +// NSPR_API(_PRCPU*) _MD_current_cpu(void); +// NSPR_API(void) _MD_set_current_cpu(_PRCPU *cpu); +// NSPR_API(void) _MD_init_running_cpu(_PRCPU *cpu); +NSPR_API(PRInt32) _MD_pause_cpu(PRIntervalTime timeout); + +/* Thread stuff */ + +// NSPR_API(PRThread*) _MD_current_thread(void); +NSPR_API(PRThread*) _MD_get_attached_thread(void); +NSPR_API(PRThread*) _MD_last_thread(void); +NSPR_API(void) _MD_set_current_thread(PRThread *thread); +NSPR_API(void) _MD_set_last_thread(PRThread *thread); +NSPR_API(PRStatus) _MD_init_thread(PRThread *thread); +NSPR_API(void) _MD_exit_thread(PRThread *thread); +NSPR_API(PRStatus) _MD_init_attached_thread(PRThread *thread); + +NSPR_API(void) _MD_suspend_thread(PRThread *thread); +NSPR_API(void) _MD_resume_thread(PRThread *thread); +// NSPR_API(void) _MD_suspend_cpu(_PRCPU *cpu); +// NSPR_API(void) _MD_resume_cpu(_PRCPU *cpu); +NSPR_API(void) _MD_begin_suspend_all(void); +NSPR_API(void) _MD_end_suspend_all(void); +NSPR_API(void) _MD_begin_resume_all(void); +NSPR_API(void) _MD_end_resume_all(void); + +NSPR_API(void *) _MD_get_sp(PRThread *thread); + +NSPR_API(void) _MD_clean_thread(PRThread *thread); +NSPR_API(void) _MD_create_primordial_user_thread(PRThread *); +NSPR_API(PRThread*) _MD_create_user_thread(PRUint32 stacksize, void (*start)(void *), void *arg); +NSPR_API(void) _MD_init_primordial_thread(PRThread *thread); +NSPR_API(PRStatus) _MD_create_thread(PRThread *thread, void (*start)(void *), PRThreadPriority priority, PRThreadScope scope, PRThreadState state, PRUint32 stackSize); +NSPR_API(void) _MD_yield(void); +NSPR_API(void) _MD_set_priority(struct _MDThread *md, PRThreadPriority newPri); + +NSPR_API(void) _MD_suspendall(void); +NSPR_API(void) _MD_resumeall(void); + +NSPR_API(void) _MD_init_context(PRThread *thread, char *top, void (*start) (void), PRBool *status); +NSPR_API(void) _MD_switch_context(PRThread *thread); +NSPR_API(void) _MD_restore_context(PRThread *thread); + +NSPR_API(PRStatus) _MD_wait(PRThread *, PRIntervalTime timeout); +NSPR_API(PRStatus) _MD_wakeup_waiter(PRThread *); + +NSPR_API(PRInt32) _MD_setthreadaffinitymask(PRThread *thread, PRUint32 mask ); +NSPR_API(PRInt32) _MD_getthreadaffinitymask(PRThread *thread, PRUint32 *mask); + +/* Thread Synchronization */ + +NSPR_API(void) _MD_init_locks(void); +NSPR_API(PRStatus) _MD_new_lock(struct _MDLock *md); +NSPR_API(void) _MD_free_lock(struct _MDLock *md); +NSPR_API(void) _MD_lock(struct _MDLock *md); +NSPR_API(PRIntn) _MD_test_and_lock(struct _MDLock *md); +NSPR_API(void) _MD_unlock(struct _MDLock *md); +NSPR_API(void) _MD_ioq_lock(void); +NSPR_API(void) _MD_ioq_unlock(void); +NSPR_API(void) _MD_new_sem(struct _MDSemaphore *md, PRUintn value); +NSPR_API(void) _MD_destroy_sem(struct _MDSemaphore *md); +NSPR_API(PRStatus) _MD_timed_wait_sem(struct _MDSemaphore *md, PRIntervalTime timeout); +NSPR_API(PRStatus) _MD_wait_sem(struct _MDSemaphore *md); +NSPR_API(void) _MD_post_sem(struct _MDSemaphore *md); +// NSPR_API(PRInt32) _MD_new_cv(struct _MDCVar *md); +// NSPR_API(void) _MD_free_cv(struct _MDCVar *md); +// NSPR_API(void) _MD_wait_cv(struct _MDCVar *mdCVar, struct _MDLock *mdLock, PRIntervalTime timeout); +// NSPR_API(void) _MD_notify_cv(struct _MDCVar *md, struct _MDLock *lock); +// NSPR_API(void) _MD_notifyall_cv(struct _MDCVar *md, struct _MDLock *lock); + +/* File I/O */ + +// NSPR_API(void) _MD_init_io(void); +NSPR_API(PRStatus) _MD_open_dir(struct _MDDir *md,const char *name); +NSPR_API(char *) _MD_read_dir(struct _MDDir *md, PRIntn flags); +NSPR_API(PRInt32) _MD_close_dir(struct _MDDir *md); +NSPR_API(void) _MD_make_nonblock(PRFileDesc *fd); +NSPR_API(void) _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported); +NSPR_API(void) _MD_query_fd_inheritable(PRFileDesc *fd); +NSPR_API(PRInt32) _MD_open(const char *name, PRIntn osflags, PRIntn mode); +NSPR_API(PRInt32) _MD_close_file(PRInt32 osfd); +NSPR_API(PRInt32) _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount); +NSPR_API(PRInt32) _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount); +NSPR_API(PRInt32) _MD_writev(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout); +NSPR_API(PRInt32) _MD_lseek(PRFileDesc *fd, PRInt32 offset, int whence); +NSPR_API(PRInt64) _MD_lseek64(PRFileDesc *fd, PRInt64 offset, int whence); +NSPR_API(PRInt32) _MD_fsync(PRFileDesc *fd); +NSPR_API(PRInt32) _MD_delete(const char *name); +NSPR_API(PRInt32) _MD_getfileinfo(const char *fn, PRFileInfo *info); +NSPR_API(PRInt32) _MD_getfileinfo64(const char *fn, PRFileInfo64 *info); +NSPR_API(PRInt32) _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info); +NSPR_API(PRInt32) _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info); +NSPR_API(PRInt32) _MD_rename(const char *from, const char *to); +NSPR_API(PRInt32) _MD_access(const char *name, PRIntn how); +NSPR_API(PRInt32) _MD_stat(const char *name, struct stat *buf); +NSPR_API(PRInt32) _MD_mkdir(const char *name, PRIntn mode); +NSPR_API(PRInt32) _MD_rmdir(const char *name); +NSPR_API(PRInt32) _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout); + +/* Network I/O */ +NSPR_API(PRInt32) _MD_close_socket(PRInt32 osfd); +NSPR_API(PRInt32) _MD_connect(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); +NSPR_API(PRInt32) _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout); +NSPR_API(PRInt32) _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen); +NSPR_API(PRInt32) _MD_listen(PRFileDesc *fd, PRIntn backlog); +NSPR_API(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how); +NSPR_API(PRInt32) _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout); +NSPR_API(PRInt32) _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout); +NSPR_API(PRInt32) _MD_accept_read(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout); +// NSPR_API(PRInt32) _MD_fast_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout, PRBool fast, _PR_AcceptTimeoutCallback callback, void *callbackArg); +// NSPR_API(PRInt32) _MD_fast_accept_read(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout, PRBool fast, _PR_AcceptTimeoutCallback callback, void *callbackArg); +// NSPR_API(void) _MD_update_accept_context(PRInt32 s, PRInt32 ls); +NSPR_API(PRStatus) _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); +NSPR_API(PRStatus) _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); +NSPR_API(PRStatus) _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen); +NSPR_API(PRStatus) _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen); +NSPR_API(PRInt32) _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout); +NSPR_API(PRInt32) _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); +NSPR_API(PRInt32) _MD_socketpair(int af, int type, int flags, PRInt32 *osfd); +NSPR_API(PRInt32) _MD_socket(int af, int type, int flags); +NSPR_API(PRInt32) _MD_socketavailable(PRFileDesc *fd); + +// NSPR_API(PRInt32) _MD_get_socket_error(void); +NSPR_API(PRStatus) _MD_gethostname(char *name, PRUint32 namelen); + +/* Process management */ + +NSPR_API(PRProcess *) _MD_create_process(const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr); +NSPR_API(PRStatus) _MD_detach_process(PRProcess *process); +NSPR_API(PRStatus) _MD_wait_process(PRProcess *process, PRInt32 *exitCode); +NSPR_API(PRStatus) _MD_kill_process(PRProcess *process); + +/* Atomic data operations */ + +// NSPR_API(void) _MD_init_atomic(void); +// NSPR_API(PRInt32) _MD_atomic_increment(PRInt32 *); +// NSPR_API(PRInt32) _MD_atomic_decrement(PRInt32 *); +// NSPR_API(PRInt32) _MD_atomic_set(PRInt32 *, PRInt32); + +/* Memory management */ + +NSPR_API(void) _MD_init_segs(void); +NSPR_API(PRStatus) _MD_alloc_segment(PRSegment *seg, PRUint32 size, void *vaddr); +NSPR_API(void) _MD_free_segment(PRSegment *seg); + +/* Memory mapped file I/O */ + +NSPR_API(PRStatus) _MD_create_file_map(PRFileMap *fmap, PRInt64 size); +NSPR_API(PRInt32) _MD_get_mem_map_alignment(void); +NSPR_API(void *) _MD_mem_map(PRFileMap *fmap, PRInt64 offset, PRUint32 len); +NSPR_API(PRStatus) _MD_mem_unmap(void *addr, PRUint32 size); +NSPR_API(PRStatus) _MD_close_file_map(PRFileMap *fmap); + +/* Time related */ + +NSPR_API(PRTime) _MD_now(void); +NSPR_API(void) _MD_interval_init(void); +NSPR_API(PRIntervalTime) _MD_get_interval(void); +NSPR_API(PRIntervalTime) _MD_interval_per_sec(void); + +/* File locking */ + +NSPR_API(PRStatus) _MD_lockfile(PRInt32 osfd); +NSPR_API(PRStatus) _MD_tlockfile(PRInt32 osfd); +NSPR_API(PRStatus) _MD_unlockfile(PRInt32 osfd); + +#endif /* _nspr_beos_defs_h___*/ diff -Nru nspr-4.9.5/nspr/pr/include/md/_bsdi.cfg nspr-4.10.7/nspr/pr/include/md/_bsdi.cfg --- nspr-4.9.5/nspr/pr/include/md/_bsdi.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_bsdi.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef BSDI +#define BSDI +#endif + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#if defined(__i386__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__sparc__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else + +#error "Unknown CPU architecture" + +#endif + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_bsdi.h nspr-4.10.7/nspr/pr/include/md/_bsdi.h --- nspr-4.9.5/nspr/pr/include/md/_bsdi.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_bsdi.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,181 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_bsdi_defs_h___ +#define nspr_bsdi_defs_h___ + +/* + * Internal configuration macros + */ + +#include /* for _BSDI_VERSION */ + +#define PR_LINKER_ARCH "bsdi" +#define _PR_SI_SYSNAME "BSDI" +#if defined(__i386__) +#define _PR_SI_ARCHITECTURE "x86" +#elif defined(__sparc__) +#define _PR_SI_ARCHITECTURE "sparc" +#else +#error "Unknown CPU architecture" +#endif +#define PR_DLL_SUFFIX ".so" + +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#define HAVE_BSD_FLOCK +#define NEED_TIME_R +#define _PR_HAVE_SOCKADDR_LEN +#define _PR_NO_LARGE_FILES + +#define USE_SETJMP + +/* BSD/OS 4.3 and newer all have IPv6 support */ +#if _BSDI_VERSION >= 200105 +#define _PR_INET6 +#define _PR_HAVE_INET_NTOP +#define _PR_HAVE_GETIPNODEBYNAME +#define _PR_HAVE_GETIPNODEBYADDR +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE +#endif + +#ifndef _PR_PTHREADS + +#include + +#if defined(_PR_BSDI_JMPBUF_IS_ARRAY) +#define _MD_GET_SP(_t) (_t)->md.context[2] +#elif defined(_PR_BSDI_JMPBUF_IS_STRUCT) +#define _MD_GET_SP(_t) (_t)->md.context[0].jb_esp +#else +#error "Unknown BSDI jmp_buf type" +#endif + +#define PR_NUM_GCREGS _JBLEN +#define PR_CONTEXT_TYPE jmp_buf + +#define CONTEXT(_th) ((_th)->md.context) + +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (setjmp(CONTEXT(_thread))) { \ + _main(); \ + } \ + _MD_GET_SP(_thread) = (int) (_sp - 64); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!setjmp(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + longjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +#endif /* ! _PR_PTHREADS */ + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit + +#include +#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) + +#define _MD_INTERVAL_USE_GTOD + +#endif /* nspr_bsdi_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/.cvsignore nspr-4.10.7/nspr/pr/include/md/.cvsignore --- nspr-4.9.5/nspr/pr/include/md/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/include/md/_darwin.cfg nspr-4.10.7/nspr/pr/include/md/_darwin.cfg --- nspr-4.9.5/nspr/pr/include/md/_darwin.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_darwin.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,165 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#define PR_AF_INET6 30 /* same as AF_INET6 */ + +#ifdef __LITTLE_ENDIAN__ +#undef IS_BIG_ENDIAN +#define IS_LITTLE_ENDIAN 1 +#else +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#endif + +#ifdef __LP64__ +#define IS_64 +#endif + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#undef HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS 1 + +#ifdef IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 +#define PR_BITS_PER_DWORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 +#define PR_BITS_PER_DWORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 +#define PR_ALIGN_OF_DWORD 8 + +#else /* IS_64 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 +#define PR_BITS_PER_DWORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#endif /* IS_64 */ + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ + diff -Nru nspr-4.9.5/nspr/pr/include/md/_darwin.h nspr-4.10.7/nspr/pr/include/md/_darwin.h --- nspr-4.9.5/nspr/pr/include/md/_darwin.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_darwin.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,303 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_darwin_defs_h___ +#define nspr_darwin_defs_h___ + +#include "prthread.h" + +#include +#include + +#ifdef __APPLE__ +#include +#include +#endif + +#define PR_LINKER_ARCH "darwin" +#define _PR_SI_SYSNAME "DARWIN" +#ifdef __i386__ +#define _PR_SI_ARCHITECTURE "x86" +#elif defined(__x86_64__) +#define _PR_SI_ARCHITECTURE "x86-64" +#elif defined(__ppc__) +#define _PR_SI_ARCHITECTURE "ppc" +#elif defined(__arm__) +#define _PR_SI_ARCHITECTURE "arm" +#elif defined(__aarch64__) +#define _PR_SI_ARCHITECTURE "aarch64" +#else +#error "Unknown CPU architecture" +#endif +#define PR_DLL_SUFFIX ".dylib" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#undef HAVE_STACK_GROWING_UP +#define HAVE_DLL +#if defined(__x86_64__) || TARGET_OS_IPHONE +#define USE_DLFCN +#else +#define USE_MACH_DYLD +#endif +#define _PR_HAVE_SOCKADDR_LEN +#define _PR_STAT_HAS_ST_ATIMESPEC +#define _PR_HAVE_LARGE_OFF_T +#define _PR_HAVE_SYSV_SEMAPHORES +#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY + +#define _PR_INET6 +/* + * I'd prefer to use getipnodebyname and getipnodebyaddr but the + * getipnodebyname(3) man page on Mac OS X 10.2 says they are not + * thread-safe. AI_V4MAPPED|AI_ADDRCONFIG doesn't work either. + */ +#define _PR_HAVE_GETHOSTBYNAME2 +#define _PR_HAVE_GETADDRINFO +/* + * On Mac OS X 10.2, gethostbyaddr fails with h_errno=NO_RECOVERY + * if you pass an IPv4-mapped IPv6 address to it. + */ +#define _PR_GHBA_DISALLOW_V4MAPPED +#ifdef __APPLE__ +#if !defined(MAC_OS_X_VERSION_10_3) || \ + MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 +/* + * socket(AF_INET6) fails with EPROTONOSUPPORT on Mac OS X 10.1. + * IPv6 under OS X 10.2 and below is not complete (see bug 222031). + */ +#define _PR_INET6_PROBE +#endif /* DT < 10.3 */ +#if defined(MAC_OS_X_VERSION_10_2) && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_2 +/* Mac OS X 10.2 has inet_ntop and inet_pton. */ +#define _PR_HAVE_INET_NTOP +#endif /* DT >= 10.2 */ +#endif /* __APPLE__ */ +#define _PR_IPV6_V6ONLY_PROBE +/* The IPV6_V6ONLY socket option is not defined on Mac OS X 10.1. */ +#ifndef IPV6_V6ONLY +#define IPV6_V6ONLY 27 +#endif + +#ifdef __ppc__ +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +extern PRInt32 _PR_DarwinPPC_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT(val) _PR_DarwinPPC_AtomicIncrement(val) +extern PRInt32 _PR_DarwinPPC_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT(val) _PR_DarwinPPC_AtomicDecrement(val) +extern PRInt32 _PR_DarwinPPC_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET(val, newval) _PR_DarwinPPC_AtomicSet(val, newval) +extern PRInt32 _PR_DarwinPPC_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD(ptr, val) _PR_DarwinPPC_AtomicAdd(ptr, val) +#endif /* __ppc__ */ + +#ifdef __i386__ +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +extern PRInt32 _PR_Darwin_x86_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT(val) _PR_Darwin_x86_AtomicIncrement(val) +extern PRInt32 _PR_Darwin_x86_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT(val) _PR_Darwin_x86_AtomicDecrement(val) +extern PRInt32 _PR_Darwin_x86_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET(val, newval) _PR_Darwin_x86_AtomicSet(val, newval) +extern PRInt32 _PR_Darwin_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD(ptr, val) _PR_Darwin_x86_AtomicAdd(ptr, val) +#endif /* __i386__ */ + +#ifdef __x86_64__ +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +extern PRInt32 _PR_Darwin_x86_64_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT(val) _PR_Darwin_x86_64_AtomicIncrement(val) +extern PRInt32 _PR_Darwin_x86_64_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT(val) _PR_Darwin_x86_64_AtomicDecrement(val) +extern PRInt32 _PR_Darwin_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET(val, newval) _PR_Darwin_x86_64_AtomicSet(val, newval) +extern PRInt32 _PR_Darwin_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD(ptr, val) _PR_Darwin_x86_64_AtomicAdd(ptr, val) +#endif /* __x86_64__ */ + +#if defined(__arm__) || defined(__aarch64__) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +#define _MD_ATOMIC_INCREMENT(val) OSAtomicIncrement32(val) +#define _MD_ATOMIC_DECREMENT(val) OSAtomicDecrement32(val) +static inline PRInt32 _MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) +{ + PRInt32 oldval; + do { + oldval = *val; + } while (!OSAtomicCompareAndSwap32(oldval, newval, val)); + return oldval; +} +#define _MD_ATOMIC_ADD(ptr, val) OSAtomicAdd32(val, ptr) +#endif /* __arm__ || __aarch64__ */ + +#define USE_SETJMP + +#if !defined(_PR_PTHREADS) + +#include + +#define PR_CONTEXT_TYPE jmp_buf + +#define CONTEXT(_th) ((_th)->md.context) +#define _MD_GET_SP(_th) (((struct sigcontext *) (_th)->md.context)->sc_onstack) +#define PR_NUM_GCREGS _JBLEN + +/* +** Initialize a thread context to run "_main()" when started +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (setjmp(CONTEXT(_thread))) { \ + _main(); \ + } \ + _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!setjmp(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + longjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +extern PRStatus _MD_InitializeThread(PRThread *thread); + +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread +#define _MD_RESUME_THREAD(thread) _MD_resume_thread +#define _MD_CLEAN_THREAD(_thread) + +extern PRStatus _MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize); +extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri); +extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout); +extern PRStatus _MD_WAKEUP_WAITER(PRThread *); +extern void _MD_YIELD(void); + +#endif /* ! _PR_PTHREADS */ + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INTERVAL_INIT _PR_Mach_IntervalInit +#define _MD_GET_INTERVAL _PR_Mach_GetInterval +#define _MD_INTERVAL_PER_SEC _PR_Mach_TicksPerSecond + +extern void _MD_EarlyInit(void); +extern void _PR_Mach_IntervalInit(void); +extern PRIntervalTime _PR_Mach_GetInterval(void); +extern PRIntervalTime _PR_Mach_TicksPerSecond(void); + +/* + * We wrapped the select() call. _MD_SELECT refers to the built-in, + * unwrapped version. + */ +#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) + +/* For writev() */ +#include + +#endif /* nspr_darwin_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_dgux.cfg nspr-4.10.7/nspr/pr/include/md/_dgux.cfg --- nspr-4.9.5/nspr/pr/include/md/_dgux.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_dgux.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef DGUX +#define DGUX +#endif + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_dgux.h nspr-4.10.7/nspr/pr/include/md/_dgux.h --- nspr-4.9.5/nspr/pr/include/md/_dgux.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_dgux.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_dgux_defs_h___ +#define nspr_dgux_defs_h___ + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "dgux" +#define _PR_SI_SYSNAME "DGUX" +#define _PR_SI_ARCHITECTURE "x86" +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#ifndef HAVE_WEAK_IO_SYMBOLS +#define HAVE_WEAK_IO_SYMBOLS +#endif + +#undef HAVE_STACK_GROWING_UP +#define HAVE_NETCONFIG +#define HAVE_DLL +#define USE_DLFCN +#define NEED_STRFTIME_LOCK +#define NEED_TIME_R +#define _PR_NEED_STRCASECMP +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_NO_LARGE_FILES +#define _PR_STAT_HAS_ONLY_ST_ATIME + +#define USE_SETJMP + +#include + +#define _SETJMP setjmp +#define _LONGJMP longjmp +#define _PR_CONTEXT_TYPE jmp_buf +#define _MD_GET_SP(_t) (_t)->md.context[4] +#define _PR_NUM_GCREGS _JBLEN + +#define CONTEXT(_th) ((_th)->md.context) + +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ + _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!_SETJMP(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + _LONGJMP(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures. + * Don't use SVR4 native threads (yet). + */ + +struct _MDThread { + _PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +/* + * The following are copied from _sunos.h, _aix.h. This means + * some of them should probably be moved into _unixos.h. But + * _irix.h seems to be quite different in regard to these macros. + */ +#define _MD_INTERVAL_USE_GTOD + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +/* + * We wrapped the select() call. _MD_SELECT refers to the built-in, + * unwrapped version. + */ +#include +#include +#include +extern int _select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *execptfds, struct timeval *timeout); +#define _MD_SELECT _select + +#define _MD_POLL _poll +#include +#include +extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); + +#endif /* nspr_dgux_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_freebsd.cfg nspr-4.10.7/nspr/pr/include/md/_freebsd.cfg --- nspr-4.9.5/nspr/pr/include/md/_freebsd.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_freebsd.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,305 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef FREEBSD +#define FREEBSD +#endif + +#define PR_AF_INET6 28 /* same as AF_INET6 */ + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif + +#if defined(__i386__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#elif defined(__alpha__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#elif defined(__sparc__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#elif defined(__ia64__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#elif defined(__amd64__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#else + +#error "Unknown CPU architecture" + +#endif + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_freebsd.h nspr-4.10.7/nspr/pr/include/md/_freebsd.h --- nspr-4.9.5/nspr/pr/include/md/_freebsd.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_freebsd.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,243 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_freebsd_defs_h___ +#define nspr_freebsd_defs_h___ + +#include "prthread.h" + +#if __FreeBSD__ >= 2 +#include /* for __FreeBSD_version */ +#endif +#include + +#define PR_LINKER_ARCH "freebsd" +#define _PR_SI_SYSNAME "FREEBSD" +#if defined(__i386__) +#define _PR_SI_ARCHITECTURE "x86" +#elif defined(__alpha__) +#define _PR_SI_ARCHITECTURE "alpha" +#elif defined(__sparc__) +#define _PR_SI_ARCHITECTURE "sparc" +#elif defined(__ia64__) +#define _PR_SI_ARCHITECTURE "ia64" +#elif defined(__amd64__) +#define _PR_SI_ARCHITECTURE "amd64" +#else +#error "Unknown CPU architecture" +#endif +#if defined(__ELF__) +#define PR_DLL_SUFFIX ".so" +#else +#define PR_DLL_SUFFIX ".so.1.0" +#endif + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#undef HAVE_STACK_GROWING_UP +#define HAVE_DLL +#define USE_DLFCN +#define _PR_HAVE_SOCKADDR_LEN +#define _PR_STAT_HAS_ST_ATIMESPEC +#define _PR_HAVE_LARGE_OFF_T + +#if defined(_PR_PTHREADS) +#if __FreeBSD_version >= 400008 +/* + * libc_r before this version of FreeBSD doesn't have poll(). + * Although libc has poll(), it is not thread-safe so we can't + * use it in the pthreads version. + */ +#define _PR_POLL_AVAILABLE +#endif +#else +#if __FreeBSD_version >= 300000 +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#endif +#endif + +#define _PR_HAVE_SYSV_SEMAPHORES +#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY + +#if __FreeBSD_version >= 400014 +#define _PR_INET6 +#define _PR_HAVE_INET_NTOP +#define _PR_HAVE_GETHOSTBYNAME2 +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE +#define _PR_IPV6_V6ONLY_PROBE +#endif + +#define USE_SETJMP + +#ifndef _PR_PTHREADS +#include + +#define PR_CONTEXT_TYPE sigjmp_buf + +#define CONTEXT(_th) ((_th)->md.context) + +#define _MD_GET_SP(_th) (_th)->md.context[0]._sjb[2] +#define PR_NUM_GCREGS _JBLEN + +/* +** Initialize a thread context to run "_main()" when started +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (sigsetjmp(CONTEXT(_thread), 1)) { \ + _main(); \ + } \ + _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!sigsetjmp(CONTEXT(_thread), 1)) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + siglongjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +extern PRStatus _MD_InitializeThread(PRThread *thread); + +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread +#define _MD_RESUME_THREAD(thread) _MD_resume_thread +#define _MD_CLEAN_THREAD(_thread) + +extern PRStatus _MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize); +extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri); +extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout); +extern PRStatus _MD_WAKEUP_WAITER(PRThread *); +extern void _MD_YIELD(void); + +#endif /* ! _PR_PTHREADS */ + +extern void _MD_EarlyInit(void); + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INTERVAL_USE_GTOD + +/* + * We wrapped the select() call. _MD_SELECT refers to the built-in, + * unwrapped version. + */ +#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) + +#if defined(_PR_POLL_AVAILABLE) +#include +#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout) +#endif + +/* freebsd has INADDR_LOOPBACK defined, but in /usr/include/rpc/types.h, and I didn't + want to be including that.. */ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK (u_long)0x7F000001 +#endif + +/* For writev() */ +#include + +#endif /* nspr_freebsd_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_hpux32.cfg nspr-4.10.7/nspr/pr/include/md/_hpux32.cfg --- nspr-4.9.5/nspr/pr/include/md/_hpux32.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_hpux32.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef HPUX +#define HPUX +#endif + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define PR_AF_INET6 22 /* same as AF_INET6 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_hpux64.cfg nspr-4.10.7/nspr/pr/include/md/_hpux64.cfg --- nspr-4.9.5/nspr/pr/include/md/_hpux64.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_hpux64.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef HPUX +#define HPUX +#endif + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define IS_64 + +#define PR_AF_INET6 22 /* same as AF_INET6 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_hpux.h nspr-4.10.7/nspr/pr/include/md/_hpux.h --- nspr-4.9.5/nspr/pr/include/md/_hpux.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_hpux.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,288 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_xhppa_defs_h___ +#define nspr_xhppa_defs_h___ + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "hpux" +#define _PR_SI_SYSNAME "HPUX" +#ifdef __ia64 +#define _PR_SI_ARCHITECTURE "ia64" +#define PR_DLL_SUFFIX ".so" +#else +/* + * _PR_SI_ARCHITECTURE must be "hppa1.1" for backward compatibility. + * It was changed to "hppa" in NSPR 4.6.2, but was changed back in + * NSPR 4.6.4. + */ +#define _PR_SI_ARCHITECTURE "hppa1.1" +#define PR_DLL_SUFFIX ".sl" +#endif + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +/* + * _USE_BIG_FDS increases the size of fd_set from 256 bytes to + * about 7500 bytes. PR_Poll allocates three fd_sets on the + * stack, so it is safer to also increase the default thread + * stack size. + */ +#define _MD_DEFAULT_STACK_SIZE (2*65536L) +#define _MD_MINIMUM_STACK_SIZE (2*65536L) +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#define NEED_TIME_R + +#define HAVE_STACK_GROWING_UP +#undef HAVE_WEAK_IO_SYMBOLS +#undef HAVE_WEAK_MALLOC_SYMBOLS +#define HAVE_DLL +#ifdef IS_64 +#define USE_DLFCN +#else +#define USE_HPSHL +#endif +#ifndef HAVE_STRERROR +#define HAVE_STRERROR +#endif +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_STAT_HAS_ONLY_ST_ATIME +#define _PR_HAVE_POSIX_SEMAPHORES +#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY +#define _PR_ACCEPT_INHERIT_NONBLOCK + +#if defined(__ia64) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT _PR_ia64_AtomicIncrement +extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT _PR_ia64_AtomicDecrement +extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD _PR_ia64_AtomicAdd +extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET _PR_ia64_AtomicSet +#endif + +#define _PR_HAVE_GETIPNODEBYNAME +#define _PR_HAVE_GETIPNODEBYADDR +#define _PR_HAVE_GETADDRINFO +#ifdef _PR_INET6 +#define _PR_HAVE_INET_NTOP +#else +#define _PR_INET6_PROBE + +/* for HP-UX 11.11 without IPv6 */ +#ifndef AF_INET6 +#define AF_INET6 22 +#define AI_CANONNAME 2 +#define AI_NUMERICHOST 4 +#define AI_NUMERICSERV 8 +#define AI_V4MAPPED 0x00000010 +#define AI_ADDRCONFIG 0x00000040 +#define AI_ALL 0x00000020 +#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) +#define NI_NUMERICHOST 2 +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* IPPROTO_xxx for IPv4 and IPv6 */ + socklen_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for host */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* for HP-UX 11.11 without IPv6 */ + +#define _PR_HAVE_MD_SOCKADDR_IN6 +/* isomorphic to struct in6_addr on HP-UX B.11.23 */ +struct _md_in6_addr { + union { + PRUint8 _S6_u8[16]; + PRUint16 _S6_u16[8]; + PRUint32 _S6_u32[4]; + PRUint32 __S6_align; + } _s6_un; +}; +/* isomorphic to struct sockaddr_in6 on HP-UX B.11.23 */ +struct _md_sockaddr_in6 { + PRUint16 sin6_family; + PRUint16 sin6_port; + PRUint32 sin6_flowinfo; + struct _md_in6_addr sin6_addr; + PRUint32 sin6_scope_id; +}; +#endif + +#if !defined(_PR_PTHREADS) + +#include +#include + +#define USE_SETJMP + +#define _MD_GET_SP(_t) (*((int *)((_t)->md.jb) + 1)) +#define PR_NUM_GCREGS _JBLEN +/* Caveat: This makes jmp_buf full of doubles. */ +#define CONTEXT(_th) ((_th)->md.jb) + + /* Stack needs two frames (64 bytes) at the bottom */ \ +#define _MD_SET_THR_SP(_t, _sp) ((_MD_GET_SP(_t)) = (int) (_sp + 64 *2)) +#define SAVE_CONTEXT(_th) _setjmp(CONTEXT(_th)) +#define GOTO_CONTEXT(_th) _longjmp(CONTEXT(_th), 1) + +#if !defined(PTHREADS_USER) + +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *(status) = PR_TRUE; \ + if (_setjmp(CONTEXT(_thread))) (*_main)(); \ + /* Stack needs two frames (64 bytes) at the bottom */ \ + (_MD_GET_SP(_thread)) = (int) ((_sp) + 64*2); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!_setjmp(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + _longjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures. HP-UX has no native threads. */ + +struct _MDThread { + jmp_buf jb; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread +#define _MD_RESUME_THREAD(thread) _MD_resume_thread +#define _MD_CLEAN_THREAD(_thread) + +#else /* PTHREADS_USER */ + +#include "_nspr_pthread.h" + +#endif /* PTHREADS_USER */ + +#endif /* !defined(_PR_PTHREADS) */ + +#if !defined(PTHREADS_USER) +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#endif + +#if defined(HPUX_LW_TIMER) +extern void _PR_HPUX_LW_IntervalInit(void); +extern PRIntervalTime _PR_HPUX_LW_GetInterval(void); +#define _MD_INTERVAL_INIT _PR_HPUX_LW_IntervalInit +#define _MD_GET_INTERVAL _PR_HPUX_LW_GetInterval +#define _MD_INTERVAL_PER_SEC() 1000 +#else +#define _MD_INTERVAL_USE_GTOD +#endif + +/* + * We wrapped the select() call. _MD_SELECT refers to the built-in, + * unwrapped version. + */ +#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) + +#include +#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout) + +#ifdef HPUX11 +extern void _MD_hpux_map_sendfile_error(int err); +#endif /* HPUX11 */ + +#endif /* nspr_xhppa_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_irix32.cfg nspr-4.10.7/nspr/pr/include/md/_irix32.cfg --- nspr-4.9.5/nspr/pr/include/md/_irix32.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_irix32.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef _SGI_MP_SOURCE +#define _SGI_MP_SOURCE +#endif + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef IRIX +#define IRIX +#endif + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#define _PR_POLL_BACKCOMPAT + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_irix64.cfg nspr-4.10.7/nspr/pr/include/md/_irix64.cfg --- nspr-4.9.5/nspr/pr/include/md/_irix64.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_irix64.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef _SGI_MP_SOURCE +#define _SGI_MP_SOURCE +#endif + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef IRIX +#define IRIX +#endif + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define IS_64 + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_irix.h nspr-4.10.7/nspr/pr/include/md/_irix.h --- nspr-4.9.5/nspr/pr/include/md/_irix.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_irix.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,438 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_irix_defs_h___ +#define nspr_irix_defs_h___ + +#define _PR_HAVE_ATOMIC_CAS + +/* + * MipsPro assembler defines _LANGUAGE_ASSEMBLY + */ +#ifndef _LANGUAGE_ASSEMBLY + +#include "prclist.h" +#include "prthread.h" +#include + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "irix" +#define _PR_SI_SYSNAME "IRIX" +#define _PR_SI_ARCHITECTURE "mips" +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _PR_NUM_GCREGS 9 +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MIN_STACK_SIZE 16384L + +#undef HAVE_STACK_GROWING_UP +#define HAVE_WEAK_IO_SYMBOLS +#define HAVE_WEAK_MALLOC_SYMBOLS +#define HAVE_DLL +#define USE_DLFCN +#define _PR_HAVE_ATOMIC_OPS +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_STAT_HAS_ST_ATIM +#define _PR_HAVE_OFF64_T +#define HAVE_POINTER_LOCALTIME_R +#define _PR_HAVE_POSIX_SEMAPHORES +#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY +#define _PR_ACCEPT_INHERIT_NONBLOCK + +#ifdef _PR_INET6 +#define _PR_HAVE_INET_NTOP +#define _PR_HAVE_GETIPNODEBYNAME +#define _PR_HAVE_GETIPNODEBYADDR +#define _PR_HAVE_GETADDRINFO +#endif + +/* Initialization entry points */ +NSPR_API(void) _MD_EarlyInit(void); +#define _MD_EARLY_INIT _MD_EarlyInit + +NSPR_API(void) _MD_IrixInit(void); +#define _MD_FINAL_INIT _MD_IrixInit + +#define _MD_INIT_IO() + +/* Timer operations */ +NSPR_API(PRIntervalTime) _MD_IrixGetInterval(void); +#define _MD_GET_INTERVAL _MD_IrixGetInterval + +NSPR_API(PRIntervalTime) _MD_IrixIntervalPerSec(void); +#define _MD_INTERVAL_PER_SEC _MD_IrixIntervalPerSec + +/* GC operations */ +NSPR_API(void *) _MD_GetSP(PRThread *thread); +#define _MD_GET_SP _MD_GetSP + +/* The atomic operations */ +#include +#define _MD_INIT_ATOMIC() +#define _MD_ATOMIC_INCREMENT(val) add_then_test((unsigned long*)val, 1) +#define _MD_ATOMIC_ADD(ptr, val) add_then_test((unsigned long*)ptr, (unsigned long)val) +#define _MD_ATOMIC_DECREMENT(val) add_then_test((unsigned long*)val, 0xffffffff) +#define _MD_ATOMIC_SET(val, newval) test_and_set((unsigned long*)val, newval) + +#if defined(_PR_PTHREADS) +#else /* defined(_PR_PTHREADS) */ + +/************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + + +/* + * Data region private to each sproc. This region is setup by calling + * mmap(...,MAP_LOCAL,...). The private data is mapped at the same + * address in every sproc, but every sproc gets a private mapping. + * + * Just make sure that this structure fits in a page, as only one page + * is allocated for the private region. + */ +struct sproc_private_data { + struct PRThread *me; + struct _PRCPU *cpu; + struct PRThread *last; + PRUintn intsOff; + int sproc_pid; +}; + +extern char *_nspr_sproc_private; + +#define _PR_PRDA() ((struct sproc_private_data *) _nspr_sproc_private) +#define _MD_SET_CURRENT_THREAD(_thread) _PR_PRDA()->me = (_thread) +#define _MD_THIS_THREAD() (_PR_PRDA()->me) +#define _MD_LAST_THREAD() (_PR_PRDA()->last) +#define _MD_SET_LAST_THREAD(_thread) _PR_PRDA()->last = (_thread) +#define _MD_CURRENT_CPU() (_PR_PRDA()->cpu) +#define _MD_SET_CURRENT_CPU(_cpu) _PR_PRDA()->cpu = (_cpu) +#define _MD_SET_INTSOFF(_val) (_PR_PRDA()->intsOff = _val) +#define _MD_GET_INTSOFF() (_PR_PRDA()->intsOff) + +#define _MD_SET_SPROC_PID(_val) (_PR_PRDA()->sproc_pid = _val) +#define _MD_GET_SPROC_PID() (_PR_PRDA()->sproc_pid) + +NSPR_API(struct PRThread*) _MD_get_attached_thread(void); +NSPR_API(struct PRThread*) _MD_get_current_thread(void); +#define _MD_GET_ATTACHED_THREAD() _MD_get_attached_thread() +#define _MD_CURRENT_THREAD() _MD_get_current_thread() + +#define _MD_CHECK_FOR_EXIT() { \ + if (_pr_irix_exit_now) { \ + _PR_POST_SEM(_pr_irix_exit_sem); \ + _MD_Wakeup_CPUs(); \ + _exit(0); \ + } \ + } + +#define _MD_ATTACH_THREAD(threadp) + +#define _MD_SAVE_ERRNO(_thread) (_thread)->md.errcode = errno; +#define _MD_RESTORE_ERRNO(_thread) errno = (_thread)->md.errcode; + +extern struct _PRCPU *_pr_primordialCPU; +extern usema_t *_pr_irix_exit_sem; +extern PRInt32 _pr_irix_exit_now; +extern int _pr_irix_primoridal_cpu_fd[]; +extern PRInt32 _pr_irix_process_exit; +extern PRInt32 _pr_irix_process_exit_code; + +/* Thread operations */ +#define _PR_LOCK_HEAP() { \ + PRIntn _is; \ + if (_pr_primordialCPU) { \ + if (_MD_GET_ATTACHED_THREAD() && \ + !_PR_IS_NATIVE_THREAD( \ + _MD_GET_ATTACHED_THREAD())) \ + _PR_INTSOFF(_is); \ + _PR_LOCK(_pr_heapLock); \ + } + +#define _PR_UNLOCK_HEAP() if (_pr_primordialCPU) { \ + _PR_UNLOCK(_pr_heapLock); \ + if (_MD_GET_ATTACHED_THREAD() && \ + !_PR_IS_NATIVE_THREAD( \ + _MD_GET_ATTACHED_THREAD())) \ + _PR_INTSON(_is); \ + } \ + } + +#define _PR_OPEN_POLL_SEM(_sem) usopenpollsema(_sem, 0666) +#define _PR_WAIT_SEM(_sem) uspsema(_sem) +#define _PR_POST_SEM(_sem) usvsema(_sem) + +#define _MD_CVAR_POST_SEM(threadp) usvsema((threadp)->md.cvar_pollsem) + +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +struct _MDLock { + ulock_t lock; + usptr_t *arena; +}; + +/* + * disable pre-emption for the LOCAL threads when calling the arena lock + * routines + */ + +#define _PR_LOCK(lock) { \ + PRIntn _is; \ + PRThread *me = _MD_GET_ATTACHED_THREAD(); \ + if (me && !_PR_IS_NATIVE_THREAD(me)) \ + _PR_INTSOFF(_is); \ + ussetlock(lock); \ + if (me && !_PR_IS_NATIVE_THREAD(me)) \ + _PR_FAST_INTSON(_is); \ + } + +#define _PR_UNLOCK(lock) { \ + PRIntn _is; \ + PRThread *me = _MD_GET_ATTACHED_THREAD(); \ + if (me && !_PR_IS_NATIVE_THREAD(me)) \ + _PR_INTSOFF(_is); \ + usunsetlock(lock); \ + if (me && !_PR_IS_NATIVE_THREAD(me)) \ + _PR_FAST_INTSON(_is); \ + } + +NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md); +NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp); + +#define _MD_LOCK(_lockp) _PR_LOCK((_lockp)->lock) +#define _MD_UNLOCK(_lockp) _PR_UNLOCK((_lockp)->lock) +#define _MD_TEST_AND_LOCK(_lockp) (uscsetlock((_lockp)->lock, 1) == 0) + +extern ulock_t _pr_heapLock; + +struct _MDThread { + jmp_buf jb; + usptr_t *pollsem_arena; + usema_t *cvar_pollsem; + PRInt32 cvar_pollsemfd; + PRInt32 cvar_pollsem_select; /* acquire sem by calling select */ + PRInt32 cvar_wait; /* if 1, thread is waiting on cvar Q */ + PRInt32 id; + PRInt32 suspending_id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDSemaphore { + usema_t *sem; +}; + +struct _MDCVar { + ulock_t mdcvar_lock; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + + +struct _MDCPU { + PRInt32 id; + PRInt32 suspending_id; + struct _MDCPU_Unix md_unix; +}; + +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + int *jb = (_thread)->md.jb; \ + *status = PR_TRUE; \ + (void) setjmp(jb); \ + (_thread)->md.jb[JB_SP] = (int) ((_sp) - 64); \ + (_thread)->md.jb[JB_PC] = (int) _main; \ + _thread->no_sched = 0; \ + PR_END_MACRO + +/* +** Switch away from the current thread context by saving its state and +** calling the thread scheduler. Reload cpu when we come back from the +** context switch because it might have changed. +* +* XXX RUNQ lock needed before clearing _PR_NO_SCHED flag, because the +* thread may be unr RUNQ? +*/ +#define _MD_SWITCH_CONTEXT(_thread) \ + PR_BEGIN_MACRO \ + PR_ASSERT(_thread->no_sched); \ + if (!setjmp(_thread->md.jb)) { \ + _MD_SAVE_ERRNO(_thread) \ + _MD_SET_LAST_THREAD(_thread); \ + _PR_Schedule(); \ + } else { \ + PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \ + _MD_LAST_THREAD()->no_sched = 0; \ + } \ + PR_END_MACRO + +/* +** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or +** initialized by _MD_INIT_CONTEXT. +*/ +#define _MD_RESTORE_CONTEXT(_newThread) \ + PR_BEGIN_MACRO \ + int *jb = (_newThread)->md.jb; \ + _MD_RESTORE_ERRNO(_newThread) \ + _MD_SET_CURRENT_THREAD(_newThread); \ + _newThread->no_sched = 1; \ + longjmp(jb, 1); \ + PR_END_MACRO + +NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread, + PRBool wakeup_parent); +NSPR_API(PRStatus) _MD_InitAttachedThread(struct PRThread *thread, + PRBool wakeup_parent); +#define _MD_INIT_THREAD(thread) _MD_InitThread(thread, PR_TRUE) +#define _MD_INIT_ATTACHED_THREAD(thread) \ + _MD_InitAttachedThread(thread, PR_FALSE) + +NSPR_API(void) _MD_ExitThread(struct PRThread *thread); +#define _MD_EXIT_THREAD _MD_ExitThread + +NSPR_API(void) _MD_SuspendThread(struct PRThread *thread); +#define _MD_SUSPEND_THREAD _MD_SuspendThread + +NSPR_API(void) _MD_ResumeThread(struct PRThread *thread); +#define _MD_RESUME_THREAD _MD_ResumeThread + +NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread); +#define _MD_SUSPEND_CPU _MD_SuspendCPU + +NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread); +#define _MD_RESUME_CPU _MD_ResumeCPU + +#define _MD_BEGIN_SUSPEND_ALL() +#define _MD_END_SUSPEND_ALL() +#define _MD_BEGIN_RESUME_ALL() +#define _MD_END_RESUME_ALL() + +NSPR_API(void) _MD_InitLocks(void); +#define _MD_INIT_LOCKS _MD_InitLocks + +NSPR_API(void) _MD_CleanThread(struct PRThread *thread); +#define _MD_CLEAN_THREAD _MD_CleanThread + +#define _MD_YIELD() sginap(0) + +/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and + * awaken a thread which is waiting on a lock or cvar. + */ +NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout); +#define _MD_WAIT _MD_wait + +NSPR_API(void) _PR_MD_primordial_cpu(); +NSPR_API(void) _PR_MD_WAKEUP_PRIMORDIAL_CPU(); + +NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *); +#define _MD_WAKEUP_WAITER _MD_WakeupWaiter + +NSPR_API(void ) _MD_exit(PRIntn status); +#define _MD_EXIT _MD_exit + +#include "prthread.h" + +NSPR_API(void) _MD_SetPriority(struct _MDThread *thread, + PRThreadPriority newPri); +#define _MD_SET_PRIORITY _MD_SetPriority + +NSPR_API(PRStatus) _MD_CreateThread( + struct PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize); +#define _MD_CREATE_THREAD _MD_CreateThread + +extern void _MD_CleanupBeforeExit(void); +#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit + +NSPR_API(void) _PR_MD_PRE_CLEANUP(PRThread *me); + + +/* The following defines the unwrapped versions of select() and poll(). */ +extern int _select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout); +#define _MD_SELECT _select + +#include +#include +#define _MD_POLL _poll +extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); + + +#define HAVE_THREAD_AFFINITY 1 + +NSPR_API(PRInt32) _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask); +#define _MD_GETTHREADAFFINITYMASK _MD_GetThreadAffinityMask + +NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu); +#define _MD_INIT_RUNNING_CPU _MD_InitRunningCPU + +#endif /* defined(_PR_PTHREADS) */ + +#endif /* _LANGUAGE_ASSEMBLY */ + +#endif /* nspr_irix_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_linux.cfg nspr-4.10.7/nspr/pr/include/md/_linux.cfg --- nspr-4.9.5/nspr/pr/include/md/_linux.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_linux.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,988 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This file is used by not only Linux but also other glibc systems + * such as GNU/Hurd and GNU/k*BSD. + */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#if !defined(LINUX) && defined(__linux__) +#define LINUX +#endif + +#ifdef __FreeBSD_kernel__ +#define PR_AF_INET6 28 /* same as AF_INET6 */ +#elif defined(__GNU__) +#define PR_AF_INET6 26 /* same as AF_INET6 */ +#else +#define PR_AF_INET6 10 /* same as AF_INET6 */ +#endif + +#ifdef __powerpc64__ + +#ifdef __LITTLE_ENDIAN__ +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#else +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#endif +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__powerpc__) + +#ifdef __LITTLE_ENDIAN__ +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#else +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#endif + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__alpha) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__ia64__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__x86_64__) + +#ifdef __ILP32__ + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#endif + +#elif defined(__mc68000__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 2 +#define PR_ALIGN_OF_LONG 2 +#define PR_ALIGN_OF_INT64 2 +#define PR_ALIGN_OF_FLOAT 2 +#define PR_ALIGN_OF_DOUBLE 2 +#define PR_ALIGN_OF_POINTER 2 +#define PR_ALIGN_OF_WORD 2 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__sparc__) && defined (__arch64__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__sparc__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__i386__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__mips__) + +#ifdef __MIPSEB__ +#define IS_BIG_ENDIAN 1 +#undef IS_LITTLE_ENDIAN +#elif defined(__MIPSEL__) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#else +#error "Unknown MIPS endianness." +#endif + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__arm__) + +#ifdef __ARMEB__ +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#elif defined(__ARMEL__) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#else +#error "Unknown ARM endianness." +#endif + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__aarch64__) + +#ifdef __AARCH64EB__ +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#elif defined(__AARCH64EL__) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#else +#error "Unknown Aarch64 endianness." +#endif +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__hppa__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__s390x__) + +#define IS_BIG_ENDIAN 1 +#undef IS_LITTLE_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__s390__) + +#define IS_BIG_ENDIAN 1 +#undef IS_LITTLE_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__sh__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__avr32__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__m32r__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else + +#error "Unknown CPU architecture" + +#endif + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#if PR_ALIGN_OF_DOUBLE == 8 +#define HAVE_ALIGNED_DOUBLES +#endif +#if PR_ALIGN_OF_INT64 == 8 +#define HAVE_ALIGNED_LONGLONGS +#endif + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_linux.h nspr-4.10.7/nspr/pr/include/md/_linux.h --- nspr-4.9.5/nspr/pr/include/md/_linux.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_linux.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,670 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This file is used by not only Linux but also other glibc systems + * such as GNU/Hurd and GNU/k*BSD. + */ + +#ifndef nspr_linux_defs_h___ +#define nspr_linux_defs_h___ + +#include "prthread.h" + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "linux" +#define _PR_SI_SYSNAME "LINUX" +#ifdef __powerpc64__ +#define _PR_SI_ARCHITECTURE "ppc64" +#elif defined(__powerpc__) +#define _PR_SI_ARCHITECTURE "ppc" +#elif defined(__alpha) +#define _PR_SI_ARCHITECTURE "alpha" +#elif defined(__ia64__) +#define _PR_SI_ARCHITECTURE "ia64" +#elif defined(__x86_64__) +#define _PR_SI_ARCHITECTURE "x86-64" +#elif defined(__mc68000__) +#define _PR_SI_ARCHITECTURE "m68k" +#elif defined(__sparc__) && defined(__arch64__) +#define _PR_SI_ARCHITECTURE "sparc64" +#elif defined(__sparc__) +#define _PR_SI_ARCHITECTURE "sparc" +#elif defined(__i386__) +#define _PR_SI_ARCHITECTURE "x86" +#elif defined(__mips__) +#define _PR_SI_ARCHITECTURE "mips" +#elif defined(__arm__) +#define _PR_SI_ARCHITECTURE "arm" +#elif defined(__aarch64__) +#define _PR_SI_ARCHITECTURE "aarch64" +#elif defined(__hppa__) +#define _PR_SI_ARCHITECTURE "hppa" +#elif defined(__s390x__) +#define _PR_SI_ARCHITECTURE "s390x" +#elif defined(__s390__) +#define _PR_SI_ARCHITECTURE "s390" +#elif defined(__sh__) +#define _PR_SI_ARCHITECTURE "sh" +#elif defined(__avr32__) +#define _PR_SI_ARCHITECTURE "avr32" +#elif defined(__m32r__) +#define _PR_SI_ARCHITECTURE "m32r" +#else +#error "Unknown CPU architecture" +#endif +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#if defined(__aarch64__) +#define _MD_MINIMUM_STACK_SIZE 0x20000 +#endif + +#undef HAVE_STACK_GROWING_UP + +/* + * Elf linux supports dl* functions + */ +#define HAVE_DLL +#define USE_DLFCN +#if defined(ANDROID) +#define NO_DLOPEN_NULL +#endif + +#if defined(__FreeBSD_kernel__) || defined(__GNU__) +#define _PR_HAVE_SOCKADDR_LEN +#endif + +#if defined(__i386__) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +extern PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT _PR_x86_AtomicIncrement +extern PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT _PR_x86_AtomicDecrement +extern PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD _PR_x86_AtomicAdd +extern PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET _PR_x86_AtomicSet +#endif + +#if defined(__ia64__) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT _PR_ia64_AtomicIncrement +extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT _PR_ia64_AtomicDecrement +extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD _PR_ia64_AtomicAdd +extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET _PR_ia64_AtomicSet +#endif + +#if defined(__x86_64__) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +extern PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT _PR_x86_64_AtomicIncrement +extern PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT _PR_x86_64_AtomicDecrement +extern PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD _PR_x86_64_AtomicAdd +extern PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET _PR_x86_64_AtomicSet +#endif + +#if defined(__powerpc__) && !defined(__powerpc64__) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +extern PRInt32 _PR_ppc_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT _PR_ppc_AtomicIncrement +extern PRInt32 _PR_ppc_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT _PR_ppc_AtomicDecrement +extern PRInt32 _PR_ppc_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD _PR_ppc_AtomicAdd +extern PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET _PR_ppc_AtomicSet +#endif + +#if defined(__powerpc64__) +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) +/* Use GCC built-in functions */ +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +#define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) +#define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) +#define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) +#define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) +#endif +#endif + +#if defined(__alpha) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +#define _MD_ATOMIC_ADD(ptr, i) ({ \ + PRInt32 __atomic_tmp, __atomic_ret; \ + __asm__ __volatile__( \ + "1: ldl_l %[ret], %[val] \n" \ + " addl %[ret], %[inc], %[tmp] \n" \ + " addl %[ret], %[inc], %[ret] \n" \ + " stl_c %[tmp], %[val] \n" \ + " beq %[tmp], 2f \n" \ + ".subsection 2 \n" \ + "2: br 1b \n" \ + ".previous" \ + : [ret] "=&r" (__atomic_ret), \ + [tmp] "=&r" (__atomic_tmp), \ + [val] "=m" (*ptr) \ + : [inc] "Ir" (i), "m" (*ptr)); \ + __atomic_ret; \ +}) +#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1) +#define _MD_ATOMIC_DECREMENT(ptr) ({ \ + PRInt32 __atomic_tmp, __atomic_ret; \ + __asm__ __volatile__( \ + "1: ldl_l %[ret], %[val] \n" \ + " subl %[ret], 1, %[tmp] \n" \ + " subl %[ret], 1, %[ret] \n" \ + " stl_c %[tmp], %[val] \n" \ + " beq %[tmp], 2f \n" \ + ".subsection 2 \n" \ + "2: br 1b \n" \ + ".previous" \ + : [ret] "=&r" (__atomic_ret), \ + [tmp] "=&r" (__atomic_tmp), \ + [val] "=m" (*ptr) \ + : "m" (*ptr)); \ + __atomic_ret; \ +}) +#define _MD_ATOMIC_SET(ptr, n) ({ \ + PRInt32 __atomic_tmp, __atomic_ret; \ + __asm__ __volatile__( \ + "1: ldl_l %[ret], %[val] \n" \ + " mov %[newval], %[tmp] \n" \ + " stl_c %[tmp], %[val] \n" \ + " beq %[tmp], 2f \n" \ + ".subsection 2 \n" \ + "2: br 1b \n" \ + ".previous" \ + : [ret] "=&r" (__atomic_ret), \ + [tmp] "=&r"(__atomic_tmp), \ + [val] "=m" (*ptr) \ + : [newval] "Ir" (n), "m" (*ptr)); \ + __atomic_ret; \ +}) +#endif + +#if defined(__arm__) || defined(__aarch64__) +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) +/* Use GCC built-in functions */ +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() + +#define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) +#define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) +#define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) +#define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) + +#elif defined(_PR_ARM_KUSER) +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() + +/* + * The kernel provides this helper function at a fixed address with a fixed + * ABI signature, directly callable from user space. + * + * Definition: + * Atomically store newval in *ptr if *ptr is equal to oldval. + * Return zero if *ptr was changed or non-zero if no exchange happened. + */ +typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) + +#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1) +#define _MD_ATOMIC_DECREMENT(ptr) _MD_ATOMIC_ADD(ptr, -1) + +static inline PRInt32 _MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 n) +{ + PRInt32 ov, nv; + volatile PRInt32 *vp = ptr; + + do { + ov = *vp; + nv = ov + n; + } while (__kernel_cmpxchg(ov, nv, vp)); + + return nv; +} + +static inline PRInt32 _MD_ATOMIC_SET(PRInt32 *ptr, PRInt32 nv) +{ + PRInt32 ov; + volatile PRInt32 *vp = ptr; + + do { + ov = *vp; + } while (__kernel_cmpxchg(ov, nv, vp)); + + return ov; +} +#endif +#endif /* __arm__ */ + +#define USE_SETJMP +#if (defined(__GLIBC__) && __GLIBC__ >= 2) || defined(ANDROID) +#define _PR_POLL_AVAILABLE +#endif +#undef _PR_USE_POLL +#define _PR_STAT_HAS_ONLY_ST_ATIME +#if defined(__alpha) || defined(__ia64__) +#define _PR_HAVE_LARGE_OFF_T +#elif (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \ + || defined(ANDROID) +#define _PR_HAVE_OFF64_T +#else +#define _PR_NO_LARGE_FILES +#endif +#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \ + || defined(ANDROID) +#define _PR_INET6 +#define _PR_HAVE_INET_NTOP +#define _PR_HAVE_GETHOSTBYNAME2 +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE +#endif +#ifndef ANDROID +#define _PR_HAVE_SYSV_SEMAPHORES +#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY +#endif +/* Android has gethostbyname_r but not gethostbyaddr_r or gethostbyname2_r. */ +#if (__GLIBC__ >= 2) && defined(_PR_PTHREADS) +#define _PR_HAVE_GETHOST_R +#define _PR_HAVE_GETHOST_R_INT +#endif + +#ifdef _PR_PTHREADS + +extern void _MD_CleanupBeforeExit(void); +#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit + +#else /* ! _PR_PTHREADS */ + +#include + +#define PR_CONTEXT_TYPE sigjmp_buf + +#define CONTEXT(_th) ((_th)->md.context) + +#ifdef __powerpc__ +/* + * PowerPC based MkLinux + * + * On the PowerPC, the new style jmp_buf isn't used until glibc + * 2.1. + */ +#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_GPR1] +#else +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__misc[0] +#endif /* glibc 2.1 or later */ +#define _MD_SET_FP(_t, val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) ((void *) 0) +/* aix = 64, macos = 70 */ +#define PR_NUM_GCREGS 64 + +#elif defined(__alpha) +/* Alpha based Linux */ + +#if defined(__GLIBC__) && __GLIBC__ >= 2 +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] +#define _MD_SET_FP(_t, val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) ((void *) 0) +#define _MD_SP_TYPE long int +#else +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp +#define _MD_SET_FP(_t, val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) ((void *) 0) +#define _MD_SP_TYPE __ptr_t +#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ + +/* XXX not sure if this is correct, or maybe it should be 17? */ +#define PR_NUM_GCREGS 9 + +#elif defined(__ia64__) + +#define _MD_GET_SP(_t) ((long *)((_t)->md.context[0].__jmpbuf)[0]) +#define _MD_SET_FP(_t, val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) ((void *) 0) +#define _MD_SP_TYPE long int + +#define PR_NUM_GCREGS _JBLEN + +#elif defined(__mc68000__) +/* m68k based Linux */ + +/* + * On the m68k, glibc still uses the old style sigjmp_buf, even + * in glibc 2.0.7. + */ +#if defined(__GLIBC__) && __GLIBC__ >= 2 +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp +#define _MD_SET_FP(_t, val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) ((void *) 0) +#define _MD_SP_TYPE int +#else +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp +#define _MD_SET_FP(_t, val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) ((void *) 0) +#define _MD_SP_TYPE __ptr_t +#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ + +/* XXX not sure if this is correct, or maybe it should be 17? */ +#define PR_NUM_GCREGS 9 + +#elif defined(__sparc__) +/* Sparc */ +#if defined(__GLIBC__) && __GLIBC__ >= 2 +/* + * You need glibc2-2.0.7-25 or later. The libraries that came with + * Red Hat 5.1 are not new enough, but they are in 5.2. + */ +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] +#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_FP] = val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_FP]) +#define _MD_SP_TYPE int +#else +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__fp +#define _MD_SET_FP(_t, val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) ((void *) 0) +#define _MD_SP_TYPE __ptr_t +#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ + +#elif defined(__i386__) +/* Intel based Linux */ +#if defined(__GLIBC__) && __GLIBC__ >= 2 +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] +#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_BP] = val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_BP]) +#define _MD_SP_TYPE int +#else +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp +#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__bp = val) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) &((_t)->md.context[0].__jmpbuf[0].__bp) +#define _MD_SP_TYPE __ptr_t +#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ +#define PR_NUM_GCREGS 6 + +#elif defined(__mips__) +/* Linux/MIPS */ +#if defined(__GLIBC__) && __GLIBC__ >= 2 +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp +#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__fp = (val)) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__fp) +#define _MD_SP_TYPE __ptr_t +#else +#error "Linux/MIPS pre-glibc2 not supported yet" +#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ + +#elif defined(__arm__) +/* ARM/Linux */ +#if defined(__GLIBC__) && __GLIBC__ >= 2 +#ifdef __ARM_EABI__ +/* EABI */ +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[8] +#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[7] = (val)) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[7]) +#define _MD_SP_TYPE __ptr_t +#else /* __ARM_EABI__ */ +/* old ABI */ +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[20] +#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[19] = (val)) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[19]) +#define _MD_SP_TYPE __ptr_t +#endif /* __ARM_EABI__ */ +#else +#error "ARM/Linux pre-glibc2 not supported yet" +#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ + +#elif defined(__sh__) +/* SH/Linux */ +#if defined(__GLIBC__) && __GLIBC__ >= 2 +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[7] +#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[6] = (val)) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[6]) +#define _MD_SP_TYPE __ptr_t +#else +#error "SH/Linux pre-glibc2 not supported yet" +#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ + +#elif defined(__m32r__) +/* Linux/M32R */ +#if defined(__GLIBC__) && __GLIBC__ >= 2 +#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__regs[JB_SP] +#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__regs[JB_FP] = (val)) +#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) +#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__regs[JB_FP]) +#define _MD_SP_TYPE __ptr_t +#else +#error "Linux/M32R pre-glibc2 not supported yet" +#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ + +#else + +#error "Unknown CPU architecture" + +#endif /*__powerpc__*/ + +/* +** Initialize a thread context to run "_main()" when started +*/ +#ifdef __powerpc__ + +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (sigsetjmp(CONTEXT(_thread), 1)) { \ + _main(); \ + } \ + _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 128); \ + _thread->md.sp = _MD_GET_SP_PTR(_thread); \ + _thread->md.fp = _MD_GET_FP_PTR(_thread); \ + _MD_SET_FP(_thread, 0); \ +} + +#elif defined(__mips__) + +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + (void) sigsetjmp(CONTEXT(_thread), 1); \ + _thread->md.context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \ + _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \ + _thread->md.sp = _MD_GET_SP_PTR(_thread); \ + _thread->md.fp = _MD_GET_FP_PTR(_thread); \ + _MD_SET_FP(_thread, 0); \ +} + +#else + +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (sigsetjmp(CONTEXT(_thread), 1)) { \ + _main(); \ + } \ + _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \ + _thread->md.sp = _MD_GET_SP_PTR(_thread); \ + _thread->md.fp = _MD_GET_FP_PTR(_thread); \ + _MD_SET_FP(_thread, 0); \ +} + +#endif /*__powerpc__*/ + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!sigsetjmp(CONTEXT(_thread), 1)) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + siglongjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + PR_CONTEXT_TYPE context; + void *sp; + void *fp; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#include /* for FD_SETSIZE */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +extern PRStatus _MD_InitializeThread(PRThread *thread); + +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread +#define _MD_RESUME_THREAD(thread) _MD_resume_thread +#define _MD_CLEAN_THREAD(_thread) + +extern PRStatus _MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize); +extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri); +extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout); +extern PRStatus _MD_WAKEUP_WAITER(PRThread *); +extern void _MD_YIELD(void); + +#endif /* ! _PR_PTHREADS */ + +extern void _MD_EarlyInit(void); + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define HAVE_CLOCK_MONOTONIC + +/* + * We wrapped the select() call. _MD_SELECT refers to the built-in, + * unwrapped version. + */ +#define _MD_SELECT __select + +#ifdef _PR_POLL_AVAILABLE +#include +extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds, + int timeout); +#define _MD_POLL __syscall_poll +#endif + +/* For writev() */ +#include + +extern void _MD_linux_map_sendfile_error(int err); + +#endif /* nspr_linux_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/Makefile.in nspr-4.10.7/nspr/pr/include/md/Makefile.in --- nspr-4.9.5/nspr/pr/include/md/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,42 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +# The .cfg files need to be exported and installed to support +# cross-compilation. +CONFIGS = $(wildcard $(srcdir)/*.cfg) + +include $(topsrcdir)/config/rules.mk + +export:: $(MDCPUCFG_H) + $(INSTALL) -m 444 $(CONFIGS) $(dist_includedir)/md + $(INSTALL) -m 444 $(srcdir)/$(MDCPUCFG_H) $(dist_includedir) + mv -f $(dist_includedir)/$(MDCPUCFG_H) $(dist_includedir)/prcpucfg.h + +install:: + $(NSINSTALL) -D $(DESTDIR)$(includedir)/md + $(NSINSTALL) -t -m 644 $(CONFIGS) $(DESTDIR)$(includedir)/md + $(NSINSTALL) -t -m 644 $(srcdir)/$(MDCPUCFG_H) $(DESTDIR)$(includedir) + mv -f $(DESTDIR)$(includedir)/$(MDCPUCFG_H) $(DESTDIR)$(includedir)/prcpucfg.h + +release:: export + @echo "Copying machine-dependent prcpucfg.h" + @if test -z "$(BUILD_NUMBER)"; then \ + echo "BUILD_NUMBER must be defined"; \ + false; \ + fi + @if test ! -d $(RELEASE_INCLUDE_DIR); then \ + rm -rf $(RELEASE_INCLUDE_DIR); \ + $(NSINSTALL) -D $(RELEASE_INCLUDE_DIR);\ + fi + cp $(srcdir)/$(MDCPUCFG_H) $(RELEASE_INCLUDE_DIR)/prcpucfg.h diff -Nru nspr-4.9.5/nspr/pr/include/md/_netbsd.cfg nspr-4.10.7/nspr/pr/include/md/_netbsd.cfg --- nspr-4.9.5/nspr/pr/include/md/_netbsd.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_netbsd.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,351 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef NETBSD +#define NETBSD +#endif + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif + +#if defined(__i386__) || defined(__arm32__) || defined(__ARMEL__) || \ + defined(__MIPSEL__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#elif defined(__sparc_v9__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#elif defined(__sparc__) || defined(__MIPSEB__) || defined(__ARMEB__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 + +#elif defined(__alpha__) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__amd64__) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__powerpc__) || defined(__m68k__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else + +#error Must define constants for type sizes here. + +#endif + + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_netbsd.h nspr-4.10.7/nspr/pr/include/md/_netbsd.h --- nspr-4.9.5/nspr/pr/include/md/_netbsd.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_netbsd.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,230 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_netbsd_defs_h___ +#define nspr_netbsd_defs_h___ + +#include +#include /* for __NetBSD_Version__ */ + +#define PR_LINKER_ARCH "netbsd" +#define _PR_SI_SYSNAME "NetBSD" +#if defined(__i386__) +#define _PR_SI_ARCHITECTURE "x86" +#elif defined(__alpha__) +#define _PR_SI_ARCHITECTURE "alpha" +#elif defined(__amd64__) +#define _PR_SI_ARCHITECTURE "amd64" +#elif defined(__m68k__) +#define _PR_SI_ARCHITECTURE "m68k" +#elif defined(__powerpc__) +#define _PR_SI_ARCHITECTURE "powerpc" +#elif defined(__sparc_v9__) +#define _PR_SI_ARCHITECTURE "sparc64" +#elif defined(__sparc__) +#define _PR_SI_ARCHITECTURE "sparc" +#elif defined(__mips__) +#define _PR_SI_ARCHITECTURE "mips" +#elif defined(__arm32__) || defined(__arm__) || defined(__armel__) \ + || defined(__armeb__) +#define _PR_SI_ARCHITECTURE "arm" +#endif + +#if defined(__ELF__) +#define PR_DLL_SUFFIX ".so" +#else +#define PR_DLL_SUFFIX ".so.1.0" +#endif + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#undef HAVE_STACK_GROWING_UP +#define HAVE_DLL +#define USE_DLFCN +#define _PR_HAVE_SOCKADDR_LEN +#define _PR_NO_LARGE_FILES +#define _PR_STAT_HAS_ST_ATIMESPEC +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_HAVE_SYSV_SEMAPHORES +#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY + +#if __NetBSD_Version__ >= 105000000 +#define _PR_INET6 +#define _PR_HAVE_INET_NTOP +#define _PR_HAVE_GETHOSTBYNAME2 +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE +#endif + +#define USE_SETJMP + +#ifndef _PR_PTHREADS +#include + +#define PR_CONTEXT_TYPE sigjmp_buf + +#define CONTEXT(_th) ((_th)->md.context) + +#if defined(__i386__) || defined(__sparc__) || defined(__m68k__) || defined(__powerpc__) +#define JB_SP_INDEX 2 +#elif defined(__mips__) +#define JB_SP_INDEX 4 +#elif defined(__alpha__) +#define JB_SP_INDEX 34 +#elif defined(__arm32__) +/* + * On the arm32, the jmpbuf regs underwent a name change after NetBSD 1.3. + */ +#ifdef JMPBUF_REG_R13 +#define JB_SP_INDEX JMPBUF_REG_R13 +#else +#define JB_SP_INDEX _JB_REG_R13 +#endif +#else +#error "Need to define SP index in jmp_buf here" +#endif +#define _MD_GET_SP(_th) (_th)->md.context[JB_SP_INDEX] + +#define PR_NUM_GCREGS _JBLEN + +/* +** Initialize a thread context to run "_main()" when started +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (sigsetjmp(CONTEXT(_thread), 1)) { \ + _main(); \ + } \ + _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!sigsetjmp(CONTEXT(_thread), 1)) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + siglongjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread +#define _MD_RESUME_THREAD(thread) _MD_resume_thread +#define _MD_CLEAN_THREAD(_thread) + +#endif /* ! _PR_PTHREADS */ + +extern void _MD_EarlyInit(void); + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INTERVAL_USE_GTOD + +/* + * We wrapped the select() call. _MD_SELECT refers to the built-in, + * unwrapped version. + */ +#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) +#if defined(_PR_POLL_AVAILABLE) +#include +#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout) +#endif + +#if NetBSD1_3 == 1L +typedef unsigned int nfds_t; +#endif + +#endif /* nspr_netbsd_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_nspr_pthread.h nspr-4.10.7/nspr/pr/include/md/_nspr_pthread.h --- nspr-4.9.5/nspr/pr/include/md/_nspr_pthread.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_nspr_pthread.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,251 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_pthread_defs_h___ +#define nspr_pthread_defs_h___ + +#include +#include "prthread.h" + +#if defined(PTHREADS_USER) +/* +** Thread Local Storage +*/ +extern pthread_key_t current_thread_key; +extern pthread_key_t current_cpu_key; +extern pthread_key_t last_thread_key; +extern pthread_key_t intsoff_key; + +#define _MD_CURRENT_THREAD() \ + ((struct PRThread *) pthread_getspecific(current_thread_key)) +#define _MD_CURRENT_CPU() \ + ((struct _PRCPU *) pthread_getspecific(current_cpu_key)) +#define _MD_LAST_THREAD() \ + ((struct PRThread *) pthread_getspecific(last_thread_key)) + +#define _MD_SET_CURRENT_THREAD(newval) \ + pthread_setspecific(current_thread_key, (void *)newval) + +#define _MD_SET_CURRENT_CPU(newval) \ + pthread_setspecific(current_cpu_key, (void *)newval) + +#define _MD_SET_LAST_THREAD(newval) \ + pthread_setspecific(last_thread_key, (void *)newval) + +#define _MD_SET_INTSOFF(_val) +#define _MD_GET_INTSOFF() 1 + +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + *status = PR_TRUE; \ + if (SAVE_CONTEXT(_thread)) { \ + (*_main)(); \ + } \ + _MD_SET_THR_SP(_thread, _sp); \ + _thread->no_sched = 0; \ + PR_END_MACRO + +#define _MD_SWITCH_CONTEXT(_thread) \ + PR_BEGIN_MACRO \ + PR_ASSERT(_thread->no_sched); \ + if (!SAVE_CONTEXT(_thread)) { \ + (_thread)->md.errcode = errno; \ + _MD_SET_LAST_THREAD(_thread); \ + _PR_Schedule(); \ + } else { \ + (_MD_LAST_THREAD())->no_sched = 0; \ + } \ + PR_END_MACRO + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ + PR_BEGIN_MACRO \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + _thread->no_sched = 1; \ + GOTO_CONTEXT(_thread); \ + PR_END_MACRO + + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + jmp_buf jb; + int id; + int errcode; + pthread_t pthread; + pthread_mutex_t pthread_mutex; + pthread_cond_t pthread_cond; + int wait; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + pthread_mutex_t mutex; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + pthread_mutex_t mutex; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + jmp_buf jb; + pthread_t pthread; + struct _MDCPU_Unix md_unix; +}; + +/* +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +*/ + +extern pthread_mutex_t _pr_heapLock; + +#define _PR_LOCK(lock) pthread_mutex_lock(lock) + +#define _PR_UNLOCK(lock) pthread_mutex_unlock(lock) + + +#define _PR_LOCK_HEAP() { \ + if (_pr_primordialCPU) { \ + _PR_LOCK(_pr_heapLock); \ + } + +#define _PR_UNLOCK_HEAP() if (_pr_primordialCPU) { \ + _PR_UNLOCK(_pr_heapLock); \ + } \ + } + +NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md); +NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp); + +#define _MD_LOCK(_lockp) _PR_LOCK(&(_lockp)->mutex) +#define _MD_UNLOCK(_lockp) _PR_UNLOCK(&(_lockp)->mutex) + +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() +#define _MD_CHECK_FOR_EXIT() + +NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread); +#define _MD_INIT_THREAD _MD_InitThread +#define _MD_INIT_ATTACHED_THREAD _MD_InitThread + +NSPR_API(void) _MD_ExitThread(struct PRThread *thread); +#define _MD_EXIT_THREAD _MD_ExitThread + +NSPR_API(void) _MD_SuspendThread(struct PRThread *thread); +#define _MD_SUSPEND_THREAD _MD_SuspendThread + +NSPR_API(void) _MD_ResumeThread(struct PRThread *thread); +#define _MD_RESUME_THREAD _MD_ResumeThread + +NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread); +#define _MD_SUSPEND_CPU _MD_SuspendCPU + +NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread); +#define _MD_RESUME_CPU _MD_ResumeCPU + +#define _MD_BEGIN_SUSPEND_ALL() +#define _MD_END_SUSPEND_ALL() +#define _MD_BEGIN_RESUME_ALL() +#define _MD_END_RESUME_ALL() + +NSPR_API(void) _MD_EarlyInit(void); +#define _MD_EARLY_INIT _MD_EarlyInit + +#define _MD_FINAL_INIT _PR_UnixInit + +NSPR_API(void) _MD_InitLocks(void); +#define _MD_INIT_LOCKS _MD_InitLocks + +NSPR_API(void) _MD_CleanThread(struct PRThread *thread); +#define _MD_CLEAN_THREAD _MD_CleanThread + +NSPR_API(PRStatus) _MD_CreateThread( + struct PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize); +#define _MD_CREATE_THREAD _MD_CreateThread + +extern void _MD_CleanupBeforeExit(void); +#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit + +NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu); +#define _MD_INIT_RUNNING_CPU _MD_InitRunningCPU + +/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and + * awaken a thread which is waiting on a lock or cvar. + */ +NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout); +#define _MD_WAIT _MD_wait + +NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *); +#define _MD_WAKEUP_WAITER _MD_WakeupWaiter + +NSPR_API(void) _MD_SetPriority(struct _MDThread *thread, + PRThreadPriority newPri); +#define _MD_SET_PRIORITY _MD_SetPriority + +#endif /* PTHREADS_USER */ + +#endif /* nspr_pthread_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_nto.cfg nspr-4.10.7/nspr/pr/include/md/_nto.cfg --- nspr-4.9.5/nspr/pr/include/md/_nto.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_nto.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef NTO +#define NTO +#endif + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#ifdef __i386__ + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1L +#define PR_BYTES_PER_SHORT 2L +#define PR_BYTES_PER_INT 4L +#define PR_BYTES_PER_INT64 8L +#define PR_BYTES_PER_LONG 4L +#define PR_BYTES_PER_FLOAT 4L +#define PR_BYTES_PER_DOUBLE 8L +#define PR_BYTES_PER_WORD 4L +#define PR_BYTES_PER_DWORD 8L + +#define PR_BITS_PER_BYTE 8L +#define PR_BITS_PER_SHORT 16L +#define PR_BITS_PER_INT 32L +#define PR_BITS_PER_INT64 64L +#define PR_BITS_PER_LONG 32L +#define PR_BITS_PER_FLOAT 32L +#define PR_BITS_PER_DOUBLE 64L +#define PR_BITS_PER_WORD 32L + +#define PR_BITS_PER_BYTE_LOG2 3L +#define PR_BITS_PER_SHORT_LOG2 4L +#define PR_BITS_PER_INT_LOG2 5L +#define PR_BITS_PER_INT64_LOG2 6L +#define PR_BITS_PER_LONG_LOG2 5L +#define PR_BITS_PER_FLOAT_LOG2 5L +#define PR_BITS_PER_DOUBLE_LOG2 6L +#define PR_BITS_PER_WORD_LOG2 5L + +#define PR_ALIGN_OF_SHORT 2L +#define PR_ALIGN_OF_INT 4L +#define PR_ALIGN_OF_LONG 4L +#define PR_ALIGN_OF_INT64 4L +#define PR_ALIGN_OF_FLOAT 4L +#define PR_ALIGN_OF_DOUBLE 4L +#define PR_ALIGN_OF_POINTER 4L +#define PR_ALIGN_OF_WORD 4L + +#define PR_BYTES_PER_WORD_LOG2 2L +#define PR_BYTES_PER_DWORD_LOG2 3L +#define PR_WORDS_PER_DWORD_LOG2 1L + +#else + +#error Undefined CPU Architecture + +#endif + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_nto.h nspr-4.10.7/nspr/pr/include/md/_nto.h --- nspr-4.9.5/nspr/pr/include/md/_nto.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_nto.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_nto_defs_h___ +#define nspr_nto_defs_h___ + +/* +** Internal configuration macros +*/ +#define PR_LINKER_ARCH "nto" +#define _PR_SI_SYSNAME "NTO" +#define _PR_SI_ARCHITECTURE "x86" +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MINIMUM_STACK_SIZE 131072L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#ifndef HAVE_WEAK_IO_SYMBOLS +#define HAVE_WEAK_IO_SYMBOLS +#endif + +#undef _PR_POLL_AVAILABLE +#undef _PR_USE_POLL +#define _PR_HAVE_SOCKADDR_LEN +#undef HAVE_BSD_FLOCK +#define HAVE_FCNTL_FILE_LOCKING +#define _PR_NO_LARGE_FILES +#define _PR_STAT_HAS_ONLY_ST_ATIME +#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY +#define _PR_HAVE_POSIX_SEMAPHORES + +#undef FD_SETSIZE +#define FD_SETSIZE 4096 +#include +#include +#include + +#undef HAVE_STACK_GROWING_UP +#define HAVE_DLL +#define USE_DLFCN +#define NEED_STRFTIME_LOCK +#define NEED_TIME_R +#define _PR_NEED_STRCASECMP + +#ifndef HAVE_STRERROR +#define HAVE_STRERROR +#endif + +#define USE_SETJMP + +#include + +#define _SETJMP setjmp +#define _LONGJMP longjmp +#define _PR_CONTEXT_TYPE jmp_buf +#define _PR_NUM_GCREGS _JBLEN +#define _MD_GET_SP(_t) (_t)->md.context[7] + +#define CONTEXT(_th) ((_th)->md.context) + + +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ + _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!_SETJMP(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + _LONGJMP(CONTEXT(_thread), 1); \ +} + +/* +** Machine-dependent (MD) data structures. +*/ +struct _MDThread { + _PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* +** md-specific cpu structure field +*/ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_INTERVAL_USE_GTOD +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +/* +** We wrapped the select() call. _MD_SELECT refers to the built-in, +** unwrapped version. +*/ +#define _MD_SELECT select + +#define SA_RESTART 0 + +#endif /* nspr_nto_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_openbsd.cfg nspr-4.10.7/nspr/pr/include/md/_openbsd.cfg --- nspr-4.9.5/nspr/pr/include/md/_openbsd.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_openbsd.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,353 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef OPENBSD +#define OPENBSD +#endif + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif + +#if defined(__i386__) || defined(__arm__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#elif defined(__amd64__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#elif defined(__sparc_v9__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__sparc__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 + +#elif defined(__alpha__) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__powerpc__) || defined(__m68k__) + +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else + +#error Must define constants for type sizes here. + +#endif + + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_openbsd.h nspr-4.10.7/nspr/pr/include/md/_openbsd.h --- nspr-4.9.5/nspr/pr/include/md/_openbsd.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_openbsd.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,209 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_openbsd_defs_h___ +#define nspr_openbsd_defs_h___ + +#include + +#define PR_LINKER_ARCH "openbsd" +#define _PR_SI_SYSNAME "OPENBSD" +#if defined(__i386__) +#define _PR_SI_ARCHITECTURE "x86" +#elif defined(__alpha__) +#define _PR_SI_ARCHITECTURE "alpha" +#elif defined(__amd64__) +#define _PR_SI_ARCHITECTURE "amd64" +#elif defined(__m68k__) +#define _PR_SI_ARCHITECTURE "m68k" +#elif defined(__powerpc__) +#define _PR_SI_ARCHITECTURE "powerpc" +#elif defined(__sparc__) +#define _PR_SI_ARCHITECTURE "sparc" +#elif defined(__arm__) +#define _PR_SI_ARCHITECTURE "arm" +#endif + +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#undef HAVE_STACK_GROWING_UP +#define HAVE_DLL +#define USE_DLFCN +#define _PR_HAVE_SOCKADDR_LEN +#define _PR_HAVE_LARGE_OFF_T +#define _PR_STAT_HAS_ST_ATIMESPEC +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_HAVE_SYSV_SEMAPHORES +#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY + +#define _PR_INET6 +#define _PR_HAVE_INET_NTOP +#define _PR_HAVE_GETHOSTBYNAME2 +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE + +#define USE_SETJMP + +#ifndef _PR_PTHREADS +#include + +#define PR_CONTEXT_TYPE sigjmp_buf + +#define CONTEXT(_th) ((_th)->md.context) + +#if defined(__i386__) || defined(__sparc__) || defined(__m68k__) +#define JB_SP_INDEX 2 +#elif defined(__powerpc__) +#define JB_SP_INDEX 1 +#elif defined(__alpha__) +#define JB_SP_INDEX 34 +#elif defined(__amd64__) +#define JB_SP_INDEX 6 +#elif defined(__arm__) +#define JB_SP_INDEX 23 +#else +#error "Need to define SP index in jmp_buf here" +#endif +#define _MD_GET_SP(_th) (_th)->md.context[JB_SP_INDEX] + +#define PR_NUM_GCREGS _JBLEN + +/* +** Initialize a thread context to run "_main()" when started +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (sigsetjmp(CONTEXT(_thread), 1)) { \ + _main(); \ + } \ + _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!sigsetjmp(CONTEXT(_thread), 1)) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + siglongjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread +#define _MD_RESUME_THREAD(thread) _MD_resume_thread +#define _MD_CLEAN_THREAD(_thread) + +#endif /* ! _PR_PTHREADS */ + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INTERVAL_USE_GTOD + +/* + * We wrapped the select() call. _MD_SELECT refers to the built-in, + * unwrapped version. + */ +#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv) +#include +#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout) + +#if OpenBSD1_3 == 1L +typedef unsigned int nfds_t; +#endif + +#endif /* nspr_openbsd_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_os2.cfg nspr-4.10.7/nspr/pr/include/md/_os2.cfg --- nspr-4.9.5/nspr/pr/include/md/_os2.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_os2.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_PC +#define XP_PC +#endif + +#ifndef XP_OS2 +#define XP_OS2 +#endif + +#ifndef OS2 +#define OS2 +#endif + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#ifdef NO_LONG_LONG +#undef HAVE_LONG_LONG +#else +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG 1 +#endif +#endif + +#define PR_AF_INET6 24 /* same as AF_INET6 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 32 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 5 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_WORD 4 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_POINTER 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 2 + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_os2_errors.h nspr-4.10.7/nspr/pr/include/md/_os2_errors.h --- nspr-4.9.5/nspr/pr/include/md/_os2_errors.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_os2_errors.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,128 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_os2_errors_h___ +#define nspr_os2_errors_h___ + +#include "md/_os2.h" +#ifndef assert + #include +#endif + +NSPR_API(void) _MD_os2_map_default_error(PRInt32 err); +#define _PR_MD_MAP_DEFAULT_ERROR _MD_os2_map_default_error + +NSPR_API(void) _MD_os2_map_opendir_error(PRInt32 err); +#define _PR_MD_MAP_OPENDIR_ERROR _MD_os2_map_opendir_error + +NSPR_API(void) _MD_os2_map_closedir_error(PRInt32 err); +#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_os2_map_closedir_error + +NSPR_API(void) _MD_os2_readdir_error(PRInt32 err); +#define _PR_MD_MAP_READDIR_ERROR _MD_os2_readdir_error + +NSPR_API(void) _MD_os2_map_delete_error(PRInt32 err); +#define _PR_MD_MAP_DELETE_ERROR _MD_os2_map_delete_error + +NSPR_API(void) _MD_os2_map_stat_error(PRInt32 err); +#define _PR_MD_MAP_STAT_ERROR _MD_os2_map_stat_error + +NSPR_API(void) _MD_os2_map_fstat_error(PRInt32 err); +#define _PR_MD_MAP_FSTAT_ERROR _MD_os2_map_fstat_error + +NSPR_API(void) _MD_os2_map_rename_error(PRInt32 err); +#define _PR_MD_MAP_RENAME_ERROR _MD_os2_map_rename_error + +NSPR_API(void) _MD_os2_map_access_error(PRInt32 err); +#define _PR_MD_MAP_ACCESS_ERROR _MD_os2_map_access_error + +NSPR_API(void) _MD_os2_map_mkdir_error(PRInt32 err); +#define _PR_MD_MAP_MKDIR_ERROR _MD_os2_map_mkdir_error + +NSPR_API(void) _MD_os2_map_rmdir_error(PRInt32 err); +#define _PR_MD_MAP_RMDIR_ERROR _MD_os2_map_rmdir_error + +NSPR_API(void) _MD_os2_map_read_error(PRInt32 err); +#define _PR_MD_MAP_READ_ERROR _MD_os2_map_read_error + +NSPR_API(void) _MD_os2_map_transmitfile_error(PRInt32 err); +#define _PR_MD_MAP_TRANSMITFILE_ERROR _MD_os2_map_transmitfile_error + +NSPR_API(void) _MD_os2_map_write_error(PRInt32 err); +#define _PR_MD_MAP_WRITE_ERROR _MD_os2_map_write_error + +NSPR_API(void) _MD_os2_map_lseek_error(PRInt32 err); +#define _PR_MD_MAP_LSEEK_ERROR _MD_os2_map_lseek_error + +NSPR_API(void) _MD_os2_map_fsync_error(PRInt32 err); +#define _PR_MD_MAP_FSYNC_ERROR _MD_os2_map_fsync_error + +NSPR_API(void) _MD_os2_map_close_error(PRInt32 err); +#define _PR_MD_MAP_CLOSE_ERROR _MD_os2_map_close_error + +NSPR_API(void) _MD_os2_map_socket_error(PRInt32 err); +#define _PR_MD_MAP_SOCKET_ERROR _MD_os2_map_socket_error + +NSPR_API(void) _MD_os2_map_recv_error(PRInt32 err); +#define _PR_MD_MAP_RECV_ERROR _MD_os2_map_recv_error + +NSPR_API(void) _MD_os2_map_recvfrom_error(PRInt32 err); +#define _PR_MD_MAP_RECVFROM_ERROR _MD_os2_map_recvfrom_error + +NSPR_API(void) _MD_os2_map_send_error(PRInt32 err); +#define _PR_MD_MAP_SEND_ERROR _MD_os2_map_send_error + +NSPR_API(void) _MD_os2_map_sendto_error(PRInt32 err); +#define _PR_MD_MAP_SENDTO_ERROR _MD_os2_map_sendto_error + +NSPR_API(void) _MD_os2_map_writev_error(int err); +#define _PR_MD_MAP_WRITEV_ERROR _MD_os2_map_writev_error + +NSPR_API(void) _MD_os2_map_accept_error(PRInt32 err); +#define _PR_MD_MAP_ACCEPT_ERROR _MD_os2_map_accept_error + +NSPR_API(void) _MD_os2_map_acceptex_error(PRInt32 err); +#define _PR_MD_MAP_ACCEPTEX_ERROR _MD_os2_map_acceptex_error + +NSPR_API(void) _MD_os2_map_connect_error(PRInt32 err); +#define _PR_MD_MAP_CONNECT_ERROR _MD_os2_map_connect_error + +NSPR_API(void) _MD_os2_map_bind_error(PRInt32 err); +#define _PR_MD_MAP_BIND_ERROR _MD_os2_map_bind_error + +NSPR_API(void) _MD_os2_map_listen_error(PRInt32 err); +#define _PR_MD_MAP_LISTEN_ERROR _MD_os2_map_listen_error + +NSPR_API(void) _MD_os2_map_shutdown_error(PRInt32 err); +#define _PR_MD_MAP_SHUTDOWN_ERROR _MD_os2_map_shutdown_error + +NSPR_API(void) _MD_os2_map_socketpair_error(int err); +#define _PR_MD_MAP_SOCKETPAIR_ERROR _MD_os2_map_socketpair_error + +NSPR_API(void) _MD_os2_map_getsockname_error(PRInt32 err); +#define _PR_MD_MAP_GETSOCKNAME_ERROR _MD_os2_map_getsockname_error + +NSPR_API(void) _MD_os2_map_getpeername_error(PRInt32 err); +#define _PR_MD_MAP_GETPEERNAME_ERROR _MD_os2_map_getpeername_error + +NSPR_API(void) _MD_os2_map_getsockopt_error(PRInt32 err); +#define _PR_MD_MAP_GETSOCKOPT_ERROR _MD_os2_map_getsockopt_error + +NSPR_API(void) _MD_os2_map_setsockopt_error(PRInt32 err); +#define _PR_MD_MAP_SETSOCKOPT_ERROR _MD_os2_map_setsockopt_error + +NSPR_API(void) _MD_os2_map_open_error(PRInt32 err); +#define _PR_MD_MAP_OPEN_ERROR _MD_os2_map_open_error + +NSPR_API(void) _MD_os2_map_gethostname_error(PRInt32 err); +#define _PR_MD_MAP_GETHOSTNAME_ERROR _MD_os2_map_gethostname_error + +NSPR_API(void) _MD_os2_map_select_error(PRInt32 err); +#define _PR_MD_MAP_SELECT_ERROR _MD_os2_map_select_error + +NSPR_API(void) _MD_os2_map_lockf_error(int err); +#define _PR_MD_MAP_LOCKF_ERROR _MD_os2_map_lockf_error + +#endif /* nspr_os2_errors_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_os2.h nspr-4.10.7/nspr/pr/include/md/_os2.h --- nspr-4.9.5/nspr/pr/include/md/_os2.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_os2.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,504 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_os2_defs_h___ +#define nspr_os2_defs_h___ + +#ifndef NO_LONG_LONG +#define INCL_LONGLONG +#endif +#define INCL_DOS +#define INCL_DOSPROCESS +#define INCL_DOSERRORS +#define INCL_WIN +#define INCL_WPS +#include +#include + +#include "prio.h" + +#include + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "os2" +#define _PR_SI_SYSNAME "OS2" +#define _PR_SI_ARCHITECTURE "x86" /* XXXMB hardcode for now */ + +#define HAVE_DLL +#define _PR_GLOBAL_THREADS_ONLY +#undef HAVE_THREAD_AFFINITY +#define _PR_HAVE_THREADSAFE_GETHOST +#define _PR_HAVE_ATOMIC_OPS +#define HAVE_NETINET_TCP_H + +#define HANDLE unsigned long +#define HINSTANCE HMODULE + +/* --- Common User-Thread/Native-Thread Definitions --------------------- */ + +/* --- Globals --- */ +extern struct PRLock *_pr_schedLock; + +/* --- Typedefs --- */ +typedef void (*FiberFunc)(void *); + +#define PR_NUM_GCREGS 8 +typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS]; +#define GC_VMBASE 0x40000000 +#define GC_VMLIMIT 0x00FFFFFF +typedef int (*FARPROC)(); + +#define _MD_MAGIC_THREAD 0x22222222 +#define _MD_MAGIC_THREADSTACK 0x33333333 +#define _MD_MAGIC_SEGMENT 0x44444444 +#define _MD_MAGIC_DIR 0x55555555 +#define _MD_MAGIC_CV 0x66666666 + +struct _MDSemaphore { + HEV sem; +}; + +struct _MDCPU { + int unused; +}; + +struct _MDThread { + HEV blocked_sema; /* Threads block on this when waiting + * for IO or CondVar. + */ + PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the + * wait queue of some cond var. + * PR_FALSE otherwise. */ + TID handle; /* OS/2 thread handle */ + void *sp; /* only valid when suspended */ + PRUint32 magic; /* for debugging */ + PR_CONTEXT_TYPE gcContext; /* Thread context for GC */ + struct PRThread *prev, *next; /* used by the cvar wait queue to + * chain the PRThread structures + * together */ +}; + +struct _MDThreadStack { + PRUint32 magic; /* for debugging */ +}; + +struct _MDSegment { + PRUint32 magic; /* for debugging */ +}; + +#undef PROFILE_LOCKS + +struct _MDDir { + HDIR d_hdl; + union { + FILEFINDBUF3 small; + FILEFINDBUF3L large; + } d_entry; + PRBool firstEntry; /* Is this the entry returned + * by FindFirstFile()? */ + PRUint32 magic; /* for debugging */ +}; + +struct _MDCVar { + PRUint32 magic; + struct PRThread *waitHead, *waitTail; /* the wait queue: a doubly- + * linked list of threads + * waiting on this condition + * variable */ + PRIntn nwait; /* number of threads in the + * wait queue */ +}; + +#define _MD_CV_NOTIFIED_LENGTH 6 +typedef struct _MDNotified _MDNotified; +struct _MDNotified { + PRIntn length; /* # of used entries in this + * structure */ + struct { + struct _MDCVar *cv; /* the condition variable notified */ + PRIntn times; /* and the number of times notified */ + struct PRThread *notifyHead; /* list of threads to wake up */ + } cv[_MD_CV_NOTIFIED_LENGTH]; + _MDNotified *link; /* link to another of these, or NULL */ +}; + +struct _MDLock { + HMTX mutex; /* this is recursive on OS/2 */ + + /* + * When notifying cvars, there is no point in actually + * waking up the threads waiting on the cvars until we've + * released the lock. So, we temporarily record the cvars. + * When doing an unlock, we'll then wake up the waiting threads. + */ + struct _MDNotified notified; /* array of conditions notified */ +#ifdef PROFILE_LOCKS + PRInt32 hitcount; + PRInt32 misscount; +#endif +}; + +struct _MDFileDesc { + PRInt32 osfd; /* The osfd can come from one of three spaces: + * - For stdin, stdout, and stderr, we are using + * the libc file handle (0, 1, 2), which is an int. + * - For files and pipes, we are using OS/2 handles, + * which is a void*. + * - For sockets, we are using int + */ +}; + +struct _MDProcess { + PID pid; +}; + +/* --- Misc stuff --- */ +#define _MD_GET_SP(thread) (thread)->md.gcContext[6] + +/* --- IO stuff --- */ + +#define _MD_OPEN (_PR_MD_OPEN) +#define _MD_OPEN_FILE (_PR_MD_OPEN) +#define _MD_READ (_PR_MD_READ) +#define _MD_WRITE (_PR_MD_WRITE) +#define _MD_WRITEV (_PR_MD_WRITEV) +#define _MD_LSEEK (_PR_MD_LSEEK) +#define _MD_LSEEK64 (_PR_MD_LSEEK64) +extern PRInt32 _MD_CloseFile(PRInt32 osfd); +#define _MD_CLOSE_FILE _MD_CloseFile +#define _MD_GETFILEINFO (_PR_MD_GETFILEINFO) +#define _MD_GETFILEINFO64 (_PR_MD_GETFILEINFO64) +#define _MD_GETOPENFILEINFO (_PR_MD_GETOPENFILEINFO) +#define _MD_GETOPENFILEINFO64 (_PR_MD_GETOPENFILEINFO64) +#define _MD_STAT (_PR_MD_STAT) +#define _MD_RENAME (_PR_MD_RENAME) +#define _MD_ACCESS (_PR_MD_ACCESS) +#define _MD_DELETE (_PR_MD_DELETE) +#define _MD_MKDIR (_PR_MD_MKDIR) +#define _MD_MAKE_DIR (_PR_MD_MKDIR) +#define _MD_RMDIR (_PR_MD_RMDIR) +#define _MD_LOCKFILE (_PR_MD_LOCKFILE) +#define _MD_TLOCKFILE (_PR_MD_TLOCKFILE) +#define _MD_UNLOCKFILE (_PR_MD_UNLOCKFILE) + +/* --- Socket IO stuff --- */ + +/* The ones that don't map directly may need to be re-visited... */ +#define _MD_EACCES EACCES +#define _MD_EADDRINUSE EADDRINUSE +#define _MD_EADDRNOTAVAIL EADDRNOTAVAIL +#define _MD_EAFNOSUPPORT EAFNOSUPPORT +#define _MD_EAGAIN EWOULDBLOCK +#define _MD_EALREADY EALREADY +#define _MD_EBADF EBADF +#define _MD_ECONNREFUSED ECONNREFUSED +#define _MD_ECONNRESET ECONNRESET +#define _MD_EFAULT SOCEFAULT +#define _MD_EINPROGRESS EINPROGRESS +#define _MD_EINTR EINTR +#define _MD_EINVAL EINVAL +#define _MD_EISCONN EISCONN +#define _MD_ENETUNREACH ENETUNREACH +#define _MD_ENOENT ENOENT +#define _MD_ENOTCONN ENOTCONN +#define _MD_ENOTSOCK ENOTSOCK +#define _MD_EOPNOTSUPP EOPNOTSUPP +#define _MD_EWOULDBLOCK EWOULDBLOCK +#define _MD_GET_SOCKET_ERROR() sock_errno() +#ifndef INADDR_LOOPBACK /* For some reason this is not defined in OS2 tcpip */ +/* #define INADDR_LOOPBACK INADDR_ANY */ +#endif + +#define _MD_INIT_FILEDESC(fd) +extern void _MD_MakeNonblock(PRFileDesc *f); +#define _MD_MAKE_NONBLOCK _MD_MakeNonblock +#define _MD_INIT_FD_INHERITABLE (_PR_MD_INIT_FD_INHERITABLE) +#define _MD_QUERY_FD_INHERITABLE (_PR_MD_QUERY_FD_INHERITABLE) +#define _MD_SHUTDOWN (_PR_MD_SHUTDOWN) +#define _MD_LISTEN _PR_MD_LISTEN +extern PRInt32 _MD_CloseSocket(PRInt32 osfd); +#define _MD_CLOSE_SOCKET _MD_CloseSocket +#define _MD_SENDTO (_PR_MD_SENDTO) +#define _MD_RECVFROM (_PR_MD_RECVFROM) +#define _MD_SOCKETPAIR (_PR_MD_SOCKETPAIR) +#define _MD_GETSOCKNAME (_PR_MD_GETSOCKNAME) +#define _MD_GETPEERNAME (_PR_MD_GETPEERNAME) +#define _MD_GETSOCKOPT (_PR_MD_GETSOCKOPT) +#define _MD_SETSOCKOPT (_PR_MD_SETSOCKOPT) + +#define _MD_FSYNC _PR_MD_FSYNC +#define _MD_SET_FD_INHERITABLE (_PR_MD_SET_FD_INHERITABLE) + +#ifdef _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +#define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT +#define _MD_ATOMIC_ADD _PR_MD_ATOMIC_ADD +#define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT +#define _MD_ATOMIC_SET _PR_MD_ATOMIC_SET +#endif + +#define _MD_INIT_IO (_PR_MD_INIT_IO) +#define _MD_PR_POLL (_PR_MD_PR_POLL) + +#define _MD_SOCKET (_PR_MD_SOCKET) +extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd); +#define _MD_SOCKETAVAILABLE _MD_SocketAvailable +#define _MD_PIPEAVAILABLE _MD_SocketAvailable +#define _MD_CONNECT (_PR_MD_CONNECT) +extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, + PRIntervalTime timeout); +#define _MD_ACCEPT _MD_Accept +#define _MD_BIND (_PR_MD_BIND) +#define _MD_RECV (_PR_MD_RECV) +#define _MD_SEND (_PR_MD_SEND) + +/* --- Scheduler stuff --- */ +/* #define _MD_PAUSE_CPU _PR_MD_PAUSE_CPU */ +#define _MD_PAUSE_CPU + +/* --- DIR stuff --- */ +#define PR_DIRECTORY_SEPARATOR '\\' +#define PR_DIRECTORY_SEPARATOR_STR "\\" +#define PR_PATH_SEPARATOR ';' +#define PR_PATH_SEPARATOR_STR ";" +#define _MD_ERRNO() errno +#define _MD_OPEN_DIR (_PR_MD_OPEN_DIR) +#define _MD_CLOSE_DIR (_PR_MD_CLOSE_DIR) +#define _MD_READ_DIR (_PR_MD_READ_DIR) + +/* --- Segment stuff --- */ +#define _MD_INIT_SEGS() +#define _MD_ALLOC_SEGMENT(seg, size, vaddr) 0 +#define _MD_FREE_SEGMENT(seg) + +/* --- Environment Stuff --- */ +#define _MD_GET_ENV (_PR_MD_GET_ENV) +#define _MD_PUT_ENV (_PR_MD_PUT_ENV) + +/* --- Threading Stuff --- */ +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_INIT_THREAD (_PR_MD_INIT_THREAD) +#define _MD_INIT_ATTACHED_THREAD (_PR_MD_INIT_THREAD) +#define _MD_CREATE_THREAD (_PR_MD_CREATE_THREAD) +#define _MD_YIELD (_PR_MD_YIELD) +#define _MD_SET_PRIORITY (_PR_MD_SET_PRIORITY) +#define _MD_CLEAN_THREAD (_PR_MD_CLEAN_THREAD) +#define _MD_SETTHREADAFFINITYMASK (_PR_MD_SETTHREADAFFINITYMASK) +#define _MD_GETTHREADAFFINITYMASK (_PR_MD_GETTHREADAFFINITYMASK) +#define _MD_EXIT_THREAD (_PR_MD_EXIT_THREAD) +#define _MD_SUSPEND_THREAD (_PR_MD_SUSPEND_THREAD) +#define _MD_RESUME_THREAD (_PR_MD_RESUME_THREAD) +#define _MD_SUSPEND_CPU (_PR_MD_SUSPEND_CPU) +#define _MD_RESUME_CPU (_PR_MD_RESUME_CPU) +#define _MD_WAKEUP_CPUS (_PR_MD_WAKEUP_CPUS) +#define _MD_BEGIN_SUSPEND_ALL() +#define _MD_BEGIN_RESUME_ALL() +#define _MD_END_SUSPEND_ALL() +#define _MD_END_RESUME_ALL() + +/* --- Lock stuff --- */ +#define _PR_LOCK _MD_LOCK +#define _PR_UNLOCK _MD_UNLOCK + +#define _MD_NEW_LOCK (_PR_MD_NEW_LOCK) +#define _MD_FREE_LOCK(lock) (DosCloseMutexSem((lock)->mutex)) +#define _MD_LOCK(lock) (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT)) +#define _MD_TEST_AND_LOCK(lock) (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0) +#define _MD_UNLOCK (_PR_MD_UNLOCK) + +/* --- lock and cv waiting --- */ +#define _MD_WAIT (_PR_MD_WAIT) +#define _MD_WAKEUP_WAITER (_PR_MD_WAKEUP_WAITER) + +/* --- CVar ------------------- */ +#define _MD_WAIT_CV (_PR_MD_WAIT_CV) +#define _MD_NEW_CV (_PR_MD_NEW_CV) +#define _MD_FREE_CV (_PR_MD_FREE_CV) +#define _MD_NOTIFY_CV (_PR_MD_NOTIFY_CV ) +#define _MD_NOTIFYALL_CV (_PR_MD_NOTIFYALL_CV) + + /* XXXMB- the IOQ stuff is certainly not working correctly yet. */ +/* extern struct _MDLock _pr_ioq_lock; */ +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + + +/* --- Initialization stuff --- */ +#define _MD_START_INTERRUPTS() +#define _MD_STOP_INTERRUPTS() +#define _MD_DISABLE_CLOCK_INTERRUPTS() +#define _MD_ENABLE_CLOCK_INTERRUPTS() +#define _MD_BLOCK_CLOCK_INTERRUPTS() +#define _MD_UNBLOCK_CLOCK_INTERRUPTS() +#define _MD_EARLY_INIT (_PR_MD_EARLY_INIT) +#define _MD_FINAL_INIT() +#define _MD_EARLY_CLEANUP() +#define _MD_INIT_CPUS() +#define _MD_INIT_RUNNING_CPU(cpu) + +struct PRProcess; +struct PRProcessAttr; + +#define _MD_CREATE_PROCESS _PR_CreateOS2Process +extern struct PRProcess * _PR_CreateOS2Process( + const char *path, + char *const *argv, + char *const *envp, + const struct PRProcessAttr *attr +); + +#define _MD_DETACH_PROCESS _PR_DetachOS2Process +extern PRStatus _PR_DetachOS2Process(struct PRProcess *process); + +/* --- Wait for a child process to terminate --- */ +#define _MD_WAIT_PROCESS _PR_WaitOS2Process +extern PRStatus _PR_WaitOS2Process(struct PRProcess *process, + PRInt32 *exitCode); + +#define _MD_KILL_PROCESS _PR_KillOS2Process +extern PRStatus _PR_KillOS2Process(struct PRProcess *process); + +#define _MD_CLEANUP_BEFORE_EXIT() +#define _MD_EXIT (_PR_MD_EXIT) +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + *status = PR_TRUE; \ + PR_END_MACRO +#define _MD_SWITCH_CONTEXT +#define _MD_RESTORE_CONTEXT + +/* --- Intervals --- */ +#define _MD_INTERVAL_INIT (_PR_MD_INTERVAL_INIT) +#define _MD_GET_INTERVAL (_PR_MD_GET_INTERVAL) +#define _MD_INTERVAL_PER_SEC (_PR_MD_INTERVAL_PER_SEC) +#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) +#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) + +/* --- Native-Thread Specific Definitions ------------------------------- */ + +typedef struct __NSPR_TLS +{ + struct PRThread *_pr_thread_last_run; + struct PRThread *_pr_currentThread; + struct _PRCPU *_pr_currentCPU; +} _NSPR_TLS; + +extern _NSPR_TLS* pThreadLocalStorage; +NSPR_API(void) _PR_MD_ENSURE_TLS(void); + +#define _MD_GET_ATTACHED_THREAD() pThreadLocalStorage->_pr_currentThread +extern struct PRThread * _MD_CURRENT_THREAD(void); +#define _MD_SET_CURRENT_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentThread = (_thread) + +#define _MD_LAST_THREAD() pThreadLocalStorage->_pr_thread_last_run +#define _MD_SET_LAST_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_thread_last_run = (_thread) + +#define _MD_CURRENT_CPU() pThreadLocalStorage->_pr_currentCPU +#define _MD_SET_CURRENT_CPU(_cpu) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentCPU = (_cpu) + +/* lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) */ +/* lth. #define _MD_GET_INTSOFF() _pr_ints_off */ +/* lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++) */ +/* lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--) */ + +/* --- Scheduler stuff --- */ +#define LOCK_SCHEDULER() 0 +#define UNLOCK_SCHEDULER() 0 +#define _PR_LockSched() 0 +#define _PR_UnlockSched() 0 + +/* --- Initialization stuff --- */ +#define _MD_INIT_LOCKS() + +/* --- Stack stuff --- */ +#define _MD_INIT_STACK(stack, redzone) +#define _MD_CLEAR_STACK(stack) + +/* --- Memory-mapped files stuff --- */ +/* ReadOnly and WriteCopy modes are simulated on OS/2; + * ReadWrite mode is not supported. + */ +struct _MDFileMap { + PROffset64 maxExtent; +}; + +extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); +#define _MD_CREATE_FILE_MAP _MD_CreateFileMap + +extern PRInt32 _MD_GetMemMapAlignment(void); +#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment + +extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, + PRUint32 len); +#define _MD_MEM_MAP _MD_MemMap + +extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); +#define _MD_MEM_UNMAP _MD_MemUnmap + +extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); +#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap + +/* Some stuff for setting up thread contexts */ +typedef ULONG DWORD, *PDWORD; + +/* The following definitions and two structures are new in OS/2 Warp 4.0. + */ +#ifndef CONTEXT_CONTROL +#define CONTEXT_CONTROL 0x00000001 +#define CONTEXT_INTEGER 0x00000002 +#define CONTEXT_SEGMENTS 0x00000004 +#define CONTEXT_FLOATING_POINT 0x00000008 +#define CONTEXT_FULL 0x0000000F + +#pragma pack(2) +typedef struct _FPREG { + ULONG losig; /* Low 32-bits of the significand. */ + ULONG hisig; /* High 32-bits of the significand. */ + USHORT signexp; /* Sign and exponent. */ +} FPREG; +typedef struct _CONTEXTRECORD { + ULONG ContextFlags; + ULONG ctx_env[7]; + FPREG ctx_stack[8]; + ULONG ctx_SegGs; /* GS register. */ + ULONG ctx_SegFs; /* FS register. */ + ULONG ctx_SegEs; /* ES register. */ + ULONG ctx_SegDs; /* DS register. */ + ULONG ctx_RegEdi; /* EDI register. */ + ULONG ctx_RegEsi; /* ESI register. */ + ULONG ctx_RegEax; /* EAX register. */ + ULONG ctx_RegEbx; /* EBX register. */ + ULONG ctx_RegEcx; /* ECX register. */ + ULONG ctx_RegEdx; /* EDX register. */ + ULONG ctx_RegEbp; /* EBP register. */ + ULONG ctx_RegEip; /* EIP register. */ + ULONG ctx_SegCs; /* CS register. */ + ULONG ctx_EFlags; /* EFLAGS register. */ + ULONG ctx_RegEsp; /* ESP register. */ + ULONG ctx_SegSs; /* SS register. */ +} CONTEXTRECORD, *PCONTEXTRECORD; +#pragma pack() +#endif + +extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD); + +/* +#define _pr_tid (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid) +#define _pr_current_Thread (_system_tls[_pr_tid-1].__pr_current_thread) +*/ + +/* Some simple mappings of Windows API's to OS/2 API's to make our lives a + * little bit easier. Only add one here if it is a DIRECT mapping. We are + * not emulating anything. Just mapping. + */ +#define FreeLibrary(x) DosFreeModule((HMODULE)x) +#define OutputDebugStringA(x) + +extern int _MD_os2_get_nonblocking_connect_error(int osfd); + +#endif /* nspr_os2_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_osf1.cfg nspr-4.10.7/nspr/pr/include/md/_osf1.cfg --- nspr-4.9.5/nspr/pr/include/md/_osf1.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_osf1.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef OSF1 +#define OSF1 +#endif + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS +#ifndef IS_64 +#define IS_64 +#endif + +#define PR_AF_INET6 26 /* same as AF_INET6 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define _PR_POLL_BACKCOMPAT + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_osf1.h nspr-4.10.7/nspr/pr/include/md/_osf1.h --- nspr-4.9.5/nspr/pr/include/md/_osf1.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_osf1.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,222 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_osf1_defs_h___ +#define nspr_osf1_defs_h___ + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "osf" +#define _PR_SI_SYSNAME "OSF" +#define _PR_SI_ARCHITECTURE "alpha" +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 131072L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#undef HAVE_STACK_GROWING_UP +#undef HAVE_WEAK_IO_SYMBOLS +#undef HAVE_WEAK_MALLOC_SYMBOLS +#define HAVE_DLL +#define HAVE_BSD_FLOCK + +#define NEED_TIME_R +#define USE_DLFCN + +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_STAT_HAS_ONLY_ST_ATIME +#define _PR_HAVE_LARGE_OFF_T +#define _PR_HAVE_GETIPNODEBYNAME +#define _PR_HAVE_GETIPNODEBYADDR +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE +#ifdef _PR_INET6 +#define _PR_HAVE_INET_NTOP +#else +#define AF_INET6 26 +#ifndef AI_CANONNAME +#define AI_CANONNAME 0x00000002 +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + char *ai_canonname; + struct sockaddr *ai_addr; + struct addrinfo *ai_next; +}; +#endif +#define AI_V4MAPPED 0x00000010 +#define AI_ALL 0x00000008 +#define AI_ADDRCONFIG 0x00000020 +#endif +#define _PR_HAVE_POSIX_SEMAPHORES +#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY + +#define USE_SETJMP + +#include + +/* + * A jmp_buf is actually a struct sigcontext. The sc_sp field of + * struct sigcontext is the stack pointer. + */ +#define _MD_GET_SP(_t) (((struct sigcontext *) (_t)->md.context)->sc_sp) +#define PR_NUM_GCREGS _JBLEN +#define CONTEXT(_th) ((_th)->md.context) + +/* +** Initialize a thread context to run "_main()" when started +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (setjmp(CONTEXT(_thread))) { \ + (*_main)(); \ + } \ + _MD_GET_SP(_thread) = (long) ((_sp) - 64); \ + _MD_GET_SP(_thread) &= ~15; \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!setjmp(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + longjmp(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures */ + +struct _MDThread { + jmp_buf context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#ifndef _PR_PTHREADS +#define _MD_INIT_LOCKS() +#endif +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +/* + * The following are copied from _sunos.h, _aix.h. This means + * some of them should probably be moved into _unixos.h. But + * _irix.h seems to be quite different in regard to these macros. + */ +#define _MD_INTERVAL_USE_GTOD + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +/* The following defines unwrapped versions of select() and poll(). */ +#include +extern int __select (int, fd_set *, fd_set *, fd_set *, struct timeval *); +#define _MD_SELECT __select + +#include +#define _MD_POLL __poll +extern int __poll(struct pollfd filedes[], unsigned int nfds, int timeout); + +/* + * Atomic operations + */ +#ifdef OSF1_HAVE_MACHINE_BUILTINS_H +#include +#define _PR_HAVE_ATOMIC_OPS +#define _MD_INIT_ATOMIC() +#define _MD_ATOMIC_INCREMENT(val) (__ATOMIC_INCREMENT_LONG(val) + 1) +#define _MD_ATOMIC_ADD(ptr, val) (__ATOMIC_ADD_LONG(ptr, val) + val) +#define _MD_ATOMIC_DECREMENT(val) (__ATOMIC_DECREMENT_LONG(val) - 1) +#define _MD_ATOMIC_SET(val, newval) __ATOMIC_EXCH_LONG(val, newval) +#endif /* OSF1_HAVE_MACHINE_BUILTINS_H */ + +#endif /* nspr_osf1_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_pcos.h nspr-4.10.7/nspr/pr/include/md/_pcos.h --- nspr-4.9.5/nspr/pr/include/md/_pcos.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_pcos.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prpcos_h___ +#define prpcos_h___ + +#define PR_DLL_SUFFIX ".dll" + +#include + +#define DIRECTORY_SEPARATOR '\\' +#define DIRECTORY_SEPARATOR_STR "\\" +#define PATH_SEPARATOR ';' + +/* +** Routines for processing command line arguments +*/ +PR_BEGIN_EXTERN_C +#ifndef XP_OS2 +extern char *optarg; +extern int optind; +extern int getopt(int argc, char **argv, char *spec); +#endif +PR_END_EXTERN_C + + +/* +** Definitions of directory structures amd functions +** These definitions are from: +** +*/ +#ifdef XP_OS2 +#include +#endif +#include +#include +#include /* O_BINARY */ + +#ifdef OS2 +extern PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen); +#define _MD_GETHOSTNAME _MD_OS2GetHostName +#else +extern PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen); +#define _MD_GETHOSTNAME _MD_WindowsGetHostName +extern PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen); +#define _MD_GETSYSINFO _MD_WindowsGetSysInfo +#endif + +#endif /* prpcos_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/prosdep.h nspr-4.10.7/nspr/pr/include/md/prosdep.h --- nspr-4.9.5/nspr/pr/include/md/prosdep.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/prosdep.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prosdep_h___ +#define prosdep_h___ + +/* +** Get OS specific header information +*/ +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +#ifdef XP_PC + +#include "md/_pcos.h" +#ifdef WINNT +#include "md/_winnt.h" +#include "md/_win32_errors.h" +#elif defined(WIN95) || defined(WINCE) +#include "md/_win95.h" +#include "md/_win32_errors.h" +#elif defined(OS2) +#include "md/_os2.h" +#include "md/_os2_errors.h" +#else +#error unknown Windows platform +#endif + +#elif defined(XP_UNIX) + +#if defined(AIX) +#include "md/_aix.h" + +#elif defined(FREEBSD) +#include "md/_freebsd.h" + +#elif defined(NETBSD) +#include "md/_netbsd.h" + +#elif defined(OPENBSD) +#include "md/_openbsd.h" + +#elif defined(BSDI) +#include "md/_bsdi.h" + +#elif defined(HPUX) +#include "md/_hpux.h" + +#elif defined(IRIX) +#include "md/_irix.h" + +#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) +#include "md/_linux.h" + +#elif defined(OSF1) +#include "md/_osf1.h" + +#elif defined(DARWIN) +#include "md/_darwin.h" + +#elif defined(SOLARIS) +#include "md/_solaris.h" + +#elif defined(SCO) +#include "md/_scoos.h" + +#elif defined(UNIXWARE) +#include "md/_unixware.h" + +#elif defined(DGUX) +#include "md/_dgux.h" + +#elif defined(QNX) +#include "md/_qnx.h" + +#elif defined(NTO) +#include "md/_nto.h" + +#elif defined(RISCOS) +#include "md/_riscos.h" + +#elif defined(SYMBIAN) +#include "md/_symbian.h" + +#else +#error unknown Unix flavor + +#endif + +#include "md/_unixos.h" +#include "md/_unix_errors.h" + +#elif defined(XP_BEOS) + +#include "md/_beos.h" +#include "md/_unix_errors.h" + +#else + +#error "The platform is not BeOS, Unix, Windows, or Mac" + +#endif + +#ifdef _PR_PTHREADS +#include "md/_pth.h" +#endif + +PR_END_EXTERN_C + +#endif /* prosdep_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_pth.h nspr-4.10.7/nspr/pr/include/md/_pth.h --- nspr-4.9.5/nspr/pr/include/md/_pth.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_pth.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,270 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_pth_defs_h_ +#define nspr_pth_defs_h_ + +/* +** Appropriate definitions of entry points not used in a pthreads world +*/ +#define _PR_MD_BLOCK_CLOCK_INTERRUPTS() +#define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS() +#define _PR_MD_DISABLE_CLOCK_INTERRUPTS() +#define _PR_MD_ENABLE_CLOCK_INTERRUPTS() + +/* In good standards fashion, the DCE threads (based on posix-4) are not + * quite the same as newer posix implementations. These are mostly name + * changes and small differences, so macros usually do the trick + */ +#ifdef _PR_DCETHREADS +#define _PT_PTHREAD_MUTEXATTR_INIT pthread_mutexattr_create +#define _PT_PTHREAD_MUTEXATTR_DESTROY pthread_mutexattr_delete +#define _PT_PTHREAD_MUTEX_INIT(m, a) pthread_mutex_init(&(m), a) +#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (0 == pthread_mutex_trylock(&(m))) +#define _PT_PTHREAD_CONDATTR_INIT pthread_condattr_create +#define _PT_PTHREAD_COND_INIT(m, a) pthread_cond_init(&(m), a) +#define _PT_PTHREAD_CONDATTR_DESTROY pthread_condattr_delete + +/* Notes about differences between DCE threads and pthreads 10: + * 1. pthread_mutex_trylock returns 1 when it locks the mutex + * 0 when it does not. The latest pthreads has a set of errno-like + * return values. + * 2. return values from pthread_cond_timedwait are different. + * + * + * + */ +#elif defined(BSDI) +/* + * Mutex and condition attributes are not supported. The attr + * argument to pthread_mutex_init() and pthread_cond_init() must + * be passed as NULL. + * + * The memset calls in _PT_PTHREAD_MUTEX_INIT and _PT_PTHREAD_COND_INIT + * are to work around BSDI's using a single bit to indicate a mutex + * or condition variable is initialized. This entire BSDI section + * will go away when BSDI releases updated threads libraries for + * BSD/OS 3.1 and 4.0. + */ +#define _PT_PTHREAD_MUTEXATTR_INIT(x) 0 +#define _PT_PTHREAD_MUTEXATTR_DESTROY(x) /* */ +#define _PT_PTHREAD_MUTEX_INIT(m, a) (memset(&(m), 0, sizeof(m)), \ + pthread_mutex_init(&(m), NULL)) +#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (EBUSY == pthread_mutex_trylock(&(m))) +#define _PT_PTHREAD_CONDATTR_INIT(x) 0 +#define _PT_PTHREAD_CONDATTR_DESTROY(x) /* */ +#define _PT_PTHREAD_COND_INIT(m, a) (memset(&(m), 0, sizeof(m)), \ + pthread_cond_init(&(m), NULL)) +#else +#define _PT_PTHREAD_MUTEXATTR_INIT pthread_mutexattr_init +#define _PT_PTHREAD_MUTEXATTR_DESTROY pthread_mutexattr_destroy +#define _PT_PTHREAD_MUTEX_INIT(m, a) pthread_mutex_init(&(m), &(a)) +#if defined(FREEBSD) +#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) pt_pthread_mutex_is_locked(&(m)) +#else +#define _PT_PTHREAD_MUTEX_IS_LOCKED(m) (EBUSY == pthread_mutex_trylock(&(m))) +#endif +#if defined(ANDROID) +/* Conditional attribute init and destroy aren't implemented in bionic. */ +#define _PT_PTHREAD_CONDATTR_INIT(x) 0 +#define _PT_PTHREAD_CONDATTR_DESTROY(x) /* */ +#else +#define _PT_PTHREAD_CONDATTR_INIT pthread_condattr_init +#define _PT_PTHREAD_CONDATTR_DESTROY pthread_condattr_destroy +#endif +#define _PT_PTHREAD_COND_INIT(m, a) pthread_cond_init(&(m), &(a)) +#endif + +/* The pthreads standard does not specify an invalid value for the + * pthread_t handle. (0 is usually an invalid pthread identifier + * but there are exceptions, for example, DG/UX.) These macros + * define a way to set the handle to or compare the handle with an + * invalid identifier. These macros are not portable and may be + * more of a problem as we adapt to more pthreads implementations. + * They are only used in the PRMonitor functions. Do not use them + * in new code. + * + * Unfortunately some of our clients depend on certain properties + * of our PRMonitor implementation, preventing us from replacing + * it by a portable implementation. + * - High-performance servers like the fact that PR_EnterMonitor + * only calls PR_Lock and PR_ExitMonitor only calls PR_Unlock. + * (A portable implementation would use a PRLock and a PRCondVar + * to implement the recursive lock in a monitor and call both + * PR_Lock and PR_Unlock in PR_EnterMonitor and PR_ExitMonitor.) + * Unfortunately this forces us to read the monitor owner field + * without holding a lock. + * - One way to make it safe to read the monitor owner field + * without holding a lock is to make that field a PRThread* + * (one should be able to read a pointer with a single machine + * instruction). However, PR_GetCurrentThread calls calloc if + * it is called by a thread that was not created by NSPR. The + * malloc tracing tools in the Mozilla client use PRMonitor for + * locking in their malloc, calloc, and free functions. If + * PR_EnterMonitor calls any of these functions, infinite + * recursion ensues. + */ +#if defined(_PR_DCETHREADS) +#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) \ + memset(&(t), 0, sizeof(pthread_t)) +#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) \ + (!memcmp(&(t), &pt_zero_tid, sizeof(pthread_t))) +#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt) (dt) = (st) +#elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(SOLARIS) \ + || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ + || defined(HPUX) || defined(FREEBSD) \ + || defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \ + || defined(NTO) || defined(DARWIN) \ + || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) +#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) (t) = 0 +#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) (t) == 0 +#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt) (dt) = (st) +#else +#error "pthreads is not supported for this architecture" +#endif + +#if defined(_PR_DCETHREADS) +#define _PT_PTHREAD_ATTR_INIT pthread_attr_create +#define _PT_PTHREAD_ATTR_DESTROY pthread_attr_delete +#define _PT_PTHREAD_CREATE(t, a, f, r) pthread_create(t, a, f, r) +#define _PT_PTHREAD_KEY_CREATE pthread_keycreate +#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY pthread_attr_setsched +#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) \ + (*(s) = pthread_attr_getstacksize(*(a)), 0) +#define _PT_PTHREAD_GETSPECIFIC(k, r) \ + pthread_getspecific((k), (pthread_addr_t *) &(r)) +#elif defined(_PR_PTHREADS) +#define _PT_PTHREAD_ATTR_INIT pthread_attr_init +#define _PT_PTHREAD_ATTR_DESTROY pthread_attr_destroy +#define _PT_PTHREAD_CREATE(t, a, f, r) pthread_create(t, &a, f, r) +#define _PT_PTHREAD_KEY_CREATE pthread_key_create +#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY pthread_attr_setschedpolicy +#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) pthread_attr_getstacksize(a, s) +#define _PT_PTHREAD_GETSPECIFIC(k, r) (r) = pthread_getspecific(k) +#else +#error "Cannot determine pthread strategy" +#endif + +#if defined(_PR_DCETHREADS) +#define _PT_PTHREAD_EXPLICIT_SCHED _PT_PTHREAD_DEFAULT_SCHED +#endif + +/* + * pthread_mutex_trylock returns different values in DCE threads and + * pthreads. + */ +#if defined(_PR_DCETHREADS) +#define PT_TRYLOCK_SUCCESS 1 +#define PT_TRYLOCK_BUSY 0 +#else +#define PT_TRYLOCK_SUCCESS 0 +#define PT_TRYLOCK_BUSY EBUSY +#endif + +/* + * These platforms don't have sigtimedwait() + */ +#if (defined(AIX) && !defined(AIX4_3_PLUS)) \ + || defined(LINUX) || defined(__GNU__)|| defined(__GLIBC__) \ + || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ + || defined(BSDI) || defined(UNIXWARE) \ + || defined(DARWIN) || defined(SYMBIAN) +#define PT_NO_SIGTIMEDWAIT +#endif + +#if defined(OSF1) +#define PT_PRIO_MIN PRI_OTHER_MIN +#define PT_PRIO_MAX PRI_OTHER_MAX +#elif defined(IRIX) +#include +#define PT_PRIO_MIN PX_PRIO_MIN +#define PT_PRIO_MAX PX_PRIO_MAX +#elif defined(AIX) +#include +#include +#ifndef PTHREAD_CREATE_JOINABLE +#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED +#endif +#define PT_PRIO_MIN DEFAULT_PRIO +#define PT_PRIO_MAX DEFAULT_PRIO +#elif defined(HPUX) + +#if defined(_PR_DCETHREADS) +#define PT_PRIO_MIN PRI_OTHER_MIN +#define PT_PRIO_MAX PRI_OTHER_MAX +#else /* defined(_PR_DCETHREADS) */ +#include +#define PT_PRIO_MIN sched_get_priority_min(SCHED_OTHER) +#define PT_PRIO_MAX sched_get_priority_max(SCHED_OTHER) +#endif /* defined(_PR_DCETHREADS) */ + +#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ + || defined(FREEBSD) || defined(SYMBIAN) +#define PT_PRIO_MIN sched_get_priority_min(SCHED_OTHER) +#define PT_PRIO_MAX sched_get_priority_max(SCHED_OTHER) +#elif defined(NTO) +/* + * Neutrino has functions that return the priority range but + * they return invalid numbers, so I just hard coded these here + * for now. Jerry.Kirk@Nexarecorp.com + */ +#define PT_PRIO_MIN 0 +#define PT_PRIO_MAX 30 +#elif defined(SOLARIS) +/* + * Solaris doesn't seem to have macros for the min/max priorities. + * The range of 0-127 is mentioned in the pthread_setschedparam(3T) + * man pages, and pthread_setschedparam indeed allows 0-127. However, + * pthread_attr_setschedparam does not allow 0; it allows 1-127. + */ +#define PT_PRIO_MIN 1 +#define PT_PRIO_MAX 127 +#elif defined(OPENBSD) +#define PT_PRIO_MIN 0 +#define PT_PRIO_MAX 31 +#elif defined(NETBSD) \ + || defined(BSDI) || defined(DARWIN) || defined(UNIXWARE) \ + || defined(RISCOS) /* XXX */ +#define PT_PRIO_MIN 0 +#define PT_PRIO_MAX 126 +#else +#error "pthreads is not supported for this architecture" +#endif + +/* + * The _PT_PTHREAD_YIELD function is called from a signal handler. + * Needed for garbage collection -- Look at PR_Suspend/PR_Resume + * implementation. + */ +#if defined(_PR_DCETHREADS) +#define _PT_PTHREAD_YIELD() pthread_yield() +#elif defined(OSF1) +/* + * sched_yield can't be called from a signal handler. Must use + * the _np version. + */ +#define _PT_PTHREAD_YIELD() pthread_yield_np() +#elif defined(AIX) +extern int (*_PT_aix_yield_fcn)(); +#define _PT_PTHREAD_YIELD() (*_PT_aix_yield_fcn)() +#elif defined(IRIX) +#include +#define _PT_PTHREAD_YIELD() \ + PR_BEGIN_MACRO \ + struct timespec onemillisec = {0}; \ + onemillisec.tv_nsec = 1000000L; \ + nanosleep(&onemillisec,NULL); \ + PR_END_MACRO +#elif defined(HPUX) || defined(SOLARIS) \ + || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ + || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ + || defined(BSDI) || defined(NTO) || defined(DARWIN) \ + || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) +#define _PT_PTHREAD_YIELD() sched_yield() +#else +#error "Need to define _PT_PTHREAD_YIELD for this platform" +#endif + +#endif /* nspr_pth_defs_h_ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_qnx.cfg nspr-4.10.7/nspr/pr/include/md/_qnx.cfg --- nspr-4.9.5/nspr/pr/include/md/_qnx.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_qnx.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef QNX +#define QNX +#endif + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#undef HAVE_LONG_LONG +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 1 +#define PR_ALIGN_OF_INT 1 +#define PR_ALIGN_OF_LONG 1 +#define PR_ALIGN_OF_INT64 1 +#define PR_ALIGN_OF_FLOAT 1 +#define PR_ALIGN_OF_DOUBLE 1 +#define PR_ALIGN_OF_POINTER 1 +#define PR_ALIGN_OF_WORD 1 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 +#define PR_WORDS_PER_DWORD_LOG2 1 + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_qnx.h nspr-4.10.7/nspr/pr/include/md/_qnx.h --- nspr-4.9.5/nspr/pr/include/md/_qnx.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_qnx.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_qnx_defs_h___ +#define nspr_qnx_defs_h___ + +/* +** Internal configuration macros +*/ +#define PR_LINKER_ARCH "qnx" +#define _PR_SI_SYSNAME "QNX" +#define _PR_SI_ARCHITECTURE "x86" +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#ifndef HAVE_WEAK_IO_SYMBOLS +#define HAVE_WEAK_IO_SYMBOLS +#endif + +#undef _PR_POLL_AVAILABLE +#undef _PR_USE_POLL +#define _PR_HAVE_SOCKADDR_LEN +#define HAVE_BSD_FLOCK +#define _PR_NO_LARGE_FILES +#define _PR_STAT_HAS_ONLY_ST_ATIME + +#include + +#undef HAVE_STACK_GROWING_UP +#undef HAVE_DLL +#undef USE_DLFCN +#define NEED_STRFTIME_LOCK +#define NEED_TIME_R +#define _PR_NEED_STRCASECMP + +#ifndef HAVE_STRERROR +#define HAVE_STRERROR +#endif + +#define USE_SETJMP + +#include + +#define _SETJMP setjmp +#define _LONGJMP longjmp +#define _PR_CONTEXT_TYPE jmp_buf +#define _PR_NUM_GCREGS _JBLEN +#define _MD_GET_SP(_t) (_t)->md.context[7] + +#define CONTEXT(_th) ((_th)->md.context) + +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ + _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!_SETJMP(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + _LONGJMP(CONTEXT(_thread), 1); \ +} + +/* +** Machine-dependent (MD) data structures. +*/ +struct _MDThread { + _PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* +** md-specific cpu structure field +*/ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_INTERVAL_USE_GTOD +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +/* +** We wrapped the select() call. _MD_SELECT refers to the built-in, +** unwrapped version. +*/ +#include +#include +#include +#define _MD_SELECT select + +#define SA_RESTART 0 + +#endif /* nspr_qnx_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_riscos.cfg nspr-4.10.7/nspr/pr/include/md/_riscos.cfg --- nspr-4.9.5/nspr/pr/include/md/_riscos.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_riscos.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef RISCOS +#define RISCOS +#endif + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 +#define PR_WORDS_PER_DWORD_LOG2 1 + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_riscos.h nspr-4.10.7/nspr/pr/include/md/_riscos.h --- nspr-4.9.5/nspr/pr/include/md/_riscos.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_riscos.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_riscos_defs_h___ +#define nspr_riscos_defs_h___ + +/* +** Internal configuration macros +*/ +#define PR_LINKER_ARCH "riscos" +#define _PR_SI_SYSNAME "RISCOS" +#define _PR_SI_ARCHITECTURE "arm" +#define PR_DLL_SUFFIX ".so" + +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_HAVE_SOCKADDR_LEN +#undef HAVE_BSD_FLOCK +#define _PR_NO_LARGE_FILES +#define _PR_STAT_HAS_ONLY_ST_ATIME +#define _PR_HAVE_POSIX_SEMAPHORES + +#include +#include +#include + + +#undef HAVE_STACK_GROWING_UP +#define HAVE_DLL +#define USE_DLFCN +#define NEED_STRFTIME_LOCK +#define NEED_TIME_R +#define PT_NO_SIGTIMEDWAIT + +#ifndef HAVE_STRERROR +#define HAVE_STRERROR +#endif + +#define USE_SETJMP + +#include + +#define _SETJMP setjmp +#define _LONGJMP longjmp +#define _PR_CONTEXT_TYPE jmp_buf +#define _PR_NUM_GCREGS _JBLEN +#define _MD_GET_SP(_t) (_t)->md.context[7] + +#define CONTEXT(_th) ((_th)->md.context) + + +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ + _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!_SETJMP(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + _LONGJMP(CONTEXT(_thread), 1); \ +} + +/* +** Machine-dependent (MD) data structures. +*/ +struct _MDThread { + _PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* +** md-specific cpu structure field +*/ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif +}; + +#define _PR_IOQ(_cpu) /* */ ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_INTERVAL_USE_GTOD +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +/* +** We wrapped the select() call. _MD_SELECT refers to the built-in, +** unwrapped version. +*/ +#include +#include +#include +#define _MD_SELECT select + +#endif /* nspr_riscos_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_scoos.cfg nspr-4.10.7/nspr/pr/include/md/_scoos.cfg --- nspr-4.9.5/nspr/pr/include/md/_scoos.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_scoos.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef SCO +#define SCO +#endif + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#undef HAVE_LONG_LONG +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#define _PR_POLL_BACKCOMPAT + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_scoos.h nspr-4.10.7/nspr/pr/include/md/_scoos.h --- nspr-4.9.5/nspr/pr/include/md/_scoos.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_scoos.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_scoos5_defs_h___ +#define nspr_scoos5_defs_h___ + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "scoos5" +#define PR_DLL_SUFFIX ".so" + +#define _PR_SI_SYSNAME "SCO" +#define _PR_SI_ARCHITECTURE "x86" +#define _PR_STACK_VMBASE 0x50000000 + +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#undef HAVE_STACK_GROWING_UP +#define HAVE_DLL +#define USE_DLFCN + +#if !defined (HAVE_STRERROR) +#define HAVE_STRERROR +#endif + +#ifndef HAVE_WEAK_IO_SYMBOLS +#define HAVE_WEAK_IO_SYMBOLS +#endif + +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_NO_LARGE_FILES +#define _PR_STAT_HAS_ONLY_ST_ATIME + +#define NEED_STRFTIME_LOCK +#define NEED_TIME_R +#define _PR_RECV_BROKEN /* recv doesn't work on Unix Domain Sockets */ + +#define USE_SETJMP + +#ifdef _PR_LOCAL_THREADS_ONLY +#include + +#define _MD_GET_SP(_t) (_t)->md.jb[4] +#define PR_NUM_GCREGS _SIGJBLEN +#define PR_CONTEXT_TYPE sigjmp_buf + +#define CONTEXT(_th) ((_th)->md.jb) + +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if (sigsetjmp(CONTEXT(_thread),1)) { \ + (*_main)(); \ + } \ + _MD_GET_SP(_thread) = (int) ((_sp) - 64); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!sigsetjmp(CONTEXT(_thread), 1)) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->osErrorCode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + siglongjmp(CONTEXT(_thread), 1); \ +} + +#endif /* _PR_LOCAL_THREADS_ONLY */ + +struct _MDThread { + jmp_buf jb; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +#define _MD_INTERVAL_USE_GTOD + +#define _MD_SELECT _select +#define _MD_POLL _poll + +#endif /* nspr_scoos5_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_solaris.cfg nspr-4.10.7/nspr/pr/include/md/_solaris.cfg --- nspr-4.9.5/nspr/pr/include/md/_solaris.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_solaris.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef SOLARIS +#define SOLARIS +#endif + +#define PR_AF_INET6 26 /* same as AF_INET6 */ + +#if defined(sparc) || defined(__sparc) +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_DOUBLE 8 +#if defined(__sparcv9) +#define IS_64 +#endif +#elif defined(__x86_64) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_DOUBLE 8 +#define IS_64 +#elif defined(i386) || defined(__i386) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_DOUBLE 4 +#else +#error unknown processor +#endif + +#ifdef IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_POINTER 8 + +#else /* IS_64 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_POINTER 4 + +#endif /* IS_64 */ + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#define HAVE_ALIGNED_DOUBLES +#define HAVE_ALIGNED_LONGLONGS + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* ifndef nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_solaris.h nspr-4.10.7/nspr/pr/include/md/_solaris.h --- nspr-4.9.5/nspr/pr/include/md/_solaris.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_solaris.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,493 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_solaris_defs_h___ +#define nspr_solaris_defs_h___ + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "solaris" +#define _PR_SI_SYSNAME "SOLARIS" +#ifdef sparc +#define _PR_SI_ARCHITECTURE "sparc" +#elif defined(__x86_64) +#define _PR_SI_ARCHITECTURE "x86-64" +#elif defined(i386) +#define _PR_SI_ARCHITECTURE "x86" +#else +#error unknown processor +#endif +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE (2*65536L) +#define _MD_MMAP_FLAGS MAP_SHARED + +#undef HAVE_STACK_GROWING_UP + +#ifndef HAVE_WEAK_IO_SYMBOLS +#define HAVE_WEAK_IO_SYMBOLS +#endif + +#undef HAVE_WEAK_MALLOC_SYMBOLS +#define HAVE_DLL +#define USE_DLFCN +#define NEED_STRFTIME_LOCK + +/* + * Intel x86 has atomic instructions. + * + * Sparc v8 does not have instructions to efficiently implement + * atomic increment/decrement operations. We use the default + * atomic routine implementation in pratom.c. + * + * 64-bit Solaris requires sparc v9, which has atomic instructions. + */ +#if defined(i386) || defined(IS_64) +#define _PR_HAVE_ATOMIC_OPS +#endif + +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_STAT_HAS_ST_ATIM +#ifdef SOLARIS2_5 +#define _PR_HAVE_SYSV_SEMAPHORES +#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY +#else +#define _PR_HAVE_POSIX_SEMAPHORES +#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY +#endif +#define _PR_HAVE_GETIPNODEBYNAME +#define _PR_HAVE_GETIPNODEBYADDR +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE +#define _PR_ACCEPT_INHERIT_NONBLOCK +#ifdef _PR_INET6 +#define _PR_HAVE_INET_NTOP +#else +#define AF_INET6 26 +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + char *ai_canonname; + struct sockaddr *ai_addr; + struct addrinfo *ai_next; +}; +#define AI_CANONNAME 0x0010 +#define AI_V4MAPPED 0x0001 +#define AI_ALL 0x0002 +#define AI_ADDRCONFIG 0x0004 +#define _PR_HAVE_MD_SOCKADDR_IN6 +/* isomorphic to struct in6_addr on Solaris 8 */ +struct _md_in6_addr { + union { + PRUint8 _S6_u8[16]; + PRUint32 _S6_u32[4]; + PRUint32 __S6_align; + } _S6_un; +}; +/* isomorphic to struct sockaddr_in6 on Solaris 8 */ +struct _md_sockaddr_in6 { + PRUint16 sin6_family; + PRUint16 sin6_port; + PRUint32 sin6_flowinfo; + struct _md_in6_addr sin6_addr; + PRUint32 sin6_scope_id; + PRUint32 __sin6_src_id; +}; +#endif +#if defined(_PR_PTHREADS) +#define _PR_HAVE_GETHOST_R +#define _PR_HAVE_GETHOST_R_POINTER +#endif + +#include "prinrval.h" +#define _MD_INTERVAL_INIT() +NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void); +#define _MD_GET_INTERVAL _MD_Solaris_GetInterval +NSPR_API(PRIntervalTime) _MD_Solaris_TicksPerSecond(void); +#define _MD_INTERVAL_PER_SEC _MD_Solaris_TicksPerSecond + +#if defined(_PR_HAVE_ATOMIC_OPS) +/* +** Atomic Operations +*/ +#define _MD_INIT_ATOMIC() + +NSPR_API(PRInt32) _MD_AtomicIncrement(PRInt32 *val); +#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement + +NSPR_API(PRInt32) _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val); +#define _MD_ATOMIC_ADD _MD_AtomicAdd + +NSPR_API(PRInt32) _MD_AtomicDecrement(PRInt32 *val); +#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement + +NSPR_API(PRInt32) _MD_AtomicSet(PRInt32 *val, PRInt32 newval); +#define _MD_ATOMIC_SET _MD_AtomicSet +#endif /* _PR_HAVE_ATOMIC_OPS */ + +#if defined(_PR_PTHREADS) + +NSPR_API(void) _MD_EarlyInit(void); + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit + +#else /* _PR_PTHREADS */ + +/* + * _PR_LOCAL_THREADS_ONLY implementation on Solaris + */ + +#include "prthread.h" + +#include +#include +#include +#include + +/* +** Initialization Related definitions +*/ + +NSPR_API(void) _MD_EarlyInit(void); +NSPR_API(void) _MD_SolarisInit(); +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _MD_SolarisInit +#define _MD_INIT_THREAD _MD_InitializeThread + +#ifdef USE_SETJMP + +#include + +#define _PR_CONTEXT_TYPE jmp_buf + +#ifdef sparc +#define _MD_GET_SP(_t) (_t)->md.context[2] +#else +#define _MD_GET_SP(_t) (_t)->md.context[4] +#endif + +#define PR_NUM_GCREGS _JBLEN +#define CONTEXT(_thread) (_thread)->md.context + +#else /* ! USE_SETJMP */ + +#ifdef sparc +#define _PR_CONTEXT_TYPE ucontext_t +#define _MD_GET_SP(_t) (_t)->md.context.uc_mcontext.gregs[REG_SP] +/* +** Sparc's use register windows. the _MD_GetRegisters for the sparc's +** doesn't actually store anything into the argument buffer; instead the +** register windows are homed to the stack. I assume that the stack +** always has room for the registers to spill to... +*/ +#define PR_NUM_GCREGS 0 +#else +#define _PR_CONTEXT_TYPE unsigned int edi; sigset_t oldMask, blockMask; ucontext_t +#define _MD_GET_SP(_t) (_t)->md.context.uc_mcontext.gregs[USP] +#define PR_NUM_GCREGS _JBLEN +#endif + +#define CONTEXT(_thread) (&(_thread)->md.context) + +#endif /* ! USE_SETJMP */ + +#include +/* + * Because clock_gettime() on Solaris/x86 always generates a + * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(), + * which is implemented using gettimeofday(). + */ +#ifdef i386 +#define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt)) +#else +#define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt)) +#endif /* i386 */ + +#define _MD_SAVE_ERRNO(_thread) (_thread)->md.errcode = errno; +#define _MD_RESTORE_ERRNO(_thread) errno = (_thread)->md.errcode; + +#ifdef sparc + +#ifdef USE_SETJMP +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + int *context = (_thread)->md.context; \ + *status = PR_TRUE; \ + (void) setjmp(context); \ + (_thread)->md.context[1] = (int) ((_sp) - 64); \ + (_thread)->md.context[2] = (int) _main; \ + (_thread)->md.context[3] = (int) _main + 4; \ + _thread->no_sched = 0; \ + PR_END_MACRO + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!setjmp(CONTEXT(_thread))) { \ + _MD_SAVE_ERRNO(_thread) \ + _MD_SET_LAST_THREAD(_thread); \ + _MD_SET_CURRENT_THREAD(_thread); \ + _PR_Schedule(); \ + } + +#define _MD_RESTORE_CONTEXT(_newThread) \ +{ \ + _MD_RESTORE_ERRNO(_newThread) \ + _MD_SET_CURRENT_THREAD(_newThread); \ + longjmp(CONTEXT(_newThread), 1); \ +} + +#else +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + ucontext_t *uc = CONTEXT(_thread); \ + *status = PR_TRUE; \ + getcontext(uc); \ + uc->uc_stack.ss_sp = (char *) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8); \ + uc->uc_stack.ss_size = _thread->stack->stackSize; \ + uc->uc_stack.ss_flags = 0; /* ? */ \ + uc->uc_mcontext.gregs[REG_SP] = (unsigned int) uc->uc_stack.ss_sp; \ + uc->uc_mcontext.gregs[REG_PC] = (unsigned int) _main; \ + uc->uc_mcontext.gregs[REG_nPC] = (unsigned int) ((char*)_main)+4; \ + uc->uc_flags = UC_ALL; \ + _thread->no_sched = 0; \ + PR_END_MACRO + +/* +** Switch away from the current thread context by saving its state and +** calling the thread scheduler. Reload cpu when we come back from the +** context switch because it might have changed. +*/ +#define _MD_SWITCH_CONTEXT(_thread) \ + PR_BEGIN_MACRO \ + if (!getcontext(CONTEXT(_thread))) { \ + _MD_SAVE_ERRNO(_thread); \ + _MD_SET_LAST_THREAD(_thread); \ + _PR_Schedule(); \ + } \ + PR_END_MACRO + +/* +** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or +** initialized by _MD_INIT_CONTEXT. +*/ +#define _MD_RESTORE_CONTEXT(_newThread) \ + PR_BEGIN_MACRO \ + ucontext_t *uc = CONTEXT(_newThread); \ + uc->uc_mcontext.gregs[11] = 1; \ + _MD_RESTORE_ERRNO(_newThread); \ + _MD_SET_CURRENT_THREAD(_newThread); \ + setcontext(uc); \ + PR_END_MACRO +#endif + +#else /* x86 solaris */ + +#ifdef USE_SETJMP + +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + *status = PR_TRUE; \ + if (setjmp(CONTEXT(_thread))) _main(); \ + _MD_GET_SP(_thread) = (int) ((_sp) - 64); \ + PR_END_MACRO + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!setjmp(CONTEXT(_thread))) { \ + _MD_SAVE_ERRNO(_thread) \ + _PR_Schedule(); \ + } + +#define _MD_RESTORE_CONTEXT(_newThread) \ +{ \ + _MD_RESTORE_ERRNO(_newThread) \ + _MD_SET_CURRENT_THREAD(_newThread); \ + longjmp(CONTEXT(_newThread), 1); \ +} + +#else /* USE_SETJMP */ + +#define WINDOWSIZE 0 + +int getedi(void); +void setedi(int); + +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + ucontext_t *uc = CONTEXT(_thread); \ + *status = PR_TRUE; \ + getcontext(uc); \ + /* Force sp to be double aligned! */ \ + uc->uc_mcontext.gregs[USP] = (int) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8); \ + uc->uc_mcontext.gregs[PC] = (int) _main; \ + (_thread)->no_sched = 0; \ + PR_END_MACRO + +/* getcontext() may return 1, contrary to what the man page says */ +#define _MD_SWITCH_CONTEXT(_thread) \ + PR_BEGIN_MACRO \ + ucontext_t *uc = CONTEXT(_thread); \ + PR_ASSERT(_thread->no_sched); \ + sigfillset(&((_thread)->md.blockMask)); \ + sigprocmask(SIG_BLOCK, &((_thread)->md.blockMask), \ + &((_thread)->md.oldMask)); \ + (_thread)->md.edi = getedi(); \ + if (! getcontext(uc)) { \ + sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \ + uc->uc_mcontext.gregs[EDI] = (_thread)->md.edi; \ + _MD_SAVE_ERRNO(_thread) \ + _MD_SET_LAST_THREAD(_thread); \ + _PR_Schedule(); \ + } else { \ + sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \ + setedi((_thread)->md.edi); \ + PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \ + _MD_LAST_THREAD()->no_sched = 0; \ + } \ + PR_END_MACRO + +/* +** Restore a thread context, saved by _PR_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_newthread) \ + PR_BEGIN_MACRO \ + ucontext_t *uc = CONTEXT(_newthread); \ + uc->uc_mcontext.gregs[EAX] = 1; \ + _MD_RESTORE_ERRNO(_newthread) \ + _MD_SET_CURRENT_THREAD(_newthread); \ + (_newthread)->no_sched = 1; \ + setcontext(uc); \ + PR_END_MACRO +#endif /* USE_SETJMP */ + +#endif /* sparc */ + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDThread { + _PR_CONTEXT_TYPE context; + int errcode; + int id; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +extern PRStatus _MD_WAIT(struct PRThread *, PRIntervalTime timeout); +extern PRStatus _MD_WAKEUP_WAITER(struct PRThread *); +extern void _MD_YIELD(void); +extern PRStatus _MD_InitializeThread(PRThread *thread); +extern void _MD_SET_PRIORITY(struct _MDThread *thread, + PRThreadPriority newPri); +extern PRStatus _MD_CREATE_THREAD(PRThread *thread, void (*start) (void *), + PRThreadPriority priority, PRThreadScope scope, PRThreadState state, + PRUint32 stackSize); + +/* The following defines the unwrapped versions of select() and poll(). */ +extern int _select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout); +#define _MD_SELECT _select + +#include +#include +#define _MD_POLL _poll +extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); + +PR_BEGIN_EXTERN_C + +/* +** Missing function prototypes +*/ +extern int gethostname (char *name, int namelen); + +PR_END_EXTERN_C + +#endif /* _PR_PTHREADS */ + +extern void _MD_solaris_map_sendfile_error(int err); + +#endif /* nspr_solaris_defs_h___ */ + diff -Nru nspr-4.9.5/nspr/pr/include/md/_symbian.cfg nspr-4.10.7/nspr/pr/include/md/_symbian.cfg --- nspr-4.9.5/nspr/pr/include/md/_symbian.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_symbian.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef SYMBIAN +#define SYMBIAN +#endif + +#define PR_AF_INET6 0x0806 /* same as AF_INET6 */ + +#ifdef __arm__ + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_DOUBLE 8 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__WINS__) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_DOUBLE 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else + +#error "Unknown CPU architecture" + +#endif + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#if PR_ALIGN_OF_DOUBLE == 8 +#define HAVE_ALIGNED_DOUBLES +#endif +#if PR_ALIGN_OF_INT64 == 8 +#define HAVE_ALIGNED_LONGLONGS +#endif + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_symbian.h nspr-4.10.7/nspr/pr/include/md/_symbian.h --- nspr-4.9.5/nspr/pr/include/md/_symbian.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_symbian.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_symbian_defs_h___ +#define nspr_symbian_defs_h___ + +#include "prthread.h" + +/* + * Internal configuration macros + */ + +#define _PR_SI_SYSNAME "SYMBIAN" +#if defined(__WINS__) +#define _PR_SI_ARCHITECTURE "i386" +#elif defined(__arm__) +#define _PR_SI_ARCHITECTURE "arm" +#else +#error "Unknown CPU architecture" +#endif +#define PR_DLL_SUFFIX ".dll" + +#undef HAVE_STACK_GROWING_UP + +#ifdef DYNAMIC_LIBRARY +#define HAVE_DLL +#define USE_DLFCN +#endif + +#define _PR_STAT_HAS_ONLY_ST_ATIME +#define _PR_NO_LARGE_FILES +#define _PR_HAVE_SYSV_SEMAPHORES +#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY + +#ifndef _PR_PTHREADS +#error "Classic NSPR is not implemented" +#endif + +extern void _MD_EarlyInit(void); + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INTERVAL_USE_GTOD + +/* For writev() */ +#include + +#endif /* nspr_symbian_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_unix_errors.h nspr-4.10.7/nspr/pr/include/md/_unix_errors.h --- nspr-4.9.5/nspr/pr/include/md/_unix_errors.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_unix_errors.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prunixerrors_h___ +#define prunixerrors_h___ + +#include +#include + +PR_BEGIN_EXTERN_C + +extern void _MD_unix_map_default_error(int err); +#define _PR_MD_MAP_DEFAULT_ERROR _MD_unix_map_default_error + +extern void _MD_unix_map_opendir_error(int err); +#define _PR_MD_MAP_OPENDIR_ERROR _MD_unix_map_opendir_error + +extern void _MD_unix_map_closedir_error(int err); +#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_unix_map_closedir_error + +extern void _MD_unix_readdir_error(int err); +#define _PR_MD_MAP_READDIR_ERROR _MD_unix_readdir_error + +extern void _MD_unix_map_unlink_error(int err); +#define _PR_MD_MAP_UNLINK_ERROR _MD_unix_map_unlink_error + +extern void _MD_unix_map_stat_error(int err); +#define _PR_MD_MAP_STAT_ERROR _MD_unix_map_stat_error + +extern void _MD_unix_map_fstat_error(int err); +#define _PR_MD_MAP_FSTAT_ERROR _MD_unix_map_fstat_error + +extern void _MD_unix_map_rename_error(int err); +#define _PR_MD_MAP_RENAME_ERROR _MD_unix_map_rename_error + +extern void _MD_unix_map_access_error(int err); +#define _PR_MD_MAP_ACCESS_ERROR _MD_unix_map_access_error + +extern void _MD_unix_map_mkdir_error(int err); +#define _PR_MD_MAP_MKDIR_ERROR _MD_unix_map_mkdir_error + +extern void _MD_unix_map_rmdir_error(int err); +#define _PR_MD_MAP_RMDIR_ERROR _MD_unix_map_rmdir_error + +extern void _MD_unix_map_read_error(int err); +#define _PR_MD_MAP_READ_ERROR _MD_unix_map_read_error + +extern void _MD_unix_map_write_error(int err); +#define _PR_MD_MAP_WRITE_ERROR _MD_unix_map_write_error + +extern void _MD_unix_map_lseek_error(int err); +#define _PR_MD_MAP_LSEEK_ERROR _MD_unix_map_lseek_error + +extern void _MD_unix_map_fsync_error(int err); +#define _PR_MD_MAP_FSYNC_ERROR _MD_unix_map_fsync_error + +extern void _MD_unix_map_close_error(int err); +#define _PR_MD_MAP_CLOSE_ERROR _MD_unix_map_close_error + +extern void _MD_unix_map_socket_error(int err); +#define _PR_MD_MAP_SOCKET_ERROR _MD_unix_map_socket_error + +extern void _MD_unix_map_socketavailable_error(int err); +#define _PR_MD_MAP_SOCKETAVAILABLE_ERROR _MD_unix_map_socketavailable_error + +extern void _MD_unix_map_recv_error(int err); +#define _PR_MD_MAP_RECV_ERROR _MD_unix_map_recv_error + +extern void _MD_unix_map_recvfrom_error(int err); +#define _PR_MD_MAP_RECVFROM_ERROR _MD_unix_map_recvfrom_error + +extern void _MD_unix_map_send_error(int err); +#define _PR_MD_MAP_SEND_ERROR _MD_unix_map_send_error + +extern void _MD_unix_map_sendto_error(int err); +#define _PR_MD_MAP_SENDTO_ERROR _MD_unix_map_sendto_error + +extern void _MD_unix_map_writev_error(int err); +#define _PR_MD_MAP_WRITEV_ERROR _MD_unix_map_writev_error + +extern void _MD_unix_map_accept_error(int err); +#define _PR_MD_MAP_ACCEPT_ERROR _MD_unix_map_accept_error + +extern void _MD_unix_map_connect_error(int err); +#define _PR_MD_MAP_CONNECT_ERROR _MD_unix_map_connect_error + +extern void _MD_unix_map_bind_error(int err); +#define _PR_MD_MAP_BIND_ERROR _MD_unix_map_bind_error + +extern void _MD_unix_map_listen_error(int err); +#define _PR_MD_MAP_LISTEN_ERROR _MD_unix_map_listen_error + +extern void _MD_unix_map_shutdown_error(int err); +#define _PR_MD_MAP_SHUTDOWN_ERROR _MD_unix_map_shutdown_error + +extern void _MD_unix_map_socketpair_error(int err); +#define _PR_MD_MAP_SOCKETPAIR_ERROR _MD_unix_map_socketpair_error + +extern void _MD_unix_map_getsockname_error(int err); +#define _PR_MD_MAP_GETSOCKNAME_ERROR _MD_unix_map_getsockname_error + +extern void _MD_unix_map_getpeername_error(int err); +#define _PR_MD_MAP_GETPEERNAME_ERROR _MD_unix_map_getpeername_error + +extern void _MD_unix_map_getsockopt_error(int err); +#define _PR_MD_MAP_GETSOCKOPT_ERROR _MD_unix_map_getsockopt_error + +extern void _MD_unix_map_setsockopt_error(int err); +#define _PR_MD_MAP_SETSOCKOPT_ERROR _MD_unix_map_setsockopt_error + +extern void _MD_unix_map_open_error(int err); +#define _PR_MD_MAP_OPEN_ERROR _MD_unix_map_open_error + +extern void _MD_unix_map_mmap_error(int err); +#define _PR_MD_MAP_MMAP_ERROR _MD_unix_map_mmap_error + +extern void _MD_unix_map_gethostname_error(int err); +#define _PR_MD_MAP_GETHOSTNAME_ERROR _MD_unix_map_gethostname_error + +extern void _MD_unix_map_select_error(int err); +#define _PR_MD_MAP_SELECT_ERROR _MD_unix_map_select_error + +extern void _MD_unix_map_poll_error(int err); +#define _PR_MD_MAP_POLL_ERROR _MD_unix_map_poll_error + +extern void _MD_unix_map_poll_revents_error(int err); +#define _PR_MD_MAP_POLL_REVENTS_ERROR _MD_unix_map_poll_revents_error + +extern void _MD_unix_map_flock_error(int err); +#define _PR_MD_MAP_FLOCK_ERROR _MD_unix_map_flock_error + +extern void _MD_unix_map_lockf_error(int err); +#define _PR_MD_MAP_LOCKF_ERROR _MD_unix_map_lockf_error + +PR_END_EXTERN_C + +#endif /* prunixerrors_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_unixos.h nspr-4.10.7/nspr/pr/include/md/_unixos.h --- nspr-4.9.5/nspr/pr/include/md/_unixos.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_unixos.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,624 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prunixos_h___ +#define prunixos_h___ + +/* + * If FD_SETSIZE is not defined on the command line, set the default value + * before include select.h + */ +/* + * Linux: FD_SETSIZE is defined in /usr/include/sys/select.h and should + * not be redefined. + */ +#if !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__) \ + && !defined(DARWIN) +#ifndef FD_SETSIZE +#define FD_SETSIZE 4096 +#endif +#endif + +#include +#include +#include +#include +#include + +#include "prio.h" +#include "prmem.h" +#include "prclist.h" + +/* + * For select(), fd_set, and struct timeval. + * + * In The Single UNIX(R) Specification, Version 2, + * the header file for select() is . + * In Version 3, the header file for select() is + * changed to . + * + * fd_set is defined in . Usually + * includes , but on some + * older systems does not include + * , so we include it explicitly. + */ +#include +#include +#if defined(AIX) || defined(SYMBIAN) +#include +#endif + +#ifndef SYMBIAN +#define HAVE_NETINET_TCP_H +#endif + +#define _PR_HAVE_O_APPEND + +#define PR_DIRECTORY_SEPARATOR '/' +#define PR_DIRECTORY_SEPARATOR_STR "/" +#define PR_PATH_SEPARATOR ':' +#define PR_PATH_SEPARATOR_STR ":" +typedef int (*FARPROC)(); + +/* + * intervals at which GLOBAL threads wakeup to check for pending interrupt + */ +#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 +extern PRIntervalTime intr_timeout_ticks; + +/* + * The bit flags for the in_flags and out_flags fields + * of _PR_UnixPollDesc + */ +#ifdef _PR_USE_POLL +#define _PR_UNIX_POLL_READ POLLIN +#define _PR_UNIX_POLL_WRITE POLLOUT +#define _PR_UNIX_POLL_EXCEPT POLLPRI +#define _PR_UNIX_POLL_ERR POLLERR +#define _PR_UNIX_POLL_NVAL POLLNVAL +#define _PR_UNIX_POLL_HUP POLLHUP +#else /* _PR_USE_POLL */ +#define _PR_UNIX_POLL_READ 0x1 +#define _PR_UNIX_POLL_WRITE 0x2 +#define _PR_UNIX_POLL_EXCEPT 0x4 +#define _PR_UNIX_POLL_ERR 0x8 +#define _PR_UNIX_POLL_NVAL 0x10 +#define _PR_UNIX_POLL_HUP 0x20 +#endif /* _PR_USE_POLL */ + +typedef struct _PRUnixPollDesc { + PRInt32 osfd; + PRInt16 in_flags; + PRInt16 out_flags; +} _PRUnixPollDesc; + +typedef struct PRPollQueue { + PRCList links; /* for linking PRPollQueue's together */ + _PRUnixPollDesc *pds; /* array of poll descriptors */ + PRUintn npds; /* length of the array */ + PRPackedBool on_ioq; /* is this on the async i/o work q? */ + PRIntervalTime timeout; /* timeout, in ticks */ + struct PRThread *thr; +} PRPollQueue; + +#define _PR_POLLQUEUE_PTR(_qp) \ + ((PRPollQueue*) ((char*) (_qp) - offsetof(PRPollQueue,links))) + + +extern PRInt32 _PR_WaitForMultipleFDs( + _PRUnixPollDesc *unixpds, + PRInt32 pdcnt, + PRIntervalTime timeout); +extern void _PR_Unblock_IO_Wait(struct PRThread *thr); + +#if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY) +#define _MD_CHECK_FOR_EXIT() +#endif + +extern fd_set _pr_md_read_set, _pr_md_write_set, _pr_md_exception_set; +extern PRInt16 _pr_md_read_cnt[], _pr_md_write_cnt[], _pr_md_exception_cnt[]; +extern PRInt32 _pr_md_ioq_max_osfd; +extern PRUint32 _pr_md_ioq_timeout; + +struct _MDFileDesc { + int osfd; +#if defined(LINUX) && defined(_PR_PTHREADS) + int tcp_nodelay; /* used by pt_LinuxSendFile */ +#endif +}; + +struct _MDDir { + DIR *d; +}; + +struct _PRCPU; +extern void _MD_unix_init_running_cpu(struct _PRCPU *cpu); + +/* +** Make a redzone at both ends of the stack segment. Disallow access +** to those pages of memory. It's ok if the mprotect call's don't +** work - it just means that we don't really have a functional +** redzone. +*/ +#include +#ifndef PROT_NONE +#define PROT_NONE 0x0 +#endif + +#if defined(DEBUG) && !defined(DARWIN) +#if !defined(SOLARIS) +#include /* for memset() */ +#define _MD_INIT_STACK(ts,REDZONE) \ + PR_BEGIN_MACRO \ + (void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE); \ + (void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\ + REDZONE, PROT_NONE); \ + /* \ + ** Fill stack memory with something that turns into an illegal \ + ** pointer value. This will sometimes find runtime references to \ + ** uninitialized pointers. We don't do this for solaris because we \ + ** can use purify instead. \ + */ \ + if (_pr_debugStacks) { \ + memset(ts->allocBase + REDZONE, 0xf7, ts->stackSize); \ + } \ + PR_END_MACRO +#else /* !SOLARIS */ +#define _MD_INIT_STACK(ts,REDZONE) \ + PR_BEGIN_MACRO \ + (void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE); \ + (void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\ + REDZONE, PROT_NONE); \ + PR_END_MACRO +#endif /* !SOLARIS */ + +/* + * _MD_CLEAR_STACK + * Allow access to the redzone pages; the access was turned off in + * _MD_INIT_STACK. + */ +#define _MD_CLEAR_STACK(ts) \ + PR_BEGIN_MACRO \ + (void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_READ|PROT_WRITE);\ + (void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\ + REDZONE, PROT_READ|PROT_WRITE); \ + PR_END_MACRO + +#else /* DEBUG */ + +#define _MD_INIT_STACK(ts,REDZONE) +#define _MD_CLEAR_STACK(ts) + +#endif /* DEBUG */ + +#if !defined(SOLARIS) + +#define PR_SET_INTSOFF(newval) + +#endif + +/************************************************************************/ + +extern void _PR_UnixInit(void); + +extern void _PR_UnixCleanup(void); +#define _MD_EARLY_CLEANUP _PR_UnixCleanup + +/************************************************************************/ + +struct _MDProcess { + pid_t pid; +}; + +struct PRProcess; +struct PRProcessAttr; + +/* Create a new process (fork() + exec()) */ +#define _MD_CREATE_PROCESS _MD_CreateUnixProcess +extern struct PRProcess * _MD_CreateUnixProcess( + const char *path, + char *const *argv, + char *const *envp, + const struct PRProcessAttr *attr +); + +#define _MD_DETACH_PROCESS _MD_DetachUnixProcess +extern PRStatus _MD_DetachUnixProcess(struct PRProcess *process); + +/* Wait for a child process to terminate */ +#define _MD_WAIT_PROCESS _MD_WaitUnixProcess +extern PRStatus _MD_WaitUnixProcess(struct PRProcess *process, + PRInt32 *exitCode); + +#define _MD_KILL_PROCESS _MD_KillUnixProcess +extern PRStatus _MD_KillUnixProcess(struct PRProcess *process); + +/************************************************************************/ + +extern void _MD_EnableClockInterrupts(void); +extern void _MD_DisableClockInterrupts(void); + +#define _MD_START_INTERRUPTS _MD_StartInterrupts +#define _MD_STOP_INTERRUPTS _MD_StopInterrupts +#define _MD_DISABLE_CLOCK_INTERRUPTS _MD_DisableClockInterrupts +#define _MD_ENABLE_CLOCK_INTERRUPTS _MD_EnableClockInterrupts +#define _MD_BLOCK_CLOCK_INTERRUPTS _MD_BlockClockInterrupts +#define _MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UnblockClockInterrupts + +/************************************************************************/ + +extern void _MD_InitCPUS(void); +#define _MD_INIT_CPUS _MD_InitCPUS + +extern void _MD_Wakeup_CPUs(void); +#define _MD_WAKEUP_CPUS _MD_Wakeup_CPUs + +#define _MD_PAUSE_CPU _MD_PauseCPU + +#if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY) +#define _MD_CLEANUP_BEFORE_EXIT() +#endif + +#ifndef IRIX +#define _MD_EXIT(status) _exit(status) +#endif + +/************************************************************************/ + +#define _MD_GET_ENV getenv +#define _MD_PUT_ENV putenv + +/************************************************************************/ + +#define _MD_INIT_FILEDESC(fd) + +extern void _MD_MakeNonblock(PRFileDesc *fd); +#define _MD_MAKE_NONBLOCK _MD_MakeNonblock + +/************************************************************************/ + +#if !defined(_PR_PTHREADS) + +extern void _MD_InitSegs(void); +extern PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, + void *vaddr); +extern void _MD_FreeSegment(PRSegment *seg); + +#define _MD_INIT_SEGS _MD_InitSegs +#define _MD_ALLOC_SEGMENT _MD_AllocSegment +#define _MD_FREE_SEGMENT _MD_FreeSegment + +#endif /* !defined(_PR_PTHREADS) */ + +/************************************************************************/ + +#ifdef _MD_INTERVAL_USE_GTOD +extern PRIntervalTime _PR_UNIX_GetInterval(void); +extern PRIntervalTime _PR_UNIX_TicksPerSecond(void); +#define _MD_INTERVAL_INIT() +#define _MD_GET_INTERVAL _PR_UNIX_GetInterval +#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond +#endif + +#ifdef HAVE_CLOCK_MONOTONIC +extern PRIntervalTime _PR_UNIX_GetInterval2(void); +extern PRIntervalTime _PR_UNIX_TicksPerSecond2(void); +#define _MD_INTERVAL_INIT() +#define _MD_GET_INTERVAL _PR_UNIX_GetInterval2 +#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond2 +#endif + +#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) +#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) + +/************************************************************************/ + +#define _MD_ERRNO() (errno) +#define _MD_GET_SOCKET_ERROR() (errno) + +/************************************************************************/ + +extern PRInt32 _MD_AvailableSocket(PRInt32 osfd); + +extern void _MD_StartInterrupts(void); +extern void _MD_StopInterrupts(void); +extern void _MD_DisableClockInterrupts(void); +extern void _MD_BlockClockInterrupts(void); +extern void _MD_UnblockClockInterrupts(void); +extern void _MD_PauseCPU(PRIntervalTime timeout); + +extern PRStatus _MD_open_dir(struct _MDDir *, const char *); +extern PRInt32 _MD_close_dir(struct _MDDir *); +extern char * _MD_read_dir(struct _MDDir *, PRIntn); +extern PRInt32 _MD_open(const char *name, PRIntn osflags, PRIntn mode); +extern PRInt32 _MD_delete(const char *name); +extern PRInt32 _MD_getfileinfo(const char *fn, PRFileInfo *info); +extern PRInt32 _MD_getfileinfo64(const char *fn, PRFileInfo64 *info); +extern PRInt32 _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info); +extern PRInt32 _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info); +extern PRInt32 _MD_rename(const char *from, const char *to); +extern PRInt32 _MD_access(const char *name, PRAccessHow how); +extern PRInt32 _MD_mkdir(const char *name, PRIntn mode); +extern PRInt32 _MD_rmdir(const char *name); +extern PRInt32 _MD_accept_read(PRInt32 sock, PRInt32 *newSock, + PRNetAddr **raddr, void *buf, PRInt32 amount); +extern PRInt32 _PR_UnixSendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout); + +extern PRStatus _MD_LockFile(PRInt32 osfd); +extern PRStatus _MD_TLockFile(PRInt32 osfd); +extern PRStatus _MD_UnlockFile(PRInt32 osfd); + +#define _MD_OPEN_DIR(dir, name) _MD_open_dir(dir, name) +#define _MD_CLOSE_DIR(dir) _MD_close_dir(dir) +#define _MD_READ_DIR(dir, flags) _MD_read_dir(dir, flags) +#define _MD_OPEN(name, osflags, mode) _MD_open(name, osflags, mode) +#define _MD_OPEN_FILE(name, osflags, mode) _MD_open(name, osflags, mode) +extern PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount); +#define _MD_READ(fd,buf,amount) _MD_read(fd,buf,amount) +extern PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount); +#define _MD_WRITE(fd,buf,amount) _MD_write(fd,buf,amount) +#define _MD_DELETE(name) _MD_delete(name) +#define _MD_GETFILEINFO(fn, info) _MD_getfileinfo(fn, info) +#define _MD_GETFILEINFO64(fn, info) _MD_getfileinfo64(fn, info) +#define _MD_GETOPENFILEINFO(fd, info) _MD_getopenfileinfo(fd, info) +#define _MD_GETOPENFILEINFO64(fd, info) _MD_getopenfileinfo64(fd, info) +#define _MD_RENAME(from, to) _MD_rename(from, to) +#define _MD_ACCESS(name, how) _MD_access(name, how) +#define _MD_MKDIR(name, mode) _MD_mkdir(name, mode) +#define _MD_MAKE_DIR(name, mode) _MD_mkdir(name, mode) +#define _MD_RMDIR(name) _MD_rmdir(name) +#define _MD_ACCEPT_READ(sock, newSock, raddr, buf, amount) _MD_accept_read(sock, newSock, raddr, buf, amount) + +#define _MD_LOCKFILE _MD_LockFile +#define _MD_TLOCKFILE _MD_TLockFile +#define _MD_UNLOCKFILE _MD_UnlockFile + + +extern PRInt32 _MD_socket(int af, int type, int flags); +#define _MD_SOCKET _MD_socket +extern PRInt32 _MD_connect(PRFileDesc *fd, const PRNetAddr *addr, + PRUint32 addrlen, PRIntervalTime timeout); +#define _MD_CONNECT _MD_connect +extern PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, + PRIntervalTime timeout); +#define _MD_ACCEPT _MD_accept +extern PRInt32 _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen); +#define _MD_BIND _MD_bind +extern PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog); +#define _MD_LISTEN _MD_listen +extern PRInt32 _MD_shutdown(PRFileDesc *fd, PRIntn how); +#define _MD_SHUTDOWN _MD_shutdown + +extern PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout); +#define _MD_RECV _MD_recv +extern PRInt32 _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout); +#define _MD_SEND _MD_send +extern PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, + PRIntervalTime timeout); +#define _MD_RECVFROM _MD_recvfrom +extern PRInt32 _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen, + PRIntervalTime timeout); +#define _MD_SENDTO _MD_sendto +extern PRInt32 _MD_writev(PRFileDesc *fd, const struct PRIOVec *iov, + PRInt32 iov_size, PRIntervalTime timeout); +#define _MD_WRITEV _MD_writev + +extern PRInt32 _MD_socketavailable(PRFileDesc *fd); +#define _MD_SOCKETAVAILABLE _MD_socketavailable +extern PRInt64 _MD_socketavailable64(PRFileDesc *fd); +#define _MD_SOCKETAVAILABLE64 _MD_socketavailable64 + +#define _MD_PIPEAVAILABLE _MD_socketavailable + +extern PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, + PRIntervalTime timeout); +#define _MD_PR_POLL _MD_pr_poll + +extern PRInt32 _MD_close(PRInt32 osfd); +#define _MD_CLOSE_FILE _MD_close +extern PRInt32 _MD_lseek(PRFileDesc*, PRInt32, PRSeekWhence); +#define _MD_LSEEK _MD_lseek +extern PRInt64 _MD_lseek64(PRFileDesc*, PRInt64, PRSeekWhence); +#define _MD_LSEEK64 _MD_lseek64 +extern PRInt32 _MD_fsync(PRFileDesc *fd); +#define _MD_FSYNC _MD_fsync + +extern PRInt32 _MD_socketpair(int af, int type, int flags, PRInt32 *osfd); +#define _MD_SOCKETPAIR _MD_socketpair + +#define _MD_CLOSE_SOCKET _MD_close + +#ifndef NO_NSPR_10_SUPPORT +#define _MD_STAT stat +#endif + +extern PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, + PRUint32 *addrlen); +#define _MD_GETPEERNAME _MD_getpeername +extern PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, + PRUint32 *addrlen); +#define _MD_GETSOCKNAME _MD_getsockname + +extern PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, + PRInt32 optname, char* optval, PRInt32* optlen); +#define _MD_GETSOCKOPT _MD_getsockopt +extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, + PRInt32 optname, const char* optval, PRInt32 optlen); +#define _MD_SETSOCKOPT _MD_setsockopt + +extern PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable); +#define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable + +extern void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported); +#define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable + +extern void _MD_query_fd_inheritable(PRFileDesc *fd); +#define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable + +extern PRStatus _MD_gethostname(char *name, PRUint32 namelen); +#define _MD_GETHOSTNAME _MD_gethostname + +extern PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen); +#define _MD_GETSYSINFO _MD_getsysinfo + +extern int _MD_unix_get_nonblocking_connect_error(int osfd); + +/* Memory-mapped files */ + +struct _MDFileMap { + PRIntn prot; + PRIntn flags; + PRBool isAnonFM; /* when true, PR_CloseFileMap() must close the related fd */ +}; + +extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); +#define _MD_CREATE_FILE_MAP _MD_CreateFileMap + +#define _MD_GET_MEM_MAP_ALIGNMENT() PR_GetPageSize() + +extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, + PRUint32 len); +#define _MD_MEM_MAP _MD_MemMap + +extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); +#define _MD_MEM_UNMAP _MD_MemUnmap + +extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); +#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap + +extern PRStatus _MD_SyncMemMap( + PRFileDesc *fd, + void *addr, + PRUint32 len); +#define _MD_SYNC_MEM_MAP _MD_SyncMemMap + +/* + * The standard (XPG4) gettimeofday() (from BSD) takes two arguments. + * On some SVR4 derivatives, gettimeofday() takes only one argument. + * The GETTIMEOFDAY macro is intended to hide this difference. + */ +#ifdef HAVE_SVID_GETTOD +#define GETTIMEOFDAY(tp) gettimeofday(tp) +#else +#define GETTIMEOFDAY(tp) gettimeofday((tp), NULL) +#endif + +#if defined(_PR_PTHREADS) && !defined(_PR_POLL_AVAILABLE) +#define _PR_NEED_FAKE_POLL +#endif + +#if defined(_PR_NEED_FAKE_POLL) + +/* + * Some platforms don't have poll(), but our pthreads code calls poll(). + * As a temporary measure, I implemented a fake poll() using select(). + * Here are the struct and macro definitions copied from sys/poll.h + * on Solaris 2.5. + */ + +struct pollfd { + int fd; + short events; + short revents; +}; + +/* poll events */ + +#define POLLIN 0x0001 /* fd is readable */ +#define POLLPRI 0x0002 /* high priority info at fd */ +#define POLLOUT 0x0004 /* fd is writeable (won't block) */ +#define POLLRDNORM 0x0040 /* normal data is readable */ +#define POLLWRNORM POLLOUT +#define POLLRDBAND 0x0080 /* out-of-band data is readable */ +#define POLLWRBAND 0x0100 /* out-of-band data is writeable */ + +#define POLLNORM POLLRDNORM + +#define POLLERR 0x0008 /* fd has error condition */ +#define POLLHUP 0x0010 /* fd has been hung up on */ +#define POLLNVAL 0x0020 /* invalid pollfd entry */ + +extern int poll(struct pollfd *, unsigned long, int); + +#endif /* _PR_NEED_FAKE_POLL */ + +/* +** A vector of the UNIX I/O calls we use. These are here to smooth over +** the rough edges needed for large files. All of NSPR's implmentaions +** go through this vector using syntax of the form +** result = _md_iovector.xxx64(args); +*/ + +#if defined(SOLARIS2_5) +/* +** Special case: Solaris 2.5.1 +** Solaris starts to have 64-bit file I/O in 2.6. We build on Solaris +** 2.5.1 so that we can use the same binaries on both Solaris 2.5.1 and +** 2.6. At run time, we detect whether 64-bit file I/O is available by +** looking up the 64-bit file function symbols in libc. At build time, +** we need to define the 64-bit file I/O datatypes that are compatible +** with their definitions on Solaris 2.6. +*/ +typedef PRInt64 off64_t; +typedef PRUint64 ino64_t; +typedef PRInt64 blkcnt64_t; +struct stat64 { + dev_t st_dev; + long st_pad1[3]; + ino64_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + long t_pad2[2]; + off64_t st_size; + timestruc_t st_atim; + timestruc_t st_mtim; + timestruc_t st_ctim; + long st_blksize; + blkcnt64_t st_blocks; + char st_fstype[_ST_FSTYPSZ]; + long st_pad4[8]; +}; +typedef struct stat64 _MDStat64; +typedef off64_t _MDOff64_t; + +#elif defined(_PR_HAVE_OFF64_T) +typedef struct stat64 _MDStat64; +typedef off64_t _MDOff64_t; +#elif defined(_PR_HAVE_LARGE_OFF_T) +typedef struct stat _MDStat64; +typedef off_t _MDOff64_t; +#elif defined(_PR_NO_LARGE_FILES) +typedef struct stat _MDStat64; +typedef PRInt64 _MDOff64_t; +#else +#error "I don't know yet" +#endif + +typedef PRIntn (*_MD_Fstat64)(PRIntn osfd, _MDStat64 *buf); +typedef PRIntn (*_MD_Open64)(const char *path, int oflag, ...); +typedef PRIntn (*_MD_Stat64)(const char *path, _MDStat64 *buf); +typedef _MDOff64_t (*_MD_Lseek64)(PRIntn osfd, _MDOff64_t, PRIntn whence); +typedef void* (*_MD_Mmap64)( + void *addr, PRSize len, PRIntn prot, PRIntn flags, + PRIntn fildes, _MDOff64_t offset); +struct _MD_IOVector +{ + _MD_Open64 _open64; + _MD_Mmap64 _mmap64; + _MD_Stat64 _stat64; + _MD_Fstat64 _fstat64; + _MD_Lseek64 _lseek64; +}; +extern struct _MD_IOVector _md_iovector; + +#endif /* prunixos_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_unixware7.cfg nspr-4.10.7/nspr/pr/include/md/_unixware7.cfg --- nspr-4.9.5/nspr/pr/include/md/_unixware7.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_unixware7.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef UNIXWARE +#define UNIXWARE +#endif + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_AF_INET6 27 /* same as AF_INET6 */ + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#define _PR_POLL_BACKCOMPAT + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_unixware.cfg nspr-4.10.7/nspr/pr/include/md/_unixware.cfg --- nspr-4.9.5/nspr/pr/include/md/_unixware.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_unixware.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_UNIX +#define XP_UNIX +#endif + +#ifndef UNIXWARE +#define UNIXWARE +#endif + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#undef HAVE_LONG_LONG +#undef HAVE_ALIGNED_DOUBLES +#undef HAVE_ALIGNED_LONGLONGS + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 4 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#define _PR_POLL_BACKCOMPAT + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_unixware.h nspr-4.10.7/nspr/pr/include/md/_unixware.h --- nspr-4.9.5/nspr/pr/include/md/_unixware.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_unixware.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,186 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_unixware_defs_h___ +#define nspr_unixware_defs_h___ + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "unixware" +#define _PR_SI_SYSNAME "UnixWare" +#define _PR_SI_ARCHITECTURE "x86" +#define PR_DLL_SUFFIX ".so" + +#define _PR_VMBASE 0x30000000 +#define _PR_STACK_VMBASE 0x50000000 +#define _MD_DEFAULT_STACK_SIZE 65536L +#define _MD_MMAP_FLAGS MAP_PRIVATE + +#ifndef HAVE_WEAK_IO_SYMBOLS +#define HAVE_WEAK_IO_SYMBOLS +#endif +#define _PR_POLL_AVAILABLE +#define _PR_USE_POLL +#define _PR_STAT_HAS_ST_ATIM_UNION + +#undef HAVE_STACK_GROWING_UP +#define HAVE_NETCONFIG +#define HAVE_DLL +#define USE_DLFCN +#define HAVE_STRERROR +#define NEED_STRFTIME_LOCK +#define NEED_TIME_R +#define _PR_NEED_STRCASECMP + +#define USE_SETJMP + +#include + +#define _SETJMP setjmp +#define _LONGJMP longjmp +#define _PR_CONTEXT_TYPE jmp_buf +#define _MD_GET_SP(_t) (_t)->md.context[4] +#define _PR_NUM_GCREGS _JBLEN + +#define CONTEXT(_th) ((_th)->md.context) + +/* +** Initialize the thread context preparing it to execute _main. +*/ +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ +{ \ + *status = PR_TRUE; \ + if(_SETJMP(CONTEXT(_thread))) (*_main)(); \ + _MD_GET_SP(_thread) = (int) ((_sp) - 128); \ +} + +#define _MD_SWITCH_CONTEXT(_thread) \ + if (!_SETJMP(CONTEXT(_thread))) { \ + (_thread)->md.errcode = errno; \ + _PR_Schedule(); \ + } + +/* +** Restore a thread context, saved by _MD_SWITCH_CONTEXT +*/ +#define _MD_RESTORE_CONTEXT(_thread) \ +{ \ + errno = (_thread)->md.errcode; \ + _MD_SET_CURRENT_THREAD(_thread); \ + _LONGJMP(CONTEXT(_thread), 1); \ +} + +/* Machine-dependent (MD) data structures. + * Don't use SVR4 native threads (yet). + */ + +struct _MDThread { + _PR_CONTEXT_TYPE context; + int id; + int errcode; +}; + +struct _MDThreadStack { + PRInt8 notused; +}; + +struct _MDLock { + PRInt8 notused; +}; + +struct _MDSemaphore { + PRInt8 notused; +}; + +struct _MDCVar { + PRInt8 notused; +}; + +struct _MDSegment { + PRInt8 notused; +}; + +/* + * md-specific cpu structure field + */ +#define _PR_MD_MAX_OSFD FD_SETSIZE + +struct _MDCPU_Unix { + PRCList ioQ; + PRUint32 ioq_timeout; + PRInt32 ioq_max_osfd; + PRInt32 ioq_osfd_cnt; +#ifndef _PR_USE_POLL + fd_set fd_read_set, fd_write_set, fd_exception_set; + PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], + fd_exception_cnt[_PR_MD_MAX_OSFD]; +#else + struct pollfd *ioq_pollfds; + int ioq_pollfds_size; +#endif /* _PR_USE_POLL */ +}; + +#define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) +#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) +#define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) +#define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) +#define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) +#define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) +#define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) +#define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) +#define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) +#define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) +#define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) +#define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) +#define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) + +#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 + +struct _MDCPU { + struct _MDCPU_Unix md_unix; +}; + +#define _MD_INIT_LOCKS() +#define _MD_NEW_LOCK(lock) PR_SUCCESS +#define _MD_FREE_LOCK(lock) +#define _MD_LOCK(lock) +#define _MD_UNLOCK(lock) +#define _MD_INIT_IO() +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + +/* + * The following are copied from _sunos.h, _aix.h. This means + * some of them should probably be moved into _unixos.h. But + * _irix.h seems to be quite different in regard to these macros. + */ +#define _MD_INTERVAL_USE_GTOD + +#define _MD_EARLY_INIT _MD_EarlyInit +#define _MD_FINAL_INIT _PR_UnixInit +#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) +#define _MD_INIT_THREAD _MD_InitializeThread +#define _MD_EXIT_THREAD(thread) +#define _MD_SUSPEND_THREAD(thread) +#define _MD_RESUME_THREAD(thread) +#define _MD_CLEAN_THREAD(_thread) + +/* + * We wrapped the select() call. _MD_SELECT refers to the built-in, + * unwrapped version. + */ +#include +#include +#include +extern int _select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *execptfds, struct timeval *timeout); +#define _MD_SELECT _select + +#define _MD_POLL _poll +extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout); + +#endif /* nspr_unixware_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_win32_errors.h nspr-4.10.7/nspr/pr/include/md/_win32_errors.h --- nspr-4.9.5/nspr/pr/include/md/_win32_errors.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_win32_errors.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,122 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_win32_errors_h___ +#define nspr_win32_errors_h___ + +#include +#include +#include + + +extern void _MD_win32_map_default_error(PRInt32 err); +#define _PR_MD_MAP_DEFAULT_ERROR _MD_win32_map_default_error + +extern void _MD_win32_map_opendir_error(PRInt32 err); +#define _PR_MD_MAP_OPENDIR_ERROR _MD_win32_map_opendir_error + +extern void _MD_win32_map_closedir_error(PRInt32 err); +#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_win32_map_closedir_error + +extern void _MD_unix_readdir_error(PRInt32 err); +#define _PR_MD_MAP_READDIR_ERROR _MD_unix_readdir_error + +extern void _MD_win32_map_delete_error(PRInt32 err); +#define _PR_MD_MAP_DELETE_ERROR _MD_win32_map_delete_error + +extern void _MD_win32_map_stat_error(PRInt32 err); +#define _PR_MD_MAP_STAT_ERROR _MD_win32_map_stat_error + +extern void _MD_win32_map_fstat_error(PRInt32 err); +#define _PR_MD_MAP_FSTAT_ERROR _MD_win32_map_fstat_error + +extern void _MD_win32_map_rename_error(PRInt32 err); +#define _PR_MD_MAP_RENAME_ERROR _MD_win32_map_rename_error + +extern void _MD_win32_map_access_error(PRInt32 err); +#define _PR_MD_MAP_ACCESS_ERROR _MD_win32_map_access_error + +extern void _MD_win32_map_mkdir_error(PRInt32 err); +#define _PR_MD_MAP_MKDIR_ERROR _MD_win32_map_mkdir_error + +extern void _MD_win32_map_rmdir_error(PRInt32 err); +#define _PR_MD_MAP_RMDIR_ERROR _MD_win32_map_rmdir_error + +extern void _MD_win32_map_read_error(PRInt32 err); +#define _PR_MD_MAP_READ_ERROR _MD_win32_map_read_error + +extern void _MD_win32_map_transmitfile_error(PRInt32 err); +#define _PR_MD_MAP_TRANSMITFILE_ERROR _MD_win32_map_transmitfile_error + +extern void _MD_win32_map_write_error(PRInt32 err); +#define _PR_MD_MAP_WRITE_ERROR _MD_win32_map_write_error + +extern void _MD_win32_map_lseek_error(PRInt32 err); +#define _PR_MD_MAP_LSEEK_ERROR _MD_win32_map_lseek_error + +extern void _MD_win32_map_fsync_error(PRInt32 err); +#define _PR_MD_MAP_FSYNC_ERROR _MD_win32_map_fsync_error + +extern void _MD_win32_map_close_error(PRInt32 err); +#define _PR_MD_MAP_CLOSE_ERROR _MD_win32_map_close_error + +extern void _MD_win32_map_socket_error(PRInt32 err); +#define _PR_MD_MAP_SOCKET_ERROR _MD_win32_map_socket_error + +extern void _MD_win32_map_recv_error(PRInt32 err); +#define _PR_MD_MAP_RECV_ERROR _MD_win32_map_recv_error + +extern void _MD_win32_map_recvfrom_error(PRInt32 err); +#define _PR_MD_MAP_RECVFROM_ERROR _MD_win32_map_recvfrom_error + +extern void _MD_win32_map_send_error(PRInt32 err); +#define _PR_MD_MAP_SEND_ERROR _MD_win32_map_send_error + +extern void _MD_win32_map_sendto_error(PRInt32 err); +#define _PR_MD_MAP_SENDTO_ERROR _MD_win32_map_sendto_error + +extern void _MD_win32_map_accept_error(PRInt32 err); +#define _PR_MD_MAP_ACCEPT_ERROR _MD_win32_map_accept_error + +extern void _MD_win32_map_acceptex_error(PRInt32 err); +#define _PR_MD_MAP_ACCEPTEX_ERROR _MD_win32_map_acceptex_error + +extern PRInt32 _MD_win32_map_connect_error(PRInt32 err); +#define _PR_MD_MAP_CONNECT_ERROR _MD_win32_map_connect_error + +extern void _MD_win32_map_bind_error(PRInt32 err); +#define _PR_MD_MAP_BIND_ERROR _MD_win32_map_bind_error + +extern void _MD_win32_map_listen_error(PRInt32 err); +#define _PR_MD_MAP_LISTEN_ERROR _MD_win32_map_listen_error + +extern void _MD_win32_map_shutdown_error(PRInt32 err); +#define _PR_MD_MAP_SHUTDOWN_ERROR _MD_win32_map_shutdown_error + +extern void _MD_win32_map_getsockname_error(PRInt32 err); +#define _PR_MD_MAP_GETSOCKNAME_ERROR _MD_win32_map_getsockname_error + +extern void _MD_win32_map_getpeername_error(PRInt32 err); +#define _PR_MD_MAP_GETPEERNAME_ERROR _MD_win32_map_getpeername_error + +extern void _MD_win32_map_getsockopt_error(PRInt32 err); +#define _PR_MD_MAP_GETSOCKOPT_ERROR _MD_win32_map_getsockopt_error + +extern void _MD_win32_map_setsockopt_error(PRInt32 err); +#define _PR_MD_MAP_SETSOCKOPT_ERROR _MD_win32_map_setsockopt_error + +extern void _MD_win32_map_open_error(PRInt32 err); +#define _PR_MD_MAP_OPEN_ERROR _MD_win32_map_open_error + +extern void _MD_win32_map_gethostname_error(PRInt32 err); +#define _PR_MD_MAP_GETHOSTNAME_ERROR _MD_win32_map_gethostname_error + +extern void _MD_win32_map_select_error(PRInt32 err); +#define _PR_MD_MAP_SELECT_ERROR _MD_win32_map_select_error + +extern void _MD_win32_map_lockf_error(int err); +#define _PR_MD_MAP_LOCKF_ERROR _MD_win32_map_lockf_error + +#endif /* nspr_win32_errors_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_win95.cfg nspr-4.10.7/nspr/pr/include/md/_win95.cfg --- nspr-4.9.5/nspr/pr/include/md/_win95.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_win95.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,272 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_PC +#define XP_PC +#endif + +#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 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 32 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 5 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 4 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 64 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 6 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 8 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(_M_IA64) || defined(_IA64_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 64 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 6 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 8 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(_M_ARM) || defined(_ARM_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 32 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 5 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 4 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else /* defined(_M_IX86) || defined(_X86_) */ + +#error unknown processor architecture + +#endif /* defined(_M_IX86) || defined(_X86_) */ + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_win95.h nspr-4.10.7/nspr/pr/include/md/_win95.h --- nspr-4.9.5/nspr/pr/include/md/_win95.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_win95.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,544 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_win95_defs_h___ +#define nspr_win95_defs_h___ + +#include "prio.h" + +#include +#include +#include + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "win32" +#define _PR_SI_SYSNAME "WIN95" +#if defined(_M_IX86) || defined(_X86_) +#define _PR_SI_ARCHITECTURE "x86" +#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) +#define _PR_SI_ARCHITECTURE "x86-64" +#elif defined(_M_IA64) || defined(_IA64_) +#define _PR_SI_ARCHITECTURE "ia64" +#elif defined(_M_ARM) || defined(_ARM_) +#define _PR_SI_ARCHITECTURE "arm" +#else +#error unknown processor architecture +#endif + +#define HAVE_DLL +#undef HAVE_THREAD_AFFINITY +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE +#ifndef _PR_INET6 +#define AF_INET6 23 +/* newer ws2tcpip.h provides these */ +#ifndef AI_CANONNAME +#define AI_CANONNAME 0x2 +#define AI_NUMERICHOST 0x4 +#define NI_NUMERICHOST 0x02 +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + char *ai_canonname; + struct sockaddr *ai_addr; + struct addrinfo *ai_next; +}; +#endif +#define _PR_HAVE_MD_SOCKADDR_IN6 +/* isomorphic to struct in6_addr on Windows */ +struct _md_in6_addr { + union { + PRUint8 _S6_u8[16]; + PRUint16 _S6_u16[8]; + } _S6_un; +}; +/* isomorphic to struct sockaddr_in6 on Windows */ +struct _md_sockaddr_in6 { + PRInt16 sin6_family; + PRUint16 sin6_port; + PRUint32 sin6_flowinfo; + struct _md_in6_addr sin6_addr; + PRUint32 sin6_scope_id; +}; +#endif +#define _PR_HAVE_THREADSAFE_GETHOST +#define _PR_HAVE_ATOMIC_OPS +#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY + +/* --- Common User-Thread/Native-Thread Definitions --------------------- */ + +/* --- Globals --- */ +extern struct PRLock *_pr_schedLock; + +/* --- Typedefs --- */ +typedef void (*FiberFunc)(void *); + +#define PR_NUM_GCREGS 8 +typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS]; +#define GC_VMBASE 0x40000000 +#define GC_VMLIMIT 0x00FFFFFF + +#define _MD_MAGIC_THREAD 0x22222222 +#define _MD_MAGIC_THREADSTACK 0x33333333 +#define _MD_MAGIC_SEGMENT 0x44444444 +#define _MD_MAGIC_DIR 0x55555555 +#define _MD_MAGIC_CV 0x66666666 + +struct _MDCPU { + int unused; +}; + +struct _MDThread { + HANDLE blocked_sema; /* Threads block on this when waiting + * for IO or CondVar. + */ + PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the + * wait queue of some cond var. + * PR_FALSE otherwise. */ + HANDLE handle; /* Win32 thread handle */ + PRUint32 id; + void *sp; /* only valid when suspended */ + PRUint32 magic; /* for debugging */ + PR_CONTEXT_TYPE gcContext; /* Thread context for GC */ + struct PRThread *prev, *next; /* used by the cvar wait queue to + * chain the PRThread structures + * together */ + void (*start)(void *); /* used by _PR_MD_CREATE_THREAD to + * pass its 'start' argument to + * pr_root. */ +}; + +struct _MDThreadStack { + PRUint32 magic; /* for debugging */ +}; + +struct _MDSegment { + PRUint32 magic; /* for debugging */ +}; + +#undef PROFILE_LOCKS + +struct _MDDir { + HANDLE d_hdl; + WIN32_FIND_DATAA d_entry; + PRBool firstEntry; /* Is this the entry returned + * by FindFirstFile()? */ + PRUint32 magic; /* for debugging */ +}; + +#ifdef MOZ_UNICODE +struct _MDDirUTF16 { + HANDLE d_hdl; + WIN32_FIND_DATAW d_entry; + PRBool firstEntry; /* Is this the entry returned + * by FindFirstFileW()? */ + PRUint32 magic; /* for debugging */ +}; +#endif /* MOZ_UNICODE */ + +struct _MDCVar { + PRUint32 magic; + struct PRThread *waitHead, *waitTail; /* the wait queue: a doubly- + * linked list of threads + * waiting on this condition + * variable */ + PRIntn nwait; /* number of threads in the + * wait queue */ +}; + +#define _MD_CV_NOTIFIED_LENGTH 6 +typedef struct _MDNotified _MDNotified; +struct _MDNotified { + PRIntn length; /* # of used entries in this + * structure */ + struct { + struct _MDCVar *cv; /* the condition variable notified */ + PRIntn times; /* and the number of times notified */ + struct PRThread *notifyHead; /* list of threads to wake up */ + } cv[_MD_CV_NOTIFIED_LENGTH]; + _MDNotified *link; /* link to another of these, or NULL */ +}; + +struct _MDLock { + CRITICAL_SECTION mutex; /* this is recursive on NT */ + + /* + * When notifying cvars, there is no point in actually + * waking up the threads waiting on the cvars until we've + * released the lock. So, we temporarily record the cvars. + * When doing an unlock, we'll then wake up the waiting threads. + */ + struct _MDNotified notified; /* array of conditions notified */ +#ifdef PROFILE_LOCKS + PRInt32 hitcount; + PRInt32 misscount; +#endif +}; + +struct _MDSemaphore { + HANDLE sem; +}; + +struct _MDFileDesc { + PROsfd osfd; /* The osfd can come from one of three spaces: + * - For stdin, stdout, and stderr, we are using + * the libc file handle (0, 1, 2), which is an int. + * - For files and pipes, we are using Win32 HANDLE, + * which is a void*. + * - For sockets, we are using Winsock SOCKET, which + * is a u_int. + */ +}; + +struct _MDProcess { + HANDLE handle; + DWORD id; +}; + +/* --- Misc stuff --- */ +#define _MD_GET_SP(thread) (thread)->md.gcContext[6] + +/* --- NT security stuff --- */ + +extern void _PR_NT_InitSids(void); +extern void _PR_NT_FreeSids(void); +extern PRStatus _PR_NT_MakeSecurityDescriptorACL( + PRIntn mode, + DWORD accessTable[], + PSECURITY_DESCRIPTOR *resultSD, + PACL *resultACL +); +extern void _PR_NT_FreeSecurityDescriptorACL( + PSECURITY_DESCRIPTOR pSD, PACL pACL); + +/* --- IO stuff --- */ + +#define _MD_OPEN _PR_MD_OPEN +#define _MD_OPEN_FILE _PR_MD_OPEN_FILE +#define _MD_READ _PR_MD_READ +#define _MD_WRITE _PR_MD_WRITE +#define _MD_WRITEV _PR_MD_WRITEV +#define _MD_LSEEK _PR_MD_LSEEK +#define _MD_LSEEK64 _PR_MD_LSEEK64 +extern PRInt32 _MD_CloseFile(PROsfd osfd); +#define _MD_CLOSE_FILE _MD_CloseFile +#define _MD_GETFILEINFO _PR_MD_GETFILEINFO +#define _MD_GETFILEINFO64 _PR_MD_GETFILEINFO64 +#define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO +#define _MD_GETOPENFILEINFO64 _PR_MD_GETOPENFILEINFO64 +#define _MD_STAT _PR_MD_STAT +#define _MD_RENAME _PR_MD_RENAME +#define _MD_ACCESS _PR_MD_ACCESS +#define _MD_DELETE _PR_MD_DELETE +#define _MD_MKDIR _PR_MD_MKDIR +#define _MD_MAKE_DIR _PR_MD_MAKE_DIR +#define _MD_RMDIR _PR_MD_RMDIR +#define _MD_LOCKFILE _PR_MD_LOCKFILE +#define _MD_TLOCKFILE _PR_MD_TLOCKFILE +#define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE + +/* --- UTF16 IO stuff --- */ +#ifdef MOZ_UNICODE +#define _MD_OPEN_FILE_UTF16 _PR_MD_OPEN_FILE_UTF16 +#define _MD_OPEN_DIR_UTF16 _PR_MD_OPEN_DIR_UTF16 +#define _MD_READ_DIR_UTF16 _PR_MD_READ_DIR_UTF16 +#define _MD_CLOSE_DIR_UTF16 _PR_MD_CLOSE_DIR_UTF16 +#define _MD_GETFILEINFO64_UTF16 _PR_MD_GETFILEINFO64_UTF16 +#endif /* MOZ_UNICODE */ + +/* --- Socket IO stuff --- */ +extern void _PR_MD_InitSockets(void); +extern void _PR_MD_CleanupSockets(void); +#define _MD_EACCES WSAEACCES +#define _MD_EADDRINUSE WSAEADDRINUSE +#define _MD_EADDRNOTAVAIL WSAEADDRNOTAVAIL +#define _MD_EAFNOSUPPORT WSAEAFNOSUPPORT +#define _MD_EAGAIN WSAEWOULDBLOCK +#define _MD_EALREADY WSAEALREADY +#define _MD_EBADF WSAEBADF +#define _MD_ECONNREFUSED WSAECONNREFUSED +#define _MD_ECONNRESET WSAECONNRESET +#define _MD_EFAULT WSAEFAULT +#define _MD_EINPROGRESS WSAEINPROGRESS +#define _MD_EINTR WSAEINTR +#define _MD_EINVAL EINVAL +#define _MD_EISCONN WSAEISCONN +#define _MD_ENETUNREACH WSAENETUNREACH +#define _MD_ENOENT ENOENT +#define _MD_ENOTCONN WSAENOTCONN +#define _MD_ENOTSOCK WSAENOTSOCK +#define _MD_EOPNOTSUPP WSAEOPNOTSUPP +#define _MD_EWOULDBLOCK WSAEWOULDBLOCK +#define _MD_GET_SOCKET_ERROR() WSAGetLastError() +#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err) + +#define _MD_INIT_FILEDESC(fd) +extern void _MD_MakeNonblock(PRFileDesc *f); +#define _MD_MAKE_NONBLOCK _MD_MakeNonblock +#define _MD_INIT_FD_INHERITABLE _PR_MD_INIT_FD_INHERITABLE +#define _MD_QUERY_FD_INHERITABLE _PR_MD_QUERY_FD_INHERITABLE +#define _MD_SHUTDOWN _PR_MD_SHUTDOWN +#define _MD_LISTEN _PR_MD_LISTEN +extern PRInt32 _MD_CloseSocket(PROsfd osfd); +#define _MD_CLOSE_SOCKET _MD_CloseSocket +#define _MD_SENDTO _PR_MD_SENDTO +#define _MD_RECVFROM _PR_MD_RECVFROM +#define _MD_SOCKETPAIR(s, type, proto, sv) -1 +#define _MD_GETSOCKNAME _PR_MD_GETSOCKNAME +#define _MD_GETPEERNAME _PR_MD_GETPEERNAME +#define _MD_GETSOCKOPT _PR_MD_GETSOCKOPT +#define _MD_SETSOCKOPT _PR_MD_SETSOCKOPT +#define _MD_SET_FD_INHERITABLE _PR_MD_SET_FD_INHERITABLE +#define _MD_SELECT select +#define _MD_FSYNC _PR_MD_FSYNC +#define READ_FD 1 +#define WRITE_FD 2 + +#define _MD_INIT_ATOMIC() +#if defined(_M_IX86) || defined(_X86_) +#define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT +#define _MD_ATOMIC_ADD _PR_MD_ATOMIC_ADD +#define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT +#else /* non-x86 processors */ +#define _MD_ATOMIC_INCREMENT(x) InterlockedIncrement((PLONG)x) +#define _MD_ATOMIC_ADD(ptr,val) (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val) +#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x) +#endif /* x86 */ +#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y) + +#define _MD_INIT_IO _PR_MD_INIT_IO + + +/* win95 doesn't have async IO */ +#define _MD_SOCKET _PR_MD_SOCKET +extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd); +#define _MD_SOCKETAVAILABLE _MD_SocketAvailable +#define _MD_PIPEAVAILABLE _PR_MD_PIPEAVAILABLE +#define _MD_CONNECT _PR_MD_CONNECT +extern PROsfd _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, + PRIntervalTime timeout); +#define _MD_ACCEPT _MD_Accept +#define _MD_BIND _PR_MD_BIND +#define _MD_RECV _PR_MD_RECV +#define _MD_SEND _PR_MD_SEND +#define _MD_PR_POLL _PR_MD_PR_POLL + +/* --- Scheduler stuff --- */ +// #define _MD_PAUSE_CPU _PR_MD_PAUSE_CPU +#define _MD_PAUSE_CPU + +/* --- DIR stuff --- */ +#define PR_DIRECTORY_SEPARATOR '\\' +#define PR_DIRECTORY_SEPARATOR_STR "\\" +#define PR_PATH_SEPARATOR ';' +#define PR_PATH_SEPARATOR_STR ";" +#define _MD_ERRNO() GetLastError() +#define _MD_OPEN_DIR _PR_MD_OPEN_DIR +#define _MD_CLOSE_DIR _PR_MD_CLOSE_DIR +#define _MD_READ_DIR _PR_MD_READ_DIR + +/* --- Segment stuff --- */ +#define _MD_INIT_SEGS() +#define _MD_ALLOC_SEGMENT(seg, size, vaddr) 0 +#define _MD_FREE_SEGMENT(seg) + +/* --- Environment Stuff --- */ +#define _MD_GET_ENV _PR_MD_GET_ENV +#define _MD_PUT_ENV _PR_MD_PUT_ENV + +/* --- Threading Stuff --- */ +#define _MD_DEFAULT_STACK_SIZE 0 +#define _MD_INIT_THREAD _PR_MD_INIT_THREAD +#define _MD_INIT_ATTACHED_THREAD _PR_MD_INIT_THREAD +#define _MD_CREATE_THREAD _PR_MD_CREATE_THREAD +#define _MD_YIELD _PR_MD_YIELD +#define _MD_SET_PRIORITY _PR_MD_SET_PRIORITY +#define _MD_SET_CURRENT_THREAD_NAME _PR_MD_SET_CURRENT_THREAD_NAME +#define _MD_CLEAN_THREAD _PR_MD_CLEAN_THREAD +#define _MD_SETTHREADAFFINITYMASK _PR_MD_SETTHREADAFFINITYMASK +#define _MD_GETTHREADAFFINITYMASK _PR_MD_GETTHREADAFFINITYMASK +#define _MD_EXIT_THREAD _PR_MD_EXIT_THREAD +#define _MD_EXIT _PR_MD_EXIT +#define _MD_SUSPEND_THREAD _PR_MD_SUSPEND_THREAD +#define _MD_RESUME_THREAD _PR_MD_RESUME_THREAD +#define _MD_SUSPEND_CPU _PR_MD_SUSPEND_CPU +#define _MD_RESUME_CPU _PR_MD_RESUME_CPU +#define _MD_BEGIN_SUSPEND_ALL() +#define _MD_BEGIN_RESUME_ALL() +#define _MD_END_SUSPEND_ALL() +#define _MD_END_RESUME_ALL() + +/* --- Lock stuff --- */ +#define _PR_LOCK _MD_LOCK +#define _PR_UNLOCK _MD_UNLOCK + +#define _MD_NEW_LOCK _PR_MD_NEW_LOCK +#define _MD_FREE_LOCK(lock) DeleteCriticalSection(&((lock)->mutex)) +#define _MD_LOCK(lock) EnterCriticalSection(&((lock)->mutex)) +#define _MD_TEST_AND_LOCK(lock) (EnterCriticalSection(&((lock)->mutex)),0) +#define _MD_UNLOCK _PR_MD_UNLOCK + +/* --- lock and cv waiting --- */ +#define _MD_WAIT _PR_MD_WAIT +#define _MD_WAKEUP_WAITER _PR_MD_WAKEUP_WAITER + +/* --- CVar ------------------- */ +#define _MD_WAIT_CV _PR_MD_WAIT_CV +#define _MD_NEW_CV _PR_MD_NEW_CV +#define _MD_FREE_CV _PR_MD_FREE_CV +#define _MD_NOTIFY_CV _PR_MD_NOTIFY_CV +#define _MD_NOTIFYALL_CV _PR_MD_NOTIFYALL_CV + + /* XXXMB- the IOQ stuff is certainly not working correctly yet. */ +// extern struct _MDLock _pr_ioq_lock; +#define _MD_IOQ_LOCK() +#define _MD_IOQ_UNLOCK() + + +/* --- Initialization stuff --- */ +#define _MD_START_INTERRUPTS() +#define _MD_STOP_INTERRUPTS() +#define _MD_DISABLE_CLOCK_INTERRUPTS() +#define _MD_ENABLE_CLOCK_INTERRUPTS() +#define _MD_BLOCK_CLOCK_INTERRUPTS() +#define _MD_UNBLOCK_CLOCK_INTERRUPTS() +#define _MD_EARLY_INIT _PR_MD_EARLY_INIT +#define _MD_FINAL_INIT() +#define _MD_EARLY_CLEANUP() +#define _MD_INIT_CPUS() +#define _MD_INIT_RUNNING_CPU(cpu) + +struct PRProcess; +struct PRProcessAttr; + +#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess +extern struct PRProcess * _PR_CreateWindowsProcess( + const char *path, + char *const *argv, + char *const *envp, + const struct PRProcessAttr *attr +); + +#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess +extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process); + +/* --- Wait for a child process to terminate --- */ +#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess +extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, + PRInt32 *exitCode); + +#define _MD_KILL_PROCESS _PR_KillWindowsProcess +extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process); + +#define _MD_CLEANUP_BEFORE_EXIT _PR_MD_CLEANUP_BEFORE_EXIT +#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ + PR_BEGIN_MACRO \ + *status = PR_TRUE; \ + PR_END_MACRO +#define _MD_SWITCH_CONTEXT +#define _MD_RESTORE_CONTEXT + +/* --- Intervals --- */ +#define _MD_INTERVAL_INIT _PR_MD_INTERVAL_INIT +#define _MD_GET_INTERVAL _PR_MD_GET_INTERVAL +#define _MD_INTERVAL_PER_SEC _PR_MD_INTERVAL_PER_SEC +#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) +#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) + +/* --- Time --- */ +extern void _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm); + +#ifdef WINCE +extern void _MD_InitTime(void); +extern void _MD_CleanupTime(void); +#endif + +/* --- Native-Thread Specific Definitions ------------------------------- */ + +extern struct PRThread * _MD_CURRENT_THREAD(void); + +#ifdef _PR_USE_STATIC_TLS +extern __declspec(thread) struct PRThread *_pr_currentThread; +#define _MD_GET_ATTACHED_THREAD() _pr_currentThread +#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread)) + +extern __declspec(thread) struct PRThread *_pr_thread_last_run; +#define _MD_LAST_THREAD() _pr_thread_last_run +#define _MD_SET_LAST_THREAD(_thread) (_pr_thread_last_run = 0) + +extern __declspec(thread) struct _PRCPU *_pr_currentCPU; +#define _MD_CURRENT_CPU() _pr_currentCPU +#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = 0) +#else /* _PR_USE_STATIC_TLS */ +extern DWORD _pr_currentThreadIndex; +#define _MD_GET_ATTACHED_THREAD() ((PRThread *) TlsGetValue(_pr_currentThreadIndex)) +#define _MD_SET_CURRENT_THREAD(_thread) TlsSetValue(_pr_currentThreadIndex, (_thread)) + +extern DWORD _pr_lastThreadIndex; +#define _MD_LAST_THREAD() ((PRThread *) TlsGetValue(_pr_lastThreadIndex)) +#define _MD_SET_LAST_THREAD(_thread) TlsSetValue(_pr_lastThreadIndex, 0) + +extern DWORD _pr_currentCPUIndex; +#define _MD_CURRENT_CPU() ((struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex)) +#define _MD_SET_CURRENT_CPU(_cpu) TlsSetValue(_pr_currentCPUIndex, 0) +#endif /* _PR_USE_STATIC_TLS */ + +/* --- Scheduler stuff --- */ +#define LOCK_SCHEDULER() 0 +#define UNLOCK_SCHEDULER() 0 +#define _PR_LockSched() 0 +#define _PR_UnlockSched() 0 + +/* --- Initialization stuff --- */ +#define _MD_INIT_LOCKS _PR_MD_INIT_LOCKS + +/* --- Stack stuff --- */ +#define _MD_INIT_STACK(stack, redzone) +#define _MD_CLEAR_STACK(stack) + +/* --- Memory-mapped files stuff --- */ + +struct _MDFileMap { + HANDLE hFileMap; + DWORD dwAccess; +}; + +extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); +#define _MD_CREATE_FILE_MAP _MD_CreateFileMap + +extern PRInt32 _MD_GetMemMapAlignment(void); +#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment + +extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, + PRUint32 len); +#define _MD_MEM_MAP _MD_MemMap + +extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); +#define _MD_MEM_UNMAP _MD_MemUnmap + +extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); +#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap + +extern PRStatus _MD_SyncMemMap( + PRFileDesc *fd, + void *addr, + PRUint32 len); +#define _MD_SYNC_MEM_MAP _MD_SyncMemMap + +/* --- Named semaphores stuff --- */ +#define _PR_HAVE_NAMED_SEMAPHORES +#define _MD_OPEN_SEMAPHORE _PR_MD_OPEN_SEMAPHORE +#define _MD_WAIT_SEMAPHORE _PR_MD_WAIT_SEMAPHORE +#define _MD_POST_SEMAPHORE _PR_MD_POST_SEMAPHORE +#define _MD_CLOSE_SEMAPHORE _PR_MD_CLOSE_SEMAPHORE +#define _MD_DELETE_SEMAPHORE(name) PR_SUCCESS /* no op */ + +#endif /* nspr_win32_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_winnt.cfg nspr-4.10.7/nspr/pr/include/md/_winnt.cfg --- nspr-4.9.5/nspr/pr/include/md/_winnt.cfg 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_winnt.cfg 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,224 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nspr_cpucfg___ +#define nspr_cpucfg___ + +#ifndef XP_PC +#define XP_PC +#endif + +#ifndef WIN32 +#define WIN32 +#endif + +#ifndef WINNT +#define WINNT +#endif + +#define PR_AF_INET6 23 /* same as AF_INET6 */ + +#if defined(_M_IX86) || defined(_X86_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 32 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 5 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 4 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 4 +#define PR_ALIGN_OF_POINTER 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 2 + +#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 64 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 6 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 8 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(_M_IA64) || defined(_IA64_) + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 +#define PR_BYTES_PER_DOUBLE 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_WORD 64 +#define PR_BITS_PER_DWORD 64 +#define PR_BITS_PER_DOUBLE 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_WORD_LOG2 6 +#define PR_BITS_PER_DWORD_LOG2 6 +#define PR_BITS_PER_DOUBLE_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_WORD 8 +#define PR_ALIGN_OF_DWORD 8 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#else /* defined(_M_IX86) || defined(_X86_) */ + +#error unknown processor architecture + +#endif /* defined(_M_IX86) || defined(_X86_) */ + +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif + +#ifndef NO_NSPR_10_SUPPORT + +#define BYTES_PER_BYTE PR_BYTES_PER_BYTE +#define BYTES_PER_SHORT PR_BYTES_PER_SHORT +#define BYTES_PER_INT PR_BYTES_PER_INT +#define BYTES_PER_INT64 PR_BYTES_PER_INT64 +#define BYTES_PER_LONG PR_BYTES_PER_LONG +#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT +#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE +#define BYTES_PER_WORD PR_BYTES_PER_WORD +#define BYTES_PER_DWORD PR_BYTES_PER_DWORD + +#define BITS_PER_BYTE PR_BITS_PER_BYTE +#define BITS_PER_SHORT PR_BITS_PER_SHORT +#define BITS_PER_INT PR_BITS_PER_INT +#define BITS_PER_INT64 PR_BITS_PER_INT64 +#define BITS_PER_LONG PR_BITS_PER_LONG +#define BITS_PER_FLOAT PR_BITS_PER_FLOAT +#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE +#define BITS_PER_WORD PR_BITS_PER_WORD + +#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 +#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 +#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 +#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 +#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 +#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 +#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 +#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 + +#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT +#define ALIGN_OF_INT PR_ALIGN_OF_INT +#define ALIGN_OF_LONG PR_ALIGN_OF_LONG +#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 +#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT +#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE +#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER +#define ALIGN_OF_WORD PR_ALIGN_OF_WORD + +#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 +#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 +#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 + +#endif /* NO_NSPR_10_SUPPORT */ + +#endif /* nspr_cpucfg___ */ diff -Nru nspr-4.9.5/nspr/pr/include/md/_winnt.h nspr-4.10.7/nspr/pr/include/md/_winnt.h --- nspr-4.9.5/nspr/pr/include/md/_winnt.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/md/_winnt.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,599 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_win32_defs_h___ +#define nspr_win32_defs_h___ + +/* Need to force service-pack 3 extensions to be defined by +** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h. +*/ +#ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0400 +#elif (_WIN32_WINNT < 0x0400) + #undef _WIN32_WINNT + #define _WIN32_WINNT 0x0400 +#endif /* _WIN32_WINNT */ + +#include +#include +#ifdef __MINGW32__ +#include +#endif +#include + +#include "prio.h" +#include "prclist.h" + +/* + * Internal configuration macros + */ + +#define PR_LINKER_ARCH "win32" +#define _PR_SI_SYSNAME "WINNT" +#if defined(_M_IX86) || defined(_X86_) +#define _PR_SI_ARCHITECTURE "x86" +#elif defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) +#define _PR_SI_ARCHITECTURE "x86-64" +#elif defined(_M_IA64) || defined(_IA64_) +#define _PR_SI_ARCHITECTURE "ia64" +#else +#error unknown processor architecture +#endif + +#define HAVE_DLL +#define HAVE_CUSTOM_USER_THREADS +#define HAVE_THREAD_AFFINITY +#define _PR_HAVE_GETADDRINFO +#define _PR_INET6_PROBE +#ifndef _PR_INET6 +#define AF_INET6 23 +/* newer ws2tcpip.h provides these */ +#ifndef AI_CANONNAME +#define AI_CANONNAME 0x2 +#define AI_NUMERICHOST 0x4 +#define NI_NUMERICHOST 0x02 +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + char *ai_canonname; + struct sockaddr *ai_addr; + struct addrinfo *ai_next; +}; +#endif +#define _PR_HAVE_MD_SOCKADDR_IN6 +/* isomorphic to struct in6_addr on Windows */ +struct _md_in6_addr { + union { + PRUint8 _S6_u8[16]; + PRUint16 _S6_u16[8]; + } _S6_un; +}; +/* isomorphic to struct sockaddr_in6 on Windows */ +struct _md_sockaddr_in6 { + PRInt16 sin6_family; + PRUint16 sin6_port; + PRUint32 sin6_flowinfo; + struct _md_in6_addr sin6_addr; + PRUint32 sin6_scope_id; +}; +#endif +#define _PR_HAVE_THREADSAFE_GETHOST +#define _PR_HAVE_ATOMIC_OPS +#if defined(_M_IX86) || defined(_X86_) +#define _PR_HAVE_ATOMIC_CAS +#endif +#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY +#define _PR_HAVE_PEEK_BUFFER +#define _PR_PEEK_BUFFER_MAX (32 * 1024) +#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) \ + (!(fd)->secret->nonblocking && (fd)->secret->inheritable != _PR_TRI_TRUE) +#define _PR_NEED_SECRET_AF + +/* --- Common User-Thread/Native-Thread Definitions --------------------- */ + +/* --- Globals --- */ +extern struct PRLock *_pr_schedLock; + +/* --- Typedefs --- */ +typedef void (*FiberFunc)(void *); + +#define PR_NUM_GCREGS 8 +typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS]; +#define GC_VMBASE 0x40000000 +#define GC_VMLIMIT 0x00FFFFFF + +#define _MD_MAGIC_THREAD 0x22222222 +#define _MD_MAGIC_THREADSTACK 0x33333333 +#define _MD_MAGIC_SEGMENT 0x44444444 +#define _MD_MAGIC_DIR 0x55555555 + +struct _MDCPU { + int unused; +}; + +enum _MDIOModel { + _MD_BlockingIO = 0x38, + _MD_MultiWaitIO = 0x49 +}; + +typedef struct _MDOverlapped { + OVERLAPPED overlapped; /* Used for async I/O */ + + enum _MDIOModel ioModel; /* The I/O model to implement + * using overlapped I/O. + */ + union { + struct _MDThread *mdThread; /* For blocking I/O, this structure + * is embedded in the _MDThread + * structure. + */ + struct { + PRCList links; /* for group->io_ready list */ + struct PRRecvWait *desc; /* For multiwait I/O, this structure + * is associated with a PRRecvWait + * structure. + */ + struct PRWaitGroup *group; + struct TimerEvent *timer; + DWORD error; + } mw; + } data; +} _MDOverlapped; + +struct _MDThread { + /* The overlapped structure must be first! */ + struct _MDOverlapped overlapped; /* Used for async IO for this thread */ + void *acceptex_buf; /* Used for AcceptEx() */ + TRANSMIT_FILE_BUFFERS *xmit_bufs; /* Used for TransmitFile() */ + HANDLE blocked_sema; /* Threads block on this when waiting + * for IO or CondVar. + */ + PRInt32 blocked_io_status; /* Status of the completed IO */ + PRInt32 blocked_io_bytes; /* Bytes transferred for completed IO */ + PRInt32 blocked_io_error; /* Save error if status is FALSE */ + HANDLE handle; + PRUint32 id; + void *sp; /* only valid when suspended */ + PRUint32 magic; /* for debugging */ + PR_CONTEXT_TYPE gcContext; /* Thread context for GC */ + struct _PRCPU *thr_bound_cpu; /* thread bound to cpu */ + PRBool interrupt_disabled;/* thread cannot be interrupted */ + HANDLE thr_event; /* For native-threads-only support, + thread blocks on this event */ + + /* The following are used only if this is a fiber */ + void *fiber_id; /* flag whether or not this is a fiber*/ + FiberFunc fiber_fn; /* main fiber routine */ + void *fiber_arg; /* arg to main fiber routine */ + PRUint32 fiber_stacksize; /* stacksize for fiber */ + PRInt32 fiber_last_error; /* last error for the fiber */ + void (*start)(void *); /* used by _PR_MD_CREATE_THREAD to + * pass its 'start' argument to + * pr_root. */ +}; + +struct _MDThreadStack { + PRUint32 magic; /* for debugging */ +}; + +struct _MDSegment { + PRUint32 magic; /* for debugging */ +}; + +#undef PROFILE_LOCKS + +struct _MDLock { + CRITICAL_SECTION mutex; /* this is recursive on NT */ +#ifdef PROFILE_LOCKS + PRInt32 hitcount; + PRInt32 misscount; +#endif +}; + +struct _MDDir { + HANDLE d_hdl; + WIN32_FIND_DATA d_entry; + PRBool firstEntry; /* Is this the entry returned + * by FindFirstFile()? */ + PRUint32 magic; /* for debugging */ +}; + +struct _MDCVar { + PRUint32 unused; +}; + +struct _MDSemaphore { + HANDLE sem; +}; + +struct _MDFileDesc { + PROsfd osfd; /* The osfd can come from one of three spaces: + * - For stdin, stdout, and stderr, we are using + * the libc file handle (0, 1, 2), which is an int. + * - For files and pipes, we are using Win32 HANDLE, + * which is a void*. + * - For sockets, we are using Winsock SOCKET, which + * is a u_int. + */ + PRBool io_model_committed; /* The io model (blocking or nonblocking) + * for this osfd has been committed and + * cannot be changed. The osfd has been + * either associated with the io + * completion port or made nonblocking. */ + PRBool sync_file_io; /* Use synchronous file I/O on the osfd + * (a file handle) */ + PRBool accepted_socket; /* Is this an accepted socket (on the + * server side)? */ + PRNetAddr peer_addr; /* If this is an accepted socket, cache + * the peer's address returned by + * AcceptEx(). This is to work around + * the bug that getpeername() on an + * socket accepted by AcceptEx() returns + * an all-zero net address. */ +}; + +struct _MDProcess { + HANDLE handle; + DWORD id; +}; + + +/* --- Misc stuff --- */ +#define _MD_GET_SP(thread) (thread)->md.gcContext[6] + +/* --- NT security stuff --- */ + +extern void _PR_NT_InitSids(void); +extern void _PR_NT_FreeSids(void); +extern PRStatus _PR_NT_MakeSecurityDescriptorACL( + PRIntn mode, + DWORD accessTable[], + PSECURITY_DESCRIPTOR *resultSD, + PACL *resultACL +); +extern void _PR_NT_FreeSecurityDescriptorACL( + PSECURITY_DESCRIPTOR pSD, PACL pACL); + +/* --- IO stuff --- */ + +extern PRInt32 _md_Associate(HANDLE); +extern PRInt32 _PR_MD_CLOSE(PROsfd osfd, PRBool socket); + +#define _MD_OPEN _PR_MD_OPEN +#define _MD_OPEN_FILE _PR_MD_OPEN_FILE +#define _MD_READ _PR_MD_READ +#define _MD_WRITE _PR_MD_WRITE +#define _MD_WRITEV _PR_MD_WRITEV +#define _MD_LSEEK _PR_MD_LSEEK +#define _MD_LSEEK64 _PR_MD_LSEEK64 +#define _MD_CLOSE_FILE(f) _PR_MD_CLOSE(f, PR_FALSE) +#define _MD_GETFILEINFO _PR_MD_GETFILEINFO +#define _MD_GETFILEINFO64 _PR_MD_GETFILEINFO64 +#define _MD_GETOPENFILEINFO _PR_MD_GETOPENFILEINFO +#define _MD_GETOPENFILEINFO64 _PR_MD_GETOPENFILEINFO64 +#define _MD_STAT _PR_MD_STAT +#define _MD_RENAME _PR_MD_RENAME +#define _MD_ACCESS _PR_MD_ACCESS +#define _MD_DELETE _PR_MD_DELETE +#define _MD_MKDIR _PR_MD_MKDIR +#define _MD_MAKE_DIR _PR_MD_MAKE_DIR +#define _MD_RMDIR _PR_MD_RMDIR +#define _MD_LOCKFILE _PR_MD_LOCKFILE +#define _MD_TLOCKFILE _PR_MD_TLOCKFILE +#define _MD_UNLOCKFILE _PR_MD_UNLOCKFILE + +/* --- Socket IO stuff --- */ +#define _MD_GET_SOCKET_ERROR() WSAGetLastError() +#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err) + +#define _MD_INIT_FILEDESC(fd) +#define _MD_MAKE_NONBLOCK _PR_MD_MAKE_NONBLOCK +#define _MD_INIT_FD_INHERITABLE _PR_MD_INIT_FD_INHERITABLE +#define _MD_QUERY_FD_INHERITABLE _PR_MD_QUERY_FD_INHERITABLE +#define _MD_SHUTDOWN _PR_MD_SHUTDOWN +#define _MD_LISTEN _PR_MD_LISTEN +#define _MD_CLOSE_SOCKET(s) _PR_MD_CLOSE(s, PR_TRUE) +#define _MD_SENDTO _PR_MD_SENDTO +#define _MD_RECVFROM _PR_MD_RECVFROM +#define _MD_SOCKETPAIR(s, type, proto, sv) -1 +#define _MD_GETSOCKNAME _PR_MD_GETSOCKNAME +#define _MD_GETPEERNAME _PR_MD_GETPEERNAME +#define _MD_GETSOCKOPT _PR_MD_GETSOCKOPT +#define _MD_SETSOCKOPT _PR_MD_SETSOCKOPT +#define _MD_SELECT select +extern int _PR_NTFiberSafeSelect(int, fd_set *, fd_set *, fd_set *, + const struct timeval *); +#define _MD_FSYNC _PR_MD_FSYNC +#define _MD_SOCKETAVAILABLE _PR_MD_SOCKETAVAILABLE +#define _MD_PIPEAVAILABLE _PR_MD_PIPEAVAILABLE +#define _MD_SET_FD_INHERITABLE _PR_MD_SET_FD_INHERITABLE + +#define _MD_INIT_ATOMIC() +#if defined(_M_IX86) || defined(_X86_) +#define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT +#define _MD_ATOMIC_ADD _PR_MD_ATOMIC_ADD +#define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT +#else /* non-x86 processors */ +#define _MD_ATOMIC_INCREMENT(x) InterlockedIncrement((PLONG)x) +#define _MD_ATOMIC_ADD(ptr,val) (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val) +#define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x) +#endif /* x86 */ +#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y) + +#define _MD_INIT_IO _PR_MD_INIT_IO +#define _MD_SOCKET _PR_MD_SOCKET +#define _MD_CONNECT _PR_MD_CONNECT + +#define _MD_ACCEPT(s, a, l, to) \ + _MD_FAST_ACCEPT(s, a, l, to, PR_FALSE, NULL, NULL) +#define _MD_FAST_ACCEPT(s, a, l, to, fast, cb, cba) \ + _PR_MD_FAST_ACCEPT(s, a, l, to, fast, cb, cba) +#define _MD_ACCEPT_READ(s, ns, ra, buf, l, t) \ + _MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, PR_FALSE, NULL, NULL) +#define _MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, fast, cb, cba) \ + _PR_MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, fast, cb, cba) +#define _MD_UPDATE_ACCEPT_CONTEXT _PR_MD_UPDATE_ACCEPT_CONTEXT + +#define _MD_BIND _PR_MD_BIND +#define _MD_RECV _PR_MD_RECV +#define _MD_SEND _PR_MD_SEND +#define _MD_SENDFILE _PR_MD_SENDFILE +#define _MD_PR_POLL _PR_MD_PR_POLL + +/* --- Scheduler stuff --- */ +#define _MD_PAUSE_CPU _PR_MD_PAUSE_CPU + +/* --- DIR stuff --- */ +#define PR_DIRECTORY_SEPARATOR '\\' +#define PR_DIRECTORY_SEPARATOR_STR "\\" +#define PR_PATH_SEPARATOR ';' +#define PR_PATH_SEPARATOR_STR ";" +#define _MD_ERRNO() GetLastError() +#define _MD_OPEN_DIR _PR_MD_OPEN_DIR +#define _MD_CLOSE_DIR _PR_MD_CLOSE_DIR +#define _MD_READ_DIR _PR_MD_READ_DIR + +/* --- Segment stuff --- */ +#define _MD_INIT_SEGS() +#define _MD_ALLOC_SEGMENT(seg, size, vaddr) 0 +#define _MD_FREE_SEGMENT(seg) + +/* --- Environment Stuff --- */ +#define _MD_GET_ENV _PR_MD_GET_ENV +#define _MD_PUT_ENV _PR_MD_PUT_ENV + +/* --- Threading Stuff --- */ +#define _MD_DEFAULT_STACK_SIZE 0 +#define _MD_INIT_THREAD _PR_MD_INIT_THREAD +#define _MD_INIT_ATTACHED_THREAD _PR_MD_INIT_THREAD +#define _MD_CREATE_THREAD _PR_MD_CREATE_THREAD +#define _MD_JOIN_THREAD _PR_MD_JOIN_THREAD +#define _MD_END_THREAD _PR_MD_END_THREAD +#define _MD_YIELD _PR_MD_YIELD +#define _MD_SET_PRIORITY _PR_MD_SET_PRIORITY +#define _MD_SET_CURRENT_THREAD_NAME _PR_MD_SET_CURRENT_THREAD_NAME +#define _MD_CLEAN_THREAD _PR_MD_CLEAN_THREAD +#define _MD_SETTHREADAFFINITYMASK _PR_MD_SETTHREADAFFINITYMASK +#define _MD_GETTHREADAFFINITYMASK _PR_MD_GETTHREADAFFINITYMASK +#define _MD_EXIT_THREAD _PR_MD_EXIT_THREAD +#define _MD_SUSPEND_THREAD _PR_MD_SUSPEND_THREAD +#define _MD_RESUME_THREAD _PR_MD_RESUME_THREAD +#define _MD_SUSPEND_CPU _PR_MD_SUSPEND_CPU +#define _MD_RESUME_CPU _PR_MD_RESUME_CPU +#define _MD_BEGIN_SUSPEND_ALL() +#define _MD_BEGIN_RESUME_ALL() +#define _MD_END_SUSPEND_ALL() +#define _MD_END_RESUME_ALL() + +extern void _PR_Unblock_IO_Wait(PRThread *thr); + +/* --- Lock stuff --- */ +#define _MD_NEW_LOCK(lock) (InitializeCriticalSection(&((lock)->mutex)),PR_SUCCESS) +#define _MD_FREE_LOCK(lock) DeleteCriticalSection(&((lock)->mutex)) +#ifndef PROFILE_LOCKS +#define _MD_LOCK(lock) EnterCriticalSection(&((lock)->mutex)) +#define _MD_TEST_AND_LOCK(lock) (TryEnterCriticalSection(&((lock)->mutex))== FALSE) +#define _MD_UNLOCK(lock) LeaveCriticalSection(&((lock)->mutex)) +#else +#define _MD_LOCK(lock) \ + PR_BEGIN_MACRO \ + BOOL rv = TryEnterCriticalSection(&((lock)->mutex)); \ + if (rv == TRUE) { \ + InterlockedIncrement(&((lock)->hitcount)); \ + } else { \ + InterlockedIncrement(&((lock)->misscount)); \ + EnterCriticalSection(&((lock)->mutex)); \ + } \ + PR_END_MACRO +#define _MD_TEST_AND_LOCK(lock) 0 /* XXXMB */ +#define _MD_UNLOCK(lock) LeaveCriticalSection(&((lock)->mutex)) +#endif +#define _PR_LOCK _MD_LOCK +#define _PR_UNLOCK _MD_UNLOCK + +/* --- lock and cv waiting --- */ +#define _MD_WAIT _PR_MD_WAIT +#define _MD_WAKEUP_WAITER _PR_MD_WAKEUP_WAITER + + /* XXXMB- the IOQ stuff is certainly not working correctly yet. */ +extern struct _MDLock _pr_ioq_lock; +#define _MD_IOQ_LOCK() _MD_LOCK(&_pr_ioq_lock) +#define _MD_IOQ_UNLOCK() _MD_UNLOCK(&_pr_ioq_lock) + + +/* --- Initialization stuff --- */ +#define _MD_START_INTERRUPTS() +#define _MD_STOP_INTERRUPTS() +#define _MD_DISABLE_CLOCK_INTERRUPTS() +#define _MD_ENABLE_CLOCK_INTERRUPTS() +#define _MD_BLOCK_CLOCK_INTERRUPTS() +#define _MD_UNBLOCK_CLOCK_INTERRUPTS() +#define _MD_EARLY_INIT _PR_MD_EARLY_INIT +#define _MD_FINAL_INIT() +#define _MD_EARLY_CLEANUP() +#define _MD_INIT_CPUS() +#define _MD_INIT_RUNNING_CPU(cpu) + +struct PRProcess; +struct PRProcessAttr; + +/* --- Create a new process --- */ +#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess +extern struct PRProcess * _PR_CreateWindowsProcess( + const char *path, + char *const *argv, + char *const *envp, + const struct PRProcessAttr *attr +); + +#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess +extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process); + +/* --- Wait for a child process to terminate --- */ +#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess +extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, + PRInt32 *exitCode); + +#define _MD_KILL_PROCESS _PR_KillWindowsProcess +extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process); + +/* --- User Threading stuff --- */ +#define HAVE_FIBERS +#define _MD_CREATE_USER_THREAD _PR_MD_CREATE_USER_THREAD +#define _MD_CREATE_PRIMORDIAL_USER_THREAD _PR_MD_CREATE_PRIMORDIAL_USER_THREAD +#define _MD_CLEANUP_BEFORE_EXIT _PR_MD_CLEANUP_BEFORE_EXIT +#define _MD_EXIT _PR_MD_EXIT +#define _MD_INIT_CONTEXT _PR_MD_INIT_CONTEXT +#define _MD_SWITCH_CONTEXT _PR_MD_SWITCH_CONTEXT +#define _MD_RESTORE_CONTEXT _PR_MD_RESTORE_CONTEXT + +/* --- Intervals --- */ +#define _MD_INTERVAL_INIT _PR_MD_INTERVAL_INIT +#define _MD_GET_INTERVAL _PR_MD_GET_INTERVAL +#define _MD_INTERVAL_PER_SEC _PR_MD_INTERVAL_PER_SEC +#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) +#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) + +/* --- Time --- */ +extern void _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm); + +/* --- Native-Thread Specific Definitions ------------------------------- */ + +extern BOOL _pr_use_static_tls; + +extern __declspec(thread) struct PRThread *_pr_current_fiber; +extern DWORD _pr_currentFiberIndex; + +#define _MD_GET_ATTACHED_THREAD() \ + (_pr_use_static_tls ? _pr_current_fiber \ + : (PRThread *) TlsGetValue(_pr_currentFiberIndex)) + +extern struct PRThread * _MD_CURRENT_THREAD(void); + +#define _MD_SET_CURRENT_THREAD(_thread) \ + PR_BEGIN_MACRO \ + if (_pr_use_static_tls) { \ + _pr_current_fiber = (_thread); \ + } else { \ + TlsSetValue(_pr_currentFiberIndex, (_thread)); \ + } \ + PR_END_MACRO + +extern __declspec(thread) struct PRThread *_pr_fiber_last_run; +extern DWORD _pr_lastFiberIndex; + +#define _MD_LAST_THREAD() \ + (_pr_use_static_tls ? _pr_fiber_last_run \ + : (PRThread *) TlsGetValue(_pr_lastFiberIndex)) + +#define _MD_SET_LAST_THREAD(_thread) \ + PR_BEGIN_MACRO \ + if (_pr_use_static_tls) { \ + _pr_fiber_last_run = (_thread); \ + } else { \ + TlsSetValue(_pr_lastFiberIndex, (_thread)); \ + } \ + PR_END_MACRO + +extern __declspec(thread) struct _PRCPU *_pr_current_cpu; +extern DWORD _pr_currentCPUIndex; + +#define _MD_CURRENT_CPU() \ + (_pr_use_static_tls ? _pr_current_cpu \ + : (struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex)) + +#define _MD_SET_CURRENT_CPU(_cpu) \ + PR_BEGIN_MACRO \ + if (_pr_use_static_tls) { \ + _pr_current_cpu = (_cpu); \ + } else { \ + TlsSetValue(_pr_currentCPUIndex, (_cpu)); \ + } \ + PR_END_MACRO + +extern __declspec(thread) PRUintn _pr_ints_off; +extern DWORD _pr_intsOffIndex; + +#define _MD_GET_INTSOFF() \ + (_pr_use_static_tls ? _pr_ints_off \ + : (PRUintn) TlsGetValue(_pr_intsOffIndex)) + +#define _MD_SET_INTSOFF(_val) \ + PR_BEGIN_MACRO \ + if (_pr_use_static_tls) { \ + _pr_ints_off = (_val); \ + } else { \ + TlsSetValue(_pr_intsOffIndex, (LPVOID) (_val)); \ + } \ + PR_END_MACRO + +/* --- Initialization stuff --- */ +#define _MD_INIT_LOCKS() + +/* --- Stack stuff --- */ +#define _MD_INIT_STACK(stack, redzone) +#define _MD_CLEAR_STACK(stack) + +/* --- Memory-mapped files stuff --- */ + +struct _MDFileMap { + HANDLE hFileMap; + DWORD dwAccess; +}; + +extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); +#define _MD_CREATE_FILE_MAP _MD_CreateFileMap + +extern PRInt32 _MD_GetMemMapAlignment(void); +#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment + +extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, + PRUint32 len); +#define _MD_MEM_MAP _MD_MemMap + +extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); +#define _MD_MEM_UNMAP _MD_MemUnmap + +extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); +#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap + +extern PRStatus _MD_SyncMemMap( + PRFileDesc *fd, + void *addr, + PRUint32 len); +#define _MD_SYNC_MEM_MAP _MD_SyncMemMap + +/* --- Named semaphores stuff --- */ +#define _PR_HAVE_NAMED_SEMAPHORES +#define _MD_OPEN_SEMAPHORE _PR_MD_OPEN_SEMAPHORE +#define _MD_WAIT_SEMAPHORE _PR_MD_WAIT_SEMAPHORE +#define _MD_POST_SEMAPHORE _PR_MD_POST_SEMAPHORE +#define _MD_CLOSE_SEMAPHORE _PR_MD_CLOSE_SEMAPHORE +#define _MD_DELETE_SEMAPHORE(name) PR_SUCCESS /* no op */ + +#endif /* nspr_win32_defs_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/nspr.h nspr-4.10.7/nspr/pr/include/nspr.h --- nspr-4.9.5/nspr/pr/include/nspr.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/nspr.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nspr_h___ +#define nspr_h___ + +#include "pratom.h" +#include "prbit.h" +#include "prclist.h" +#include "prcmon.h" +#include "prcvar.h" +#include "prdtoa.h" +#include "prenv.h" +#include "prerror.h" +#include "prinet.h" +#include "prinit.h" +#include "prinrval.h" +#include "prio.h" +#include "pripcsem.h" +#include "prlink.h" +#include "prlock.h" +#include "prlog.h" +#include "prlong.h" +#include "prmem.h" +#include "prmon.h" +#include "prmwait.h" +#include "prnetdb.h" +#include "prprf.h" +#include "prproces.h" +#include "prrng.h" +#include "prrwlock.h" +#include "prshm.h" +#include "prshma.h" +#include "prsystem.h" +#include "prthread.h" +#include "prtime.h" +#include "prtpool.h" +#include "prtrace.h" +#include "prtypes.h" + +#endif /* nspr_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/obsolete/.cvsignore nspr-4.10.7/nspr/pr/include/obsolete/.cvsignore --- nspr-4.9.5/nspr/pr/include/obsolete/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/obsolete/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/include/obsolete/Makefile.in nspr-4.10.7/nspr/pr/include/obsolete/Makefile.in --- nspr-4.9.5/nspr/pr/include/obsolete/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/obsolete/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,28 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +HEADERS = $(wildcard $(srcdir)/*.h) + +RELEASE_HEADERS = $(HEADERS) +RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)/obsolete + +include_subdir = obsolete + +include $(topsrcdir)/config/rules.mk + +export:: $(RELEASE_HEADERS) + $(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)/obsolete diff -Nru nspr-4.9.5/nspr/pr/include/obsolete/pralarm.h nspr-4.10.7/nspr/pr/include/obsolete/pralarm.h --- nspr-4.9.5/nspr/pr/include/obsolete/pralarm.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/obsolete/pralarm.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,162 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: pralarm.h +** Description: API to periodic alarms. +** +** +** Alarms are defined to invoke some client specified function at +** a time in the future. The notification may be a one time event +** or repeated at a fixed interval. The interval at which the next +** notification takes place may be modified by the client code only +** during the respective notification. +** +** The notification is delivered on a thread that is part of the +** alarm context (PRAlarm). The thread will inherit the priority +** of the Alarm creator. +** +** Any number of periodic alarms (PRAlarmID) may be created within +** the context of a single alarm (PRAlarm). The notifications will be +** scheduled as close to the desired time as possible. +** +** Repeating periodic notifies are expected to run at a fixed rate. +** That rate is expressed as some number of notifies per period where +** the period is much larger than a PRIntervalTime (see prinrval.h). +*/ + +#if !defined(pralarm_h) +#define pralarm_h + +#include "prtypes.h" +#include "prinrval.h" + + +PR_BEGIN_EXTERN_C + +/**********************************************************************/ +/************************* TYPES AND CONSTANTS ************************/ +/**********************************************************************/ + +typedef struct PRAlarm PRAlarm; +typedef struct PRAlarmID PRAlarmID; + +typedef PRBool (PR_CALLBACK *PRPeriodicAlarmFn)( + PRAlarmID *id, void *clientData, PRUint32 late); + +/**********************************************************************/ +/****************************** FUNCTIONS *****************************/ +/**********************************************************************/ + +/*********************************************************************** +** FUNCTION: PR_CreateAlarm +** DESCRIPTION: +** Create an alarm context. +** INPUTS: void +** OUTPUTS: None +** RETURN: PRAlarm* +** +** SIDE EFFECTS: +** This creates an alarm context, which is an object used for subsequent +** notification creations. It also creates a thread that will be used to +** deliver the notifications that are expected to be defined. The client +** is resposible for destroying the context when appropriate. +** RESTRICTIONS: +** None. +** MEMORY: The object (PRAlarm) and a thread to support notifications. +** ALGORITHM: N/A +***********************************************************************/ +NSPR_API(PRAlarm*) PR_CreateAlarm(void); + +/*********************************************************************** +** FUNCTION: PR_DestroyAlarm +** DESCRIPTION: +** Destroys the context created by PR_CreateAlarm(). +** INPUTS: PRAlarm* +** OUTPUTS: None +** RETURN: PRStatus +** +** SIDE EFFECTS: +** This destroys the context that was created by PR_CreateAlarm(). +** If there are any active alarms (PRAlarmID), they will be cancelled. +** Once that is done, the thread that was used to deliver the alarms +** will be joined. +** RESTRICTIONS: +** None. +** MEMORY: N/A +** ALGORITHM: N/A +***********************************************************************/ +NSPR_API(PRStatus) PR_DestroyAlarm(PRAlarm *alarm); + +/*********************************************************************** +** FUNCTION: PR_SetAlarm +** DESCRIPTION: +** Creates a periodic notifier that is to be delivered to a specified +** function at some fixed interval. +** INPUTS: PRAlarm *alarm Parent alarm context +** PRIntervalTime period Interval over which the notifies +** are delivered. +** PRUint32 rate The rate within the interval that +** the notifies will be delivered. +** PRPeriodicAlarmFn function Entry point where the notifies +** will be delivered. +** OUTPUTS: None +** RETURN: PRAlarmID* Handle to the notifier just created +** or NULL if the request failed. +** +** SIDE EFFECTS: +** A periodic notifier is created. The notifications will be delivered +** by the alarm's internal thread at a fixed interval whose rate is the +** number of interrupts per interval specified. The first notification +** will be delivered as soon as possible, and they will continue until +** the notifier routine indicates that they should cease of the alarm +** context is destroyed (PR_DestroyAlarm). +** RESTRICTIONS: +** None. +** MEMORY: Memory for the notifier object. +** ALGORITHM: The rate at which notifications are delivered are stated +** to be "'rate' notifies per 'interval'". The exact time of +** the notification is computed based on a epoch established +** when the notifier was set. Each notification is delivered +** not ealier than the epoch plus the fixed rate times the +** notification sequence number. Such notifications have the +** potential to be late by not more than 'interval'/'rate'. +** The amount of lateness of one notification is taken into +** account on the next in an attempt to avoid long term slew. +***********************************************************************/ +NSPR_API(PRAlarmID*) PR_SetAlarm( + PRAlarm *alarm, PRIntervalTime period, PRUint32 rate, + PRPeriodicAlarmFn function, void *clientData); + +/*********************************************************************** +** FUNCTION: PR_ResetAlarm +** DESCRIPTION: +** Resets an existing alarm. +** INPUTS: PRAlarmID *id Identify of the notifier. +** PRIntervalTime period Interval over which the notifies +** are delivered. +** PRUint32 rate The rate within the interval that +** the notifies will be delivered. +** OUTPUTS: None +** RETURN: PRStatus Indication of completion. +** +** SIDE EFFECTS: +** An existing alarm may have its period and rate redefined. The +** additional side effect is that the notifier's epoch is recomputed. +** The first notification delivered by the newly refreshed alarm is +** defined to be 'interval'/'rate' from the time of the reset. +** RESTRICTIONS: +** This function may only be called in the notifier for that alarm. +** MEMORY: N/A. +** ALGORITHM: See PR_SetAlarm(). +***********************************************************************/ +NSPR_API(PRStatus) PR_ResetAlarm( + PRAlarmID *id, PRIntervalTime period, PRUint32 rate); + +PR_END_EXTERN_C + +#endif /* !defined(pralarm_h) */ + +/* prinrval.h */ diff -Nru nspr-4.9.5/nspr/pr/include/obsolete/probslet.h nspr-4.10.7/nspr/pr/include/obsolete/probslet.h --- nspr-4.9.5/nspr/pr/include/obsolete/probslet.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/obsolete/probslet.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** A collection of things thought to be obsolete +*/ + +#if defined(PROBSLET_H) +#else +#define PROBSLET_H + +#include "prio.h" +#include "private/pprio.h" /* for PROsfd */ + +PR_BEGIN_EXTERN_C + +/* +** Yield the current thread. The proper function to use in place of +** PR_Yield() is PR_Sleep() with an argument of PR_INTERVAL_NO_WAIT. +*/ +NSPR_API(PRStatus) PR_Yield(void); + +/************************************************************************/ +/************* The following definitions are for select *****************/ +/************************************************************************/ + +/* +** The following is obsolete and will be deleted in the next release! +** These are provided for compatibility, but are GUARANTEED to be slow. +** +** Override PR_MAX_SELECT_DESC if you need more space in the select set. +*/ +#ifndef PR_MAX_SELECT_DESC +#define PR_MAX_SELECT_DESC 1024 +#endif +typedef struct PR_fd_set { + PRUint32 hsize; + PRFileDesc *harray[PR_MAX_SELECT_DESC]; + PRUint32 nsize; + PROsfd narray[PR_MAX_SELECT_DESC]; +} PR_fd_set; + +/* +************************************************************************* +** FUNCTION: PR_Select +** DESCRIPTION: +** +** The call returns as soon as I/O is ready on one or more of the underlying +** file/socket descriptors or an exceptional condition is pending. A count of the +** number of ready descriptors is returned unless a timeout occurs in which case +** zero is returned. On return, PR_Select replaces the given descriptor sets with +** subsets consisting of those descriptors that are ready for the requested condition. +** The total number of ready descriptors in all the sets is the return value. +** +** INPUTS: +** PRInt32 num +** This argument is unused but is provided for select(unix) interface +** compatability. All input PR_fd_set arguments are self-describing +** with its own maximum number of elements in the set. +** +** PR_fd_set *readfds +** A set describing the io descriptors for which ready for reading +** condition is of interest. +** +** PR_fd_set *writefds +** A set describing the io descriptors for which ready for writing +** condition is of interest. +** +** PR_fd_set *exceptfds +** A set describing the io descriptors for which exception pending +** condition is of interest. +** +** Any of the above readfds, writefds or exceptfds may be given as NULL +** pointers if no descriptors are of interest for that particular condition. +** +** PRIntervalTime timeout +** Amount of time the call will block waiting for I/O to become ready. +** If this time expires without any I/O becoming ready, the result will +** be zero. +** +** OUTPUTS: +** PR_fd_set *readfds +** A set describing the io descriptors which are ready for reading. +** +** PR_fd_set *writefds +** A set describing the io descriptors which are ready for writing. +** +** PR_fd_set *exceptfds +** A set describing the io descriptors which have pending exception. +** +** RETURN:PRInt32 +** Number of io descriptors with asked for conditions or zero if the function +** timed out or -1 on failure. The reason for the failure is obtained by +** calling PR_GetError(). +** XXX can we implement this on windoze and mac? +************************************************************************** +*/ +NSPR_API(PRInt32) PR_Select( + PRInt32 num, PR_fd_set *readfds, PR_fd_set *writefds, + PR_fd_set *exceptfds, PRIntervalTime timeout); + +/* +** The following are not thread safe for two threads operating on them at the +** same time. +** +** The following routines are provided for manipulating io descriptor sets. +** PR_FD_ZERO(&fdset) initializes a descriptor set fdset to the null set. +** PR_FD_SET(fd, &fdset) includes a particular file descriptor fd in fdset. +** PR_FD_CLR(fd, &fdset) removes a file descriptor fd from fdset. +** PR_FD_ISSET(fd, &fdset) is nonzero if file descriptor fd is a member of +** fdset, zero otherwise. +** +** PR_FD_NSET(osfd, &fdset) includes a particular native file descriptor osfd +** in fdset. +** PR_FD_NCLR(osfd, &fdset) removes a native file descriptor osfd from fdset. +** PR_FD_NISSET(osfd, &fdset) is nonzero if native file descriptor osfd is a member of +** fdset, zero otherwise. +*/ + +NSPR_API(void) PR_FD_ZERO(PR_fd_set *set); +NSPR_API(void) PR_FD_SET(PRFileDesc *fd, PR_fd_set *set); +NSPR_API(void) PR_FD_CLR(PRFileDesc *fd, PR_fd_set *set); +NSPR_API(PRInt32) PR_FD_ISSET(PRFileDesc *fd, PR_fd_set *set); +NSPR_API(void) PR_FD_NSET(PROsfd osfd, PR_fd_set *set); +NSPR_API(void) PR_FD_NCLR(PROsfd osfd, PR_fd_set *set); +NSPR_API(PRInt32) PR_FD_NISSET(PROsfd osfd, PR_fd_set *set); + +/* +** The next two entry points should not be in the API, but they are +** declared here for historical reasons. +*/ + +NSPR_API(PRInt32) PR_GetSysfdTableMax(void); + +NSPR_API(PRInt32) PR_SetSysfdTableSize(PRIntn table_size); + +#ifndef NO_NSPR_10_SUPPORT +#include + +NSPR_API(PRInt32) PR_Stat(const char *path, struct stat *buf); +#endif /* NO_NSPR_10_SUPPORT */ + +PR_END_EXTERN_C + +#endif /* defined(PROBSLET_H) */ + +/* probslet.h */ diff -Nru nspr-4.9.5/nspr/pr/include/obsolete/protypes.h nspr-4.10.7/nspr/pr/include/obsolete/protypes.h --- nspr-4.9.5/nspr/pr/include/obsolete/protypes.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/obsolete/protypes.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,199 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This header typedefs the old 'native' types to the new PRs. + * These definitions are scheduled to be eliminated at the earliest + * possible time. The NSPR API is implemented and documented using + * the new definitions. + */ + +#if !defined(PROTYPES_H) +#define PROTYPES_H + +typedef PRUintn uintn; +#ifndef _XP_Core_ +typedef PRIntn intn; +#endif + +/* + * It is trickier to define uint, int8, uint8, int16, uint16, + * int32, uint32, int64, and uint64 because some of these int + * types are defined by standard header files on some platforms. + * Our strategy here is to include all such standard headers + * first, and then define these int types only if they are not + * defined by those standard headers. + */ + +/* + * BeOS defines all the int types below in its standard header + * file SupportDefs.h. + */ +#ifdef XP_BEOS +#include +#endif + +/* + * SVR4 typedef of uint is commonly found on UNIX machines. + * + * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h) + * defines the types int8, int16, int32, and int64. + * + * On OS/2, sys/types.h defines uint. + */ +#if defined(XP_UNIX) || defined(XP_OS2) +#include +#endif + +/* model.h on HP-UX defines int8, int16, and int32. */ +#ifdef HPUX +#include +#endif + +/* + * uint + */ + +#if !defined(XP_BEOS) && !defined(XP_OS2) && !defined(XP_UNIX) || defined(NTO) +typedef PRUintn uint; +#endif + +/* + * uint64 + */ + +#if !defined(XP_BEOS) +typedef PRUint64 uint64; +#endif + +/* + * uint32 + */ + +#if !defined(XP_BEOS) +#if !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO) +typedef PRUint32 uint32; +#else +typedef unsigned long uint32; +#endif +#endif + +/* + * uint16 + */ + +#if !defined(XP_BEOS) +typedef PRUint16 uint16; +#endif + +/* + * uint8 + */ + +#if !defined(XP_BEOS) +typedef PRUint8 uint8; +#endif + +/* + * int64 + */ + +#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) +typedef PRInt64 int64; +#endif + +/* + * int32 + */ + +#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ + && !defined(HPUX) +#if !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO) +typedef PRInt32 int32; +#else +typedef long int32; +#endif +#endif + +/* + * int16 + */ + +#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ + && !defined(HPUX) +typedef PRInt16 int16; +#endif + +/* + * int8 + */ + +#if !defined(XP_BEOS) && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \ + && !defined(HPUX) +typedef PRInt8 int8; +#endif + +typedef PRFloat64 float64; +typedef PRUptrdiff uptrdiff_t; +typedef PRUword uprword_t; +typedef PRWord prword_t; + + +/* Re: prbit.h */ +#define TEST_BIT PR_TEST_BIT +#define SET_BIT PR_SET_BIT +#define CLEAR_BIT PR_CLEAR_BIT + +/* Re: prarena.h->plarena.h */ +#define PRArena PLArena +#define PRArenaPool PLArenaPool +#define PRArenaStats PLArenaStats +#define PR_ARENA_ALIGN PL_ARENA_ALIGN +#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL +#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE +#define PR_ARENA_GROW PL_ARENA_GROW +#define PR_ARENA_MARK PL_ARENA_MARK +#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED +#define PR_CLEAR_ARENA PL_CLEAR_ARENA +#define PR_ARENA_RELEASE PL_ARENA_RELEASE +#define PR_COUNT_ARENA PL_COUNT_ARENA +#define PR_ARENA_DESTROY PL_ARENA_DESTROY +#define PR_InitArenaPool PL_InitArenaPool +#define PR_FreeArenaPool PL_FreeArenaPool +#define PR_FinishArenaPool PL_FinishArenaPool +#define PR_CompactArenaPool PL_CompactArenaPool +#define PR_ArenaFinish PL_ArenaFinish +#define PR_ArenaAllocate PL_ArenaAllocate +#define PR_ArenaGrow PL_ArenaGrow +#define PR_ArenaRelease PL_ArenaRelease +#define PR_ArenaCountAllocation PL_ArenaCountAllocation +#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth +#define PR_ArenaCountGrowth PL_ArenaCountGrowth +#define PR_ArenaCountRelease PL_ArenaCountRelease +#define PR_ArenaCountRetract PL_ArenaCountRetract + +/* Re: prhash.h->plhash.h */ +#define PRHashEntry PLHashEntry +#define PRHashTable PLHashTable +#define PRHashNumber PLHashNumber +#define PRHashFunction PLHashFunction +#define PRHashComparator PLHashComparator +#define PRHashEnumerator PLHashEnumerator +#define PRHashAllocOps PLHashAllocOps +#define PR_NewHashTable PL_NewHashTable +#define PR_HashTableDestroy PL_HashTableDestroy +#define PR_HashTableRawLookup PL_HashTableRawLookup +#define PR_HashTableRawAdd PL_HashTableRawAdd +#define PR_HashTableRawRemove PL_HashTableRawRemove +#define PR_HashTableAdd PL_HashTableAdd +#define PR_HashTableRemove PL_HashTableRemove +#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries +#define PR_HashTableLookup PL_HashTableLookup +#define PR_HashTableDump PL_HashTableDump +#define PR_HashString PL_HashString +#define PR_CompareStrings PL_CompareStrings +#define PR_CompareValues PL_CompareValues + +#endif /* !defined(PROTYPES_H) */ diff -Nru nspr-4.9.5/nspr/pr/include/obsolete/prsem.h nspr-4.10.7/nspr/pr/include/obsolete/prsem.h --- nspr-4.9.5/nspr/pr/include/obsolete/prsem.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/obsolete/prsem.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prsem_h___ +#define prsem_h___ + +/* +** API for counting semaphores. Semaphores are counting synchronizing +** variables based on a lock and a condition variable. They are lightweight +** contention control for a given count of resources. +*/ +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +typedef struct PRSemaphore PRSemaphore; + +/* +** Create a new semaphore object. +*/ +NSPR_API(PRSemaphore*) PR_NewSem(PRUintn value); + +/* +** Destroy the given semaphore object. +** +*/ +NSPR_API(void) PR_DestroySem(PRSemaphore *sem); + +/* +** Wait on a Semaphore. +** +** This routine allows a calling thread to wait or proceed depending upon the +** state of the semahore sem. The thread can proceed only if the counter value +** of the semaphore sem is currently greater than 0. If the value of semaphore +** sem is positive, it is decremented by one and the routine returns immediately +** allowing the calling thread to continue. If the value of semaphore sem is 0, +** the calling thread blocks awaiting the semaphore to be released by another +** thread. +** +** This routine can return PR_PENDING_INTERRUPT if the waiting thread +** has been interrupted. +*/ +NSPR_API(PRStatus) PR_WaitSem(PRSemaphore *sem); + +/* +** This routine increments the counter value of the semaphore. If other threads +** are blocked for the semaphore, then the scheduler will determine which ONE +** thread will be unblocked. +*/ +NSPR_API(void) PR_PostSem(PRSemaphore *sem); + +/* +** Returns the value of the semaphore referenced by sem without affecting +** the state of the semaphore. The value represents the semaphore vaule +F** at the time of the call, but may not be the actual value when the +** caller inspects it. +*/ +NSPR_API(PRUintn) PR_GetValueSem(PRSemaphore *sem); + +PR_END_EXTERN_C + +#endif /* prsem_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/pratom.h nspr-4.10.7/nspr/pr/include/pratom.h --- nspr-4.9.5/nspr/pr/include/pratom.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/pratom.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,196 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* GLOBAL FUNCTIONS: +** DESCRIPTION: +** PR Atomic operations +*/ + +#ifndef pratom_h___ +#define pratom_h___ + +#include "prtypes.h" +#include "prlock.h" + +PR_BEGIN_EXTERN_C + +/* +** FUNCTION: PR_AtomicIncrement +** DESCRIPTION: +** Atomically increment a 32 bit value. +** INPUTS: +** val: a pointer to the value to increment +** RETURN: +** the returned value is the result of the increment +*/ +NSPR_API(PRInt32) PR_AtomicIncrement(PRInt32 *val); + +/* +** FUNCTION: PR_AtomicDecrement +** DESCRIPTION: +** Atomically decrement a 32 bit value. +** INPUTS: +** val: a pointer to the value to decrement +** RETURN: +** the returned value is the result of the decrement +*/ +NSPR_API(PRInt32) PR_AtomicDecrement(PRInt32 *val); + +/* +** FUNCTION: PR_AtomicSet +** DESCRIPTION: +** Atomically set a 32 bit value. +** INPUTS: +** val: A pointer to a 32 bit value to be set +** newval: The newvalue to assign to val +** RETURN: +** Returns the prior value +*/ +NSPR_API(PRInt32) PR_AtomicSet(PRInt32 *val, PRInt32 newval); + +/* +** FUNCTION: PR_AtomicAdd +** DESCRIPTION: +** Atomically add a 32 bit value. +** INPUTS: +** ptr: a pointer to the value to increment +** val: value to be added +** RETURN: +** the returned value is the result of the addition +*/ +NSPR_API(PRInt32) PR_AtomicAdd(PRInt32 *ptr, PRInt32 val); + +/* +** MACRO: PR_ATOMIC_INCREMENT +** MACRO: PR_ATOMIC_DECREMENT +** MACRO: PR_ATOMIC_SET +** MACRO: PR_ATOMIC_ADD +** DESCRIPTION: +** Macro versions of the atomic operations. They may be implemented +** as compiler intrinsics. +** +** IMPORTANT NOTE TO NSPR MAINTAINERS: +** Implement these macros with compiler intrinsics only on platforms +** where the PR_AtomicXXX functions are truly atomic (i.e., where the +** configuration macro _PR_HAVE_ATOMIC_OPS is defined). Otherwise, +** the macros and functions won't be compatible and can't be used +** interchangeably. +*/ +#if defined(_WIN32) && !defined(_WIN32_WCE) && \ + (!defined(_MSC_VER) || (_MSC_VER >= 1310)) + +#include + +#ifdef _MSC_VER +#pragma intrinsic(_InterlockedIncrement) +#pragma intrinsic(_InterlockedDecrement) +#pragma intrinsic(_InterlockedExchange) +#pragma intrinsic(_InterlockedExchangeAdd) +#endif + +#define PR_ATOMIC_INCREMENT(val) _InterlockedIncrement((long volatile *)(val)) +#define PR_ATOMIC_DECREMENT(val) _InterlockedDecrement((long volatile *)(val)) +#define PR_ATOMIC_SET(val, newval) \ + _InterlockedExchange((long volatile *)(val), (long)(newval)) +#define PR_ATOMIC_ADD(ptr, val) \ + (_InterlockedExchangeAdd((long volatile *)(ptr), (long)(val)) + (val)) + +#elif ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && \ + ((defined(__APPLE__) && \ + (defined(__ppc__) || defined(__i386__) || defined(__x86_64__))) || \ + (defined(__linux__) && \ + ((defined(__i386__) && \ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \ + defined(__ia64__) || defined(__x86_64__) || \ + defined(__powerpc__) || \ + (defined(__arm__) && \ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \ + defined(__aarch64__) || defined(__alpha)))) + +/* + * Because the GCC manual warns that some processors may support + * reduced functionality of __sync_lock_test_and_set, we test for the + * processors that we believe support a full atomic exchange operation. + */ + +#define PR_ATOMIC_INCREMENT(val) __sync_add_and_fetch(val, 1) +#define PR_ATOMIC_DECREMENT(val) __sync_sub_and_fetch(val, 1) +#define PR_ATOMIC_SET(val, newval) __sync_lock_test_and_set(val, newval) +#define PR_ATOMIC_ADD(ptr, val) __sync_add_and_fetch(ptr, val) + +#else + +#define PR_ATOMIC_INCREMENT(val) PR_AtomicIncrement(val) +#define PR_ATOMIC_DECREMENT(val) PR_AtomicDecrement(val) +#define PR_ATOMIC_SET(val, newval) PR_AtomicSet(val, newval) +#define PR_ATOMIC_ADD(ptr, val) PR_AtomicAdd(ptr, val) + +#endif + +/* +** LIFO linked-list (stack) +*/ +typedef struct PRStackElemStr PRStackElem; + +struct PRStackElemStr { + PRStackElem *prstk_elem_next; /* next pointer MUST be at offset 0; + assembly language code relies on this */ +}; + +typedef struct PRStackStr PRStack; + +/* +** FUNCTION: PR_CreateStack +** DESCRIPTION: +** Create a stack, a LIFO linked list +** INPUTS: +** stack_name: a pointer to string containing the name of the stack +** RETURN: +** A pointer to the created stack, if successful, else NULL. +*/ +NSPR_API(PRStack *) PR_CreateStack(const char *stack_name); + +/* +** FUNCTION: PR_StackPush +** DESCRIPTION: +** Push an element on the top of the stack +** INPUTS: +** stack: pointer to the stack +** stack_elem: pointer to the stack element +** RETURN: +** None +*/ +NSPR_API(void) PR_StackPush(PRStack *stack, PRStackElem *stack_elem); + +/* +** FUNCTION: PR_StackPop +** DESCRIPTION: +** Remove the element on the top of the stack +** INPUTS: +** stack: pointer to the stack +** RETURN: +** A pointer to the stack element removed from the top of the stack, +** if non-empty, +** else NULL +*/ +NSPR_API(PRStackElem *) PR_StackPop(PRStack *stack); + +/* +** FUNCTION: PR_DestroyStack +** DESCRIPTION: +** Destroy the stack +** INPUTS: +** stack: pointer to the stack +** RETURN: +** PR_SUCCESS - if successfully deleted +** PR_FAILURE - if the stack is not empty +** PR_GetError will return +** PR_INVALID_STATE_ERROR - stack is not empty +*/ +NSPR_API(PRStatus) PR_DestroyStack(PRStack *stack); + +PR_END_EXTERN_C + +#endif /* pratom_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prbit.h nspr-4.10.7/nspr/pr/include/prbit.h --- nspr-4.9.5/nspr/pr/include/prbit.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prbit.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,150 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prbit_h___ +#define prbit_h___ + +#include "prtypes.h" +PR_BEGIN_EXTERN_C + +/* +** Replace compare/jump/add/shift sequence with compiler built-in/intrinsic +** functions. +*/ +#if defined(_WIN32) && (_MSC_VER >= 1300) && \ + (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_ARM)) +# include +# pragma intrinsic(_BitScanForward,_BitScanReverse) + __forceinline static int __prBitScanForward32(unsigned int val) + { + unsigned long idx; + _BitScanForward(&idx, (unsigned long)val); + return( (int)idx ); + } + __forceinline static int __prBitScanReverse32(unsigned int val) + { + unsigned long idx; + _BitScanReverse(&idx, (unsigned long)val); + return( (int)(31-idx) ); + } +# define pr_bitscan_ctz32(val) __prBitScanForward32(val) +# define pr_bitscan_clz32(val) __prBitScanReverse32(val) +# define PR_HAVE_BUILTIN_BITSCAN32 +#elif ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && \ + (defined(__i386__) || defined(__x86_64__) || defined(__arm__)) +# define pr_bitscan_ctz32(val) __builtin_ctz(val) +# define pr_bitscan_clz32(val) __builtin_clz(val) +# define PR_HAVE_BUILTIN_BITSCAN32 +#endif /* MSVC || GCC */ + +/* +** A prbitmap_t is a long integer that can be used for bitmaps +*/ +typedef unsigned long prbitmap_t; + +#define PR_TEST_BIT(_map,_bit) \ + ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] & (1L << ((_bit) & (PR_BITS_PER_LONG-1)))) +#define PR_SET_BIT(_map,_bit) \ + ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] |= (1L << ((_bit) & (PR_BITS_PER_LONG-1)))) +#define PR_CLEAR_BIT(_map,_bit) \ + ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] &= ~(1L << ((_bit) & (PR_BITS_PER_LONG-1)))) + +/* +** Compute the log of the least power of 2 greater than or equal to n +*/ +NSPR_API(PRIntn) PR_CeilingLog2(PRUint32 i); + +/* +** Compute the log of the greatest power of 2 less than or equal to n +*/ +NSPR_API(PRIntn) PR_FloorLog2(PRUint32 i); + +/* +** Macro version of PR_CeilingLog2: Compute the log of the least power of +** 2 greater than or equal to _n. The result is returned in _log2. +*/ +#ifdef PR_HAVE_BUILTIN_BITSCAN32 +#define PR_CEILING_LOG2(_log2,_n) \ + PR_BEGIN_MACRO \ + PRUint32 j_ = (PRUint32)(_n); \ + (_log2) = (j_ <= 1 ? 0 : 32 - pr_bitscan_clz32(j_ - 1)); \ + PR_END_MACRO +#else +#define PR_CEILING_LOG2(_log2,_n) \ + PR_BEGIN_MACRO \ + PRUint32 j_ = (PRUint32)(_n); \ + (_log2) = 0; \ + if ((j_) & ((j_)-1)) \ + (_log2) += 1; \ + if ((j_) >> 16) \ + (_log2) += 16, (j_) >>= 16; \ + if ((j_) >> 8) \ + (_log2) += 8, (j_) >>= 8; \ + if ((j_) >> 4) \ + (_log2) += 4, (j_) >>= 4; \ + if ((j_) >> 2) \ + (_log2) += 2, (j_) >>= 2; \ + if ((j_) >> 1) \ + (_log2) += 1; \ + PR_END_MACRO +#endif /* PR_HAVE_BUILTIN_BITSCAN32 */ + +/* +** Macro version of PR_FloorLog2: Compute the log of the greatest power of +** 2 less than or equal to _n. The result is returned in _log2. +** +** This is equivalent to finding the highest set bit in the word. +*/ +#ifdef PR_HAVE_BUILTIN_BITSCAN32 +#define PR_FLOOR_LOG2(_log2,_n) \ + PR_BEGIN_MACRO \ + PRUint32 j_ = (PRUint32)(_n); \ + (_log2) = 31 - pr_bitscan_clz32((j_) | 1); \ + PR_END_MACRO +#else +#define PR_FLOOR_LOG2(_log2,_n) \ + PR_BEGIN_MACRO \ + PRUint32 j_ = (PRUint32)(_n); \ + (_log2) = 0; \ + if ((j_) >> 16) \ + (_log2) += 16, (j_) >>= 16; \ + if ((j_) >> 8) \ + (_log2) += 8, (j_) >>= 8; \ + if ((j_) >> 4) \ + (_log2) += 4, (j_) >>= 4; \ + if ((j_) >> 2) \ + (_log2) += 2, (j_) >>= 2; \ + if ((j_) >> 1) \ + (_log2) += 1; \ + PR_END_MACRO +#endif /* PR_HAVE_BUILTIN_BITSCAN32 */ + +/* +** Macros for rotate left and right. The argument 'a' must be an unsigned +** 32-bit integer type such as PRUint32. +** +** There is no rotate operation in the C Language, so the construct +** (a << 4) | (a >> 28) is frequently used instead. Most compilers convert +** this to a rotate instruction, but MSVC doesn't without a little help. +** To get MSVC to generate a rotate instruction, we have to use the _rotl +** or _rotr intrinsic and use a pragma to make it inline. +** +** Note: MSVC in VS2005 will do an inline rotate instruction on the above +** construct. +*/ + +#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \ + defined(_M_X64) || defined(_M_ARM)) +#include +#pragma intrinsic(_rotl, _rotr) +#define PR_ROTATE_LEFT32(a, bits) _rotl(a, bits) +#define PR_ROTATE_RIGHT32(a, bits) _rotr(a, bits) +#else +#define PR_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits)))) +#define PR_ROTATE_RIGHT32(a, bits) (((a) >> (bits)) | ((a) << (32 - (bits)))) +#endif + +PR_END_EXTERN_C +#endif /* prbit_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prclist.h nspr-4.10.7/nspr/pr/include/prclist.h --- nspr-4.9.5/nspr/pr/include/prclist.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prclist.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prclist_h___ +#define prclist_h___ + +#include "prtypes.h" + +typedef struct PRCListStr PRCList; + +/* +** Circular linked list +*/ +struct PRCListStr { + PRCList *next; + PRCList *prev; +}; + +/* +** Insert element "_e" into the list, before "_l". +*/ +#define PR_INSERT_BEFORE(_e,_l) \ + PR_BEGIN_MACRO \ + (_e)->next = (_l); \ + (_e)->prev = (_l)->prev; \ + (_l)->prev->next = (_e); \ + (_l)->prev = (_e); \ + PR_END_MACRO + +/* +** Insert element "_e" into the list, after "_l". +*/ +#define PR_INSERT_AFTER(_e,_l) \ + PR_BEGIN_MACRO \ + (_e)->next = (_l)->next; \ + (_e)->prev = (_l); \ + (_l)->next->prev = (_e); \ + (_l)->next = (_e); \ + PR_END_MACRO + +/* +** Return the element following element "_e" +*/ +#define PR_NEXT_LINK(_e) \ + ((_e)->next) +/* +** Return the element preceding element "_e" +*/ +#define PR_PREV_LINK(_e) \ + ((_e)->prev) + +/* +** Append an element "_e" to the end of the list "_l" +*/ +#define PR_APPEND_LINK(_e,_l) PR_INSERT_BEFORE(_e,_l) + +/* +** Insert an element "_e" at the head of the list "_l" +*/ +#define PR_INSERT_LINK(_e,_l) PR_INSERT_AFTER(_e,_l) + +/* Return the head/tail of the list */ +#define PR_LIST_HEAD(_l) (_l)->next +#define PR_LIST_TAIL(_l) (_l)->prev + +/* +** Remove the element "_e" from it's circular list. +*/ +#define PR_REMOVE_LINK(_e) \ + PR_BEGIN_MACRO \ + (_e)->prev->next = (_e)->next; \ + (_e)->next->prev = (_e)->prev; \ + PR_END_MACRO + +/* +** Remove the element "_e" from it's circular list. Also initializes the +** linkage. +*/ +#define PR_REMOVE_AND_INIT_LINK(_e) \ + PR_BEGIN_MACRO \ + (_e)->prev->next = (_e)->next; \ + (_e)->next->prev = (_e)->prev; \ + (_e)->next = (_e); \ + (_e)->prev = (_e); \ + PR_END_MACRO + +/* +** Return non-zero if the given circular list "_l" is empty, zero if the +** circular list is not empty +*/ +#define PR_CLIST_IS_EMPTY(_l) \ + ((_l)->next == (_l)) + +/* +** Initialize a circular list +*/ +#define PR_INIT_CLIST(_l) \ + PR_BEGIN_MACRO \ + (_l)->next = (_l); \ + (_l)->prev = (_l); \ + PR_END_MACRO + +#define PR_INIT_STATIC_CLIST(_l) \ + {(_l), (_l)} + +#endif /* prclist_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prcmon.h nspr-4.10.7/nspr/pr/include/prcmon.h --- nspr-4.9.5/nspr/pr/include/prcmon.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prcmon.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prcmon_h___ +#define prcmon_h___ + +/* +** Interface to cached monitors. Cached monitors use an address to find a +** given PR monitor. In this way a monitor can be associated with another +** object without preallocating a monitor for all objects. +** +** A hash table is used to quickly map addresses to individual monitors +** and the system automatically grows the hash table as needed. +** +** Cache monitors are about 5 times slower to use than uncached monitors. +*/ +#include "prmon.h" +#include "prinrval.h" + +PR_BEGIN_EXTERN_C + +/** +** Like PR_EnterMonitor except use the "address" to find a monitor in the +** monitor cache. If successful, returns the PRMonitor now associated +** with "address". Note that you must PR_CExitMonitor the address to +** release the monitor cache entry (otherwise the monitor cache will fill +** up). This call will return NULL if the monitor cache needs to be +** expanded and the system is out of memory. +*/ +NSPR_API(PRMonitor*) PR_CEnterMonitor(void *address); + +/* +** Like PR_ExitMonitor except use the "address" to find a monitor in the +** monitor cache. +*/ +NSPR_API(PRStatus) PR_CExitMonitor(void *address); + +/* +** Like PR_Wait except use the "address" to find a monitor in the +** monitor cache. +*/ +NSPR_API(PRStatus) PR_CWait(void *address, PRIntervalTime timeout); + +/* +** Like PR_Notify except use the "address" to find a monitor in the +** monitor cache. +*/ +NSPR_API(PRStatus) PR_CNotify(void *address); + +/* +** Like PR_NotifyAll except use the "address" to find a monitor in the +** monitor cache. +*/ +NSPR_API(PRStatus) PR_CNotifyAll(void *address); + +/* +** Set a callback to be invoked each time a monitor is recycled from the cache +** freelist, with the monitor's cache-key passed in address. +*/ +NSPR_API(void) PR_CSetOnMonitorRecycle(void (PR_CALLBACK *callback)(void *address)); + +PR_END_EXTERN_C + +#endif /* prcmon_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prcountr.h nspr-4.10.7/nspr/pr/include/prcountr.h --- nspr-4.9.5/nspr/pr/include/prcountr.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prcountr.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,525 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prcountr_h___ +#define prcountr_h___ + +/*---------------------------------------------------------------------------- +** prcountr.h -- NSPR Instrumentation counters +** +** The NSPR Counter Feature provides a means to "count +** something." Counters can be dynamically defined, incremented, +** decremented, set, and deleted under application program +** control. +** +** The Counter Feature is intended to be used as instrumentation, +** not as operational data. If you need a counter for operational +** data, use native integral types. +** +** Counters are 32bit unsigned intergers. On overflow, a counter +** will wrap. No exception is recognized or reported. +** +** A counter can be dynamically created using a two level naming +** convention. A "handle" is returned when the counter is +** created. The counter can subsequently be addressed by its +** handle. An API is provided to get an existing counter's handle +** given the names with which it was originally created. +** Similarly, a counter's name can be retrieved given its handle. +** +** The counter naming convention is a two-level hierarchy. The +** QName is the higher level of the hierarchy; RName is the +** lower level. RNames can be thought of as existing within a +** QName. The same RName can exist within multiple QNames. QNames +** are unique. The NSPR Counter is not a near-zero overhead +** feature. Application designers should be aware of +** serialization issues when using the Counter API. Creating a +** counter locks a large asset, potentially causing a stall. This +** suggest that applications should create counters at component +** initialization, for example, and not create and destroy them +** willy-nilly. ... You have been warned. +** +** Incrementing and Adding to counters uses atomic operations. +** The performance of these operations will vary from platform +** to platform. On platforms where atomic operations are not +** supported the overhead may be substantial. +** +** When traversing the counter database with FindNext functions, +** the instantaneous values of any given counter is that at the +** moment of extraction. The state of the entire counter database +** may not be viewed as atomic. +** +** The counter interface may be disabled (No-Op'd) at compile +** time. When DEBUG is defined at compile time, the Counter +** Feature is compiled into NSPR and applications invoking it. +** When DEBUG is not defined, the counter macros compile to +** nothing. To force the Counter Feature to be compiled into an +** optimized build, define FORCE_NSPR_COUNTERS at compile time +** for both NSPR and the application intending to use it. +** +** Application designers should use the macro form of the Counter +** Feature methods to minimize performance impact in optimized +** builds. The macros normally compile to nothing on optimized +** builds. +** +** Application designers should be aware of the effects of +** debug and optimized build differences when using result of the +** Counter Feature macros in expressions. +** +** The Counter Feature is thread-safe and SMP safe. +** +** /lth. 09-Jun-1998. +*/ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* +** Opaque counter handle type. +** ... don't even think of looking in here. +** +*/ +typedef void * PRCounterHandle; + +#define PRCOUNTER_NAME_MAX 31 +#define PRCOUNTER_DESC_MAX 255 + + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_DEFINE_COUNTER() -- Define a PRCounterHandle +** +** DESCRIPTION: PR_DEFINE_COUNTER() is used to define a counter +** handle. +** +*/ +#define PR_DEFINE_COUNTER(name) PRCounterHandle name + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_INIT_COUNTER_HANDLE() -- Set the value of a PRCounterHandle +** +** DESCRIPTION: +** PR_INIT_COUNTER_HANDLE() sets the value of a PRCounterHandle +** to value. +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_INIT_COUNTER_HANDLE(handle,value)\ + (handle) = (PRCounterHandle)(value) +#else +#define PR_INIT_COUNTER_HANDLE(handle,value) +#endif + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_CreateCounter() -- Create a counter +** +** DESCRIPTION: PR_CreateCounter() creates a counter object and +** initializes it to zero. +** +** The macro form takes as its first argument the name of the +** PRCounterHandle to receive the handle returned from +** PR_CreateCounter(). +** +** INPUTS: +** qName: The QName for the counter object. The maximum length +** of qName is defined by PRCOUNTER_NAME_MAX +** +** rName: The RName for the counter object. The maximum length +** of qName is defined by PRCOUNTER_NAME_MAX +** +** descrioption: The description of the counter object. The +** maximum length of description is defined by +** PRCOUNTER_DESC_MAX. +** +** OUTPUTS: +** +** RETURNS: +** PRCounterHandle. +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_CREATE_COUNTER(handle,qName,rName,description)\ + (handle) = PR_CreateCounter((qName),(rName),(description)) +#else +#define PR_CREATE_COUNTER(handle,qName,rName,description) +#endif + +NSPR_API(PRCounterHandle) + PR_CreateCounter( + const char *qName, + const char *rName, + const char *description +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_DestroyCounter() -- Destroy a counter object. +** +** DESCRIPTION: PR_DestroyCounter() removes a counter and +** unregisters its handle from the counter database. +** +** INPUTS: +** handle: the PRCounterHandle of the counter to be destroyed. +** +** OUTPUTS: +** The counter is destroyed. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_DESTROY_COUNTER(handle) PR_DestroyCounter((handle)) +#else +#define PR_DESTROY_COUNTER(handle) +#endif + +NSPR_API(void) + PR_DestroyCounter( + PRCounterHandle handle +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_GetCounterHandleFromName() -- Retreive a +** counter's handle give its name. +** +** DESCRIPTION: PR_GetCounterHandleFromName() retreives a +** counter's handle from the counter database, given the name +** the counter was originally created with. +** +** INPUTS: +** qName: Counter's original QName. +** rName: Counter's original RName. +** +** OUTPUTS: +** +** RETURNS: +** PRCounterHandle or PRCounterError. +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)\ + (handle) = PR_GetCounterHandleFromName((qName),(rName)) +#else +#define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName) +#endif + +NSPR_API(PRCounterHandle) + PR_GetCounterHandleFromName( + const char *qName, + const char *rName +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_GetCounterNameFromHandle() -- Retreive a +** counter's name, given its handle. +** +** DESCRIPTION: PR_GetCounterNameFromHandle() retreives a +** counter's name given its handle. +** +** INPUTS: +** qName: Where to store a pointer to qName. +** rName: Where to store a pointer to rName. +** description: Where to store a pointer to description. +** +** OUTPUTS: Pointers to the Counter Feature's copies of the names +** used when the counters were created. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description)\ + PR_GetCounterNameFromHandle((handle),(qName),(rName),(description)) +#else +#define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description ) +#endif + +NSPR_API(void) + PR_GetCounterNameFromHandle( + PRCounterHandle handle, + const char **qName, + const char **rName, + const char **description +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_IncrementCounter() -- Add one to the referenced +** counter. +** +** DESCRIPTION: Add one to the referenced counter. +** +** INPUTS: +** handle: The PRCounterHandle of the counter to be incremented +** +** OUTPUTS: The counter is incrementd. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_INCREMENT_COUNTER(handle) PR_IncrementCounter(handle) +#else +#define PR_INCREMENT_COUNTER(handle) +#endif + +NSPR_API(void) + PR_IncrementCounter( + PRCounterHandle handle +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_DecrementCounter() -- Subtract one from the +** referenced counter +** +** DESCRIPTION: Subtract one from the referenced counter. +** +** INPUTS: +** handle: The PRCounterHandle of the coutner to be +** decremented. +** +** OUTPUTS: the counter is decremented. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_DECREMENT_COUNTER(handle) PR_DecrementCounter(handle) +#else +#define PR_DECREMENT_COUNTER(handle) +#endif + +NSPR_API(void) + PR_DecrementCounter( + PRCounterHandle handle +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_AddToCounter() -- Add a value to a counter. +** +** DESCRIPTION: Add value to the counter referenced by handle. +** +** INPUTS: +** handle: the PRCounterHandle of the counter to be added to. +** +** value: the value to be added to the counter. +** +** OUTPUTS: new value for counter. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_ADD_TO_COUNTER(handle,value)\ + PR_AddToCounter((handle),(value)) +#else +#define PR_ADD_TO_COUNTER(handle,value) +#endif + +NSPR_API(void) + PR_AddToCounter( + PRCounterHandle handle, + PRUint32 value +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_SubtractFromCounter() -- A value is subtracted +** from a counter. +** +** DESCRIPTION: +** Subtract a value from a counter. +** +** INPUTS: +** handle: the PRCounterHandle of the counter to be subtracted +** from. +** +** value: the value to be subtracted from the counter. +** +** OUTPUTS: new value for counter +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_SUBTRACT_FROM_COUNTER(handle,value)\ + PR_SubtractFromCounter((handle),(value)) +#else +#define PR_SUBTRACT_FROM_COUNTER(handle,value) +#endif + +NSPR_API(void) + PR_SubtractFromCounter( + PRCounterHandle handle, + PRUint32 value +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_GetCounter() -- Retreive the value of a counter +** +** DESCRIPTION: +** Retreive the value of a counter. +** +** INPUTS: +** handle: the PR_CounterHandle of the counter to be retreived +** +** OUTPUTS: +** +** RETURNS: The value of the referenced counter +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_GET_COUNTER(counter,handle)\ + (counter) = PR_GetCounter((handle)) +#else +#define PR_GET_COUNTER(counter,handle) 0 +#endif + +NSPR_API(PRUint32) + PR_GetCounter( + PRCounterHandle handle +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_SetCounter() -- Replace the content of counter +** with value. +** +** DESCRIPTION: The contents of the referenced counter are +** replaced by value. +** +** INPUTS: +** handle: the PRCounterHandle of the counter whose contents +** are to be replaced. +** +** value: the new value of the counter. +** +** OUTPUTS: +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_SET_COUNTER(handle,value) PR_SetCounter((handle),(value)) +#else +#define PR_SET_COUNTER(handle,value) +#endif + +NSPR_API(void) + PR_SetCounter( + PRCounterHandle handle, + PRUint32 value +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_FindNextCounterQname() -- Retreive the next QName counter +** handle iterator +** +** DESCRIPTION: +** PR_FindNextCounterQname() retreives the first or next Qname +** the counter data base, depending on the value of handle. When +** handle is NULL, the function attempts to retreive the first +** QName handle in the database. When handle is a handle previosly +** retreived QName handle, then the function attempts to retreive +** the next QName handle. +** +** INPUTS: +** handle: PRCounterHandle or NULL. +** +** OUTPUTS: returned +** +** RETURNS: PRCounterHandle or NULL when no more QName counter +** handles are present. +** +** RESTRICTIONS: +** A concurrent PR_CreateCounter() or PR_DestroyCounter() may +** cause unpredictable results. +** +** A PRCounterHandle returned from this function may only be used +** in another PR_FindNextCounterQname() function call; other +** operations may cause unpredictable results. +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_FIND_NEXT_COUNTER_QNAME(next,handle)\ + (next) = PR_FindNextCounterQname((handle)) +#else +#define PR_FIND_NEXT_COUNTER_QNAME(next,handle) NULL +#endif + +NSPR_API(PRCounterHandle) + PR_FindNextCounterQname( + PRCounterHandle handle +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_FindNextCounterRname() -- Retreive the next RName counter +** handle iterator +** +** DESCRIPTION: +** PR_FindNextCounterRname() retreives the first or next RNname +** handle from the counter data base, depending on the +** value of handle. When handle is NULL, the function attempts to +** retreive the first RName handle in the database. When handle is +** a handle previosly retreived RName handle, then the function +** attempts to retreive the next RName handle. +** +** INPUTS: +** handle: PRCounterHandle or NULL. +** qhandle: PRCounterHandle of a previously aquired via +** PR_FIND_NEXT_QNAME_HANDLE() +** +** OUTPUTS: returned +** +** RETURNS: PRCounterHandle or NULL when no more RName counter +** handles are present. +** +** RESTRICTIONS: +** A concurrent PR_CreateCounter() or PR_DestroyCounter() may +** cause unpredictable results. +** +** A PRCounterHandle returned from this function may only be used +** in another PR_FindNextCounterRname() function call; other +** operations may cause unpredictable results. +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) +#define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)\ + (next) = PR_FindNextCounterRname((rhandle),(qhandle)) +#else +#define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle) +#endif + +NSPR_API(PRCounterHandle) + PR_FindNextCounterRname( + PRCounterHandle rhandle, + PRCounterHandle qhandle +); + +PR_END_EXTERN_C + +#endif /* prcountr_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prcvar.h nspr-4.10.7/nspr/pr/include/prcvar.h --- nspr-4.9.5/nspr/pr/include/prcvar.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prcvar.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prcvar_h___ +#define prcvar_h___ + +#include "prlock.h" +#include "prinrval.h" + +PR_BEGIN_EXTERN_C + +typedef struct PRCondVar PRCondVar; + +/* +** Create a new condition variable. +** +** "lock" is the lock used to protect the condition variable. +** +** Condition variables are synchronization objects that threads can use +** to wait for some condition to occur. +** +** This may fail if memory is tight or if some operating system resource +** is low. In such cases, a NULL will be returned. +*/ +NSPR_API(PRCondVar*) PR_NewCondVar(PRLock *lock); + +/* +** Destroy a condition variable. There must be no thread +** waiting on the condvar. The caller is responsible for guaranteeing +** that the condvar is no longer in use. +** +*/ +NSPR_API(void) PR_DestroyCondVar(PRCondVar *cvar); + +/* +** The thread that waits on a condition is blocked in a "waiting on +** condition" state until another thread notifies the condition or a +** caller specified amount of time expires. The lock associated with +** the condition variable will be released, which must have be held +** prior to the call to wait. +** +** Logically a notified thread is moved from the "waiting on condition" +** state and made "ready." When scheduled, it will attempt to reacquire +** the lock that it held when wait was called. +** +** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and +** PR_INTERVAL_NO_WAIT. The former value requires that a condition be +** notified (or the thread interrupted) before it will resume from the +** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect +** is to release the lock, possibly causing a rescheduling within the +** runtime, then immediately attempting to reacquire the lock and resume. +** +** Any other value for timeout will cause the thread to be rescheduled +** either due to explicit notification or an expired interval. The latter +** must be determined by treating time as one part of the monitored data +** being protected by the lock and tested explicitly for an expired +** interval. +** +** Returns PR_FAILURE if the caller has not locked the lock associated +** with the condition variable or the thread was interrupted (PR_Interrupt()). +** The particular reason can be extracted with PR_GetError(). +*/ +NSPR_API(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout); + +/* +** Notify ONE thread that is currently waiting on 'cvar'. Which thread is +** dependent on the implementation of the runtime. Common sense would dictate +** that all threads waiting on a single condition have identical semantics, +** therefore which one gets notified is not significant. +** +** The calling thead must hold the lock that protects the condition, as +** well as the invariants that are tightly bound to the condition, when +** notify is called. +** +** Returns PR_FAILURE if the caller has not locked the lock associated +** with the condition variable. +*/ +NSPR_API(PRStatus) PR_NotifyCondVar(PRCondVar *cvar); + +/* +** Notify all of the threads waiting on the condition variable. The order +** that the threads are notified is indeterminant. The lock that protects +** the condition must be held. +** +** Returns PR_FAILURE if the caller has not locked the lock associated +** with the condition variable. +*/ +NSPR_API(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar); + +PR_END_EXTERN_C + +#endif /* prcvar_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prdtoa.h nspr-4.10.7/nspr/pr/include/prdtoa.h --- nspr-4.9.5/nspr/pr/include/prdtoa.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prdtoa.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prdtoa_h___ +#define prdtoa_h___ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* +** PR_strtod() returns as a double-precision floating-point number +** the value represented by the character string pointed to by +** s00. The string is scanned up to the first unrecognized +** character. +**a +** If the value of se is not (char **)NULL, a pointer to +** the character terminating the scan is returned in the location pointed +** to by se. If no number can be formed, se is set to s00, and +** zero is returned. +*/ +NSPR_API(PRFloat64) +PR_strtod(const char *s00, char **se); + +/* +** PR_cnvtf() +** conversion routines for floating point +** prcsn - number of digits of precision to generate floating +** point value. +*/ +NSPR_API(void) PR_cnvtf(char *buf, PRIntn bufsz, PRIntn prcsn, PRFloat64 fval); + +/* +** PR_dtoa() converts double to a string. +** +** ARGUMENTS: +** If rve is not null, *rve is set to point to the end of the return value. +** If d is +-Infinity or NaN, then *decpt is set to 9999. +** +** mode: +** 0 ==> shortest string that yields d when read in +** and rounded to nearest. +*/ +NSPR_API(PRStatus) PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits, + PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize); + +PR_END_EXTERN_C + +#endif /* prdtoa_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prenv.h nspr-4.10.7/nspr/pr/include/prenv.h --- nspr-4.9.5/nspr/pr/include/prenv.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prenv.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prenv_h___ +#define prenv_h___ + +#include "prtypes.h" + +/*******************************************************************************/ +/*******************************************************************************/ +/****************** THESE FUNCTIONS MAY NOT BE THREAD SAFE *********************/ +/*******************************************************************************/ +/*******************************************************************************/ + +PR_BEGIN_EXTERN_C + +/* +** PR_GetEnv() -- Retrieve value of environment variable +** +** Description: +** PR_GetEnv() is modeled on Unix getenv(). +** +** +** Inputs: +** var -- The name of the environment variable +** +** Returns: +** The value of the environment variable 'var' or NULL if +** the variable is undefined. +** +** Restrictions: +** You'd think that a POSIX getenv(), putenv() would be +** consistently implemented everywhere. Surprise! It is not. On +** some platforms, a putenv() where the argument is of +** the form "name" causes the named environment variable to +** be un-set; that is: a subsequent getenv() returns NULL. On +** other platforms, the putenv() fails, on others, it is a +** no-op. Similarly, a putenv() where the argument is of the +** form "name=" causes the named environment variable to be +** un-set; a subsequent call to getenv() returns NULL. On +** other platforms, a subsequent call to getenv() returns a +** pointer to a null-string (a byte of zero). +** +** PR_GetEnv(), PR_SetEnv() provide a consistent behavior +** across all supported platforms. There are, however, some +** restrictions and some practices you must use to achieve +** consistent results everywhere. +** +** When manipulating the environment there is no way to un-set +** an environment variable across all platforms. We suggest +** you interpret the return of a pointer to null-string to +** mean the same as a return of NULL from PR_GetEnv(). +** +** A call to PR_SetEnv() where the parameter is of the form +** "name" will return PR_FAILURE; the environment remains +** unchanged. A call to PR_SetEnv() where the parameter is +** of the form "name=" may un-set the envrionment variable on +** some platforms; on others it may set the value of the +** environment variable to the null-string. +** +** For example, to test for NULL return or return of the +** null-string from PR_GetEnv(), use the following code +** fragment: +** +** char *val = PR_GetEnv("foo"); +** if ((NULL == val) || ('\0' == *val)) { +** ... interpret this as un-set ... +** } +** +** The caller must ensure that the string passed +** to PR_SetEnv() is persistent. That is: The string should +** not be on the stack, where it can be overwritten +** on return from the function calling PR_SetEnv(). +** Similarly, the string passed to PR_SetEnv() must not be +** overwritten by other actions of the process. ... Some +** platforms use the string by reference rather than copying +** it into the environment space. ... You have been warned! +** +** Use of platform-native functions that manipulate the +** environment (getenv(), putenv(), +** SetEnvironmentVariable(), etc.) must not be used with +** NSPR's similar functions. The platform-native functions +** may not be thread safe and/or may operate on different +** conceptual environment space than that operated upon by +** NSPR's functions or other environment manipulating +** functions on the same platform. (!) +** +*/ +NSPR_API(char*) PR_GetEnv(const char *var); + +/* +** PR_SetEnv() -- set, unset or change an environment variable +** +** Description: +** PR_SetEnv() is modeled on the Unix putenv() function. +** +** Inputs: +** string -- pointer to a caller supplied +** constant, persistent string of the form name=value. Where +** name is the name of the environment variable to be set or +** changed; value is the value assigned to the variable. +** +** Returns: +** PRStatus. +** +** Restrictions: +** See the Restrictions documented in the description of +** PR_GetEnv() in this header file. +** +** +*/ +NSPR_API(PRStatus) PR_SetEnv(const char *string); + +PR_END_EXTERN_C + +#endif /* prenv_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prerr.h nspr-4.10.7/nspr/pr/include/prerr.h --- nspr-4.9.5/nspr/pr/include/prerr.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prerr.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,249 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prerr_h___ +#define prerr_h___ + +/* + * + * prerr.h + * This file is automatically generated; please do not edit it. + */ + +/* Memory allocation attempt failed */ +#define PR_OUT_OF_MEMORY_ERROR (-6000L) + +/* Invalid file descriptor */ +#define PR_BAD_DESCRIPTOR_ERROR (-5999L) + +/* The operation would have blocked */ +#define PR_WOULD_BLOCK_ERROR (-5998L) + +/* Invalid memory address argument */ +#define PR_ACCESS_FAULT_ERROR (-5997L) + +/* Invalid function for file type */ +#define PR_INVALID_METHOD_ERROR (-5996L) + +/* Invalid memory address argument */ +#define PR_ILLEGAL_ACCESS_ERROR (-5995L) + +/* Some unknown error has occurred */ +#define PR_UNKNOWN_ERROR (-5994L) + +/* Operation interrupted by another thread */ +#define PR_PENDING_INTERRUPT_ERROR (-5993L) + +/* function not implemented */ +#define PR_NOT_IMPLEMENTED_ERROR (-5992L) + +/* I/O function error */ +#define PR_IO_ERROR (-5991L) + +/* I/O operation timed out */ +#define PR_IO_TIMEOUT_ERROR (-5990L) + +/* I/O operation on busy file descriptor */ +#define PR_IO_PENDING_ERROR (-5989L) + +/* The directory could not be opened */ +#define PR_DIRECTORY_OPEN_ERROR (-5988L) + +/* Invalid function argument */ +#define PR_INVALID_ARGUMENT_ERROR (-5987L) + +/* Network address not available (in use?) */ +#define PR_ADDRESS_NOT_AVAILABLE_ERROR (-5986L) + +/* Network address type not supported */ +#define PR_ADDRESS_NOT_SUPPORTED_ERROR (-5985L) + +/* Already connected */ +#define PR_IS_CONNECTED_ERROR (-5984L) + +/* Network address is invalid */ +#define PR_BAD_ADDRESS_ERROR (-5983L) + +/* Local Network address is in use */ +#define PR_ADDRESS_IN_USE_ERROR (-5982L) + +/* Connection refused by peer */ +#define PR_CONNECT_REFUSED_ERROR (-5981L) + +/* Network address is presently unreachable */ +#define PR_NETWORK_UNREACHABLE_ERROR (-5980L) + +/* Connection attempt timed out */ +#define PR_CONNECT_TIMEOUT_ERROR (-5979L) + +/* Network file descriptor is not connected */ +#define PR_NOT_CONNECTED_ERROR (-5978L) + +/* Failure to load dynamic library */ +#define PR_LOAD_LIBRARY_ERROR (-5977L) + +/* Failure to unload dynamic library */ +#define PR_UNLOAD_LIBRARY_ERROR (-5976L) + +/* Symbol not found in any of the loaded dynamic libraries */ +#define PR_FIND_SYMBOL_ERROR (-5975L) + +/* Insufficient system resources */ +#define PR_INSUFFICIENT_RESOURCES_ERROR (-5974L) + +/* A directory lookup on a network address has failed */ +#define PR_DIRECTORY_LOOKUP_ERROR (-5973L) + +/* Attempt to access a TPD key that is out of range */ +#define PR_TPD_RANGE_ERROR (-5972L) + +/* Process open FD table is full */ +#define PR_PROC_DESC_TABLE_FULL_ERROR (-5971L) + +/* System open FD table is full */ +#define PR_SYS_DESC_TABLE_FULL_ERROR (-5970L) + +/* Network operation attempted on non-network file descriptor */ +#define PR_NOT_SOCKET_ERROR (-5969L) + +/* TCP-specific function attempted on a non-TCP file descriptor */ +#define PR_NOT_TCP_SOCKET_ERROR (-5968L) + +/* TCP file descriptor is already bound */ +#define PR_SOCKET_ADDRESS_IS_BOUND_ERROR (-5967L) + +/* Access Denied */ +#define PR_NO_ACCESS_RIGHTS_ERROR (-5966L) + +/* The requested operation is not supported by the platform */ +#define PR_OPERATION_NOT_SUPPORTED_ERROR (-5965L) + +/* The host operating system does not support the protocol requested */ +#define PR_PROTOCOL_NOT_SUPPORTED_ERROR (-5964L) + +/* Access to the remote file has been severed */ +#define PR_REMOTE_FILE_ERROR (-5963L) + +/* The value requested is too large to be stored in the data buffer provided */ +#define PR_BUFFER_OVERFLOW_ERROR (-5962L) + +/* TCP connection reset by peer */ +#define PR_CONNECT_RESET_ERROR (-5961L) + +/* Unused */ +#define PR_RANGE_ERROR (-5960L) + +/* The operation would have deadlocked */ +#define PR_DEADLOCK_ERROR (-5959L) + +/* The file is already locked */ +#define PR_FILE_IS_LOCKED_ERROR (-5958L) + +/* Write would result in file larger than the system allows */ +#define PR_FILE_TOO_BIG_ERROR (-5957L) + +/* The device for storing the file is full */ +#define PR_NO_DEVICE_SPACE_ERROR (-5956L) + +/* Unused */ +#define PR_PIPE_ERROR (-5955L) + +/* Unused */ +#define PR_NO_SEEK_DEVICE_ERROR (-5954L) + +/* Cannot perform a normal file operation on a directory */ +#define PR_IS_DIRECTORY_ERROR (-5953L) + +/* Symbolic link loop */ +#define PR_LOOP_ERROR (-5952L) + +/* File name is too long */ +#define PR_NAME_TOO_LONG_ERROR (-5951L) + +/* File not found */ +#define PR_FILE_NOT_FOUND_ERROR (-5950L) + +/* Cannot perform directory operation on a normal file */ +#define PR_NOT_DIRECTORY_ERROR (-5949L) + +/* Cannot write to a read-only file system */ +#define PR_READ_ONLY_FILESYSTEM_ERROR (-5948L) + +/* Cannot delete a directory that is not empty */ +#define PR_DIRECTORY_NOT_EMPTY_ERROR (-5947L) + +/* Cannot delete or rename a file object while the file system is busy */ +#define PR_FILESYSTEM_MOUNTED_ERROR (-5946L) + +/* Cannot rename a file to a file system on another device */ +#define PR_NOT_SAME_DEVICE_ERROR (-5945L) + +/* The directory object in the file system is corrupted */ +#define PR_DIRECTORY_CORRUPTED_ERROR (-5944L) + +/* Cannot create or rename a filename that already exists */ +#define PR_FILE_EXISTS_ERROR (-5943L) + +/* Directory is full. No additional filenames may be added */ +#define PR_MAX_DIRECTORY_ENTRIES_ERROR (-5942L) + +/* The required device was in an invalid state */ +#define PR_INVALID_DEVICE_STATE_ERROR (-5941L) + +/* The device is locked */ +#define PR_DEVICE_IS_LOCKED_ERROR (-5940L) + +/* No more entries in the directory */ +#define PR_NO_MORE_FILES_ERROR (-5939L) + +/* Encountered end of file */ +#define PR_END_OF_FILE_ERROR (-5938L) + +/* Seek error */ +#define PR_FILE_SEEK_ERROR (-5937L) + +/* The file is busy */ +#define PR_FILE_IS_BUSY_ERROR (-5936L) + +/* The I/O operation was aborted */ +#define PR_OPERATION_ABORTED_ERROR (-5935L) + +/* Operation is still in progress (probably a non-blocking connect) */ +#define PR_IN_PROGRESS_ERROR (-5934L) + +/* Operation has already been initiated (probably a non-blocking connect) */ +#define PR_ALREADY_INITIATED_ERROR (-5933L) + +/* The wait group is empty */ +#define PR_GROUP_EMPTY_ERROR (-5932L) + +/* Object state improper for request */ +#define PR_INVALID_STATE_ERROR (-5931L) + +/* Network is down */ +#define PR_NETWORK_DOWN_ERROR (-5930L) + +/* Socket shutdown */ +#define PR_SOCKET_SHUTDOWN_ERROR (-5929L) + +/* Connection aborted */ +#define PR_CONNECT_ABORTED_ERROR (-5928L) + +/* Host is unreachable */ +#define PR_HOST_UNREACHABLE_ERROR (-5927L) + +/* The library is not loaded */ +#define PR_LIBRARY_NOT_LOADED_ERROR (-5926L) + +/* The one-time function was previously called and failed. Its error code is no longer available */ +#define PR_CALL_ONCE_ERROR (-5925L) + +/* Placeholder for the end of the list */ +#define PR_MAX_ERROR (-5924L) + +extern void nspr_InitializePRErrorTable(void); +#define ERROR_TABLE_BASE_nspr (-6000L) + +#endif /* prerr_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prerror.h nspr-4.10.7/nspr/pr/include/prerror.h --- nspr-4.9.5/nspr/pr/include/prerror.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prerror.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,294 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prerror_h___ +#define prerror_h___ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +typedef PRInt32 PRErrorCode; + +#define PR_NSPR_ERROR_BASE -6000 + +#include "prerr.h" + +/* +** Set error will preserve an error condition within a thread context. +** The values stored are the NSPR (platform independent) translation of +** the error. Also, if available, the platform specific oserror is stored. +** If there is no appropriate OS error number, a zero my be supplied. +*/ +NSPR_API(void) PR_SetError(PRErrorCode errorCode, PRInt32 oserr); + +/* +** The text value specified may be NULL. If it is not NULL and the text length +** is zero, the string is assumed to be a null terminated C string. Otherwise +** the text is assumed to be the length specified and possibly include NULL +** characters (e.g., a multi-national string). +** +** The text will be copied into to thread structure and remain there +** until the next call to PR_SetError. +*/ +NSPR_API(void) PR_SetErrorText( + PRIntn textLength, const char *text); + +/* +** Return the current threads last set error code. +*/ +NSPR_API(PRErrorCode) PR_GetError(void); + +/* +** Return the current threads last set os error code. This is used for +** machine specific code that desires the underlying os error. +*/ +NSPR_API(PRInt32) PR_GetOSError(void); + +/* +** Get the length of the error text. If a zero is returned, then there +** is no text. Otherwise, the value returned is sufficient to contain +** the error text currently available. +*/ +NSPR_API(PRInt32) PR_GetErrorTextLength(void); + +/* +** Copy the current threads current error text. Then actual number of bytes +** copied is returned as the result. If the result is zero, the 'text' area +** is unaffected. +*/ +NSPR_API(PRInt32) PR_GetErrorText(char *text); + + +/* +Copyright (C) 1987, 1988 Student Information Processing Board of the +Massachusetts Institute of Technology. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be +used in advertising or publicity pertaining to distribution of the software +without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B. +make no representations about the suitability of this software for any +purpose. It is provided "as is" without express or implied warranty. +*/ + + +/* + * NOTE: + * The interfaces for error-code-translation described in the rest of + * this file are preliminary in the 3.1 release of nspr and are subject + * to change in future releases. + */ + +/* +** Description: Localizable error code to string function. +** +** +** NSPR provides a mechanism for converting an error code to a +** descriptive string, in a caller-specified language. +** +** Error codes themselves are 32 bit (signed) integers. Typically, +** the high order 24 bits are an identifier of which error table the +** error code is from, and the low order 8 bits are a sequential error +** number within the table. NSPR supports error tables whose first +** error code is not a multiple of 256, such error code assignments +** should be avoided when possible. +** +** Error table 0 is defined to match the UNIX system call error table +** (sys_errlist); this allows errno values to be used directly in the +** library. Other error table numbers are typically formed by +** compacting together the first four characters of the error table +** name. The mapping between characters in the name and numeric +** values in the error code are defined in a system-independent +** fashion, so that two systems that can pass integral values between +** them can reliably pass error codes without loss of meaning; this +** should work even if the character sets used are not the +** same. (However, if this is to be done, error table 0 should be +** avoided, since the local system call error tables may differ.) +** +** Libraries defining error codes need only provide a table mapping +** error code numbers to names and default English descriptions, +** calling a routine to install the table, making it ``known'' to NSPR +** library. Once installed, a table may not be removed. Any error +** code the library generates can be converted to the corresponding +** error message. There is also a default format for error codes +** accidentally returned before making the table known, which is of +** the form "unknown code foo 32", where "foo" would be the name of +** the table. +** +** Normally, the error code conversion routine only supports the +** languages "i-default" and "en", returning the error-table-provided +** English description for both languages. The application may +** provide a localization plugin, allowing support for additional +** languages. +** +**/ + +/**********************************************************************/ +/************************* TYPES AND CONSTANTS ************************/ +/**********************************************************************/ + +/* + * PRLanguageCode -- + * + * NSPR represents a language code as a non-negative integer. + * Languages 0 is always "i-default" the language you get without + * explicit negotiation. Language 1 is always "en", English + * which has been explicitly negotiated. Additional language + * codes are defined by an application-provided localization plugin. + */ +typedef PRUint32 PRLanguageCode; +#define PR_LANGUAGE_I_DEFAULT 0 /* i-default, the default language */ +#define PR_LANGUAGE_EN 1 /* English, explicitly negotiated */ + +/* + * struct PRErrorMessage -- + * + * An error message in an error table. + */ +struct PRErrorMessage { + const char * name; /* Macro name for error */ + const char * en_text; /* Default English text */ +}; + +/* + * struct PRErrorTable -- + * + * An error table, provided by a library. + */ +struct PRErrorTable { + const struct PRErrorMessage * msgs; /* Array of error information */ + const char *name; /* Name of error table source */ + PRErrorCode base; /* Error code for first error in table */ + int n_msgs; /* Number of codes in table */ +}; + +/* + * struct PRErrorCallbackPrivate -- + * + * A private structure for the localization plugin + */ +struct PRErrorCallbackPrivate; + +/* + * struct PRErrorCallbackTablePrivate -- + * + * A data structure under which the localization plugin may store information, + * associated with an error table, that is private to itself. + */ +struct PRErrorCallbackTablePrivate; + +/* + * PRErrorCallbackLookupFn -- + * + * A function of PRErrorCallbackLookupFn type is a localization + * plugin callback which converts an error code into a description + * in the requested language. The callback is provided the + * appropriate error table, private data for the plugin and the table. + * The callback returns the appropriate UTF-8 encoded description, or NULL + * if no description can be found. + */ +typedef const char * +PRErrorCallbackLookupFn(PRErrorCode code, PRLanguageCode language, + const struct PRErrorTable *table, + struct PRErrorCallbackPrivate *cb_private, + struct PRErrorCallbackTablePrivate *table_private); + +/* + * PRErrorCallbackNewTableFn -- + * + * A function PRErrorCallbackNewTableFn type is a localization plugin + * callback which is called once with each error table registered + * with NSPR. The callback is provided with the error table and + * the plugin's private structure. The callback returns any table private + * data it wishes to associate with the error table. Does not need to be thread + * safe. + */ +typedef struct PRErrorCallbackTablePrivate * +PRErrorCallbackNewTableFn(const struct PRErrorTable *table, + struct PRErrorCallbackPrivate *cb_private); + +/**********************************************************************/ +/****************************** FUNCTIONS *****************************/ +/**********************************************************************/ + +/*********************************************************************** +** FUNCTION: PR_ErrorToString +** DESCRIPTION: +** Returns the UTF-8 message for an error code in +** the requested language. May return the message +** in the default language if a translation in the requested +** language is not available. The returned string is +** valid for the duration of the process. Never returns NULL. +** +***********************************************************************/ +NSPR_API(const char *) PR_ErrorToString(PRErrorCode code, + PRLanguageCode language); + + +/*********************************************************************** +** FUNCTION: PR_ErrorToName +** DESCRIPTION: +** Returns the macro name for an error code, or NULL +** if the error code is not known. The returned string is +** valid for the duration of the process. +** +** Does not work for error table 0, the system error codes. +** +***********************************************************************/ +NSPR_API(const char *) PR_ErrorToName(PRErrorCode code); + + +/*********************************************************************** +** FUNCTION: PR_ErrorLanguages +** DESCRIPTION: +** Returns the RFC 1766 language tags for the language +** codes PR_ErrorToString() supports. The returned array is valid +** for the duration of the process. Never returns NULL. The first +** item in the returned array is the language tag for PRLanguageCode 0, +** the second is for PRLanguageCode 1, and so on. The array is terminated +** with a null pointer. +** +***********************************************************************/ +NSPR_API(const char * const *) PR_ErrorLanguages(void); + + +/*********************************************************************** +** FUNCTION: PR_ErrorInstallTable +** DESCRIPTION: +** Registers an error table with NSPR. Must be done exactly once per +** table. Memory pointed to by `table' must remain valid for the life +** of the process. +** +** NOT THREAD SAFE! +** +***********************************************************************/ +NSPR_API(PRErrorCode) PR_ErrorInstallTable(const struct PRErrorTable *table); + + +/*********************************************************************** +** FUNCTION: PR_ErrorInstallCallback +** DESCRIPTION: +** Registers an error localization plugin with NSPR. May be called +** at most one time. `languages' contains the language codes supported +** by this plugin. Languages 0 and 1 must be "i-default" and "en" +** respectively. `lookup' and `newtable' contain pointers to +** the plugin callback functions. `cb_private' contains any information +** private to the plugin functions. +** +** NOT THREAD SAFE! +** +***********************************************************************/ +NSPR_API(void) PR_ErrorInstallCallback(const char * const * languages, + PRErrorCallbackLookupFn *lookup, + PRErrorCallbackNewTableFn *newtable, + struct PRErrorCallbackPrivate *cb_private); + +PR_END_EXTERN_C + +#endif /* prerror_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prinet.h nspr-4.10.7/nspr/pr/include/prinet.h --- nspr-4.9.5/nspr/pr/include/prinet.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prinet.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: prinet.h + * Description: + * Header file used to find the system header files for socket support[1]. + * This file serves the following purposes: + * - A cross-platform, "get-everything" socket header file. On + * Unix, socket support is scattered in several header files, + * while Windows has a "get-everything" socket header file[2]. + * - NSPR needs the following macro definitions and function + * prototype declarations from these header files: + * AF_INET + * INADDR_ANY, INADDR_LOOPBACK, INADDR_BROADCAST + * ntohl(), ntohs(), htonl(), ntons(). + * NSPR does not define its own versions of these macros and + * functions. It simply uses the native versions, which have + * the same names on all supported platforms. + * This file is intended to be included by NSPR public header + * files, such as prio.h. One should not include this file directly. + * + * Notes: + * 1. This file should have been an internal header. Please do not + * depend on it to pull in the system header files you need. + * 2. WARNING: This file is no longer cross-platform as it is a no-op + * for WIN32! See the comment in the WIN32 section for details. + */ + +#ifndef prinet_h__ +#define prinet_h__ + +#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) +#include +#include /* AF_INET */ +#include /* INADDR_ANY, ..., ntohl(), ... */ +#ifdef XP_OS2 +#include +#endif +#ifdef XP_UNIX +#ifdef AIX +/* + * On AIX 4.3, the header refers to struct + * ether_addr and struct sockaddr_dl that are not declared. + * The following struct declarations eliminate the compiler + * warnings. + */ +struct ether_addr; +struct sockaddr_dl; +#endif /* AIX */ +#include +#endif /* XP_UNIX */ +#include + +#if defined(FREEBSD) || defined(BSDI) || defined(QNX) +#include /* the only place that defines INADDR_LOOPBACK */ +#endif + +/* + * OS/2 hack. For some reason INADDR_LOOPBACK is not defined in the + * socket headers. + */ +#if defined(OS2) && !defined(INADDR_LOOPBACK) +#define INADDR_LOOPBACK 0x7f000001 +#endif + +/* + * Prototypes of ntohl() etc. are declared in + * on these platforms. + */ +#if defined(BSDI) || defined(OSF1) +#include +#endif + +/* On Android, ntohl() etc. are declared in . */ +#ifdef __ANDROID__ +#include +#endif + +#elif defined(WIN32) + +/* + * Do not include any system header files. + * + * Originally we were including . It slowed down the + * compilation of files that included NSPR headers, so we removed + * the inclusion at customer's request, which created + * an unfortunate inconsistency with other platforms. + */ + +#else + +#error Unknown platform + +#endif + +#endif /* prinet_h__ */ diff -Nru nspr-4.9.5/nspr/pr/include/prinit.h nspr-4.10.7/nspr/pr/include/prinit.h --- nspr-4.9.5/nspr/pr/include/prinit.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prinit.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,215 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prinit_h___ +#define prinit_h___ + +#include "prthread.h" +#include "prtypes.h" +#include "prwin16.h" +#include + +PR_BEGIN_EXTERN_C + +/************************************************************************/ +/**************************IDENTITY AND VERSIONING***********************/ +/************************************************************************/ + +/* +** NSPR's name, this should persist until at least the turn of the +** century. +*/ +#define PR_NAME "NSPR" + +/* +** NSPR's version is used to determine the likelihood that the version you +** used to build your component is anywhere close to being compatible with +** what is in the underlying library. +** +** The format of the version string is +** ".[.] []" +*/ +#define PR_VERSION "4.10.7" +#define PR_VMAJOR 4 +#define PR_VMINOR 10 +#define PR_VPATCH 7 +#define PR_BETA PR_FALSE + +/* +** PRVersionCheck +** +** The basic signature of the function that is called to provide version +** checking. The result will be a boolean that indicates the likelihood +** that the underling library will perform as the caller expects. +** +** The only argument is a string, which should be the verson identifier +** of the library in question. That string will be compared against an +** equivalent string that represents the actual build version of the +** exporting library. +** +** The result will be the logical union of the directly called library +** and all dependent libraries. +*/ + +typedef PRBool (*PRVersionCheck)(const char*); + +/* +** PR_VersionCheck +** +** NSPR's existance proof of the version check function. +** +** Note that NSPR has no cooperating dependencies. +*/ + +NSPR_API(PRBool) PR_VersionCheck(const char *importedVersion); + +/* + * Returns a const string of the NSPR library version. + */ +NSPR_API(const char*) PR_GetVersion(void); + + +/************************************************************************/ +/*******************************INITIALIZATION***************************/ +/************************************************************************/ + +/* +** Initialize the runtime. Attach a thread object to the currently +** executing native thread of type "type". +** +** The specificaiton of 'maxPTDs' is ignored. +*/ +NSPR_API(void) PR_Init( + PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs); + +/* +** And alternate form of initialization, one that may become the default if +** not the only mechanism, provides a method to get the NSPR runtime init- +** ialized and place NSPR between the caller and the runtime library. This +** allows main() to be treated as any other thread root function, signalling +** its compeletion by returning and allowing the runtime to coordinate the +** completion of the other threads of the runtime. +** +** The priority of the main (or primordial) thread will be PR_PRIORITY_NORMAL. +** The thread may adjust its own priority by using PR_SetPriority(), though +** at this time the support for priorities is somewhat weak. +** +** The specificaiton of 'maxPTDs' is ignored. +** +** The value returned by PR_Initialize is the value returned from the root +** function, 'prmain'. +*/ + +typedef PRIntn (PR_CALLBACK *PRPrimordialFn)(PRIntn argc, char **argv); + +NSPR_API(PRIntn) PR_Initialize( + PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs); + +/* +** Return PR_TRUE if PR_Init has already been called. +*/ +NSPR_API(PRBool) PR_Initialized(void); + +/* + * Perform a graceful shutdown of NSPR. PR_Cleanup() may be called by + * the primordial thread near the end of the main() function. + * + * PR_Cleanup() attempts to synchronize the natural termination of + * process. It does that by blocking the caller, if and only if it is + * the primordial thread, until the number of user threads has dropped + * to zero. When the primordial thread returns from main(), the process + * will immediately and silently exit. That is, it will (if necessary) + * forcibly terminate any existing threads and exit without significant + * blocking and there will be no error messages or core files. + * + * PR_Cleanup() returns PR_SUCCESS if NSPR is successfully shutdown, + * or PR_FAILURE if the calling thread of this function is not the + * primordial thread. + */ +NSPR_API(PRStatus) PR_Cleanup(void); + +/* +** Disable Interrupts +** Disables timer signals used for pre-emptive scheduling. +*/ +NSPR_API(void) PR_DisableClockInterrupts(void); + +/* +** Enables Interrupts +** Enables timer signals used for pre-emptive scheduling. +*/ +NSPR_API(void) PR_EnableClockInterrupts(void); + +/* +** Block Interrupts +** Blocks the timer signal used for pre-emptive scheduling +*/ +NSPR_API(void) PR_BlockClockInterrupts(void); + +/* +** Unblock Interrupts +** Unblocks the timer signal used for pre-emptive scheduling +*/ +NSPR_API(void) PR_UnblockClockInterrupts(void); + +/* +** Create extra virtual processor threads. Generally used with MP systems. +*/ +NSPR_API(void) PR_SetConcurrency(PRUintn numCPUs); + +/* +** Control the method and size of the file descriptor (PRFileDesc*) +** cache used by the runtime. Setting 'high' to zero is for performance, +** any other value probably for debugging (see memo on FD caching). +*/ +NSPR_API(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high); + +/* + * Cause an immediate, nongraceful, forced termination of the process. + * It takes a PRIntn argument, which is the exit status code of the + * process. + */ +NSPR_API(void) PR_ProcessExit(PRIntn status); + +/* +** Abort the process in a non-graceful manner. This will cause a core file, +** call to the debugger or other moral equivalent as well as causing the +** entire process to stop. +*/ +NSPR_API(void) PR_Abort(void); + +/* + **************************************************************** + * + * Module initialization: + * + **************************************************************** + */ + +typedef struct PRCallOnceType { + PRIntn initialized; + PRInt32 inProgress; + PRStatus status; +} PRCallOnceType; + +typedef PRStatus (PR_CALLBACK *PRCallOnceFN)(void); + +typedef PRStatus (PR_CALLBACK *PRCallOnceWithArgFN)(void *arg); + +NSPR_API(PRStatus) PR_CallOnce( + PRCallOnceType *once, + PRCallOnceFN func +); + +NSPR_API(PRStatus) PR_CallOnceWithArg( + PRCallOnceType *once, + PRCallOnceWithArgFN func, + void *arg +); + + +PR_END_EXTERN_C + +#endif /* prinit_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prinrval.h nspr-4.10.7/nspr/pr/include/prinrval.h --- nspr-4.9.5/nspr/pr/include/prinrval.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prinrval.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prinrval.h +** Description: API to interval timing functions of NSPR. +** +** +** NSPR provides interval times that are independent of network time +** of day values. Interval times are (in theory) accurate regardless +** of host processing requirements and also very cheap to acquire. It +** is expected that getting an interval time while in a synchronized +** function (holding one's lock). +**/ + +#if !defined(prinrval_h) +#define prinrval_h + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/**********************************************************************/ +/************************* TYPES AND CONSTANTS ************************/ +/**********************************************************************/ + +typedef PRUint32 PRIntervalTime; + +/*********************************************************************** +** DEFINES: PR_INTERVAL_MIN +** PR_INTERVAL_MAX +** DESCRIPTION: +** These two constants define the range (in ticks / second) of the +** platform dependent type, PRIntervalTime. These constants bound both +** the period and the resolution of a PRIntervalTime. +***********************************************************************/ +#define PR_INTERVAL_MIN 1000UL +#define PR_INTERVAL_MAX 100000UL + +/*********************************************************************** +** DEFINES: PR_INTERVAL_NO_WAIT +** PR_INTERVAL_NO_TIMEOUT +** DESCRIPTION: +** Two reserved constants are defined in the PRIntervalTime namespace. +** They are used to indicate that the process should wait no time (return +** immediately) or wait forever (never time out), respectively. +** Note: PR_INTERVAL_NO_TIMEOUT passed as input to PR_Connect is +** interpreted as use the OS's connect timeout. +** +***********************************************************************/ +#define PR_INTERVAL_NO_WAIT 0UL +#define PR_INTERVAL_NO_TIMEOUT 0xffffffffUL + +/**********************************************************************/ +/****************************** FUNCTIONS *****************************/ +/**********************************************************************/ + +/*********************************************************************** +** FUNCTION: PR_IntervalNow +** DESCRIPTION: +** Return the value of NSPR's free running interval timer. That timer +** can be used to establish epochs and determine intervals (be computing +** the difference between two times). +** INPUTS: void +** OUTPUTS: void +** RETURN: PRIntervalTime +** +** SIDE EFFECTS: +** None +** RESTRICTIONS: +** The units of PRIntervalTime are platform dependent. They are chosen +** such that they are appropriate for the host OS, yet provide sufficient +** resolution and period to be useful to clients. +** MEMORY: N/A +** ALGORITHM: Platform dependent +***********************************************************************/ +NSPR_API(PRIntervalTime) PR_IntervalNow(void); + +/*********************************************************************** +** FUNCTION: PR_TicksPerSecond +** DESCRIPTION: +** Return the number of ticks per second for PR_IntervalNow's clock. +** The value will be in the range [PR_INTERVAL_MIN..PR_INTERVAL_MAX]. +** INPUTS: void +** OUTPUTS: void +** RETURN: PRUint32 +** +** SIDE EFFECTS: +** None +** RESTRICTIONS: +** None +** MEMORY: N/A +** ALGORITHM: N/A +***********************************************************************/ +NSPR_API(PRUint32) PR_TicksPerSecond(void); + +/*********************************************************************** +** FUNCTION: PR_SecondsToInterval +** PR_MillisecondsToInterval +** PR_MicrosecondsToInterval +** DESCRIPTION: +** Convert standard clock units to platform dependent intervals. +** INPUTS: PRUint32 +** OUTPUTS: void +** RETURN: PRIntervalTime +** +** SIDE EFFECTS: +** None +** RESTRICTIONS: +** Conversion may cause overflow, which is not reported. +** MEMORY: N/A +** ALGORITHM: N/A +***********************************************************************/ +NSPR_API(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds); +NSPR_API(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli); +NSPR_API(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro); + +/*********************************************************************** +** FUNCTION: PR_IntervalToSeconds +** PR_IntervalToMilliseconds +** PR_IntervalToMicroseconds +** DESCRIPTION: +** Convert platform dependent intervals to standard clock units. +** INPUTS: PRIntervalTime +** OUTPUTS: void +** RETURN: PRUint32 +** +** SIDE EFFECTS: +** None +** RESTRICTIONS: +** Conversion may cause overflow, which is not reported. +** MEMORY: N/A +** ALGORITHM: N/A +***********************************************************************/ +NSPR_API(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks); +NSPR_API(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks); +NSPR_API(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks); + +PR_END_EXTERN_C + + +#endif /* !defined(prinrval_h) */ + +/* prinrval.h */ diff -Nru nspr-4.9.5/nspr/pr/include/prio.h nspr-4.10.7/nspr/pr/include/prio.h --- nspr-4.9.5/nspr/pr/include/prio.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prio.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,2022 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: prio.h + * + * Description: PR i/o related stuff, such as file system access, file + * i/o, socket i/o, etc. + */ + +#ifndef prio_h___ +#define prio_h___ + +#include "prlong.h" +#include "prtime.h" +#include "prinrval.h" +#include "prinet.h" + +PR_BEGIN_EXTERN_C + +/* Typedefs */ +typedef struct PRDir PRDir; +typedef struct PRDirEntry PRDirEntry; +#ifdef MOZ_UNICODE +typedef struct PRDirUTF16 PRDirUTF16; +typedef struct PRDirEntryUTF16 PRDirEntryUTF16; +#endif /* MOZ_UNICODE */ +typedef struct PRFileDesc PRFileDesc; +typedef struct PRFileInfo PRFileInfo; +typedef struct PRFileInfo64 PRFileInfo64; +typedef union PRNetAddr PRNetAddr; +typedef struct PRIOMethods PRIOMethods; +typedef struct PRPollDesc PRPollDesc; +typedef struct PRFilePrivate PRFilePrivate; +typedef struct PRSendFileData PRSendFileData; + +/* +*************************************************************************** +** The file descriptor. +** This is the primary structure to represent any active open socket, +** whether it be a normal file or a network connection. Such objects +** are stackable (or layerable). Each layer may have its own set of +** method pointers and context private to that layer. All each layer +** knows about its neighbors is how to get to their method table. +*************************************************************************** +*/ + +typedef PRIntn PRDescIdentity; /* see: Layering file descriptors */ + +struct PRFileDesc { + const PRIOMethods *methods; /* the I/O methods table */ + PRFilePrivate *secret; /* layer dependent data */ + PRFileDesc *lower, *higher; /* pointers to adjacent layers */ + void (PR_CALLBACK *dtor)(PRFileDesc *fd); + /* A destructor function for layer */ + PRDescIdentity identity; /* Identity of this particular layer */ +}; + +/* +*************************************************************************** +** PRTransmitFileFlags +** +** Flags for PR_TransmitFile. Pass PR_TRANSMITFILE_CLOSE_SOCKET to +** PR_TransmitFile if the connection should be closed after the file +** is transmitted. +*************************************************************************** +*/ +typedef enum PRTransmitFileFlags { + PR_TRANSMITFILE_KEEP_OPEN = 0, /* socket is left open after file + * is transmitted. */ + PR_TRANSMITFILE_CLOSE_SOCKET = 1 /* socket is closed after file + * is transmitted. */ +} PRTransmitFileFlags; + +/* +************************************************************************** +** Macros for PRNetAddr +** +** Address families: PR_AF_INET, PR_AF_INET6, PR_AF_LOCAL +** IP addresses: PR_INADDR_ANY, PR_INADDR_LOOPBACK, PR_INADDR_BROADCAST +************************************************************************** +*/ + +#ifdef WIN32 + +#define PR_AF_INET 2 +#define PR_AF_LOCAL 1 +#define PR_INADDR_ANY (unsigned long)0x00000000 +#define PR_INADDR_LOOPBACK 0x7f000001 +#define PR_INADDR_BROADCAST (unsigned long)0xffffffff + +#else /* WIN32 */ + +#define PR_AF_INET AF_INET +#define PR_AF_LOCAL AF_UNIX +#define PR_INADDR_ANY INADDR_ANY +#define PR_INADDR_LOOPBACK INADDR_LOOPBACK +#define PR_INADDR_BROADCAST INADDR_BROADCAST + +#endif /* WIN32 */ + +/* +** Define PR_AF_INET6 in prcpucfg.h with the same +** value as AF_INET6 on platforms with IPv6 support. +** Otherwise define it here. +*/ +#ifndef PR_AF_INET6 +#define PR_AF_INET6 100 +#endif + +#define PR_AF_INET_SDP 101 +#define PR_AF_INET6_SDP 102 + +#ifndef PR_AF_UNSPEC +#define PR_AF_UNSPEC 0 +#endif + +/* +************************************************************************** +** A network address +** +** Only Internet Protocol (IPv4 and IPv6) addresses are supported. +** The address family must always represent IPv4 (AF_INET, probably == 2) +** or IPv6 (AF_INET6). +************************************************************************** +*************************************************************************/ + +struct PRIPv6Addr { + union { + PRUint8 _S6_u8[16]; + PRUint16 _S6_u16[8]; + PRUint32 _S6_u32[4]; + PRUint64 _S6_u64[2]; + } _S6_un; +}; +#define pr_s6_addr _S6_un._S6_u8 +#define pr_s6_addr16 _S6_un._S6_u16 +#define pr_s6_addr32 _S6_un._S6_u32 +#define pr_s6_addr64 _S6_un._S6_u64 + +typedef struct PRIPv6Addr PRIPv6Addr; + +union PRNetAddr { + struct { + PRUint16 family; /* address family (0x00ff maskable) */ +#ifdef XP_BEOS + char data[10]; /* Be has a smaller structure */ +#else + char data[14]; /* raw address data */ +#endif + } raw; + struct { + PRUint16 family; /* address family (AF_INET) */ + PRUint16 port; /* port number */ + PRUint32 ip; /* The actual 32 bits of address */ +#ifdef XP_BEOS + char pad[4]; /* Be has a smaller structure */ +#else + char pad[8]; +#endif + } inet; + struct { + PRUint16 family; /* address family (AF_INET6) */ + PRUint16 port; /* port number */ + PRUint32 flowinfo; /* routing information */ + PRIPv6Addr ip; /* the actual 128 bits of address */ + PRUint32 scope_id; /* set of interfaces for a scope */ + } ipv6; +#if defined(XP_UNIX) || defined(XP_OS2) + struct { /* Unix domain socket address */ + PRUint16 family; /* address family (AF_UNIX) */ +#ifdef XP_OS2 + char path[108]; /* null-terminated pathname */ + /* bind fails if size is not 108. */ +#else + char path[104]; /* null-terminated pathname */ +#endif + } local; +#endif +}; + +/* +*************************************************************************** +** PRSockOption +** +** The file descriptors can have predefined options set after they file +** descriptor is created to change their behavior. Only the options in +** the following enumeration are supported. +*************************************************************************** +*/ +typedef enum PRSockOption +{ + PR_SockOpt_Nonblocking, /* nonblocking io */ + PR_SockOpt_Linger, /* linger on close if data present */ + PR_SockOpt_Reuseaddr, /* allow local address reuse */ + PR_SockOpt_Keepalive, /* keep connections alive */ + PR_SockOpt_RecvBufferSize, /* send buffer size */ + PR_SockOpt_SendBufferSize, /* receive buffer size */ + + PR_SockOpt_IpTimeToLive, /* time to live */ + PR_SockOpt_IpTypeOfService, /* type of service and precedence */ + + PR_SockOpt_AddMember, /* add an IP group membership */ + PR_SockOpt_DropMember, /* drop an IP group membership */ + PR_SockOpt_McastInterface, /* multicast interface address */ + PR_SockOpt_McastTimeToLive, /* multicast timetolive */ + PR_SockOpt_McastLoopback, /* multicast loopback */ + + PR_SockOpt_NoDelay, /* don't delay send to coalesce packets */ + PR_SockOpt_MaxSegment, /* maximum segment size */ + PR_SockOpt_Broadcast, /* enable broadcast */ + PR_SockOpt_Reuseport, /* allow local address & port reuse on + * platforms that support it */ + PR_SockOpt_Last +} PRSockOption; + +typedef struct PRLinger { + PRBool polarity; /* Polarity of the option's setting */ + PRIntervalTime linger; /* Time to linger before closing */ +} PRLinger; + +typedef struct PRMcastRequest { + PRNetAddr mcaddr; /* IP multicast address of group */ + PRNetAddr ifaddr; /* local IP address of interface */ +} PRMcastRequest; + +typedef struct PRSocketOptionData +{ + PRSockOption option; + union + { + PRUintn ip_ttl; /* IP time to live */ + PRUintn mcast_ttl; /* IP multicast time to live */ + PRUintn tos; /* IP type of service and precedence */ + PRBool non_blocking; /* Non-blocking (network) I/O */ + PRBool reuse_addr; /* Allow local address reuse */ + PRBool reuse_port; /* Allow local address & port reuse on + * platforms that support it */ + PRBool keep_alive; /* Keep connections alive */ + PRBool mcast_loopback; /* IP multicast loopback */ + PRBool no_delay; /* Don't delay send to coalesce packets */ + PRBool broadcast; /* Enable broadcast */ + PRSize max_segment; /* Maximum segment size */ + PRSize recv_buffer_size; /* Receive buffer size */ + PRSize send_buffer_size; /* Send buffer size */ + PRLinger linger; /* Time to linger on close if data present */ + PRMcastRequest add_member; /* add an IP group membership */ + PRMcastRequest drop_member; /* Drop an IP group membership */ + PRNetAddr mcast_if; /* multicast interface address */ + } value; +} PRSocketOptionData; + +/* +*************************************************************************** +** PRIOVec +** +** The I/O vector is used by the write vector method to describe the areas +** that are affected by the ouput operation. +*************************************************************************** +*/ +typedef struct PRIOVec { + char *iov_base; + int iov_len; +} PRIOVec; + +/* +*************************************************************************** +** Discover what type of socket is being described by the file descriptor. +*************************************************************************** +*/ +typedef enum PRDescType +{ + PR_DESC_FILE = 1, + PR_DESC_SOCKET_TCP = 2, + PR_DESC_SOCKET_UDP = 3, + PR_DESC_LAYERED = 4, + PR_DESC_PIPE = 5 +} PRDescType; + +typedef enum PRSeekWhence { + PR_SEEK_SET = 0, + PR_SEEK_CUR = 1, + PR_SEEK_END = 2 +} PRSeekWhence; + +NSPR_API(PRDescType) PR_GetDescType(PRFileDesc *file); + +/* +*************************************************************************** +** PRIOMethods +** +** The I/O methods table provides procedural access to the functions of +** the file descriptor. It is the responsibility of a layer implementor +** to provide suitable functions at every entry point. If a layer provides +** no functionality, it should call the next lower(higher) function of the +** same name (e.g., return fd->lower->method->close(fd->lower)); +** +** Not all functions are implemented for all types of files. In cases where +** that is true, the function will return a error indication with an error +** code of PR_INVALID_METHOD_ERROR. +*************************************************************************** +*/ + +typedef PRStatus (PR_CALLBACK *PRCloseFN)(PRFileDesc *fd); +typedef PRInt32 (PR_CALLBACK *PRReadFN)(PRFileDesc *fd, void *buf, PRInt32 amount); +typedef PRInt32 (PR_CALLBACK *PRWriteFN)(PRFileDesc *fd, const void *buf, PRInt32 amount); +typedef PRInt32 (PR_CALLBACK *PRAvailableFN)(PRFileDesc *fd); +typedef PRInt64 (PR_CALLBACK *PRAvailable64FN)(PRFileDesc *fd); +typedef PRStatus (PR_CALLBACK *PRFsyncFN)(PRFileDesc *fd); +typedef PROffset32 (PR_CALLBACK *PRSeekFN)(PRFileDesc *fd, PROffset32 offset, PRSeekWhence how); +typedef PROffset64 (PR_CALLBACK *PRSeek64FN)(PRFileDesc *fd, PROffset64 offset, PRSeekWhence how); +typedef PRStatus (PR_CALLBACK *PRFileInfoFN)(PRFileDesc *fd, PRFileInfo *info); +typedef PRStatus (PR_CALLBACK *PRFileInfo64FN)(PRFileDesc *fd, PRFileInfo64 *info); +typedef PRInt32 (PR_CALLBACK *PRWritevFN)( + PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, + PRIntervalTime timeout); +typedef PRStatus (PR_CALLBACK *PRConnectFN)( + PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout); +typedef PRFileDesc* (PR_CALLBACK *PRAcceptFN) ( + PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout); +typedef PRStatus (PR_CALLBACK *PRBindFN)(PRFileDesc *fd, const PRNetAddr *addr); +typedef PRStatus (PR_CALLBACK *PRListenFN)(PRFileDesc *fd, PRIntn backlog); +typedef PRStatus (PR_CALLBACK *PRShutdownFN)(PRFileDesc *fd, PRIntn how); +typedef PRInt32 (PR_CALLBACK *PRRecvFN)( + PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout); +typedef PRInt32 (PR_CALLBACK *PRSendFN) ( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout); +typedef PRInt32 (PR_CALLBACK *PRRecvfromFN)( + PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout); +typedef PRInt32 (PR_CALLBACK *PRSendtoFN)( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout); +typedef PRInt16 (PR_CALLBACK *PRPollFN)( + PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags); +typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)( + PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, + void *buf, PRInt32 amount, PRIntervalTime t); +typedef PRInt32 (PR_CALLBACK *PRTransmitfileFN)( + PRFileDesc *sd, PRFileDesc *fd, const void *headers, + PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime t); +typedef PRStatus (PR_CALLBACK *PRGetsocknameFN)(PRFileDesc *fd, PRNetAddr *addr); +typedef PRStatus (PR_CALLBACK *PRGetpeernameFN)(PRFileDesc *fd, PRNetAddr *addr); +typedef PRStatus (PR_CALLBACK *PRGetsocketoptionFN)( + PRFileDesc *fd, PRSocketOptionData *data); +typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)( + PRFileDesc *fd, const PRSocketOptionData *data); +typedef PRInt32 (PR_CALLBACK *PRSendfileFN)( + PRFileDesc *networkSocket, PRSendFileData *sendData, + PRTransmitFileFlags flags, PRIntervalTime timeout); +typedef PRStatus (PR_CALLBACK *PRConnectcontinueFN)( + PRFileDesc *fd, PRInt16 out_flags); +typedef PRIntn (PR_CALLBACK *PRReservedFN)(PRFileDesc *fd); + +struct PRIOMethods { + PRDescType file_type; /* Type of file represented (tos) */ + PRCloseFN close; /* close file and destroy descriptor */ + PRReadFN read; /* read up to specified bytes into buffer */ + PRWriteFN write; /* write specified bytes from buffer */ + PRAvailableFN available; /* determine number of bytes available */ + PRAvailable64FN available64; /* ditto, 64 bit */ + PRFsyncFN fsync; /* flush all buffers to permanent store */ + PRSeekFN seek; /* position the file to the desired place */ + PRSeek64FN seek64; /* ditto, 64 bit */ + PRFileInfoFN fileInfo; /* Get information about an open file */ + PRFileInfo64FN fileInfo64; /* ditto, 64 bit */ + PRWritevFN writev; /* Write segments as described by iovector */ + PRConnectFN connect; /* Connect to the specified (net) address */ + PRAcceptFN accept; /* Accept a connection for a (net) peer */ + PRBindFN bind; /* Associate a (net) address with the fd */ + PRListenFN listen; /* Prepare to listen for (net) connections */ + PRShutdownFN shutdown; /* Shutdown a (net) connection */ + PRRecvFN recv; /* Solicit up the the specified bytes */ + PRSendFN send; /* Send all the bytes specified */ + PRRecvfromFN recvfrom; /* Solicit (net) bytes and report source */ + PRSendtoFN sendto; /* Send bytes to (net) address specified */ + PRPollFN poll; /* Test the fd to see if it is ready */ + PRAcceptreadFN acceptread; /* Accept and read on a new (net) fd */ + PRTransmitfileFN transmitfile; /* Transmit at entire file */ + PRGetsocknameFN getsockname; /* Get (net) address associated with fd */ + PRGetpeernameFN getpeername; /* Get peer's (net) address */ + PRReservedFN reserved_fn_6; /* reserved for future use */ + PRReservedFN reserved_fn_5; /* reserved for future use */ + PRGetsocketoptionFN getsocketoption; + /* Get current setting of specified option */ + PRSetsocketoptionFN setsocketoption; + /* Set value of specified option */ + PRSendfileFN sendfile; /* Send a (partial) file with header/trailer*/ + PRConnectcontinueFN connectcontinue; + /* Continue a nonblocking connect */ + PRReservedFN reserved_fn_3; /* reserved for future use */ + PRReservedFN reserved_fn_2; /* reserved for future use */ + PRReservedFN reserved_fn_1; /* reserved for future use */ + PRReservedFN reserved_fn_0; /* reserved for future use */ +}; + +/* + ************************************************************************** + * FUNCTION: PR_GetSpecialFD + * DESCRIPTION: Get the file descriptor that represents the standard input, + * output, or error stream. + * INPUTS: + * PRSpecialFD id + * A value indicating the type of stream desired: + * PR_StandardInput: standard input + * PR_StandardOuput: standard output + * PR_StandardError: standard error + * OUTPUTS: none + * RETURNS: PRFileDesc * + * If the argument is valid, PR_GetSpecialFD returns a file descriptor + * that represents the corresponding standard I/O stream. Otherwise, + * PR_GetSpecialFD returns NULL and sets error PR_INVALID_ARGUMENT_ERROR. + ************************************************************************** + */ + +typedef enum PRSpecialFD +{ + PR_StandardInput, /* standard input */ + PR_StandardOutput, /* standard output */ + PR_StandardError /* standard error */ +} PRSpecialFD; + +NSPR_API(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD id); + +#define PR_STDIN PR_GetSpecialFD(PR_StandardInput) +#define PR_STDOUT PR_GetSpecialFD(PR_StandardOutput) +#define PR_STDERR PR_GetSpecialFD(PR_StandardError) + +/* + ************************************************************************** + * Layering file descriptors + * + * File descriptors may be layered. Each layer has it's own identity. + * Identities are allocated by the runtime and are to be associated + * (by the layer implementor) with all layers that are of that type. + * It is then possible to scan the chain of layers and find a layer + * that one recongizes and therefore predict that it will implement + * a desired protocol. + * + * There are three well-known identities: + * PR_INVALID_IO_LAYER => an invalid layer identity, for error return + * PR_TOP_IO_LAYER => the identity of the top of the stack + * PR_NSPR_IO_LAYER => the identity used by NSPR proper + * PR_TOP_IO_LAYER may be used as a shorthand for identifying the topmost + * layer of an existing stack. Ie., the following two constructs are + * equivalent. + * + * rv = PR_PushIOLayer(stack, PR_TOP_IO_LAYER, my_layer); + * rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), my_layer) + * + * A string may be associated with the creation of the identity. It + * will be copied by the runtime. If queried the runtime will return + * a reference to that copied string (not yet another copy). There + * is no facility for deleting an identity. + ************************************************************************** + */ + +#define PR_IO_LAYER_HEAD (PRDescIdentity)-3 +#define PR_INVALID_IO_LAYER (PRDescIdentity)-1 +#define PR_TOP_IO_LAYER (PRDescIdentity)-2 +#define PR_NSPR_IO_LAYER (PRDescIdentity)0 + +NSPR_API(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name); +NSPR_API(const char*) PR_GetNameForIdentity(PRDescIdentity ident); +NSPR_API(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd); +NSPR_API(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd_stack, PRDescIdentity id); + +/* + ************************************************************************** + * PR_GetDefaultIOMethods: Accessing the default methods table. + * You may get a pointer to the default methods table by calling this function. + * You may then select any elements from that table with which to build your + * layer's methods table. You may NOT modify the table directly. + ************************************************************************** + */ +NSPR_API(const PRIOMethods *) PR_GetDefaultIOMethods(void); + +/* + ************************************************************************** + * Creating a layer + * + * A new layer may be allocated by calling PR_CreateIOLayerStub(). The + * file descriptor returned will contain the pointer to the methods table + * provided. The runtime will not modify the table nor test its correctness. + ************************************************************************** + */ +NSPR_API(PRFileDesc*) PR_CreateIOLayerStub( + PRDescIdentity ident, const PRIOMethods *methods); + +/* + ************************************************************************** + * Creating a layer + * + * A new stack may be created by calling PR_CreateIOLayer(). The + * file descriptor returned will point to the top of the stack, which has + * the layer 'fd' as the topmost layer. + * + * NOTE: This function creates a new style stack, which has a fixed, dummy + * header. The old style stack, created by a call to PR_PushIOLayer, + * results in modifying contents of the top layer of the stack, when + * pushing and popping layers of the stack. + ************************************************************************** + */ +NSPR_API(PRFileDesc*) PR_CreateIOLayer(PRFileDesc* fd); + +/* + ************************************************************************** + * Pushing a layer + * + * A file descriptor (perhaps allocated using PR_CreateIOLayerStub()) may + * be pushed into an existing stack of file descriptors at any point the + * caller deems appropriate. The new layer will be inserted into the stack + * just above the layer with the indicated identity. + * + * Note: Even if the identity parameter indicates the top-most layer of + * the stack, the value of the file descriptor describing the original + * stack will not change. + ************************************************************************** + */ +NSPR_API(PRStatus) PR_PushIOLayer( + PRFileDesc *fd_stack, PRDescIdentity id, PRFileDesc *layer); + +/* + ************************************************************************** + * Popping a layer + * + * A layer may be popped from a stack by indicating the identity of the + * layer to be removed. If found, a pointer to the removed object will + * be returned to the caller. The object then becomes the responsibility + * of the caller. + * + * Note: Even if the identity indicates the top layer of the stack, the + * reference returned will not be the file descriptor for the stack and + * that file descriptor will remain valid. + ************************************************************************** + */ +NSPR_API(PRFileDesc*) PR_PopIOLayer(PRFileDesc *fd_stack, PRDescIdentity id); + +/* + ************************************************************************** + * FUNCTION: PR_Open + * DESCRIPTION: Open a file for reading, writing, or both. + * INPUTS: + * const char *name + * The path name of the file to be opened + * PRIntn flags + * The file status flags. + * It is a bitwise OR of the following bit flags (only one of + * the first three flags below may be used): + * PR_RDONLY Open for reading only. + * PR_WRONLY Open for writing only. + * PR_RDWR Open for reading and writing. + * PR_CREATE_FILE If the file does not exist, the file is created + * If the file exists, this flag has no effect. + * PR_SYNC If set, each write will wait for both the file data + * and file status to be physically updated. + * PR_APPEND The file pointer is set to the end of + * the file prior to each write. + * PR_TRUNCATE If the file exists, its length is truncated to 0. + * PR_EXCL With PR_CREATE_FILE, if the file does not exist, + * the file is created. If the file already + * exists, no action and NULL is returned + * + * PRIntn mode + * The access permission bits of the file mode, if the file is + * created when PR_CREATE_FILE is on. + * OUTPUTS: None + * RETURNS: PRFileDesc * + * If the file is successfully opened, + * returns a pointer to the PRFileDesc + * created for the newly opened file. + * Returns a NULL pointer if the open + * failed. + * SIDE EFFECTS: + * RESTRICTIONS: + * MEMORY: + * The return value, if not NULL, points to a dynamically allocated + * PRFileDesc object. + * ALGORITHM: + ************************************************************************** + */ + +/* Open flags */ +#define PR_RDONLY 0x01 +#define PR_WRONLY 0x02 +#define PR_RDWR 0x04 +#define PR_CREATE_FILE 0x08 +#define PR_APPEND 0x10 +#define PR_TRUNCATE 0x20 +#define PR_SYNC 0x40 +#define PR_EXCL 0x80 + +/* +** File modes .... +** +** CAVEAT: 'mode' is currently only applicable on UNIX platforms. +** The 'mode' argument may be ignored by PR_Open on other platforms. +** +** 00400 Read by owner. +** 00200 Write by owner. +** 00100 Execute (search if a directory) by owner. +** 00040 Read by group. +** 00020 Write by group. +** 00010 Execute by group. +** 00004 Read by others. +** 00002 Write by others +** 00001 Execute by others. +** +*/ + +NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode); + +/* + ************************************************************************** + * FUNCTION: PR_OpenFile + * DESCRIPTION: + * Open a file for reading, writing, or both. + * PR_OpenFile has the same prototype as PR_Open but implements + * the specified file mode where possible. + ************************************************************************** + */ + +/* File mode bits */ +#define PR_IRWXU 00700 /* read, write, execute/search by owner */ +#define PR_IRUSR 00400 /* read permission, owner */ +#define PR_IWUSR 00200 /* write permission, owner */ +#define PR_IXUSR 00100 /* execute/search permission, owner */ +#define PR_IRWXG 00070 /* read, write, execute/search by group */ +#define PR_IRGRP 00040 /* read permission, group */ +#define PR_IWGRP 00020 /* write permission, group */ +#define PR_IXGRP 00010 /* execute/search permission, group */ +#define PR_IRWXO 00007 /* read, write, execute/search by others */ +#define PR_IROTH 00004 /* read permission, others */ +#define PR_IWOTH 00002 /* write permission, others */ +#define PR_IXOTH 00001 /* execute/search permission, others */ + +NSPR_API(PRFileDesc*) PR_OpenFile( + const char *name, PRIntn flags, PRIntn mode); + +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRFileDesc*) PR_OpenFileUTF16( + const PRUnichar *name, PRIntn flags, PRIntn mode); +#endif /* MOZ_UNICODE */ + +/* + ************************************************************************** + * FUNCTION: PR_Close + * DESCRIPTION: + * Close a file or socket. + * INPUTS: + * PRFileDesc *fd + * a pointer to a PRFileDesc. + * OUTPUTS: + * None. + * RETURN: + * PRStatus + * SIDE EFFECTS: + * RESTRICTIONS: + * None. + * MEMORY: + * The dynamic memory pointed to by the argument fd is freed. + ************************************************************************** + */ + +NSPR_API(PRStatus) PR_Close(PRFileDesc *fd); + +/* + ************************************************************************** + * FUNCTION: PR_Read + * DESCRIPTION: + * Read bytes from a file or socket. + * The operation will block until either an end of stream indication is + * encountered, some positive number of bytes are transferred, or there + * is an error. No more than 'amount' bytes will be transferred. + * INPUTS: + * PRFileDesc *fd + * pointer to the PRFileDesc object for the file or socket + * void *buf + * pointer to a buffer to hold the data read in. + * PRInt32 amount + * the size of 'buf' (in bytes) + * OUTPUTS: + * RETURN: + * PRInt32 + * a positive number indicates the number of bytes actually read in. + * 0 means end of file is reached or the network connection is closed. + * -1 indicates a failure. The reason for the failure is obtained + * by calling PR_GetError(). + * SIDE EFFECTS: + * data is written into the buffer pointed to by 'buf'. + * RESTRICTIONS: + * None. + * MEMORY: + * N/A + * ALGORITHM: + * N/A + ************************************************************************** + */ + +NSPR_API(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount); + +/* + *************************************************************************** + * FUNCTION: PR_Write + * DESCRIPTION: + * Write a specified number of bytes to a file or socket. The thread + * invoking this function blocks until all the data is written. + * INPUTS: + * PRFileDesc *fd + * pointer to a PRFileDesc object that refers to a file or socket + * const void *buf + * pointer to the buffer holding the data + * PRInt32 amount + * amount of data in bytes to be written from the buffer + * OUTPUTS: + * None. + * RETURN: PRInt32 + * A positive number indicates the number of bytes successfully written. + * A -1 is an indication that the operation failed. The reason + * for the failure is obtained by calling PR_GetError(). + *************************************************************************** + */ + +NSPR_API(PRInt32) PR_Write(PRFileDesc *fd,const void *buf,PRInt32 amount); + +/* + *************************************************************************** + * FUNCTION: PR_Writev + * DESCRIPTION: + * Write data to a socket. The data is organized in a PRIOVec array. The + * operation will block until all the data is written or the operation + * fails. + * INPUTS: + * PRFileDesc *fd + * Pointer that points to a PRFileDesc object for a socket. + * const PRIOVec *iov + * An array of PRIOVec. PRIOVec is a struct with the following + * two fields: + * char *iov_base; + * int iov_len; + * PRInt32 iov_size + * Number of elements in the iov array. The value of this + * argument must not be greater than PR_MAX_IOVECTOR_SIZE. + * If it is, the method will fail (PR_BUFFER_OVERFLOW_ERROR). + * PRIntervalTime timeout + * Time limit for completion of the entire write operation. + * OUTPUTS: + * None + * RETURN: + * A positive number indicates the number of bytes successfully written. + * A -1 is an indication that the operation failed. The reason + * for the failure is obtained by calling PR_GetError(). + *************************************************************************** + */ + +#define PR_MAX_IOVECTOR_SIZE 16 /* 'iov_size' must be <= */ + +NSPR_API(PRInt32) PR_Writev( + PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, + PRIntervalTime timeout); + +/* + *************************************************************************** + * FUNCTION: PR_Delete + * DESCRIPTION: + * Delete a file from the filesystem. The operation may fail if the + * file is open. + * INPUTS: + * const char *name + * Path name of the file to be deleted. + * OUTPUTS: + * None. + * RETURN: PRStatus + * The function returns PR_SUCCESS if the file is successfully + * deleted, otherwise it returns PR_FAILURE. + *************************************************************************** + */ + +NSPR_API(PRStatus) PR_Delete(const char *name); + +/**************************************************************************/ + +typedef enum PRFileType +{ + PR_FILE_FILE = 1, + PR_FILE_DIRECTORY = 2, + PR_FILE_OTHER = 3 +} PRFileType; + +struct PRFileInfo { + PRFileType type; /* Type of file */ + PROffset32 size; /* Size, in bytes, of file's contents */ + PRTime creationTime; /* Creation time per definition of PRTime */ + PRTime modifyTime; /* Last modification time per definition of PRTime */ +}; + +struct PRFileInfo64 { + PRFileType type; /* Type of file */ + PROffset64 size; /* Size, in bytes, of file's contents */ + PRTime creationTime; /* Creation time per definition of PRTime */ + PRTime modifyTime; /* Last modification time per definition of PRTime */ +}; + +/**************************************************************************** + * FUNCTION: PR_GetFileInfo, PR_GetFileInfo64 + * DESCRIPTION: + * Get the information about the file with the given path name. This is + * applicable only to NSFileDesc describing 'file' types (see + * INPUTS: + * const char *fn + * path name of the file + * OUTPUTS: + * PRFileInfo *info + * Information about the given file is written into the file + * information object pointer to by 'info'. + * RETURN: PRStatus + * PR_GetFileInfo returns PR_SUCCESS if file information is successfully + * obtained, otherwise it returns PR_FAILURE. + *************************************************************************** + */ + +NSPR_API(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info); +NSPR_API(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info); + +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info); +#endif /* MOZ_UNICODE */ + +/* + ************************************************************************** + * FUNCTION: PR_GetOpenFileInfo, PR_GetOpenFileInfo64 + * DESCRIPTION: + * Get information about an open file referred to by the + * given PRFileDesc object. + * INPUTS: + * const PRFileDesc *fd + * A reference to a valid, open file. + * OUTPUTS: + * Same as PR_GetFileInfo, PR_GetFileInfo64 + * RETURN: PRStatus + * PR_GetFileInfo returns PR_SUCCESS if file information is successfully + * obtained, otherwise it returns PR_FAILURE. + *************************************************************************** + */ + +NSPR_API(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info); +NSPR_API(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info); + +/* + ************************************************************************** + * FUNCTION: PR_Rename + * DESCRIPTION: + * Rename a file from the old name 'from' to the new name 'to'. + * INPUTS: + * const char *from + * The old name of the file to be renamed. + * const char *to + * The new name of the file. + * OUTPUTS: + * None. + * RETURN: PRStatus + ************************************************************************** + */ + +NSPR_API(PRStatus) PR_Rename(const char *from, const char *to); + +/* + ************************************************************************* + * FUNCTION: PR_Access + * DESCRIPTION: + * Determine accessibility of a file. + * INPUTS: + * const char *name + * path name of the file + * PRAccessHow how + * specifies which access permission to check for. + * It can be one of the following values: + * PR_ACCESS_READ_OK Test for read permission + * PR_ACCESS_WRITE_OK Test for write permission + * PR_ACCESS_EXISTS Check existence of file + * OUTPUTS: + * None. + * RETURN: PRStatus + * PR_SUCCESS is returned if the requested access is permitted. + * Otherwise, PR_FAILURE is returned. Additional information + * regarding the reason for the failure may be retrieved from + * PR_GetError(). + ************************************************************************* + */ + +typedef enum PRAccessHow { + PR_ACCESS_EXISTS = 1, + PR_ACCESS_WRITE_OK = 2, + PR_ACCESS_READ_OK = 3 +} PRAccessHow; + +NSPR_API(PRStatus) PR_Access(const char *name, PRAccessHow how); + +/* + ************************************************************************* + * FUNCTION: PR_Seek, PR_Seek64 + * DESCRIPTION: + * Moves read-write file offset + * INPUTS: + * PRFileDesc *fd + * Pointer to a PRFileDesc object. + * PROffset32, PROffset64 offset + * Specifies a value, in bytes, that is used in conjunction + * with the 'whence' parameter to set the file pointer. A + * negative value causes seeking in the reverse direction. + * PRSeekWhence whence + * Specifies how to interpret the 'offset' parameter in setting + * the file pointer associated with the 'fd' parameter. + * Values for the 'whence' parameter are: + * PR_SEEK_SET Sets the file pointer to the value of the + * 'offset' parameter + * PR_SEEK_CUR Sets the file pointer to its current location + * plus the value of the offset parameter. + * PR_SEEK_END Sets the file pointer to the size of the + * file plus the value of the offset parameter. + * OUTPUTS: + * None. + * RETURN: PROffset32, PROffset64 + * Upon successful completion, the resulting pointer location, + * measured in bytes from the beginning of the file, is returned. + * If the PR_Seek() function fails, the file offset remains + * unchanged, and the returned value is -1. The error code can + * then be retrieved via PR_GetError(). + ************************************************************************* + */ + +NSPR_API(PROffset32) PR_Seek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence); +NSPR_API(PROffset64) PR_Seek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence); + +/* + ************************************************************************ + * FUNCTION: PR_Available + * DESCRIPTION: + * Determine the amount of data in bytes available for reading + * in the given file or socket. + * INPUTS: + * PRFileDesc *fd + * Pointer to a PRFileDesc object that refers to a file or + * socket. + * OUTPUTS: + * None + * RETURN: PRInt32, PRInt64 + * Upon successful completion, PR_Available returns the number of + * bytes beyond the current read pointer that is available for + * reading. Otherwise, it returns a -1 and the reason for the + * failure can be retrieved via PR_GetError(). + ************************************************************************ + */ + +NSPR_API(PRInt32) PR_Available(PRFileDesc *fd); +NSPR_API(PRInt64) PR_Available64(PRFileDesc *fd); + +/* + ************************************************************************ + * FUNCTION: PR_Sync + * DESCRIPTION: + * Sync any buffered data for a fd to its backing device (disk). + * INPUTS: + * PRFileDesc *fd + * Pointer to a PRFileDesc object that refers to a file or + * socket + * OUTPUTS: + * None + * RETURN: PRStatus + * PR_SUCCESS is returned if the requested access is permitted. + * Otherwise, PR_FAILURE is returned. + ************************************************************************ + */ + +NSPR_API(PRStatus) PR_Sync(PRFileDesc *fd); + +/************************************************************************/ + +struct PRDirEntry { + const char *name; /* name of entry, relative to directory name */ +}; + +#ifdef MOZ_UNICODE +struct PRDirEntryUTF16 { + const PRUnichar *name; /* name of entry in UTF16, relative to + * directory name */ +}; +#endif /* MOZ_UNICODE */ + +#if !defined(NO_NSPR_10_SUPPORT) +#define PR_DirName(dirEntry) (dirEntry->name) +#endif + +/* + ************************************************************************* + * FUNCTION: PR_OpenDir + * DESCRIPTION: + * Open the directory by the given name + * INPUTS: + * const char *name + * path name of the directory to be opened + * OUTPUTS: + * None + * RETURN: PRDir * + * If the directory is sucessfully opened, a PRDir object is + * dynamically allocated and a pointer to it is returned. + * If the directory cannot be opened, a NULL pointer is returned. + * MEMORY: + * Upon successful completion, the return value points to + * dynamically allocated memory. + ************************************************************************* + */ + +NSPR_API(PRDir*) PR_OpenDir(const char *name); + +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name); +#endif /* MOZ_UNICODE */ + +/* + ************************************************************************* + * FUNCTION: PR_ReadDir + * DESCRIPTION: + * INPUTS: + * PRDir *dir + * pointer to a PRDir object that designates an open directory + * PRDirFlags flags + * PR_SKIP_NONE Do not skip any files + * PR_SKIP_DOT Skip the directory entry "." that + * represents the current directory + * PR_SKIP_DOT_DOT Skip the directory entry ".." that + * represents the parent directory. + * PR_SKIP_BOTH Skip both '.' and '..' + * PR_SKIP_HIDDEN Skip hidden files + * OUTPUTS: + * RETURN: PRDirEntry* + * Returns a pointer to the next entry in the directory. Returns + * a NULL pointer upon reaching the end of the directory or when an + * error occurs. The actual reason can be retrieved via PR_GetError(). + ************************************************************************* + */ + +typedef enum PRDirFlags { + PR_SKIP_NONE = 0x0, + PR_SKIP_DOT = 0x1, + PR_SKIP_DOT_DOT = 0x2, + PR_SKIP_BOTH = 0x3, + PR_SKIP_HIDDEN = 0x4 +} PRDirFlags; + +NSPR_API(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags); + +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags); +#endif /* MOZ_UNICODE */ + +/* + ************************************************************************* + * FUNCTION: PR_CloseDir + * DESCRIPTION: + * Close the specified directory. + * INPUTS: + * PRDir *dir + * The directory to be closed. + * OUTPUTS: + * None + * RETURN: PRStatus + * If successful, will return a status of PR_SUCCESS. Otherwise + * a value of PR_FAILURE. The reason for the failure may be re- + * trieved using PR_GetError(). + ************************************************************************* + */ + +NSPR_API(PRStatus) PR_CloseDir(PRDir *dir); + +#ifdef MOZ_UNICODE +/* + * EXPERIMENTAL: This function may be removed in a future release. + */ +NSPR_API(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir); +#endif /* MOZ_UNICODE */ + +/* + ************************************************************************* + * FUNCTION: PR_MkDir + * DESCRIPTION: + * Create a new directory with the given name and access mode. + * INPUTS: + * const char *name + * The name of the directory to be created. All the path components + * up to but not including the leaf component must already exist. + * PRIntn mode + * See 'mode' definiton in PR_Open(). + * OUTPUTS: + * None + * RETURN: PRStatus + * If successful, will return a status of PR_SUCCESS. Otherwise + * a value of PR_FAILURE. The reason for the failure may be re- + * trieved using PR_GetError(). + ************************************************************************* + */ + +NSPR_API(PRStatus) PR_MkDir(const char *name, PRIntn mode); + +/* + ************************************************************************* + * FUNCTION: PR_MakeDir + * DESCRIPTION: + * Create a new directory with the given name and access mode. + * PR_MakeDir has the same prototype as PR_MkDir but implements + * the specified access mode where possible. + ************************************************************************* + */ + +NSPR_API(PRStatus) PR_MakeDir(const char *name, PRIntn mode); + +/* + ************************************************************************* + * FUNCTION: PR_RmDir + * DESCRIPTION: + * Remove a directory by the given name. + * INPUTS: + * const char *name + * The name of the directory to be removed. All the path components + * must already exist. Only the leaf component will be removed. + * OUTPUTS: + * None + * RETURN: PRStatus + * If successful, will return a status of PR_SUCCESS. Otherwise + * a value of PR_FAILURE. The reason for the failure may be re- + * trieved using PR_GetError(). + ************************************************************************** + */ + +NSPR_API(PRStatus) PR_RmDir(const char *name); + +/* + ************************************************************************* + * FUNCTION: PR_NewUDPSocket + * DESCRIPTION: + * Create a new UDP socket. + * INPUTS: + * None + * OUTPUTS: + * None + * RETURN: PRFileDesc* + * Upon successful completion, PR_NewUDPSocket returns a pointer + * to the PRFileDesc created for the newly opened UDP socket. + * Returns a NULL pointer if the creation of a new UDP socket failed. + * + ************************************************************************** + */ + +NSPR_API(PRFileDesc*) PR_NewUDPSocket(void); + +/* + ************************************************************************* + * FUNCTION: PR_NewTCPSocket + * DESCRIPTION: + * Create a new TCP socket. + * INPUTS: + * None + * OUTPUTS: + * None + * RETURN: PRFileDesc* + * Upon successful completion, PR_NewTCPSocket returns a pointer + * to the PRFileDesc created for the newly opened TCP socket. + * Returns a NULL pointer if the creation of a new TCP socket failed. + * + ************************************************************************** + */ + +NSPR_API(PRFileDesc*) PR_NewTCPSocket(void); + +/* + ************************************************************************* + * FUNCTION: PR_OpenUDPSocket + * DESCRIPTION: + * Create a new UDP socket of the specified address family. + * INPUTS: + * PRIntn af + * Address family + * OUTPUTS: + * None + * RETURN: PRFileDesc* + * Upon successful completion, PR_OpenUDPSocket returns a pointer + * to the PRFileDesc created for the newly opened UDP socket. + * Returns a NULL pointer if the creation of a new UDP socket failed. + * + ************************************************************************** + */ + +NSPR_API(PRFileDesc*) PR_OpenUDPSocket(PRIntn af); + +/* + ************************************************************************* + * FUNCTION: PR_OpenTCPSocket + * DESCRIPTION: + * Create a new TCP socket of the specified address family. + * INPUTS: + * PRIntn af + * Address family + * OUTPUTS: + * None + * RETURN: PRFileDesc* + * Upon successful completion, PR_NewTCPSocket returns a pointer + * to the PRFileDesc created for the newly opened TCP socket. + * Returns a NULL pointer if the creation of a new TCP socket failed. + * + ************************************************************************** + */ + +NSPR_API(PRFileDesc*) PR_OpenTCPSocket(PRIntn af); + +/* + ************************************************************************* + * FUNCTION: PR_Connect + * DESCRIPTION: + * Initiate a connection on a socket. + * INPUTS: + * PRFileDesc *fd + * Points to a PRFileDesc object representing a socket + * PRNetAddr *addr + * Specifies the address of the socket in its own communication + * space. + * PRIntervalTime timeout + * The function uses the lesser of the provided timeout and + * the OS's connect timeout. In particular, if you specify + * PR_INTERVAL_NO_TIMEOUT as the timeout, the OS's connection + * time limit will be used. + * + * OUTPUTS: + * None + * RETURN: PRStatus + * Upon successful completion of connection initiation, PR_Connect + * returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further + * failure information can be obtained by calling PR_GetError(). + ************************************************************************** + */ + +NSPR_API(PRStatus) PR_Connect( + PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout); + +/* + ************************************************************************* + * FUNCTION: PR_ConnectContinue + * DESCRIPTION: + * Continue a nonblocking connect. After a nonblocking connect + * is initiated with PR_Connect() (which fails with + * PR_IN_PROGRESS_ERROR), one should call PR_Poll() on the socket, + * with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT. When + * PR_Poll() returns, one calls PR_ConnectContinue() on the + * socket to determine whether the nonblocking connect has + * completed or is still in progress. Repeat the PR_Poll(), + * PR_ConnectContinue() sequence until the nonblocking connect + * has completed. + * INPUTS: + * PRFileDesc *fd + * the file descriptor representing a socket + * PRInt16 out_flags + * the out_flags field of the poll descriptor returned by + * PR_Poll() + * RETURN: PRStatus + * If the nonblocking connect has successfully completed, + * PR_ConnectContinue returns PR_SUCCESS. If PR_ConnectContinue() + * returns PR_FAILURE, call PR_GetError(): + * - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in + * progress and has not completed yet. The caller should poll + * on the file descriptor for the in_flags + * PR_POLL_WRITE|PR_POLL_EXCEPT and retry PR_ConnectContinue + * later when PR_Poll() returns. + * - Other errors: the nonblocking connect has failed with this + * error code. + */ + +NSPR_API(PRStatus) PR_ConnectContinue(PRFileDesc *fd, PRInt16 out_flags); + +/* + ************************************************************************* + * THIS FUNCTION IS DEPRECATED. USE PR_ConnectContinue INSTEAD. + * + * FUNCTION: PR_GetConnectStatus + * DESCRIPTION: + * Get the completion status of a nonblocking connect. After + * a nonblocking connect is initiated with PR_Connect() (which + * fails with PR_IN_PROGRESS_ERROR), one should call PR_Poll() + * on the socket, with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT. + * When PR_Poll() returns, one calls PR_GetConnectStatus on the + * PRPollDesc structure to determine whether the nonblocking + * connect has succeeded or failed. + * INPUTS: + * const PRPollDesc *pd + * Pointer to a PRPollDesc whose fd member is the socket, + * and in_flags must contain PR_POLL_WRITE and PR_POLL_EXCEPT. + * PR_Poll() should have been called and set the out_flags. + * RETURN: PRStatus + * If the nonblocking connect has successfully completed, + * PR_GetConnectStatus returns PR_SUCCESS. If PR_GetConnectStatus() + * returns PR_FAILURE, call PR_GetError(): + * - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in + * progress and has not completed yet. + * - Other errors: the nonblocking connect has failed with this + * error code. + */ + +NSPR_API(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd); + +/* + ************************************************************************* + * FUNCTION: PR_Accept + * DESCRIPTION: + * Accept a connection on a socket. + * INPUTS: + * PRFileDesc *fd + * Points to a PRFileDesc object representing the rendezvous socket + * on which the caller is willing to accept new connections. + * PRIntervalTime timeout + * Time limit for completion of the accept operation. + * OUTPUTS: + * PRNetAddr *addr + * Returns the address of the connecting entity in its own + * communication space. It may be NULL. + * RETURN: PRFileDesc* + * Upon successful acceptance of a connection, PR_Accept + * returns a valid file descriptor. Otherwise, it returns NULL. + * Further failure information can be obtained by calling PR_GetError(). + ************************************************************************** + */ + +NSPR_API(PRFileDesc*) PR_Accept( + PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout); + +/* + ************************************************************************* + * FUNCTION: PR_Bind + * DESCRIPTION: + * Bind an address to a socket. + * INPUTS: + * PRFileDesc *fd + * Points to a PRFileDesc object representing a socket. + * PRNetAddr *addr + * Specifies the address to which the socket will be bound. + * OUTPUTS: + * None + * RETURN: PRStatus + * Upon successful binding of an address to a socket, PR_Bind + * returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further + * failure information can be obtained by calling PR_GetError(). + ************************************************************************** + */ + +NSPR_API(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr); + +/* + ************************************************************************* + * FUNCTION: PR_Listen + * DESCRIPTION: + * Listen for connections on a socket. + * INPUTS: + * PRFileDesc *fd + * Points to a PRFileDesc object representing a socket that will be + * used to listen for new connections. + * PRIntn backlog + * Specifies the maximum length of the queue of pending connections. + * OUTPUTS: + * None + * RETURN: PRStatus + * Upon successful completion of listen request, PR_Listen + * returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further + * failure information can be obtained by calling PR_GetError(). + ************************************************************************** + */ + +NSPR_API(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog); + +/* + ************************************************************************* + * FUNCTION: PR_Shutdown + * DESCRIPTION: + * Shut down part of a full-duplex connection on a socket. + * INPUTS: + * PRFileDesc *fd + * Points to a PRFileDesc object representing a connected socket. + * PRIntn how + * Specifies the kind of disallowed operations on the socket. + * PR_SHUTDOWN_RCV - Further receives will be disallowed + * PR_SHUTDOWN_SEND - Further sends will be disallowed + * PR_SHUTDOWN_BOTH - Further sends and receives will be disallowed + * OUTPUTS: + * None + * RETURN: PRStatus + * Upon successful completion of shutdown request, PR_Shutdown + * returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further + * failure information can be obtained by calling PR_GetError(). + ************************************************************************** + */ + +typedef enum PRShutdownHow +{ + PR_SHUTDOWN_RCV = 0, /* disallow further receives */ + PR_SHUTDOWN_SEND = 1, /* disallow further sends */ + PR_SHUTDOWN_BOTH = 2 /* disallow further receives and sends */ +} PRShutdownHow; + +NSPR_API(PRStatus) PR_Shutdown(PRFileDesc *fd, PRShutdownHow how); + +/* + ************************************************************************* + * FUNCTION: PR_Recv + * DESCRIPTION: + * Receive a specified number of bytes from a connected socket. + * The operation will block until some positive number of bytes are + * transferred, a time out has occurred, or there is an error. + * No more than 'amount' bytes will be transferred. + * INPUTS: + * PRFileDesc *fd + * points to a PRFileDesc object representing a socket. + * void *buf + * pointer to a buffer to hold the data received. + * PRInt32 amount + * the size of 'buf' (in bytes) + * PRIntn flags + * must be zero or PR_MSG_PEEK. + * PRIntervalTime timeout + * Time limit for completion of the receive operation. + * OUTPUTS: + * None + * RETURN: PRInt32 + * a positive number indicates the number of bytes actually received. + * 0 means the network connection is closed. + * -1 indicates a failure. The reason for the failure is obtained + * by calling PR_GetError(). + ************************************************************************** + */ + +#define PR_MSG_PEEK 0x2 + +NSPR_API(PRInt32) PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout); + +/* + ************************************************************************* + * FUNCTION: PR_Send + * DESCRIPTION: + * Send a specified number of bytes from a connected socket. + * The operation will block until all bytes are + * processed, a time out has occurred, or there is an error. + * INPUTS: + * PRFileDesc *fd + * points to a PRFileDesc object representing a socket. + * void *buf + * pointer to a buffer from where the data is sent. + * PRInt32 amount + * the size of 'buf' (in bytes) + * PRIntn flags + * (OBSOLETE - must always be zero) + * PRIntervalTime timeout + * Time limit for completion of the send operation. + * OUTPUTS: + * None + * RETURN: PRInt32 + * A positive number indicates the number of bytes successfully processed. + * This number must always equal 'amount'. A -1 is an indication that the + * operation failed. The reason for the failure is obtained by calling + * PR_GetError(). + ************************************************************************** + */ + +NSPR_API(PRInt32) PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout); + +/* + ************************************************************************* + * FUNCTION: PR_RecvFrom + * DESCRIPTION: + * Receive up to a specified number of bytes from socket which may + * or may not be connected. + * The operation will block until one or more bytes are + * transferred, a time out has occurred, or there is an error. + * No more than 'amount' bytes will be transferred. + * INPUTS: + * PRFileDesc *fd + * points to a PRFileDesc object representing a socket. + * void *buf + * pointer to a buffer to hold the data received. + * PRInt32 amount + * the size of 'buf' (in bytes) + * PRIntn flags + * (OBSOLETE - must always be zero) + * PRNetAddr *addr + * Specifies the address of the sending peer. It may be NULL. + * PRIntervalTime timeout + * Time limit for completion of the receive operation. + * OUTPUTS: + * None + * RETURN: PRInt32 + * a positive number indicates the number of bytes actually received. + * 0 means the network connection is closed. + * -1 indicates a failure. The reason for the failure is obtained + * by calling PR_GetError(). + ************************************************************************** + */ + +NSPR_API(PRInt32) PR_RecvFrom( + PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRNetAddr *addr, PRIntervalTime timeout); + +/* + ************************************************************************* + * FUNCTION: PR_SendTo + * DESCRIPTION: + * Send a specified number of bytes from an unconnected socket. + * The operation will block until all bytes are + * sent, a time out has occurred, or there is an error. + * INPUTS: + * PRFileDesc *fd + * points to a PRFileDesc object representing an unconnected socket. + * void *buf + * pointer to a buffer from where the data is sent. + * PRInt32 amount + * the size of 'buf' (in bytes) + * PRIntn flags + * (OBSOLETE - must always be zero) + * PRNetAddr *addr + * Specifies the address of the peer. +.* PRIntervalTime timeout + * Time limit for completion of the send operation. + * OUTPUTS: + * None + * RETURN: PRInt32 + * A positive number indicates the number of bytes successfully sent. + * -1 indicates a failure. The reason for the failure is obtained + * by calling PR_GetError(). + ************************************************************************** + */ + +NSPR_API(PRInt32) PR_SendTo( + PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRIntervalTime timeout); + +/* +************************************************************************* +** FUNCTION: PR_TransmitFile +** DESCRIPTION: +** Transmitfile sends a complete file (sourceFile) across a socket +** (networkSocket). If headers is non-NULL, the headers will be sent across +** the socket prior to sending the file. +** +** Optionally, the PR_TRANSMITFILE_CLOSE_SOCKET flag may be passed to +** transmitfile. This flag specifies that transmitfile should close the +** socket after sending the data. +** +** INPUTS: +** PRFileDesc *networkSocket +** The socket to send data over +** PRFileDesc *sourceFile +** The file to send +** const void *headers +** A pointer to headers to be sent before sending data +** PRInt32 hlen +** length of header buffers in bytes. +** PRTransmitFileFlags flags +** If the flags indicate that the connection should be closed, +** it will be done immediately after transferring the file, unless +** the operation is unsuccessful. +.* PRIntervalTime timeout + * Time limit for completion of the transmit operation. +** +** RETURNS: +** Returns the number of bytes written or -1 if the operation failed. +** If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_ +** SOCKET flag is ignored. The reason for the failure is obtained +** by calling PR_GetError(). +************************************************************************** +*/ + +NSPR_API(PRInt32) PR_TransmitFile( + PRFileDesc *networkSocket, PRFileDesc *sourceFile, + const void *headers, PRInt32 hlen, PRTransmitFileFlags flags, + PRIntervalTime timeout); + +/* +************************************************************************* +** FUNCTION: PR_SendFile +** DESCRIPTION: +** PR_SendFile sends data from a file (sendData->fd) across a socket +** (networkSocket). If specified, a header and/or trailer buffer are sent +** before and after the file, respectively. The file offset, number of bytes +** of file data to send, the header and trailer buffers are specified in the +** sendData argument. +** +** Optionally, if the PR_TRANSMITFILE_CLOSE_SOCKET flag is passed, the +** socket is closed after successfully sending the data. +** +** INPUTS: +** PRFileDesc *networkSocket +** The socket to send data over +** PRSendFileData *sendData +** Contains the FD, file offset and length, header and trailer +** buffer specifications. +** PRTransmitFileFlags flags +** If the flags indicate that the connection should be closed, +** it will be done immediately after transferring the file, unless +** the operation is unsuccessful. +.* PRIntervalTime timeout + * Time limit for completion of the send operation. +** +** RETURNS: +** Returns the number of bytes written or -1 if the operation failed. +** If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_ +** SOCKET flag is ignored. The reason for the failure is obtained +** by calling PR_GetError(). +************************************************************************** +*/ + +struct PRSendFileData { + PRFileDesc *fd; /* file to send */ + PRUint32 file_offset; /* file offset */ + PRSize file_nbytes; /* number of bytes of file data to send */ + /* if 0, send data from file_offset to */ + /* end-of-file. */ + const void *header; /* header buffer */ + PRInt32 hlen; /* header len */ + const void *trailer; /* trailer buffer */ + PRInt32 tlen; /* trailer len */ +}; + + +NSPR_API(PRInt32) PR_SendFile( + PRFileDesc *networkSocket, PRSendFileData *sendData, + PRTransmitFileFlags flags, PRIntervalTime timeout); + +/* +************************************************************************* +** FUNCTION: PR_AcceptRead +** DESCRIPTION: +** AcceptRead accepts a new connection, returns the newly created +** socket's descriptor and also returns the connecting peer's address. +** AcceptRead, as its name suggests, also receives the first block of data +** sent by the peer. +** +** INPUTS: +** PRFileDesc *listenSock +** A socket descriptor that has been called with the PR_Listen() +** function, also known as the rendezvous socket. +** void *buf +** A pointer to a buffer to receive data sent by the client. This +** buffer must be large enough to receive bytes of data +** and two PRNetAddr structures, plus an extra 32 bytes. See: +** PR_ACCEPT_READ_BUF_OVERHEAD. +** PRInt32 amount +** The number of bytes of client data to receive. Does not include +** the size of the PRNetAddr structures. If 0, no data will be read +** from the client. +** PRIntervalTime timeout +** The timeout interval only applies to the read portion of the +** operation. PR_AcceptRead will block indefinitely until the +** connection is accepted; the read will timeout after the timeout +** interval elapses. +** OUTPUTS: +** PRFileDesc **acceptedSock +** The file descriptor for the newly connected socket. This parameter +** will only be valid if the function return does not indicate failure. +** PRNetAddr **peerAddr, +** The address of the remote socket. This parameter will only be +** valid if the function return does not indicate failure. The +** returned address is not guaranteed to be properly aligned. +** +** RETURNS: +** The number of bytes read from the client or -1 on failure. The reason +** for the failure is obtained by calling PR_GetError(). +************************************************************************** +**/ +/* define buffer overhead constant. Add this value to the user's +** data length when allocating a buffer to accept data. +** Example: +** #define USER_DATA_SIZE 10 +** char buf[USER_DATA_SIZE + PR_ACCEPT_READ_BUF_OVERHEAD]; +** bytesRead = PR_AcceptRead( s, fd, &a, &p, USER_DATA_SIZE, ...); +*/ +#define PR_ACCEPT_READ_BUF_OVERHEAD (32+(2*sizeof(PRNetAddr))) + +NSPR_API(PRInt32) PR_AcceptRead( + PRFileDesc *listenSock, PRFileDesc **acceptedSock, + PRNetAddr **peerAddr, void *buf, PRInt32 amount, PRIntervalTime timeout); + +/* +************************************************************************* +** FUNCTION: PR_NewTCPSocketPair +** DESCRIPTION: +** Create a new TCP socket pair. The returned descriptors can be used +** interchangeably; they are interconnected full-duplex descriptors: data +** written to one can be read from the other and vice-versa. +** +** INPUTS: +** None +** OUTPUTS: +** PRFileDesc *fds[2] +** The file descriptor pair for the newly created TCP sockets. +** RETURN: PRStatus +** Upon successful completion of TCP socket pair, PR_NewTCPSocketPair +** returns PR_SUCCESS. Otherwise, it returns PR_FAILURE. Further +** failure information can be obtained by calling PR_GetError(). +** XXX can we implement this on windoze and mac? +************************************************************************** +**/ +NSPR_API(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]); + +/* +************************************************************************* +** FUNCTION: PR_GetSockName +** DESCRIPTION: +** Get socket name. Return the network address for this socket. +** +** INPUTS: +** PRFileDesc *fd +** Points to a PRFileDesc object representing the socket. +** OUTPUTS: +** PRNetAddr *addr +** Returns the address of the socket in its own communication space. +** RETURN: PRStatus +** Upon successful completion, PR_GetSockName returns PR_SUCCESS. +** Otherwise, it returns PR_FAILURE. Further failure information can +** be obtained by calling PR_GetError(). +************************************************************************** +**/ +NSPR_API(PRStatus) PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr); + +/* +************************************************************************* +** FUNCTION: PR_GetPeerName +** DESCRIPTION: +** Get name of the connected peer. Return the network address for the +** connected peer socket. +** +** INPUTS: +** PRFileDesc *fd +** Points to a PRFileDesc object representing the connected peer. +** OUTPUTS: +** PRNetAddr *addr +** Returns the address of the connected peer in its own communication +** space. +** RETURN: PRStatus +** Upon successful completion, PR_GetPeerName returns PR_SUCCESS. +** Otherwise, it returns PR_FAILURE. Further failure information can +** be obtained by calling PR_GetError(). +************************************************************************** +**/ +NSPR_API(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr); + +NSPR_API(PRStatus) PR_GetSocketOption( + PRFileDesc *fd, PRSocketOptionData *data); + +NSPR_API(PRStatus) PR_SetSocketOption( + PRFileDesc *fd, const PRSocketOptionData *data); + +/* + ********************************************************************* + * + * File descriptor inheritance + * + ********************************************************************* + */ + +/* + ************************************************************************ + * FUNCTION: PR_SetFDInheritable + * DESCRIPTION: + * Set the inheritance attribute of a file descriptor. + * + * INPUTS: + * PRFileDesc *fd + * Points to a PRFileDesc object. + * PRBool inheritable + * If PR_TRUE, the file descriptor fd is set to be inheritable + * by a child process. If PR_FALSE, the file descriptor is set + * to be not inheritable by a child process. + * RETURN: PRStatus + * Upon successful completion, PR_SetFDInheritable returns PR_SUCCESS. + * Otherwise, it returns PR_FAILURE. Further failure information can + * be obtained by calling PR_GetError(). + ************************************************************************* + */ +NSPR_API(PRStatus) PR_SetFDInheritable( + PRFileDesc *fd, + PRBool inheritable); + +/* + ************************************************************************ + * FUNCTION: PR_GetInheritedFD + * DESCRIPTION: + * Get an inherited file descriptor with the specified name. + * + * INPUTS: + * const char *name + * The name of the inherited file descriptor. + * RETURN: PRFileDesc * + * Upon successful completion, PR_GetInheritedFD returns the + * inherited file descriptor with the specified name. Otherwise, + * it returns NULL. Further failure information can be obtained + * by calling PR_GetError(). + ************************************************************************* + */ +NSPR_API(PRFileDesc *) PR_GetInheritedFD(const char *name); + +/* + ********************************************************************* + * + * Memory-mapped files + * + ********************************************************************* + */ + +typedef struct PRFileMap PRFileMap; + +/* + * protection options for read and write accesses of a file mapping + */ +typedef enum PRFileMapProtect { + PR_PROT_READONLY, /* read only */ + PR_PROT_READWRITE, /* readable, and write is shared */ + PR_PROT_WRITECOPY /* readable, and write is private (copy-on-write) */ +} PRFileMapProtect; + +NSPR_API(PRFileMap *) PR_CreateFileMap( + PRFileDesc *fd, + PRInt64 size, + PRFileMapProtect prot); + +/* + * return the alignment (in bytes) of the offset argument to PR_MemMap + */ +NSPR_API(PRInt32) PR_GetMemMapAlignment(void); + +NSPR_API(void *) PR_MemMap( + PRFileMap *fmap, + PROffset64 offset, /* must be aligned and sized according to the + * return value of PR_GetMemMapAlignment() */ + PRUint32 len); + +NSPR_API(PRStatus) PR_MemUnmap(void *addr, PRUint32 len); + +NSPR_API(PRStatus) PR_CloseFileMap(PRFileMap *fmap); + +/* + * Synchronously flush the given memory-mapped address range of the given open + * file to disk. The function does not return until all modified data have + * been written to disk. + * + * On some platforms, the function will call PR_Sync(fd) internally if it is + * necessary for flushing modified data to disk synchronously. + */ +NSPR_API(PRStatus) PR_SyncMemMap( + PRFileDesc *fd, + void *addr, + PRUint32 len); + +/* + ****************************************************************** + * + * Interprocess communication + * + ****************************************************************** + */ + +/* + * Creates an anonymous pipe and returns file descriptors for the + * read and write ends of the pipe. + */ + +NSPR_API(PRStatus) PR_CreatePipe( + PRFileDesc **readPipe, + PRFileDesc **writePipe +); + +/************************************************************************/ +/************** The following definitions are for poll ******************/ +/************************************************************************/ + +struct PRPollDesc { + PRFileDesc* fd; + PRInt16 in_flags; + PRInt16 out_flags; +}; + +/* +** Bit values for PRPollDesc.in_flags or PRPollDesc.out_flags. Binary-or +** these together to produce the desired poll request. +*/ + +#if defined(_PR_POLL_BACKCOMPAT) + +#include +#define PR_POLL_READ POLLIN +#define PR_POLL_WRITE POLLOUT +#define PR_POLL_EXCEPT POLLPRI +#define PR_POLL_ERR POLLERR /* only in out_flags */ +#define PR_POLL_NVAL POLLNVAL /* only in out_flags when fd is bad */ +#define PR_POLL_HUP POLLHUP /* only in out_flags */ + +#else /* _PR_POLL_BACKCOMPAT */ + +#define PR_POLL_READ 0x1 +#define PR_POLL_WRITE 0x2 +#define PR_POLL_EXCEPT 0x4 +#define PR_POLL_ERR 0x8 /* only in out_flags */ +#define PR_POLL_NVAL 0x10 /* only in out_flags when fd is bad */ +#define PR_POLL_HUP 0x20 /* only in out_flags */ + +#endif /* _PR_POLL_BACKCOMPAT */ + +/* +************************************************************************* +** FUNCTION: PR_Poll +** DESCRIPTION: +** +** The call returns as soon as I/O is ready on one or more of the underlying +** socket objects. A count of the number of ready descriptors is +** returned unless a timeout occurs in which case zero is returned. +** +** PRPollDesc.fd should be set to a pointer to a PRFileDesc object +** representing a socket. This field can be set to NULL to indicate to +** PR_Poll that this PRFileDesc object should be ignored. +** PRPollDesc.in_flags should be set to the desired request +** (read/write/except or some combination). Upon successful return from +** this call PRPollDesc.out_flags will be set to indicate what kind of +** i/o can be performed on the respective descriptor. PR_Poll() uses the +** out_flags fields as scratch variables during the call. If PR_Poll() +** returns 0 or -1, the out_flags fields do not contain meaningful values +** and must not be used. +** +** INPUTS: +** PRPollDesc *pds A pointer to an array of PRPollDesc +** +** PRIntn npds The number of elements in the array +** If this argument is zero PR_Poll is +** equivalent to a PR_Sleep(timeout). +** +** PRIntervalTime timeout Amount of time the call will block waiting +** for I/O to become ready. If this time expires +** w/o any I/O becoming ready, the result will +** be zero. +** +** OUTPUTS: None +** RETURN: +** PRInt32 Number of PRPollDesc's with events or zero +** if the function timed out or -1 on failure. +** The reason for the failure is obtained by +** calling PR_GetError(). +************************************************************************** +*/ +NSPR_API(PRInt32) PR_Poll( + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout); + +/* +************************************************************************** +** +** Pollable events +** +** A pollable event is a special kind of file descriptor. +** The only I/O operation you can perform on a pollable event +** is to poll it with the PR_POLL_READ flag. You can't +** read from or write to a pollable event. +** +** The purpose of a pollable event is to combine event waiting +** with I/O waiting in a single PR_Poll call. Pollable events +** are implemented using a pipe or a pair of TCP sockets +** connected via the loopback address, therefore setting and +** waiting for pollable events are expensive operating system +** calls. Do not use pollable events for general thread +** synchronization. Use condition variables instead. +** +** A pollable event has two states: set and unset. Events +** are not queued, so there is no notion of an event count. +** A pollable event is either set or unset. +** +** A new pollable event is created by a PR_NewPollableEvent +** call and is initially in the unset state. +** +** PR_WaitForPollableEvent blocks the calling thread until +** the pollable event is set, and then it atomically unsets +** the pollable event before it returns. +** +** To set a pollable event, call PR_SetPollableEvent. +** +** One can call PR_Poll with the PR_POLL_READ flag on a pollable +** event. When the pollable event is set, PR_Poll returns with +** the PR_POLL_READ flag set in the out_flags. +** +** To close a pollable event, call PR_DestroyPollableEvent +** (not PR_Close). +** +************************************************************************** +*/ + +NSPR_API(PRFileDesc *) PR_NewPollableEvent(void); + +NSPR_API(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event); + +NSPR_API(PRStatus) PR_SetPollableEvent(PRFileDesc *event); + +NSPR_API(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event); + +PR_END_EXTERN_C + +#endif /* prio_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/pripcsem.h nspr-4.10.7/nspr/pr/include/pripcsem.h --- nspr-4.9.5/nspr/pr/include/pripcsem.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/pripcsem.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: pripcsem.h + * + * Description: named semaphores for interprocess + * synchronization + * + * Unrelated processes obtain access to a shared semaphore + * by specifying its name. + * + * Our goal is to support named semaphores on at least + * Unix and Win32 platforms. The implementation will use + * one of the three native semaphore APIs: POSIX, System V, + * and Win32. + * + * Because POSIX named semaphores have kernel persistence, + * we are forced to have a delete function in this API. + */ + +#ifndef pripcsem_h___ +#define pripcsem_h___ + +#include "prtypes.h" +#include "prio.h" + +PR_BEGIN_EXTERN_C + +/* + * PRSem is an opaque structure that represents a named + * semaphore. + */ +typedef struct PRSem PRSem; + +/* + * PR_OpenSemaphore -- + * + * Create or open a named semaphore with the specified name. + * A handle to the semaphore is returned. + * + * If the named semaphore doesn't exist and the PR_SEM_CREATE + * flag is specified, the named semaphore is created. The + * created semaphore needs to be removed from the system with + * a PR_DeleteSemaphore call. + * + * If PR_SEM_CREATE is specified, the third argument is the + * access permission bits of the new semaphore (same + * interpretation as the mode argument to PR_Open) and the + * fourth argument is the initial value of the new semaphore. + * If PR_SEM_CREATE is not specified, the third and fourth + * arguments are ignored. + */ + +#define PR_SEM_CREATE 0x1 /* create if not exist */ +#define PR_SEM_EXCL 0x2 /* fail if already exists */ + +NSPR_API(PRSem *) PR_OpenSemaphore( + const char *name, PRIntn flags, PRIntn mode, PRUintn value); + +/* + * PR_WaitSemaphore -- + * + * If the value of the semaphore is > 0, decrement the value and return. + * If the value is 0, sleep until the value becomes > 0, then decrement + * the value and return. + * + * The "test and decrement" operation is performed atomically. + */ + +NSPR_API(PRStatus) PR_WaitSemaphore(PRSem *sem); + +/* + * PR_PostSemaphore -- + * + * Increment the value of the named semaphore by 1. + */ + +NSPR_API(PRStatus) PR_PostSemaphore(PRSem *sem); + +/* + * PR_CloseSemaphore -- + * + * Close a named semaphore handle. + */ + +NSPR_API(PRStatus) PR_CloseSemaphore(PRSem *sem); + +/* + * PR_DeleteSemaphore -- + * + * Remove a named semaphore from the system. + */ + +NSPR_API(PRStatus) PR_DeleteSemaphore(const char *name); + +PR_END_EXTERN_C + +#endif /* pripcsem_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/private/.cvsignore nspr-4.10.7/nspr/pr/include/private/.cvsignore --- nspr-4.9.5/nspr/pr/include/private/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/private/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/include/private/Makefile.in nspr-4.10.7/nspr/pr/include/private/Makefile.in --- nspr-4.9.5/nspr/pr/include/private/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/private/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,29 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +RELEASE_HEADERS = pprio.h pprthred.h prpriv.h +RELEASE_HEADERS := $(addprefix $(srcdir)/, $(RELEASE_HEADERS)) +RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)/private + +HEADERS = $(RELEASE_HEADERS) $(srcdir)/pprmwait.h $(srcdir)/primpl.h + +include_subdir = private + +include $(topsrcdir)/config/rules.mk + +export:: $(RELEASE_HEADERS) + $(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)/private diff -Nru nspr-4.9.5/nspr/pr/include/private/pprio.h nspr-4.10.7/nspr/pr/include/private/pprio.h --- nspr-4.9.5/nspr/pr/include/private/pprio.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/private/pprio.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: pprio.h +** +** Description: Private definitions for I/O related structures +*/ + +#ifndef pprio_h___ +#define pprio_h___ + +#include "prtypes.h" +#include "prio.h" + +PR_BEGIN_EXTERN_C + +/************************************************************************/ +/************************************************************************/ + +#ifdef _WIN64 +typedef __int64 PROsfd; +#else +typedef PRInt32 PROsfd; +#endif + +/* Return the method tables for files, tcp sockets and udp sockets */ +NSPR_API(const PRIOMethods*) PR_GetFileMethods(void); +NSPR_API(const PRIOMethods*) PR_GetTCPMethods(void); +NSPR_API(const PRIOMethods*) PR_GetUDPMethods(void); +NSPR_API(const PRIOMethods*) PR_GetPipeMethods(void); + +/* +** Convert a NSPR socket handle to a native socket handle. +** +** Using this function makes your code depend on the properties of the +** current NSPR implementation, which may change (although extremely +** unlikely because of NSPR's backward compatibility requirement). Avoid +** using it if you can. +** +** If you use this function, you need to understand what NSPR does to +** the native handle. For example, NSPR puts native socket handles in +** non-blocking mode or associates them with an I/O completion port (the +** WINNT build configuration only). Your use of the native handle should +** not interfere with NSPR's use of the native handle. If your code +** changes the configuration of the native handle, (e.g., changes it to +** blocking or closes it), NSPR will not work correctly. +*/ +NSPR_API(PROsfd) PR_FileDesc2NativeHandle(PRFileDesc *); +NSPR_API(void) PR_ChangeFileDescNativeHandle(PRFileDesc *, PROsfd); +NSPR_API(PRFileDesc*) PR_AllocFileDesc(PROsfd osfd, + const PRIOMethods *methods); +NSPR_API(void) PR_FreeFileDesc(PRFileDesc *fd); +/* +** Import an existing OS file to NSPR. +*/ +NSPR_API(PRFileDesc*) PR_ImportFile(PROsfd osfd); +NSPR_API(PRFileDesc*) PR_ImportPipe(PROsfd osfd); +NSPR_API(PRFileDesc*) PR_ImportTCPSocket(PROsfd osfd); +NSPR_API(PRFileDesc*) PR_ImportUDPSocket(PROsfd osfd); + + +/* + ************************************************************************* + * FUNCTION: PR_CreateSocketPollFd + * DESCRIPTION: + * Create a PRFileDesc wrapper for a native socket handle, for use with + * PR_Poll only + * INPUTS: + * None + * OUTPUTS: + * None + * RETURN: PRFileDesc* + * Upon successful completion, PR_CreateSocketPollFd returns a pointer + * to the PRFileDesc created for the native socket handle + * Returns a NULL pointer if the create of a new PRFileDesc failed + * + ************************************************************************** + */ + +NSPR_API(PRFileDesc*) PR_CreateSocketPollFd(PROsfd osfd); + +/* + ************************************************************************* + * FUNCTION: PR_DestroySocketPollFd + * DESCRIPTION: + * Destroy the PRFileDesc wrapper created by PR_CreateSocketPollFd + * INPUTS: + * None + * OUTPUTS: + * None + * RETURN: PRFileDesc* + * Upon successful completion, PR_DestroySocketPollFd returns + * PR_SUCCESS, else PR_FAILURE + * + ************************************************************************** + */ + +NSPR_API(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd); + + +/* +** Macros for PR_Socket +** +** Socket types: PR_SOCK_STREAM, PR_SOCK_DGRAM +*/ + +#ifdef WIN32 + +#define PR_SOCK_STREAM 1 +#define PR_SOCK_DGRAM 2 + +#else /* WIN32 */ + +#define PR_SOCK_STREAM SOCK_STREAM +#define PR_SOCK_DGRAM SOCK_DGRAM + +#endif /* WIN32 */ + +/* +** Create a new Socket; this function is obsolete. +*/ +NSPR_API(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto); + +/* FUNCTION: PR_LockFile +** DESCRIPTION: +** Lock a file for exclusive access. +** RETURNS: +** PR_SUCCESS when the lock is held +** PR_FAILURE otherwise +*/ +NSPR_API(PRStatus) PR_LockFile(PRFileDesc *fd); + +/* FUNCTION: PR_TLockFile +** DESCRIPTION: +** Test and Lock a file for exclusive access. Do not block if the +** file cannot be locked immediately. +** RETURNS: +** PR_SUCCESS when the lock is held +** PR_FAILURE otherwise +*/ +NSPR_API(PRStatus) PR_TLockFile(PRFileDesc *fd); + +/* FUNCTION: PR_UnlockFile +** DESCRIPTION: +** Unlock a file which has been previously locked successfully by this +** process. +** RETURNS: +** PR_SUCCESS when the lock is released +** PR_FAILURE otherwise +*/ +NSPR_API(PRStatus) PR_UnlockFile(PRFileDesc *fd); + +/* +** Emulate acceptread by accept and recv. +*/ +NSPR_API(PRInt32) PR_EmulateAcceptRead(PRFileDesc *sd, PRFileDesc **nd, + PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout); + +/* +** Emulate sendfile by reading from the file and writing to the socket. +** The file is memory-mapped if memory-mapped files are supported. +*/ +NSPR_API(PRInt32) PR_EmulateSendFile( + PRFileDesc *networkSocket, PRSendFileData *sendData, + PRTransmitFileFlags flags, PRIntervalTime timeout); + +#ifdef WIN32 +/* FUNCTION: PR_NTFast_AcceptRead +** DESCRIPTION: +** NT has the notion of an "accept context", which is only needed in +** order to make certain calls. By default, a socket connected via +** AcceptEx can only do a limited number of things without updating +** the acceptcontext. The generic version of PR_AcceptRead always +** updates the accept context. This version does not. +**/ +NSPR_API(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, + PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime t); + +typedef void (*_PR_AcceptTimeoutCallback)(void *); + +/* FUNCTION: PR_NTFast_AcceptRead_WithTimeoutCallback +** DESCRIPTION: +** The AcceptEx call combines the accept with the read function. However, +** our daemon threads need to be able to wakeup and reliably flush their +** log buffers if the Accept times out. However, with the current blocking +** interface to AcceptRead, there is no way for us to timeout the Accept; +** this is because when we timeout the Read, we can close the newly +** socket and continue; but when we timeout the accept itself, there is no +** new socket to timeout. So instead, this version of the function is +** provided. After the initial timeout period elapses on the accept() +** portion of the function, it will call the callback routine and then +** continue the accept. If the timeout occurs on the read, it will +** close the connection and return error. +*/ +NSPR_API(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback( + PRFileDesc *sd, + PRFileDesc **nd, + PRNetAddr **raddr, + void *buf, + PRInt32 amount, + PRIntervalTime t, + _PR_AcceptTimeoutCallback callback, + void *callback_arg); + +/* FUNCTION: PR_NTFast_Accept +** DESCRIPTION: +** NT has the notion of an "accept context", which is only needed in +** order to make certain calls. By default, a socket connected via +** AcceptEx can only do a limited number of things without updating +** the acceptcontext. The generic version of PR_Accept always +** updates the accept context. This version does not. +**/ +NSPR_API(PRFileDesc*) PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr, + PRIntervalTime timeout); + +/* FUNCTION: PR_NTFast_Update +** DESCRIPTION: +** For sockets accepted with PR_NTFast_Accept or PR_NTFastAcceptRead, +** this function will update the accept context for those sockets, +** so that the socket can make general purpose socket calls. +** Without calling this, the only operations supported on the socket +** Are PR_Read, PR_Write, PR_Transmitfile, and PR_Close. +*/ +NSPR_API(void) PR_NTFast_UpdateAcceptContext(PRFileDesc *acceptSock, + PRFileDesc *listenSock); + + +/* FUNCTION: PR_NT_CancelIo +** DESCRIPTION: +** Cancel IO operations on fd. +*/ +NSPR_API(PRStatus) PR_NT_CancelIo(PRFileDesc *fd); + + +#endif /* WIN32 */ + +PR_END_EXTERN_C + +#endif /* pprio_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/private/pprmwait.h nspr-4.10.7/nspr/pr/include/private/pprmwait.h --- nspr-4.9.5/nspr/pr/include/private/pprmwait.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/private/pprmwait.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if defined(_PPRMWAIT_H) +#else +#define _PPRMWAIT_H + +#include "prlock.h" +#include "prcvar.h" +#include "prclist.h" +#include "prthread.h" + +#define MAX_POLLING_INTERVAL 100 +#define _PR_POLL_COUNT_FUDGE 64 +#define _PR_DEFAULT_HASH_LENGTH 59 + +/* + * Our hash table resolves collisions by open addressing with + * double hashing. See Cormen, Leiserson, and Rivest, + * Introduction to Algorithms, p. 232, The MIT Press, 1990. + */ + +#define _MW_HASH(a, m) ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m)) +#define _MW_HASH2(a, m) (1 + ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m - 2))) +#define _MW_ABORTED(_rv) \ + ((PR_FAILURE == (_rv)) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) + +typedef enum {_prmw_success, _prmw_rehash, _prmw_error} _PR_HashStory; + +typedef struct _PRWaiterHash +{ + PRUint16 count; /* current number in hash table */ + PRUint16 length; /* current size of the hash table */ + PRRecvWait *recv_wait; /* hash table of receive wait objects */ +} _PRWaiterHash; + +typedef enum {_prmw_running, _prmw_stopping, _prmw_stopped} PRMWGroupState; + +struct PRWaitGroup +{ + PRCList group_link; /* all groups are linked to each other */ + PRCList io_ready; /* list of I/O requests that are ready */ + PRMWGroupState state; /* state of this group (so we can shut down) */ + + PRLock *ml; /* lock for synchronizing this wait group */ + PRCondVar *io_taken; /* calling threads notify when they take I/O */ + PRCondVar *io_complete; /* calling threads wait here for completions */ + PRCondVar *new_business; /* polling thread waits here more work */ + PRCondVar *mw_manage; /* used to manage group lists */ + PRThread* poller; /* thread that's actually doing the poll() */ + PRUint16 waiting_threads; /* number of threads waiting for recv */ + PRUint16 polling_count; /* number of elements in the polling list */ + PRUint32 p_timestamp; /* pseudo-time group had element removed */ + PRPollDesc *polling_list; /* list poller builds for polling */ + PRIntervalTime last_poll; /* last time we polled */ + _PRWaiterHash *waiter; /* pointer to hash table of wait receive objects */ + +#ifdef WINNT + /* + * On NT, idle threads are responsible for getting completed i/o. + * They need to add completed i/o to the io_ready list. Since + * idle threads cannot use nspr locks, we have to use an md lock + * to protect the io_ready list. + */ + _MDLock mdlock; /* protect io_ready, waiter, and wait_list */ + PRCList wait_list; /* used in place of io_complete. reuse + * waitQLinks in the PRThread structure. */ +#endif /* WINNT */ +}; + +/********************************************************************** +*********************************************************************** +******************** Wait group enumerations ************************** +*********************************************************************** +**********************************************************************/ +typedef struct _PRGlobalState +{ + PRCList group_list; /* master of the group list */ + PRWaitGroup *group; /* the default (NULL) group */ +} _PRGlobalState; + +#ifdef WINNT +extern PRStatus NT_HashRemoveInternal(PRWaitGroup *group, PRFileDesc *fd); +#endif + +typedef enum {_PR_ENUM_UNSEALED=0, _PR_ENUM_SEALED=0x0eadface} _PREnumSeal; + +struct PRMWaitEnumerator +{ + PRWaitGroup *group; /* group this enumerator is bound to */ + PRThread *thread; /* thread in midst of an enumeration */ + _PREnumSeal seal; /* trying to detect deleted objects */ + PRUint32 p_timestamp; /* when enumeration was (re)started */ + PRRecvWait **waiter; /* pointer into hash table */ + PRUintn index; /* position in hash table */ + void *pad[4]; /* some room to grow */ +}; + +#endif /* defined(_PPRMWAIT_H) */ + +/* pprmwait.h */ diff -Nru nspr-4.9.5/nspr/pr/include/private/pprthred.h nspr-4.10.7/nspr/pr/include/private/pprthred.h --- nspr-4.9.5/nspr/pr/include/private/pprthred.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/private/pprthred.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,331 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef pprthred_h___ +#define pprthred_h___ + +/* +** API for PR private functions. These calls are to be used by internal +** developers only. +*/ +#include "nspr.h" + +#if defined(XP_OS2) +#define INCL_DOS +#define INCL_DOSERRORS +#define INCL_WIN +#include +#endif + +PR_BEGIN_EXTERN_C + +/*--------------------------------------------------------------------------- +** THREAD PRIVATE FUNCTIONS +---------------------------------------------------------------------------*/ + +/* +** Associate a thread object with an existing native thread. +** "type" is the type of thread object to attach +** "priority" is the priority to assign to the thread +** "stack" defines the shape of the threads stack +** +** This can return NULL if some kind of error occurs, or if memory is +** tight. This call invokes "start(obj,arg)" and returns when the +** function returns. The thread object is automatically destroyed. +** +** This call is not normally needed unless you create your own native +** thread. PR_Init does this automatically for the primordial thread. +*/ +NSPR_API(PRThread*) PR_AttachThread(PRThreadType type, + PRThreadPriority priority, + PRThreadStack *stack); + +/* +** Detach the nspr thread from the currently executing native thread. +** The thread object will be destroyed and all related data attached +** to it. The exit procs will be invoked. +** +** This call is not normally needed unless you create your own native +** thread. PR_Exit will automatially detach the nspr thread object +** created by PR_Init for the primordial thread. +** +** This call returns after the nspr thread object is destroyed. +*/ +NSPR_API(void) PR_DetachThread(void); + +/* +** Get the id of the named thread. Each thread is assigned a unique id +** when it is created or attached. +*/ +NSPR_API(PRUint32) PR_GetThreadID(PRThread *thread); + +/* +** Set the procedure that is called when a thread is dumped. The procedure +** will be applied to the argument, arg, when called. Setting the procedure +** to NULL effectively removes it. +*/ +typedef void (*PRThreadDumpProc)(PRFileDesc *fd, PRThread *t, void *arg); +NSPR_API(void) PR_SetThreadDumpProc( + PRThread* thread, PRThreadDumpProc dump, void *arg); + +/* +** Get this thread's affinity mask. The affinity mask is a 32 bit quantity +** marking a bit for each processor this process is allowed to run on. +** The processor mask is returned in the mask argument. +** The least-significant-bit represents processor 0. +** +** Returns 0 on success, -1 on failure. +*/ +NSPR_API(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask); + +/* +** Set this thread's affinity mask. +** +** Returns 0 on success, -1 on failure. +*/ +NSPR_API(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask ); + +/* +** Set the default CPU Affinity mask. +** +*/ +NSPR_API(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask); + +/* +** Show status of all threads to standard error output. +*/ +NSPR_API(void) PR_ShowStatus(void); + +/* +** Set thread recycle mode to on (1) or off (0) +*/ +NSPR_API(void) PR_SetThreadRecycleMode(PRUint32 flag); + + +/*--------------------------------------------------------------------------- +** THREAD PRIVATE FUNCTIONS FOR GARBAGE COLLECTIBLE THREADS +---------------------------------------------------------------------------*/ + +/* +** Only Garbage collectible threads participate in resume all, suspend all and +** enumeration operations. They are also different during creation when +** platform specific action may be needed (For example, all Solaris GC able +** threads are bound threads). +*/ + +/* +** Same as PR_CreateThread except that the thread is marked as garbage +** collectible. +*/ +NSPR_API(PRThread*) PR_CreateThreadGCAble(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize); + +/* +** Same as PR_AttachThread except that the thread being attached is marked as +** garbage collectible. +*/ +NSPR_API(PRThread*) PR_AttachThreadGCAble(PRThreadType type, + PRThreadPriority priority, + PRThreadStack *stack); + +/* +** Mark the thread as garbage collectible. +*/ +NSPR_API(void) PR_SetThreadGCAble(void); + +/* +** Unmark the thread as garbage collectible. +*/ +NSPR_API(void) PR_ClearThreadGCAble(void); + +/* +** This routine prevents all other GC able threads from running. This call is needed by +** the garbage collector. +*/ +NSPR_API(void) PR_SuspendAll(void); + +/* +** This routine unblocks all other GC able threads that were suspended from running by +** PR_SuspendAll(). This call is needed by the garbage collector. +*/ +NSPR_API(void) PR_ResumeAll(void); + +/* +** Return the thread stack pointer of the given thread. +** Needed by the garbage collector. +*/ +NSPR_API(void *) PR_GetSP(PRThread *thread); + +/* +** Save the registers that the GC would find interesting into the thread +** "t". isCurrent will be non-zero if the thread state that is being +** saved is the currently executing thread. Return the address of the +** first register to be scanned as well as the number of registers to +** scan in "np". +** +** If "isCurrent" is non-zero then it is allowed for the thread context +** area to be used as scratch storage to hold just the registers +** necessary for scanning. +** +** This function simply calls the internal function _MD_HomeGCRegisters(). +*/ +NSPR_API(PRWord *) PR_GetGCRegisters(PRThread *t, int isCurrent, int *np); + +/* +** (Get|Set)ExecutionEnvironent +** +** Used by Java to associate it's execution environment so garbage collector +** can find it. If return is NULL, then it's probably not a collectable thread. +** +** There's no locking required around these calls. +*/ +NSPR_API(void*) GetExecutionEnvironment(PRThread *thread); +NSPR_API(void) SetExecutionEnvironment(PRThread* thread, void *environment); + +/* +** Enumeration function that applies "func(thread,i,arg)" to each active +** thread in the process. The enumerator returns PR_SUCCESS if the enumeration +** should continue, any other value is considered failure, and enumeration +** stops, returning the failure value from PR_EnumerateThreads. +** Needed by the garbage collector. +*/ +typedef PRStatus (PR_CALLBACK *PREnumerator)(PRThread *t, int i, void *arg); +NSPR_API(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg); + +/* +** Signature of a thread stack scanning function. It is applied to every +** contiguous group of potential pointers within a thread. Count denotes the +** number of pointers. +*/ +typedef PRStatus +(PR_CALLBACK *PRScanStackFun)(PRThread* t, + void** baseAddr, PRUword count, void* closure); + +/* +** Applies scanFun to all contiguous groups of potential pointers +** within a thread. This includes the stack, registers, and thread-local +** data. If scanFun returns a status value other than PR_SUCCESS the scan +** is aborted, and the status value is returned. +*/ +NSPR_API(PRStatus) +PR_ThreadScanStackPointers(PRThread* t, + PRScanStackFun scanFun, void* scanClosure); + +/* +** Calls PR_ThreadScanStackPointers for every thread. +*/ +NSPR_API(PRStatus) +PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure); + +/* +** Returns a conservative estimate on the amount of stack space left +** on a thread in bytes, sufficient for making decisions about whether +** to continue recursing or not. +*/ +NSPR_API(PRUword) +PR_GetStackSpaceLeft(PRThread* t); + +/*--------------------------------------------------------------------------- +** THREAD CPU PRIVATE FUNCTIONS +---------------------------------------------------------------------------*/ + +/* +** Get a pointer to the primordial CPU. +*/ +NSPR_API(struct _PRCPU *) _PR_GetPrimordialCPU(void); + +/*--------------------------------------------------------------------------- +** THREAD SYNCHRONIZATION PRIVATE FUNCTIONS +---------------------------------------------------------------------------*/ + +/* +** Create a new named monitor (named for debugging purposes). +** Monitors are re-entrant locks with a built-in condition variable. +** +** This may fail if memory is tight or if some operating system resource +** is low. +*/ +NSPR_API(PRMonitor*) PR_NewNamedMonitor(const char* name); + +/* +** Test and then lock the lock if it's not already locked by some other +** thread. Return PR_FALSE if some other thread owned the lock at the +** time of the call. +*/ +NSPR_API(PRBool) PR_TestAndLock(PRLock *lock); + +/* +** Test and then enter the mutex associated with the monitor if it's not +** already entered by some other thread. Return PR_FALSE if some other +** thread owned the mutex at the time of the call. +*/ +NSPR_API(PRBool) PR_TestAndEnterMonitor(PRMonitor *mon); + +/* +** Return the number of times that the current thread has entered the +** mutex. Returns zero if the current thread has not entered the mutex. +*/ +NSPR_API(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon); + +/* +** Just like PR_CEnterMonitor except that if the monitor is owned by +** another thread NULL is returned. +*/ +NSPR_API(PRMonitor*) PR_CTestAndEnterMonitor(void *address); + +/*--------------------------------------------------------------------------- +** PLATFORM-SPECIFIC INITIALIZATION FUNCTIONS +---------------------------------------------------------------------------*/ +#if defined(IRIX) +/* +** Irix specific initialization funtion to be called before PR_Init +** is called by the application. Sets the CONF_INITUSERS and CONF_INITSIZE +** attributes of the shared arena set up by nspr. +** +** The environment variables _NSPR_IRIX_INITUSERS and _NSPR_IRIX_INITSIZE +** can also be used to set these arena attributes. If _NSPR_IRIX_INITUSERS +** is set, but not _NSPR_IRIX_INITSIZE, the value of the CONF_INITSIZE +** attribute of the nspr arena is scaled as a function of the +** _NSPR_IRIX_INITUSERS value. +** +** If the _PR_Irix_Set_Arena_Params() is called in addition to setting the +** environment variables, the values of the environment variables are used. +** +*/ +NSPR_API(void) _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize); + +#endif /* IRIX */ + +#if defined(XP_OS2) +/* +** These functions need to be called at the start and end of a thread. +** An EXCEPTIONREGISTRATIONRECORD must be declared on the stack and its +** address passed to the two functions. +*/ +NSPR_API(void) PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* e); +NSPR_API(void) PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* e); +#endif /* XP_OS2 */ + +/* I think PR_GetMonitorEntryCount is useless. All you really want is this... */ +#define PR_InMonitor(m) (PR_GetMonitorEntryCount(m) > 0) + +/*--------------------------------------------------------------------------- +** Special X-Lock hack for client +---------------------------------------------------------------------------*/ + +#ifdef XP_UNIX +extern void PR_XLock(void); +extern void PR_XUnlock(void); +extern PRBool PR_XIsLocked(void); +#endif /* XP_UNIX */ + +PR_END_EXTERN_C + +#endif /* pprthred_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/private/primpl.h nspr-4.10.7/nspr/pr/include/private/primpl.h --- nspr-4.9.5/nspr/pr/include/private/primpl.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/private/primpl.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,2151 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef primpl_h___ +#define primpl_h___ + +/* + * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which + * has: + * #define sigaction _sigaction_sys + * This macro causes chaos if signal.h gets included before pthread.h. + * To be safe, we include pthread.h first. + */ + +#if defined(_PR_PTHREADS) +#include +#endif + +#if defined(_PR_BTHREADS) +#include +#endif + +#ifdef WIN32 +/* + * Allow use of functions and symbols first defined in Win2k. + */ +#if !defined(WINVER) || (WINVER < 0x0500) +#undef WINVER +#define WINVER 0x0500 +#endif +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 +#endif +#endif /* WIN32 */ + +#include "nspr.h" +#include "prpriv.h" + +typedef struct PRSegment PRSegment; + +#include "md/prosdep.h" +#include "obsolete/probslet.h" + +#ifdef _PR_HAVE_POSIX_SEMAPHORES +#include +#elif defined(_PR_HAVE_SYSV_SEMAPHORES) +#include +#endif + +#ifdef HAVE_SYSCALL +#include +#endif + +/************************************************************************* +***** A Word about Model Dependent Function Naming Convention *********** +*************************************************************************/ + +/* +NSPR 2.0 must implement its function across a range of platforms +including: MAC, Windows/16, Windows/95, Windows/NT, and several +variants of Unix. Each implementation shares common code as well +as having platform dependent portions. This standard describes how +the model dependent portions are to be implemented. + +In header file pr/include/primpl.h, each publicly declared +platform dependent function is declared as: + +NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 ); +#define _PR_MD_FUNCTION _MD_FUNCTION + +In header file pr/include/md//_.h, +each #define'd macro is redefined as one of: + +#define _MD_FUNCTION +#define _MD_FUNCTION +#define _MD_FUNCTION +#define _MD_FUNCTION <_MD_Function> + +Where: + + is no definition at all. In this case, the function is not implemented +and is never called for this platform. +For example: +#define _MD_INIT_CPUS() + + is a C language macro expansion. +For example: +#define _MD_CLEAN_THREAD(_thread) \ + PR_BEGIN_MACRO \ + PR_DestroyCondVar(_thread->md.asyncIOCVar); \ + PR_DestroyLock(_thread->md.asyncIOLock); \ + PR_END_MACRO + + is some function implemented by the host operating system. +For example: +#define _MD_EXIT exit + +<_MD_function> is the name of a function implemented for this platform in +pr/src/md//.c file. +For example: +#define _MD_GETFILEINFO _MD_GetFileInfo + +In .c, the implementation is: +PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info); +*/ + +PR_BEGIN_EXTERN_C + +typedef struct _MDLock _MDLock; +typedef struct _MDCVar _MDCVar; +typedef struct _MDSegment _MDSegment; +typedef struct _MDThread _MDThread; +typedef struct _MDThreadStack _MDThreadStack; +typedef struct _MDSemaphore _MDSemaphore; +typedef struct _MDDir _MDDir; +#ifdef MOZ_UNICODE +typedef struct _MDDirUTF16 _MDDirUTF16; +#endif /* MOZ_UNICODE */ +typedef struct _MDFileDesc _MDFileDesc; +typedef struct _MDProcess _MDProcess; +typedef struct _MDFileMap _MDFileMap; + +#if defined(_PR_PTHREADS) + +/* +** The following definitions are unique to implementing NSPR using pthreads. +** Since pthreads defines most of the thread and thread synchronization +** stuff, this is a pretty small set. +*/ + +#define PT_CV_NOTIFIED_LENGTH 6 +typedef struct _PT_Notified _PT_Notified; +struct _PT_Notified +{ + PRIntn length; /* # of used entries in this structure */ + struct + { + PRCondVar *cv; /* the condition variable notified */ + PRIntn times; /* and the number of times notified */ + } cv[PT_CV_NOTIFIED_LENGTH]; + _PT_Notified *link; /* link to another of these | NULL */ +}; + +/* + * bits defined for pthreads 'state' field + */ +#define PT_THREAD_DETACHED 0x01 /* thread can't be joined */ +#define PT_THREAD_GLOBAL 0x02 /* a global thread (unlikely) */ +#define PT_THREAD_SYSTEM 0x04 /* system (not user) thread */ +#define PT_THREAD_PRIMORD 0x08 /* this is the primordial thread */ +#define PT_THREAD_ABORTED 0x10 /* thread has been interrupted */ +#define PT_THREAD_GCABLE 0x20 /* thread is garbage collectible */ +#define PT_THREAD_SUSPENDED 0x40 /* thread has been suspended */ +#define PT_THREAD_FOREIGN 0x80 /* thread is not one of ours */ +#define PT_THREAD_BOUND 0x100 /* a bound-global thread */ + +#define _PT_THREAD_INTERRUPTED(thr) \ + (!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED)) +#define _PT_THREAD_BLOCK_INTERRUPT(thr) \ + (thr->interrupt_blocked = 1) +#define _PT_THREAD_UNBLOCK_INTERRUPT(thr) \ + (thr->interrupt_blocked = 0) + +#define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE) + +/* +** Possible values for thread's suspend field +** Note that the first two can be the same as they are really mutually exclusive, +** i.e. both cannot be happening at the same time. We have two symbolic names +** just as a mnemonic. +**/ +#define PT_THREAD_RESUMED 0x80 /* thread has been resumed */ +#define PT_THREAD_SETGCABLE 0x100 /* set the GCAble flag */ + +#if defined(DEBUG) + +typedef struct PTDebug +{ + PRTime timeStarted; + PRUintn locks_created, locks_destroyed; + PRUintn locks_acquired, locks_released; + PRUintn cvars_created, cvars_destroyed; + PRUintn cvars_notified, delayed_cv_deletes; +} PTDebug; + +#endif /* defined(DEBUG) */ + +NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg); + +/* + * On Linux and its derivatives POSIX priority scheduling works only for + * real-time threads. On those platforms we set thread's nice values + * instead which requires us to track kernel thread IDs for each POSIX + * thread we create. + */ +#if defined(LINUX) && defined(HAVE_SETPRIORITY) && \ + ((defined(HAVE_SYSCALL) && defined(SYS_gettid)) || defined(HAVE_GETTID)) +#define _PR_NICE_PRIORITY_SCHEDULING +#endif + +#else /* defined(_PR_PTHREADS) */ + +NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg); + +/* +** This section is contains those parts needed to implement NSPR on +** platforms in general. One would assume that the pthreads implementation +** included lots of the same types, at least conceptually. +*/ + +/* + * Local threads only. No multiple CPU support and hence all the + * following routines are no-op. + */ +#ifdef _PR_LOCAL_THREADS_ONLY + +#define _PR_MD_SUSPEND_THREAD(thread) +#define _PR_MD_RESUME_THREAD(thread) +#define _PR_MD_SUSPEND_CPU(cpu) +#define _PR_MD_RESUME_CPU(cpu) +#define _PR_MD_BEGIN_SUSPEND_ALL() +#define _PR_MD_END_SUSPEND_ALL() +#define _PR_MD_BEGIN_RESUME_ALL() +#define _PR_MD_END_RESUME_ALL() +#define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE + +#endif + +typedef struct _PRCPUQueue _PRCPUQueue; +typedef struct _PRCPU _PRCPU; +typedef struct _MDCPU _MDCPU; + +struct _PRCPUQueue { + _MDLock runQLock; /* lock for the run + wait queues */ + _MDLock sleepQLock; /* lock for the run + wait queues */ + _MDLock miscQLock; /* lock for the run + wait queues */ + + PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */ + PRUint32 runQReadyMask; + PRCList sleepQ; + PRIntervalTime sleepQmax; + PRCList pauseQ; + PRCList suspendQ; + PRCList waitingToJoinQ; + + PRUintn numCPUs; /* number of CPUs using this Q */ +}; + +struct _PRCPU { + PRCList links; /* link list of CPUs */ + PRUint32 id; /* id for this CPU */ + + union { + PRInt32 bits; + PRUint8 missed[4]; + } u; + PRIntn where; /* index into u.missed */ + PRPackedBool paused; /* cpu is paused */ + PRPackedBool exit; /* cpu should exit */ + + PRThread *thread; /* native thread for this CPUThread */ + PRThread *idle_thread; /* user-level idle thread for this CPUThread */ + + PRIntervalTime last_clock; /* the last time we went into + * _PR_ClockInterrupt() on this CPU + */ + + _PRCPUQueue *queue; + + _MDCPU md; +}; + +typedef struct _PRInterruptTable { + const char *name; + PRUintn missed_bit; + void (*handler)(void); +} _PRInterruptTable; + +#define _PR_CPU_PTR(_qp) \ + ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links))) + +#if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \ + && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)) +#define _MD_GET_ATTACHED_THREAD() (_PR_MD_CURRENT_THREAD()) +#endif + +#ifdef _PR_LOCAL_THREADS_ONLY + +NSPR_API(struct _PRCPU *) _pr_currentCPU; +NSPR_API(PRThread *) _pr_currentThread; +NSPR_API(PRThread *) _pr_lastThread; +NSPR_API(PRInt32) _pr_intsOff; + +#define _MD_CURRENT_CPU() (_pr_currentCPU) +#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (_cpu)) +#define _MD_CURRENT_THREAD() (_pr_currentThread) +#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread)) +#define _MD_LAST_THREAD() (_pr_lastThread) +#define _MD_SET_LAST_THREAD(t) (_pr_lastThread = t) + +#define _MD_GET_INTSOFF() (_pr_intsOff) +#define _MD_SET_INTSOFF(_val) (_pr_intsOff = _val) + + +/* The unbalanced curly braces in these two macros are intentional */ +#define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is); +#define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); } + +#endif /* _PR_LOCAL_THREADS_ONLY */ + +extern PRInt32 _native_threads_only; + +#if defined(_PR_GLOBAL_THREADS_ONLY) + +#define _MD_GET_INTSOFF() 0 +#define _MD_SET_INTSOFF(_val) +#define _PR_INTSOFF(_is) +#define _PR_FAST_INTSON(_is) +#define _PR_INTSON(_is) +#define _PR_THREAD_LOCK(_thread) +#define _PR_THREAD_UNLOCK(_thread) +#define _PR_RUNQ_LOCK(cpu) +#define _PR_RUNQ_UNLOCK(cpu) +#define _PR_SLEEPQ_LOCK(thread) +#define _PR_SLEEPQ_UNLOCK(thread) +#define _PR_MISCQ_LOCK(thread) +#define _PR_MISCQ_UNLOCK(thread) +#define _PR_CPU_LIST_LOCK() +#define _PR_CPU_LIST_UNLOCK() + +#define _PR_ADD_RUNQ(_thread, _cpu, _pri) +#define _PR_DEL_RUNQ(_thread) +#define _PR_ADD_SLEEPQ(_thread, _timeout) +#define _PR_DEL_SLEEPQ(_thread, _propogate) +#define _PR_ADD_JOINQ(_thread, _cpu) +#define _PR_DEL_JOINQ(_thread) +#define _PR_ADD_SUSPENDQ(_thread, _cpu) +#define _PR_DEL_SUSPENDQ(_thread) + +#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) + +#define _PR_IS_NATIVE_THREAD(thread) 1 +#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1 + +#else + +#define _PR_INTSOFF(_is) \ + PR_BEGIN_MACRO \ + (_is) = _PR_MD_GET_INTSOFF(); \ + _PR_MD_SET_INTSOFF(1); \ + PR_END_MACRO + +#define _PR_FAST_INTSON(_is) \ + PR_BEGIN_MACRO \ + _PR_MD_SET_INTSOFF(_is); \ + PR_END_MACRO + +#define _PR_INTSON(_is) \ + PR_BEGIN_MACRO \ + if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \ + _PR_IntsOn((_PR_MD_CURRENT_CPU())); \ + _PR_MD_SET_INTSOFF(_is); \ + PR_END_MACRO + +#ifdef _PR_LOCAL_THREADS_ONLY + +#define _PR_IS_NATIVE_THREAD(thread) 0 +#define _PR_THREAD_LOCK(_thread) +#define _PR_THREAD_UNLOCK(_thread) +#define _PR_RUNQ_LOCK(cpu) +#define _PR_RUNQ_UNLOCK(cpu) +#define _PR_SLEEPQ_LOCK(thread) +#define _PR_SLEEPQ_UNLOCK(thread) +#define _PR_MISCQ_LOCK(thread) +#define _PR_MISCQ_UNLOCK(thread) +#define _PR_CPU_LIST_LOCK() +#define _PR_CPU_LIST_UNLOCK() + +#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \ + PR_BEGIN_MACRO \ + PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \ + _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \ + PR_END_MACRO + +#define _PR_DEL_RUNQ(_thread) \ + PR_BEGIN_MACRO \ + _PRCPU *_cpu = _thread->cpu; \ + PRInt32 _pri = _thread->priority; \ + PR_REMOVE_LINK(&(_thread)->links); \ + if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \ + _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \ + PR_END_MACRO + +#define _PR_ADD_SLEEPQ(_thread, _timeout) \ + _PR_AddSleepQ(_thread, _timeout); + +#define _PR_DEL_SLEEPQ(_thread, _propogate) \ + _PR_DelSleepQ(_thread, _propogate); + +#define _PR_ADD_JOINQ(_thread, _cpu) \ + PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu)); + +#define _PR_DEL_JOINQ(_thread) \ + PR_REMOVE_LINK(&(_thread)->links); + +#define _PR_ADD_SUSPENDQ(_thread, _cpu) \ + PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu)); + +#define _PR_DEL_SUSPENDQ(_thread) \ + PR_REMOVE_LINK(&(_thread)->links); + +#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) + +#define _PR_IS_NATIVE_THREAD_SUPPORTED() 0 + +#else /* _PR_LOCAL_THREADS_ONLY */ + +/* These are for the "combined" thread model */ + +#define _PR_THREAD_LOCK(_thread) \ + _PR_MD_LOCK(&(_thread)->threadLock); + +#define _PR_THREAD_UNLOCK(_thread) \ + _PR_MD_UNLOCK(&(_thread)->threadLock); + +#define _PR_RUNQ_LOCK(_cpu) \ + PR_BEGIN_MACRO \ + _PR_MD_LOCK(&(_cpu)->queue->runQLock );\ + PR_END_MACRO + +#define _PR_RUNQ_UNLOCK(_cpu) \ + PR_BEGIN_MACRO \ + _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\ + PR_END_MACRO + +#define _PR_SLEEPQ_LOCK(_cpu) \ + _PR_MD_LOCK(&(_cpu)->queue->sleepQLock ); + +#define _PR_SLEEPQ_UNLOCK(_cpu) \ + _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock ); + +#define _PR_MISCQ_LOCK(_cpu) \ + _PR_MD_LOCK(&(_cpu)->queue->miscQLock ); + +#define _PR_MISCQ_UNLOCK(_cpu) \ + _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock ); + +#define _PR_CPU_LIST_LOCK() _PR_MD_LOCK(&_pr_cpuLock) +#define _PR_CPU_LIST_UNLOCK() _PR_MD_UNLOCK(&_pr_cpuLock) + +#define QUEUE_RUN 0x1 +#define QUEUE_SLEEP 0x2 +#define QUEUE_JOIN 0x4 +#define QUEUE_SUSPEND 0x8 +#define QUEUE_LOCK 0x10 + +#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \ + PR_BEGIN_MACRO \ + PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \ + _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \ + PR_ASSERT((_thread)->queueCount == 0); \ + (_thread)->queueCount = QUEUE_RUN; \ + PR_END_MACRO + +#define _PR_DEL_RUNQ(_thread) \ + PR_BEGIN_MACRO \ + _PRCPU *_cpu = _thread->cpu; \ + PRInt32 _pri = _thread->priority; \ + PR_REMOVE_LINK(&(_thread)->links); \ + if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \ + _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \ + PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\ + (_thread)->queueCount = 0; \ + PR_END_MACRO + +#define _PR_ADD_SLEEPQ(_thread, _timeout) \ + PR_ASSERT((_thread)->queueCount == 0); \ + (_thread)->queueCount = QUEUE_SLEEP; \ + _PR_AddSleepQ(_thread, _timeout); + +#define _PR_DEL_SLEEPQ(_thread, _propogate) \ + PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\ + (_thread)->queueCount = 0; \ + _PR_DelSleepQ(_thread, _propogate); + +#define _PR_ADD_JOINQ(_thread, _cpu) \ + PR_ASSERT((_thread)->queueCount == 0); \ + (_thread)->queueCount = QUEUE_JOIN; \ + PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu)); + +#define _PR_DEL_JOINQ(_thread) \ + PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\ + (_thread)->queueCount = 0; \ + PR_REMOVE_LINK(&(_thread)->links); + +#define _PR_ADD_SUSPENDQ(_thread, _cpu) \ + PR_ASSERT((_thread)->queueCount == 0); \ + (_thread)->queueCount = QUEUE_SUSPEND; \ + PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu)); + +#define _PR_DEL_SUSPENDQ(_thread) \ + PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\ + (_thread)->queueCount = 0; \ + PR_REMOVE_LINK(&(_thread)->links); + +#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \ + (_thread)->cpu = (_newCPU); + +#define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE) +#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1 + +#endif /* _PR_LOCAL_THREADS_ONLY */ + +#endif /* _PR_GLOBAL_THREADS_ONLY */ + +#define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1 +#define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0 + +extern _PRInterruptTable _pr_interruptTable[]; + +/* Bits for _pr_interruptState.u.missed[0,1] */ +#define _PR_MISSED_CLOCK 0x1 +#define _PR_MISSED_IO 0x2 +#define _PR_MISSED_CHILD 0x4 + +extern void _PR_IntsOn(_PRCPU *cpu); + +NSPR_API(void) _PR_WakeupCPU(void); +NSPR_API(void) _PR_PauseCPU(void); + +/************************************************************************/ + +#define _PR_LOCK_LOCK(_lock) \ + _PR_MD_LOCK(&(_lock)->ilock); +#define _PR_LOCK_UNLOCK(_lock) \ + _PR_MD_UNLOCK(&(_lock)->ilock); + +extern void _PR_UnblockLockWaiter(PRLock *lock); +extern PRStatus _PR_InitLock(PRLock *lock); +extern void _PR_FreeLock(PRLock *lock); + +#define _PR_LOCK_PTR(_qp) \ + ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links))) + +/************************************************************************/ + +#define _PR_CVAR_LOCK(_cvar) \ + _PR_MD_LOCK(&(_cvar)->ilock); +#define _PR_CVAR_UNLOCK(_cvar) \ + _PR_MD_UNLOCK(&(_cvar)->ilock); + +extern PRStatus _PR_InitCondVar(PRCondVar *cvar, PRLock *lock); +extern void _PR_FreeCondVar(PRCondVar *cvar); +extern PRStatus _PR_WaitCondVar( + PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout); +extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me); +extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen); + +NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky); + +/* PRThread.flags */ +#define _PR_SYSTEM 0x01 +#define _PR_INTERRUPT 0x02 +#define _PR_ATTACHED 0x04 /* created via PR_AttachThread */ +#define _PR_PRIMORDIAL 0x08 /* the thread that called PR_Init */ +#define _PR_ON_SLEEPQ 0x10 /* thread is on the sleepQ */ +#define _PR_ON_PAUSEQ 0x20 /* thread is on the pauseQ */ +#define _PR_SUSPENDING 0x40 /* thread wants to suspend */ +#define _PR_GLOBAL_SCOPE 0x80 /* thread is global scope */ +#define _PR_IDLE_THREAD 0x200 /* this is an idle thread */ +#define _PR_GCABLE_THREAD 0x400 /* this is a collectable thread */ +#define _PR_BOUND_THREAD 0x800 /* a bound thread */ +#define _PR_INTERRUPT_BLOCKED 0x1000 /* interrupts blocked */ + +/* PRThread.state */ +#define _PR_UNBORN 0 +#define _PR_RUNNABLE 1 +#define _PR_RUNNING 2 +#define _PR_LOCK_WAIT 3 +#define _PR_COND_WAIT 4 +#define _PR_JOIN_WAIT 5 +#define _PR_IO_WAIT 6 +#define _PR_SUSPENDED 7 +#define _PR_DEAD_STATE 8 /* for debugging */ + +/* PRThreadStack.flags */ +#define _PR_STACK_VM 0x1 /* using vm instead of malloc */ +#define _PR_STACK_MAPPED 0x2 /* vm is mapped */ +#define _PR_STACK_PRIMORDIAL 0x4 /* stack for primordial thread */ + +/* +** If the default stcksize from the client is zero, we need to pick a machine +** dependent value. This is only for standard user threads. For custom threads, +** 0 has a special meaning. +** Adjust stackSize. Round up to a page boundary. +*/ + +#ifndef _MD_MINIMUM_STACK_SIZE +#define _MD_MINIMUM_STACK_SIZE 0 +#endif + +#if (!defined(HAVE_CUSTOM_USER_THREADS)) +#define _PR_ADJUST_STACKSIZE(stackSize) \ + PR_BEGIN_MACRO \ + if (stackSize == 0) \ + stackSize = _MD_DEFAULT_STACK_SIZE; \ + if (stackSize < _MD_MINIMUM_STACK_SIZE) \ + stackSize = _MD_MINIMUM_STACK_SIZE; \ + stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \ + stackSize <<= _pr_pageShift; \ + PR_END_MACRO +#else +#define _PR_ADJUST_STACKSIZE(stackSize) +#endif + +#define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD) + +#define _PR_PENDING_INTERRUPT(thr) \ + (!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT)) +#define _PR_THREAD_BLOCK_INTERRUPT(thr) \ + (thr->flags |= _PR_INTERRUPT_BLOCKED) +#define _PR_THREAD_UNBLOCK_INTERRUPT(thr) \ + (thr->flags &= ~_PR_INTERRUPT_BLOCKED) + +#define _PR_THREAD_PTR(_qp) \ + ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links))) + +#define _PR_ACTIVE_THREAD_PTR(_qp) \ + ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active))) + +#define _PR_THREAD_CONDQ_PTR(_qp) \ + ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks))) + +#define _PR_THREAD_MD_TO_PTR(_md) \ + ((PRThread*) ((char*) (_md) - offsetof(PRThread,md))) + +#define _PR_THREAD_STACK_TO_PTR(_stack) \ + ((PRThread*) (_stack->thr)) + +extern PRCList _pr_active_local_threadQ; +extern PRCList _pr_active_global_threadQ; +extern PRCList _pr_cpuQ; +extern _MDLock _pr_cpuLock; +extern PRInt32 _pr_md_idle_cpus; + +#define _PR_ACTIVE_LOCAL_THREADQ() _pr_active_local_threadQ +#define _PR_ACTIVE_GLOBAL_THREADQ() _pr_active_global_threadQ +#define _PR_CPUQ() _pr_cpuQ +#define _PR_RUNQ(_cpu) ((_cpu)->queue->runQ) +#define _PR_RUNQREADYMASK(_cpu) ((_cpu)->queue->runQReadyMask) +#define _PR_SLEEPQ(_cpu) ((_cpu)->queue->sleepQ) +#define _PR_SLEEPQMAX(_cpu) ((_cpu)->queue->sleepQmax) +#define _PR_PAUSEQ(_cpu) ((_cpu)->queue->pauseQ) +#define _PR_SUSPENDQ(_cpu) ((_cpu)->queue->suspendQ) +#define _PR_WAITINGTOJOINQ(_cpu) ((_cpu)->queue->waitingToJoinQ) + +extern PRUint32 _pr_recycleThreads; /* Flag for behavior on thread cleanup */ +extern PRLock *_pr_deadQLock; +extern PRUint32 _pr_numNativeDead; +extern PRUint32 _pr_numUserDead; +extern PRCList _pr_deadNativeQ; +extern PRCList _pr_deadUserQ; +#define _PR_DEADNATIVEQ _pr_deadNativeQ +#define _PR_DEADUSERQ _pr_deadUserQ +#define _PR_DEADQ_LOCK PR_Lock(_pr_deadQLock); +#define _PR_DEADQ_UNLOCK PR_Unlock(_pr_deadQLock); +#define _PR_INC_DEADNATIVE (_pr_numNativeDead++) +#define _PR_DEC_DEADNATIVE (_pr_numNativeDead--) +#define _PR_NUM_DEADNATIVE (_pr_numNativeDead) +#define _PR_INC_DEADUSER (_pr_numUserDead++) +#define _PR_DEC_DEADUSER (_pr_numUserDead--) +#define _PR_NUM_DEADUSER (_pr_numUserDead) + +extern PRUint32 _pr_utid; + +extern struct _PRCPU *_pr_primordialCPU; + +extern PRLock *_pr_activeLock; /* lock for userActive and systemActive */ +extern PRInt32 _pr_userActive; /* number of active user threads */ +extern PRInt32 _pr_systemActive; /* number of active system threads */ +extern PRInt32 _pr_primordialExitCount; /* number of user threads left + * before the primordial thread + * can exit. */ +extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for + * notifying the primordial thread + * when all other user threads + * have terminated. */ + +extern PRUintn _pr_maxPTDs; + +extern PRLock *_pr_terminationCVLock; + +/************************************************************************* +* Internal routines either called by PR itself or from machine-dependent * +* code. * +*************************************************************************/ + +extern void _PR_ClockInterrupt(void); + +extern void _PR_Schedule(void); +extern void _PR_SetThreadPriority( + PRThread* thread, PRThreadPriority priority); + +/*********************************************************************** +** FUNCTION: _PR_NewSegment() +** DESCRIPTION: +** Allocate a memory segment. The "size" value is rounded up to the +** native system page size and a page aligned portion of memory is +** returned. This memory is not part of the malloc heap. If "vaddr" is +** not NULL then PR tries to allocate the segment at the desired virtual +** address. +** INPUTS: size: size of the desired memory segment +** vaddr: address at which the newly aquired segment is to be +** mapped into memory. +** OUTPUTS: a memory segment is allocated, a PRSegment is allocated +** RETURN: pointer to PRSegment +***********************************************************************/ +extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr); + +/*********************************************************************** +** FUNCTION: _PR_DestroySegment() +** DESCRIPTION: +** The memory segment and the PRSegment are freed +** INPUTS: seg: pointer to PRSegment to be freed +** OUTPUTS: the the PRSegment and its associated memory segment are freed +** RETURN: void +***********************************************************************/ +extern void _PR_DestroySegment(PRSegment *seg); + +extern PRThreadStack * _PR_NewStack(PRUint32 stackSize); +extern void _PR_FreeStack(PRThreadStack *stack); +extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me); +extern void _PR_NotifyLockedThread (PRThread *thread); + +NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout); +NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time); + +extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread); + +NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize, + PRUint32 flags); + +extern void _PR_NativeDestroyThread(PRThread *thread); +extern void _PR_UserDestroyThread(PRThread *thread); + +extern PRThread* _PRI_AttachThread( + PRThreadType type, PRThreadPriority priority, + PRThreadStack *stack, PRUint32 flags); + +extern void _PRI_DetachThread(void); + + +#define _PR_IO_PENDING(_thread) ((_thread)->io_pending) + +NSPR_API(void) _PR_MD_INIT_CPUS(); +#define _PR_MD_INIT_CPUS _MD_INIT_CPUS + +NSPR_API(void) _PR_MD_WAKEUP_CPUS(); +#define _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS + +/* Interrupts related */ + +NSPR_API(void) _PR_MD_START_INTERRUPTS(void); +#define _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS + +NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void); +#define _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS + +NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void); +#define _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS + +NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void); +#define _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS + +NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void); +#define _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS + +NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void); +#define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS + +/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and + * awaken a thread which is waiting on a lock or cvar. + */ +extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout); +#define _PR_MD_WAIT _MD_WAIT + +extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *); +#define _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER + +#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ +NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void); +#define _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT +#endif + +/* Stack debugging */ +NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone); +#define _PR_MD_INIT_STACK _MD_INIT_STACK + +NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts); +#define _PR_MD_CLEAR_STACK _MD_CLEAR_STACK + +/* CPU related */ +NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void); +#define _PR_MD_GET_INTSOFF _MD_GET_INTSOFF + +NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val); +#define _PR_MD_SET_INTSOFF _MD_SET_INTSOFF + +NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void); +#define _PR_MD_CURRENT_CPU _MD_CURRENT_CPU + +NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu); +#define _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU + +NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu); +#define _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU + +/* + * Returns the number of threads awoken or 0 if a timeout occurred; + */ +extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout); +#define _PR_MD_PAUSE_CPU _MD_PAUSE_CPU + +extern void _PR_MD_CLEANUP_BEFORE_EXIT(void); +#define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT + +extern void _PR_MD_EXIT(PRIntn status); +#define _PR_MD_EXIT _MD_EXIT + +/* Locks related */ + +NSPR_API(void) _PR_MD_INIT_LOCKS(void); +#define _PR_MD_INIT_LOCKS _MD_INIT_LOCKS + +NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md); +#define _PR_MD_NEW_LOCK _MD_NEW_LOCK + +NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md); +#define _PR_MD_FREE_LOCK _MD_FREE_LOCK + +NSPR_API(void) _PR_MD_LOCK(_MDLock *md); +#define _PR_MD_LOCK _MD_LOCK + +/* Return 0 on success, a nonzero value on failure. */ +NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md); +#define _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK + +NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md); +#define _PR_MD_UNLOCK _MD_UNLOCK + +NSPR_API(void) _PR_MD_IOQ_LOCK(void); +#define _PR_MD_IOQ_LOCK _MD_IOQ_LOCK + +NSPR_API(void) _PR_MD_IOQ_UNLOCK(void); +#define _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK + +#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ +/* Semaphore related -- only for native threads */ +#ifdef HAVE_CVAR_BUILT_ON_SEM +NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value); +#define _PR_MD_NEW_SEM _MD_NEW_SEM + +NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md); +#define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM + +NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM( + _MDSemaphore *md, PRIntervalTime timeout); +#define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM + +NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md); +#define _PR_MD_WAIT_SEM _MD_WAIT_SEM + +NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md); +#define _PR_MD_POST_SEM _MD_POST_SEM +#endif /* HAVE_CVAR_BUILT_ON_SEM */ + +#endif + +/* Condition Variables related -- only for native threads */ + +#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ +NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md); +#define _PR_MD_NEW_CV _MD_NEW_CV + +NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md); +#define _PR_MD_FREE_CV _MD_FREE_CV + +NSPR_API(void) _PR_MD_WAIT_CV( + _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout); +#define _PR_MD_WAIT_CV _MD_WAIT_CV + +NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock); +#define _PR_MD_NOTIFY_CV _MD_NOTIFY_CV + +NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock); +#define _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV +#endif /* _PR_LOCAL_THREADS_ONLY */ + +/* Threads related */ +NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void); +#define _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD + +NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void); +#define _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD + +NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void); +#define _PR_MD_LAST_THREAD _MD_LAST_THREAD + +NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread); +#define _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD + +NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread); +#define _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD + +extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread); +#define _PR_MD_INIT_THREAD _MD_INIT_THREAD + +extern void _PR_MD_EXIT_THREAD(PRThread *thread); +#define _PR_MD_EXIT_THREAD _MD_EXIT_THREAD + +#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */ + +NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread); +#define _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD + +extern void _PR_MD_SUSPEND_THREAD(PRThread *thread); +#define _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD + +extern void _PR_MD_RESUME_THREAD(PRThread *thread); +#define _PR_MD_RESUME_THREAD _MD_RESUME_THREAD + +extern void _PR_MD_SUSPEND_CPU(_PRCPU *cpu); +#define _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU + +extern void _PR_MD_RESUME_CPU(_PRCPU *cpu); +#define _PR_MD_RESUME_CPU _MD_RESUME_CPU + +extern void _PR_MD_BEGIN_SUSPEND_ALL(void); +#define _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL + +extern void _PR_MD_END_SUSPEND_ALL(void); +#define _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL + +extern void _PR_MD_BEGIN_RESUME_ALL(void); +#define _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL + +extern void _PR_MD_END_RESUME_ALL(void); +#define _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL + +#if defined(IRIX) +NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void); +#endif /* IRIX */ + +#endif /* !_PR_LOCAL_THREADS_ONLY */ + +extern void _PR_MD_CLEAN_THREAD(PRThread *thread); +#define _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD + +#ifdef HAVE_CUSTOM_USER_THREADS +extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *); +#define _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD + +extern PRThread* _PR_MD_CREATE_USER_THREAD( + PRUint32 stacksize, + void (*start)(void *), + void *arg); +#define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD +#endif + +extern PRStatus _PR_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize); +#define _PR_MD_CREATE_THREAD _MD_CREATE_THREAD + +extern void _PR_MD_JOIN_THREAD(_MDThread *md); +#define _PR_MD_JOIN_THREAD _MD_JOIN_THREAD + +extern void _PR_MD_END_THREAD(void); +#define _PR_MD_END_THREAD _MD_END_THREAD + +extern void _PR_MD_YIELD(void); +#define _PR_MD_YIELD _MD_YIELD + +extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri); +#define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY + +extern void _PR_MD_SET_CURRENT_THREAD_NAME(const char *name); +#define _PR_MD_SET_CURRENT_THREAD_NAME _MD_SET_CURRENT_THREAD_NAME + +NSPR_API(void) _PR_MD_SUSPENDALL(void); +#define _PR_MD_SUSPENDALL _MD_SUSPENDALL + +NSPR_API(void) _PR_MD_RESUMEALL(void); +#define _PR_MD_RESUMEALL _MD_RESUMEALL + +extern void _PR_MD_INIT_CONTEXT( + PRThread *thread, char *top, void (*start) (void), PRBool *status); +#define _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT + +extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread); +#define _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT + +extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread); +#define _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT + +/* Segment related */ +extern void _PR_MD_INIT_SEGS(void); +#define _PR_MD_INIT_SEGS _MD_INIT_SEGS + +extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr); +#define _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT + +extern void _PR_MD_FREE_SEGMENT(PRSegment *seg); +#define _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT + +/* Directory enumeration related */ +extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name); +#define _PR_MD_OPEN_DIR _MD_OPEN_DIR + +extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags); +#define _PR_MD_READ_DIR _MD_READ_DIR + +extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md); +#define _PR_MD_CLOSE_DIR _MD_CLOSE_DIR + +/* Named semaphores related */ +extern PRSem * _PR_MD_OPEN_SEMAPHORE( + const char *osname, PRIntn flags, PRIntn mode, PRUintn value); +#define _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE + +extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem); +#define _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE + +extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem); +#define _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE + +extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem); +#define _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE + +extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname); +#define _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE + +/* I/O related */ +extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd); +#define _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC + +extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd); +#define _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK + +/* File I/O related */ +extern PROsfd _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode); +#define _PR_MD_OPEN _MD_OPEN + +extern PROsfd _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode); +#define _PR_MD_OPEN_FILE _MD_OPEN_FILE + +extern PRInt32 _PR_MD_CLOSE_FILE(PROsfd osfd); +#define _PR_MD_CLOSE_FILE _MD_CLOSE_FILE + +extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount); +#define _PR_MD_READ _MD_READ + +extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount); +#define _PR_MD_WRITE _MD_WRITE + +extern PRInt32 _PR_MD_WRITEV( + PRFileDesc *fd, const struct PRIOVec *iov, + PRInt32 iov_size, PRIntervalTime timeout); +#define _PR_MD_WRITEV _MD_WRITEV + +extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd); +#define _PR_MD_FSYNC _MD_FSYNC + +extern PRInt32 _PR_MD_DELETE(const char *name); +#define _PR_MD_DELETE _MD_DELETE + +extern PRInt32 _PR_MD_RENAME(const char *from, const char *to); +#define _PR_MD_RENAME _MD_RENAME + +extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how); +#define _PR_MD_ACCESS _MD_ACCESS + +extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf); +#define _PR_MD_STAT _MD_STAT + +extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode); +#define _PR_MD_MKDIR _MD_MKDIR + +extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode); +#define _PR_MD_MAKE_DIR _MD_MAKE_DIR + +extern PRInt32 _PR_MD_RMDIR(const char *name); +#define _PR_MD_RMDIR _MD_RMDIR + +#ifdef MOZ_UNICODE +/* UTF16 File I/O related */ +extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name); +#define _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16 + +extern PROsfd _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode); +#define _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16 + +extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags); +#define _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16 + +extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md); +#define _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16 + +extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info); +#define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16 +#endif /* MOZ_UNICODE */ + +/* Socket I/O related */ +extern void _PR_MD_INIT_IO(void); +#define _PR_MD_INIT_IO _MD_INIT_IO + +extern PRInt32 _PR_MD_CLOSE_SOCKET(PROsfd osfd); +#define _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET + +extern PRInt32 _PR_MD_CONNECT( + PRFileDesc *fd, const PRNetAddr *addr, + PRUint32 addrlen, PRIntervalTime timeout); +#define _PR_MD_CONNECT _MD_CONNECT + +extern PROsfd _PR_MD_ACCEPT( + PRFileDesc *fd, PRNetAddr *addr, + PRUint32 *addrlen, PRIntervalTime timeout); +#define _PR_MD_ACCEPT _MD_ACCEPT + +extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen); +#define _PR_MD_BIND _MD_BIND + +extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog); +#define _PR_MD_LISTEN _MD_LISTEN + +extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how); +#define _PR_MD_SHUTDOWN _MD_SHUTDOWN + +extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout); +#define _PR_MD_RECV _MD_RECV + +extern PRInt32 _PR_MD_SEND( + PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + PRIntervalTime timeout); +#define _PR_MD_SEND _MD_SEND + +extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, + PRNetAddr **raddr, void *buf, PRInt32 amount, + PRIntervalTime timeout); +#define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ + +#ifdef WIN32 +extern PROsfd _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, + PRUint32 *addrlen, PRIntervalTime timeout, + PRBool fast, + _PR_AcceptTimeoutCallback callback, + void *callbackArg); + +extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, + PRNetAddr **raddr, void *buf, PRInt32 amount, + PRIntervalTime timeout, PRBool fast, + _PR_AcceptTimeoutCallback callback, + void *callbackArg); + +extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls); +#define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT +/* + * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME. + * We store the value in a PRTime variable for convenience. + * This constant is used by _PR_FileTimeToPRTime(). + * This is defined in ntmisc.c + */ +extern const PRTime _pr_filetime_offset; +#endif /* WIN32 */ + +extern PRInt32 _PR_MD_SENDFILE( + PRFileDesc *sock, PRSendFileData *sfd, + PRInt32 flags, PRIntervalTime timeout); +#define _PR_MD_SENDFILE _MD_SENDFILE + +extern PRStatus _PR_MD_GETSOCKNAME( + PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); +#define _PR_MD_GETSOCKNAME _MD_GETSOCKNAME + +extern PRStatus _PR_MD_GETPEERNAME( + PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen); +#define _PR_MD_GETPEERNAME _MD_GETPEERNAME + +extern PRStatus _PR_MD_GETSOCKOPT( + PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen); +#define _PR_MD_GETSOCKOPT _MD_GETSOCKOPT + +extern PRStatus _PR_MD_SETSOCKOPT( + PRFileDesc *fd, PRInt32 level, PRInt32 optname, + const char* optval, PRInt32 optlen); +#define _PR_MD_SETSOCKOPT _MD_SETSOCKOPT + +extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption( + PRFileDesc *fd, PRSocketOptionData *data); + +extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption( + PRFileDesc *fd, const PRSocketOptionData *data); + +extern PRInt32 _PR_MD_RECVFROM( + PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout); +#define _PR_MD_RECVFROM _MD_RECVFROM + +extern PRInt32 _PR_MD_SENDTO( + PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); +#define _PR_MD_SENDTO _MD_SENDTO + +extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd); +#define _PR_MD_SOCKETPAIR _MD_SOCKETPAIR + +extern PROsfd _PR_MD_SOCKET(int af, int type, int flags); +#define _PR_MD_SOCKET _MD_SOCKET + +extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd); +#define _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE + +extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd); +#define _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE + +extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, + PRIntervalTime timeout); +#define _PR_MD_PR_POLL _MD_PR_POLL + +/* + * Initialize fd->secret->inheritable for a newly created fd. + * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd) + * was created by NSPR and hence has the OS-dependent default + * inheritable attribute. If 'imported' is true, the osfd was + * not created by NSPR and hence a system call is required to + * query its inheritable attribute. Since we may never need to + * know the inheritable attribute of a fd, a platform may choose + * to initialize fd->secret->inheritable of an imported fd to + * _PR_TRI_UNKNOWN and only pay the cost of the system call + * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary. + */ +extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported); +#define _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE + +extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable); +#define _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE + + +#define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \ + if (_PR_PENDING_INTERRUPT(me)) { \ + me->flags &= ~_PR_INTERRUPT; \ + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \ + } else { \ + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \ + } + +extern void *_PR_MD_GET_SP(PRThread *thread); +#define _PR_MD_GET_SP _MD_GET_SP + +#endif /* defined(_PR_PTHREADS) */ + +/************************************************************************/ +/************************************************************************* +** The remainder of the definitions are shared by pthreads and the classic +** NSPR code. These too may be conditionalized. +*************************************************************************/ +/************************************************************************/ + +extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence); +#define _PR_MD_LSEEK _MD_LSEEK + +extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence); +#define _PR_MD_LSEEK64 _MD_LSEEK64 + +extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info); +#define _PR_MD_GETFILEINFO _MD_GETFILEINFO + +extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info); +#define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64 + +extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info); +#define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO + +extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info); +#define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64 + + +/*****************************************************************************/ +/************************** File descriptor caching **************************/ +/*****************************************************************************/ +extern void _PR_InitFdCache(void); +extern void _PR_CleanupFdCache(void); +extern PRFileDesc *_PR_Getfd(void); +extern void _PR_Putfd(PRFileDesc *fd); + +/* + * These flags are used by NSPR temporarily in the poll + * descriptor's out_flags field to record the mapping of + * NSPR's poll flags to the system poll flags. + * + * If _PR_POLL_READ_SYS_WRITE bit is set, it means the + * PR_POLL_READ flag specified by the topmost layer is + * mapped to the WRITE flag at the system layer. Similarly + * for the other three _PR_POLL_XXX_SYS_YYY flags. It is + * assumed that the PR_POLL_EXCEPT flag doesn't get mapped + * to other flags. + */ +#define _PR_POLL_READ_SYS_READ 0x1 +#define _PR_POLL_READ_SYS_WRITE 0x2 +#define _PR_POLL_WRITE_SYS_READ 0x4 +#define _PR_POLL_WRITE_SYS_WRITE 0x8 + +/* +** These methods are coerced into file descriptor methods table +** when the intended service is inappropriate for the particular +** type of file descriptor. +*/ +extern PRIntn _PR_InvalidInt(void); +extern PRInt16 _PR_InvalidInt16(void); +extern PRInt64 _PR_InvalidInt64(void); +extern PRStatus _PR_InvalidStatus(void); +extern PRFileDesc *_PR_InvalidDesc(void); + +extern PRIOMethods _pr_faulty_methods; + +/* +** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union +** whose 'family' field is set. It returns the size of the union +** member corresponding to the specified address family. +*/ + +extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr); + +#if defined(_PR_INET6) + +#define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr) + +#elif defined(_PR_HAVE_MD_SOCKADDR_IN6) + +/* +** Under the following conditions: +** 1. _PR_INET6 is not defined; +** 2. _PR_INET6_PROBE is defined; +** 3. struct sockaddr_in6 has nonstandard fields at the end +** (e.g., on Solaris 8), +** (_addr)->ipv6 is smaller than struct sockaddr_in6, and +** hence we can't pass sizeof((_addr)->ipv6) to socket +** functions such as connect because they would fail with +** EINVAL. +** +** To pass the correct socket address length to socket +** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and +** define struct _md_sockaddr_in6 to be isomorphic to +** struct sockaddr_in6. +*/ + +#if defined(XP_UNIX) || defined(XP_OS2) +#define PR_NETADDR_SIZE(_addr) \ + ((_addr)->raw.family == PR_AF_INET \ + ? sizeof((_addr)->inet) \ + : ((_addr)->raw.family == PR_AF_INET6 \ + ? sizeof(struct _md_sockaddr_in6) \ + : sizeof((_addr)->local))) +#else +#define PR_NETADDR_SIZE(_addr) \ + ((_addr)->raw.family == PR_AF_INET \ + ? sizeof((_addr)->inet) \ + : sizeof(struct _md_sockaddr_in6)) +#endif /* defined(XP_UNIX) */ + +#else + +#if defined(XP_UNIX) || defined(XP_OS2) +#define PR_NETADDR_SIZE(_addr) \ + ((_addr)->raw.family == PR_AF_INET \ + ? sizeof((_addr)->inet) \ + : ((_addr)->raw.family == PR_AF_INET6 \ + ? sizeof((_addr)->ipv6) \ + : sizeof((_addr)->local))) +#else +#define PR_NETADDR_SIZE(_addr) \ + ((_addr)->raw.family == PR_AF_INET \ + ? sizeof((_addr)->inet) \ + : sizeof((_addr)->ipv6)) +#endif /* defined(XP_UNIX) */ + +#endif /* defined(_PR_INET6) */ + +extern PRStatus _PR_MapOptionName( + PRSockOption optname, PRInt32 *level, PRInt32 *name); +extern void _PR_InitThreads( + PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs); + +struct PRLock { +#if defined(_PR_PTHREADS) + pthread_mutex_t mutex; /* the underlying lock */ + _PT_Notified notified; /* array of conditions notified */ + PRBool locked; /* whether the mutex is locked */ + pthread_t owner; /* if locked, current lock owner */ +#elif defined(_PR_BTHREADS) + sem_id semaphoreID; /* the underlying lock */ + int32 benaphoreCount; /* number of people in lock */ + thread_id owner; /* current lock owner */ +#else /* not pthreads or Be threads */ + PRCList links; /* linkage for PRThread.lockList */ + struct PRThread *owner; /* current lock owner */ + PRCList waitQ; /* list of threads waiting for lock */ + PRThreadPriority priority; /* priority of lock */ + PRThreadPriority boostPriority; /* boosted priority of lock owner */ + _MDLock ilock; /* Internal Lock to protect user-level fields */ +#endif +}; + +struct PRCondVar { + PRLock *lock; /* associated lock that protects the condition */ +#if defined(_PR_PTHREADS) + pthread_cond_t cv; /* underlying pthreads condition */ + PRInt32 notify_pending; /* CV has destroy pending notification */ +#elif defined(_PR_BTHREADS) + sem_id sem; /* the underlying lock */ + sem_id handshakeSem; /* the lock for 'notify'-threads waiting for confirmation */ + sem_id signalSem; /* the lock for threads waiting for someone to notify */ + volatile int32 nw; /* the number waiting */ + volatile int32 ns; /* the number signalling */ + long signalBenCount; /* the number waiting on the underlying sem */ +#else /* not pthreads or Be threads */ + PRCList condQ; /* Condition variable wait Q */ + _MDLock ilock; /* Internal Lock to protect condQ */ + _MDCVar md; +#endif +}; + +/************************************************************************/ + +struct PRMonitor { + const char* name; /* monitor name for debugging */ +#if defined(_PR_PTHREADS) + pthread_mutex_t lock; /* lock is only held when accessing fields + * of the PRMonitor, instead of being held + * while the monitor is entered. The only + * exception is notifyTimes, which is + * protected by the monitor. */ + pthread_t owner; /* the owner of the monitor or invalid */ + pthread_cond_t entryCV; /* for threads waiting to enter the monitor */ + + pthread_cond_t waitCV; /* for threads waiting on the monitor */ + PRInt32 refCount; /* reference count, an atomic variable. + * PR_NewMonitor adds a reference to the + * newly created PRMonitor, and + * PR_DestroyMonitor releases that reference. + * PR_ExitMonitor adds a reference before + * unlocking the internal lock if it needs to + * signal entryCV, and releases the reference + * after signaling entryCV. */ +#else /* defined(_PR_PTHREADS) */ + PRLock lock; /* lock is only held when accessing fields + * of the PRMonitor, instead of being held + * while the monitor is entered. The only + * exception is notifyTimes, which is + * protected by the monitor. */ + PRThread *owner; /* the owner of the monitor or invalid */ + PRCondVar entryCV; /* for threads waiting to enter the monitor */ + + PRCondVar waitCV; /* for threads waiting on the monitor */ +#endif /* defined(_PR_PTHREADS) */ + PRUint32 entryCount; /* # of times re-entered */ + PRIntn notifyTimes; /* number of pending notifies for waitCV. + * The special value -1 means a broadcast + * (PR_NotifyAll). */ +}; + +/************************************************************************/ + +struct PRSemaphore { +#if defined(_PR_BTHREADS) + sem_id sem; + int32 benaphoreCount; +#else + PRCondVar *cvar; /* associated lock and condition variable queue */ + PRUintn count; /* the value of the counting semaphore */ + PRUint32 waiters; /* threads waiting on the semaphore */ +#if defined(_PR_PTHREADS) +#else /* defined(_PR_PTHREADS) */ + _MDSemaphore md; +#endif /* defined(_PR_PTHREADS) */ +#endif /* defined(_PR_BTHREADS) */ +}; + +/*************************************************************************/ + +struct PRSem { +#ifdef _PR_HAVE_POSIX_SEMAPHORES + sem_t *sem; +#elif defined(_PR_HAVE_SYSV_SEMAPHORES) + int semid; +#elif defined(WIN32) + HANDLE sem; +#else + PRInt8 notused; +#endif +}; + +/*************************************************************************/ + +struct PRStackStr { + /* head MUST be at offset 0; assembly language code relies on this */ +#if defined(AIX) + volatile PRStackElem prstk_head; +#else + PRStackElem prstk_head; +#endif + + PRLock *prstk_lock; + char *prstk_name; +}; + +/************************************************************************/ + +/* XXX this needs to be exported (sigh) */ +struct PRThreadStack { + PRCList links; + PRUintn flags; + + char *allocBase; /* base of stack's allocated memory */ + PRUint32 allocSize; /* size of stack's allocated memory */ + char *stackBottom; /* bottom of stack from C's point of view */ + char *stackTop; /* top of stack from C's point of view */ + PRUint32 stackSize; /* size of usable portion of the stack */ + + PRSegment *seg; + PRThread* thr; /* back pointer to thread owning this stack */ + +#if defined(_PR_PTHREADS) +#else /* defined(_PR_PTHREADS) */ + _MDThreadStack md; +#endif /* defined(_PR_PTHREADS) */ +}; + +extern void _PR_DestroyThreadPrivate(PRThread*); + +typedef void (PR_CALLBACK *_PRStartFn)(void *); + +struct PRThread { + PRUint32 state; /* thread's creation state */ + PRThreadPriority priority; /* apparent priority, loosly defined */ + + void *arg; /* argument to the client's entry point */ + _PRStartFn startFunc; /* the root of the client's thread */ + + PRThreadStack *stack; /* info about thread's stack (for GC) */ + void *environment; /* pointer to execution environment */ + + PRThreadDumpProc dump; /* dump thread info out */ + void *dumpArg; /* argument for the dump function */ + + /* + ** Per thread private data + */ + PRUint32 tpdLength; /* thread's current vector length */ + void **privateData; /* private data vector or NULL */ + PRErrorCode errorCode; /* current NSPR error code | zero */ + PRInt32 osErrorCode; /* mapping of errorCode | zero */ + PRIntn errorStringLength; /* textLength from last call to PR_SetErrorText() */ + PRInt32 errorStringSize; /* malloc()'d size of buffer | zero */ + char *errorString; /* current error string | NULL */ + char *name; /* thread's name */ + +#if defined(_PR_PTHREADS) + pthread_t id; /* pthread identifier for the thread */ + PRBool idSet; /* whether 'id' has been set. Protected by + * pt_book.ml. */ +#ifdef _PR_NICE_PRIORITY_SCHEDULING + pid_t tid; /* Linux-specific kernel thread ID */ +#endif + PRBool okToDelete; /* ok to delete the PRThread struct? */ + PRCondVar *waiting; /* where the thread is waiting | NULL */ + void *sp; /* recorded sp for garbage collection */ + PRThread *next, *prev; /* simple linked list of all threads */ + PRUint32 suspend; /* used to store suspend and resume flags */ +#ifdef PT_NO_SIGTIMEDWAIT + pthread_mutex_t suspendResumeMutex; + pthread_cond_t suspendResumeCV; +#endif + PRUint32 interrupt_blocked; /* interrupt blocked */ + struct pollfd *syspoll_list; /* Unix polling list used by PR_Poll */ + PRUint32 syspoll_count; /* number of elements in syspoll_list */ +#if defined(_PR_POLL_WITH_SELECT) + int *selectfd_list; /* Unix fd's that PR_Poll selects on */ + PRUint32 selectfd_count; /* number of elements in selectfd_list */ +#endif +#elif defined(_PR_BTHREADS) + PRUint32 flags; + _MDThread md; + PRBool io_pending; + PRInt32 io_fd; + PRBool io_suspended; +#else /* not pthreads or Be threads */ + _MDLock threadLock; /* Lock to protect thread state variables. + * Protects the following fields: + * state + * priority + * links + * wait + * cpu + */ + PRUint32 queueCount; + PRUint32 waitCount; + + PRCList active; /* on list of all active threads */ + PRCList links; + PRCList waitQLinks; /* when thread is PR_Wait'ing */ + PRCList lockList; /* list of locks currently holding */ + PRIntervalTime sleep; /* sleep time when thread is sleeping */ + struct _wait { + struct PRLock *lock; + struct PRCondVar *cvar; + } wait; + + PRUint32 id; + PRUint32 flags; + PRUint32 no_sched; /* Don't schedule the thread to run. + * This flag has relevance only when + * multiple NSPR CPUs are created. + * When a thread is de-scheduled, there + * is a narrow window of time in which + * the thread is put on the run queue + * but the scheduler is actually using + * the stack of this thread. It is safe + * to run this thread on a different CPU + * only when its stack is not in use on + * any other CPU. The no_sched flag is + * set during this interval to prevent + * the thread from being scheduled on a + * different CPU. + */ + + /* thread termination condition variable for join */ + PRCondVar *term; + + _PRCPU *cpu; /* cpu to which this thread is bound */ + PRUint32 threadAllocatedOnStack;/* boolean */ + + /* When an async IO is in progress and a second async IO cannot be + * initiated, the io_pending flag is set to true. Some platforms will + * not use the io_pending flag. If the io_pending flag is true, then + * io_fd is the OS-file descriptor on which IO is pending. + */ + PRBool io_pending; + PRInt32 io_fd; + + /* If a timeout occurs or if an outstanding IO is interrupted and the + * OS doesn't support a real cancellation (NT or MAC), then the + * io_suspended flag will be set to true. The thread will be resumed + * but may run into trouble issuing additional IOs until the io_pending + * flag can be cleared + */ + PRBool io_suspended; + + _MDThread md; +#endif +}; + +struct PRProcessAttr { + PRFileDesc *stdinFd; + PRFileDesc *stdoutFd; + PRFileDesc *stderrFd; + char *currentDirectory; + char *fdInheritBuffer; + PRSize fdInheritBufferSize; + PRSize fdInheritBufferUsed; +}; + +struct PRProcess { + _MDProcess md; +}; + +struct PRFileMap { + PRFileDesc *fd; + PRFileMapProtect prot; + _MDFileMap md; +}; + +/************************************************************************/ + +/* +** File descriptors of the NSPR layer can be in one of the +** following states (stored in the 'state' field of struct +** PRFilePrivate): +** - _PR_FILEDESC_OPEN: The OS fd is open. +** - _PR_FILEDESC_CLOSED: The OS fd is closed. The PRFileDesc +** is still open but is unusable. The only operation allowed +** on the PRFileDesc is PR_Close(). +** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc +** structure is freed. +*/ + +#define _PR_FILEDESC_OPEN 0xaaaaaaaa /* 1010101... */ +#define _PR_FILEDESC_CLOSED 0x55555555 /* 0101010... */ +#define _PR_FILEDESC_FREED 0x11111111 + +/* +** A boolean type with an additional "unknown" state +*/ + +typedef enum { + _PR_TRI_TRUE = 1, + _PR_TRI_FALSE = 0, + _PR_TRI_UNKNOWN = -1 +} _PRTriStateBool; + +struct PRFilePrivate { + PRInt32 state; + PRBool nonblocking; + _PRTriStateBool inheritable; + PRFileDesc *next; + PRIntn lockCount; /* 0: not locked + * -1: a native lockfile call is in progress + * > 0: # times the file is locked */ +#ifdef _PR_HAVE_PEEK_BUFFER + char *peekBuffer; + PRInt32 peekBufSize; + PRInt32 peekBytes; +#endif +#if !defined(_PR_HAVE_O_APPEND) + PRBool appendMode; /* Some platforms don't have O_APPEND or its + * equivalent, so they have to seek to end of + * file on write if the file was opened in + * append mode. See Bugzilla 4090, 276330. */ +#endif + _MDFileDesc md; +#ifdef _PR_NEED_SECRET_AF + PRUint16 af; /* If the platform's implementation of accept() + * requires knowing the address family of the + * socket, we save the address family here. */ +#endif +}; + +#ifdef _WIN64 +#define PR_PRIdOSFD "lld" /* for printing PROsfd */ +#define PR_PRIxOSFD "llx" +#define PR_SCNdOSFD "lld" /* for scanning PROsfd */ +#define PR_SCNxOSFD "llx" +#else +#define PR_PRIdOSFD "ld" /* for printing PROsfd */ +#define PR_PRIxOSFD "lx" +#define PR_SCNdOSFD "ld" /* for scanning PROsfd */ +#define PR_SCNxOSFD "lx" +#endif + +struct PRDir { + PRDirEntry d; + _MDDir md; +}; + +#ifdef MOZ_UNICODE +struct PRDirUTF16 { + PRDirEntry d; + _MDDirUTF16 md; +}; +#endif /* MOZ_UNICODE */ + +extern void _PR_InitLocks(void); +extern void _PR_InitSegs(void); +extern void _PR_InitStacks(void); +extern void _PR_InitTPD(void); +extern void _PR_InitMem(void); +extern void _PR_InitEnv(void); +extern void _PR_InitCMon(void); +extern void _PR_InitIO(void); +extern void _PR_InitLog(void); +extern void _PR_InitNet(void); +extern void _PR_InitClock(void); +extern void _PR_InitLinker(void); +extern void _PR_InitAtomic(void); +extern void _PR_InitCPUs(void); +extern void _PR_InitDtoa(void); +extern void _PR_InitTime(void); +extern void _PR_InitMW(void); +extern void _PR_InitRWLocks(void); +extern void _PR_CleanupThread(PRThread *thread); +extern void _PR_CleanupCallOnce(void); +extern void _PR_CleanupMW(void); +extern void _PR_CleanupTime(void); +extern void _PR_CleanupDtoa(void); +extern void _PR_ShutdownLinker(void); +extern void _PR_CleanupEnv(void); +extern void _PR_CleanupIO(void); +extern void _PR_CleanupCMon(void); +extern void _PR_CleanupNet(void); +extern void _PR_CleanupLayerCache(void); +extern void _PR_CleanupStacks(void); +#ifdef WINNT +extern void _PR_CleanupCPUs(void); +#endif +extern void _PR_CleanupThreads(void); +extern void _PR_CleanupTPD(void); +extern void _PR_Cleanup(void); +extern void _PR_LogCleanup(void); +extern void _PR_InitLayerCache(void); + +extern PRBool _pr_initialized; +extern void _PR_ImplicitInitialization(void); +extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred); + +/************************************************************************/ + +struct PRSegment { + void *vaddr; + PRUint32 size; + PRUintn flags; +#if defined(_PR_PTHREADS) +#else /* defined(_PR_PTHREADS) */ + _MDSegment md; +#endif /* defined(_PR_PTHREADS) */ +}; + +/* PRSegment.flags */ +#define _PR_SEG_VM 0x1 + +/************************************************************************/ + +extern PRInt32 _pr_pageSize; +extern PRInt32 _pr_pageShift; + +extern PRLogModuleInfo *_pr_clock_lm; +extern PRLogModuleInfo *_pr_cmon_lm; +extern PRLogModuleInfo *_pr_io_lm; +extern PRLogModuleInfo *_pr_cvar_lm; +extern PRLogModuleInfo *_pr_mon_lm; +extern PRLogModuleInfo *_pr_linker_lm; +extern PRLogModuleInfo *_pr_sched_lm; +extern PRLogModuleInfo *_pr_thread_lm; +extern PRLogModuleInfo *_pr_gc_lm; + +extern PRFileDesc *_pr_stdin; +extern PRFileDesc *_pr_stdout; +extern PRFileDesc *_pr_stderr; + +/* Zone allocator */ +/* +** The zone allocator code has hardcoded pthread types and +** functions, so it can only be used in the pthreads version. +** This can be fixed by replacing the hardcoded pthread types +** and functions with macros that expand to the native thread +** types and functions on each platform. +*/ +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) +#define _PR_ZONE_ALLOCATOR +#endif + +#ifdef _PR_ZONE_ALLOCATOR +extern void _PR_InitZones(void); +extern void _PR_DestroyZones(void); +#endif + +/* Overriding malloc, free, etc. */ +#if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \ + && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \ + && !defined(PURIFY) \ + && !defined(DARWIN) \ + && !defined(QNX) \ + && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS)) +#define _PR_OVERRIDE_MALLOC +#endif + +/************************************************************************* +* External machine-dependent code provided by each OS. * * +*************************************************************************/ + +/* Initialization related */ +extern void _PR_MD_EARLY_INIT(void); +#define _PR_MD_EARLY_INIT _MD_EARLY_INIT + +extern void _PR_MD_INTERVAL_INIT(void); +#define _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT + +NSPR_API(void) _PR_MD_FINAL_INIT(void); +#define _PR_MD_FINAL_INIT _MD_FINAL_INIT + +extern void _PR_MD_EARLY_CLEANUP(void); +#define _PR_MD_EARLY_CLEANUP _MD_EARLY_CLEANUP + +/* Process control */ + +extern PRProcess * _PR_MD_CREATE_PROCESS( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr); +#define _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS + +extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process); +#define _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS + +extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode); +#define _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS + +extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process); +#define _PR_MD_KILL_PROCESS _MD_KILL_PROCESS + +/* Current Time */ +NSPR_API(PRTime) _PR_MD_NOW(void); +#define _PR_MD_NOW _MD_NOW + +/* Environment related */ +extern char* _PR_MD_GET_ENV(const char *name); +#define _PR_MD_GET_ENV _MD_GET_ENV + +extern PRIntn _PR_MD_PUT_ENV(const char *name); +#define _PR_MD_PUT_ENV _MD_PUT_ENV + +/* Atomic operations */ + +extern void _PR_MD_INIT_ATOMIC(void); +#define _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC + +extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *); +#define _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT + +extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32); +#define _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD + +extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *); +#define _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT + +extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32); +#define _PR_MD_ATOMIC_SET _MD_ATOMIC_SET + +/* Garbage collection */ + +/* +** Save the registers that the GC would find interesting into the thread +** "t". isCurrent will be non-zero if the thread state that is being +** saved is the currently executing thread. Return the address of the +** first register to be scanned as well as the number of registers to +** scan in "np". +** +** If "isCurrent" is non-zero then it is allowed for the thread context +** area to be used as scratch storage to hold just the registers +** necessary for scanning. +*/ +extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np); + +/* Time intervals */ + +extern PRIntervalTime _PR_MD_GET_INTERVAL(void); +#define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL + +extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void); +#define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC + +/* Affinity masks */ + +extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ); +#define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK + +extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask); +#define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK + +/* File locking */ + +extern PRStatus _PR_MD_LOCKFILE(PROsfd osfd); +#define _PR_MD_LOCKFILE _MD_LOCKFILE + +extern PRStatus _PR_MD_TLOCKFILE(PROsfd osfd); +#define _PR_MD_TLOCKFILE _MD_TLOCKFILE + +extern PRStatus _PR_MD_UNLOCKFILE(PROsfd osfd); +#define _PR_MD_UNLOCKFILE _MD_UNLOCKFILE + +/* Memory-mapped files */ + +extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size); +#define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP + +extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void); +#define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT + +extern void * _PR_MD_MEM_MAP( + PRFileMap *fmap, + PROffset64 offset, + PRUint32 len); +#define _PR_MD_MEM_MAP _MD_MEM_MAP + +extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size); +#define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP + +extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap); +#define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP + +extern PRStatus _PR_MD_SYNC_MEM_MAP( + PRFileDesc *fd, + void *addr, + PRUint32 len); +#define _PR_MD_SYNC_MEM_MAP _MD_SYNC_MEM_MAP + +/* Named Shared Memory */ + +/* +** Declare PRSharedMemory. +*/ +struct PRSharedMemory +{ + char *ipcname; /* after conversion to native */ + PRSize size; /* from open */ + PRIntn mode; /* from open */ + PRIntn flags; /* from open */ +#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY) + int id; +#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY) + int id; +#elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY) + HANDLE handle; +#else + PRUint32 nothing; /* placeholder, nothing behind here */ +#endif + PRUint32 ident; /* guard word at end of struct */ +#define _PR_SHM_IDENT 0xdeadbad +}; + +extern PRSharedMemory * _MD_OpenSharedMemory( + const char *name, + PRSize size, + PRIntn flags, + PRIntn mode +); +#define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory + +extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ); +#define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory + +extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ); +#define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory + +extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ); +#define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory + +extern PRStatus _MD_DeleteSharedMemory( const char *name ); +#define _PR_MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory + +extern PRFileMap* _md_OpenAnonFileMap( + const char *dirName, + PRSize size, + PRFileMapProtect prot +); +#define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap + +extern PRStatus _md_ExportFileMapAsString( + PRFileMap *fm, + PRSize bufSize, + char *buf +); +#define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString + +extern PRFileMap * _md_ImportFileMapFromString( + const char *fmstring +); +#define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString + + + +/* Interprocess communications (IPC) */ + +/* + * The maximum length of an NSPR IPC name, including the + * terminating null byte. + */ +#define PR_IPC_NAME_SIZE 1024 + +/* + * Types of NSPR IPC objects + */ +typedef enum { + _PRIPCSem, /* semaphores */ + _PRIPCShm /* shared memory segments */ +} _PRIPCType; + +/* + * Make a native IPC name from an NSPR IPC name. + */ +extern PRStatus _PR_MakeNativeIPCName( + const char *name, /* NSPR IPC name */ + char *result, /* result buffer */ + PRIntn size, /* size of result buffer */ + _PRIPCType type /* type of IPC object */ +); + +/* Socket call error code */ + +NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void); +#define _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR + +/* Get name of current host */ +extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen); +#define _PR_MD_GETHOSTNAME _MD_GETHOSTNAME + +extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen); +#define _PR_MD_GETSYSINFO _MD_GETSYSINFO + +/* File descriptor inheritance */ + +/* + * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to + * know the inheritable attribute of the fd, call this function + * to find that out. This typically requires a system call. + */ +extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd); +#define _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE + +/* --- PR_GetRandomNoise() related things --- */ + +extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ); +#define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size)) +extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srclen ); + +/* end PR_GetRandomNoise() related */ + +#ifdef XP_BEOS + +extern PRLock *_connectLock; + +typedef struct _ConnectListNode { + PRInt32 osfd; + PRNetAddr addr; + PRUint32 addrlen; + PRIntervalTime timeout; +} ConnectListNode; + +extern ConnectListNode connectList[64]; + +extern PRUint32 connectCount; + +#endif /* XP_BEOS */ + +PR_END_EXTERN_C + +#endif /* primpl_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/private/prpriv.h nspr-4.10.7/nspr/pr/include/private/prpriv.h --- nspr-4.9.5/nspr/pr/include/private/prpriv.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/private/prpriv.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,16 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prpriv_h___ +#define prpriv_h___ + +/* + * NSPR 2.0 Private API + */ + +#include "private/pprio.h" +#include "private/pprthred.h" + +#endif /* prpriv_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prlink.h nspr-4.10.7/nspr/pr/include/prlink.h --- nspr-4.9.5/nspr/pr/include/prlink.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prlink.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,230 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prlink_h___ +#define prlink_h___ + +/* +** API to static and dynamic linking. +*/ +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +typedef struct PRLibrary PRLibrary; + +typedef struct PRStaticLinkTable { + const char *name; + void (*fp)(void); +} PRStaticLinkTable; + +/* +** Change the default library path to the given string. The string is +** copied. This call will fail if it runs out of memory. +** +** The string provided as 'path' is copied. The caller can do whatever is +** convenient with the argument when the function is complete. +*/ +NSPR_API(PRStatus) PR_SetLibraryPath(const char *path); + +/* +** Return a character string which contains the path used to search for +** dynamically loadable libraries. +** +** The returned value is basically a copy of a PR_SetLibraryPath(). +** The storage is allocated by the runtime and becomes the responsibilty +** of the caller. +*/ +NSPR_API(char*) PR_GetLibraryPath(void); + +/* +** Given a directory name "dir" and a library name "lib" construct a full +** path name that will refer to the actual dynamically loaded +** library. This does not test for existance of said file, it just +** constructs the full filename. The name constructed is system dependent +** and prepared for PR_LoadLibrary. The result must be free'd when the +** caller is done with it. +** +** The storage for the result is allocated by the runtime and becomes the +** responsibility of the caller. +*/ +NSPR_API(char*) PR_GetLibraryName(const char *dir, const char *lib); + +/* +** +** Free the memory allocated, for the caller, by PR_GetLibraryName +*/ +NSPR_API(void) PR_FreeLibraryName(char *mem); + +/* +** Given a library "name" try to load the library. The argument "name" +** is a machine-dependent name for the library, such as the full pathname +** returned by PR_GetLibraryName. If the library is already loaded, +** this function will avoid loading the library twice. +** +** If the library is loaded successfully, then a pointer to the PRLibrary +** structure representing the library is returned. Otherwise, NULL is +** returned. +** +** This increments the reference count of the library. +*/ +NSPR_API(PRLibrary*) PR_LoadLibrary(const char *name); + +/* +** Each operating system has its preferred way of specifying +** a file in the file system. Most operating systems use +** a pathname. Mac OS Classic, on the other hand, uses the FSSpec +** structure to specify a file. PRLibSpec allows NSPR clients +** to use the type of file specification that is most efficient +** for a particular platform. +** +** On some operating systems such as Mac OS Classic, a shared library +** may contain code fragments that can be individually loaded. +** PRLibSpec also allows NSPR clients to identify a code fragment +** in a library, if code fragments are supported by the OS. +** A code fragment can be specified by name or by an integer index. +** +** Right now PRLibSpec supports four types of library specification: +** a pathname in the native character encoding, a Mac code fragment +** by name, a Mac code fragment by index, and a UTF-16 pathname. +*/ + +typedef enum PRLibSpecType { + PR_LibSpec_Pathname, + PR_LibSpec_MacNamedFragment, /* obsolete (for Mac OS Classic) */ + PR_LibSpec_MacIndexedFragment, /* obsolete (for Mac OS Classic) */ + PR_LibSpec_PathnameU /* supported only on Win32 */ +} PRLibSpecType; + +struct FSSpec; /* Mac OS Classic FSSpec */ + +typedef struct PRLibSpec { + PRLibSpecType type; + union { + /* if type is PR_LibSpec_Pathname */ + const char *pathname; + + /* if type is PR_LibSpec_MacNamedFragment */ + struct { + const struct FSSpec *fsspec; + const char *name; + } mac_named_fragment; /* obsolete (for Mac OS Classic) */ + + /* if type is PR_LibSpec_MacIndexedFragment */ + struct { + const struct FSSpec *fsspec; + PRUint32 index; + } mac_indexed_fragment; /* obsolete (for Mac OS Classic) */ + + /* if type is PR_LibSpec_PathnameU */ + const PRUnichar *pathname_u; /* supported only on Win32 */ + } value; +} PRLibSpec; + +/* +** The following bit flags may be or'd together and passed +** as the 'flags' argument to PR_LoadLibraryWithFlags. +** Flags not supported by the underlying OS are ignored. +*/ + +#define PR_LD_LAZY 0x1 /* equivalent to RTLD_LAZY on Unix */ +#define PR_LD_NOW 0x2 /* equivalent to RTLD_NOW on Unix */ +#define PR_LD_GLOBAL 0x4 /* equivalent to RTLD_GLOBAL on Unix */ +#define PR_LD_LOCAL 0x8 /* equivalent to RTLD_LOCAL on Unix */ +/* The following is equivalent to LOAD_WITH_ALTERED_SEARCH_PATH on Windows */ +#define PR_LD_ALT_SEARCH_PATH 0x10 +/* 0x8000 reserved for NSPR internal use */ + +/* +** Load the specified library, in the manner specified by 'flags'. +*/ + +NSPR_API(PRLibrary *) +PR_LoadLibraryWithFlags( + PRLibSpec libSpec, /* the shared library */ + PRIntn flags /* flags that affect the loading */ +); + +/* +** Unload a previously loaded library. If the library was a static +** library then the static link table will no longer be referenced. The +** associated PRLibrary object is freed. +** +** PR_FAILURE is returned if the library cannot be unloaded. +** +** This function decrements the reference count of the library. +*/ +NSPR_API(PRStatus) PR_UnloadLibrary(PRLibrary *lib); + +/* +** Given the name of a procedure, return the address of the function that +** implements the procedure, or NULL if no such function can be +** found. This does not find symbols in the main program (the ".exe"); +** use PR_LoadStaticLibrary to register symbols in the main program. +** +** This function does not modify the reference count of the library. +*/ +NSPR_API(void*) PR_FindSymbol(PRLibrary *lib, const char *name); + +/* +** Similar to PR_FindSymbol, except that the return value is a pointer to +** a function, and not a pointer to void. Casting between a data pointer +** and a function pointer is not portable according to the C standard. +** Any function pointer can be cast to any other function pointer. +** +** This function does not modify the reference count of the library. +*/ +typedef void (*PRFuncPtr)(void); +NSPR_API(PRFuncPtr) PR_FindFunctionSymbol(PRLibrary *lib, const char *name); + +/* +** Finds a symbol in one of the currently loaded libraries. Given the +** name of a procedure, return the address of the function that +** implements the procedure, and return the library that contains that +** symbol, or NULL if no such function can be found. This does not find +** symbols in the main program (the ".exe"); use PR_AddStaticLibrary to +** register symbols in the main program. +** +** This increments the reference count of the library. +*/ +NSPR_API(void*) PR_FindSymbolAndLibrary(const char *name, + PRLibrary* *lib); + +/* +** Similar to PR_FindSymbolAndLibrary, except that the return value is +** a pointer to a function, and not a pointer to void. Casting between a +** data pointer and a function pointer is not portable according to the C +** standard. Any function pointer can be cast to any other function pointer. +** +** This increments the reference count of the library. +*/ +NSPR_API(PRFuncPtr) PR_FindFunctionSymbolAndLibrary(const char *name, + PRLibrary* *lib); + +/* +** Register a static link table with the runtime under the name +** "name". The symbols present in the static link table will be made +** available to PR_FindSymbol. If "name" is null then the symbols will be +** made available to the library which represents the executable. The +** tables are not copied. +** +** Returns the library object if successful, null otherwise. +** +** This increments the reference count of the library. +*/ +NSPR_API(PRLibrary*) PR_LoadStaticLibrary( + const char *name, const PRStaticLinkTable *table); + +/* +** Return the pathname of the file that the library "name" was loaded +** from. "addr" is the address of a function defined in the library. +** +** The caller is responsible for freeing the result with PR_Free. +*/ +NSPR_API(char *) PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr); + +PR_END_EXTERN_C + +#endif /* prlink_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prlock.h nspr-4.10.7/nspr/pr/include/prlock.h --- nspr-4.9.5/nspr/pr/include/prlock.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prlock.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prlock.h +** Description: API to basic locking functions of NSPR. +** +** +** NSPR provides basic locking mechanisms for thread synchronization. Locks +** are lightweight resource contention controls that prevent multiple threads +** from accessing something (code/data) simultaneously. +**/ + +#ifndef prlock_h___ +#define prlock_h___ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/**********************************************************************/ +/************************* TYPES AND CONSTANTS ************************/ +/**********************************************************************/ + +/* + * PRLock -- + * + * NSPR represents the lock as an opaque entity to the client of the + * API. All routines operate on a pointer to this opaque entity. + */ + +typedef struct PRLock PRLock; + +/**********************************************************************/ +/****************************** FUNCTIONS *****************************/ +/**********************************************************************/ + +/*********************************************************************** +** FUNCTION: PR_NewLock +** DESCRIPTION: +** Returns a pointer to a newly created opaque lock object. +** INPUTS: void +** OUTPUTS: void +** RETURN: PRLock* +** If the lock can not be created because of resource constraints, NULL +** is returned. +** +***********************************************************************/ +NSPR_API(PRLock*) PR_NewLock(void); + +/*********************************************************************** +** FUNCTION: PR_DestroyLock +** DESCRIPTION: +** Destroys a given opaque lock object. +** INPUTS: PRLock *lock +** Lock to be freed. +** OUTPUTS: void +** RETURN: None +***********************************************************************/ +NSPR_API(void) PR_DestroyLock(PRLock *lock); + +/*********************************************************************** +** FUNCTION: PR_Lock +** DESCRIPTION: +** Lock a lock. +** INPUTS: PRLock *lock +** Lock to locked. +** OUTPUTS: void +** RETURN: None +***********************************************************************/ +NSPR_API(void) PR_Lock(PRLock *lock); + +/*********************************************************************** +** FUNCTION: PR_Unlock +** DESCRIPTION: +** Unlock a lock. Unlocking an unlocked lock has undefined results. +** INPUTS: PRLock *lock +** Lock to unlocked. +** OUTPUTS: void +** RETURN: PR_STATUS +** Returns PR_FAILURE if the caller does not own the lock. +***********************************************************************/ +NSPR_API(PRStatus) PR_Unlock(PRLock *lock); + +/*********************************************************************** +** MACRO: PR_ASSERT_CURRENT_THREAD_OWNS_LOCK +** DESCRIPTION: +** If the current thread owns |lock|, this assertion is guaranteed to +** succeed. Otherwise, the behavior of this function is undefined. +** INPUTS: PRLock *lock +** Lock to assert ownership of. +** OUTPUTS: void +** RETURN: None +***********************************************************************/ +#if defined(DEBUG) || defined(FORCE_PR_ASSERT) +#define PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(/* PrLock* */ lock) \ + PR_AssertCurrentThreadOwnsLock(lock) +#else +#define PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(/* PrLock* */ lock) +#endif + +/* Don't call this function directly. */ +NSPR_API(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock); + +PR_END_EXTERN_C + +#endif /* prlock_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prlog.h nspr-4.10.7/nspr/pr/include/prlog.h --- nspr-4.9.5/nspr/pr/include/prlog.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prlog.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,221 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prlog_h___ +#define prlog_h___ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* +** prlog.h -- Declare interfaces to NSPR's Logging service +** +** NSPR provides a logging service that is used by NSPR itself and is +** available to client programs. +** +** To use the service from a client program, you should create a +** PRLogModuleInfo structure by calling PR_NewLogModule(). After +** creating the LogModule, you can write to the log using the PR_LOG() +** macro. +** +** Initialization of the log service is handled by NSPR initialization. +** +** At execution time, you must enable the log service. To enable the +** log service, set the environment variable: NSPR_LOG_MODULES +** variable. +** +** NSPR_LOG_MODULES variable has the form: +** +** :[, :]* +** +** Where: +** is the name passed to PR_NewLogModule(). +** is a numeric constant, e.g. 5. This value is the maximum +** value of a log event, enumerated by PRLogModuleLevel, that you want +** written to the log. +** +** For example: to record all events of greater value than or equal to +** PR_LOG_ERROR for a LogModule names "gizmo", say: +** +** set NSPR_LOG_MODULES=gizmo:2 +** +** Note that you must specify the numeric value of PR_LOG_ERROR. +** +** Special LogModule names are provided for controlling NSPR's log +** service at execution time. These controls should be set in the +** NSPR_LOG_MODULES environment variable at execution time to affect +** NSPR's log service for your application. +** +** The special LogModule "all" enables all LogModules. To enable all +** LogModule calls to PR_LOG(), say: +** +** set NSPR_LOG_MODULES=all:5 +** +** The special LogModule name "sync" tells the NSPR log service to do +** unbuffered logging. +** +** The special LogModule name "bufsize:" tells NSPR to set the +** log buffer to . +** +** The environment variable NSPR_LOG_FILE specifies the log file to use +** unless the default of "stderr" is acceptable. For MS Windows +** systems, NSPR_LOG_FILE can be set to a special value: "WinDebug" +** (case sensitive). This value causes PR_LOG() output to be written +** using the Windows API OutputDebugString(). OutputDebugString() +** writes to the debugger window; some people find this helpful. +** +** +** To put log messages in your programs, use the PR_LOG macro: +** +** PR_LOG(, , (, *)); +** +** Where is the address of a PRLogModuleInfo structure, and +** is one of the levels defined by the enumeration: +** PRLogModuleLevel. is a printf() style of argument list. That +** is: (fmtstring, ...). +** +** Example: +** +** main() { +** PRIntn one = 1; +** PRLogModuleInfo * myLm = PR_NewLogModule("gizmo"); +** PR_LOG( myLm, PR_LOG_ALWAYS, ("Log this! %d\n", one)); +** return; +** } +** +** Note the use of printf() style arguments as the third agrument(s) to +** PR_LOG(). +** +** After compiling and linking you application, set the environment: +** +** set NSPR_LOG_MODULES=gizmo:5 +** set NSPR_LOG_FILE=logfile.txt +** +** When you execute your application, the string "Log this! 1" will be +** written to the file "logfile.txt". +** +** Note to NSPR engineers: a number of PRLogModuleInfo structures are +** defined and initialized in prinit.c. See this module for ideas on +** what to log where. +** +*/ + +typedef enum PRLogModuleLevel { + PR_LOG_NONE = 0, /* nothing */ + PR_LOG_ALWAYS = 1, /* always printed */ + PR_LOG_ERROR = 2, /* error messages */ + PR_LOG_WARNING = 3, /* warning messages */ + PR_LOG_DEBUG = 4, /* debug messages */ + + PR_LOG_NOTICE = PR_LOG_DEBUG, /* notice messages */ + PR_LOG_WARN = PR_LOG_WARNING, /* warning messages */ + PR_LOG_MIN = PR_LOG_DEBUG, /* minimal debugging messages */ + PR_LOG_MAX = PR_LOG_DEBUG /* maximal debugging messages */ +} PRLogModuleLevel; + +/* +** One of these structures is created for each module that uses logging. +** "name" is the name of the module +** "level" is the debugging level selected for that module +*/ +typedef struct PRLogModuleInfo { + const char *name; + PRLogModuleLevel level; + struct PRLogModuleInfo *next; +} PRLogModuleInfo; + +/* +** Create a new log module. +*/ +NSPR_API(PRLogModuleInfo*) PR_NewLogModule(const char *name); + +/* +** Set the file to use for logging. Returns PR_FALSE if the file cannot +** be created +*/ +NSPR_API(PRBool) PR_SetLogFile(const char *name); + +/* +** Set the size of the logging buffer. If "buffer_size" is zero then the +** logging becomes "synchronous" (or unbuffered). +*/ +NSPR_API(void) PR_SetLogBuffering(PRIntn buffer_size); + +/* +** Print a string to the log. "fmt" is a PR_snprintf format type. All +** messages printed to the log are preceeded by the name of the thread +** and a time stamp. Also, the routine provides a missing newline if one +** is not provided. +*/ +NSPR_API(void) PR_LogPrint(const char *fmt, ...); + +/* +** Flush the log to its file. +*/ +NSPR_API(void) PR_LogFlush(void); + +NSPR_API(void) PR_Assert(const char *s, const char *file, PRIntn ln); + +#if defined(DEBUG) || defined(FORCE_PR_LOG) +#define PR_LOGGING 1 + +#define PR_LOG_TEST(_module,_level) \ + ((_module)->level >= (_level)) + +/* +** Log something. +** "module" is the address of a PRLogModuleInfo structure +** "level" is the desired logging level +** "args" is a variable length list of arguments to print, in the following +** format: ("printf style format string", ...) +*/ +#define PR_LOG(_module,_level,_args) \ + PR_BEGIN_MACRO \ + if (PR_LOG_TEST(_module,_level)) { \ + PR_LogPrint _args; \ + } \ + PR_END_MACRO + +#else /* defined(DEBUG) || defined(FORCE_PR_LOG) */ + +#undef PR_LOGGING +#define PR_LOG_TEST(module,level) 0 +#define PR_LOG(module,level,args) + +#endif /* defined(DEBUG) || defined(FORCE_PR_LOG) */ + +#ifndef NO_NSPR_10_SUPPORT + +#ifdef PR_LOGGING +#define PR_LOG_BEGIN PR_LOG +#define PR_LOG_END PR_LOG +#define PR_LOG_DEFINE PR_NewLogModule +#else +#define PR_LOG_BEGIN(module,level,args) +#define PR_LOG_END(module,level,args) +#define PR_LOG_DEFINE(_name) NULL +#endif /* PR_LOGGING */ + +#endif /* NO_NSPR_10_SUPPORT */ + +#if defined(DEBUG) || defined(FORCE_PR_ASSERT) + +#define PR_ASSERT(_expr) \ + ((_expr)?((void)0):PR_Assert(# _expr,__FILE__,__LINE__)) + +#define PR_NOT_REACHED(_reasonStr) \ + PR_Assert(_reasonStr,__FILE__,__LINE__) + +#else + +#define PR_ASSERT(expr) ((void) 0) +#define PR_NOT_REACHED(reasonStr) + +#endif /* defined(DEBUG) || defined(FORCE_PR_ASSERT) */ + +PR_END_EXTERN_C + +#endif /* prlog_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prlong.h nspr-4.10.7/nspr/pr/include/prlong.h --- nspr-4.9.5/nspr/pr/include/prlong.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prlong.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,403 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prlong.h +** Description: Portable access to 64 bit numerics +** +** Long-long (64-bit signed integer type) support. Some C compilers +** don't support 64 bit integers yet, so we use these macros to +** support both machines that do and don't. +**/ +#ifndef prlong_h___ +#define prlong_h___ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/*********************************************************************** +** DEFINES: LL_MaxInt +** LL_MinInt +** LL_Zero +** LL_MaxUint +** DESCRIPTION: +** Various interesting constants and static variable +** initializer +***********************************************************************/ +NSPR_API(PRInt64) LL_MaxInt(void); +NSPR_API(PRInt64) LL_MinInt(void); +NSPR_API(PRInt64) LL_Zero(void); +NSPR_API(PRUint64) LL_MaxUint(void); + +#if defined(HAVE_LONG_LONG) + +/* Keep this in sync with prtypes.h. */ +#if PR_BYTES_PER_LONG == 8 && !defined(PR_ALTERNATE_INT64_TYPEDEF) +#define LL_MAXINT 9223372036854775807L +#define LL_MININT (-LL_MAXINT - 1L) +#define LL_ZERO 0L +#define LL_MAXUINT 18446744073709551615UL +#define LL_INIT(hi, lo) ((hi ## L << 32) + lo ## L) +#elif defined(WIN32) && !defined(__GNUC__) +#define LL_MAXINT 9223372036854775807i64 +#define LL_MININT (-LL_MAXINT - 1i64) +#define LL_ZERO 0i64 +#define LL_MAXUINT 18446744073709551615ui64 +#define LL_INIT(hi, lo) ((hi ## i64 << 32) + lo ## i64) +#else +#define LL_MAXINT 9223372036854775807LL +#define LL_MININT (-LL_MAXINT - 1LL) +#define LL_ZERO 0LL +#define LL_MAXUINT 18446744073709551615ULL +#define LL_INIT(hi, lo) ((hi ## LL << 32) + lo ## LL) +#endif + +/*********************************************************************** +** MACROS: LL_* +** DESCRIPTION: +** The following macros define portable access to the 64 bit +** math facilities. +** +***********************************************************************/ + +/*********************************************************************** +** MACROS: LL_ +** +** LL_IS_ZERO Test for zero +** LL_EQ Test for equality +** LL_NE Test for inequality +** LL_GE_ZERO Test for zero or positive +** LL_CMP Compare two values +***********************************************************************/ +#define LL_IS_ZERO(a) ((a) == 0) +#define LL_EQ(a, b) ((a) == (b)) +#define LL_NE(a, b) ((a) != (b)) +#define LL_GE_ZERO(a) ((a) >= 0) +#define LL_CMP(a, op, b) ((PRInt64)(a) op (PRInt64)(b)) +#define LL_UCMP(a, op, b) ((PRUint64)(a) op (PRUint64)(b)) + +/*********************************************************************** +** MACROS: LL_ +** +** LL_AND Logical and +** LL_OR Logical or +** LL_XOR Logical exclusion +** LL_OR2 A disgusting deviation +** LL_NOT Negation (one's complement) +***********************************************************************/ +#define LL_AND(r, a, b) ((r) = (a) & (b)) +#define LL_OR(r, a, b) ((r) = (a) | (b)) +#define LL_XOR(r, a, b) ((r) = (a) ^ (b)) +#define LL_OR2(r, a) ((r) = (r) | (a)) +#define LL_NOT(r, a) ((r) = ~(a)) + +/*********************************************************************** +** MACROS: LL_ +** +** LL_NEG Negation (two's complement) +** LL_ADD Summation (two's complement) +** LL_SUB Difference (two's complement) +***********************************************************************/ +#define LL_NEG(r, a) ((r) = -(a)) +#define LL_ADD(r, a, b) ((r) = (a) + (b)) +#define LL_SUB(r, a, b) ((r) = (a) - (b)) + +/*********************************************************************** +** MACROS: LL_ +** +** LL_MUL Product (two's complement) +** LL_DIV Quotient (two's complement) +** LL_MOD Modulus (two's complement) +***********************************************************************/ +#define LL_MUL(r, a, b) ((r) = (a) * (b)) +#define LL_DIV(r, a, b) ((r) = (a) / (b)) +#define LL_MOD(r, a, b) ((r) = (a) % (b)) + +/*********************************************************************** +** MACROS: LL_ +** +** LL_SHL Shift left [0..64] bits +** LL_SHR Shift right [0..64] bits with sign extension +** LL_USHR Unsigned shift right [0..64] bits +** LL_ISHL Signed shift left [0..64] bits +***********************************************************************/ +#define LL_SHL(r, a, b) ((r) = (PRInt64)(a) << (b)) +#define LL_SHR(r, a, b) ((r) = (PRInt64)(a) >> (b)) +#define LL_USHR(r, a, b) ((r) = (PRUint64)(a) >> (b)) +#define LL_ISHL(r, a, b) ((r) = (PRInt64)(a) << (b)) + +/*********************************************************************** +** MACROS: LL_ +** +** LL_L2I Convert to signed 32 bit +** LL_L2UI Convert to unsigned 32 bit +** LL_L2F Convert to floating point +** LL_L2D Convert to floating point +** LL_I2L Convert signed to 64 bit +** LL_UI2L Convert unsigned to 64 bit +** LL_F2L Convert float to 64 bit +** LL_D2L Convert float to 64 bit +***********************************************************************/ +#define LL_L2I(i, l) ((i) = (PRInt32)(l)) +#define LL_L2UI(ui, l) ((ui) = (PRUint32)(l)) +#define LL_L2F(f, l) ((f) = (PRFloat64)(l)) +#define LL_L2D(d, l) ((d) = (PRFloat64)(l)) + +#define LL_I2L(l, i) ((l) = (PRInt64)(i)) +#define LL_UI2L(l, ui) ((l) = (PRInt64)(ui)) +#define LL_F2L(l, f) ((l) = (PRInt64)(f)) +#define LL_D2L(l, d) ((l) = (PRInt64)(d)) + +/*********************************************************************** +** MACROS: LL_UDIVMOD +** DESCRIPTION: +** Produce both a quotient and a remainder given an unsigned +** INPUTS: PRUint64 a: The dividend of the operation +** PRUint64 b: The quotient of the operation +** OUTPUTS: PRUint64 *qp: pointer to quotient +** PRUint64 *rp: pointer to remainder +***********************************************************************/ +#define LL_UDIVMOD(qp, rp, a, b) \ + (*(qp) = ((PRUint64)(a) / (b)), \ + *(rp) = ((PRUint64)(a) % (b))) + +#else /* !HAVE_LONG_LONG */ + +#define LL_MAXINT LL_MaxInt() +#define LL_MININT LL_MinInt() +#define LL_ZERO LL_Zero() +#define LL_MAXUINT LL_MaxUint() + +#ifdef IS_LITTLE_ENDIAN +#define LL_INIT(hi, lo) {PR_UINT32(lo), PR_UINT32(hi)} +#else +#define LL_INIT(hi, lo) {PR_UINT32(hi), PR_UINT32(lo)} +#endif + +#define LL_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0)) +#define LL_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo)) +#define LL_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo)) +#define LL_GE_ZERO(a) (((a).hi >> 31) == 0) + +#define LL_CMP(a, op, b) (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \ + ((PRInt32)(a).hi op (PRInt32)(b).hi)) +#define LL_UCMP(a, op, b) (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \ + ((a).hi op (b).hi)) + +#define LL_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \ + (r).hi = (a).hi & (b).hi) +#define LL_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \ + (r).hi = (a).hi | (b).hi) +#define LL_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \ + (r).hi = (a).hi ^ (b).hi) +#define LL_OR2(r, a) ((r).lo = (r).lo | (a).lo, \ + (r).hi = (r).hi | (a).hi) +#define LL_NOT(r, a) ((r).lo = ~(a).lo, \ + (r).hi = ~(a).hi) + +#define LL_NEG(r, a) ((r).lo = -(PRInt32)(a).lo, \ + (r).hi = -(PRInt32)(a).hi - ((r).lo != 0)) +#define LL_ADD(r, a, b) { \ + PRInt64 _a, _b; \ + _a = a; _b = b; \ + (r).lo = _a.lo + _b.lo; \ + (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \ +} + +#define LL_SUB(r, a, b) { \ + PRInt64 _a, _b; \ + _a = a; _b = b; \ + (r).lo = _a.lo - _b.lo; \ + (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \ +} + +#define LL_MUL(r, a, b) { \ + PRInt64 _a, _b; \ + _a = a; _b = b; \ + LL_MUL32(r, _a.lo, _b.lo); \ + (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \ +} + +#define _lo16(a) ((a) & PR_BITMASK(16)) +#define _hi16(a) ((a) >> 16) + +#define LL_MUL32(r, a, b) { \ + PRUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \ + _a1 = _hi16(a), _a0 = _lo16(a); \ + _b1 = _hi16(b), _b0 = _lo16(b); \ + _y0 = _a0 * _b0; \ + _y1 = _a0 * _b1; \ + _y2 = _a1 * _b0; \ + _y3 = _a1 * _b1; \ + _y1 += _hi16(_y0); /* can't carry */ \ + _y1 += _y2; /* might carry */ \ + if (_y1 < _y2) \ + _y3 += (PRUint32)(PR_BIT(16)); /* propagate */ \ + (r).lo = (_lo16(_y1) << 16) + _lo16(_y0); \ + (r).hi = _y3 + _hi16(_y1); \ +} + +#define LL_UDIVMOD(qp, rp, a, b) ll_udivmod(qp, rp, a, b) + +NSPR_API(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b); + +#define LL_DIV(r, a, b) { \ + PRInt64 _a, _b; \ + PRUint32 _negative = (PRInt32)(a).hi < 0; \ + if (_negative) { \ + LL_NEG(_a, a); \ + } else { \ + _a = a; \ + } \ + if ((PRInt32)(b).hi < 0) { \ + _negative ^= 1; \ + LL_NEG(_b, b); \ + } else { \ + _b = b; \ + } \ + LL_UDIVMOD(&(r), 0, _a, _b); \ + if (_negative) \ + LL_NEG(r, r); \ +} + +#define LL_MOD(r, a, b) { \ + PRInt64 _a, _b; \ + PRUint32 _negative = (PRInt32)(a).hi < 0; \ + if (_negative) { \ + LL_NEG(_a, a); \ + } else { \ + _a = a; \ + } \ + if ((PRInt32)(b).hi < 0) { \ + LL_NEG(_b, b); \ + } else { \ + _b = b; \ + } \ + LL_UDIVMOD(0, &(r), _a, _b); \ + if (_negative) \ + LL_NEG(r, r); \ +} + +#define LL_SHL(r, a, b) { \ + if (b) { \ + PRInt64 _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = _a.lo << ((b) & 31); \ + (r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \ + } else { \ + (r).lo = 0; \ + (r).hi = _a.lo << ((b) & 31); \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +/* a is an PRInt32, b is PRInt32, r is PRInt64 */ +#define LL_ISHL(r, a, b) { \ + if (b) { \ + PRInt64 _a; \ + _a.lo = (a); \ + _a.hi = 0; \ + if ((b) < 32) { \ + (r).lo = (a) << ((b) & 31); \ + (r).hi = ((a) >> (32 - (b))); \ + } else { \ + (r).lo = 0; \ + (r).hi = (a) << ((b) & 31); \ + } \ + } else { \ + (r).lo = (a); \ + (r).hi = 0; \ + } \ +} + +#define LL_SHR(r, a, b) { \ + if (b) { \ + PRInt64 _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \ + (r).hi = (PRInt32)_a.hi >> ((b) & 31); \ + } else { \ + (r).lo = (PRInt32)_a.hi >> ((b) & 31); \ + (r).hi = (PRInt32)_a.hi >> 31; \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +#define LL_USHR(r, a, b) { \ + if (b) { \ + PRInt64 _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \ + (r).hi = _a.hi >> ((b) & 31); \ + } else { \ + (r).lo = _a.hi >> ((b) & 31); \ + (r).hi = 0; \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +#define LL_L2I(i, l) ((i) = (l).lo) +#define LL_L2UI(ui, l) ((ui) = (l).lo) +#define LL_L2F(f, l) { double _d; LL_L2D(_d, l); (f) = (PRFloat64)_d; } + +#define LL_L2D(d, l) { \ + int _negative; \ + PRInt64 _absval; \ + \ + _negative = (l).hi >> 31; \ + if (_negative) { \ + LL_NEG(_absval, l); \ + } else { \ + _absval = l; \ + } \ + (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \ + if (_negative) \ + (d) = -(d); \ +} + +#define LL_I2L(l, i) { PRInt32 _i = ((PRInt32)(i)) >> 31; (l).lo = (i); (l).hi = _i; } +#define LL_UI2L(l, ui) ((l).lo = (ui), (l).hi = 0) +#define LL_F2L(l, f) { double _d = (double)f; LL_D2L(l, _d); } + +#define LL_D2L(l, d) { \ + int _negative; \ + double _absval, _d_hi; \ + PRInt64 _lo_d; \ + \ + _negative = ((d) < 0); \ + _absval = _negative ? -(d) : (d); \ + \ + (l).hi = _absval / 4.294967296e9; \ + (l).lo = 0; \ + LL_L2D(_d_hi, l); \ + _absval -= _d_hi; \ + _lo_d.hi = 0; \ + if (_absval < 0) { \ + _lo_d.lo = -_absval; \ + LL_SUB(l, l, _lo_d); \ + } else { \ + _lo_d.lo = _absval; \ + LL_ADD(l, l, _lo_d); \ + } \ + \ + if (_negative) \ + LL_NEG(l, l); \ +} + +#endif /* !HAVE_LONG_LONG */ + +PR_END_EXTERN_C + +#endif /* prlong_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prmem.h nspr-4.10.7/nspr/pr/include/prmem.h --- nspr-4.9.5/nspr/pr/include/prmem.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prmem.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prmem.h +** Description: API to NSPR memory management functions +** +*/ +#ifndef prmem_h___ +#define prmem_h___ + +#include "prtypes.h" +#include + +PR_BEGIN_EXTERN_C + +/* +** Thread safe memory allocation. +** +** NOTE: pr wraps up malloc, free, calloc, realloc so they are already +** thread safe (and are not declared here - look in stdlib.h). +*/ + +/* +** PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free have the same signatures +** as their libc equivalent malloc, calloc, realloc, and free, and have +** the same semantics. (Note that the argument type size_t is replaced +** by PRUint32.) Memory allocated by PR_Malloc, PR_Calloc, or PR_Realloc +** must be freed by PR_Free. +*/ + +NSPR_API(void *) PR_Malloc(PRUint32 size); + +NSPR_API(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize); + +NSPR_API(void *) PR_Realloc(void *ptr, PRUint32 size); + +NSPR_API(void) PR_Free(void *ptr); + +/* +** The following are some convenience macros defined in terms of +** PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free. +*/ + +/*********************************************************************** +** FUNCTION: PR_MALLOC() +** DESCRIPTION: +** PR_NEW() allocates an untyped item of size _size from the heap. +** INPUTS: _size: size in bytes of item to be allocated +** OUTPUTS: untyped pointer to the node allocated +** RETURN: pointer to node or error returned from malloc(). +***********************************************************************/ +#define PR_MALLOC(_bytes) (PR_Malloc((_bytes))) + +/*********************************************************************** +** FUNCTION: PR_NEW() +** DESCRIPTION: +** PR_NEW() allocates an item of type _struct from the heap. +** INPUTS: _struct: a data type +** OUTPUTS: pointer to _struct +** RETURN: pointer to _struct or error returns from malloc(). +***********************************************************************/ +#define PR_NEW(_struct) ((_struct *) PR_MALLOC(sizeof(_struct))) + +/*********************************************************************** +** FUNCTION: PR_REALLOC() +** DESCRIPTION: +** PR_REALLOC() re-allocates _ptr bytes from the heap as a _size +** untyped item. +** INPUTS: _ptr: pointer to node to reallocate +** _size: size of node to allocate +** OUTPUTS: pointer to node allocated +** RETURN: pointer to node allocated +***********************************************************************/ +#define PR_REALLOC(_ptr, _size) (PR_Realloc((_ptr), (_size))) + +/*********************************************************************** +** FUNCTION: PR_CALLOC() +** DESCRIPTION: +** PR_CALLOC() allocates a _size bytes untyped item from the heap +** and sets the allocated memory to all 0x00. +** INPUTS: _size: size of node to allocate +** OUTPUTS: pointer to node allocated +** RETURN: pointer to node allocated +***********************************************************************/ +#define PR_CALLOC(_size) (PR_Calloc(1, (_size))) + +/*********************************************************************** +** FUNCTION: PR_NEWZAP() +** DESCRIPTION: +** PR_NEWZAP() allocates an item of type _struct from the heap +** and sets the allocated memory to all 0x00. +** INPUTS: _struct: a data type +** OUTPUTS: pointer to _struct +** RETURN: pointer to _struct +***********************************************************************/ +#define PR_NEWZAP(_struct) ((_struct*)PR_Calloc(1, sizeof(_struct))) + +/*********************************************************************** +** FUNCTION: PR_DELETE() +** DESCRIPTION: +** PR_DELETE() unallocates an object previosly allocated via PR_NEW() +** or PR_NEWZAP() to the heap. +** INPUTS: pointer to previously allocated object +** OUTPUTS: the referenced object is returned to the heap +** RETURN: void +***********************************************************************/ +#define PR_DELETE(_ptr) { PR_Free(_ptr); (_ptr) = NULL; } + +/*********************************************************************** +** FUNCTION: PR_FREEIF() +** DESCRIPTION: +** PR_FREEIF() conditionally unallocates an object previously allocated +** vial PR_NEW() or PR_NEWZAP(). If the pointer to the object is +** equal to zero (0), the object is not released. +** INPUTS: pointer to previously allocated object +** OUTPUTS: the referenced object is conditionally returned to the heap +** RETURN: void +***********************************************************************/ +#define PR_FREEIF(_ptr) if (_ptr) PR_DELETE(_ptr) + +PR_END_EXTERN_C + +#endif /* prmem_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prmon.h nspr-4.10.7/nspr/pr/include/prmon.h --- nspr-4.9.5/nspr/pr/include/prmon.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prmon.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prmon_h___ +#define prmon_h___ + +#include "prtypes.h" +#include "prinrval.h" + +PR_BEGIN_EXTERN_C + +typedef struct PRMonitor PRMonitor; + +/* +** Create a new monitor. Monitors are re-entrant locks with a single built-in +** condition variable. +** +** This may fail if memory is tight or if some operating system resource +** is low. +*/ +NSPR_API(PRMonitor*) PR_NewMonitor(void); + +/* +** Destroy a monitor. The caller is responsible for guaranteeing that the +** monitor is no longer in use. There must be no thread waiting on the monitor's +** condition variable and that the lock is not held. +** +*/ +NSPR_API(void) PR_DestroyMonitor(PRMonitor *mon); + +/* +** Enter the lock associated with the monitor. If the calling thread currently +** is in the monitor, the call to enter will silently succeed. In either case, +** it will increment the entry count by one. +*/ +NSPR_API(void) PR_EnterMonitor(PRMonitor *mon); + +/* +** Decrement the entry count associated with the monitor. If the decremented +** entry count is zero, the monitor is exited. Returns PR_FAILURE if the +** calling thread has not entered the monitor. +*/ +NSPR_API(PRStatus) PR_ExitMonitor(PRMonitor *mon); + +/* +** Wait for a notify on the monitor's condition variable. Sleep for "ticks" +** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is +** indefinite). +** +** While the thread is waiting it exits the monitor (as if it called +** PR_ExitMonitor as many times as it had called PR_EnterMonitor). When +** the wait has finished the thread regains control of the monitors lock +** with the same entry count as before the wait began. +** +** The thread waiting on the monitor will be resumed when the monitor is +** notified (assuming the thread is the next in line to receive the +** notify) or when the "ticks" timeout elapses. +** +** Returns PR_FAILURE if the caller has not entered the monitor. +*/ +NSPR_API(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks); + +/* +** Notify a thread waiting on the monitor's condition variable. If a thread +** is waiting on the condition variable (using PR_Wait) then it is awakened +** and attempts to reenter the monitor. +*/ +NSPR_API(PRStatus) PR_Notify(PRMonitor *mon); + +/* +** Notify all of the threads waiting on the monitor's condition variable. +** All of threads waiting on the condition are scheduled to reenter the +** monitor. +*/ +NSPR_API(PRStatus) PR_NotifyAll(PRMonitor *mon); + +/* +** PR_ASSERT_CURRENT_THREAD_IN_MONITOR +** If the current thread is in |mon|, this assertion is guaranteed to +** succeed. Otherwise, the behavior of this function is undefined. +*/ +#if defined(DEBUG) || defined(FORCE_PR_ASSERT) +#define PR_ASSERT_CURRENT_THREAD_IN_MONITOR(/* PRMonitor* */ mon) \ + PR_AssertCurrentThreadInMonitor(mon) +#else +#define PR_ASSERT_CURRENT_THREAD_IN_MONITOR(/* PRMonitor* */ mon) +#endif + +/* Don't call this function directly. */ +NSPR_API(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon); + +PR_END_EXTERN_C + +#endif /* prmon_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prmwait.h nspr-4.10.7/nspr/pr/include/prmwait.h --- nspr-4.9.5/nspr/pr/include/prmwait.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prmwait.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,380 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if defined(_PRMWAIT_H) +#else +#define _PRMWAIT_H + +#include "prio.h" +#include "prtypes.h" +#include "prclist.h" + +PR_BEGIN_EXTERN_C + +/********************************************************************************/ +/********************************************************************************/ +/********************************************************************************/ +/****************************** WARNING ****************************/ +/********************************************************************************/ +/**************************** This is work in progress. *************************/ +/************************** Do not make any assumptions *************************/ +/************************** about the stability of this *************************/ +/************************** API or the underlying imple- ************************/ +/************************** mentation. ************************/ +/********************************************************************************/ +/********************************************************************************/ + +/* +** STRUCTURE: PRWaitGroup +** DESCRIPTION: +** The client may define several wait groups in order to semantically +** tie a collection of file descriptors for a single purpose. This allows +** easier dispatching of threads that returned with active file descriptors +** from the wait function. +*/ +typedef struct PRWaitGroup PRWaitGroup; + +/* +** ENUMERATION: PRMWStatus +** DESCRIPTION: +** This enumeration is used to indicate the completion status of +** a receive wait object. Generally stated, a positive value indicates +** that the operation is not yet complete. A zero value indicates +** success (similar to PR_SUCCESS) and any negative value is an +** indication of failure. The reason for the failure can be retrieved +** by calling PR_GetError(). +** +** PR_MW_PENDING The operation is still pending. None of the other +** fields of the object are currently valid. +** PR_MW_SUCCESS The operation is complete and it was successful. +** PR_MW_FAILURE The operation failed. The reason for the failure +** can be retrieved by calling PR_GetError(). +** PR_MW_TIMEOUT The amount of time allowed for by the object's +** 'timeout' field has expired w/o the operation +** otherwise coming to closure. +** PR_MW_INTERRUPT The operation was cancelled, either by the client +** calling PR_CancelWaitFileDesc() or destroying the +** entire wait group (PR_DestroyWaitGroup()). +*/ +typedef enum PRMWStatus +{ + PR_MW_PENDING = 1, + PR_MW_SUCCESS = 0, + PR_MW_FAILURE = -1, + PR_MW_TIMEOUT = -2, + PR_MW_INTERRUPT = -3 +} PRMWStatus; + +/* +** STRUCTURE: PRMemoryDescriptor +** DESCRIPTION: +** THis is a descriptor for an interval of memory. It contains a +** pointer to the first byte of that memory and the length (in +** bytes) of the interval. +*/ +typedef struct PRMemoryDescriptor +{ + void *start; /* pointer to first byte of memory */ + PRSize length; /* length (in bytes) of memory interval */ +} PRMemoryDescriptor; + +/* +** STRUCTURE: PRMWaitClientData +** DESCRIPTION: +** An opague stucture for which a client MAY give provide a concrete +** definition and associate with a receive descriptor. The NSPR runtime +** does not manage this field. It is completely up to the client. +*/ +typedef struct PRMWaitClientData PRMWaitClientData; + +/* +** STRUCTURE: PRRecvWait +** DESCRIPTION: +** A receive wait object contains the file descriptor that is subject +** to the wait and the amount of time (beginning epoch established +** when the object is presented to the runtime) the the channel should +** block before abandoning the process. +** +** The success of the wait operation will be noted in the object's +** 'outcome' field. The fields are not valid when the NSPR runtime +** is in possession of the object. +** +** The memory descriptor describes an interval of writable memory +** in the caller's address space where data from an initial read +** can be placed. The description may indicate a null interval. +*/ +typedef struct PRRecvWait +{ + PRCList internal; /* internal runtime linkages */ + + PRFileDesc *fd; /* file descriptor associated w/ object */ + PRMWStatus outcome; /* outcome of the current/last operation */ + PRIntervalTime timeout; /* time allowed for entire operation */ + + PRInt32 bytesRecv; /* number of bytes transferred into buffer */ + PRMemoryDescriptor buffer; /* where to store first segment of input data */ + PRMWaitClientData *client; /* pointer to arbitrary client defined data */ +} PRRecvWait; + +/* +** STRUCTURE: PRMWaitEnumerator +** DESCRIPTION: +** An enumeration object is used to store the state of an existing +** enumeration over a wait group. The opaque object must be allocated +** by the client and the reference presented on each call to the +** pseudo-stateless enumerator. The enumeration objects are sharable +** only in serial fashion. +*/ +typedef struct PRMWaitEnumerator PRMWaitEnumerator; + + +/* +** FUNCTION: PR_AddWaitFileDesc +** DESCRIPTION: +** This function will effectively add a file descriptor to the +** list of those waiting for network receive. The new descriptor +** will be semantically tied to the wait group specified. +** +** The ownership for the storage pointed to by 'desc' is temporarily +** passed over the the NSPR runtime. It will be handed back by the +** function PR_WaitRecvReady(). +** +** INPUTS +** group A reference to a PRWaitGroup or NULL. Wait groups are +** created by calling PR_CreateWaitGroup() and are used +** to semantically group various file descriptors by the +** client's application. +** desc A reference to a valid PRRecvWait. The object of the +** reference must be preserved and not be modified +** until its ownership is returned to the client. +** RETURN +** PRStatus An indication of success. If equal to PR_FAILUE details +** of the failure are avaiable via PR_GetError(). +** +** ERRORS +** PR_INVALID_ARGUMENT_ERROR +** Invalid 'group' identifier or duplicate 'desc' object. +** PR_OUT_OF_MEMORY_ERROR +** Insuffient memory for internal data structures. +** PR_INVALID_STATE_ERROR +** The group is being destroyed. +*/ +NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc); + +/* +** FUNCTION: PR_WaitRecvReady +** DESCRIPTION: +** PR_WaitRecvReady will block the calling thread until one of the +** file descriptors that have been added via PR_AddWaitFileDesc is +** available for input I/O. +** INPUT +** group A pointer to a valid PRWaitGroup or NULL (the null +** group. The function will block the caller until a +** channel from the wait group becomes ready for receive +** or there is some sort of error. +** RETURN +** PRReciveWait +** When the caller is resumed it is either returned a +** valid pointer to a previously added receive wait or +** a NULL. If the latter, the function has terminated +** for a reason that can be determined by calling +** PR_GetError(). +** If a valid pointer is returned, the reference is to the +** file descriptor contained in the receive wait object. +** The outcome of the wait operation may still fail, and +** if it has, that fact will be noted in the object's +** outcome field. Details can be retrieved from PR_GetError(). +** +** ERRORS +** PR_INVALID_ARGUMENT_ERROR +** The 'group' is not known by the runtime. +** PR_PENDING_INTERRUPT_ERROR + The thread was interrupted. +** PR_INVALID_STATE_ERROR +** The group is being destroyed. +*/ +NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group); + +/* +** FUNCTION: PR_CancelWaitFileDesc +** DESCRIPTION: +** PR_CancelWaitFileDesc is provided as a means for cancelling operations +** on objects previously submitted by use of PR_AddWaitFileDesc(). If +** the runtime knows of the object, it will be marked as having failed +** because it was interrupted (similar to PR_Interrupt()). The first +** available thread waiting on the group will be made to return the +** PRRecvWait object with the outcome noted. +** +** INPUTS +** group The wait group under which the wait receive object was +** added. +** desc A pointer to the wait receive object that is to be +** cancelled. +** RETURN +** PRStatus If the wait receive object was located and associated +** with the specified wait group, the status returned will +** be PR_SUCCESS. There is still a race condition that would +** permit the offected object to complete normally, but it +** is assured that it will complete in the near future. +** If the receive object or wait group are invalid, the +** function will return with a status of PR_FAILURE. +** +** ERRORS +** PR_INVALID_ARGUMENT_ERROR +** The 'group' argument is not recognized as a valid group. +** PR_COLLECTION_EMPTY_ERROR +** There are no more receive wait objects in the group's +** collection. +** PR_INVALID_STATE_ERROR +** The group is being destroyed. +*/ +NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc); + +/* +** FUNCTION: PR_CancelWaitGroup +** DESCRIPTION: +** PR_CancelWaitGroup is provided as a means for cancelling operations +** on objects previously submitted by use of PR_AddWaitFileDesc(). Each +** successive call will return a pointer to a PRRecvWait object that +** was previously registered via PR_AddWaitFileDesc(). If no wait +** objects are associated with the wait group, a NULL will be returned. +** This function should be called in a loop until a NULL is returned +** to reclaim all the wait objects prior to calling PR_DestroyWaitGroup(). +** +** INPUTS +** group The wait group under which the wait receive object was +** added. +** RETURN +** PRRecvWait* If the wait group is valid and at least one receive wait +** object is present in the group, that object will be +** marked as PR_MW_INTERRUPT'd and removed from the group's +** queues. Otherwise a NULL will be returned and the reason +** for the NULL may be retrieved by calling PR_GetError(). +** +** ERRORS +** PR_INVALID_ARGUMENT_ERROR +** PR_GROUP_EMPTY_ERROR +*/ +NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group); + +/* +** FUNCTION: PR_CreateWaitGroup +** DESCRIPTION: +** A wait group is an opaque object that a client may create in order +** to semantically group various wait requests. Each wait group is +** unique, including the default wait group (NULL). A wait request +** that was added under a wait group will only be serviced by a caller +** that specified the same wait group. +** +** INPUT +** size The size of the hash table to be used to contain the +** receive wait objects. This is just the initial size. +** It will grow as it needs to, but to avoid that hassle +** one can suggest a suitable size initially. It should +** be ~30% larger than the maximum number of receive wait +** objects expected. +** RETURN +** PRWaitGroup If successful, the function will return a pointer to an +** object that was allocated by and owned by the runtime. +** The reference remains valid until it is explicitly destroyed +** by calling PR_DestroyWaitGroup(). +** +** ERRORS +** PR_OUT_OF_MEMORY_ERROR +*/ +NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size); + +/* +** FUNCTION: PR_DestroyWaitGroup +** DESCRIPTION: +** Undo the effects of PR_CreateWaitGroup(). Any receive wait operations +** on the group will be treated as if the each had been the target of a +** PR_CancelWaitFileDesc(). +** +** INPUT +** group Reference to a wait group previously allocated using +** PR_CreateWaitGroup(). +** RETURN +** PRStatus Will be PR_SUCCESS if the wait group was valid and there +** are no receive wait objects in that group. Otherwise +** will indicate PR_FAILURE. +** +** ERRORS +** PR_INVALID_ARGUMENT_ERROR +** The 'group' argument does not reference a known object. +** PR_INVALID_STATE_ERROR +** The group still contains receive wait objects. +*/ +NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group); + +/* +** FUNCTION: PR_CreateMWaitEnumerator +** DESCRIPTION: +** The PR_CreateMWaitEnumerator() function returns a reference to an +** opaque PRMWaitEnumerator object. The enumerator object is required +** as an argument for each successive call in the stateless enumeration +** of the indicated wait group. +** +** group The wait group that the enumeration is intended to +** process. It may be be the default wait group (NULL). +** RETURN +** PRMWaitEnumerator* group +** A reference to an object that will be used to store +** intermediate state of enumerations. +** ERRORS +** Errors are indicated by the function returning a NULL. +** PR_INVALID_ARGUMENT_ERROR +** The 'group' argument does not reference a known object. +** PR_OUT_OF_MEMORY_ERROR +*/ +NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group); + +/* +** FUNCTION: PR_DestroyMWaitEnumerator +** DESCRIPTION: +** Destroys the object created by PR_CreateMWaitEnumerator(). The reference +** used as an argument becomes invalid. +** +** INPUT +** PRMWaitEnumerator* enumerator +** The PRMWaitEnumerator object to destroy. +** RETURN +** PRStatus +** PR_SUCCESS if successful, PR_FAILURE otherwise. +** ERRORS +** PR_INVALID_ARGUMENT_ERROR +** The enumerator is invalid. +*/ +NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator); + +/* +** FUNCTION: PR_EnumerateWaitGroup +** DESCRIPTION: +** PR_EnumerateWaitGroup is a thread safe enumerator over a wait group. +** Each call to the enumerator must present a valid PRMWaitEnumerator +** rererence and a pointer to the "previous" element returned from the +** enumeration process or a NULL. +** +** An enumeration is started by passing a NULL as the "previous" value. +** Subsequent calls to the enumerator must pass in the result of the +** previous call. The enumeration end is signaled by the runtime returning +** a NULL as the result. +** +** Modifications to the content of the wait group are allowed during +** an enumeration. The effect is that the enumeration may have to be +** "reset" and that may result in duplicates being returned from the +** enumeration. +** +** An enumeration may be abandoned at any time. The runtime is not +** keeping any state, so there are no issues in that regard. +*/ +NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup( + PRMWaitEnumerator *enumerator, const PRRecvWait *previous); + +PR_END_EXTERN_C + +#endif /* defined(_PRMWAIT_H) */ + +/* prmwait.h */ diff -Nru nspr-4.9.5/nspr/pr/include/prnetdb.h nspr-4.10.7/nspr/pr/include/prnetdb.h --- nspr-4.9.5/nspr/pr/include/prnetdb.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prnetdb.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,467 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prnetdb_h___ +#define prnetdb_h___ + +#include "prtypes.h" +#include "prio.h" + +PR_BEGIN_EXTERN_C + + +/* + ********************************************************************* + * Translate an Internet address to/from a character string + ********************************************************************* + */ +NSPR_API(PRStatus) PR_StringToNetAddr( + const char *string, PRNetAddr *addr); + +NSPR_API(PRStatus) PR_NetAddrToString( + const PRNetAddr *addr, char *string, PRUint32 size); + +/* +** Structures returned by network data base library. All addresses are +** supplied in host order, and returned in network order (suitable for +** use in system calls). +*/ +/* +** Beware that WINSOCK.H defines h_addrtype and h_length as short. +** Client code does direct struct copies of hostent to PRHostEnt and +** hence the ifdef. +*/ +typedef struct PRHostEnt { + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ +#ifdef WIN32 + PRInt16 h_addrtype; /* host address type */ + PRInt16 h_length; /* length of address */ +#else + PRInt32 h_addrtype; /* host address type */ + PRInt32 h_length; /* length of address */ +#endif + char **h_addr_list; /* list of addresses from name server */ +} PRHostEnt; + +/* A safe size to use that will mostly work... */ +#if (defined(AIX) && defined(_THREAD_SAFE)) || defined(OSF1) +#define PR_NETDB_BUF_SIZE sizeof(struct protoent_data) +#else +#define PR_NETDB_BUF_SIZE 1024 +#endif + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_GetHostByName() +** Lookup a host by name. +** +** INPUTS: +** char *hostname Character string defining the host name of interest +** char *buf A scratch buffer for the runtime to return result. +** This buffer is allocated by the caller. +** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to +** use is PR_NETDB_BUF_SIZE. +** OUTPUTS: +** PRHostEnt *hostentry +** This structure is filled in by the runtime if +** the function returns PR_SUCCESS. This structure +** is allocated by the caller. +** RETURN: +** PRStatus PR_SUCCESS if the lookup succeeds. If it fails +** the result will be PR_FAILURE and the reason +** for the failure can be retrieved by PR_GetError(). +***********************************************************************/ +NSPR_API(PRStatus) PR_GetHostByName( + const char *hostname, char *buf, PRIntn bufsize, PRHostEnt *hostentry); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_GetIPNodeByName() +** Lookup a host by name. Equivalent to getipnodebyname(AI_DEFAULT) +** of RFC 2553. +** +** INPUTS: +** char *hostname Character string defining the host name of interest +** PRUint16 af Address family (either PR_AF_INET or PR_AF_INET6) +** PRIntn flags Specifies the types of addresses that are searched +** for and the types of addresses that are returned. +** The only supported flag is PR_AI_DEFAULT. +** char *buf A scratch buffer for the runtime to return result. +** This buffer is allocated by the caller. +** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to +** use is PR_NETDB_BUF_SIZE. +** OUTPUTS: +** PRHostEnt *hostentry +** This structure is filled in by the runtime if +** the function returns PR_SUCCESS. This structure +** is allocated by the caller. +** RETURN: +** PRStatus PR_SUCCESS if the lookup succeeds. If it fails +** the result will be PR_FAILURE and the reason +** for the failure can be retrieved by PR_GetError(). +***********************************************************************/ + + +#define PR_AI_ALL 0x08 +#define PR_AI_V4MAPPED 0x10 +#define PR_AI_ADDRCONFIG 0x20 +#define PR_AI_NOCANONNAME 0x8000 +#define PR_AI_DEFAULT (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG) + +NSPR_API(PRStatus) PR_GetIPNodeByName( + const char *hostname, + PRUint16 af, + PRIntn flags, + char *buf, + PRIntn bufsize, + PRHostEnt *hostentry); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_GetHostByAddr() +** Lookup a host entry by its network address. +** +** INPUTS: +** char *hostaddr IP address of host in question +** char *buf A scratch buffer for the runtime to return result. +** This buffer is allocated by the caller. +** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to +** use is PR_NETDB_BUF_SIZE. +** OUTPUTS: +** PRHostEnt *hostentry +** This structure is filled in by the runtime if +** the function returns PR_SUCCESS. This structure +** is allocated by the caller. +** RETURN: +** PRStatus PR_SUCCESS if the lookup succeeds. If it fails +** the result will be PR_FAILURE and the reason +** for the failure can be retrieved by PR_GetError(). +***********************************************************************/ +NSPR_API(PRStatus) PR_GetHostByAddr( + const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry); + +/*********************************************************************** +** FUNCTION: PR_EnumerateHostEnt() +** DESCRIPTION: +** A stateless enumerator over a PRHostEnt structure acquired from +** PR_GetHostByName() PR_GetHostByAddr() to evaluate the possible +** network addresses. +** +** INPUTS: +** PRIntn enumIndex Index of the enumeration. The enumeration starts +** and ends with a value of zero. +** +** PRHostEnt *hostEnt A pointer to a host entry struct that was +** previously returned by PR_GetHostByName() or +** PR_GetHostByAddr(). +** +** PRUint16 port The port number to be assigned as part of the +** PRNetAddr. +** +** OUTPUTS: +** PRNetAddr *address A pointer to an address structure that will be +** filled in by the call to the enumeration if the +** result of the call is greater than zero. +** +** RETURN: +** PRIntn The value that should be used for the next call +** of the enumerator ('enumIndex'). The enumeration +** is ended if this value is returned zero. +** If a value of -1 is returned, the enumeration +** has failed. The reason for the failure can be +** retrieved by calling PR_GetError(). +***********************************************************************/ +NSPR_API(PRIntn) PR_EnumerateHostEnt( + PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address); + +/*********************************************************************** +** FUNCTION: PR_InitializeNetAddr(), +** DESCRIPTION: +** Initialize the fields of a PRNetAddr, assigning well known values as +** appropriate. +** +** INPUTS +** PRNetAddrValue val The value to be assigned to the IP Address portion +** of the network address. This can only specify the +** special well known values that are equivalent to +** INADDR_ANY and INADDR_LOOPBACK. +** +** PRUint16 port The port number to be assigned in the structure. +** +** OUTPUTS: +** PRNetAddr *addr The address to be manipulated. +** +** RETURN: +** PRStatus To indicate success or failure. If the latter, the +** reason for the failure can be retrieved by calling +** PR_GetError(); +***********************************************************************/ +typedef enum PRNetAddrValue +{ + PR_IpAddrNull, /* do NOT overwrite the IP address */ + PR_IpAddrAny, /* assign logical INADDR_ANY to IP address */ + PR_IpAddrLoopback, /* assign logical INADDR_LOOPBACK */ + PR_IpAddrV4Mapped /* IPv4 mapped address */ +} PRNetAddrValue; + +NSPR_API(PRStatus) PR_InitializeNetAddr( + PRNetAddrValue val, PRUint16 port, PRNetAddr *addr); + +/*********************************************************************** +** FUNCTION: PR_SetNetAddr(), +** DESCRIPTION: +** Set the fields of a PRNetAddr, assigning well known values as +** appropriate. This function is similar to PR_InitializeNetAddr +** but differs in that the address family is specified. +** +** INPUTS +** PRNetAddrValue val The value to be assigned to the IP Address portion +** of the network address. This can only specify the +** special well known values that are equivalent to +** INADDR_ANY and INADDR_LOOPBACK. +** +** PRUint16 af The address family (either PR_AF_INET or PR_AF_INET6) +** +** PRUint16 port The port number to be assigned in the structure. +** +** OUTPUTS: +** PRNetAddr *addr The address to be manipulated. +** +** RETURN: +** PRStatus To indicate success or failure. If the latter, the +** reason for the failure can be retrieved by calling +** PR_GetError(); +***********************************************************************/ +NSPR_API(PRStatus) PR_SetNetAddr( + PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_IsNetAddrType() +** Determine if the network address is of the specified type. +** +** INPUTS: +** const PRNetAddr *addr A network address. +** PRNetAddrValue The type of network address +** +** RETURN: +** PRBool PR_TRUE if the network address is of the +** specified type, else PR_FALSE. +***********************************************************************/ +NSPR_API(PRBool) PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_ConvertIPv4AddrToIPv6() +** Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr +** +** INPUTS: +** PRUint32 v4addr IPv4 address +** +** OUTPUTS: +** PRIPv6Addr *v6addr The converted IPv6 address +** +** RETURN: +** void +** +***********************************************************************/ +NSPR_API(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr); + +/*********************************************************************** +** MACRO: +** DESCRIPTION: PR_NetAddrFamily() +** Get the 'family' field of a PRNetAddr union. +** +** INPUTS: +** const PRNetAddr *addr A network address. +** +** RETURN: +** PRUint16 The 'family' field of 'addr'. +***********************************************************************/ +#define PR_NetAddrFamily(addr) ((addr)->raw.family) + +/*********************************************************************** +** MACRO: +** DESCRIPTION: PR_NetAddrInetPort() +** Get the 'port' field of a PRNetAddr union. +** +** INPUTS: +** const PRNetAddr *addr A network address. +** +** RETURN: +** PRUint16 The 'port' field of 'addr'. +***********************************************************************/ +#define PR_NetAddrInetPort(addr) \ + ((addr)->raw.family == PR_AF_INET6 ? (addr)->ipv6.port : (addr)->inet.port) + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_GetProtoByName() +** Lookup a protocol entry based on protocol's name +** +** INPUTS: +** char *protocolname Character string of the protocol's name. +** char *buf A scratch buffer for the runtime to return result. +** This buffer is allocated by the caller. +** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to +** use is PR_NETDB_BUF_SIZE. +** OUTPUTS: +** PRHostEnt *PRProtoEnt +** This structure is filled in by the runtime if +** the function returns PR_SUCCESS. This structure +** is allocated by the caller. +** RETURN: +** PRStatus PR_SUCCESS if the lookup succeeds. If it fails +** the result will be PR_FAILURE and the reason +** for the failure can be retrieved by PR_GetError(). +***********************************************************************/ + +typedef struct PRProtoEnt { + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ +#ifdef WIN32 + PRInt16 p_num; /* protocol # */ +#else + PRInt32 p_num; /* protocol # */ +#endif +} PRProtoEnt; + +NSPR_API(PRStatus) PR_GetProtoByName( + const char* protocolname, char* buffer, PRInt32 bufsize, PRProtoEnt* result); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_GetProtoByNumber() +** Lookup a protocol entry based on protocol's number +** +** INPUTS: +** PRInt32 protocolnumber +** Number assigned to the protocol. +** char *buf A scratch buffer for the runtime to return result. +** This buffer is allocated by the caller. +** PRIntn bufsize Number of bytes in 'buf'. A recommnded value to +** use is PR_NETDB_BUF_SIZE. +** OUTPUTS: +** PRHostEnt *PRProtoEnt +** This structure is filled in by the runtime if +** the function returns PR_SUCCESS. This structure +** is allocated by the caller. +** RETURN: +** PRStatus PR_SUCCESS if the lookup succeeds. If it fails +** the result will be PR_FAILURE and the reason +** for the failure can be retrieved by PR_GetError(). +***********************************************************************/ +NSPR_API(PRStatus) PR_GetProtoByNumber( + PRInt32 protocolnumber, char* buffer, PRInt32 bufsize, PRProtoEnt* result); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_GetAddrInfoByName() +** Look up a host by name. Equivalent to getaddrinfo(host, NULL, ...) of +** RFC 3493. +** +** INPUTS: +** char *hostname Character string defining the host name of interest +** PRUint16 af May be PR_AF_UNSPEC or PR_AF_INET. +** PRIntn flags May be either PR_AI_ADDRCONFIG or +** PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME. Include +** PR_AI_NOCANONNAME to suppress the determination of +** the canonical name corresponding to hostname. +** RETURN: +** PRAddrInfo* Handle to a data structure containing the results +** of the host lookup. Use PR_EnumerateAddrInfo to +** inspect the PRNetAddr values stored in this object. +** When no longer needed, this handle must be destroyed +** with a call to PR_FreeAddrInfo. If a lookup error +** occurs, then NULL will be returned. +***********************************************************************/ +typedef struct PRAddrInfo PRAddrInfo; + +NSPR_API(PRAddrInfo*) PR_GetAddrInfoByName( + const char *hostname, PRUint16 af, PRIntn flags); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_FreeAddrInfo() +** Destroy the PRAddrInfo handle allocated by PR_GetAddrInfoByName(). +** +** INPUTS: +** PRAddrInfo *addrInfo +** The handle resulting from a successful call to +** PR_GetAddrInfoByName(). +** RETURN: +** void +***********************************************************************/ +NSPR_API(void) PR_FreeAddrInfo(PRAddrInfo *addrInfo); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_EnumerateAddrInfo() +** A stateless enumerator over a PRAddrInfo handle acquired from +** PR_GetAddrInfoByName() to inspect the possible network addresses. +** +** INPUTS: +** void *enumPtr Index pointer of the enumeration. The enumeration +** starts and ends with a value of NULL. +** const PRAddrInfo *addrInfo +** The PRAddrInfo handle returned by a successful +** call to PR_GetAddrInfoByName(). +** PRUint16 port The port number to be assigned as part of the +** PRNetAddr. +** OUTPUTS: +** PRNetAddr *result A pointer to an address structure that will be +** filled in by the call to the enumeration if the +** result of the call is not NULL. +** RETURN: +** void* The value that should be used for the next call +** of the enumerator ('enumPtr'). The enumeration +** is ended if this value is NULL. +***********************************************************************/ +NSPR_API(void *) PR_EnumerateAddrInfo( + void *enumPtr, const PRAddrInfo *addrInfo, PRUint16 port, PRNetAddr *result); + +/*********************************************************************** +** FUNCTION: +** DESCRIPTION: PR_GetCanonNameFromAddrInfo() +** Extracts the canonical name of the hostname passed to +** PR_GetAddrInfoByName(). +** +** INPUTS: +** const PRAddrInfo *addrInfo +** The PRAddrInfo handle returned by a successful +** call to PR_GetAddrInfoByName(). +** RETURN: +** const char * A const pointer to the canonical hostname stored +** in the given PRAddrInfo handle. This pointer is +** invalidated once the PRAddrInfo handle is destroyed +** by a call to PR_FreeAddrInfo(). +***********************************************************************/ +NSPR_API(const char *) PR_GetCanonNameFromAddrInfo( + const PRAddrInfo *addrInfo); + +/*********************************************************************** +** FUNCTIONS: PR_ntohs, PR_ntohl, PR_ntohll, PR_htons, PR_htonl, PR_htonll +** +** DESCRIPTION: API entries for the common byte ordering routines. +** +** PR_ntohs 16 bit conversion from network to host +** PR_ntohl 32 bit conversion from network to host +** PR_ntohll 64 bit conversion from network to host +** PR_htons 16 bit conversion from host to network +** PR_htonl 32 bit conversion from host to network +** PR_ntonll 64 bit conversion from host to network +** +***********************************************************************/ +NSPR_API(PRUint16) PR_ntohs(PRUint16); +NSPR_API(PRUint32) PR_ntohl(PRUint32); +NSPR_API(PRUint64) PR_ntohll(PRUint64); +NSPR_API(PRUint16) PR_htons(PRUint16); +NSPR_API(PRUint32) PR_htonl(PRUint32); +NSPR_API(PRUint64) PR_htonll(PRUint64); + +PR_END_EXTERN_C + +#endif /* prnetdb_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prolock.h nspr-4.10.7/nspr/pr/include/prolock.h --- nspr-4.9.5/nspr/pr/include/prolock.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prolock.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,178 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prolock_h___ +#define prolock_h___ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* +** A locking mechanism, built on the existing PRLock definiion, +** is provided that will permit applications to define a Lock +** Hierarchy (or Lock Ordering) schema. An application designed +** using the Ordered Lock functions will terminate with a +** diagnostic message when a lock inversion condition is +** detected. +** +** The lock ordering detection is complile-time enabled only. in +** optimized builds of NSPR, the Ordered Lock functions map +** directly to PRLock functions, providing no lock order +** detection. +** +** The Ordered Lock Facility is compiled in when DEBUG is defined at +** compile time. Ordered Lock can be forced on in optimized builds by +** defining FORCE_NSPR_ORDERED_LOCK at compile time. Both the +** application using Ordered Lock and NSPR must be compiled with the +** facility enabled to achieve the desired results. +** +** Application designers should use the macro interfaces to the Ordered +** Lock facility to ensure that it is compiled out in optimized builds. +** +** Application designers are responsible for defining their own +** lock hierarchy. +** +** Ordered Lock is thread-safe and SMP safe. +** +** See Also: prlock.h +** +** /lth. 10-Jun-1998. +** +*/ + +/* +** Opaque type for ordered lock. +** ... Don't even think of looking in here. +** +*/ + +#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) +typedef void * PROrderedLock; +#else +/* +** Map PROrderedLock and methods onto PRLock when ordered locking +** is not compiled in. +** +*/ +#include "prlock.h" + +typedef PRLock PROrderedLock; +#endif + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_CreateOrderedLock() -- Create an Ordered Lock +** +** DESCRIPTION: PR_CreateOrderedLock() creates an ordered lock. +** +** INPUTS: +** order: user defined order of this lock. +** name: name of the lock. For debugging purposes. +** +** OUTPUTS: returned +** +** RETURNS: PR_OrderedLock pointer +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) +#define PR_CREATE_ORDERED_LOCK(order,name)\ + PR_CreateOrderedLock((order),(name)) +#else +#define PR_CREATE_ORDERED_LOCK(order) PR_NewLock() +#endif + +NSPR_API(PROrderedLock *) + PR_CreateOrderedLock( + PRInt32 order, + const char *name +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_DestroyOrderedLock() -- Destroy an Ordered Lock +** +** DESCRIPTION: PR_DestroyOrderedLock() destroys the ordered lock +** referenced by lock. +** +** INPUTS: lock: pointer to a PROrderedLock +** +** OUTPUTS: the lock is destroyed +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) +#define PR_DESTROY_ORDERED_LOCK(lock) PR_DestroyOrderedLock((lock)) +#else +#define PR_DESTROY_ORDERED_LOCK(lock) PR_DestroyLock((lock)) +#endif + +NSPR_API(void) + PR_DestroyOrderedLock( + PROrderedLock *lock +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_LockOrderedLock() -- Lock an ordered lock +** +** DESCRIPTION: PR_LockOrderedLock() locks the ordered lock +** referenced by lock. If the order of lock is less than or equal +** to the order of the highest lock held by the locking thread, +** the function asserts. +** +** INPUTS: lock: a pointer to a PROrderedLock +** +** OUTPUTS: The lock is held or the function asserts. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) +#define PR_LOCK_ORDERED_LOCK(lock) PR_LockOrderedLock((lock)) +#else +#define PR_LOCK_ORDERED_LOCK(lock) PR_Lock((lock)) +#endif + +NSPR_API(void) + PR_LockOrderedLock( + PROrderedLock *lock +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_UnlockOrderedLock() -- unlock and Ordered Lock +** +** DESCRIPTION: PR_UnlockOrderedLock() unlocks the lock referenced +** by lock. +** +** INPUTS: lock: a pointer to a PROrderedLock +** +** OUTPUTS: the lock is unlocked +** +** RETURNS: +** PR_SUCCESS +** PR_FAILURE +** +** RESTRICTIONS: +** +*/ +#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS) +#define PR_UNLOCK_ORDERED_LOCK(lock) PR_UnlockOrderedLock((lock)) +#else +#define PR_UNLOCK_ORDERED_LOCK(lock) PR_Unlock((lock)) +#endif + +NSPR_API(PRStatus) + PR_UnlockOrderedLock( + PROrderedLock *lock +); + +PR_END_EXTERN_C + +#endif /* prolock_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prpdce.h nspr-4.10.7/nspr/pr/include/prpdce.h --- nspr-4.9.5/nspr/pr/include/prpdce.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prpdce.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: prpdce.h + * Description: This file is the API defined to allow for DCE (aka POSIX) + * thread emulation in an NSPR environment. It is not the + * intent that this be a fully supported API. + */ + +#if !defined(PRPDCE_H) +#define PRPDCE_H + +#include "prlock.h" +#include "prcvar.h" +#include "prtypes.h" +#include "prinrval.h" + +PR_BEGIN_EXTERN_C + +#define _PR_NAKED_CV_LOCK (PRLock*)0xdce1dce1 + +/* +** Test and acquire a lock. +** +** If the lock is acquired by the calling thread, the +** return value will be PR_SUCCESS. If the lock is +** already held, by another thread or this thread, the +** result will be PR_FAILURE. +*/ +NSPR_API(PRStatus) PRP_TryLock(PRLock *lock); + +/* +** Create a naked condition variable +** +** A "naked" condition variable is one that is not created bound +** to a lock. The CV created with this function is the only type +** that may be used in the subsequent "naked" condition variable +** operations (see PRP_NakedWait, PRP_NakedNotify, PRP_NakedBroadcast); +*/ +NSPR_API(PRCondVar*) PRP_NewNakedCondVar(void); + +/* +** Destroy a naked condition variable +** +** Destroy the condition variable created by PR_NewNakedCondVar. +*/ +NSPR_API(void) PRP_DestroyNakedCondVar(PRCondVar *cvar); + +/* +** Wait on a condition +** +** Wait on the condition variable 'cvar'. It is asserted that +** the lock protecting the condition 'lock' is held by the +** calling thread. If more time expires than that declared in +** 'timeout' the condition will be notified. Waits can be +** interrupted by another thread. +** +** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar. +*/ +NSPR_API(PRStatus) PRP_NakedWait( + PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout); + +/* +** Notify a thread waiting on a condition +** +** Notify the condition specified 'cvar'. +** +** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar. +*/ +NSPR_API(PRStatus) PRP_NakedNotify(PRCondVar *cvar); + +/* +** Notify all threads waiting on a condition +** +** Notify the condition specified 'cvar'. +** +** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar. +*/ +NSPR_API(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar); + +PR_END_EXTERN_C + +#endif /* PRPDCE_H */ diff -Nru nspr-4.9.5/nspr/pr/include/prprf.h nspr-4.10.7/nspr/pr/include/prprf.h --- nspr-4.9.5/nspr/pr/include/prprf.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prprf.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,122 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prprf_h___ +#define prprf_h___ + +/* +** API for PR printf like routines. Supports the following formats +** %d - decimal +** %u - unsigned decimal +** %x - unsigned hex +** %X - unsigned uppercase hex +** %o - unsigned octal +** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above +** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above +** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above +** %s - string +** %c - character +** %p - pointer (deals with machine dependent pointer size) +** %f - float +** %g - float +*/ +#include "prtypes.h" +#include "prio.h" +#include +#include + +PR_BEGIN_EXTERN_C + +/* +** sprintf into a fixed size buffer. Guarantees that a NUL is at the end +** of the buffer. Returns the length of the written output, NOT including +** the NUL, or (PRUint32)-1 if an error occurs. +*/ +NSPR_API(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...); + +/* +** sprintf into a PR_MALLOC'd buffer. Return a pointer to the malloc'd +** buffer on success, NULL on failure. Call "PR_smprintf_free" to release +** the memory returned. +*/ +NSPR_API(char*) PR_smprintf(const char *fmt, ...); + +/* +** Free the memory allocated, for the caller, by PR_smprintf +*/ +NSPR_API(void) PR_smprintf_free(char *mem); + +/* +** "append" sprintf into a PR_MALLOC'd buffer. "last" is the last value of +** the PR_MALLOC'd buffer. sprintf will append data to the end of last, +** growing it as necessary using realloc. If last is NULL, PR_sprintf_append +** will allocate the initial string. The return value is the new value of +** last for subsequent calls, or NULL if there is a malloc failure. +*/ +NSPR_API(char*) PR_sprintf_append(char *last, const char *fmt, ...); + +/* +** sprintf into a function. The function "f" is called with a string to +** place into the output. "arg" is an opaque pointer used by the stuff +** function to hold any state needed to do the storage of the output +** data. The return value is a count of the number of characters fed to +** the stuff function, or (PRUint32)-1 if an error occurs. +*/ +typedef PRIntn (*PRStuffFunc)(void *arg, const char *s, PRUint32 slen); + +NSPR_API(PRUint32) PR_sxprintf(PRStuffFunc f, void *arg, const char *fmt, ...); + +/* +** fprintf to a PRFileDesc +*/ +NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...); + +/* +** va_list forms of the above. +*/ +NSPR_API(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen, const char *fmt, va_list ap); +NSPR_API(char*) PR_vsmprintf(const char *fmt, va_list ap); +NSPR_API(char*) PR_vsprintf_append(char *last, const char *fmt, va_list ap); +NSPR_API(PRUint32) PR_vsxprintf(PRStuffFunc f, void *arg, const char *fmt, va_list ap); +NSPR_API(PRUint32) PR_vfprintf(struct PRFileDesc* fd, const char *fmt, va_list ap); + +/* +*************************************************************************** +** FUNCTION: PR_sscanf +** DESCRIPTION: +** PR_sscanf() scans the input character string, performs data +** conversions, and stores the converted values in the data objects +** pointed to by its arguments according to the format control +** string. +** +** PR_sscanf() behaves the same way as the sscanf() function in the +** Standard C Library (stdio.h), with the following exceptions: +** - PR_sscanf() handles the NSPR integer and floating point types, +** such as PRInt16, PRInt32, PRInt64, and PRFloat64, whereas +** sscanf() handles the standard C types like short, int, long, +** and double. +** - PR_sscanf() has no multibyte character support, while sscanf() +** does. +** INPUTS: +** const char *buf +** a character string holding the input to scan +** const char *fmt +** the format control string for the conversions +** ... +** variable number of arguments, each of them is a pointer to +** a data object in which the converted value will be stored +** OUTPUTS: none +** RETURNS: PRInt32 +** The number of values converted and stored. +** RESTRICTIONS: +** Multibyte characters in 'buf' or 'fmt' are not allowed. +*************************************************************************** +*/ + +NSPR_API(PRInt32) PR_sscanf(const char *buf, const char *fmt, ...); + +PR_END_EXTERN_C + +#endif /* prprf_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prproces.h nspr-4.10.7/nspr/pr/include/prproces.h --- nspr-4.9.5/nspr/pr/include/prproces.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prproces.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prproces_h___ +#define prproces_h___ + +#include "prtypes.h" +#include "prio.h" + +PR_BEGIN_EXTERN_C + +/************************************************************************/ +/*****************************PROCESS OPERATIONS*************************/ +/************************************************************************/ + +typedef struct PRProcess PRProcess; +typedef struct PRProcessAttr PRProcessAttr; + +NSPR_API(PRProcessAttr *) PR_NewProcessAttr(void); + +NSPR_API(void) PR_ResetProcessAttr(PRProcessAttr *attr); + +NSPR_API(void) PR_DestroyProcessAttr(PRProcessAttr *attr); + +NSPR_API(void) PR_ProcessAttrSetStdioRedirect( + PRProcessAttr *attr, + PRSpecialFD stdioFd, + PRFileDesc *redirectFd +); + +/* + * OBSOLETE -- use PR_ProcessAttrSetStdioRedirect instead. + */ +NSPR_API(void) PR_SetStdioRedirect( + PRProcessAttr *attr, + PRSpecialFD stdioFd, + PRFileDesc *redirectFd +); + +NSPR_API(PRStatus) PR_ProcessAttrSetCurrentDirectory( + PRProcessAttr *attr, + const char *dir +); + +NSPR_API(PRStatus) PR_ProcessAttrSetInheritableFD( + PRProcessAttr *attr, + PRFileDesc *fd, + const char *name +); + +/* +** Create a new process +** +** Create a new process executing the file specified as 'path' and with +** the supplied arguments and environment. +** +** This function may fail because of illegal access (permissions), +** invalid arguments or insufficient resources. +** +** A process may be created such that the creator can later synchronize its +** termination using PR_WaitProcess(). +*/ + +NSPR_API(PRProcess*) PR_CreateProcess( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr); + +NSPR_API(PRStatus) PR_CreateProcessDetached( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr); + +NSPR_API(PRStatus) PR_DetachProcess(PRProcess *process); + +NSPR_API(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode); + +NSPR_API(PRStatus) PR_KillProcess(PRProcess *process); + +PR_END_EXTERN_C + +#endif /* prproces_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prrng.h nspr-4.10.7/nspr/pr/include/prrng.h --- nspr-4.9.5/nspr/pr/include/prrng.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prrng.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/* +** prrng.h -- NSPR Random Number Generator +** +** +** lth. 29-Oct-1999. +*/ + +#ifndef prrng_h___ +#define prrng_h___ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* +** PR_GetRandomNoise() -- Get random noise from the host platform +** +** Description: +** PR_GetRandomNoise() provides, depending on platform, a random value. +** The length of the random value is dependent on platform and the +** platform's ability to provide a random value at that moment. +** +** The intent of PR_GetRandomNoise() is to provide a "seed" value for a +** another random number generator that may be suitable for +** cryptographic operations. This implies that the random value +** provided may not be, by itself, cryptographically secure. The value +** generated by PR_GetRandomNoise() is at best, extremely difficult to +** predict and is as non-deterministic as the underlying platfrom can +** provide. +** +** Inputs: +** buf -- pointer to a caller supplied buffer to contain the +** generated random number. buf must be at least as large as +** is specified in the 'size' argument. +** +** size -- the requested size of the generated random number +** +** Outputs: +** a random number provided in 'buf'. +** +** Returns: +** PRSize value equal to the size of the random number actually +** generated, or zero. The generated size may be less than the size +** requested. A return value of zero means that PR_GetRandomNoise() is +** not implemented on this platform, or there is no available noise +** available to be returned at the time of the call. +** +** Restrictions: +** Calls to PR_GetRandomNoise() may use a lot of CPU on some platforms. +** Some platforms may block for up to a few seconds while they +** accumulate some noise. Busy machines generate lots of noise, but +** care is advised when using PR_GetRandomNoise() frequently in your +** application. +** +** History: +** Parts of the model dependent implementation for PR_GetRandomNoise() +** were taken in whole or part from code previously in Netscape's NSS +** component. +** +*/ +NSPR_API(PRSize) PR_GetRandomNoise( + void *buf, + PRSize size +); + +PR_END_EXTERN_C + +#endif /* prrng_h___ */ +/* end prrng.h */ diff -Nru nspr-4.9.5/nspr/pr/include/prrwlock.h nspr-4.10.7/nspr/pr/include/prrwlock.h --- nspr-4.9.5/nspr/pr/include/prrwlock.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prrwlock.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prrwlock.h +** Description: API to basic reader-writer lock functions of NSPR. +** +**/ + +#ifndef prrwlock_h___ +#define prrwlock_h___ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* + * PRRWLock -- + * + * The reader writer lock, PRRWLock, is an opaque object to the clients + * of NSPR. All routines operate on a pointer to this opaque entity. + */ + + +typedef struct PRRWLock PRRWLock; + +#define PR_RWLOCK_RANK_NONE 0 + + +/*********************************************************************** +** FUNCTION: PR_NewRWLock +** DESCRIPTION: +** Returns a pointer to a newly created reader-writer lock object. +** INPUTS: Lock rank +** Lock name +** OUTPUTS: void +** RETURN: PRRWLock* +** If the lock cannot be created because of resource constraints, NULL +** is returned. +** +***********************************************************************/ +NSPR_API(PRRWLock*) PR_NewRWLock(PRUint32 lock_rank, const char *lock_name); + +/*********************************************************************** +** FUNCTION: PR_DestroyRWLock +** DESCRIPTION: +** Destroys a given RW lock object. +** INPUTS: PRRWLock *lock - Lock to be freed. +** OUTPUTS: void +** RETURN: None +***********************************************************************/ +NSPR_API(void) PR_DestroyRWLock(PRRWLock *lock); + +/*********************************************************************** +** FUNCTION: PR_RWLock_Rlock +** DESCRIPTION: +** Apply a read lock (non-exclusive) on a RWLock +** INPUTS: PRRWLock *lock - Lock to be read-locked. +** OUTPUTS: void +** RETURN: None +***********************************************************************/ +NSPR_API(void) PR_RWLock_Rlock(PRRWLock *lock); + +/*********************************************************************** +** FUNCTION: PR_RWLock_Wlock +** DESCRIPTION: +** Apply a write lock (exclusive) on a RWLock +** INPUTS: PRRWLock *lock - Lock to write-locked. +** OUTPUTS: void +** RETURN: None +***********************************************************************/ +NSPR_API(void) PR_RWLock_Wlock(PRRWLock *lock); + +/*********************************************************************** +** FUNCTION: PR_RWLock_Unlock +** DESCRIPTION: +** Release a RW lock. Unlocking an unlocked lock has undefined results. +** INPUTS: PRRWLock *lock - Lock to unlocked. +** OUTPUTS: void +** RETURN: void +***********************************************************************/ +NSPR_API(void) PR_RWLock_Unlock(PRRWLock *lock); + +PR_END_EXTERN_C + +#endif /* prrwlock_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prshma.h nspr-4.10.7/nspr/pr/include/prshma.h --- nspr-4.9.5/nspr/pr/include/prshma.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prshma.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** prshma.h -- NSPR Anonymous Shared Memory +** +** NSPR provides an anonymous shared memory based on NSPR's PRFileMap +** type. The anonymous file-mapped shared memory provides an inheritable +** shared memory, as in: the child process inherits the shared memory. +** Compare the file-mapped anonymous shared memory to to a named shared +** memory described in prshm.h. The intent is to provide a shared +** memory that is accessable only by parent and child processes. ... +** It's a security thing. +** +** Depending on the underlying platform, the file-mapped shared memory +** may be backed by a file. ... surprise! ... On some platforms, no +** real file backs the shared memory. On platforms where the shared +** memory is backed by a file, the file's name in the filesystem is +** visible to other processes for only the duration of the creation of +** the file, hopefully a very short time. This restricts processess +** that do not inherit the shared memory from opening the file and +** reading or writing its contents. Further, when all processes +** using an anonymous shared memory terminate, the backing file is +** deleted. ... If you are not paranoid, you're not paying attention. +** +** The file-mapped shared memory requires a protocol for the parent +** process and child process to share the memory. NSPR provides two +** protocols. Use one or the other; don't mix and match. +** +** In the first protocol, the job of passing the inheritable shared +** memory is done via helper-functions with PR_CreateProcess(). In the +** second protocol, the parent process is responsible for creating the +** child process; the parent and child are mutually responsible for +** passing a FileMap string. NSPR provides helper functions for +** extracting data from the PRFileMap object. ... See the examples +** below. +** +** Both sides should adhere strictly to the protocol for proper +** operation. The pseudo-code below shows the use of a file-mapped +** shared memory by a parent and child processes. In the examples, the +** server creates the file-mapped shared memory, the client attaches to +** it. +** +** First protocol. +** Server: +** +** fm = PR_OpenAnonFileMap(dirName, size, FilemapProt); +** addr = PR_MemMap(fm); +** attr = PR_NewProcessAttr(); +** PR_ProcessAttrSetInheritableFileMap( attr, fm, shmname ); +** PR_CreateProcess(Client); +** PR_DestroyProcessAttr(attr); +** ... yadda ... +** PR_MemUnmap( addr ); +** PR_CloseFileMap(fm); +** +** +** Client: +** ... started by server via PR_CreateProcess() +** fm = PR_GetInheritedFileMap( shmname ); +** addr = PR_MemMap(fm); +** ... yadda ... +** PR_MemUnmap(addr); +** PR_CloseFileMap(fm); +** +** +** Second Protocol: +** Server: +** +** fm = PR_OpenAnonFileMap(dirName, size, FilemapProt); +** fmstring = PR_ExportFileMapAsString( fm ); +** addr = PR_MemMap(fm); +** ... application specific technique to pass fmstring to child +** ... yadda ... Server uses his own magic to create child +** PR_MemUnmap( addr ); +** PR_CloseFileMap(fm); +** +** +** Client: +** ... started by server via his own magic +** ... application specific technique to find fmstring from parent +** fm = PR_ImportFileMapFromString( fmstring ) +** addr = PR_MemMap(fm); +** ... yadda ... +** PR_MemUnmap(addr); +** PR_CloseFileMap(fm); +** +** +** lth. 2-Jul-1999. +** +** Note: The second protocol was requested by NelsonB (7/1999); this is +** to accomodate servers which already create their own child processes +** using platform native methods. +** +*/ + +#ifndef prshma_h___ +#define prshma_h___ + +#include "prtypes.h" +#include "prio.h" +#include "prproces.h" + +PR_BEGIN_EXTERN_C + +/* +** PR_OpenAnonFileMap() -- Creates an anonymous file-mapped shared memory +** +** Description: +** PR_OpenAnonFileMap() creates an anonymous shared memory. If the +** shared memory already exists, a handle is returned to that shared +** memory object. +** +** On Unix platforms, PR_OpenAnonFileMap() uses 'dirName' as a +** directory name, without the trailing '/', to contain the anonymous +** file. A filename is generated for the name. +** +** On Windows platforms, dirName is ignored. +** +** Inputs: +** dirName -- A directory name to contain the anonymous file. +** size -- The size of the shared memory +** prot -- How the shared memory is mapped. See prio.h +** +** Outputs: +** PRFileMap * +** +** Returns: +** Pointer to PRFileMap or NULL on error. +** +*/ +NSPR_API( PRFileMap *) +PR_OpenAnonFileMap( + const char *dirName, + PRSize size, + PRFileMapProtect prot +); + +/* +** PR_ProcessAttrSetInheritableFileMap() -- Prepare FileMap for export +** to my children processes via PR_CreateProcess() +** +** Description: +** PR_ProcessAttrSetInheritableFileMap() connects the PRFileMap to +** PRProcessAttr with shmname. A subsequent call to PR_CreateProcess() +** makes the PRFileMap importable by the child process. +** +** Inputs: +** attr -- PRProcessAttr, used to pass data to PR_CreateProcess() +** fm -- PRFileMap structure to be passed to the child process +** shmname -- The name for the PRFileMap; used by child. +** +** Outputs: +** PRFileMap * +** +** Returns: +** PRStatus +** +*/ +NSPR_API(PRStatus) +PR_ProcessAttrSetInheritableFileMap( + PRProcessAttr *attr, + PRFileMap *fm, + const char *shmname +); + +/* +** PR_GetInheritedFileMap() -- Import a PRFileMap previously exported +** by my parent process via PR_CreateProcess() +** +** Description: +** PR_GetInheritedFileMap() retrieves a PRFileMap object exported from +** its parent process via PR_CreateProcess(). +** +** Inputs: +** shmname -- The name provided to PR_ProcessAttrSetInheritableFileMap() +** +** Outputs: +** PRFileMap * +** +** Returns: +** PRFileMap pointer or NULL. +** +*/ +NSPR_API( PRFileMap *) +PR_GetInheritedFileMap( + const char *shmname +); + +/* +** PR_ExportFileMapAsString() -- Creates a string identifying a PRFileMap +** +** Description: +** Creates an identifier, as a string, from a PRFileMap object +** previously created with PR_OpenAnonFileMap(). +** +** Inputs: +** fm -- PRFileMap pointer to be represented as a string. +** bufsize -- sizeof(buf) +** buf -- a buffer of length PR_FILEMAP_STRING_BUFSIZE +** +** Outputs: +** buf contains the stringized PRFileMap identifier +** +** Returns: +** PRStatus +** +*/ +NSPR_API( PRStatus ) +PR_ExportFileMapAsString( + PRFileMap *fm, + PRSize bufsize, + char *buf +); +#define PR_FILEMAP_STRING_BUFSIZE 128 + +/* +** PR_ImportFileMapFromString() -- Creates a PRFileMap from the identifying string +** +** Description: +** PR_ImportFileMapFromString() creates a PRFileMap object from a +** string previously created by PR_ExportFileMapAsString(). +** +** Inputs: +** fmstring -- string created by PR_ExportFileMapAsString() +** +** Returns: +** PRFileMap pointer or NULL. +** +*/ +NSPR_API( PRFileMap * ) +PR_ImportFileMapFromString( + const char *fmstring +); + +PR_END_EXTERN_C +#endif /* prshma_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prshm.h nspr-4.10.7/nspr/pr/include/prshm.h --- nspr-4.9.5/nspr/pr/include/prshm.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prshm.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,257 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** prshm.h -- NSPR Shared Memory +** +** NSPR Named Shared Memory API provides a cross-platform named +** shared-memory interface. NSPR Named Shared Memory is modeled on +** similar constructs in Unix and Windows operating systems. Shared +** memory allows multiple processes to access one or more common shared +** memory regions, using it as an inter-process communication channel. +** +** Notes on Platform Independence: +** NSPR Named Shared Memory is built on the native services offered +** by most platforms. The NSPR Named Shared Memory API tries to +** provide a least common denominator interface so that it works +** across all supported platforms. To ensure that it works everywhere, +** some platform considerations must be accomodated and the protocol +** for using NSPR Shared Memory API must be observed. +** +** Protocol: +** Multiple shared memories can be created using NSPR's Shared Memory +** feature. For each named shared memory, as defined by the name +** given in the PR_OpenSharedMemory() call, a protocol for using the +** shared memory API is required to ensure desired behavior. Failing +** to follow the protocol may yield unpredictable results. +** +** PR_OpenSharedMemory() will create the shared memory segment, if it +** does not already exist, or open a connection that the existing +** shared memory segment if it already exists. +** +** PR_AttachSharedMemory() should be called following +** PR_OpenSharedMemory() to map the memory segment to an address in +** the application's address space. +** +** PR_AttachSharedMemory() may be called to re-map a shared memory +** segment after detaching the same PRSharedMemory object. Be +** sure to detach it when done. +** +** PR_DetachSharedMemory() should be called to un-map the shared +** memory segment from the application's address space. +** +** PR_CloseSharedMemory() should be called when no further use of the +** PRSharedMemory object is required within a process. Following a +** call to PR_CloseSharedMemory() the PRSharedMemory object is +** invalid and cannot be reused. +** +** PR_DeleteSharedMemory() should be called before process +** termination. After calling PR_DeleteSharedMemory() any further use +** of the shared memory associated with the name may cause +** unpredictable results. +** +** Files: +** The name passed to PR_OpenSharedMemory() should be a valid filename +** for a unix platform. PR_OpenSharedMemory() creates file using the +** name passed in. Some platforms may mangle the name before creating +** the file and the shared memory. +** +** The unix implementation may use SysV IPC shared memory, Posix +** shared memory, or memory mapped files; the filename may used to +** define the namespace. On Windows, the name is significant, but +** there is no file associated with name. +** +** No assumptions about the persistence of data in the named file +** should be made. Depending on platform, the shared memory may be +** mapped onto system paging space and be discarded at process +** termination. +** +** All names provided to PR_OpenSharedMemory() should be valid +** filename syntax or name syntax for shared memory for the target +** platform. Referenced directories should have permissions +** appropriate for writing. +** +** Limits: +** Different platforms have limits on both the number and size of +** shared memory resources. The default system limits on some +** platforms may be smaller than your requirements. These limits may +** be adjusted on some platforms either via boot-time options or by +** setting the size of the system paging space to accomodate more +** and/or larger shared memory segment(s). +** +** Security: +** On unix platforms, depending on implementation, contents of the +** backing store for the shared memory can be exposed via the file +** system. Set permissions and or access controls at create and attach +** time to ensure you get the desired security. +** +** On windows platforms, no special security measures are provided. +** +** Example: +** The test case pr/tests/nameshm1.c provides an example of use as +** well as testing the operation of NSPR's Named Shared Memory. +** +** lth. 18-Aug-1999. +*/ + +#ifndef prshm_h___ +#define prshm_h___ + +#include "prtypes.h" +#include "prio.h" + +PR_BEGIN_EXTERN_C + +/* +** Declare opaque type PRSharedMemory. +*/ +typedef struct PRSharedMemory PRSharedMemory; + +/* +** FUNCTION: PR_OpenSharedMemory() +** +** DESCRIPTION: +** PR_OpenSharedMemory() creates a new shared-memory segment or +** associates a previously created memory segment with name. +** +** When parameter create is (PR_SHM_EXCL | PR_SHM_CREATE) and the +** shared memory already exists, the function returns NULL with the +** error set to PR_FILE_EXISTS_ERROR. +** +** When parameter create is PR_SHM_CREATE and the shared memory +** already exists, a handle to that memory segment is returned. If +** the segment does not exist, it is created and a pointer to the +** related PRSharedMemory structure is returned. +** +** When parameter create is 0, and the shared memory exists, a +** pointer to a PRSharedMemory is returned. If the shared memory does +** not exist, NULL is returned with the error set to +** PR_FILE_NOT_FOUND_ERROR. +** +** INPUTS: +** name -- the name the shared-memory segment is known as. +** size -- the size of the shared memory segment. +** flags -- Options for creating the shared memory +** mode -- Same as is passed to PR_Open() +** +** OUTPUTS: +** The shared memory is allocated. +** +** RETURNS: Pointer to opaque structure PRSharedMemory or NULL. +** NULL is returned on error. The reason for the error can be +** retrieved via PR_GetError() and PR_GetOSError(); +** +*/ +NSPR_API( PRSharedMemory * ) + PR_OpenSharedMemory( + const char *name, + PRSize size, + PRIntn flags, + PRIntn mode +); +/* Define values for PR_OpenShareMemory(...,create) */ +#define PR_SHM_CREATE 0x1 /* create if not exist */ +#define PR_SHM_EXCL 0x2 /* fail if already exists */ + +/* +** FUNCTION: PR_AttachSharedMemory() +** +** DESCRIPTION: +** PR_AttachSharedMemory() maps the shared-memory described by +** shm to the current process. +** +** INPUTS: +** shm -- The handle returned from PR_OpenSharedMemory(). +** flags -- options for mapping the shared memory. +** PR_SHM_READONLY causes the memory to be attached +** read-only. +** +** OUTPUTS: +** On success, the shared memory segment represented by shm is mapped +** into the process' address space. +** +** RETURNS: Address where shared memory is mapped, or NULL. +** NULL is returned on error. The reason for the error can be +** retrieved via PR_GetError() and PR_GetOSError(); +** +** +*/ +NSPR_API( void * ) + PR_AttachSharedMemory( + PRSharedMemory *shm, + PRIntn flags +); +/* Define values for PR_AttachSharedMemory(...,flags) */ +#define PR_SHM_READONLY 0x01 + +/* +** FUNCTION: PR_DetachSharedMemory() +** +** DESCRIPTION: +** PR_DetachSharedMemory() detaches the shared-memory described +** by shm. +** +** INPUTS: +** shm -- The handle returned from PR_OpenSharedMemory(). +** addr -- The address at which the memory was attached. +** +** OUTPUTS: +** The shared memory mapped to an address via a previous call to +** PR_AttachSharedMemory() is unmapped. +** +** RETURNS: PRStatus +** +*/ +NSPR_API( PRStatus ) + PR_DetachSharedMemory( + PRSharedMemory *shm, + void *addr +); + +/* +** FUNCTION: PR_CloseSharedMemory() +** +** DESCRIPTION: +** PR_CloseSharedMemory() closes the shared-memory described by +** shm. +** +** INPUTS: +** shm -- The handle returned from PR_OpenSharedMemory(). +** +** OUTPUTS: +** the shared memory represented by shm is closed +** +** RETURNS: PRStatus +** +*/ +NSPR_API( PRStatus ) + PR_CloseSharedMemory( + PRSharedMemory *shm +); + +/* +** FUNCTION: PR_DeleteSharedMemory() +** +** DESCRIPTION: +** The shared memory resource represented by name is released. +** +** INPUTS: +** name -- the name the shared-memory segment +** +** OUTPUTS: +** depending on platform, resources may be returned to the underlying +** operating system. +** +** RETURNS: PRStatus +** +*/ +NSPR_API( PRStatus ) + PR_DeleteSharedMemory( + const char *name +); + +PR_END_EXTERN_C + +#endif /* prshm_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prsystem.h nspr-4.10.7/nspr/pr/include/prsystem.h --- nspr-4.9.5/nspr/pr/include/prsystem.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prsystem.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prsystem_h___ +#define prsystem_h___ + +/* +** API to NSPR functions returning system info. +*/ +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* +** Get the host' directory separator. +** Pathnames are then assumed to be of the form: +** []*() +*/ + +NSPR_API(char) PR_GetDirectorySeparator(void); + +/* +** OBSOLETE -- the function name is misspelled. +** Use PR_GetDirectorySeparator instead. +*/ + +NSPR_API(char) PR_GetDirectorySepartor(void); + +/* +** Get the host' path separator. +** Paths are assumed to be of the form: +** []* +*/ + +NSPR_API(char) PR_GetPathSeparator(void); + +/* Types of information available via PR_GetSystemInfo(...) */ +typedef enum { + PR_SI_HOSTNAME, /* the hostname with the domain name (if any) + * removed */ + PR_SI_SYSNAME, + PR_SI_RELEASE, + PR_SI_ARCHITECTURE, + PR_SI_HOSTNAME_UNTRUNCATED /* the hostname exactly as configured + * on the system */ +} PRSysInfo; + + +/* +** If successful returns a null termintated string in 'buf' for +** the information indicated in 'cmd'. If unseccussful the reason for +** the failure can be retrieved from PR_GetError(). +** +** The buffer is allocated by the caller and should be at least +** SYS_INFO_BUFFER_LENGTH bytes in length. +*/ + +#define SYS_INFO_BUFFER_LENGTH 256 + +NSPR_API(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen); + +/* +** Return the number of bytes in a page +*/ +NSPR_API(PRInt32) PR_GetPageSize(void); + +/* +** Return log2 of the size of a page +*/ +NSPR_API(PRInt32) PR_GetPageShift(void); + +/* +** PR_GetNumberOfProcessors() -- returns the number of CPUs +** +** Description: +** PR_GetNumberOfProcessors() extracts the number of processors +** (CPUs available in an SMP system) and returns the number. +** +** Parameters: +** none +** +** Returns: +** The number of available processors or -1 on error +** +*/ +NSPR_API(PRInt32) PR_GetNumberOfProcessors( void ); + +/* +** PR_GetPhysicalMemorySize() -- returns the amount of system RAM +** +** Description: +** PR_GetPhysicalMemorySize() determines the amount of physical RAM +** in the system and returns the size in bytes. +** +** Parameters: +** none +** +** Returns: +** The amount of system RAM, or 0 on failure. +** +*/ +NSPR_API(PRUint64) PR_GetPhysicalMemorySize(void); + +PR_END_EXTERN_C + +#endif /* prsystem_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prthread.h nspr-4.10.7/nspr/pr/include/prthread.h --- nspr-4.9.5/nspr/pr/include/prthread.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prthread.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,272 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prthread_h___ +#define prthread_h___ + +/* +** API for NSPR threads. On some architectures (Mac OS Classic +** notably) pre-emptibility is not guaranteed. Hard priority scheduling +** is not guaranteed, so programming using priority based synchronization +** is a no-no. +** +** NSPR threads are scheduled based loosely on their client set priority. +** In general, a thread of a higher priority has a statistically better +** chance of running relative to threads of lower priority. However, +** NSPR uses multiple strategies to provide execution vehicles for thread +** abstraction of various host platforms. As it turns out, there is little +** NSPR can do to affect the scheduling attributes of "GLOBAL" threads. +** However, a semblance of GLOBAL threads is used to implement "LOCAL" +** threads. An arbitrary number of such LOCAL threads can be assigned to +** a single GLOBAL thread. +** +** For scheduling, NSPR will attempt to run the highest priority LOCAL +** thread associated with a given GLOBAL thread. It is further assumed +** that the host OS will apply some form of "fair" scheduling on the +** GLOBAL threads. +** +** Threads have a "system flag" which when set indicates the thread +** doesn't count for determining when the process should exit (the +** process exits when the last user thread exits). +** +** Threads also have a "scope flag" which controls whether the threads +** are scheduled in the local scope or scheduled by the OS globally. This +** indicates whether a thread is permanently bound to a native OS thread. +** An unbound thread competes for scheduling resources in the same process. +** +** Another flag is "state flag" which control whether the thread is joinable. +** It allows other threads to wait for the created thread to reach completion. +** +** Threads can have "per-thread-data" attached to them. Each thread has a +** per-thread error number and error string which are updated when NSPR +** operations fail. +*/ +#include "prtypes.h" +#include "prinrval.h" + +PR_BEGIN_EXTERN_C + +typedef struct PRThread PRThread; +typedef struct PRThreadStack PRThreadStack; + +typedef enum PRThreadType { + PR_USER_THREAD, + PR_SYSTEM_THREAD +} PRThreadType; + +typedef enum PRThreadScope { + PR_LOCAL_THREAD, + PR_GLOBAL_THREAD, + PR_GLOBAL_BOUND_THREAD +} PRThreadScope; + +typedef enum PRThreadState { + PR_JOINABLE_THREAD, + PR_UNJOINABLE_THREAD +} PRThreadState; + +typedef enum PRThreadPriority +{ + PR_PRIORITY_FIRST = 0, /* just a placeholder */ + PR_PRIORITY_LOW = 0, /* the lowest possible priority */ + PR_PRIORITY_NORMAL = 1, /* most common expected priority */ + PR_PRIORITY_HIGH = 2, /* slightly more aggressive scheduling */ + PR_PRIORITY_URGENT = 3, /* it does little good to have more than one */ + PR_PRIORITY_LAST = 3 /* this is just a placeholder */ +} PRThreadPriority; + +/* +** Create a new thread: +** "type" is the type of thread to create +** "start(arg)" will be invoked as the threads "main" +** "priority" will be created thread's priority +** "scope" will specify whether the thread is local or global +** "state" will specify whether the thread is joinable or not +** "stackSize" the size of the stack, in bytes. The value can be zero +** and then a machine specific stack size will be chosen. +** +** This can return NULL if some kind of error occurs, such as if memory is +** tight. +** +** If you want the thread to start up waiting for the creator to do +** something, enter a lock before creating the thread and then have the +** threads start routine enter and exit the same lock. When you are ready +** for the thread to run, exit the lock. +** +** If you want to detect the completion of the created thread, the thread +** should be created joinable. Then, use PR_JoinThread to synchrnoize the +** termination of another thread. +** +** When the start function returns the thread exits. If it is the last +** PR_USER_THREAD to exit then the process exits. +*/ +NSPR_API(PRThread*) PR_CreateThread(PRThreadType type, + void (PR_CALLBACK *start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize); + +/* +** Wait for thread termination: +** "thread" is the target thread +** +** This can return PR_FAILURE if no joinable thread could be found +** corresponding to the specified target thread. +** +** The calling thread is blocked until the target thread completes. +** Several threads cannot wait for the same thread to complete; one thread +** will operate successfully and others will terminate with an error PR_FAILURE. +** The calling thread will not be blocked if the target thread has already +** terminated. +*/ +NSPR_API(PRStatus) PR_JoinThread(PRThread *thread); + +/* +** Return the current thread object for the currently running code. +** Never returns NULL. +*/ +NSPR_API(PRThread*) PR_GetCurrentThread(void); +#ifndef NO_NSPR_10_SUPPORT +#define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */ +#endif /* NO_NSPR_10_SUPPORT */ + +/* +** Get the priority of "thread". +*/ +NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread); + +/* +** Change the priority of the "thread" to "priority". +** +** PR_SetThreadPriority works in a best-effort manner. On some platforms a +** special privilege, such as root access, is required to change thread +** priorities, especially to raise thread priorities. If the caller doesn't +** have enough privileges to change thread priorites, the function has no +** effect except causing a future PR_GetThreadPriority call to return +** |priority|. +*/ +NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority); + +/* +** Set the name of the current thread, which will be visible in a debugger +** and accessible via a call to PR_GetThreadName(). +*/ +NSPR_API(PRStatus) PR_SetCurrentThreadName(const char *name); + +/* +** Return the name of "thread", if set. Otherwise return NULL. +*/ +NSPR_API(const char *) PR_GetThreadName(const PRThread *thread); + +/* +** This routine returns a new index for per-thread-private data table. +** The index is visible to all threads within a process. This index can +** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines +** to save and retrieve data associated with the index for a thread. +** +** Each index is associationed with a destructor function ('dtor'). The function +** may be specified as NULL when the index is created. If it is not NULL, the +** function will be called when: +** - the thread exits and the private data for the associated index +** is not NULL, +** - new thread private data is set and the current private data is +** not NULL. +** +** The index independently maintains specific values for each binding thread. +** A thread can only get access to its own thread-specific-data. +** +** Upon a new index return the value associated with the index for all threads +** is NULL, and upon thread creation the value associated with all indices for +** that thread is NULL. +** +** Returns PR_FAILURE if the total number of indices will exceed the maximun +** allowed. +*/ +typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv); + +NSPR_API(PRStatus) PR_NewThreadPrivateIndex( + PRUintn *newIndex, PRThreadPrivateDTOR destructor); + +/* +** Define some per-thread-private data. +** "tpdIndex" is an index into the per-thread private data table +** "priv" is the per-thread-private data +** +** If the per-thread private data table has a previously registered +** destructor function and a non-NULL per-thread-private data value, +** the destructor function is invoked. +** +** This can return PR_FAILURE if the index is invalid. +*/ +NSPR_API(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv); + +/* +** Recover the per-thread-private data for the current thread. "tpdIndex" is +** the index into the per-thread private data table. +** +** The returned value may be NULL which is indistinguishable from an error +** condition. +** +** A thread can only get access to its own thread-specific-data. +*/ +NSPR_API(void*) PR_GetThreadPrivate(PRUintn tpdIndex); + +/* +** This routine sets the interrupt request for a target thread. The interrupt +** request remains in the thread's state until it is delivered exactly once +** or explicitly canceled. +** +** A thread that has been interrupted will fail all NSPR blocking operations +** that return a PRStatus (I/O, waiting on a condition, etc). +** +** PR_Interrupt may itself fail if the target thread is invalid. +*/ +NSPR_API(PRStatus) PR_Interrupt(PRThread *thread); + +/* +** Clear the interrupt request for the calling thread. If no such request +** is pending, this operation is a noop. +*/ +NSPR_API(void) PR_ClearInterrupt(void); + +/* +** Block the interrupt for the calling thread. +*/ +NSPR_API(void) PR_BlockInterrupt(void); + +/* +** Unblock the interrupt for the calling thread. +*/ +NSPR_API(void) PR_UnblockInterrupt(void); + +/* +** Make the current thread sleep until "ticks" time amount of time +** has expired. If "ticks" is PR_INTERVAL_NO_WAIT then the call is +** equivalent to calling PR_Yield. Calling PR_Sleep with an argument +** equivalent to PR_INTERVAL_NO_TIMEOUT is an error and will result +** in a PR_FAILURE error return. +*/ +NSPR_API(PRStatus) PR_Sleep(PRIntervalTime ticks); + +/* +** Get the scoping of this thread. +*/ +NSPR_API(PRThreadScope) PR_GetThreadScope(const PRThread *thread); + +/* +** Get the type of this thread. +*/ +NSPR_API(PRThreadType) PR_GetThreadType(const PRThread *thread); + +/* +** Get the join state of this thread. +*/ +NSPR_API(PRThreadState) PR_GetThreadState(const PRThread *thread); + +PR_END_EXTERN_C + +#endif /* prthread_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prtime.h nspr-4.10.7/nspr/pr/include/prtime.h --- nspr-4.9.5/nspr/pr/include/prtime.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prtime.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,262 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + *---------------------------------------------------------------------- + * + * prtime.h -- + * + * NSPR date and time functions + * + *----------------------------------------------------------------------- + */ + +#ifndef prtime_h___ +#define prtime_h___ + +#include "prlong.h" + +PR_BEGIN_EXTERN_C + +/**********************************************************************/ +/************************* TYPES AND CONSTANTS ************************/ +/**********************************************************************/ + +#define PR_MSEC_PER_SEC 1000L +#define PR_USEC_PER_SEC 1000000L +#define PR_NSEC_PER_SEC 1000000000L +#define PR_USEC_PER_MSEC 1000L +#define PR_NSEC_PER_MSEC 1000000L + +/* + * PRTime -- + * + * NSPR represents basic time as 64-bit signed integers relative + * to midnight (00:00:00), January 1, 1970 Greenwich Mean Time (GMT). + * (GMT is also known as Coordinated Universal Time, UTC.) + * The units of time are in microseconds. Negative times are allowed + * to represent times prior to the January 1970 epoch. Such values are + * intended to be exported to other systems or converted to human + * readable form. + * + * Notes on porting: PRTime corresponds to time_t in ANSI C. NSPR 1.0 + * simply uses PRInt64. + */ + +typedef PRInt64 PRTime; + +/* + * Time zone and daylight saving time corrections applied to GMT to + * obtain the local time of some geographic location + */ + +typedef struct PRTimeParameters { + PRInt32 tp_gmt_offset; /* the offset from GMT in seconds */ + PRInt32 tp_dst_offset; /* contribution of DST in seconds */ +} PRTimeParameters; + +/* + * PRExplodedTime -- + * + * Time broken down into human-readable components such as year, month, + * day, hour, minute, second, and microsecond. Time zone and daylight + * saving time corrections may be applied. If they are applied, the + * offsets from the GMT must be saved in the 'tm_params' field so that + * all the information is available to reconstruct GMT. + * + * Notes on porting: PRExplodedTime corrresponds to struct tm in + * ANSI C, with the following differences: + * - an additional field tm_usec; + * - replacing tm_isdst by tm_params; + * - the month field is spelled tm_month, not tm_mon; + * - we use absolute year, AD, not the year since 1900. + * The corresponding type in NSPR 1.0 is called PRTime. Below is + * a table of date/time type correspondence in the three APIs: + * API time since epoch time in components + * ANSI C time_t struct tm + * NSPR 1.0 PRInt64 PRTime + * NSPR 2.0 PRTime PRExplodedTime + */ + +typedef struct PRExplodedTime { + PRInt32 tm_usec; /* microseconds past tm_sec (0-99999) */ + PRInt32 tm_sec; /* seconds past tm_min (0-61, accomodating + up to two leap seconds) */ + PRInt32 tm_min; /* minutes past tm_hour (0-59) */ + PRInt32 tm_hour; /* hours past tm_day (0-23) */ + PRInt32 tm_mday; /* days past tm_mon (1-31, note that it + starts from 1) */ + PRInt32 tm_month; /* months past tm_year (0-11, Jan = 0) */ + PRInt16 tm_year; /* absolute year, AD (note that we do not + count from 1900) */ + + PRInt8 tm_wday; /* calculated day of the week + (0-6, Sun = 0) */ + PRInt16 tm_yday; /* calculated day of the year + (0-365, Jan 1 = 0) */ + + PRTimeParameters tm_params; /* time parameters used by conversion */ +} PRExplodedTime; + +/* + * PRTimeParamFn -- + * + * A function of PRTimeParamFn type returns the time zone and + * daylight saving time corrections for some geographic location, + * given the current time in GMT. The input argument gmt should + * point to a PRExplodedTime that is in GMT, i.e., whose + * tm_params contains all 0's. + * + * For any time zone other than GMT, the computation is intended to + * consist of two steps: + * - Figure out the time zone correction, tp_gmt_offset. This number + * usually depends on the geographic location only. But it may + * also depend on the current time. For example, all of China + * is one time zone right now. But this situation may change + * in the future. + * - Figure out the daylight saving time correction, tp_dst_offset. + * This number depends on both the geographic location and the + * current time. Most of the DST rules are expressed in local + * current time. If so, one should apply the time zone correction + * to GMT before applying the DST rules. + */ + +typedef PRTimeParameters (PR_CALLBACK *PRTimeParamFn)(const PRExplodedTime *gmt); + +/**********************************************************************/ +/****************************** FUNCTIONS *****************************/ +/**********************************************************************/ + +/* + * The PR_Now routine returns the current time relative to the + * epoch, midnight, January 1, 1970 UTC. The units of the returned + * value are microseconds since the epoch. + * + * The values returned are not guaranteed to advance in a linear fashion + * due to the application of time correction protocols which synchronize + * computer clocks to some external time source. Consequently it should + * not be depended on for interval timing. + * + * The implementation is machine dependent. + * Cf. time_t time(time_t *tp) in ANSI C. + */ +NSPR_API(PRTime) +PR_Now(void); + +/* + * Expand time binding it to time parameters provided by PRTimeParamFn. + * The calculation is envisoned to proceed in the following steps: + * - From given PRTime, calculate PRExplodedTime in GMT + * - Apply the given PRTimeParamFn to the GMT that we just calculated + * to obtain PRTimeParameters. + * - Add the PRTimeParameters offsets to GMT to get the local time + * as PRExplodedTime. + */ + +NSPR_API(void) PR_ExplodeTime( + PRTime usecs, PRTimeParamFn params, PRExplodedTime *exploded); + +/* Reverse operation of PR_ExplodeTime */ +NSPR_API(PRTime) +PR_ImplodeTime(const PRExplodedTime *exploded); + +/* + * Adjust exploded time to normalize field overflows after manipulation. + * Note that the following fields of PRExplodedTime should not be + * manipulated: + * - tm_month and tm_year: because the number of days in a month and + * number of days in a year are not constant, it is ambiguous to + * manipulate the month and year fields, although one may be tempted + * to. For example, what does "a month from January 31st" mean? + * - tm_wday and tm_yday: these fields are calculated by NSPR. Users + * should treat them as "read-only". + */ + +NSPR_API(void) PR_NormalizeTime( + PRExplodedTime *exploded, PRTimeParamFn params); + +/**********************************************************************/ +/*********************** TIME PARAMETER FUNCTIONS *********************/ +/**********************************************************************/ + +/* Time parameters that suit current host machine */ +NSPR_API(PRTimeParameters) PR_LocalTimeParameters(const PRExplodedTime *gmt); + +/* Time parameters that represent Greenwich Mean Time */ +NSPR_API(PRTimeParameters) PR_GMTParameters(const PRExplodedTime *gmt); + +/* + * Time parameters that represent the US Pacific Time Zone, with the + * current daylight saving time rules (for testing only) + */ +NSPR_API(PRTimeParameters) PR_USPacificTimeParameters(const PRExplodedTime *gmt); + +/* + * This parses a time/date string into a PRExplodedTime + * struct. It populates all fields but it can't split + * the offset from UTC into tp_gmt_offset and tp_dst_offset in + * most cases (exceptions: PST/PDT, MST/MDT, CST/CDT, EST/EDT, GMT/BST). + * In those cases tp_gmt_offset will be the sum of these two and + * tp_dst_offset will be 0. + * It returns PR_SUCCESS on success, and PR_FAILURE + * if the time/date string can't be parsed. + * + * Many formats are handled, including: + * + * 14 Apr 89 03:20:12 + * 14 Apr 89 03:20 GMT + * Fri, 17 Mar 89 4:01:33 + * Fri, 17 Mar 89 4:01 GMT + * Mon Jan 16 16:12 PDT 1989 + * Mon Jan 16 16:12 +0130 1989 + * 6 May 1992 16:41-JST (Wednesday) + * 22-AUG-1993 10:59:12.82 + * 22-AUG-1993 10:59pm + * 22-AUG-1993 12:59am + * 22-AUG-1993 12:59 PM + * Friday, August 04, 1995 3:54 PM + * 06/21/95 04:24:34 PM + * 20/06/95 21:07 + * 95-06-08 19:32:48 EDT + * + * If the input string doesn't contain a description of the timezone, + * we consult the `default_to_gmt' to decide whether the string should + * be interpreted relative to the local time zone (PR_FALSE) or GMT (PR_TRUE). + * The correct value for this argument depends on what standard specified + * the time string which you are parsing. + */ + +NSPR_API(PRStatus) PR_ParseTimeStringToExplodedTime ( + const char *string, + PRBool default_to_gmt, + PRExplodedTime *result); + +/* + * This uses PR_ParseTimeStringToExplodedTime to parse + * a time/date string and PR_ImplodeTime to transform it into + * a PRTime (microseconds after "1-Jan-1970 00:00:00 GMT"). + * It returns PR_SUCCESS on success, and PR_FAILURE + * if the time/date string can't be parsed. + */ + +NSPR_API(PRStatus) PR_ParseTimeString ( + const char *string, + PRBool default_to_gmt, + PRTime *result); + +/* Format a time value into a buffer. Same semantics as strftime() */ +NSPR_API(PRUint32) PR_FormatTime(char *buf, int buflen, const char *fmt, + const PRExplodedTime *tm); + +/* Format a time value into a buffer. Time is always in US English format, regardless + * of locale setting. + */ +NSPR_API(PRUint32) +PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize, + const char* format, const PRExplodedTime* tm ); + +PR_END_EXTERN_C + +#endif /* prtime_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prtpool.h nspr-4.10.7/nspr/pr/include/prtpool.h --- nspr-4.9.5/nspr/pr/include/prtpool.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prtpool.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prtpool_h___ +#define prtpool_h___ + +#include "prtypes.h" +#include "prthread.h" +#include "prio.h" +#include "prerror.h" + +/* + * NOTE: + * THIS API IS A PRELIMINARY VERSION IN NSPR 4.0 AND IS SUBJECT TO + * CHANGE + */ + +PR_BEGIN_EXTERN_C + +typedef struct PRJobIoDesc { + PRFileDesc *socket; + PRErrorCode error; + PRIntervalTime timeout; +} PRJobIoDesc; + +typedef struct PRThreadPool PRThreadPool; +typedef struct PRJob PRJob; +typedef void (PR_CALLBACK *PRJobFn) (void *arg); + +/* Create thread pool */ +NSPR_API(PRThreadPool *) +PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads, + PRUint32 stacksize); + +/* queue a job */ +NSPR_API(PRJob *) +PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable); + +/* queue a job, when a socket is readable */ +NSPR_API(PRJob *) +PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, + PRJobFn fn, void * arg, PRBool joinable); + +/* queue a job, when a socket is writeable */ +NSPR_API(PRJob *) +PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, + PRJobFn fn, void * arg, PRBool joinable); + +/* queue a job, when a socket has a pending connection */ +NSPR_API(PRJob *) +PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, + PRJobFn fn, void * arg, PRBool joinable); + +/* queue a job, when the socket connection to addr succeeds or fails */ +NSPR_API(PRJob *) +PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod, + const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable); + +/* queue a job, when a timer exipres */ +NSPR_API(PRJob *) +PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout, + PRJobFn fn, void * arg, PRBool joinable); +/* cancel a job */ +NSPR_API(PRStatus) +PR_CancelJob(PRJob *job); + +/* join a job */ +NSPR_API(PRStatus) +PR_JoinJob(PRJob *job); + +/* shutdown pool */ +NSPR_API(PRStatus) +PR_ShutdownThreadPool(PRThreadPool *tpool); + +/* join pool, wait for exit of all threads */ +NSPR_API(PRStatus) +PR_JoinThreadPool(PRThreadPool *tpool); + +PR_END_EXTERN_C + +#endif /* prtpool_h___ */ diff -Nru nspr-4.9.5/nspr/pr/include/prtrace.h nspr-4.10.7/nspr/pr/include/prtrace.h --- nspr-4.9.5/nspr/pr/include/prtrace.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prtrace.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,646 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prtrace_h___ +#define prtrace_h___ +/* +** prtrace.h -- NSPR's Trace Facility. +** +** The Trace Facility provides a means to trace application +** program events within a process. When implementing an +** application program an engineer may insert a "Trace" function +** call, passing arguments to be traced. The "Trace" function +** combines the user trace data with identifying data and +** writes this data in time ordered sequence into a circular +** in-memory buffer; when the buffer fills, it wraps. +** +** Functions are provided to set and/or re-configure the size of +** the trace buffer, control what events are recorded in the +** buffer, enable and disable tracing based on specific user +** supplied data and other control functions. Methods are provided +** to record the trace entries in the in-memory trace buffer to +** a file. +** +** Tracing may cause a performance degredation to the application +** depending on the number and placement of calls to the tracing +** facility. When tracing is compiled in and all tracing is +** disabled via the runtime controls, the overhead should be +** minimal. ... Famous last words, eh? +** +** When DEBUG is defined at compile time, the Trace Facility is +** compiled as part of NSPR and any application using NSPR's +** header files will have tracing compiled in. When DEBUG is not +** defined, the Trace Facility is not compiled into NSPR nor +** exported in its header files. If the Trace Facility is +** desired in a non-debug build, then FORCE_NSPR_TRACE may be +** defined at compile time for both the optimized build of NSPR +** and the application. NSPR and any application using NSPR's +** Trace Facility must be compiled with the same level of trace +** conditioning or unresolved references may be realized at link +** time. +** +** For any of the Trace Facility methods that requires a trace +** handle as an input argument, the caller must ensure that the +** trace handle argument is valid. An invalid trace handle +** argument may cause unpredictable results. +** +** Trace Facility methods are thread-safe and SMP safe. +** +** Users of the Trace Facility should use the defined macros to +** invoke trace methods, not the function calls directly. e.g. +** PR_TRACE( h1,0,1,2, ...); not PR_Trace(h1,0,1,2, ...); +** +** Application designers should be aware of the effects of +** debug and optimized build differences when using result of the +** Trace Facility macros in expressions. +** +** See Also: prcountr.h +** +** /lth. 08-Jun-1998. +*/ + +#include "prtypes.h" +#include "prthread.h" +#include "prtime.h" + +PR_BEGIN_EXTERN_C + +/* +** Opaque type for the trace handle +** ... Don't even think about looking in here. +** +*/ +typedef void * PRTraceHandle; + +/* +** PRTraceEntry -- A trace entry in the in-memory trace buffer +** looks like this. +** +*/ +typedef struct PRTraceEntry +{ + PRThread *thread; /* The thread creating the trace entry */ + PRTraceHandle handle; /* PRTraceHandle creating the trace entry */ + PRTime time; /* Value of PR_Now() at time of trace entry */ + PRUint32 userData[8]; /* user supplied trace data */ +} PRTraceEntry; + +/* +** PRTraceOption -- command operands to +** PR_[Set|Get]TraceOption(). See descriptive meanings there. +** +*/ +typedef enum PRTraceOption +{ + PRTraceBufSize, + PRTraceEnable, + PRTraceDisable, + PRTraceSuspend, + PRTraceResume, + PRTraceSuspendRecording, + PRTraceResumeRecording, + PRTraceLockHandles, + PRTraceUnLockHandles, + PRTraceStopRecording +} PRTraceOption; + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_DEFINE_TRACE() -- Define a PRTraceHandle +** +** DESCRIPTION: PR_DEFINE_TRACE() is used to define a trace +** handle. +** +*/ +#define PR_DEFINE_TRACE(name) PRTraceHandle name + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_INIT_TRACE_HANDLE() -- Set the value of a PRTraceHandle +** +** DESCRIPTION: +** PR_INIT_TRACE_HANDLE() sets the value of a PRTraceHandle +** to value. e.g. PR_INIT_TRACE_HANDLE( myHandle, NULL ); +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_INIT_TRACE_HANDLE(handle,value)\ + (handle) = (PRCounterHandle)(value) +#else +#define PR_INIT_TRACE_HANDLE(handle,value) +#endif + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_CreateTrace() -- Create a trace handle +** +** DESCRIPTION: +** PR_CreateTrace() creates a new trace handle. Tracing is +** enabled for this handle when it is created. The trace handle +** is intended for use in other Trace Facility calls. +** +** PR_CreateTrace() registers the QName, RName and description +** data so that this data can be retrieved later. +** +** INPUTS: +** qName: pointer to string. QName for this trace handle. +** +** rName: pointer to string. RName for this trace handle. +** +** description: pointer to string. Descriptive data about this +** trace handle. +** +** OUTPUTS: +** Creates the trace handle. +** Registers the QName and RName with the trace facility. +** +** RETURNS: +** PRTraceHandle +** +** RESTRICTIONS: +** qName is limited to 31 characters. +** rName is limited to 31 characters. +** description is limited to 255 characters. +** +*/ +#define PRTRACE_NAME_MAX 31 +#define PRTRACE_DESC_MAX 255 + +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_CREATE_TRACE(handle,qName,rName,description)\ + (handle) = PR_CreateTrace((qName),(rName),(description)) +#else +#define PR_CREATE_TRACE(handle,qName,rName,description) +#endif + +NSPR_API(PRTraceHandle) + PR_CreateTrace( + const char *qName, /* QName for this trace handle */ + const char *rName, /* RName for this trace handle */ + const char *description /* description for this trace handle */ +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_DestroyTrace() -- Destroy a trace handle +** +** DESCRIPTION: +** PR_DestroyTrace() removes the referenced trace handle and +** associated QName, RName and description data from the Trace +** Facility. +** +** INPUTS: handle. A PRTraceHandle +** +** OUTPUTS: +** The trace handle is unregistered. +** The QName, RName and description are removed. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_DESTROY_TRACE(handle)\ + PR_DestroyTrace((handle)) +#else +#define PR_DESTROY_TRACE(handle) +#endif + +NSPR_API(void) + PR_DestroyTrace( + PRTraceHandle handle /* Handle to be destroyed */ +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_Trace() -- Make a trace entry in the in-memory trace +** +** DESCRIPTION: +** PR_Trace() makes an entry in the in-memory trace buffer for +** the referenced trace handle. The next logically available +** PRTraceEntry is used; when the next trace entry would overflow +** the trace table, the table wraps. +** +** PR_Trace() for a specific trace handle may be disabled by +** calling PR_SetTraceOption() specifying PRTraceDisable for the +** trace handle to be disabled. +** +** INPUTS: +** handle: PRTraceHandle. The trace handle for this trace. +** +** userData[0..7]: unsigned 32bit integers. user supplied data +** that is copied into the PRTraceEntry +** +** OUTPUTS: +** A PRTraceEntry is (conditionally) formatted in the in-memory +** trace buffer. +** +** RETURNS: void. +** +** RESTRICTIONS: +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_TRACE(handle,ud0,ud1,ud2,ud3,ud4,ud5,ud6,ud7)\ + PR_Trace((handle),(ud0),(ud1),(ud2),(ud3),(ud4),(ud5),(ud6),(ud7)) +#else +#define PR_TRACE(handle,ud0,ud1,ud2,ud3,ud4,ud5,ud6,ud7) +#endif + +NSPR_API(void) + PR_Trace( + PRTraceHandle handle, /* use this trace handle */ + PRUint32 userData0, /* User supplied data word 0 */ + PRUint32 userData1, /* User supplied data word 1 */ + PRUint32 userData2, /* User supplied data word 2 */ + PRUint32 userData3, /* User supplied data word 3 */ + PRUint32 userData4, /* User supplied data word 4 */ + PRUint32 userData5, /* User supplied data word 5 */ + PRUint32 userData6, /* User supplied data word 6 */ + PRUint32 userData7 /* User supplied data word 7 */ +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_SetTraceOption() -- Control the Trace Facility +** +** DESCRIPTION: +** PR_SetTraceOption() controls the Trace Facility. Depending on +** command and value, attributes of the Trace Facility may be +** changed. +** +** INPUTS: +** command: An enumerated value in the set of PRTraceOption. +** value: pointer to the data to be set. Type of the data is +** dependent on command; for each value of command, the type +** and meaning of dereferenced value is shown. +** +** PRTraceBufSize: unsigned long: the size of the trace buffer, +** in bytes. +** +** PRTraceEnable: PRTraceHandle. The trace handle to be +** enabled. +** +** PRTraceDisable: PRTraceHandle. The trace handle to be +** disabled. +** +** PRTraceSuspend: void. value must be NULL. All tracing is +** suspended. +** +** PRTraceResume: void. value must be NULL. Tracing for all +** previously enabled, prior to a PRTraceSuspend, is resumed. +** +** PRTraceStopRecording: void. value must be NULL. If recording +** (see: ** PR_RecordTraceEntries()) is being done, +** PRTraceStopRecording causes PR_RecordTraceEntries() to return +** to its caller. If recording is not being done, this function +** has no effect. +** +** PRTraceSuspendRecording: void. Must be NULL. If recording is +** being done, PRTraceSuspendRecording causes further writes to +** the trace file to be suspended. Data in the in-memory +** trace buffer that would ordinarily be written to the +** trace file will not be written. Trace entries will continue +** to be entered in the in-memory buffer. If the Trace Facility +** recording is already in a suspended state, the call has no +** effect. +** +** PRTraceResumeRecording: void. value must be NULL. If +** recording for the Trace Facility has been previously been +** suspended, this causes recording to resume. Recording resumes +** with the next in-memory buffer segment that would be written +** if trace recording had not been suspended. If recording is +** not currently suspended, the call has no effect. +** +** PRTraceLockHandles: void. value must be NULL. Locks the +** trace handle lock. While the trace handle lock is held, +** calls to PR_CreateTrace() will block until the lock is +** released. +** +** PRTraceUnlockHandles: void. value must be NULL. Unlocks the +** trace handle lock. +** +** OUTPUTS: +** The operation of the Trace Facility may be changed. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_SET_TRACE_OPTION(command,value)\ + PR_SetTraceOption((command),(value)) +#else +#define PR_SET_TRACE_OPTION(command,value) +#endif + +NSPR_API(void) + PR_SetTraceOption( + PRTraceOption command, /* One of the enumerated values */ + void *value /* command value or NULL */ +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_GetTraceOption() -- Retrieve settings from the Trace Facility +** +** DESCRIPTION: +** PR_GetTraceOption() retrieves the current setting of the +** Trace Facility control depending on command. +** +** +** PRTraceBufSize: unsigned long: the size of the trace buffer, +** in bytes. +** +** +** INPUTS: +** command: one of the enumerated values in PRTraceOptions +** valid for PR_GetTraceOption(). +** +** OUTPUTS: +** dependent on command. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_GET_TRACE_OPTION(command,value)\ + PR_GetTraceOption((command),(value)) +#else +#define PR_GET_TRACE_OPTION(command,value) +#endif + +NSPR_API(void) + PR_GetTraceOption( + PRTraceOption command, /* One of the enumerated values */ + void *value /* command value or NULL */ +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_GetTraceHandleFromName() -- Retrieve an existing +** handle by name. +** +** DESCRIPTION: +** PR_GetTraceHandleFromName() retreives an existing tracehandle +** using the name specified by qName and rName. +** +** INPUTS: +** qName: pointer to string. QName for this trace handle. +** +** rName: pointer to string. RName for this trace handle. +** +** +** OUTPUTS: returned. +** +** RETURNS: +** PRTraceHandle associated with qName and rName or NULL when +** there is no match. +** +** RESTRICTIONS: +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_GET_TRACE_HANDLE_FROM_NAME(handle,qName,rName)\ + (handle) = PR_GetTraceHandleFromName((qName),(rName)) +#else +#define PR_GET_TRACE_HANDLE_FROM_NAME(handle,qName,rName) +#endif + +NSPR_API(PRTraceHandle) + PR_GetTraceHandleFromName( + const char *qName, /* QName search argument */ + const char *rName /* RName search argument */ +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_GetTraceNameFromHandle() -- Retreive trace name +** by bandle. +** +** DESCRIPTION: +** PR_GetTraceNameFromHandle() retreives the existing qName, +** rName, and description for the referenced trace handle. +** +** INPUTS: handle: PRTraceHandle. +** +** OUTPUTS: pointers to the Trace Facility's copy of qName, +** rName and description. ... Don't mess with these values. +** They're mine. +** +** RETURNS: void +** +** RESTRICTIONS: +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_GET_TRACE_NAME_FROM_HANDLE(handle,qName,rName,description)\ + PR_GetTraceNameFromHandle((handle),(qName),(rName),(description)) +#else +#define PR_GET_TRACE_NAME_FROM_HANDLE(handle,qName,rName,description) +#endif + +NSPR_API(void) + PR_GetTraceNameFromHandle( + PRTraceHandle handle, /* handle as search argument */ + const char **qName, /* pointer to associated QName */ + const char **rName, /* pointer to associated RName */ + const char **description /* pointer to associated description */ +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_FindNextTraceQname() -- Retrieive a QName handle +** iterator. +** +** DESCRIPTION: +** PR_FindNextTraceQname() retreives the first or next trace +** QName handle, depending on the value of handle, from the trace +** database. The PRTraceHandle returned can be used as an +** iterator to traverse the QName handles in the Trace database. +** +** INPUTS: +** handle: When NULL, PR_FindNextQname() returns the first QName +** handle. When a handle is a valid PRTraceHandle previously +** retreived using PR_FindNextQname() the next QName handle is +** retreived. +** +** OUTPUTS: returned. +** +** RETURNS: +** PRTraceHandle or NULL when there are no trace handles. +** +** RESTRICTIONS: +** Iterating thru the trace handles via FindFirst/FindNext +** should be done under protection of the trace handle lock. +** See: PR_SetTraceOption( PRLockTraceHandles ). +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_FIND_NEXT_TRACE_QNAME(next,handle)\ + (next) = PR_FindNextTraceQname((handle)) +#else +#define PR_FIND_NEXT_TRACE_QNAME(next,handle) +#endif + +NSPR_API(PRTraceHandle) + PR_FindNextTraceQname( + PRTraceHandle handle +); + + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_FindNextTraceRname() -- Retrieive an RName handle +** iterator. +** +** DESCRIPTION: +** PR_FindNextTraceRname() retreives the first or next trace +** RName handle, depending on the value of handle, from the trace +** database. The PRTraceHandle returned can be used as an +** iterator to traverse the RName handles in the Trace database. +** +** INPUTS: +** rhandle: When NULL, PR_FindNextRname() returns the first +** RName handle. When a handle is a valid PRTraceHandle +** previously retreived using PR_FindNextRname() the next RName +** handle is retreived. +** qhandle: A valid PRTraceHandle retruned from a previous call +** to PR_FIND_NEXT_TRACE_QNAME(). +** +** OUTPUTS: returned. +** +** RETURNS: +** PRTraceHandle or NULL when there are no trace handles. +** +** RESTRICTIONS: +** Iterating thru the trace handles via FindNext should be done +** under protection of the trace handle lock. See: ( +** PR_SetTraceOption( PRLockTraceHandles ). +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_FIND_NEXT_TRACE_RNAME(next,rhandle,qhandle)\ + (next) = PR_FindNextTraceRname((rhandle),(qhandle)) +#else +#define PR_FIND_NEXT_TRACE_RNAME(next,rhandle,qhandle) +#endif + +NSPR_API(PRTraceHandle) + PR_FindNextTraceRname( + PRTraceHandle rhandle, + PRTraceHandle qhandle +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_RecordTraceEntries() -- Write trace entries to external media +** +** DESCRIPTION: +** PR_RecordTraceEntries() causes entries in the in-memory trace +** buffer to be written to external media. +** +** When PR_RecordTraceEntries() is called from an application +** thread, the function appears to block until another thread +** calls PR_SetTraceOption() with the PRTraceStopRecording +** option. This suggests that PR_RecordTraceEntries() should be +** called from a user supplied thread whose only job is to +** record trace entries. +** +** The environment variable NSPR_TRACE_LOG controls the operation +** of this function. When NSPR_TRACE_LOG is not defined in the +** environment, no recording of trace entries occurs. When +** NSPR_TRACE_LOG is defined, the value of its definition must be +** the filename of the file to receive the trace entry buffer. +** +** PR_RecordTraceEntries() attempts to record the in-memory +** buffer to a file, subject to the setting of the environment +** variable NSPR_TRACE_LOG. It is possible because of system +** load, the thread priority of the recording thread, number of +** active trace records being written over time, and other +** variables that some trace records can be lost. ... In other +** words: don't bet the farm on getting everything. +** +** INPUTS: none +** +** OUTPUTS: none +** +** RETURNS: PR_STATUS +** PR_SUCCESS no errors were found. +** PR_FAILURE errors were found. +** +** RESTRICTIONS: +** Only one thread can call PR_RecordTraceEntries() within a +** process. +** +** On error, PR_RecordTraceEntries() may return prematurely. +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_RECORD_TRACE_ENTRIES()\ + PR_RecordTraceEntries() +#else +#define PR_RECORD_TRACE_ENTRIES() +#endif + +NSPR_API(void) + PR_RecordTraceEntries( + void +); + +/* ----------------------------------------------------------------------- +** FUNCTION: PR_GetTraceEntries() -- Retreive trace entries from +** the Trace Facility +** +** DESCRIPTION: +** PR_GetTraceEntries() retreives trace entries from the Trace +** Facility. Up to count trace entries are copied from the Trace +** Facility into buffer. Only those trace entries that have not +** been copied via a previous call to PR_GetTraceEntries() are +** copied. The actual number copied is placed in the PRInt32 +** variable pointed to by found. +** +** If more than count trace entries have entered the Trace +** Facility since the last call to PR_GetTraceEntries() +** a lost data condition is returned. In this case, the most +** recent count trace entries are copied into buffer and found is +** set to count. +** +** INPUTS: +** count. The number of trace entries to be copied into buffer. +** +** +** OUTPUTS: +** buffer. An array of PRTraceEntries. The buffer is supplied +** by the caller. +** +** found: 32bit signed integer. The number of PRTraceEntries +** actually copied. found is always less than or equal to count. +** +** RETURNS: +** zero when there is no lost data. +** non-zero when some PRTraceEntries have been lost. +** +** RESTRICTIONS: +** This is a real performance pig. The copy out operation is bad +** enough, but depending on then frequency of calls to the +** function, serious performance impact to the operating +** application may be realized. ... YMMV. +** +*/ +#if defined (DEBUG) || defined (FORCE_NSPR_TRACE) +#define PR_GET_TRACE_ENTRIES(buffer,count,found)\ + PR_GetTraceEntries((buffer),(count),(found)) +#else +#define PR_GET_TRACE_ENTRIES(buffer,count,found) +#endif + +NSPR_API(PRIntn) + PR_GetTraceEntries( + PRTraceEntry *buffer, /* where to write output */ + PRInt32 count, /* number to get */ + PRInt32 *found /* number you got */ +); + +PR_END_EXTERN_C + +#endif /* prtrace_h___ */ + diff -Nru nspr-4.9.5/nspr/pr/include/prtypes.h nspr-4.10.7/nspr/pr/include/prtypes.h --- nspr-4.9.5/nspr/pr/include/prtypes.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prtypes.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,565 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prtypes.h +** Description: Definitions of NSPR's basic types +** +** Prototypes and macros used to make up for deficiencies that we have found +** in ANSI environments. +** +** Since we do not wrap and all the other standard headers, authors +** of portable code will not know in general that they need these definitions. +** Instead of requiring these authors to find the dependent uses in their code +** and take the following steps only in those C files, we take steps once here +** for all C files. +**/ + +#ifndef prtypes_h___ +#define prtypes_h___ + +#ifdef MDCPUCFG +#include MDCPUCFG +#else +#include "prcpucfg.h" +#endif + +#include + +/*********************************************************************** +** MACROS: PR_EXTERN +** PR_IMPLEMENT +** DESCRIPTION: +** These are only for externally visible routines and globals. For +** internal routines, just use "extern" for type checking and that +** will not export internal cross-file or forward-declared symbols. +** Define a macro for declaring procedures return types. We use this to +** deal with windoze specific type hackery for DLL definitions. Use +** PR_EXTERN when the prototype for the method is declared. Use +** PR_IMPLEMENT for the implementation of the method. +** +** Example: +** in dowhim.h +** PR_EXTERN( void ) DoWhatIMean( void ); +** in dowhim.c +** PR_IMPLEMENT( void ) DoWhatIMean( void ) { return; } +** +** +***********************************************************************/ +#if defined(WIN32) + +#define PR_EXPORT(__type) extern __declspec(dllexport) __type +#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPORT(__type) __declspec(dllimport) __type +#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type + +#define PR_EXTERN(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT(__type) __declspec(dllexport) __type +#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type + +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#elif defined(XP_BEOS) + +#define PR_EXPORT(__type) extern __declspec(dllexport) __type +#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPORT(__type) extern __declspec(dllexport) __type +#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type + +#define PR_EXTERN(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT(__type) __declspec(dllexport) __type +#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type + +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#elif defined(XP_OS2) && defined(__declspec) + +#define PR_EXPORT(__type) extern __declspec(dllexport) __type +#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPORT(__type) extern __declspec(dllimport) __type +#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type + +#define PR_EXTERN(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT(__type) __declspec(dllexport) __type +#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type +#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type + +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#elif defined(SYMBIAN) + +#define PR_EXPORT(__type) extern __declspec(dllexport) __type +#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type +#ifdef __WINS__ +#define PR_IMPORT(__type) extern __declspec(dllexport) __type +#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type +#else +#define PR_IMPORT(__type) extern __declspec(dllimport) __type +#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type +#endif + +#define PR_EXTERN(__type) extern __type +#define PR_IMPLEMENT(__type) __type +#define PR_EXTERN_DATA(__type) extern __type +#define PR_IMPLEMENT_DATA(__type) __type + +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#else /* Unix */ + +/* GCC 3.3 and later support the visibility attribute. */ +#if (__GNUC__ >= 4) || \ + (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) +#define PR_VISIBILITY_DEFAULT __attribute__((visibility("default"))) +#else +#define PR_VISIBILITY_DEFAULT +#endif + +#define PR_EXPORT(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_EXPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_IMPORT(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_IMPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type + +#define PR_EXTERN(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_IMPLEMENT(__type) PR_VISIBILITY_DEFAULT __type +#define PR_EXTERN_DATA(__type) extern PR_VISIBILITY_DEFAULT __type +#define PR_IMPLEMENT_DATA(__type) PR_VISIBILITY_DEFAULT __type +#define PR_CALLBACK +#define PR_CALLBACK_DECL +#define PR_STATIC_CALLBACK(__x) static __x + +#endif + +#if defined(_NSPR_BUILD_) +#define NSPR_API(__type) PR_EXPORT(__type) +#define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type) +#else +#define NSPR_API(__type) PR_IMPORT(__type) +#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type) +#endif + +/*********************************************************************** +** MACROS: PR_BEGIN_MACRO +** PR_END_MACRO +** DESCRIPTION: +** Macro body brackets so that macros with compound statement definitions +** behave syntactically more like functions when called. +***********************************************************************/ +#define PR_BEGIN_MACRO do { +#define PR_END_MACRO } while (0) + +/*********************************************************************** +** MACROS: PR_BEGIN_EXTERN_C +** PR_END_EXTERN_C +** DESCRIPTION: +** Macro shorthands for conditional C++ extern block delimiters. +***********************************************************************/ +#ifdef __cplusplus +#define PR_BEGIN_EXTERN_C extern "C" { +#define PR_END_EXTERN_C } +#else +#define PR_BEGIN_EXTERN_C +#define PR_END_EXTERN_C +#endif + +/*********************************************************************** +** MACROS: PR_BIT +** PR_BITMASK +** DESCRIPTION: +** Bit masking macros. XXX n must be <= 31 to be portable +***********************************************************************/ +#define PR_BIT(n) ((PRUint32)1 << (n)) +#define PR_BITMASK(n) (PR_BIT(n) - 1) + +/*********************************************************************** +** MACROS: PR_ROUNDUP +** PR_MIN +** PR_MAX +** PR_ABS +** DESCRIPTION: +** Commonly used macros for operations on compatible types. +***********************************************************************/ +#define PR_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y)) +#define PR_MIN(x,y) ((x)<(y)?(x):(y)) +#define PR_MAX(x,y) ((x)>(y)?(x):(y)) +#define PR_ABS(x) ((x)<0?-(x):(x)) + +/*********************************************************************** +** MACROS: PR_ARRAY_SIZE +** DESCRIPTION: +** The number of elements in an array. +***********************************************************************/ +#define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) + +PR_BEGIN_EXTERN_C + +/* +** Starting in NSPR 4.9.5, NSPR's exact-width integer types should match +** the exact-width integer types defined in . This allows sloppy +** code to use PRInt{N} and int{N}_t interchangeably. +** +** The 8-bit and 16-bit integer types can only be defined using char and +** short. All platforms define the 32-bit integer types using int. So only +** the 64-bit integer types could be defined differently. +** +** NSPR's original strategy was to use the "shortest" 64-bit integer type: +** if long is 64-bit, then prefer it over long long. This strategy is also +** used by Linux/glibc, FreeBSD, and NetBSD. +** +** Other platforms use a different strategy: simply define the 64-bit +** integer types using long long. We define the PR_ALTERNATE_INT64_TYPEDEF +** macro on these platforms. Note that PR_ALTERNATE_INT64_TYPEDEF is for +** internal use by NSPR headers only. Do not define or test this macro in +** your code. +** +** NOTE: NSPR can't use because C99 requires C++ code to define +** __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS to make all the macros +** defined in available. This strange requirement is gone in +** C11. When most platforms ignore this C99 requirement, NSPR will be able +** to use . A patch to do that is in NSPR bug 634793. +*/ + +#if defined(__APPLE__) || defined(__ANDROID__) || defined(__OpenBSD__) +#define PR_ALTERNATE_INT64_TYPEDEF +#endif + +/************************************************************************ +** TYPES: PRUint8 +** PRInt8 +** DESCRIPTION: +** The int8 types are known to be 8 bits each. There is no type that +** is equivalent to a plain "char". +************************************************************************/ +#if PR_BYTES_PER_BYTE == 1 +typedef unsigned char PRUint8; +/* +** Some cfront-based C++ compilers do not like 'signed char' and +** issue the warning message: +** warning: "signed" not implemented (ignored) +** For these compilers, we have to define PRInt8 as plain 'char'. +** Make sure that plain 'char' is indeed signed under these compilers. +*/ +#if (defined(HPUX) && defined(__cplusplus) \ + && !defined(__GNUC__) && __cplusplus < 199707L) \ + || (defined(SCO) && defined(__cplusplus) \ + && !defined(__GNUC__) && __cplusplus == 1L) +typedef char PRInt8; +#else +typedef signed char PRInt8; +#endif +#else +#error No suitable type for PRInt8/PRUint8 +#endif + +/************************************************************************ + * MACROS: PR_INT8_MAX + * PR_INT8_MIN + * PR_UINT8_MAX + * DESCRIPTION: + * The maximum and minimum values of a PRInt8 or PRUint8. +************************************************************************/ + +#define PR_INT8_MAX 127 +#define PR_INT8_MIN (-128) +#define PR_UINT8_MAX 255U + +/************************************************************************ +** TYPES: PRUint16 +** PRInt16 +** DESCRIPTION: +** The int16 types are known to be 16 bits each. +************************************************************************/ +#if PR_BYTES_PER_SHORT == 2 +typedef unsigned short PRUint16; +typedef short PRInt16; +#else +#error No suitable type for PRInt16/PRUint16 +#endif + +/************************************************************************ + * MACROS: PR_INT16_MAX + * PR_INT16_MIN + * PR_UINT16_MAX + * DESCRIPTION: + * The maximum and minimum values of a PRInt16 or PRUint16. +************************************************************************/ + +#define PR_INT16_MAX 32767 +#define PR_INT16_MIN (-32768) +#define PR_UINT16_MAX 65535U + +/************************************************************************ +** TYPES: PRUint32 +** PRInt32 +** DESCRIPTION: +** The int32 types are known to be 32 bits each. +************************************************************************/ +#if PR_BYTES_PER_INT == 4 +typedef unsigned int PRUint32; +typedef int PRInt32; +#define PR_INT32(x) x +#define PR_UINT32(x) x ## U +#elif PR_BYTES_PER_LONG == 4 +typedef unsigned long PRUint32; +typedef long PRInt32; +#define PR_INT32(x) x ## L +#define PR_UINT32(x) x ## UL +#else +#error No suitable type for PRInt32/PRUint32 +#endif + +/************************************************************************ + * MACROS: PR_INT32_MAX + * PR_INT32_MIN + * PR_UINT32_MAX + * DESCRIPTION: + * The maximum and minimum values of a PRInt32 or PRUint32. +************************************************************************/ + +#define PR_INT32_MAX PR_INT32(2147483647) +#define PR_INT32_MIN (-PR_INT32_MAX - 1) +#define PR_UINT32_MAX PR_UINT32(4294967295) + +/************************************************************************ +** TYPES: PRUint64 +** PRInt64 +** DESCRIPTION: +** The int64 types are known to be 64 bits each. Care must be used when +** declaring variables of type PRUint64 or PRInt64. Different hardware +** architectures and even different compilers have varying support for +** 64 bit values. The only guaranteed portability requires the use of +** the LL_ macros (see prlong.h). +** +** MACROS: PR_INT64 +** PR_UINT64 +** DESCRIPTION: +** The PR_INT64 and PR_UINT64 macros provide a portable way for +** specifying 64-bit integer constants. They can only be used if +** PRInt64 and PRUint64 are defined as compiler-supported 64-bit +** integer types (i.e., if HAVE_LONG_LONG is defined, which is true +** for all the supported compilers topday). If PRInt64 and PRUint64 +** are defined as structs, the LL_INIT macro defined in prlong.h has +** to be used. +** +** MACROS: PR_INT64_MAX +** PR_INT64_MIN +** PR_UINT64_MAX +** DESCRIPTION: +** The maximum and minimum values of a PRInt64 or PRUint64. +************************************************************************/ +#ifdef HAVE_LONG_LONG +/* Keep this in sync with prlong.h. */ +#if PR_BYTES_PER_LONG == 8 && !defined(PR_ALTERNATE_INT64_TYPEDEF) +typedef long PRInt64; +typedef unsigned long PRUint64; +#define PR_INT64(x) x ## L +#define PR_UINT64(x) x ## UL +#elif defined(WIN32) && !defined(__GNUC__) +typedef __int64 PRInt64; +typedef unsigned __int64 PRUint64; +#define PR_INT64(x) x ## i64 +#define PR_UINT64(x) x ## ui64 +#else +typedef long long PRInt64; +typedef unsigned long long PRUint64; +#define PR_INT64(x) x ## LL +#define PR_UINT64(x) x ## ULL +#endif /* PR_BYTES_PER_LONG == 8 */ + +#define PR_INT64_MAX PR_INT64(0x7fffffffffffffff) +#define PR_INT64_MIN (-PR_INT64_MAX - 1) +#define PR_UINT64_MAX PR_UINT64(-1) +#else /* !HAVE_LONG_LONG */ +typedef struct { +#ifdef IS_LITTLE_ENDIAN + PRUint32 lo, hi; +#else + PRUint32 hi, lo; +#endif +} PRInt64; +typedef PRInt64 PRUint64; + +#define PR_INT64_MAX (PRInt64){0x7fffffff, 0xffffffff} +#define PR_INT64_MIN (PRInt64){0xffffffff, 0xffffffff} +#define PR_UINT64_MAX (PRUint64){0xffffffff, 0xffffffff} + +#endif /* !HAVE_LONG_LONG */ + +/************************************************************************ +** TYPES: PRUintn +** PRIntn +** DESCRIPTION: +** The PRIntn types are most appropriate for automatic variables. They are +** guaranteed to be at least 16 bits, though various architectures may +** define them to be wider (e.g., 32 or even 64 bits). These types are +** never valid for fields of a structure. +************************************************************************/ +#if PR_BYTES_PER_INT >= 2 +typedef int PRIntn; +typedef unsigned int PRUintn; +#else +#error 'sizeof(int)' not sufficient for platform use +#endif + +/************************************************************************ +** TYPES: PRFloat64 +** DESCRIPTION: +** NSPR's floating point type is always 64 bits. +************************************************************************/ +typedef double PRFloat64; + +/************************************************************************ +** TYPES: PRSize +** DESCRIPTION: +** A type for representing the size of objects. +************************************************************************/ +typedef size_t PRSize; + + +/************************************************************************ +** TYPES: PROffset32, PROffset64 +** DESCRIPTION: +** A type for representing byte offsets from some location. +************************************************************************/ +typedef PRInt32 PROffset32; +typedef PRInt64 PROffset64; + +/************************************************************************ +** TYPES: PRPtrDiff +** DESCRIPTION: +** A type for pointer difference. Variables of this type are suitable +** for storing a pointer or pointer subtraction. +************************************************************************/ +typedef ptrdiff_t PRPtrdiff; + +/************************************************************************ +** TYPES: PRUptrdiff +** DESCRIPTION: +** A type for pointer difference. Variables of this type are suitable +** for storing a pointer or pointer sutraction. +************************************************************************/ +#ifdef _WIN64 +typedef PRUint64 PRUptrdiff; +#else +typedef unsigned long PRUptrdiff; +#endif + +/************************************************************************ +** TYPES: PRBool +** DESCRIPTION: +** Use PRBool for variables and parameter types. Use PR_FALSE and PR_TRUE +** for clarity of target type in assignments and actual arguments. Use +** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans +** just as you would C int-valued conditions. +************************************************************************/ +typedef PRIntn PRBool; +#define PR_TRUE 1 +#define PR_FALSE 0 + +/************************************************************************ +** TYPES: PRPackedBool +** DESCRIPTION: +** Use PRPackedBool within structs where bitfields are not desirable +** but minimum and consistant overhead matters. +************************************************************************/ +typedef PRUint8 PRPackedBool; + +/* +** Status code used by some routines that have a single point of failure or +** special status return. +*/ +typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus; + +#ifndef __PRUNICHAR__ +#define __PRUNICHAR__ +#ifdef WIN32 +typedef wchar_t PRUnichar; +#else +typedef PRUint16 PRUnichar; +#endif +#endif + +/* +** WARNING: The undocumented data types PRWord and PRUword are +** only used in the garbage collection and arena code. Do not +** use PRWord and PRUword in new code. +** +** A PRWord is an integer that is the same size as a void*. +** It implements the notion of a "word" in the Java Virtual +** Machine. (See Sec. 3.4 "Words", The Java Virtual Machine +** Specification, Addison-Wesley, September 1996. +** http://java.sun.com/docs/books/vmspec/index.html.) +*/ +#ifdef _WIN64 +typedef PRInt64 PRWord; +typedef PRUint64 PRUword; +#else +typedef long PRWord; +typedef unsigned long PRUword; +#endif + +#if defined(NO_NSPR_10_SUPPORT) +#else +/********* ???????????????? FIX ME ??????????????????????????? *****/ +/********************** Some old definitions until pr=>ds transition is done ***/ +/********************** Also, we are still using NSPR 1.0. GC ******************/ +/* +** Fundamental NSPR macros, used nearly everywhere. +*/ + +#define PR_PUBLIC_API PR_IMPLEMENT + +/* +** Macro body brackets so that macros with compound statement definitions +** behave syntactically more like functions when called. +*/ +#define NSPR_BEGIN_MACRO do { +#define NSPR_END_MACRO } while (0) + +/* +** Macro shorthands for conditional C++ extern block delimiters. +*/ +#ifdef NSPR_BEGIN_EXTERN_C +#undef NSPR_BEGIN_EXTERN_C +#endif +#ifdef NSPR_END_EXTERN_C +#undef NSPR_END_EXTERN_C +#endif + +#ifdef __cplusplus +#define NSPR_BEGIN_EXTERN_C extern "C" { +#define NSPR_END_EXTERN_C } +#else +#define NSPR_BEGIN_EXTERN_C +#define NSPR_END_EXTERN_C +#endif + +#include "obsolete/protypes.h" + +/********* ????????????? End Fix me ?????????????????????????????? *****/ +#endif /* NO_NSPR_10_SUPPORT */ + +/* +** Compile-time assert. "condition" must be a constant expression. +** The macro can be used only in places where an "extern" declaration is +** allowed. +*/ +#define PR_STATIC_ASSERT(condition) \ + extern void pr_static_assert(int arg[(condition) ? 1 : -1]) + +PR_END_EXTERN_C + +#endif /* prtypes_h___ */ + diff -Nru nspr-4.9.5/nspr/pr/include/prvrsion.h nspr-4.10.7/nspr/pr/include/prvrsion.h --- nspr-4.9.5/nspr/pr/include/prvrsion.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prvrsion.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/* author: jstewart */ + +#if defined(_PRVERSION_H) +#else +#define _PRVERSION_H + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +/* All components participating in the PR version protocol must expose + * a structure and a function. The structure is defined below and named + * according to the naming conventions outlined further below. The function + * is called libVersionPoint and returns a pointer to this structure. + */ + +/* on NT, always pack the structure the same. */ +#ifdef _WIN32 +#pragma pack(push, 8) +#endif + +typedef struct { + /* + * The first field defines which version of this structure is in use. + * At this time, only version 2 is specified. If this value is not + * 2, you must read no further into the structure. + */ + PRInt32 version; + + /* for Version 2, this is the body format. */ + PRInt64 buildTime; /* 64 bits - usecs since midnight, 1/1/1970 */ + char * buildTimeString;/* a human readable version of the time */ + + PRUint8 vMajor; /* Major version of this component */ + PRUint8 vMinor; /* Minor version of this component */ + PRUint8 vPatch; /* Patch level of this component */ + + PRBool beta; /* true if this is a beta component */ + PRBool debug; /* true if this is a debug component */ + PRBool special; /* true if this component is a special build */ + + char * filename; /* The original filename */ + char * description; /* description of this component */ + char * security; /* level of security in this component */ + char * copyright; /* The copyright for this file */ + char * comment; /* free form field for misc usage */ + char * specialString; /* the special variant for this build */ +} PRVersionDescription; + +/* on NT, restore the previous packing */ +#ifdef _WIN32 +#pragma pack(pop) +#endif + +/* + * All components must define an entrypoint named libVersionPoint which + * is of type versionEntryPointType. + * + * For example, for a library named libfoo, we would have: + * + * PRVersionDescription prVersionDescription_libfoo = + * { + * ... + * }; + * + * PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void) + * { + * return &prVersionDescription_libfoo; + * } + */ +typedef const PRVersionDescription *(*versionEntryPointType)(void); + +/* + * Where you declare your libVersionPoint, do it like this: + * PR_IMPLEMENT(const PRVersionDescription *) libVersionPoint(void) { + * fill it in... + * } + */ + +/* + * NAMING CONVENTION FOR struct + * + * all components should also expose a static PRVersionDescription + * The name of the struct should be calculated as follows: + * Take the value of filename. (If filename is not specified, calculate + * a short, unique string.) Convert all non-alphanumeric characters + * to '_'. To this, prepend "PRVersionDescription_". Thus for libfoo.so, + * the symbol name is "PRVersionDescription_libfoo_so". + * so the file should have + * PRVersionDescription PRVersionDescription_libfoo_so { fill it in }; + * on NT, this file should be declspec export. + */ + +PR_END_EXTERN_C + +#endif /* defined(_PRVERSION_H) */ + +/* prvrsion.h */ + diff -Nru nspr-4.9.5/nspr/pr/include/prwin16.h nspr-4.10.7/nspr/pr/include/prwin16.h --- nspr-4.9.5/nspr/pr/include/prwin16.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/include/prwin16.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef prwin16_h___ +#define prwin16_h___ + +/* +** Condition use of this header on platform. +*/ +#if (defined(XP_PC) && !defined(_WIN32) && !defined(XP_OS2) && defined(MOZILLA_CLIENT)) || defined(WIN16) +#include + +PR_BEGIN_EXTERN_C +/* +** Win16 stdio special case. +** To get stdio to work for Win16, all calls to printf() and related +** things must be called from the environment of the .EXE; calls to +** printf() from the .DLL send output to the bit-bucket. +** +** To make sure that PR_fprintf(), and related functions, work correctly, +** the actual stream I/O to stdout, stderr, stdin must be done in the +** .EXE. To do this, a hack is placed in _MD_Write() such that the +** fd for stdio handles results in a call to the .EXE. +** +** file w16stdio.c contains the functions that get called from NSPR +** to do the actual I/O. w16stdio.o must be statically linked with +** any application needing stdio for Win16. +** +** The address of these functions must be made available to the .DLL +** so he can call back to the .EXE. To do this, function +** PR_MD_RegisterW16StdioCallbacks() is called from the .EXE. +** The arguments are the functions defined in w16stdio.c +** At runtime, MD_Write() calls the registered functions, if any +** were registered. +** +** prinit.h contains a macro PR_STDIO_INIT() that calls the registration +** function for Win16; For other platforms, the macro is a No-Op. +** +** Note that stdio is not operational at all on Win16 GUI applications. +** This special case exists to provide stdio capability from the NSPR +** .DLL for command line applications only. NSPR's test cases are +** almost exclusively command line applications. +** +** See also: w16io.c, w16stdio.c +*/ +typedef PRInt32 (PR_CALLBACK *PRStdinRead)( void *buf, PRInt32 amount); +typedef PRInt32 (PR_CALLBACK *PRStdoutWrite)( void *buf, PRInt32 amount); +typedef PRInt32 (PR_CALLBACK *PRStderrWrite)( void *buf, PRInt32 amount); + +NSPR_API(PRStatus) +PR_MD_RegisterW16StdioCallbacks( + PRStdinRead inReadf, /* i: function pointer for stdin read */ + PRStdoutWrite outWritef, /* i: function pointer for stdout write */ + PRStderrWrite errWritef /* i: function pointer for stderr write */ + ); + +NSPR_API(PRInt32) +_PL_W16StdioWrite( void *buf, PRInt32 amount ); + +NSPR_API(PRInt32) +_PL_W16StdioRead( void *buf, PRInt32 amount ); + +#define PR_STDIO_INIT() PR_MD_RegisterW16StdioCallbacks( \ + _PL_W16StdioRead, _PL_W16StdioWrite, _PL_W16StdioWrite ); \ + PR_INIT_CALLBACKS(); + +/* +** Win16 hackery. +** +*/ +struct PRMethodCallbackStr { + int (PR_CALLBACK *auxOutput)(const char *outputString); + size_t (PR_CALLBACK *strftime)(char *s, size_t len, const char *fmt, const struct tm *p); + void * (PR_CALLBACK *malloc)( size_t size ); + void * (PR_CALLBACK *calloc)(size_t n, size_t size ); + void * (PR_CALLBACK *realloc)( void* old_blk, size_t size ); + void (PR_CALLBACK *free)( void *ptr ); + void * (PR_CALLBACK *getenv)( const char *name); + int (PR_CALLBACK *putenv)( const char *assoc); +/* void * (PR_CALLBACK *perror)( const char *prefix ); */ +}; + +NSPR_API(void) PR_MDRegisterCallbacks(struct PRMethodCallbackStr *); + +int PR_CALLBACK _PL_W16CallBackPuts( const char *outputString ); +size_t PR_CALLBACK _PL_W16CallBackStrftime( + char *s, + size_t len, + const char *fmt, + const struct tm *p ); +void * PR_CALLBACK _PL_W16CallBackMalloc( size_t size ); +void * PR_CALLBACK _PL_W16CallBackCalloc( size_t n, size_t size ); +void * PR_CALLBACK _PL_W16CallBackRealloc( + void *old_blk, + size_t size ); +void PR_CALLBACK _PL_W16CallBackFree( void *ptr ); +void * PR_CALLBACK _PL_W16CallBackGetenv( const char *name ); +int PR_CALLBACK _PL_W16CallBackPutenv( const char *assoc ); + +/* +** Hackery! +** +** These functions are provided as static link points. +** This is to satisfy the quick port of Gromit to NSPR 2.0 +** ... Don't do this! ... alas, It may never go away. +** +*/ +NSPR_API(int) PR_MD_printf(const char *, ...); +NSPR_API(void) PR_MD_exit(int); +NSPR_API(size_t) PR_MD_strftime(char *, size_t, const char *, const struct tm *); +NSPR_API(int) PR_MD_sscanf(const char *, const char *, ...); +NSPR_API(void*) PR_MD_malloc( size_t size ); +NSPR_API(void*) PR_MD_calloc( size_t n, size_t size ); +NSPR_API(void*) PR_MD_realloc( void* old_blk, size_t size ); +NSPR_API(void) PR_MD_free( void *ptr ); +NSPR_API(char*) PR_MD_getenv( const char *name ); +NSPR_API(int) PR_MD_putenv( const char *assoc ); +NSPR_API(int) PR_MD_fprintf(FILE *fPtr, const char *fmt, ...); + +#define PR_INIT_CALLBACKS() \ + { \ + static struct PRMethodCallbackStr cbf = { \ + _PL_W16CallBackPuts, \ + _PL_W16CallBackStrftime, \ + _PL_W16CallBackMalloc, \ + _PL_W16CallBackCalloc, \ + _PL_W16CallBackRealloc, \ + _PL_W16CallBackFree, \ + _PL_W16CallBackGetenv, \ + _PL_W16CallBackPutenv, \ + }; \ + PR_MDRegisterCallbacks( &cbf ); \ + } + + +/* +** Get the exception context for Win16 MFC applications threads +*/ +NSPR_API(void *) PR_W16GetExceptionContext(void); +/* +** Set the exception context for Win16 MFC applications threads +*/ +NSPR_API(void) PR_W16SetExceptionContext(void *context); + +PR_END_EXTERN_C +#else +/* +** For platforms other than Win16, define +** PR_STDIO_INIT() as a No-Op. +*/ +#define PR_STDIO_INIT() +#endif /* WIN16 || MOZILLA_CLIENT */ + +#endif /* prwin16_h___ */ + + + + + + + + diff -Nru nspr-4.9.5/nspr/pr/Makefile.in nspr-4.10.7/nspr/pr/Makefile.in --- nspr-4.9.5/nspr/pr/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,17 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = .. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +DIRS = include src + +include $(topsrcdir)/config/rules.mk diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/bsrcs.mk nspr-4.10.7/nspr/pr/src/bthreads/bsrcs.mk --- nspr-4.9.5/nspr/pr/src/bthreads/bsrcs.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/bsrcs.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,17 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# this file lists the source files to be compiled (used in Makefile) and +# then enumerated as object files (in objs.mk) for inclusion in the NSPR +# shared library + +BTCSRCS = \ + btthread.c \ + btlocks.c \ + btcvar.c \ + btmon.c \ + btsem.c \ + btmisc.c \ + $(NULL) diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/btcvar.c nspr-4.10.7/nspr/pr/src/bthreads/btcvar.c --- nspr-4.9.5/nspr/pr/src/bthreads/btcvar.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/btcvar.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,244 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "primpl.h" + +/* +** Create a new condition variable. +** +** "lock" is the lock used to protect the condition variable. +** +** Condition variables are synchronization objects that threads can use +** to wait for some condition to occur. +** +** This may fail if memory is tight or if some operating system resource +** is low. In such cases, a NULL will be returned. +*/ +PR_IMPLEMENT(PRCondVar*) + PR_NewCondVar (PRLock *lock) +{ + PRCondVar *cv = PR_NEW( PRCondVar ); + PR_ASSERT( NULL != lock ); + if( NULL != cv ) + { + cv->lock = lock; + cv->sem = create_sem(0, "CVSem"); + cv->handshakeSem = create_sem(0, "CVHandshake"); + cv->signalSem = create_sem( 0, "CVSignal"); + cv->signalBenCount = 0; + cv->ns = cv->nw = 0; + PR_ASSERT( cv->sem >= B_NO_ERROR ); + PR_ASSERT( cv->handshakeSem >= B_NO_ERROR ); + PR_ASSERT( cv->signalSem >= B_NO_ERROR ); + } + return cv; +} /* PR_NewCondVar */ + +/* +** Destroy a condition variable. There must be no thread +** waiting on the condvar. The caller is responsible for guaranteeing +** that the condvar is no longer in use. +** +*/ +PR_IMPLEMENT(void) + PR_DestroyCondVar (PRCondVar *cvar) +{ + status_t result = delete_sem( cvar->sem ); + PR_ASSERT( result == B_NO_ERROR ); + + result = delete_sem( cvar->handshakeSem ); + PR_ASSERT( result == B_NO_ERROR ); + + result = delete_sem( cvar->signalSem ); + PR_ASSERT( result == B_NO_ERROR ); + + PR_DELETE( cvar ); +} + +/* +** The thread that waits on a condition is blocked in a "waiting on +** condition" state until another thread notifies the condition or a +** caller specified amount of time expires. The lock associated with +** the condition variable will be released, which must have be held +** prior to the call to wait. +** +** Logically a notified thread is moved from the "waiting on condition" +** state and made "ready." When scheduled, it will attempt to reacquire +** the lock that it held when wait was called. +** +** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and +** PR_INTERVAL_NO_WAIT. The former value requires that a condition be +** notified (or the thread interrupted) before it will resume from the +** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect +** is to release the lock, possibly causing a rescheduling within the +** runtime, then immediately attempting to reacquire the lock and resume. +** +** Any other value for timeout will cause the thread to be rescheduled +** either due to explicit notification or an expired interval. The latter +** must be determined by treating time as one part of the monitored data +** being protected by the lock and tested explicitly for an expired +** interval. +** +** Returns PR_FAILURE if the caller has not locked the lock associated +** with the condition variable or the thread was interrupted (PR_Interrupt()). +** The particular reason can be extracted with PR_GetError(). +*/ +PR_IMPLEMENT(PRStatus) + PR_WaitCondVar (PRCondVar *cvar, PRIntervalTime timeout) +{ + status_t err; + if( timeout == PR_INTERVAL_NO_WAIT ) + { + PR_Unlock( cvar->lock ); + PR_Lock( cvar->lock ); + return PR_SUCCESS; + } + + if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) + { + if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) + { + atomic_add( &cvar->signalBenCount, -1 ); + return PR_FAILURE; + } + } + cvar->nw += 1; + if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) + { + release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); + } + + PR_Unlock( cvar->lock ); + if( timeout==PR_INTERVAL_NO_TIMEOUT ) + { + err = acquire_sem(cvar->sem); + } + else + { + err = acquire_sem_etc(cvar->sem, 1, B_RELATIVE_TIMEOUT, PR_IntervalToMicroseconds(timeout) ); + } + + if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) + { + while (acquire_sem(cvar->signalSem) == B_INTERRUPTED); + } + + if (cvar->ns > 0) + { + release_sem_etc(cvar->handshakeSem, 1, B_DO_NOT_RESCHEDULE); + cvar->ns -= 1; + } + cvar->nw -= 1; + if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) + { + release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); + } + + PR_Lock( cvar->lock ); + if(err!=B_NO_ERROR) + { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +/* +** Notify ONE thread that is currently waiting on 'cvar'. Which thread is +** dependent on the implementation of the runtime. Common sense would dictate +** that all threads waiting on a single condition have identical semantics, +** therefore which one gets notified is not significant. +** +** The calling thead must hold the lock that protects the condition, as +** well as the invariants that are tightly bound to the condition, when +** notify is called. +** +** Returns PR_FAILURE if the caller has not locked the lock associated +** with the condition variable. +*/ +PR_IMPLEMENT(PRStatus) + PR_NotifyCondVar (PRCondVar *cvar) +{ + status_t err ; + if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) + { + if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) + { + atomic_add( &cvar->signalBenCount, -1 ); + return PR_FAILURE; + } + } + if (cvar->nw > cvar->ns) + { + cvar->ns += 1; + release_sem_etc(cvar->sem, 1, B_DO_NOT_RESCHEDULE); + if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) + { + release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); + } + + while (acquire_sem(cvar->handshakeSem) == B_INTERRUPTED) + { + err = B_INTERRUPTED; + } + } + else + { + if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) + { + release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); + } + } + return PR_SUCCESS; +} + +/* +** Notify all of the threads waiting on the condition variable. The order +** that the threads are notified is indeterminant. The lock that protects +** the condition must be held. +** +** Returns PR_FAILURE if the caller has not locked the lock associated +** with the condition variable. +*/ +PR_IMPLEMENT(PRStatus) + PR_NotifyAllCondVar (PRCondVar *cvar) +{ + int32 handshakes; + status_t err = B_OK; + + if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) + { + if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) + { + atomic_add( &cvar->signalBenCount, -1 ); + return PR_FAILURE; + } + } + + if (cvar->nw > cvar->ns) + { + handshakes = cvar->nw - cvar->ns; + cvar->ns = cvar->nw; + release_sem_etc(cvar->sem, handshakes, B_DO_NOT_RESCHEDULE); + if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) + { + release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); + } + + while (acquire_sem_etc(cvar->handshakeSem, handshakes, 0, 0) == B_INTERRUPTED) + { + err = B_INTERRUPTED; + } + } + else + { + if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) + { + release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); + } + } + return PR_SUCCESS; +} diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/btlocks.c nspr-4.10.7/nspr/pr/src/bthreads/btlocks.c --- nspr-4.9.5/nspr/pr/src/bthreads/btlocks.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/btlocks.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,91 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: btlocks.c +** Description: Implemenation for thread locks using bthreads +** Exports: prlock.h +*/ + +#include "primpl.h" + +#include +#include + +void +_PR_InitLocks (void) +{ +} + +PR_IMPLEMENT(PRLock*) + PR_NewLock (void) +{ + PRLock *lock; + status_t semresult; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + lock = PR_NEWZAP(PRLock); + if (lock != NULL) { + + lock->benaphoreCount = 0; + lock->semaphoreID = create_sem( 0, "nsprLockSem" ); + if( lock->semaphoreID < B_NO_ERROR ) { + + PR_DELETE( lock ); + lock = NULL; + } + } + + return lock; +} + +PR_IMPLEMENT(void) + PR_DestroyLock (PRLock* lock) +{ + status_t result; + + PR_ASSERT(NULL != lock); + result = delete_sem(lock->semaphoreID); + PR_ASSERT(result == B_NO_ERROR); + PR_DELETE(lock); +} + +PR_IMPLEMENT(void) + PR_Lock (PRLock* lock) +{ + PR_ASSERT(lock != NULL); + + if( atomic_add( &lock->benaphoreCount, 1 ) > 0 ) { + + if( acquire_sem(lock->semaphoreID ) != B_NO_ERROR ) { + + atomic_add( &lock->benaphoreCount, -1 ); + return; + } + } + + lock->owner = find_thread( NULL ); +} + +PR_IMPLEMENT(PRStatus) + PR_Unlock (PRLock* lock) +{ + PR_ASSERT(lock != NULL); + lock->owner = NULL; + if( atomic_add( &lock->benaphoreCount, -1 ) > 1 ) { + + release_sem_etc( lock->semaphoreID, 1, B_DO_NOT_RESCHEDULE ); + } + + return PR_SUCCESS; +} + +PR_IMPLEMENT(void) + PR_AssertCurrentThreadOwnsLock(PRLock *lock) +{ + PR_ASSERT(lock != NULL); + PR_ASSERT(lock->owner == find_thread( NULL )); +} diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/btmisc.c nspr-4.10.7/nspr/pr/src/bthreads/btmisc.c --- nspr-4.9.5/nspr/pr/src/bthreads/btmisc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/btmisc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,72 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include + +// void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")} +// void _MD_StartInterrupts(void) {PT_LOG("_MD_StartInterrupts")} + +/* this is a total hack.. */ + +struct protoent* getprotobyname(const char* name) +{ + return 0; +} + +struct protoent* getprotobynumber(int number) +{ + return 0; +} + +/* this is needed by prinit for some reason */ +void +_PR_InitStacks (void) +{ +} + +/* this is needed by prinit for some reason */ +void +_PR_InitTPD (void) +{ +} + +/* +** Create extra virtual processor threads. Generally used with MP systems. +*/ +PR_IMPLEMENT(void) + PR_SetConcurrency (PRUintn numCPUs) +{ +} + +/* +** Set thread recycle mode to on (1) or off (0) +*/ +PR_IMPLEMENT(void) + PR_SetThreadRecycleMode (PRUint32 flag) +{ +} + +/* +** Get context registers, return with error for now. +*/ + +PR_IMPLEMENT(PRWord *) +_MD_HomeGCRegisters( PRThread *t, int isCurrent, int *np ) +{ + return 0; +} + +PR_IMPLEMENT(void *) +PR_GetSP( PRThread *t ) +{ + return 0; +} + +PR_IMPLEMENT(PRStatus) +PR_EnumerateThreads( PREnumerator func, void *arg ) +{ + return PR_FAILURE; +} diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/btmon.c nspr-4.10.7/nspr/pr/src/bthreads/btmon.c --- nspr-4.9.5/nspr/pr/src/bthreads/btmon.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/btmon.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "primpl.h" + +/* +** Create a new monitor. Monitors are re-entrant locks with a single built-in +** condition variable. +** +** This may fail if memory is tight or if some operating system resource +** is low. +*/ +PR_IMPLEMENT(PRMonitor*) + PR_NewMonitor (void) +{ + PRMonitor *mon; + PRCondVar *cvar; + PRLock *lock; + + mon = PR_NEWZAP( PRMonitor ); + if( mon ) + { + lock = PR_NewLock(); + if( !lock ) + { + PR_DELETE( mon ); + return( 0 ); + } + + cvar = PR_NewCondVar( lock ); + if( !cvar ) + { + PR_DestroyLock( lock ); + PR_DELETE( mon ); + return( 0 ); + } + + mon->cvar = cvar; + mon->name = NULL; + } + + return( mon ); +} + +PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name) +{ + PRMonitor* mon = PR_NewMonitor(); + if( mon ) + { + mon->name = name; + } + return mon; +} + +/* +** Destroy a monitor. The caller is responsible for guaranteeing that the +** monitor is no longer in use. There must be no thread waiting on the +** monitor's condition variable and that the lock is not held. +** +*/ +PR_IMPLEMENT(void) + PR_DestroyMonitor (PRMonitor *mon) +{ + PR_DestroyLock( mon->cvar->lock ); + PR_DestroyCondVar( mon->cvar ); + PR_DELETE( mon ); +} + +/* +** Enter the lock associated with the monitor. If the calling thread currently +** is in the monitor, the call to enter will silently succeed. In either case, +** it will increment the entry count by one. +*/ +PR_IMPLEMENT(void) + PR_EnterMonitor (PRMonitor *mon) +{ + if( mon->cvar->lock->owner == find_thread( NULL ) ) + { + mon->entryCount++; + + } else + { + PR_Lock( mon->cvar->lock ); + mon->entryCount = 1; + } +} + +/* +** Decrement the entry count associated with the monitor. If the decremented +** entry count is zero, the monitor is exited. Returns PR_FAILURE if the +** calling thread has not entered the monitor. +*/ +PR_IMPLEMENT(PRStatus) + PR_ExitMonitor (PRMonitor *mon) +{ + if( mon->cvar->lock->owner != find_thread( NULL ) ) + { + return( PR_FAILURE ); + } + if( --mon->entryCount == 0 ) + { + return( PR_Unlock( mon->cvar->lock ) ); + } + return( PR_SUCCESS ); +} + +/* +** Wait for a notify on the monitor's condition variable. Sleep for "ticks" +** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is +** indefinite). +** +** While the thread is waiting it exits the monitor (as if it called +** PR_ExitMonitor as many times as it had called PR_EnterMonitor). When +** the wait has finished the thread regains control of the monitors lock +** with the same entry count as before the wait began. +** +** The thread waiting on the monitor will be resumed when the monitor is +** notified (assuming the thread is the next in line to receive the +** notify) or when the "ticks" timeout elapses. +** +** Returns PR_FAILURE if the caller has not entered the monitor. +*/ +PR_IMPLEMENT(PRStatus) + PR_Wait (PRMonitor *mon, PRIntervalTime ticks) +{ + PRUint32 entryCount; + PRUintn status; + PRThread *meThread; + thread_id me = find_thread( NULL ); + meThread = PR_GetCurrentThread(); + + if( mon->cvar->lock->owner != me ) return( PR_FAILURE ); + + entryCount = mon->entryCount; + mon->entryCount = 0; + + status = PR_WaitCondVar( mon->cvar, ticks ); + + mon->entryCount = entryCount; + + return( status ); +} + +/* +** Notify a thread waiting on the monitor's condition variable. If a thread +** is waiting on the condition variable (using PR_Wait) then it is awakened +** and attempts to reenter the monitor. +*/ +PR_IMPLEMENT(PRStatus) + PR_Notify (PRMonitor *mon) +{ + if( mon->cvar->lock->owner != find_thread( NULL ) ) + { + return( PR_FAILURE ); + } + + PR_NotifyCondVar( mon->cvar ); + return( PR_SUCCESS ); +} + +/* +** Notify all of the threads waiting on the monitor's condition variable. +** All of threads waiting on the condition are scheduled to reenter the +** monitor. +*/ +PR_IMPLEMENT(PRStatus) + PR_NotifyAll (PRMonitor *mon) +{ + if( mon->cvar->lock->owner != find_thread( NULL ) ) + { + return( PR_FAILURE ); + } + + PR_NotifyAllCondVar( mon->cvar ); + return( PR_SUCCESS ); +} + +/* +** Return the number of times that the current thread has entered the +** lock. Returns zero if the current thread has not entered the lock. +*/ +PR_IMPLEMENT(PRIntn) + PR_GetMonitorEntryCount(PRMonitor *mon) +{ + return( (mon->cvar->lock->owner == find_thread( NULL )) ? + mon->entryCount : 0 ); +} + +/* +** If the current thread is in |mon|, this assertion is guaranteed to +** succeed. Otherwise, the behavior of this function is undefined. +*/ +PR_IMPLEMENT(void) + PR_AssertCurrentThreadInMonitor(PRMonitor *mon) +{ + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mon->cvar->lock); +} diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/btsem.c nspr-4.10.7/nspr/pr/src/bthreads/btsem.c --- nspr-4.9.5/nspr/pr/src/bthreads/btsem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/btsem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "primpl.h" + +/* +** Create a new semaphore object. +*/ +PR_IMPLEMENT(PRSemaphore*) + PR_NewSem (PRUintn value) +{ + PRSemaphore *semaphore; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + semaphore = PR_NEWZAP(PRSemaphore); + if (NULL != semaphore) { + if ((semaphore->sem = create_sem(value, "nspr_sem")) < B_NO_ERROR) + return NULL; + else + return semaphore; + } + return NULL; +} + +/* +** Destroy the given semaphore object. +** +*/ +PR_IMPLEMENT(void) + PR_DestroySem (PRSemaphore *sem) +{ + status_t result; + + PR_ASSERT(sem != NULL); + result = delete_sem(sem->sem); + PR_ASSERT(result == B_NO_ERROR); + PR_DELETE(sem); +} + +/* +** Wait on a Semaphore. +** +** This routine allows a calling thread to wait or proceed depending upon +** the state of the semahore sem. The thread can proceed only if the +** counter value of the semaphore sem is currently greater than 0. If the +** value of semaphore sem is positive, it is decremented by one and the +** routine returns immediately allowing the calling thread to continue. If +** the value of semaphore sem is 0, the calling thread blocks awaiting the +** semaphore to be released by another thread. +** +** This routine can return PR_PENDING_INTERRUPT if the waiting thread +** has been interrupted. +*/ +PR_IMPLEMENT(PRStatus) + PR_WaitSem (PRSemaphore *sem) +{ + PR_ASSERT(sem != NULL); + if (acquire_sem(sem->sem) == B_NO_ERROR) + return PR_SUCCESS; + else + return PR_FAILURE; +} + +/* +** This routine increments the counter value of the semaphore. If other +** threads are blocked for the semaphore, then the scheduler will +** determine which ONE thread will be unblocked. +*/ +PR_IMPLEMENT(void) + PR_PostSem (PRSemaphore *sem) +{ + status_t result; + + PR_ASSERT(sem != NULL); + result = release_sem_etc(sem->sem, 1, B_DO_NOT_RESCHEDULE); + PR_ASSERT(result == B_NO_ERROR); +} + +/* +** Returns the value of the semaphore referenced by sem without affecting +** the state of the semaphore. The value represents the semaphore value +** at the time of the call, but may not be the actual value when the +** caller inspects it. +*/ +PR_IMPLEMENT(PRUintn) + PR_GetValueSem (PRSemaphore *sem) +{ + sem_info info; + + PR_ASSERT(sem != NULL); + get_sem_info(sem->sem, &info); + return info.count; +} diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/btthread.c nspr-4.10.7/nspr/pr/src/bthreads/btthread.c --- nspr-4.9.5/nspr/pr/src/bthreads/btthread.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/btthread.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,662 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include + +#include "prlog.h" +#include "primpl.h" +#include "prcvar.h" +#include "prpdce.h" + +#include +#include +#include + +/* values for PRThread.state */ +#define BT_THREAD_PRIMORD 0x01 /* this is the primordial thread */ +#define BT_THREAD_SYSTEM 0x02 /* this is a system thread */ +#define BT_THREAD_JOINABLE 0x04 /* this is a joinable thread */ + +struct _BT_Bookeeping +{ + PRLock *ml; /* a lock to protect ourselves */ + sem_id cleanUpSem; /* the primoridal thread will block on this + sem while waiting for the user threads */ + PRInt32 threadCount; /* user thred count */ + +} bt_book = { NULL, B_ERROR, 0 }; + + +#define BT_TPD_LIMIT 128 /* number of TPD slots we'll provide (arbitrary) */ + +/* these will be used to map an index returned by PR_NewThreadPrivateIndex() + to the corresponding beos native TLS slot number, and to the destructor + for that slot - note that, because it is allocated globally, this data + will be automatically zeroed for us when the program begins */ +static int32 tpd_beosTLSSlots[BT_TPD_LIMIT]; +static PRThreadPrivateDTOR tpd_dtors[BT_TPD_LIMIT]; + +static vint32 tpd_slotsUsed=0; /* number of currently-allocated TPD slots */ +static int32 tls_prThreadSlot; /* TLS slot in which PRThread will be stored */ + +/* this mutex will be used to synchronize access to every + PRThread.md.joinSem and PRThread.md.is_joining (we could + actually allocate one per thread, but that seems a bit excessive, + especially considering that there will probably be little + contention, PR_JoinThread() is allowed to block anyway, and the code + protected by the mutex is short/fast) */ +static PRLock *joinSemLock; + +static PRUint32 _bt_MapNSPRToNativePriority( PRThreadPriority priority ); +static PRThreadPriority _bt_MapNativeToNSPRPriority( PRUint32 priority ); +static void _bt_CleanupThread(void *arg); +static PRThread *_bt_AttachThread(); + +void +_PR_InitThreads (PRThreadType type, PRThreadPriority priority, + PRUintn maxPTDs) +{ + PRThread *primordialThread; + PRUint32 beThreadPriority; + + /* allocate joinSem mutex */ + joinSemLock = PR_NewLock(); + if (joinSemLock == NULL) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return; + } + + /* + ** Create and initialize NSPR structure for our primordial thread. + */ + + primordialThread = PR_NEWZAP(PRThread); + if( NULL == primordialThread ) + { + PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 ); + return; + } + + primordialThread->md.joinSem = B_ERROR; + + /* + ** Set the priority to the desired level. + */ + + beThreadPriority = _bt_MapNSPRToNativePriority( priority ); + + set_thread_priority( find_thread( NULL ), beThreadPriority ); + + primordialThread->priority = priority; + + + /* set the thread's state - note that the thread is not joinable */ + primordialThread->state |= BT_THREAD_PRIMORD; + if (type == PR_SYSTEM_THREAD) + primordialThread->state |= BT_THREAD_SYSTEM; + + /* + ** Allocate a TLS slot for the PRThread structure (just using + ** native TLS, as opposed to NSPR TPD, will make PR_GetCurrentThread() + ** somewhat faster, and will leave one more TPD slot for our client) + */ + + tls_prThreadSlot = tls_allocate(); + + /* + ** Stuff our new PRThread structure into our thread specific + ** slot. + */ + + tls_set(tls_prThreadSlot, primordialThread); + + /* allocate lock for bt_book */ + bt_book.ml = PR_NewLock(); + if( NULL == bt_book.ml ) + { + PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 ); + return; + } +} + +PRUint32 +_bt_MapNSPRToNativePriority( PRThreadPriority priority ) + { + switch( priority ) + { + case PR_PRIORITY_LOW: return( B_LOW_PRIORITY ); + case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY ); + case PR_PRIORITY_HIGH: return( B_DISPLAY_PRIORITY ); + case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY ); + default: return( B_NORMAL_PRIORITY ); + } +} + +PRThreadPriority +_bt_MapNativeToNSPRPriority(PRUint32 priority) + { + if (priority < B_NORMAL_PRIORITY) + return PR_PRIORITY_LOW; + if (priority < B_DISPLAY_PRIORITY) + return PR_PRIORITY_NORMAL; + if (priority < B_URGENT_DISPLAY_PRIORITY) + return PR_PRIORITY_HIGH; + return PR_PRIORITY_URGENT; +} + +PRUint32 +_bt_mapNativeToNSPRPriority( int32 priority ) +{ + switch( priority ) + { + case PR_PRIORITY_LOW: return( B_LOW_PRIORITY ); + case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY ); + case PR_PRIORITY_HIGH: return( B_DISPLAY_PRIORITY ); + case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY ); + default: return( B_NORMAL_PRIORITY ); + } +} + +/* This method is called by all NSPR threads as they exit */ +void _bt_CleanupThread(void *arg) +{ + PRThread *me = PR_GetCurrentThread(); + int32 i; + + /* first, clean up all thread-private data */ + for (i = 0; i < tpd_slotsUsed; i++) + { + void *oldValue = tls_get(tpd_beosTLSSlots[i]); + if ( oldValue != NULL && tpd_dtors[i] != NULL ) + (*tpd_dtors[i])(oldValue); + } + + /* if this thread is joinable, wait for someone to join it */ + if (me->state & BT_THREAD_JOINABLE) + { + /* protect access to our joinSem */ + PR_Lock(joinSemLock); + + if (me->md.is_joining) + { + /* someone is already waiting to join us (they've + allocated a joinSem for us) - let them know we're + ready */ + delete_sem(me->md.joinSem); + + PR_Unlock(joinSemLock); + + } + else + { + /* noone is currently waiting for our demise - it + is our responsibility to allocate the joinSem + and block on it */ + me->md.joinSem = create_sem(0, "join sem"); + + /* we're done accessing our joinSem */ + PR_Unlock(joinSemLock); + + /* wait for someone to join us */ + while (acquire_sem(me->md.joinSem) == B_INTERRUPTED); + } + } + + /* if this is a user thread, we must update our books */ + if ((me->state & BT_THREAD_SYSTEM) == 0) + { + /* synchronize access to bt_book */ + PR_Lock( bt_book.ml ); + + /* decrement the number of currently-alive user threads */ + bt_book.threadCount--; + + if (bt_book.threadCount == 0 && bt_book.cleanUpSem != B_ERROR) { + /* we are the last user thread, and the primordial thread is + blocked in PR_Cleanup() waiting for us to finish - notify + it */ + delete_sem(bt_book.cleanUpSem); + } + + PR_Unlock( bt_book.ml ); + } + + /* finally, delete this thread's PRThread */ + PR_DELETE(me); +} + +/** + * This is a wrapper that all threads invoke that allows us to set some + * things up prior to a thread's invocation and clean up after a thread has + * exited. + */ +static void* +_bt_root (void* arg) + { + PRThread *thred = (PRThread*)arg; + PRIntn rv; + void *privData; + status_t result; + int i; + + /* save our PRThread object into our TLS */ + tls_set(tls_prThreadSlot, thred); + + thred->startFunc(thred->arg); /* run the dang thing */ + + /* clean up */ + _bt_CleanupThread(NULL); + + return 0; +} + +PR_IMPLEMENT(PRThread*) + PR_CreateThread (PRThreadType type, void (*start)(void* arg), void* arg, + PRThreadPriority priority, PRThreadScope scope, + PRThreadState state, PRUint32 stackSize) +{ + PRUint32 bePriority; + + PRThread* thred; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + thred = PR_NEWZAP(PRThread); + if (thred == NULL) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + thred->md.joinSem = B_ERROR; + + thred->arg = arg; + thred->startFunc = start; + thred->priority = priority; + + if( state == PR_JOINABLE_THREAD ) + { + thred->state |= BT_THREAD_JOINABLE; + } + + /* keep some books */ + + PR_Lock( bt_book.ml ); + + if (type == PR_USER_THREAD) + { + bt_book.threadCount++; + } + + PR_Unlock( bt_book.ml ); + + bePriority = _bt_MapNSPRToNativePriority( priority ); + + thred->md.tid = spawn_thread((thread_func)_bt_root, "moz-thread", + bePriority, thred); + if (thred->md.tid < B_OK) { + PR_SetError(PR_UNKNOWN_ERROR, thred->md.tid); + PR_DELETE(thred); + return NULL; + } + + if (resume_thread(thred->md.tid) < B_OK) { + PR_SetError(PR_UNKNOWN_ERROR, 0); + PR_DELETE(thred); + return NULL; + } + + return thred; + } + +PR_IMPLEMENT(PRThread*) + PR_AttachThread(PRThreadType type, PRThreadPriority priority, + PRThreadStack *stack) +{ + /* PR_GetCurrentThread() will attach a thread if necessary */ + return PR_GetCurrentThread(); +} + +PR_IMPLEMENT(void) + PR_DetachThread() +{ + /* we don't support detaching */ +} + +PR_IMPLEMENT(PRStatus) + PR_JoinThread (PRThread* thred) +{ + status_t eval, status; + + PR_ASSERT(thred != NULL); + + if ((thred->state & BT_THREAD_JOINABLE) == 0) + { + PR_SetError( PR_INVALID_ARGUMENT_ERROR, 0 ); + return( PR_FAILURE ); + } + + /* synchronize access to the thread's joinSem */ + PR_Lock(joinSemLock); + + if (thred->md.is_joining) + { + /* another thread is already waiting to join the specified + thread - we must fail */ + PR_Unlock(joinSemLock); + return PR_FAILURE; + } + + /* let others know we are waiting to join */ + thred->md.is_joining = PR_TRUE; + + if (thred->md.joinSem == B_ERROR) + { + /* the thread hasn't finished yet - it is our responsibility to + allocate a joinSem and wait on it */ + thred->md.joinSem = create_sem(0, "join sem"); + + /* we're done changing the joinSem now */ + PR_Unlock(joinSemLock); + + /* wait for the thread to finish */ + while (acquire_sem(thred->md.joinSem) == B_INTERRUPTED); + + } + else + { + /* the thread has already finished, and has allocated the + joinSem itself - let it know it can finally die */ + delete_sem(thred->md.joinSem); + + PR_Unlock(joinSemLock); + } + + /* make sure the thread is dead */ + wait_for_thread(thred->md.tid, &eval); + + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRThread*) + PR_GetCurrentThread () +{ + PRThread* thred; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + thred = (PRThread *)tls_get( tls_prThreadSlot); + if (thred == NULL) + { + /* this thread doesn't have a PRThread structure (it must be + a native thread not created by the NSPR) - assimilate it */ + thred = _bt_AttachThread(); + } + PR_ASSERT(NULL != thred); + + return thred; +} + +PR_IMPLEMENT(PRThreadScope) + PR_GetThreadScope (const PRThread* thred) +{ + PR_ASSERT(thred != NULL); + return PR_GLOBAL_THREAD; +} + +PR_IMPLEMENT(PRThreadType) + PR_GetThreadType (const PRThread* thred) +{ + PR_ASSERT(thred != NULL); + return (thred->state & BT_THREAD_SYSTEM) ? + PR_SYSTEM_THREAD : PR_USER_THREAD; +} + +PR_IMPLEMENT(PRThreadState) + PR_GetThreadState (const PRThread* thred) +{ + PR_ASSERT(thred != NULL); + return (thred->state & BT_THREAD_JOINABLE)? + PR_JOINABLE_THREAD: PR_UNJOINABLE_THREAD; +} + +PR_IMPLEMENT(PRThreadPriority) + PR_GetThreadPriority (const PRThread* thred) +{ + PR_ASSERT(thred != NULL); + return thred->priority; +} /* PR_GetThreadPriority */ + +PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred, + PRThreadPriority newPri) +{ + PRUint32 bePriority; + + PR_ASSERT( thred != NULL ); + + thred->priority = newPri; + bePriority = _bt_MapNSPRToNativePriority( newPri ); + set_thread_priority( thred->md.tid, bePriority ); +} + +PR_IMPLEMENT(PRStatus) + PR_NewThreadPrivateIndex (PRUintn* newIndex, + PRThreadPrivateDTOR destructor) +{ + int32 index; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + /* reserve the next available tpd slot */ + index = atomic_add( &tpd_slotsUsed, 1 ); + if (index >= BT_TPD_LIMIT) + { + /* no slots left - decrement value, then fail */ + atomic_add( &tpd_slotsUsed, -1 ); + PR_SetError( PR_TPD_RANGE_ERROR, 0 ); + return( PR_FAILURE ); + } + + /* allocate a beos-native TLS slot for this index (the new slot + automatically contains NULL) */ + tpd_beosTLSSlots[index] = tls_allocate(); + + /* remember the destructor */ + tpd_dtors[index] = destructor; + + *newIndex = (PRUintn)index; + + return( PR_SUCCESS ); +} + +PR_IMPLEMENT(PRStatus) + PR_SetThreadPrivate (PRUintn index, void* priv) +{ + void *oldValue; + + /* + ** Sanity checking + */ + + if(index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT) + { + PR_SetError( PR_TPD_RANGE_ERROR, 0 ); + return( PR_FAILURE ); + } + + /* if the old value isn't NULL, and the dtor for this slot isn't + NULL, we must destroy the data */ + oldValue = tls_get(tpd_beosTLSSlots[index]); + if (oldValue != NULL && tpd_dtors[index] != NULL) + (*tpd_dtors[index])(oldValue); + + /* save new value */ + tls_set(tpd_beosTLSSlots[index], priv); + + return( PR_SUCCESS ); + } + +PR_IMPLEMENT(void*) + PR_GetThreadPrivate (PRUintn index) +{ + /* make sure the index is valid */ + if (index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT) + { + PR_SetError( PR_TPD_RANGE_ERROR, 0 ); + return NULL; + } + + /* return the value */ + return tls_get( tpd_beosTLSSlots[index] ); + } + + +PR_IMPLEMENT(PRStatus) + PR_Interrupt (PRThread* thred) +{ + PRIntn rv; + + PR_ASSERT(thred != NULL); + + /* + ** there seems to be a bug in beos R5 in which calling + ** resume_thread() on a blocked thread returns B_OK instead + ** of B_BAD_THREAD_STATE (beos bug #20000422-19095). as such, + ** to interrupt a thread, we will simply suspend then resume it + ** (no longer call resume_thread(), check for B_BAD_THREAD_STATE, + ** the suspend/resume to wake up a blocked thread). this wakes + ** up blocked threads properly, and doesn't hurt unblocked threads + ** (they simply get stopped then re-started immediately) + */ + + rv = suspend_thread( thred->md.tid ); + if( rv != B_NO_ERROR ) + { + /* this doesn't appear to be a valid thread_id */ + PR_SetError( PR_UNKNOWN_ERROR, rv ); + return PR_FAILURE; + } + + rv = resume_thread( thred->md.tid ); + if( rv != B_NO_ERROR ) + { + PR_SetError( PR_UNKNOWN_ERROR, rv ); + return PR_FAILURE; + } + + return PR_SUCCESS; +} + +PR_IMPLEMENT(void) + PR_ClearInterrupt () +{ +} + +PR_IMPLEMENT(PRStatus) + PR_Yield () +{ + /* we just sleep for long enough to cause a reschedule (100 + microseconds) */ + snooze(100); +} + +#define BT_MILLION 1000000UL + +PR_IMPLEMENT(PRStatus) + PR_Sleep (PRIntervalTime ticks) +{ + bigtime_t tps; + status_t status; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + tps = PR_IntervalToMicroseconds( ticks ); + + status = snooze(tps); + if (status == B_NO_ERROR) return PR_SUCCESS; + + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, status); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) + PR_Cleanup () +{ + PRThread *me = PR_GetCurrentThread(); + + PR_ASSERT(me->state & BT_THREAD_PRIMORD); + if ((me->state & BT_THREAD_PRIMORD) == 0) { + return PR_FAILURE; + } + + PR_Lock( bt_book.ml ); + + if (bt_book.threadCount != 0) + { + /* we'll have to wait for some threads to finish - create a + sem to block on */ + bt_book.cleanUpSem = create_sem(0, "cleanup sem"); + } + + PR_Unlock( bt_book.ml ); + + /* note that, if all the user threads were already dead, we + wouldn't have created a sem above, so this acquire_sem() + will fail immediately */ + while (acquire_sem(bt_book.cleanUpSem) == B_INTERRUPTED); + + return PR_SUCCESS; +} + +PR_IMPLEMENT(void) + PR_ProcessExit (PRIntn status) +{ + exit(status); +} + +PRThread *_bt_AttachThread() +{ + PRThread *thread; + thread_info tInfo; + + /* make sure this thread doesn't already have a PRThread structure */ + PR_ASSERT(tls_get(tls_prThreadSlot) == NULL); + + /* allocate a PRThread structure for this thread */ + thread = PR_NEWZAP(PRThread); + if (thread == NULL) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + /* get the native thread's current state */ + get_thread_info(find_thread(NULL), &tInfo); + + /* initialize new PRThread */ + thread->md.tid = tInfo.thread; + thread->md.joinSem = B_ERROR; + thread->priority = _bt_MapNativeToNSPRPriority(tInfo.priority); + + /* attached threads are always non-joinable user threads */ + thread->state = 0; + + /* increment user thread count */ + PR_Lock(bt_book.ml); + bt_book.threadCount++; + PR_Unlock(bt_book.ml); + + /* store this thread's PRThread */ + tls_set(tls_prThreadSlot, thread); + + /* the thread must call _bt_CleanupThread() before it dies, in order + to clean up its PRThread, synchronize with the primordial thread, + etc. */ + on_exit_thread(_bt_CleanupThread, NULL); + + return thread; +} diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/.cvsignore nspr-4.10.7/nspr/pr/src/bthreads/.cvsignore --- nspr-4.9.5/nspr/pr/src/bthreads/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/Makefile.in nspr-4.10.7/nspr/pr/src/bthreads/Makefile.in --- nspr-4.9.5/nspr/pr/src/bthreads/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,31 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +include $(srcdir)/bsrcs.mk +CSRCS += $(BTCSRCS) + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +include $(topsrcdir)/config/rules.mk + +DEFINES += -D_NSPR_BUILD_ + +export:: $(TARGETS) + + diff -Nru nspr-4.9.5/nspr/pr/src/bthreads/objs.mk nspr-4.10.7/nspr/pr/src/bthreads/objs.mk --- nspr-4.9.5/nspr/pr/src/bthreads/objs.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/bthreads/objs.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,11 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This makefile appends to the variable OBJS the bthread object modules +# that will be part of the nspr20 library. + +include $(srcdir)/bthreads/bsrcs.mk + +OBJS += $(BTCSRCS:%.c=bthreads/$(OBJDIR)/%.$(OBJ_SUFFIX)) diff -Nru nspr-4.9.5/nspr/pr/src/cplus/.cvsignore nspr-4.10.7/nspr/pr/src/cplus/.cvsignore --- nspr-4.9.5/nspr/pr/src/cplus/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/cplus/Makefile.in nspr-4.10.7/nspr/pr/src/cplus/Makefile.in --- nspr-4.9.5/nspr/pr/src/cplus/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,43 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CXXSRCS = \ + rcbase.cpp \ + rccv.cpp \ + rcfileio.cpp \ + rcinrval.cpp \ + rcio.cpp \ + rclock.cpp \ + rcnetdb.cpp \ + rcnetio.cpp \ + rcthread.cpp \ + rctime.cpp \ + $(NULL) + +OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX))) + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +HEADERS = $(wildcard $(srcdir)/*.h) + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcascii.h nspr-4.10.7/nspr/pr/src/cplus/rcascii.h --- nspr-4.9.5/nspr/pr/src/cplus/rcascii.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcascii.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Class definitions to format ASCII data. +*/ + +#if defined(_RCASCII_H) +#else +#define _RCASCII_H + +/* +** RCFormatStuff +** This class maintains no state - that is the responsibility of +** the class' client. For each call to Sx_printf(), the StuffFunction +** will be called for each embedded "%" in the 'fmt' string and once +** for each interveaning literal. +*/ +class PR_IMPLEMENT(RCFormatStuff) +{ +public: + RCFormatStuff(); + virtual ~RCFormatStuff(); + + /* + ** Process the arbitrary argument list using as indicated by + ** the 'fmt' string. Each segment of the processing the stuff + ** function is called with the relavent translation. + */ + virtual PRInt32 Sx_printf(void *state, const char *fmt, ...); + + /* + ** The 'state' argument is not processed by the runtime. It + ** is merely passed from the Sx_printf() call. It is intended + ** to be used by the client to figure out what to do with the + ** new string. + ** + ** The new string ('stuff') is ASCII translation driven by the + ** Sx_printf()'s 'fmt' string. It is not guaranteed to be a null + ** terminated string. + ** + ** The return value is the number of bytes copied from the 'stuff' + ** string. It is accumulated for each of the calls to the stuff + ** function and returned from the original caller of Sx_printf(). + */ + virtual PRSize StuffFunction( + void *state, const char *stuff, PRSize stufflen) = 0; +}; /* RCFormatStuff */ + + +/* +** RCFormatBuffer +** The caller is supplying the buffer, the runtime is doing all +** the conversion. The object contains no state, so is reusable +** and reentrant. +*/ +class PR_IMPLEMENT(RCFormatBuffer): public RCFormatStuff +{ +public: + RCFormatBuffer(); + virtual ~RCFormatBuffer(); + + /* + ** Format the trailing arguments as indicated by the 'fmt' + ** string. Put the result in 'buffer'. Return the number + ** of bytes moved into 'buffer'. 'buffer' will always be + ** a properly terminated string even if the convresion fails. + */ + virtual PRSize Sn_printf( + char *buffer, PRSize length, const char *fmt, ...); + + virtual char *Sm_append(char *buffer, const char *fmt, ...); + +private: + /* + ** This class overrides the stuff function, does not preserve + ** its virtual-ness and no longer allows the clients to call + ** it in the clear. In other words, it is now the implementation + ** for this class. + */ + PRSize StuffFunction(void*, const char*, PRSize); + +}; /* RCFormatBuffer */ + +/* +** RCFormat +** The runtime is supplying the buffer. The object has state - the +** buffer. Each operation must run to completion before the object +** can be reused. When it is, the buffer is reset (whatever that +** means). The result of a conversion is available via the extractor. +** After extracted, the memory still belongs to the class - if the +** caller wants to retain or modify, it must first be copied. +*/ +class PR_IMPLEMENT(RCFormat): pubic RCFormatBuffer +{ +public: + RCFormat(); + virtual ~RCFormat(); + + /* + ** Translate the trailing arguments according to the 'fmt' + ** string and store the results in the object. + */ + virtual PRSize Sm_printf(const char *fmt, ...); + + /* + ** Extract the latest translation. + ** The object does not surrender the memory occupied by + ** the string. If the caller wishes to modify the data, + ** it must first be copied. + */ + const char*(); + +private: + char *buffer; + + RCFormat(const RCFormat&); + RCFormat& operator=(const RCFormat&); +}; /* RCFormat */ + +/* +** RCPrint +** The output is formatted and then written to an associated file +** descriptor. The client can provide a suitable file descriptor +** or can indicate that the output should be directed to one of +** the well-known "console" devices. +*/ +class PR_IMPLEMENT(RCPrint): public RCFormat +{ + virtual ~RCPrint(); + RCPrint(RCIO* output); + RCPrint(RCFileIO::SpecialFile output); + + virtual PRSize Printf(const char *fmt, ...); +private: + RCPrint(); +}; /* RCPrint */ + +#endif /* defined(_RCASCII_H) */ + +/* RCAscii.h */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcbase.cpp nspr-4.10.7/nspr/pr/src/cplus/rcbase.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rcbase.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcbase.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** RCBase.cpp - Mixin class for NSPR C++ wrappers +*/ + +#include "rcbase.h" + +RCBase::~RCBase() { } + +PRSize RCBase::GetErrorTextLength() { return PR_GetErrorTextLength(); } +PRSize RCBase::CopyErrorText(char *text) { return PR_GetErrorText(text); } + +void RCBase::SetError(PRErrorCode error, PRInt32 oserror) + { PR_SetError(error, oserror); } + +void RCBase::SetErrorText(PRSize text_length, const char *text) + { PR_SetErrorText(text_length, text); } + +/* rcbase.cpp */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcbase.h nspr-4.10.7/nspr/pr/src/cplus/rcbase.h --- nspr-4.9.5/nspr/pr/src/cplus/rcbase.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcbase.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** RCBase.h - Mixin class for NSPR C++ wrappers +*/ + +#if defined(_RCRUNTIME_H) +#else +#define _RCRUNTIME_H + +#include + +/* +** Class: RCBase (mixin) +** +** Generally mixed into every base class. The functions in this class are all +** static. Therefore this entire class is just syntatic sugar. It gives the +** illusion that errors (in particular) are retrieved via the same object +** that just reported a failure. It also (unfortunately) might lead one to +** believe that the errors are persistent in that object. They're not. +*/ + +class PR_IMPLEMENT(RCBase) +{ +public: + virtual ~RCBase(); + + static void AbortSelf(); + + static PRErrorCode GetError(); + static PRInt32 GetOSError(); + + static PRSize GetErrorTextLength(); + static PRSize CopyErrorText(char *text); + + static void SetError(PRErrorCode error, PRInt32 oserror); + static void SetErrorText(PRSize textLength, const char *text); + +protected: + RCBase() { } +}; /* RCObject */ + +inline PRErrorCode RCBase::GetError() { return PR_GetError(); } +inline PRInt32 RCBase::GetOSError() { return PR_GetOSError(); } + +#endif /* defined(_RCRUNTIME_H) */ + +/* rcbase.h */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rccv.cpp nspr-4.10.7/nspr/pr/src/cplus/rccv.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rccv.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rccv.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** RCCondition - C++ wrapper around NSPR's PRCondVar +*/ + +#include "rccv.h" + +#include +#include +#include + +RCCondition::RCCondition(class RCLock *lock): RCBase() +{ + cv = PR_NewCondVar(lock->lock); + PR_ASSERT(NULL != cv); + timeout = PR_INTERVAL_NO_TIMEOUT; +} /* RCCondition::RCCondition */ + +RCCondition::~RCCondition() +{ + if (NULL != cv) PR_DestroyCondVar(cv); +} /* RCCondition::~RCCondition */ + +PRStatus RCCondition::Wait() +{ + PRStatus rv; + PR_ASSERT(NULL != cv); + if (NULL == cv) + { + SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; + } + else + rv = PR_WaitCondVar(cv, timeout.interval); + return rv; +} /* RCCondition::Wait */ + +PRStatus RCCondition::Notify() +{ + return PR_NotifyCondVar(cv); +} /* RCCondition::Notify */ + +PRStatus RCCondition::Broadcast() +{ + return PR_NotifyAllCondVar(cv); +} /* RCCondition::Broadcast */ + +PRStatus RCCondition::SetTimeout(const RCInterval& tmo) +{ + if (NULL == cv) + { + SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + timeout = tmo; + return PR_SUCCESS; +} /* RCCondition::SetTimeout */ + +RCInterval RCCondition::GetTimeout() const { return timeout; } + +/* rccv.cpp */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rccv.h nspr-4.10.7/nspr/pr/src/cplus/rccv.h --- nspr-4.9.5/nspr/pr/src/cplus/rccv.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rccv.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** RCCondition - C++ wrapper around NSPR's PRCondVar +** +** Conditions have a notion of timeouts. A thread that waits on a condition +** will resume execution when the condition is notified OR when a specified +** interval of time has expired. +** +** Most applications don't adjust the timeouts on conditions. The literature +** would argue that all threads waiting on a single condition must have the +** same semantics. But if an application wishes to modify the timeout with +** (perhaps) each wait call, that modification should be done consistantly +** and under protection of the condition's associated lock. +** +** The default timeout is infinity. +*/ + +#if defined(_RCCOND_H) +#else +#define _RCCOND_H + +#include "rclock.h" +#include "rcbase.h" +#include "rcinrval.h" + +struct PRCondVar; + +class PR_IMPLEMENT(RCCondition): public RCBase +{ +public: + RCCondition(RCLock*); /* associates CV with a lock and infinite tmo */ + virtual ~RCCondition(); + + virtual PRStatus Wait(); /* applies object's current timeout */ + + virtual PRStatus Notify(); /* perhaps ready one thread */ + virtual PRStatus Broadcast(); /* perhaps ready many threads */ + + virtual PRStatus SetTimeout(const RCInterval&); + /* set object's current timeout value */ + +private: + PRCondVar *cv; + RCInterval timeout; + + RCCondition(); + RCCondition(const RCCondition&); + void operator=(const RCCondition&); + +public: + RCInterval GetTimeout() const; +}; /* RCCondition */ + +inline RCCondition::RCCondition(): RCBase() { } +inline RCCondition::RCCondition(const RCCondition&): RCBase() { } +inline void RCCondition::operator=(const RCCondition&) { } + +#endif /* defined(_RCCOND_H) */ + +/* RCCond.h */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcfileio.cpp nspr-4.10.7/nspr/pr/src/cplus/rcfileio.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rcfileio.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcfileio.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Class implementation for normal and special file I/O (ref: prio.h) +*/ + +#include "rcfileio.h" + +#include + +RCFileIO::RCFileIO(): RCIO(RCIO::file) { } + +RCFileIO::~RCFileIO() { if (NULL != fd) (void)Close(); } + +PRInt64 RCFileIO::Available() + { return fd->methods->available(fd); } + +PRStatus RCFileIO::Close() + { PRStatus rv = fd->methods->close(fd); fd = NULL; return rv; } + +PRStatus RCFileIO::Delete(const char* filename) { return PR_Delete(filename); } + +PRStatus RCFileIO::FileInfo(RCFileInfo* info) const + { return fd->methods->fileInfo64(fd, &info->info); } + +PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo* info) + { return PR_GetFileInfo64(name, &info->info); } + +PRStatus RCFileIO::Fsync() + { return fd->methods->fsync(fd); } + +PRStatus RCFileIO::Open(const char *filename, PRIntn flags, PRIntn mode) +{ + fd = PR_Open(filename, flags, mode); + return (NULL == fd) ? PR_FAILURE : PR_SUCCESS; +} /* RCFileIO::Open */ + +PRInt32 RCFileIO::Read(void *buf, PRSize amount) + { return fd->methods->read(fd, buf, amount); } + +PRInt64 RCFileIO::Seek(PRInt64 offset, RCIO::Whence how) +{ + PRSeekWhence whence; + switch (how) + { + case RCFileIO::set: whence = PR_SEEK_SET; break; + case RCFileIO::current: whence = PR_SEEK_CUR; break; + case RCFileIO::end: whence = PR_SEEK_END; break; + default: whence = (PRSeekWhence)-1; + } + return fd->methods->seek64(fd, offset, whence); +} /* RCFileIO::Seek */ + +PRInt32 RCFileIO::Write(const void *buf, PRSize amount) + { return fd->methods->write(fd, buf, amount); } + +PRInt32 RCFileIO::Writev( + const PRIOVec *iov, PRSize size, const RCInterval& timeout) + { return fd->methods->writev(fd, iov, size, timeout); } + +RCIO *RCFileIO::GetSpecialFile(RCFileIO::SpecialFile special) +{ + PRFileDesc* fd; + PRSpecialFD which; + RCFileIO* spec = NULL; + + switch (special) + { + case RCFileIO::input: which = PR_StandardInput; break; + case RCFileIO::output: which = PR_StandardOutput; break; + case RCFileIO::error: which = PR_StandardError; break; + default: which = (PRSpecialFD)-1; + } + fd = PR_GetSpecialFD(which); + if (NULL != fd) + { + spec = new RCFileIO(); + if (NULL != spec) spec->fd = fd; + } + return spec; +} /* RCFileIO::GetSpecialFile */ + + +/* +** The following methods have been made non-virtual and private. These +** default implementations are intended to NEVER be called. They +** are not valid for this type of I/O class (normal and special file). +*/ +PRStatus RCFileIO::Connect(const RCNetAddr&, const RCInterval&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRStatus RCFileIO::GetLocalName(RCNetAddr*) const +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRStatus RCFileIO::GetPeerName(RCNetAddr*) const +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRStatus RCFileIO::GetSocketOption(PRSocketOptionData*) const +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRStatus RCFileIO::Listen(PRIntn) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRInt16 RCFileIO::Poll(PRInt16, PRInt16*) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return 0; } + +PRInt32 RCFileIO::Recv(void*, PRSize, PRIntn, const RCInterval&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } + +PRInt32 RCFileIO::Recvfrom(void*, PRSize, PRIntn, RCNetAddr*, const RCInterval&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } + +PRInt32 RCFileIO::Send( + const void*, PRSize, PRIntn, const RCInterval&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } + +PRInt32 RCFileIO::Sendto( + const void*, PRSize, PRIntn, const RCNetAddr&, const RCInterval&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } + +RCIO* RCFileIO::Accept(RCNetAddr*, const RCInterval&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return NULL; } + +PRStatus RCFileIO::Bind(const RCNetAddr&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRInt32 RCFileIO::AcceptRead( + RCIO**, RCNetAddr**, void*, PRSize, const RCInterval&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } + +PRStatus RCFileIO::SetSocketOption(const PRSocketOptionData*) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRStatus RCFileIO::Shutdown(RCIO::ShutdownHow) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRInt32 RCFileIO::TransmitFile( + RCIO*, const void*, PRSize, RCIO::FileDisposition, const RCInterval&) +{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } + +/* +** Class implementation for file information object (ref: prio.h) +*/ + +RCFileInfo::~RCFileInfo() { } + +RCFileInfo::RCFileInfo(const RCFileInfo& her): RCBase() + { info = her.info; } /* RCFileInfo::RCFileInfo */ + +RCTime RCFileInfo::CreationTime() const { return RCTime(info.creationTime); } + +RCTime RCFileInfo::ModifyTime() const { return RCTime(info.modifyTime); } + +RCFileInfo::FileType RCFileInfo::Type() const +{ + RCFileInfo::FileType type; + switch (info.type) + { + case PR_FILE_FILE: type = RCFileInfo::file; break; + case PR_FILE_DIRECTORY: type = RCFileInfo::directory; break; + default: type = RCFileInfo::other; + } + return type; +} /* RCFileInfo::Type */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcfileio.h nspr-4.10.7/nspr/pr/src/cplus/rcfileio.h --- nspr-4.9.5/nspr/pr/src/cplus/rcfileio.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcfileio.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Class definitions for normal and special file I/O (ref: prio.h) +*/ + +#if defined(_RCFILEIO_H) +#else +#define _RCFILEIO_H + +#include "rcio.h" +#include "rctime.h" + +/* +** One would normally create a concrete class, such as RCFileIO, but then +** pass around more generic references, ie., RCIO. +** +** This subclass of RCIO hides (makes private) the methods that are not +** applicable to normal files. +*/ + +class RCFileInfo; + +class PR_IMPLEMENT(RCFileIO): public RCIO +{ +public: + RCFileIO(); + virtual ~RCFileIO(); + + virtual PRInt64 Available(); + virtual PRStatus Close(); + static PRStatus Delete(const char *name); + virtual PRStatus FileInfo(RCFileInfo* info) const; + static PRStatus FileInfo(const char *name, RCFileInfo* info); + virtual PRStatus Fsync(); + virtual PRStatus Open(const char *name, PRIntn flags, PRIntn mode); + virtual PRInt32 Read(void *buf, PRSize amount); + virtual PRInt64 Seek(PRInt64 offset, RCIO::Whence how); + virtual PRInt32 Write(const void *buf, PRSize amount); + virtual PRInt32 Writev( + const PRIOVec *iov, PRSize size, + const RCInterval& timeout); + +private: + + /* These methods made private are unavailable for this object */ + RCFileIO(const RCFileIO&); + void operator=(const RCFileIO&); + + RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout); + PRInt32 AcceptRead( + RCIO **newfd, RCNetAddr **address, void *buffer, + PRSize amount, const RCInterval& timeout); + PRStatus Bind(const RCNetAddr& addr); + PRStatus Connect(const RCNetAddr& addr, const RCInterval& timeout); + PRStatus GetLocalName(RCNetAddr *addr) const; + PRStatus GetPeerName(RCNetAddr *addr) const; + PRStatus GetSocketOption(PRSocketOptionData *data) const; + PRStatus Listen(PRIntn backlog); + PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags); + PRInt32 Recv( + void *buf, PRSize amount, PRIntn flags, + const RCInterval& timeout); + PRInt32 Recvfrom( + void *buf, PRSize amount, PRIntn flags, + RCNetAddr* addr, const RCInterval& timeout); + PRInt32 Send( + const void *buf, PRSize amount, PRIntn flags, + const RCInterval& timeout); + PRInt32 Sendto( + const void *buf, PRSize amount, PRIntn flags, + const RCNetAddr& addr, + const RCInterval& timeout); + PRStatus SetSocketOption(const PRSocketOptionData *data); + PRStatus Shutdown(RCIO::ShutdownHow how); + PRInt32 TransmitFile( + RCIO *source, const void *headers, + PRSize hlen, RCIO::FileDisposition flags, + const RCInterval& timeout); +public: + + /* + ** The following function return a valid normal file object, + ** Such objects can be used for scanned input and console output. + */ + typedef enum { + input = PR_StandardInput, + output = PR_StandardOutput, + error = PR_StandardError + } SpecialFile; + + static RCIO *GetSpecialFile(RCFileIO::SpecialFile special); + +}; /* RCFileIO */ + +class PR_IMPLEMENT(RCFileInfo): public RCBase +{ +public: + typedef enum { + file = PR_FILE_FILE, + directory = PR_FILE_DIRECTORY, + other = PR_FILE_OTHER + } FileType; + +public: + RCFileInfo(); + RCFileInfo(const RCFileInfo&); + + virtual ~RCFileInfo(); + + PRInt64 Size() const; + RCTime CreationTime() const; + RCTime ModifyTime() const; + RCFileInfo::FileType Type() const; + +friend PRStatus RCFileIO::FileInfo(RCFileInfo*) const; +friend PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo*); + +private: + PRFileInfo64 info; +}; /* RCFileInfo */ + +inline RCFileInfo::RCFileInfo(): RCBase() { } +inline PRInt64 RCFileInfo::Size() const { return info.size; } + +#endif /* defined(_RCFILEIO_H) */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcinrval.cpp nspr-4.10.7/nspr/pr/src/cplus/rcinrval.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rcinrval.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcinrval.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** C++ interval times (ref: prinrval.h) +** +** An interval is a period of time. The start of the interval (epoch) +** must be defined by the application. The unit of time of an interval +** is platform dependent, therefore so is the maximum interval that is +** representable. However, that interval is never less that ~12 hours. +*/ + +#include "rcinrval.h" + +RCInterval::~RCInterval() { } + +RCInterval::RCInterval(RCInterval::RCReservedInterval special): RCBase() +{ + switch (special) + { + case RCInterval::now: + interval = PR_IntervalNow(); + break; + case RCInterval::no_timeout: + interval = PR_INTERVAL_NO_TIMEOUT; + break; + case RCInterval::no_wait: + interval = PR_INTERVAL_NO_WAIT; + break; + default: + break; + } +} /* RCInterval::RCInterval */ + +/* rcinrval.cpp */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcinrval.h nspr-4.10.7/nspr/pr/src/cplus/rcinrval.h --- nspr-4.9.5/nspr/pr/src/cplus/rcinrval.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcinrval.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,137 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** C++ interval times (ref: prinrval.h) +** +** An interval is a period of time. The start of the interval (epoch) +** must be defined by the application. The unit of time of an interval +** is platform dependent, therefore so is the maximum interval that is +** representable. However, that interval is never less than ~6 hours. +*/ +#if defined(_RCINTERVAL_H) +#else +#define _RCINTERVAL_H + +#include "rcbase.h" +#include + +class PR_IMPLEMENT(RCInterval): public RCBase +{ +public: + typedef enum {now, no_timeout, no_wait} RCReservedInterval; + + virtual ~RCInterval(); + + RCInterval(); + + RCInterval(PRIntervalTime interval); + RCInterval(const RCInterval& copy); + RCInterval(RCReservedInterval special); + + void SetToNow(); + + void operator=(const RCInterval&); + void operator=(PRIntervalTime interval); + + PRBool operator<(const RCInterval&); + PRBool operator>(const RCInterval&); + PRBool operator==(const RCInterval&); + PRBool operator>=(const RCInterval&); + PRBool operator<=(const RCInterval&); + + RCInterval operator+(const RCInterval&); + RCInterval operator-(const RCInterval&); + RCInterval& operator+=(const RCInterval&); + RCInterval& operator-=(const RCInterval&); + + RCInterval operator/(PRUint32); + RCInterval operator*(PRUint32); + RCInterval& operator/=(PRUint32); + RCInterval& operator*=(PRUint32); + + + PRUint32 ToSeconds() const; + PRUint32 ToMilliseconds() const; + PRUint32 ToMicroseconds() const; + operator PRIntervalTime() const; + + static PRIntervalTime FromSeconds(PRUint32 seconds); + static PRIntervalTime FromMilliseconds(PRUint32 milli); + static PRIntervalTime FromMicroseconds(PRUint32 micro); + + friend class RCCondition; + +private: + PRIntervalTime interval; + +}; /* RCInterval */ + + +inline RCInterval::RCInterval(): RCBase() { } + +inline RCInterval::RCInterval(const RCInterval& his): RCBase() + { interval = his.interval; } + +inline RCInterval::RCInterval(PRIntervalTime ticks): RCBase() + { interval = ticks; } + +inline void RCInterval::SetToNow() { interval = PR_IntervalNow(); } + +inline void RCInterval::operator=(const RCInterval& his) + { interval = his.interval; } + +inline void RCInterval::operator=(PRIntervalTime his) + { interval = his; } + +inline PRBool RCInterval::operator==(const RCInterval& his) + { return (interval == his.interval) ? PR_TRUE : PR_FALSE; } +inline PRBool RCInterval::operator<(const RCInterval& his) + { return (interval < his.interval)? PR_TRUE : PR_FALSE; } +inline PRBool RCInterval::operator>(const RCInterval& his) + { return (interval > his.interval) ? PR_TRUE : PR_FALSE; } +inline PRBool RCInterval::operator<=(const RCInterval& his) + { return (interval <= his.interval) ? PR_TRUE : PR_FALSE; } +inline PRBool RCInterval::operator>=(const RCInterval& his) + { return (interval <= his.interval) ? PR_TRUE : PR_FALSE; } + +inline RCInterval RCInterval::operator+(const RCInterval& his) + { return RCInterval((PRIntervalTime)(interval + his.interval)); } +inline RCInterval RCInterval::operator-(const RCInterval& his) + { return RCInterval((PRIntervalTime)(interval - his.interval)); } +inline RCInterval& RCInterval::operator+=(const RCInterval& his) + { interval += his.interval; return *this; } +inline RCInterval& RCInterval::operator-=(const RCInterval& his) + { interval -= his.interval; return *this; } + +inline RCInterval RCInterval::operator/(PRUint32 him) + { return RCInterval((PRIntervalTime)(interval / him)); } +inline RCInterval RCInterval::operator*(PRUint32 him) + { return RCInterval((PRIntervalTime)(interval * him)); } + +inline RCInterval& RCInterval::operator/=(PRUint32 him) + { interval /= him; return *this; } + +inline RCInterval& RCInterval::operator*=(PRUint32 him) + { interval *= him; return *this; } + +inline PRUint32 RCInterval::ToSeconds() const + { return PR_IntervalToSeconds(interval); } +inline PRUint32 RCInterval::ToMilliseconds() const + { return PR_IntervalToMilliseconds(interval); } +inline PRUint32 RCInterval::ToMicroseconds() const + { return PR_IntervalToMicroseconds(interval); } +inline RCInterval::operator PRIntervalTime() const { return interval; } + +inline PRIntervalTime RCInterval::FromSeconds(PRUint32 seconds) + { return PR_SecondsToInterval(seconds); } +inline PRIntervalTime RCInterval::FromMilliseconds(PRUint32 milli) + { return PR_MillisecondsToInterval(milli); } +inline PRIntervalTime RCInterval::FromMicroseconds(PRUint32 micro) + { return PR_MicrosecondsToInterval(micro); } + +#endif /* defined(_RCINTERVAL_H) */ + +/* RCInterval.h */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcio.cpp nspr-4.10.7/nspr/pr/src/cplus/rcio.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rcio.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcio.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,14 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Base class implmenation for I/O (ref: prio.h) +*/ + +#include "rcio.h" + +RCIO::~RCIO() { } + +RCIO::RCIO(RCIO::RCIOType): RCBase() { } diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcio.h nspr-4.10.7/nspr/pr/src/cplus/rcio.h --- nspr-4.9.5/nspr/pr/src/cplus/rcio.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcio.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Base class definitions for I/O (ref: prio.h) +** +** This class is a virtual base class. Construction must be done by a +** subclass, but the I/O operations can be done on a RCIO object reference. +*/ + +#if defined(_RCIO_H) +#else +#define _RCIO_H + +#include "rcbase.h" +#include "rcnetdb.h" +#include "rcinrval.h" + +#include "prio.h" + +class RCFileInfo; + +class PR_IMPLEMENT(RCIO): public RCBase +{ +public: + typedef enum { + open = PR_TRANSMITFILE_KEEP_OPEN, /* socket is left open after file + * is transmitted. */ + close = PR_TRANSMITFILE_CLOSE_SOCKET/* socket is closed after file + * is transmitted. */ + } FileDisposition; + + typedef enum { + set = PR_SEEK_SET, /* Set to value specified */ + current = PR_SEEK_CUR, /* Seek relative to current position */ + end = PR_SEEK_END /* seek past end of current eof */ + } Whence; + + typedef enum { + recv = PR_SHUTDOWN_RCV, /* receives will be disallowed */ + send = PR_SHUTDOWN_SEND, /* sends will be disallowed */ + both = PR_SHUTDOWN_BOTH /* sends & receives will be disallowed */ + } ShutdownHow; + +public: + virtual ~RCIO(); + + virtual RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout) = 0; + virtual PRInt32 AcceptRead( + RCIO **nd, RCNetAddr **raddr, void *buf, + PRSize amount, const RCInterval& timeout) = 0; + virtual PRInt64 Available() = 0; + virtual PRStatus Bind(const RCNetAddr& addr) = 0; + virtual PRStatus Close() = 0; + virtual PRStatus Connect( + const RCNetAddr& addr, + const RCInterval& timeout) = 0; + virtual PRStatus FileInfo(RCFileInfo *info) const = 0; + virtual PRStatus Fsync() = 0; + virtual PRStatus GetLocalName(RCNetAddr *addr) const = 0; + virtual PRStatus GetPeerName(RCNetAddr *addr) const = 0; + virtual PRStatus GetSocketOption(PRSocketOptionData *data) const = 0; + virtual PRStatus Listen(PRIntn backlog) = 0; + virtual PRStatus Open(const char *name, PRIntn flags, PRIntn mode) = 0; + virtual PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags) = 0; + virtual PRInt32 Read(void *buf, PRSize amount) = 0; + virtual PRInt32 Recv( + void *buf, PRSize amount, PRIntn flags, + const RCInterval& timeout) = 0; + virtual PRInt32 Recvfrom( + void *buf, PRSize amount, PRIntn flags, + RCNetAddr* addr, const RCInterval& timeout) = 0; + virtual PRInt64 Seek(PRInt64 offset, Whence how) = 0; + virtual PRInt32 Send( + const void *buf, PRSize amount, PRIntn flags, + const RCInterval& timeout) = 0; + virtual PRInt32 Sendto( + const void *buf, PRSize amount, PRIntn flags, + const RCNetAddr& addr, + const RCInterval& timeout) = 0; + virtual PRStatus SetSocketOption(const PRSocketOptionData *data) = 0; + virtual PRStatus Shutdown(ShutdownHow how) = 0; + virtual PRInt32 TransmitFile( + RCIO *source, const void *headers, + PRSize hlen, RCIO::FileDisposition flags, + const RCInterval& timeout) = 0; + virtual PRInt32 Write(const void *buf, PRSize amount) = 0; + virtual PRInt32 Writev( + const PRIOVec *iov, PRSize size, + const RCInterval& timeout) = 0; + +protected: + typedef enum { + file = PR_DESC_FILE, + tcp = PR_DESC_SOCKET_TCP, + udp = PR_DESC_SOCKET_UDP, + layered = PR_DESC_LAYERED} RCIOType; + + RCIO(RCIOType); + + PRFileDesc *fd; /* where the real code hides */ + +private: + /* no default construction and no copies allowed */ + RCIO(); + RCIO(const RCIO&); + +}; /* RCIO */ + +#endif /* defined(_RCIO_H) */ + +/* RCIO.h */ + + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rclock.cpp nspr-4.10.7/nspr/pr/src/cplus/rclock.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rclock.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rclock.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* +** C++ access to NSPR locks (PRLock) +*/ + +#include "rclock.h" +#include + +RCLock::RCLock() +{ + lock = PR_NewLock(); /* it might be NULL */ + PR_ASSERT(NULL != lock); +} /* RCLock::RCLock */ + +RCLock::~RCLock() +{ + if (NULL != lock) PR_DestroyLock(lock); + lock = NULL; +} /* RCLock::~RCLock */ + +void RCLock::Acquire() +{ + PR_ASSERT(NULL != lock); + PR_Lock(lock); +} /* RCLock::Acquire */ + +void RCLock::Release() +{ + PRStatus rv; + PR_ASSERT(NULL != lock); + rv = PR_Unlock(lock); + PR_ASSERT(PR_SUCCESS == rv); +} /* RCLock::Release */ + +/* RCLock.cpp */ + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rclock.h nspr-4.10.7/nspr/pr/src/cplus/rclock.h --- nspr-4.9.5/nspr/pr/src/cplus/rclock.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rclock.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** C++ access to NSPR locks (PRLock) +*/ + +#if defined(_RCLOCK_H) +#else +#define _RCLOCK_H + +#include "rcbase.h" + +#include + +class PR_IMPLEMENT(RCLock): public RCBase +{ +public: + RCLock(); + virtual ~RCLock(); + + void Acquire(); /* non-reentrant */ + void Release(); /* should be by owning thread */ + + friend class RCCondition; + +private: + RCLock(const RCLock&); /* can't do that */ + void operator=(const RCLock&); /* nor that */ + + PRLock *lock; +}; /* RCLock */ + +/* +** Class: RCEnter +** +** In scope locks. You can only allocate them on the stack. The language +** will insure that they get released (by calling the destructor) when +** the thread leaves scope, even if via an exception. +*/ +class PR_IMPLEMENT(RCEnter) +{ +public: + ~RCEnter(); /* releases the lock */ + RCEnter(RCLock*); /* acquires the lock */ + +private: + RCLock *lock; + + RCEnter(); + RCEnter(const RCEnter&); + void operator=(const RCEnter&); + + void *operator new(PRSize) { return NULL; } + void operator delete(void*) { } +}; /* RCEnter */ + + +inline RCEnter::RCEnter(RCLock* ml) { lock = ml; lock->Acquire(); } +inline RCEnter::~RCEnter() { lock->Release(); lock = NULL; } + +#endif /* defined(_RCLOCK_H) */ + +/* RCLock.h */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcmon.h nspr-4.10.7/nspr/pr/src/cplus/rcmon.h --- nspr-4.9.5/nspr/pr/src/cplus/rcmon.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcmon.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Class: RCMonitor (ref prmonitor.h) +** +** RCMonitor.h - C++ wrapper around NSPR's monitors +*/ +#if defined(_RCMONITOR_H) +#else +#define _RCMONITOR_H + +#include "rcbase.h" +#include "rcinrval.h" + +struct PRMonitor; + +class PR_IMPLEMENT(RCMonitor): public RCBase +{ +public: + RCMonitor(); /* timeout is infinity */ + virtual ~RCMonitor(); + + virtual void Enter(); /* reentrant entry */ + virtual void Exit(); + + virtual void Notify(); /* possibly enable one thread */ + virtual void NotifyAll(); /* enable all waiters */ + + virtual void Wait(); /* applies object's timeout */ + + virtual void SetTimeout(const RCInterval& timeout); + +private: + PRMonitor *monitor; + RCInterval timeout; + +public: + RCInterval GetTimeout() const; /* get the current value */ + +}; /* RCMonitor */ + +#endif /* defined(_RCMONITOR_H) */ + +/* RCMonitor.h */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcnetdb.cpp nspr-4.10.7/nspr/pr/src/cplus/rcnetdb.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rcnetdb.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcnetdb.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,200 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Base class implementation for network access functions (ref: prnetdb.h) +*/ + +#include "rclock.h" +#include "rcnetdb.h" + +#include +#include +#include + +RCNetAddr::RCNetAddr(const RCNetAddr& his): RCBase() + { address = his.address; } + +RCNetAddr::RCNetAddr(const RCNetAddr& his, PRUint16 port): RCBase() +{ + address = his.address; + switch (address.raw.family) + { + case PR_AF_INET: address.inet.port = port; break; + case PR_AF_INET6: address.ipv6.port = port; break; + default: break; + } +} /* RCNetAddr::RCNetAddr */ + +RCNetAddr::RCNetAddr(RCNetAddr::HostValue host, PRUint16 port): RCBase() +{ + PRNetAddrValue how; + switch (host) + { + case RCNetAddr::any: how = PR_IpAddrAny; break; + case RCNetAddr::loopback: how = PR_IpAddrLoopback; break; + default: PR_ASSERT(!"This can't happen -- and did!"); + } + (void)PR_InitializeNetAddr(how, port, &address); +} /* RCNetAddr::RCNetAddr */ + +RCNetAddr::~RCNetAddr() { } + +void RCNetAddr::operator=(const RCNetAddr& his) { address = his.address; } + +PRStatus RCNetAddr::FromString(const char* string) + { return PR_StringToNetAddr(string, &address); } + +void RCNetAddr::operator=(const PRNetAddr* addr) { address = *addr; } + +PRBool RCNetAddr::operator==(const RCNetAddr& his) const +{ + PRBool rv = EqualHost(his); + if (rv) + { + switch (address.raw.family) + { + case PR_AF_INET: + rv = (address.inet.port == his.address.inet.port); break; + case PR_AF_INET6: + rv = (address.ipv6.port == his.address.ipv6.port); break; + case PR_AF_LOCAL: + default: break; + } + } + return rv; +} /* RCNetAddr::operator== */ + +PRBool RCNetAddr::EqualHost(const RCNetAddr& his) const +{ + PRBool rv; + switch (address.raw.family) + { + case PR_AF_INET: + rv = (address.inet.ip == his.address.inet.ip); break; + case PR_AF_INET6: + rv = (0 == memcmp( + &address.ipv6.ip, &his.address.ipv6.ip, + sizeof(address.ipv6.ip))); + break; +#if defined(XP_UNIX) + case PR_AF_LOCAL: + rv = (0 == strncmp( + address.local.path, his.address.local.path, + sizeof(address.local.path))); + break; +#endif + default: break; + } + return rv; +} /* RCNetAddr::operator== */ + +PRStatus RCNetAddr::ToString(char *string, PRSize size) const + { return PR_NetAddrToString(&address, string, size); } + +/* +** RCHostLookup +*/ + +RCHostLookup::~RCHostLookup() +{ + if (NULL != address) delete [] address; +} /* RCHostLookup::~RCHostLookup */ + +RCHostLookup::RCHostLookup(): RCBase() +{ + address = NULL; + max_index = 0; +} /* RCHostLookup::RCHostLookup */ + +PRStatus RCHostLookup::ByName(const char* name) +{ + PRStatus rv; + PRNetAddr addr; + PRHostEnt hostentry; + PRIntn index = 0, max; + RCNetAddr* vector = NULL; + RCNetAddr* old_vector = NULL; + void* buffer = PR_Malloc(PR_NETDB_BUF_SIZE); + if (NULL == buffer) return PR_FAILURE; + rv = PR_GetHostByName(name, (char*)buffer, PR_NETDB_BUF_SIZE, &hostentry); + if (PR_SUCCESS == rv) + { + for (max = 0, index = 0;; ++max) + { + index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); + if (0 == index) break; + } + if (max > 0) + { + vector = new RCNetAddr[max]; + while (--max > 0) + { + index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); + if (0 == index) break; + vector[index] = &addr; + } + { + RCEnter entry(&ml); + old_vector = address; + address = vector; + max_index = max; + } + if (NULL != old_vector) delete [] old_vector; + } + } + if (NULL != buffer) PR_DELETE(buffer); + return PR_SUCCESS; +} /* RCHostLookup::ByName */ + +PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr) +{ + PRStatus rv; + PRNetAddr addr; + PRHostEnt hostentry; + PRIntn index = 0, max; + RCNetAddr* vector = NULL; + RCNetAddr* old_vector = NULL; + char *buffer = (char*)PR_Malloc(PR_NETDB_BUF_SIZE); + if (NULL == buffer) return PR_FAILURE; + rv = PR_GetHostByAddr(host_addr, buffer, PR_NETDB_BUF_SIZE, &hostentry); + if (PR_SUCCESS == rv) + { + for (max = 0, index = 0;; ++max) + { + index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); + if (0 == index) break; + } + if (max > 0) + { + vector = new RCNetAddr[max]; + while (--max > 0) + { + index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); + if (0 == index) break; + vector[index] = &addr; + } + { + RCEnter entry(&ml); + old_vector = address; + address = vector; + max_index = max; + } + if (NULL != old_vector) delete [] old_vector; + } + } + if (NULL != buffer) PR_DELETE(buffer); + return PR_SUCCESS; +} /* RCHostLookup::ByAddress */ + +const RCNetAddr* RCHostLookup::operator[](PRUintn which) +{ + RCNetAddr* addr = NULL; + if (which < max_index) + addr = &address[which]; + return addr; +} /* RCHostLookup::operator[] */ + +/* RCNetdb.cpp */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcnetdb.h nspr-4.10.7/nspr/pr/src/cplus/rcnetdb.h --- nspr-4.9.5/nspr/pr/src/cplus/rcnetdb.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcnetdb.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Base class definitions for network access functions (ref: prnetdb.h) +*/ + +#if defined(_RCNETDB_H) +#else +#define _RCNETDB_H + +#include "rclock.h" +#include "rcbase.h" + +#include + +class PR_IMPLEMENT(RCNetAddr): public RCBase +{ +public: + typedef enum { + any = PR_IpAddrAny, /* assign logical INADDR_ANY */ + loopback = PR_IpAddrLoopback /* assign logical INADDR_LOOPBACK */ + } HostValue; + + RCNetAddr(); /* default constructor is unit'd object */ + RCNetAddr(const RCNetAddr&); /* copy constructor */ + RCNetAddr(HostValue, PRUint16 port);/* init'd w/ 'special' assignments */ + RCNetAddr(const RCNetAddr&, PRUint16 port); + /* copy w/ port reassigment */ + + virtual ~RCNetAddr(); + + void operator=(const RCNetAddr&); + + virtual PRBool operator==(const RCNetAddr&) const; + /* compare of all relavent fields */ + virtual PRBool EqualHost(const RCNetAddr&) const; + /* compare of just host field */ + + +public: + + void operator=(const PRNetAddr*); /* construction from more primitive data */ + operator const PRNetAddr*() const; /* extraction of underlying representation */ + virtual PRStatus FromString(const char* string); + /* initialization from an ASCII string */ + virtual PRStatus ToString(char *string, PRSize size) const; + /* convert internal fromat to a string */ + +private: + + PRNetAddr address; + +}; /* RCNetAddr */ + +/* +** Class: RCHostLookup +** +** Abstractions to look up host names and addresses. +** +** This is a stateful class. One looks up the host by name or by +** address, then enumerates over a possibly empty array of network +** addresses. The storage for the addresses is owned by the class. +*/ + +class RCHostLookup: public RCBase +{ +public: + virtual ~RCHostLookup(); + + RCHostLookup(); + + virtual PRStatus ByName(const char* name); + virtual PRStatus ByAddress(const RCNetAddr&); + + virtual const RCNetAddr* operator[](PRUintn); + +private: + RCLock ml; + PRIntn max_index; + RCNetAddr* address; + + RCHostLookup(const RCHostLookup&); + RCHostLookup& operator=(const RCHostLookup&); +}; + +inline RCNetAddr::RCNetAddr(): RCBase() { } +inline RCNetAddr::operator const PRNetAddr*() const { return &address; } + + +#endif /* defined(_RCNETDB_H) */ + +/* RCNetdb.h */ + + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcnetio.cpp nspr-4.10.7/nspr/pr/src/cplus/rcnetio.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rcnetio.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcnetio.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,163 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Subclass implementation for streamed network I/O (ref: prio.h) +*/ + +#include "rcnetio.h" + +#include + +RCNetStreamIO::~RCNetStreamIO() + { PRStatus rv = (fd->methods->close)(fd); fd = NULL; } + +RCNetStreamIO::RCNetStreamIO(): RCIO(RCIO::tcp) + { fd = PR_NewTCPSocket(); } + +RCNetStreamIO::RCNetStreamIO(PRIntn protocol): RCIO(RCIO::tcp) + { fd = PR_Socket(PR_AF_INET, PR_SOCK_STREAM, protocol); } + +RCIO* RCNetStreamIO::Accept(RCNetAddr* addr, const RCInterval& timeout) +{ + PRNetAddr peer; + RCNetStreamIO* rcio = NULL; + PRFileDesc* newfd = fd->methods->accept(fd, &peer, timeout); + if (NULL != newfd) + { + rcio = new RCNetStreamIO(); + if (NULL != rcio) + { + *addr = &peer; + rcio->fd = newfd; + } + else + (void)(newfd->methods->close)(newfd); + } + return rcio; +} /* RCNetStreamIO::Accept */ + +PRInt32 RCNetStreamIO::AcceptRead( + RCIO **nd, RCNetAddr **raddr, void *buf, + PRSize amount, const RCInterval& timeout) +{ + PRNetAddr *from; + PRFileDesc *accepted; + PRInt32 rv = (fd->methods->acceptread)( + fd, &accepted, &from, buf, amount, timeout); + if (rv >= 0) + { + RCNetStreamIO *ns = new RCNetStreamIO(); + if (NULL != *nd) ns->fd = accepted; + else {PR_Close(accepted); rv = -1; } + *nd = ns; + } + return rv; +} /* RCNetStreamIO::AcceptRead */ + +PRInt64 RCNetStreamIO::Available() + { return (fd->methods->available64)(fd); } + +PRStatus RCNetStreamIO::Bind(const RCNetAddr& addr) + { return (fd->methods->bind)(fd, addr); } + +PRStatus RCNetStreamIO::Connect(const RCNetAddr& addr, const RCInterval& timeout) + { return (fd->methods->connect)(fd, addr, timeout); } + +PRStatus RCNetStreamIO::GetLocalName(RCNetAddr *addr) const +{ + PRNetAddr local; + PRStatus rv = (fd->methods->getsockname)(fd, &local); + if (PR_SUCCESS == rv) *addr = &local; + return rv; +} /* RCNetStreamIO::GetLocalName */ + +PRStatus RCNetStreamIO::GetPeerName(RCNetAddr *addr) const +{ + PRNetAddr peer; + PRStatus rv = (fd->methods->getpeername)(fd, &peer); + if (PR_SUCCESS == rv) *addr = &peer; + return rv; +} /* RCNetStreamIO::GetPeerName */ + +PRStatus RCNetStreamIO::GetSocketOption(PRSocketOptionData *data) const + { return (fd->methods->getsocketoption)(fd, data); } + +PRStatus RCNetStreamIO::Listen(PRIntn backlog) + { return (fd->methods->listen)(fd, backlog); } + +PRInt16 RCNetStreamIO::Poll(PRInt16 in_flags, PRInt16 *out_flags) + { return (fd->methods->poll)(fd, in_flags, out_flags); } + +PRInt32 RCNetStreamIO::Read(void *buf, PRSize amount) + { return (fd->methods->read)(fd, buf, amount); } + +PRInt32 RCNetStreamIO::Recv( + void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout) + { return (fd->methods->recv)(fd, buf, amount, flags, timeout); } + +PRInt32 RCNetStreamIO::Recvfrom( + void *buf, PRSize amount, PRIntn flags, + RCNetAddr* addr, const RCInterval& timeout) +{ + PRNetAddr peer; + PRInt32 rv = (fd->methods->recvfrom)( + fd, buf, amount, flags, &peer, timeout); + if (-1 != rv) *addr = &peer; + return rv; +} /* RCNetStreamIO::Recvfrom */ + +PRInt32 RCNetStreamIO::Send( + const void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout) + { return (fd->methods->send)(fd, buf, amount, flags, timeout); } + +PRInt32 RCNetStreamIO::Sendto( + const void *buf, PRSize amount, PRIntn flags, + const RCNetAddr& addr, const RCInterval& timeout) + { return (fd->methods->sendto)(fd, buf, amount, flags, addr, timeout); } + +PRStatus RCNetStreamIO::SetSocketOption(const PRSocketOptionData *data) + { return (fd->methods->setsocketoption)(fd, data); } + +PRStatus RCNetStreamIO::Shutdown(RCIO::ShutdownHow how) + { return (fd->methods->shutdown)(fd, (PRIntn)how); } + +PRInt32 RCNetStreamIO::TransmitFile( + RCIO *source, const void *headers, PRSize hlen, + RCIO::FileDisposition flags, const RCInterval& timeout) +{ + RCNetStreamIO *src = (RCNetStreamIO*)source; + return (fd->methods->transmitfile)( + fd, src->fd, headers, hlen, (PRTransmitFileFlags)flags, timeout); } + +PRInt32 RCNetStreamIO::Write(const void *buf, PRSize amount) + { return (fd->methods->write)(fd, buf, amount); } + +PRInt32 RCNetStreamIO::Writev( + const PRIOVec *iov, PRSize size, const RCInterval& timeout) + { return (fd->methods->writev)(fd, iov, size, timeout); } + +/* +** Invalid functions +*/ + +PRStatus RCNetStreamIO::Close() + { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRStatus RCNetStreamIO::FileInfo(RCFileInfo*) const + { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRStatus RCNetStreamIO::Fsync() + { return (fd->methods->fsync)(fd); } + +PRStatus RCNetStreamIO::Open(const char*, PRIntn, PRIntn) + { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +PRInt64 RCNetStreamIO::Seek(PRInt64, RCIO::Whence) + { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; } + +/* RCNetStreamIO.cpp */ + + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcnetio.h nspr-4.10.7/nspr/pr/src/cplus/rcnetio.h --- nspr-4.9.5/nspr/pr/src/cplus/rcnetio.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcnetio.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Subclass definitions for network I/O (ref: prio.h) +*/ + +#if defined(_RCNETIO_H) +#else +#define _RCNETIO_H + +#include "rcbase.h" +#include "rcinrval.h" +#include "rcio.h" +#include "rcnetdb.h" + +#include "prio.h" + +class RCFileInfo; + +/* +** Class: RCNetStreamIO (ref prio.h) +** +** Streamed (reliable) network I/O (e.g., TCP). +** This class hides (makes private) the functions that are not applicable +** to network I/O (i.e., those for file I/O). +*/ + +class PR_IMPLEMENT(RCNetStreamIO): public RCIO +{ + +public: + RCNetStreamIO(); + virtual ~RCNetStreamIO(); + + virtual RCIO* Accept(RCNetAddr* addr, const RCInterval& timeout); + virtual PRInt32 AcceptRead( + RCIO **nd, RCNetAddr **raddr, void *buf, + PRSize amount, const RCInterval& timeout); + virtual PRInt64 Available(); + virtual PRStatus Bind(const RCNetAddr& addr); + virtual PRStatus Connect( + const RCNetAddr& addr, const RCInterval& timeout); + virtual PRStatus GetLocalName(RCNetAddr *addr) const; + virtual PRStatus GetPeerName(RCNetAddr *addr) const; + virtual PRStatus GetSocketOption(PRSocketOptionData *data) const; + virtual PRStatus Listen(PRIntn backlog); + virtual PRInt16 Poll(PRInt16 in_flags, PRInt16 *out_flags); + virtual PRInt32 Read(void *buf, PRSize amount); + virtual PRInt32 Recv( + void *buf, PRSize amount, PRIntn flags, + const RCInterval& timeout); + virtual PRInt32 Recvfrom( + void *buf, PRSize amount, PRIntn flags, + RCNetAddr* addr, const RCInterval& timeout); + virtual PRInt32 Send( + const void *buf, PRSize amount, PRIntn flags, + const RCInterval& timeout); + virtual PRInt32 Sendto( + const void *buf, PRSize amount, PRIntn flags, + const RCNetAddr& addr, + const RCInterval& timeout); + virtual PRStatus SetSocketOption(const PRSocketOptionData *data); + virtual PRStatus Shutdown(ShutdownHow how); + virtual PRInt32 TransmitFile( + RCIO *source, const void *headers, + PRSize hlen, RCIO::FileDisposition flags, + const RCInterval& timeout); + virtual PRInt32 Write(const void *buf, PRSize amount); + virtual PRInt32 Writev( + const PRIOVec *iov, PRSize size, + const RCInterval& timeout); + +private: + /* functions unavailable to this clients of this class */ + RCNetStreamIO(const RCNetStreamIO&); + + PRStatus Close(); + PRStatus Open(const char *name, PRIntn flags, PRIntn mode); + PRStatus FileInfo(RCFileInfo *info) const; + PRStatus Fsync(); + PRInt64 Seek(PRInt64 offset, RCIO::Whence how); + +public: + RCNetStreamIO(PRIntn protocol); +}; /* RCNetIO */ + +#endif /* defined(_RCNETIO_H) */ + +/* RCNetStreamIO.h */ + + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcthread.cpp nspr-4.10.7/nspr/pr/src/cplus/rcthread.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rcthread.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcthread.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* RCThread.cpp - C++ wrapper on NSPR */ + +#include "rcthread.h" +#include "rcinrval.h" + +#include +#include +#include +#include + +static RCPrimordialThread *primordial = NULL; + +void nas_Root(void *arg) +{ + RCThread *him = (RCThread*)arg; + while (RCThread::ex_unstarted == him->execution) + (void)PR_Sleep(PR_INTERVAL_NO_TIMEOUT); /* wait for Start() */ + him->RootFunction(); /* he gets a self reference */ + if (PR_UNJOINABLE_THREAD == PR_GetThreadState(him->identity)) + delete him; +} /* nas_Root */ + +RCThread::~RCThread() { } + +RCThread::RCThread(): RCBase() { } + +RCThread::RCThread(const RCThread&): RCBase() +{ + PR_NOT_REACHED("Cannot call thread copy constructor"); +} /* RCThread::RCThread */ + +RCThread::RCThread( + RCThread::Scope scope, RCThread::State join, PRUint32 stackSize): + RCBase() +{ + execution = ex_unstarted; + identity = PR_CreateThread( + PR_USER_THREAD, nas_Root, this, + PR_GetThreadPriority(PR_GetCurrentThread()), + (PRThreadScope)scope, (PRThreadState)join, stackSize); +} /* RCThread::RCThread */ + +void RCThread::operator=(const RCThread&) +{ + PR_NOT_REACHED("Cannot call thread assignment operator"); +} /* RCThread::operator= */ + + +PRStatus RCThread::Start() +{ + PRStatus rv; + /* This is an unsafe check, but not too critical */ + if (RCThread::ex_unstarted == execution) + { + execution = RCThread::ex_started; + rv = PR_Interrupt(identity); + PR_ASSERT(PR_SUCCESS == rv); + } + else + { + rv = PR_FAILURE; + PR_SetError(PR_INVALID_STATE_ERROR, 0); + } + return rv; +} /* RCThread::Start */ + +PRStatus RCThread::Join() +{ + PRStatus rv; + if (RCThread::ex_unstarted == execution) + { + rv = PR_FAILURE; + PR_SetError(PR_INVALID_STATE_ERROR, 0); + } + else rv = PR_JoinThread(identity); + if (PR_SUCCESS == rv) delete this; + return rv; +} /* RCThread::Join */ + +PRStatus RCThread::Interrupt() +{ + PRStatus rv; + if (RCThread::ex_unstarted == execution) + { + rv = PR_FAILURE; + PR_SetError(PR_INVALID_STATE_ERROR, 0); + } + else rv = PR_Interrupt(identity); + return rv; +} /* RCThread::Interrupt */ + +void RCThread::ClearInterrupt() { PR_ClearInterrupt(); } + +void RCThread::SetPriority(RCThread::Priority new_priority) + { PR_SetThreadPriority(identity, (PRThreadPriority)new_priority); } + +PRThread *RCThread::Self() + { return PR_GetCurrentThread(); } + +RCThread::Scope RCThread::GetScope() const + { return (RCThread::Scope)PR_GetThreadScope(identity); } + +RCThread::State RCThread::GetState() const + { return (RCThread::State)PR_GetThreadState(identity); } + +RCThread::Priority RCThread::GetPriority() const + { return (RCThread::Priority)PR_GetThreadPriority(identity); } + +static void _rc_PDDestructor(RCThreadPrivateData* privateData) +{ + PR_ASSERT(NULL != privateData); + privateData->Release(); +} + +static PRThreadPrivateDTOR _tpd_dtor = (PRThreadPrivateDTOR)_rc_PDDestructor; + +PRStatus RCThread::NewPrivateIndex(PRUintn* index) + { return PR_NewThreadPrivateIndex(index, _tpd_dtor); } + +PRStatus RCThread::SetPrivateData(PRUintn index) + { return PR_SetThreadPrivate(index, NULL); } + +PRStatus RCThread::SetPrivateData(PRUintn index, RCThreadPrivateData* data) +{ + return PR_SetThreadPrivate(index, data); +} + +RCThreadPrivateData* RCThread::GetPrivateData(PRUintn index) + { return (RCThreadPrivateData*)PR_GetThreadPrivate(index); } + +PRStatus RCThread::Sleep(const RCInterval& ticks) + { PRIntervalTime tmo = ticks; return PR_Sleep(tmo); } + +RCPrimordialThread *RCThread::WrapPrimordialThread() +{ + /* + ** This needs to take more care in insuring that the thread + ** being wrapped is really the primordial thread. This code + ** is assuming that the caller is the primordial thread, and + ** there's nothing to insure that. + */ + if (NULL == primordial) + { + /* it doesn't have to be perfect */ + RCPrimordialThread *me = new RCPrimordialThread(); + PR_ASSERT(NULL != me); + if (NULL == primordial) + { + primordial = me; + me->execution = RCThread::ex_started; + me->identity = PR_GetCurrentThread(); + } + else delete me; /* somebody beat us to it */ + } + return primordial; +} /* RCThread::WrapPrimordialThread */ + +RCPrimordialThread::RCPrimordialThread(): RCThread() { } + +RCPrimordialThread::~RCPrimordialThread() { } + +void RCPrimordialThread::RootFunction() +{ + PR_NOT_REACHED("Primordial thread calling root function"); +} /* RCPrimordialThread::RootFunction */ + +PRStatus RCPrimordialThread::Cleanup() { return PR_Cleanup(); } + +PRStatus RCPrimordialThread::SetVirtualProcessors(PRIntn count) +{ + PR_SetConcurrency(count); + return PR_SUCCESS; +} /* SetVirutalProcessors */ + +RCThreadPrivateData::RCThreadPrivateData() { } + +RCThreadPrivateData::RCThreadPrivateData( + const RCThreadPrivateData& him) { } + +RCThreadPrivateData::~RCThreadPrivateData() { } + +/* RCThread.c */ + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rcthread.h nspr-4.10.7/nspr/pr/src/cplus/rcthread.h --- nspr-4.9.5/nspr/pr/src/cplus/rcthread.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rcthread.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* RCThread.h */ + +#if defined(_RCTHREAD_H) +#else +#define _RCTHREAD_H + +#include "rcbase.h" + +#include + +class RCInterval; + +class PR_IMPLEMENT(RCThreadPrivateData) +{ +public: + RCThreadPrivateData(); + RCThreadPrivateData(const RCThreadPrivateData&); + + virtual ~RCThreadPrivateData(); + + virtual void Release() = 0; + +}; /* RCThreadPrivateData */ + +class PR_IMPLEMENT(RCThread): public RCBase +{ +public: + + typedef enum + { + local = PR_LOCAL_THREAD, global = PR_GLOBAL_THREAD + } Scope; + + typedef enum + { + joinable = PR_JOINABLE_THREAD, unjoinable = PR_UNJOINABLE_THREAD + } State; + + typedef enum + { + first = PR_PRIORITY_FIRST, + low = PR_PRIORITY_LOW, + normal = PR_PRIORITY_NORMAL, + high = PR_PRIORITY_HIGH, + urgent = PR_PRIORITY_URGENT, + last = PR_PRIORITY_LAST + } Priority; + + /* + * Create a new thread, providing scope and joinability state. + */ + RCThread(Scope scope, State state, PRUint32 stackSize=0); + + /* + * New threads are created in a suspended state. It must be 'started" + * before it begins execution in the class' defined 'RootFunction()'. + */ + virtual PRStatus Start(); + + /* + * If a thread is created joinable, then the thread's object exists + * until join is called. The thread that calls join will block until + * the target thread returns from it's root function. + */ + virtual PRStatus Join(); + + /* + * The priority of a newly created thread is the same as the creator. + * The priority may be changed either by the new thread itself, by + * the creator or any other arbitrary thread. + */ + virtual void SetPriority(Priority newPriority); + + + /* + * Interrupt another thread, causing it to stop what it + * is doing and return with a well known error code. + */ + virtual PRStatus Interrupt(); + + /* + * And in case a thread was interrupted and didn't get a chance + * to have the notification delivered, a way to cancel the pending + * status. + */ + static void ClearInterrupt(); + + /* + * Methods to discover the attributes of an existing thread. + */ + static PRThread *Self(); + Scope GetScope() const; + State GetState() const; + Priority GetPriority() const; + + /* + * Thread private data + */ + static PRStatus NewPrivateIndex(PRUintn* index); + + /* + * Getting it - if you want to modify, make a copy + */ + static RCThreadPrivateData* GetPrivateData(PRUintn index); + + /* + * Setting it to - deletes existing data + */ + static PRStatus SetPrivateData(PRUintn index); + + /* + * Setting it - runtime will make a copy, freeing old iff necessary + */ + static PRStatus SetPrivateData(PRUintn index, RCThreadPrivateData* data); + + /* + * Scheduling control + */ + static PRStatus Sleep(const RCInterval& ticks); + + friend void nas_Root(void*); + friend class RCPrimordialThread; +protected: + + /* + * The instantiator of a class must not call the destructor. The base + * implementation of Join will, and if the thread is created unjoinable, + * then the code that called the RootFunction will call the desctructor. + */ + virtual ~RCThread(); + +private: + + /* + * This is where a newly created thread begins execution. Returning + * from this function is equivalent to terminating the thread. + */ + virtual void RootFunction() = 0; + + PRThread *identity; + + /* Threads are unstarted until started - pretty startling */ + enum {ex_unstarted, ex_started} execution; + + /* There is no public default constructor or copy constructor */ + RCThread(); + RCThread(const RCThread&); + + /* And there is no assignment operator */ + void operator=(const RCThread&); + +public: + static RCPrimordialThread *WrapPrimordialThread(); + + }; + +/* +** class RCPrimordialThread +*/ +class PR_IMPLEMENT(RCPrimordialThread): public RCThread +{ +public: + /* + ** The primordial thread can (optionally) wait for all created + ** threads to terminate before allowing the process to exit. + ** Not calling Cleanup() before returning from main() will cause + ** the immediate termination of the entire process, including + ** any running threads. + */ + static PRStatus Cleanup(); + + /* + ** Only the primordial thread is allowed to adjust the number of + ** virtual processors of the runtime. It's a lame security thing. + */ + static PRStatus SetVirtualProcessors(PRIntn count=10); + +friend class RCThread; +private: + /* + ** None other than the runtime can create of destruct + ** a primordial thread. It is fabricated by the runtime + ** to wrap the thread that initiated the application. + */ + RCPrimordialThread(); + ~RCPrimordialThread(); + void RootFunction(); +}; /* RCPrimordialThread */ + + #endif /* defined(_RCTHREAD_H) */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rctime.cpp nspr-4.10.7/nspr/pr/src/cplus/rctime.cpp --- nspr-4.9.5/nspr/pr/src/cplus/rctime.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rctime.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Class implementation for calendar time routines (ref: prtime.h) +*/ + +#include "rctime.h" + +RCTime::~RCTime() { } + +RCTime::RCTime(PRTime time): RCBase() { gmt = time; } +RCTime::RCTime(const RCTime& his): RCBase() { gmt = his.gmt; } +RCTime::RCTime(RCTime::Current): RCBase() { gmt = PR_Now(); } +RCTime::RCTime(const PRExplodedTime& time): RCBase() +{ gmt = PR_ImplodeTime(&time); } + +void RCTime::operator=(const PRExplodedTime& time) +{ gmt = PR_ImplodeTime(&time); } + +RCTime RCTime::operator+(const RCTime& his) +{ RCTime sum(gmt + his.gmt); return sum; } + +RCTime RCTime::operator-(const RCTime& his) +{ RCTime difference(gmt - his.gmt); return difference; } + +RCTime RCTime::operator/(PRUint64 his) +{ RCTime quotient(gmt / gmt); return quotient; } + +RCTime RCTime::operator*(PRUint64 his) +{ RCTime product(gmt * his); return product; } + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/rctime.h nspr-4.10.7/nspr/pr/src/cplus/rctime.h --- nspr-4.9.5/nspr/pr/src/cplus/rctime.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/rctime.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Class definitions for calendar time routines (ref: prtime.h) +*/ + +#if defined(_RCTIME_H) +#else +#define _RCTIME_H + +#include "rcbase.h" + +#include + +/* +** Class: RCTime (ref: prtime.h) +** +** RCTimes are objects that are intended to be used to represent calendar +** times. They maintain units internally as microseconds since the defined +** epoch (midnight, January 1, 1970, GMT). Conversions to and from external +** formats (PRExplodedTime) are available. +** +** In general, NCTimes possess normal algebretic capabilities. +*/ + +class PR_IMPLEMENT(RCTime): public RCBase +{ +public: + typedef enum {now} Current; + + RCTime(); /* leaves the object unitialized */ + RCTime(Current); /* initializes to current system time */ + RCTime(const RCTime&); /* copy constructor */ + RCTime(const PRExplodedTime&); /* construction from exploded representation */ + + virtual ~RCTime(); + + /* assignment operators */ + void operator=(const RCTime&); + void operator=(const PRExplodedTime&); + + /* comparitive operators */ + PRBool operator<(const RCTime&); + PRBool operator>(const RCTime&); + PRBool operator<=(const RCTime&); + PRBool operator>=(const RCTime&); + PRBool operator==(const RCTime&); + + /* associative operators */ + RCTime operator+(const RCTime&); + RCTime operator-(const RCTime&); + RCTime& operator+=(const RCTime&); + RCTime& operator-=(const RCTime&); + + /* multiply and divide operators */ + RCTime operator/(PRUint64); + RCTime operator*(PRUint64); + RCTime& operator/=(PRUint64); + RCTime& operator*=(PRUint64); + + void Now(); /* assign current time to object */ + +private: + PRTime gmt; + +public: + + RCTime(PRTime); /* construct from raw PRTime */ + void operator=(PRTime); /* assign from raw PRTime */ + operator PRTime() const; /* extract internal representation */ +}; /* RCTime */ + +inline RCTime::RCTime(): RCBase() { } + +inline void RCTime::Now() { gmt = PR_Now(); } +inline RCTime::operator PRTime() const { return gmt; } + +inline void RCTime::operator=(PRTime his) { gmt = his; } +inline void RCTime::operator=(const RCTime& his) { gmt = his.gmt; } + +inline PRBool RCTime::operator<(const RCTime& his) + { return (gmt < his.gmt) ? PR_TRUE : PR_FALSE; } +inline PRBool RCTime::operator>(const RCTime& his) + { return (gmt > his.gmt) ? PR_TRUE : PR_FALSE; } +inline PRBool RCTime::operator<=(const RCTime& his) + { return (gmt <= his.gmt) ? PR_TRUE : PR_FALSE; } +inline PRBool RCTime::operator>=(const RCTime& his) + { return (gmt >= his.gmt) ? PR_TRUE : PR_FALSE; } +inline PRBool RCTime::operator==(const RCTime& his) + { return (gmt == his.gmt) ? PR_TRUE : PR_FALSE; } + +inline RCTime& RCTime::operator+=(const RCTime& his) + { gmt += his.gmt; return *this; } +inline RCTime& RCTime::operator-=(const RCTime& his) + { gmt -= his.gmt; return *this; } +inline RCTime& RCTime::operator/=(PRUint64 his) + { gmt /= his; return *this; } +inline RCTime& RCTime::operator*=(PRUint64 his) + { gmt *= his; return *this; } + +#endif /* defined(_RCTIME_H) */ + +/* RCTime.h */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/.cvsignore nspr-4.10.7/nspr/pr/src/cplus/tests/.cvsignore --- nspr-4.9.5/nspr/pr/src/cplus/tests/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/fileio.cpp nspr-4.10.7/nspr/pr/src/cplus/tests/fileio.cpp --- nspr-4.9.5/nspr/pr/src/cplus/tests/fileio.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/fileio.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* fileio.cpp - a test program */ + +#include "rcfileio.h" + +#include +#include + +#define DEFAULT_ITERATIONS 100 + +PRIntn main(PRIntn argc, char **argv) +{ + PRStatus rv; + RCFileIO fd; + RCFileInfo info; + rv = fd.Open("filio.dat", PR_CREATE_FILE, 0666); + PR_ASSERT(PR_SUCCESS == rv); + rv = fd.FileInfo(&info); + PR_ASSERT(PR_SUCCESS == rv); + rv = fd.Delete("filio.dat"); + PR_ASSERT(PR_SUCCESS == rv); + fd.Close(); + PR_ASSERT(PR_SUCCESS == rv); + + return 0; +} /* main */ + +/* interval.cpp */ + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/interval.cpp nspr-4.10.7/nspr/pr/src/cplus/tests/interval.cpp --- nspr-4.9.5/nspr/pr/src/cplus/tests/interval.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/interval.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* interval.cpp - a test program */ + +#include "rclock.h" +#include "rcthread.h" +#include "rcinrval.h" +#include "rccv.h" + +#include +#include +#include + +#define DEFAULT_ITERATIONS 100 + +PRIntn main(PRIntn argc, char **argv) +{ + RCLock ml; + PRStatus rv; + RCCondition cv(&ml); + + RCInterval now, timeout, epoch, elapsed; + PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput); + PRIntn msecs, seconds, loops, iterations = DEFAULT_ITERATIONS; + + /* slow, agonizing waits */ + for (seconds = 0; seconds < 10; ++seconds) + { + timeout = RCInterval::FromSeconds(seconds); + cv.SetTimeout(timeout); + { + RCEnter lock(&ml); + + epoch.SetToNow(); + + rv = cv.Wait(); + PR_ASSERT(PR_SUCCESS == rv); + + now = RCInterval(RCInterval::now); + elapsed = now - epoch; + } + + PR_fprintf( + output, "Waiting %u seconds took %s%u milliseconds\n", + seconds, ((elapsed < timeout)? "**" : ""), + elapsed.ToMilliseconds()); + } + + /* more slow, agonizing sleeps */ + for (seconds = 0; seconds < 10; ++seconds) + { + timeout = RCInterval::FromSeconds(seconds); + { + epoch.SetToNow(); + + rv = RCThread::Sleep(timeout); + PR_ASSERT(PR_SUCCESS == rv); + + now = RCInterval(RCInterval::now); + elapsed = now - epoch; + } + + PR_fprintf( + output, "Sleeping %u seconds took %s%u milliseconds\n", + seconds, ((elapsed < timeout)? "**" : ""), + elapsed.ToMilliseconds()); + } + + /* fast, spritely little devils */ + for (msecs = 10; msecs < 100; msecs += 10) + { + timeout = RCInterval::FromMilliseconds(msecs); + cv.SetTimeout(timeout); + { + RCEnter lock(&ml); + + epoch.SetToNow(); + + for (loops = 0; loops < iterations; ++loops) + { + rv = cv.Wait(); + PR_ASSERT(PR_SUCCESS == rv); + } + + now = RCInterval(RCInterval::now); + elapsed = now - epoch; + } + elapsed /= iterations; + + PR_fprintf( + output, "Waiting %u msecs took %s%u milliseconds average\n", + msecs, ((elapsed < timeout)? "**" : ""), elapsed.ToMilliseconds()); + } + return 0; +} /* main */ + +/* interval.cpp */ + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/Makefile.in nspr-4.10.7/nspr/pr/src/cplus/tests/Makefile.in --- nspr-4.9.5/nspr/pr/src/cplus/tests/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,221 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +ifeq ($(OS_TARGET), WIN16) +OS_CFLAGS = $(OS_EXE_CFLAGS) +endif + +CXXSRCS = \ + ranfile.cpp \ + thread.cpp \ + interval.cpp \ + time.cpp \ + fileio.cpp \ + switch.cpp \ + tpd.cpp \ + $(NULL) + +OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX))) + +ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) +PROG_SUFFIX = .exe +else +PROG_SUFFIX = +endif + +PROGS = $(addprefix $(OBJDIR)/, $(CXXSRCS:.cpp=$(PROG_SUFFIX))) + +TARGETS = $(PROGS) $(OBJS) + +INCLUDES = -I.. -I$(dist_includedir) + +# Setting the variables LDOPTS and LIBPR. We first initialize +# them to the default values, then adjust them for some platforms. +LDOPTS = -L$(dist_libdir) +LIBPR = -lnspr$(MOD_MAJOR_VERSION) +LIBPL = -lplc$(MOD_MAJOR_VERSION) + +ifeq ($(OS_ARCH), IRIX) + LDOPTS += -rpath $(PWD)/$(dist_libdir) -rdata_shared + # For 6.x machines, include this flag + ifeq ($(basename $(OS_RELEASE)),6) + ifeq ($(USE_N32),1) + LDOPTS += -n32 + else + LDOPTS += -32 + endif + + ifeq ($(USE_PTHREADS), 1) + ifeq ($(OS_RELEASE), 6.2) + LDOPTS += -Wl,-woff,85 + endif + endif + endif +endif + +# Solaris +ifeq ($(OS_ARCH), SunOS) + ifdef NS_USE_GCC + LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir) + else + LDOPTS += -R $(PWD)/$(dist_libdir) + endif + +# SunOS 5.5 needs to link with -lpthread, even though we already +# linked with this system library when we built libnspr.so. + ifeq ($(OS_RELEASE), 5.5) + ifdef USE_PTHREADS + EXTRA_LIBS = -lpthread + endif + endif +endif # SunOS + +ifeq ($(OS_ARCH), WINNT) +ifeq ($(OS_TARGET), WIN16) + LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib + LIBPL = $(dist_libdir)/plc$(MOD_MAJOR_VERSION).lib +else + LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO + LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) + LIBPL = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX) +endif +endif + +ifeq ($(OS_ARCH),OS2) +LDOPTS += -Zomf -Zlinker /PM:VIO -lstdcpp +endif + +ifneq ($(OS_ARCH), WINNT) +PWD = $(shell pwd) +endif + +ifeq ($(OS_ARCH), OSF1) +LDOPTS += -rpath $(PWD)/$(dist_libdir) +endif + +ifeq ($(OS_ARCH), HP-UX) + LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir) +endif + +# AIX +ifeq ($(OS_ARCH),AIX) + LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib + ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1) + LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr + LIBPLC = -lplc$(MOD_MAJOR_VERSION)_shr + else + LDOPTS += -brtl + EXTRA_LIBS = -ldl + endif +endif + +ifeq ($(OS_ARCH), Linux) + ifeq ($(OS_RELEASE), 1.2) + EXTRA_LIBS = -ldl + else + LDOPTS += -Xlinker -rpath $(PWD)/$(dist_libdir) + ifeq ($(USE_PTHREADS),1) + EXTRA_LIBS = -lpthread + endif + endif +endif + +ifeq ($(OS_ARCH), SCO_SV) +# SCO Unix needs to link against -lsocket again even though we +# already linked with these system libraries when we built libnspr.so. +EXTRA_LIBS = -lsocket +# This hardcodes in the executable programs the directory to find +# libnspr.so etc. at program startup. Equivalent to the -R or -rpath +# option for ld on other platforms. +export LD_RUN_PATH = $(PWD)/$(dist_libdir) +endif + +ifeq ($(OS_ARCH), UNIXWARE) +export LD_RUN_PATH = $(PWD)/$(dist_libdir) +endif + +##################################################### +# +# The rules +# +##################################################### + +include $(topsrcdir)/config/rules.mk + +AIX_PRE_4_2 = 0 +ifeq ($(OS_ARCH),AIX) +ifneq ($(OS_RELEASE),4.2) +ifneq ($(USE_PTHREADS), 1) +#AIX_PRE_4_2 = 1 +endif +endif +endif + +ifeq ($(AIX_PRE_4_2),1) + +# AIX releases prior to 4.2 need a special two-step linking hack +# in order to both override the system select() and be able to +# get at the original system select(). +# +# We use a pattern rule in ns/nspr20/config/rules.mk to generate +# the .$(OBJ_SUFFIX) file from the .c source file, then do the +# two-step linking hack below. + +$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) + rm -f $@ $(AIX_TMP) + $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a + $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) + rm -f $(AIX_TMP) + +else + +# All platforms that are not AIX pre-4.2. + +$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH), WINNT) +ifeq ($(OS_TARGET),WIN16) + echo system windows >w16link + echo option map >>w16link + echo option stack=10K >>w16link + echo option heapsize=32K >>w16link + echo debug $(DEBUGTYPE) all >>w16link + echo name $@ >>w16link + echo file >>w16link + echo $< >>w16link + echo library >>w16link + echo $(LIBPR), >>w16link + echo $(LIBPL), >>w16link + echo winsock.lib >>w16link + wlink @w16link. +else + link $(LDOPTS) $< $(LIBPR) $(LIBPL) ws2_32.lib -out:$@ +endif +else +ifeq ($(OS_ARCH),OS2) + $(LINK) $(LDOPTS) $< $(LIBGC) $(LIBPLC) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS) -o $@ +else + $(CCC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPL) $(EXTRA_LIBS) -o $@ +endif +endif +endif + +export:: $(TARGETS) +clean:: + rm -f $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/ranfile.cpp nspr-4.10.7/nspr/pr/src/cplus/tests/ranfile.cpp --- nspr-4.9.5/nspr/pr/src/cplus/tests/ranfile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/ranfile.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,400 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Contact: AOF +** +** Name: ranfile.c +** +** Description: Test to hammer on various components of NSPR +** Modification History: +** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include +#include +#include + +#include "rccv.h" +#include "rcthread.h" +#include "rcfileio.h" +#include "rclock.h" + +#include +#include +#include + +static PRFileDesc *output; +static PRIntn debug_mode = 0; +static PRIntn failed_already = 0; + +class HammerData +{ +public: + typedef enum { + sg_go, sg_stop, sg_done} Action; + typedef enum { + sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem; + + virtual ~HammerData(); + HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip); + virtual PRUint32 Random(); + + Action action; + Problem problem; + PRUint32 writes; + RCInterval timein; +friend class Hammer; +private: + RCLock *ml; + RCCondition *cv; + PRUint32 limit; + + PRFloat64 seed; +}; /* HammerData */ + +class Hammer: public HammerData, public RCThread +{ +public: + virtual ~Hammer(); + Hammer(RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip); + +private: + void RootFunction(); + +}; + +static PRInt32 pageSize = 1024; +static const char* baseName = "./"; +static const char *programName = "Random File"; + +/*********************************************************************** +** PRIVATE FUNCTION: Random +** DESCRIPTION: +** Generate a pseudo-random number +** INPUTS: None +** OUTPUTS: None +** RETURN: A pseudo-random unsigned number, 32-bits wide +** SIDE EFFECTS: +** Updates random seed (a static) +** RESTRICTIONS: +** None +** MEMORY: NA +** ALGORITHM: +** Uses the current interval timer value, promoted to a 64 bit +** float as a multiplier for a static residue (which begins +** as an uninitialized variable). The result is bits [16..48) +** of the product. Seed is then updated with the return value +** promoted to a float-64. +***********************************************************************/ +PRUint32 HammerData::Random() +{ + PRUint32 rv; + PRUint64 shift; + RCInterval now = RCInterval(RCInterval::now); + PRFloat64 random = seed * (PRFloat64)((PRIntervalTime)now); + LL_USHR(shift, *((PRUint64*)&random), 16); + LL_L2UI(rv, shift); + seed = (PRFloat64)rv; + return rv; +} /* HammerData::Random */ + +Hammer::~Hammer() { } + +Hammer::Hammer( + RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip): + HammerData(lock, cond, clip), RCThread(scope, RCThread::joinable, 0) { } + +HammerData::~HammerData() { } + +HammerData::HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip) +{ + ml = lock; + cv = cond; + writes = 0; + limit = clip; + seed = 0x58a9382; + action = HammerData::sg_go; + problem = HammerData::sg_okay; + timein = RCInterval(RCInterval::now); +} /* HammerData::HammerData */ + + +/*********************************************************************** +** PRIVATE FUNCTION: Hammer::RootFunction +** DESCRIPTION: +** Hammer on the file I/O system +** INPUTS: A pointer to the thread's private data +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** Creates, accesses and deletes a file +** RESTRICTIONS: +** (Currently) must have file create permission in "/usr/tmp". +** MEMORY: NA +** ALGORITHM: +** This function is a root of a thread +** 1) Creates a (hopefully) unique file in /usr/tmp/ +** 2) Writes a zero to a random number of sequential pages +** 3) Closes the file +** 4) Reopens the file +** 5) Seeks to a random page within the file +** 6) Writes a one byte on that page +** 7) Repeat steps [5..6] for each page in the file +** 8) Close and delete the file +** 9) Repeat steps [1..8] until told to stop +** 10) Notify complete and return +***********************************************************************/ +void Hammer::RootFunction() +{ + PRUint32 index; + RCFileIO file; + char filename[30]; + const char zero = 0; + PRStatus rv = PR_SUCCESS; + + limit = (Random() % limit) + 1; + + (void)sprintf(filename, "%ssg%04p.dat", baseName, this); + + if (debug_mode) PR_fprintf(output, "Starting work on %s\n", filename); + + while (PR_TRUE) + { + PRUint64 bytes; + PRUint32 minor = (Random() % limit) + 1; + PRUint32 random = (Random() % limit) + 1; + PRUint32 pages = (Random() % limit) + 10; + while (minor-- > 0) + { + problem = sg_okay; + if (action != sg_go) goto finished; + problem = sg_open; + rv = file.Open(filename, PR_RDWR|PR_CREATE_FILE, 0666); + if (PR_FAILURE == rv) goto finished; + for (index = 0; index < pages; index++) + { + problem = sg_okay; + if (action != sg_go) goto close; + problem = sg_seek; + bytes = file.Seek(pageSize * index, RCFileIO::set); + if (bytes != pageSize * index) goto close; + problem = sg_write; + bytes = file.Write(&zero, sizeof(zero)); + if (bytes <= 0) goto close; + writes += 1; + } + problem = sg_close; + rv = file.Close(); + if (rv != PR_SUCCESS) goto purge; + + problem = sg_okay; + if (action != sg_go) goto purge; + + problem = sg_open; + rv = file.Open(filename, PR_RDWR, 0666); + if (PR_FAILURE == rv) goto finished; + for (index = 0; index < pages; index++) + { + problem = sg_okay; + if (action != sg_go) goto close; + problem = sg_seek; + bytes = file.Seek(pageSize * index, RCFileIO::set); + if (bytes != pageSize * index) goto close; + problem = sg_write; + bytes = file.Write(&zero, sizeof(zero)); + if (bytes <= 0) goto close; + writes += 1; + random = (random + 511) % pages; + } + problem = sg_close; + rv = file.Close(); + if (rv != PR_SUCCESS) goto purge; + problem = sg_delete; + rv = file.Delete(filename); + if (rv != PR_SUCCESS) goto finished; + } + } + +close: + (void)file.Close(); +purge: + (void)file.Delete(filename); +finished: + RCEnter scope(ml); + action = HammerData::sg_done; + cv->Notify(); + + if (debug_mode) PR_fprintf(output, "Ending work on %s\n", filename); + + return; +} /* Hammer::RootFunction */ + +static Hammer* hammer[100]; +/*********************************************************************** +** PRIVATE FUNCTION: main +** DESCRIPTION: +** Hammer on the file I/O system +** INPUTS: The usual argc and argv +** argv[0] - program name (not used) +** argv[1] - the number of virtual_procs to execute the major loop +** argv[2] - the number of threads to toss into the batch +** argv[3] - the clipping number applied to randoms +** default values: max_virtual_procs = 2, threads = 10, limit = 57 +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** Creates, accesses and deletes lots of files +** RESTRICTIONS: +** (Currently) must have file create permission in "/usr/tmp". +** MEMORY: NA +** ALGORITHM: +** 1) Fork a "Thread()" +** 2) Wait for 'interleave' seconds +** 3) For [0..'threads') repeat [1..2] +** 4) Mark all objects to stop +** 5) Collect the threads, accumulating the results +** 6) For [0..'max_virtual_procs') repeat [1..5] +** 7) Print accumulated results and exit +** +** Characteristic output (from IRIX) +** Random File: Using max_virtual_procs = 2, threads = 10, limit = 57 +** Random File: [min [avg] max] writes/sec average +***********************************************************************/ +PRIntn main (PRIntn argc, char *argv[]) +{ + RCLock ml; + PLOptStatus os; + RCCondition cv(&ml); + PRUint32 writesMax = 0, durationTot = 0; + RCThread::Scope thread_scope = RCThread::local; + PRUint32 writes, writesMin = 0x7fffffff, writesTot = 0; + PRIntn active, poll, limit = 0, max_virtual_procs = 0, threads = 0, virtual_procs; + RCInterval interleave(RCInterval::FromMilliseconds(10000)), duration(0); + + const char *where[] = {"okay", "open", "close", "delete", "write", "seek"}; + + PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: + baseName = opt->value; + break; + case 'G': /* global threads */ + thread_scope = RCThread::global; + break; + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'l': /* limiting number */ + limit = atoi(opt->value); + break; + case 't': /* number of threads */ + threads = atoi(opt->value); + break; + case 'i': /* iteration counter */ + max_virtual_procs = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + output = PR_GetSpecialFD(PR_StandardOutput); + + /* main test */ + + cv.SetTimeout(interleave); + + if (max_virtual_procs == 0) max_virtual_procs = 2; + if (limit == 0) limit = 57; + if (threads == 0) threads = 10; + + if (debug_mode) PR_fprintf(output, + "%s: Using %d virtual processors, %d threads, limit = %d and %s threads\n", + programName, max_virtual_procs, threads, limit, + (thread_scope == RCThread::local) ? "LOCAL" : "GLOBAL"); + + for (virtual_procs = 0; virtual_procs < max_virtual_procs; ++virtual_procs) + { + if (debug_mode) + PR_fprintf(output, + "%s: Setting number of virtual processors to %d\n", + programName, virtual_procs + 1); + RCPrimordialThread::SetVirtualProcessors(virtual_procs + 1); + for (active = 0; active < threads; active++) + { + hammer[active] = new Hammer(thread_scope, &ml, &cv, limit); + hammer[active]->Start(); /* then make it roll */ + RCThread::Sleep(interleave); /* start them slowly */ + } + + /* + * The last thread started has had the opportunity to run for + * 'interleave' seconds. Now gather them all back in. + */ + { + RCEnter scope(&ml); + for (poll = 0; poll < threads; poll++) + { + if (hammer[poll]->action == HammerData::sg_go) /* don't overwrite done */ + hammer[poll]->action = HammerData::sg_stop; /* ask him to stop */ + } + } + + while (active > 0) + { + for (poll = 0; poll < threads; poll++) + { + ml.Acquire(); + while (hammer[poll]->action < HammerData::sg_done) cv.Wait(); + ml.Release(); + + if (hammer[poll]->problem == HammerData::sg_okay) + { + duration = RCInterval(RCInterval::now) - hammer[poll]->timein; + writes = hammer[poll]->writes * 1000 / duration; + if (writes < writesMin) writesMin = writes; + if (writes > writesMax) writesMax = writes; + writesTot += hammer[poll]->writes; + durationTot += duration; + } + else + { + if (debug_mode) PR_fprintf(output, + "%s: test failed %s after %ld seconds\n", + programName, where[hammer[poll]->problem], duration); + else failed_already=1; + } + active -= 1; /* this is another one down */ + (void)hammer[poll]->Join(); + hammer[poll] = NULL; + } + } + if (debug_mode) PR_fprintf(output, + "%s: [%ld [%ld] %ld] writes/sec average\n", + programName, writesMin, + writesTot * 1000 / durationTot, writesMax); + } + + failed_already |= (PR_FAILURE == RCPrimordialThread::Cleanup()); + PR_fprintf(output, "%s\n", (failed_already) ? "FAIL\n" : "PASS\n"); + return failed_already; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/switch.cpp nspr-4.10.7/nspr/pr/src/cplus/tests/switch.cpp --- nspr-4.9.5/nspr/pr/src/cplus/tests/switch.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/switch.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,234 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: switch.cpp +** Description: trying to time context switches +*/ + +#include "rccv.h" +#include "rcinrval.h" +#include "rclock.h" +#include "rcthread.h" + +#include +#include +#include +#include +#include + +#include + +#define INNER_LOOPS 100 +#define DEFAULT_LOOPS 100 +#define DEFAULT_THREADS 10 + +static PRFileDesc *debug_out = NULL; +static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE; + +class Home: public RCCondition +{ +public: + virtual ~Home(); + Home(Home *link, RCLock* ml); + +public: + Home *next; + RCLock* ml; + PRBool twiddle; +}; /* Home */ + +Home::~Home() { } + +Home::Home(Home *link, RCLock* lock): RCCondition(lock) +{ + ml = lock; + next = link; + twiddle = PR_FALSE; +} /* Home::Home */ + +class Shared: public Home, public RCThread +{ +public: + Shared(RCThread::Scope scope, Home* link, RCLock* ml); + +private: + ~Shared(); + void RootFunction(); +}; /* Shared */ + +Shared::Shared(RCThread::Scope scope, Home* link, RCLock* lock): + Home(link, lock), RCThread(scope, RCThread::joinable) { } + +Shared::~Shared() { } + +void Shared::RootFunction() +{ + PRStatus status = PR_SUCCESS; + while (PR_SUCCESS == status) + { + RCEnter entry(ml); + while (twiddle && (PR_SUCCESS == status)) status = Wait(); + if (verbosity) PR_fprintf(debug_out, "+"); + twiddle = PR_TRUE; + next->twiddle = PR_FALSE; + next->Notify(); + } +} /* Shared::RootFunction */ + +static void Help(void) +{ + debug_out = PR_STDOUT; + + PR_fprintf( + debug_out, "Usage: >./switch [-d] [-c n] [-t n] [-T n] [-G]\n"); + PR_fprintf( + debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS); + PR_fprintf( + debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS); + PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n"); + PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n"); + PR_fprintf(debug_out, "-G n\tglobal threads only (default: FALSE)\n"); + PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n"); +} /* Help */ + +PRIntn main(PRIntn argc, char **argv) +{ + PLOptStatus os; + PRStatus status; + PRBool help = PR_FALSE; + PRUintn concurrency = 1; + RCThread::Scope thread_scope = RCThread::local; + PRUintn thread_count, inner_count, loop_count, average; + PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS; + PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'v': /* verbose mode */ + verbosity = PR_TRUE; + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'c': /* loop counter */ + loop_limit = atoi(opt->value); + break; + case 't': /* thread limit */ + thread_limit = atoi(opt->value); + break; + case 'C': /* Concurrency limit */ + concurrency = atoi(opt->value); + break; + case 'G': /* global threads only */ + thread_scope = RCThread::global; + break; + case 'h': /* help message */ + Help(); + help = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (help) return -1; + + if (PR_TRUE == debug_mode) + { + debug_out = PR_STDOUT; + PR_fprintf(debug_out, "Test parameters\n"); + PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit); + PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit); + PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency); + PR_fprintf( + debug_out, "\tThread type: %s\n", + (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); + } + + /* + ** The interesting part starts here + */ + RCLock lock; + Shared* shared; + Home home(NULL, &lock); + Home* link = &home; + RCInterval timein, timeout = 0; + + /* Build up the string of objects */ + for (thread_count = 1; thread_count <= thread_limit; ++thread_count) + { + shared = new Shared(thread_scope, link, &lock); + shared->Start(); /* make it run */ + link = (Home*)shared; + } + + /* Pass the message around the horn a few times */ + for (loop_count = 1; loop_count <= loop_limit; ++loop_count) + { + timein.SetToNow(); + for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count) + { + RCEnter entry(&lock); + home.twiddle = PR_TRUE; + shared->twiddle = PR_FALSE; + shared->Notify(); + while (home.twiddle) + { + failed = (PR_FAILURE == home.Wait()) ? PR_TRUE : PR_FALSE; + } + } + timeout += (RCInterval(RCInterval::now) - timein); + } + + /* Figure out how well we did */ + if (debug_mode) + { + average = timeout.ToMicroseconds() + / (INNER_LOOPS * loop_limit * thread_count); + PR_fprintf( + debug_out, "Average switch times %d usecs for %d threads\n", + average, thread_limit); + } + + /* Start reclamation process */ + link = shared; + for (thread_count = 1; thread_count <= thread_limit; ++thread_count) + { + if (&home == link) break; + status = ((Shared*)link)->Interrupt(); + if (PR_SUCCESS != status) + { + failed = PR_TRUE; + if (debug_mode) + PL_FPrintError(debug_out, "Failed to interrupt"); + } + link = link->next; + } + + for (thread_count = 1; thread_count <= thread_limit; ++thread_count) + { + link = shared->next; + status = shared->Join(); + if (PR_SUCCESS != status) + { + failed = PR_TRUE; + if (debug_mode) + PL_FPrintError(debug_out, "Failed to join"); + } + if (&home == link) break; + shared = (Shared*)link; + } + + PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n")); + + failed |= (PR_SUCCESS == RCPrimordialThread::Cleanup()); + + return ((failed) ? 1 : 0); +} /* main */ + +/* switch.c */ diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/thread.cpp nspr-4.10.7/nspr/pr/src/cplus/tests/thread.cpp --- nspr-4.9.5/nspr/pr/src/cplus/tests/thread.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/thread.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* thread.cpp - a test program */ + +#include "rcthread.h" + +#include + +#include + +class TestThread: public RCThread +{ +public: + TestThread(RCThread::State state, PRIntn count); + + virtual void RootFunction(); + +protected: + virtual ~TestThread(); + +private: + PRUint32 mydata; +}; + +TestThread::~TestThread() { } + +TestThread::TestThread(RCThread::State state, PRIntn count): + RCThread(RCThread::global, state, 0) { mydata = count; } + +void TestThread::RootFunction() +{ + SetPriority(RCThread::high); + printf("TestThread::RootFunction %d did it\n", mydata); +} /* TestThread::RootFunction */ + +class Foo1 +{ +public: + Foo1(); + virtual ~Foo1(); + + TestThread *thread; + PRIntn data; +}; + +Foo1::Foo1() +{ + data = 0xafaf; + thread = new TestThread(RCThread::joinable, 0xafaf); + thread->Start(); +} + +Foo1::~Foo1() +{ + PRStatus rv = thread->Join(); + PR_ASSERT(PR_SUCCESS == rv); +} /* Foo1::~Foo1 */ + +PRIntn main(PRIntn argc, char **agrv) +{ + PRStatus status; + PRIntn count = 100; + RCThread *thread[10]; + while (--count > 0) + { + TestThread *thread = new TestThread(RCThread::joinable, count); + status = thread->Start(); /* have to remember to start it */ + PR_ASSERT(PR_SUCCESS == status); + status = thread->Join(); /* this should work */ + PR_ASSERT(PR_SUCCESS == status); + } + while (++count < 100) + { + TestThread *thread = new TestThread(RCThread::unjoinable, count); + status = thread->Start(); /* have to remember to start it */ + PR_ASSERT(PR_SUCCESS == status); + } + + { + Foo1 *foo1 = new Foo1(); + PR_ASSERT(NULL != foo1); + delete foo1; + } + + { + for (count = 0; count < 10; ++count) + { + thread[count] = new TestThread( RCThread::joinable, count); + status = thread[count]->Start(); /* have to remember to start it */ + PR_ASSERT(PR_SUCCESS == status); + } + for (count = 0; count < 10; ++count) + { + PRStatus rv = thread[count]->Join(); + PR_ASSERT(PR_SUCCESS == rv); + } + } + + (void)RCPrimordialThread::Cleanup(); + + return 0; +} /* main */ + +/* thread.cpp */ + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/time.cpp nspr-4.10.7/nspr/pr/src/cplus/tests/time.cpp --- nspr-4.9.5/nspr/pr/src/cplus/tests/time.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/time.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* time.cpp - a test program */ + +#include "rctime.h" + +#include +#include + +#define DEFAULT_ITERATIONS 100 + +PRIntn main(PRIntn argc, char **argv) +{ + RCTime unitialized; + RCTime now(PR_Now()); + RCTime current(RCTime::now); + PRTime time = current; + + unitialized = now; + now.Now(); + + return 0; +} /* main */ + +/* time.cpp */ + diff -Nru nspr-4.9.5/nspr/pr/src/cplus/tests/tpd.cpp nspr-4.10.7/nspr/pr/src/cplus/tests/tpd.cpp --- nspr-4.9.5/nspr/pr/src/cplus/tests/tpd.cpp 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/cplus/tests/tpd.cpp 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,336 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: tpd.cpp +** Description: Exercising the thread private data bailywick. +*/ + +#include "prlog.h" +#include "prprf.h" +#include "rcthread.h" + +#include + +#include "plgetopt.h" + +/* +** class MyThread +*/ +class MyThread: public RCThread +{ +public: + MyThread(); + +private: + ~MyThread(); + void RootFunction(); +}; /* MyThread */ + +/* +** class MyPrivateData +*/ +class MyPrivateData: public RCThreadPrivateData +{ +public: + virtual ~MyPrivateData(); + + MyPrivateData(); + MyPrivateData(char*); + MyPrivateData(const MyPrivateData&); + + void Release(); + +private: + char *string; +}; /* MyPrivateData */ + +static PRUintn key[128]; +static PRIntn debug = 0; +static PRBool failed = PR_FALSE; +static PRBool should = PR_TRUE; +static PRBool did = PR_TRUE; +static PRFileDesc *fout = NULL; + +static void PrintProgress(PRIntn line) +{ + failed = failed || (should && !did); + failed = failed || (!should && did); + if (debug > 0) + { + PR_fprintf( + fout, "@ line %d destructor should %shave been called and was%s\n", + line, ((should) ? "" : "NOT "), ((did) ? "" : " NOT")); + } +} /* PrintProgress */ + +static void MyAssert(const char *expr, const char *file, PRIntn line) +{ + if (debug > 0) + (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line); +} /* MyAssert */ + +#define MY_ASSERT(_expr) \ + ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__)) + +int main(PRIntn argc, char *argv[]) +{ + PRStatus rv; + PRUintn keys; + MyThread *thread; + const RCThreadPrivateData *pd; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + RCThread *primordial = RCThread::WrapPrimordialThread(); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + fout = PR_STDOUT; + + MyPrivateData extension = MyPrivateData("EXTENSION"); + MyPrivateData key_string[] = { + "Key #0", "Key #1", "Key #2", "Key #3", + "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; + + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = RCThread::NewPrivateIndex(&key[keys]); + key[keys + 4] = key[keys] + 4; + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + /* the first four should be bu null, the last four undefined and null */ + did = should = PR_FALSE; + for (keys = 0; keys < 8; ++keys) + { + pd = RCThread::GetPrivateData(key[keys]); + MY_ASSERT(NULL == pd); + } + PrintProgress(__LINE__); + + /* initially set private data for new keys */ + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = RCThread::SetPrivateData(key[keys], &key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + /* re-assign the private data, albeit the same content */ + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + pd = RCThread::GetPrivateData(key[keys]); + PR_ASSERT(NULL != pd); + rv = RCThread::SetPrivateData(key[keys], &key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + /* set private to */ + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = RCThread::SetPrivateData(key[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + /* should all be null now */ + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + pd = RCThread::GetPrivateData(key[keys]); + PR_ASSERT(NULL == pd); + } + PrintProgress(__LINE__); + + /* allocate another batch of keys and assign data to them */ + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = RCThread::NewPrivateIndex(&key[keys]); + MY_ASSERT(PR_SUCCESS == rv); + rv = RCThread::SetPrivateData(key[keys], &extension); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + /* set all the extended slots to */ + did = PR_FALSE; should = PR_TRUE; + for (keys = 8; keys < 127; ++keys) + { + rv = RCThread::SetPrivateData(key[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + /* set all the extended slots to again (noop) */ + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = RCThread::SetPrivateData(key[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + + if (debug) PR_fprintf(fout, "Creating thread\n"); + thread = new MyThread(); + if (debug) PR_fprintf(fout, "Starting thread\n"); + thread->Start(); + if (debug) PR_fprintf(fout, "Joining thread\n"); + (void)thread->Join(); + if (debug) PR_fprintf(fout, "Joined thread\n"); + + failed |= (PR_FAILURE == RCPrimordialThread::Cleanup()); + + (void)PR_fprintf( + fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); + + return (failed) ? 1 : 0; + +} /* main */ + +/* +** class MyPrivateData +*/ +MyPrivateData::~MyPrivateData() +{ + PR_fprintf( + fout, "MyPrivateData::~MyPrivateData[%s]\n", + (NULL != string) ? string : "NULL"); +} /* MyPrivateData::~MyPrivateData */ + +MyPrivateData::MyPrivateData(): RCThreadPrivateData() +{ + PR_fprintf(fout, "MyPrivateData::MyPrivateData()\n"); + string = NULL; +} /* MyPrivateData::MyPrivateData */ + +MyPrivateData::MyPrivateData(char* data): RCThreadPrivateData() +{ + PR_fprintf(fout, "MyPrivateData::MyPrivateData(char* data)\n"); + string = data; +} /* MyPrivateData:: MyPrivateData */ + +MyPrivateData::MyPrivateData(const MyPrivateData& him): RCThreadPrivateData(him) +{ + PR_fprintf(fout, "MyPrivateData::MyPrivateData(const MyPrivateData& him)\n"); + string = him.string; +} /* MyPrivateData:: MyPrivateData */ + +void MyPrivateData::Release() +{ + if (should) did = PR_TRUE; + else failed = PR_TRUE; +} /* MyPrivateData::operator= */ + +/* +** class MyThread +*/ +MyThread::~MyThread() { } +MyThread::MyThread(): RCThread(RCThread::global, RCThread::joinable) { } + + +void MyThread::RootFunction() +{ + PRStatus rv; + PRUintn keys; + const RCThreadPrivateData *pd; + + MyPrivateData extension = MyPrivateData("EXTENSION"); + MyPrivateData key_string[] = { + "Key #0", "Key #1", "Key #2", "Key #3", + "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; + + did = should = PR_FALSE; + for (keys = 0; keys < 8; ++keys) + { + pd = GetPrivateData(key[keys]); + MY_ASSERT(NULL == pd); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = SetPrivateData(keys, &key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + +#if !defined(DEBUG) + did = should = PR_FALSE; + for (keys = 4; keys < 8; ++keys) + { + rv = SetPrivateData(keys, &key_string[keys]); + MY_ASSERT(PR_FAILURE == rv); + } + PrintProgress(__LINE__); +#endif + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = SetPrivateData(key[keys], &key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = SetPrivateData(key[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = SetPrivateData(key[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = SetPrivateData(key[keys], &extension); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 8; keys < 127; ++keys) + { + rv = SetPrivateData(key[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = SetPrivateData(key[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } +} /* MyThread::RootFunction */ + +/* tpd.c */ diff -Nru nspr-4.9.5/nspr/pr/src/.cvsignore nspr-4.10.7/nspr/pr/src/.cvsignore --- nspr-4.9.5/nspr/pr/src/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,2 @@ +Makefile +_pr_bld.h diff -Nru nspr-4.9.5/nspr/pr/src/io/.cvsignore nspr-4.10.7/nspr/pr/src/io/.cvsignore --- nspr-4.9.5/nspr/pr/src/io/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/io/Makefile.in nspr-4.10.7/nspr/pr/src/io/Makefile.in --- nspr-4.9.5/nspr/pr/src/io/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,50 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CSRCS = \ + prfdcach.c \ + prmwait.c \ + priometh.c \ + pripv6.c \ + prmapopt.c \ + prlayer.c \ + prlog.c \ + prmmap.c \ + prpolevt.c \ + prprf.c \ + prscanf.c \ + prstdio.c \ + $(NULL) + +ifndef USE_PTHREADS + CSRCS += \ + prdir.c \ + prfile.c \ + prio.c \ + prsocket.c \ + $(NULL) +endif + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/io/prdir.c nspr-4.10.7/nspr/pr/src/io/prdir.c --- nspr-4.9.5/nspr/pr/src/io/prdir.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prdir.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name) +{ + PRDir *dir; + PRStatus sts; + + dir = PR_NEW(PRDir); + if (dir) { + sts = _PR_MD_OPEN_DIR(&dir->md,name); + if (sts != PR_SUCCESS) { + PR_DELETE(dir); + return NULL; + } + } else { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + } + return dir; +} + +PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags) +{ + /* _MD_READ_DIR return a char* to the name; allocation in machine-dependent code */ + char* name = _PR_MD_READ_DIR(&dir->md, flags); + dir->d.name = name; + return name ? &dir->d : NULL; +} + +PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir) +{ +PRInt32 rv; + + if (dir) { + rv = _PR_MD_CLOSE_DIR(&dir->md); + PR_DELETE(dir); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode) +{ +PRInt32 rv; + + rv = _PR_MD_MKDIR(name, mode); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode) +{ +PRInt32 rv; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + rv = _PR_MD_MAKE_DIR(name, mode); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name) +{ +PRInt32 rv; + + rv = _PR_MD_RMDIR(name); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; +} + +#ifdef MOZ_UNICODE +/* + * UTF16 Interface + */ +PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name) +{ + PRDirUTF16 *dir; + PRStatus sts; + + dir = PR_NEW(PRDirUTF16); + if (dir) { + sts = _PR_MD_OPEN_DIR_UTF16(&dir->md,name); + if (sts != PR_SUCCESS) { + PR_DELETE(dir); + return NULL; + } + } else { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + } + return dir; +} + +PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags) +{ + /* + * _MD_READ_DIR_UTF16 return a PRUnichar* to the name; allocation in + * machine-dependent code + */ + PRUnichar* name = _PR_MD_READ_DIR_UTF16(&dir->md, flags); + dir->d.name = name; + return name ? &dir->d : NULL; +} + +PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir) +{ + PRInt32 rv; + + if (dir) { + rv = _PR_MD_CLOSE_DIR_UTF16(&dir->md); + PR_DELETE(dir); + if (rv < 0) + return PR_FAILURE; + else + return PR_SUCCESS; + } + return PR_SUCCESS; +} + +#endif /* MOZ_UNICODE */ diff -Nru nspr-4.9.5/nspr/pr/src/io/prfdcach.c nspr-4.10.7/nspr/pr/src/io/prfdcach.c --- nspr-4.9.5/nspr/pr/src/io/prfdcach.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prfdcach.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,292 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +/*****************************************************************************/ +/*****************************************************************************/ +/************************** File descriptor caching **************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +/* +** This code is built into debuggable versions of NSPR to assist in +** finding misused file descriptors. Since file descritors (PRFileDesc) +** are identified by a pointer to their structure, they can be the +** target of dangling references. Furthermore, NSPR caches and tries +** to aggressively reuse file descriptors, leading to more ambiguity. +** The following code will allow a debugging client to set environment +** variables and control the number of file descriptors that will be +** preserved before they are recycled. The environment variables are +** NSPR_FD_CACHE_SIZE_LOW and NSPR_FD_CACHE_SIZE_HIGH. The former sets +** the number of descriptors NSPR will allocate before beginning to +** recycle. The latter is the maximum number permitted in the cache +** (exclusive of those in use) at a time. +*/ +typedef struct _PR_Fd_Cache +{ + PRLock *ml; + PRIntn count; + PRStack *stack; + PRFileDesc *head, *tail; + PRIntn limit_low, limit_high; +} _PR_Fd_Cache; + +static _PR_Fd_Cache _pr_fd_cache; +static PRFileDesc **stack2fd = &(((PRFileDesc*)NULL)->higher); + + +/* +** Get a FileDescriptor from the cache if one exists. If not allocate +** a new one from the heap. +*/ +PRFileDesc *_PR_Getfd(void) +{ + PRFileDesc *fd; + /* + ** $$$ + ** This may look a little wasteful. We'll see. Right now I want to + ** be able to toggle between caching and not at runtime to measure + ** the differences. If it isn't too annoying, I'll leave it in. + ** $$$$ + ** + ** The test is against _pr_fd_cache.limit_high. If that's zero, + ** we're not doing the extended cache but going for performance. + */ + if (0 == _pr_fd_cache.limit_high) + { + PRStackElem *pop; + PR_ASSERT(NULL != _pr_fd_cache.stack); + pop = PR_StackPop(_pr_fd_cache.stack); + if (NULL == pop) goto allocate; + fd = (PRFileDesc*)((PRPtrdiff)pop - (PRPtrdiff)stack2fd); + } + else + { + do + { + if (NULL == _pr_fd_cache.head) goto allocate; /* nothing there */ + if (_pr_fd_cache.count < _pr_fd_cache.limit_low) goto allocate; + + /* we "should" be able to extract an fd from the cache */ + PR_Lock(_pr_fd_cache.ml); /* need the lock to do this safely */ + fd = _pr_fd_cache.head; /* protected extraction */ + if (NULL == fd) /* unexpected, but not fatal */ + { + PR_ASSERT(0 == _pr_fd_cache.count); + PR_ASSERT(NULL == _pr_fd_cache.tail); + } + else + { + _pr_fd_cache.count -= 1; + _pr_fd_cache.head = fd->higher; + if (NULL == _pr_fd_cache.head) + { + PR_ASSERT(0 == _pr_fd_cache.count); + _pr_fd_cache.tail = NULL; + } + PR_ASSERT(&_pr_faulty_methods == fd->methods); + PR_ASSERT(PR_INVALID_IO_LAYER == fd->identity); + PR_ASSERT(_PR_FILEDESC_FREED == fd->secret->state); + } + PR_Unlock(_pr_fd_cache.ml); + + } while (NULL == fd); /* then go around and allocate a new one */ + } + +finished: + fd->dtor = NULL; + fd->lower = fd->higher = NULL; + fd->identity = PR_NSPR_IO_LAYER; + memset(fd->secret, 0, sizeof(PRFilePrivate)); + return fd; + +allocate: + fd = PR_NEW(PRFileDesc); + if (NULL != fd) + { + fd->secret = PR_NEW(PRFilePrivate); + if (NULL == fd->secret) PR_DELETE(fd); + } + if (NULL != fd) goto finished; + else return NULL; + +} /* _PR_Getfd */ + +/* +** Return a file descriptor to the cache unless there are too many in +** there already. If put in cache, clear the fields first. +*/ +void _PR_Putfd(PRFileDesc *fd) +{ + PR_ASSERT(PR_NSPR_IO_LAYER == fd->identity); + fd->methods = &_pr_faulty_methods; + fd->identity = PR_INVALID_IO_LAYER; + fd->secret->state = _PR_FILEDESC_FREED; + + if (0 == _pr_fd_cache.limit_high) + { + PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher)); + } + else + { + if (_pr_fd_cache.count > _pr_fd_cache.limit_high) + { + PR_Free(fd->secret); + PR_Free(fd); + } + else + { + PR_Lock(_pr_fd_cache.ml); + if (NULL == _pr_fd_cache.tail) + { + PR_ASSERT(0 == _pr_fd_cache.count); + PR_ASSERT(NULL == _pr_fd_cache.head); + _pr_fd_cache.head = _pr_fd_cache.tail = fd; + } + else + { + PR_ASSERT(NULL == _pr_fd_cache.tail->higher); + _pr_fd_cache.tail->higher = fd; + _pr_fd_cache.tail = fd; /* new value */ + } + fd->higher = NULL; /* always so */ + _pr_fd_cache.count += 1; /* count the new entry */ + PR_Unlock(_pr_fd_cache.ml); + } + } +} /* _PR_Putfd */ + +PR_IMPLEMENT(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high) +{ + /* + ** This can be called at any time, may adjust the cache sizes, + ** turn the caches off, or turn them on. It is not dependent + ** on the compilation setting of DEBUG. + */ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (low > high) low = high; /* sanity check the params */ + + PR_Lock(_pr_fd_cache.ml); + if (0 == high) /* shutting down or staying down */ + { + if (0 != _pr_fd_cache.limit_high) /* shutting down */ + { + _pr_fd_cache.limit_high = 0; /* stop use */ + /* + ** Hold the lock throughout - nobody's going to want it + ** other than another caller to this routine. Just don't + ** let that happen. + ** + ** Put all the cached fds onto the new cache. + */ + while (NULL != _pr_fd_cache.head) + { + PRFileDesc *fd = _pr_fd_cache.head; + _pr_fd_cache.head = fd->higher; + PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher)); + } + _pr_fd_cache.limit_low = 0; + _pr_fd_cache.tail = NULL; + _pr_fd_cache.count = 0; + } + } + else /* starting up or just adjusting parameters */ + { + PRBool was_using_stack = (0 == _pr_fd_cache.limit_high); + _pr_fd_cache.limit_low = low; + _pr_fd_cache.limit_high = high; + if (was_using_stack) /* was using stack - feed into cache */ + { + PRStackElem *pop; + while (NULL != (pop = PR_StackPop(_pr_fd_cache.stack))) + { + PRFileDesc *fd = (PRFileDesc*) + ((PRPtrdiff)pop - (PRPtrdiff)stack2fd); + if (NULL == _pr_fd_cache.tail) _pr_fd_cache.tail = fd; + fd->higher = _pr_fd_cache.head; + _pr_fd_cache.head = fd; + _pr_fd_cache.count += 1; + } + } + } + PR_Unlock(_pr_fd_cache.ml); + return PR_SUCCESS; +} /* PR_SetFDCacheSize */ + +void _PR_InitFdCache(void) +{ + /* + ** The fd caching is enabled by default for DEBUG builds, + ** disabled by default for OPT builds. That default can + ** be overridden at runtime using environment variables + ** or a super-wiz-bang API. + */ + const char *low = PR_GetEnv("NSPR_FD_CACHE_SIZE_LOW"); + const char *high = PR_GetEnv("NSPR_FD_CACHE_SIZE_HIGH"); + + /* + ** _low is allowed to be zero, _high is not. + ** If _high is zero, we're not doing the caching. + */ + + _pr_fd_cache.limit_low = 0; +#if defined(DEBUG) + _pr_fd_cache.limit_high = FD_SETSIZE; +#else + _pr_fd_cache.limit_high = 0; +#endif /* defined(DEBUG) */ + + if (NULL != low) _pr_fd_cache.limit_low = atoi(low); + if (NULL != high) _pr_fd_cache.limit_high = atoi(high); + + if (_pr_fd_cache.limit_low < 0) + _pr_fd_cache.limit_low = 0; + if (_pr_fd_cache.limit_low > FD_SETSIZE) + _pr_fd_cache.limit_low = FD_SETSIZE; + + if (_pr_fd_cache.limit_high > FD_SETSIZE) + _pr_fd_cache.limit_high = FD_SETSIZE; + + if (_pr_fd_cache.limit_high < _pr_fd_cache.limit_low) + _pr_fd_cache.limit_high = _pr_fd_cache.limit_low; + + _pr_fd_cache.ml = PR_NewLock(); + PR_ASSERT(NULL != _pr_fd_cache.ml); + _pr_fd_cache.stack = PR_CreateStack("FD"); + PR_ASSERT(NULL != _pr_fd_cache.stack); + +} /* _PR_InitFdCache */ + +void _PR_CleanupFdCache(void) +{ + PRFileDesc *fd, *next; + PRStackElem *pop; + + for (fd = _pr_fd_cache.head; fd != NULL; fd = next) + { + next = fd->higher; + PR_DELETE(fd->secret); + PR_DELETE(fd); + } + _pr_fd_cache.head = NULL; + _pr_fd_cache.tail = NULL; + _pr_fd_cache.count = 0; + PR_DestroyLock(_pr_fd_cache.ml); + _pr_fd_cache.ml = NULL; + while ((pop = PR_StackPop(_pr_fd_cache.stack)) != NULL) + { + fd = (PRFileDesc*)((PRPtrdiff)pop - (PRPtrdiff)stack2fd); + PR_DELETE(fd->secret); + PR_DELETE(fd); + } + PR_DestroyStack(_pr_fd_cache.stack); + _pr_fd_cache.stack = NULL; +} /* _PR_CleanupFdCache */ + +/* prfdcach.c */ diff -Nru nspr-4.9.5/nspr/pr/src/io/prfile.c nspr-4.10.7/nspr/pr/src/io/prfile.c --- nspr-4.9.5/nspr/pr/src/io/prfile.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prfile.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,783 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include + +#ifdef XP_UNIX +#if defined(AIX) || defined(QNX) +/* To pick up sysconf */ +#include +#else +/* To pick up getrlimit, setrlimit */ +#include +#include +#endif +#endif /* XP_UNIX */ + +extern PRLock *_pr_flock_lock; +extern PRCondVar *_pr_flock_cv; + +static PRInt32 PR_CALLBACK FileRead(PRFileDesc *fd, void *buf, PRInt32 amount) +{ + PRInt32 rv = 0; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + rv = -1; + } + if (rv == -1) + return rv; + + rv = _PR_MD_READ(fd, buf, amount); + if (rv < 0) { + PR_ASSERT(rv == -1); + } + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv)); + return rv; +} + +static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 amount) +{ + PRInt32 rv = 0; + PRInt32 temp, count; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + rv = -1; + } + if (rv != 0) + return rv; + + count = 0; +#if !defined(_PR_HAVE_O_APPEND) /* Bugzilla: 4090, 276330 */ + if (fd->secret->appendMode) { + if (PR_Seek64(fd, 0, PR_SEEK_END) == -1) { + return -1; + } + } /* if (fd->secret->appendMode...) */ +#endif /* _PR_HAVE_O_APPEND */ + while (amount > 0) { + temp = _PR_MD_WRITE(fd, buf, amount); + if (temp < 0) { + count = -1; + break; + } + count += temp; + if (fd->secret->nonblocking) { + break; + } + buf = (const void*) ((const char*)buf + temp); + amount -= temp; + } + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count)); + return count; +} + +static PROffset32 PR_CALLBACK FileSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) +{ + PROffset32 result; + + result = _PR_MD_LSEEK(fd, offset, whence); + return result; +} + +static PROffset64 PR_CALLBACK FileSeek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) +{ + PROffset64 result; + + result = _PR_MD_LSEEK64(fd, offset, whence); + return result; +} + +static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc *fd) +{ + PRInt32 result, cur, end; + + cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR); + + if (cur >= 0) + end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END); + + if ((cur < 0) || (end < 0)) { + return -1; + } + + result = end - cur; + _PR_MD_LSEEK(fd, cur, PR_SEEK_SET); + + return result; +} + +static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd) +{ + PRInt64 result, cur, end; + PRInt64 minus_one; + + LL_I2L(minus_one, -1); + cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR); + + if (LL_GE_ZERO(cur)) + end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END); + + if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one; + + LL_SUB(result, end, cur); + (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET); + + return result; +} + +static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd) +{ + PRInt32 rv; + rv = _PR_MD_PIPEAVAILABLE(fd); + return rv; +} + +static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd) +{ + PRInt64 rv; + LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd)); + return rv; +} + +static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd) +{ + return PR_SUCCESS; +} + +static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info) +{ + PRInt32 rv; + + rv = _PR_MD_GETOPENFILEINFO(fd, info); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; +} + +static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info) +{ + /* $$$$ NOT YET IMPLEMENTED */ + PRInt32 rv; + + rv = _PR_MD_GETOPENFILEINFO64(fd, info); + if (rv < 0) return PR_FAILURE; + else return PR_SUCCESS; +} + +static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd) +{ + PRInt32 result; + result = _PR_MD_FSYNC(fd); + if (result < 0) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd) +{ + if (!fd || !fd->secret + || (fd->secret->state != _PR_FILEDESC_OPEN + && fd->secret->state != _PR_FILEDESC_CLOSED)) { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + return PR_FAILURE; + } + + if (fd->secret->state == _PR_FILEDESC_OPEN) { + if (_PR_MD_CLOSE_FILE(fd->secret->md.osfd) < 0) { + return PR_FAILURE; + } + fd->secret->state = _PR_FILEDESC_CLOSED; + } + PR_FreeFileDesc(fd); + return PR_SUCCESS; +} + +static PRInt16 PR_CALLBACK FilePoll( + PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) +{ + *out_flags = 0; + return in_flags; +} /* FilePoll */ + +static PRIOMethods _pr_fileMethods = { + PR_DESC_FILE, + FileClose, + FileRead, + FileWrite, + FileAvailable, + FileAvailable64, + FileSync, + FileSeek, + FileSeek64, + FileGetInfo, + FileGetInfo64, + (PRWritevFN)_PR_InvalidInt, + (PRConnectFN)_PR_InvalidStatus, + (PRAcceptFN)_PR_InvalidDesc, + (PRBindFN)_PR_InvalidStatus, + (PRListenFN)_PR_InvalidStatus, + (PRShutdownFN)_PR_InvalidStatus, + (PRRecvFN)_PR_InvalidInt, + (PRSendFN)_PR_InvalidInt, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + FilePoll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + (PRGetsocknameFN)_PR_InvalidStatus, + (PRGetpeernameFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRGetsocketoptionFN)_PR_InvalidStatus, + (PRSetsocketoptionFN)_PR_InvalidStatus, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void) +{ + return &_pr_fileMethods; +} + +static PRIOMethods _pr_pipeMethods = { + PR_DESC_PIPE, + FileClose, + FileRead, + FileWrite, + PipeAvailable, + PipeAvailable64, + PipeSync, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + (PRWritevFN)_PR_InvalidInt, + (PRConnectFN)_PR_InvalidStatus, + (PRAcceptFN)_PR_InvalidDesc, + (PRBindFN)_PR_InvalidStatus, + (PRListenFN)_PR_InvalidStatus, + (PRShutdownFN)_PR_InvalidStatus, + (PRRecvFN)_PR_InvalidInt, + (PRSendFN)_PR_InvalidInt, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + FilePoll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + (PRGetsocknameFN)_PR_InvalidStatus, + (PRGetpeernameFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRGetsocketoptionFN)_PR_InvalidStatus, + (PRSetsocketoptionFN)_PR_InvalidStatus, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void) +{ + return &_pr_pipeMethods; +} + +PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode) +{ + PROsfd osfd; + PRFileDesc *fd = 0; +#if !defined(_PR_HAVE_O_APPEND) + PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + /* Map pr open flags and mode to os specific flags */ + + osfd = _PR_MD_OPEN(name, flags, mode); + if (osfd != -1) { + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); + if (!fd) { + (void) _PR_MD_CLOSE_FILE(osfd); + } else { +#if !defined(_PR_HAVE_O_APPEND) + fd->secret->appendMode = appendMode; +#endif + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); + } + } + return fd; +} + +PR_IMPLEMENT(PRFileDesc*) PR_OpenFile( + const char *name, PRIntn flags, PRIntn mode) +{ + PROsfd osfd; + PRFileDesc *fd = 0; +#if !defined(_PR_HAVE_O_APPEND) + PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + /* Map pr open flags and mode to os specific flags */ + + osfd = _PR_MD_OPEN_FILE(name, flags, mode); + if (osfd != -1) { + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); + if (!fd) { + (void) _PR_MD_CLOSE_FILE(osfd); + } else { +#if !defined(_PR_HAVE_O_APPEND) + fd->secret->appendMode = appendMode; +#endif + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); + } + } + return fd; +} + +PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void) +{ +#if defined(XP_UNIX) && !defined(AIX) && !defined(QNX) + struct rlimit rlim; + + if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) { + /* XXX need to call PR_SetError() */ + return -1; + } + + return rlim.rlim_max; +#elif defined(AIX) || defined(QNX) + return sysconf(_SC_OPEN_MAX); +#elif defined(WIN32) + /* + * There is a systemwide limit of 65536 user handles. + */ + return 16384; +#elif defined (WIN16) + return FOPEN_MAX; +#elif defined(XP_OS2) + ULONG ulReqCount = 0; + ULONG ulCurMaxFH = 0; + DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH); + return ulCurMaxFH; +#elif defined(XP_BEOS) + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return -1; +#else + write me; +#endif +} + +PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size) +{ +#if defined(XP_UNIX) && !defined(AIX) && !defined(QNX) + struct rlimit rlim; + PRInt32 tableMax = PR_GetSysfdTableMax(); + + if (tableMax < 0) + return -1; + + if (tableMax > FD_SETSIZE) + tableMax = FD_SETSIZE; + + rlim.rlim_max = tableMax; + + /* Grow as much as we can; even if too big */ + if ( rlim.rlim_max < table_size ) + rlim.rlim_cur = rlim.rlim_max; + else + rlim.rlim_cur = table_size; + + if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) { + /* XXX need to call PR_SetError() */ + return -1; + } + + return rlim.rlim_cur; +#elif defined(XP_OS2) + PRInt32 tableMax = PR_GetSysfdTableMax(); + if (table_size > tableMax) { + APIRET rc = NO_ERROR; + rc = DosSetMaxFH(table_size); + if (rc == NO_ERROR) + return table_size; + else + return -1; + } + return tableMax; +#elif defined(AIX) || defined(QNX) \ + || defined(WIN32) || defined(WIN16) || defined(XP_BEOS) + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return -1; +#else + write me; +#endif +} + +PR_IMPLEMENT(PRStatus) PR_Delete(const char *name) +{ + PRInt32 rv; + + rv = _PR_MD_DELETE(name); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info) +{ + PRInt32 rv; + + rv = _PR_MD_GETFILEINFO(fn, info); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info) +{ + PRInt32 rv; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + rv = _PR_MD_GETFILEINFO64(fn, info); + if (rv < 0) { + return PR_FAILURE; + } else { + return PR_SUCCESS; + } +} + +PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to) +{ + PRInt32 rv; + + rv = _PR_MD_RENAME(from, to); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how) +{ +PRInt32 rv; + + rv = _PR_MD_ACCESS(name, how); + if (rv < 0) { + return PR_FAILURE; + } else + return PR_SUCCESS; +} + +/* +** Import an existing OS file to NSPR +*/ +PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd) +{ + PRFileDesc *fd = NULL; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); + if( !fd ) { + (void) _PR_MD_CLOSE_FILE(osfd); + } else { + _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); + } + + return fd; +} + +/* +** Import an existing OS pipe to NSPR +*/ +PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd) +{ + PRFileDesc *fd = NULL; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + fd = PR_AllocFileDesc(osfd, &_pr_pipeMethods); + if( !fd ) { + (void) _PR_MD_CLOSE_FILE(osfd); + } else { + _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); +#ifdef WINNT + fd->secret->md.sync_file_io = PR_TRUE; +#endif + } + + return fd; +} + +#ifndef NO_NSPR_10_SUPPORT +/* +** PR_Stat() for Win16 is defined in w16io.c +** it is a hack to circumvent problems in Gromit and Java +** See also: BugSplat: 98516. +*/ +#if !defined(WIN16) +/* + * This function is supposed to be for backward compatibility with + * nspr 1.0. Therefore, it still uses the nspr 1.0 error-reporting + * mechanism -- returns a PRInt32, which is the error code when the call + * fails. + * + * If we need this function in nspr 2.0, it should be changed to + * return PRStatus, as follows: + * + * PR_IMPLEMENT(PRStatus) PR_Stat(const char *name, struct stat *buf) + * { + * PRInt32 rv; + * + * rv = _PR_MD_STAT(name, buf); + * if (rv < 0) + * return PR_FAILURE; + * else + * return PR_SUCCESS; + * } + * + * -- wtc, 2/14/97. + */ +PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf) +{ + PRInt32 rv; + + rv = _PR_MD_STAT(name, buf); + return rv; +} + +#endif /* !defined(WIN16) */ +#endif /* ! NO_NSPR_10_SUPPORT */ + +PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd) +{ + PRStatus status = PR_SUCCESS; + +#ifdef WINNT + if (!fd->secret->md.io_model_committed) { + PRInt32 rv; + rv = _md_Associate((HANDLE)fd->secret->md.osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } +#endif + + PR_Lock(_pr_flock_lock); + while (fd->secret->lockCount == -1) + PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT); + if (fd->secret->lockCount == 0) { + fd->secret->lockCount = -1; + PR_Unlock(_pr_flock_lock); + status = _PR_MD_LOCKFILE(fd->secret->md.osfd); + PR_Lock(_pr_flock_lock); + fd->secret->lockCount = (status == PR_SUCCESS) ? 1 : 0; + PR_NotifyAllCondVar(_pr_flock_cv); + } else { + fd->secret->lockCount++; + } + PR_Unlock(_pr_flock_lock); + + return status; +} + +PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd) +{ + PRStatus status = PR_SUCCESS; + +#ifdef WINNT + if (!fd->secret->md.io_model_committed) { + PRInt32 rv; + rv = _md_Associate((HANDLE)fd->secret->md.osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } +#endif + + PR_Lock(_pr_flock_lock); + if (fd->secret->lockCount == 0) { + status = _PR_MD_TLOCKFILE(fd->secret->md.osfd); + PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0); + if (status == PR_SUCCESS) + fd->secret->lockCount = 1; + } else { + fd->secret->lockCount++; + } + PR_Unlock(_pr_flock_lock); + + return status; +} + +PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd) +{ + PRStatus rv = PR_SUCCESS; + + PR_Lock(_pr_flock_lock); + if (fd->secret->lockCount == 1) { + rv = _PR_MD_UNLOCKFILE(fd->secret->md.osfd); + if (rv == PR_SUCCESS) + fd->secret->lockCount = 0; + } else { + fd->secret->lockCount--; + } + PR_Unlock(_pr_flock_lock); + + return rv; +} + +PR_IMPLEMENT(PRStatus) PR_CreatePipe( + PRFileDesc **readPipe, + PRFileDesc **writePipe +) +{ +#if defined(WIN32) && !defined(WINCE) + HANDLE readEnd, writeEnd; + SECURITY_ATTRIBUTES pipeAttributes; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + ZeroMemory(&pipeAttributes, sizeof(pipeAttributes)); + pipeAttributes.nLength = sizeof(pipeAttributes); + pipeAttributes.bInheritHandle = TRUE; + if (CreatePipe(&readEnd, &writeEnd, &pipeAttributes, 0) == 0) { + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + return PR_FAILURE; + } + *readPipe = PR_AllocFileDesc((PROsfd)readEnd, &_pr_pipeMethods); + if (NULL == *readPipe) { + CloseHandle(readEnd); + CloseHandle(writeEnd); + return PR_FAILURE; + } + *writePipe = PR_AllocFileDesc((PROsfd)writeEnd, &_pr_pipeMethods); + if (NULL == *writePipe) { + PR_Close(*readPipe); + CloseHandle(writeEnd); + return PR_FAILURE; + } +#ifdef WINNT + (*readPipe)->secret->md.sync_file_io = PR_TRUE; + (*writePipe)->secret->md.sync_file_io = PR_TRUE; +#endif + (*readPipe)->secret->inheritable = _PR_TRI_TRUE; + (*writePipe)->secret->inheritable = _PR_TRI_TRUE; + return PR_SUCCESS; +#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) +#ifdef XP_OS2 + HFILE pipefd[2]; +#else + int pipefd[2]; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + +#ifdef XP_OS2 + if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) { +#else + if (pipe(pipefd) == -1) { +#endif + /* XXX map pipe error */ + PR_SetError(PR_UNKNOWN_ERROR, errno); + return PR_FAILURE; + } + *readPipe = PR_AllocFileDesc(pipefd[0], &_pr_pipeMethods); + if (NULL == *readPipe) { + close(pipefd[0]); + close(pipefd[1]); + return PR_FAILURE; + } + *writePipe = PR_AllocFileDesc(pipefd[1], &_pr_pipeMethods); + if (NULL == *writePipe) { + PR_Close(*readPipe); + close(pipefd[1]); + return PR_FAILURE; + } +#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */ + _PR_MD_MAKE_NONBLOCK(*readPipe); +#endif + _PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE); +#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */ + _PR_MD_MAKE_NONBLOCK(*writePipe); +#endif + _PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE); + return PR_SUCCESS; +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +#endif +} + +#ifdef MOZ_UNICODE +/* ================ UTF16 Interfaces ================================ */ +PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16( + const PRUnichar *name, PRIntn flags, PRIntn mode) +{ + PROsfd osfd; + PRFileDesc *fd = 0; +#if !defined(_PR_HAVE_O_APPEND) + PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + /* Map pr open flags and mode to os specific flags */ + osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode); + if (osfd != -1) { + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); + if (!fd) { + (void) _PR_MD_CLOSE_FILE(osfd); + } else { +#if !defined(_PR_HAVE_O_APPEND) + fd->secret->appendMode = appendMode; +#endif + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); + } + } + return fd; +} + +PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info) +{ + PRInt32 rv; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + rv = _PR_MD_GETFILEINFO64_UTF16(fn, info); + if (rv < 0) { + return PR_FAILURE; + } else { + return PR_SUCCESS; + } +} + +/* ================ UTF16 Interfaces ================================ */ +#endif /* MOZ_UNICODE */ diff -Nru nspr-4.9.5/nspr/pr/src/io/prio.c nspr-4.10.7/nspr/pr/src/io/prio.c --- nspr-4.9.5/nspr/pr/src/io/prio.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prio.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include /* for memset() */ + + +/************************************************************************/ + +PRLock *_pr_flock_lock; +PRCondVar *_pr_flock_cv; + +#ifdef WINCE +/* + * There are no stdin, stdout, stderr in Windows CE. INVALID_HANDLE_VALUE + * should cause all I/O functions on the handle to fail. + */ +#define STD_INPUT_HANDLE ((DWORD)-10) +#define STD_OUTPUT_HANDLE ((DWORD)-11) +#define STD_ERROR_HANDLE ((DWORD)-12) + +static HANDLE GetStdHandle(DWORD nStdHandle) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return INVALID_HANDLE_VALUE; +} +#endif + +void _PR_InitIO(void) +{ + const PRIOMethods *methods = PR_GetFileMethods(); + + _PR_InitFdCache(); + + _pr_flock_lock = PR_NewLock(); + _pr_flock_cv = PR_NewCondVar(_pr_flock_lock); + +#ifdef WIN32 + _pr_stdin = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_INPUT_HANDLE), + methods); + _pr_stdout = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_OUTPUT_HANDLE), + methods); + _pr_stderr = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_ERROR_HANDLE), + methods); +#ifdef WINNT + _pr_stdin->secret->md.sync_file_io = PR_TRUE; + _pr_stdout->secret->md.sync_file_io = PR_TRUE; + _pr_stderr->secret->md.sync_file_io = PR_TRUE; +#endif +#else + _pr_stdin = PR_AllocFileDesc(0, methods); + _pr_stdout = PR_AllocFileDesc(1, methods); + _pr_stderr = PR_AllocFileDesc(2, methods); +#endif + _PR_MD_INIT_FD_INHERITABLE(_pr_stdin, PR_TRUE); + _PR_MD_INIT_FD_INHERITABLE(_pr_stdout, PR_TRUE); + _PR_MD_INIT_FD_INHERITABLE(_pr_stderr, PR_TRUE); + + _PR_MD_INIT_IO(); +} + +void _PR_CleanupIO(void) +{ + PR_FreeFileDesc(_pr_stdin); + _pr_stdin = NULL; + PR_FreeFileDesc(_pr_stdout); + _pr_stdout = NULL; + PR_FreeFileDesc(_pr_stderr); + _pr_stderr = NULL; + + if (_pr_flock_cv) { + PR_DestroyCondVar(_pr_flock_cv); + _pr_flock_cv = NULL; + } + if (_pr_flock_lock) { + PR_DestroyLock(_pr_flock_lock); + _pr_flock_lock = NULL; + } + + _PR_CleanupFdCache(); +} + +PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd) +{ + PRFileDesc *result = NULL; + PR_ASSERT((int) osfd >= PR_StandardInput && osfd <= PR_StandardError); + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + switch (osfd) + { + case PR_StandardInput: result = _pr_stdin; break; + case PR_StandardOutput: result = _pr_stdout; break; + case PR_StandardError: result = _pr_stderr; break; + default: + (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + } + return result; +} + +PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc( + PROsfd osfd, const PRIOMethods *methods) +{ + PRFileDesc *fd; + +#ifdef XP_UNIX + /* + * Assert that the file descriptor is small enough to fit in the + * fd_set passed to select + */ + PR_ASSERT(osfd < FD_SETSIZE); +#endif + fd = _PR_Getfd(); + if (fd) { + /* Initialize the members of PRFileDesc and PRFilePrivate */ + fd->methods = methods; + fd->secret->state = _PR_FILEDESC_OPEN; + fd->secret->md.osfd = osfd; + _PR_MD_INIT_FILEDESC(fd); + } else { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + } + + return fd; +} + +PR_IMPLEMENT(void) PR_FreeFileDesc(PRFileDesc *fd) +{ + PR_ASSERT(fd); + _PR_Putfd(fd); +} + +/* +** Wait for some i/o to finish on one or more more poll descriptors. +*/ +PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + return(_PR_MD_PR_POLL(pds, npds, timeout)); +} + +/* +** Set the inheritance attribute of a file descriptor. +*/ +PR_IMPLEMENT(PRStatus) PR_SetFDInheritable( + PRFileDesc *fd, + PRBool inheritable) +{ +#if defined(XP_UNIX) || defined(WIN32) || defined(XP_OS2) || defined(XP_BEOS) + /* + * Only a non-layered, NSPR file descriptor can be inherited + * by a child process. + */ + if (fd->identity != PR_NSPR_IO_LAYER) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + if (fd->secret->inheritable != inheritable) { + if (_PR_MD_SET_FD_INHERITABLE(fd, inheritable) == PR_FAILURE) { + return PR_FAILURE; + } + fd->secret->inheritable = inheritable; + } + return PR_SUCCESS; +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +#endif +} + +/* +** This function only has a useful implementation in the debug build of +** the pthreads version. +*/ +PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) +{ + /* do nothing */ +} /* PT_FPrintStats */ diff -Nru nspr-4.9.5/nspr/pr/src/io/priometh.c nspr-4.10.7/nspr/pr/src/io/priometh.c --- nspr-4.9.5/nspr/pr/src/io/priometh.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/priometh.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,596 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "primpl.h" + +#include + +/*****************************************************************************/ +/************************** Invalid I/O method object ************************/ +/*****************************************************************************/ +PRIOMethods _pr_faulty_methods = { + (PRDescType)0, + (PRCloseFN)_PR_InvalidStatus, + (PRReadFN)_PR_InvalidInt, + (PRWriteFN)_PR_InvalidInt, + (PRAvailableFN)_PR_InvalidInt, + (PRAvailable64FN)_PR_InvalidInt64, + (PRFsyncFN)_PR_InvalidStatus, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + (PRWritevFN)_PR_InvalidInt, + (PRConnectFN)_PR_InvalidStatus, + (PRAcceptFN)_PR_InvalidDesc, + (PRBindFN)_PR_InvalidStatus, + (PRListenFN)_PR_InvalidStatus, + (PRShutdownFN)_PR_InvalidStatus, + (PRRecvFN)_PR_InvalidInt, + (PRSendFN)_PR_InvalidInt, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + (PRPollFN)_PR_InvalidInt16, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + (PRGetsocknameFN)_PR_InvalidStatus, + (PRGetpeernameFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRGetsocketoptionFN)_PR_InvalidStatus, + (PRSetsocketoptionFN)_PR_InvalidStatus, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +PRIntn _PR_InvalidInt(void) +{ + PR_ASSERT(!"I/O method is invalid"); + PR_SetError(PR_INVALID_METHOD_ERROR, 0); + return -1; +} /* _PR_InvalidInt */ + +PRInt16 _PR_InvalidInt16(void) +{ + PR_ASSERT(!"I/O method is invalid"); + PR_SetError(PR_INVALID_METHOD_ERROR, 0); + return -1; +} /* _PR_InvalidInt */ + +PRInt64 _PR_InvalidInt64(void) +{ + PRInt64 rv; + LL_I2L(rv, -1); + PR_ASSERT(!"I/O method is invalid"); + PR_SetError(PR_INVALID_METHOD_ERROR, 0); + return rv; +} /* _PR_InvalidInt */ + +/* + * An invalid method that returns PRStatus + */ + +PRStatus _PR_InvalidStatus(void) +{ + PR_ASSERT(!"I/O method is invalid"); + PR_SetError(PR_INVALID_METHOD_ERROR, 0); + return PR_FAILURE; +} /* _PR_InvalidDesc */ + +/* + * An invalid method that returns a pointer + */ + +PRFileDesc *_PR_InvalidDesc(void) +{ + PR_ASSERT(!"I/O method is invalid"); + PR_SetError(PR_INVALID_METHOD_ERROR, 0); + return NULL; +} /* _PR_InvalidDesc */ + +PR_IMPLEMENT(PRDescType) PR_GetDescType(PRFileDesc *file) +{ + return file->methods->file_type; +} + +PR_IMPLEMENT(PRStatus) PR_Close(PRFileDesc *fd) +{ + return (fd->methods->close)(fd); +} + +PR_IMPLEMENT(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount) +{ + return((fd->methods->read)(fd,buf,amount)); +} + +PR_IMPLEMENT(PRInt32) PR_Write(PRFileDesc *fd, const void *buf, PRInt32 amount) +{ + return((fd->methods->write)(fd,buf,amount)); +} + +PR_IMPLEMENT(PRInt32) PR_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence) +{ + return((fd->methods->seek)(fd, offset, whence)); +} + +PR_IMPLEMENT(PRInt64) PR_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence) +{ + return((fd->methods->seek64)(fd, offset, whence)); +} + +PR_IMPLEMENT(PRInt32) PR_Available(PRFileDesc *fd) +{ + return((fd->methods->available)(fd)); +} + +PR_IMPLEMENT(PRInt64) PR_Available64(PRFileDesc *fd) +{ + return((fd->methods->available64)(fd)); +} + +PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info) +{ + return((fd->methods->fileInfo)(fd, info)); +} + +PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info) +{ + return((fd->methods->fileInfo64)(fd, info)); +} + +PR_IMPLEMENT(PRStatus) PR_Sync(PRFileDesc *fd) +{ + return((fd->methods->fsync)(fd)); +} + +PR_IMPLEMENT(PRStatus) PR_Connect( + PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) +{ + return((fd->methods->connect)(fd,addr,timeout)); +} + +PR_IMPLEMENT(PRStatus) PR_ConnectContinue( + PRFileDesc *fd, PRInt16 out_flags) +{ + return((fd->methods->connectcontinue)(fd,out_flags)); +} + +PR_IMPLEMENT(PRFileDesc*) PR_Accept(PRFileDesc *fd, PRNetAddr *addr, +PRIntervalTime timeout) +{ + return((fd->methods->accept)(fd,addr,timeout)); +} + +PR_IMPLEMENT(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr) +{ + return((fd->methods->bind)(fd,addr)); +} + +PR_IMPLEMENT(PRStatus) PR_Shutdown(PRFileDesc *fd, PRShutdownHow how) +{ + return((fd->methods->shutdown)(fd,how)); +} + +PR_IMPLEMENT(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog) +{ + return((fd->methods->listen)(fd,backlog)); +} + +PR_IMPLEMENT(PRInt32) PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount, +PRIntn flags, PRIntervalTime timeout) +{ + return((fd->methods->recv)(fd,buf,amount,flags,timeout)); +} + +PR_IMPLEMENT(PRInt32) PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount, +PRIntn flags, PRIntervalTime timeout) +{ + return((fd->methods->send)(fd,buf,amount,flags,timeout)); +} + +PR_IMPLEMENT(PRInt32) PR_Writev(PRFileDesc *fd, const PRIOVec *iov, +PRInt32 iov_size, PRIntervalTime timeout) +{ + if (iov_size > PR_MAX_IOVECTOR_SIZE) + { + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); + return -1; + } + return((fd->methods->writev)(fd,iov,iov_size,timeout)); +} + +PR_IMPLEMENT(PRInt32) PR_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, +PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) +{ + return((fd->methods->recvfrom)(fd,buf,amount,flags,addr,timeout)); +} + +PR_IMPLEMENT(PRInt32) PR_SendTo( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout) +{ + return((fd->methods->sendto)(fd,buf,amount,flags,addr,timeout)); +} + +PR_IMPLEMENT(PRInt32) PR_TransmitFile( + PRFileDesc *sd, PRFileDesc *fd, const void *hdr, PRInt32 hlen, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + return((sd->methods->transmitfile)(sd,fd,hdr,hlen,flags,timeout)); +} + +PR_IMPLEMENT(PRInt32) PR_AcceptRead( + PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, + void *buf, PRInt32 amount, PRIntervalTime timeout) +{ + return((sd->methods->acceptread)(sd, nd, raddr, buf, amount,timeout)); +} + +PR_IMPLEMENT(PRStatus) PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr) +{ + return((fd->methods->getsockname)(fd,addr)); +} + +PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) +{ + return((fd->methods->getpeername)(fd,addr)); +} + +PR_IMPLEMENT(PRStatus) PR_GetSocketOption( + PRFileDesc *fd, PRSocketOptionData *data) +{ + return((fd->methods->getsocketoption)(fd, data)); +} + +PR_IMPLEMENT(PRStatus) PR_SetSocketOption( + PRFileDesc *fd, const PRSocketOptionData *data) +{ + return((fd->methods->setsocketoption)(fd, data)); +} + +PR_IMPLEMENT(PRInt32) PR_SendFile( + PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + return((sd->methods->sendfile)(sd,sfd,flags,timeout)); +} + +PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead( + PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, + void *buf, PRInt32 amount, PRIntervalTime timeout) +{ + PRInt32 rv = -1; + PRNetAddr remote; + PRFileDesc *accepted = NULL; + + /* + ** The timeout does not apply to the accept portion of the + ** operation - it waits indefinitely. + */ + accepted = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT); + if (NULL == accepted) return rv; + + rv = PR_Recv(accepted, buf, amount, 0, timeout); + if (rv >= 0) + { + /* copy the new info out where caller can see it */ +#define AMASK ((PRPtrdiff)7) /* mask for alignment of PRNetAddr */ + PRPtrdiff aligned = (PRPtrdiff)buf + amount + AMASK; + *raddr = (PRNetAddr*)(aligned & ~AMASK); + memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote)); + *nd = accepted; + return rv; + } + + PR_Close(accepted); + return rv; +} + +/* + * PR_EmulateSendFile + * + * Send file sfd->fd across socket sd. If header/trailer are specified + * they are sent before and after the file, respectively. + * + * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file + * + * return number of bytes sent or -1 on error + * + */ + +#if defined(XP_UNIX) || defined(WIN32) + +/* + * An implementation based on memory-mapped files + */ + +#define SENDFILE_MMAP_CHUNK (256 * 1024) + +PR_IMPLEMENT(PRInt32) PR_EmulateSendFile( + PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + PRInt32 rv, count = 0; + PRInt32 len, file_bytes, index = 0; + PRFileInfo info; + PRIOVec iov[3]; + PRFileMap *mapHandle = NULL; + void *addr = (void*)0; /* initialized to some arbitrary value. Keeps compiler warnings down. */ + PRUint32 file_mmap_offset, alignment; + PRInt64 zero64; + PROffset64 file_mmap_offset64; + PRUint32 addr_offset, mmap_len; + + /* Get file size */ + if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) { + count = -1; + goto done; + } + if (sfd->file_nbytes && + (info.size < (sfd->file_offset + sfd->file_nbytes))) { + /* + * there are fewer bytes in file to send than specified + */ + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + count = -1; + goto done; + } + if (sfd->file_nbytes) + file_bytes = sfd->file_nbytes; + else + file_bytes = info.size - sfd->file_offset; + + alignment = PR_GetMemMapAlignment(); + + /* number of initial bytes to skip in mmap'd segment */ + addr_offset = sfd->file_offset % alignment; + + /* find previous mmap alignment boundary */ + file_mmap_offset = sfd->file_offset - addr_offset; + + /* + * If the file is large, mmap and send the file in chunks so as + * to not consume too much virtual address space + */ + mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK); + len = mmap_len - addr_offset; + + /* + * Map in (part of) file. Take care of zero-length files. + */ + if (len) { + LL_I2L(zero64, 0); + mapHandle = PR_CreateFileMap(sfd->fd, zero64, PR_PROT_READONLY); + if (!mapHandle) { + count = -1; + goto done; + } + LL_I2L(file_mmap_offset64, file_mmap_offset); + addr = PR_MemMap(mapHandle, file_mmap_offset64, mmap_len); + if (!addr) { + count = -1; + goto done; + } + } + /* + * send headers first, followed by the file + */ + if (sfd->hlen) { + iov[index].iov_base = (char *) sfd->header; + iov[index].iov_len = sfd->hlen; + index++; + } + if (len) { + iov[index].iov_base = (char*)addr + addr_offset; + iov[index].iov_len = len; + index++; + } + if ((file_bytes == len) && (sfd->tlen)) { + /* + * all file data is mapped in; send the trailer too + */ + iov[index].iov_base = (char *) sfd->trailer; + iov[index].iov_len = sfd->tlen; + index++; + } + rv = PR_Writev(sd, iov, index, timeout); + if (len) + PR_MemUnmap(addr, mmap_len); + if (rv < 0) { + count = -1; + goto done; + } + + PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0)); + + file_bytes -= len; + count += rv; + if (!file_bytes) /* header, file and trailer are sent */ + goto done; + + /* + * send remaining bytes of the file, if any + */ + len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); + while (len > 0) { + /* + * Map in (part of) file + */ + file_mmap_offset = sfd->file_offset + count - sfd->hlen; + PR_ASSERT((file_mmap_offset % alignment) == 0); + + LL_I2L(file_mmap_offset64, file_mmap_offset); + addr = PR_MemMap(mapHandle, file_mmap_offset64, len); + if (!addr) { + count = -1; + goto done; + } + rv = PR_Send(sd, addr, len, 0, timeout); + PR_MemUnmap(addr, len); + if (rv < 0) { + count = -1; + goto done; + } + + PR_ASSERT(rv == len); + file_bytes -= rv; + count += rv; + len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); + } + PR_ASSERT(0 == file_bytes); + if (sfd->tlen) { + rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout); + if (rv >= 0) { + PR_ASSERT(rv == sfd->tlen); + count += rv; + } else + count = -1; + } +done: + if (mapHandle) + PR_CloseFileMap(mapHandle); + if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) + PR_Close(sd); + return count; +} + +#else + +PR_IMPLEMENT(PRInt32) PR_EmulateSendFile( + PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + PRInt32 rv, count = 0; + PRInt32 rlen; + const void * buffer; + PRInt32 buflen; + PRInt32 sendbytes, readbytes; + char *buf; + +#define _SENDFILE_BUFSIZE (16 * 1024) + + buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE); + if (buf == NULL) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + + /* + * send header first + */ + buflen = sfd->hlen; + buffer = sfd->header; + while (buflen) { + rv = PR_Send(sd, buffer, buflen, 0, timeout); + if (rv < 0) { + /* PR_Send() has invoked PR_SetError(). */ + rv = -1; + goto done; + } else { + count += rv; + buffer = (const void*) ((const char*)buffer + rv); + buflen -= rv; + } + } + + /* + * send file next + */ + if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) { + rv = -1; + goto done; + } + sendbytes = sfd->file_nbytes; + if (sendbytes == 0) { + /* send entire file */ + while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) { + while (rlen) { + char *bufptr = buf; + + rv = PR_Send(sd, bufptr, rlen, 0, timeout); + if (rv < 0) { + /* PR_Send() has invoked PR_SetError(). */ + rv = -1; + goto done; + } else { + count += rv; + bufptr = ((char*)bufptr + rv); + rlen -= rv; + } + } + } + if (rlen < 0) { + /* PR_Read() has invoked PR_SetError(). */ + rv = -1; + goto done; + } + } else { + readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); + while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) { + while (rlen) { + char *bufptr = buf; + + rv = PR_Send(sd, bufptr, rlen, 0, timeout); + if (rv < 0) { + /* PR_Send() has invoked PR_SetError(). */ + rv = -1; + goto done; + } else { + count += rv; + sendbytes -= rv; + bufptr = ((char*)bufptr + rv); + rlen -= rv; + } + } + readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); + } + if (rlen < 0) { + /* PR_Read() has invoked PR_SetError(). */ + rv = -1; + goto done; + } else if (sendbytes != 0) { + /* + * there are fewer bytes in file to send than specified + */ + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = -1; + goto done; + } + } + + /* + * send trailer last + */ + buflen = sfd->tlen; + buffer = sfd->trailer; + while (buflen) { + rv = PR_Send(sd, buffer, buflen, 0, timeout); + if (rv < 0) { + /* PR_Send() has invoked PR_SetError(). */ + rv = -1; + goto done; + } else { + count += rv; + buffer = (const void*) ((const char*)buffer + rv); + buflen -= rv; + } + } + rv = count; + +done: + if (buf) + PR_DELETE(buf); + if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) + PR_Close(sd); + return rv; +} + +#endif + +/* priometh.c */ diff -Nru nspr-4.9.5/nspr/pr/src/io/pripv6.c nspr-4.10.7/nspr/pr/src/io/pripv6.c --- nspr-4.9.5/nspr/pr/src/io/pripv6.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/pripv6.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,364 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: pripv6.c +** Description: Support for various functions unique to IPv6 +*/ +#include "primpl.h" +#include + +#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE) + +static PRIOMethods ipv6_to_v4_tcpMethods; +static PRIOMethods ipv6_to_v4_udpMethods; +static PRDescIdentity _pr_ipv6_to_ipv4_id; +extern PRBool IsValidNetAddr(const PRNetAddr *addr); +extern PRIPv6Addr _pr_in6addr_any; +extern PRIPv6Addr _pr_in6addr_loopback; + +/* + * convert an IPv4-mapped IPv6 addr to an IPv4 addr + */ +static void _PR_ConvertToIpv4NetAddr(const PRNetAddr *src_v6addr, + PRNetAddr *dst_v4addr) +{ +const PRUint8 *srcp; + + PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family); + + if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) { + srcp = src_v6addr->ipv6.ip.pr_s6_addr; + memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4); + } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrAny)) { + dst_v4addr->inet.ip = htonl(INADDR_ANY); + } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback)) { + dst_v4addr->inet.ip = htonl(INADDR_LOOPBACK); + } + dst_v4addr->inet.family = PR_AF_INET; + dst_v4addr->inet.port = src_v6addr->ipv6.port; +} + +/* + * convert an IPv4 addr to an IPv4-mapped IPv6 addr + */ +static void _PR_ConvertToIpv6NetAddr(const PRNetAddr *src_v4addr, + PRNetAddr *dst_v6addr) +{ +PRUint8 *dstp; + + PR_ASSERT(PR_AF_INET == src_v4addr->inet.family); + dst_v6addr->ipv6.family = PR_AF_INET6; + dst_v6addr->ipv6.port = src_v4addr->inet.port; + + if (htonl(INADDR_ANY) == src_v4addr->inet.ip) { + dst_v6addr->ipv6.ip = _pr_in6addr_any; + } else { + dstp = dst_v6addr->ipv6.ip.pr_s6_addr; + memset(dstp, 0, 10); + memset(dstp + 10, 0xff, 2); + memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4); + } +} + +static PRStatus PR_CALLBACK Ipv6ToIpv4SocketBind(PRFileDesc *fd, + const PRNetAddr *addr) +{ + PRNetAddr tmp_ipv4addr; + const PRNetAddr *tmp_addrp; + PRFileDesc *lo = fd->lower; + + if (PR_AF_INET6 != addr->raw.family) { + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); + return PR_FAILURE; + } + if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || + PR_IsNetAddrType(addr, PR_IpAddrAny)) { + _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); + tmp_addrp = &tmp_ipv4addr; + } else { + PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); + return PR_FAILURE; + } + return((lo->methods->bind)(lo,tmp_addrp)); +} + +static PRStatus PR_CALLBACK Ipv6ToIpv4SocketConnect( + PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) +{ + PRNetAddr tmp_ipv4addr; + const PRNetAddr *tmp_addrp; + + if (PR_AF_INET6 != addr->raw.family) { + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); + return PR_FAILURE; + } + if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || + PR_IsNetAddrType(addr, PR_IpAddrLoopback)) { + _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); + tmp_addrp = &tmp_ipv4addr; + } else { + PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); + return PR_FAILURE; + } + return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout); +} + +static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketSendTo( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout) +{ + PRNetAddr tmp_ipv4addr; + const PRNetAddr *tmp_addrp; + + if (PR_AF_INET6 != addr->raw.family) { + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); + return PR_FAILURE; + } + if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) || + PR_IsNetAddrType(addr, PR_IpAddrLoopback)) { + _PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr); + tmp_addrp = &tmp_ipv4addr; + } else { + PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0); + return PR_FAILURE; + } + return (fd->lower->methods->sendto)( + fd->lower, buf, amount, flags, tmp_addrp, timeout); +} + +static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept ( + PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout) +{ + PRStatus rv; + PRFileDesc *newfd; + PRFileDesc *newstack; + PRNetAddr tmp_ipv4addr; + PRNetAddr *addrlower = NULL; + + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + newstack = PR_NEW(PRFileDesc); + if (NULL == newstack) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + *newstack = *fd; /* make a copy of the accepting layer */ + + if (addr) + addrlower = &tmp_ipv4addr; + newfd = (fd->lower->methods->accept)(fd->lower, addrlower, timeout); + if (NULL == newfd) + { + PR_DELETE(newstack); + return NULL; + } + if (addr) + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, addr); + + rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); + PR_ASSERT(PR_SUCCESS == rv); + return newfd; /* that's it */ +} + +static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd, + PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount, + PRIntervalTime timeout) +{ + PRInt32 nbytes; + PRStatus rv; + PRNetAddr tmp_ipv4addr; + PRFileDesc *newstack; + + PR_ASSERT(sd != NULL); + PR_ASSERT(sd->lower != NULL); + + newstack = PR_NEW(PRFileDesc); + if (NULL == newstack) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + *newstack = *sd; /* make a copy of the accepting layer */ + + nbytes = sd->lower->methods->acceptread( + sd->lower, nd, ipv6_raddr, buf, amount, timeout); + if (-1 == nbytes) + { + PR_DELETE(newstack); + return nbytes; + } + tmp_ipv4addr = **ipv6_raddr; /* copy */ + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr); + + /* this PR_PushIOLayer call cannot fail */ + rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack); + PR_ASSERT(PR_SUCCESS == rv); + return nbytes; +} + +static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetName(PRFileDesc *fd, + PRNetAddr *ipv6addr) +{ + PRStatus result; + PRNetAddr tmp_ipv4addr; + + result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr); + if (PR_SUCCESS == result) { + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); + PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); + } + return result; +} + +static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetPeerName(PRFileDesc *fd, + PRNetAddr *ipv6addr) +{ + PRStatus result; + PRNetAddr tmp_ipv4addr; + + result = (fd->lower->methods->getpeername)(fd->lower, &tmp_ipv4addr); + if (PR_SUCCESS == result) { + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); + PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); + } + return result; +} + +static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf, + PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr, + PRIntervalTime timeout) +{ + PRNetAddr tmp_ipv4addr; + PRInt32 result; + + result = (fd->lower->methods->recvfrom)( + fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout); + if (-1 != result) { + _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr); + PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE); + } + return result; +} + +#if defined(_PR_INET6_PROBE) +static PRBool ipv6_is_present; +extern PRBool _pr_test_ipv6_socket(void); + +#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) +extern PRStatus _pr_find_getipnodebyname(void); +#endif + +#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO) +extern PRStatus _pr_find_getaddrinfo(void); +#endif + +static PRBool +_pr_probe_ipv6_presence(void) +{ +#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) + if (_pr_find_getipnodebyname() != PR_SUCCESS) + return PR_FALSE; +#endif + +#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO) + if (_pr_find_getaddrinfo() != PR_SUCCESS) + return PR_FALSE; +#endif + + return _pr_test_ipv6_socket(); +} +#endif /* _PR_INET6_PROBE */ + +static PRCallOnceType _pr_init_ipv6_once; + +static PRStatus PR_CALLBACK _pr_init_ipv6(void) +{ + const PRIOMethods *stubMethods; + +#if defined(_PR_INET6_PROBE) + ipv6_is_present = _pr_probe_ipv6_presence(); + if (ipv6_is_present) + return PR_SUCCESS; +#endif + + _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer"); + PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id); + + stubMethods = PR_GetDefaultIOMethods(); + + ipv6_to_v4_tcpMethods = *stubMethods; /* first get the entire batch */ + /* then override the ones we care about */ + ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect; + ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind; + ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept; + ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead; + ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName; + ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName; +/* + ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption; + ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption; +*/ + ipv6_to_v4_udpMethods = *stubMethods; /* first get the entire batch */ + /* then override the ones we care about */ + ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect; + ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind; + ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo; + ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom; + ipv6_to_v4_udpMethods.getsockname = Ipv6ToIpv4SocketGetName; + ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName; +/* + ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption; + ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption; +*/ + return PR_SUCCESS; +} + +#if defined(_PR_INET6_PROBE) +PRBool _pr_ipv6_is_present(void) +{ + if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) + return PR_FALSE; + return ipv6_is_present; +} +#endif + +PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd) +{ + PRFileDesc *ipv6_fd = NULL; + + if (PR_CallOnce(&_pr_init_ipv6_once, _pr_init_ipv6) != PR_SUCCESS) + return PR_FAILURE; + + /* + * For platforms with no support for IPv6 + * create layered socket for IPv4-mapped IPv6 addresses + */ + if (fd->methods->file_type == PR_DESC_SOCKET_TCP) + ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id, + &ipv6_to_v4_tcpMethods); + else + ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id, + &ipv6_to_v4_udpMethods); + if (NULL == ipv6_fd) { + goto errorExit; + } + ipv6_fd->secret = NULL; + + if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) { + goto errorExit; + } + + return PR_SUCCESS; +errorExit: + + if (ipv6_fd) + ipv6_fd->dtor(ipv6_fd); + return PR_FAILURE; +} + +#endif /* !defined(_PR_INET6) || defined(_PR_INET6_PROBE) */ diff -Nru nspr-4.9.5/nspr/pr/src/io/prlayer.c nspr-4.10.7/nspr/pr/src/io/prlayer.c --- nspr-4.9.5/nspr/pr/src/io/prlayer.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prlayer.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,752 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prlayer.c +** Description: Routines for handling pushable protocol modules on sockets. +*/ + +#include "primpl.h" +#include "prerror.h" +#include "prmem.h" +#include "prlock.h" +#include "prlog.h" +#include "prio.h" + +#include /* for memset() */ +static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack); + +void PR_CALLBACK pl_FDDestructor(PRFileDesc *fd) +{ + PR_ASSERT(fd != NULL); + if (NULL != fd->lower) fd->lower->higher = fd->higher; + if (NULL != fd->higher) fd->higher->lower = fd->lower; + PR_DELETE(fd); +} + +/* +** Default methods that just call down to the next fd. +*/ +static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd) +{ + PRFileDesc *top, *lower; + PRStatus rv; + + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + PR_ASSERT(fd->secret == NULL); + PR_ASSERT(fd->methods->file_type == PR_DESC_LAYERED); + + if (PR_IO_LAYER_HEAD == fd->identity) { + /* + * new style stack; close all the layers, before deleting the + * stack head + */ + rv = fd->lower->methods->close(fd->lower); + _PR_DestroyIOLayer(fd); + return rv; + } else if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) { + /* + * lower layers of new style stack + */ + lower = fd->lower; + /* + * pop and cleanup current layer + */ + top = PR_PopIOLayer(fd->higher, PR_TOP_IO_LAYER); + top->dtor(top); + /* + * then call lower layer + */ + return (lower->methods->close(lower)); + } else { + /* old style stack */ + top = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); + top->dtor(top); + return (fd->methods->close)(fd); + } +} + +static PRInt32 PR_CALLBACK pl_DefRead (PRFileDesc *fd, void *buf, PRInt32 amount) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->read)(fd->lower, buf, amount); +} + +static PRInt32 PR_CALLBACK pl_DefWrite ( + PRFileDesc *fd, const void *buf, PRInt32 amount) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->write)(fd->lower, buf, amount); +} + +static PRInt32 PR_CALLBACK pl_DefAvailable (PRFileDesc *fd) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->available)(fd->lower); +} + +static PRInt64 PR_CALLBACK pl_DefAvailable64 (PRFileDesc *fd) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->available64)(fd->lower); +} + +static PRStatus PR_CALLBACK pl_DefFsync (PRFileDesc *fd) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->fsync)(fd->lower); +} + +static PRInt32 PR_CALLBACK pl_DefSeek ( + PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->seek)(fd->lower, offset, how); +} + +static PRInt64 PR_CALLBACK pl_DefSeek64 ( + PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->seek64)(fd->lower, offset, how); +} + +static PRStatus PR_CALLBACK pl_DefFileInfo (PRFileDesc *fd, PRFileInfo *info) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->fileInfo)(fd->lower, info); +} + +static PRStatus PR_CALLBACK pl_DefFileInfo64 (PRFileDesc *fd, PRFileInfo64 *info) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->fileInfo64)(fd->lower, info); +} + +static PRInt32 PR_CALLBACK pl_DefWritev (PRFileDesc *fd, const PRIOVec *iov, + PRInt32 size, PRIntervalTime timeout) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->writev)(fd->lower, iov, size, timeout); +} + +static PRStatus PR_CALLBACK pl_DefConnect ( + PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->connect)(fd->lower, addr, timeout); +} + +static PRStatus PR_CALLBACK pl_DefConnectcontinue ( + PRFileDesc *fd, PRInt16 out_flags) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->connectcontinue)(fd->lower, out_flags); +} + +static PRFileDesc* PR_CALLBACK pl_TopAccept ( + PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout) +{ + PRStatus rv; + PRFileDesc *newfd, *layer = fd; + PRFileDesc *newstack; + PRBool newstyle_stack = PR_FALSE; + + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + /* test for new style stack */ + while (NULL != layer->higher) + layer = layer->higher; + newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE; + newstack = PR_NEW(PRFileDesc); + if (NULL == newstack) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + *newstack = *fd; /* make a copy of the accepting layer */ + + newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout); + if (NULL == newfd) + { + PR_DELETE(newstack); + return NULL; + } + + if (newstyle_stack) { + newstack->lower = newfd; + newfd->higher = newstack; + return newstack; + } else { + /* this PR_PushIOLayer call cannot fail */ + rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); + PR_ASSERT(PR_SUCCESS == rv); + return newfd; /* that's it */ + } +} + +static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->bind)(fd->lower, addr); +} + +static PRStatus PR_CALLBACK pl_DefListen (PRFileDesc *fd, PRIntn backlog) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->listen)(fd->lower, backlog); +} + +static PRStatus PR_CALLBACK pl_DefShutdown (PRFileDesc *fd, PRIntn how) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->shutdown)(fd->lower, how); +} + +static PRInt32 PR_CALLBACK pl_DefRecv ( + PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->recv)( + fd->lower, buf, amount, flags, timeout); +} + +static PRInt32 PR_CALLBACK pl_DefSend ( + PRFileDesc *fd, const void *buf, + PRInt32 amount, PRIntn flags, PRIntervalTime timeout) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->send)(fd->lower, buf, amount, flags, timeout); +} + +static PRInt32 PR_CALLBACK pl_DefRecvfrom ( + PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->recvfrom)( + fd->lower, buf, amount, flags, addr, timeout); +} + +static PRInt32 PR_CALLBACK pl_DefSendto ( + PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRIntervalTime timeout) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->sendto)( + fd->lower, buf, amount, flags, addr, timeout); +} + +static PRInt16 PR_CALLBACK pl_DefPoll ( + PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags); +} + +static PRInt32 PR_CALLBACK pl_DefAcceptread ( + PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf, + PRInt32 amount, PRIntervalTime t) +{ + PRInt32 nbytes; + PRStatus rv; + PRFileDesc *newstack; + PRFileDesc *layer = sd; + PRBool newstyle_stack = PR_FALSE; + + PR_ASSERT(sd != NULL); + PR_ASSERT(sd->lower != NULL); + + /* test for new style stack */ + while (NULL != layer->higher) + layer = layer->higher; + newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE; + newstack = PR_NEW(PRFileDesc); + if (NULL == newstack) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + *newstack = *sd; /* make a copy of the accepting layer */ + + nbytes = sd->lower->methods->acceptread( + sd->lower, nd, raddr, buf, amount, t); + if (-1 == nbytes) + { + PR_DELETE(newstack); + return nbytes; + } + if (newstyle_stack) { + newstack->lower = *nd; + (*nd)->higher = newstack; + *nd = newstack; + return nbytes; + } else { + /* this PR_PushIOLayer call cannot fail */ + rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack); + PR_ASSERT(PR_SUCCESS == rv); + return nbytes; + } +} + +static PRInt32 PR_CALLBACK pl_DefTransmitfile ( + PRFileDesc *sd, PRFileDesc *fd, const void *headers, PRInt32 hlen, + PRTransmitFileFlags flags, PRIntervalTime t) +{ + PR_ASSERT(sd != NULL); + PR_ASSERT(sd->lower != NULL); + + return sd->lower->methods->transmitfile( + sd->lower, fd, headers, hlen, flags, t); +} + +static PRStatus PR_CALLBACK pl_DefGetsockname (PRFileDesc *fd, PRNetAddr *addr) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->getsockname)(fd->lower, addr); +} + +static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->getpeername)(fd->lower, addr); +} + +static PRStatus PR_CALLBACK pl_DefGetsocketoption ( + PRFileDesc *fd, PRSocketOptionData *data) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->getsocketoption)(fd->lower, data); +} + +static PRStatus PR_CALLBACK pl_DefSetsocketoption ( + PRFileDesc *fd, const PRSocketOptionData *data) +{ + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + return (fd->lower->methods->setsocketoption)(fd->lower, data); +} + +static PRInt32 PR_CALLBACK pl_DefSendfile ( + PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + PR_ASSERT(sd != NULL); + PR_ASSERT(sd->lower != NULL); + + return sd->lower->methods->sendfile( + sd->lower, sfd, flags, timeout); +} + +/* Methods for the top of the stack. Just call down to the next fd. */ +static PRIOMethods pl_methods = { + PR_DESC_LAYERED, + pl_TopClose, + pl_DefRead, + pl_DefWrite, + pl_DefAvailable, + pl_DefAvailable64, + pl_DefFsync, + pl_DefSeek, + pl_DefSeek64, + pl_DefFileInfo, + pl_DefFileInfo64, + pl_DefWritev, + pl_DefConnect, + pl_TopAccept, + pl_DefBind, + pl_DefListen, + pl_DefShutdown, + pl_DefRecv, + pl_DefSend, + pl_DefRecvfrom, + pl_DefSendto, + pl_DefPoll, + pl_DefAcceptread, + pl_DefTransmitfile, + pl_DefGetsockname, + pl_DefGetpeername, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + pl_DefGetsocketoption, + pl_DefSetsocketoption, + pl_DefSendfile, + pl_DefConnectcontinue, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods(void) +{ + return &pl_methods; +} /* PR_GetDefaultIOMethods */ + +PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub( + PRDescIdentity ident, const PRIOMethods *methods) +{ + PRFileDesc *fd = NULL; + PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident)); + if ((PR_NSPR_IO_LAYER == ident) || (PR_TOP_IO_LAYER == ident)) + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + else + { + fd = PR_NEWZAP(PRFileDesc); + if (NULL == fd) + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + else + { + fd->methods = methods; + fd->dtor = pl_FDDestructor; + fd->identity = ident; + } + } + return fd; +} /* PR_CreateIOLayerStub */ + +/* + * PR_CreateIOLayer + * Create a new style stack, where the stack top is a dummy header. + * Unlike the old style stacks, the contents of the stack head + * are not modified when a layer is pushed onto or popped from a new + * style stack. + */ + +PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayer(PRFileDesc *top) +{ + PRFileDesc *fd = NULL; + + fd = PR_NEWZAP(PRFileDesc); + if (NULL == fd) + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + else + { + fd->methods = &pl_methods; + fd->dtor = pl_FDDestructor; + fd->identity = PR_IO_LAYER_HEAD; + fd->higher = NULL; + fd->lower = top; + top->higher = fd; + top->lower = NULL; + } + return fd; +} /* PR_CreateIOLayer */ + +/* + * _PR_DestroyIOLayer + * Delete the stack head of a new style stack. + */ + +static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack) +{ + if (NULL == stack) + return PR_FAILURE; + else { + PR_DELETE(stack); + return PR_SUCCESS; + } +} /* _PR_DestroyIOLayer */ + +PR_IMPLEMENT(PRStatus) PR_PushIOLayer( + PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd) +{ + PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id); + + PR_ASSERT(fd != NULL); + PR_ASSERT(stack != NULL); + PR_ASSERT(insert != NULL); + PR_ASSERT(PR_IO_LAYER_HEAD != id); + if ((NULL == stack) || (NULL == fd) || (NULL == insert)) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + if (stack == insert) + { + /* going on top of the stack */ + /* old-style stack */ + PRFileDesc copy = *stack; + *stack = *fd; + *fd = copy; + fd->higher = stack; + if (fd->lower) + { + PR_ASSERT(fd->lower->higher == stack); + fd->lower->higher = fd; + } + stack->lower = fd; + stack->higher = NULL; + } else { + /* + * going somewhere in the middle of the stack for both old and new + * style stacks, or going on top of stack for new style stack + */ + fd->lower = insert; + fd->higher = insert->higher; + + insert->higher->lower = fd; + insert->higher = fd; + } + + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id) +{ + PRFileDesc *extract = PR_GetIdentitiesLayer(stack, id); + + PR_ASSERT(0 != id); + PR_ASSERT(NULL != stack); + PR_ASSERT(NULL != extract); + if ((NULL == stack) || (0 == id) || (NULL == extract)) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } + + if (extract == stack) { + /* popping top layer of the stack */ + /* old style stack */ + PRFileDesc copy = *stack; + extract = stack->lower; + *stack = *extract; + *extract = copy; + stack->higher = NULL; + if (stack->lower) { + PR_ASSERT(stack->lower->higher == extract); + stack->lower->higher = stack; + } + } else if ((PR_IO_LAYER_HEAD == stack->identity) && + (extract == stack->lower) && (extract->lower == NULL)) { + /* + * new style stack + * popping the only layer in the stack; delete the stack too + */ + stack->lower = NULL; + _PR_DestroyIOLayer(stack); + } else { + /* for both kinds of stacks */ + extract->lower->higher = extract->higher; + extract->higher->lower = extract->lower; + } + extract->higher = extract->lower = NULL; + return extract; +} /* PR_PopIOLayer */ + +#define ID_CACHE_INCREMENT 16 +typedef struct _PRIdentity_cache +{ + PRLock *ml; + char **name; + PRIntn length; + PRDescIdentity ident; +} _PRIdentity_cache; + +static _PRIdentity_cache identity_cache; + +PR_IMPLEMENT(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name) +{ + PRDescIdentity identity, length; + char **names = NULL, *name = NULL, **old = NULL; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + PR_ASSERT((PRDescIdentity)0x7fff > identity_cache.ident); + + if (NULL != layer_name) + { + name = (char*)PR_Malloc(strlen(layer_name) + 1); + if (NULL == name) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return PR_INVALID_IO_LAYER; + } + strcpy(name, layer_name); + } + + /* this initial code runs unsafe */ +retry: + PR_ASSERT(NULL == names); + /* + * In the initial round, both identity_cache.ident and + * identity_cache.length are 0, so (identity_cache.ident + 1) is greater + * than length. In later rounds, identity_cache.ident is always less + * than length, so (identity_cache.ident + 1) can be equal to but cannot + * be greater than length. + */ + length = identity_cache.length; + if ((identity_cache.ident + 1) >= length) + { + length += ID_CACHE_INCREMENT; + names = (char**)PR_CALLOC(length * sizeof(char*)); + if (NULL == names) + { + if (NULL != name) PR_DELETE(name); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return PR_INVALID_IO_LAYER; + } + } + + /* now we get serious about thread safety */ + PR_Lock(identity_cache.ml); + PR_ASSERT(identity_cache.length == 0 || + identity_cache.ident < identity_cache.length); + identity = identity_cache.ident + 1; + if (identity >= identity_cache.length) /* there's no room */ + { + /* we have to do something - hopefully it's already done */ + if ((NULL != names) && (identity < length)) + { + /* what we did is still okay */ + memcpy( + names, identity_cache.name, + identity_cache.length * sizeof(char*)); + old = identity_cache.name; + identity_cache.name = names; + identity_cache.length = length; + names = NULL; + } + else + { + PR_Unlock(identity_cache.ml); + if (NULL != names) PR_DELETE(names); + goto retry; + } + } + if (NULL != name) /* there's a name to be stored */ + { + identity_cache.name[identity] = name; + } + identity_cache.ident = identity; + PR_ASSERT(identity_cache.ident < identity_cache.length); + PR_Unlock(identity_cache.ml); + + if (NULL != old) PR_DELETE(old); + if (NULL != names) PR_DELETE(names); + + return identity; +} /* PR_GetUniqueIdentity */ + +PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (PR_TOP_IO_LAYER == ident) return NULL; + + PR_ASSERT(ident <= identity_cache.ident); + return (ident > identity_cache.ident) ? NULL : identity_cache.name[ident]; +} /* PR_GetNameForIdentity */ + +PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd) +{ + PR_ASSERT(NULL != fd); + if (PR_IO_LAYER_HEAD == fd->identity) { + PR_ASSERT(NULL != fd->lower); + return fd->lower->identity; + } else + return fd->identity; +} /* PR_GetLayersIdentity */ + +PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id) +{ + PRFileDesc *layer = fd; + + if (PR_TOP_IO_LAYER == id) { + if (PR_IO_LAYER_HEAD == fd->identity) + return fd->lower; + else + return fd; + } + + for (layer = fd; layer != NULL; layer = layer->lower) + { + if (id == layer->identity) return layer; + } + for (layer = fd; layer != NULL; layer = layer->higher) + { + if (id == layer->identity) return layer; + } + return NULL; +} /* PR_GetIdentitiesLayer */ + +void _PR_InitLayerCache(void) +{ + memset(&identity_cache, 0, sizeof(identity_cache)); + identity_cache.ml = PR_NewLock(); + PR_ASSERT(NULL != identity_cache.ml); +} /* _PR_InitLayerCache */ + +void _PR_CleanupLayerCache(void) +{ + if (identity_cache.ml) + { + PR_DestroyLock(identity_cache.ml); + identity_cache.ml = NULL; + } + + if (identity_cache.name) + { + PRDescIdentity ident; + + for (ident = 0; ident <= identity_cache.ident; ident++) + PR_DELETE(identity_cache.name[ident]); + + PR_DELETE(identity_cache.name); + } +} /* _PR_CleanupLayerCache */ + +/* prlayer.c */ diff -Nru nspr-4.9.5/nspr/pr/src/io/prlog.c nspr-4.10.7/nspr/pr/src/io/prlog.c --- nspr-4.9.5/nspr/pr/src/io/prlog.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prlog.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,555 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include "prenv.h" +#include "prprf.h" +#include +#ifdef ANDROID +#include +#endif + +/* + * Lock used to lock the log. + * + * We can't define _PR_LOCK_LOG simply as PR_Lock because PR_Lock may + * contain assertions. We have to avoid assertions in _PR_LOCK_LOG + * because PR_ASSERT calls PR_LogPrint, which in turn calls _PR_LOCK_LOG. + * This can lead to infinite recursion. + */ +static PRLock *_pr_logLock; +#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) +#define _PR_LOCK_LOG() PR_Lock(_pr_logLock); +#define _PR_UNLOCK_LOG() PR_Unlock(_pr_logLock); +#elif defined(_PR_GLOBAL_THREADS_ONLY) +#define _PR_LOCK_LOG() { _PR_LOCK_LOCK(_pr_logLock) +#define _PR_UNLOCK_LOG() _PR_LOCK_UNLOCK(_pr_logLock); } +#else + +#define _PR_LOCK_LOG() \ +{ \ + PRIntn _is; \ + PRThread *_me = _PR_MD_CURRENT_THREAD(); \ + if (!_PR_IS_NATIVE_THREAD(_me)) \ + _PR_INTSOFF(_is); \ + _PR_LOCK_LOCK(_pr_logLock) + +#define _PR_UNLOCK_LOG() \ + _PR_LOCK_UNLOCK(_pr_logLock); \ + PR_ASSERT(_me == _PR_MD_CURRENT_THREAD()); \ + if (!_PR_IS_NATIVE_THREAD(_me)) \ + _PR_INTSON(_is); \ +} + +#endif + +#if defined(XP_PC) +#define strcasecmp stricmp +#endif + +/* + * On NT, we can't define _PUT_LOG as PR_Write or _PR_MD_WRITE, + * because every asynchronous file io operation leads to a fiber context + * switch. So we define _PUT_LOG as fputs (from stdio.h). A side + * benefit is that fputs handles the LF->CRLF translation. This + * code can also be used on other platforms with file stream io. + */ +#if defined(WIN32) || defined(XP_OS2) +#define _PR_USE_STDIO_FOR_LOGGING +#endif + +/* +** Coerce Win32 log output to use OutputDebugString() when +** NSPR_LOG_FILE is set to "WinDebug". +*/ +#if defined(XP_PC) +#define WIN32_DEBUG_FILE (FILE*)-2 +#endif + +#ifdef WINCE +static void OutputDebugStringA(const char* msg) { + int len = MultiByteToWideChar(CP_ACP, 0, msg, -1, 0, 0); + WCHAR *wMsg = (WCHAR *)PR_Malloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, msg, -1, wMsg, len); + OutputDebugStringW(wMsg); + PR_Free(wMsg); +} +#endif + +/* Macros used to reduce #ifdef pollution */ + +#if defined(_PR_USE_STDIO_FOR_LOGGING) && defined(XP_PC) +#define _PUT_LOG(fd, buf, nb) \ + PR_BEGIN_MACRO \ + if (logFile == WIN32_DEBUG_FILE) { \ + char savebyte = buf[nb]; \ + buf[nb] = '\0'; \ + OutputDebugStringA(buf); \ + buf[nb] = savebyte; \ + } else { \ + fwrite(buf, 1, nb, fd); \ + fflush(fd); \ + } \ + PR_END_MACRO +#elif defined(_PR_USE_STDIO_FOR_LOGGING) +#define _PUT_LOG(fd, buf, nb) {fwrite(buf, 1, nb, fd); fflush(fd);} +#elif defined(ANDROID) +#define _PUT_LOG(fd, buf, nb) \ + PR_BEGIN_MACRO \ + if (fd == _pr_stderr) { \ + char savebyte = buf[nb]; \ + buf[nb] = '\0'; \ + __android_log_write(ANDROID_LOG_INFO, "PRLog", buf); \ + buf[nb] = savebyte; \ + } else { \ + PR_Write(fd, buf, nb); \ + } \ + PR_END_MACRO +#elif defined(_PR_PTHREADS) +#define _PUT_LOG(fd, buf, nb) PR_Write(fd, buf, nb) +#else +#define _PUT_LOG(fd, buf, nb) _PR_MD_WRITE(fd, buf, nb) +#endif + +/************************************************************************/ + +static PRLogModuleInfo *logModules; + +static char *logBuf = NULL; +static char *logp; +static char *logEndp; +#ifdef _PR_USE_STDIO_FOR_LOGGING +static FILE *logFile = NULL; +#else +static PRFileDesc *logFile = 0; +#endif +static PRBool outputTimeStamp = PR_FALSE; +static PRBool appendToLog = PR_FALSE; + +#define LINE_BUF_SIZE 512 +#define DEFAULT_BUF_SIZE 16384 + +#ifdef _PR_NEED_STRCASECMP + +/* + * strcasecmp is defined in /usr/ucblib/libucb.a on some platforms + * such as NCR and Unixware. Linking with both libc and libucb + * may cause some problem, so I just provide our own implementation + * of strcasecmp here. + */ + +static const unsigned char uc[] = +{ + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + ' ', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '{', '|', '}', '~', '\177' +}; + +PRIntn strcasecmp(const char *a, const char *b) +{ + const unsigned char *ua = (const unsigned char *)a; + const unsigned char *ub = (const unsigned char *)b; + + if( ((const char *)0 == a) || (const char *)0 == b ) + return (PRIntn)(a-b); + + while( (uc[*ua] == uc[*ub]) && ('\0' != *a) ) + { + a++; + ua++; + ub++; + } + + return (PRIntn)(uc[*ua] - uc[*ub]); +} + +#endif /* _PR_NEED_STRCASECMP */ + +void _PR_InitLog(void) +{ + char *ev; + + _pr_logLock = PR_NewLock(); + + ev = PR_GetEnv("NSPR_LOG_MODULES"); + if (ev && ev[0]) { + char module[64]; /* Security-Critical: If you change this + * size, you must also change the sscanf + * format string to be size-1. + */ + PRBool isSync = PR_FALSE; + PRIntn evlen = strlen(ev), pos = 0; + PRInt32 bufSize = DEFAULT_BUF_SIZE; + while (pos < evlen) { + PRIntn level = 1, count = 0, delta = 0; + count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n", + module, &delta, &level, &delta); + pos += delta; + if (count == 0) break; + + /* + ** If count == 2, then we got module and level. If count + ** == 1, then level defaults to 1 (module enabled). + */ + if (strcasecmp(module, "sync") == 0) { + isSync = PR_TRUE; + } else if (strcasecmp(module, "bufsize") == 0) { + if (level >= LINE_BUF_SIZE) { + bufSize = level; + } + } else if (strcasecmp(module, "timestamp") == 0) { + outputTimeStamp = PR_TRUE; + } else if (strcasecmp(module, "append") == 0) { + appendToLog = PR_TRUE; + } else { + PRLogModuleInfo *lm = logModules; + PRBool skip_modcheck = + (0 == strcasecmp (module, "all")) ? PR_TRUE : PR_FALSE; + + while (lm != NULL) { + if (skip_modcheck) lm -> level = (PRLogModuleLevel)level; + else if (strcasecmp(module, lm->name) == 0) { + lm->level = (PRLogModuleLevel)level; + break; + } + lm = lm->next; + } + } + /*found:*/ + count = sscanf(&ev[pos], " , %n", &delta); + pos += delta; + if (count == EOF) break; + } + PR_SetLogBuffering(isSync ? 0 : bufSize); + +#ifdef XP_UNIX + if ((getuid() != geteuid()) || (getgid() != getegid())) { + return; + } +#endif /* XP_UNIX */ + + ev = PR_GetEnv("NSPR_LOG_FILE"); + if (ev && ev[0]) { + if (!PR_SetLogFile(ev)) { +#ifdef XP_PC + char* str = PR_smprintf("Unable to create nspr log file '%s'\n", ev); + if (str) { + OutputDebugStringA(str); + PR_smprintf_free(str); + } +#else + fprintf(stderr, "Unable to create nspr log file '%s'\n", ev); +#endif + } + } else { +#ifdef _PR_USE_STDIO_FOR_LOGGING + logFile = stderr; +#else + logFile = _pr_stderr; +#endif + } + } +} + +void _PR_LogCleanup(void) +{ + PRLogModuleInfo *lm = logModules; + + PR_LogFlush(); + +#ifdef _PR_USE_STDIO_FOR_LOGGING + if (logFile + && logFile != stdout + && logFile != stderr +#ifdef XP_PC + && logFile != WIN32_DEBUG_FILE +#endif + ) { + fclose(logFile); + } +#else + if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) { + PR_Close(logFile); + } +#endif + logFile = NULL; + + if (logBuf) + PR_DELETE(logBuf); + + while (lm != NULL) { + PRLogModuleInfo *next = lm->next; + free((/*const*/ char *)lm->name); + PR_Free(lm); + lm = next; + } + logModules = NULL; + + if (_pr_logLock) { + PR_DestroyLock(_pr_logLock); + _pr_logLock = NULL; + } +} + +static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm ) +{ + char *ev; + + ev = PR_GetEnv("NSPR_LOG_MODULES"); + if (ev && ev[0]) { + char module[64]; /* Security-Critical: If you change this + * size, you must also change the sscanf + * format string to be size-1. + */ + PRIntn evlen = strlen(ev), pos = 0; + while (pos < evlen) { + PRIntn level = 1, count = 0, delta = 0; + + count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n", + module, &delta, &level, &delta); + pos += delta; + if (count == 0) break; + + /* + ** If count == 2, then we got module and level. If count + ** == 1, then level defaults to 1 (module enabled). + */ + if (lm != NULL) + { + if ((strcasecmp(module, "all") == 0) + || (strcasecmp(module, lm->name) == 0)) + { + lm->level = (PRLogModuleLevel)level; + } + } + count = sscanf(&ev[pos], " , %n", &delta); + pos += delta; + if (count == EOF) break; + } + } +} /* end _PR_SetLogModuleLevel() */ + +PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name) +{ + PRLogModuleInfo *lm; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + lm = PR_NEWZAP(PRLogModuleInfo); + if (lm) { + lm->name = strdup(name); + lm->level = PR_LOG_NONE; + lm->next = logModules; + logModules = lm; + _PR_SetLogModuleLevel(lm); + } + return lm; +} + +PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file) +{ +#ifdef _PR_USE_STDIO_FOR_LOGGING + FILE *newLogFile; + +#ifdef XP_PC + if ( strcmp( file, "WinDebug") == 0) + { + newLogFile = WIN32_DEBUG_FILE; + } + else +#endif + { + const char *mode = appendToLog ? "a" : "w"; + newLogFile = fopen(file, mode); + if (!newLogFile) + return PR_FALSE; + +#ifndef WINCE /* _IONBF does not exist in the Windows Mobile 6 SDK. */ + /* We do buffering ourselves. */ + setvbuf(newLogFile, NULL, _IONBF, 0); +#endif + } + if (logFile + && logFile != stdout + && logFile != stderr +#ifdef XP_PC + && logFile != WIN32_DEBUG_FILE +#endif + ) { + fclose(logFile); + } + logFile = newLogFile; + return PR_TRUE; +#else + PRFileDesc *newLogFile; + PRIntn flags = PR_WRONLY|PR_CREATE_FILE; + if (appendToLog) { + flags |= PR_APPEND; + } else { + flags |= PR_TRUNCATE; + } + + newLogFile = PR_Open(file, flags, 0666); + if (newLogFile) { + if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) { + PR_Close(logFile); + } + logFile = newLogFile; + } + return (PRBool) (newLogFile != 0); +#endif /* _PR_USE_STDIO_FOR_LOGGING */ +} + +PR_IMPLEMENT(void) PR_SetLogBuffering(PRIntn buffer_size) +{ + PR_LogFlush(); + + if (logBuf) + PR_DELETE(logBuf); + + if (buffer_size >= LINE_BUF_SIZE) { + logp = logBuf = (char*) PR_MALLOC(buffer_size); + logEndp = logp + buffer_size; + } +} + +PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...) +{ + va_list ap; + char line[LINE_BUF_SIZE]; + char *line_long = NULL; + PRUint32 nb_tid = 0, nb; + PRThread *me; + PRExplodedTime now; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (!logFile) { + return; + } + + if (outputTimeStamp) { + PR_ExplodeTime(PR_Now(), PR_GMTParameters, &now); + nb_tid = PR_snprintf(line, sizeof(line)-1, + "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC - ", + now.tm_year, now.tm_month + 1, now.tm_mday, + now.tm_hour, now.tm_min, now.tm_sec, + now.tm_usec); + } + + me = PR_GetCurrentThread(); + nb_tid += PR_snprintf(line+nb_tid, sizeof(line)-nb_tid-1, "%ld[%p]: ", +#if defined(_PR_BTHREADS) + me, me); +#else + me ? me->id : 0L, me); +#endif + + va_start(ap, fmt); + nb = nb_tid + PR_vsnprintf(line+nb_tid, sizeof(line)-nb_tid-1, fmt, ap); + va_end(ap); + + /* + * Check if we might have run out of buffer space (in case we have a + * long line), and malloc a buffer just this once. + */ + if (nb == sizeof(line)-2) { + va_start(ap, fmt); + line_long = PR_vsmprintf(fmt, ap); + va_end(ap); + /* If this failed, we'll fall back to writing the truncated line. */ + } + + if (line_long) { + nb = strlen(line_long); + _PR_LOCK_LOG(); + if (logBuf != 0) { + _PUT_LOG(logFile, logBuf, logp - logBuf); + logp = logBuf; + } + /* + * Write out the thread id (with an optional timestamp) and the + * malloc'ed buffer. + */ + _PUT_LOG(logFile, line, nb_tid); + _PUT_LOG(logFile, line_long, nb); + /* Ensure there is a trailing newline. */ + if (!nb || (line_long[nb-1] != '\n')) { + char eol[2]; + eol[0] = '\n'; + eol[1] = '\0'; + _PUT_LOG(logFile, eol, 1); + } + _PR_UNLOCK_LOG(); + PR_smprintf_free(line_long); + } else { + /* Ensure there is a trailing newline. */ + if (nb && (line[nb-1] != '\n')) { + line[nb++] = '\n'; + line[nb] = '\0'; + } + _PR_LOCK_LOG(); + if (logBuf == 0) { + _PUT_LOG(logFile, line, nb); + } else { + /* If nb can't fit into logBuf, write out logBuf first. */ + if (logp + nb > logEndp) { + _PUT_LOG(logFile, logBuf, logp - logBuf); + logp = logBuf; + } + /* nb is guaranteed to fit into logBuf. */ + memcpy(logp, line, nb); + logp += nb; + } + _PR_UNLOCK_LOG(); + } + PR_LogFlush(); +} + +PR_IMPLEMENT(void) PR_LogFlush(void) +{ + if (logBuf && logFile) { + _PR_LOCK_LOG(); + if (logp > logBuf) { + _PUT_LOG(logFile, logBuf, logp - logBuf); + logp = logBuf; + } + _PR_UNLOCK_LOG(); + } +} + +PR_IMPLEMENT(void) PR_Abort(void) +{ + PR_LogPrint("Aborting"); + abort(); +} + +PR_IMPLEMENT(void) PR_Assert(const char *s, const char *file, PRIntn ln) +{ + PR_LogPrint("Assertion failure: %s, at %s:%d\n", s, file, ln); + fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); + fflush(stderr); +#ifdef WIN32 + DebugBreak(); +#endif +#ifdef XP_OS2 + asm("int $3"); +#endif + abort(); +} diff -Nru nspr-4.9.5/nspr/pr/src/io/prmapopt.c nspr-4.10.7/nspr/pr/src/io/prmapopt.c --- nspr-4.9.5/nspr/pr/src/io/prmapopt.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prmapopt.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,458 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This file defines _PR_MapOptionName(). The purpose of putting + * _PR_MapOptionName() in a separate file is to work around a Winsock + * header file problem on Windows NT. + * + * On Windows NT, if we define _WIN32_WINNT to be 0x0400 (in order + * to use Service Pack 3 extensions), windows.h includes winsock2.h + * (instead of winsock.h), which doesn't define many socket options + * defined in winsock.h. + * + * We need the socket options defined in winsock.h. So this file + * includes winsock.h, with _WIN32_WINNT undefined. + */ + +#if defined(WINNT) || defined(__MINGW32__) +#include +#endif + +/* MinGW doesn't define these in its winsock.h. */ +#ifdef __MINGW32__ +#ifndef IP_TTL +#define IP_TTL 7 +#endif +#ifndef IP_TOS +#define IP_TOS 8 +#endif +#endif + +#include "primpl.h" + +#ifdef HAVE_NETINET_TCP_H +#include /* TCP_NODELAY, TCP_MAXSEG */ +#endif + +#ifndef _PR_PTHREADS + +PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data) +{ + PRStatus rv; + PRInt32 length; + PRInt32 level, name; + + /* + * PR_SockOpt_Nonblocking is a special case that does not + * translate to a getsockopt() call + */ + if (PR_SockOpt_Nonblocking == data->option) + { + data->value.non_blocking = fd->secret->nonblocking; + return PR_SUCCESS; + } + + rv = _PR_MapOptionName(data->option, &level, &name); + if (PR_SUCCESS == rv) + { + switch (data->option) + { + case PR_SockOpt_Linger: + { +#if !defined(XP_BEOS) || defined(BONE_VERSION) + struct linger linger; + length = sizeof(linger); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, (char *) &linger, &length); + if (PR_SUCCESS == rv) + { + PR_ASSERT(sizeof(linger) == length); + data->value.linger.polarity = + (linger.l_onoff) ? PR_TRUE : PR_FALSE; + data->value.linger.linger = + PR_SecondsToInterval(linger.l_linger); + } + break; +#else + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return PR_FAILURE; +#endif + } + case PR_SockOpt_Reuseaddr: + case PR_SockOpt_Keepalive: + case PR_SockOpt_NoDelay: + case PR_SockOpt_Broadcast: + case PR_SockOpt_Reuseport: + { +#ifdef WIN32 /* Winsock */ + BOOL value; +#else + PRIntn value; +#endif + length = sizeof(value); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, (char*)&value, &length); + if (PR_SUCCESS == rv) + data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE; + break; + } + case PR_SockOpt_McastLoopback: + { +#ifdef WIN32 /* Winsock */ + BOOL bool; +#else + PRUint8 bool; +#endif + length = sizeof(bool); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, (char*)&bool, &length); + if (PR_SUCCESS == rv) + data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE; + break; + } + case PR_SockOpt_RecvBufferSize: + case PR_SockOpt_SendBufferSize: + case PR_SockOpt_MaxSegment: + { + PRIntn value; + length = sizeof(value); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, (char*)&value, &length); + if (PR_SUCCESS == rv) + data->value.recv_buffer_size = value; + break; + } + case PR_SockOpt_IpTimeToLive: + case PR_SockOpt_IpTypeOfService: + { + /* These options should really be an int (or PRIntn). */ + length = sizeof(PRUintn); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, (char*)&data->value.ip_ttl, &length); + break; + } + case PR_SockOpt_McastTimeToLive: + { +#ifdef WIN32 /* Winsock */ + int ttl; +#else + PRUint8 ttl; +#endif + length = sizeof(ttl); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, (char*)&ttl, &length); + if (PR_SUCCESS == rv) + data->value.mcast_ttl = ttl; + break; + } +#ifdef IP_ADD_MEMBERSHIP + case PR_SockOpt_AddMember: + case PR_SockOpt_DropMember: + { + struct ip_mreq mreq; + length = sizeof(mreq); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, (char*)&mreq, &length); + if (PR_SUCCESS == rv) + { + data->value.add_member.mcaddr.inet.ip = + mreq.imr_multiaddr.s_addr; + data->value.add_member.ifaddr.inet.ip = + mreq.imr_interface.s_addr; + } + break; + } +#endif /* IP_ADD_MEMBERSHIP */ + case PR_SockOpt_McastInterface: + { + /* This option is a struct in_addr. */ + length = sizeof(data->value.mcast_if.inet.ip); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, + (char*)&data->value.mcast_if.inet.ip, &length); + break; + } + default: + PR_NOT_REACHED("Unknown socket option"); + break; + } + } + return rv; +} /* _PR_SocketGetSocketOption */ + +PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data) +{ + PRStatus rv; + PRInt32 level, name; + + /* + * PR_SockOpt_Nonblocking is a special case that does not + * translate to a setsockopt call. + */ + if (PR_SockOpt_Nonblocking == data->option) + { +#ifdef WINNT + PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE) + || (fd->secret->nonblocking == data->value.non_blocking)); + if (fd->secret->md.io_model_committed + && (fd->secret->nonblocking != data->value.non_blocking)) + { + /* + * On NT, once we have associated a socket with the io + * completion port, we can't disassociate it. So we + * can't change the nonblocking option of the socket + * afterwards. + */ + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } +#endif + fd->secret->nonblocking = data->value.non_blocking; + return PR_SUCCESS; + } + + rv = _PR_MapOptionName(data->option, &level, &name); + if (PR_SUCCESS == rv) + { + switch (data->option) + { + case PR_SockOpt_Linger: + { +#if !defined(XP_BEOS) || defined(BONE_VERSION) + struct linger linger; + linger.l_onoff = data->value.linger.polarity; + linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger); + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&linger, sizeof(linger)); + break; +#else + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return PR_FAILURE; +#endif + } + case PR_SockOpt_Reuseaddr: + case PR_SockOpt_Keepalive: + case PR_SockOpt_NoDelay: + case PR_SockOpt_Broadcast: + case PR_SockOpt_Reuseport: + { +#ifdef WIN32 /* Winsock */ + BOOL value; +#else + PRIntn value; +#endif + value = (data->value.reuse_addr) ? 1 : 0; + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&value, sizeof(value)); + break; + } + case PR_SockOpt_McastLoopback: + { +#ifdef WIN32 /* Winsock */ + BOOL bool; +#else + PRUint8 bool; +#endif + bool = data->value.mcast_loopback ? 1 : 0; + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&bool, sizeof(bool)); + break; + } + case PR_SockOpt_RecvBufferSize: + case PR_SockOpt_SendBufferSize: + case PR_SockOpt_MaxSegment: + { + PRIntn value = data->value.recv_buffer_size; + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&value, sizeof(value)); + break; + } + case PR_SockOpt_IpTimeToLive: + case PR_SockOpt_IpTypeOfService: + { + /* These options should really be an int (or PRIntn). */ + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&data->value.ip_ttl, sizeof(PRUintn)); + break; + } + case PR_SockOpt_McastTimeToLive: + { +#ifdef WIN32 /* Winsock */ + int ttl; +#else + PRUint8 ttl; +#endif + ttl = data->value.mcast_ttl; + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&ttl, sizeof(ttl)); + break; + } +#ifdef IP_ADD_MEMBERSHIP + case PR_SockOpt_AddMember: + case PR_SockOpt_DropMember: + { + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = + data->value.add_member.mcaddr.inet.ip; + mreq.imr_interface.s_addr = + data->value.add_member.ifaddr.inet.ip; + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&mreq, sizeof(mreq)); + break; + } +#endif /* IP_ADD_MEMBERSHIP */ + case PR_SockOpt_McastInterface: + { + /* This option is a struct in_addr. */ + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&data->value.mcast_if.inet.ip, + sizeof(data->value.mcast_if.inet.ip)); + break; + } + default: + PR_NOT_REACHED("Unknown socket option"); + break; + } + } + return rv; +} /* _PR_SocketSetSocketOption */ + +#endif /* ! _PR_PTHREADS */ + +/* + ********************************************************************* + ********************************************************************* + ** + ** Make sure that the following is at the end of this file, + ** because we will be playing with macro redefines. + ** + ********************************************************************* + ********************************************************************* + */ + +/* + * Not every platform has all the socket options we want to + * support. Some older operating systems such as SunOS 4.1.3 + * don't have the IP multicast socket options. Win32 doesn't + * have TCP_MAXSEG. + * + * To deal with this problem, we define the missing socket + * options as _PR_NO_SUCH_SOCKOPT. _PR_MapOptionName() fails with + * PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not + * available on the platform is requested. + */ + +/* + * Sanity check. SO_LINGER and TCP_NODELAY should be available + * on all platforms. Just to make sure we have included the + * appropriate header files. Then any undefined socket options + * are really missing. + */ + +#if !defined(SO_LINGER) +#error "SO_LINGER is not defined" +#endif + +#if !defined(TCP_NODELAY) +#error "TCP_NODELAY is not defined" +#endif + +/* + * Make sure the value of _PR_NO_SUCH_SOCKOPT is not + * a valid socket option. + */ +#define _PR_NO_SUCH_SOCKOPT -1 + +#ifndef SO_KEEPALIVE +#define SO_KEEPALIVE _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef SO_SNDBUF +#define SO_SNDBUF _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef SO_RCVBUF +#define SO_RCVBUF _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef IP_MULTICAST_IF /* set/get IP multicast interface */ +#define IP_MULTICAST_IF _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef IP_MULTICAST_TTL /* set/get IP multicast timetolive */ +#define IP_MULTICAST_TTL _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef IP_MULTICAST_LOOP /* set/get IP multicast loopback */ +#define IP_MULTICAST_LOOP _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef IP_ADD_MEMBERSHIP /* add an IP group membership */ +#define IP_ADD_MEMBERSHIP _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef IP_DROP_MEMBERSHIP /* drop an IP group membership */ +#define IP_DROP_MEMBERSHIP _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef IP_TTL /* set/get IP Time To Live */ +#define IP_TTL _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef IP_TOS /* set/get IP Type Of Service */ +#define IP_TOS _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef TCP_NODELAY /* don't delay to coalesce data */ +#define TCP_NODELAY _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef TCP_MAXSEG /* maxumum segment size for tcp */ +#define TCP_MAXSEG _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef SO_BROADCAST /* enable broadcast on UDP sockets */ +#define SO_BROADCAST _PR_NO_SUCH_SOCKOPT +#endif + +#ifndef SO_REUSEPORT /* allow local address & port reuse */ +#define SO_REUSEPORT _PR_NO_SUCH_SOCKOPT +#endif + +PRStatus _PR_MapOptionName( + PRSockOption optname, PRInt32 *level, PRInt32 *name) +{ + static PRInt32 socketOptions[PR_SockOpt_Last] = + { + 0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF, + IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, + IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP, + TCP_NODELAY, TCP_MAXSEG, SO_BROADCAST, SO_REUSEPORT + }; + static PRInt32 socketLevels[PR_SockOpt_Last] = + { + 0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, + IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, + IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, + IPPROTO_TCP, IPPROTO_TCP, SOL_SOCKET, SOL_SOCKET + }; + + if ((optname < PR_SockOpt_Linger) + || (optname >= PR_SockOpt_Last)) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT) + { + PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0); + return PR_FAILURE; + } + *name = socketOptions[optname]; + *level = socketLevels[optname]; + return PR_SUCCESS; +} /* _PR_MapOptionName */ diff -Nru nspr-4.9.5/nspr/pr/src/io/prmmap.c nspr-4.10.7/nspr/pr/src/io/prmmap.c --- nspr-4.9.5/nspr/pr/src/io/prmmap.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prmmap.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + ********************************************************************* + * + * Memory-mapped files + * + ********************************************************************* + */ + +#include "primpl.h" + +PR_IMPLEMENT(PRFileMap *) PR_CreateFileMap( + PRFileDesc *fd, + PRInt64 size, + PRFileMapProtect prot) +{ + PRFileMap *fmap; + + PR_ASSERT(prot == PR_PROT_READONLY || prot == PR_PROT_READWRITE + || prot == PR_PROT_WRITECOPY); + fmap = PR_NEWZAP(PRFileMap); + if (NULL == fmap) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + fmap->fd = fd; + fmap->prot = prot; + if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) { + return fmap; + } else { + PR_DELETE(fmap); + return NULL; + } +} + +PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void) +{ + return _PR_MD_GET_MEM_MAP_ALIGNMENT(); +} + +PR_IMPLEMENT(void *) PR_MemMap( + PRFileMap *fmap, + PROffset64 offset, + PRUint32 len) +{ + return _PR_MD_MEM_MAP(fmap, offset, len); +} + +PR_IMPLEMENT(PRStatus) PR_MemUnmap(void *addr, PRUint32 len) +{ + return _PR_MD_MEM_UNMAP(addr, len); +} + +PR_IMPLEMENT(PRStatus) PR_CloseFileMap(PRFileMap *fmap) +{ + return _PR_MD_CLOSE_FILE_MAP(fmap); +} + +PR_IMPLEMENT(PRStatus) PR_SyncMemMap( + PRFileDesc *fd, + void *addr, + PRUint32 len) +{ + return _PR_MD_SYNC_MEM_MAP(fd, addr, len); +} diff -Nru nspr-4.9.5/nspr/pr/src/io/prmwait.c nspr-4.10.7/nspr/pr/src/io/prmwait.c --- nspr-4.9.5/nspr/pr/src/io/prmwait.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prmwait.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1456 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include "pprmwait.h" + +#define _MW_REHASH_MAX 11 + +static PRLock *mw_lock = NULL; +static _PRGlobalState *mw_state = NULL; + +static PRIntervalTime max_polling_interval; + +#ifdef WINNT + +typedef struct TimerEvent { + PRIntervalTime absolute; + void (*func)(void *); + void *arg; + LONG ref_count; + PRCList links; +} TimerEvent; + +#define TIMER_EVENT_PTR(_qp) \ + ((TimerEvent *) ((char *) (_qp) - offsetof(TimerEvent, links))) + +struct { + PRLock *ml; + PRCondVar *new_timer; + PRCondVar *cancel_timer; + PRThread *manager_thread; + PRCList timer_queue; +} tm_vars; + +static PRStatus TimerInit(void); +static void TimerManager(void *arg); +static TimerEvent *CreateTimer(PRIntervalTime timeout, + void (*func)(void *), void *arg); +static PRBool CancelTimer(TimerEvent *timer); + +static void TimerManager(void *arg) +{ + PRIntervalTime now; + PRIntervalTime timeout; + PRCList *head; + TimerEvent *timer; + + PR_Lock(tm_vars.ml); + while (1) + { + if (PR_CLIST_IS_EMPTY(&tm_vars.timer_queue)) + { + PR_WaitCondVar(tm_vars.new_timer, PR_INTERVAL_NO_TIMEOUT); + } + else + { + now = PR_IntervalNow(); + head = PR_LIST_HEAD(&tm_vars.timer_queue); + timer = TIMER_EVENT_PTR(head); + if ((PRInt32) (now - timer->absolute) >= 0) + { + PR_REMOVE_LINK(head); + /* + * make its prev and next point to itself so that + * it's obvious that it's not on the timer_queue. + */ + PR_INIT_CLIST(head); + PR_ASSERT(2 == timer->ref_count); + PR_Unlock(tm_vars.ml); + timer->func(timer->arg); + PR_Lock(tm_vars.ml); + timer->ref_count -= 1; + if (0 == timer->ref_count) + { + PR_NotifyAllCondVar(tm_vars.cancel_timer); + } + } + else + { + timeout = (PRIntervalTime)(timer->absolute - now); + PR_WaitCondVar(tm_vars.new_timer, timeout); + } + } + } + PR_Unlock(tm_vars.ml); +} + +static TimerEvent *CreateTimer( + PRIntervalTime timeout, + void (*func)(void *), + void *arg) +{ + TimerEvent *timer; + PRCList *links, *tail; + TimerEvent *elem; + + timer = PR_NEW(TimerEvent); + if (NULL == timer) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return timer; + } + timer->absolute = PR_IntervalNow() + timeout; + timer->func = func; + timer->arg = arg; + timer->ref_count = 2; + PR_Lock(tm_vars.ml); + tail = links = PR_LIST_TAIL(&tm_vars.timer_queue); + while (links->prev != tail) + { + elem = TIMER_EVENT_PTR(links); + if ((PRInt32)(timer->absolute - elem->absolute) >= 0) + { + break; + } + links = links->prev; + } + PR_INSERT_AFTER(&timer->links, links); + PR_NotifyCondVar(tm_vars.new_timer); + PR_Unlock(tm_vars.ml); + return timer; +} + +static PRBool CancelTimer(TimerEvent *timer) +{ + PRBool canceled = PR_FALSE; + + PR_Lock(tm_vars.ml); + timer->ref_count -= 1; + if (timer->links.prev == &timer->links) + { + while (timer->ref_count == 1) + { + PR_WaitCondVar(tm_vars.cancel_timer, PR_INTERVAL_NO_TIMEOUT); + } + } + else + { + PR_REMOVE_LINK(&timer->links); + canceled = PR_TRUE; + } + PR_Unlock(tm_vars.ml); + PR_DELETE(timer); + return canceled; +} + +static PRStatus TimerInit(void) +{ + tm_vars.ml = PR_NewLock(); + if (NULL == tm_vars.ml) + { + goto failed; + } + tm_vars.new_timer = PR_NewCondVar(tm_vars.ml); + if (NULL == tm_vars.new_timer) + { + goto failed; + } + tm_vars.cancel_timer = PR_NewCondVar(tm_vars.ml); + if (NULL == tm_vars.cancel_timer) + { + goto failed; + } + PR_INIT_CLIST(&tm_vars.timer_queue); + tm_vars.manager_thread = PR_CreateThread( + PR_SYSTEM_THREAD, TimerManager, NULL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); + if (NULL == tm_vars.manager_thread) + { + goto failed; + } + return PR_SUCCESS; + +failed: + if (NULL != tm_vars.cancel_timer) + { + PR_DestroyCondVar(tm_vars.cancel_timer); + } + if (NULL != tm_vars.new_timer) + { + PR_DestroyCondVar(tm_vars.new_timer); + } + if (NULL != tm_vars.ml) + { + PR_DestroyLock(tm_vars.ml); + } + return PR_FAILURE; +} + +#endif /* WINNT */ + +/******************************************************************/ +/******************************************************************/ +/************************ The private portion *********************/ +/******************************************************************/ +/******************************************************************/ +void _PR_InitMW(void) +{ +#ifdef WINNT + /* + * We use NT 4's InterlockedCompareExchange() to operate + * on PRMWStatus variables. + */ + PR_ASSERT(sizeof(LONG) == sizeof(PRMWStatus)); + TimerInit(); +#endif + mw_lock = PR_NewLock(); + PR_ASSERT(NULL != mw_lock); + mw_state = PR_NEWZAP(_PRGlobalState); + PR_ASSERT(NULL != mw_state); + PR_INIT_CLIST(&mw_state->group_list); + max_polling_interval = PR_MillisecondsToInterval(MAX_POLLING_INTERVAL); +} /* _PR_InitMW */ + +void _PR_CleanupMW(void) +{ + PR_DestroyLock(mw_lock); + mw_lock = NULL; + if (mw_state->group) { + PR_DestroyWaitGroup(mw_state->group); + /* mw_state->group is set to NULL as a side effect. */ + } + PR_DELETE(mw_state); +} /* _PR_CleanupMW */ + +static PRWaitGroup *MW_Init2(void) +{ + PRWaitGroup *group = mw_state->group; /* it's the null group */ + if (NULL == group) /* there is this special case */ + { + group = PR_CreateWaitGroup(_PR_DEFAULT_HASH_LENGTH); + if (NULL == group) goto failed_alloc; + PR_Lock(mw_lock); + if (NULL == mw_state->group) + { + mw_state->group = group; + group = NULL; + } + PR_Unlock(mw_lock); + if (group != NULL) (void)PR_DestroyWaitGroup(group); + group = mw_state->group; /* somebody beat us to it */ + } +failed_alloc: + return group; /* whatever */ +} /* MW_Init2 */ + +static _PR_HashStory MW_AddHashInternal(PRRecvWait *desc, _PRWaiterHash *hash) +{ + /* + ** The entries are put in the table using the fd (PRFileDesc*) of + ** the receive descriptor as the key. This allows us to locate + ** the appropriate entry aqain when the poll operation finishes. + ** + ** The pointer to the file descriptor object is first divided by + ** the natural alignment of a pointer in the belief that object + ** will have at least that many zeros in the low order bits. + ** This may not be a good assuption. + ** + ** We try to put the entry in by rehashing _MW_REHASH_MAX times. After + ** that we declare defeat and force the table to be reconstructed. + ** Since some fds might be added more than once, won't that cause + ** collisions even in an empty table? + */ + PRIntn rehash = _MW_REHASH_MAX; + PRRecvWait **waiter; + PRUintn hidx = _MW_HASH(desc->fd, hash->length); + PRUintn hoffset = 0; + + while (rehash-- > 0) + { + waiter = &hash->recv_wait; + if (NULL == waiter[hidx]) + { + waiter[hidx] = desc; + hash->count += 1; +#if 0 + printf("Adding 0x%x->0x%x ", desc, desc->fd); + printf( + "table[%u:%u:*%u]: 0x%x->0x%x\n", + hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd); +#endif + return _prmw_success; + } + if (desc == waiter[hidx]) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); /* desc already in table */ + return _prmw_error; + } +#if 0 + printf("Failing 0x%x->0x%x ", desc, desc->fd); + printf( + "table[*%u:%u:%u]: 0x%x->0x%x\n", + hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd); +#endif + if (0 == hoffset) + { + hoffset = _MW_HASH2(desc->fd, hash->length); + PR_ASSERT(0 != hoffset); + } + hidx = (hidx + hoffset) % (hash->length); + } + return _prmw_rehash; +} /* MW_AddHashInternal */ + +static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group) +{ + PRRecvWait **desc; + PRUint32 pidx, length; + _PRWaiterHash *newHash, *oldHash = group->waiter; + PRBool retry; + _PR_HashStory hrv; + + static const PRInt32 prime_number[] = { + _PR_DEFAULT_HASH_LENGTH, 179, 521, 907, 1427, + 2711, 3917, 5021, 8219, 11549, 18911, 26711, 33749, 44771}; + PRUintn primes = (sizeof(prime_number) / sizeof(PRInt32)); + + /* look up the next size we'd like to use for the hash table */ + for (pidx = 0; pidx < primes; ++pidx) + { + if (prime_number[pidx] == oldHash->length) + { + break; + } + } + /* table size must be one of the prime numbers */ + PR_ASSERT(pidx < primes); + + /* if pidx == primes - 1, we can't expand the table any more */ + while (pidx < primes - 1) + { + /* next size */ + ++pidx; + length = prime_number[pidx]; + + /* allocate the new hash table and fill it in with the old */ + newHash = (_PRWaiterHash*)PR_CALLOC( + sizeof(_PRWaiterHash) + (length * sizeof(PRRecvWait*))); + if (NULL == newHash) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return _prmw_error; + } + + newHash->length = length; + retry = PR_FALSE; + for (desc = &oldHash->recv_wait; + newHash->count < oldHash->count; ++desc) + { + PR_ASSERT(desc < &oldHash->recv_wait + oldHash->length); + if (NULL != *desc) + { + hrv = MW_AddHashInternal(*desc, newHash); + PR_ASSERT(_prmw_error != hrv); + if (_prmw_success != hrv) + { + PR_DELETE(newHash); + retry = PR_TRUE; + break; + } + } + } + if (retry) continue; + + PR_DELETE(group->waiter); + group->waiter = newHash; + group->p_timestamp += 1; + return _prmw_success; + } + + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return _prmw_error; /* we're hosed */ +} /* MW_ExpandHashInternal */ + +#ifndef WINNT +static void _MW_DoneInternal( + PRWaitGroup *group, PRRecvWait **waiter, PRMWStatus outcome) +{ + /* + ** Add this receive wait object to the list of finished I/O + ** operations for this particular group. If there are other + ** threads waiting on the group, notify one. If not, arrange + ** for this thread to return. + */ + +#if 0 + printf("Removing 0x%x->0x%x\n", *waiter, (*waiter)->fd); +#endif + (*waiter)->outcome = outcome; + PR_APPEND_LINK(&((*waiter)->internal), &group->io_ready); + PR_NotifyCondVar(group->io_complete); + PR_ASSERT(0 != group->waiter->count); + group->waiter->count -= 1; + *waiter = NULL; +} /* _MW_DoneInternal */ +#endif /* WINNT */ + +static PRRecvWait **_MW_LookupInternal(PRWaitGroup *group, PRFileDesc *fd) +{ + /* + ** Find the receive wait object corresponding to the file descriptor. + ** Only search the wait group specified. + */ + PRRecvWait **desc; + PRIntn rehash = _MW_REHASH_MAX; + _PRWaiterHash *hash = group->waiter; + PRUintn hidx = _MW_HASH(fd, hash->length); + PRUintn hoffset = 0; + + while (rehash-- > 0) + { + desc = (&hash->recv_wait) + hidx; + if ((*desc != NULL) && ((*desc)->fd == fd)) return desc; + if (0 == hoffset) + { + hoffset = _MW_HASH2(fd, hash->length); + PR_ASSERT(0 != hoffset); + } + hidx = (hidx + hoffset) % (hash->length); + } + return NULL; +} /* _MW_LookupInternal */ + +#ifndef WINNT +static PRStatus _MW_PollInternal(PRWaitGroup *group) +{ + PRRecvWait **waiter; + PRStatus rv = PR_FAILURE; + PRInt32 count, count_ready; + PRIntervalTime polling_interval; + + group->poller = PR_GetCurrentThread(); + + while (PR_TRUE) + { + PRIntervalTime now, since_last_poll; + PRPollDesc *poll_list; + + while (0 == group->waiter->count) + { + PRStatus st; + st = PR_WaitCondVar(group->new_business, PR_INTERVAL_NO_TIMEOUT); + if (_prmw_running != group->state) + { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + goto aborted; + } + if (_MW_ABORTED(st)) goto aborted; + } + + /* + ** There's something to do. See if our existing polling list + ** is large enough for what we have to do? + */ + + while (group->polling_count < group->waiter->count) + { + PRUint32 old_count = group->waiter->count; + PRUint32 new_count = PR_ROUNDUP(old_count, _PR_POLL_COUNT_FUDGE); + PRSize new_size = sizeof(PRPollDesc) * new_count; + PRPollDesc *old_polling_list = group->polling_list; + + PR_Unlock(group->ml); + poll_list = (PRPollDesc*)PR_CALLOC(new_size); + if (NULL == poll_list) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + PR_Lock(group->ml); + goto failed_alloc; + } + if (NULL != old_polling_list) + PR_DELETE(old_polling_list); + PR_Lock(group->ml); + if (_prmw_running != group->state) + { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + goto aborted; + } + group->polling_list = poll_list; + group->polling_count = new_count; + } + + now = PR_IntervalNow(); + polling_interval = max_polling_interval; + since_last_poll = now - group->last_poll; + + waiter = &group->waiter->recv_wait; + poll_list = group->polling_list; + for (count = 0; count < group->waiter->count; ++waiter) + { + PR_ASSERT(waiter < &group->waiter->recv_wait + + group->waiter->length); + if (NULL != *waiter) /* a live one! */ + { + if ((PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout) + && (since_last_poll >= (*waiter)->timeout)) + _MW_DoneInternal(group, waiter, PR_MW_TIMEOUT); + else + { + if (PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout) + { + (*waiter)->timeout -= since_last_poll; + if ((*waiter)->timeout < polling_interval) + polling_interval = (*waiter)->timeout; + } + PR_ASSERT(poll_list < group->polling_list + + group->polling_count); + poll_list->fd = (*waiter)->fd; + poll_list->in_flags = PR_POLL_READ; + poll_list->out_flags = 0; +#if 0 + printf( + "Polling 0x%x[%d]: [fd: 0x%x, tmo: %u]\n", + poll_list, count, poll_list->fd, (*waiter)->timeout); +#endif + poll_list += 1; + count += 1; + } + } + } + + PR_ASSERT(count == group->waiter->count); + + /* + ** If there are no more threads waiting for completion, + ** we need to return. + */ + if ((!PR_CLIST_IS_EMPTY(&group->io_ready)) + && (1 == group->waiting_threads)) break; + + if (0 == count) continue; /* wait for new business */ + + group->last_poll = now; + + PR_Unlock(group->ml); + + count_ready = PR_Poll(group->polling_list, count, polling_interval); + + PR_Lock(group->ml); + + if (_prmw_running != group->state) + { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + goto aborted; + } + if (-1 == count_ready) + { + goto failed_poll; /* that's a shame */ + } + else if (0 < count_ready) + { + for (poll_list = group->polling_list; count > 0; + poll_list++, count--) + { + PR_ASSERT( + poll_list < group->polling_list + group->polling_count); + if (poll_list->out_flags != 0) + { + waiter = _MW_LookupInternal(group, poll_list->fd); + /* + ** If 'waiter' is NULL, that means the wait receive + ** descriptor has been canceled. + */ + if (NULL != waiter) + _MW_DoneInternal(group, waiter, PR_MW_SUCCESS); + } + } + } + /* + ** If there are no more threads waiting for completion, + ** we need to return. + ** This thread was "borrowed" to do the polling, but it really + ** belongs to the client. + */ + if ((!PR_CLIST_IS_EMPTY(&group->io_ready)) + && (1 == group->waiting_threads)) break; + } + + rv = PR_SUCCESS; + +aborted: +failed_poll: +failed_alloc: + group->poller = NULL; /* we were that, not we ain't */ + if ((_prmw_running == group->state) && (group->waiting_threads > 1)) + { + /* Wake up one thread to become the new poller. */ + PR_NotifyCondVar(group->io_complete); + } + return rv; /* we return with the lock held */ +} /* _MW_PollInternal */ +#endif /* !WINNT */ + +static PRMWGroupState MW_TestForShutdownInternal(PRWaitGroup *group) +{ + PRMWGroupState rv = group->state; + /* + ** Looking at the group's fields is safe because + ** once the group's state is no longer running, it + ** cannot revert and there is a safe check on entry + ** to make sure no more threads are made to wait. + */ + if ((_prmw_stopping == rv) + && (0 == group->waiting_threads)) + { + rv = group->state = _prmw_stopped; + PR_NotifyCondVar(group->mw_manage); + } + return rv; +} /* MW_TestForShutdownInternal */ + +#ifndef WINNT +static void _MW_InitialRecv(PRCList *io_ready) +{ + PRRecvWait *desc = (PRRecvWait*)io_ready; + if ((NULL == desc->buffer.start) + || (0 == desc->buffer.length)) + desc->bytesRecv = 0; + else + { + desc->bytesRecv = (desc->fd->methods->recv)( + desc->fd, desc->buffer.start, + desc->buffer.length, 0, desc->timeout); + if (desc->bytesRecv < 0) /* SetError should already be there */ + desc->outcome = PR_MW_FAILURE; + } +} /* _MW_InitialRecv */ +#endif + +#ifdef WINNT +static void NT_TimeProc(void *arg) +{ + _MDOverlapped *overlapped = (_MDOverlapped *)arg; + PRRecvWait *desc = overlapped->data.mw.desc; + PRFileDesc *bottom; + + if (InterlockedCompareExchange((LONG *)&desc->outcome, + (LONG)PR_MW_TIMEOUT, (LONG)PR_MW_PENDING) != (LONG)PR_MW_PENDING) + { + /* This wait recv descriptor has already completed. */ + return; + } + + /* close the osfd to abort the outstanding async io request */ + /* $$$$ + ** Little late to be checking if NSPR's on the bottom of stack, + ** but if we don't check, we can't assert that the private data + ** is what we think it is. + ** $$$$ + */ + bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + if (NULL != bottom) /* now what!?!?! */ + { + bottom->secret->state = _PR_FILEDESC_CLOSED; + if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR) + { + fprintf(stderr, "closesocket failed: %d\n", WSAGetLastError()); + PR_ASSERT(!"What shall I do?"); + } + } + return; +} /* NT_TimeProc */ + +static PRStatus NT_HashRemove(PRWaitGroup *group, PRFileDesc *fd) +{ + PRRecvWait **waiter; + + _PR_MD_LOCK(&group->mdlock); + waiter = _MW_LookupInternal(group, fd); + if (NULL != waiter) + { + group->waiter->count -= 1; + *waiter = NULL; + } + _PR_MD_UNLOCK(&group->mdlock); + return (NULL != waiter) ? PR_SUCCESS : PR_FAILURE; +} + +PRStatus NT_HashRemoveInternal(PRWaitGroup *group, PRFileDesc *fd) +{ + PRRecvWait **waiter; + + waiter = _MW_LookupInternal(group, fd); + if (NULL != waiter) + { + group->waiter->count -= 1; + *waiter = NULL; + } + return (NULL != waiter) ? PR_SUCCESS : PR_FAILURE; +} +#endif /* WINNT */ + +/******************************************************************/ +/******************************************************************/ +/********************** The public API portion ********************/ +/******************************************************************/ +/******************************************************************/ +PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc( + PRWaitGroup *group, PRRecvWait *desc) +{ + _PR_HashStory hrv; + PRStatus rv = PR_FAILURE; +#ifdef WINNT + _MDOverlapped *overlapped; + HANDLE hFile; + BOOL bResult; + DWORD dwError; + PRFileDesc *bottom; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + if ((NULL == group) && (NULL == (group = MW_Init2()))) + { + return rv; + } + + PR_ASSERT(NULL != desc->fd); + + desc->outcome = PR_MW_PENDING; /* nice, well known value */ + desc->bytesRecv = 0; /* likewise, though this value is ambiguious */ + + PR_Lock(group->ml); + + if (_prmw_running != group->state) + { + /* Not allowed to add after cancelling the group */ + desc->outcome = PR_MW_INTERRUPT; + PR_SetError(PR_INVALID_STATE_ERROR, 0); + PR_Unlock(group->ml); + return rv; + } + +#ifdef WINNT + _PR_MD_LOCK(&group->mdlock); +#endif + + /* + ** If the waiter count is zero at this point, there's no telling + ** how long we've been idle. Therefore, initialize the beginning + ** of the timing interval. As long as the list doesn't go empty, + ** it will maintain itself. + */ + if (0 == group->waiter->count) + group->last_poll = PR_IntervalNow(); + + do + { + hrv = MW_AddHashInternal(desc, group->waiter); + if (_prmw_rehash != hrv) break; + hrv = MW_ExpandHashInternal(group); /* gruesome */ + if (_prmw_success != hrv) break; + } while (PR_TRUE); + +#ifdef WINNT + _PR_MD_UNLOCK(&group->mdlock); +#endif + + PR_NotifyCondVar(group->new_business); /* tell the world */ + rv = (_prmw_success == hrv) ? PR_SUCCESS : PR_FAILURE; + PR_Unlock(group->ml); + +#ifdef WINNT + overlapped = PR_NEWZAP(_MDOverlapped); + if (NULL == overlapped) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + NT_HashRemove(group, desc->fd); + return rv; + } + overlapped->ioModel = _MD_MultiWaitIO; + overlapped->data.mw.desc = desc; + overlapped->data.mw.group = group; + if (desc->timeout != PR_INTERVAL_NO_TIMEOUT) + { + overlapped->data.mw.timer = CreateTimer( + desc->timeout, + NT_TimeProc, + overlapped); + if (0 == overlapped->data.mw.timer) + { + NT_HashRemove(group, desc->fd); + PR_DELETE(overlapped); + /* + * XXX It appears that a maximum of 16 timer events can + * be outstanding. GetLastError() returns 0 when I try it. + */ + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, GetLastError()); + return PR_FAILURE; + } + } + + /* Reach to the bottom layer to get the OS fd */ + bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + if (NULL == bottom) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + hFile = (HANDLE)bottom->secret->md.osfd; + if (!bottom->secret->md.io_model_committed) + { + PRInt32 st; + st = _md_Associate(hFile); + PR_ASSERT(0 != st); + bottom->secret->md.io_model_committed = PR_TRUE; + } + bResult = ReadFile(hFile, + desc->buffer.start, + (DWORD)desc->buffer.length, + NULL, + &overlapped->overlapped); + if (FALSE == bResult && (dwError = GetLastError()) != ERROR_IO_PENDING) + { + if (desc->timeout != PR_INTERVAL_NO_TIMEOUT) + { + if (InterlockedCompareExchange((LONG *)&desc->outcome, + (LONG)PR_MW_FAILURE, (LONG)PR_MW_PENDING) + == (LONG)PR_MW_PENDING) + { + CancelTimer(overlapped->data.mw.timer); + } + NT_HashRemove(group, desc->fd); + PR_DELETE(overlapped); + } + _PR_MD_MAP_READ_ERROR(dwError); + rv = PR_FAILURE; + } +#endif + + return rv; +} /* PR_AddWaitFileDesc */ + +PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group) +{ + PRCList *io_ready = NULL; +#ifdef WINNT + PRThread *me = _PR_MD_CURRENT_THREAD(); + _MDOverlapped *overlapped; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + if ((NULL == group) && (NULL == (group = MW_Init2()))) goto failed_init; + + PR_Lock(group->ml); + + if (_prmw_running != group->state) + { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + goto invalid_state; + } + + group->waiting_threads += 1; /* the polling thread is counted */ + +#ifdef WINNT + _PR_MD_LOCK(&group->mdlock); + while (PR_CLIST_IS_EMPTY(&group->io_ready)) + { + _PR_THREAD_LOCK(me); + me->state = _PR_IO_WAIT; + PR_APPEND_LINK(&me->waitQLinks, &group->wait_list); + if (!_PR_IS_NATIVE_THREAD(me)) + { + _PR_SLEEPQ_LOCK(me->cpu); + _PR_ADD_SLEEPQ(me, PR_INTERVAL_NO_TIMEOUT); + _PR_SLEEPQ_UNLOCK(me->cpu); + } + _PR_THREAD_UNLOCK(me); + _PR_MD_UNLOCK(&group->mdlock); + PR_Unlock(group->ml); + _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT); + me->state = _PR_RUNNING; + PR_Lock(group->ml); + _PR_MD_LOCK(&group->mdlock); + if (_PR_PENDING_INTERRUPT(me)) { + PR_REMOVE_LINK(&me->waitQLinks); + _PR_MD_UNLOCK(&group->mdlock); + me->flags &= ~_PR_INTERRUPT; + me->io_suspended = PR_FALSE; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + goto aborted; + } + } + io_ready = PR_LIST_HEAD(&group->io_ready); + PR_ASSERT(io_ready != NULL); + PR_REMOVE_LINK(io_ready); + _PR_MD_UNLOCK(&group->mdlock); + overlapped = (_MDOverlapped *) + ((char *)io_ready - offsetof(_MDOverlapped, data)); + io_ready = &overlapped->data.mw.desc->internal; +#else + do + { + /* + ** If the I/O ready list isn't empty, have this thread + ** return with the first receive wait object that's available. + */ + if (PR_CLIST_IS_EMPTY(&group->io_ready)) + { + /* + ** Is there a polling thread yet? If not, grab this thread + ** and use it. + */ + if (NULL == group->poller) + { + /* + ** This thread will stay do polling until it becomes the only one + ** left to service a completion. Then it will return and there will + ** be none left to actually poll or to run completions. + ** + ** The polling function should only return w/ failure or + ** with some I/O ready. + */ + if (PR_FAILURE == _MW_PollInternal(group)) goto failed_poll; + } + else + { + /* + ** There are four reasons a thread can be awakened from + ** a wait on the io_complete condition variable. + ** 1. Some I/O has completed, i.e., the io_ready list + ** is nonempty. + ** 2. The wait group is canceled. + ** 3. The thread is interrupted. + ** 4. The current polling thread has to leave and needs + ** a replacement. + ** The logic to find a new polling thread is made more + ** complicated by all the other possible events. + ** I tried my best to write the logic clearly, but + ** it is still full of if's with continue and goto. + */ + PRStatus st; + do + { + st = PR_WaitCondVar(group->io_complete, PR_INTERVAL_NO_TIMEOUT); + if (_prmw_running != group->state) + { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + goto aborted; + } + if (_MW_ABORTED(st) || (NULL == group->poller)) break; + } while (PR_CLIST_IS_EMPTY(&group->io_ready)); + + /* + ** The thread is interrupted and has to leave. It might + ** have also been awakened to process ready i/o or be the + ** new poller. To be safe, if either condition is true, + ** we awaken another thread to take its place. + */ + if (_MW_ABORTED(st)) + { + if ((NULL == group->poller + || !PR_CLIST_IS_EMPTY(&group->io_ready)) + && group->waiting_threads > 1) + PR_NotifyCondVar(group->io_complete); + goto aborted; + } + + /* + ** A new poller is needed, but can I be the new poller? + ** If there is no i/o ready, sure. But if there is any + ** i/o ready, it has a higher priority. I want to + ** process the ready i/o first and wake up another + ** thread to be the new poller. + */ + if (NULL == group->poller) + { + if (PR_CLIST_IS_EMPTY(&group->io_ready)) + continue; + if (group->waiting_threads > 1) + PR_NotifyCondVar(group->io_complete); + } + } + PR_ASSERT(!PR_CLIST_IS_EMPTY(&group->io_ready)); + } + io_ready = PR_LIST_HEAD(&group->io_ready); + PR_NotifyCondVar(group->io_taken); + PR_ASSERT(io_ready != NULL); + PR_REMOVE_LINK(io_ready); + } while (NULL == io_ready); + +failed_poll: + +#endif + +aborted: + + group->waiting_threads -= 1; +invalid_state: + (void)MW_TestForShutdownInternal(group); + PR_Unlock(group->ml); + +failed_init: + if (NULL != io_ready) + { + /* If the operation failed, record the reason why */ + switch (((PRRecvWait*)io_ready)->outcome) + { + case PR_MW_PENDING: + PR_ASSERT(0); + break; + case PR_MW_SUCCESS: +#ifndef WINNT + _MW_InitialRecv(io_ready); +#endif + break; +#ifdef WINNT + case PR_MW_FAILURE: + _PR_MD_MAP_READ_ERROR(overlapped->data.mw.error); + break; +#endif + case PR_MW_TIMEOUT: + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + break; + case PR_MW_INTERRUPT: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + break; + default: break; + } +#ifdef WINNT + if (NULL != overlapped->data.mw.timer) + { + PR_ASSERT(PR_INTERVAL_NO_TIMEOUT + != overlapped->data.mw.desc->timeout); + CancelTimer(overlapped->data.mw.timer); + } + else + { + PR_ASSERT(PR_INTERVAL_NO_TIMEOUT + == overlapped->data.mw.desc->timeout); + } + PR_DELETE(overlapped); +#endif + } + return (PRRecvWait*)io_ready; +} /* PR_WaitRecvReady */ + +PR_IMPLEMENT(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc) +{ +#if !defined(WINNT) + PRRecvWait **recv_wait; +#endif + PRStatus rv = PR_SUCCESS; + if (NULL == group) group = mw_state->group; + PR_ASSERT(NULL != group); + if (NULL == group) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + PR_Lock(group->ml); + + if (_prmw_running != group->state) + { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + rv = PR_FAILURE; + goto unlock; + } + +#ifdef WINNT + if (InterlockedCompareExchange((LONG *)&desc->outcome, + (LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING) == (LONG)PR_MW_PENDING) + { + PRFileDesc *bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + if (NULL == bottom) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + goto unlock; + } + bottom->secret->state = _PR_FILEDESC_CLOSED; +#if 0 + fprintf(stderr, "cancel wait recv: closing socket\n"); +#endif + if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR) + { + fprintf(stderr, "closesocket failed: %d\n", WSAGetLastError()); + exit(1); + } + } +#else + if (NULL != (recv_wait = _MW_LookupInternal(group, desc->fd))) + { + /* it was in the wait table */ + _MW_DoneInternal(group, recv_wait, PR_MW_INTERRUPT); + goto unlock; + } + if (!PR_CLIST_IS_EMPTY(&group->io_ready)) + { + /* is it already complete? */ + PRCList *head = PR_LIST_HEAD(&group->io_ready); + do + { + PRRecvWait *done = (PRRecvWait*)head; + if (done == desc) goto unlock; + head = PR_NEXT_LINK(head); + } while (head != &group->io_ready); + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; + +#endif +unlock: + PR_Unlock(group->ml); + return rv; +} /* PR_CancelWaitFileDesc */ + +PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group) +{ + PRRecvWait **desc; + PRRecvWait *recv_wait = NULL; +#ifdef WINNT + _MDOverlapped *overlapped; + PRRecvWait **end; + PRThread *me = _PR_MD_CURRENT_THREAD(); +#endif + + if (NULL == group) group = mw_state->group; + PR_ASSERT(NULL != group); + if (NULL == group) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } + + PR_Lock(group->ml); + if (_prmw_stopped != group->state) + { + if (_prmw_running == group->state) + group->state = _prmw_stopping; /* so nothing new comes in */ + if (0 == group->waiting_threads) /* is there anybody else? */ + group->state = _prmw_stopped; /* we can stop right now */ + else + { + PR_NotifyAllCondVar(group->new_business); + PR_NotifyAllCondVar(group->io_complete); + } + while (_prmw_stopped != group->state) + (void)PR_WaitCondVar(group->mw_manage, PR_INTERVAL_NO_TIMEOUT); + } + +#ifdef WINNT + _PR_MD_LOCK(&group->mdlock); +#endif + /* make all the existing descriptors look done/interrupted */ +#ifdef WINNT + end = &group->waiter->recv_wait + group->waiter->length; + for (desc = &group->waiter->recv_wait; desc < end; ++desc) + { + if (NULL != *desc) + { + if (InterlockedCompareExchange((LONG *)&(*desc)->outcome, + (LONG)PR_MW_INTERRUPT, (LONG)PR_MW_PENDING) + == (LONG)PR_MW_PENDING) + { + PRFileDesc *bottom = PR_GetIdentitiesLayer( + (*desc)->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + if (NULL == bottom) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + goto invalid_arg; + } + bottom->secret->state = _PR_FILEDESC_CLOSED; +#if 0 + fprintf(stderr, "cancel wait group: closing socket\n"); +#endif + if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR) + { + fprintf(stderr, "closesocket failed: %d\n", + WSAGetLastError()); + exit(1); + } + } + } + } + while (group->waiter->count > 0) + { + _PR_THREAD_LOCK(me); + me->state = _PR_IO_WAIT; + PR_APPEND_LINK(&me->waitQLinks, &group->wait_list); + if (!_PR_IS_NATIVE_THREAD(me)) + { + _PR_SLEEPQ_LOCK(me->cpu); + _PR_ADD_SLEEPQ(me, PR_INTERVAL_NO_TIMEOUT); + _PR_SLEEPQ_UNLOCK(me->cpu); + } + _PR_THREAD_UNLOCK(me); + _PR_MD_UNLOCK(&group->mdlock); + PR_Unlock(group->ml); + _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT); + me->state = _PR_RUNNING; + PR_Lock(group->ml); + _PR_MD_LOCK(&group->mdlock); + } +#else + for (desc = &group->waiter->recv_wait; group->waiter->count > 0; ++desc) + { + PR_ASSERT(desc < &group->waiter->recv_wait + group->waiter->length); + if (NULL != *desc) + _MW_DoneInternal(group, desc, PR_MW_INTERRUPT); + } +#endif + + /* take first element of finished list and return it or NULL */ + if (PR_CLIST_IS_EMPTY(&group->io_ready)) + PR_SetError(PR_GROUP_EMPTY_ERROR, 0); + else + { + PRCList *head = PR_LIST_HEAD(&group->io_ready); + PR_REMOVE_AND_INIT_LINK(head); +#ifdef WINNT + overlapped = (_MDOverlapped *) + ((char *)head - offsetof(_MDOverlapped, data)); + head = &overlapped->data.mw.desc->internal; + if (NULL != overlapped->data.mw.timer) + { + PR_ASSERT(PR_INTERVAL_NO_TIMEOUT + != overlapped->data.mw.desc->timeout); + CancelTimer(overlapped->data.mw.timer); + } + else + { + PR_ASSERT(PR_INTERVAL_NO_TIMEOUT + == overlapped->data.mw.desc->timeout); + } + PR_DELETE(overlapped); +#endif + recv_wait = (PRRecvWait*)head; + } +#ifdef WINNT +invalid_arg: + _PR_MD_UNLOCK(&group->mdlock); +#endif + PR_Unlock(group->ml); + + return recv_wait; +} /* PR_CancelWaitGroup */ + +PR_IMPLEMENT(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size /* ignored */) +{ + PRWaitGroup *wg; + + if (NULL == (wg = PR_NEWZAP(PRWaitGroup))) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto failed; + } + /* the wait group itself */ + wg->ml = PR_NewLock(); + if (NULL == wg->ml) goto failed_lock; + wg->io_taken = PR_NewCondVar(wg->ml); + if (NULL == wg->io_taken) goto failed_cvar0; + wg->io_complete = PR_NewCondVar(wg->ml); + if (NULL == wg->io_complete) goto failed_cvar1; + wg->new_business = PR_NewCondVar(wg->ml); + if (NULL == wg->new_business) goto failed_cvar2; + wg->mw_manage = PR_NewCondVar(wg->ml); + if (NULL == wg->mw_manage) goto failed_cvar3; + + PR_INIT_CLIST(&wg->group_link); + PR_INIT_CLIST(&wg->io_ready); + + /* the waiters sequence */ + wg->waiter = (_PRWaiterHash*)PR_CALLOC( + sizeof(_PRWaiterHash) + + (_PR_DEFAULT_HASH_LENGTH * sizeof(PRRecvWait*))); + if (NULL == wg->waiter) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto failed_waiter; + } + wg->waiter->count = 0; + wg->waiter->length = _PR_DEFAULT_HASH_LENGTH; + +#ifdef WINNT + _PR_MD_NEW_LOCK(&wg->mdlock); + PR_INIT_CLIST(&wg->wait_list); +#endif /* WINNT */ + + PR_Lock(mw_lock); + PR_APPEND_LINK(&wg->group_link, &mw_state->group_list); + PR_Unlock(mw_lock); + return wg; + +failed_waiter: + PR_DestroyCondVar(wg->mw_manage); +failed_cvar3: + PR_DestroyCondVar(wg->new_business); +failed_cvar2: + PR_DestroyCondVar(wg->io_complete); +failed_cvar1: + PR_DestroyCondVar(wg->io_taken); +failed_cvar0: + PR_DestroyLock(wg->ml); +failed_lock: + PR_DELETE(wg); + wg = NULL; + +failed: + return wg; +} /* MW_CreateWaitGroup */ + +PR_IMPLEMENT(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group) +{ + PRStatus rv = PR_SUCCESS; + if (NULL == group) group = mw_state->group; + PR_ASSERT(NULL != group); + if (NULL != group) + { + PR_Lock(group->ml); + if ((group->waiting_threads == 0) + && (group->waiter->count == 0) + && PR_CLIST_IS_EMPTY(&group->io_ready)) + { + group->state = _prmw_stopped; + } + else + { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + rv = PR_FAILURE; + } + PR_Unlock(group->ml); + if (PR_FAILURE == rv) return rv; + + PR_Lock(mw_lock); + PR_REMOVE_LINK(&group->group_link); + PR_Unlock(mw_lock); + +#ifdef WINNT + /* + * XXX make sure wait_list is empty and waiter is empty. + * These must be checked while holding mdlock. + */ + _PR_MD_FREE_LOCK(&group->mdlock); +#endif + + PR_DELETE(group->waiter); + PR_DELETE(group->polling_list); + PR_DestroyCondVar(group->mw_manage); + PR_DestroyCondVar(group->new_business); + PR_DestroyCondVar(group->io_complete); + PR_DestroyCondVar(group->io_taken); + PR_DestroyLock(group->ml); + if (group == mw_state->group) mw_state->group = NULL; + PR_DELETE(group); + } + else + { + /* The default wait group is not created yet. */ + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; + } + return rv; +} /* PR_DestroyWaitGroup */ + +/********************************************************************** +*********************************************************************** +******************** Wait group enumerations ************************** +*********************************************************************** +**********************************************************************/ + +PR_IMPLEMENT(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group) +{ + PRMWaitEnumerator *enumerator = PR_NEWZAP(PRMWaitEnumerator); + if (NULL == enumerator) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + else + { + enumerator->group = group; + enumerator->seal = _PR_ENUM_SEALED; + } + return enumerator; +} /* PR_CreateMWaitEnumerator */ + +PR_IMPLEMENT(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator) +{ + PR_ASSERT(NULL != enumerator); + PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal); + if ((NULL == enumerator) || (_PR_ENUM_SEALED != enumerator->seal)) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + enumerator->seal = _PR_ENUM_UNSEALED; + PR_Free(enumerator); + return PR_SUCCESS; +} /* PR_DestroyMWaitEnumerator */ + +PR_IMPLEMENT(PRRecvWait*) PR_EnumerateWaitGroup( + PRMWaitEnumerator *enumerator, const PRRecvWait *previous) +{ + PRRecvWait *result = NULL; + + /* entry point sanity checking */ + PR_ASSERT(NULL != enumerator); + PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal); + if ((NULL == enumerator) + || (_PR_ENUM_SEALED != enumerator->seal)) goto bad_argument; + + /* beginning of enumeration */ + if (NULL == previous) + { + if (NULL == enumerator->group) + { + enumerator->group = mw_state->group; + if (NULL == enumerator->group) + { + PR_SetError(PR_GROUP_EMPTY_ERROR, 0); + return NULL; + } + } + enumerator->waiter = &enumerator->group->waiter->recv_wait; + enumerator->p_timestamp = enumerator->group->p_timestamp; + enumerator->thread = PR_GetCurrentThread(); + enumerator->index = 0; + } + /* continuing an enumeration */ + else + { + PRThread *me = PR_GetCurrentThread(); + PR_ASSERT(me == enumerator->thread); + if (me != enumerator->thread) goto bad_argument; + + /* need to restart the enumeration */ + if (enumerator->p_timestamp != enumerator->group->p_timestamp) + return PR_EnumerateWaitGroup(enumerator, NULL); + } + + /* actually progress the enumeration */ +#if defined(WINNT) + _PR_MD_LOCK(&enumerator->group->mdlock); +#else + PR_Lock(enumerator->group->ml); +#endif + while (enumerator->index++ < enumerator->group->waiter->length) + { + if (NULL != (result = *(enumerator->waiter)++)) break; + } +#if defined(WINNT) + _PR_MD_UNLOCK(&enumerator->group->mdlock); +#else + PR_Unlock(enumerator->group->ml); +#endif + + return result; /* what we live for */ + +bad_argument: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; /* probably ambiguous */ +} /* PR_EnumerateWaitGroup */ + +/* prmwait.c */ diff -Nru nspr-4.9.5/nspr/pr/src/io/prpolevt.c nspr-4.10.7/nspr/pr/src/io/prpolevt.c --- nspr-4.9.5/nspr/pr/src/io/prpolevt.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prpolevt.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,230 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + ********************************************************************* + * + * Pollable events + * + * Pollable events are implemented using layered I/O. The only + * I/O methods that are implemented for pollable events are poll + * and close. No other methods can be invoked on a pollable + * event. + * + * A pipe or socket pair is created and the pollable event layer + * is pushed onto the read end. A pointer to the write end is + * saved in the PRFilePrivate structure of the pollable event. + * + ********************************************************************* + */ + +#include "prinit.h" +#include "prio.h" +#include "prmem.h" +#include "prerror.h" +#include "prlog.h" + +/* + * These internal functions are declared in primpl.h, + * but we can't include primpl.h because the definition + * of struct PRFilePrivate in this file (for the pollable + * event layer) will conflict with the definition of + * struct PRFilePrivate in primpl.h (for the NSPR layer). + */ +extern PRIntn _PR_InvalidInt(void); +extern PRInt64 _PR_InvalidInt64(void); +extern PRStatus _PR_InvalidStatus(void); +extern PRFileDesc *_PR_InvalidDesc(void); + +/* + * PRFilePrivate structure for the NSPR pollable events layer + */ +struct PRFilePrivate { + PRFileDesc *writeEnd; /* the write end of the pipe/socketpair */ +}; + +static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd); + +static PRInt16 PR_CALLBACK _pr_PolEvtPoll( + PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags); + +static PRIOMethods _pr_polevt_methods = { + PR_DESC_LAYERED, + _pr_PolEvtClose, + (PRReadFN)_PR_InvalidInt, + (PRWriteFN)_PR_InvalidInt, + (PRAvailableFN)_PR_InvalidInt, + (PRAvailable64FN)_PR_InvalidInt64, + (PRFsyncFN)_PR_InvalidStatus, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + (PRWritevFN)_PR_InvalidInt, + (PRConnectFN)_PR_InvalidStatus, + (PRAcceptFN)_PR_InvalidDesc, + (PRBindFN)_PR_InvalidStatus, + (PRListenFN)_PR_InvalidStatus, + (PRShutdownFN)_PR_InvalidStatus, + (PRRecvFN)_PR_InvalidInt, + (PRSendFN)_PR_InvalidInt, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + _pr_PolEvtPoll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + (PRGetsocknameFN)_PR_InvalidStatus, + (PRGetpeernameFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRGetsocketoptionFN)_PR_InvalidStatus, + (PRSetsocketoptionFN)_PR_InvalidStatus, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +static PRDescIdentity _pr_polevt_id; +static PRCallOnceType _pr_polevt_once_control; +static PRStatus PR_CALLBACK _pr_PolEvtInit(void); + +static PRInt16 PR_CALLBACK _pr_PolEvtPoll( + PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) +{ + return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags); +} + +static PRStatus PR_CALLBACK _pr_PolEvtInit(void) +{ + _pr_polevt_id = PR_GetUniqueIdentity("NSPR pollable events"); + if (PR_INVALID_IO_LAYER == _pr_polevt_id) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +#if !defined(XP_UNIX) +#define USE_TCP_SOCKETPAIR +#endif + +PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void) +{ + PRFileDesc *event; + PRFileDesc *fd[2]; /* fd[0] is the read end; fd[1] is the write end */ +#ifdef USE_TCP_SOCKETPAIR + PRSocketOptionData socket_opt; + PRStatus rv; +#endif + + fd[0] = fd[1] = NULL; + + if (PR_CallOnce(&_pr_polevt_once_control, _pr_PolEvtInit) == PR_FAILURE) { + return NULL; + } + + event = PR_CreateIOLayerStub(_pr_polevt_id, &_pr_polevt_methods); + if (NULL == event) { + goto errorExit; + } + event->secret = PR_NEW(PRFilePrivate); + if (event->secret == NULL) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto errorExit; + } + +#ifndef USE_TCP_SOCKETPAIR + if (PR_CreatePipe(&fd[0], &fd[1]) == PR_FAILURE) { + fd[0] = fd[1] = NULL; + goto errorExit; + } +#else + if (PR_NewTCPSocketPair(fd) == PR_FAILURE) { + fd[0] = fd[1] = NULL; + goto errorExit; + } + /* + * set the TCP_NODELAY option to reduce notification latency + */ + socket_opt.option = PR_SockOpt_NoDelay; + socket_opt.value.no_delay = PR_TRUE; + rv = PR_SetSocketOption(fd[1], &socket_opt); + PR_ASSERT(PR_SUCCESS == rv); +#endif + + event->secret->writeEnd = fd[1]; + if (PR_PushIOLayer(fd[0], PR_TOP_IO_LAYER, event) == PR_FAILURE) { + goto errorExit; + } + + return fd[0]; + +errorExit: + if (fd[0]) { + PR_Close(fd[0]); + PR_Close(fd[1]); + } + if (event) { + PR_DELETE(event->secret); + event->dtor(event); + } + return NULL; +} + +static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd) +{ + PRFileDesc *event; + + event = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); + PR_ASSERT(NULL == event->higher && NULL == event->lower); + PR_Close(fd); + PR_Close(event->secret->writeEnd); + PR_DELETE(event->secret); + event->dtor(event); + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event) +{ + return PR_Close(event); +} + +static const char magicChar = '\x38'; + +PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event) +{ + if (PR_Write(event->secret->writeEnd, &magicChar, 1) != 1) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event) +{ + char buf[1024]; + PRInt32 nBytes; +#ifdef DEBUG + PRIntn i; +#endif + + nBytes = PR_Read(event->lower, buf, sizeof(buf)); + if (nBytes == -1) { + return PR_FAILURE; + } + +#ifdef DEBUG + /* + * Make sure people do not write to the pollable event fd + * directly. + */ + for (i = 0; i < nBytes; i++) { + PR_ASSERT(buf[i] == magicChar); + } +#endif + + return PR_SUCCESS; +} diff -Nru nspr-4.9.5/nspr/pr/src/io/prprf.c nspr-4.10.7/nspr/pr/src/io/prprf.c --- nspr-4.9.5/nspr/pr/src/io/prprf.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prprf.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1248 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Portable safe sprintf code. +** +** Author: Kipp E.B. Hickman +*/ +#include +#include +#include +#include +#include "primpl.h" +#include "prprf.h" +#include "prlong.h" +#include "prlog.h" +#include "prmem.h" + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +/* +** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it) +*/ + +/* +** XXX This needs to be internationalized! +*/ + +typedef struct SprintfStateStr SprintfState; + +struct SprintfStateStr { + int (*stuff)(SprintfState *ss, const char *sp, PRUint32 len); + + char *base; + char *cur; + PRUint32 maxlen; + + int (*func)(void *arg, const char *sp, PRUint32 len); + void *arg; +}; + +/* +** Numbered Argument +*/ +struct NumArg { + int type; /* type of the numbered argument */ + union { /* the numbered argument */ + int i; + unsigned int ui; + PRInt32 i32; + PRUint32 ui32; + PRInt64 ll; + PRUint64 ull; + double d; + const char *s; + int *ip; +#ifdef WIN32 + const WCHAR *ws; +#endif + } u; +}; + +#define NAS_DEFAULT_NUM 20 /* default number of NumberedArgument array */ + + +#define TYPE_INT16 0 +#define TYPE_UINT16 1 +#define TYPE_INTN 2 +#define TYPE_UINTN 3 +#define TYPE_INT32 4 +#define TYPE_UINT32 5 +#define TYPE_INT64 6 +#define TYPE_UINT64 7 +#define TYPE_STRING 8 +#define TYPE_DOUBLE 9 +#define TYPE_INTSTR 10 +#ifdef WIN32 +#define TYPE_WSTRING 11 +#endif +#define TYPE_UNKNOWN 20 + +#define FLAG_LEFT 0x1 +#define FLAG_SIGNED 0x2 +#define FLAG_SPACED 0x4 +#define FLAG_ZEROS 0x8 +#define FLAG_NEG 0x10 + +/* +** Fill into the buffer using the data in src +*/ +static int fill2(SprintfState *ss, const char *src, int srclen, int width, + int flags) +{ + char space = ' '; + int rv; + + width -= srclen; + if ((width > 0) && ((flags & FLAG_LEFT) == 0)) { /* Right adjusting */ + if (flags & FLAG_ZEROS) { + space = '0'; + } + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } + } + + /* Copy out the source data */ + rv = (*ss->stuff)(ss, src, srclen); + if (rv < 0) { + return rv; + } + + if ((width > 0) && ((flags & FLAG_LEFT) != 0)) { /* Left adjusting */ + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } + } + return 0; +} + +/* +** Fill a number. The order is: optional-sign zero-filling conversion-digits +*/ +static int fill_n(SprintfState *ss, const char *src, int srclen, int width, + int prec, int type, int flags) +{ + int zerowidth = 0; + int precwidth = 0; + int signwidth = 0; + int leftspaces = 0; + int rightspaces = 0; + int cvtwidth; + int rv; + char sign; + + if ((type & 1) == 0) { + if (flags & FLAG_NEG) { + sign = '-'; + signwidth = 1; + } else if (flags & FLAG_SIGNED) { + sign = '+'; + signwidth = 1; + } else if (flags & FLAG_SPACED) { + sign = ' '; + signwidth = 1; + } + } + cvtwidth = signwidth + srclen; + + if (prec > 0) { + if (prec > srclen) { + precwidth = prec - srclen; /* Need zero filling */ + cvtwidth += precwidth; + } + } + + if ((flags & FLAG_ZEROS) && (prec < 0)) { + if (width > cvtwidth) { + zerowidth = width - cvtwidth; /* Zero filling */ + cvtwidth += zerowidth; + } + } + + if (flags & FLAG_LEFT) { + if (width > cvtwidth) { + /* Space filling on the right (i.e. left adjusting) */ + rightspaces = width - cvtwidth; + } + } else { + if (width > cvtwidth) { + /* Space filling on the left (i.e. right adjusting) */ + leftspaces = width - cvtwidth; + } + } + while (--leftspaces >= 0) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + if (signwidth) { + rv = (*ss->stuff)(ss, &sign, 1); + if (rv < 0) { + return rv; + } + } + while (--precwidth >= 0) { + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } + } + while (--zerowidth >= 0) { + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } + } + rv = (*ss->stuff)(ss, src, srclen); + if (rv < 0) { + return rv; + } + while (--rightspaces >= 0) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + return 0; +} + +/* +** Convert a long into its printable form +*/ +static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, + int type, int flags, const char *hexp) +{ + char cvtbuf[100]; + char *cvt; + int digits; + + /* according to the man page this needs to happen */ + if ((prec == 0) && (num == 0)) { + return 0; + } + + /* + ** Converting decimal is a little tricky. In the unsigned case we + ** need to stop when we hit 10 digits. In the signed case, we can + ** stop when the number is zero. + */ + cvt = cvtbuf + sizeof(cvtbuf); + digits = 0; + while (num) { + int digit = (((unsigned long)num) % radix) & 0xF; + *--cvt = hexp[digit]; + digits++; + num = (long)(((unsigned long)num) / radix); + } + if (digits == 0) { + *--cvt = '0'; + digits++; + } + + /* + ** Now that we have the number converted without its sign, deal with + ** the sign and zero padding. + */ + return fill_n(ss, cvt, digits, width, prec, type, flags); +} + +/* +** Convert a 64-bit integer into its printable form +*/ +static int cvt_ll(SprintfState *ss, PRInt64 num, int width, int prec, int radix, + int type, int flags, const char *hexp) +{ + char cvtbuf[100]; + char *cvt; + int digits; + PRInt64 rad; + + /* according to the man page this needs to happen */ + if ((prec == 0) && (LL_IS_ZERO(num))) { + return 0; + } + + /* + ** Converting decimal is a little tricky. In the unsigned case we + ** need to stop when we hit 10 digits. In the signed case, we can + ** stop when the number is zero. + */ + LL_I2L(rad, radix); + cvt = cvtbuf + sizeof(cvtbuf); + digits = 0; + while (!LL_IS_ZERO(num)) { + PRInt32 digit; + PRInt64 quot, rem; + LL_UDIVMOD(", &rem, num, rad); + LL_L2I(digit, rem); + *--cvt = hexp[digit & 0xf]; + digits++; + num = quot; + } + if (digits == 0) { + *--cvt = '0'; + digits++; + } + + /* + ** Now that we have the number converted without its sign, deal with + ** the sign and zero padding. + */ + return fill_n(ss, cvt, digits, width, prec, type, flags); +} + +/* +** Convert a double precision floating point number into its printable +** form. +** +** XXX stop using snprintf to convert floating point +*/ +static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) +{ + char fin[20]; + char fout[300]; + int amount = fmt1 - fmt0; + + if (amount <= 0 || amount >= sizeof(fin)) { + /* Totally bogus % command to snprintf. Just ignore it */ + return 0; + } + memcpy(fin, fmt0, amount); + fin[amount] = 0; + + /* Convert floating point using the native snprintf code */ +#ifdef DEBUG + { + const char *p = fin; + while (*p) { + PR_ASSERT(*p != 'L'); + p++; + } + } +#endif + memset(fout, 0, sizeof(fout)); + snprintf(fout, sizeof(fout), fin, d); + /* Explicitly null-terminate fout because on Windows snprintf doesn't + * append a null-terminator if the buffer is too small. */ + fout[sizeof(fout) - 1] = '\0'; + + return (*ss->stuff)(ss, fout, strlen(fout)); +} + +/* +** Convert a string into its printable form. "width" is the output +** width. "prec" is the maximum number of characters of "s" to output, +** where -1 means until NUL. +*/ +static int cvt_s(SprintfState *ss, const char *str, int width, int prec, + int flags) +{ + int slen; + + if (prec == 0) + return 0; + + /* Limit string length by precision value */ + if (!str) { + str = "(null)"; + } + if (prec > 0) { + /* this is: slen = strnlen(str, prec); */ + register const char *s; + + for(s = str; prec && *s; s++, prec-- ) + ; + slen = s - str; + } else { + slen = strlen(str); + } + + /* and away we go */ + return fill2(ss, str, slen, width, flags); +} + +/* +** BuildArgArray stands for Numbered Argument list Sprintf +** for example, +** fmp = "%4$i, %2$d, %3s, %1d"; +** the number must start from 1, and no gap among them +*/ + +static struct NumArg* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArg* nasArray ) +{ + int number = 0, cn = 0, i; + const char* p; + char c; + struct NumArg* nas; + + + /* + ** first pass: + ** determine how many legal % I have got, then allocate space + */ + + p = fmt; + *rv = 0; + i = 0; + while( ( c = *p++ ) != 0 ){ + if( c != '%' ) + continue; + if( ( c = *p++ ) == '%' ) /* skip %% case */ + continue; + + while( c != 0 ){ + if( c > '9' || c < '0' ){ + if( c == '$' ){ /* numbered argument case */ + if( i > 0 ){ + *rv = -1; + return NULL; + } + number++; + } else{ /* non-numbered argument case */ + if( number > 0 ){ + *rv = -1; + return NULL; + } + i = 1; + } + break; + } + + c = *p++; + } + } + + if( number == 0 ){ + return NULL; + } + + + if( number > NAS_DEFAULT_NUM ){ + nas = (struct NumArg*)PR_MALLOC( number * sizeof( struct NumArg ) ); + if( !nas ){ + *rv = -1; + return NULL; + } + } else { + nas = nasArray; + } + + for( i = 0; i < number; i++ ){ + nas[i].type = TYPE_UNKNOWN; + } + + + /* + ** second pass: + ** set nas[].type + */ + + p = fmt; + while( ( c = *p++ ) != 0 ){ + if( c != '%' ) continue; + c = *p++; + if( c == '%' ) continue; + + cn = 0; + while( c && c != '$' ){ /* should imporve error check later */ + cn = cn*10 + c - '0'; + c = *p++; + } + + if( !c || cn < 1 || cn > number ){ + *rv = -1; + break; + } + + /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */ + cn--; + if( nas[cn].type != TYPE_UNKNOWN ) + continue; + + c = *p++; + + /* width */ + if (c == '*') { + /* not supported feature, for the argument is not numbered */ + *rv = -1; + break; + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; + } + + /* precision */ + if (c == '.') { + c = *p++; + if (c == '*') { + /* not supported feature, for the argument is not numbered */ + *rv = -1; + break; + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; + } + } + + /* size */ + nas[cn].type = TYPE_INTN; + if (c == 'h') { + nas[cn].type = TYPE_INT16; + c = *p++; + } else if (c == 'L') { + /* XXX not quite sure here */ + nas[cn].type = TYPE_INT64; + c = *p++; + } else if (c == 'l') { + nas[cn].type = TYPE_INT32; + c = *p++; + if (c == 'l') { + nas[cn].type = TYPE_INT64; + c = *p++; + } + } + + /* format */ + switch (c) { + case 'd': + case 'c': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + break; + + case 'e': + case 'f': + case 'g': + nas[ cn ].type = TYPE_DOUBLE; + break; + + case 'p': + /* XXX should use cpp */ + if (sizeof(void *) == sizeof(PRInt32)) { + nas[ cn ].type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(PRInt64)) { + nas[ cn ].type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(PRIntn)) { + nas[ cn ].type = TYPE_UINTN; + } else { + nas[ cn ].type = TYPE_UNKNOWN; + } + break; + + case 'S': +#ifdef WIN32 + nas[ cn ].type = TYPE_WSTRING; + break; +#endif + case 'C': + case 'E': + case 'G': + /* XXX not supported I suppose */ + PR_ASSERT(0); + nas[ cn ].type = TYPE_UNKNOWN; + break; + + case 's': + nas[ cn ].type = TYPE_STRING; + break; + + case 'n': + nas[ cn ].type = TYPE_INTSTR; + break; + + default: + PR_ASSERT(0); + nas[ cn ].type = TYPE_UNKNOWN; + break; + } + + /* get a legal para. */ + if( nas[ cn ].type == TYPE_UNKNOWN ){ + *rv = -1; + break; + } + } + + + /* + ** third pass + ** fill the nas[cn].ap + */ + + if( *rv < 0 ){ + if( nas != nasArray ) + PR_DELETE( nas ); + return NULL; + } + + cn = 0; + while( cn < number ){ + if( nas[cn].type == TYPE_UNKNOWN ){ + cn++; + continue; + } + + switch( nas[cn].type ){ + case TYPE_INT16: + case TYPE_UINT16: + case TYPE_INTN: + nas[cn].u.i = va_arg( ap, int ); + break; + + case TYPE_UINTN: + nas[cn].u.ui = va_arg( ap, unsigned int ); + break; + + case TYPE_INT32: + nas[cn].u.i32 = va_arg( ap, PRInt32 ); + break; + + case TYPE_UINT32: + nas[cn].u.ui32 = va_arg( ap, PRUint32 ); + break; + + case TYPE_INT64: + nas[cn].u.ll = va_arg( ap, PRInt64 ); + break; + + case TYPE_UINT64: + nas[cn].u.ull = va_arg( ap, PRUint64 ); + break; + + case TYPE_STRING: + nas[cn].u.s = va_arg( ap, char* ); + break; + +#ifdef WIN32 + case TYPE_WSTRING: + nas[cn].u.ws = va_arg( ap, WCHAR* ); + break; +#endif + + case TYPE_INTSTR: + nas[cn].u.ip = va_arg( ap, int* ); + break; + + case TYPE_DOUBLE: + nas[cn].u.d = va_arg( ap, double ); + break; + + default: + if( nas != nasArray ) + PR_DELETE( nas ); + *rv = -1; + return NULL; + } + + cn++; + } + + + return nas; +} + +/* +** The workhorse sprintf code. +*/ +static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) +{ + char c; + int flags, width, prec, radix, type; + union { + char ch; + int i; + long l; + PRInt64 ll; + double d; + const char *s; + int *ip; +#ifdef WIN32 + const WCHAR *ws; +#endif + } u; + const char *fmt0; + static char *hex = "0123456789abcdef"; + static char *HEX = "0123456789ABCDEF"; + char *hexp; + int rv, i; + struct NumArg* nas = NULL; + struct NumArg* nap; + struct NumArg nasArray[ NAS_DEFAULT_NUM ]; + char pattern[20]; + const char* dolPt = NULL; /* in "%4$.2f", dolPt will point to . */ +#ifdef WIN32 + char *pBuf = NULL; +#endif + + /* + ** build an argument array, IF the fmt is numbered argument + ** list style, to contain the Numbered Argument list pointers + */ + + nas = BuildArgArray( fmt, ap, &rv, nasArray ); + if( rv < 0 ){ + /* the fmt contains error Numbered Argument format, jliu@netscape.com */ + PR_ASSERT(0); + return rv; + } + + while ((c = *fmt++) != 0) { + if (c != '%') { + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + fmt0 = fmt - 1; + + /* + ** Gobble up the % format string. Hopefully we have handled all + ** of the strange cases! + */ + flags = 0; + c = *fmt++; + if (c == '%') { + /* quoting a % with %% */ + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + + if( nas != NULL ){ + /* the fmt contains the Numbered Arguments feature */ + i = 0; + while( c && c != '$' ){ /* should imporve error check later */ + i = ( i * 10 ) + ( c - '0' ); + c = *fmt++; + } + + if( nas[i-1].type == TYPE_UNKNOWN ){ + if( nas && ( nas != nasArray ) ) + PR_DELETE( nas ); + return -1; + } + + nap = &nas[i-1]; + dolPt = fmt; + c = *fmt++; + } + + /* + * Examine optional flags. Note that we do not implement the + * '#' flag of sprintf(). The ANSI C spec. of the '#' flag is + * somewhat ambiguous and not ideal, which is perhaps why + * the various sprintf() implementations are inconsistent + * on this feature. + */ + while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) { + if (c == '-') flags |= FLAG_LEFT; + if (c == '+') flags |= FLAG_SIGNED; + if (c == ' ') flags |= FLAG_SPACED; + if (c == '0') flags |= FLAG_ZEROS; + c = *fmt++; + } + if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED; + if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS; + + /* width */ + if (c == '*') { + c = *fmt++; + width = va_arg(ap, int); + } else { + width = 0; + while ((c >= '0') && (c <= '9')) { + width = (width * 10) + (c - '0'); + c = *fmt++; + } + } + + /* precision */ + prec = -1; + if (c == '.') { + c = *fmt++; + if (c == '*') { + c = *fmt++; + prec = va_arg(ap, int); + } else { + prec = 0; + while ((c >= '0') && (c <= '9')) { + prec = (prec * 10) + (c - '0'); + c = *fmt++; + } + } + } + + /* size */ + type = TYPE_INTN; + if (c == 'h') { + type = TYPE_INT16; + c = *fmt++; + } else if (c == 'L') { + /* XXX not quite sure here */ + type = TYPE_INT64; + c = *fmt++; + } else if (c == 'l') { + type = TYPE_INT32; + c = *fmt++; + if (c == 'l') { + type = TYPE_INT64; + c = *fmt++; + } + } + + /* format */ + hexp = hex; + switch (c) { + case 'd': case 'i': /* decimal/integer */ + radix = 10; + goto fetch_and_convert; + + case 'o': /* octal */ + radix = 8; + type |= 1; + goto fetch_and_convert; + + case 'u': /* unsigned decimal */ + radix = 10; + type |= 1; + goto fetch_and_convert; + + case 'x': /* unsigned hex */ + radix = 16; + type |= 1; + goto fetch_and_convert; + + case 'X': /* unsigned HEX */ + radix = 16; + hexp = HEX; + type |= 1; + goto fetch_and_convert; + + fetch_and_convert: + switch (type) { + case TYPE_INT16: + u.l = nas ? nap->u.i : va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINT16: + u.l = (nas ? nap->u.i : va_arg(ap, int)) & 0xffff; + goto do_long; + case TYPE_INTN: + u.l = nas ? nap->u.i : va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINTN: + u.l = (long)(nas ? nap->u.ui : va_arg(ap, unsigned int)); + goto do_long; + + case TYPE_INT32: + u.l = nas ? nap->u.i32 : va_arg(ap, PRInt32); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINT32: + u.l = (long)(nas ? nap->u.ui32 : va_arg(ap, PRUint32)); + do_long: + rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + + case TYPE_INT64: + u.ll = nas ? nap->u.ll : va_arg(ap, PRInt64); + if (!LL_GE_ZERO(u.ll)) { + LL_NEG(u.ll, u.ll); + flags |= FLAG_NEG; + } + goto do_longlong; + case TYPE_UINT64: + u.ll = nas ? nap->u.ull : va_arg(ap, PRUint64); + do_longlong: + rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + } + break; + + case 'e': + case 'E': + case 'f': + case 'g': + u.d = nas ? nap->u.d : va_arg(ap, double); + if( nas != NULL ){ + i = fmt - dolPt; + if( i < sizeof( pattern ) ){ + pattern[0] = '%'; + memcpy( &pattern[1], dolPt, i ); + rv = cvt_f(ss, u.d, pattern, &pattern[i+1] ); + } + } else + rv = cvt_f(ss, u.d, fmt0, fmt); + + if (rv < 0) { + return rv; + } + break; + + case 'c': + u.ch = nas ? nap->u.i : va_arg(ap, int); + if ((flags & FLAG_LEFT) == 0) { + while (width-- > 1) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + } + rv = (*ss->stuff)(ss, &u.ch, 1); + if (rv < 0) { + return rv; + } + if (flags & FLAG_LEFT) { + while (width-- > 1) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + } + break; + + case 'p': + if (sizeof(void *) == sizeof(PRInt32)) { + type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(PRInt64)) { + type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(int)) { + type = TYPE_UINTN; + } else { + PR_ASSERT(0); + break; + } + radix = 16; + goto fetch_and_convert; + +#ifndef WIN32 + case 'S': + /* XXX not supported I suppose */ + PR_ASSERT(0); + break; +#endif + +#if 0 + case 'C': + case 'E': + case 'G': + /* XXX not supported I suppose */ + PR_ASSERT(0); + break; +#endif + +#ifdef WIN32 + case 'S': + u.ws = nas ? nap->u.ws : va_arg(ap, const WCHAR*); + + /* Get the required size in rv */ + rv = WideCharToMultiByte(CP_ACP, 0, u.ws, -1, NULL, 0, NULL, NULL); + if (rv == 0) + rv = 1; + pBuf = PR_MALLOC(rv); + WideCharToMultiByte(CP_ACP, 0, u.ws, -1, pBuf, (int)rv, NULL, NULL); + pBuf[rv-1] = '\0'; + + rv = cvt_s(ss, pBuf, width, prec, flags); + + /* We don't need the allocated buffer anymore */ + PR_Free(pBuf); + if (rv < 0) { + return rv; + } + break; + +#endif + + case 's': + u.s = nas ? nap->u.s : va_arg(ap, const char*); + rv = cvt_s(ss, u.s, width, prec, flags); + if (rv < 0) { + return rv; + } + break; + + case 'n': + u.ip = nas ? nap->u.ip : va_arg(ap, int*); + if (u.ip) { + *u.ip = ss->cur - ss->base; + } + break; + + default: + /* Not a % token after all... skip it */ +#if 0 + PR_ASSERT(0); +#endif + rv = (*ss->stuff)(ss, "%", 1); + if (rv < 0) { + return rv; + } + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + } + } + + /* Stuff trailing NUL */ + rv = (*ss->stuff)(ss, "\0", 1); + + if( nas && ( nas != nasArray ) ){ + PR_DELETE( nas ); + } + + return rv; +} + +/************************************************************************/ + +static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len) +{ + int rv; + + rv = (*ss->func)(ss->arg, sp, len); + if (rv < 0) { + return rv; + } + ss->maxlen += len; + return 0; +} + +PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, + const char *fmt, ...) +{ + va_list ap; + PRUint32 rv; + + va_start(ap, fmt); + rv = PR_vsxprintf(func, arg, fmt, ap); + va_end(ap); + return rv; +} + +PR_IMPLEMENT(PRUint32) PR_vsxprintf(PRStuffFunc func, void *arg, + const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = FuncStuff; + ss.func = func; + ss.arg = arg; + ss.maxlen = 0; + rv = dosprintf(&ss, fmt, ap); + return (rv < 0) ? (PRUint32)-1 : ss.maxlen; +} + +/* +** Stuff routine that automatically grows the malloc'd output buffer +** before it overflows. +*/ +static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len) +{ + ptrdiff_t off; + char *newbase; + PRUint32 newlen; + + off = ss->cur - ss->base; + if (off + len >= ss->maxlen) { + /* Grow the buffer */ + newlen = ss->maxlen + ((len > 32) ? len : 32); + if (ss->base) { + newbase = (char*) PR_REALLOC(ss->base, newlen); + } else { + newbase = (char*) PR_MALLOC(newlen); + } + if (!newbase) { + /* Ran out of memory */ + return -1; + } + ss->base = newbase; + ss->maxlen = newlen; + ss->cur = ss->base + off; + } + + /* Copy data */ + while (len) { + --len; + *ss->cur++ = *sp++; + } + PR_ASSERT((PRUint32)(ss->cur - ss->base) <= ss->maxlen); + return 0; +} + +/* +** sprintf into a malloc'd buffer +*/ +PR_IMPLEMENT(char *) PR_smprintf(const char *fmt, ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = PR_vsmprintf(fmt, ap); + va_end(ap); + return rv; +} + +/* +** Free memory allocated, for the caller, by PR_smprintf +*/ +PR_IMPLEMENT(void) PR_smprintf_free(char *mem) +{ + PR_DELETE(mem); +} + +PR_IMPLEMENT(char *) PR_vsmprintf(const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = GrowStuff; + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; + rv = dosprintf(&ss, fmt, ap); + if (rv < 0) { + if (ss.base) { + PR_DELETE(ss.base); + } + return 0; + } + return ss.base; +} + +/* +** Stuff routine that discards overflow data +*/ +static int LimitStuff(SprintfState *ss, const char *sp, PRUint32 len) +{ + PRUint32 limit = ss->maxlen - (ss->cur - ss->base); + + if (len > limit) { + len = limit; + } + while (len) { + --len; + *ss->cur++ = *sp++; + } + return 0; +} + +/* +** sprintf into a fixed size buffer. Make sure there is a NUL at the end +** when finished. +*/ +PR_IMPLEMENT(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...) +{ + va_list ap; + PRUint32 rv; + + va_start(ap, fmt); + rv = PR_vsnprintf(out, outlen, fmt, ap); + va_end(ap); + return rv; +} + +PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt, + va_list ap) +{ + SprintfState ss; + PRUint32 n; + + PR_ASSERT((PRInt32)outlen > 0); + if ((PRInt32)outlen <= 0) { + return 0; + } + + ss.stuff = LimitStuff; + ss.base = out; + ss.cur = out; + ss.maxlen = outlen; + (void) dosprintf(&ss, fmt, ap); + + /* If we added chars, and we didn't append a null, do it now. */ + if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') ) + *(ss.cur - 1) = '\0'; + + n = ss.cur - ss.base; + return n ? n - 1 : n; +} + +PR_IMPLEMENT(char *) PR_sprintf_append(char *last, const char *fmt, ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = PR_vsprintf_append(last, fmt, ap); + va_end(ap); + return rv; +} + +PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = GrowStuff; + if (last) { + int lastlen = strlen(last); + ss.base = last; + ss.cur = last + lastlen; + ss.maxlen = lastlen; + } else { + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; + } + rv = dosprintf(&ss, fmt, ap); + if (rv < 0) { + if (ss.base) { + PR_DELETE(ss.base); + } + return 0; + } + return ss.base; +} + diff -Nru nspr-4.9.5/nspr/pr/src/io/prscanf.c nspr-4.10.7/nspr/pr/src/io/prscanf.c --- nspr-4.9.5/nspr/pr/src/io/prscanf.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prscanf.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,634 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Scan functions for NSPR types + * + * Author: Wan-Teh Chang + * + * Acknowledgment: The implementation is inspired by the source code + * in P.J. Plauger's "The Standard C Library," Prentice-Hall, 1992. + */ + +#include +#include +#include +#include +#include "prprf.h" +#include "prdtoa.h" +#include "prlog.h" +#include "prerror.h" + +/* + * A function that reads a character from 'stream'. + * Returns the character read, or EOF if end of stream is reached. + */ +typedef int (*_PRGetCharFN)(void *stream); + +/* + * A function that pushes the character 'ch' back to 'stream'. + */ +typedef void (*_PRUngetCharFN)(void *stream, int ch); + +/* + * The size specifier for the integer and floating point number + * conversions in format control strings. + */ +typedef enum { + _PR_size_none, /* No size specifier is given */ + _PR_size_h, /* The 'h' specifier, suggesting "short" */ + _PR_size_l, /* The 'l' specifier, suggesting "long" */ + _PR_size_L, /* The 'L' specifier, meaning a 'long double' */ + _PR_size_ll /* The 'll' specifier, suggesting "long long" */ +} _PRSizeSpec; + +/* + * The collection of data that is passed between the scan function + * and its subordinate functions. The fields of this structure + * serve as the input or output arguments for these functions. + */ +typedef struct { + _PRGetCharFN get; /* get a character from input stream */ + _PRUngetCharFN unget; /* unget (push back) a character */ + void *stream; /* argument for get and unget */ + va_list ap; /* the variable argument list */ + int nChar; /* number of characters read from 'stream' */ + + PRBool assign; /* assign, or suppress assignment? */ + int width; /* field width */ + _PRSizeSpec sizeSpec; /* 'h', 'l', 'L', or 'll' */ + + PRBool converted; /* is the value actually converted? */ +} ScanfState; + +#define GET(state) ((state)->nChar++, (state)->get((state)->stream)) +#define UNGET(state, ch) \ + ((state)->nChar--, (state)->unget((state)->stream, ch)) + +/* + * The following two macros, GET_IF_WITHIN_WIDTH and WITHIN_WIDTH, + * are always used together. + * + * GET_IF_WITHIN_WIDTH calls the GET macro and assigns its return + * value to 'ch' only if we have not exceeded the field width of + * 'state'. Therefore, after GET_IF_WITHIN_WIDTH, the value of + * 'ch' is valid only if the macro WITHIN_WIDTH evaluates to true. + */ + +#define GET_IF_WITHIN_WIDTH(state, ch) \ + if (--(state)->width >= 0) { \ + (ch) = GET(state); \ + } +#define WITHIN_WIDTH(state) ((state)->width >= 0) + +/* + * _pr_strtoull: + * Convert a string to an unsigned 64-bit integer. The string + * 'str' is assumed to be a representation of the integer in + * base 'base'. + * + * Warning: + * - Only handle base 8, 10, and 16. + * - No overflow checking. + */ + +static PRUint64 +_pr_strtoull(const char *str, char **endptr, int base) +{ + static const int BASE_MAX = 16; + static const char digits[] = "0123456789abcdef"; + char *digitPtr; + PRUint64 x; /* return value */ + PRInt64 base64; + const char *cPtr; + PRBool negative; + const char *digitStart; + + PR_ASSERT(base == 0 || base == 8 || base == 10 || base == 16); + if (base < 0 || base == 1 || base > BASE_MAX) { + if (endptr) { + *endptr = (char *) str; + return LL_ZERO; + } + } + + cPtr = str; + while (isspace(*cPtr)) { + ++cPtr; + } + + negative = PR_FALSE; + if (*cPtr == '-') { + negative = PR_TRUE; + cPtr++; + } else if (*cPtr == '+') { + cPtr++; + } + + if (base == 16) { + if (*cPtr == '0' && (cPtr[1] == 'x' || cPtr[1] == 'X')) { + cPtr += 2; + } + } else if (base == 0) { + if (*cPtr != '0') { + base = 10; + } else if (cPtr[1] == 'x' || cPtr[1] == 'X') { + base = 16; + cPtr += 2; + } else { + base = 8; + } + } + PR_ASSERT(base != 0); + LL_I2L(base64, base); + digitStart = cPtr; + + /* Skip leading zeros */ + while (*cPtr == '0') { + cPtr++; + } + + LL_I2L(x, 0); + while ((digitPtr = (char*)memchr(digits, tolower(*cPtr), base)) != NULL) { + PRUint64 d; + + LL_I2L(d, (digitPtr - digits)); + LL_MUL(x, x, base64); + LL_ADD(x, x, d); + cPtr++; + } + + if (cPtr == digitStart) { + if (endptr) { + *endptr = (char *) str; + } + return LL_ZERO; + } + + if (negative) { +#ifdef HAVE_LONG_LONG + /* The cast to a signed type is to avoid a compiler warning */ + x = -(PRInt64)x; +#else + LL_NEG(x, x); +#endif + } + + if (endptr) { + *endptr = (char *) cPtr; + } + return x; +} + +/* + * The maximum field width (in number of characters) that is enough + * (may be more than necessary) to represent a 64-bit integer or + * floating point number. + */ +#define FMAX 31 +#define DECIMAL_POINT '.' + +static PRStatus +GetInt(ScanfState *state, int code) +{ + char buf[FMAX + 1], *p; + int ch; + static const char digits[] = "0123456789abcdefABCDEF"; + PRBool seenDigit = PR_FALSE; + int base; + int dlen; + + switch (code) { + case 'd': case 'u': + base = 10; + break; + case 'i': + base = 0; + break; + case 'x': case 'X': case 'p': + base = 16; + break; + case 'o': + base = 8; + break; + default: + return PR_FAILURE; + } + if (state->width == 0 || state->width > FMAX) { + state->width = FMAX; + } + p = buf; + GET_IF_WITHIN_WIDTH(state, ch); + if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + } + if (WITHIN_WIDTH(state) && ch == '0') { + seenDigit = PR_TRUE; + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + if (WITHIN_WIDTH(state) + && (ch == 'x' || ch == 'X') + && (base == 0 || base == 16)) { + base = 16; + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + } else if (base == 0) { + base = 8; + } + } + if (base == 0 || base == 10) { + dlen = 10; + } else if (base == 8) { + dlen = 8; + } else { + PR_ASSERT(base == 16); + dlen = 16 + 6; /* 16 digits, plus 6 in uppercase */ + } + while (WITHIN_WIDTH(state) && memchr(digits, ch, dlen)) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + seenDigit = PR_TRUE; + } + if (WITHIN_WIDTH(state)) { + UNGET(state, ch); + } + if (!seenDigit) { + return PR_FAILURE; + } + *p = '\0'; + if (state->assign) { + if (code == 'd' || code == 'i') { + if (state->sizeSpec == _PR_size_ll) { + PRInt64 llval = _pr_strtoull(buf, NULL, base); + *va_arg(state->ap, PRInt64 *) = llval; + } else { + long lval = strtol(buf, NULL, base); + + if (state->sizeSpec == _PR_size_none) { + *va_arg(state->ap, PRIntn *) = lval; + } else if (state->sizeSpec == _PR_size_h) { + *va_arg(state->ap, PRInt16 *) = (PRInt16)lval; + } else if (state->sizeSpec == _PR_size_l) { + *va_arg(state->ap, PRInt32 *) = lval; + } else { + return PR_FAILURE; + } + } + } else { + if (state->sizeSpec == _PR_size_ll) { + PRUint64 llval = _pr_strtoull(buf, NULL, base); + *va_arg(state->ap, PRUint64 *) = llval; + } else { + unsigned long lval = strtoul(buf, NULL, base); + + if (state->sizeSpec == _PR_size_none) { + *va_arg(state->ap, PRUintn *) = lval; + } else if (state->sizeSpec == _PR_size_h) { + *va_arg(state->ap, PRUint16 *) = (PRUint16)lval; + } else if (state->sizeSpec == _PR_size_l) { + *va_arg(state->ap, PRUint32 *) = lval; + } else { + return PR_FAILURE; + } + } + } + state->converted = PR_TRUE; + } + return PR_SUCCESS; +} + +static PRStatus +GetFloat(ScanfState *state) +{ + char buf[FMAX + 1], *p; + int ch; + PRBool seenDigit = PR_FALSE; + + if (state->width == 0 || state->width > FMAX) { + state->width = FMAX; + } + p = buf; + GET_IF_WITHIN_WIDTH(state, ch); + if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + } + while (WITHIN_WIDTH(state) && isdigit(ch)) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + seenDigit = PR_TRUE; + } + if (WITHIN_WIDTH(state) && ch == DECIMAL_POINT) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + while (WITHIN_WIDTH(state) && isdigit(ch)) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + seenDigit = PR_TRUE; + } + } + + /* + * This is not robust. For example, "1.2e+" would confuse + * the code below to read 'e' and '+', only to realize that + * it should have stopped at "1.2". But we can't push back + * more than one character, so there is nothing I can do. + */ + + /* Parse exponent */ + if (WITHIN_WIDTH(state) && (ch == 'e' || ch == 'E') && seenDigit) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + } + while (WITHIN_WIDTH(state) && isdigit(ch)) { + *p++ = ch; + GET_IF_WITHIN_WIDTH(state, ch); + } + } + if (WITHIN_WIDTH(state)) { + UNGET(state, ch); + } + if (!seenDigit) { + return PR_FAILURE; + } + *p = '\0'; + if (state->assign) { + PRFloat64 dval = PR_strtod(buf, NULL); + + state->converted = PR_TRUE; + if (state->sizeSpec == _PR_size_l) { + *va_arg(state->ap, PRFloat64 *) = dval; + } else if (state->sizeSpec == _PR_size_L) { +#if defined(OSF1) || defined(IRIX) + *va_arg(state->ap, double *) = dval; +#else + *va_arg(state->ap, long double *) = dval; +#endif + } else { + *va_arg(state->ap, float *) = (float) dval; + } + } + return PR_SUCCESS; +} + +/* + * Convert, and return the end of the conversion spec. + * Return NULL on error. + */ + +static const char * +Convert(ScanfState *state, const char *fmt) +{ + const char *cPtr; + int ch; + char *cArg = NULL; + + state->converted = PR_FALSE; + cPtr = fmt; + if (*cPtr != 'c' && *cPtr != 'n' && *cPtr != '[') { + do { + ch = GET(state); + } while (isspace(ch)); + UNGET(state, ch); + } + switch (*cPtr) { + case 'c': + if (state->assign) { + cArg = va_arg(state->ap, char *); + } + if (state->width == 0) { + state->width = 1; + } + for (; state->width > 0; state->width--) { + ch = GET(state); + if (ch == EOF) { + return NULL; + } else if (state->assign) { + *cArg++ = ch; + } + } + if (state->assign) { + state->converted = PR_TRUE; + } + break; + case 'p': + case 'd': case 'i': case 'o': + case 'u': case 'x': case 'X': + if (GetInt(state, *cPtr) == PR_FAILURE) { + return NULL; + } + break; + case 'e': case 'E': case 'f': + case 'g': case 'G': + if (GetFloat(state) == PR_FAILURE) { + return NULL; + } + break; + case 'n': + /* do not consume any input */ + if (state->assign) { + switch (state->sizeSpec) { + case _PR_size_none: + *va_arg(state->ap, PRIntn *) = state->nChar; + break; + case _PR_size_h: + *va_arg(state->ap, PRInt16 *) = state->nChar; + break; + case _PR_size_l: + *va_arg(state->ap, PRInt32 *) = state->nChar; + break; + case _PR_size_ll: + LL_I2L(*va_arg(state->ap, PRInt64 *), state->nChar); + break; + default: + PR_ASSERT(0); + } + } + break; + case 's': + if (state->width == 0) { + state->width = INT_MAX; + } + if (state->assign) { + cArg = va_arg(state->ap, char *); + } + for (; state->width > 0; state->width--) { + ch = GET(state); + if ((ch == EOF) || isspace(ch)) { + UNGET(state, ch); + break; + } + if (state->assign) { + *cArg++ = ch; + } + } + if (state->assign) { + *cArg = '\0'; + state->converted = PR_TRUE; + } + break; + case '%': + ch = GET(state); + if (ch != '%') { + UNGET(state, ch); + return NULL; + } + break; + case '[': + { + PRBool complement = PR_FALSE; + const char *closeBracket; + size_t n; + + if (*++cPtr == '^') { + complement = PR_TRUE; + cPtr++; + } + closeBracket = strchr(*cPtr == ']' ? cPtr + 1 : cPtr, ']'); + if (closeBracket == NULL) { + return NULL; + } + n = closeBracket - cPtr; + if (state->width == 0) { + state->width = INT_MAX; + } + if (state->assign) { + cArg = va_arg(state->ap, char *); + } + for (; state->width > 0; state->width--) { + ch = GET(state); + if ((ch == EOF) + || (!complement && !memchr(cPtr, ch, n)) + || (complement && memchr(cPtr, ch, n))) { + UNGET(state, ch); + break; + } + if (state->assign) { + *cArg++ = ch; + } + } + if (state->assign) { + *cArg = '\0'; + state->converted = PR_TRUE; + } + cPtr = closeBracket; + } + break; + default: + return NULL; + } + return cPtr; +} + +static PRInt32 +DoScanf(ScanfState *state, const char *fmt) +{ + PRInt32 nConverted = 0; + const char *cPtr; + int ch; + + state->nChar = 0; + cPtr = fmt; + while (1) { + if (isspace(*cPtr)) { + /* white space: skip */ + do { + cPtr++; + } while (isspace(*cPtr)); + do { + ch = GET(state); + } while (isspace(ch)); + UNGET(state, ch); + } else if (*cPtr == '%') { + /* format spec: convert */ + cPtr++; + state->assign = PR_TRUE; + if (*cPtr == '*') { + cPtr++; + state->assign = PR_FALSE; + } + for (state->width = 0; isdigit(*cPtr); cPtr++) { + state->width = state->width * 10 + *cPtr - '0'; + } + state->sizeSpec = _PR_size_none; + if (*cPtr == 'h') { + cPtr++; + state->sizeSpec = _PR_size_h; + } else if (*cPtr == 'l') { + cPtr++; + if (*cPtr == 'l') { + cPtr++; + state->sizeSpec = _PR_size_ll; + } else { + state->sizeSpec = _PR_size_l; + } + } else if (*cPtr == 'L') { + cPtr++; + state->sizeSpec = _PR_size_L; + } + cPtr = Convert(state, cPtr); + if (cPtr == NULL) { + return (nConverted > 0 ? nConverted : EOF); + } + if (state->converted) { + nConverted++; + } + cPtr++; + } else { + /* others: must match */ + if (*cPtr == '\0') { + return nConverted; + } + ch = GET(state); + if (ch != *cPtr) { + UNGET(state, ch); + return nConverted; + } + cPtr++; + } + } +} + +static int +StringGetChar(void *stream) +{ + char *cPtr = *((char **) stream); + + if (*cPtr == '\0') { + return EOF; + } else { + *((char **) stream) = cPtr + 1; + return (unsigned char) *cPtr; + } +} + +static void +StringUngetChar(void *stream, int ch) +{ + char *cPtr = *((char **) stream); + + if (ch != EOF) { + *((char **) stream) = cPtr - 1; + } +} + +PR_IMPLEMENT(PRInt32) +PR_sscanf(const char *buf, const char *fmt, ...) +{ + PRInt32 rv; + ScanfState state; + + state.get = &StringGetChar; + state.unget = &StringUngetChar; + state.stream = (void *) &buf; + va_start(state.ap, fmt); + rv = DoScanf(&state, fmt); + va_end(state.ap); + return rv; +} diff -Nru nspr-4.9.5/nspr/pr/src/io/prsocket.c nspr-4.10.7/nspr/pr/src/io/prsocket.c --- nspr-4.9.5/nspr/pr/src/io/prsocket.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prsocket.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1794 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +/************************************************************************/ + +/* These two functions are only used in assertions. */ +#if defined(DEBUG) + +PRBool IsValidNetAddr(const PRNetAddr *addr) +{ + if ((addr != NULL) +#if defined(XP_UNIX) || defined(XP_OS2) + && (addr->raw.family != PR_AF_LOCAL) +#endif + && (addr->raw.family != PR_AF_INET6) + && (addr->raw.family != PR_AF_INET)) { + return PR_FALSE; + } + return PR_TRUE; +} + +static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len) +{ + /* + * The definition of the length of a Unix domain socket address + * is not uniform, so we don't check it. + */ + if ((addr != NULL) +#if defined(XP_UNIX) || defined(XP_OS2) + && (addr->raw.family != AF_UNIX) +#endif + && (PR_NETADDR_SIZE(addr) != addr_len)) { +#if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1 + /* + * In glibc 2.1, struct sockaddr_in6 is 24 bytes. In glibc 2.2 + * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id + * field and is 28 bytes. It is possible for socket functions + * to return an addr_len greater than sizeof(struct sockaddr_in6). + * We need to allow that. (Bugzilla bug #77264) + */ + if ((PR_AF_INET6 == addr->raw.family) + && (sizeof(addr->ipv6) == addr_len)) { + return PR_TRUE; + } +#endif + /* + * The accept(), getsockname(), etc. calls on some platforms + * do not set the actual socket address length on return. + * In this case, we verifiy addr_len is still the value we + * passed in (i.e., sizeof(PRNetAddr)). + */ +#if defined(QNX) + if (sizeof(PRNetAddr) == addr_len) { + return PR_TRUE; + } +#endif + return PR_FALSE; + } + return PR_TRUE; +} + +#endif /* DEBUG */ + +static PRInt32 PR_CALLBACK SocketWritev(PRFileDesc *fd, const PRIOVec *iov, +PRInt32 iov_size, PRIntervalTime timeout) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + int w = 0; + const PRIOVec *tmp_iov; +#define LOCAL_MAXIOV 8 + PRIOVec local_iov[LOCAL_MAXIOV]; + PRIOVec *iov_copy = NULL; + int tmp_out; + int index, iov_cnt; + int count=0, sz = 0; /* 'count' is the return value. */ + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + + /* + * Assume the first writev will succeed. Copy iov's only on + * failure. + */ + tmp_iov = iov; + for (index = 0; index < iov_size; index++) + sz += iov[index].iov_len; + + iov_cnt = iov_size; + + while (sz > 0) { + + w = _PR_MD_WRITEV(fd, tmp_iov, iov_cnt, timeout); + if (w < 0) { + count = -1; + break; + } + count += w; + if (fd->secret->nonblocking) { + break; + } + sz -= w; + + if (sz > 0) { + /* find the next unwritten vector */ + for ( index = 0, tmp_out = count; + tmp_out >= iov[index].iov_len; + tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */ + + if (tmp_iov == iov) { + /* + * The first writev failed so we + * must copy iov's around. + * Avoid calloc/free if there + * are few enough iov's. + */ + if (iov_size - index <= LOCAL_MAXIOV) + iov_copy = local_iov; + else if ((iov_copy = (PRIOVec *) PR_CALLOC((iov_size - index) * + sizeof *iov_copy)) == NULL) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + tmp_iov = iov_copy; + } + + PR_ASSERT(tmp_iov == iov_copy); + + /* fill in the first partial read */ + iov_copy[0].iov_base = &(((char *)iov[index].iov_base)[tmp_out]); + iov_copy[0].iov_len = iov[index].iov_len - tmp_out; + index++; + + /* copy the remaining vectors */ + for (iov_cnt=1; indexsecret->af = AF_INET; +#endif + } else + _PR_MD_CLOSE_SOCKET(osfd); + return(fd); +} + +PR_IMPLEMENT(PRFileDesc *) PR_ImportUDPSocket(PROsfd osfd) +{ +PRFileDesc *fd; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods()); + if (fd != NULL) { + _PR_MD_MAKE_NONBLOCK(fd); + _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE); + } else + _PR_MD_CLOSE_SOCKET(osfd); + return(fd); +} + + +static const PRIOMethods* PR_GetSocketPollFdMethods(void); + +PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PROsfd osfd) +{ + PRFileDesc *fd; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + fd = _PR_Getfd(); + + if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + else + { + fd->secret->md.osfd = osfd; + fd->secret->inheritable = _PR_TRI_FALSE; + fd->secret->state = _PR_FILEDESC_OPEN; + fd->methods = PR_GetSocketPollFdMethods(); + } + + return fd; +} /* PR_CreateSocketPollFD */ + +PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd) +{ + if (NULL == fd) + { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + return PR_FAILURE; + } + fd->secret->state = _PR_FILEDESC_CLOSED; + _PR_Putfd(fd); + return PR_SUCCESS; +} /* PR_DestroySocketPollFd */ + +static PRStatus PR_CALLBACK SocketConnect( + PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) +{ + PRInt32 rv; /* Return value of _PR_MD_CONNECT */ + const PRNetAddr *addrp = addr; +#if defined(_PR_INET6) + PRNetAddr addrCopy; +#endif + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return PR_FAILURE; + } +#if defined(_PR_INET6) + if (addr->raw.family == PR_AF_INET6) { + addrCopy = *addr; + addrCopy.raw.family = AF_INET6; + addrp = &addrCopy; + } +#endif + + rv = _PR_MD_CONNECT(fd, addrp, PR_NETADDR_SIZE(addr), timeout); + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("connect -> %d", rv)); + if (rv == 0) + return PR_SUCCESS; + else + return PR_FAILURE; +} + +static PRStatus PR_CALLBACK SocketConnectContinue( + PRFileDesc *fd, PRInt16 out_flags) +{ + PROsfd osfd; + int err; + + if (out_flags & PR_POLL_NVAL) { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + return PR_FAILURE; + } + if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) { + PR_ASSERT(out_flags == 0); + PR_SetError(PR_IN_PROGRESS_ERROR, 0); + return PR_FAILURE; + } + + osfd = fd->secret->md.osfd; + +#if defined(XP_UNIX) + + err = _MD_unix_get_nonblocking_connect_error(osfd); + if (err != 0) { + _PR_MD_MAP_CONNECT_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; + +#elif defined(WIN32) || defined(WIN16) + + if (out_flags & PR_POLL_EXCEPT) { + int len = sizeof(err); + if (getsockopt(osfd, (int)SOL_SOCKET, SO_ERROR, (char *) &err, &len) + == SOCKET_ERROR) { + _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); + return PR_FAILURE; + } + if (err != 0) { + _PR_MD_MAP_CONNECT_ERROR(err); + } else { + PR_SetError(PR_UNKNOWN_ERROR, 0); + } + return PR_FAILURE; + } + + PR_ASSERT(out_flags & PR_POLL_WRITE); + return PR_SUCCESS; + +#elif defined(XP_OS2) + + err = _MD_os2_get_nonblocking_connect_error(osfd); + if (err != 0) { + _PR_MD_MAP_CONNECT_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; + +#elif defined(XP_BEOS) + +#ifdef BONE_VERSION /* bug 122364 */ + /* temporary workaround until getsockopt(SO_ERROR) works in BONE */ + if (out_flags & PR_POLL_EXCEPT) { + PR_SetError(PR_CONNECT_REFUSED_ERROR, 0); + return PR_FAILURE; + } + PR_ASSERT(out_flags & PR_POLL_WRITE); + return PR_SUCCESS; +#else + err = _MD_beos_get_nonblocking_connect_error(fd); + if( err != 0 ) { + _PR_MD_MAP_CONNECT_ERROR(err); + return PR_FAILURE; + } + else + return PR_SUCCESS; +#endif /* BONE_VERSION */ + +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +#endif +} + +PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd) +{ + /* Find the NSPR layer and invoke its connectcontinue method */ + PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + + if (NULL == bottom) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + return SocketConnectContinue(bottom, pd->out_flags); +} + +static PRFileDesc* PR_CALLBACK SocketAccept(PRFileDesc *fd, PRNetAddr *addr, +PRIntervalTime timeout) +{ + PROsfd osfd; + PRFileDesc *fd2; + PRUint32 al; + PRThread *me = _PR_MD_CURRENT_THREAD(); +#ifdef WINNT + PRNetAddr addrCopy; +#endif + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return 0; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return 0; + } + +#ifdef WINNT + if (addr == NULL) { + addr = &addrCopy; + } +#endif + al = sizeof(PRNetAddr); + osfd = _PR_MD_ACCEPT(fd, addr, &al, timeout); + if (osfd == -1) + return 0; + + fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods()); + if (!fd2) { + _PR_MD_CLOSE_SOCKET(osfd); + return NULL; + } + + fd2->secret->nonblocking = fd->secret->nonblocking; + fd2->secret->inheritable = fd->secret->inheritable; +#ifdef WINNT + if (!fd2->secret->nonblocking && fd2->secret->inheritable != _PR_TRI_TRUE) { + /* + * The new socket has been associated with an I/O + * completion port. There is no going back. + */ + fd2->secret->md.io_model_committed = PR_TRUE; + } + PR_ASSERT(al == PR_NETADDR_SIZE(addr)); + fd2->secret->md.accepted_socket = PR_TRUE; + memcpy(&fd2->secret->md.peer_addr, addr, al); +#endif + + /* + * On some platforms, the new socket created by accept() + * inherits the nonblocking (or overlapped io) attribute + * of the listening socket. As an optimization, these + * platforms can skip the following _PR_MD_MAKE_NONBLOCK + * call. + */ +#if !defined(SOLARIS) && !defined(IRIX) && !defined(WINNT) + _PR_MD_MAKE_NONBLOCK(fd2); +#endif + +#ifdef _PR_INET6 + if (addr && (AF_INET6 == addr->raw.family)) + addr->raw.family = PR_AF_INET6; +#endif + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE); + + return fd2; +} + +#ifdef WINNT +PR_IMPLEMENT(PRFileDesc*) PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr, +PRIntervalTime timeout) +{ + PROsfd osfd; + PRFileDesc *fd2; + PRIntn al; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRNetAddr addrCopy; + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return 0; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return 0; + } + + if (addr == NULL) { + addr = &addrCopy; + } + al = PR_NETADDR_SIZE(addr); + osfd = _PR_MD_FAST_ACCEPT(fd, addr, &al, timeout, PR_TRUE, NULL, NULL); + if (osfd == -1) { + return 0; + } + + fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods()); + if (!fd2) { + _PR_MD_CLOSE_SOCKET(osfd); + } else { + fd2->secret->nonblocking = fd->secret->nonblocking; + fd2->secret->md.io_model_committed = PR_TRUE; + PR_ASSERT(al == PR_NETADDR_SIZE(addr)); + fd2->secret->md.accepted_socket = PR_TRUE; + memcpy(&fd2->secret->md.peer_addr, addr, al); +#ifdef _PR_INET6 + if (AF_INET6 == addr->raw.family) + addr->raw.family = PR_AF_INET6; +#endif +#ifdef _PR_NEED_SECRET_AF + fd2->secret->af = fd->secret->af; +#endif + } + return fd2; +} +#endif /* WINNT */ + + +static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr) +{ + PRInt32 result; + const PRNetAddr *addrp = addr; +#if defined(_PR_INET6) + PRNetAddr addrCopy; +#endif + + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + +#ifdef XP_UNIX + if (addr->raw.family == AF_UNIX) { + /* Disallow relative pathnames */ + if (addr->local.path[0] != '/') { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + } +#endif /* XP_UNIX */ + +#if defined(_PR_INET6) + if (addr->raw.family == PR_AF_INET6) { + addrCopy = *addr; + addrCopy.raw.family = AF_INET6; + addrp = &addrCopy; + } +#endif + result = _PR_MD_BIND(fd, addrp, PR_NETADDR_SIZE(addr)); + if (result < 0) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +static PRStatus PR_CALLBACK SocketListen(PRFileDesc *fd, PRIntn backlog) +{ + PRInt32 result; + + result = _PR_MD_LISTEN(fd, backlog); + if (result < 0) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +static PRStatus PR_CALLBACK SocketShutdown(PRFileDesc *fd, PRIntn how) +{ + PRInt32 result; + + result = _PR_MD_SHUTDOWN(fd, how); + if (result < 0) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +static PRInt32 PR_CALLBACK SocketRecv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, +PRIntervalTime timeout) +{ + PRInt32 rv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if ((flags != 0) && (flags != PR_MSG_PEEK)) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + + PR_LOG(_pr_io_lm, PR_LOG_MAX, + ("recv: fd=%p osfd=%" PR_PRIdOSFD " buf=%p amount=%d flags=%d", + fd, fd->secret->md.osfd, buf, amount, flags)); + +#ifdef _PR_HAVE_PEEK_BUFFER + if (fd->secret->peekBytes != 0) { + rv = (amount < fd->secret->peekBytes) ? + amount : fd->secret->peekBytes; + memcpy(buf, fd->secret->peekBuffer, rv); + if (flags == 0) { + /* consume the bytes in the peek buffer */ + fd->secret->peekBytes -= rv; + if (fd->secret->peekBytes != 0) { + memmove(fd->secret->peekBuffer, + fd->secret->peekBuffer + rv, + fd->secret->peekBytes); + } + } + return rv; + } + + /* allocate peek buffer, if necessary */ + if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) { + PR_ASSERT(0 == fd->secret->peekBytes); + /* impose a max size on the peek buffer */ + if (amount > _PR_PEEK_BUFFER_MAX) { + amount = _PR_PEEK_BUFFER_MAX; + } + if (fd->secret->peekBufSize < amount) { + if (fd->secret->peekBuffer) { + PR_Free(fd->secret->peekBuffer); + } + fd->secret->peekBufSize = amount; + fd->secret->peekBuffer = PR_Malloc(amount); + if (NULL == fd->secret->peekBuffer) { + fd->secret->peekBufSize = 0; + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + } + } +#endif + + rv = _PR_MD_RECV(fd, buf, amount, flags, timeout); + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv -> %d, error = %d, os error = %d", + rv, PR_GetError(), PR_GetOSError())); + +#ifdef _PR_HAVE_PEEK_BUFFER + if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) { + if (rv > 0) { + memcpy(fd->secret->peekBuffer, buf, rv); + fd->secret->peekBytes = rv; + } + } +#endif + + return rv; +} + +static PRInt32 PR_CALLBACK SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount) +{ + return SocketRecv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); +} + +static PRInt32 PR_CALLBACK SocketSend(PRFileDesc *fd, const void *buf, PRInt32 amount, +PRIntn flags, PRIntervalTime timeout) +{ + PRInt32 temp, count; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + + count = 0; + while (amount > 0) { + PR_LOG(_pr_io_lm, PR_LOG_MAX, + ("send: fd=%p osfd=%" PR_PRIdOSFD " buf=%p amount=%d", + fd, fd->secret->md.osfd, buf, amount)); + temp = _PR_MD_SEND(fd, buf, amount, flags, timeout); + if (temp < 0) { + count = -1; + break; + } + + count += temp; + if (fd->secret->nonblocking) { + break; + } + buf = (const void*) ((const char*)buf + temp); + + amount -= temp; + } + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("send -> %d", count)); + return count; +} + +static PRInt32 PR_CALLBACK SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount) +{ + return SocketSend(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); +} + +static PRStatus PR_CALLBACK SocketClose(PRFileDesc *fd) +{ + if (!fd || !fd->secret + || (fd->secret->state != _PR_FILEDESC_OPEN + && fd->secret->state != _PR_FILEDESC_CLOSED)) { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + return PR_FAILURE; + } + + if (fd->secret->state == _PR_FILEDESC_OPEN) { + if (_PR_MD_CLOSE_SOCKET(fd->secret->md.osfd) < 0) { + return PR_FAILURE; + } + fd->secret->state = _PR_FILEDESC_CLOSED; + } + +#ifdef _PR_HAVE_PEEK_BUFFER + if (fd->secret->peekBuffer) { + PR_ASSERT(fd->secret->peekBufSize > 0); + PR_DELETE(fd->secret->peekBuffer); + fd->secret->peekBufSize = 0; + fd->secret->peekBytes = 0; + } +#endif + + PR_FreeFileDesc(fd); + return PR_SUCCESS; +} + +static PRInt32 PR_CALLBACK SocketAvailable(PRFileDesc *fd) +{ + PRInt32 rv; +#ifdef _PR_HAVE_PEEK_BUFFER + if (fd->secret->peekBytes != 0) { + return fd->secret->peekBytes; + } +#endif + rv = _PR_MD_SOCKETAVAILABLE(fd); + return rv; +} + +static PRInt64 PR_CALLBACK SocketAvailable64(PRFileDesc *fd) +{ + PRInt64 rv; +#ifdef _PR_HAVE_PEEK_BUFFER + if (fd->secret->peekBytes != 0) { + LL_I2L(rv, fd->secret->peekBytes); + return rv; + } +#endif + LL_I2L(rv, _PR_MD_SOCKETAVAILABLE(fd)); + return rv; +} + +static PRStatus PR_CALLBACK SocketSync(PRFileDesc *fd) +{ + return PR_SUCCESS; +} + +static PRInt32 PR_CALLBACK SocketSendTo( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout) +{ + PRInt32 temp, count; + const PRNetAddr *addrp = addr; +#if defined(_PR_INET6) + PRNetAddr addrCopy; +#endif + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); +#if defined(_PR_INET6) + if (addr->raw.family == PR_AF_INET6) { + addrCopy = *addr; + addrCopy.raw.family = AF_INET6; + addrp = &addrCopy; + } +#endif + + count = 0; + while (amount > 0) { + temp = _PR_MD_SENDTO(fd, buf, amount, flags, + addrp, PR_NETADDR_SIZE(addr), timeout); + if (temp < 0) { + count = -1; + break; + } + count += temp; + if (fd->secret->nonblocking) { + break; + } + buf = (const void*) ((const char*)buf + temp); + amount -= temp; + } + return count; +} + +static PRInt32 PR_CALLBACK SocketRecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, +PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) +{ + PRInt32 rv; + PRUint32 al; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + + al = sizeof(PRNetAddr); + rv = _PR_MD_RECVFROM(fd, buf, amount, flags, addr, &al, timeout); +#ifdef _PR_INET6 + if (addr && (AF_INET6 == addr->raw.family)) + addr->raw.family = PR_AF_INET6; +#endif + return rv; +} + +static PRInt32 PR_CALLBACK SocketAcceptRead(PRFileDesc *sd, PRFileDesc **nd, +PRNetAddr **raddr, void *buf, PRInt32 amount, +PRIntervalTime timeout) +{ + PRInt32 rv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + /* The socket must be in blocking mode. */ + if (sd->secret->nonblocking) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + *nd = NULL; + +#if defined(WINNT) + { + PROsfd newSock; + PRNetAddr *raddrCopy; + + if (raddr == NULL) { + raddr = &raddrCopy; + } + rv = _PR_MD_ACCEPT_READ(sd, &newSock, raddr, buf, amount, timeout); + if (rv < 0) { + rv = -1; + } else { + /* Successfully accepted and read; create the new PRFileDesc */ + *nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods()); + if (*nd == 0) { + _PR_MD_CLOSE_SOCKET(newSock); + /* PR_AllocFileDesc() has invoked PR_SetError(). */ + rv = -1; + } else { + (*nd)->secret->md.io_model_committed = PR_TRUE; + (*nd)->secret->md.accepted_socket = PR_TRUE; + memcpy(&(*nd)->secret->md.peer_addr, *raddr, + PR_NETADDR_SIZE(*raddr)); +#ifdef _PR_INET6 + if (AF_INET6 == *raddr->raw.family) + *raddr->raw.family = PR_AF_INET6; +#endif + } + } + } +#else + rv = PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout); +#endif + return rv; +} + +#ifdef WINNT +PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, +PRNetAddr **raddr, void *buf, PRInt32 amount, +PRIntervalTime timeout) +{ + PRInt32 rv; + PROsfd newSock; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRNetAddr *raddrCopy; + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + *nd = NULL; + + if (raddr == NULL) { + raddr = &raddrCopy; + } + rv = _PR_MD_FAST_ACCEPT_READ(sd, &newSock, raddr, buf, amount, + timeout, PR_TRUE, NULL, NULL); + if (rv < 0) { + rv = -1; + } else { + /* Successfully accepted and read; create the new PRFileDesc */ + *nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods()); + if (*nd == 0) { + _PR_MD_CLOSE_SOCKET(newSock); + /* PR_AllocFileDesc() has invoked PR_SetError(). */ + rv = -1; + } else { + (*nd)->secret->md.io_model_committed = PR_TRUE; + (*nd)->secret->md.accepted_socket = PR_TRUE; + memcpy(&(*nd)->secret->md.peer_addr, *raddr, + PR_NETADDR_SIZE(*raddr)); +#ifdef _PR_INET6 + if (AF_INET6 == *raddr->raw.family) + *raddr->raw.family = PR_AF_INET6; +#endif +#ifdef _PR_NEED_SECRET_AF + (*nd)->secret->af = sd->secret->af; +#endif + } + } + return rv; +} + +PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback( +PRFileDesc *sd, PRFileDesc **nd, +PRNetAddr **raddr, void *buf, PRInt32 amount, +PRIntervalTime timeout, +_PR_AcceptTimeoutCallback callback, +void *callbackArg) +{ + PRInt32 rv; + PROsfd newSock; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRNetAddr *raddrCopy; + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + *nd = NULL; + + if (raddr == NULL) { + raddr = &raddrCopy; + } + rv = _PR_MD_FAST_ACCEPT_READ(sd, &newSock, raddr, buf, amount, + timeout, PR_TRUE, callback, callbackArg); + if (rv < 0) { + rv = -1; + } else { + /* Successfully accepted and read; create the new PRFileDesc */ + *nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods()); + if (*nd == 0) { + _PR_MD_CLOSE_SOCKET(newSock); + /* PR_AllocFileDesc() has invoked PR_SetError(). */ + rv = -1; + } else { + (*nd)->secret->md.io_model_committed = PR_TRUE; + (*nd)->secret->md.accepted_socket = PR_TRUE; + memcpy(&(*nd)->secret->md.peer_addr, *raddr, + PR_NETADDR_SIZE(*raddr)); +#ifdef _PR_INET6 + if (AF_INET6 == *raddr->raw.family) + *raddr->raw.family = PR_AF_INET6; +#endif +#ifdef _PR_NEED_SECRET_AF + (*nd)->secret->af = sd->secret->af; +#endif + } + } + return rv; +} +#endif /* WINNT */ + +#ifdef WINNT +PR_IMPLEMENT(void) +PR_NTFast_UpdateAcceptContext(PRFileDesc *socket, PRFileDesc *acceptSocket) +{ + _PR_MD_UPDATE_ACCEPT_CONTEXT( + socket->secret->md.osfd, acceptSocket->secret->md.osfd); +} +#endif /* WINNT */ + +static PRInt32 PR_CALLBACK SocketSendFile( + PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + PRInt32 rv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + /* The socket must be in blocking mode. */ + if (sd->secret->nonblocking) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } +#if defined(WINNT) + rv = _PR_MD_SENDFILE(sd, sfd, flags, timeout); + if ((rv >= 0) && (flags == PR_TRANSMITFILE_CLOSE_SOCKET)) { + /* + * This should be kept the same as SocketClose, except + * that _PR_MD_CLOSE_SOCKET(sd->secret->md.osfd) should + * not be called because the socket will be recycled. + */ + PR_FreeFileDesc(sd); + } +#else + rv = PR_EmulateSendFile(sd, sfd, flags, timeout); +#endif /* WINNT */ + + return rv; +} + +static PRInt32 PR_CALLBACK SocketTransmitFile(PRFileDesc *sd, PRFileDesc *fd, +const void *headers, PRInt32 hlen, PRTransmitFileFlags flags, +PRIntervalTime timeout) +{ + PRSendFileData sfd; + + sfd.fd = fd; + sfd.file_offset = 0; + sfd.file_nbytes = 0; + sfd.header = headers; + sfd.hlen = hlen; + sfd.trailer = NULL; + sfd.tlen = 0; + + return(SocketSendFile(sd, &sfd, flags, timeout)); +} + +static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr) +{ + PRInt32 result; + PRUint32 addrlen; + + addrlen = sizeof(PRNetAddr); + result = _PR_MD_GETSOCKNAME(fd, addr, &addrlen); + if (result < 0) { + return PR_FAILURE; + } +#ifdef _PR_INET6 + if (AF_INET6 == addr->raw.family) + addr->raw.family = PR_AF_INET6; +#endif + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE); + return PR_SUCCESS; +} + +static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr) +{ + PRInt32 result; + PRUint32 addrlen; + + addrlen = sizeof(PRNetAddr); + result = _PR_MD_GETPEERNAME(fd, addr, &addrlen); + if (result < 0) { + return PR_FAILURE; + } +#ifdef _PR_INET6 + if (AF_INET6 == addr->raw.family) + addr->raw.family = PR_AF_INET6; +#endif + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE); + return PR_SUCCESS; +} + +static PRInt16 PR_CALLBACK SocketPoll( + PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) +{ + *out_flags = 0; + return in_flags; +} /* SocketPoll */ + +static PRIOMethods tcpMethods = { + PR_DESC_SOCKET_TCP, + SocketClose, + SocketRead, + SocketWrite, + SocketAvailable, + SocketAvailable64, + SocketSync, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + SocketWritev, + SocketConnect, + SocketAccept, + SocketBind, + SocketListen, + SocketShutdown, + SocketRecv, + SocketSend, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + SocketPoll, + SocketAcceptRead, + SocketTransmitFile, + SocketGetName, + SocketGetPeerName, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + _PR_SocketGetSocketOption, + _PR_SocketSetSocketOption, + SocketSendFile, + SocketConnectContinue, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +static PRIOMethods udpMethods = { + PR_DESC_SOCKET_UDP, + SocketClose, + SocketRead, + SocketWrite, + SocketAvailable, + SocketAvailable64, + SocketSync, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + SocketWritev, + SocketConnect, + (PRAcceptFN)_PR_InvalidDesc, + SocketBind, + SocketListen, + SocketShutdown, + SocketRecv, + SocketSend, + SocketRecvFrom, + SocketSendTo, + SocketPoll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + SocketGetName, + SocketGetPeerName, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + _PR_SocketGetSocketOption, + _PR_SocketSetSocketOption, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + + +static PRIOMethods socketpollfdMethods = { + (PRDescType) 0, + (PRCloseFN)_PR_InvalidStatus, + (PRReadFN)_PR_InvalidInt, + (PRWriteFN)_PR_InvalidInt, + (PRAvailableFN)_PR_InvalidInt, + (PRAvailable64FN)_PR_InvalidInt64, + (PRFsyncFN)_PR_InvalidStatus, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + (PRWritevFN)_PR_InvalidInt, + (PRConnectFN)_PR_InvalidStatus, + (PRAcceptFN)_PR_InvalidDesc, + (PRBindFN)_PR_InvalidStatus, + (PRListenFN)_PR_InvalidStatus, + (PRShutdownFN)_PR_InvalidStatus, + (PRRecvFN)_PR_InvalidInt, + (PRSendFN)_PR_InvalidInt, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + SocketPoll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + (PRGetsocknameFN)_PR_InvalidStatus, + (PRGetpeernameFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRGetsocketoptionFN)_PR_InvalidStatus, + (PRSetsocketoptionFN)_PR_InvalidStatus, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods() +{ + return &tcpMethods; +} + +PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods() +{ + return &udpMethods; +} + +static const PRIOMethods* PR_GetSocketPollFdMethods() +{ + return &socketpollfdMethods; +} /* PR_GetSocketPollFdMethods */ + +#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE) +PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd); + +#if defined(_PR_INET6_PROBE) + +extern PRBool _pr_ipv6_is_present(void); + +PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket() +{ + PROsfd osfd; + + osfd = _PR_MD_SOCKET(AF_INET6, SOCK_STREAM, 0); + if (osfd != -1) { + _PR_MD_CLOSE_SOCKET(osfd); + return PR_TRUE; + } + return PR_FALSE; +} +#endif /* _PR_INET6_PROBE */ + +#endif + +PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto) +{ + PROsfd osfd; + PRFileDesc *fd; + PRInt32 tmp_domain = domain; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + if (PR_AF_INET != domain + && PR_AF_INET6 != domain +#if defined(XP_UNIX) || defined(XP_OS2) + && PR_AF_LOCAL != domain +#endif + ) { + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); + return NULL; + } + +#if defined(_PR_INET6_PROBE) + if (PR_AF_INET6 == domain) + domain = _pr_ipv6_is_present() ? AF_INET6 : AF_INET; +#elif defined(_PR_INET6) + if (PR_AF_INET6 == domain) + domain = AF_INET6; +#else + if (PR_AF_INET6 == domain) + domain = AF_INET; +#endif /* _PR_INET6 */ + osfd = _PR_MD_SOCKET(domain, type, proto); + if (osfd == -1) { + return 0; + } + if (type == SOCK_STREAM) + fd = PR_AllocFileDesc(osfd, PR_GetTCPMethods()); + else + fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods()); + /* + * Make the sockets non-blocking + */ + if (fd != NULL) { + _PR_MD_MAKE_NONBLOCK(fd); + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); +#ifdef _PR_NEED_SECRET_AF + fd->secret->af = domain; +#endif +#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6) + /* + * For platforms with no support for IPv6 + * create layered socket for IPv4-mapped IPv6 addresses + */ + if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) { + if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) { + PR_Close(fd); + fd = NULL; + } + } +#endif + } else + _PR_MD_CLOSE_SOCKET(osfd); + + return fd; +} + +PR_IMPLEMENT(PRFileDesc *) PR_NewTCPSocket(void) +{ + PRInt32 domain = AF_INET; + + return PR_Socket(domain, SOCK_STREAM, 0); +} + +PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void) +{ + PRInt32 domain = AF_INET; + + return PR_Socket(domain, SOCK_DGRAM, 0); +} + +PR_IMPLEMENT(PRFileDesc *) PR_OpenTCPSocket(PRIntn af) +{ + return PR_Socket(af, SOCK_STREAM, 0); +} + +PR_IMPLEMENT(PRFileDesc*) PR_OpenUDPSocket(PRIntn af) +{ + return PR_Socket(af, SOCK_DGRAM, 0); +} + +PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[]) +{ +#ifdef XP_UNIX + PRInt32 rv, osfd[2]; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + rv = _PR_MD_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, osfd); + if (rv == -1) { + return PR_FAILURE; + } + + f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods()); + if (!f[0]) { + _PR_MD_CLOSE_SOCKET(osfd[0]); + _PR_MD_CLOSE_SOCKET(osfd[1]); + /* PR_AllocFileDesc() has invoked PR_SetError(). */ + return PR_FAILURE; + } + f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods()); + if (!f[1]) { + PR_Close(f[0]); + _PR_MD_CLOSE_SOCKET(osfd[1]); + /* PR_AllocFileDesc() has invoked PR_SetError(). */ + return PR_FAILURE; + } + _PR_MD_MAKE_NONBLOCK(f[0]); + _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE); + _PR_MD_MAKE_NONBLOCK(f[1]); + _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE); + return PR_SUCCESS; +#elif defined(WINNT) + /* + * A socket pair is often used for interprocess communication, + * so we need to make sure neither socket is associated with + * the I/O completion port; otherwise it can't be used by a + * child process. + * + * The default implementation below cannot be used for NT + * because PR_Accept would have associated the I/O completion + * port with the listening and accepted sockets. + */ + SOCKET listenSock; + SOCKET osfd[2]; + struct sockaddr_in selfAddr, peerAddr; + int addrLen; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + osfd[0] = osfd[1] = INVALID_SOCKET; + listenSock = socket(AF_INET, SOCK_STREAM, 0); + if (listenSock == INVALID_SOCKET) { + goto failed; + } + selfAddr.sin_family = AF_INET; + selfAddr.sin_port = 0; + selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* BugZilla: 35408 */ + addrLen = sizeof(selfAddr); + if (bind(listenSock, (struct sockaddr *) &selfAddr, + addrLen) == SOCKET_ERROR) { + goto failed; + } + if (getsockname(listenSock, (struct sockaddr *) &selfAddr, + &addrLen) == SOCKET_ERROR) { + goto failed; + } + if (listen(listenSock, 5) == SOCKET_ERROR) { + goto failed; + } + osfd[0] = socket(AF_INET, SOCK_STREAM, 0); + if (osfd[0] == INVALID_SOCKET) { + goto failed; + } + selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + /* + * Only a thread is used to do the connect and accept. + * I am relying on the fact that connect returns + * successfully as soon as the connect request is put + * into the listen queue (but before accept is called). + * This is the behavior of the BSD socket code. If + * connect does not return until accept is called, we + * will need to create another thread to call connect. + */ + if (connect(osfd[0], (struct sockaddr *) &selfAddr, + addrLen) == SOCKET_ERROR) { + goto failed; + } + /* + * A malicious local process may connect to the listening + * socket, so we need to verify that the accepted connection + * is made from our own socket osfd[0]. + */ + if (getsockname(osfd[0], (struct sockaddr *) &selfAddr, + &addrLen) == SOCKET_ERROR) { + goto failed; + } + osfd[1] = accept(listenSock, (struct sockaddr *) &peerAddr, &addrLen); + if (osfd[1] == INVALID_SOCKET) { + goto failed; + } + if (peerAddr.sin_port != selfAddr.sin_port) { + /* the connection we accepted is not from osfd[0] */ + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + goto failed; + } + closesocket(listenSock); + + f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods()); + if (!f[0]) { + closesocket(osfd[0]); + closesocket(osfd[1]); + /* PR_AllocFileDesc() has invoked PR_SetError(). */ + return PR_FAILURE; + } + f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods()); + if (!f[1]) { + PR_Close(f[0]); + closesocket(osfd[1]); + /* PR_AllocFileDesc() has invoked PR_SetError(). */ + return PR_FAILURE; + } + _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE); + _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE); + return PR_SUCCESS; + +failed: + if (listenSock != INVALID_SOCKET) { + closesocket(listenSock); + } + if (osfd[0] != INVALID_SOCKET) { + closesocket(osfd[0]); + } + if (osfd[1] != INVALID_SOCKET) { + closesocket(osfd[1]); + } + return PR_FAILURE; +#else /* not Unix or NT */ + /* + * default implementation + */ + PRFileDesc *listenSock; + PRNetAddr selfAddr, peerAddr; + PRUint16 port; + + f[0] = f[1] = NULL; + listenSock = PR_NewTCPSocket(); + if (listenSock == NULL) { + goto failed; + } + PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */ + if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) { + goto failed; + } + if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) { + goto failed; + } + port = ntohs(selfAddr.inet.port); + if (PR_Listen(listenSock, 5) == PR_FAILURE) { + goto failed; + } + f[0] = PR_NewTCPSocket(); + if (f[0] == NULL) { + goto failed; + } +#ifdef _PR_CONNECT_DOES_NOT_BIND + /* + * If connect does not implicitly bind the socket (e.g., on + * BeOS), we have to bind the socket so that we can get its + * port with getsockname later. + */ + PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); + if (PR_Bind(f[0], &selfAddr) == PR_FAILURE) { + goto failed; + } +#endif + PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr); + + /* + * Only a thread is used to do the connect and accept. + * I am relying on the fact that PR_Connect returns + * successfully as soon as the connect request is put + * into the listen queue (but before PR_Accept is called). + * This is the behavior of the BSD socket code. If + * connect does not return until accept is called, we + * will need to create another thread to call connect. + */ + if (PR_Connect(f[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT) + == PR_FAILURE) { + goto failed; + } + /* + * A malicious local process may connect to the listening + * socket, so we need to verify that the accepted connection + * is made from our own socket f[0]. + */ + if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) { + goto failed; + } + f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT); + if (f[1] == NULL) { + goto failed; + } + if (peerAddr.inet.port != selfAddr.inet.port) { + /* the connection we accepted is not from f[0] */ + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + goto failed; + } + PR_Close(listenSock); + return PR_SUCCESS; + +failed: + if (listenSock) { + PR_Close(listenSock); + } + if (f[0]) { + PR_Close(f[0]); + } + if (f[1]) { + PR_Close(f[1]); + } + return PR_FAILURE; +#endif +} + +PR_IMPLEMENT(PROsfd) +PR_FileDesc2NativeHandle(PRFileDesc *fd) +{ + if (fd) { + fd = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER); + } + if (!fd) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + return fd->secret->md.osfd; +} + +PR_IMPLEMENT(void) +PR_ChangeFileDescNativeHandle(PRFileDesc *fd, PROsfd handle) +{ + if (fd) + fd->secret->md.osfd = handle; +} + +/* +** Select compatibility +** +*/ + +PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set) +{ + memset(set, 0, sizeof(PR_fd_set)); +} + +PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set) +{ + PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC ); + + set->harray[set->hsize++] = fh; +} + +PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set) +{ + PRUint32 index, index2; + + for (index = 0; indexhsize; index++) + if (set->harray[index] == fh) { + for (index2=index; index2 < (set->hsize-1); index2++) { + set->harray[index2] = set->harray[index2+1]; + } + set->hsize--; + break; + } +} + +PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set) +{ + PRUint32 index; + for (index = 0; indexhsize; index++) + if (set->harray[index] == fh) { + return 1; + } + return 0; +} + +PR_IMPLEMENT(void) PR_FD_NSET(PROsfd fd, PR_fd_set *set) +{ + PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC ); + + set->narray[set->nsize++] = fd; +} + +PR_IMPLEMENT(void) PR_FD_NCLR(PROsfd fd, PR_fd_set *set) +{ + PRUint32 index, index2; + + for (index = 0; indexnsize; index++) + if (set->narray[index] == fd) { + for (index2=index; index2 < (set->nsize-1); index2++) { + set->narray[index2] = set->narray[index2+1]; + } + set->nsize--; + break; + } +} + +PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PROsfd fd, PR_fd_set *set) +{ + PRUint32 index; + for (index = 0; indexnsize; index++) + if (set->narray[index] == fd) { + return 1; + } + return 0; +} + + +#if !defined(NEED_SELECT) +#include "obsolete/probslet.h" + +#define PD_INCR 20 + +static PRPollDesc *_pr_setfd( + PR_fd_set *set, PRInt16 flags, PRPollDesc *polldesc) +{ + PRUintn fsidx, pdidx; + PRPollDesc *poll = polldesc; + + if (NULL == set) return poll; + + /* First set the pr file handle osfds */ + for (fsidx = 0; fsidx < set->hsize; fsidx++) + { + for (pdidx = 0; 1; pdidx++) + { + if ((PRFileDesc*)-1 == poll[pdidx].fd) + { + /* our vector is full - extend and condition it */ + poll = (PRPollDesc*)PR_Realloc( + poll, (pdidx + 1 + PD_INCR) * sizeof(PRPollDesc)); + if (NULL == poll) goto out_of_memory; + memset( + poll + pdidx * sizeof(PRPollDesc), + 0, PD_INCR * sizeof(PRPollDesc)); + poll[pdidx + PD_INCR].fd = (PRFileDesc*)-1; + } + if ((NULL == poll[pdidx].fd) + || (poll[pdidx].fd == set->harray[fsidx])) + { + /* PR_ASSERT(0 == (poll[pdidx].in_flags & flags)); */ + /* either empty or prevously defined */ + poll[pdidx].fd = set->harray[fsidx]; /* possibly redundant */ + poll[pdidx].in_flags |= flags; /* possibly redundant */ + break; + } + } + } + +#if 0 + /* Second set the native osfds */ + for (fsidx = 0; fsidx < set->nsize; fsidx++) + { + for (pdidx = 0; ((PRFileDesc*)-1 != poll[pdidx].fd); pdidx++) + { + if ((PRFileDesc*)-1 == poll[pdidx].fd) + { + /* our vector is full - extend and condition it */ + poll = PR_Realloc( + poll, (pdidx + PD_INCR) * sizeof(PRPollDesc)); + if (NULL == poll) goto out_of_memory; + memset( + poll + pdidx * sizeof(PRPollDesc), + 0, PD_INCR * sizeof(PRPollDesc)); + poll[(pdidx + PD_INCR)].fd = (PRFileDesc*)-1; + } + if ((NULL == poll[pdidx].fd) + || (poll[pdidx].fd == set->narray[fsidx])) + { + /* either empty or prevously defined */ + poll[pdidx].fd = set->narray[fsidx]; + PR_ASSERT(0 == (poll[pdidx].in_flags & flags)); + poll[pdidx].in_flags |= flags; + break; + } + } + } +#endif /* 0 */ + + return poll; + +out_of_memory: + if (NULL != polldesc) PR_DELETE(polldesc); + return NULL; +} /* _pr_setfd */ + +#endif /* !defined(NEED_SELECT) */ + +PR_IMPLEMENT(PRInt32) PR_Select( + PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, + PR_fd_set *pr_ex, PRIntervalTime timeout) +{ + +#if !defined(NEED_SELECT) + PRInt32 npds = 0; + /* + ** Find out how many fds are represented in the three lists. + ** Then allocate a polling descriptor for the logical union + ** (there can't be any overlapping) and call PR_Poll(). + */ + + PRPollDesc *copy, *poll; + + static PRBool warning = PR_TRUE; + if (warning) warning = _PR_Obsolete( "PR_Select()", "PR_Poll()"); + + /* try to get an initial guesss at how much space we need */ + npds = 0; + if ((NULL != pr_rd) && ((pr_rd->hsize + pr_rd->nsize - npds) > 0)) + npds = pr_rd->hsize + pr_rd->nsize; + if ((NULL != pr_wr) && ((pr_wr->hsize + pr_wr->nsize - npds) > 0)) + npds = pr_wr->hsize + pr_wr->nsize; + if ((NULL != pr_ex) && ((pr_ex->hsize + pr_ex->nsize - npds) > 0)) + npds = pr_ex->hsize + pr_ex->nsize; + + if (0 == npds) + { + PR_Sleep(timeout); + return 0; + } + + copy = poll = (PRPollDesc*)PR_Calloc(npds + PD_INCR, sizeof(PRPollDesc)); + if (NULL == poll) goto out_of_memory; + poll[npds + PD_INCR - 1].fd = (PRFileDesc*)-1; + + poll = _pr_setfd(pr_rd, PR_POLL_READ, poll); + if (NULL == poll) goto out_of_memory; + poll = _pr_setfd(pr_wr, PR_POLL_WRITE, poll); + if (NULL == poll) goto out_of_memory; + poll = _pr_setfd(pr_ex, PR_POLL_EXCEPT, poll); + if (NULL == poll) goto out_of_memory; + unused = 0; + while (NULL != poll[unused].fd && (PRFileDesc*)-1 != poll[unused].fd) + { + ++unused; + } + + PR_ASSERT(unused > 0); + npds = PR_Poll(poll, unused, timeout); + + if (npds > 0) + { + /* Copy the results back into the fd sets */ + if (NULL != pr_rd) pr_rd->nsize = pr_rd->hsize = 0; + if (NULL != pr_wr) pr_wr->nsize = pr_wr->hsize = 0; + if (NULL != pr_ex) pr_ex->nsize = pr_ex->hsize = 0; + for (copy = &poll[unused - 1]; copy >= poll; --copy) + { + if (copy->out_flags & PR_POLL_NVAL) + { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + npds = -1; + break; + } + if (copy->out_flags & PR_POLL_READ) + if (NULL != pr_rd) pr_rd->harray[pr_rd->hsize++] = copy->fd; + if (copy->out_flags & PR_POLL_WRITE) + if (NULL != pr_wr) pr_wr->harray[pr_wr->hsize++] = copy->fd; + if (copy->out_flags & PR_POLL_EXCEPT) + if (NULL != pr_ex) pr_ex->harray[pr_ex->hsize++] = copy->fd; + } + } + PR_DELETE(poll); + + return npds; +out_of_memory: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + +#endif /* !defined(NEED_SELECT) */ + +} diff -Nru nspr-4.9.5/nspr/pr/src/io/prstdio.c nspr-4.10.7/nspr/pr/src/io/prstdio.c --- nspr-4.9.5/nspr/pr/src/io/prstdio.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/io/prstdio.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +/* +** fprintf to a PRFileDesc +*/ +PR_IMPLEMENT(PRUint32) PR_fprintf(PRFileDesc* fd, const char *fmt, ...) +{ + va_list ap; + PRUint32 rv; + + va_start(ap, fmt); + rv = PR_vfprintf(fd, fmt, ap); + va_end(ap); + return rv; +} + +PR_IMPLEMENT(PRUint32) PR_vfprintf(PRFileDesc* fd, const char *fmt, va_list ap) +{ + /* XXX this could be better */ + PRUint32 rv, len; + char* msg = PR_vsmprintf(fmt, ap); + if (NULL == msg) { + return -1; + } + len = strlen(msg); +#ifdef XP_OS2 + /* + * OS/2 really needs a \r for every \n. + * In the future we should try to use scatter-gather instead of a + * succession of PR_Write. + */ + if (isatty(PR_FileDesc2NativeHandle(fd))) { + PRUint32 last = 0, idx; + PRInt32 tmp; + rv = 0; + for (idx = 0; idx < len+1; idx++) { + if ((idx - last > 0) && (('\n' == msg[idx]) || (idx == len))) { + tmp = PR_Write(fd, msg + last, idx - last); + if (tmp >= 0) { + rv += tmp; + } + last = idx; + } + /* + * if current character is \n, and + * previous character isn't \r, and + * next character isn't \r + */ + if (('\n' == msg[idx]) && + ((0 == idx) || ('\r' != msg[idx-1])) && + ('\r' != msg[idx+1])) { + /* add extra \r */ + tmp = PR_Write(fd, "\r", 1); + if (tmp >= 0) { + rv += tmp; + } + } + } + } else { + rv = PR_Write(fd, msg, len); + } +#else + rv = PR_Write(fd, msg, len); +#endif + PR_DELETE(msg); + return rv; +} diff -Nru nspr-4.9.5/nspr/pr/src/linking/.cvsignore nspr-4.10.7/nspr/pr/src/linking/.cvsignore --- nspr-4.9.5/nspr/pr/src/linking/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/linking/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/linking/Makefile.in nspr-4.10.7/nspr/pr/src/linking/Makefile.in --- nspr-4.9.5/nspr/pr/src/linking/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/linking/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,31 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CSRCS = \ + prlink.c \ + $(NULL) + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/linking/prlink.c nspr-4.10.7/nspr/pr/src/linking/prlink.c --- nspr-4.9.5/nspr/pr/src/linking/prlink.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/linking/prlink.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1608 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +#ifdef XP_BEOS +#include +#endif + +#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) +#include +#include +#endif + +#ifdef XP_UNIX +#ifdef USE_DLFCN +#include +/* Define these on systems that don't have them. */ +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif +#ifndef RTLD_LAZY +#define RTLD_LAZY RTLD_NOW +#endif +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif +#ifndef RTLD_LOCAL +#define RTLD_LOCAL 0 +#endif +#ifdef AIX +#include +#ifndef L_IGNOREUNLOAD /* AIX 4.3.3 does not have L_IGNOREUNLOAD. */ +#define L_IGNOREUNLOAD 0x10000000 +#endif +#endif +#ifdef OSF1 +#include +#include +#endif +#elif defined(USE_HPSHL) +#include +#elif defined(USE_MACH_DYLD) +#include +#endif +#endif /* XP_UNIX */ + +#define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY + +/* + * On these platforms, symbols have a leading '_'. + */ +#if (defined(DARWIN) && defined(USE_MACH_DYLD)) \ + || defined(XP_OS2) \ + || ((defined(OPENBSD) || defined(NETBSD)) && !defined(__ELF__)) +#define NEED_LEADING_UNDERSCORE +#endif + +#define PR_LD_PATHW 0x8000 /* for PR_LibSpec_PathnameU */ + +/************************************************************************/ + +struct PRLibrary { + char* name; /* Our own copy of the name string */ + PRLibrary* next; + int refCount; + const PRStaticLinkTable* staticTable; + +#ifdef XP_PC +#ifdef XP_OS2 + HMODULE dlh; +#else + HINSTANCE dlh; +#endif +#endif + +#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) + CFragConnectionID connection; + CFBundleRef bundle; + Ptr main; + CFMutableDictionaryRef wrappers; + const struct mach_header* image; +#endif + +#ifdef XP_UNIX +#if defined(USE_HPSHL) + shl_t dlh; +#elif defined(USE_MACH_DYLD) + NSModule dlh; +#else + void* dlh; +#endif +#endif + +#ifdef XP_BEOS + void* dlh; + void* stub_dlh; +#endif +}; + +static PRLibrary *pr_loadmap; +static PRLibrary *pr_exe_loadmap; +static PRMonitor *pr_linker_lock; +static char* _pr_currentLibPath = NULL; + +static PRLibrary *pr_LoadLibraryByPathname(const char *name, PRIntn flags); + +/************************************************************************/ + +#if !defined(USE_DLFCN) && !defined(HAVE_STRERROR) +#define ERR_STR_BUF_LENGTH 20 +#endif + +static void DLLErrorInternal(PRIntn oserr) +/* +** This whole function, and most of the code in this file, are run +** with a big hairy lock wrapped around it. Not the best of situations, +** but will eventually come up with the right answer. +*/ +{ + const char *error = NULL; +#ifdef USE_DLFCN + error = dlerror(); /* $$$ That'll be wrong some of the time - AOF */ +#elif defined(HAVE_STRERROR) + error = strerror(oserr); /* this should be okay */ +#else + char errStrBuf[ERR_STR_BUF_LENGTH]; + PR_snprintf(errStrBuf, sizeof(errStrBuf), "error %d", oserr); + error = errStrBuf; +#endif + if (NULL != error) + PR_SetErrorText(strlen(error), error); +} /* DLLErrorInternal */ + +void _PR_InitLinker(void) +{ + PRLibrary *lm = NULL; +#if defined(XP_UNIX) + void *h; +#endif + + if (!pr_linker_lock) { + pr_linker_lock = PR_NewNamedMonitor("linker-lock"); + } + PR_EnterMonitor(pr_linker_lock); + +#if defined(XP_PC) + lm = PR_NEWZAP(PRLibrary); + lm->name = strdup("Executable"); +#if defined(XP_OS2) + lm->dlh = NULLHANDLE; +#else + /* A module handle for the executable. */ + lm->dlh = GetModuleHandle(NULL); +#endif /* ! XP_OS2 */ + + lm->refCount = 1; + lm->staticTable = NULL; + pr_exe_loadmap = lm; + pr_loadmap = lm; + +#elif defined(XP_UNIX) +#ifdef HAVE_DLL +#if defined(USE_DLFCN) && !defined(NO_DLOPEN_NULL) + h = dlopen(0, RTLD_LAZY); + if (!h) { + char *error; + + DLLErrorInternal(_MD_ERRNO()); + error = (char*)PR_MALLOC(PR_GetErrorTextLength()); + (void) PR_GetErrorText(error); + fprintf(stderr, "failed to initialize shared libraries [%s]\n", + error); + PR_DELETE(error); + abort();/* XXX */ + } +#elif defined(USE_HPSHL) + h = NULL; + /* don't abort with this NULL */ +#elif defined(USE_MACH_DYLD) || defined(NO_DLOPEN_NULL) + h = NULL; /* XXXX toshok */ /* XXXX vlad */ +#else +#error no dll strategy +#endif /* USE_DLFCN */ + + lm = PR_NEWZAP(PRLibrary); + if (lm) { + lm->name = strdup("a.out"); + lm->refCount = 1; + lm->dlh = h; + lm->staticTable = NULL; + } + pr_exe_loadmap = lm; + pr_loadmap = lm; +#endif /* HAVE_DLL */ +#endif /* XP_UNIX */ + + if (lm) { + PR_LOG(_pr_linker_lm, PR_LOG_MIN, + ("Loaded library %s (init)", lm->name)); + } + + PR_ExitMonitor(pr_linker_lock); +} + +/* + * _PR_ShutdownLinker does not unload the dlls loaded by the application + * via calls to PR_LoadLibrary. Any dlls that still remain on the + * pr_loadmap list when NSPR shuts down are application programming errors. + * The only exception is pr_exe_loadmap, which was added to the list by + * NSPR and hence should be cleaned up by NSPR. + */ +void _PR_ShutdownLinker(void) +{ + /* FIXME: pr_exe_loadmap should be destroyed. */ + + PR_DestroyMonitor(pr_linker_lock); + pr_linker_lock = NULL; + + if (_pr_currentLibPath) { + free(_pr_currentLibPath); + _pr_currentLibPath = NULL; + } +} + +/******************************************************************************/ + +PR_IMPLEMENT(PRStatus) PR_SetLibraryPath(const char *path) +{ + PRStatus rv = PR_SUCCESS; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + PR_EnterMonitor(pr_linker_lock); + if (_pr_currentLibPath) { + free(_pr_currentLibPath); + } + if (path) { + _pr_currentLibPath = strdup(path); + if (!_pr_currentLibPath) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + rv = PR_FAILURE; + } + } else { + _pr_currentLibPath = 0; + } + PR_ExitMonitor(pr_linker_lock); + return rv; +} + +/* +** Return the library path for finding shared libraries. +*/ +PR_IMPLEMENT(char *) +PR_GetLibraryPath(void) +{ + char *ev; + char *copy = NULL; /* a copy of _pr_currentLibPath */ + + if (!_pr_initialized) _PR_ImplicitInitialization(); + PR_EnterMonitor(pr_linker_lock); + if (_pr_currentLibPath != NULL) { + goto exit; + } + + /* initialize pr_currentLibPath */ + +#ifdef XP_PC + ev = getenv("LD_LIBRARY_PATH"); + if (!ev) { + ev = ".;\\lib"; + } + ev = strdup(ev); +#endif + +#if defined(XP_UNIX) || defined(XP_BEOS) +#if defined(USE_DLFCN) || defined(USE_MACH_DYLD) || defined(XP_BEOS) + { + char *p=NULL; + int len; + +#ifdef XP_BEOS + ev = getenv("LIBRARY_PATH"); + if (!ev) { + ev = "%A/lib:/boot/home/config/lib:/boot/beos/system/lib"; + } +#else + ev = getenv("LD_LIBRARY_PATH"); + if (!ev) { + ev = "/usr/lib:/lib"; + } +#endif + len = strlen(ev) + 1; /* +1 for the null */ + + p = (char*) malloc(len); + if (p) { + strcpy(p, ev); + } /* if (p) */ + ev = p; + PR_LOG(_pr_io_lm, PR_LOG_NOTICE, ("linker path '%s'", ev)); + + } +#else + /* AFAIK there isn't a library path with the HP SHL interface --Rob */ + ev = strdup(""); +#endif +#endif + + /* + * If ev is NULL, we have run out of memory + */ + _pr_currentLibPath = ev; + + exit: + if (_pr_currentLibPath) { + copy = strdup(_pr_currentLibPath); + } + PR_ExitMonitor(pr_linker_lock); + if (!copy) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + } + return copy; +} + +/* +** Build library name from path, lib and extensions +*/ +PR_IMPLEMENT(char*) +PR_GetLibraryName(const char *path, const char *lib) +{ + char *fullname; + +#ifdef XP_PC + if (strstr(lib, PR_DLL_SUFFIX) == NULL) + { + if (path) { + fullname = PR_smprintf("%s\\%s%s", path, lib, PR_DLL_SUFFIX); + } else { + fullname = PR_smprintf("%s%s", lib, PR_DLL_SUFFIX); + } + } else { + if (path) { + fullname = PR_smprintf("%s\\%s", path, lib); + } else { + fullname = PR_smprintf("%s", lib); + } + } +#endif /* XP_PC */ +#if defined(XP_UNIX) || defined(XP_BEOS) + if (strstr(lib, PR_DLL_SUFFIX) == NULL) + { + if (path) { + fullname = PR_smprintf("%s/lib%s%s", path, lib, PR_DLL_SUFFIX); + } else { + fullname = PR_smprintf("lib%s%s", lib, PR_DLL_SUFFIX); + } + } else { + if (path) { + fullname = PR_smprintf("%s/%s", path, lib); + } else { + fullname = PR_smprintf("%s", lib); + } + } +#endif /* XP_UNIX || XP_BEOS */ + return fullname; +} + +/* +** Free the memory allocated, for the caller, by PR_GetLibraryName +*/ +PR_IMPLEMENT(void) +PR_FreeLibraryName(char *mem) +{ + PR_smprintf_free(mem); +} + +static PRLibrary* +pr_UnlockedFindLibrary(const char *name) +{ + PRLibrary* lm = pr_loadmap; + const char* np = strrchr(name, PR_DIRECTORY_SEPARATOR); + np = np ? np + 1 : name; + while (lm) { + const char* cp = strrchr(lm->name, PR_DIRECTORY_SEPARATOR); + cp = cp ? cp + 1 : lm->name; +#ifdef WIN32 + /* Windows DLL names are case insensitive... */ + if (strcmpi(np, cp) == 0) +#elif defined(XP_OS2) + if (stricmp(np, cp) == 0) +#else + if (strcmp(np, cp) == 0) +#endif + { + /* found */ + lm->refCount++; + PR_LOG(_pr_linker_lm, PR_LOG_MIN, + ("%s incr => %d (find lib)", + lm->name, lm->refCount)); + return lm; + } + lm = lm->next; + } + return NULL; +} + +PR_IMPLEMENT(PRLibrary*) +PR_LoadLibraryWithFlags(PRLibSpec libSpec, PRIntn flags) +{ + if (flags == 0) { + flags = _PR_DEFAULT_LD_FLAGS; + } + switch (libSpec.type) { + case PR_LibSpec_Pathname: + return pr_LoadLibraryByPathname(libSpec.value.pathname, flags); +#ifdef WIN32 + case PR_LibSpec_PathnameU: + /* + * cast to |char *| and set PR_LD_PATHW flag so that + * it can be cast back to PRUnichar* in the callee. + */ + return pr_LoadLibraryByPathname((const char*) + libSpec.value.pathname_u, + flags | PR_LD_PATHW); +#endif + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } +} + +PR_IMPLEMENT(PRLibrary*) +PR_LoadLibrary(const char *name) +{ + PRLibSpec libSpec; + + libSpec.type = PR_LibSpec_Pathname; + libSpec.value.pathname = name; + return PR_LoadLibraryWithFlags(libSpec, 0); +} + +#if defined(USE_MACH_DYLD) +static NSModule +pr_LoadMachDyldModule(const char *name) +{ + NSObjectFileImage ofi; + NSModule h = NULL; + if (NSCreateObjectFileImageFromFile(name, &ofi) + == NSObjectFileImageSuccess) { + h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE + | NSLINKMODULE_OPTION_RETURN_ON_ERROR); + if (h == NULL) { + NSLinkEditErrors linkEditError; + int errorNum; + const char *fileName; + const char *errorString; + NSLinkEditError(&linkEditError, &errorNum, &fileName, &errorString); + PR_LOG(_pr_linker_lm, PR_LOG_MIN, + ("LoadMachDyldModule error %d:%d for file %s:\n%s", + linkEditError, errorNum, fileName, errorString)); + } + if (NSDestroyObjectFileImage(ofi) == FALSE) { + if (h) { + (void)NSUnLinkModule(h, NSUNLINKMODULE_OPTION_NONE); + h = NULL; + } + } + } + return h; +} +#endif + +#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) + +/* +** macLibraryLoadProc is a function definition for a Mac shared library +** loading method. The "name" param is the same full or partial pathname +** that was passed to pr_LoadLibraryByPathName. The function must fill +** in the fields of "lm" which apply to its library type. Returns +** PR_SUCCESS if successful. +*/ + +typedef PRStatus (*macLibraryLoadProc)(const char *name, PRLibrary *lm); + +#ifdef __ppc__ + +/* +** CFM and its TVectors only exist on PowerPC. Other OS X architectures +** only use Mach-O as a native binary format. +*/ + +static void* TV2FP(CFMutableDictionaryRef dict, const char* name, void *tvp) +{ + static uint32 glue[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 }; + uint32* newGlue = NULL; + + if (tvp != NULL) { + CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII); + if (nameRef) { + CFMutableDataRef glueData = (CFMutableDataRef) CFDictionaryGetValue(dict, nameRef); + if (glueData == NULL) { + glueData = CFDataCreateMutable(NULL, sizeof(glue)); + if (glueData != NULL) { + newGlue = (uint32*) CFDataGetMutableBytePtr(glueData); + memcpy(newGlue, glue, sizeof(glue)); + newGlue[0] |= ((UInt32)tvp >> 16); + newGlue[1] |= ((UInt32)tvp & 0xFFFF); + MakeDataExecutable(newGlue, sizeof(glue)); + CFDictionaryAddValue(dict, nameRef, glueData); + CFRelease(glueData); + + PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: created wrapper for CFM function %s().", name)); + } + } else { + PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: found wrapper for CFM function %s().", name)); + + newGlue = (uint32*) CFDataGetMutableBytePtr(glueData); + } + CFRelease(nameRef); + } + } + + return newGlue; +} + +static PRStatus +pr_LoadViaCFM(const char *name, PRLibrary *lm) +{ + OSErr err; + Str255 errName; + FSRef ref; + FSSpec fileSpec; + Boolean tempUnusedBool; + + /* + * Make an FSSpec from the path name and call GetDiskFragment. + */ + + /* Use direct conversion of POSIX path to FSRef to FSSpec. */ + err = FSPathMakeRef((const UInt8*)name, &ref, NULL); + if (err != noErr) + return PR_FAILURE; + err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, + &fileSpec, NULL); + if (err != noErr) + return PR_FAILURE; + + /* Resolve an alias if this was one */ + err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool, + &tempUnusedBool); + if (err != noErr) + return PR_FAILURE; + + /* Finally, try to load the library */ + err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, fileSpec.name, + kLoadCFrag, &lm->connection, &lm->main, errName); + + if (err == noErr && lm->connection) { + /* + * if we're a mach-o binary, need to wrap all CFM function + * pointers. need a hash-table of already seen function + * pointers, etc. + */ + lm->wrappers = CFDictionaryCreateMutable(NULL, 16, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (lm->wrappers) { + lm->main = TV2FP(lm->wrappers, "main", lm->main); + } else + err = memFullErr; + } + return (err == noErr) ? PR_SUCCESS : PR_FAILURE; +} +#endif /* __ppc__ */ + +/* +** Creates a CFBundleRef if the pathname refers to a Mac OS X bundle +** directory. The caller is responsible for calling CFRelease() to +** deallocate. +*/ + +static PRStatus +pr_LoadCFBundle(const char *name, PRLibrary *lm) +{ + CFURLRef bundleURL; + CFBundleRef bundle = NULL; + char pathBuf[PATH_MAX]; + const char *resolvedPath; + CFStringRef pathRef; + + /* Takes care of relative paths and symlinks */ + resolvedPath = realpath(name, pathBuf); + if (!resolvedPath) + return PR_FAILURE; + + pathRef = CFStringCreateWithCString(NULL, pathBuf, kCFStringEncodingUTF8); + if (pathRef) { + bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef, + kCFURLPOSIXPathStyle, true); + if (bundleURL) { + bundle = CFBundleCreate(NULL, bundleURL); + CFRelease(bundleURL); + } + CFRelease(pathRef); + } + + lm->bundle = bundle; + return (bundle != NULL) ? PR_SUCCESS : PR_FAILURE; +} + +static PRStatus +pr_LoadViaDyld(const char *name, PRLibrary *lm) +{ + lm->dlh = pr_LoadMachDyldModule(name); + if (lm->dlh == NULL) { + lm->image = NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ON_ERROR + | NSADDIMAGE_OPTION_WITH_SEARCHING); + if (lm->image == NULL) { + NSLinkEditErrors linkEditError; + int errorNum; + const char *fileName; + const char *errorString; + NSLinkEditError(&linkEditError, &errorNum, &fileName, &errorString); + PR_LOG(_pr_linker_lm, PR_LOG_MIN, + ("LoadMachDyldModule error %d:%d for file %s:\n%s", + linkEditError, errorNum, fileName, errorString)); + } + } + return (lm->dlh != NULL || lm->image != NULL) ? PR_SUCCESS : PR_FAILURE; +} + +#endif /* XP_MACOSX && USE_MACH_DYLD */ + +/* +** Dynamically load a library. Only load libraries once, so scan the load +** map first. +*/ +static PRLibrary* +pr_LoadLibraryByPathname(const char *name, PRIntn flags) +{ + PRLibrary *lm; + PRLibrary* result = NULL; + PRInt32 oserr; +#ifdef WIN32 + char utf8name_stack[MAX_PATH]; + char *utf8name_malloc = NULL; + char *utf8name = utf8name_stack; + PRUnichar wname_stack[MAX_PATH]; + PRUnichar *wname_malloc = NULL; + PRUnichar *wname = wname_stack; + int len; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + /* See if library is already loaded */ + PR_EnterMonitor(pr_linker_lock); + +#ifdef WIN32 + if (flags & PR_LD_PATHW) { + /* cast back what's cast to |char *| for the argument passing. */ + wname = (LPWSTR) name; + } else { + int wlen = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0); + if (wlen > MAX_PATH) + wname = wname_malloc = PR_Malloc(wlen * sizeof(PRUnichar)); + if (wname == NULL || + !MultiByteToWideChar(CP_ACP, 0, name, -1, wname, wlen)) { + oserr = _MD_ERRNO(); + goto unlock; + } + } + len = WideCharToMultiByte(CP_UTF8, 0, wname, -1, NULL, 0, NULL, NULL); + if (len > MAX_PATH) + utf8name = utf8name_malloc = PR_Malloc(len); + if (utf8name == NULL || + !WideCharToMultiByte(CP_UTF8, 0, wname, -1, + utf8name, len, NULL, NULL)) { + oserr = _MD_ERRNO(); + goto unlock; + } + /* the list of loaded library names are always kept in UTF-8 + * on Win32 platforms */ + result = pr_UnlockedFindLibrary(utf8name); +#else + result = pr_UnlockedFindLibrary(name); +#endif + + if (result != NULL) goto unlock; + + lm = PR_NEWZAP(PRLibrary); + if (lm == NULL) { + oserr = _MD_ERRNO(); + goto unlock; + } + lm->staticTable = NULL; + +#ifdef XP_OS2 /* Why isn't all this stuff in MD code?! */ + { + HMODULE h; + UCHAR pszError[_MAX_PATH]; + ULONG ulRc = NO_ERROR; + + ulRc = DosLoadModule(pszError, _MAX_PATH, (PSZ) name, &h); + if (ulRc != NO_ERROR) { + oserr = ulRc; + PR_DELETE(lm); + goto unlock; + } + lm->name = strdup(name); + lm->dlh = h; + lm->next = pr_loadmap; + pr_loadmap = lm; + } +#endif /* XP_OS2 */ + +#ifdef WIN32 + { + HINSTANCE h; + + h = LoadLibraryExW(wname, NULL, + (flags & PR_LD_ALT_SEARCH_PATH) ? + LOAD_WITH_ALTERED_SEARCH_PATH : 0); + if (h == NULL) { + oserr = _MD_ERRNO(); + PR_DELETE(lm); + goto unlock; + } + lm->name = strdup(utf8name); + lm->dlh = h; + lm->next = pr_loadmap; + pr_loadmap = lm; + } +#endif /* WIN32 */ + +#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) + { + int i; + PRStatus status; + + static const macLibraryLoadProc loadProcs[] = { +#ifdef __ppc__ + pr_LoadViaDyld, pr_LoadCFBundle, pr_LoadViaCFM +#else /* __ppc__ */ + pr_LoadViaDyld, pr_LoadCFBundle +#endif /* __ppc__ */ + }; + + for (i = 0; i < sizeof(loadProcs) / sizeof(loadProcs[0]); i++) { + if ((status = loadProcs[i](name, lm)) == PR_SUCCESS) + break; + } + if (status != PR_SUCCESS) { + oserr = cfragNoLibraryErr; + PR_DELETE(lm); + goto unlock; + } + lm->name = strdup(name); + lm->next = pr_loadmap; + pr_loadmap = lm; + } +#endif + +#if defined(XP_UNIX) && !(defined(XP_MACOSX) && defined(USE_MACH_DYLD)) +#ifdef HAVE_DLL + { +#if defined(USE_DLFCN) +#ifdef NTO + /* Neutrino needs RTLD_GROUP to load Netscape plugins. (bug 71179) */ + int dl_flags = RTLD_GROUP; +#elif defined(AIX) + /* AIX needs RTLD_MEMBER to load an archive member. (bug 228899) */ + int dl_flags = RTLD_MEMBER; +#else + int dl_flags = 0; +#endif + void *h = NULL; + + if (flags & PR_LD_LAZY) { + dl_flags |= RTLD_LAZY; + } + if (flags & PR_LD_NOW) { + dl_flags |= RTLD_NOW; + } + if (flags & PR_LD_GLOBAL) { + dl_flags |= RTLD_GLOBAL; + } + if (flags & PR_LD_LOCAL) { + dl_flags |= RTLD_LOCAL; + } +#if defined(DARWIN) + /* ensure the file exists if it contains a slash character i.e. path */ + /* DARWIN's dlopen ignores the provided path and checks for the */ + /* plain filename in DYLD_LIBRARY_PATH */ + if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL || + PR_Access(name, PR_ACCESS_EXISTS) == PR_SUCCESS) { + h = dlopen(name, dl_flags); + } +#else + h = dlopen(name, dl_flags); +#endif +#elif defined(USE_HPSHL) + int shl_flags = 0; + shl_t h; + + /* + * Use the DYNAMIC_PATH flag only if 'name' is a plain file + * name (containing no directory) to match the behavior of + * dlopen(). + */ + if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) { + shl_flags |= DYNAMIC_PATH; + } + if (flags & PR_LD_LAZY) { + shl_flags |= BIND_DEFERRED; + } + if (flags & PR_LD_NOW) { + shl_flags |= BIND_IMMEDIATE; + } + /* No equivalent of PR_LD_GLOBAL and PR_LD_LOCAL. */ + h = shl_load(name, shl_flags, 0L); +#elif defined(USE_MACH_DYLD) + NSModule h = pr_LoadMachDyldModule(name); +#else +#error Configuration error +#endif + if (!h) { + oserr = _MD_ERRNO(); + PR_DELETE(lm); + goto unlock; + } + lm->name = strdup(name); + lm->dlh = h; + lm->next = pr_loadmap; + pr_loadmap = lm; + } +#endif /* HAVE_DLL */ +#endif /* XP_UNIX && !(XP_MACOSX && USE_MACH_DYLD) */ + + lm->refCount = 1; + +#ifdef XP_BEOS + { + image_info info; + int32 cookie = 0; + image_id imageid = B_ERROR; + image_id stubid = B_ERROR; + PRLibrary *p; + + for (p = pr_loadmap; p != NULL; p = p->next) { + /* hopefully, our caller will always use the same string + to refer to the same library */ + if (strcmp(name, p->name) == 0) { + /* we've already loaded this library */ + imageid = info.id; + lm->refCount++; + break; + } + } + + if(imageid == B_ERROR) { + /* it appears the library isn't yet loaded - load it now */ + char stubName [B_PATH_NAME_LENGTH + 1]; + + /* the following is a work-around to a "bug" in the beos - + the beos system loader allows only 32M (system-wide) + to be used by code loaded as "add-ons" (code loaded + through the 'load_add_on()' system call, which includes + mozilla components), but allows 256M to be used by + shared libraries. + + unfortunately, mozilla is too large to fit into the + "add-on" space, so we must trick the loader into + loading some of the components as shared libraries. this + is accomplished by creating a "stub" add-on (an empty + shared object), and linking it with the component + (the actual .so file generated by the build process, + without any modifications). when this stub is loaded + by load_add_on(), the loader will automatically load the + component into the shared library space. + */ + + strcpy(stubName, name); + strcat(stubName, ".stub"); + + /* first, attempt to load the stub (thereby loading the + component as a shared library */ + if ((stubid = load_add_on(stubName)) > B_ERROR) { + /* the stub was loaded successfully. */ + imageid = B_FILE_NOT_FOUND; + + cookie = 0; + while (get_next_image_info(0, &cookie, &info) == B_OK) { + const char *endOfSystemName = strrchr(info.name, '/'); + const char *endOfPassedName = strrchr(name, '/'); + if( 0 == endOfSystemName ) + endOfSystemName = info.name; + else + endOfSystemName++; + if( 0 == endOfPassedName ) + endOfPassedName = name; + else + endOfPassedName++; + if (strcmp(endOfSystemName, endOfPassedName) == 0) { + /* this is the actual component - remember it */ + imageid = info.id; + break; + } + } + + } else { + /* we failed to load the "stub" - try to load the + component directly as an add-on */ + stubid = B_ERROR; + imageid = load_add_on(name); + } + } + + if (imageid <= B_ERROR) { + oserr = imageid; + PR_DELETE( lm ); + goto unlock; + } + lm->name = strdup(name); + lm->dlh = (void*)imageid; + lm->stub_dlh = (void*)stubid; + lm->next = pr_loadmap; + pr_loadmap = lm; + } +#endif + + result = lm; /* success */ + PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", lm->name)); + + unlock: + if (result == NULL) { + PR_SetError(PR_LOAD_LIBRARY_ERROR, oserr); + DLLErrorInternal(oserr); /* sets error text */ + } +#ifdef WIN32 + if (utf8name_malloc) + PR_Free(utf8name_malloc); + if (wname_malloc) + PR_Free(wname_malloc); +#endif + PR_ExitMonitor(pr_linker_lock); + return result; +} + +/* +** Unload a shared library which was loaded via PR_LoadLibrary +*/ +PR_IMPLEMENT(PRStatus) +PR_UnloadLibrary(PRLibrary *lib) +{ + int result = 0; + PRStatus status = PR_SUCCESS; + + if (lib == 0) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + PR_EnterMonitor(pr_linker_lock); + + if (lib->refCount <= 0) { + PR_ExitMonitor(pr_linker_lock); + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + if (--lib->refCount > 0) { + PR_LOG(_pr_linker_lm, PR_LOG_MIN, + ("%s decr => %d", + lib->name, lib->refCount)); + goto done; + } + +#ifdef XP_BEOS + if(((image_id)lib->stub_dlh) == B_ERROR) + unload_add_on( (image_id) lib->dlh ); + else + unload_add_on( (image_id) lib->stub_dlh); +#endif + +#ifdef XP_UNIX +#ifdef HAVE_DLL +#ifdef USE_DLFCN + result = dlclose(lib->dlh); +#elif defined(USE_HPSHL) + result = shl_unload(lib->dlh); +#elif defined(USE_MACH_DYLD) + if (lib->dlh) + result = NSUnLinkModule(lib->dlh, NSUNLINKMODULE_OPTION_NONE) ? 0 : -1; +#else +#error Configuration error +#endif +#endif /* HAVE_DLL */ +#endif /* XP_UNIX */ +#ifdef XP_PC + if (lib->dlh) { + FreeLibrary((HINSTANCE)(lib->dlh)); + lib->dlh = (HINSTANCE)NULL; + } +#endif /* XP_PC */ + +#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) + /* Close the connection */ + if (lib->connection) + CloseConnection(&(lib->connection)); + if (lib->bundle) + CFRelease(lib->bundle); + if (lib->wrappers) + CFRelease(lib->wrappers); + /* No way to unload an image (lib->image) */ +#endif + + /* unlink from library search list */ + if (pr_loadmap == lib) + pr_loadmap = pr_loadmap->next; + else if (pr_loadmap != NULL) { + PRLibrary* prev = pr_loadmap; + PRLibrary* next = pr_loadmap->next; + while (next != NULL) { + if (next == lib) { + prev->next = next->next; + goto freeLib; + } + prev = next; + next = next->next; + } + /* + * fail (the library is not on the _pr_loadmap list), + * but don't wipe out an error from dlclose/shl_unload. + */ + PR_ASSERT(!"_pr_loadmap and lib->refCount inconsistent"); + if (result == 0) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + status = PR_FAILURE; + } + } + /* + * We free the PRLibrary structure whether dlclose/shl_unload + * succeeds or not. + */ + + freeLib: + PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Unloaded library %s", lib->name)); + free(lib->name); + lib->name = NULL; + PR_DELETE(lib); + if (result != 0) { + PR_SetError(PR_UNLOAD_LIBRARY_ERROR, _MD_ERRNO()); + DLLErrorInternal(_MD_ERRNO()); + status = PR_FAILURE; + } + +done: + PR_ExitMonitor(pr_linker_lock); + return status; +} + +static void* +pr_FindSymbolInLib(PRLibrary *lm, const char *name) +{ + void *f = NULL; +#ifdef XP_OS2 + int rc; +#endif + + if (lm->staticTable != NULL) { + const PRStaticLinkTable* tp; + for (tp = lm->staticTable; tp->name; tp++) { + if (strcmp(name, tp->name) == 0) { + return (void*) tp->fp; + } + } + /* + ** If the symbol was not found in the static table then check if + ** the symbol was exported in the DLL... Win16 only!! + */ +#if !defined(WIN16) && !defined(XP_BEOS) + PR_SetError(PR_FIND_SYMBOL_ERROR, 0); + return (void*)NULL; +#endif + } + +#ifdef XP_OS2 + rc = DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f); +#if defined(NEED_LEADING_UNDERSCORE) + /* + * Older plugins (not built using GCC) will have symbols that are not + * underscore prefixed. We check for that here. + */ + if (rc != NO_ERROR) { + name++; + DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f); + } +#endif +#endif /* XP_OS2 */ + +#ifdef WIN32 + f = GetProcAddress(lm->dlh, name); +#endif /* WIN32 */ + +#if defined(XP_MACOSX) && defined(USE_MACH_DYLD) +/* add this offset to skip the leading underscore in name */ +#define SYM_OFFSET 1 + if (lm->bundle) { + CFStringRef nameRef = CFStringCreateWithCString(NULL, name + SYM_OFFSET, kCFStringEncodingASCII); + if (nameRef) { + f = CFBundleGetFunctionPointerForName(lm->bundle, nameRef); + CFRelease(nameRef); + } + } + if (lm->connection) { + Ptr symAddr; + CFragSymbolClass symClass; + Str255 pName; + + PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Looking up symbol: %s", name + SYM_OFFSET)); + + c2pstrcpy(pName, name + SYM_OFFSET); + + f = (FindSymbol(lm->connection, pName, &symAddr, &symClass) == noErr) ? symAddr : NULL; + +#ifdef __ppc__ + /* callers expect mach-o function pointers, so must wrap tvectors with glue. */ + if (f && symClass == kTVectorCFragSymbol) { + f = TV2FP(lm->wrappers, name + SYM_OFFSET, f); + } +#endif /* __ppc__ */ + + if (f == NULL && strcmp(name + SYM_OFFSET, "main") == 0) f = lm->main; + } + if (lm->image) { + NSSymbol symbol; + symbol = NSLookupSymbolInImage(lm->image, name, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + if (symbol != NULL) + f = NSAddressOfSymbol(symbol); + else + f = NULL; + } +#undef SYM_OFFSET +#endif /* XP_MACOSX && USE_MACH_DYLD */ + +#ifdef XP_BEOS + if( B_NO_ERROR != get_image_symbol( (image_id)lm->dlh, name, B_SYMBOL_TYPE_TEXT, &f ) ) { + f = NULL; + } +#endif + +#ifdef XP_UNIX +#ifdef HAVE_DLL +#ifdef USE_DLFCN + f = dlsym(lm->dlh, name); +#elif defined(USE_HPSHL) + if (shl_findsym(&lm->dlh, name, TYPE_PROCEDURE, &f) == -1) { + f = NULL; + } +#elif defined(USE_MACH_DYLD) + if (lm->dlh) { + NSSymbol symbol; + symbol = NSLookupSymbolInModule(lm->dlh, name); + if (symbol != NULL) + f = NSAddressOfSymbol(symbol); + else + f = NULL; + } +#endif +#endif /* HAVE_DLL */ +#endif /* XP_UNIX */ + if (f == NULL) { + PR_SetError(PR_FIND_SYMBOL_ERROR, _MD_ERRNO()); + DLLErrorInternal(_MD_ERRNO()); + } + return f; +} + +/* +** Called by class loader to resolve missing native's +*/ +PR_IMPLEMENT(void*) +PR_FindSymbol(PRLibrary *lib, const char *raw_name) +{ + void *f = NULL; +#if defined(NEED_LEADING_UNDERSCORE) + char *name; +#else + const char *name; +#endif + /* + ** Mangle the raw symbol name in any way that is platform specific. + */ +#if defined(NEED_LEADING_UNDERSCORE) + /* Need a leading _ */ + name = PR_smprintf("_%s", raw_name); +#elif defined(AIX) + /* + ** AIX with the normal linker put's a "." in front of the symbol + ** name. When use "svcc" and "svld" then the "." disappears. Go + ** figure. + */ + name = raw_name; +#else + name = raw_name; +#endif + + PR_EnterMonitor(pr_linker_lock); + PR_ASSERT(lib != NULL); + f = pr_FindSymbolInLib(lib, name); + +#if defined(NEED_LEADING_UNDERSCORE) + PR_smprintf_free(name); +#endif + + PR_ExitMonitor(pr_linker_lock); + return f; +} + +/* +** Return the address of the function 'raw_name' in the library 'lib' +*/ +PR_IMPLEMENT(PRFuncPtr) +PR_FindFunctionSymbol(PRLibrary *lib, const char *raw_name) +{ + return ((PRFuncPtr) PR_FindSymbol(lib, raw_name)); +} + +PR_IMPLEMENT(void*) +PR_FindSymbolAndLibrary(const char *raw_name, PRLibrary* *lib) +{ + void *f = NULL; +#if defined(NEED_LEADING_UNDERSCORE) + char *name; +#else + const char *name; +#endif + PRLibrary* lm; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + /* + ** Mangle the raw symbol name in any way that is platform specific. + */ +#if defined(NEED_LEADING_UNDERSCORE) + /* Need a leading _ */ + name = PR_smprintf("_%s", raw_name); +#elif defined(AIX) + /* + ** AIX with the normal linker put's a "." in front of the symbol + ** name. When use "svcc" and "svld" then the "." disappears. Go + ** figure. + */ + name = raw_name; +#else + name = raw_name; +#endif + + PR_EnterMonitor(pr_linker_lock); + + /* search all libraries */ + for (lm = pr_loadmap; lm != NULL; lm = lm->next) { + f = pr_FindSymbolInLib(lm, name); + if (f != NULL) { + *lib = lm; + lm->refCount++; + PR_LOG(_pr_linker_lm, PR_LOG_MIN, + ("%s incr => %d (for %s)", + lm->name, lm->refCount, name)); + break; + } + } +#if defined(NEED_LEADING_UNDERSCORE) + PR_smprintf_free(name); +#endif + + PR_ExitMonitor(pr_linker_lock); + return f; +} + +PR_IMPLEMENT(PRFuncPtr) +PR_FindFunctionSymbolAndLibrary(const char *raw_name, PRLibrary* *lib) +{ + return ((PRFuncPtr) PR_FindSymbolAndLibrary(raw_name, lib)); +} + +/* +** Add a static library to the list of loaded libraries. If LoadLibrary +** is called with the name then we will pretend it was already loaded +*/ +PR_IMPLEMENT(PRLibrary*) +PR_LoadStaticLibrary(const char *name, const PRStaticLinkTable *slt) +{ + PRLibrary *lm=NULL; + PRLibrary* result = NULL; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + /* See if library is already loaded */ + PR_EnterMonitor(pr_linker_lock); + + /* If the lbrary is already loaded, then add the static table information... */ + result = pr_UnlockedFindLibrary(name); + if (result != NULL) { + PR_ASSERT( (result->staticTable == NULL) || (result->staticTable == slt) ); + result->staticTable = slt; + goto unlock; + } + + /* Add library to list...Mark it static */ + lm = PR_NEWZAP(PRLibrary); + if (lm == NULL) goto unlock; + + lm->name = strdup(name); + lm->refCount = 1; + lm->dlh = pr_exe_loadmap ? pr_exe_loadmap->dlh : 0; + lm->staticTable = slt; + lm->next = pr_loadmap; + pr_loadmap = lm; + + result = lm; /* success */ + PR_ASSERT(lm->refCount == 1); + PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (static lib)", lm->name)); + unlock: + PR_ExitMonitor(pr_linker_lock); + return result; +} + +PR_IMPLEMENT(char *) +PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr) +{ +#if defined(USE_DLFCN) && defined(HAVE_DLADDR) + Dl_info dli; + char *result; + + if (dladdr((void *)addr, &dli) == 0) { + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO()); + DLLErrorInternal(_MD_ERRNO()); + return NULL; + } + result = PR_Malloc(strlen(dli.dli_fname)+1); + if (result != NULL) { + strcpy(result, dli.dli_fname); + } + return result; +#elif defined(USE_MACH_DYLD) + char *result; + const char *image_name; + int i, count = _dyld_image_count(); + + for (i = 0; i < count; i++) { + image_name = _dyld_get_image_name(i); + if (strstr(image_name, name) != NULL) { + result = PR_Malloc(strlen(image_name)+1); + if (result != NULL) { + strcpy(result, image_name); + } + return result; + } + } + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); + return NULL; +#elif defined(AIX) + char *result; +#define LD_INFO_INCREMENT 64 + struct ld_info *info; + unsigned int info_length = LD_INFO_INCREMENT * sizeof(struct ld_info); + struct ld_info *infop; + int loadflags = L_GETINFO | L_IGNOREUNLOAD; + + for (;;) { + info = PR_Malloc(info_length); + if (info == NULL) { + return NULL; + } + /* If buffer is too small, loadquery fails with ENOMEM. */ + if (loadquery(loadflags, info, info_length) != -1) { + break; + } + /* + * Calling loadquery when compiled for 64-bit with the + * L_IGNOREUNLOAD flag can cause an invalid argument error + * on AIX 5.1. Detect this error the first time that + * loadquery is called, and try calling it again without + * this flag set. + */ + if (errno == EINVAL && (loadflags & L_IGNOREUNLOAD)) { + loadflags &= ~L_IGNOREUNLOAD; + if (loadquery(loadflags, info, info_length) != -1) { + break; + } + } + PR_Free(info); + if (errno != ENOMEM) { + /* should not happen */ + _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); + return NULL; + } + /* retry with a larger buffer */ + info_length += LD_INFO_INCREMENT * sizeof(struct ld_info); + } + + for (infop = info; + ; + infop = (struct ld_info *)((char *)infop + infop->ldinfo_next)) { + unsigned long start = (unsigned long)infop->ldinfo_dataorg; + unsigned long end = start + infop->ldinfo_datasize; + if (start <= (unsigned long)addr && end > (unsigned long)addr) { + result = PR_Malloc(strlen(infop->ldinfo_filename)+1); + if (result != NULL) { + strcpy(result, infop->ldinfo_filename); + } + break; + } + if (!infop->ldinfo_next) { + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); + result = NULL; + break; + } + } + PR_Free(info); + return result; +#elif defined(OSF1) + /* Contributed by Steve Streeter of HP */ + ldr_process_t process, ldr_my_process(); + ldr_module_t mod_id; + ldr_module_info_t info; + ldr_region_t regno; + ldr_region_info_t reginfo; + size_t retsize; + int rv; + char *result; + + /* Get process for which dynamic modules will be listed */ + + process = ldr_my_process(); + + /* Attach to process */ + + rv = ldr_xattach(process); + if (rv) { + /* should not happen */ + _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); + return NULL; + } + + /* Print information for list of modules */ + + mod_id = LDR_NULL_MODULE; + + for (;;) { + + /* Get information for the next module in the module list. */ + + ldr_next_module(process, &mod_id); + if (ldr_inq_module(process, mod_id, &info, sizeof(info), + &retsize) != 0) { + /* No more modules */ + break; + } + if (retsize < sizeof(info)) { + continue; + } + + /* + * Get information for each region in the module and check if any + * contain the address of this function. + */ + + for (regno = 0; ; regno++) { + if (ldr_inq_region(process, mod_id, regno, ®info, + sizeof(reginfo), &retsize) != 0) { + /* No more regions */ + break; + } + if (((unsigned long)reginfo.lri_mapaddr <= + (unsigned long)addr) && + (((unsigned long)reginfo.lri_mapaddr + reginfo.lri_size) > + (unsigned long)addr)) { + /* Found it. */ + result = PR_Malloc(strlen(info.lmi_name)+1); + if (result != NULL) { + strcpy(result, info.lmi_name); + } + return result; + } + } + } + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); + return NULL; +#elif defined(HPUX) && defined(USE_HPSHL) + int index; + struct shl_descriptor desc; + char *result; + + for (index = 0; shl_get_r(index, &desc) == 0; index++) { + if (strstr(desc.filename, name) != NULL) { + result = PR_Malloc(strlen(desc.filename)+1); + if (result != NULL) { + strcpy(result, desc.filename); + } + return result; + } + } + /* + * Since the index value of a library is decremented if + * a library preceding it in the shared library search + * list was unloaded, it is possible that we missed some + * libraries as we went up the list. So we should go + * down the list to be sure that we not miss anything. + */ + for (index--; index >= 0; index--) { + if ((shl_get_r(index, &desc) == 0) + && (strstr(desc.filename, name) != NULL)) { + result = PR_Malloc(strlen(desc.filename)+1); + if (result != NULL) { + strcpy(result, desc.filename); + } + return result; + } + } + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0); + return NULL; +#elif defined(HPUX) && defined(USE_DLFCN) + struct load_module_desc desc; + char *result; + const char *module_name; + + if (dlmodinfo((unsigned long)addr, &desc, sizeof desc, NULL, 0, 0) == 0) { + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO()); + DLLErrorInternal(_MD_ERRNO()); + return NULL; + } + module_name = dlgetname(&desc, sizeof desc, NULL, 0, 0); + if (module_name == NULL) { + /* should not happen */ + _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); + DLLErrorInternal(_MD_ERRNO()); + return NULL; + } + result = PR_Malloc(strlen(module_name)+1); + if (result != NULL) { + strcpy(result, module_name); + } + return result; +#elif defined(WIN32) + PRUnichar wname[MAX_PATH]; + HMODULE handle = NULL; + PRUnichar module_name[MAX_PATH]; + int len; + char *result; + + if (MultiByteToWideChar(CP_ACP, 0, name, -1, wname, MAX_PATH)) { + handle = GetModuleHandleW(wname); + } + if (handle == NULL) { + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO()); + DLLErrorInternal(_MD_ERRNO()); + return NULL; + } + if (GetModuleFileNameW(handle, module_name, MAX_PATH) == 0) { + /* should not happen */ + _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); + return NULL; + } + len = WideCharToMultiByte(CP_ACP, 0, module_name, -1, + NULL, 0, NULL, NULL); + if (len == 0) { + _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); + return NULL; + } + result = PR_Malloc(len * sizeof(PRUnichar)); + if (result != NULL) { + WideCharToMultiByte(CP_ACP, 0, module_name, -1, + result, len, NULL, NULL); + } + return result; +#elif defined(XP_OS2) + HMODULE module = NULL; + char module_name[_MAX_PATH]; + char *result; + APIRET ulrc = DosQueryModFromEIP(&module, NULL, 0, NULL, NULL, (ULONG) addr); + if ((NO_ERROR != ulrc) || (NULL == module) ) { + PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO()); + DLLErrorInternal(_MD_ERRNO()); + return NULL; + } + ulrc = DosQueryModuleName(module, sizeof module_name, module_name); + if (NO_ERROR != ulrc) { + /* should not happen */ + _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO()); + return NULL; + } + result = PR_Malloc(strlen(module_name)+1); + if (result != NULL) { + strcpy(result, module_name); + } + return result; +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +#endif +} diff -Nru nspr-4.9.5/nspr/pr/src/Makefile.in nspr-4.10.7/nspr/pr/src/Makefile.in --- nspr-4.9.5/nspr/pr/src/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,379 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +DIRS = io linking malloc md memory misc threads + +ifeq ($(USE_PTHREADS), 1) + DIRS += pthreads +endif + +ifeq ($(USE_BTHREADS), 1) + DIRS += bthreads +endif + +ifeq ($(USE_CPLUS), 1) + DIRS += cplus +endif + +# +# Define platform-dependent OS_LIBS +# + +ifeq ($(OS_ARCH),SunOS) +MAPFILE = $(OBJDIR)/nsprmap.sun +GARBAGE += $(MAPFILE) +ifdef NS_USE_GCC +ifdef GCC_USE_GNU_LD +MKSHLIB += -Wl,--version-script,$(MAPFILE) +else +MKSHLIB += -Wl,-M,$(MAPFILE) +endif +else +MKSHLIB += -M $(MAPFILE) +endif +# +# In Solaris 2.6 or earlier, -lrt is called -lposix4. +# +LIBRT_TEST=$(firstword $(sort 5.7 $(OS_RELEASE))) +ifeq (5.7, $(LIBRT_TEST)) +LIBRT=-lrt +else +LIBRT=-lposix4 +endif + +ifdef USE_PTHREADS +OS_LIBS = -lpthread ${LIBRT} -lsocket -lnsl -ldl -lc +else +OS_LIBS = -lsocket -lnsl -ldl -lc +endif # USE_PTHREADS +ifeq ($(CPU_ARCH),sparc) +ifndef USE_64 +DSO_LDOPTS += -Wl,-f,\$$ORIGIN/cpu/\$$ISALIST/lib$(ULTRASPARC_LIBRARY)$(LIBRARY_VERSION).so +endif +endif # sparc +endif # SunOS + +ifeq ($(OS_ARCH), IRIX) +ifeq ($(USE_PTHREADS), 1) +OS_LIBS = -lpthread +endif +OS_LIBS += -lc +endif + +ifeq ($(OS_ARCH),AIX) +DSO_LDOPTS += -binitfini::_PR_Fini +OS_LIBS = -lodm -lcfg +ifeq ($(CLASSIC_NSPR),1) +ifeq ($(OS_RELEASE),4.1) +OS_LIBS += -lsvld -lc +else +OS_LIBS += -ldl -lc +endif +else +ifeq ($(OS_RELEASE),4.1) +OS_LIBS += -lpthreads -lsvld -lC_r -lC -lc_r -lm /usr/lib/libc.a +else +OS_LIBS += -lpthreads -ldl -lC_r -lC -lc_r -lm /usr/lib/libc.a +endif +endif +endif + +# On AIX, we override malloc in non-pthread versions. On AIX 4.2 or +# above, this requires that we use the rtl-enabled version of libc.a. +ifeq ($(OS_ARCH),AIX) +ifneq (,$(filter-out 3.2 4.1,$(OS_RELEASE))) +ifneq ($(USE_PTHREADS),1) +BUILD_AIX_RTL_LIBC = 1 +AIX_RTL_LIBC = $(OBJDIR)/libc.a +endif +endif +endif + +ifeq ($(OS_ARCH),OS2) +MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def +ADD_TO_DEF_FILE = cat $(srcdir)/os2extra.def >> $(MAPFILE) +GARBAGE += $(MAPFILE) +MKSHLIB += $(MAPFILE) +endif + +ifeq ($(OS_ARCH),OSF1) +ifeq ($(USE_PTHREADS), 1) +OS_LIBS = -lpthread -lrt +endif +ifneq ($(OS_RELEASE),V2.0) +OS_LIBS += -lc_r +endif +endif + +# Linux, GNU/Hurd, and GNU/kFreeBSD systems +ifneq (,$(filter Linux GNU%,$(OS_ARCH))) +ifeq ($(USE_PTHREADS), 1) +ifeq ($(OS_TARGET),Android) +# Android has no libpthread.so in NDK +OS_LIBS = -ldl +else +OS_LIBS = -lpthread -ldl +endif +else +OS_LIBS = -ldl +endif +ifneq ($(OS_TARGET),Android) +# Android has no librt - realtime functions are in libc +OS_LIBS += -lrt +endif +endif + +ifeq ($(OS_ARCH),HP-UX) +ifeq ($(USE_PTHREADS), 1) +ifeq (,$(filter-out B.10.10 B.10.20,$(OS_RELEASE))) +OS_LIBS = -ldce +else +OS_LIBS = -lpthread -lrt +endif +endif +ifeq ($(PTHREADS_USER), 1) +OS_LIBS = -lpthread +endif +ifeq ($(basename $(OS_RELEASE)),A.09) +OS_LIBS += -ldld -L/lib/pa1.1 -lm +else +OS_LIBS += -ldld -lm -lc +endif +ifneq ($(OS_TEST),ia64) +ifndef USE_64 +DSO_LDOPTS += +I PR_HPUX10xInit +endif +endif +endif + +ifeq ($(OS_ARCH),UNIXWARE) +OS_LIBS = -lsocket -lc +endif + +ifeq ($(OS_ARCH),WINNT) +ifdef NS_USE_GCC +OS_LIBS = -ladvapi32 -lws2_32 -lwinmm +else +OS_LIBS = advapi32.lib ws2_32.lib winmm.lib +endif +endif + +ifeq ($(OS_ARCH),WINCE) +OS_LIBS = ws2.lib +endif + +ifeq ($(OS_TARGET),Android) +OS_LIBS += -llog +endif + +ifeq ($(OS_TARGET),MacOSX) +OS_LIBS = -framework CoreServices -framework CoreFoundation +endif + +EXTRA_LIBS += $(OS_LIBS) + +# +# Define platform-dependent OBJS +# + +OBJS = \ + $(OBJDIR)/prvrsion.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prfdcach.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prmwait.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prmapopt.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/priometh.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prlayer.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prlog.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prmmap.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prpolevt.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prprf.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prscanf.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prstdio.$(OBJ_SUFFIX) \ + threads/$(OBJDIR)/prcmon.$(OBJ_SUFFIX) \ + threads/$(OBJDIR)/prrwlock.$(OBJ_SUFFIX) \ + threads/$(OBJDIR)/prtpd.$(OBJ_SUFFIX) \ + linking/$(OBJDIR)/prlink.$(OBJ_SUFFIX) \ + malloc/$(OBJDIR)/prmalloc.$(OBJ_SUFFIX) \ + malloc/$(OBJDIR)/prmem.$(OBJ_SUFFIX) \ + md/$(OBJDIR)/prosdep.$(OBJ_SUFFIX) \ + memory/$(OBJDIR)/prshm.$(OBJ_SUFFIX) \ + memory/$(OBJDIR)/prshma.$(OBJ_SUFFIX) \ + memory/$(OBJDIR)/prseg.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/pralarm.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/pratom.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prcountr.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prdtoa.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prenv.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prerr.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prerror.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prerrortable.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prinit.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prinrval.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/pripc.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prlog2.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prlong.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prnetdb.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/praton.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prolock.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prrng.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prsystem.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prthinfo.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prtpool.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prtrace.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/prtime.$(OBJ_SUFFIX) + +ifdef USE_PTHREADS +OBJS += \ + pthreads/$(OBJDIR)/ptsynch.$(OBJ_SUFFIX) \ + pthreads/$(OBJDIR)/ptio.$(OBJ_SUFFIX) \ + pthreads/$(OBJDIR)/ptthread.$(OBJ_SUFFIX) \ + pthreads/$(OBJDIR)/ptmisc.$(OBJ_SUFFIX) +else +OBJS += \ + io/$(OBJDIR)/prdir.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prfile.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prio.$(OBJ_SUFFIX) \ + io/$(OBJDIR)/prsocket.$(OBJ_SUFFIX) \ + misc/$(OBJDIR)/pripcsem.$(OBJ_SUFFIX) + +ifndef USE_BTHREADS +OBJS += \ + threads/$(OBJDIR)/prcthr.$(OBJ_SUFFIX) \ + threads/$(OBJDIR)/prdump.$(OBJ_SUFFIX) \ + threads/$(OBJDIR)/prmon.$(OBJ_SUFFIX) \ + threads/$(OBJDIR)/prsem.$(OBJ_SUFFIX) \ + threads/combined/$(OBJDIR)/prucpu.$(OBJ_SUFFIX) \ + threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \ + threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \ + threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \ + threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX) +endif + +endif + +ifeq ($(USE_CPLUS), 1) +OBJS += \ + cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rccv.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rcfileio.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rcinrval.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rcio.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rclock.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rcnetdb.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rcnetio.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rcthread.$(OBJ_SUFFIX) \ + cplus/$(OBJDIR)/rctime.$(OBJ_SUFFIX) +endif + +ifeq ($(OS_ARCH), WINNT) +RES=$(OBJDIR)/nspr.res +RESNAME=nspr.rc +endif # WINNT + +include $(srcdir)/md/$(PR_MD_ARCH_DIR)/objs.mk +ifdef USE_BTHREADS +include $(srcdir)/bthreads/objs.mk +endif + +LIBRARY_NAME = nspr +LIBRARY_VERSION = $(MOD_MAJOR_VERSION) + +RELEASE_LIBS = $(TARGETS) + +include $(topsrcdir)/config/rules.mk + +ifeq ($(BUILD_AIX_RTL_LIBC),1) +TARGETS += $(AIX_RTL_LIBC) +# XXX is this a shared library? +endif + +# +# Version information generation (begin) +# +ECHO = echo +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private +TINC = $(OBJDIR)/_pr_bld.h + +ifeq ($(OS_TARGET),OS2) +PROD = nspr$(MOD_MAJOR_VERSION).$(DLL_SUFFIX) +else +PROD = $(notdir $(SHARED_LIBRARY)) +endif + +NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now +SH_DATE = $(shell date "+%Y-%m-%d %T") +SH_NOW = $(shell $(NOW)) + +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + SUF = i64 +else + SUF = LL +endif + +DEFINES += -D_NSPR_BUILD_ + +GARBAGE += $(TINC) + +$(TINC): + @$(MAKE_OBJDIR) + @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC) + @if test ! -z "$(SH_NOW)"; then \ + $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \ + else \ + true; \ + fi + @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) + + +$(OBJDIR)/prvrsion.$(OBJ_SUFFIX): prvrsion.c $(TINC) +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $< +else + $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $< +endif +# +# Version information generation (end) +# + + +# We use a 'build' target here to ensure that we build $(TARGETS) after +# looping over $(DIRS) to create the object files in a parallel build. +# Recipe commands are executed sequentially in a parallel build while +# target dependencies are executed in parallel. +export:: + $(MAKE) build + +# +# The Client build wants the shared libraries in $(dist_bindir) +# so we also install them there. +# + +build:: $(TARGETS) + $(INSTALL) -m 444 $(TARGETS) $(dist_libdir) +ifdef SHARED_LIBRARY +ifeq ($(OS_ARCH),HP-UX) + $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir) + $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir) +else + $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir) +endif +endif + +ifeq ($(BUILD_AIX_RTL_LIBC),1) +$(AIX_RTL_LIBC): /usr/ccs/lib/libc.a + rtl_enable -o $@ $< +endif diff -Nru nspr-4.9.5/nspr/pr/src/malloc/.cvsignore nspr-4.10.7/nspr/pr/src/malloc/.cvsignore --- nspr-4.9.5/nspr/pr/src/malloc/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/malloc/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/malloc/Makefile.in nspr-4.10.7/nspr/pr/src/malloc/Makefile.in --- nspr-4.9.5/nspr/pr/src/malloc/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/malloc/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,28 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +CSRCS = prmalloc.c prmem.c + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/malloc/prmalloc.c nspr-4.10.7/nspr/pr/src/malloc/prmalloc.c --- nspr-4.9.5/nspr/pr/src/malloc/prmalloc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/malloc/prmalloc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1142 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +/* +** We override malloc etc. on any platform which has preemption + +** nspr20 user level threads. When we're debugging, we can make our +** version of malloc fail occasionally. +*/ +#ifdef _PR_OVERRIDE_MALLOC + +/* +** Thread safe version of malloc, calloc, realloc, free +*/ +#include + +#ifdef DEBUG +#define SANITY +#define EXTRA_SANITY +#else +#undef SANITY +#undef EXTRA_SANITY +#endif + +/* Forward decls */ +void *_PR_UnlockedMalloc(size_t size); +void _PR_UnlockedFree(void *ptr); +void *_PR_UnlockedRealloc(void *ptr, size_t size); +void *_PR_UnlockedCalloc(size_t n, size_t elsize); + +/************************************************************************/ + +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + */ + +/* + * Defining SANITY will enable some checks which will tell you if the users + * program did botch something + */ + +/* + * Defining EXTRA_SANITY will enable some checks which are mostly related + * to internal conditions in malloc.c + */ + +/* + * Very verbose progress on stdout... + */ +#if 0 +# define TRACE(foo) printf foo +static int malloc_event; +#else +# define TRACE(foo) +#endif + +/* XXX Pick a number, any number */ +# define malloc_pagesize 4096UL +# define malloc_pageshift 12UL + +#ifdef XP_UNIX +#include +#include +#include +#include +#include +#include +#include +#endif + +/* + * This structure describes a page's worth of chunks. + */ + +struct pginfo { + struct pginfo *next; /* next on the free list */ + char *page; /* Pointer to the page */ + u_short size; /* size of this page's chunks */ + u_short shift; /* How far to shift for this size chunks */ + u_short free; /* How many free chunks */ + u_short total; /* How many chunk */ + u_long bits[1]; /* Which chunks are free */ +}; + +struct pgfree { + struct pgfree *next; /* next run of free pages */ + struct pgfree *prev; /* prev run of free pages */ + char *page; /* pointer to free pages */ + char *end; /* pointer to end of free pages */ + u_long size; /* number of bytes free */ +}; + +/* + * How many bits per u_long in the bitmap. + * Change only if not 8 bits/byte + */ +#define MALLOC_BITS (8*sizeof(u_long)) + +/* + * Magic values to put in the page_directory + */ +#define MALLOC_NOT_MINE ((struct pginfo*) 0) +#define MALLOC_FREE ((struct pginfo*) 1) +#define MALLOC_FIRST ((struct pginfo*) 2) +#define MALLOC_FOLLOW ((struct pginfo*) 3) +#define MALLOC_MAGIC ((struct pginfo*) 4) + +/* + * Set to one when malloc_init has been called + */ +static unsigned initialized; + +/* + * The size of a page. + * Must be a integral multiplum of the granularity of mmap(2). + * Your toes will curl if it isn't a power of two + */ +#define malloc_pagemask ((malloc_pagesize)-1) + +/* + * The size of the largest chunk. + * Half a page. + */ +#define malloc_maxsize ((malloc_pagesize)>>1) + +/* + * malloc_pagesize == 1 << malloc_pageshift + */ +#ifndef malloc_pageshift +static unsigned malloc_pageshift; +#endif /* malloc_pageshift */ + +/* + * The smallest allocation we bother about. + * Must be power of two + */ +#ifndef malloc_minsize +static unsigned malloc_minsize; +#endif /* malloc_minsize */ + +/* + * The largest chunk we care about. + * Must be smaller than pagesize + * Must be power of two + */ +#ifndef malloc_maxsize +static unsigned malloc_maxsize; +#endif /* malloc_maxsize */ + +#ifndef malloc_cache +static unsigned malloc_cache; +#endif /* malloc_cache */ + +/* + * The offset from pagenumber to index into the page directory + */ +static u_long malloc_origo; + +/* + * The last index in the page directory we care about + */ +static u_long last_index; + +/* + * Pointer to page directory. + * Allocated "as if with" malloc + */ +static struct pginfo **page_dir; + +/* + * How many slots in the page directory + */ +static unsigned malloc_ninfo; + +/* + * Free pages line up here + */ +static struct pgfree free_list; + +/* + * Abort() if we fail to get VM ? + */ +static int malloc_abort; + +#ifdef SANITY +/* + * Are we trying to die ? + */ +static int suicide; +#endif + +/* + * dump statistics + */ +static int malloc_stats; + +/* + * always realloc ? + */ +static int malloc_realloc; + +/* + * my last break. + */ +static void *malloc_brk; + +/* + * one location cache for free-list holders + */ +static struct pgfree *px; + +static int set_pgdir(void *ptr, struct pginfo *info); +static int extend_page_directory(u_long index); + +#ifdef SANITY +void +malloc_dump(FILE *fd) +{ + struct pginfo **pd; + struct pgfree *pf; + int j; + + pd = page_dir; + + /* print out all the pages */ + for(j=0;j<=last_index;j++) { + fprintf(fd,"%08lx %5d ",(j+malloc_origo) << malloc_pageshift,j); + if (pd[j] == MALLOC_NOT_MINE) { + for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++) + ; + j--; + fprintf(fd,".. %5d not mine\n", j); + } else if (pd[j] == MALLOC_FREE) { + for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++) + ; + j--; + fprintf(fd,".. %5d free\n", j); + } else if (pd[j] == MALLOC_FIRST) { + for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++) + ; + j--; + fprintf(fd,".. %5d in use\n", j); + } else if (pd[j] < MALLOC_MAGIC) { + fprintf(fd,"(%p)\n", pd[j]); + } else { + fprintf(fd,"%p %d (of %d) x %d @ %p --> %p\n", + pd[j],pd[j]->free, pd[j]->total, + pd[j]->size, pd[j]->page, pd[j]->next); + } + } + + for(pf=free_list.next; pf; pf=pf->next) { + fprintf(fd,"Free: @%p [%p...%p[ %ld ->%p <-%p\n", + pf,pf->page,pf->end,pf->size,pf->prev,pf->next); + if (pf == pf->next) { + fprintf(fd,"Free_list loops.\n"); + break; + } + } + + /* print out various info */ + fprintf(fd,"Minsize\t%d\n",malloc_minsize); + fprintf(fd,"Maxsize\t%ld\n",malloc_maxsize); + fprintf(fd,"Pagesize\t%ld\n",malloc_pagesize); + fprintf(fd,"Pageshift\t%ld\n",malloc_pageshift); + fprintf(fd,"FirstPage\t%ld\n",malloc_origo); + fprintf(fd,"LastPage\t%ld %lx\n",last_index+malloc_pageshift, + (last_index + malloc_pageshift) << malloc_pageshift); + fprintf(fd,"Break\t%ld\n",(u_long)sbrk(0) >> malloc_pageshift); +} + +static void wrterror(char *fmt, ...) +{ + char *q = "malloc() error: "; + char buf[100]; + va_list ap; + + suicide = 1; + + va_start(ap, fmt); + PR_vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + fputs(q, stderr); + fputs(buf, stderr); + + malloc_dump(stderr); + PR_Abort(); +} + +static void wrtwarning(char *fmt, ...) +{ + char *q = "malloc() warning: "; + char buf[100]; + va_list ap; + + va_start(ap, fmt); + PR_vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + fputs(q, stderr); + fputs(buf, stderr); +} +#endif /* SANITY */ + + +/* + * Allocate a number of pages from the OS + */ +static caddr_t +map_pages(int pages, int update) +{ + caddr_t result,tail; + + result = ((caddr_t)sbrk(0)) + malloc_pagemask - 1; + result = (caddr_t) ((u_long)result & ~malloc_pagemask); + tail = result + (pages << malloc_pageshift); + if (!brk(tail)) { + last_index = ((u_long)tail >> malloc_pageshift) - malloc_origo -1; + malloc_brk = tail; + TRACE(("%6d S %p .. %p\n",malloc_event++, result, tail)); + if (!update || last_index < malloc_ninfo || + extend_page_directory(last_index)) + return result; + } + TRACE(("%6d s %d %p %d\n",malloc_event++,pages,sbrk(0),errno)); +#ifdef EXTRA_SANITY + wrterror("map_pages fails\n"); +#endif + return 0; +} + +#define set_bit(_pi,_bit) \ + (_pi)->bits[(_bit)/MALLOC_BITS] |= 1L<<((_bit)%MALLOC_BITS) + +#define clr_bit(_pi,_bit) \ + (_pi)->bits[(_bit)/MALLOC_BITS] &= ~(1L<<((_bit)%MALLOC_BITS)); + +#define tst_bit(_pi,_bit) \ + ((_pi)->bits[(_bit)/MALLOC_BITS] & (1L<<((_bit)%MALLOC_BITS))) + +/* + * Extend page directory + */ +static int +extend_page_directory(u_long index) +{ + struct pginfo **young, **old; + int i; + + TRACE(("%6d E %lu\n",malloc_event++,index)); + + /* Make it this many pages */ + i = index * sizeof *page_dir; + i /= malloc_pagesize; + i += 2; + + /* Get new pages, if you used this much mem you don't care :-) */ + young = (struct pginfo**) map_pages(i,0); + if (!young) + return 0; + + /* Copy the old stuff */ + memset(young, 0, i * malloc_pagesize); + memcpy(young, page_dir, + malloc_ninfo * sizeof *page_dir); + + /* register the new size */ + malloc_ninfo = i * malloc_pagesize / sizeof *page_dir; + + /* swap the pointers */ + old = page_dir; + page_dir = young; + + /* Mark the pages */ + index = ((u_long)young >> malloc_pageshift) - malloc_origo; + page_dir[index] = MALLOC_FIRST; + while (--i) { + page_dir[++index] = MALLOC_FOLLOW; + } + + /* Now free the old stuff */ + _PR_UnlockedFree(old); + return 1; +} + +/* + * Set entry in page directory. + * Extend page directory if need be. + */ +static int +set_pgdir(void *ptr, struct pginfo *info) +{ + u_long index = ((u_long)ptr >> malloc_pageshift) - malloc_origo; + + if (index >= malloc_ninfo && !extend_page_directory(index)) + return 0; + page_dir[index] = info; + return 1; +} + +/* + * Initialize the world + */ +static void +malloc_init (void) +{ + int i; + char *p; + + TRACE(("%6d I\n",malloc_event++)); +#ifdef DEBUG + for (p=getenv("MALLOC_OPTIONS"); p && *p; p++) { + switch (*p) { + case 'a': malloc_abort = 0; break; + case 'A': malloc_abort = 1; break; + case 'd': malloc_stats = 0; break; + case 'D': malloc_stats = 1; break; + case 'r': malloc_realloc = 0; break; + case 'R': malloc_realloc = 1; break; + default: + wrtwarning("Unknown chars in MALLOC_OPTIONS\n"); + break; + } + } +#endif + +#ifndef malloc_pagesize + /* determine our pagesize */ + malloc_pagesize = getpagesize(); +#endif /* malloc_pagesize */ + +#ifndef malloc_pageshift + /* determine how much we shift by to get there */ + for (i = malloc_pagesize; i > 1; i >>= 1) + malloc_pageshift++; +#endif /* malloc_pageshift */ + +#ifndef malloc_cache + malloc_cache = 50 << malloc_pageshift; +#endif /* malloc_cache */ + +#ifndef malloc_minsize + /* + * find the smallest size allocation we will bother about. + * this is determined as the smallest allocation that can hold + * it's own pginfo; + */ + i = 2; + for(;;) { + int j; + + /* Figure out the size of the bits */ + j = malloc_pagesize/i; + j /= 8; + if (j < sizeof(u_long)) + j = sizeof (u_long); + if (sizeof(struct pginfo) + j - sizeof (u_long) <= i) + break; + i += i; + } + malloc_minsize = i; +#endif /* malloc_minsize */ + + + /* Allocate one page for the page directory */ + page_dir = (struct pginfo **) map_pages(1,0); +#ifdef SANITY + if (!page_dir) + wrterror("fatal: my first mmap failed. (check limits ?)\n"); +#endif + + /* + * We need a maximum of malloc_pageshift buckets, steal these from the + * front of the page_directory; + */ + malloc_origo = (u_long) page_dir >> malloc_pageshift; + malloc_origo -= malloc_pageshift; + + /* Clear it */ + memset(page_dir,0,malloc_pagesize); + + /* Find out how much it tells us */ + malloc_ninfo = malloc_pagesize / sizeof *page_dir; + + /* Plug the page directory into itself */ + i = set_pgdir(page_dir,MALLOC_FIRST); +#ifdef SANITY + if (!i) + wrterror("fatal: couldn't set myself in the page directory\n"); +#endif + + /* Been here, done that */ + initialized++; +} + +/* + * Allocate a number of complete pages + */ +static void *malloc_pages(size_t size) +{ + void *p,*delay_free = 0; + int i; + struct pgfree *pf; + u_long index; + + /* How many pages ? */ + size += (malloc_pagesize-1); + size &= ~malloc_pagemask; + + p = 0; + /* Look for free pages before asking for more */ + for(pf = free_list.next; pf; pf = pf->next) { +#ifdef EXTRA_SANITY + if (pf->page == pf->end) + wrterror("zero entry on free_list\n"); + if (pf->page > pf->end) { + TRACE(("%6d !s %p %p %p <%d>\n",malloc_event++, + pf,pf->page,pf->end,__LINE__)); + wrterror("sick entry on free_list\n"); + } + if ((void*)pf->page >= (void*)sbrk(0)) + wrterror("entry on free_list past brk\n"); + if (page_dir[((u_long)pf->page >> malloc_pageshift) - malloc_origo] + != MALLOC_FREE) { + TRACE(("%6d !f %p %p %p <%d>\n",malloc_event++, + pf,pf->page,pf->end,__LINE__)); + wrterror("non-free first page on free-list\n"); + } + if (page_dir[((u_long)pf->end >> malloc_pageshift) - 1 - malloc_origo] + != MALLOC_FREE) + wrterror("non-free last page on free-list\n"); +#endif /* EXTRA_SANITY */ + if (pf->size < size) + continue; + else if (pf->size == size) { + p = pf->page; + if (pf->next) + pf->next->prev = pf->prev; + pf->prev->next = pf->next; + delay_free = pf; + break; + } else { + p = pf->page; + pf->page += size; + pf->size -= size; + break; + } + } +#ifdef EXTRA_SANITY + if (p && page_dir[((u_long)p >> malloc_pageshift) - malloc_origo] + != MALLOC_FREE) { + wrterror("allocated non-free page on free-list\n"); + } +#endif /* EXTRA_SANITY */ + + size >>= malloc_pageshift; + + /* Map new pages */ + if (!p) + p = map_pages(size,1); + + if (p) { + /* Mark the pages in the directory */ + index = ((u_long)p >> malloc_pageshift) - malloc_origo; + page_dir[index] = MALLOC_FIRST; + for (i=1;i> bits)+MALLOC_BITS-1) / MALLOC_BITS); + if ((1<<(bits)) <= l+l) { + bp = (struct pginfo *)pp; + } else { + bp = (struct pginfo *)_PR_UnlockedMalloc(l); + } + if (!bp) + return 0; + bp->size = (1<shift = bits; + bp->total = bp->free = malloc_pagesize >> bits; + bp->next = page_dir[bits]; + bp->page = (char*)pp; + i = set_pgdir(pp,bp); + if (!i) + return 0; + + /* We can safely assume that there is nobody in this chain */ + page_dir[bits] = bp; + + /* set all valid bits in the bits */ + k = bp->total; + i = 0; +/* + for(;k-i >= MALLOC_BITS; i += MALLOC_BITS) + bp->bits[i / MALLOC_BITS] = ~0; +*/ + for(; i < k; i++) + set_bit(bp,i); + + if (bp != pp) + return 1; + + /* We may have used the first ones already */ + for(i=0;l > 0;i++) { + clr_bit(bp,i); + bp->free--; + bp->total--; + l -= (1 << bits); + } + return 1; +} + +/* + * Allocate a fragment + */ +static void *malloc_bytes(size_t size) +{ + size_t s; + int j; + struct pginfo *bp; + int k; + u_long *lp, bf; + + /* Don't bother with anything less than this */ + if (size < malloc_minsize) { + size = malloc_minsize; + } + + /* Find the right bucket */ + j = 1; + s = size - 1; + while (s >>= 1) { + j++; + } + + /* If it's empty, make a page more of that size chunks */ + if (!page_dir[j] && !malloc_make_chunks(j)) + return 0; + + /* Find first word of bitmap which isn't empty */ + bp = page_dir[j]; + for (lp = bp->bits; !*lp; lp++) + ; + + /* Find that bit */ + bf = *lp; + k = 0; + while ((bf & 1) == 0) { + bf >>= 1; + k++; + } + + *lp ^= 1L<free--; + if (!bp->free) { + page_dir[j] = bp->next; + bp->next = 0; + } + k += (lp - bp->bits)*MALLOC_BITS; + return bp->page + (k << bp->shift); +} + +void *_PR_UnlockedMalloc(size_t size) +{ + void *result; + + /* Round up to a multiple of 8 bytes */ + if (size & 7) { + size = size + 8 - (size & 7); + } + + if (!initialized) + malloc_init(); + +#ifdef SANITY + if (suicide) + PR_Abort(); +#endif + + if (size <= malloc_maxsize) + result = malloc_bytes(size); + else + result = malloc_pages(size); +#ifdef SANITY + if (malloc_abort && !result) + wrterror("malloc() returns NULL\n"); +#endif + TRACE(("%6d M %p %d\n",malloc_event++,result,size)); + + return result; +} + +void *_PR_UnlockedMemalign(size_t alignment, size_t size) +{ + void *result; + + /* + * alignment has to be a power of 2 + */ + + if ((size <= alignment) && (alignment <= malloc_maxsize)) + size = alignment; + else + size += alignment - 1; + + /* Round up to a multiple of 8 bytes */ + if (size & 7) { + size = size + 8 - (size & 7); + } + + if (!initialized) + malloc_init(); + +#ifdef SANITY + if (suicide) + abort(); +#endif + + if (size <= malloc_maxsize) + result = malloc_bytes(size); + else + result = malloc_pages(size); +#ifdef SANITY + if (malloc_abort && !result) + wrterror("malloc() returns NULL\n"); +#endif + TRACE(("%6d A %p %d\n",malloc_event++,result,size)); + + if ((u_long)result & (alignment - 1)) + return ((void *)(((u_long)result + alignment) & ~(alignment - 1))); + else + return result; +} + +void *_PR_UnlockedCalloc(size_t n, size_t nelem) +{ + void *p; + + /* Compute total size and then round up to a double word amount */ + n *= nelem; + if (n & 7) { + n = n + 8 - (n & 7); + } + + /* Get the memory */ + p = _PR_UnlockedMalloc(n); + if (p) { + /* Zero it */ + memset(p, 0, n); + } + return p; +} + +/* + * Change an allocation's size + */ +void *_PR_UnlockedRealloc(void *ptr, size_t size) +{ + void *p; + u_long osize,page,index,tmp_index; + struct pginfo **mp; + + if (!initialized) + malloc_init(); + +#ifdef SANITY + if (suicide) + PR_Abort(); +#endif + + /* used as free() */ + TRACE(("%6d R %p %d\n",malloc_event++, ptr, size)); + if (ptr && !size) { + _PR_UnlockedFree(ptr); + return _PR_UnlockedMalloc (1); + } + + /* used as malloc() */ + if (!ptr) { + p = _PR_UnlockedMalloc(size); + return p; + } + + /* Find the page directory entry for the page in question */ + page = (u_long)ptr >> malloc_pageshift; + index = page - malloc_origo; + + /* + * check if memory was allocated by memalign + */ + tmp_index = index; + while (page_dir[tmp_index] == MALLOC_FOLLOW) + tmp_index--; + if (tmp_index != index) { + /* + * memalign-allocated memory + */ + index = tmp_index; + page = index + malloc_origo; + ptr = (void *) (page << malloc_pageshift); + } + TRACE(("%6d R2 %p %d\n",malloc_event++, ptr, size)); + + /* make sure it makes sense in some fashion */ + if (index < malloc_pageshift || index > last_index) { +#ifdef SANITY + wrtwarning("junk pointer passed to realloc()\n"); +#endif + return 0; + } + + /* find the size of that allocation, and see if we need to relocate */ + mp = &page_dir[index]; + if (*mp == MALLOC_FIRST) { + osize = malloc_pagesize; + while (mp[1] == MALLOC_FOLLOW) { + osize += malloc_pagesize; + mp++; + } + if (!malloc_realloc && + size < osize && + size > malloc_maxsize && + size > (osize - malloc_pagesize)) { + return ptr; + } + } else if (*mp >= MALLOC_MAGIC) { + osize = (*mp)->size; + if (!malloc_realloc && + size < osize && + (size > (*mp)->size/2 || (*mp)->size == malloc_minsize)) { + return ptr; + } + } else { +#ifdef SANITY + wrterror("realloc() of wrong page.\n"); +#endif + } + + /* try to reallocate */ + p = _PR_UnlockedMalloc(size); + + if (p) { + /* copy the lesser of the two sizes */ + if (osize < size) + memcpy(p,ptr,osize); + else + memcpy(p,ptr,size); + _PR_UnlockedFree(ptr); + } +#ifdef DEBUG + else if (malloc_abort) + wrterror("realloc() returns NULL\n"); +#endif + + return p; +} + +/* + * Free a sequence of pages + */ + +static void +free_pages(char *ptr, u_long page, int index, struct pginfo *info) +{ + int i; + struct pgfree *pf,*pt; + u_long l; + char *tail; + + TRACE(("%6d FP %p %d\n",malloc_event++, ptr, page)); + /* Is it free already ? */ + if (info == MALLOC_FREE) { +#ifdef SANITY + wrtwarning("freeing free page at %p.\n", ptr); +#endif + return; + } + +#ifdef SANITY + /* Is it not the right place to begin ? */ + if (info != MALLOC_FIRST) + wrterror("freeing wrong page.\n"); + + /* Is this really a pointer to a page ? */ + if ((u_long)ptr & malloc_pagemask) + wrterror("freeing messed up page pointer.\n"); +#endif + + /* Count how many pages it is anyway */ + page_dir[index] = MALLOC_FREE; + for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++) + page_dir[index + i] = MALLOC_FREE; + + l = i << malloc_pageshift; + + tail = ptr+l; + + /* add to free-list */ + if (!px) + px = (struct pgfree*)_PR_UnlockedMalloc(sizeof *pt); + /* XXX check success */ + px->page = ptr; + px->end = tail; + px->size = l; + if (!free_list.next) { + px->next = free_list.next; + px->prev = &free_list; + free_list.next = px; + pf = px; + px = 0; + } else { + tail = ptr+l; + for(pf = free_list.next; pf->next && pf->end < ptr; pf = pf->next) + ; + for(; pf; pf = pf->next) { + if (pf->end == ptr ) { + /* append to entry */ + pf->end += l; + pf->size += l; + if (pf->next && pf->end == pf->next->page ) { + pt = pf->next; + pf->end = pt->end; + pf->size += pt->size; + pf->next = pt->next; + if (pf->next) + pf->next->prev = pf; + _PR_UnlockedFree(pt); + } + } else if (pf->page == tail) { + /* prepend to entry */ + pf->size += l; + pf->page = ptr; + } else if (pf->page > ptr) { + px->next = pf; + px->prev = pf->prev; + pf->prev = px; + px->prev->next = px; + pf = px; + px = 0; + } else if (!pf->next) { + px->next = 0; + px->prev = pf; + pf->next = px; + pf = px; + px = 0; + } else { + continue; + } + break; + } + } + if (!pf->next && + pf->size > malloc_cache && + pf->end == malloc_brk && + malloc_brk == (void*)sbrk(0)) { + pf->end = pf->page + malloc_cache; + pf->size = malloc_cache; + TRACE(("%6d U %p %d\n",malloc_event++,pf->end,pf->end - pf->page)); + brk(pf->end); + malloc_brk = pf->end; + /* Find the page directory entry for the page in question */ + page = (u_long)pf->end >> malloc_pageshift; + index = page - malloc_origo; + /* Now update the directory */ + for(i=index;i <= last_index;) + page_dir[i++] = MALLOC_NOT_MINE; + last_index = index - 1; + } +} + +/* + * Free a chunk, and possibly the page it's on, if the page becomes empty. + */ + +static void +free_bytes(void *ptr, u_long page, int index, struct pginfo *info) +{ + int i; + struct pginfo **mp; + void *vp; + + /* Make sure that pointer is multiplum of chunk-size */ +#ifdef SANITY + if ((u_long)ptr & (info->size - 1)) + wrterror("freeing messed up chunk pointer\n"); +#endif + + /* Find the chunk number on the page */ + i = ((u_long)ptr & malloc_pagemask) >> info->shift; + + /* See if it's free already */ + if (tst_bit(info,i)) { +#ifdef SANITY + wrtwarning("freeing free chunk at %p\n", ptr); +#endif + return; + } + + /* Mark it free */ + set_bit(info,i); + info->free++; + + /* If the page was full before, we need to put it on the queue now */ + if (info->free == 1) { + mp = page_dir + info->shift; + while (*mp && (*mp)->next && (*mp)->next->page < info->page) + mp = &(*mp)->next; + info->next = *mp; + *mp = info; + return; + } + + /* If this page isn't empty, don't do anything. */ + if (info->free != info->total) + return; + + /* We may want to keep at least one page of each size chunks around. */ + mp = page_dir + info->shift; + if (0 && (*mp == info) && !info->next) + return; + + /* Find & remove this page in the queue */ + while (*mp != info) { + mp = &((*mp)->next); +#ifdef EXTRA_SANITY + if (!*mp) { + TRACE(("%6d !q %p\n",malloc_event++,info)); + wrterror("Not on queue\n"); + } +#endif + } + *mp = info->next; + + /* Free the page & the info structure if need be */ + set_pgdir(info->page,MALLOC_FIRST); + if((void*)info->page == (void*)info) { + _PR_UnlockedFree(info->page); + } else { + vp = info->page; + _PR_UnlockedFree(info); + _PR_UnlockedFree(vp); + } +} + +void _PR_UnlockedFree(void *ptr) +{ + u_long page; + struct pginfo *info; + int index, tmp_index; + + TRACE(("%6d F %p\n",malloc_event++,ptr)); + /* This is legal */ + if (!ptr) + return; + +#ifdef SANITY + /* There wouldn't be anything to free */ + if (!initialized) { + wrtwarning("free() called before malloc() ever got called\n"); + return; + } +#endif + +#ifdef SANITY + if (suicide) + PR_Abort(); +#endif + + /* Find the page directory entry for the page in question */ + page = (u_long)ptr >> malloc_pageshift; + index = page - malloc_origo; + + /* + * check if memory was allocated by memalign + */ + tmp_index = index; + while (page_dir[tmp_index] == MALLOC_FOLLOW) + tmp_index--; + if (tmp_index != index) { + /* + * memalign-allocated memory + */ + index = tmp_index; + page = index + malloc_origo; + ptr = (void *) (page << malloc_pageshift); + } + /* make sure it makes sense in some fashion */ + if (index < malloc_pageshift) { +#ifdef SANITY + wrtwarning("junk pointer %p (low) passed to free()\n", ptr); +#endif + return; + } + if (index > last_index) { +#ifdef SANITY + wrtwarning("junk pointer %p (high) passed to free()\n", ptr); +#endif + return; + } + + /* handle as page-allocation or chunk allocation */ + info = page_dir[index]; + if (info < MALLOC_MAGIC) + free_pages((char*)ptr, page, index, info); + else + free_bytes(ptr,page,index,info); + return; +} +#endif /* _PR_OVERRIDE_MALLOC */ diff -Nru nspr-4.9.5/nspr/pr/src/malloc/prmem.c nspr-4.10.7/nspr/pr/src/malloc/prmem.c --- nspr-4.9.5/nspr/pr/src/malloc/prmem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/malloc/prmem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,694 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Thread safe versions of malloc, free, realloc, calloc and cfree. +*/ + +#include "primpl.h" + +#ifdef _PR_ZONE_ALLOCATOR + +/* +** The zone allocator code must use native mutexes and cannot +** use PRLocks because PR_NewLock calls PR_Calloc, resulting +** in cyclic dependency of initialization. +*/ + +#include + +union memBlkHdrUn; + +typedef struct MemoryZoneStr { + union memBlkHdrUn *head; /* free list */ + pthread_mutex_t lock; + size_t blockSize; /* size of blocks on this free list */ + PRUint32 locked; /* current state of lock */ + PRUint32 contention; /* counter: had to wait for lock */ + PRUint32 hits; /* allocated from free list */ + PRUint32 misses; /* had to call malloc */ + PRUint32 elements; /* on free list */ +} MemoryZone; + +typedef union memBlkHdrUn { + unsigned char filler[48]; /* fix the size of this beast */ + struct memBlkHdrStr { + union memBlkHdrUn *next; + MemoryZone *zone; + size_t blockSize; + size_t requestedSize; + PRUint32 magic; + } s; +} MemBlockHdr; + +#define MEM_ZONES 7 +#define THREAD_POOLS 11 /* prime number for modulus */ +#define ZONE_MAGIC 0x0BADC0DE + +static MemoryZone zones[MEM_ZONES][THREAD_POOLS]; + +static PRBool use_zone_allocator = PR_FALSE; + +static void pr_ZoneFree(void *ptr); + +void +_PR_DestroyZones(void) +{ + int i, j; + + if (!use_zone_allocator) + return; + + for (j = 0; j < THREAD_POOLS; j++) { + for (i = 0; i < MEM_ZONES; i++) { + MemoryZone *mz = &zones[i][j]; + pthread_mutex_destroy(&mz->lock); + while (mz->head) { + MemBlockHdr *hdr = mz->head; + mz->head = hdr->s.next; /* unlink it */ + free(hdr); + mz->elements--; + } + } + } + use_zone_allocator = PR_FALSE; +} + +/* +** pr_FindSymbolInProg +** +** Find the specified data symbol in the program and return +** its address. +*/ + +#ifdef HAVE_DLL + +#if defined(USE_DLFCN) && !defined(NO_DLOPEN_NULL) + +#include + +static void * +pr_FindSymbolInProg(const char *name) +{ + void *h; + void *sym; + + h = dlopen(0, RTLD_LAZY); + if (h == NULL) + return NULL; + sym = dlsym(h, name); + (void)dlclose(h); + return sym; +} + +#elif defined(USE_HPSHL) + +#include + +static void * +pr_FindSymbolInProg(const char *name) +{ + shl_t h = NULL; + void *sym; + + if (shl_findsym(&h, name, TYPE_DATA, &sym) == -1) + return NULL; + return sym; +} + +#elif defined(USE_MACH_DYLD) || defined(NO_DLOPEN_NULL) + +static void * +pr_FindSymbolInProg(const char *name) +{ + /* FIXME: not implemented */ + return NULL; +} + +#else + +#error "The zone allocator is not supported on this platform" + +#endif + +#else /* !defined(HAVE_DLL) */ + +static void * +pr_FindSymbolInProg(const char *name) +{ + /* can't be implemented */ + return NULL; +} + +#endif /* HAVE_DLL */ + +void +_PR_InitZones(void) +{ + int i, j; + char *envp; + PRBool *sym; + + if ((sym = (PRBool *)pr_FindSymbolInProg("nspr_use_zone_allocator")) != NULL) { + use_zone_allocator = *sym; + } else if ((envp = getenv("NSPR_USE_ZONE_ALLOCATOR")) != NULL) { + use_zone_allocator = (atoi(envp) == 1); + } + + if (!use_zone_allocator) + return; + + for (j = 0; j < THREAD_POOLS; j++) { + for (i = 0; i < MEM_ZONES; i++) { + MemoryZone *mz = &zones[i][j]; + int rv = pthread_mutex_init(&mz->lock, NULL); + PR_ASSERT(0 == rv); + if (rv != 0) { + goto loser; + } + mz->blockSize = 16 << ( 2 * i); + } + } + return; + +loser: + _PR_DestroyZones(); + return; +} + +PR_IMPLEMENT(void) +PR_FPrintZoneStats(PRFileDesc *debug_out) +{ + int i, j; + + for (j = 0; j < THREAD_POOLS; j++) { + for (i = 0; i < MEM_ZONES; i++) { + MemoryZone *mz = &zones[i][j]; + MemoryZone zone = *mz; + if (zone.elements || zone.misses || zone.hits) { + PR_fprintf(debug_out, +"pool: %d, zone: %d, size: %d, free: %d, hit: %d, miss: %d, contend: %d\n", + j, i, zone.blockSize, zone.elements, + zone.hits, zone.misses, zone.contention); + } + } + } +} + +static void * +pr_ZoneMalloc(PRUint32 size) +{ + void *rv; + unsigned int zone; + size_t blockSize; + MemBlockHdr *mb, *mt; + MemoryZone *mz; + + /* Always allocate a non-zero amount of bytes */ + if (size < 1) { + size = 1; + } + for (zone = 0, blockSize = 16; zone < MEM_ZONES; ++zone, blockSize <<= 2) { + if (size <= blockSize) { + break; + } + } + if (zone < MEM_ZONES) { + pthread_t me = pthread_self(); + unsigned int pool = (PRUptrdiff)me % THREAD_POOLS; + PRUint32 wasLocked; + mz = &zones[zone][pool]; + wasLocked = mz->locked; + pthread_mutex_lock(&mz->lock); + mz->locked = 1; + if (wasLocked) + mz->contention++; + if (mz->head) { + mb = mz->head; + PR_ASSERT(mb->s.magic == ZONE_MAGIC); + PR_ASSERT(mb->s.zone == mz); + PR_ASSERT(mb->s.blockSize == blockSize); + PR_ASSERT(mz->blockSize == blockSize); + + mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); + PR_ASSERT(mt->s.magic == ZONE_MAGIC); + PR_ASSERT(mt->s.zone == mz); + PR_ASSERT(mt->s.blockSize == blockSize); + + mz->hits++; + mz->elements--; + mz->head = mb->s.next; /* take off free list */ + mz->locked = 0; + pthread_mutex_unlock(&mz->lock); + + mt->s.next = mb->s.next = NULL; + mt->s.requestedSize = mb->s.requestedSize = size; + + rv = (void *)(mb + 1); + return rv; + } + + mz->misses++; + mz->locked = 0; + pthread_mutex_unlock(&mz->lock); + + mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb)); + if (!mb) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + mb->s.next = NULL; + mb->s.zone = mz; + mb->s.magic = ZONE_MAGIC; + mb->s.blockSize = blockSize; + mb->s.requestedSize = size; + + mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); + memcpy(mt, mb, sizeof *mb); + + rv = (void *)(mb + 1); + return rv; + } + + /* size was too big. Create a block with no zone */ + blockSize = (size & 15) ? size + 16 - (size & 15) : size; + mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb)); + if (!mb) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + mb->s.next = NULL; + mb->s.zone = NULL; + mb->s.magic = ZONE_MAGIC; + mb->s.blockSize = blockSize; + mb->s.requestedSize = size; + + mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); + memcpy(mt, mb, sizeof *mb); + + rv = (void *)(mb + 1); + return rv; +} + + +static void * +pr_ZoneCalloc(PRUint32 nelem, PRUint32 elsize) +{ + PRUint32 size = nelem * elsize; + void *p = pr_ZoneMalloc(size); + if (p) { + memset(p, 0, size); + } + return p; +} + +static void * +pr_ZoneRealloc(void *oldptr, PRUint32 bytes) +{ + void *rv; + MemBlockHdr *mb; + int ours; + MemBlockHdr phony; + + if (!oldptr) + return pr_ZoneMalloc(bytes); + mb = (MemBlockHdr *)((char *)oldptr - (sizeof *mb)); + if (mb->s.magic != ZONE_MAGIC) { + /* Maybe this just came from ordinary malloc */ +#ifdef DEBUG + fprintf(stderr, + "Warning: reallocing memory block %p from ordinary malloc\n", + oldptr); +#endif + /* + * We are going to realloc oldptr. If realloc succeeds, the + * original value of oldptr will point to freed memory. So this + * function must not fail after a successfull realloc call. We + * must perform any operation that may fail before the realloc + * call. + */ + rv = pr_ZoneMalloc(bytes); /* this may fail */ + if (!rv) { + return rv; + } + + /* We don't know how big it is. But we can fix that. */ + oldptr = realloc(oldptr, bytes); + /* + * If realloc returns NULL, this function loses the original + * value of oldptr. This isn't a leak because the caller of + * this function still has the original value of oldptr. + */ + if (!oldptr) { + if (bytes) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + pr_ZoneFree(rv); + return oldptr; + } + } + phony.s.requestedSize = bytes; + mb = &phony; + ours = 0; + } else { + size_t blockSize = mb->s.blockSize; + MemBlockHdr *mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); + + PR_ASSERT(mt->s.magic == ZONE_MAGIC); + PR_ASSERT(mt->s.zone == mb->s.zone); + PR_ASSERT(mt->s.blockSize == blockSize); + + if (bytes <= blockSize) { + /* The block is already big enough. */ + mt->s.requestedSize = mb->s.requestedSize = bytes; + return oldptr; + } + ours = 1; + rv = pr_ZoneMalloc(bytes); + if (!rv) { + return rv; + } + } + + if (oldptr && mb->s.requestedSize) + memcpy(rv, oldptr, mb->s.requestedSize); + if (ours) + pr_ZoneFree(oldptr); + else if (oldptr) + free(oldptr); + return rv; +} + +static void +pr_ZoneFree(void *ptr) +{ + MemBlockHdr *mb, *mt; + MemoryZone *mz; + size_t blockSize; + PRUint32 wasLocked; + + if (!ptr) + return; + + mb = (MemBlockHdr *)((char *)ptr - (sizeof *mb)); + + if (mb->s.magic != ZONE_MAGIC) { + /* maybe this came from ordinary malloc */ +#ifdef DEBUG + fprintf(stderr, + "Warning: freeing memory block %p from ordinary malloc\n", ptr); +#endif + free(ptr); + return; + } + + blockSize = mb->s.blockSize; + mz = mb->s.zone; + mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); + PR_ASSERT(mt->s.magic == ZONE_MAGIC); + PR_ASSERT(mt->s.zone == mz); + PR_ASSERT(mt->s.blockSize == blockSize); + if (!mz) { + PR_ASSERT(blockSize > 65536); + /* This block was not in any zone. Just free it. */ + free(mb); + return; + } + PR_ASSERT(mz->blockSize == blockSize); + wasLocked = mz->locked; + pthread_mutex_lock(&mz->lock); + mz->locked = 1; + if (wasLocked) + mz->contention++; + mt->s.next = mb->s.next = mz->head; /* put on head of list */ + mz->head = mb; + mz->elements++; + mz->locked = 0; + pthread_mutex_unlock(&mz->lock); +} + +PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + return use_zone_allocator ? pr_ZoneMalloc(size) : malloc(size); +} + +PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + return use_zone_allocator ? + pr_ZoneCalloc(nelem, elsize) : calloc(nelem, elsize); +} + +PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + return use_zone_allocator ? pr_ZoneRealloc(ptr, size) : realloc(ptr, size); +} + +PR_IMPLEMENT(void) PR_Free(void *ptr) +{ + if (use_zone_allocator) + pr_ZoneFree(ptr); + else + free(ptr); +} + +#else /* !defined(_PR_ZONE_ALLOCATOR) */ + +/* +** The PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free functions simply +** call their libc equivalents now. This may seem redundant, but it +** ensures that we are calling into the same runtime library. On +** Win32, it is possible to have multiple runtime libraries (e.g., +** objects compiled with /MD and /MDd) in the same process, and +** they maintain separate heaps, which cannot be mixed. +*/ +PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size) +{ +#if defined (WIN16) + return PR_MD_malloc( (size_t) size); +#else + return malloc(size); +#endif +} + +PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize) +{ +#if defined (WIN16) + return PR_MD_calloc( (size_t)nelem, (size_t)elsize ); + +#else + return calloc(nelem, elsize); +#endif +} + +PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size) +{ +#if defined (WIN16) + return PR_MD_realloc( ptr, (size_t) size); +#else + return realloc(ptr, size); +#endif +} + +PR_IMPLEMENT(void) PR_Free(void *ptr) +{ +#if defined (WIN16) + PR_MD_free( ptr ); +#else + free(ptr); +#endif +} + +#endif /* _PR_ZONE_ALLOCATOR */ + +/* +** Complexity alert! +** +** If malloc/calloc/free (etc.) were implemented to use pr lock's then +** the entry points could block when called if some other thread had the +** lock. +** +** Most of the time this isn't a problem. However, in the case that we +** are using the thread safe malloc code after PR_Init but before +** PR_AttachThread has been called (on a native thread that nspr has yet +** to be told about) we could get royally screwed if the lock was busy +** and we tried to context switch the thread away. In this scenario +** PR_CURRENT_THREAD() == NULL +** +** To avoid this unfortunate case, we use the low level locking +** facilities for malloc protection instead of the slightly higher level +** locking. This makes malloc somewhat faster so maybe it's a good thing +** anyway. +*/ +#ifdef _PR_OVERRIDE_MALLOC + +/* Imports */ +extern void *_PR_UnlockedMalloc(size_t size); +extern void *_PR_UnlockedMemalign(size_t alignment, size_t size); +extern void _PR_UnlockedFree(void *ptr); +extern void *_PR_UnlockedRealloc(void *ptr, size_t size); +extern void *_PR_UnlockedCalloc(size_t n, size_t elsize); + +static PRBool _PR_malloc_initialised = PR_FALSE; + +#ifdef _PR_PTHREADS +static pthread_mutex_t _PR_MD_malloc_crustylock; + +#define _PR_Lock_Malloc() { \ + if(PR_TRUE == _PR_malloc_initialised) { \ + PRStatus rv; \ + rv = pthread_mutex_lock(&_PR_MD_malloc_crustylock); \ + PR_ASSERT(0 == rv); \ + } + +#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ + PRStatus rv; \ + rv = pthread_mutex_unlock(&_PR_MD_malloc_crustylock); \ + PR_ASSERT(0 == rv); \ + } \ + } +#else /* _PR_PTHREADS */ +static _MDLock _PR_MD_malloc_crustylock; + +#ifdef IRIX +#define _PR_Lock_Malloc() { \ + PRIntn _is; \ + if(PR_TRUE == _PR_malloc_initialised) { \ + if (_PR_MD_GET_ATTACHED_THREAD() && \ + !_PR_IS_NATIVE_THREAD( \ + _PR_MD_GET_ATTACHED_THREAD())) \ + _PR_INTSOFF(_is); \ + _PR_MD_LOCK(&_PR_MD_malloc_crustylock); \ + } + +#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ + _PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \ + if (_PR_MD_GET_ATTACHED_THREAD() && \ + !_PR_IS_NATIVE_THREAD( \ + _PR_MD_GET_ATTACHED_THREAD())) \ + _PR_INTSON(_is); \ + } \ + } +#else /* IRIX */ +#define _PR_Lock_Malloc() { \ + PRIntn _is; \ + if(PR_TRUE == _PR_malloc_initialised) { \ + if (_PR_MD_CURRENT_THREAD() && \ + !_PR_IS_NATIVE_THREAD( \ + _PR_MD_CURRENT_THREAD())) \ + _PR_INTSOFF(_is); \ + _PR_MD_LOCK(&_PR_MD_malloc_crustylock); \ + } + +#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ + _PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \ + if (_PR_MD_CURRENT_THREAD() && \ + !_PR_IS_NATIVE_THREAD( \ + _PR_MD_CURRENT_THREAD())) \ + _PR_INTSON(_is); \ + } \ + } +#endif /* IRIX */ +#endif /* _PR_PTHREADS */ + +PR_IMPLEMENT(PRStatus) _PR_MallocInit(void) +{ + PRStatus rv = PR_SUCCESS; + + if( PR_TRUE == _PR_malloc_initialised ) return PR_SUCCESS; + +#ifdef _PR_PTHREADS + { + int status; + pthread_mutexattr_t mattr; + + status = _PT_PTHREAD_MUTEXATTR_INIT(&mattr); + PR_ASSERT(0 == status); + status = _PT_PTHREAD_MUTEX_INIT(_PR_MD_malloc_crustylock, mattr); + PR_ASSERT(0 == status); + status = _PT_PTHREAD_MUTEXATTR_DESTROY(&mattr); + PR_ASSERT(0 == status); + } +#else /* _PR_PTHREADS */ + _MD_NEW_LOCK(&_PR_MD_malloc_crustylock); +#endif /* _PR_PTHREADS */ + + if( PR_SUCCESS == rv ) + { + _PR_malloc_initialised = PR_TRUE; + } + + return rv; +} + +void *malloc(size_t size) +{ + void *p; + _PR_Lock_Malloc(); + p = _PR_UnlockedMalloc(size); + _PR_Unlock_Malloc(); + return p; +} + +#if defined(IRIX) +void *memalign(size_t alignment, size_t size) +{ + void *p; + _PR_Lock_Malloc(); + p = _PR_UnlockedMemalign(alignment, size); + _PR_Unlock_Malloc(); + return p; +} + +void *valloc(size_t size) +{ + return(memalign(sysconf(_SC_PAGESIZE),size)); +} +#endif /* IRIX */ + +void free(void *ptr) +{ + _PR_Lock_Malloc(); + _PR_UnlockedFree(ptr); + _PR_Unlock_Malloc(); +} + +void *realloc(void *ptr, size_t size) +{ + void *p; + _PR_Lock_Malloc(); + p = _PR_UnlockedRealloc(ptr, size); + _PR_Unlock_Malloc(); + return p; +} + +void *calloc(size_t n, size_t elsize) +{ + void *p; + _PR_Lock_Malloc(); + p = _PR_UnlockedCalloc(n, elsize); + _PR_Unlock_Malloc(); + return p; +} + +void cfree(void *p) +{ + _PR_Lock_Malloc(); + _PR_UnlockedFree(p); + _PR_Unlock_Malloc(); +} + +void _PR_InitMem(void) +{ + PRStatus rv; + rv = _PR_MallocInit(); + PR_ASSERT(PR_SUCCESS == rv); +} + +#endif /* _PR_OVERRIDE_MALLOC */ diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bcpu.c nspr-4.10.7/nspr/pr/src/md/beos/bcpu.c --- nspr-4.9.5/nspr/pr/src/md/beos/bcpu.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bcpu.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,23 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +PR_EXTERN(void) _PR_MD_INIT_CPUS(); +PR_EXTERN(void) _PR_MD_WAKEUP_CPUS(); +PR_EXTERN(void) _PR_MD_START_INTERRUPTS(void); +PR_EXTERN(void) _PR_MD_STOP_INTERRUPTS(void); +PR_EXTERN(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void); +PR_EXTERN(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void); +PR_EXTERN(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void); +PR_EXTERN(void) _PR_MD_CLOCK_INTERRUPT(void); +PR_EXTERN(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone); +PR_EXTERN(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts); +PR_EXTERN(PRInt32) _PR_MD_GET_INTSOFF(void); +PR_EXTERN(void) _PR_MD_SET_INTSOFF(PRInt32 _val); +PR_EXTERN(_PRCPU*) _PR_MD_CURRENT_CPU(void); +PR_EXTERN(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu); +PR_EXTERN(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu); +PR_EXTERN(PRInt32) _PR_MD_PAUSE_CPU(PRIntervalTime timeout); diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/beos.c nspr-4.10.7/nspr/pr/src/md/beos/beos.c --- nspr-4.9.5/nspr/pr/src/md/beos/beos.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/beos.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or + * PRInt32* pointer to a _PRSockLen_t* pointer. + */ +#define _PRSockLen_t int + +/* +** Global lock variable used to bracket calls into rusty libraries that +** aren't thread safe (like libc, libX, etc). +*/ +static PRLock *_pr_rename_lock = NULL; +static PRMonitor *_pr_Xfe_mon = NULL; + +/* + * Variables used by the GC code, initialized in _MD_InitSegs(). + * _pr_zero_fd should be a static variable. Unfortunately, there is + * still some Unix-specific code left in function PR_GrowSegment() + * in file memory/prseg.c that references it, so it needs + * to be a global variable for now. + */ +PRInt32 _pr_zero_fd = -1; +static PRLock *_pr_md_lock = NULL; + +sigset_t timer_set; + +void _PR_UnixInit() +{ + struct sigaction sigact; + int rv; + + sigemptyset(&timer_set); + + sigact.sa_handler = SIG_IGN; + sigemptyset(&sigact.sa_mask); + sigact.sa_flags = 0; + rv = sigaction(SIGPIPE, &sigact, 0); + PR_ASSERT(0 == rv); + + _pr_rename_lock = PR_NewLock(); + PR_ASSERT(NULL != _pr_rename_lock); + _pr_Xfe_mon = PR_NewMonitor(); + PR_ASSERT(NULL != _pr_Xfe_mon); +} + +/* + *----------------------------------------------------------------------- + * + * PR_Now -- + * + * Returns the current time in microseconds since the epoch. + * The epoch is midnight January 1, 1970 GMT. + * The implementation is machine dependent. This is the Unix + * implementation. + * Cf. time_t time(time_t *tp) + * + *----------------------------------------------------------------------- + */ + +PR_IMPLEMENT(PRTime) +PR_Now(void) +{ + struct timeval tv; + PRInt64 s, us, s2us; + + GETTIMEOFDAY(&tv); + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(s, tv.tv_sec); + LL_I2L(us, tv.tv_usec); + LL_MUL(s, s, s2us); + LL_ADD(s, s, us); + return s; +} + +PRIntervalTime +_PR_UNIX_GetInterval() +{ + struct timeval time; + PRIntervalTime ticks; + + (void)GETTIMEOFDAY(&time); /* fallicy of course */ + ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; /* that's in milliseconds */ + ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC; /* so's that */ + return ticks; +} /* _PR_SUNOS_GetInterval */ + +PRIntervalTime _PR_UNIX_TicksPerSecond() +{ + return 1000; /* this needs some work :) */ +} + +/************************************************************************/ + +/* +** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread +** safe. Unfortunately, neither is mozilla. To make these programs work +** in a pre-emptive threaded environment, we need to use a lock. +*/ + +void PR_XLock() +{ + PR_EnterMonitor(_pr_Xfe_mon); +} + +void PR_XUnlock() +{ + PR_ExitMonitor(_pr_Xfe_mon); +} + +PRBool PR_XIsLocked() +{ + return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE; +} + +void PR_XWait(int ms) +{ + PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms)); +} + +void PR_XNotify(void) +{ + PR_Notify(_pr_Xfe_mon); +} + +void PR_XNotifyAll(void) +{ + PR_NotifyAll(_pr_Xfe_mon); +} + +#if !defined(BEOS) +#ifdef HAVE_BSD_FLOCK + +#include + +PR_IMPLEMENT(PRStatus) +_MD_LOCKFILE (PRInt32 f) +{ + PRInt32 rv; + rv = flock(f, LOCK_EX); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) +_MD_TLOCKFILE (PRInt32 f) +{ + PRInt32 rv; + rv = flock(f, LOCK_EX|LOCK_NB); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) +_MD_UNLOCKFILE (PRInt32 f) +{ + PRInt32 rv; + rv = flock(f, LOCK_UN); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} +#else + +PR_IMPLEMENT(PRStatus) +_MD_LOCKFILE (PRInt32 f) +{ + PRInt32 rv; + rv = lockf(f, F_LOCK, 0); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) +_MD_TLOCKFILE (PRInt32 f) +{ + PRInt32 rv; + rv = lockf(f, F_TLOCK, 0); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) +_MD_UNLOCKFILE (PRInt32 f) +{ + PRInt32 rv; + rv = lockf(f, F_ULOCK, 0); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} +#endif + +PR_IMPLEMENT(PRStatus) + _MD_GETHOSTNAME (char *name, PRUint32 namelen) +{ + PRIntn rv; + + rv = gethostname(name, namelen); + if (0 == rv) { + return PR_SUCCESS; + } + _PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +#endif diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/beos_errors.c nspr-4.10.7/nspr/pr/src/md/beos/beos_errors.c --- nspr-4.9.5/nspr/pr/src/md/beos/beos_errors.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/beos_errors.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1494 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prtypes.h" +#include "md/_unix_errors.h" +#include "prerror.h" +#include + +void _MD_unix_map_opendir_error(int err) +{ + switch (err) { + case ENOTDIR: + PR_SetError(PR_NOT_DIRECTORY_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EMFILE: + PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); + break; + case ENFILE: + PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ELOOP: + PR_SetError(PR_LOOP_ERROR, err); + break; + case ENAMETOOLONG: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_closedir_error(int err) +{ + switch (err) { + case EINVAL: + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_readdir_error(int err) +{ + + switch (err) { + case 0: + case ENOENT: + PR_SetError(PR_NO_MORE_FILES_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#ifdef IRIX +#ifdef IRIX5_3 +#else + case EDIRCORRUPTED: + PR_SetError(PR_DIRECTORY_CORRUPTED_ERROR, err); + break; +#endif +#endif +#ifdef EOVERFLOW + case EOVERFLOW: + PR_SetError(PR_IO_ERROR, err); + break; +#endif + case EINVAL: + PR_SetError(PR_IO_ERROR, err); + break; +#ifdef EBADMSG + case EBADMSG: + PR_SetError(PR_IO_ERROR, err); + break; +#endif + case EDEADLK: + PR_SetError(PR_DEADLOCK_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + case ENOLCK: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; +#ifdef ENOLINK + case ENOLINK: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; +#endif + case ENXIO: + PR_SetError(PR_IO_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_unlink_error(int err) +{ + switch (err) { + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EBUSY: + PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case ELOOP: + PR_SetError(PR_LOOP_ERROR, err); + break; + case ENAMETOOLONG: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ENOTDIR: + PR_SetError(PR_NOT_DIRECTORY_ERROR, err); + break; + case EPERM: + PR_SetError(PR_IS_DIRECTORY_ERROR, err); + break; + case EROFS: + PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_stat_error(int err) +{ + switch (err) { + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case ETIMEDOUT: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; + case ELOOP: + PR_SetError(PR_LOOP_ERROR, err); + break; + case ENAMETOOLONG: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ENOTDIR: + PR_SetError(PR_NOT_DIRECTORY_ERROR, err); + break; +#ifdef EOVERFLOW + case EOVERFLOW: + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_fstat_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case ETIMEDOUT: +#ifdef ENOLINK + case ENOLINK: +#endif + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; +#ifdef EOVERFLOW + case EOVERFLOW: + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_rename_error(int err) +{ + switch (err) { + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EBUSY: + PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err); + break; +#ifdef EDQUOT + case EDQUOT: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; +#endif + case EEXIST: + PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + case EISDIR: + PR_SetError(PR_IS_DIRECTORY_ERROR, err); + break; + case ELOOP: + PR_SetError(PR_LOOP_ERROR, err); + break; + case ENAMETOOLONG: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ENOSPC: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; + case ENOTDIR: + PR_SetError(PR_NOT_DIRECTORY_ERROR, err); + break; + case EROFS: + PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); + break; + case EXDEV: + PR_SetError(PR_NOT_SAME_DEVICE_ERROR, err); + break; + case EMLINK: + PR_SetError(PR_MAX_DIRECTORY_ENTRIES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_access_error(int err) +{ + switch (err) { + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ELOOP: + PR_SetError(PR_LOOP_ERROR, err); + break; + case ETIMEDOUT: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; + case ENAMETOOLONG: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ENOTDIR: + PR_SetError(PR_NOT_DIRECTORY_ERROR, err); + break; + case EROFS: + PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_mkdir_error(int err) +{ + switch (err) { + case ENOTDIR: + PR_SetError(PR_NOT_DIRECTORY_ERROR, err); + break; + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ENAMETOOLONG: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EEXIST: + PR_SetError(PR_FILE_EXISTS_ERROR, err); + break; + case EROFS: + PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ELOOP: + PR_SetError(PR_LOOP_ERROR, err); + break; + case EMLINK: + PR_SetError(PR_MAX_DIRECTORY_ENTRIES_ERROR, err); + break; + case ENOSPC: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; +#ifdef EDQUOT + case EDQUOT: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; +#endif + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_rmdir_error(int err) +{ + + switch (err) { + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EBUSY: + PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err); + break; + case EEXIST: + PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err); + break; + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + case ELOOP: + PR_SetError(PR_LOOP_ERROR, err); + break; + case ETIMEDOUT: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; + case ENAMETOOLONG: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ENOTDIR: + PR_SetError(PR_NOT_DIRECTORY_ERROR, err); + break; + case EROFS: + PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_read_error(int err) +{ + switch (err) { + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#ifdef EBADMSG + case EBADMSG: + PR_SetError(PR_IO_ERROR, err); + break; +#endif + case EDEADLK: + PR_SetError(PR_DEADLOCK_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_METHOD_ERROR, err); + break; + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + case ENOLCK: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ENXIO: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case EISDIR: + PR_SetError(PR_IS_DIRECTORY_ERROR, err); + break; + case ECONNRESET: + case EPIPE: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; +#ifdef ENOLINK + case ENOLINK: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_write_error(int err) +{ + switch (err) { + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EDEADLK: + PR_SetError(PR_DEADLOCK_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EFBIG: + PR_SetError(PR_FILE_TOO_BIG_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_METHOD_ERROR, err); + break; + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + case ENOLCK: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + case ENOSPC: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; + case ENXIO: + PR_SetError(PR_INVALID_METHOD_ERROR, err); + break; + case ERANGE: + PR_SetError(PR_INVALID_METHOD_ERROR, err); + break; + case ETIMEDOUT: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; + case ECONNRESET: + case EPIPE: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; +#ifdef EDQUOT + case EDQUOT: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; +#endif +#ifdef ENOLINK + case ENOLINK: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_lseek_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ESPIPE: + PR_SetError(PR_INVALID_METHOD_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_fsync_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#ifdef ENOLINK + case ENOLINK: +#endif + case ETIMEDOUT: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_METHOD_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_close_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; +#ifdef ENOLINK + case ENOLINK: +#endif + case ETIMEDOUT: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_socket_error(int err) +{ + switch (err) { + case EPROTONOSUPPORT: + PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err); + break; + case EMFILE: + PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); + break; + case ENFILE: + PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; +#if !defined(SCO) + case ENOBUFS: +#endif /* !defined(SCO) */ + case ENOMEM: +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_socketavailable_error(int err) +{ + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); +} + +void _MD_unix_map_recv_error(int err) +{ + switch (err) { + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ENOMEM: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); + break; + case ECONNRESET: + case EPIPE: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_recvfrom_error(int err) +{ + switch (err) { + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ENOMEM: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + case ECONNRESET: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_send_error(int err) +{ + switch (err) { + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif +#if !defined(BEOS) + case EMSGSIZE: +#endif + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; +#if !defined(SCO) + case ENOBUFS: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif /* !defined(SCO) */ + case ECONNREFUSED: + PR_SetError(PR_CONNECT_REFUSED_ERROR, err); + break; + case EISCONN: + PR_SetError(PR_IS_CONNECTED_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case ENOMEM: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + case ECONNRESET: + case EPIPE: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_sendto_error(int err) +{ + switch (err) { + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif +#if !defined(BEOS) + case EMSGSIZE: +#endif + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; +#if !defined(SCO) + case ENOBUFS: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif /* !defined(SCO) */ + case ECONNREFUSED: + PR_SetError(PR_CONNECT_REFUSED_ERROR, err); + break; + case EISCONN: + PR_SetError(PR_IS_CONNECTED_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case ENOMEM: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + case ECONNRESET: + case EPIPE: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_writev_error(int err) +{ + switch (err) { + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ECONNRESET: + case EPIPE: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_accept_error(int err) +{ + switch (err) { + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif +#if !defined(BEOS) + case EOPNOTSUPP: +#endif + case ENODEV: + PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EMFILE: + PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); + break; + case ENFILE: + PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case ENOMEM: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif +#ifdef EPROTO + case EPROTO: + PR_SetError(PR_IO_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_connect_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EADDRNOTAVAIL: + PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); + break; + case EINPROGRESS: + PR_SetError(PR_IN_PROGRESS_ERROR, err); + break; + case EALREADY: + PR_SetError(PR_ALREADY_INITIATED_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case EAFNOSUPPORT: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; + case EISCONN: + PR_SetError(PR_IS_CONNECTED_ERROR, err); + break; + case ETIMEDOUT: + PR_SetError(PR_IO_TIMEOUT_ERROR, err); + break; + case ECONNREFUSED: + PR_SetError(PR_CONNECT_REFUSED_ERROR, err); + break; + case ENETUNREACH: + PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err); + break; + case EADDRINUSE: + PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + /* + * UNIX domain sockets are not supported in NSPR + */ + case EACCES: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case EIO: +#if defined(UNIXWARE) + /* + * On some platforms, if we connect to a port on + * the local host (the loopback address) that no + * process is listening on, we get EIO instead + * of ECONNREFUSED. + */ + PR_SetError(PR_CONNECT_REFUSED_ERROR, err); +#else + PR_SetError(PR_IO_ERROR, err); +#endif + break; + case ELOOP: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; + case ENOENT: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + case ENXIO: + PR_SetError(PR_IO_ERROR, err); + break; + case EPROTOTYPE: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_bind_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EADDRNOTAVAIL: + PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); + break; + case EADDRINUSE: + PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_SOCKET_ADDRESS_IS_BOUND_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + /* + * UNIX domain sockets are not supported in NSPR + */ + case EIO: + case EISDIR: + case ELOOP: + case ENOENT: + case ENOTDIR: + case EROFS: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_listen_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif +#if !defined(BEOS) + case EOPNOTSUPP: + PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_shutdown_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case ENOTCONN: + PR_SetError(PR_NOT_CONNECTED_ERROR, err); + break; + case ENOMEM: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_socketpair_error(int err) +{ + switch (err) { + case EMFILE: + PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ENOMEM: +#ifdef ENOSR + case ENOSR: +#endif + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case EAFNOSUPPORT: + case EPROTONOSUPPORT: +#if !defined(BEOS) + case EOPNOTSUPP: +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_getsockname_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#if !defined(SCO) + case ENOBUFS: +#endif /* !defined(SCO) */ + case ENOMEM: +#ifdef ENOSR + case ENOSR: +#endif + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_getpeername_error(int err) +{ + + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case ENOTCONN: + PR_SetError(PR_NOT_CONNECTED_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#if !defined(SCO) + case ENOBUFS: +#endif /* !defined(SCO) */ + case ENOMEM: +#ifdef ENOSR + case ENOSR: +#endif + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_getsockopt_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case ENOPROTOOPT: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); + break; + case ENOMEM: +#ifdef ENOSR + case ENOSR: +#endif + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_setsockopt_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; +#if !defined(BEOS) + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#endif + case ENOPROTOOPT: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); + break; + case ENOMEM: +#ifdef ENOSR + case ENOSR: +#endif + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_open_error(int err) +{ + switch (err) { + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EAGAIN: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case EBUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case EEXIST: + PR_SetError(PR_FILE_EXISTS_ERROR, err); + break; + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case EIO: + PR_SetError(PR_IO_ERROR, err); + break; + case EISDIR: + PR_SetError(PR_IS_DIRECTORY_ERROR, err); + break; + case ELOOP: + PR_SetError(PR_LOOP_ERROR, err); + break; + case EMFILE: + PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err); + break; + case ENAMETOOLONG: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ENFILE: + PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); + break; + case ENODEV: + case ENOENT: + case ENXIO: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ENOMEM: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ENOSPC: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; +#ifdef ENOSR + case ENOSR: +#endif + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ENOTDIR: + PR_SetError(PR_NOT_DIRECTORY_ERROR, err); + break; + case EPERM: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ETIMEDOUT: + PR_SetError(PR_REMOTE_FILE_ERROR, err); + break; + case EROFS: + PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_mmap_error(int err) +{ + + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EAGAIN: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ENOMEM: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_gethostname_error(int err) +{ + switch (err) { + case EFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_select_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_poll_error(int err) +{ + PRErrorCode prerror; + switch (err) { + case EAGAIN: + prerror = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case EINVAL: + prerror = PR_INVALID_ARGUMENT_ERROR; + break; + case EFAULT: + prerror = PR_ACCESS_FAULT_ERROR; + break; + default: + prerror = PR_UNKNOWN_ERROR; + break; + } + PR_SetError(prerror, err); +} + +void _MD_unix_map_flock_error(int err) +{ + switch (err) { + case EBADF: + case EINVAL: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EWOULDBLOCK: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_unix_map_lockf_error(int err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EACCES: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case EDEADLK: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +#ifdef HPUX11 +void _MD_hpux_map_sendfile_error(int oserror) +{ + PRErrorCode prerror; + + switch (oserror) { + case ENOTSOCK: + prerror = PR_NOT_SOCKET_ERROR; + break; + case EFAULT: + prerror = PR_ACCESS_FAULT_ERROR; + break; + case ENOBUFS: + prerror = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case EINVAL: + prerror = PR_INVALID_ARGUMENT_ERROR; + break; + case ENOTCONN: + prerror = PR_NOT_CONNECTED_ERROR; + break; + case EPIPE: + prerror = PR_CONNECT_RESET_ERROR; + break; + case ENOMEM: + prerror = PR_OUT_OF_MEMORY_ERROR; + break; + case EOPNOTSUPP: + prerror = PR_NOT_TCP_SOCKET_ERROR; + break; + default: + prerror = PR_UNKNOWN_ERROR; + } + PR_SetError(prerror, oserror); +} +#endif /* HPUX11 */ diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bfile.c nspr-4.10.7/nspr/pr/src/md/beos/bfile.c --- nspr-4.9.5/nspr/pr/src/md/beos/bfile.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bfile.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,873 @@ +/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +/* +** Global lock variable used to bracket calls into rusty libraries that +** aren't thread safe (like libc, libX, etc). +*/ +static PRLock *_pr_rename_lock = NULL; + +void +_MD_InitIO (void) +{ +} + +PRStatus +_MD_open_dir (_MDDir *md,const char *name) +{ +int err; + + md->d = opendir(name); + if (!md->d) { + err = _MD_ERRNO(); + _PR_MD_MAP_OPENDIR_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +char* +_MD_read_dir (_MDDir *md, PRIntn flags) +{ +struct dirent *de; +int err; + + for (;;) { + /* + * XXX: readdir() is not MT-safe + */ + _MD_ERRNO() = 0; + de = readdir(md->d); + + if (!de) { + err = _MD_ERRNO(); + _PR_MD_MAP_READDIR_ERROR(err); + return 0; + } + + if ((flags & PR_SKIP_DOT) && + (de->d_name[0] == '.') && (de->d_name[1] == 0)) + continue; + + if ((flags & PR_SKIP_DOT_DOT) && + (de->d_name[0] == '.') && (de->d_name[1] == '.') && + (de->d_name[2] == 0)) + continue; + + if ((flags & PR_SKIP_HIDDEN) && (de->d_name[1] == '.')) + continue; + + break; + } + return de->d_name; +} + + +PRInt32 +_MD_close_dir (_MDDir *md) +{ +int rv = 0, err; + + if (md->d) { + rv = closedir(md->d); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_CLOSEDIR_ERROR(err); + } + } + return(rv); +} + +void +_MD_make_nonblock (PRFileDesc *fd) +{ + int blocking = 1; + setsockopt(fd->secret->md.osfd, SOL_SOCKET, SO_NONBLOCK, &blocking, sizeof(blocking)); + +} + +PRStatus +_MD_set_fd_inheritable (PRFileDesc *fd, PRBool inheritable) +{ + int rv; + + rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC); + if (-1 == rv) { + PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +void +_MD_init_fd_inheritable (PRFileDesc *fd, PRBool imported) +{ + if (imported) { + fd->secret->inheritable = _PR_TRI_UNKNOWN; + } else { + int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0); + if (flags == -1) { + PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); + return; + } + fd->secret->inheritable = (flags & FD_CLOEXEC) ? + _PR_TRI_TRUE : _PR_TRI_FALSE; + } +} + +void +_MD_query_fd_inheritable (PRFileDesc *fd) +{ + int flags; + + PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); + flags = fcntl(fd->secret->md.osfd, F_GETFD, 0); + PR_ASSERT(-1 != flags); + fd->secret->inheritable = (flags & FD_CLOEXEC) ? + _PR_TRI_FALSE : _PR_TRI_TRUE; +} + +PRInt32 +_MD_open (const char *name, PRIntn flags, PRIntn mode) +{ + PRInt32 osflags; + PRInt32 rv, err; + + if (flags & PR_RDWR) { + osflags = O_RDWR; + } else if (flags & PR_WRONLY) { + osflags = O_WRONLY; + } else { + osflags = O_RDONLY; + } + + if (flags & PR_EXCL) + osflags |= O_EXCL; + if (flags & PR_APPEND) + osflags |= O_APPEND; + if (flags & PR_TRUNCATE) + osflags |= O_TRUNC; + if (flags & PR_SYNC) { +/* Ummmm. BeOS doesn't appear to + support sync in any way shape or + form. */ + return PR_NOT_IMPLEMENTED_ERROR; + } + + /* + ** On creations we hold the 'create' lock in order to enforce + ** the semantics of PR_Rename. (see the latter for more details) + */ + if (flags & PR_CREATE_FILE) + { + osflags |= O_CREAT ; + if (NULL !=_pr_rename_lock) + PR_Lock(_pr_rename_lock); + } + + rv = open(name, osflags, mode); + + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_OPEN_ERROR(err); + } + + if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock)) + PR_Unlock(_pr_rename_lock); + return rv; +} + +PRInt32 +_MD_close_file (PRInt32 osfd) +{ +PRInt32 rv, err; + + rv = close(osfd); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_CLOSE_ERROR(err); + } + return(rv); +} + +PRInt32 +_MD_read (PRFileDesc *fd, void *buf, PRInt32 amount) +{ + PRInt32 rv, err; + PRInt32 osfd = fd->secret->md.osfd; + + rv = read( osfd, buf, amount ); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_READ_ERROR(err); + } + return(rv); +} + +PRInt32 +_MD_write (PRFileDesc *fd, const void *buf, PRInt32 amount) +{ + PRInt32 rv, err; + PRInt32 osfd = fd->secret->md.osfd; + + rv = write( osfd, buf, amount ); + + if( rv < 0 ) { + + err = _MD_ERRNO(); + _PR_MD_MAP_WRITE_ERROR(err); + } + return( rv ); +} + +#ifndef BONE_VERSION /* Writev moves to bnet.c with BONE */ +PRInt32 +_MD_writev (PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, + PRIntervalTime timeout) +{ + return PR_NOT_IMPLEMENTED_ERROR; +} +#endif + +PRInt32 +_MD_lseek (PRFileDesc *fd, PRInt32 offset, int whence) +{ +PRInt32 rv, err; + + rv = lseek (fd->secret->md.osfd, offset, whence); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_LSEEK_ERROR(err); + } + return( rv ); +} + +PRInt64 +_MD_lseek64 (PRFileDesc *fd, PRInt64 offset, int whence) +{ +PRInt32 rv, err; + +/* According to the BeOS headers, lseek accepts a + * variable of type off_t for the offset, and off_t + * is defined to be a 64-bit value. So no special + * cracking needs to be done on "offset". + */ + + rv = lseek (fd->secret->md.osfd, offset, whence); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_LSEEK_ERROR(err); + } + return( rv ); +} + +PRInt32 +_MD_fsync (PRFileDesc *fd) +{ +PRInt32 rv, err; + + rv = fsync(fd->secret->md.osfd); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_FSYNC_ERROR(err); + } + return(rv); +} + +PRInt32 +_MD_delete (const char *name) +{ +PRInt32 rv, err; + + rv = unlink(name); + if (rv == -1) + { + err = _MD_ERRNO(); + _PR_MD_MAP_UNLINK_ERROR(err); + } + return (rv); +} + +PRInt32 +_MD_getfileinfo (const char *fn, PRFileInfo *info) +{ +struct stat sb; +PRInt32 rv, err; +PRInt64 s, s2us; + + rv = stat(fn, &sb); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_STAT_ERROR(err); + } else if (info) { + if (S_IFREG & sb.st_mode) + info->type = PR_FILE_FILE; + else if (S_IFDIR & sb.st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + + /* Must truncate file size for the 32 bit + version */ + info->size = (sb.st_size & 0xffffffff); + LL_I2L(s, sb.st_mtime); + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, sb.st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; + } + return rv; +} + +PRInt32 +_MD_getfileinfo64 (const char *fn, PRFileInfo64 *info) +{ +struct stat sb; +PRInt32 rv, err; +PRInt64 s, s2us; + + rv = stat(fn, &sb); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_STAT_ERROR(err); + } else if (info) { + if (S_IFREG & sb.st_mode) + info->type = PR_FILE_FILE; + else if (S_IFDIR & sb.st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + + /* For the 64 bit version we can use + * the native st_size without modification + */ + info->size = sb.st_size; + LL_I2L(s, sb.st_mtime); + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, sb.st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; + } + return rv; +} + +PRInt32 +_MD_getopenfileinfo (const PRFileDesc *fd, PRFileInfo *info) +{ + struct stat sb; + PRInt64 s, s2us; + PRInt32 rv, err; + + rv = fstat(fd->secret->md.osfd, &sb); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_FSTAT_ERROR(err); + } else if (info) { + if (info) { + if (S_IFREG & sb.st_mode) + info->type = PR_FILE_FILE ; + else if (S_IFDIR & sb.st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + /* Use lower 32 bits of file size */ + info->size = ( sb.st_size & 0xffffffff); + LL_I2L(s, sb.st_mtime); + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, sb.st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; + } + } + return rv; +} + +PRInt32 +_MD_getopenfileinfo64 (const PRFileDesc *fd, PRFileInfo64 *info) +{ + struct stat sb; + PRInt64 s, s2us; + PRInt32 rv, err; + + rv = fstat(fd->secret->md.osfd, &sb); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_FSTAT_ERROR(err); + } else if (info) { + if (info) { + if (S_IFREG & sb.st_mode) + info->type = PR_FILE_FILE ; + else if (S_IFDIR & sb.st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + info->size = sb.st_size; + LL_I2L(s, sb.st_mtime); + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, sb.st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; + } + } + return rv; +} + +PRInt32 +_MD_rename (const char *from, const char *to) +{ + PRInt32 rv = -1, err; + + /* + ** This is trying to enforce the semantics of WINDOZE' rename + ** operation. That means one is not allowed to rename over top + ** of an existing file. Holding a lock across these two function + ** and the open function is known to be a bad idea, but .... + */ + if (NULL != _pr_rename_lock) + PR_Lock(_pr_rename_lock); + if (0 == access(to, F_OK)) + PR_SetError(PR_FILE_EXISTS_ERROR, 0); + else + { + rv = rename(from, to); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_RENAME_ERROR(err); + } + } + if (NULL != _pr_rename_lock) + PR_Unlock(_pr_rename_lock); + return rv; +} + +PRInt32 +_MD_access (const char *name, PRIntn how) +{ +PRInt32 rv, err; +int checkFlags; +struct stat buf; + + switch (how) { + case PR_ACCESS_WRITE_OK: + checkFlags = S_IWUSR | S_IWGRP | S_IWOTH; + break; + + case PR_ACCESS_READ_OK: + checkFlags = S_IRUSR | S_IRGRP | S_IROTH; + break; + + case PR_ACCESS_EXISTS: + /* we don't need to examine st_mode. */ + break; + + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + rv = stat(name, &buf); + if (rv == 0 && how != PR_ACCESS_EXISTS && (!(buf.st_mode & checkFlags))) { + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0); + return -1; + } + + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_STAT_ERROR(err); + } + + return(rv); +} + +PRInt32 +_MD_stat (const char *name, struct stat *buf) +{ + return PR_NOT_IMPLEMENTED_ERROR; +} + +PRInt32 +_MD_mkdir (const char *name, PRIntn mode) +{ + status_t rv; + int err; + + /* + ** This lock is used to enforce rename semantics as described + ** in PR_Rename. Look there for more fun details. + */ + if (NULL !=_pr_rename_lock) + PR_Lock(_pr_rename_lock); + + rv = mkdir(name, mode); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_MKDIR_ERROR(err); + } + if (NULL !=_pr_rename_lock) + PR_Unlock(_pr_rename_lock); + return rv; +} + +PRInt32 +_MD_rmdir (const char *name) +{ +int rv, err; + + rv = rmdir(name); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_RMDIR_ERROR(err); + } + return rv; +} + +PRInt32 +_MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + PRInt32 rv = 0; + PRThread *me = _PR_MD_CURRENT_THREAD(); + /* + * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL(). + */ + fd_set rd, wt, ex; + PRFileDesc *bottom; + PRPollDesc *pd, *epd; + PRInt32 maxfd = -1, ready, err; + PRIntervalTime remaining, elapsed, start; + + struct timeval tv, *tvp = NULL; + + if (_PR_PENDING_INTERRUPT(me)) + { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + + if (0 == npds) { + PR_Sleep(timeout); + return rv; + } + + FD_ZERO(&rd); + FD_ZERO(&wt); + FD_ZERO(&ex); + + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRInt16 in_flags_read = 0, in_flags_write = 0; + PRInt16 out_flags_read = 0, out_flags_write = 0; + + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + if (pd->in_flags & PR_POLL_READ) + { + in_flags_read = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); + } + if (pd->in_flags & PR_POLL_WRITE) + { + in_flags_write = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); + } + if ((0 != (in_flags_read & out_flags_read)) + || (0 != (in_flags_write & out_flags_write))) + { + /* this one's ready right now */ + if (0 == ready) + { + /* + * We will have to return without calling the + * system poll/select function. So zero the + * out_flags fields of all the poll descriptors + * before this one. + */ + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; + pd->out_flags = out_flags_read | out_flags_write; + } + else + { + pd->out_flags = 0; /* pre-condition */ + + /* make sure this is an NSPR supported stack */ + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); /* what to do about that? */ + if ((NULL != bottom) + && (_PR_FILEDESC_OPEN == bottom->secret->state)) + { + if (0 == ready) + { + PRInt32 osfd = bottom->secret->md.osfd; + if (osfd > maxfd) maxfd = osfd; + if (in_flags_read & PR_POLL_READ) + { + pd->out_flags |= _PR_POLL_READ_SYS_READ; + FD_SET(osfd, &rd); + } + if (in_flags_read & PR_POLL_WRITE) + { + pd->out_flags |= _PR_POLL_READ_SYS_WRITE; + FD_SET(osfd, &wt); + } + if (in_flags_write & PR_POLL_READ) + { + pd->out_flags |= _PR_POLL_WRITE_SYS_READ; + FD_SET(osfd, &rd); + } + if (in_flags_write & PR_POLL_WRITE) + { + pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; + FD_SET(osfd, &wt); + } + if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex); + } + } + else + { + if (0 == ready) + { + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; /* this will cause an abrupt return */ + pd->out_flags = PR_POLL_NVAL; /* bogii */ + } + } + } + else + { + pd->out_flags = 0; + } + } + + if (0 != ready) return ready; /* no need to block */ + + remaining = timeout; + start = PR_IntervalNow(); + + retry: + if (timeout != PR_INTERVAL_NO_TIMEOUT) + { + PRInt32 ticksPerSecond = PR_TicksPerSecond(); + tv.tv_sec = remaining / ticksPerSecond; + tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); + tvp = &tv; + } + + ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp); + + if (ready == -1 && errno == EINTR) + { + if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; + else + { + elapsed = (PRIntervalTime) (PR_IntervalNow() - start); + if (elapsed > timeout) ready = 0; /* timed out */ + else + { + remaining = timeout - elapsed; + goto retry; + } + } + } + + /* + ** Now to unravel the select sets back into the client's poll + ** descriptor list. Is this possibly an area for pissing away + ** a few cycles or what? + */ + if (ready > 0) + { + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRInt16 out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + PRInt32 osfd; + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + + osfd = bottom->secret->md.osfd; + + if (FD_ISSET(osfd, &rd)) + { + if (pd->out_flags & _PR_POLL_READ_SYS_READ) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) + out_flags |= PR_POLL_WRITE; + } + if (FD_ISSET(osfd, &wt)) + { + if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) + out_flags |= PR_POLL_WRITE; + } + if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; + +/* Workaround for nonblocking connects under net_server */ +#ifndef BONE_VERSION + if (out_flags) + { + /* check if it is a pending connect */ + int i = 0, j = 0; + PR_Lock( _connectLock ); + for( i = 0; i < connectCount; i++ ) + { + if(connectList[i].osfd == osfd) + { + int connectError; + int connectResult; + + connectResult = connect(connectList[i].osfd, + &connectList[i].addr, + connectList[i].addrlen); + connectError = errno; + + if(connectResult < 0 ) + { + if(connectError == EINTR || connectError == EWOULDBLOCK || + connectError == EINPROGRESS || connectError == EALREADY) + { + break; + } + } + + if(i == (connectCount - 1)) + { + connectList[i].osfd = -1; + } else { + for(j = i; j < connectCount; j++ ) + { + memcpy( &connectList[j], &connectList[j+1], + sizeof(connectList[j])); + } + } + connectCount--; + + bottom->secret->md.connectReturnValue = connectResult; + bottom->secret->md.connectReturnError = connectError; + bottom->secret->md.connectValueValid = PR_TRUE; + break; + } + } + PR_Unlock( _connectLock ); + } +#endif + } + pd->out_flags = out_flags; + if (out_flags) ready++; + } + PR_ASSERT(ready > 0); + } + else if (ready < 0) + { + err = _MD_ERRNO(); + if (err == EBADF) + { + /* Find the bad fds */ + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + pd->out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1) + { + pd->out_flags = PR_POLL_NVAL; + ready++; + } + } + } + PR_ASSERT(ready > 0); + } + else _PR_MD_MAP_SELECT_ERROR(err); + } + + return ready; +} /* _MD_pr_poll */ + +/* + * File locking. + */ + +PRStatus +_MD_lockfile (PRInt32 osfd) +{ + PRInt32 rv; + struct flock linfo; + + linfo.l_type = + linfo.l_whence = SEEK_SET; + linfo.l_start = 0; + linfo.l_len = 0; + + rv = fcntl(osfd, F_SETLKW, &linfo); + if (rv == 0) + return PR_SUCCESS; + + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus +_MD_tlockfile (PRInt32 osfd) +{ + PRInt32 rv; + struct flock linfo; + + linfo.l_type = + linfo.l_whence = SEEK_SET; + linfo.l_start = 0; + linfo.l_len = 0; + + rv = fcntl(osfd, F_SETLK, &linfo); + if (rv == 0) + return PR_SUCCESS; + + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus +_MD_unlockfile (PRInt32 osfd) +{ + PRInt32 rv; + struct flock linfo; + + linfo.l_type = + linfo.l_whence = SEEK_SET; + linfo.l_start = 0; + linfo.l_len = 0; + + rv = fcntl(osfd, F_UNLCK, &linfo); + + if (rv == 0) + return PR_SUCCESS; + + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bmemory.c nspr-4.10.7/nspr/pr/src/md/beos/bmemory.c --- nspr-4.9.5/nspr/pr/src/md/beos/bmemory.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bmemory.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,10 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +PR_EXTERN(void) _PR_MD_INIT_SEGS(void); +PR_EXTERN(PRStatus) _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr); +PR_EXTERN(void) _PR_MD_FREE_SEGMENT(PRSegment *seg); diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bmisc.c nspr-4.10.7/nspr/pr/src/md/beos/bmisc.c --- nspr-4.9.5/nspr/pr/src/md/beos/bmisc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bmisc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,91 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +PRLock *_connectLock = NULL; + +#ifndef BONE_VERSION +/* Workaround for nonblocking connects under net_server */ +PRUint32 connectCount = 0; +ConnectListNode connectList[64]; +#endif + +void +_MD_cleanup_before_exit (void) +{ +} + +void +_MD_exit (PRIntn status) +{ + exit(status); +} + +void +_MD_early_init (void) +{ +} + +static PRLock *monitor = NULL; + +void +_MD_final_init (void) +{ + _connectLock = PR_NewLock(); + PR_ASSERT(NULL != _connectLock); +#ifndef BONE_VERSION + /* Workaround for nonblocking connects under net_server */ + connectCount = 0; +#endif +} + +void +_MD_AtomicInit (void) +{ + if (monitor == NULL) { + monitor = PR_NewLock(); + } +} + +/* +** This is exceedingly messy. atomic_add returns the last value, NSPR expects the new value. +** We just add or subtract 1 from the result. The actual memory update is atomic. +*/ + +PRInt32 +_MD_AtomicAdd( PRInt32 *ptr, PRInt32 val ) +{ + return( ( atomic_add( (long *)ptr, val ) ) + val ); +} + +PRInt32 +_MD_AtomicIncrement( PRInt32 *val ) +{ + return( ( atomic_add( (long *)val, 1 ) ) + 1 ); +} + +PRInt32 +_MD_AtomicDecrement( PRInt32 *val ) +{ + return( ( atomic_add( (long *)val, -1 ) ) - 1 ); +} + +PRInt32 +_MD_AtomicSet( PRInt32 *val, PRInt32 newval ) +{ + PRInt32 rv; + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + PR_Lock(monitor); + rv = *val; + *val = newval; + PR_Unlock(monitor); + return rv; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bmmap.c nspr-4.10.7/nspr/pr/src/md/beos/bmmap.c --- nspr-4.9.5/nspr/pr/src/md/beos/bmmap.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bmmap.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,41 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +PR_EXTERN(PRStatus) +_PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size) +{ + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return PR_FAILURE; +} + +PR_EXTERN(PRInt32) +_PR_MD_GET_MEM_MAP_ALIGNMENT(void) +{ + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return -1; +} + +PR_EXTERN(void *) +_PR_MD_MEM_MAP(PRFileMap *fmap, PRInt64 offset, PRUint32 len) +{ + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return 0; +} + +PR_EXTERN(PRStatus) +_PR_MD_MEM_UNMAP(void *addr, PRUint32 size) +{ + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return PR_FAILURE; +} + +PR_EXTERN(PRStatus) +_PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap) +{ + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return PR_FAILURE; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bnet.c nspr-4.10.7/nspr/pr/src/md/beos/bnet.c --- nspr-4.9.5/nspr/pr/src/md/beos/bnet.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bnet.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,911 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or + * PRInt32* pointer to a _PRSockLen_t* pointer. + */ +#define _PRSockLen_t int + + +/* +** Global lock variable used to bracket calls into rusty libraries that +** aren't thread safe (like libc, libX, etc). +*/ +static PRLock *_pr_rename_lock = NULL; +static PRMonitor *_pr_Xfe_mon = NULL; + +#define READ_FD 1 +#define WRITE_FD 2 + +/* +** This is a support routine to handle "deferred" i/o on sockets. +** It uses "select", so it is subject to all of the BeOS limitations +** (only READ notification, only sockets) +*/ + +/* + * socket_io_wait -- + * + * wait for socket i/o, periodically checking for interrupt + * + */ + +static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type, + PRIntervalTime timeout) +{ + PRInt32 rv = -1; + struct timeval tv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRIntervalTime epoch, now, elapsed, remaining; + PRBool wait_for_remaining; + PRInt32 syserror; + fd_set rd_wr; + + switch (timeout) { + case PR_INTERVAL_NO_WAIT: + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + break; + case PR_INTERVAL_NO_TIMEOUT: + /* + * This is a special case of the 'default' case below. + * Please see the comments there. + */ + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; + tv.tv_usec = 0; + FD_ZERO(&rd_wr); + do { + FD_SET(osfd, &rd_wr); + if (fd_type == READ_FD) + rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv); + else + rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv); + if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { +#ifdef BONE_VERSION + _PR_MD_MAP_SELECT_ERROR(syserror); +#else + if (syserror == EBADF) { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF); + } else { + PR_SetError(PR_UNKNOWN_ERROR, syserror); + } +#endif + break; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + } while (rv == 0 || (rv == -1 && syserror == EINTR)); + break; + default: + now = epoch = PR_IntervalNow(); + remaining = timeout; + FD_ZERO(&rd_wr); + do { + /* + * We block in _MD_SELECT for at most + * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, + * so that there is an upper limit on the delay + * before the interrupt bit is checked. + */ + wait_for_remaining = PR_TRUE; + tv.tv_sec = PR_IntervalToSeconds(remaining); + if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { + wait_for_remaining = PR_FALSE; + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; + tv.tv_usec = 0; + } else { + tv.tv_usec = PR_IntervalToMicroseconds( + remaining - + PR_SecondsToInterval(tv.tv_sec)); + } + FD_SET(osfd, &rd_wr); + if (fd_type == READ_FD) + rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv); + else + rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv); + /* + * we don't consider EINTR a real error + */ + if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { +#ifdef BONE_VERSION + _PR_MD_MAP_SELECT_ERROR(syserror); +#else + if (syserror == EBADF) { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF); + } else { + PR_SetError(PR_UNKNOWN_ERROR, syserror); + } +#endif + break; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + /* + * We loop again if _MD_SELECT timed out or got interrupted + * by a signal, and the timeout deadline has not passed yet. + */ + if (rv == 0 || (rv == -1 && syserror == EINTR)) { + /* + * If _MD_SELECT timed out, we know how much time + * we spent in blocking, so we can avoid a + * PR_IntervalNow() call. + */ + if (rv == 0) { + if (wait_for_remaining) { + now += remaining; + } else { + now += PR_SecondsToInterval(tv.tv_sec) + + PR_MicrosecondsToInterval(tv.tv_usec); + } + } else { + now = PR_IntervalNow(); + } + elapsed = (PRIntervalTime) (now - epoch); + if (elapsed >= timeout) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + rv = -1; + break; + } else { + remaining = timeout - elapsed; + } + } + } while (rv == 0 || (rv == -1 && syserror == EINTR)); + break; + } + return(rv); +} + +PRInt32 +_MD_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRInt32 flags, + PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + +#ifndef BONE_VERSION + if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_READ) { + _PR_MD_MAP_RECV_ERROR(EPIPE); + return -1; + } +#endif + +#ifdef BONE_VERSION + /* + ** Gah, stupid hack. If reading a zero amount, instantly return success. + ** BONE beta 6 returns EINVAL for reads of zero bytes, which parts of + ** mozilla use to check for socket availability. + */ + + if( 0 == amount ) return(0); +#endif + + while ((rv = recv(osfd, buf, amount, flags)) == -1) { + err = _MD_ERRNO(); + + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + /* If socket was supposed to be blocking, + wait a while for the condition to be + satisfied. */ + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + + } else + break; + } + + if (rv < 0) { + _PR_MD_MAP_RECV_ERROR(err); + } + +done: + return(rv); +} + +PRInt32 +_MD_recvfrom (PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + while ((*addrlen = PR_NETADDR_SIZE(addr)), + ((rv = recvfrom(osfd, buf, amount, flags, + (struct sockaddr *) addr, + (_PRSockLen_t *)addrlen)) == -1)) { + err = _MD_ERRNO(); + + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) { + continue; + } else { + break; + } + } + + if (rv < 0) { + _PR_MD_MAP_RECVFROM_ERROR(err); + } + +done: +#ifdef _PR_HAVE_SOCKADDR_LEN + if (rv != -1) { + /* ignore the sa_len field of struct sockaddr */ + if (addr) { + addr->raw.family = ((struct sockaddr *) addr)->sa_family; + } + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ + return(rv); +} + +PRInt32 +_MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags, + PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + +#ifndef BONE_VERSION + if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_WRITE) + { + _PR_MD_MAP_SEND_ERROR(EPIPE); + return -1; + } +#endif + + while ((rv = send(osfd, buf, amount, flags)) == -1) { + err = _MD_ERRNO(); + + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + +#ifndef BONE_VERSION + if( _PR_PENDING_INTERRUPT(me)) { + + me->flags &= ~_PR_INTERRUPT; + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + + /* in UNIX implementations, you could do a socket_io_wait here. + * but since BeOS doesn't yet support WRITE notification in select, + * you're spanked. + */ + snooze( 10000L ); + continue; +#else /* BONE_VERSION */ + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0) + goto done; +#endif + + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) { + continue; + + } else { + break; + } + } + +#ifdef BONE_VERSION + /* + * optimization; if bytes sent is less than "amount" call + * select before returning. This is because it is likely that + * the next writev() call will return EWOULDBLOCK. + */ + if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) + && (timeout != PR_INTERVAL_NO_WAIT)) { + if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { + rv = -1; + goto done; + } + } +#endif /* BONE_VERSION */ + + if (rv < 0) { + _PR_MD_MAP_SEND_ERROR(err); + } + +#ifdef BONE_VERSION +done: +#endif + return(rv); +} + +PRInt32 +_MD_sendto (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; + + addrCopy = *addr; + ((struct sockaddr *) &addrCopy)->sa_len = addrlen; + ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; + + while ((rv = sendto(osfd, buf, amount, flags, + (struct sockaddr *) &addrCopy, addrlen)) == -1) { +#else + while ((rv = sendto(osfd, buf, amount, flags, + (struct sockaddr *) addr, addrlen)) == -1) { +#endif + err = _MD_ERRNO(); + + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + +#ifdef BONE_VERSION + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0) + goto done; +#endif + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) { + continue; + + } else { + break; + } + } + + if (rv < 0) { + _PR_MD_MAP_SENDTO_ERROR(err); + } + +#ifdef BONE_VERSION +done: +#endif + return(rv); +} + +#ifdef BONE_VERSION + +PRInt32 _MD_writev( + PRFileDesc *fd, const PRIOVec *iov, + PRInt32 iov_size, PRIntervalTime timeout) +{ + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 index, amount = 0; + PRInt32 osfd = fd->secret->md.osfd; + struct iovec osiov[PR_MAX_IOVECTOR_SIZE]; + + /* Ensured by PR_Writev */ + PR_ASSERT(iov_size <= PR_MAX_IOVECTOR_SIZE); + + /* + * We can't pass iov to writev because PRIOVec and struct iovec + * may not be binary compatible. Make osiov a copy of iov and + * pass osiov to writev. + */ + for (index = 0; index < iov_size; index++) { + osiov[index].iov_base = iov[index].iov_base; + osiov[index].iov_len = iov[index].iov_len; + } + + /* + * Calculate the total number of bytes to be sent; needed for + * optimization later. + * We could avoid this if this number was passed in; but it is + * probably not a big deal because iov_size is usually small (less than + * 3) + */ + if (!fd->secret->nonblocking) { + for (index=0; indexsecret->nonblocking) { + break; + } + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0) + goto done; + + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + + /* + * optimization; if bytes sent is less than "amount" call + * select before returning. This is because it is likely that + * the next writev() call will return EWOULDBLOCK. + */ + if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) + && (timeout != PR_INTERVAL_NO_WAIT)) { + if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { + rv = -1; + goto done; + } + } + + + if (rv < 0) { + _PR_MD_MAP_WRITEV_ERROR(err); + } +done: + return(rv); +} + +#endif /* BONE_VERSION */ + +PRInt32 +_MD_accept (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, + PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + while ((rv = accept(osfd, (struct sockaddr *) addr, + (_PRSockLen_t *)addrlen)) == -1) { + err = _MD_ERRNO(); + + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + /* If it's SUPPOSED to be a blocking thread, wait + * a while to see if the triggering condition gets + * satisfied. + */ + /* Assume that we're always using a native thread */ + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) { + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_ACCEPT_ERROR(err); + } else if (addr != NULL) { + /* bug 134099 */ + err = getpeername(rv, (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); + } +done: +#ifdef _PR_HAVE_SOCKADDR_LEN + if (rv != -1) { + /* Mask off the first byte of struct sockaddr (the length field) */ + if (addr) { + addr->raw.family = ((struct sockaddr *) addr)->sa_family; + } + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ + return(rv); +} + +PRInt32 +_MD_connect (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, + PRIntervalTime timeout) +{ + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 osfd = fd->secret->md.osfd; + +#ifndef BONE_VERSION + fd->secret->md.connectValueValid = PR_FALSE; +#endif +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; + + addrCopy = *addr; + ((struct sockaddr *) &addrCopy)->sa_len = addrlen; + ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; +#endif + + /* (Copied from unix.c) + * We initiate the connection setup by making a nonblocking connect() + * call. If the connect() call fails, there are two cases we handle + * specially: + * 1. The connect() call was interrupted by a signal. In this case + * we simply retry connect(). + * 2. The NSPR socket is nonblocking and connect() fails with + * EINPROGRESS. We first wait until the socket becomes writable. + * Then we try to find out whether the connection setup succeeded + * or failed. + */ + +retry: +#ifdef _PR_HAVE_SOCKADDR_LEN + if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) { +#else + if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) { +#endif + err = _MD_ERRNO(); +#ifndef BONE_VERSION + fd->secret->md.connectReturnValue = rv; + fd->secret->md.connectReturnError = err; + fd->secret->md.connectValueValid = PR_TRUE; +#endif + if( err == EINTR ) { + + if( _PR_PENDING_INTERRUPT(me)) { + + me->flags &= ~_PR_INTERRUPT; + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } +#ifndef BONE_VERSION + snooze( 100000L ); +#endif + goto retry; + } + +#ifndef BONE_VERSION + if(!fd->secret->nonblocking && ((err == EINPROGRESS) || (err==EAGAIN) || (err==EALREADY))) { + + /* + ** There's no timeout on this connect, but that's not + ** a big deal, since the connect times out anyways + ** after 30 seconds. Just sleep for 1/10th of a second + ** and retry until we go through or die. + */ + + if( _PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + + goto retry; + } + + if( fd->secret->nonblocking && ((err == EAGAIN) || (err == EINPROGRESS))) { + PR_Lock(_connectLock); + if (connectCount < sizeof(connectList)/sizeof(connectList[0])) { + connectList[connectCount].osfd = osfd; + memcpy(&connectList[connectCount].addr, addr, addrlen); + connectList[connectCount].addrlen = addrlen; + connectList[connectCount].timeout = timeout; + connectCount++; + PR_Unlock(_connectLock); + _PR_MD_MAP_CONNECT_ERROR(err); + } else { + PR_Unlock(_connectLock); + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } + return rv; + } +#else /* BONE_VERSION */ + if(!fd->secret->nonblocking && (err == EINTR)) { + + rv = socket_io_wait(osfd, WRITE_FD, timeout); + if (rv == -1) { + return -1; + } + + PR_ASSERT(rv == 1); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + err = _MD_beos_get_nonblocking_connect_error(osfd); + if (err != 0) { + _PR_MD_MAP_CONNECT_ERROR(err); + return -1; + } + return 0; + } +#endif + + _PR_MD_MAP_CONNECT_ERROR(err); + } + + return rv; +} + +PRInt32 +_MD_bind (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) +{ + PRInt32 rv, err; +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; + + addrCopy = *addr; + ((struct sockaddr *) &addrCopy)->sa_len = addrlen; + ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; + rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen); +#else + rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen); +#endif + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_BIND_ERROR(err); + } + + return(rv); +} + +PRInt32 +_MD_listen (PRFileDesc *fd, PRIntn backlog) +{ + PRInt32 rv, err; + +#ifndef BONE_VERSION + /* Bug workaround! Setting listen to 0 on Be accepts no connections. + ** On most UN*Xes this sets the default. + */ + + if( backlog == 0 ) backlog = 5; +#endif + + rv = listen(fd->secret->md.osfd, backlog); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_LISTEN_ERROR(err); + } + + return(rv); +} + +PRInt32 +_MD_shutdown (PRFileDesc *fd, PRIntn how) +{ + PRInt32 rv, err; + +#ifndef BONE_VERSION + if (how == PR_SHUTDOWN_SEND) + fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_WRITE; + else if (how == PR_SHUTDOWN_RCV) + fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_READ; + else if (how == PR_SHUTDOWN_BOTH) { + fd->secret->md.sock_state = (BE_SOCK_SHUTDOWN_WRITE | BE_SOCK_SHUTDOWN_READ); + } + + return 0; +#else /* BONE_VERSION */ + rv = shutdown(fd->secret->md.osfd, how); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_SHUTDOWN_ERROR(err); + } + return(rv); +#endif +} + +PRInt32 +_MD_socketpair (int af, int type, int flags, PRInt32 *osfd) +{ + return PR_NOT_IMPLEMENTED_ERROR; +} + +PRInt32 +_MD_close_socket (PRInt32 osfd) +{ +#ifdef BONE_VERSION + close( osfd ); +#else + closesocket( osfd ); +#endif +} + +PRStatus +_MD_getsockname (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) +{ + PRInt32 rv, err; + + rv = getsockname(fd->secret->md.osfd, + (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); +#ifdef _PR_HAVE_SOCKADDR_LEN + if (rv == 0) { + /* ignore the sa_len field of struct sockaddr */ + if (addr) { + addr->raw.family = ((struct sockaddr *) addr)->sa_family; + } + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_GETSOCKNAME_ERROR(err); + } + + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus +_MD_getpeername (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) +{ + PRInt32 rv, err; + + rv = getpeername(fd->secret->md.osfd, + (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); + +#ifdef _PR_HAVE_SOCKADDR_LEN + if (rv == 0) { + /* ignore the sa_len field of struct sockaddr */ + if (addr) { + addr->raw.family = ((struct sockaddr *) addr)->sa_family; + } + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ + + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_GETPEERNAME_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus +_MD_getsockopt (PRFileDesc *fd, PRInt32 level, + PRInt32 optname, char* optval, PRInt32* optlen) +{ + PRInt32 rv, err; + + rv = getsockopt(fd->secret->md.osfd, level, optname, + optval, (_PRSockLen_t *)optlen); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_GETSOCKOPT_ERROR(err); + } + + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus +_MD_setsockopt (PRFileDesc *fd, PRInt32 level, + PRInt32 optname, const char* optval, PRInt32 optlen) +{ + PRInt32 rv, err; + + rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_SETSOCKOPT_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRInt32 +_MD_accept_read (PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, + void *buf, PRInt32 amount, PRIntervalTime timeout) +{ + return PR_NOT_IMPLEMENTED_ERROR; +} + +#ifndef BONE_VERSION +PRInt32 +_MD_socket (int af, int type, int flags) +{ + PRInt32 osfd, err; + + osfd = socket( af, type, 0 ); + + if( -1 == osfd ) { + + err = _MD_ERRNO(); + _PR_MD_MAP_SOCKET_ERROR( err ); + } + + return( osfd ); +} +#else +PRInt32 +_MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto) +{ + PRInt32 osfd, err; + + osfd = socket(domain, type, proto); + + if (osfd == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_SOCKET_ERROR(err); + } + + return(osfd); +} +#endif + +PRInt32 +_MD_socketavailable (PRFileDesc *fd) +{ +#ifdef BONE_VERSION + PRInt32 result; + + if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) { + _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO()); + return -1; + } + return result; +#else + return PR_NOT_IMPLEMENTED_ERROR; +#endif +} + +PRInt32 +_MD_get_socket_error (void) +{ + return PR_NOT_IMPLEMENTED_ERROR; +} + +PRStatus +_MD_gethostname (char *name, PRUint32 namelen) +{ + PRInt32 rv, err; + + rv = gethostname(name, namelen); + if (rv == 0) + { + err = _MD_ERRNO(); + _PR_MD_MAP_GETHOSTNAME_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +#ifndef BONE_VERSION +PRInt32 +_MD_beos_get_nonblocking_connect_error(PRFileDesc *fd) +{ + int rv; + int flags = 0; + + rv = recv(fd->secret->md.osfd, NULL, 0, flags); + PR_ASSERT(-1 == rv || 0 == rv); + if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) { + return errno; + } + return 0; /* no error */ +} +#else +PRInt32 +_MD_beos_get_nonblocking_connect_error(int osfd) +{ + return PR_NOT_IMPLEMENTED_ERROR; + // int err; + // _PRSockLen_t optlen = sizeof(err); + // if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) { + // return errno; + // } else { + // return err; + // } +} +#endif /* BONE_VERSION */ diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bproc.c nspr-4.10.7/nspr/pr/src/md/beos/bproc.c --- nspr-4.9.5/nspr/pr/src/md/beos/bproc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bproc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,212 @@ +/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include +#include + +#define _PR_SIGNALED_EXITSTATUS 256 + +PRProcess* +_MD_create_process (const char *path, char *const *argv, + char *const *envp, const PRProcessAttr *attr) +{ + PRProcess *process; + int nEnv, idx; + char *const *childEnvp; + char **newEnvp = NULL; + int flags; + PRBool found = PR_FALSE; + + process = PR_NEW(PRProcess); + if (!process) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + childEnvp = envp; + if (attr && attr->fdInheritBuffer) { + if (NULL == childEnvp) { + childEnvp = environ; + } + for (nEnv = 0; childEnvp[nEnv]; nEnv++) { + } + newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *)); + if (NULL == newEnvp) { + PR_DELETE(process); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + for (idx = 0; idx < nEnv; idx++) { + newEnvp[idx] = childEnvp[idx]; + if (!found && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) { + newEnvp[idx] = attr->fdInheritBuffer; + found = PR_TRUE; + } + } + if (!found) { + newEnvp[idx++] = attr->fdInheritBuffer; + } + newEnvp[idx] = NULL; + childEnvp = newEnvp; + } + + process->md.pid = fork(); + + if ((pid_t) -1 == process->md.pid) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno); + PR_DELETE(process); + if (newEnvp) { + PR_DELETE(newEnvp); + } + return NULL; + } else if (0 == process->md.pid) { /* the child process */ + /* + * If the child process needs to exit, it must call _exit(). + * Do not call exit(), because exit() will flush and close + * the standard I/O file descriptors, and hence corrupt + * the parent process's standard I/O data structures. + */ + + if (attr) { + /* the osfd's to redirect stdin, stdout, and stderr to */ + int in_osfd = -1, out_osfd = -1, err_osfd = -1; + + if (attr->stdinFd + && attr->stdinFd->secret->md.osfd != 0) { + in_osfd = attr->stdinFd->secret->md.osfd; + if (dup2(in_osfd, 0) != 0) { + _exit(1); /* failed */ + } + flags = fcntl(0, F_GETFL, 0); + if (flags & O_NONBLOCK) { + fcntl(0, F_SETFL, flags & ~O_NONBLOCK); + } + } + if (attr->stdoutFd + && attr->stdoutFd->secret->md.osfd != 1) { + out_osfd = attr->stdoutFd->secret->md.osfd; + if (dup2(out_osfd, 1) != 1) { + _exit(1); /* failed */ + } + flags = fcntl(1, F_GETFL, 0); + if (flags & O_NONBLOCK) { + fcntl(1, F_SETFL, flags & ~O_NONBLOCK); + } + } + if (attr->stderrFd + && attr->stderrFd->secret->md.osfd != 2) { + err_osfd = attr->stderrFd->secret->md.osfd; + if (dup2(err_osfd, 2) != 2) { + _exit(1); /* failed */ + } + flags = fcntl(2, F_GETFL, 0); + if (flags & O_NONBLOCK) { + fcntl(2, F_SETFL, flags & ~O_NONBLOCK); + } + } + if (in_osfd != -1) { + close(in_osfd); + } + if (out_osfd != -1 && out_osfd != in_osfd) { + close(out_osfd); + } + if (err_osfd != -1 && err_osfd != in_osfd + && err_osfd != out_osfd) { + close(err_osfd); + } + if (attr->currentDirectory) { + if (chdir(attr->currentDirectory) < 0) { + _exit(1); /* failed */ + } + } + } + + if (childEnvp) { + (void)execve(path, argv, childEnvp); + } else { + /* Inherit the environment of the parent. */ + (void)execv(path, argv); + } + /* Whoops! It returned. That's a bad sign. */ + _exit(1); + } + + if (newEnvp) { + PR_DELETE(newEnvp); + } + + return process; +} + +PRStatus +_MD_detach_process (PRProcess *process) +{ + /* If we kept a process table like unix does, + * we'd remove the entry here. + * Since we dont', just delete the process variable + */ + PR_DELETE(process); + return PR_SUCCESS; +} + +PRStatus +_MD_wait_process (PRProcess *process, PRInt32 *exitCode) +{ + PRStatus retVal = PR_SUCCESS; + int ret, status; + + /* Ignore interruptions */ + do { + ret = waitpid(process->md.pid, &status, 0); + } while (ret == -1 && errno == EINTR); + + /* + * waitpid() cannot return 0 because we did not invoke it + * with the WNOHANG option. + */ + PR_ASSERT(0 != ret); + + if (ret < 0) { + PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } + + /* If child process exited normally, return child exit code */ + if (WIFEXITED(status)) { + *exitCode = WEXITSTATUS(status); + } else { + PR_ASSERT(WIFSIGNALED(status)); + *exitCode = _PR_SIGNALED_EXITSTATUS; + } + + PR_DELETE(process); + return PR_SUCCESS; +} + +PRStatus +_MD_kill_process (PRProcess *process) +{ + PRErrorCode prerror; + PRInt32 oserror; + + if (kill(process->md.pid, SIGKILL) == 0) { + return PR_SUCCESS; + } + oserror = errno; + switch (oserror) { + case EPERM: + prerror = PR_NO_ACCESS_RIGHTS_ERROR; + break; + case ESRCH: + prerror = PR_INVALID_ARGUMENT_ERROR; + break; + default: + prerror = PR_UNKNOWN_ERROR; + break; + } + PR_SetError(prerror, oserror); + return PR_FAILURE; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/brng.c nspr-4.10.7/nspr/pr/src/md/beos/brng.c --- nspr-4.9.5/nspr/pr/src/md/beos/brng.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/brng.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "primpl.h" + +extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ) +{ + struct timeval tv; + int n = 0; + int s; + + GETTIMEOFDAY(&tv); + + if ( size > 0 ) { + s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec)); + size -= s; + n += s; + } + if ( size > 0 ) { + s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec)); + size -= s; + n += s; + } + + return n; +} /* end _PR_MD_GetRandomNoise() */ diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bseg.c nspr-4.10.7/nspr/pr/src/md/beos/bseg.c --- nspr-4.9.5/nspr/pr/src/md/beos/bseg.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bseg.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,22 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +PR_IMPLEMENT(void) + _MD_init_segs (void) +{ +} + +PR_IMPLEMENT(PRStatus) + _MD_alloc_segment (PRSegment *seg, PRUint32 size, void *vaddr) +{ + return PR_NOT_IMPLEMENTED_ERROR; +} + +PR_IMPLEMENT(void) + _MD_free_segment (PRSegment *seg) +{ +} diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/bsrcs.mk nspr-4.10.7/nspr/pr/src/md/beos/bsrcs.mk --- nspr-4.9.5/nspr/pr/src/md/beos/bsrcs.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/bsrcs.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,22 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +# this file lists the source files to be compiled (used in Makefile) and +# then enumerated as object files (in objs.mk) for inclusion in the NSPR +# shared library + +MDCSRCS = \ + beos.c \ + beos_errors.c \ + bfile.c \ + bmisc.c \ + bnet.c \ + bproc.c \ + brng.c \ + bseg.c \ + btime.c \ + bmmap.c \ + $(NULL) diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/btime.c nspr-4.10.7/nspr/pr/src/md/beos/btime.c --- nspr-4.9.5/nspr/pr/src/md/beos/btime.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/btime.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,43 @@ +/* -*- Mode: C++; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include + +static bigtime_t start; + +PRTime +_MD_now (void) +{ + return (PRTime)real_time_clock_usecs(); +} + +void +_MD_interval_init (void) +{ + /* grab the base interval time */ + start = real_time_clock_usecs(); +} + +PRIntervalTime +_MD_get_interval (void) +{ + return( (PRIntervalTime) real_time_clock_usecs() / 10 ); + +#if 0 + /* return the number of tens of microseconds that have elapsed since + we were initialized */ + bigtime_t now = real_time_clock_usecs(); + now -= start; + now /= 10; + return (PRIntervalTime)now; +#endif +} + +PRIntervalTime +_MD_interval_per_sec (void) +{ + return 100000L; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/.cvsignore nspr-4.10.7/nspr/pr/src/md/beos/.cvsignore --- nspr-4.9.5/nspr/pr/src/md/beos/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/Makefile.in nspr-4.10.7/nspr/pr/src/md/beos/Makefile.in --- nspr-4.9.5/nspr/pr/src/md/beos/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,28 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +MOD_DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +include $(srcdir)/bsrcs.mk +CSRCS += $(MDCSRCS) + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/md/beos/objs.mk nspr-4.10.7/nspr/pr/src/md/beos/objs.mk --- nspr-4.9.5/nspr/pr/src/md/beos/objs.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/beos/objs.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,11 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This makefile appends to the variable OBJS the platform-dependent +# object modules that will be part of the nspr20 library. + +include $(srcdir)/md/beos/bsrcs.mk + +OBJS += $(MDCSRCS:%.c=md/beos/$(OBJDIR)/%.$(OBJ_SUFFIX)) diff -Nru nspr-4.9.5/nspr/pr/src/md/.cvsignore nspr-4.10.7/nspr/pr/src/md/.cvsignore --- nspr-4.9.5/nspr/pr/src/md/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/md/Makefile.in nspr-4.10.7/nspr/pr/src/md/Makefile.in --- nspr-4.9.5/nspr/pr/src/md/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,32 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +DIRS = $(PR_MD_ARCH_DIR) + +CSRCS = \ + prosdep.c \ + $(NULL) + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/.cvsignore nspr-4.10.7/nspr/pr/src/md/os2/.cvsignore --- nspr-4.9.5/nspr/pr/src/md/os2/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/Makefile.in nspr-4.10.7/nspr/pr/src/md/os2/Makefile.in --- nspr-4.9.5/nspr/pr/src/md/os2/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,47 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +ifeq ($(OS_TARGET), OS2) +CSRCS = \ + os2misc.c \ + os2sem.c \ + os2inrval.c \ + os2gc.c \ + os2thred.c \ + os2io.c \ + os2cv.c \ + os2sock.c \ + os2_errors.c \ + os2poll.c \ + os2rng.c \ + $(NULL) +endif + +ASFILES = os2emx.s os2vaclegacy.s + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + + + + diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/objs.mk nspr-4.10.7/nspr/pr/src/md/os2/objs.mk --- nspr-4.9.5/nspr/pr/src/md/os2/objs.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/objs.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,27 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This makefile appends to the variable OBJS the platform-dependent +# object modules that will be part of the nspr20 library. + +CSRCS = \ + os2io.c \ + os2sock.c \ + os2thred.c \ + os2cv.c \ + os2gc.c \ + os2misc.c \ + os2inrval.c \ + os2sem.c \ + os2_errors.c \ + os2poll.c \ + os2rng.c \ + $(NULL) + +ASFILES = os2emx.s os2vaclegacy.s + +OBJS += $(addprefix md/os2/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \ + $(addprefix md/os2/$(OBJDIR)/,$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))) + diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2cv.c nspr-4.10.7/nspr/pr/src/md/os2/os2cv.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2cv.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2cv.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,330 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * os2cv.c -- OS/2 Machine-Dependent Code for Condition Variables + * + * We implement our own condition variable wait queue. Each thread + * has a semaphore object (thread->md.blocked_sema) to block on while + * waiting on a condition variable. + * + * We use a deferred condition notify algorithm. When PR_NotifyCondVar + * or PR_NotifyAllCondVar is called, the condition notifies are simply + * recorded in the _MDLock structure. We defer the condition notifies + * until right after we unlock the lock. This way the awakened threads + * have a better chance to reaquire the lock. + */ + +#include "primpl.h" + +/* + * AddThreadToCVWaitQueueInternal -- + * + * Add the thread to the end of the condition variable's wait queue. + * The CV's lock must be locked when this function is called. + */ + +static void +AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv) +{ + PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL) + || (cv->waitTail == NULL && cv->waitHead == NULL)); + cv->nwait += 1; + thred->md.inCVWaitQueue = PR_TRUE; + thred->md.next = NULL; + thred->md.prev = cv->waitTail; + if (cv->waitHead == NULL) { + cv->waitHead = thred; + } else { + cv->waitTail->md.next = thred; + } + cv->waitTail = thred; +} + +/* + * md_UnlockAndPostNotifies -- + * + * Unlock the lock, and then do the deferred condition notifies. + * If waitThred and waitCV are not NULL, waitThred is added to + * the wait queue of waitCV before the lock is unlocked. + * + * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK, + * the two places where a lock is unlocked. + */ +void +md_UnlockAndPostNotifies( + _MDLock *lock, + PRThread *waitThred, + _MDCVar *waitCV) +{ + PRIntn index; + _MDNotified post; + _MDNotified *notified, *prev = NULL; + + /* + * Time to actually notify any conditions that were affected + * while the lock was held. Get a copy of the list that's in + * the lock structure and then zero the original. If it's + * linked to other such structures, we own that storage. + */ + post = lock->notified; /* a safe copy; we own the lock */ + +#if defined(DEBUG) + memset(&lock->notified, 0, sizeof(_MDNotified)); /* reset */ +#else + lock->notified.length = 0; /* these are really sufficient */ + lock->notified.link = NULL; +#endif + + /* + * Figure out how many threads we need to wake up. + */ + notified = &post; /* this is where we start */ + do { + for (index = 0; index < notified->length; ++index) { + _MDCVar *cv = notified->cv[index].cv; + PRThread *thred; + int i; + + /* Fast special case: no waiting threads */ + if (cv->waitHead == NULL) { + notified->cv[index].notifyHead = NULL; + continue; + } + + /* General case */ + if (-1 == notified->cv[index].times) { + /* broadcast */ + thred = cv->waitHead; + while (thred != NULL) { + thred->md.inCVWaitQueue = PR_FALSE; + thred = thred->md.next; + } + notified->cv[index].notifyHead = cv->waitHead; + cv->waitHead = cv->waitTail = NULL; + cv->nwait = 0; + } else { + thred = cv->waitHead; + i = notified->cv[index].times; + while (thred != NULL && i > 0) { + thred->md.inCVWaitQueue = PR_FALSE; + thred = thred->md.next; + i--; + } + notified->cv[index].notifyHead = cv->waitHead; + cv->waitHead = thred; + if (cv->waitHead == NULL) { + cv->waitTail = NULL; + } else { + if (cv->waitHead->md.prev != NULL) { + cv->waitHead->md.prev->md.next = NULL; + cv->waitHead->md.prev = NULL; + } + } + cv->nwait -= notified->cv[index].times - i; + } + } + notified = notified->link; + } while (NULL != notified); + + if (waitThred) { + AddThreadToCVWaitQueueInternal(waitThred, waitCV); + } + + /* Release the lock before notifying */ + DosReleaseMutexSem(lock->mutex); + + notified = &post; /* this is where we start */ + do { + for (index = 0; index < notified->length; ++index) { + PRThread *thred; + PRThread *next; + + thred = notified->cv[index].notifyHead; + while (thred != NULL) { + BOOL rv; + + next = thred->md.next; + thred->md.prev = thred->md.next = NULL; + rv = DosPostEventSem(thred->md.blocked_sema); + PR_ASSERT(rv == NO_ERROR); + thred = next; + } + } + prev = notified; + notified = notified->link; + if (&post != prev) PR_DELETE(prev); + } while (NULL != notified); +} + +/* + * Notifies just get posted to the protecting mutex. The + * actual notification is done when the lock is released so that + * MP systems don't contend for a lock that they can't have. + */ +static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock, + PRBool broadcast) +{ + PRIntn index = 0; + _MDNotified *notified = &lock->notified; + + while (1) { + for (index = 0; index < notified->length; ++index) { + if (notified->cv[index].cv == cvar) { + if (broadcast) { + notified->cv[index].times = -1; + } else if (-1 != notified->cv[index].times) { + notified->cv[index].times += 1; + } + return; + } + } + /* if not full, enter new CV in this array */ + if (notified->length < _MD_CV_NOTIFIED_LENGTH) break; + + /* if there's no link, create an empty array and link it */ + if (NULL == notified->link) { + notified->link = PR_NEWZAP(_MDNotified); + } + + notified = notified->link; + } + + /* A brand new entry in the array */ + notified->cv[index].times = (broadcast) ? -1 : 1; + notified->cv[index].cv = cvar; + notified->length += 1; +} + +/* + * _PR_MD_NEW_CV() -- Creating new condition variable + * ... Solaris uses cond_init() in similar function. + * + * returns: -1 on failure + * 0 when it succeeds. + * + */ +PRInt32 +_PR_MD_NEW_CV(_MDCVar *cv) +{ + cv->magic = _MD_MAGIC_CV; + /* + * The waitHead, waitTail, and nwait fields are zeroed + * when the PRCondVar structure is created. + */ + return 0; +} + +void _PR_MD_FREE_CV(_MDCVar *cv) +{ + cv->magic = (PRUint32)-1; + return; +} + +/* + * _PR_MD_WAIT_CV() -- Wait on condition variable + */ +void +_PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout ) +{ + PRThread *thred = _PR_MD_CURRENT_THREAD(); + ULONG rv, count; + ULONG msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ? + SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(timeout); + + /* + * If we have pending notifies, post them now. + */ + if (0 != lock->notified.length) { + md_UnlockAndPostNotifies(lock, thred, cv); + } else { + AddThreadToCVWaitQueueInternal(thred, cv); + DosReleaseMutexSem(lock->mutex); + } + + /* Wait for notification or timeout; don't really care which */ + rv = DosWaitEventSem(thred->md.blocked_sema, msecs); + if (rv == NO_ERROR) { + DosResetEventSem(thred->md.blocked_sema, &count); + } + + DosRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT); + + PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT); + + if(rv == ERROR_TIMEOUT) + { + if (thred->md.inCVWaitQueue) { + PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL) + || (cv->waitTail == NULL && cv->waitHead == NULL)); + cv->nwait -= 1; + thred->md.inCVWaitQueue = PR_FALSE; + if (cv->waitHead == thred) { + cv->waitHead = thred->md.next; + if (cv->waitHead == NULL) { + cv->waitTail = NULL; + } else { + cv->waitHead->md.prev = NULL; + } + } else { + PR_ASSERT(thred->md.prev != NULL); + thred->md.prev->md.next = thred->md.next; + if (thred->md.next != NULL) { + thred->md.next->md.prev = thred->md.prev; + } else { + PR_ASSERT(cv->waitTail == thred); + cv->waitTail = thred->md.prev; + } + } + thred->md.next = thred->md.prev = NULL; + } else { + /* + * This thread must have been notified, but the + * SemRelease call happens after SemRequest + * times out. Wait on the semaphore again to make it + * non-signaled. We assume this wait won't take long. + */ + rv = DosWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT); + if (rv == NO_ERROR) { + DosResetEventSem(thred->md.blocked_sema, &count); + } + PR_ASSERT(rv == NO_ERROR); + } + } + PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE); + return; +} /* --- end _PR_MD_WAIT_CV() --- */ + +void +_PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock) +{ + md_PostNotifyToCvar(cv, lock, PR_FALSE); + return; +} + +PRStatus +_PR_MD_NEW_LOCK(_MDLock *lock) +{ + DosCreateMutexSem(0, &(lock->mutex), 0, 0); + (lock)->notified.length=0; + (lock)->notified.link=NULL; + return PR_SUCCESS; +} + +void +_PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock) +{ + md_PostNotifyToCvar(cv, lock, PR_TRUE); + return; +} + +void _PR_MD_UNLOCK(_MDLock *lock) +{ + if (0 != lock->notified.length) { + md_UnlockAndPostNotifies(lock, NULL, NULL); + } else { + DosReleaseMutexSem(lock->mutex); + } +} diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2emx.s nspr-4.10.7/nspr/pr/src/md/os2/os2emx.s --- nspr-4.9.5/nspr/pr/src/md/os2/os2emx.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2emx.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,82 @@ +/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/ +/ This Source Code Form is subject to the terms of the Mozilla Public +/ License, v. 2.0. If a copy of the MPL was not distributed with this +/ file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/ PRInt32 __PR_MD_ATOMIC_INCREMENT(PRInt32 *val) +/ +/ Atomically increment the integer pointed to by 'val' and return +/ the result of the increment. +/ + .text + .globl __PR_MD_ATOMIC_INCREMENT + .align 4 +__PR_MD_ATOMIC_INCREMENT: + movl 4(%esp), %ecx + movl $1, %eax + lock + xaddl %eax, (%ecx) + incl %eax + ret + +/ PRInt32 __PR_MD_ATOMIC_DECREMENT(PRInt32 *val) +/ +/ Atomically decrement the integer pointed to by 'val' and return +/ the result of the decrement. +/ + .text + .globl __PR_MD_ATOMIC_DECREMENT + .align 4 +__PR_MD_ATOMIC_DECREMENT: + movl 4(%esp), %ecx + movl $-1, %eax + lock + xaddl %eax, (%ecx) + decl %eax + ret + +/ PRInt32 __PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) +/ +/ Atomically set the integer pointed to by 'val' to the new +/ value 'newval' and return the old value. +/ +/ An alternative implementation: +/ .text +/ .globl __PR_MD_ATOMIC_SET +/ .align 4 +/__PR_MD_ATOMIC_SET: +/ movl 4(%esp), %ecx +/ movl 8(%esp), %edx +/ movl (%ecx), %eax +/retry: +/ lock +/ cmpxchgl %edx, (%ecx) +/ jne retry +/ ret +/ + .text + .globl __PR_MD_ATOMIC_SET + .align 4 +__PR_MD_ATOMIC_SET: + movl 4(%esp), %ecx + movl 8(%esp), %eax + xchgl %eax, (%ecx) + ret + +/ PRInt32 __PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) +/ +/ Atomically add 'val' to the integer pointed to by 'ptr' +/ and return the result of the addition. +/ + .text + .globl __PR_MD_ATOMIC_ADD + .align 4 +__PR_MD_ATOMIC_ADD: + movl 4(%esp), %ecx + movl 8(%esp), %eax + movl %eax, %edx + lock + xaddl %eax, (%ecx) + addl %edx, %eax + ret diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2_errors.c nspr-4.10.7/nspr/pr/src/md/os2/os2_errors.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2_errors.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2_errors.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1095 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prerror.h" +#include "primpl.h" + +void _MD_os2_map_default_error(PRInt32 err) +{ + switch (err) { + case EWOULDBLOCK: + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case EMSGSIZE: + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ENOBUFS: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ECONNREFUSED: + PR_SetError(PR_CONNECT_REFUSED_ERROR, err); + break; + case EISCONN: + PR_SetError(PR_IS_CONNECTED_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case ERROR_NETNAME_DELETED: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} +void _MD_os2_map_opendir_error(PRInt32 err) +{ + switch (err) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + case ERROR_INVALID_ACCESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_INVALID_NAME: + case ERROR_INVALID_PARAMETER: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ERROR_TOO_MANY_OPEN_FILES: + case ERROR_NOT_DOS_DISK: + case ERROR_NOT_READY: + case ERROR_OPEN_FAILED: + case ERROR_PATH_BUSY: + case ERROR_CANNOT_MAKE: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + case ERROR_DEVICE_IN_USE: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_FILENAME_EXCED_RANGE: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_SHARING_BUFFER_EXCEEDED: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_closedir_error(PRInt32 err) +{ + switch (err) { + case ERROR_FILE_NOT_FOUND: + case ERROR_ACCESS_DENIED: + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_readdir_error(PRInt32 err) +{ + + switch (err) { + case ERROR_NO_MORE_FILES: + PR_SetError(PR_NO_MORE_FILES_ERROR, err); + break; + case ERROR_FILE_NOT_FOUND: + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_NOT_DOS_DISK: + case ERROR_LOCK_VIOLATION: + case ERROR_BROKEN_PIPE: + case ERROR_NOT_READY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_delete_error(PRInt32 err) +{ + switch (err) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_ACCESS_DENIED: + case ERROR_WRITE_PROTECT: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + case ERROR_LOCKED: + case ERROR_SHARING_VIOLATION: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +/* The error code for stat() is in errno. */ +void _MD_os2_map_stat_error(PRInt32 err) +{ + switch (err) { + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + } +} + +void _MD_os2_map_fstat_error(PRInt32 err) +{ + switch (err) { + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + case ERROR_LOCKED: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_rename_error(PRInt32 err) +{ + switch (err) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_INVALID_NAME: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_FILENAME_EXCED_RANGE: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + PR_SetError(PR_FILE_EXISTS_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +/* The error code for access() is in errno. */ +void _MD_os2_map_access_error(PRInt32 err) +{ + switch (err) { + case ENOENT: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + } +} + +void _MD_os2_map_mkdir_error(PRInt32 err) +{ + switch (err) { + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + PR_SetError(PR_FILE_EXISTS_ERROR, err); + break; + case ERROR_FILE_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_INVALID_NAME: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_FILENAME_EXCED_RANGE: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ERROR_TOO_MANY_OPEN_FILES: + PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); + break; + case ERROR_PATH_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ERROR_DISK_FULL: + case ERROR_HANDLE_DISK_FULL: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; + case ERROR_WRITE_PROTECT: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_rmdir_error(PRInt32 err) +{ + + switch (err) { + case ERROR_FILE_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_INVALID_NAME: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_FILENAME_EXCED_RANGE: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ERROR_TOO_MANY_OPEN_FILES: + PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); + break; + case ERROR_PATH_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ERROR_WRITE_PROTECT: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_read_error(PRInt32 err) +{ + switch (err) { + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + case ERROR_LOCKED: + case ERROR_SHARING_VIOLATION: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_NETNAME_DELETED: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_transmitfile_error(PRInt32 err) +{ + switch (err) { + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + case ERROR_LOCKED: + case ERROR_SHARING_VIOLATION: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_FILENAME_EXCED_RANGE: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ERROR_TOO_MANY_OPEN_FILES: + PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); + break; + case ERROR_PATH_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_write_error(PRInt32 err) +{ + switch (err) { + case ERROR_ACCESS_DENIED: + case ERROR_WRITE_PROTECT: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + case ERROR_LOCKED: + case ERROR_SHARING_VIOLATION: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + case ERROR_DISK_FULL: + case ERROR_HANDLE_DISK_FULL: + case ENOSPC: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; + case ERROR_NETNAME_DELETED: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case EMSGSIZE: + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ENOBUFS: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ECONNREFUSED: + PR_SetError(PR_CONNECT_REFUSED_ERROR, err); + break; + case EISCONN: + PR_SetError(PR_IS_CONNECTED_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_lseek_error(PRInt32 err) +{ + switch (err) { + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_SEEK_ON_DEVICE: + PR_SetError(PR_IO_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_fsync_error(PRInt32 err) +{ + switch (err) { + case ERROR_ACCESS_DENIED: + case ERROR_WRITE_PROTECT: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ERROR_DISK_FULL: + case ERROR_HANDLE_DISK_FULL: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_close_error(PRInt32 err) +{ + switch (err) { + case ERROR_INVALID_HANDLE: + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_socket_error(PRInt32 err) +{ + switch (err) { + case EPROTONOSUPPORT: + PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + case ENOBUFS: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_recv_error(PRInt32 err) +{ + switch (err) { + case EWOULDBLOCK: + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case ERROR_NETNAME_DELETED: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_recvfrom_error(PRInt32 err) +{ + switch (err) { + case EWOULDBLOCK: + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case ERROR_NETNAME_DELETED: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_send_error(PRInt32 err) +{ + switch (err) { + case EWOULDBLOCK: + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case EMSGSIZE: + case EINVAL: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ENOBUFS: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ECONNREFUSED: + PR_SetError(PR_CONNECT_REFUSED_ERROR, err); + break; + case EISCONN: + PR_SetError(PR_IS_CONNECTED_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case ERROR_NETNAME_DELETED: + PR_SetError(PR_CONNECT_RESET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_sendto_error(PRInt32 err) +{ + _MD_os2_map_default_error(err); +} + +void _MD_os2_map_writev_error(int err) +{ + _MD_os2_map_default_error(err); +} + +void _MD_os2_map_accept_error(PRInt32 err) +{ + _MD_os2_map_default_error(err); +} + +void _MD_os2_map_acceptex_error(PRInt32 err) +{ + switch (err) { + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +/* + * An error code of 0 means that the nonblocking connect succeeded. + */ + +int _MD_os2_get_nonblocking_connect_error(int osfd) +{ + int err; + int len = sizeof(err); + if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == -1) { + return sock_errno(); + } else { + return err; + } +} + +void _MD_os2_map_connect_error(PRInt32 err) +{ + switch (err) { + case EWOULDBLOCK: + PR_SetError(PR_WOULD_BLOCK_ERROR, err); + break; + case EINPROGRESS: + PR_SetError(PR_IN_PROGRESS_ERROR, err); + break; + case EALREADY: + case EINVAL: + PR_SetError(PR_ALREADY_INITIATED_ERROR, err); + break; + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case EADDRNOTAVAIL: + PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case EAFNOSUPPORT: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; + case ETIMEDOUT: + PR_SetError(PR_IO_TIMEOUT_ERROR, err); + break; + case ECONNREFUSED: + PR_SetError(PR_CONNECT_REFUSED_ERROR, err); + break; + case ENETUNREACH: + PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err); + break; + case EADDRINUSE: + PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); + break; + case EISCONN: + PR_SetError(PR_IS_CONNECTED_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_bind_error(PRInt32 err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case EADDRNOTAVAIL: + PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err); + break; + case EADDRINUSE: + PR_SetError(PR_ADDRESS_IN_USE_ERROR, err); + break; + case EACCES: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case EINVAL: + PR_SetError(PR_SOCKET_ADDRESS_IS_BOUND_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_listen_error(PRInt32 err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case EOPNOTSUPP: + PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_shutdown_error(PRInt32 err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case ENOTCONN: + PR_SetError(PR_NOT_CONNECTED_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_socketpair_error(PRInt32 err) +{ + switch (err) { + case ENOMEM: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case EAFNOSUPPORT: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; + case EPROTONOSUPPORT: + PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err); + break; + case EOPNOTSUPP: + PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err); + break; + case EPROTOTYPE: + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err); + break; + default: + _MD_os2_map_default_error(err); + return; + } +} + +void _MD_os2_map_getsockname_error(PRInt32 err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case ENOBUFS: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_getpeername_error(PRInt32 err) +{ + + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case ENOTCONN: + PR_SetError(PR_NOT_CONNECTED_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case ENOBUFS: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_getsockopt_error(PRInt32 err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case ENOPROTOOPT: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case EINVAL: + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_setsockopt_error(PRInt32 err) +{ + switch (err) { + case EBADF: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ENOTSOCK: + PR_SetError(PR_NOT_SOCKET_ERROR, err); + break; + case ENOPROTOOPT: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case EINVAL: + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_open_error(PRInt32 err) +{ + switch (err) { + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + PR_SetError(PR_FILE_EXISTS_ERROR, err); + break; + case ERROR_FILE_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_INVALID_NAME: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, err); + break; + case ERROR_NOT_READY: + case ERROR_OPEN_FAILED: + case ERROR_PATH_BUSY: + PR_SetError(PR_IO_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_FILENAME_EXCED_RANGE: + PR_SetError(PR_NAME_TOO_LONG_ERROR, err); + break; + case ERROR_TOO_MANY_OPEN_FILES: + PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err); + break; + case ERROR_PATH_NOT_FOUND: + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + case ERROR_DISK_FULL: + case ERROR_HANDLE_DISK_FULL: + PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err); + break; + case ERROR_WRITE_PROTECT: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_gethostname_error(PRInt32 err) +{ + switch (err) { +#ifdef SOCEFAULT + case SOCEFAULT: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; +#endif + case ENETDOWN: + case EINPROGRESS: + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} + +void _MD_os2_map_select_error(PRInt32 err) +{ + PRErrorCode prerror; + + switch (err) { + /* + * OS/2 select() only works on sockets. So in this + * context, ENOTSOCK is equivalent to EBADF on Unix. + */ + case ENOTSOCK: + prerror = PR_BAD_DESCRIPTOR_ERROR; + break; + case EINVAL: + prerror = PR_INVALID_ARGUMENT_ERROR; + break; +#ifdef SOCEFAULT + case SOCEFAULT: + prerror = PR_ACCESS_FAULT_ERROR; + break; +#endif + default: + prerror = PR_UNKNOWN_ERROR; + } + PR_SetError(prerror, err); +} + +void _MD_os2_map_lockf_error(PRInt32 err) +{ + switch (err) { + case ERROR_ACCESS_DENIED: + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err); + break; + case ERROR_INVALID_HANDLE: + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); + break; + case ERROR_INVALID_ADDRESS: + PR_SetError(PR_ACCESS_FAULT_ERROR, err); + break; + case ERROR_DRIVE_LOCKED: + case ERROR_LOCKED: + case ERROR_SHARING_VIOLATION: + PR_SetError(PR_FILE_IS_LOCKED_ERROR, err); + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_MORE_DATA: + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err); + break; + default: + PR_SetError(PR_UNKNOWN_ERROR, err); + break; + } +} diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2gc.c nspr-4.10.7/nspr/pr/src/md/os2/os2gc.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2gc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2gc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * GC related routines + * + */ +#include "primpl.h" + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + CONTEXTRECORD context; + context.ContextFlags = CONTEXT_INTEGER; + + if (_PR_IS_NATIVE_THREAD(t)) { + context.ContextFlags |= CONTEXT_CONTROL; + if (QueryThreadContext(t->md.handle, CONTEXT_CONTROL, &context)) { + t->md.gcContext[0] = context.ctx_RegEax; + t->md.gcContext[1] = context.ctx_RegEbx; + t->md.gcContext[2] = context.ctx_RegEcx; + t->md.gcContext[3] = context.ctx_RegEdx; + t->md.gcContext[4] = context.ctx_RegEsi; + t->md.gcContext[5] = context.ctx_RegEdi; + t->md.gcContext[6] = context.ctx_RegEsp; + t->md.gcContext[7] = context.ctx_RegEbp; + *np = PR_NUM_GCREGS; + } else { + PR_ASSERT(0);/* XXX */ + } + } + return (PRWord *)&t->md.gcContext; +} + +/* This function is not used right now, but is left as a reference. + * If you ever need to get the fiberID from the currently running fiber, + * this is it. + */ +void * +GetMyFiberID() +{ + void *fiberData = 0; + + /* A pointer to our tib entry is found at FS:[18] + * At offset 10h is the fiberData pointer. The context of the + * fiber is stored in there. + */ +#ifdef HAVE_ASM + __asm { + mov EDX, FS:[18h] + mov EAX, DWORD PTR [EDX+10h] + mov [fiberData], EAX + } +#endif + + return fiberData; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2inrval.c nspr-4.10.7/nspr/pr/src/md/os2/os2inrval.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2inrval.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2inrval.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * OS/2 interval timers + * + */ + +#include "primpl.h" + +static PRBool useHighResTimer = PR_FALSE; +PRIntervalTime _os2_ticksPerSec = -1; +PRIntn _os2_bitShift = 0; +PRInt32 _os2_highMask = 0; + +void +_PR_MD_INTERVAL_INIT() +{ + char *envp; + ULONG timerFreq; + APIRET rc; + + if ((envp = getenv("NSPR_OS2_NO_HIRES_TIMER")) != NULL) { + if (atoi(envp) == 1) + return; + } + + timerFreq = 0; /* OS/2 high-resolution timer frequency in Hz */ + rc = DosTmrQueryFreq(&timerFreq); + if (NO_ERROR == rc) { + useHighResTimer = PR_TRUE; + PR_ASSERT(timerFreq != 0); + while (timerFreq > PR_INTERVAL_MAX) { + timerFreq >>= 1; + _os2_bitShift++; + _os2_highMask = (_os2_highMask << 1)+1; + } + + _os2_ticksPerSec = timerFreq; + PR_ASSERT(_os2_ticksPerSec > PR_INTERVAL_MIN); + } +} + +PRIntervalTime +_PR_MD_GET_INTERVAL() +{ + if (useHighResTimer) { + QWORD timestamp; + PRInt32 top; + APIRET rc = DosTmrQueryTime(×tamp); + if (NO_ERROR != rc) { + return -1; + } + /* Sadly, nspr requires the interval to range from 1000 ticks per + * second to only 100000 ticks per second. DosTmrQueryTime is too + * high resolution... + */ + top = timestamp.ulHi & _os2_highMask; + top = top << (32 - _os2_bitShift); + timestamp.ulLo = timestamp.ulLo >> _os2_bitShift; + timestamp.ulLo = timestamp.ulLo + top; + return (PRUint32)timestamp.ulLo; + } else { + ULONG msCount = -1; + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msCount, sizeof(msCount)); + return msCount; + } +} + +PRIntervalTime +_PR_MD_INTERVAL_PER_SEC() +{ + if (useHighResTimer) { + return _os2_ticksPerSec; + } else { + return 1000; + } +} diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2io.c nspr-4.10.7/nspr/pr/src/md/os2/os2io.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2io.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2io.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,942 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* OS2 IO module + * + * Assumes synchronous I/O. + * + */ + +#include "primpl.h" +#include "prio.h" +#include +#include +#include +#include +#include +#include + +struct _MDLock _pr_ioq_lock; + +static PRBool isWSEB = PR_FALSE; /* whether we are using an OS/2 kernel that supports large files */ + +typedef APIRET (*DosOpenLType)(PSZ pszFileName, PHFILE pHf, PULONG pulAction, + LONGLONG cbFile, ULONG ulAttribute, + ULONG fsOpenFlags, ULONG fsOpenMode, + PEAOP2 peaop2); + +typedef APIRET (*DosSetFileLocksLType)(HFILE hFile, PFILELOCKL pflUnlock, + PFILELOCKL pflLock, ULONG timeout, + ULONG flags); + +typedef APIRET (*DosSetFilePtrLType)(HFILE hFile, LONGLONG ib, ULONG method, + PLONGLONG ibActual); + +DosOpenLType myDosOpenL; +DosSetFileLocksLType myDosSetFileLocksL; +DosSetFilePtrLType myDosSetFilePtrL; + +void +_PR_MD_INIT_IO() +{ + APIRET rc; + HMODULE module; + + sock_init(); + + rc = DosLoadModule(NULL, 0, "DOSCALL1", &module); + if (rc != NO_ERROR) + { + return; + } + rc = DosQueryProcAddr(module, 981, NULL, (PFN*) &myDosOpenL); + if (rc != NO_ERROR) + { + return; + } + rc = DosQueryProcAddr(module, 986, NULL, (PFN*) &myDosSetFileLocksL); + if (rc != NO_ERROR) + { + return; + } + rc = DosQueryProcAddr(module, 988, NULL, (PFN*) &myDosSetFilePtrL); + if (rc != NO_ERROR) + { + return; + } + isWSEB = PR_TRUE; +} + +PRStatus +_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PRInt32 rv; + ULONG count; + + PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? + SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks); + rv = DosWaitEventSem(thread->md.blocked_sema, msecs); + DosResetEventSem(thread->md.blocked_sema, &count); + switch(rv) + { + case NO_ERROR: + return PR_SUCCESS; + break; + case ERROR_TIMEOUT: + _PR_THREAD_LOCK(thread); + if (thread->state == _PR_IO_WAIT) { + ; + } else { + if (thread->wait.cvar != NULL) { + thread->wait.cvar = NULL; + _PR_THREAD_UNLOCK(thread); + } else { + /* The CVAR was notified just as the timeout + * occurred. This led to us being notified twice. + * call SemRequest() to clear the semaphore. + */ + _PR_THREAD_UNLOCK(thread); + rv = DosWaitEventSem(thread->md.blocked_sema, 0); + DosResetEventSem(thread->md.blocked_sema, &count); + PR_ASSERT(rv == NO_ERROR); + } + } + return PR_SUCCESS; + break; + default: + break; + } + return PR_FAILURE; +} +PRStatus +_PR_MD_WAKEUP_WAITER(PRThread *thread) +{ + if ( _PR_IS_NATIVE_THREAD(thread) ) + { + if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR) + return PR_FAILURE; + else + return PR_SUCCESS; + } +} + + +/* --- FILE IO ----------------------------------------------------------- */ +/* + * _PR_MD_OPEN() -- Open a file + * + * returns: a fileHandle + * + * The NSPR open flags (osflags) are translated into flags for OS/2 + * + * Mode seems to be passed in as a unix style file permissions argument + * as in 0666, in the case of opening the logFile. + * + */ +PRInt32 +_PR_MD_OPEN(const char *name, PRIntn osflags, int mode) +{ + HFILE file; + PRInt32 access = OPEN_SHARE_DENYNONE; + PRInt32 flags = 0L; + APIRET rc = 0; + PRUword actionTaken; + +#ifdef MOZ_OS2_HIGH_MEMORY + /* + * All the pointer arguments (&file, &actionTaken and name) have to be in + * low memory for DosOpen to use them. + * The following moves name to low memory. + */ + if ((ULONG)name >= 0x20000000) + { + size_t len = strlen(name) + 1; + char *copy = (char *)alloca(len); + memcpy(copy, name, len); + name = copy; + } +#endif + + if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH; + + if (osflags & PR_RDONLY) + access |= OPEN_ACCESS_READONLY; + else if (osflags & PR_WRONLY) + access |= OPEN_ACCESS_WRITEONLY; + else if(osflags & PR_RDWR) + access |= OPEN_ACCESS_READWRITE; + + if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) + { + flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; + } + else if (osflags & PR_CREATE_FILE) + { + if (osflags & PR_TRUNCATE) + flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; + else + flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; + } + else + { + if (osflags & PR_TRUNCATE) + flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS; + else + flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; + } + + do { + if (isWSEB) + { + rc = myDosOpenL((char*)name, + &file, /* file handle if successful */ + &actionTaken, /* reason for failure */ + 0, /* initial size of new file */ + FILE_NORMAL, /* file system attributes */ + flags, /* Open flags */ + access, /* Open mode and rights */ + 0); /* OS/2 Extended Attributes */ + } + else + { + rc = DosOpen((char*)name, + &file, /* file handle if successful */ + &actionTaken, /* reason for failure */ + 0, /* initial size of new file */ + FILE_NORMAL, /* file system attributes */ + flags, /* Open flags */ + access, /* Open mode and rights */ + 0); /* OS/2 Extended Attributes */ + }; + if (rc == ERROR_TOO_MANY_OPEN_FILES) { + ULONG CurMaxFH = 0; + LONG ReqCount = 20; + APIRET rc2; + rc2 = DosSetRelMaxFH(&ReqCount, &CurMaxFH); + if (rc2 != NO_ERROR) { + break; + } + } + } while (rc == ERROR_TOO_MANY_OPEN_FILES); + + if (rc != NO_ERROR) { + _PR_MD_MAP_OPEN_ERROR(rc); + return -1; + } + + return (PRInt32)file; +} + +PRInt32 +_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len) +{ + ULONG bytes; + int rv; + + rv = DosRead((HFILE)fd->secret->md.osfd, + (PVOID)buf, + len, + &bytes); + + if (rv != NO_ERROR) + { + /* ERROR_HANDLE_EOF can only be returned by async io */ + PR_ASSERT(rv != ERROR_HANDLE_EOF); + if (rv == ERROR_BROKEN_PIPE) + return 0; + else { + _PR_MD_MAP_READ_ERROR(rv); + return -1; + } + } + return (PRInt32)bytes; +} + +PRInt32 +_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len) +{ + PRInt32 bytes; + int rv; + + rv = DosWrite((HFILE)fd->secret->md.osfd, + (PVOID)buf, + len, + (PULONG)&bytes); + + if (rv != NO_ERROR) + { + _PR_MD_MAP_WRITE_ERROR(rv); + return -1; + } + + if (len != bytes) { + rv = ERROR_DISK_FULL; + _PR_MD_MAP_WRITE_ERROR(rv); + return -1; + } + + return bytes; +} /* --- end _PR_MD_WRITE() --- */ + +PRInt32 +_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence) +{ + PRInt32 rv; + PRUword newLocation; + + rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation); + + if (rv != NO_ERROR) { + _PR_MD_MAP_LSEEK_ERROR(rv); + return -1; + } else + return newLocation; +} + +PRInt64 +_PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence) +{ +#ifdef NO_LONG_LONG + PRInt64 result; + PRInt32 rv, low = offset.lo, hi = offset.hi; + PRUword newLocation; + + rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation); + rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation); + + if (rv != NO_ERROR) { + _PR_MD_MAP_LSEEK_ERROR(rv); + hi = newLocation = -1; + } + + result.lo = newLocation; + result.hi = hi; + return result; + +#else + PRInt32 where, rc, lo = (PRInt32)offset, hi = (PRInt32)(offset >> 32); + PRUint64 rv; + PRUint32 newLocation, uhi; + PRUint64 newLocationL; + + switch (whence) + { + case PR_SEEK_SET: + where = FILE_BEGIN; + break; + case PR_SEEK_CUR: + where = FILE_CURRENT; + break; + case PR_SEEK_END: + where = FILE_END; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + if (isWSEB) + { + rc = myDosSetFilePtrL((HFILE)fd->secret->md.osfd, offset, where, (PLONGLONG)&newLocationL); + } + else + { + rc = DosSetFilePtr((HFILE)fd->secret->md.osfd, lo, where, (PULONG)&newLocation); + } + + if (rc != NO_ERROR) { + _PR_MD_MAP_LSEEK_ERROR(rc); + return -1; + } + + if (isWSEB) + { + return newLocationL; + } + + uhi = (PRUint32)hi; + PR_ASSERT((PRInt32)uhi >= 0); + rv = uhi; + PR_ASSERT((PRInt64)rv >= 0); + rv = (rv << 32); + PR_ASSERT((PRInt64)rv >= 0); + rv += newLocation; + PR_ASSERT((PRInt64)rv >= 0); + return (PRInt64)rv; +#endif +} + +PRInt32 +_PR_MD_FSYNC(PRFileDesc *fd) +{ + PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd); + + if (rc != NO_ERROR) { + if (rc != ERROR_ACCESS_DENIED) { + _PR_MD_MAP_FSYNC_ERROR(rc); + return -1; + } + } + return 0; +} + +PRInt32 +_MD_CloseFile(PRInt32 osfd) +{ + PRInt32 rv; + + rv = DosClose((HFILE)osfd); + if (rv != NO_ERROR) + _PR_MD_MAP_CLOSE_ERROR(rv); + return rv; +} + + +/* --- DIR IO ------------------------------------------------------------ */ +#define GetFileFromDIR(d) (isWSEB?(d)->d_entry.large.achName:(d)->d_entry.small.achName) +#define GetFileAttr(d) (isWSEB?(d)->d_entry.large.attrFile:(d)->d_entry.small.attrFile) + +void FlipSlashes(char *cp, int len) +{ + while (--len >= 0) { + if (cp[0] == '/') { + cp[0] = PR_DIRECTORY_SEPARATOR; + } + cp++; + } +} + +/* +** +** Local implementations of standard Unix RTL functions which are not provided +** by the VAC RTL. +** +*/ + +PRInt32 +_PR_MD_CLOSE_DIR(_MDDir *d) +{ + PRInt32 rc; + + if ( d ) { + rc = DosFindClose(d->d_hdl); + if(rc == NO_ERROR){ + d->magic = (PRUint32)-1; + return PR_SUCCESS; + } else { + _PR_MD_MAP_CLOSEDIR_ERROR(rc); + return PR_FAILURE; + } + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; +} + + +PRStatus +_PR_MD_OPEN_DIR(_MDDir *d, const char *name) +{ + char filename[ CCHMAXPATH ]; + PRUword numEntries, rc; + + numEntries = 1; + + PR_snprintf(filename, CCHMAXPATH, "%s%s%s", + name, PR_DIRECTORY_SEPARATOR_STR, "*.*"); + FlipSlashes( filename, strlen(filename) ); + + d->d_hdl = HDIR_CREATE; + + if (isWSEB) + { + rc = DosFindFirst( filename, + &d->d_hdl, + FILE_DIRECTORY | FILE_HIDDEN, + &(d->d_entry.large), + sizeof(d->d_entry.large), + &numEntries, + FIL_STANDARDL); + } + else + { + rc = DosFindFirst( filename, + &d->d_hdl, + FILE_DIRECTORY | FILE_HIDDEN, + &(d->d_entry.small), + sizeof(d->d_entry.small), + &numEntries, + FIL_STANDARD); + } + if ( rc != NO_ERROR ) { + _PR_MD_MAP_OPENDIR_ERROR(rc); + return PR_FAILURE; + } + d->firstEntry = PR_TRUE; + d->magic = _MD_MAGIC_DIR; + return PR_SUCCESS; +} + +char * +_PR_MD_READ_DIR(_MDDir *d, PRIntn flags) +{ + PRUword numFiles = 1; + BOOL rv; + char *fileName; + USHORT fileAttr; + + if ( d ) { + while (1) { + if (d->firstEntry) { + d->firstEntry = PR_FALSE; + rv = NO_ERROR; + } else { + rv = DosFindNext(d->d_hdl, + &(d->d_entry), + sizeof(d->d_entry), + &numFiles); + } + if (rv != NO_ERROR) { + break; + } + fileName = GetFileFromDIR(d); + fileAttr = GetFileAttr(d); + if ( (flags & PR_SKIP_DOT) && + (fileName[0] == '.') && (fileName[1] == '\0')) + continue; + if ( (flags & PR_SKIP_DOT_DOT) && + (fileName[0] == '.') && (fileName[1] == '.') && + (fileName[2] == '\0')) + continue; + /* + * XXX + * Is this the correct definition of a hidden file on OS/2? + */ + if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN)) + return fileName; + else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN)) + continue; + return fileName; + } + PR_ASSERT(NO_ERROR != rv); + _PR_MD_MAP_READDIR_ERROR(rv); + return NULL; + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; +} + +PRInt32 +_PR_MD_DELETE(const char *name) +{ + PRInt32 rc = DosDelete((char*)name); + if(rc == NO_ERROR) { + return 0; + } else { + _PR_MD_MAP_DELETE_ERROR(rc); + return -1; + } +} + +PRInt32 +_PR_MD_STAT(const char *fn, struct stat *info) +{ + PRInt32 rv; + char filename[CCHMAXPATH]; + + PR_snprintf(filename, CCHMAXPATH, "%s", fn); + FlipSlashes(filename, strlen(filename)); + + rv = _stat((char*)filename, info); + if (-1 == rv) { + /* + * Check for MSVC runtime library _stat() bug. + * (It's really a bug in FindFirstFile().) + * If a pathname ends in a backslash or slash, + * e.g., c:\temp\ or c:/temp/, _stat() will fail. + * Note: a pathname ending in a slash (e.g., c:/temp/) + * can be handled by _stat() on NT but not on Win95. + * + * We remove the backslash or slash at the end and + * try again. + * + * Not sure if this happens on OS/2 or not, + * but it doesn't hurt to be careful. + */ + + int len = strlen(fn); + if (len > 0 && len <= _MAX_PATH + && (fn[len - 1] == '\\' || fn[len - 1] == '/')) { + char newfn[_MAX_PATH + 1]; + + strcpy(newfn, fn); + newfn[len - 1] = '\0'; + rv = _stat(newfn, info); + } + } + + if (-1 == rv) { + _PR_MD_MAP_STAT_ERROR(errno); + } + return rv; +} + +PRInt32 +_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info) +{ + struct stat sb; + PRInt32 rv; + PRInt64 s, s2us; + + if ( (rv = _PR_MD_STAT(fn, &sb)) == 0 ) { + if (info) { + if (S_IFREG & sb.st_mode) + info->type = PR_FILE_FILE ; + else if (S_IFDIR & sb.st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + info->size = sb.st_size; + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(s, sb.st_mtime); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, sb.st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; + } + } + return rv; +} + +PRInt32 +_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) +{ + PRFileInfo info32; + PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32); + if (rv != 0) + { + return rv; + } + info->type = info32.type; + LL_UI2L(info->size,info32.size); + info->modifyTime = info32.modifyTime; + info->creationTime = info32.creationTime; + + if (isWSEB) + { + APIRET rc ; + FILESTATUS3L fstatus; + + rc = DosQueryPathInfo(fn, FIL_STANDARDL, &fstatus, sizeof(fstatus)); + + if (NO_ERROR != rc) + { + _PR_MD_MAP_OPEN_ERROR(rc); + return -1; + } + + if (! (fstatus.attrFile & FILE_DIRECTORY)) + { + info->size = fstatus.cbFile; + } + } + + return rv; +} + +PRInt32 +_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) +{ + /* For once, the VAC compiler/library did a nice thing. + * The file handle used by the C runtime is the same one + * returned by the OS when you call DosOpen(). This means + * that you can take an OS HFILE and use it with C file + * functions. The only caveat is that you have to call + * _setmode() first to initialize some junk. This is + * immensely useful because I did not have a clue how to + * implement this function otherwise. The windows folks + * took the source from the Microsoft C library source, but + * IBM wasn't kind enough to ship the source with VAC. + * On second thought, the needed function could probably + * be gotten from the OS/2 GNU library source, but the + * point is now moot. + */ + struct stat hinfo; + PRInt64 s, s2us; + + _setmode(fd->secret->md.osfd, O_BINARY); + if(fstat((int)fd->secret->md.osfd, &hinfo) != NO_ERROR) { + _PR_MD_MAP_FSTAT_ERROR(errno); + return -1; + } + + if (hinfo.st_mode & S_IFDIR) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_FILE; + + info->size = hinfo.st_size; + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(s, hinfo.st_mtime); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, hinfo.st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; + + return 0; +} + +PRInt32 +_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info) +{ + PRFileInfo info32; + PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32); + if (0 == rv) + { + info->type = info32.type; + LL_UI2L(info->size,info32.size); + + info->modifyTime = info32.modifyTime; + info->creationTime = info32.creationTime; + } + + if (isWSEB) + { + APIRET rc ; + FILESTATUS3L fstatus; + + rc = DosQueryFileInfo(fd->secret->md.osfd, FIL_STANDARDL, &fstatus, sizeof(fstatus)); + + if (NO_ERROR != rc) + { + _PR_MD_MAP_OPEN_ERROR(rc); + return -1; + } + + if (! (fstatus.attrFile & FILE_DIRECTORY)) + { + info->size = fstatus.cbFile; + } + } + + return rv; +} + + +PRInt32 +_PR_MD_RENAME(const char *from, const char *to) +{ + PRInt32 rc; + /* Does this work with dot-relative pathnames? */ + if ( (rc = DosMove((char *)from, (char *)to)) == NO_ERROR) { + return 0; + } else { + _PR_MD_MAP_RENAME_ERROR(rc); + return -1; + } +} + +PRInt32 +_PR_MD_ACCESS(const char *name, PRAccessHow how) +{ + PRInt32 rv; + switch (how) { + case PR_ACCESS_WRITE_OK: + rv = access(name, 02); + break; + case PR_ACCESS_READ_OK: + rv = access(name, 04); + break; + case PR_ACCESS_EXISTS: + return access(name, 00); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + if (rv < 0) + _PR_MD_MAP_ACCESS_ERROR(errno); + return rv; +} + +PRInt32 +_PR_MD_MKDIR(const char *name, PRIntn mode) +{ + PRInt32 rc; + /* XXXMB - how to translate the "mode"??? */ + if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) { + return 0; + } else { + _PR_MD_MAP_MKDIR_ERROR(rc); + return -1; + } +} + +PRInt32 +_PR_MD_RMDIR(const char *name) +{ + PRInt32 rc; + if ( (rc = DosDeleteDir((char *)name)) == NO_ERROR) { + return 0; + } else { + _PR_MD_MAP_RMDIR_ERROR(rc); + return -1; + } +} + +PRStatus +_PR_MD_LOCKFILE(PRInt32 f) +{ + PRInt32 rv; + FILELOCK lock, unlock; + FILELOCKL lockL, unlockL; + + lock.lOffset = 0; + lockL.lOffset = 0; + lock.lRange = 0xffffffff; + lockL.lRange = 0xffffffffffffffff; + unlock.lOffset = 0; + unlock.lRange = 0; + unlockL.lOffset = 0; + unlockL.lRange = 0; + + /* + * loop trying to DosSetFileLocks(), + * pause for a few miliseconds when can't get the lock + * and try again + */ + for( rv = FALSE; rv == FALSE; /* do nothing */ ) + { + if (isWSEB) + { + rv = myDosSetFileLocksL( (HFILE) f, + &unlockL, &lockL, + 0, 0); + } + else + { + rv = DosSetFileLocks( (HFILE) f, + &unlock, &lock, + 0, 0); + } + if ( rv != NO_ERROR ) + { + DosSleep( 50 ); /* Sleep() a few milisecs and try again. */ + } + } /* end for() */ + return PR_SUCCESS; +} /* end _PR_MD_LOCKFILE() */ + +PRStatus +_PR_MD_TLOCKFILE(PRInt32 f) +{ + return _PR_MD_LOCKFILE(f); +} /* end _PR_MD_TLOCKFILE() */ + + +PRStatus +_PR_MD_UNLOCKFILE(PRInt32 f) +{ + PRInt32 rv; + FILELOCK lock, unlock; + FILELOCKL lockL, unlockL; + + lock.lOffset = 0; + lockL.lOffset = 0; + lock.lRange = 0; + lockL.lRange = 0; + unlock.lOffset = 0; + unlockL.lOffset = 0; + unlock.lRange = 0xffffffff; + unlockL.lRange = 0xffffffffffffffff; + + if (isWSEB) + { + rv = myDosSetFileLocksL( (HFILE) f, + &unlockL, &lockL, + 0, 0); + } + else + { + rv = DosSetFileLocks( (HFILE) f, + &unlock, &lock, + 0, 0); + } + + if ( rv != NO_ERROR ) + { + return PR_SUCCESS; + } + else + { + return PR_FAILURE; + } +} /* end _PR_MD_UNLOCKFILE() */ + +PRStatus +_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) +{ + APIRET rc = 0; + ULONG flags; + switch (fd->methods->file_type) + { + case PR_DESC_PIPE: + case PR_DESC_FILE: + rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags); + if (rc != NO_ERROR) { + PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } + + if (inheritable) + flags &= ~OPEN_FLAGS_NOINHERIT; + else + flags |= OPEN_FLAGS_NOINHERIT; + + /* Mask off flags DosSetFHState don't want. */ + flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT); + rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags); + if (rc != NO_ERROR) { + PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } + break; + + case PR_DESC_LAYERED: + /* what to do here? */ + PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/); + return PR_FAILURE; + + case PR_DESC_SOCKET_TCP: + case PR_DESC_SOCKET_UDP: + /* These are global on OS/2. */ + break; + } + + return PR_SUCCESS; +} + +void +_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported) +{ + /* XXX this function needs to be implemented */ + fd->secret->inheritable = _PR_TRI_UNKNOWN; +} + +void +_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd) +{ + /* XXX this function needs to be reviewed */ + ULONG flags; + + PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); + if (DosQueryFHState((HFILE)fd->secret->md.osfd, &flags) == 0) { + if (flags & OPEN_FLAGS_NOINHERIT) { + fd->secret->inheritable = _PR_TRI_FALSE; + } else { + fd->secret->inheritable = _PR_TRI_TRUE; + } + } +} diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2misc.c nspr-4.10.7/nspr/pr/src/md/os2/os2misc.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2misc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2misc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,619 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * os2misc.c + * + */ + +#ifdef MOZ_OS2_HIGH_MEMORY +/* os2safe.h has to be included before os2.h, needed for high mem */ +#include +#endif + +#include +#include "primpl.h" + +extern int _CRT_init(void); +extern void _CRT_term(void); +extern void __ctordtorInit(int flag); +extern void __ctordtorTerm(int flag); + +char * +_PR_MD_GET_ENV(const char *name) +{ + return getenv(name); +} + +PRIntn +_PR_MD_PUT_ENV(const char *name) +{ + return putenv(name); +} + + +/* + ************************************************************************** + ************************************************************************** + ** + ** Date and time routines + ** + ************************************************************************** + ************************************************************************** + */ + +#include +/* + *----------------------------------------------------------------------- + * + * PR_Now -- + * + * Returns the current time in microseconds since the epoch. + * The epoch is midnight January 1, 1970 GMT. + * The implementation is machine dependent. This is the + * implementation for OS/2. + * Cf. time_t time(time_t *tp) + * + *----------------------------------------------------------------------- + */ + +PR_IMPLEMENT(PRTime) +PR_Now(void) +{ + PRInt64 s, ms, ms2us, s2us; + struct timeb b; + + ftime(&b); + LL_I2L(ms2us, PR_USEC_PER_MSEC); + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(s, b.time); + LL_I2L(ms, b.millitm); + LL_MUL(ms, ms, ms2us); + LL_MUL(s, s, s2us); + LL_ADD(s, s, ms); + return s; +} + + +/* + *********************************************************************** + *********************************************************************** + * + * Process creation routines + * + *********************************************************************** + *********************************************************************** + */ + +/* + * Assemble the command line by concatenating the argv array. + * Special characters intentionally do not get escaped, and it is + * expected that the caller wraps arguments in quotes if needed + * (e.g. for filename with spaces). + * + * On success, this function returns 0 and the resulting command + * line is returned in *cmdLine. On failure, it returns -1. + */ +static int assembleCmdLine(char *const *argv, char **cmdLine) +{ + char *const *arg; + int cmdLineSize; + + /* + * Find out how large the command line buffer should be. + */ + cmdLineSize = 1; /* final null */ + for (arg = argv+1; *arg; arg++) { + cmdLineSize += strlen(*arg) + 1; /* space in between */ + } + *cmdLine = PR_MALLOC(cmdLineSize); + if (*cmdLine == NULL) { + return -1; + } + + (*cmdLine)[0] = '\0'; + + for (arg = argv+1; *arg; arg++) { + if (arg > argv +1) { + strcat(*cmdLine, " "); + } + strcat(*cmdLine, *arg); + } + return 0; +} + +/* + * Assemble the environment block by concatenating the envp array + * (preserving the terminating null byte in each array element) + * and adding a null byte at the end. + * + * Returns 0 on success. The resulting environment block is returned + * in *envBlock. Note that if envp is NULL, a NULL pointer is returned + * in *envBlock. Returns -1 on failure. + */ +static int assembleEnvBlock(char **envp, char **envBlock) +{ + char *p; + char *q; + char **env; + char *curEnv; + char *cwdStart, *cwdEnd; + int envBlockSize; + + PPIB ppib = NULL; + PTIB ptib = NULL; + + if (envp == NULL) { + *envBlock = NULL; + return 0; + } + + if(DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR) + return -1; + + curEnv = ppib->pib_pchenv; + + cwdStart = curEnv; + while (*cwdStart) { + if (cwdStart[0] == '=' && cwdStart[1] != '\0' + && cwdStart[2] == ':' && cwdStart[3] == '=') { + break; + } + cwdStart += strlen(cwdStart) + 1; + } + cwdEnd = cwdStart; + if (*cwdEnd) { + cwdEnd += strlen(cwdEnd) + 1; + while (*cwdEnd) { + if (cwdEnd[0] != '=' || cwdEnd[1] == '\0' + || cwdEnd[2] != ':' || cwdEnd[3] != '=') { + break; + } + cwdEnd += strlen(cwdEnd) + 1; + } + } + envBlockSize = cwdEnd - cwdStart; + + for (env = envp; *env; env++) { + envBlockSize += strlen(*env) + 1; + } + envBlockSize++; + + p = *envBlock = PR_MALLOC(envBlockSize); + if (p == NULL) { + return -1; + } + + q = cwdStart; + while (q < cwdEnd) { + *p++ = *q++; + } + + for (env = envp; *env; env++) { + q = *env; + while (*q) { + *p++ = *q++; + } + *p++ = '\0'; + } + *p = '\0'; + return 0; +} + +/* + * For qsort. We sort (case-insensitive) the environment strings + * before generating the environment block. + */ +static int compare(const void *arg1, const void *arg2) +{ + return stricmp(* (char**)arg1, * (char**)arg2); +} + +PRProcess * _PR_CreateOS2Process( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr) +{ + PRProcess *proc = NULL; + char *cmdLine = NULL; + char **newEnvp = NULL; + char *envBlock = NULL; + + STARTDATA startData = {0}; + APIRET rc; + ULONG ulAppType = 0; + PID pid = 0; + char *pszComSpec; + char pszEXEName[CCHMAXPATH] = ""; + char pszFormatString[CCHMAXPATH]; + char pszObjectBuffer[CCHMAXPATH]; + char *pszFormatResult = NULL; + + /* + * Variables for DosExecPgm + */ + char szFailed[CCHMAXPATH]; + char *pszCmdLine = NULL; + RESULTCODES procInfo; + HFILE hStdIn = 0, + hStdOut = 0, + hStdErr = 0; + HFILE hStdInSave = -1, + hStdOutSave = -1, + hStdErrSave = -1; + + proc = PR_NEW(PRProcess); + if (!proc) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto errorExit; + } + + if (assembleCmdLine(argv, &cmdLine) == -1) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto errorExit; + } + +#ifdef MOZ_OS2_HIGH_MEMORY + /* + * DosQueryAppType() fails if path (the char* in the first argument) is in + * high memory. If that is the case, the following moves it to low memory. + */ + if ((ULONG)path >= 0x20000000) { + size_t len = strlen(path) + 1; + char *copy = (char *)alloca(len); + memcpy(copy, path, len); + path = copy; + } +#endif + + if (envp == NULL) { + newEnvp = NULL; + } else { + int i; + int numEnv = 0; + while (envp[numEnv]) { + numEnv++; + } + newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *)); + for (i = 0; i <= numEnv; i++) { + newEnvp[i] = envp[i]; + } + qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare); + } + if (assembleEnvBlock(newEnvp, &envBlock) == -1) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto errorExit; + } + + rc = DosQueryAppType(path, &ulAppType); + if (rc != NO_ERROR) { + char *pszDot = strrchr(path, '.'); + if (pszDot) { + /* If it is a CMD file, launch the users command processor */ + if (!stricmp(pszDot, ".cmd")) { + rc = DosScanEnv("COMSPEC", (PSZ *)&pszComSpec); + if (!rc) { + strcpy(pszFormatString, "/C %s %s"); + strcpy(pszEXEName, pszComSpec); + ulAppType = FAPPTYP_WINDOWCOMPAT; + } + } + } + } + if (ulAppType == 0) { + PR_SetError(PR_UNKNOWN_ERROR, 0); + goto errorExit; + } + + if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) { + startData.SessionType = SSF_TYPE_PM; + } + else if (ulAppType & FAPPTYP_WINDOWCOMPAT) { + startData.SessionType = SSF_TYPE_WINDOWABLEVIO; + } + else { + startData.SessionType = SSF_TYPE_DEFAULT; + } + + if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL)) + { + strcpy(pszEXEName, "WINOS2.COM"); + startData.SessionType = PROG_31_STDSEAMLESSVDM; + strcpy(pszFormatString, "/3 %s %s"); + } + + startData.InheritOpt = SSF_INHERTOPT_SHELL; + + if (pszEXEName[0]) { + pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine)); + sprintf(pszFormatResult, pszFormatString, path, cmdLine); + startData.PgmInputs = pszFormatResult; + } else { + strcpy(pszEXEName, path); + startData.PgmInputs = cmdLine; + } + startData.PgmName = pszEXEName; + + startData.Length = sizeof(startData); + startData.Related = SSF_RELATED_INDEPENDENT; + startData.ObjectBuffer = pszObjectBuffer; + startData.ObjectBuffLen = CCHMAXPATH; + startData.Environment = envBlock; + + if (attr) { + /* On OS/2, there is really no way to pass file handles for stdin, + * stdout, and stderr to a new process. Instead, we can make it + * a child process and make the given file handles a copy of our + * stdin, stdout, and stderr. The child process then inherits + * ours, and we set ours back. Twisted and gross I know. If you + * know a better way, please use it. + */ + if (attr->stdinFd) { + hStdIn = 0; + DosDupHandle(hStdIn, &hStdInSave); + DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn); + } + + if (attr->stdoutFd) { + hStdOut = 1; + DosDupHandle(hStdOut, &hStdOutSave); + DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut); + } + + if (attr->stderrFd) { + hStdErr = 2; + DosDupHandle(hStdErr, &hStdErrSave); + DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr); + } + /* + * Build up the Command Line for DosExecPgm + */ + pszCmdLine = PR_MALLOC(strlen(pszEXEName) + + strlen(startData.PgmInputs) + 3); + sprintf(pszCmdLine, "%s%c%s%c", pszEXEName, '\0', + startData.PgmInputs, '\0'); + rc = DosExecPgm(szFailed, + CCHMAXPATH, + EXEC_ASYNCRESULT, + pszCmdLine, + envBlock, + &procInfo, + pszEXEName); + PR_DELETE(pszCmdLine); + + /* Restore our old values. Hope this works */ + if (hStdInSave != -1) { + DosDupHandle(hStdInSave, &hStdIn); + DosClose(hStdInSave); + } + + if (hStdOutSave != -1) { + DosDupHandle(hStdOutSave, &hStdOut); + DosClose(hStdOutSave); + } + + if (hStdErrSave != -1) { + DosDupHandle(hStdErrSave, &hStdErr); + DosClose(hStdErrSave); + } + + if (rc != NO_ERROR) { + /* XXX what error code? */ + PR_SetError(PR_UNKNOWN_ERROR, rc); + goto errorExit; + } + + proc->md.pid = procInfo.codeTerminate; + } else { + /* + * If no STDIN/STDOUT redirection is not needed, use DosStartSession + * to create a new, independent session + */ + rc = DosStartSession(&startData, &ulAppType, &pid); + + if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) { + PR_SetError(PR_UNKNOWN_ERROR, rc); + goto errorExit; + } + + proc->md.pid = pid; + } + + if (pszFormatResult) { + PR_DELETE(pszFormatResult); + } + + PR_DELETE(cmdLine); + if (newEnvp) { + PR_DELETE(newEnvp); + } + if (envBlock) { + PR_DELETE(envBlock); + } + return proc; + +errorExit: + if (cmdLine) { + PR_DELETE(cmdLine); + } + if (newEnvp) { + PR_DELETE(newEnvp); + } + if (envBlock) { + PR_DELETE(envBlock); + } + if (proc) { + PR_DELETE(proc); + } + return NULL; +} /* _PR_CreateOS2Process */ + +PRStatus _PR_DetachOS2Process(PRProcess *process) +{ + /* On OS/2, a process is either created as a child or not. + * You can't 'detach' it later on. + */ + PR_DELETE(process); + return PR_SUCCESS; +} + +/* + * XXX: This will currently only work on a child process. + */ +PRStatus _PR_WaitOS2Process(PRProcess *process, + PRInt32 *exitCode) +{ + ULONG ulRetVal; + RESULTCODES results; + PID pidEnded = 0; + + ulRetVal = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, + &results, + &pidEnded, process->md.pid); + + if (ulRetVal != NO_ERROR) { + printf("\nDosWaitChild rc = %lu\n", ulRetVal); + PR_SetError(PR_UNKNOWN_ERROR, ulRetVal); + return PR_FAILURE; + } + PR_DELETE(process); + return PR_SUCCESS; +} + +PRStatus _PR_KillOS2Process(PRProcess *process) +{ + ULONG ulRetVal; + if ((ulRetVal = DosKillProcess(DKP_PROCESS, process->md.pid)) == NO_ERROR) { + return PR_SUCCESS; + } + PR_SetError(PR_UNKNOWN_ERROR, ulRetVal); + return PR_FAILURE; +} + +PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen) +{ + PRIntn rv; + + rv = gethostname(name, (PRInt32) namelen); + if (0 == rv) { + return PR_SUCCESS; + } + _PR_MD_MAP_GETHOSTNAME_ERROR(sock_errno()); + return PR_FAILURE; +} + +void +_PR_MD_WAKEUP_CPUS( void ) +{ + return; +} + +/* + ********************************************************************** + * + * Memory-mapped files + * + * A credible emulation of memory-mapped i/o on OS/2 would require + * an exception-handler on each thread that might access the mapped + * memory. In the Mozilla environment, that would be impractical. + * Instead, the following simulates those modes which don't modify + * the mapped file. It reads the entire mapped file segment at once + * when MemMap is called, and frees it on MemUnmap. CreateFileMap + * only does sanity-checks, while CloseFileMap does almost nothing. + * + ********************************************************************** + */ + +PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size) +{ + PRFileInfo64 info; + + /* assert on PR_PROT_READWRITE which modifies the underlying file */ + PR_ASSERT(fmap->prot == PR_PROT_READONLY || + fmap->prot == PR_PROT_WRITECOPY); + if (fmap->prot != PR_PROT_READONLY && + fmap->prot != PR_PROT_WRITECOPY) { + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; + } + if (PR_GetOpenFileInfo64(fmap->fd, &info) == PR_FAILURE) { + return PR_FAILURE; + } + /* reject zero-byte mappings & zero-byte files */ + if (!size || !info.size) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + /* file size rounded up to the next page boundary */ + fmap->md.maxExtent = (info.size + 0xfff) & ~(0xfff); + + return PR_SUCCESS; +} + +PRInt32 _MD_GetMemMapAlignment(void) +{ + /* OS/2 pages are 4k */ + return 0x1000; +} + +void * _MD_MemMap(PRFileMap *fmap, PROffset64 offset, PRUint32 len) +{ + PRUint32 rv; + void *addr; + + /* prevent mappings beyond EOF + remainder of page */ + if (offset + len > fmap->md.maxExtent) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } + if (PR_Seek64(fmap->fd, offset, PR_SEEK_SET) == -1) { + return NULL; + } + /* try for high memory, fall back to low memory if hi-mem fails */ + rv = DosAllocMem(&addr, len, OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE); + if (rv) { + rv = DosAllocMem(&addr, len, PAG_COMMIT | PAG_READ | PAG_WRITE); + if (rv) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, rv); + return NULL; + } + } + if (PR_Read(fmap->fd, addr, len) == -1) { + DosFreeMem(addr); + return NULL; + } + /* don't permit writes if readonly */ + if (fmap->prot == PR_PROT_READONLY) { + rv = DosSetMem(addr, len, PAG_READ); + if (rv) { + DosFreeMem(addr); + PR_SetError(PR_UNKNOWN_ERROR, rv); + return NULL; + } + } + return addr; +} + +PRStatus _MD_MemUnmap(void *addr, PRUint32 len) +{ + PRUint32 rv; + + /* we just have to trust that addr & len are those used by MemMap */ + rv = DosFreeMem(addr); + if (rv) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PRStatus _MD_CloseFileMap(PRFileMap *fmap) +{ + /* nothing to do except free the PRFileMap struct */ + PR_Free(fmap); + return PR_SUCCESS; +} + diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2poll.c nspr-4.10.7/nspr/pr/src/md/os2/os2poll.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2poll.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2poll.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,348 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This file implements _PR_MD_PR_POLL for OS/2. + */ + +#include /* For timeval. */ + +#include "primpl.h" + +#ifndef BSD_SELECT +/* Utility functions called when using OS/2 select */ + +PRBool IsSocketSet( PRInt32 osfd, int* socks, int start, int count ) +{ + int i; + PRBool isSet = PR_FALSE; + + for( i = start; i < start+count; i++ ) + { + if( socks[i] == osfd ) + isSet = PR_TRUE; + } + + return isSet; +} +#endif + +PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ +#ifdef BSD_SELECT + fd_set rd, wt, ex; +#else + int rd, wt, ex; + int* socks; + unsigned long msecs; + int i, j; +#endif + PRFileDesc *bottom; + PRPollDesc *pd, *epd; + PRInt32 maxfd = -1, ready, err; + PRIntervalTime remaining, elapsed, start; + +#ifdef BSD_SELECT + struct timeval tv, *tvp = NULL; + + FD_ZERO(&rd); + FD_ZERO(&wt); + FD_ZERO(&ex); +#else + rd = 0; + wt = 0; + ex = 0; + socks = (int) PR_MALLOC( npds * 3 * sizeof(int) ); + + if (!socks) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } +#endif + + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRInt16 in_flags_read = 0, in_flags_write = 0; + PRInt16 out_flags_read = 0, out_flags_write = 0; + + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + if (pd->in_flags & PR_POLL_READ) + { + in_flags_read = (pd->fd->methods->poll)( + pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); + } + if (pd->in_flags & PR_POLL_WRITE) + { + in_flags_write = (pd->fd->methods->poll)( + pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); + } + if ((0 != (in_flags_read & out_flags_read)) || + (0 != (in_flags_write & out_flags_write))) + { + /* this one's ready right now */ + if (0 == ready) + { + /* + * We will have to return without calling the + * system poll/select function. So zero the + * out_flags fields of all the poll descriptors + * before this one. + */ + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; + pd->out_flags = out_flags_read | out_flags_write; + } + else + { + pd->out_flags = 0; /* pre-condition */ + + /* make sure this is an NSPR supported stack */ + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); /* what to do about that? */ + if ((NULL != bottom) && + (_PR_FILEDESC_OPEN == bottom->secret->state)) + { + if (0 == ready) + { + PRInt32 osfd = bottom->secret->md.osfd; + if (osfd > maxfd) + maxfd = osfd; + if (in_flags_read & PR_POLL_READ) + { + pd->out_flags |= _PR_POLL_READ_SYS_READ; +#ifdef BSD_SELECT + FD_SET(osfd, &rd); +#else + socks[rd] = osfd; + rd++; +#endif + } + if (in_flags_read & PR_POLL_WRITE) + { + pd->out_flags |= _PR_POLL_READ_SYS_WRITE; +#ifdef BSD_SELECT + FD_SET(osfd, &wt); +#else + socks[npds+wt] = osfd; + wt++; +#endif + } + if (in_flags_write & PR_POLL_READ) + { + pd->out_flags |= _PR_POLL_WRITE_SYS_READ; +#ifdef BSD_SELECT + FD_SET(osfd, &rd); +#else + socks[rd] = osfd; + rd++; +#endif + } + if (in_flags_write & PR_POLL_WRITE) + { + pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; +#ifdef BSD_SELECT + FD_SET(osfd, &wt); +#else + socks[npds+wt] = osfd; + wt++; +#endif + } + if (pd->in_flags & PR_POLL_EXCEPT) + { +#ifdef BSD_SELECT + FD_SET(osfd, &ex); +#else + socks[npds*2+ex] = osfd; + ex++; +#endif + } + } + } + else + { + if (0 == ready) + { + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; /* this will cause an abrupt return */ + pd->out_flags = PR_POLL_NVAL; /* bogii */ + } + } + } + else + { + pd->out_flags = 0; + } + } + + if (0 != ready) + { +#ifndef BSD_SELECT + PR_Free(socks); +#endif + return ready; /* no need to block */ + } + + remaining = timeout; + start = PR_IntervalNow(); + +retry: +#ifdef BSD_SELECT + if (timeout != PR_INTERVAL_NO_TIMEOUT) + { + PRInt32 ticksPerSecond = PR_TicksPerSecond(); + tv.tv_sec = remaining / ticksPerSecond; + tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); + tvp = &tv; + } + + ready = bsdselect(maxfd + 1, &rd, &wt, &ex, tvp); +#else + switch (timeout) + { + case PR_INTERVAL_NO_WAIT: + msecs = 0; + break; + case PR_INTERVAL_NO_TIMEOUT: + msecs = -1; + break; + default: + msecs = PR_IntervalToMilliseconds(remaining); + } + + /* compact array */ + for( i = rd, j = npds; j < npds+wt; i++,j++ ) + socks[i] = socks[j]; + for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ ) + socks[i] = socks[j]; + + ready = os2_select(socks, rd, wt, ex, msecs); +#endif + + if (ready == -1 && errno == EINTR) + { + if (timeout == PR_INTERVAL_NO_TIMEOUT) + goto retry; + else + { + elapsed = (PRIntervalTime) (PR_IntervalNow() - start); + if (elapsed > timeout) + ready = 0; /* timed out */ + else + { + remaining = timeout - elapsed; + goto retry; + } + } + } + + /* + ** Now to unravel the select sets back into the client's poll + ** descriptor list. Is this possibly an area for pissing away + ** a few cycles or what? + */ + if (ready > 0) + { + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRInt16 out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + PRInt32 osfd; + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + + osfd = bottom->secret->md.osfd; + +#ifdef BSD_SELECT + if (FD_ISSET(osfd, &rd)) +#else + if( IsSocketSet(osfd, socks, 0, rd) ) +#endif + { + if (pd->out_flags & _PR_POLL_READ_SYS_READ) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) + out_flags |= PR_POLL_WRITE; + } + +#ifdef BSD_SELECT + if (FD_ISSET(osfd, &wt)) +#else + if( IsSocketSet(osfd, socks, rd, wt) ) +#endif + { + if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) + out_flags |= PR_POLL_WRITE; + } + +#ifdef BSD_SELECT + if (FD_ISSET(osfd, &ex)) +#else + if( IsSocketSet(osfd, socks, rd+wt, ex) ) +#endif + { + out_flags |= PR_POLL_EXCEPT; + } + } + pd->out_flags = out_flags; + if (out_flags) ready++; + } + PR_ASSERT(ready > 0); + } + else if (ready < 0) + { + err = _MD_ERRNO(); + if (err == EBADF) + { + /* Find the bad fds */ + int optval; + int optlen = sizeof(optval); + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + pd->out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET, + SO_TYPE, (char *) &optval, &optlen) == -1) + { + PR_ASSERT(sock_errno() == ENOTSOCK); + if (sock_errno() == ENOTSOCK) + { + pd->out_flags = PR_POLL_NVAL; + ready++; + } + } + } + } + PR_ASSERT(ready > 0); + } + else + _PR_MD_MAP_SELECT_ERROR(err); + } + +#ifndef BSD_SELECT + PR_Free(socks); +#endif + return ready; +} + diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2rng.c nspr-4.10.7/nspr/pr/src/md/os2/os2rng.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2rng.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2rng.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#define INCL_DOS +#define INCL_DOSERRORS +#include +#include +#include +#include "primpl.h" + +static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow) +{ + APIRET rc = NO_ERROR; + QWORD qword = {0,0}; + + rc = DosTmrQueryTime(&qword); + if (rc != NO_ERROR) + return FALSE; + + *phigh = qword.ulHi; + *plow = qword.ulLo; + + return TRUE; +} + +extern PRSize _PR_MD_GetRandomNoise(void *buf, PRSize size ) +{ + unsigned long high = 0; + unsigned long low = 0; + clock_t val = 0; + int n = 0; + int nBytes = 0; + time_t sTime; + + if (size <= 0) + return 0; + + clockTickTime(&high, &low); + + /* get the maximally changing bits first */ + nBytes = sizeof(low) > size ? size : sizeof(low); + memcpy(buf, &low, nBytes); + n += nBytes; + size -= nBytes; + + if (size <= 0) + return n; + + nBytes = sizeof(high) > size ? size : sizeof(high); + memcpy(((char *)buf) + n, &high, nBytes); + n += nBytes; + size -= nBytes; + + if (size <= 0) + return n; + + /* get the number of milliseconds that have elapsed since application started */ + val = clock(); + + nBytes = sizeof(val) > size ? size : sizeof(val); + memcpy(((char *)buf) + n, &val, nBytes); + n += nBytes; + size -= nBytes; + + if (size <= 0) + return n; + + /* get the time in seconds since midnight Jan 1, 1970 */ + time(&sTime); + nBytes = sizeof(sTime) > size ? size : sizeof(sTime); + memcpy(((char *)buf) + n, &sTime, nBytes); + n += nBytes; + + return n; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2sem.c nspr-4.10.7/nspr/pr/src/md/os2/os2sem.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2sem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2sem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * OS/2-specific semaphore handling code. + * + */ + +#include "primpl.h" + + +void +_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value) +{ + int rv; + + /* Our Sems don't support a value > 1 */ + PR_ASSERT(value <= 1); + + rv = DosCreateEventSem(NULL, &md->sem, 0, 0); + PR_ASSERT(rv == NO_ERROR); +} + +void +_PR_MD_DESTROY_SEM(_MDSemaphore *md) +{ + int rv; + rv = DosCloseEventSem(md->sem); + PR_ASSERT(rv == NO_ERROR); + +} + +PRStatus +_PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks) +{ + int rv; + rv = DosWaitEventSem(md->sem, PR_IntervalToMilliseconds(ticks)); + + if (rv == NO_ERROR) + return PR_SUCCESS; + else + return PR_FAILURE; +} + +PRStatus +_PR_MD_WAIT_SEM(_MDSemaphore *md) +{ + return _PR_MD_TIMED_WAIT_SEM(md, PR_INTERVAL_NO_TIMEOUT); +} + +void +_PR_MD_POST_SEM(_MDSemaphore *md) +{ + int rv; + rv = DosPostEventSem(md->sem); + PR_ASSERT(rv == NO_ERROR); +} + + diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2sock.c nspr-4.10.7/nspr/pr/src/md/os2/os2sock.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2sock.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2sock.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,654 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* OS/2 Sockets module + * + */ + +/*Note from DSR111297 - it should be noted that there are two flavors of select() on OS/2 */ +/*There is standard BSD (which is kind of slow) and a new flavor of select() that takes */ +/*an integer list of sockets, the number of read sockets, write sockets, except sockets, and */ +/*a millisecond count for timeout. In the interest of performance I have choosen the OS/2 */ +/*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info. */ + +#include "primpl.h" + +#include /* For timeval. */ + +#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 +#define READ_FD 1 +#define WRITE_FD 2 + +/* --- SOCKET IO --------------------------------------------------------- */ + + +PRInt32 +_PR_MD_SOCKET(int domain, int type, int flags) +{ + PRInt32 osfd, err; + + osfd = socket(domain, type, flags); + + if (osfd == -1) + { + err = sock_errno(); + _PR_MD_MAP_SOCKET_ERROR(err); + } + + return(osfd); +} + +/* +** _MD_CloseSocket() -- Close a socket +** +*/ +PRInt32 +_MD_CloseSocket(PRInt32 osfd) +{ + PRInt32 rv, err; + + rv = soclose(osfd); + if (rv == -1) { + err = sock_errno(); + _PR_MD_MAP_CLOSE_ERROR(err); + } + return rv; +} + +PRInt32 +_MD_SocketAvailable(PRFileDesc *fd) +{ + PRInt32 result; + + if (so_ioctl(fd->secret->md.osfd, FIONREAD, (char *) &result, sizeof(result)) < 0) { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, sock_errno()); + return -1; + } + return result; +} + +static PRInt32 +socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout ) +{ + PRInt32 rv = -1; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRIntervalTime epoch, now, elapsed, remaining; + PRBool wait_for_remaining; + PRInt32 syserror; +#ifdef BSD_SELECT + struct timeval tv; + fd_set rd_wr; +#else + int socks[1]; + long lTimeout; +#endif + + switch (timeout) { + case PR_INTERVAL_NO_WAIT: + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + break; + case PR_INTERVAL_NO_TIMEOUT: + /* + * This is a special case of the 'default' case below. + * Please see the comments there. + */ +#ifdef BSD_SELECT + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; + tv.tv_usec = 0; + FD_ZERO(&rd_wr); + do { + FD_SET(osfd, &rd_wr); + if (fd_type == READ_FD) + rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv); + else + rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv); +#else + lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; + do { + socks[0] = osfd; + if (fd_type == READ_FD) + rv = os2_select(socks, 1, 0, 0, lTimeout); + else + rv = os2_select(socks, 0, 1, 0, lTimeout); +#endif + if (rv == -1 && (syserror = sock_errno()) != EINTR) { + _PR_MD_MAP_SELECT_ERROR(syserror); + break; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + } while (rv == 0 || (rv == -1 && syserror == EINTR)); + break; + default: + now = epoch = PR_IntervalNow(); + remaining = timeout; +#ifdef BSD_SELECT + FD_ZERO(&rd_wr); +#endif + do { + /* + * We block in select for at most + * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, + * so that there is an upper limit on the delay + * before the interrupt bit is checked. + */ +#ifdef BSD_SELECT + wait_for_remaining = PR_TRUE; + tv.tv_sec = PR_IntervalToSeconds(remaining); + if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { + wait_for_remaining = PR_FALSE; + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; + tv.tv_usec = 0; + } else { + tv.tv_usec = PR_IntervalToMicroseconds( + remaining - + PR_SecondsToInterval(tv.tv_sec)); + } + FD_SET(osfd, &rd_wr); + if (fd_type == READ_FD) + rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv); + else + rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv); +#else + wait_for_remaining = PR_TRUE; + lTimeout = PR_IntervalToMilliseconds(remaining); + if (lTimeout > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) { + wait_for_remaining = PR_FALSE; + lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; + } + socks[0] = osfd; + if (fd_type == READ_FD) + rv = os2_select(socks, 1, 0, 0, lTimeout); + else + rv = os2_select(socks, 0, 1, 0, lTimeout); +#endif + /* + * we don't consider EINTR a real error + */ + if (rv == -1 && (syserror = sock_errno()) != EINTR) { + _PR_MD_MAP_SELECT_ERROR(syserror); + break; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + /* + * We loop again if select timed out or got interrupted + * by a signal, and the timeout deadline has not passed yet. + */ + if (rv == 0 || (rv == -1 && syserror == EINTR)) { + /* + * If select timed out, we know how much time + * we spent in blocking, so we can avoid a + * PR_IntervalNow() call. + */ + if (rv == 0) { + if (wait_for_remaining) { + now += remaining; + } else { +#ifdef BSD_SELECT + now += PR_SecondsToInterval(tv.tv_sec) + + PR_MicrosecondsToInterval(tv.tv_usec); +#else + now += PR_MillisecondsToInterval(lTimeout); +#endif + } + } else { + now = PR_IntervalNow(); + } + elapsed = (PRIntervalTime) (now - epoch); + if (elapsed >= timeout) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + rv = -1; + break; + } else { + remaining = timeout - elapsed; + } + } + } while (rv == 0 || (rv == -1 && syserror == EINTR)); + break; + } + return(rv); +} + +PRInt32 +_MD_Accept(PRFileDesc *fd, PRNetAddr *addr, + PRUint32 *addrlen, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + while ((rv = accept(osfd, (struct sockaddr*) addr, (int*)addrlen)) == -1) + { + err = sock_errno(); + if ((err == EWOULDBLOCK) || (err == ECONNABORTED)) + { + if (fd->secret->nonblocking) { + break; + } + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_ACCEPT_ERROR(err); + } +done: + return(rv); +} + +PRInt32 +_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, + PRIntervalTime timeout) +{ + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 osfd = fd->secret->md.osfd; + PRNetAddr addrCopy = *addr; /* Work around a bug in OS/2 where connect + * modifies the sockaddr structure. + * See Bugzilla bug 100776. */ + + /* + * We initiate the connection setup by making a nonblocking connect() + * call. If the connect() call fails, there are two cases we handle + * specially: + * 1. The connect() call was interrupted by a signal. In this case + * we simply retry connect(). + * 2. The NSPR socket is nonblocking and connect() fails with + * EINPROGRESS. We first wait until the socket becomes writable. + * Then we try to find out whether the connection setup succeeded + * or failed. + */ + +retry: + if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) + { + err = sock_errno(); + + if (err == EINTR) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + goto retry; + } + + if (!fd->secret->nonblocking && (err == EINPROGRESS)) + { + /* + * socket_io_wait() may return -1 or 1. + */ + + rv = socket_io_wait(osfd, WRITE_FD, timeout); + if (rv == -1) { + return -1; + } + + PR_ASSERT(rv == 1); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + err = _MD_os2_get_nonblocking_connect_error(osfd); + if (err != 0) { + _PR_MD_MAP_CONNECT_ERROR(err); + return -1; + } + return 0; + } + + _PR_MD_MAP_CONNECT_ERROR(err); + } + + return rv; +} /* _MD_connect */ + +PRInt32 +_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) +{ + PRInt32 rv, err; + rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen); + if (rv < 0) { + err = sock_errno(); + _PR_MD_MAP_BIND_ERROR(err); + } + return(rv); +} + + +PRInt32 +_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog) +{ + PRInt32 rv, err; + rv = listen(fd->secret->md.osfd, backlog); + if (rv < 0) { + err = sock_errno(); + _PR_MD_MAP_DEFAULT_ERROR(err); + } + return(rv); +} + + +PRInt32 +_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + while ((rv = recv(osfd,buf,amount,flags)) == -1) + { + err = sock_errno(); + if ((err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_RECV_ERROR(err); + } +done: + return(rv); +} + +PRInt32 +_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + while ((rv = send(osfd,buf,amount,flags)) == -1) + { + err = sock_errno(); + if ((err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0) + goto done; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + + /* + * optimization; if bytes sent is less than "amount" call + * select before returning. This is because it is likely that + * the next send() call will return EWOULDBLOCK. + */ + if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) + && (timeout != PR_INTERVAL_NO_WAIT)) + { + if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) { + rv = -1; + goto done; + } + } + if (rv < 0) { + _PR_MD_MAP_SEND_ERROR(err); + } +done: + return(rv); +} + +PRInt32 +_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + while ((rv = sendto(osfd, buf, amount, flags, + (struct sockaddr *) addr, addrlen)) == -1) + { + err = sock_errno(); + if ((err == EWOULDBLOCK)) + { + if (fd->secret->nonblocking) { + break; + } + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0) + goto done; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_SENDTO_ERROR(err); + } +done: + return(rv); +} + +PRInt32 +_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + while( (*addrlen = PR_NETADDR_SIZE(addr)), + ((rv = recvfrom(osfd, buf, amount, flags, + (struct sockaddr *) addr, (int *)addrlen)) == -1)) + { + err = sock_errno(); + if ((err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_RECVFROM_ERROR(err); + } +done: + return(rv); +} + +PRInt32 +_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, + PRIntervalTime timeout) +{ + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 index, amount = 0; + PRInt32 osfd = fd->secret->md.osfd; + struct iovec osiov[PR_MAX_IOVECTOR_SIZE]; + + /* Ensured by PR_Writev */ + PR_ASSERT(iov_size <= PR_MAX_IOVECTOR_SIZE); + + /* + * We can't pass iov to so_writev because PRIOVec and struct iovec + * may not be binary compatible. Make osiov a copy of iov and + * pass osiov to so_writev . + */ + for (index = 0; index < iov_size; index++) { + osiov[index].iov_base = iov[index].iov_base; + osiov[index].iov_len = iov[index].iov_len; + } + + /* + * Calculate the total number of bytes to be sent; needed for + * optimization later. + * We could avoid this if this number was passed in; but it is + * probably not a big deal because iov_size is usually small (less than + * 3) + */ + if (!fd->secret->nonblocking) { + for (index=0; indexsecret->nonblocking) { + break; + } + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0) + goto done; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + + /* + * optimization; if bytes sent is less than "amount" call + * select before returning. This is because it is likely that + * the next writev() call will return EWOULDBLOCK. + */ + if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) + && (timeout != PR_INTERVAL_NO_WAIT)) { + if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { + rv = -1; + goto done; + } + } + if (rv < 0) { + _PR_MD_MAP_WRITEV_ERROR(err); + } +done: + return(rv); +} + +PRInt32 +_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how) +{ + PRInt32 rv; + + rv = shutdown(fd->secret->md.osfd, how); + if (rv < 0) + _PR_MD_MAP_SHUTDOWN_ERROR(sock_errno()); + return rv; +} + +PRInt32 +_PR_MD_SOCKETPAIR(int af, int type, int flags, PRInt32 *osfd) +{ + PRInt32 rv, err; + + rv = socketpair(af, type, flags, osfd); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_SOCKETPAIR_ERROR(err); + } + return rv; +} + +PRStatus +_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) +{ + PRInt32 rv, err; + + rv = getsockname(fd->secret->md.osfd, + (struct sockaddr *) addr, (int *)addrlen); + if (rv < 0) { + err = sock_errno(); + _PR_MD_MAP_GETSOCKNAME_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus +_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) +{ + PRInt32 rv, err; + + rv = getpeername(fd->secret->md.osfd, + (struct sockaddr *) addr, (int *)addrlen); + if (rv < 0) { + err = sock_errno(); + _PR_MD_MAP_GETPEERNAME_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus +_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, + char* optval, PRInt32* optlen) +{ + PRInt32 rv, err; + + rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (int *)optlen); + if (rv < 0) { + err = sock_errno(); + _PR_MD_MAP_GETSOCKOPT_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus +_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, + const char* optval, PRInt32 optlen) +{ + PRInt32 rv, err; + + rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen); + if (rv < 0) { + err = sock_errno(); + _PR_MD_MAP_SETSOCKOPT_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +void +_MD_MakeNonblock(PRFileDesc *fd) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 err; + PRUint32 one = 1; + + if (osfd <= 2) { + /* Don't mess around with stdin, stdout or stderr */ + return; + } + + err = so_ioctl( osfd, FIONBIO, (char *) &one, sizeof(one)); + if ( err != 0 ) + { + err = sock_errno(); + _PR_MD_MAP_SOCKET_ERROR(err); + } +} diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2thred.c nspr-4.10.7/nspr/pr/src/md/os2/os2thred.c --- nspr-4.9.5/nspr/pr/src/md/os2/os2thred.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2thred.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,353 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include /* for _beginthread() */ +#include +#include + +/* --- globals ------------------------------------------------ */ +_NSPR_TLS* pThreadLocalStorage = 0; +_PRInterruptTable _pr_interruptTable[] = { { 0 } }; +APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD); + +void +_PR_MD_ENSURE_TLS(void) +{ + if(!pThreadLocalStorage) + { + /* Allocate thread local storage (TLS). Note, that only 32 bytes can + * be allocated at a time. + */ + int rc = DosAllocThreadLocalMemory(sizeof(_NSPR_TLS) / 4, (PULONG*)&pThreadLocalStorage); + PR_ASSERT(rc == NO_ERROR); + memset(pThreadLocalStorage, 0, sizeof(_NSPR_TLS)); + } +} + +void +_PR_MD_EARLY_INIT() +{ + HMODULE hmod; + + if (DosLoadModule(NULL, 0, "DOSCALL1", &hmod) == 0) + DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT", + (PFN *)&QueryThreadContext); +} + +static void +_pr_SetThreadMDHandle(PRThread *thread) +{ + PTIB ptib; + PPIB ppib; + PRUword rc; + + rc = DosGetInfoBlocks(&ptib, &ppib); + + thread->md.handle = ptib->tib_ptib2->tib2_ultid; +} + +/* On OS/2, some system function calls seem to change the FPU control word, + * such that we crash with a floating underflow exception. The FIX_FPU() call + * in jsnum.c does not always work, as sometimes FIX_FPU() is called BEFORE the + * OS/2 system call that horks the FPU control word. So, we set an exception + * handler that covers any floating point exceptions and resets the FPU CW to + * the required value. + */ +static ULONG +_System OS2_FloatExcpHandler(PEXCEPTIONREPORTRECORD p1, + PEXCEPTIONREGISTRATIONRECORD p2, + PCONTEXTRECORD p3, + PVOID pv) +{ +#ifdef DEBUG_pedemonte + printf("Entering exception handler; ExceptionNum = %x\n", p1->ExceptionNum); + switch(p1->ExceptionNum) { + case XCPT_FLOAT_DENORMAL_OPERAND: + printf("got XCPT_FLOAT_DENORMAL_OPERAND\n"); + break; + case XCPT_FLOAT_DIVIDE_BY_ZERO: + printf("got XCPT_FLOAT_DIVIDE_BY_ZERO\n"); + break; + case XCPT_FLOAT_INEXACT_RESULT: + printf("got XCPT_FLOAT_INEXACT_RESULT\n"); + break; + case XCPT_FLOAT_INVALID_OPERATION: + printf("got XCPT_FLOAT_INVALID_OPERATION\n"); + break; + case XCPT_FLOAT_OVERFLOW: + printf("got XCPT_FLOAT_OVERFLOW\n"); + break; + case XCPT_FLOAT_STACK_CHECK: + printf("got XCPT_FLOAT_STACK_CHECK\n"); + break; + case XCPT_FLOAT_UNDERFLOW: + printf("got XCPT_FLOAT_UNDERFLOW\n"); + break; + } +#endif + + switch(p1->ExceptionNum) { + case XCPT_FLOAT_DENORMAL_OPERAND: + case XCPT_FLOAT_DIVIDE_BY_ZERO: + case XCPT_FLOAT_INEXACT_RESULT: + case XCPT_FLOAT_INVALID_OPERATION: + case XCPT_FLOAT_OVERFLOW: + case XCPT_FLOAT_STACK_CHECK: + case XCPT_FLOAT_UNDERFLOW: + { + unsigned cw = p3->ctx_env[0]; + if ((cw & MCW_EM) != MCW_EM) { + /* Mask out all floating point exceptions */ + p3->ctx_env[0] |= MCW_EM; + /* Following two lines set precision to 53 bit mantissa. See jsnum.c */ + p3->ctx_env[0] &= ~MCW_PC; + p3->ctx_env[0] |= PC_53; + return XCPT_CONTINUE_EXECUTION; + } + } + } + return XCPT_CONTINUE_SEARCH; +} + +PR_IMPLEMENT(void) +PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg) +{ + /* setup the exception handler for the thread */ + APIRET rv; + excpreg->ExceptionHandler = OS2_FloatExcpHandler; + excpreg->prev_structure = NULL; + rv = DosSetExceptionHandler(excpreg); + PR_ASSERT(rv == NO_ERROR); +} + +PR_IMPLEMENT(void) +PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg) +{ + /* unset exception handler */ + APIRET rv = DosUnsetExceptionHandler(excpreg); + PR_ASSERT(rv == NO_ERROR); +} + +PRStatus +_PR_MD_INIT_THREAD(PRThread *thread) +{ + APIRET rv; + + if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { + _pr_SetThreadMDHandle(thread); + } + + /* Create the blocking IO semaphore */ + rv = DosCreateEventSem(NULL, &(thread->md.blocked_sema), 0, 0); + return (rv == NO_ERROR) ? PR_SUCCESS : PR_FAILURE; +} + +typedef struct param_store +{ + void (*start)(void *); + PRThread* thread; +} PARAMSTORE; + +/* This is a small intermediate function that sets/unsets the exception + handler before calling the initial thread function */ +static void +ExcpStartFunc(void* arg) +{ + EXCEPTIONREGISTRATIONRECORD excpreg; + PARAMSTORE params, *pParams = arg; + + PR_OS2_SetFloatExcpHandler(&excpreg); + + params = *pParams; + PR_Free(pParams); + params.start(params.thread); + + PR_OS2_UnsetFloatExcpHandler(&excpreg); +} + +PRStatus +_PR_MD_CREATE_THREAD(PRThread *thread, + void (*start)(void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PARAMSTORE* params = PR_Malloc(sizeof(PARAMSTORE)); + params->start = start; + params->thread = thread; + thread->md.handle = thread->id = (TID) _beginthread(ExcpStartFunc, + NULL, + thread->stack->stackSize, + params); + if(thread->md.handle == -1) { + return PR_FAILURE; + } + + /* + * On OS/2, a thread is created with a thread priority of + * THREAD_PRIORITY_NORMAL + */ + + if (priority != PR_PRIORITY_NORMAL) { + _PR_MD_SET_PRIORITY(&(thread->md), priority); + } + + return PR_SUCCESS; +} + +void +_PR_MD_YIELD(void) +{ + /* Isn't there some problem with DosSleep(0) on OS/2? */ + DosSleep(0); +} + +void +_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) +{ + int nativePri = PRTYC_NOCHANGE; + BOOL rv; + + if (newPri < PR_PRIORITY_FIRST) { + newPri = PR_PRIORITY_FIRST; + } else if (newPri > PR_PRIORITY_LAST) { + newPri = PR_PRIORITY_LAST; + } + switch (newPri) { + case PR_PRIORITY_LOW: + case PR_PRIORITY_NORMAL: + nativePri = PRTYC_REGULAR; + break; + case PR_PRIORITY_HIGH: + nativePri = PRTYC_FOREGROUNDSERVER; + break; + case PR_PRIORITY_URGENT: + nativePri = PRTYC_TIMECRITICAL; + } + rv = DosSetPriority(PRTYS_THREAD, nativePri, 0, thread->handle); + PR_ASSERT(rv == NO_ERROR); + if (rv != NO_ERROR) { + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("PR_SetThreadPriority: can't set thread priority\n")); + } + return; +} + +void +_PR_MD_CLEAN_THREAD(PRThread *thread) +{ + APIRET rv; + + if (thread->md.blocked_sema) { + rv = DosCloseEventSem(thread->md.blocked_sema); + PR_ASSERT(rv == NO_ERROR); + thread->md.blocked_sema = 0; + } + + if (thread->md.handle) { + thread->md.handle = 0; + } +} + +void +_PR_MD_EXIT_THREAD(PRThread *thread) +{ + _PR_MD_CLEAN_THREAD(thread); + _PR_MD_SET_CURRENT_THREAD(NULL); +} + + +void +_PR_MD_EXIT(PRIntn status) +{ + _exit(status); +} + +#ifdef HAVE_THREAD_AFFINITY +PR_EXTERN(PRInt32) +_PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ) +{ + /* Can we do this on OS/2? Only on SMP versions? */ + PR_ASSERT(!"Not implemented"); + return 0; + + /* This is what windows does: + int rv; + + rv = SetThreadAffinityMask(thread->md.handle, mask); + + return rv?0:-1; + */ +} + +PR_EXTERN(PRInt32) +_PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask) +{ + /* Can we do this on OS/2? Only on SMP versions? */ + PR_ASSERT(!"Not implemented"); + return 0; + + /* This is what windows does: + PRInt32 rv, system_mask; + + rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask); + + return rv?0:-1; + */ +} +#endif /* HAVE_THREAD_AFFINITY */ + +void +_PR_MD_SUSPEND_CPU(_PRCPU *cpu) +{ + _PR_MD_SUSPEND_THREAD(cpu->thread); +} + +void +_PR_MD_RESUME_CPU(_PRCPU *cpu) +{ + _PR_MD_RESUME_THREAD(cpu->thread); +} + +void +_PR_MD_SUSPEND_THREAD(PRThread *thread) +{ + if (_PR_IS_NATIVE_THREAD(thread)) { + APIRET rc; + + /* XXXMB - DosSuspendThread() is not a blocking call; how do we + * know when the thread is *REALLY* suspended? + */ + rc = DosSuspendThread(thread->md.handle); + PR_ASSERT(rc == NO_ERROR); + } +} + +void +_PR_MD_RESUME_THREAD(PRThread *thread) +{ + if (_PR_IS_NATIVE_THREAD(thread)) { + DosResumeThread(thread->md.handle); + } +} + + +PRThread* +_MD_CURRENT_THREAD(void) +{ + PRThread *thread; + + thread = _MD_GET_ATTACHED_THREAD(); + + if (NULL == thread) { + thread = _PRI_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); + } + + PR_ASSERT(thread != NULL); + return thread; +} + diff -Nru nspr-4.9.5/nspr/pr/src/md/os2/os2vaclegacy.s nspr-4.10.7/nspr/pr/src/md/os2/os2vaclegacy.s --- nspr-4.9.5/nspr/pr/src/md/os2/os2vaclegacy.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/os2/os2vaclegacy.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,45 @@ +/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/ +/ This Source Code Form is subject to the terms of the Mozilla Public +/ License, v. 2.0. If a copy of the MPL was not distributed with this +/ file, You can obtain one at http://mozilla.org/MPL/2.0/. + + .text + .align 4 + .globl PR_NewMonitor +PR_NewMonitor: + jmp _PR_NewMonitor + + .align 4 + .globl PR_EnterMonitor +PR_EnterMonitor: + mov %eax, 4(%esp) + jmp _PR_EnterMonitor + + .align 4 + .globl PR_ExitMonitor +PR_ExitMonitor: + mov %eax, 4(%esp) + jmp _PR_ExitMonitor + + + + .align 4 + .globl PR_AttachThread +PR_AttachThread: + mov %eax, 4(%esp) + mov %edx, 8(%esp) + mov %ecx, 12(%esp) + jmp _PR_AttachThread + + .align 4 + .globl PR_DetachThread +PR_DetachThread: + jmp _PR_DetachThread + + .align 4 + .globl PR_GetCurrentThread +PR_GetCurrentThread: + jmp _PR_GetCurrentThread + + diff -Nru nspr-4.9.5/nspr/pr/src/md/prosdep.c nspr-4.10.7/nspr/pr/src/md/prosdep.c --- nspr-4.9.5/nspr/pr/src/md/prosdep.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/prosdep.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prbit.h" +#include "prsystem.h" + +#ifdef XP_UNIX +#include +#endif +#ifdef _WIN32 +#include +#endif +#ifdef XP_BEOS +#include +#endif + +PRInt32 _pr_pageShift; +PRInt32 _pr_pageSize; + +/* +** Get system page size +*/ +static void GetPageSize(void) +{ + PRInt32 pageSize; + + /* Get page size */ +#ifdef XP_UNIX +#if defined BSDI || defined AIX \ + || defined LINUX || defined __GNU__ || defined __GLIBC__ \ + || defined FREEBSD || defined NETBSD || defined OPENBSD \ + || defined DARWIN || defined SYMBIAN + _pr_pageSize = getpagesize(); +#elif defined(HPUX) + /* I have no idea. Don't get me started. --Rob */ + _pr_pageSize = sysconf(_SC_PAGE_SIZE); +#else + _pr_pageSize = sysconf(_SC_PAGESIZE); +#endif +#endif /* XP_UNIX */ + +#ifdef XP_BEOS + _pr_pageSize = B_PAGE_SIZE; +#endif + +#ifdef XP_PC +#ifdef _WIN32 + SYSTEM_INFO info; + GetSystemInfo(&info); + _pr_pageSize = info.dwPageSize; +#else + _pr_pageSize = 4096; +#endif +#endif /* XP_PC */ + + pageSize = _pr_pageSize; + PR_CEILING_LOG2(_pr_pageShift, pageSize); +} + +PR_IMPLEMENT(PRInt32) PR_GetPageShift(void) +{ + if (!_pr_pageSize) { + GetPageSize(); + } + return _pr_pageShift; +} + +PR_IMPLEMENT(PRInt32) PR_GetPageSize(void) +{ + if (!_pr_pageSize) { + GetPageSize(); + } + return _pr_pageSize; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/aix.c nspr-4.10.7/nspr/pr/src/md/unix/aix.c --- nspr-4.9.5/nspr/pr/src/md/unix/aix.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/aix.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,301 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#ifdef AIX_HAVE_ATOMIC_OP_H +#include + +PRInt32 _AIX_AtomicSet(PRInt32 *val, PRInt32 newval) +{ + PRIntn oldval; + boolean_t stored; + oldval = fetch_and_add((atomic_p)val, 0); + do + { + stored = compare_and_swap((atomic_p)val, &oldval, newval); + } while (!stored); + return oldval; +} /* _AIX_AtomicSet */ +#endif /* AIX_HAVE_ATOMIC_OP_H */ + +#if defined(AIX_TIMERS) + +#include + +static PRUint32 _aix_baseline_epoch; + +static void _MD_AixIntervalInit(void) +{ + timebasestruct_t real_time; + read_real_time(&real_time, TIMEBASE_SZ); + (void)time_base_to_time(&real_time, TIMEBASE_SZ); + _aix_baseline_epoch = real_time.tb_high; +} /* _MD_AixIntervalInit */ + +PRIntervalTime _MD_AixGetInterval(void) +{ + PRIntn rv; + PRUint64 temp; + timebasestruct_t real_time; + read_real_time(&real_time, TIMEBASE_SZ); + (void)time_base_to_time(&real_time, TIMEBASE_SZ); + /* tb_high is in seconds, tb_low in 10(-9)seconds */ + temp = 1000000000ULL * (PRUint64)(real_time.tb_high - _aix_baseline_epoch); + temp += (PRUint64)real_time.tb_low; /* everything's 10(-9) seconds */ + temp >>= 16; /* now it's something way different */ + return (PRIntervalTime)temp; +} /* _MD_AixGetInterval */ + +PRIntervalTime _MD_AixIntervalPerSec(void) +{ + return 1000000000ULL >> 16; /* that's 15258, I think */ +} /* _MD_AixIntervalPerSec */ + +#endif /* defined(AIX_TIMERS) */ + +#if !defined(PTHREADS_USER) + +#if defined(_PR_PTHREADS) + +/* + * AIX 4.3 has sched_yield(). AIX 4.2 has pthread_yield(). + * So we look up the appropriate function pointer at run time. + */ + +#include + +int (*_PT_aix_yield_fcn)() = NULL; +int _pr_aix_send_file_use_disabled = 0; + +void _MD_EarlyInit(void) +{ + void *main_app_handle; + char *evp; + + main_app_handle = dlopen(NULL, RTLD_NOW); + PR_ASSERT(NULL != main_app_handle); + + _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle, "sched_yield"); + if (!_PT_aix_yield_fcn) { + _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle,"pthread_yield"); + PR_ASSERT(NULL != _PT_aix_yield_fcn); + } + dlclose(main_app_handle); + + if (evp = getenv("NSPR_AIX_SEND_FILE_USE_DISABLED")) { + if (1 == atoi(evp)) + _pr_aix_send_file_use_disabled = 1; + } + +#if defined(AIX_TIMERS) + _MD_AixIntervalInit(); +#endif +} + +#else /* _PR_PTHREADS */ + +void _MD_EarlyInit(void) +{ +#if defined(AIX_TIMERS) + _MD_AixIntervalInit(); +#endif +} + +#endif /* _PR_PTHREADS */ + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifndef _PR_PTHREADS +PR_IMPLEMENT(void) +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PR_IMPLEMENT(PRStatus) +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for AIX */ +PR_IMPLEMENT(void) +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for AIX."); +} + +PR_IMPLEMENT(PRStatus) +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for AIX."); +} +#endif /* _PR_PTHREADS */ +#endif /* PTHREADS_USER */ + +/* + * NSPR 2.0 overrides the system select() and poll() functions. + * On AIX 4.2, we use dlopen("/unix", RTLD_NOW) and dlsym() to get + * at the original system select() and poll() functions. + */ + +#if !defined(AIX_RENAME_SELECT) + +#include +#include +#include + +static int (*aix_select_fcn)() = NULL; +static int (*aix_poll_fcn)() = NULL; + +int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) +{ + int rv; + + if (!aix_select_fcn) { + void *aix_handle; + + aix_handle = dlopen("/unix", RTLD_NOW); + if (!aix_handle) { + PR_SetError(PR_UNKNOWN_ERROR, 0); + return -1; + } + aix_select_fcn = (int(*)())dlsym(aix_handle,"select"); + dlclose(aix_handle); + if (!aix_select_fcn) { + PR_SetError(PR_UNKNOWN_ERROR, 0); + return -1; + } + } + rv = (*aix_select_fcn)(width, r, w, e, t); + return rv; +} + +int _MD_POLL(void *listptr, unsigned long nfds, long timeout) +{ + int rv; + + if (!aix_poll_fcn) { + void *aix_handle; + + aix_handle = dlopen("/unix", RTLD_NOW); + if (!aix_handle) { + PR_SetError(PR_UNKNOWN_ERROR, 0); + return -1; + } + aix_poll_fcn = (int(*)())dlsym(aix_handle,"poll"); + dlclose(aix_handle); + if (!aix_poll_fcn) { + PR_SetError(PR_UNKNOWN_ERROR, 0); + return -1; + } + } + rv = (*aix_poll_fcn)(listptr, nfds, timeout); + return rv; +} + +#else + +/* + * In AIX versions prior to 4.2, we use the two-step rename/link trick. + * The binary must contain at least one "poll" symbol for linker's rename + * to work. So we must have this dummy function that references poll(). + */ +#include +void _pr_aix_dummy() +{ + poll(0,0,0); +} + +#endif /* !defined(AIX_RENAME_SELECT) */ + +#ifdef _PR_HAVE_ATOMIC_CAS + +#include "pratom.h" + +#define _PR_AIX_ATOMIC_LOCK -1 + +PR_IMPLEMENT(void) +PR_StackPush(PRStack *stack, PRStackElem *stack_elem) +{ +PRStackElem *addr; +boolean_t locked = TRUE; + + /* Is it safe to cast a pointer to an int? */ + PR_ASSERT(sizeof(int) == sizeof(PRStackElem *)); + do { + while ((addr = stack->prstk_head.prstk_elem_next) == + (PRStackElem *)_PR_AIX_ATOMIC_LOCK) + ; + locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next, + (int) addr, _PR_AIX_ATOMIC_LOCK); + } while (locked == TRUE); + stack_elem->prstk_elem_next = addr; + _clear_lock((atomic_p)&stack->prstk_head.prstk_elem_next, (int)stack_elem); + return; +} + +PR_IMPLEMENT(PRStackElem *) +PR_StackPop(PRStack *stack) +{ +PRStackElem *element; +boolean_t locked = TRUE; + + /* Is it safe to cast a pointer to an int? */ + PR_ASSERT(sizeof(int) == sizeof(PRStackElem *)); + do { + while ((element = stack->prstk_head.prstk_elem_next) == + (PRStackElem *) _PR_AIX_ATOMIC_LOCK) + ; + locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next, + (int)element, _PR_AIX_ATOMIC_LOCK); + } while (locked == TRUE); + + if (element == NULL) { + _clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next, NULL); + } else { + _clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next, + (int) element->prstk_elem_next); + } + return element; +} + +#endif /* _PR_HAVE_ATOMIC_CAS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/aixwrap.c nspr-4.10.7/nspr/pr/src/md/unix/aixwrap.c --- nspr-4.9.5/nspr/pr/src/md/unix/aixwrap.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/aixwrap.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: aixwrap.c + * Description: + * This file contains a single function, _MD_SELECT(), which simply + * invokes the select() function. This file is used in an ugly + * hack to override the system select() function on AIX releases + * prior to 4.2. (On AIX 4.2, we use a different mechanism to + * override select().) + */ + +#ifndef AIX_RENAME_SELECT +#error aixwrap.c should only be used on AIX 3.2 or 4.1 +#else + +#include +#include + +int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) +{ + return select(width, r, w, e, t); +} + +int _MD_POLL(void *listptr, unsigned long nfds, long timeout) +{ + return poll(listptr, nfds, timeout); +} + +#endif /* AIX_RENAME_SELECT */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/bsdi.c nspr-4.10.7/nspr/pr/src/md/unix/bsdi.c --- nspr-4.9.5/nspr/pr/src/md/unix/bsdi.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/bsdi.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +void _MD_EarlyInit(void) +{ + /* + * Ignore FPE because coercion of a NaN to an int causes SIGFPE + * to be raised. + */ + struct sigaction act; + + act.sa_handler = SIG_IGN; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGFPE, &act, 0); +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifndef _PR_PTHREADS +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for BSDI */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for BSDI."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for BSDI."); + return PR_FAILURE; +} +#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/.cvsignore nspr-4.10.7/nspr/pr/src/md/unix/.cvsignore --- nspr-4.9.5/nspr/pr/src/md/unix/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/darwin.c nspr-4.10.7/nspr/pr/src/md/unix/darwin.c --- nspr-4.9.5/nspr/pr/src/md/unix/darwin.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/darwin.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +void _MD_EarlyInit(void) +{ +} + +/* + * The multiplier (as a fraction) for converting the Mach absolute time + * unit to nanoseconds. + */ +static mach_timebase_info_data_t machTimebaseInfo; + +void _PR_Mach_IntervalInit(void) +{ + kern_return_t rv; + + rv = mach_timebase_info(&machTimebaseInfo); + PR_ASSERT(rv == KERN_SUCCESS); +} + +PRIntervalTime _PR_Mach_GetInterval(void) +{ + uint64_t time; + + /* + * mach_absolute_time returns the time in the Mach absolute time unit. + * Convert it to milliseconds. See Mac Technical Q&A QA1398. + */ + time = mach_absolute_time(); + time = time * machTimebaseInfo.numer / machTimebaseInfo.denom / + PR_NSEC_PER_MSEC; + return (PRIntervalTime)time; +} /* _PR_Mach_GetInterval */ + +PRIntervalTime _PR_Mach_TicksPerSecond(void) +{ + return 1000; +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#if !defined(_PR_PTHREADS) + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#if !defined(_PR_PTHREADS) +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for Darwin */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for Darwin."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Darwin."); + return PR_FAILURE; +} +#endif /* ! _PR_PTHREADS */ + +/* darwin.c */ + diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/dgux.c nspr-4.10.7/nspr/pr/src/md/unix/dgux.c --- nspr-4.9.5/nspr/pr/src/md/unix/dgux.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/dgux.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +/* + * using only NSPR threads here + * + * Copied from the UnixWare implementation. Should be kept in sync + * with ../../../include/md/_dgux.h. + */ + +#include + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +} + +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for DG/UX */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for DG/UX."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for DG/UX."); +} + diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/freebsd.c nspr-4.10.7/nspr/pr/src/md/unix/freebsd.c --- nspr-4.9.5/nspr/pr/src/md/unix/freebsd.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/freebsd.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +void _MD_EarlyInit(void) +{ + /* + * Ignore FPE because coercion of a NaN to an int causes SIGFPE + * to be raised. + */ + struct sigaction act; + + act.sa_handler = SIG_IGN; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGFPE, &act, 0); +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) sigsetjmp(CONTEXT(t), 1); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifndef _PR_PTHREADS +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for FreeBSD */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for FreeBSD."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for FreeBSD."); + return PR_FAILURE; +} +#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/hpux.c nspr-4.10.7/nspr/pr/src/md/unix/hpux.c --- nspr-4.9.5/nspr/pr/src/md/unix/hpux.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/hpux.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,229 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include + +#if defined(HPUX_LW_TIMER) + +#include +#include +#include +#include +#include + +int __lw_get_thread_times(int which, int64_t *sample, int64_t *time); + +static double msecond_per_itick; + +void _PR_HPUX_LW_IntervalInit(void) +{ + struct pst_processor psp; + int iticksperclktick, clk_tck; + int rv; + + rv = pstat_getprocessor(&psp, sizeof(psp), 1, 0); + PR_ASSERT(rv != -1); + + iticksperclktick = psp.psp_iticksperclktick; + clk_tck = sysconf(_SC_CLK_TCK); + msecond_per_itick = (1000.0)/(double)(iticksperclktick * clk_tck); +} + +PRIntervalTime _PR_HPUX_LW_GetInterval(void) +{ + int64_t time, sample; + + __lw_get_thread_times(1, &sample, &time); + /* + * Division is slower than float multiplication. + * return (time / iticks_per_msecond); + */ + return (time * msecond_per_itick); +} +#endif /* HPUX_LW_TIMER */ + +#if !defined(PTHREADS_USER) + +void _MD_EarlyInit(void) +{ +#ifndef _PR_PTHREADS + /* + * The following piece of code is taken from ns/nspr/src/md_HP-UX.c. + * In the comment for revision 1.6, dated 1995/09/11 23:33:34, + * robm says: + * This version has some problems which need to be addressed. + * First, intercept all system calls and prevent them from + * executing the library code which performs stack switches + * before normal system call invocation. In order for library + * calls which make system calls to work (like stdio), however, + * we must also allocate our own stack and switch the primordial + * stack to use it. This isn't so bad, except that I fudged the + * backtrace length when copying the old stack to the new one. + * + * This is the original comment of robm in the code: + * XXXrobm Horrific. To avoid a problem with HP's system call + * code, we allocate a new stack for the primordial thread and + * use it. However, we don't know how far back the original stack + * goes. We should create a routine that performs a backtrace and + * finds out just how much we need to copy. As a temporary measure, + * I just copy an arbitrary guess. + * + * In an email to servereng dated 2 Jan 1997, Mike Patnode (mikep) + * suggests that this only needs to be done for HP-UX 9. + */ +#ifdef HPUX9 +#define PIDOOMA_STACK_SIZE 524288 +#define BACKTRACE_SIZE 8192 + { + jmp_buf jb; + char *newstack; + char *oldstack; + + if(!setjmp(jb)) { + newstack = (char *) PR_MALLOC(PIDOOMA_STACK_SIZE); + oldstack = (char *) (*(((int *) jb) + 1) - BACKTRACE_SIZE); + memcpy(newstack, oldstack, BACKTRACE_SIZE); + *(((int *) jb) + 1) = (int) (newstack + BACKTRACE_SIZE); + longjmp(jb, 1); + } + } +#endif /* HPUX9 */ +#endif /* !_PR_PTHREADS */ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifndef _PR_PTHREADS +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for HP-UX */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for HP-UX."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for HP-UX."); +} +#endif /* _PR_PTHREADS */ + +void +_MD_suspend_thread(PRThread *thread) +{ +#ifdef _PR_PTHREADS +#endif +} + +void +_MD_resume_thread(PRThread *thread) +{ +#ifdef _PR_PTHREADS +#endif +} +#endif /* PTHREADS_USER */ + +/* + * The HP version of strchr is buggy. It looks past the end of the + * string and causes a segmentation fault when our (NSPR) version + * of malloc is used. + * + * A better solution might be to put a cushion in our malloc just in + * case HP's version of strchr somehow gets used instead of this one. + */ +char * +strchr(const char *s, int c) +{ + char ch; + + if (!s) { + return NULL; + } + + ch = (char) c; + + while ((*s) && ((*s) != ch)) { + s++; + } + + if ((*s) == ch) { + return (char *) s; + } + + return NULL; +} + +/* + * Implemementation of memcmp in HP-UX (verified on releases A.09.03, + * A.09.07, and B.10.10) dumps core if called with: + * 1. First operand with address = 1(mod 4). + * 2. Size = 1(mod 4) + * 3. Last byte of the second operand is the last byte of the page and + * next page is not accessible(not mapped or protected) + * Thus, using the following naive version (tons of optimizations are + * possible;^) + */ + +int memcmp(const void *s1, const void *s2, size_t n) +{ + register unsigned char *p1 = (unsigned char *) s1, + *p2 = (unsigned char *) s2; + + while (n-- > 0) { + register int r = ((int) ((unsigned int) *p1)) + - ((int) ((unsigned int) *p2)); + if (r) return r; + p1++; p2++; + } + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/irix.c nspr-4.10.7/nspr/pr/src/md/unix/irix.c --- nspr-4.9.5/nspr/pr/src/md/unix/irix.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/irix.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1648 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void _MD_IrixIntervalInit(void); + +#if defined(_PR_PTHREADS) +/* + * for compatibility with classic nspr + */ +void _PR_IRIX_CHILD_PROCESS() +{ +} +#else /* defined(_PR_PTHREADS) */ + +static void irix_detach_sproc(void); +char *_nspr_sproc_private; /* ptr. to private region in every sproc */ + +extern PRUintn _pr_numCPU; + +typedef struct nspr_arena { + PRCList links; + usptr_t *usarena; +} nspr_arena; + +#define ARENA_PTR(qp) \ + ((nspr_arena *) ((char*) (qp) - offsetof(nspr_arena , links))) + +static usptr_t *alloc_new_arena(void); + +PRCList arena_list = PR_INIT_STATIC_CLIST(&arena_list); +ulock_t arena_list_lock; +nspr_arena first_arena; +int _nspr_irix_arena_cnt = 1; + +PRCList sproc_list = PR_INIT_STATIC_CLIST(&sproc_list); +ulock_t sproc_list_lock; + +typedef struct sproc_data { + void (*entry) (void *, size_t); + unsigned inh; + void *arg; + caddr_t sp; + size_t len; + int *pid; + int creator_pid; +} sproc_data; + +typedef struct sproc_params { + PRCList links; + sproc_data sd; +} sproc_params; + +#define SPROC_PARAMS_PTR(qp) \ + ((sproc_params *) ((char*) (qp) - offsetof(sproc_params , links))) + +long _nspr_irix_lock_cnt = 0; +long _nspr_irix_sem_cnt = 0; +long _nspr_irix_pollsem_cnt = 0; + +usptr_t *_pr_usArena; +ulock_t _pr_heapLock; + +usema_t *_pr_irix_exit_sem; +PRInt32 _pr_irix_exit_now = 0; +PRInt32 _pr_irix_process_exit_code = 0; /* exit code for PR_ProcessExit */ +PRInt32 _pr_irix_process_exit = 0; /* process exiting due to call to + PR_ProcessExit */ + +int _pr_irix_primoridal_cpu_fd[2] = { -1, -1 }; +static void (*libc_exit)(int) = NULL; +static void *libc_handle = NULL; + +#define _NSPR_DEF_INITUSERS 100 /* default value of CONF_INITUSERS */ +#define _NSPR_DEF_INITSIZE (4 * 1024 * 1024) /* 4 MB */ + +int _irix_initusers = _NSPR_DEF_INITUSERS; +int _irix_initsize = _NSPR_DEF_INITSIZE; + +PRIntn _pr_io_in_progress, _pr_clock_in_progress; + +PRInt32 _pr_md_irix_sprocs_created, _pr_md_irix_sprocs_failed; +PRInt32 _pr_md_irix_sprocs = 1; +PRCList _pr_md_irix_sproc_list = +PR_INIT_STATIC_CLIST(&_pr_md_irix_sproc_list); + +sigset_t ints_off; +extern sigset_t timer_set; + +#if !defined(PR_SETABORTSIG) +#define PR_SETABORTSIG 18 +#endif +/* + * terminate the entire application if any sproc exits abnormally + */ +PRBool _nspr_terminate_on_error = PR_TRUE; + +/* + * exported interface to set the shared arena parameters + */ +void _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize) +{ + _irix_initusers = initusers; + _irix_initsize = initsize; +} + +static usptr_t *alloc_new_arena() +{ + return(usinit("/dev/zero")); +} + +static PRStatus new_poll_sem(struct _MDThread *mdthr, int val) +{ +PRIntn _is; +PRStatus rv = PR_SUCCESS; +usema_t *sem = NULL; +PRCList *qp; +nspr_arena *arena; +usptr_t *irix_arena; +PRThread *me = _MD_GET_ATTACHED_THREAD(); + + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(_is); + _PR_LOCK(arena_list_lock); + for (qp = arena_list.next; qp != &arena_list; qp = qp->next) { + arena = ARENA_PTR(qp); + sem = usnewpollsema(arena->usarena, val); + if (sem != NULL) { + mdthr->cvar_pollsem = sem; + mdthr->pollsem_arena = arena->usarena; + break; + } + } + if (sem == NULL) { + /* + * If no space left in the arena allocate a new one. + */ + if (errno == ENOMEM) { + arena = PR_NEWZAP(nspr_arena); + if (arena != NULL) { + irix_arena = alloc_new_arena(); + if (irix_arena) { + PR_APPEND_LINK(&arena->links, &arena_list); + _nspr_irix_arena_cnt++; + arena->usarena = irix_arena; + sem = usnewpollsema(arena->usarena, val); + if (sem != NULL) { + mdthr->cvar_pollsem = sem; + mdthr->pollsem_arena = arena->usarena; + } else + rv = PR_FAILURE; + } else { + PR_DELETE(arena); + rv = PR_FAILURE; + } + + } else + rv = PR_FAILURE; + } else + rv = PR_FAILURE; + } + _PR_UNLOCK(arena_list_lock); + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(_is); + if (rv == PR_SUCCESS) + _MD_ATOMIC_INCREMENT(&_nspr_irix_pollsem_cnt); + return rv; +} + +static void free_poll_sem(struct _MDThread *mdthr) +{ +PRIntn _is; +PRThread *me = _MD_GET_ATTACHED_THREAD(); + + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(_is); + usfreepollsema(mdthr->cvar_pollsem, mdthr->pollsem_arena); + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(_is); + _MD_ATOMIC_DECREMENT(&_nspr_irix_pollsem_cnt); +} + +static PRStatus new_lock(struct _MDLock *lockp) +{ +PRIntn _is; +PRStatus rv = PR_SUCCESS; +ulock_t lock = NULL; +PRCList *qp; +nspr_arena *arena; +usptr_t *irix_arena; +PRThread *me = _MD_GET_ATTACHED_THREAD(); + + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(_is); + _PR_LOCK(arena_list_lock); + for (qp = arena_list.next; qp != &arena_list; qp = qp->next) { + arena = ARENA_PTR(qp); + lock = usnewlock(arena->usarena); + if (lock != NULL) { + lockp->lock = lock; + lockp->arena = arena->usarena; + break; + } + } + if (lock == NULL) { + /* + * If no space left in the arena allocate a new one. + */ + if (errno == ENOMEM) { + arena = PR_NEWZAP(nspr_arena); + if (arena != NULL) { + irix_arena = alloc_new_arena(); + if (irix_arena) { + PR_APPEND_LINK(&arena->links, &arena_list); + _nspr_irix_arena_cnt++; + arena->usarena = irix_arena; + lock = usnewlock(irix_arena); + if (lock != NULL) { + lockp->lock = lock; + lockp->arena = arena->usarena; + } else + rv = PR_FAILURE; + } else { + PR_DELETE(arena); + rv = PR_FAILURE; + } + + } else + rv = PR_FAILURE; + } else + rv = PR_FAILURE; + } + _PR_UNLOCK(arena_list_lock); + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(_is); + if (rv == PR_SUCCESS) + _MD_ATOMIC_INCREMENT(&_nspr_irix_lock_cnt); + return rv; +} + +static void free_lock(struct _MDLock *lockp) +{ +PRIntn _is; +PRThread *me = _MD_GET_ATTACHED_THREAD(); + + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(_is); + usfreelock(lockp->lock, lockp->arena); + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(_is); + _MD_ATOMIC_DECREMENT(&_nspr_irix_lock_cnt); +} + +void _MD_FREE_LOCK(struct _MDLock *lockp) +{ + PRIntn _is; + PRThread *me = _MD_GET_ATTACHED_THREAD(); + + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(_is); + free_lock(lockp); + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(_is); +} + +/* + * _MD_get_attached_thread + * Return the thread pointer of the current thread if it is attached. + * + * This function is needed for Irix because the thread-local-storage is + * implemented by mmapin'g a page with the MAP_LOCAL flag. This causes the + * sproc-private page to inherit contents of the page of the caller of sproc(). + */ +PRThread *_MD_get_attached_thread(void) +{ + + if (_MD_GET_SPROC_PID() == get_pid()) + return _MD_THIS_THREAD(); + else + return 0; +} + +/* + * _MD_get_current_thread + * Return the thread pointer of the current thread (attaching it if + * necessary) + */ +PRThread *_MD_get_current_thread(void) +{ +PRThread *me; + + me = _MD_GET_ATTACHED_THREAD(); + if (NULL == me) { + me = _PRI_AttachThread( + PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); + } + PR_ASSERT(me != NULL); + return(me); +} + +/* + * irix_detach_sproc + * auto-detach a sproc when it exits + */ +void irix_detach_sproc(void) +{ +PRThread *me; + + me = _MD_GET_ATTACHED_THREAD(); + if ((me != NULL) && (me->flags & _PR_ATTACHED)) { + _PRI_DetachThread(); + } +} + + +PRStatus _MD_NEW_LOCK(struct _MDLock *lockp) +{ + PRStatus rv; + PRIntn is; + PRThread *me = _MD_GET_ATTACHED_THREAD(); + + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + rv = new_lock(lockp); + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return rv; +} + +static void +sigchld_handler(int sig) +{ + pid_t pid; + int status; + + /* + * If an sproc exited abnormally send a SIGKILL signal to all the + * sprocs in the process to terminate the application + */ + while ((pid = waitpid(0, &status, WNOHANG)) > 0) { + if (WIFSIGNALED(status) && ((WTERMSIG(status) == SIGSEGV) || + (WTERMSIG(status) == SIGBUS) || + (WTERMSIG(status) == SIGABRT) || + (WTERMSIG(status) == SIGILL))) { + + prctl(PR_SETEXITSIG, SIGKILL); + _exit(status); + } + } +} + +static void save_context_and_block(int sig) +{ +PRThread *me = _PR_MD_CURRENT_THREAD(); +_PRCPU *cpu = _PR_MD_CURRENT_CPU(); + + /* + * save context + */ + (void) setjmp(me->md.jb); + /* + * unblock the suspending thread + */ + if (me->cpu) { + /* + * I am a cpu thread, not a user-created GLOBAL thread + */ + unblockproc(cpu->md.suspending_id); + } else { + unblockproc(me->md.suspending_id); + } + /* + * now, block current thread + */ + blockproc(getpid()); +} + +/* +** The irix kernel has a bug in it which causes async connect's which are +** interrupted by a signal to fail terribly (EADDRINUSE is returned). +** We work around the bug by blocking signals during the async connect +** attempt. +*/ +PRInt32 _MD_irix_connect( + PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout) +{ + PRInt32 rv; + sigset_t oldset; + + sigprocmask(SIG_BLOCK, &ints_off, &oldset); + rv = connect(osfd, addr, addrlen); + sigprocmask(SIG_SETMASK, &oldset, 0); + + return(rv); +} + +#include "prprf.h" + +/********************************************************************/ +/********************************************************************/ +/*************** Various thread like things for IRIX ****************/ +/********************************************************************/ +/********************************************************************/ + +void *_MD_GetSP(PRThread *t) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + void *sp; + + if (me == t) + (void) setjmp(t->md.jb); + + sp = (void *)(t->md.jb[JB_SP]); + PR_ASSERT((sp >= (void *) t->stack->stackBottom) && + (sp <= (void *) (t->stack->stackBottom + t->stack->stackSize))); + return(sp); +} + +void _MD_InitLocks() +{ + char buf[200]; + char *init_users, *init_size; + + PR_snprintf(buf, sizeof(buf), "/dev/zero"); + + if (init_users = getenv("_NSPR_IRIX_INITUSERS")) + _irix_initusers = atoi(init_users); + + if (init_size = getenv("_NSPR_IRIX_INITSIZE")) + _irix_initsize = atoi(init_size); + + usconfig(CONF_INITUSERS, _irix_initusers); + usconfig(CONF_INITSIZE, _irix_initsize); + usconfig(CONF_AUTOGROW, 1); + usconfig(CONF_AUTORESV, 1); + if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) { + perror("PR_Init: unable to config mutex arena"); + exit(-1); + } + + _pr_usArena = usinit(buf); + if (!_pr_usArena) { + fprintf(stderr, + "PR_Init: Error - unable to create lock/monitor arena\n"); + exit(-1); + } + _pr_heapLock = usnewlock(_pr_usArena); + _nspr_irix_lock_cnt++; + + arena_list_lock = usnewlock(_pr_usArena); + _nspr_irix_lock_cnt++; + + sproc_list_lock = usnewlock(_pr_usArena); + _nspr_irix_lock_cnt++; + + _pr_irix_exit_sem = usnewsema(_pr_usArena, 0); + _nspr_irix_sem_cnt = 1; + + first_arena.usarena = _pr_usArena; + PR_INIT_CLIST(&first_arena.links); + PR_APPEND_LINK(&first_arena.links, &arena_list); +} + +/* _PR_IRIX_CHILD_PROCESS is a private API for Server group */ +void _PR_IRIX_CHILD_PROCESS() +{ +extern PRUint32 _pr_global_threads; + + PR_ASSERT(_PR_MD_CURRENT_CPU() == _pr_primordialCPU); + PR_ASSERT(_pr_numCPU == 1); + PR_ASSERT(_pr_global_threads == 0); + /* + * save the new pid + */ + _pr_primordialCPU->md.id = getpid(); + _MD_SET_SPROC_PID(getpid()); +} + +static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout) +{ + int rv; + +#ifdef _PR_USE_POLL + struct pollfd pfd; + int msecs; + + if (timeout == PR_INTERVAL_NO_TIMEOUT) + msecs = -1; + else + msecs = PR_IntervalToMilliseconds(timeout); +#else + struct timeval tv, *tvp; + fd_set rd; + + if(timeout == PR_INTERVAL_NO_TIMEOUT) + tvp = NULL; + else { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + } + FD_ZERO(&rd); + FD_SET(thread->md.cvar_pollsemfd, &rd); +#endif + + /* + * call uspsema only if a previous select call on this semaphore + * did not timeout + */ + if (!thread->md.cvar_pollsem_select) { + rv = _PR_WAIT_SEM(thread->md.cvar_pollsem); + PR_ASSERT(rv >= 0); + } else + rv = 0; +again: + if(!rv) { +#ifdef _PR_USE_POLL + pfd.events = POLLIN; + pfd.fd = thread->md.cvar_pollsemfd; + rv = _MD_POLL(&pfd, 1, msecs); +#else + rv = _MD_SELECT(thread->md.cvar_pollsemfd + 1, &rd, NULL,NULL,tvp); +#endif + if ((rv == -1) && (errno == EINTR)) { + rv = 0; + goto again; + } + PR_ASSERT(rv >= 0); + } + + if (rv > 0) { + /* + * acquired the semaphore, call uspsema next time + */ + thread->md.cvar_pollsem_select = 0; + return PR_SUCCESS; + } else { + /* + * select timed out; must call select, not uspsema, when trying + * to acquire the semaphore the next time + */ + thread->md.cvar_pollsem_select = 1; + return PR_FAILURE; + } +} + +PRStatus _MD_wait(PRThread *thread, PRIntervalTime ticks) +{ + if ( thread->flags & _PR_GLOBAL_SCOPE ) { + _MD_CHECK_FOR_EXIT(); + if (pr_cvar_wait_sem(thread, ticks) == PR_FAILURE) { + _MD_CHECK_FOR_EXIT(); + /* + * wait timed out + */ + _PR_THREAD_LOCK(thread); + if (thread->wait.cvar) { + /* + * The thread will remove itself from the waitQ + * of the cvar in _PR_WaitCondVar + */ + thread->wait.cvar = NULL; + thread->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(thread); + } else { + _PR_THREAD_UNLOCK(thread); + /* + * This thread was woken up by a notifying thread + * at the same time as a timeout; so, consume the + * extra post operation on the semaphore + */ + _MD_CHECK_FOR_EXIT(); + pr_cvar_wait_sem(thread, PR_INTERVAL_NO_TIMEOUT); + } + _MD_CHECK_FOR_EXIT(); + } + } else { + _PR_MD_SWITCH_CONTEXT(thread); + } + return PR_SUCCESS; +} + +PRStatus _MD_WakeupWaiter(PRThread *thread) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRIntn is; + + PR_ASSERT(_pr_md_idle_cpus >= 0); + if (thread == NULL) { + if (_pr_md_idle_cpus) + _MD_Wakeup_CPUs(); + } else if (!_PR_IS_NATIVE_THREAD(thread)) { + if (_pr_md_idle_cpus) + _MD_Wakeup_CPUs(); + } else { + PR_ASSERT(_PR_IS_NATIVE_THREAD(thread)); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + _MD_CVAR_POST_SEM(thread); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + } + return PR_SUCCESS; +} + +void create_sproc (void (*entry) (void *, size_t), unsigned inh, + void *arg, caddr_t sp, size_t len, int *pid) +{ +sproc_params sparams; +char data; +int rv; +PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) { + *pid = sprocsp(entry, /* startup func */ + inh, /* attribute flags */ + arg, /* thread param */ + sp, /* stack address */ + len); /* stack size */ + } else { + sparams.sd.entry = entry; + sparams.sd.inh = inh; + sparams.sd.arg = arg; + sparams.sd.sp = sp; + sparams.sd.len = len; + sparams.sd.pid = pid; + sparams.sd.creator_pid = getpid(); + _PR_LOCK(sproc_list_lock); + PR_APPEND_LINK(&sparams.links, &sproc_list); + rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1); + PR_ASSERT(rv == 1); + _PR_UNLOCK(sproc_list_lock); + blockproc(getpid()); + } +} + +/* + * _PR_MD_WAKEUP_PRIMORDIAL_CPU + * + * wakeup cpu 0 + */ + +void _PR_MD_WAKEUP_PRIMORDIAL_CPU() +{ +char data = '0'; +int rv; + + rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1); + PR_ASSERT(rv == 1); +} + +/* + * _PR_MD_primordial_cpu + * + * process events that need to executed by the primordial cpu on each + * iteration through the idle loop + */ + +void _PR_MD_primordial_cpu() +{ +PRCList *qp; +sproc_params *sp; +int pid; + + _PR_LOCK(sproc_list_lock); + while ((qp = sproc_list.next) != &sproc_list) { + sp = SPROC_PARAMS_PTR(qp); + PR_REMOVE_LINK(&sp->links); + pid = sp->sd.creator_pid; + (*(sp->sd.pid)) = sprocsp(sp->sd.entry, /* startup func */ + sp->sd.inh, /* attribute flags */ + sp->sd.arg, /* thread param */ + sp->sd.sp, /* stack address */ + sp->sd.len); /* stack size */ + unblockproc(pid); + } + _PR_UNLOCK(sproc_list_lock); +} + +PRStatus _MD_CreateThread(PRThread *thread, +void (*start)(void *), +PRThreadPriority priority, +PRThreadScope scope, +PRThreadState state, +PRUint32 stackSize) +{ + typedef void (*SprocEntry) (void *, size_t); + SprocEntry spentry = (SprocEntry)start; + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 pid; + PRStatus rv; + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + thread->md.cvar_pollsem_select = 0; + thread->flags |= _PR_GLOBAL_SCOPE; + + thread->md.cvar_pollsemfd = -1; + if (new_poll_sem(&thread->md,0) == PR_FAILURE) { + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return PR_FAILURE; + } + thread->md.cvar_pollsemfd = + _PR_OPEN_POLL_SEM(thread->md.cvar_pollsem); + if ((thread->md.cvar_pollsemfd < 0)) { + free_poll_sem(&thread->md); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return PR_FAILURE; + } + + create_sproc(spentry, /* startup func */ + PR_SALL, /* attribute flags */ + (void *)thread, /* thread param */ + NULL, /* stack address */ + stackSize, &pid); /* stack size */ + if (pid > 0) { + _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_created); + _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs); + rv = PR_SUCCESS; + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return rv; + } else { + close(thread->md.cvar_pollsemfd); + thread->md.cvar_pollsemfd = -1; + free_poll_sem(&thread->md); + thread->md.cvar_pollsem = NULL; + _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_failed); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return PR_FAILURE; + } +} + +void _MD_CleanThread(PRThread *thread) +{ + if (thread->flags & _PR_GLOBAL_SCOPE) { + close(thread->md.cvar_pollsemfd); + thread->md.cvar_pollsemfd = -1; + free_poll_sem(&thread->md); + thread->md.cvar_pollsem = NULL; + } +} + +void _MD_SetPriority(_MDThread *thread, PRThreadPriority newPri) +{ + return; +} + +extern void _MD_unix_terminate_waitpid_daemon(void); + +void +_MD_CleanupBeforeExit(void) +{ + extern PRInt32 _pr_cpus_exit; + + _MD_unix_terminate_waitpid_daemon(); + + _pr_irix_exit_now = 1; + if (_pr_numCPU > 1) { + /* + * Set a global flag, and wakeup all cpus which will notice the flag + * and exit. + */ + _pr_cpus_exit = getpid(); + _MD_Wakeup_CPUs(); + while(_pr_numCPU > 1) { + _PR_WAIT_SEM(_pr_irix_exit_sem); + _pr_numCPU--; + } + } + /* + * cause global threads on the recycle list to exit + */ + _PR_DEADQ_LOCK; + if (_PR_NUM_DEADNATIVE != 0) { + PRThread *thread; + PRCList *ptr; + + ptr = _PR_DEADNATIVEQ.next; + while( ptr != &_PR_DEADNATIVEQ ) { + thread = _PR_THREAD_PTR(ptr); + _MD_CVAR_POST_SEM(thread); + ptr = ptr->next; + } + } + _PR_DEADQ_UNLOCK; + while(_PR_NUM_DEADNATIVE > 1) { + _PR_WAIT_SEM(_pr_irix_exit_sem); + _PR_DEC_DEADNATIVE; + } +} + +#ifdef _PR_HAVE_SGI_PRDA_PROCMASK +extern void __sgi_prda_procmask(int); +#endif + +PRStatus +_MD_InitAttachedThread(PRThread *thread, PRBool wakeup_parent) +{ + PRStatus rv = PR_SUCCESS; + + if (thread->flags & _PR_GLOBAL_SCOPE) { + if (new_poll_sem(&thread->md,0) == PR_FAILURE) { + return PR_FAILURE; + } + thread->md.cvar_pollsemfd = + _PR_OPEN_POLL_SEM(thread->md.cvar_pollsem); + if ((thread->md.cvar_pollsemfd < 0)) { + free_poll_sem(&thread->md); + return PR_FAILURE; + } + if (_MD_InitThread(thread, PR_FALSE) == PR_FAILURE) { + close(thread->md.cvar_pollsemfd); + thread->md.cvar_pollsemfd = -1; + free_poll_sem(&thread->md); + thread->md.cvar_pollsem = NULL; + return PR_FAILURE; + } + } + return rv; +} + +PRStatus +_MD_InitThread(PRThread *thread, PRBool wakeup_parent) +{ + struct sigaction sigact; + PRStatus rv = PR_SUCCESS; + + if (thread->flags & _PR_GLOBAL_SCOPE) { + thread->md.id = getpid(); + setblockproccnt(thread->md.id, 0); + _MD_SET_SPROC_PID(getpid()); +#ifdef _PR_HAVE_SGI_PRDA_PROCMASK + /* + * enable user-level processing of sigprocmask(); this is an + * undocumented feature available in Irix 6.2, 6.3, 6.4 and 6.5 + */ + __sgi_prda_procmask(USER_LEVEL); +#endif + /* + * set up SIGUSR1 handler; this is used to save state + */ + sigact.sa_handler = save_context_and_block; + sigact.sa_flags = SA_RESTART; + /* + * Must mask clock interrupts + */ + sigact.sa_mask = timer_set; + sigaction(SIGUSR1, &sigact, 0); + + + /* + * PR_SETABORTSIG is a new command implemented in a patch to + * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all + * sprocs in the process when one of them terminates abnormally + * + */ + if (prctl(PR_SETABORTSIG, SIGKILL) < 0) { + /* + * if (errno == EINVAL) + * + * PR_SETABORTSIG not supported under this OS. + * You may want to get a recent kernel rollup patch that + * supports this feature. + */ + } + /* + * SIGCLD handler for detecting abormally-terminating + * sprocs and for reaping sprocs + */ + sigact.sa_handler = sigchld_handler; + sigact.sa_flags = SA_RESTART; + sigact.sa_mask = ints_off; + sigaction(SIGCLD, &sigact, NULL); + } + return rv; +} + +/* + * PR_Cleanup should be executed on the primordial sproc; migrate the thread + * to the primordial cpu + */ + +void _PR_MD_PRE_CLEANUP(PRThread *me) +{ +PRIntn is; +_PRCPU *cpu = _pr_primordialCPU; + + PR_ASSERT(cpu); + + me->flags |= _PR_BOUND_THREAD; + + if (me->cpu->id != 0) { + _PR_INTSOFF(is); + _PR_RUNQ_LOCK(cpu); + me->cpu = cpu; + me->state = _PR_RUNNABLE; + _PR_ADD_RUNQ(me, cpu, me->priority); + _PR_RUNQ_UNLOCK(cpu); + _MD_Wakeup_CPUs(); + + _PR_MD_SWITCH_CONTEXT(me); + + _PR_FAST_INTSON(is); + PR_ASSERT(me->cpu->id == 0); + } +} + +/* + * process exiting + */ +PR_EXTERN(void ) _MD_exit(PRIntn status) +{ +PRThread *me = _PR_MD_CURRENT_THREAD(); + + /* + * the exit code of the process is the exit code of the primordial + * sproc + */ + if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) { + /* + * primordial sproc case: call _exit directly + * Cause SIGKILL to be sent to other sprocs + */ + prctl(PR_SETEXITSIG, SIGKILL); + _exit(status); + } else { + int rv; + char data; + sigset_t set; + + /* + * non-primordial sproc case: cause the primordial sproc, cpu 0, + * to wakeup and call _exit + */ + _pr_irix_process_exit = 1; + _pr_irix_process_exit_code = status; + rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1); + PR_ASSERT(rv == 1); + /* + * block all signals and wait for SIGKILL to terminate this sproc + */ + sigfillset(&set); + sigsuspend(&set); + /* + * this code doesn't (shouldn't) execute + */ + prctl(PR_SETEXITSIG, SIGKILL); + _exit(status); + } +} + +/* + * Override the exit() function in libc to cause the process to exit + * when the primodial/main nspr thread calls exit. Calls to exit by any + * other thread simply result in a call to the exit function in libc. + * The exit code of the process is the exit code of the primordial + * sproc. + */ + +void exit(int status) +{ +PRThread *me, *thr; +PRCList *qp; + + if (!_pr_initialized) { + if (!libc_exit) { + + if (!libc_handle) + libc_handle = dlopen("libc.so",RTLD_NOW); + if (libc_handle) + libc_exit = (void (*)(int)) dlsym(libc_handle, "exit"); + } + if (libc_exit) + (*libc_exit)(status); + else + _exit(status); + } + + me = _PR_MD_CURRENT_THREAD(); + + if (me == NULL) /* detached thread */ + (*libc_exit)(status); + + PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || + (_PR_MD_CURRENT_CPU())->id == me->cpu->id); + + if (me->flags & _PR_PRIMORDIAL) { + + me->flags |= _PR_BOUND_THREAD; + + PR_ASSERT((_PR_MD_CURRENT_CPU())->id == me->cpu->id); + if (me->cpu->id != 0) { + _PRCPU *cpu = _pr_primordialCPU; + PRIntn is; + + _PR_INTSOFF(is); + _PR_RUNQ_LOCK(cpu); + me->cpu = cpu; + me->state = _PR_RUNNABLE; + _PR_ADD_RUNQ(me, cpu, me->priority); + _PR_RUNQ_UNLOCK(cpu); + _MD_Wakeup_CPUs(); + + _PR_MD_SWITCH_CONTEXT(me); + + _PR_FAST_INTSON(is); + } + + PR_ASSERT((_PR_MD_CURRENT_CPU())->id == 0); + + if (prctl(PR_GETNSHARE) > 1) { +#define SPROC_EXIT_WAIT_TIME 5 + int sleep_cnt = SPROC_EXIT_WAIT_TIME; + + /* + * sprocs still running; caue cpus and recycled global threads + * to exit + */ + _pr_irix_exit_now = 1; + if (_pr_numCPU > 1) { + _MD_Wakeup_CPUs(); + } + _PR_DEADQ_LOCK; + if (_PR_NUM_DEADNATIVE != 0) { + PRThread *thread; + PRCList *ptr; + + ptr = _PR_DEADNATIVEQ.next; + while( ptr != &_PR_DEADNATIVEQ ) { + thread = _PR_THREAD_PTR(ptr); + _MD_CVAR_POST_SEM(thread); + ptr = ptr->next; + } + } + + while (sleep_cnt-- > 0) { + if (waitpid(0, NULL, WNOHANG) >= 0) + sleep(1); + else + break; + } + prctl(PR_SETEXITSIG, SIGKILL); + } + (*libc_exit)(status); + } else { + /* + * non-primordial thread; simply call exit in libc. + */ + (*libc_exit)(status); + } +} + + +void +_MD_InitRunningCPU(_PRCPU *cpu) +{ + extern int _pr_md_pipefd[2]; + + _MD_unix_init_running_cpu(cpu); + cpu->md.id = getpid(); + _MD_SET_SPROC_PID(getpid()); + if (_pr_md_pipefd[0] >= 0) { + _PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0]; +#ifndef _PR_USE_POLL + FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu)); +#endif + } +} + +void +_MD_ExitThread(PRThread *thread) +{ + if (thread->flags & _PR_GLOBAL_SCOPE) { + _MD_ATOMIC_DECREMENT(&_pr_md_irix_sprocs); + _MD_CLEAN_THREAD(thread); + _MD_SET_CURRENT_THREAD(NULL); + } +} + +void +_MD_SuspendCPU(_PRCPU *cpu) +{ + PRInt32 rv; + + cpu->md.suspending_id = getpid(); + rv = kill(cpu->md.id, SIGUSR1); + PR_ASSERT(rv == 0); + /* + * now, block the current thread/cpu until woken up by the suspended + * thread from it's SIGUSR1 signal handler + */ + blockproc(getpid()); + +} + +void +_MD_ResumeCPU(_PRCPU *cpu) +{ + unblockproc(cpu->md.id); +} + +#if 0 +/* + * save the register context of a suspended sproc + */ +void get_context(PRThread *thr) +{ + int len, fd; + char pidstr[24]; + char path[24]; + + /* + * open the file corresponding to this process in procfs + */ + sprintf(path,"/proc/%s","00000"); + len = strlen(path); + sprintf(pidstr,"%d",thr->md.id); + len -= strlen(pidstr); + sprintf(path + len,"%s",pidstr); + fd = open(path,O_RDONLY); + if (fd >= 0) { + (void) ioctl(fd, PIOCGREG, thr->md.gregs); + close(fd); + } + return; +} +#endif /* 0 */ + +void +_MD_SuspendThread(PRThread *thread) +{ + PRInt32 rv; + + PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) && + _PR_IS_GCABLE_THREAD(thread)); + + thread->md.suspending_id = getpid(); + rv = kill(thread->md.id, SIGUSR1); + PR_ASSERT(rv == 0); + /* + * now, block the current thread/cpu until woken up by the suspended + * thread from it's SIGUSR1 signal handler + */ + blockproc(getpid()); +} + +void +_MD_ResumeThread(PRThread *thread) +{ + PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) && + _PR_IS_GCABLE_THREAD(thread)); + (void)unblockproc(thread->md.id); +} + +/* + * return the set of processors available for scheduling procs in the + * "mask" argument + */ +PRInt32 _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask) +{ + PRInt32 nprocs, rv; + struct pda_stat *pstat; +#define MAX_PROCESSORS 32 + + nprocs = sysmp(MP_NPROCS); + if (nprocs < 0) + return(-1); + pstat = (struct pda_stat*)PR_MALLOC(sizeof(struct pda_stat) * nprocs); + if (pstat == NULL) + return(-1); + rv = sysmp(MP_STAT, pstat); + if (rv < 0) { + PR_DELETE(pstat); + return(-1); + } + /* + * look at the first 32 cpus + */ + nprocs = (nprocs > MAX_PROCESSORS) ? MAX_PROCESSORS : nprocs; + *mask = 0; + while (nprocs) { + if ((pstat->p_flags & PDAF_ENABLED) && + !(pstat->p_flags & PDAF_ISOLATED)) { + *mask |= (1 << pstat->p_cpuid); + } + nprocs--; + pstat++; + } + return 0; +} + +static char *_thr_state[] = { + "UNBORN", + "RUNNABLE", + "RUNNING", + "LOCK_WAIT", + "COND_WAIT", + "JOIN_WAIT", + "IO_WAIT", + "SUSPENDED", + "DEAD" +}; + +void _PR_List_Threads() +{ + PRThread *thr; + void *handle; + struct _PRCPU *cpu; + PRCList *qp; + int len, fd; + char pidstr[24]; + char path[24]; + prpsinfo_t pinfo; + + + printf("\n%s %-s\n"," ","LOCAL Threads"); + printf("%s %-s\n"," ","----- -------"); + printf("%s %-14s %-10s %-12s %-3s %-10s %-10s %-12s\n\n"," ", + "Thread", "State", "Wait-Handle", + "Cpu","Stk-Base","Stk-Sz","SP"); + for (qp = _PR_ACTIVE_LOCAL_THREADQ().next; + qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) { + thr = _PR_ACTIVE_THREAD_PTR(qp); + printf("%s 0x%-12x %-10s "," ",thr,_thr_state[thr->state]); + if (thr->state == _PR_LOCK_WAIT) + handle = thr->wait.lock; + else if (thr->state == _PR_COND_WAIT) + handle = thr->wait.cvar; + else + handle = NULL; + if (handle) + printf("0x%-10x ",handle); + else + printf("%-12s "," "); + printf("%-3d ",thr->cpu->id); + printf("0x%-8x ",thr->stack->stackBottom); + printf("0x%-8x ",thr->stack->stackSize); + printf("0x%-10x\n",thr->md.jb[JB_SP]); + } + + printf("\n%s %-s\n"," ","GLOBAL Threads"); + printf("%s %-s\n"," ","------ -------"); + printf("%s %-14s %-6s %-12s %-12s %-12s %-12s\n\n"," ","Thread", + "Pid","State","Wait-Handle", + "Stk-Base","Stk-Sz"); + + for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next; + qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) { + thr = _PR_ACTIVE_THREAD_PTR(qp); + if (thr->cpu != NULL) + continue; /* it is a cpu thread */ + printf("%s 0x%-12x %-6d "," ",thr,thr->md.id); + /* + * check if the sproc is still running + * first call prctl(PR_GETSHMASK,pid) to check if + * the process is part of the share group (the pid + * could have been recycled by the OS) + */ + if (prctl(PR_GETSHMASK,thr->md.id) < 0) { + printf("%-12s\n","TERMINATED"); + continue; + } + /* + * Now, check if the sproc terminated and is in zombie + * state + */ + sprintf(path,"/proc/pinfo/%s","00000"); + len = strlen(path); + sprintf(pidstr,"%d",thr->md.id); + len -= strlen(pidstr); + sprintf(path + len,"%s",pidstr); + fd = open(path,O_RDONLY); + if (fd >= 0) { + if (ioctl(fd, PIOCPSINFO, &pinfo) < 0) + printf("%-12s ","TERMINATED"); + else if (pinfo.pr_zomb) + printf("%-12s ","TERMINATED"); + else + printf("%-12s ",_thr_state[thr->state]); + close(fd); + } else { + printf("%-12s ","TERMINATED"); + } + + if (thr->state == _PR_LOCK_WAIT) + handle = thr->wait.lock; + else if (thr->state == _PR_COND_WAIT) + handle = thr->wait.cvar; + else + handle = NULL; + if (handle) + printf("%-12x ",handle); + else + printf("%-12s "," "); + printf("0x%-10x ",thr->stack->stackBottom); + printf("0x%-10x\n",thr->stack->stackSize); + } + + printf("\n%s %-s\n"," ","CPUs"); + printf("%s %-s\n"," ","----"); + printf("%s %-14s %-6s %-12s \n\n"," ","Id","Pid","State"); + + + for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) { + cpu = _PR_CPU_PTR(qp); + printf("%s %-14d %-6d "," ",cpu->id,cpu->md.id); + /* + * check if the sproc is still running + * first call prctl(PR_GETSHMASK,pid) to check if + * the process is part of the share group (the pid + * could have been recycled by the OS) + */ + if (prctl(PR_GETSHMASK,cpu->md.id) < 0) { + printf("%-12s\n","TERMINATED"); + continue; + } + /* + * Now, check if the sproc terminated and is in zombie + * state + */ + sprintf(path,"/proc/pinfo/%s","00000"); + len = strlen(path); + sprintf(pidstr,"%d",cpu->md.id); + len -= strlen(pidstr); + sprintf(path + len,"%s",pidstr); + fd = open(path,O_RDONLY); + if (fd >= 0) { + if (ioctl(fd, PIOCPSINFO, &pinfo) < 0) + printf("%-12s\n","TERMINATED"); + else if (pinfo.pr_zomb) + printf("%-12s\n","TERMINATED"); + else + printf("%-12s\n","RUNNING"); + close(fd); + } else { + printf("%-12s\n","TERMINATED"); + } + + } + fflush(stdout); +} +#endif /* defined(_PR_PTHREADS) */ + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#if !defined(_PR_PTHREADS) + if (isCurrent) { + (void) setjmp(t->md.jb); + } + *np = sizeof(t->md.jb) / sizeof(PRWord); + return (PRWord *) (t->md.jb); +#else + *np = 0; + return NULL; +#endif +} + +void _MD_EarlyInit(void) +{ +#if !defined(_PR_PTHREADS) + char *eval; + int fd; + extern int __ateachexit(void (*func)(void)); + + sigemptyset(&ints_off); + sigaddset(&ints_off, SIGALRM); + sigaddset(&ints_off, SIGIO); + sigaddset(&ints_off, SIGCLD); + + if (eval = getenv("_NSPR_TERMINATE_ON_ERROR")) + _nspr_terminate_on_error = (0 == atoi(eval) == 0) ? PR_FALSE : PR_TRUE; + + fd = open("/dev/zero",O_RDWR , 0); + if (fd < 0) { + perror("open /dev/zero failed"); + exit(1); + } + /* + * Set up the sproc private data area. + * This region exists at the same address, _nspr_sproc_private, for + * every sproc, but each sproc gets a private copy of the region. + */ + _nspr_sproc_private = (char*)mmap(0, _pr_pageSize, PROT_READ | PROT_WRITE, + MAP_PRIVATE| MAP_LOCAL, fd, 0); + if (_nspr_sproc_private == (void*)-1) { + perror("mmap /dev/zero failed"); + exit(1); + } + _MD_SET_SPROC_PID(getpid()); + close(fd); + __ateachexit(irix_detach_sproc); +#endif + _MD_IrixIntervalInit(); +} /* _MD_EarlyInit */ + +void _MD_IrixInit(void) +{ +#if !defined(_PR_PTHREADS) + struct sigaction sigact; + PRThread *me = _PR_MD_CURRENT_THREAD(); + int rv; + +#ifdef _PR_HAVE_SGI_PRDA_PROCMASK + /* + * enable user-level processing of sigprocmask(); this is an undocumented + * feature available in Irix 6.2, 6.3, 6.4 and 6.5 + */ + __sgi_prda_procmask(USER_LEVEL); +#endif + + /* + * set up SIGUSR1 handler; this is used to save state + * during PR_SuspendAll + */ + sigact.sa_handler = save_context_and_block; + sigact.sa_flags = SA_RESTART; + sigact.sa_mask = ints_off; + sigaction(SIGUSR1, &sigact, 0); + + /* + * Change the name of the core file from core to core.pid, + * This is inherited by the sprocs created by this process + */ +#ifdef PR_COREPID + prctl(PR_COREPID, 0, 1); +#endif + /* + * Irix-specific terminate on error processing + */ + /* + * PR_SETABORTSIG is a new command implemented in a patch to + * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all + * sprocs in the process when one of them terminates abnormally + * + */ + if (prctl(PR_SETABORTSIG, SIGKILL) < 0) { + /* + * if (errno == EINVAL) + * + * PR_SETABORTSIG not supported under this OS. + * You may want to get a recent kernel rollup patch that + * supports this feature. + * + */ + } + /* + * PR_SETEXITSIG - send the SIGCLD signal to the parent + * sproc when any sproc terminates + * + * This is used to cause the entire application to + * terminate when any sproc terminates abnormally by + * receipt of a SIGSEGV, SIGBUS or SIGABRT signal. + * If this is not done, the application may seem + * "hung" to the user because the other sprocs may be + * waiting for resources held by the + * abnormally-terminating sproc. + */ + prctl(PR_SETEXITSIG, 0); + + sigact.sa_handler = sigchld_handler; + sigact.sa_flags = SA_RESTART; + sigact.sa_mask = ints_off; + sigaction(SIGCLD, &sigact, NULL); + + /* + * setup stack fields for the primordial thread + */ + me->stack->stackSize = prctl(PR_GETSTACKSIZE); + me->stack->stackBottom = me->stack->stackTop - me->stack->stackSize; + + rv = pipe(_pr_irix_primoridal_cpu_fd); + PR_ASSERT(rv == 0); +#ifndef _PR_USE_POLL + _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0]; + FD_SET(_pr_irix_primoridal_cpu_fd[0], &_PR_FD_READ_SET(me->cpu)); +#endif + + libc_handle = dlopen("libc.so",RTLD_NOW); + PR_ASSERT(libc_handle != NULL); + libc_exit = (void (*)(int)) dlsym(libc_handle, "exit"); + PR_ASSERT(libc_exit != NULL); + /* dlclose(libc_handle); */ + +#endif /* _PR_PTHREADS */ + + _PR_UnixInit(); +} + +/**************************************************************************/ +/************** code and such for NSPR 2.0's interval times ***************/ +/**************************************************************************/ + +#define PR_PSEC_PER_SEC 1000000000000ULL /* 10^12 */ + +#ifndef SGI_CYCLECNTR_SIZE +#define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */ +#endif + +static PRIntn mmem_fd = -1; +static PRIntn clock_width = 0; +static void *iotimer_addr = NULL; +static PRUint32 pr_clock_mask = 0; +static PRUint32 pr_clock_shift = 0; +static PRIntervalTime pr_ticks = 0; +static PRUint32 pr_clock_granularity = 1; +static PRUint32 pr_previous = 0, pr_residual = 0; +static PRUint32 pr_ticks_per_second = 0; + +extern PRIntervalTime _PR_UNIX_GetInterval(void); +extern PRIntervalTime _PR_UNIX_TicksPerSecond(void); + +static void _MD_IrixIntervalInit(void) +{ + /* + * As much as I would like, the service available through this + * interface on R3000's (aka, IP12) just isn't going to make it. + * The register is only 24 bits wide, and rolls over at a verocious + * rate. + */ + PRUint32 one_tick = 0; + struct utsname utsinfo; + uname(&utsinfo); + if ((strncmp("IP12", utsinfo.machine, 4) != 0) + && ((mmem_fd = open("/dev/mmem", O_RDONLY)) != -1)) + { + int poffmask = getpagesize() - 1; + __psunsigned_t phys_addr, raddr, cycleval; + + phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval); + raddr = phys_addr & ~poffmask; + iotimer_addr = mmap( + 0, poffmask, PROT_READ, MAP_PRIVATE, mmem_fd, (__psint_t)raddr); + + clock_width = syssgi(SGI_CYCLECNTR_SIZE); + if (clock_width < 0) + { + /* + * We must be executing on a 6.0 or earlier system, since the + * SGI_CYCLECNTR_SIZE call is not supported. + * + * The only pre-6.1 platforms with 64-bit counters are + * IP19 and IP21 (Challenge, PowerChallenge, Onyx). + */ + if (!strncmp(utsinfo.machine, "IP19", 4) || + !strncmp(utsinfo.machine, "IP21", 4)) + clock_width = 64; + else + clock_width = 32; + } + + /* + * 'cycleval' is picoseconds / increment of the counter. + * I'm pushing for a tick to be 100 microseconds, 10^(-4). + * That leaves 10^(-8) left over, or 10^8 / cycleval. + * Did I do that right? + */ + + one_tick = 100000000UL / cycleval ; /* 100 microseconds */ + + while (0 != one_tick) + { + pr_clock_shift += 1; + one_tick = one_tick >> 1; + pr_clock_granularity = pr_clock_granularity << 1; + } + pr_clock_mask = pr_clock_granularity - 1; /* to make a mask out of it */ + pr_ticks_per_second = PR_PSEC_PER_SEC + / ((PRUint64)pr_clock_granularity * (PRUint64)cycleval); + + iotimer_addr = (void*) + ((__psunsigned_t)iotimer_addr + (phys_addr & poffmask)); + } + else + { + pr_ticks_per_second = _PR_UNIX_TicksPerSecond(); + } +} /* _MD_IrixIntervalInit */ + +PRIntervalTime _MD_IrixIntervalPerSec(void) +{ + return pr_ticks_per_second; +} + +PRIntervalTime _MD_IrixGetInterval(void) +{ + if (mmem_fd != -1) + { + if (64 == clock_width) + { + PRUint64 temp = *(PRUint64*)iotimer_addr; + pr_ticks = (PRIntervalTime)(temp >> pr_clock_shift); + } + else + { + PRIntervalTime ticks = pr_ticks; + PRUint32 now = *(PRUint32*)iotimer_addr, temp; + PRUint32 residual = pr_residual, previous = pr_previous; + + temp = now - previous + residual; + residual = temp & pr_clock_mask; + ticks += temp >> pr_clock_shift; + + pr_previous = now; + pr_residual = residual; + pr_ticks = ticks; + } + } + else + { + /* + * No fast access. Use the time of day clock. This isn't the + * right answer since this clock can get set back, tick at odd + * rates, and it's expensive to acqurie. + */ + pr_ticks = _PR_UNIX_GetInterval(); + } + return pr_ticks; +} /* _MD_IrixGetInterval */ + diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/linux.c nspr-4.10.7/nspr/pr/src/md/unix/linux.c --- nspr-4.9.5/nspr/pr/src/md/unix/linux.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/linux.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifdef _PR_PTHREADS + +extern void _MD_unix_terminate_waitpid_daemon(void); + +void _MD_CleanupBeforeExit(void) +{ + _MD_unix_terminate_waitpid_daemon(); +} + +#else /* ! _PR_PTHREADS */ + +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + /* + * set the pointers to the stack-pointer and frame-pointer words in the + * context structure; this is for debugging use. + */ + thread->md.sp = _MD_GET_SP_PTR(thread); + thread->md.fp = _MD_GET_FP_PTR(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for Linux */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for Linux."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Linux."); + return PR_FAILURE; +} +#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/Makefile.in nspr-4.10.7/nspr/pr/src/md/unix/Makefile.in --- nspr-4.9.5/nspr/pr/src/md/unix/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,99 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +MOD_DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CSRCS = \ + unix.c \ + unix_errors.c \ + uxproces.c \ + uxrng.c \ + uxshm.c \ + uxwrap.c \ + $(NULL) + +ifneq ($(USE_PTHREADS),1) +CSRCS += uxpoll.c +endif + +ifeq ($(PTHREADS_USER),1) +CSRCS += pthreads_user.c +endif + +CSRCS += $(PR_MD_CSRCS) +ASFILES += $(PR_MD_ASFILES) + +TARGETS = $(OBJS) + +ifeq ($(OS_ARCH),SunOS) + ifeq ($(CPU_ARCH),sparc) + ifdef USE_64 + ULTRASPARC_ASFILES = os_SunOS_sparcv9.s + ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX))) + else + LIBRARY_NAME = $(ULTRASPARC_LIBRARY) + LIBRARY_VERSION = $(MOD_MAJOR_VERSION) + ULTRASPARC_ASFILES = os_SunOS_ultrasparc.s + ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX))) + TARGETS += $(ULTRASPARC_ASOBJS) $(SHARED_LIBRARY) + RELEASE_LIBS = $(SHARED_LIBRARY) + RELEASE_LIBS_DEST = $(RELEASE_LIB_DIR)/cpu/sparcv8plus + lib_subdir = cpu/sparcv8plus + endif + endif +endif + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + +ifeq ($(OS_ARCH),SunOS) +ifeq ($(CPU_ARCH),sparc) + +ifdef USE_64 +$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES) + /usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v9 $< +else +$(SHARED_LIBRARY): $(ULTRASPARC_ASOBJS) + $(LD) -G -z text -z endfiltee -o $@ $(ULTRASPARC_ASOBJS) + $(INSTALL) -m 444 $@ $(dist_libdir)/cpu/sparcv8plus + $(INSTALL) -m 444 $@ $(dist_bindir)/cpu/sparcv8plus +# +# The -f $(ORIGIN)/... linker flag uses the real file, after symbolic links +# are resolved, as the origin. If NSDISTMODE is not "copy", libnspr4.so +# will be installed as a symbolic link in $(dist_libdir), pointing to the +# real libnspr4.so file in pr/src. Therefore we need to install an +# additional copy of libnspr_flt4.so in pr/src/cpu/sparcv8plus. +# +ifneq ($(NSDISTMODE),copy) + $(INSTALL) -m 444 $@ ../../cpu/sparcv8plus +endif + +ifneq ($(NSDISTMODE),copy) +clobber realclean clobber_all distclean:: + rm -rf ../../cpu +endif + +$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES) + /usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v8plus $< + +clean:: + rm -rf $(ULTRASPARC_ASOBJS) +endif + +endif +endif diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/netbsd.c nspr-4.10.7/nspr/pr/src/md/unix/netbsd.c --- nspr-4.9.5/nspr/pr/src/md/unix/netbsd.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/netbsd.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include +#include + +void _MD_EarlyInit(void) +{ + /* + * Ignore FPE because coercion of a NaN to an int causes SIGFPE + * to be raised. + */ + struct sigaction act; + + act.sa_handler = SIG_IGN; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGFPE, &act, 0); +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) sigsetjmp(CONTEXT(t), 1); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifndef _PR_PTHREADS +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for NetBSD */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for NetBSD."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NetBSD."); + return PR_FAILURE; +} +#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/nto.c nspr-4.10.7/nspr/pr/src/md/unix/nto.c --- nspr-4.9.5/nspr/pr/src/md/unix/nto.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/nto.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +/* Fake this out */ +int socketpair (int foo, int foo2, int foo3, int sv[2]) +{ + printf("error in socketpair\n"); + exit (-1); +} + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/objs.mk nspr-4.10.7/nspr/pr/src/md/unix/objs.mk --- nspr-4.9.5/nspr/pr/src/md/unix/objs.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/objs.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,31 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This makefile appends to the variable OBJS the platform-dependent +# object modules that will be part of the nspr20 library. + +CSRCS = \ + unix.c \ + unix_errors.c \ + uxproces.c \ + uxrng.c \ + uxshm.c \ + uxwrap.c \ + $(NULL) + +ifneq ($(USE_PTHREADS),1) +CSRCS += uxpoll.c +endif + +ifeq ($(PTHREADS_USER),1) +CSRCS += pthreads_user.c +endif + +CSRCS += $(PR_MD_CSRCS) +ASFILES += $(PR_MD_ASFILES) + +OBJS += $(addprefix md/unix/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \ + $(addprefix md/unix/$(OBJDIR)/,$(ASFILES:.s=.$(OBJ_SUFFIX))) + diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/openbsd.c nspr-4.10.7/nspr/pr/src/md/unix/openbsd.c --- nspr-4.9.5/nspr/pr/src/md/unix/openbsd.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/openbsd.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include +#include + +void _MD_EarlyInit(void) +{ + /* + * Ignore FPE because coercion of a NaN to an int causes SIGFPE + * to be raised. + */ + struct sigaction act; + + act.sa_handler = SIG_IGN; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGFPE, &act, 0); +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) sigsetjmp(CONTEXT(t), 1); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifndef _PR_PTHREADS +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for OpenBSD */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for OpenBSD."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OpenBSD."); + return PR_FAILURE; +} +#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_AIX.s nspr-4.10.7/nspr/pr/src/md/unix/os_AIX.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_AIX.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_AIX.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,91 @@ +# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 + + + .rename H.10.NO_SYMBOL{PR},"" + .rename H.18.longjmp{TC},"longjmp" + + .lglobl H.10.NO_SYMBOL{PR} + .globl .longjmp + .globl longjmp{DS} + .extern .sigcleanup + .extern .jmprestfpr + +# .text section + + .csect H.10.NO_SYMBOL{PR} +.longjmp: + mr r13,r3 + mr r14,r4 + stu SP,-56(SP) + bl .sigcleanup + l RTOC,0x14(SP) + cal SP,0x38(SP) + mr r3,r13 + mr r4,r14 + l r5,0x8(r3) + l SP,0xc(r3) + l r7,0xf8(r3) + st r7,0x0(SP) + l RTOC,0x10(r3) + bl .jmprestfpr +# 1 == cr0 in disassembly + cmpi 1,r4,0x0 + mtlr r5 + lm r13,0x14(r3) + l r5,0x60(r3) + mtcrf 0x38,r5 + mr r3,r4 + bne __L1 + lil r3,0x1 +__L1: + br + +# traceback table + .long 0x00000000 + .byte 0x00 # VERSION=0 + .byte 0x00 # LANG=TB_C + .byte 0x20 # IS_GL=0,IS_EPROL=0,HAS_TBOFF=1 + # INT_PROC=0,HAS_CTL=0,TOCLESS=0 + # FP_PRESENT=0,LOG_ABORT=0 + .byte 0x40 # INT_HNDL=0,NAME_PRESENT=1 + # USES_ALLOCA=0,CL_DIS_INV=WALK_ONCOND + # SAVES_CR=0,SAVES_LR=0 + .byte 0x80 # STORES_BC=1,FPR_SAVED=0 + .byte 0x00 # GPR_SAVED=0 + .byte 0x02 # FIXEDPARMS=2 + .byte 0x01 # FLOATPARMS=0,PARMSONSTK=1 + .long 0x00000000 # + .long 0x00000014 # TB_OFFSET + .short 7 # NAME_LEN + .byte "longjmp" + .byte 0 # padding + .byte 0 # padding + .byte 0 # padding +# End of traceback table + .long 0x00000000 # "\0\0\0\0" + +# .data section + + .toc # 0x00000038 +T.18.longjmp: + .tc H.18.longjmp{TC},longjmp{DS} + + .csect longjmp{DS} + .long .longjmp # "\0\0\0\0" + .long TOC{TC0} # "\0\0\0008" + .long 0x00000000 # "\0\0\0\0" +# End csect longjmp{DS} + +# .bss section diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_BSD_386_2.s nspr-4.10.7/nspr/pr/src/md/unix/os_BSD_386_2.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_BSD_386_2.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_BSD_386_2.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * os_BSD_386_2.s + * We need to define our own setjmp/longjmp on BSDI 2.x because libc's + * implementation does some sanity checking that defeats user level threads. + * This should no longer be necessary in BSDI 3.0. + */ + +.globl _setjmp +.align 2 +_setjmp: + movl 4(%esp),%eax + movl 0(%esp),%edx + movl %edx, 0(%eax) /* rta */ + movl %ebx, 4(%eax) + movl %esp, 8(%eax) + movl %ebp,12(%eax) + movl %esi,16(%eax) + movl %edi,20(%eax) + movl $0,%eax + ret + +.globl _longjmp +.align 2 +_longjmp: + movl 4(%esp),%edx + movl 8(%esp),%eax + movl 0(%edx),%ecx + movl 4(%edx),%ebx + movl 8(%edx),%esp + movl 12(%edx),%ebp + movl 16(%edx),%esi + movl 20(%edx),%edi + cmpl $0,%eax + jne 1f + movl $1,%eax +1: movl %ecx,0(%esp) + ret diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Darwin_ppc.s nspr-4.10.7/nspr/pr/src/md/unix/os_Darwin_ppc.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Darwin_ppc.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Darwin_ppc.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,68 @@ +# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# +# Based on the programming examples in The PowerPC Architecture: +# A Specification for A New Family of RISC Processors, 2nd Ed., +# Book I, Section E.1, "Synchronization," pp. 249-256, May 1994. +# + +.text + +# +# PRInt32 __PR_DarwinPPC_AtomicIncrement(PRInt32 *val); +# + .align 2 + .globl __PR_DarwinPPC_AtomicIncrement + .private_extern __PR_DarwinPPC_AtomicIncrement +__PR_DarwinPPC_AtomicIncrement: + lwarx r4,0,r3 + addi r0,r4,1 + stwcx. r0,0,r3 + bne- __PR_DarwinPPC_AtomicIncrement + mr r3,r0 + blr + +# +# PRInt32 __PR_DarwinPPC_AtomicDecrement(PRInt32 *val); +# + .align 2 + .globl __PR_DarwinPPC_AtomicDecrement + .private_extern __PR_DarwinPPC_AtomicDecrement +__PR_DarwinPPC_AtomicDecrement: + lwarx r4,0,r3 + addi r0,r4,-1 + stwcx. r0,0,r3 + bne- __PR_DarwinPPC_AtomicDecrement + mr r3,r0 + blr + +# +# PRInt32 __PR_DarwinPPC_AtomicSet(PRInt32 *val, PRInt32 newval); +# + .align 2 + .globl __PR_DarwinPPC_AtomicSet + .private_extern __PR_DarwinPPC_AtomicSet +__PR_DarwinPPC_AtomicSet: + lwarx r5,0,r3 + stwcx. r4,0,r3 + bne- __PR_DarwinPPC_AtomicSet + mr r3,r5 + blr + +# +# PRInt32 __PR_DarwinPPC_AtomicAdd(PRInt32 *ptr, PRInt32 val); +# + .align 2 + .globl __PR_DarwinPPC_AtomicAdd + .private_extern __PR_DarwinPPC_AtomicAdd +__PR_DarwinPPC_AtomicAdd: + lwarx r5,0,r3 + add r0,r4,r5 + stwcx. r0,0,r3 + bne- __PR_DarwinPPC_AtomicAdd + mr r3,r0 + blr diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Darwin.s nspr-4.10.7/nspr/pr/src/md/unix/os_Darwin.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Darwin.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Darwin.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,13 @@ +# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifdef __i386__ +#include "os_Darwin_x86.s" +#elif defined(__x86_64__) +#include "os_Darwin_x86_64.s" +#elif defined(__ppc__) +#include "os_Darwin_ppc.s" +#endif diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Darwin_x86_64.s nspr-4.10.7/nspr/pr/src/md/unix/os_Darwin_x86_64.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Darwin_x86_64.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Darwin_x86_64.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,67 @@ +# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# PRInt32 __PR_Darwin_x86_64_AtomicIncrement(PRInt32 *val) +# +# Atomically increment the integer pointed to by 'val' and return +# the result of the increment. +# + .text + .globl __PR_Darwin_x86_64_AtomicIncrement + .private_extern __PR_Darwin_x86_64_AtomicIncrement + .align 4 +__PR_Darwin_x86_64_AtomicIncrement: + movl $1, %eax + lock + xaddl %eax, (%rdi) + incl %eax + ret + +# PRInt32 __PR_Darwin_x86_64_AtomicDecrement(PRInt32 *val) +# +# Atomically decrement the integer pointed to by 'val' and return +# the result of the decrement. +# + .text + .globl __PR_Darwin_x86_64_AtomicDecrement + .private_extern __PR_Darwin_x86_64_AtomicDecrement + .align 4 +__PR_Darwin_x86_64_AtomicDecrement: + movl $-1, %eax + lock + xaddl %eax, (%rdi) + decl %eax + ret + +# PRInt32 __PR_Darwin_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval) +# +# Atomically set the integer pointed to by 'val' to the new +# value 'newval' and return the old value. +# + .text + .globl __PR_Darwin_x86_64_AtomicSet + .private_extern __PR_Darwin_x86_64_AtomicSet + .align 4 +__PR_Darwin_x86_64_AtomicSet: + movl %esi, %eax + xchgl %eax, (%rdi) + ret + +# PRInt32 __PR_Darwin_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val) +# +# Atomically add 'val' to the integer pointed to by 'ptr' +# and return the result of the addition. +# + .text + .globl __PR_Darwin_x86_64_AtomicAdd + .private_extern __PR_Darwin_x86_64_AtomicAdd + .align 4 +__PR_Darwin_x86_64_AtomicAdd: + movl %esi, %eax + lock + xaddl %eax, (%rdi) + addl %esi, %eax + ret diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Darwin_x86.s nspr-4.10.7/nspr/pr/src/md/unix/os_Darwin_x86.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Darwin_x86.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Darwin_x86.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,80 @@ +# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# +# Based on os_Linux_x86.s +# + +# +# PRInt32 __PR_Darwin_x86_AtomicIncrement(PRInt32 *val); +# +# Atomically increment the integer pointed to by 'val' and return +# the result of the increment. +# + .text + .globl __PR_Darwin_x86_AtomicIncrement + .private_extern __PR_Darwin_x86_AtomicIncrement + .align 4 +__PR_Darwin_x86_AtomicIncrement: + movl 4(%esp), %ecx + movl $1, %eax + lock + xaddl %eax, (%ecx) + incl %eax + ret + +# +# PRInt32 __PR_Darwin_x86_AtomicDecrement(PRInt32 *val); +# +# Atomically decrement the integer pointed to by 'val' and return +# the result of the decrement. +# + .text + .globl __PR_Darwin_x86_AtomicDecrement + .private_extern __PR_Darwin_x86_AtomicDecrement + .align 4 +__PR_Darwin_x86_AtomicDecrement: + movl 4(%esp), %ecx + movl $-1, %eax + lock + xaddl %eax, (%ecx) + decl %eax + ret + +# +# PRInt32 __PR_Darwin_x86_AtomicSet(PRInt32 *val, PRInt32 newval); +# +# Atomically set the integer pointed to by 'val' to the new +# value 'newval' and return the old value. +# + .text + .globl __PR_Darwin_x86_AtomicSet + .private_extern __PR_Darwin_x86_AtomicSet + .align 4 +__PR_Darwin_x86_AtomicSet: + movl 4(%esp), %ecx + movl 8(%esp), %eax + xchgl %eax, (%ecx) + ret + +# +# PRInt32 __PR_Darwin_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val); +# +# Atomically add 'val' to the integer pointed to by 'ptr' +# and return the result of the addition. +# + .text + .globl __PR_Darwin_x86_AtomicAdd + .private_extern __PR_Darwin_x86_AtomicAdd + .align 4 +__PR_Darwin_x86_AtomicAdd: + movl 4(%esp), %ecx + movl 8(%esp), %eax + movl %eax, %edx + lock + xaddl %eax, (%ecx) + addl %edx, %eax + ret diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/osf1.c nspr-4.10.7/nspr/pr/src/md/unix/osf1.c --- nspr-4.9.5/nspr/pr/src/md/unix/osf1.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/osf1.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifndef _PR_PTHREADS +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for OSF1 */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for OSF1."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OSF1."); + return PR_FAILURE; +} +#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_HPUX_ia64.s nspr-4.10.7/nspr/pr/src/md/unix/os_HPUX_ia64.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_HPUX_ia64.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_HPUX_ia64.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,80 @@ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +.text + +// PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// + .align 16 + .global _PR_ia64_AtomicIncrement# + .proc _PR_ia64_AtomicIncrement# +_PR_ia64_AtomicIncrement: +#ifndef _LP64 + addp4 r32 = 0, r32 ;; +#endif + fetchadd4.acq r8 = [r32], 1 ;; + adds r8 = 1, r8 + br.ret.sptk.many b0 + .endp _PR_ia64_AtomicIncrement# + +// PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// + .align 16 + .global _PR_ia64_AtomicDecrement# + .proc _PR_ia64_AtomicDecrement# +_PR_ia64_AtomicDecrement: +#ifndef _LP64 + addp4 r32 = 0, r32 ;; +#endif + fetchadd4.rel r8 = [r32], -1 ;; + adds r8 = -1, r8 + br.ret.sptk.many b0 + .endp _PR_ia64_AtomicDecrement# + +// PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// + .align 16 + .global _PR_ia64_AtomicAdd# + .proc _PR_ia64_AtomicAdd# +_PR_ia64_AtomicAdd: +#ifndef _LP64 + addp4 r32 = 0, r32 ;; +#endif + ld4 r15 = [r32] ;; +.L3: + mov r14 = r15 + mov ar.ccv = r15 + add r8 = r15, r33 ;; + cmpxchg4.acq r15 = [r32], r8, ar.ccv ;; + cmp4.ne p6, p7 = r15, r14 + (p6) br.cond.dptk .L3 + br.ret.sptk.many b0 + .endp _PR_ia64_AtomicAdd# + +// PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// + .align 16 + .global _PR_ia64_AtomicSet# + .proc _PR_ia64_AtomicSet# +_PR_ia64_AtomicSet: +#ifndef _LP64 + addp4 r32 = 0, r32 ;; +#endif + xchg4 r8 = [r32], r33 + br.ret.sptk.many b0 + .endp _PR_ia64_AtomicSet# diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_HPUX.s nspr-4.10.7/nspr/pr/src/md/unix/os_HPUX.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_HPUX.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_HPUX.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,25 @@ +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifdef __LP64__ + .LEVEL 2.0W +#else + .LEVEL 1.1 +#endif + + .CODE ; equivalent to the following two lines +; .SPACE $TEXT$,SORT=8 +; .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24 + +ret_cr16 + .PROC + .CALLINFO FRAME=0, NO_CALLS + .EXPORT ret_cr16,ENTRY + .ENTRY + BV %r0(%rp) + .EXIT + MFCTL %cr16,%ret0 + .PROCEND + .END diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Irix.s nspr-4.10.7/nspr/pr/src/md/unix/os_Irix.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Irix.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Irix.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Atomically add a new element to the top of the stack + * + * usage : PR_StackPush(listp, elementp); + * ----------------------- + */ + +#include "md/_irix.h" +#ifdef _PR_HAVE_ATOMIC_CAS + +#include +#include + +LEAF(PR_StackPush) + +retry_push: +.set noreorder + lw v0,0(a0) + li t1,1 + beq v0,t1,retry_push + move t0,a1 + + ll v0,0(a0) + beq v0,t1,retry_push + nop + sc t1,0(a0) + beq t1,0,retry_push + nop + sw v0,0(a1) + sync + sw t0,0(a0) + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + jr ra + nop + +END(PR_StackPush) + +/* + * + * Atomically remove the element at the top of the stack + * + * usage : elemep = PR_StackPop(listp); + * + */ + +LEAF(PR_StackPop) +retry_pop: +.set noreorder + + + lw v0,0(a0) + li t1,1 + beq v0,0,done + nop + beq v0,t1,retry_pop + nop + + ll v0,0(a0) + beq v0,0,done + nop + beq v0,t1,retry_pop + nop + sc t1,0(a0) + beq t1,0,retry_pop + nop + lw t0,0(v0) + sw t0,0(a0) +done: + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + jr ra + nop + +END(PR_StackPop) + +#endif /* _PR_HAVE_ATOMIC_CAS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Linux_ia64.s nspr-4.10.7/nspr/pr/src/md/unix/os_Linux_ia64.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Linux_ia64.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Linux_ia64.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,71 @@ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +.text + +// PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// + .align 16 + .global _PR_ia64_AtomicIncrement# + .proc _PR_ia64_AtomicIncrement# +_PR_ia64_AtomicIncrement: + fetchadd4.acq r8 = [r32], 1 ;; + adds r8 = 1, r8 + br.ret.sptk.many b0 + .endp _PR_ia64_AtomicIncrement# + +// PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// + .align 16 + .global _PR_ia64_AtomicDecrement# + .proc _PR_ia64_AtomicDecrement# +_PR_ia64_AtomicDecrement: + fetchadd4.rel r8 = [r32], -1 ;; + adds r8 = -1, r8 + br.ret.sptk.many b0 + .endp _PR_ia64_AtomicDecrement# + +// PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// + .align 16 + .global _PR_ia64_AtomicAdd# + .proc _PR_ia64_AtomicAdd# +_PR_ia64_AtomicAdd: + ld4 r15 = [r32] ;; +.L3: + mov r14 = r15 + mov ar.ccv = r15 + add r8 = r15, r33 ;; + cmpxchg4.acq r15 = [r32], r8, ar.ccv ;; + cmp4.ne p6, p7 = r15, r14 + (p6) br.cond.dptk .L3 + br.ret.sptk.many b0 + .endp _PR_ia64_AtomicAdd# + +// PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// + .align 16 + .global _PR_ia64_AtomicSet# + .proc _PR_ia64_AtomicSet# +_PR_ia64_AtomicSet: + xchg4 r8 = [r32], r33 + br.ret.sptk.many b0 + .endp _PR_ia64_AtomicSet# + +// Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits ; .previous diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Linux_ppc.s nspr-4.10.7/nspr/pr/src/md/unix/os_Linux_ppc.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Linux_ppc.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Linux_ppc.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,75 @@ +# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# +# Based on the programming examples in The PowerPC Architecture: +# A Specification for A New Family of RISC Processors, 2nd Ed., +# Book I, Section E.1, "Synchronization," pp. 249-256, May 1994. +# + + .section ".text" + +# +# PRInt32 _PR_ppc_AtomicIncrement(PRInt32 *val); +# + .align 2 + .globl _PR_ppc_AtomicIncrement + .type _PR_ppc_AtomicIncrement,@function +_PR_ppc_AtomicIncrement: +.Lfd1: lwarx 4,0,3 + addi 0,4,1 + stwcx. 0,0,3 + bne- .Lfd1 + mr 3,0 + blr +.Lfe1: .size _PR_ppc_AtomicIncrement,.Lfe1-_PR_ppc_AtomicIncrement + +# +# PRInt32 _PR_ppc_AtomicDecrement(PRInt32 *val); +# + .align 2 + .globl _PR_ppc_AtomicDecrement + .type _PR_ppc_AtomicDecrement,@function +_PR_ppc_AtomicDecrement: +.Lfd2: lwarx 4,0,3 + addi 0,4,-1 + stwcx. 0,0,3 + bne- .Lfd2 + mr 3,0 + blr +.Lfe2: .size _PR_ppc_AtomicDecrement,.Lfe2-_PR_ppc_AtomicDecrement + +# +# PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval); +# + .align 2 + .globl _PR_ppc_AtomicSet + .type _PR_ppc_AtomicSet,@function +_PR_ppc_AtomicSet: +.Lfd3: lwarx 5,0,3 + stwcx. 4,0,3 + bne- .Lfd3 + mr 3,5 + blr +.Lfe3: .size _PR_ppc_AtomicSet,.Lfe3-_PR_ppc_AtomicSet + +# +# PRInt32 _PR_ppc_AtomicAdd(PRInt32 *ptr, PRInt32 val); +# + .align 2 + .globl _PR_ppc_AtomicAdd + .type _PR_ppc_AtomicAdd,@function +_PR_ppc_AtomicAdd: +.Lfd4: lwarx 5,0,3 + add 0,4,5 + stwcx. 0,0,3 + bne- .Lfd4 + mr 3,0 + blr +.Lfe4: .size _PR_ppc_AtomicAdd,.Lfe4-_PR_ppc_AtomicAdd + +# Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits ; .previous diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Linux_x86_64.s nspr-4.10.7/nspr/pr/src/md/unix/os_Linux_x86_64.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Linux_x86_64.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Linux_x86_64.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,74 @@ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// + .text + .globl _PR_x86_64_AtomicIncrement + .type _PR_x86_64_AtomicIncrement, @function + .align 4 +_PR_x86_64_AtomicIncrement: + movl $1, %eax + lock + xaddl %eax, (%rdi) + incl %eax + ret + .size _PR_x86_64_AtomicIncrement, .-_PR_x86_64_AtomicIncrement + +// PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// + .text + .globl _PR_x86_64_AtomicDecrement + .type _PR_x86_64_AtomicDecrement, @function + .align 4 +_PR_x86_64_AtomicDecrement: + movl $-1, %eax + lock + xaddl %eax, (%rdi) + decl %eax + ret + .size _PR_x86_64_AtomicDecrement, .-_PR_x86_64_AtomicDecrement + +// PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// + .text + .globl _PR_x86_64_AtomicSet + .type _PR_x86_64_AtomicSet, @function + .align 4 +_PR_x86_64_AtomicSet: + movl %esi, %eax + xchgl %eax, (%rdi) + ret + .size _PR_x86_64_AtomicSet, .-_PR_x86_64_AtomicSet + +// PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// + .text + .globl _PR_x86_64_AtomicAdd + .type _PR_x86_64_AtomicAdd, @function + .align 4 +_PR_x86_64_AtomicAdd: + movl %esi, %eax + lock + xaddl %eax, (%rdi) + addl %esi, %eax + ret + .size _PR_x86_64_AtomicAdd, .-_PR_x86_64_AtomicAdd + +// Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits ; .previous diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_Linux_x86.s nspr-4.10.7/nspr/pr/src/md/unix/os_Linux_x86.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_Linux_x86.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_Linux_x86.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,85 @@ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// + .text + .globl _PR_x86_AtomicIncrement + .align 4 +_PR_x86_AtomicIncrement: + movl 4(%esp), %ecx + movl $1, %eax + lock + xaddl %eax, (%ecx) + incl %eax + ret + +// PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// + .text + .globl _PR_x86_AtomicDecrement + .align 4 +_PR_x86_AtomicDecrement: + movl 4(%esp), %ecx + movl $-1, %eax + lock + xaddl %eax, (%ecx) + decl %eax + ret + +// PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// +// An alternative implementation: +// .text +// .globl _PR_x86_AtomicSet +// .align 4 +//_PR_x86_AtomicSet: +// movl 4(%esp), %ecx +// movl 8(%esp), %edx +// movl (%ecx), %eax +//retry: +// lock +// cmpxchgl %edx, (%ecx) +// jne retry +// ret +// + .text + .globl _PR_x86_AtomicSet + .align 4 +_PR_x86_AtomicSet: + movl 4(%esp), %ecx + movl 8(%esp), %eax + xchgl %eax, (%ecx) + ret + +// PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// + .text + .globl _PR_x86_AtomicAdd + .align 4 +_PR_x86_AtomicAdd: + movl 4(%esp), %ecx + movl 8(%esp), %eax + movl %eax, %edx + lock + xaddl %eax, (%ecx) + addl %edx, %eax + ret + +// Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits ; .previous diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_SunOS_sparcv9.s nspr-4.10.7/nspr/pr/src/md/unix/os_SunOS_sparcv9.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_SunOS_sparcv9.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_SunOS_sparcv9.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,173 @@ +! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +! +! This Source Code Form is subject to the terms of the Mozilla Public +! License, v. 2.0. If a copy of the MPL was not distributed with this +! file, You can obtain one at http://mozilla.org/MPL/2.0/. + +! +! atomic increment, decrement and swap routines for V8+ sparc (ultrasparc) +! using CAS (compare-and-swap) atomic instructions +! +! this MUST be compiled with an ultrasparc-aware assembler +! +! standard asm linkage macros; this module must be compiled +! with the -P option (use C preprocessor) + +#include + +! ====================================================================== +! +! Perform the sequence a = a + 1 atomically with respect to other +! fetch-and-adds to location a in a wait-free fashion. +! +! usage : val = PR_AtomicIncrement(address) +! return: current value (you'd think this would be old val) +! +! ----------------------- +! Note on REGISTER USAGE: +! as this is a LEAF procedure, a new stack frame is not created; +! we use the caller's stack frame so what would normally be %i (input) +! registers are actually %o (output registers). Also, we must not +! overwrite the contents of %l (local) registers as they are not +! assumed to be volatile during calls. +! +! So, the registers used are: +! %o0 [input] - the address of the value to increment +! %o1 [local] - work register +! %o2 [local] - work register +! %o3 [local] - work register +! ----------------------- + + ENTRY(_MD_AtomicIncrement) ! standard assembler/ELF prologue + +retryAI: + ld [%o0], %o2 ! set o2 to the current value + add %o2, 0x1, %o3 ! calc the new value + mov %o3, %o1 ! save the return value + cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed + cmp %o2, %o3 ! see if we set the value + bne retryAI ! if not, try again + nop ! empty out the branch pipeline + retl ! return back to the caller + mov %o1, %o0 ! set the return code to the new value + + SET_SIZE(_MD_AtomicIncrement) ! standard assembler/ELF epilogue + +! +! end +! +! ====================================================================== +! + +! ====================================================================== +! +! Perform the sequence a = a - 1 atomically with respect to other +! fetch-and-decs to location a in a wait-free fashion. +! +! usage : val = PR_AtomicDecrement(address) +! return: current value (you'd think this would be old val) +! +! ----------------------- +! Note on REGISTER USAGE: +! as this is a LEAF procedure, a new stack frame is not created; +! we use the caller's stack frame so what would normally be %i (input) +! registers are actually %o (output registers). Also, we must not +! overwrite the contents of %l (local) registers as they are not +! assumed to be volatile during calls. +! +! So, the registers used are: +! %o0 [input] - the address of the value to increment +! %o1 [local] - work register +! %o2 [local] - work register +! %o3 [local] - work register +! ----------------------- + + ENTRY(_MD_AtomicDecrement) ! standard assembler/ELF prologue + +retryAD: + ld [%o0], %o2 ! set o2 to the current value + sub %o2, 0x1, %o3 ! calc the new value + mov %o3, %o1 ! save the return value + cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed + cmp %o2, %o3 ! see if we set the value + bne retryAD ! if not, try again + nop ! empty out the branch pipeline + retl ! return back to the caller + mov %o1, %o0 ! set the return code to the new value + + SET_SIZE(_MD_AtomicDecrement) ! standard assembler/ELF epilogue + +! +! end +! +! ====================================================================== +! + +! ====================================================================== +! +! Perform the sequence a = b atomically with respect to other +! fetch-and-stores to location a in a wait-free fashion. +! +! usage : old_val = PR_AtomicSet(address, newval) +! +! ----------------------- +! Note on REGISTER USAGE: +! as this is a LEAF procedure, a new stack frame is not created; +! we use the caller's stack frame so what would normally be %i (input) +! registers are actually %o (output registers). Also, we must not +! overwrite the contents of %l (local) registers as they are not +! assumed to be volatile during calls. +! +! So, the registers used are: +! %o0 [input] - the address of the value to increment +! %o1 [input] - the new value to set for [%o0] +! %o2 [local] - work register +! %o3 [local] - work register +! ----------------------- + + ENTRY(_MD_AtomicSet) ! standard assembler/ELF prologue + +retryAS: + ld [%o0], %o2 ! set o2 to the current value + mov %o1, %o3 ! set up the new value + cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed + cmp %o2, %o3 ! see if we set the value + bne retryAS ! if not, try again + nop ! empty out the branch pipeline + retl ! return back to the caller + mov %o3, %o0 ! set the return code to the prev value + + SET_SIZE(_MD_AtomicSet) ! standard assembler/ELF epilogue + +! +! end +! +! ====================================================================== +! + +! ====================================================================== +! +! Perform the sequence a = a + b atomically with respect to other +! fetch-and-adds to location a in a wait-free fashion. +! +! usage : newval = PR_AtomicAdd(address, val) +! return: the value after addition +! + ENTRY(_MD_AtomicAdd) ! standard assembler/ELF prologue + +retryAA: + ld [%o0], %o2 ! set o2 to the current value + add %o2, %o1, %o3 ! calc the new value + mov %o3, %o4 ! save the return value + cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed + cmp %o2, %o3 ! see if we set the value + bne retryAA ! if not, try again + nop ! empty out the branch pipeline + retl ! return back to the caller + mov %o4, %o0 ! set the return code to the new value + + SET_SIZE(_MD_AtomicAdd) ! standard assembler/ELF epilogue + +! +! end +! diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_SunOS_ultrasparc.s nspr-4.10.7/nspr/pr/src/md/unix/os_SunOS_ultrasparc.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_SunOS_ultrasparc.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_SunOS_ultrasparc.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,173 @@ +! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +! +! This Source Code Form is subject to the terms of the Mozilla Public +! License, v. 2.0. If a copy of the MPL was not distributed with this +! file, You can obtain one at http://mozilla.org/MPL/2.0/. + +! +! atomic increment, decrement and swap routines for V8+ sparc (ultrasparc) +! using CAS (compare-and-swap) atomic instructions +! +! this MUST be compiled with an ultrasparc-aware assembler +! +! standard asm linkage macros; this module must be compiled +! with the -P option (use C preprocessor) + +#include + +! ====================================================================== +! +! Perform the sequence a = a + 1 atomically with respect to other +! fetch-and-adds to location a in a wait-free fashion. +! +! usage : val = PR_AtomicIncrement(address) +! return: current value (you'd think this would be old val) +! +! ----------------------- +! Note on REGISTER USAGE: +! as this is a LEAF procedure, a new stack frame is not created; +! we use the caller's stack frame so what would normally be %i (input) +! registers are actually %o (output registers). Also, we must not +! overwrite the contents of %l (local) registers as they are not +! assumed to be volatile during calls. +! +! So, the registers used are: +! %o0 [input] - the address of the value to increment +! %o1 [local] - work register +! %o2 [local] - work register +! %o3 [local] - work register +! ----------------------- + + ENTRY(PR_AtomicIncrement) ! standard assembler/ELF prologue + +retryAI: + ld [%o0], %o2 ! set o2 to the current value + add %o2, 0x1, %o3 ! calc the new value + mov %o3, %o1 ! save the return value + cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed + cmp %o2, %o3 ! see if we set the value + bne retryAI ! if not, try again + nop ! empty out the branch pipeline + retl ! return back to the caller + mov %o1, %o0 ! set the return code to the new value + + SET_SIZE(PR_AtomicIncrement) ! standard assembler/ELF epilogue + +! +! end +! +! ====================================================================== +! + +! ====================================================================== +! +! Perform the sequence a = a - 1 atomically with respect to other +! fetch-and-decs to location a in a wait-free fashion. +! +! usage : val = PR_AtomicDecrement(address) +! return: current value (you'd think this would be old val) +! +! ----------------------- +! Note on REGISTER USAGE: +! as this is a LEAF procedure, a new stack frame is not created; +! we use the caller's stack frame so what would normally be %i (input) +! registers are actually %o (output registers). Also, we must not +! overwrite the contents of %l (local) registers as they are not +! assumed to be volatile during calls. +! +! So, the registers used are: +! %o0 [input] - the address of the value to increment +! %o1 [local] - work register +! %o2 [local] - work register +! %o3 [local] - work register +! ----------------------- + + ENTRY(PR_AtomicDecrement) ! standard assembler/ELF prologue + +retryAD: + ld [%o0], %o2 ! set o2 to the current value + sub %o2, 0x1, %o3 ! calc the new value + mov %o3, %o1 ! save the return value + cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed + cmp %o2, %o3 ! see if we set the value + bne retryAD ! if not, try again + nop ! empty out the branch pipeline + retl ! return back to the caller + mov %o1, %o0 ! set the return code to the new value + + SET_SIZE(PR_AtomicDecrement) ! standard assembler/ELF epilogue + +! +! end +! +! ====================================================================== +! + +! ====================================================================== +! +! Perform the sequence a = b atomically with respect to other +! fetch-and-stores to location a in a wait-free fashion. +! +! usage : old_val = PR_AtomicSet(address, newval) +! +! ----------------------- +! Note on REGISTER USAGE: +! as this is a LEAF procedure, a new stack frame is not created; +! we use the caller's stack frame so what would normally be %i (input) +! registers are actually %o (output registers). Also, we must not +! overwrite the contents of %l (local) registers as they are not +! assumed to be volatile during calls. +! +! So, the registers used are: +! %o0 [input] - the address of the value to increment +! %o1 [input] - the new value to set for [%o0] +! %o2 [local] - work register +! %o3 [local] - work register +! ----------------------- + + ENTRY(PR_AtomicSet) ! standard assembler/ELF prologue + +retryAS: + ld [%o0], %o2 ! set o2 to the current value + mov %o1, %o3 ! set up the new value + cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed + cmp %o2, %o3 ! see if we set the value + bne retryAS ! if not, try again + nop ! empty out the branch pipeline + retl ! return back to the caller + mov %o3, %o0 ! set the return code to the prev value + + SET_SIZE(PR_AtomicSet) ! standard assembler/ELF epilogue + +! +! end +! +! ====================================================================== +! + +! ====================================================================== +! +! Perform the sequence a = a + b atomically with respect to other +! fetch-and-adds to location a in a wait-free fashion. +! +! usage : newval = PR_AtomicAdd(address, val) +! return: the value after addition +! + ENTRY(PR_AtomicAdd) ! standard assembler/ELF prologue + +retryAA: + ld [%o0], %o2 ! set o2 to the current value + add %o2, %o1, %o3 ! calc the new value + mov %o3, %o4 ! save the return value + cas [%o0], %o2, %o3 ! atomically set if o0 hasn't changed + cmp %o2, %o3 ! see if we set the value + bne retryAA ! if not, try again + nop ! empty out the branch pipeline + retl ! return back to the caller + mov %o4, %o0 ! set the return code to the new value + + SET_SIZE(PR_AtomicAdd) ! standard assembler/ELF epilogue + +! +! end +! diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_SunOS_x86_64.s nspr-4.10.7/nspr/pr/src/md/unix/os_SunOS_x86_64.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_SunOS_x86_64.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_SunOS_x86_64.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,63 @@ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// PRInt32 _MD_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// + .text + .globl _MD_AtomicIncrement + .align 4 +_MD_AtomicIncrement: + movl $1, %eax + lock + xaddl %eax, (%rdi) + incl %eax + ret + +// PRInt32 _MD_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// + .text + .globl _MD_AtomicDecrement + .align 4 +_MD_AtomicDecrement: + movl $-1, %eax + lock + xaddl %eax, (%rdi) + decl %eax + ret + +// PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// + .text + .globl _MD_AtomicSet + .align 4 +_MD_AtomicSet: + movl %esi, %eax + xchgl %eax, (%rdi) + ret + +// PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// + .text + .globl _MD_AtomicAdd + .align 4 +_MD_AtomicAdd: + movl %esi, %eax + lock + xaddl %eax, (%rdi) + addl %esi, %eax + ret diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/os_SunOS_x86.s nspr-4.10.7/nspr/pr/src/md/unix/os_SunOS_x86.s --- nspr-4.9.5/nspr/pr/src/md/unix/os_SunOS_x86.s 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/os_SunOS_x86.s 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,126 @@ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + + .text + + .globl getedi +getedi: + movl %edi,%eax + ret + .type getedi,@function + .size getedi,.-getedi + + .globl setedi +setedi: + movl 4(%esp),%edi + ret + .type setedi,@function + .size setedi,.-setedi + + .globl __MD_FlushRegisterWindows + .globl _MD_FlushRegisterWindows + +__MD_FlushRegisterWindows: +_MD_FlushRegisterWindows: + + ret + +// +// sol_getsp() +// +// Return the current sp (for debugging) +// + .globl sol_getsp +sol_getsp: + movl %esp, %eax + ret + +// +// sol_curthread() +// +// Return a unique identifier for the currently active thread. +// + .globl sol_curthread +sol_curthread: + movl %ecx, %eax + ret + +// PRInt32 _MD_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// + .text + .globl _MD_AtomicIncrement + .align 4 +_MD_AtomicIncrement: + movl 4(%esp), %ecx + movl $1, %eax + lock + xaddl %eax, (%ecx) + incl %eax + ret + +// PRInt32 _MD_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// + .text + .globl _MD_AtomicDecrement + .align 4 +_MD_AtomicDecrement: + movl 4(%esp), %ecx + movl $-1, %eax + lock + xaddl %eax, (%ecx) + decl %eax + ret + +// PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// +// An alternative implementation: +// .text +// .globl _MD_AtomicSet +// .align 4 +//_MD_AtomicSet: +// movl 4(%esp), %ecx +// movl 8(%esp), %edx +// movl (%ecx), %eax +//retry: +// lock +// cmpxchgl %edx, (%ecx) +// jne retry +// ret +// + .text + .globl _MD_AtomicSet + .align 4 +_MD_AtomicSet: + movl 4(%esp), %ecx + movl 8(%esp), %eax + xchgl %eax, (%ecx) + ret + +// PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// + .text + .globl _MD_AtomicAdd + .align 4 +_MD_AtomicAdd: + movl 4(%esp), %ecx + movl 8(%esp), %eax + movl %eax, %edx + lock + xaddl %eax, (%ecx) + addl %edx, %eax + ret diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/pthreads_user.c nspr-4.10.7/nspr/pr/src/md/unix/pthreads_user.c --- nspr-4.9.5/nspr/pr/src/md/unix/pthreads_user.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/pthreads_user.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,448 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include +#include +#include +#include + + +sigset_t ints_off; +pthread_mutex_t _pr_heapLock; +pthread_key_t current_thread_key; +pthread_key_t current_cpu_key; +pthread_key_t last_thread_key; +pthread_key_t intsoff_key; + + +PRInt32 _pr_md_pthreads_created, _pr_md_pthreads_failed; +PRInt32 _pr_md_pthreads = 1; + +void _MD_EarlyInit(void) +{ +extern PRInt32 _nspr_noclock; + + if (pthread_key_create(¤t_thread_key, NULL) != 0) { + perror("pthread_key_create failed"); + exit(1); + } + if (pthread_key_create(¤t_cpu_key, NULL) != 0) { + perror("pthread_key_create failed"); + exit(1); + } + if (pthread_key_create(&last_thread_key, NULL) != 0) { + perror("pthread_key_create failed"); + exit(1); + } + if (pthread_key_create(&intsoff_key, NULL) != 0) { + perror("pthread_key_create failed"); + exit(1); + } + + sigemptyset(&ints_off); + sigaddset(&ints_off, SIGALRM); + sigaddset(&ints_off, SIGIO); + sigaddset(&ints_off, SIGCLD); + + /* + * disable clock interrupts + */ + _nspr_noclock = 1; + +} + +void _MD_InitLocks() +{ + if (pthread_mutex_init(&_pr_heapLock, NULL) != 0) { + perror("pthread_mutex_init failed"); + exit(1); + } +} + +PR_IMPLEMENT(void) _MD_FREE_LOCK(struct _MDLock *lockp) +{ + PRIntn _is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(_is); + pthread_mutex_destroy(&lockp->mutex); + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(_is); +} + + + +PR_IMPLEMENT(PRStatus) _MD_NEW_LOCK(struct _MDLock *lockp) +{ + PRStatus rv; + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + rv = pthread_mutex_init(&lockp->mutex, NULL); + if (me && !_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return (rv == 0) ? PR_SUCCESS : PR_FAILURE; +} + + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +} + +PR_IMPLEMENT(void) +_MD_SetPriority(_MDThread *thread, PRThreadPriority newPri) +{ + /* + * XXX - to be implemented + */ + return; +} + +PR_IMPLEMENT(PRStatus) _MD_InitThread(struct PRThread *thread) +{ + struct sigaction sigact; + + if (thread->flags & _PR_GLOBAL_SCOPE) { + thread->md.pthread = pthread_self(); +#if 0 + /* + * set up SIGUSR1 handler; this is used to save state + * during PR_SuspendAll + */ + sigact.sa_handler = save_context_and_block; + sigact.sa_flags = SA_RESTART; + /* + * Must mask clock interrupts + */ + sigact.sa_mask = timer_set; + sigaction(SIGUSR1, &sigact, 0); +#endif + } + + return PR_SUCCESS; +} + +PR_IMPLEMENT(void) _MD_ExitThread(struct PRThread *thread) +{ + if (thread->flags & _PR_GLOBAL_SCOPE) { + _MD_CLEAN_THREAD(thread); + _MD_SET_CURRENT_THREAD(NULL); + } +} + +PR_IMPLEMENT(void) _MD_CleanThread(struct PRThread *thread) +{ + if (thread->flags & _PR_GLOBAL_SCOPE) { + pthread_mutex_destroy(&thread->md.pthread_mutex); + pthread_cond_destroy(&thread->md.pthread_cond); + } +} + +PR_IMPLEMENT(void) _MD_SuspendThread(struct PRThread *thread) +{ + PRInt32 rv; + + PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) && + _PR_IS_GCABLE_THREAD(thread)); +#if 0 + thread->md.suspending_id = getpid(); + rv = kill(thread->md.id, SIGUSR1); + PR_ASSERT(rv == 0); + /* + * now, block the current thread/cpu until woken up by the suspended + * thread from it's SIGUSR1 signal handler + */ + blockproc(getpid()); +#endif +} + +PR_IMPLEMENT(void) _MD_ResumeThread(struct PRThread *thread) +{ + PRInt32 rv; + + PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) && + _PR_IS_GCABLE_THREAD(thread)); +#if 0 + rv = unblockproc(thread->md.id); +#endif +} + +PR_IMPLEMENT(void) _MD_SuspendCPU(struct _PRCPU *thread) +{ + PRInt32 rv; + +#if 0 + cpu->md.suspending_id = getpid(); + rv = kill(cpu->md.id, SIGUSR1); + PR_ASSERT(rv == 0); + /* + * now, block the current thread/cpu until woken up by the suspended + * thread from it's SIGUSR1 signal handler + */ + blockproc(getpid()); +#endif +} + +PR_IMPLEMENT(void) _MD_ResumeCPU(struct _PRCPU *thread) +{ +#if 0 + unblockproc(cpu->md.id); +#endif +} + + +#define PT_NANOPERMICRO 1000UL +#define PT_BILLION 1000000000UL + +PR_IMPLEMENT(PRStatus) +_pt_wait(PRThread *thread, PRIntervalTime timeout) +{ +int rv; +struct timeval now; +struct timespec tmo; +PRUint32 ticks = PR_TicksPerSecond(); + + + if (timeout != PR_INTERVAL_NO_TIMEOUT) { + tmo.tv_sec = timeout / ticks; + tmo.tv_nsec = timeout - (tmo.tv_sec * ticks); + tmo.tv_nsec = PR_IntervalToMicroseconds(PT_NANOPERMICRO * + tmo.tv_nsec); + + /* pthreads wants this in absolute time, off we go ... */ + (void)GETTIMEOFDAY(&now); + /* that one's usecs, this one's nsecs - grrrr! */ + tmo.tv_sec += now.tv_sec; + tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec); + tmo.tv_sec += tmo.tv_nsec / PT_BILLION; + tmo.tv_nsec %= PT_BILLION; + } + + pthread_mutex_lock(&thread->md.pthread_mutex); + thread->md.wait--; + if (thread->md.wait < 0) { + if (timeout != PR_INTERVAL_NO_TIMEOUT) { + rv = pthread_cond_timedwait(&thread->md.pthread_cond, + &thread->md.pthread_mutex, &tmo); + } + else + rv = pthread_cond_wait(&thread->md.pthread_cond, + &thread->md.pthread_mutex); + if (rv != 0) { + thread->md.wait++; + } + } else + rv = 0; + pthread_mutex_unlock(&thread->md.pthread_mutex); + + return (rv == 0) ? PR_SUCCESS : PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) +_MD_wait(PRThread *thread, PRIntervalTime ticks) +{ + if ( thread->flags & _PR_GLOBAL_SCOPE ) { + _MD_CHECK_FOR_EXIT(); + if (_pt_wait(thread, ticks) == PR_FAILURE) { + _MD_CHECK_FOR_EXIT(); + /* + * wait timed out + */ + _PR_THREAD_LOCK(thread); + if (thread->wait.cvar) { + /* + * The thread will remove itself from the waitQ + * of the cvar in _PR_WaitCondVar + */ + thread->wait.cvar = NULL; + thread->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(thread); + } else { + _pt_wait(thread, PR_INTERVAL_NO_TIMEOUT); + _PR_THREAD_UNLOCK(thread); + } + } + } else { + _PR_MD_SWITCH_CONTEXT(thread); + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) +_MD_WakeupWaiter(PRThread *thread) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 pid, rv; + PRIntn is; + + PR_ASSERT(_pr_md_idle_cpus >= 0); + if (thread == NULL) { + if (_pr_md_idle_cpus) + _MD_Wakeup_CPUs(); + } else if (!_PR_IS_NATIVE_THREAD(thread)) { + /* + * If the thread is on my cpu's runq there is no need to + * wakeup any cpus + */ + if (!_PR_IS_NATIVE_THREAD(me)) { + if (me->cpu != thread->cpu) { + if (_pr_md_idle_cpus) + _MD_Wakeup_CPUs(); + } + } else { + if (_pr_md_idle_cpus) + _MD_Wakeup_CPUs(); + } + } else { + PR_ASSERT(_PR_IS_NATIVE_THREAD(thread)); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + + pthread_mutex_lock(&thread->md.pthread_mutex); + thread->md.wait++; + rv = pthread_cond_signal(&thread->md.pthread_cond); + PR_ASSERT(rv == 0); + pthread_mutex_unlock(&thread->md.pthread_mutex); + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + } + return PR_SUCCESS; +} + +/* These functions should not be called for AIX */ +PR_IMPLEMENT(void) +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for AIX."); +} + +PR_IMPLEMENT(PRStatus) +_MD_CreateThread( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PRIntn is; + int rv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + pthread_attr_t attr; + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + + if (pthread_mutex_init(&thread->md.pthread_mutex, NULL) != 0) { + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return PR_FAILURE; + } + + if (pthread_cond_init(&thread->md.pthread_cond, NULL) != 0) { + pthread_mutex_destroy(&thread->md.pthread_mutex); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return PR_FAILURE; + } + thread->flags |= _PR_GLOBAL_SCOPE; + + pthread_attr_init(&attr); /* initialize attr with default attributes */ + if (pthread_attr_setstacksize(&attr, (size_t) stackSize) != 0) { + pthread_mutex_destroy(&thread->md.pthread_mutex); + pthread_cond_destroy(&thread->md.pthread_cond); + pthread_attr_destroy(&attr); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return PR_FAILURE; + } + + thread->md.wait = 0; + rv = pthread_create(&thread->md.pthread, &attr, start, (void *)thread); + if (0 == rv) { + _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_created); + _MD_ATOMIC_INCREMENT(&_pr_md_pthreads); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return PR_SUCCESS; + } else { + pthread_mutex_destroy(&thread->md.pthread_mutex); + pthread_cond_destroy(&thread->md.pthread_cond); + pthread_attr_destroy(&attr); + _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_failed); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, rv); + return PR_FAILURE; + } +} + +PR_IMPLEMENT(void) +_MD_InitRunningCPU(struct _PRCPU *cpu) +{ + extern int _pr_md_pipefd[2]; + + _MD_unix_init_running_cpu(cpu); + cpu->md.pthread = pthread_self(); + if (_pr_md_pipefd[0] >= 0) { + _PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0]; +#ifndef _PR_USE_POLL + FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu)); +#endif + } +} + + +void +_MD_CleanupBeforeExit(void) +{ +#if 0 + extern PRInt32 _pr_cpus_exit; + + _pr_irix_exit_now = 1; + if (_pr_numCPU > 1) { + /* + * Set a global flag, and wakeup all cpus which will notice the flag + * and exit. + */ + _pr_cpus_exit = getpid(); + _MD_Wakeup_CPUs(); + while(_pr_numCPU > 1) { + _PR_WAIT_SEM(_pr_irix_exit_sem); + _pr_numCPU--; + } + } + /* + * cause global threads on the recycle list to exit + */ + _PR_DEADQ_LOCK; + if (_PR_NUM_DEADNATIVE != 0) { + PRThread *thread; + PRCList *ptr; + + ptr = _PR_DEADNATIVEQ.next; + while( ptr != &_PR_DEADNATIVEQ ) { + thread = _PR_THREAD_PTR(ptr); + _MD_CVAR_POST_SEM(thread); + ptr = ptr->next; + } + } + _PR_DEADQ_UNLOCK; + while(_PR_NUM_DEADNATIVE > 1) { + _PR_WAIT_SEM(_pr_irix_exit_sem); + _PR_DEC_DEADNATIVE; + } +#endif +} diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/qnx.c nspr-4.10.7/nspr/pr/src/md/unix/qnx.c --- nspr-4.9.5/nspr/pr/src/md/unix/qnx.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/qnx.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +} + +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for Unixware */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for Unixware."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRUintn priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware."); + return PR_FAILURE; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/riscos.c nspr-4.10.7/nspr/pr/src/md/unix/riscos.c --- nspr-4.9.5/nspr/pr/src/md/unix/riscos.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/riscos.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#ifndef _PR_PTHREADS + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +#else + *np = 0; + return NULL; +#endif +} + +#ifdef _PR_PTHREADS + +void _MD_CleanupBeforeExit(void) +{ +} + +#else /* ! _PR_PTHREADS */ + +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + /* + * set the pointers to the stack-pointer and frame-pointer words in the + * context structure; this is for debugging use. + */ + thread->md.sp = _MD_GET_SP_PTR(thread); + thread->md.fp = _MD_GET_FP_PTR(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for RISC OS */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for RISC OS."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for RISC OS."); + return PR_FAILURE; +} +#endif /* ! _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/scoos.c nspr-4.10.7/nspr/pr/src/md/unix/scoos.c --- nspr-4.9.5/nspr/pr/src/md/unix/scoos.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/scoos.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * SCO ODT 5.0 - originally created by mikep + */ +#include "primpl.h" + +#include + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +} + +#ifdef ALARMS_BREAK_TCP /* I don't think they do */ + +PRInt32 _MD_connect(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen, + PRIntervalTime timeout) +{ + PRInt32 rv; + + _MD_BLOCK_CLOCK_INTERRUPTS(); + rv = _connect(osfd,addr,addrlen); + _MD_UNBLOCK_CLOCK_INTERRUPTS(); +} + +PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen, + PRIntervalTime timeout) +{ + PRInt32 rv; + + _MD_BLOCK_CLOCK_INTERRUPTS(); + rv = _accept(osfd,addr,addrlen); + _MD_UNBLOCK_CLOCK_INTERRUPTS(); + return(rv); +} +#endif + +/* + * These are also implemented in pratom.c using NSPR locks. Any reason + * this might be better or worse? If you like this better, define + * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h + */ +#ifdef _PR_HAVE_ATOMIC_OPS +/* Atomic operations */ +#include +static FILE *_uw_semf; + +void +_MD_INIT_ATOMIC(void) +{ + /* Sigh. Sure wish SYSV semaphores weren't such a pain to use */ + if ((_uw_semf = tmpfile()) == NULL) + PR_ASSERT(0); + + return; +} + +void +_MD_ATOMIC_INCREMENT(PRInt32 *val) +{ + flockfile(_uw_semf); + (*val)++; + unflockfile(_uw_semf); +} + +void +_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) +{ + flockfile(_uw_semf); + (*ptr) += val; + unflockfile(_uw_semf); +} + +void +_MD_ATOMIC_DECREMENT(PRInt32 *val) +{ + flockfile(_uw_semf); + (*val)--; + unflockfile(_uw_semf); +} + +void +_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) +{ + flockfile(_uw_semf); + *val = newval; + unflockfile(_uw_semf); +} +#endif + +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for SCO */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for SCO."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SCO."); +} diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/solaris.c nspr-4.10.7/nspr/pr/src/md/unix/solaris.c --- nspr-4.9.5/nspr/pr/src/md/unix/solaris.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/solaris.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,161 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + + +extern PRBool suspendAllOn; +extern PRThread *suspendAllThread; + +extern void _MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri); + +PRIntervalTime _MD_Solaris_TicksPerSecond(void) +{ + /* + * Ticks have a 10-microsecond resolution. So there are + * 100000 ticks per second. + */ + return 100000UL; +} + +/* Interval timers, implemented using gethrtime() */ + +PRIntervalTime _MD_Solaris_GetInterval(void) +{ + union { + hrtime_t hrt; /* hrtime_t is a 64-bit (long long) integer */ + PRInt64 pr64; + } time; + PRInt64 resolution; + PRIntervalTime ticks; + + time.hrt = gethrtime(); /* in nanoseconds */ + /* + * Convert from nanoseconds to ticks. A tick's resolution is + * 10 microseconds, or 10000 nanoseconds. + */ + LL_I2L(resolution, 10000); + LL_DIV(time.pr64, time.pr64, resolution); + LL_L2UI(ticks, time.pr64); + return ticks; +} + +#ifdef _PR_PTHREADS +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np) +{ + *np = 0; + return NULL; +} +#endif /* _PR_PTHREADS */ + +#if defined(_PR_LOCAL_THREADS_ONLY) + +void _MD_EarlyInit(void) +{ +} + +void _MD_SolarisInit() +{ + _PR_UnixInit(); +} + +void +_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + PR_ASSERT((thread == NULL) || (!(thread->flags & _PR_GLOBAL_SCOPE))); + return PR_SUCCESS; +} + +/* These functions should not be called for Solaris */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for Solaris"); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Solaris"); + return(PR_FAILURE); +} + +#ifdef USE_SETJMP +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +} +#else +PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np) +{ + if (isCurrent) { + (void) getcontext(CONTEXT(t)); + } + *np = NGREG; + return (PRWord*) &t->md.context.uc_mcontext.gregs[0]; +} +#endif /* USE_SETJMP */ + +#endif /* _PR_LOCAL_THREADS_ONLY */ + +#ifndef _PR_PTHREADS +#if defined(i386) && defined(SOLARIS2_4) +/* + * Because clock_gettime() on Solaris/x86 2.4 always generates a + * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(), + * which is implemented using gettimeofday(). + */ + +int +_pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct timeval tv; + + if (clock_id != CLOCK_REALTIME) { + errno = EINVAL; + return -1; + } + + gettimeofday(&tv, NULL); + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * 1000; + return 0; +} +#endif /* i386 && SOLARIS2_4 */ +#endif /* _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/symbian.c nspr-4.10.7/nspr/pr/src/md/unix/symbian.c --- nspr-4.9.5/nspr/pr/src/md/unix/symbian.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/symbian.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,16 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + *np = 0; + return NULL; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/unix.c nspr-4.10.7/nspr/pr/src/md/unix/unix.c --- nspr-4.9.5/nspr/pr/src/md/unix/unix.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/unix.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,3787 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _PR_POLL_AVAILABLE +#include +#endif + +#if defined(ANDROID) +#include +#endif + +/* To get FIONREAD */ +#if defined(UNIXWARE) +#include +#endif + +#if defined(NTO) +#include +#endif + +/* + * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or + * PRInt32* pointer to a _PRSockLen_t* pointer. + */ +#if defined(HAVE_SOCKLEN_T) \ + || (defined(__GLIBC__) && __GLIBC__ >= 2) +#define _PRSockLen_t socklen_t +#elif defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \ + || defined(AIX4_1) || defined(LINUX) \ + || defined(BSDI) || defined(SCO) \ + || defined(DARWIN) \ + || defined(QNX) +#define _PRSockLen_t int +#elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \ + || defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \ + || defined(DGUX) || defined(NTO) || defined(RISCOS) +#define _PRSockLen_t size_t +#else +#error "Cannot determine architecture" +#endif + +/* +** Global lock variable used to bracket calls into rusty libraries that +** aren't thread safe (like libc, libX, etc). +*/ +static PRLock *_pr_rename_lock = NULL; +static PRMonitor *_pr_Xfe_mon = NULL; + +static PRInt64 minus_one; + +sigset_t timer_set; + +#if !defined(_PR_PTHREADS) + +static sigset_t empty_set; + +#ifdef SOLARIS +#include +#include +#endif + +#ifndef PIPE_BUF +#define PIPE_BUF 512 +#endif + +/* + * _nspr_noclock - if set clock interrupts are disabled + */ +int _nspr_noclock = 1; + +#ifdef IRIX +extern PRInt32 _nspr_terminate_on_error; +#endif + +/* + * There is an assertion in this code that NSPR's definition of PRIOVec + * is bit compatible with UNIX' definition of a struct iovec. This is + * applicable to the 'writev()' operations where the types are casually + * cast to avoid warnings. + */ + +int _pr_md_pipefd[2] = { -1, -1 }; +static char _pr_md_pipebuf[PIPE_BUF]; +static PRInt32 local_io_wait(PRInt32 osfd, PRInt32 wait_flag, + PRIntervalTime timeout); + +_PRInterruptTable _pr_interruptTable[] = { + { + "clock", _PR_MISSED_CLOCK, _PR_ClockInterrupt, }, + { + 0 } +}; + +void _MD_unix_init_running_cpu(_PRCPU *cpu) +{ + PR_INIT_CLIST(&(cpu->md.md_unix.ioQ)); + cpu->md.md_unix.ioq_max_osfd = -1; + cpu->md.md_unix.ioq_timeout = PR_INTERVAL_NO_TIMEOUT; +} + +PRStatus _MD_open_dir(_MDDir *d, const char *name) +{ +int err; + + d->d = opendir(name); + if (!d->d) { + err = _MD_ERRNO(); + _PR_MD_MAP_OPENDIR_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PRInt32 _MD_close_dir(_MDDir *d) +{ +int rv = 0, err; + + if (d->d) { + rv = closedir(d->d); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_CLOSEDIR_ERROR(err); + } + } + return rv; +} + +char * _MD_read_dir(_MDDir *d, PRIntn flags) +{ +struct dirent *de; +int err; + + for (;;) { + /* + * XXX: readdir() is not MT-safe. There is an MT-safe version + * readdir_r() on some systems. + */ + _MD_ERRNO() = 0; + de = readdir(d->d); + if (!de) { + err = _MD_ERRNO(); + _PR_MD_MAP_READDIR_ERROR(err); + return 0; + } + if ((flags & PR_SKIP_DOT) && + (de->d_name[0] == '.') && (de->d_name[1] == 0)) + continue; + if ((flags & PR_SKIP_DOT_DOT) && + (de->d_name[0] == '.') && (de->d_name[1] == '.') && + (de->d_name[2] == 0)) + continue; + if ((flags & PR_SKIP_HIDDEN) && (de->d_name[0] == '.')) + continue; + break; + } + return de->d_name; +} + +PRInt32 _MD_delete(const char *name) +{ +PRInt32 rv, err; +#ifdef UNIXWARE + sigset_t set, oset; +#endif + +#ifdef UNIXWARE + sigfillset(&set); + sigprocmask(SIG_SETMASK, &set, &oset); +#endif + rv = unlink(name); +#ifdef UNIXWARE + sigprocmask(SIG_SETMASK, &oset, NULL); +#endif + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_UNLINK_ERROR(err); + } + return(rv); +} + +PRInt32 _MD_rename(const char *from, const char *to) +{ + PRInt32 rv = -1, err; + + /* + ** This is trying to enforce the semantics of WINDOZE' rename + ** operation. That means one is not allowed to rename over top + ** of an existing file. Holding a lock across these two function + ** and the open function is known to be a bad idea, but .... + */ + if (NULL != _pr_rename_lock) + PR_Lock(_pr_rename_lock); + if (0 == access(to, F_OK)) + PR_SetError(PR_FILE_EXISTS_ERROR, 0); + else + { + rv = rename(from, to); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_RENAME_ERROR(err); + } + } + if (NULL != _pr_rename_lock) + PR_Unlock(_pr_rename_lock); + return rv; +} + +PRInt32 _MD_access(const char *name, PRAccessHow how) +{ +PRInt32 rv, err; +int amode; + + switch (how) { + case PR_ACCESS_WRITE_OK: + amode = W_OK; + break; + case PR_ACCESS_READ_OK: + amode = R_OK; + break; + case PR_ACCESS_EXISTS: + amode = F_OK; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = -1; + goto done; + } + rv = access(name, amode); + + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_ACCESS_ERROR(err); + } + +done: + return(rv); +} + +PRInt32 _MD_mkdir(const char *name, PRIntn mode) +{ +int rv, err; + + /* + ** This lock is used to enforce rename semantics as described + ** in PR_Rename. Look there for more fun details. + */ + if (NULL !=_pr_rename_lock) + PR_Lock(_pr_rename_lock); + rv = mkdir(name, mode); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_MKDIR_ERROR(err); + } + if (NULL !=_pr_rename_lock) + PR_Unlock(_pr_rename_lock); + return rv; +} + +PRInt32 _MD_rmdir(const char *name) +{ +int rv, err; + + rv = rmdir(name); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_RMDIR_ERROR(err); + } + return rv; +} + +PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount) +{ +PRThread *me = _PR_MD_CURRENT_THREAD(); +PRInt32 rv, err; +#ifndef _PR_USE_POLL +fd_set rd; +#else +struct pollfd pfd; +#endif /* _PR_USE_POLL */ +PRInt32 osfd = fd->secret->md.osfd; + +#ifndef _PR_USE_POLL + FD_ZERO(&rd); + FD_SET(osfd, &rd); +#else + pfd.fd = osfd; + pfd.events = POLLIN; +#endif /* _PR_USE_POLL */ + while ((rv = read(osfd,buf,amount)) == -1) { + err = _MD_ERRNO(); + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) { + if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, + PR_INTERVAL_NO_TIMEOUT)) < 0) + goto done; + } else { +#ifndef _PR_USE_POLL + while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL)) + == -1 && (err = _MD_ERRNO()) == EINTR) { + /* retry _MD_SELECT() if it is interrupted */ + } +#else /* _PR_USE_POLL */ + while ((rv = _MD_POLL(&pfd, 1, -1)) + == -1 && (err = _MD_ERRNO()) == EINTR) { + /* retry _MD_POLL() if it is interrupted */ + } +#endif /* _PR_USE_POLL */ + if (rv == -1) { + break; + } + } + if (_PR_PENDING_INTERRUPT(me)) + break; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + _PR_MD_MAP_READ_ERROR(err); + } + } +done: + return(rv); +} + +PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount) +{ +PRThread *me = _PR_MD_CURRENT_THREAD(); +PRInt32 rv, err; +#ifndef _PR_USE_POLL +fd_set wd; +#else +struct pollfd pfd; +#endif /* _PR_USE_POLL */ +PRInt32 osfd = fd->secret->md.osfd; + +#ifndef _PR_USE_POLL + FD_ZERO(&wd); + FD_SET(osfd, &wd); +#else + pfd.fd = osfd; + pfd.events = POLLOUT; +#endif /* _PR_USE_POLL */ + while ((rv = write(osfd,buf,amount)) == -1) { + err = _MD_ERRNO(); + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) { + if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, + PR_INTERVAL_NO_TIMEOUT)) < 0) + goto done; + } else { +#ifndef _PR_USE_POLL + while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL)) + == -1 && (err = _MD_ERRNO()) == EINTR) { + /* retry _MD_SELECT() if it is interrupted */ + } +#else /* _PR_USE_POLL */ + while ((rv = _MD_POLL(&pfd, 1, -1)) + == -1 && (err = _MD_ERRNO()) == EINTR) { + /* retry _MD_POLL() if it is interrupted */ + } +#endif /* _PR_USE_POLL */ + if (rv == -1) { + break; + } + } + if (_PR_PENDING_INTERRUPT(me)) + break; + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + _PR_MD_MAP_WRITE_ERROR(err); + } + } +done: + return(rv); +} + +PRInt32 _MD_fsync(PRFileDesc *fd) +{ +PRInt32 rv, err; + + rv = fsync(fd->secret->md.osfd); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_FSYNC_ERROR(err); + } + return(rv); +} + +PRInt32 _MD_close(PRInt32 osfd) +{ +PRInt32 rv, err; + + rv = close(osfd); + if (rv == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_CLOSE_ERROR(err); + } + return(rv); +} + +PRInt32 _MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto) +{ + PRInt32 osfd, err; + + osfd = socket(domain, type, proto); + + if (osfd == -1) { + err = _MD_ERRNO(); + _PR_MD_MAP_SOCKET_ERROR(err); + return(osfd); + } + + return(osfd); +} + +PRInt32 _MD_socketavailable(PRFileDesc *fd) +{ + PRInt32 result; + + if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) { + _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO()); + return -1; + } + return result; +} + +PRInt64 _MD_socketavailable64(PRFileDesc *fd) +{ + PRInt64 result; + LL_I2L(result, _MD_socketavailable(fd)); + return result; +} /* _MD_socketavailable64 */ + +#define READ_FD 1 +#define WRITE_FD 2 + +/* + * socket_io_wait -- + * + * wait for socket i/o, periodically checking for interrupt + * + * The first implementation uses select(), for platforms without + * poll(). The second (preferred) implementation uses poll(). + */ + +#ifndef _PR_USE_POLL + +static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type, + PRIntervalTime timeout) +{ + PRInt32 rv = -1; + struct timeval tv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRIntervalTime epoch, now, elapsed, remaining; + PRBool wait_for_remaining; + PRInt32 syserror; + fd_set rd_wr; + + switch (timeout) { + case PR_INTERVAL_NO_WAIT: + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + break; + case PR_INTERVAL_NO_TIMEOUT: + /* + * This is a special case of the 'default' case below. + * Please see the comments there. + */ + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; + tv.tv_usec = 0; + FD_ZERO(&rd_wr); + do { + FD_SET(osfd, &rd_wr); + if (fd_type == READ_FD) + rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv); + else + rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv); + if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { + _PR_MD_MAP_SELECT_ERROR(syserror); + break; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + } while (rv == 0 || (rv == -1 && syserror == EINTR)); + break; + default: + now = epoch = PR_IntervalNow(); + remaining = timeout; + FD_ZERO(&rd_wr); + do { + /* + * We block in _MD_SELECT for at most + * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, + * so that there is an upper limit on the delay + * before the interrupt bit is checked. + */ + wait_for_remaining = PR_TRUE; + tv.tv_sec = PR_IntervalToSeconds(remaining); + if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { + wait_for_remaining = PR_FALSE; + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; + tv.tv_usec = 0; + } else { + tv.tv_usec = PR_IntervalToMicroseconds( + remaining - + PR_SecondsToInterval(tv.tv_sec)); + } + FD_SET(osfd, &rd_wr); + if (fd_type == READ_FD) + rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv); + else + rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv); + /* + * we don't consider EINTR a real error + */ + if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { + _PR_MD_MAP_SELECT_ERROR(syserror); + break; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + /* + * We loop again if _MD_SELECT timed out or got interrupted + * by a signal, and the timeout deadline has not passed yet. + */ + if (rv == 0 || (rv == -1 && syserror == EINTR)) { + /* + * If _MD_SELECT timed out, we know how much time + * we spent in blocking, so we can avoid a + * PR_IntervalNow() call. + */ + if (rv == 0) { + if (wait_for_remaining) { + now += remaining; + } else { + now += PR_SecondsToInterval(tv.tv_sec) + + PR_MicrosecondsToInterval(tv.tv_usec); + } + } else { + now = PR_IntervalNow(); + } + elapsed = (PRIntervalTime) (now - epoch); + if (elapsed >= timeout) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + rv = -1; + break; + } else { + remaining = timeout - elapsed; + } + } + } while (rv == 0 || (rv == -1 && syserror == EINTR)); + break; + } + return(rv); +} + +#else /* _PR_USE_POLL */ + +static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type, + PRIntervalTime timeout) +{ + PRInt32 rv = -1; + int msecs; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRIntervalTime epoch, now, elapsed, remaining; + PRBool wait_for_remaining; + PRInt32 syserror; + struct pollfd pfd; + + switch (timeout) { + case PR_INTERVAL_NO_WAIT: + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + break; + case PR_INTERVAL_NO_TIMEOUT: + /* + * This is a special case of the 'default' case below. + * Please see the comments there. + */ + msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; + pfd.fd = osfd; + if (fd_type == READ_FD) { + pfd.events = POLLIN; + } else { + pfd.events = POLLOUT; + } + do { + rv = _MD_POLL(&pfd, 1, msecs); + if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { + _PR_MD_MAP_POLL_ERROR(syserror); + break; + } + /* + * If POLLERR is set, don't process it; retry the operation + */ + if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) { + rv = -1; + _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents); + break; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + } while (rv == 0 || (rv == -1 && syserror == EINTR)); + break; + default: + now = epoch = PR_IntervalNow(); + remaining = timeout; + pfd.fd = osfd; + if (fd_type == READ_FD) { + pfd.events = POLLIN; + } else { + pfd.events = POLLOUT; + } + do { + /* + * We block in _MD_POLL for at most + * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, + * so that there is an upper limit on the delay + * before the interrupt bit is checked. + */ + wait_for_remaining = PR_TRUE; + msecs = PR_IntervalToMilliseconds(remaining); + if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) { + wait_for_remaining = PR_FALSE; + msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; + } + rv = _MD_POLL(&pfd, 1, msecs); + /* + * we don't consider EINTR a real error + */ + if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) { + _PR_MD_MAP_POLL_ERROR(syserror); + break; + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + /* + * If POLLERR is set, don't process it; retry the operation + */ + if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) { + rv = -1; + _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents); + break; + } + /* + * We loop again if _MD_POLL timed out or got interrupted + * by a signal, and the timeout deadline has not passed yet. + */ + if (rv == 0 || (rv == -1 && syserror == EINTR)) { + /* + * If _MD_POLL timed out, we know how much time + * we spent in blocking, so we can avoid a + * PR_IntervalNow() call. + */ + if (rv == 0) { + if (wait_for_remaining) { + now += remaining; + } else { + now += PR_MillisecondsToInterval(msecs); + } + } else { + now = PR_IntervalNow(); + } + elapsed = (PRIntervalTime) (now - epoch); + if (elapsed >= timeout) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + rv = -1; + break; + } else { + remaining = timeout - elapsed; + } + } + } while (rv == 0 || (rv == -1 && syserror == EINTR)); + break; + } + return(rv); +} + +#endif /* _PR_USE_POLL */ + +static PRInt32 local_io_wait( + PRInt32 osfd, + PRInt32 wait_flag, + PRIntervalTime timeout) +{ + _PRUnixPollDesc pd; + PRInt32 rv; + + PR_LOG(_pr_io_lm, PR_LOG_MIN, + ("waiting to %s on osfd=%d", + (wait_flag == _PR_UNIX_POLL_READ) ? "read" : "write", + osfd)); + + if (timeout == PR_INTERVAL_NO_WAIT) return 0; + + pd.osfd = osfd; + pd.in_flags = wait_flag; + pd.out_flags = 0; + + rv = _PR_WaitForMultipleFDs(&pd, 1, timeout); + + if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + rv = -1; + } + return rv; +} + + +PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, + PRInt32 flags, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + +/* + * Many OS's (Solaris, Unixware) have a broken recv which won't read + * from socketpairs. As long as we don't use flags on socketpairs, this + * is a decent fix. - mikep + */ +#if defined(UNIXWARE) || defined(SOLARIS) + while ((rv = read(osfd,buf,amount)) == -1) { +#else + while ((rv = recv(osfd,buf,amount,flags)) == -1) { +#endif + err = _MD_ERRNO(); + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) { + if ((rv = local_io_wait(osfd,_PR_UNIX_POLL_READ,timeout)) < 0) + goto done; + } else { + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + } + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_RECV_ERROR(err); + } +done: + return(rv); +} + +PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, + PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + while ((*addrlen = PR_NETADDR_SIZE(addr)), + ((rv = recvfrom(osfd, buf, amount, flags, + (struct sockaddr *) addr, (_PRSockLen_t *)addrlen)) == -1)) { + err = _MD_ERRNO(); + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) { + if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0) + goto done; + } else { + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + } + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_RECVFROM_ERROR(err); + } +done: +#ifdef _PR_HAVE_SOCKADDR_LEN + if (rv != -1) { + /* ignore the sa_len field of struct sockaddr */ + if (addr) { + addr->raw.family = ((struct sockaddr *) addr)->sa_family; + } + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ + return(rv); +} + +PRInt32 _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount, + PRInt32 flags, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); +#if defined(SOLARIS) + PRInt32 tmp_amount = amount; +#endif + + /* + * On pre-2.6 Solaris, send() is much slower than write(). + * On 2.6 and beyond, with in-kernel sockets, send() and + * write() are fairly equivalent in performance. + */ +#if defined(SOLARIS) + PR_ASSERT(0 == flags); + while ((rv = write(osfd,buf,tmp_amount)) == -1) { +#else + while ((rv = send(osfd,buf,amount,flags)) == -1) { +#endif + err = _MD_ERRNO(); + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) { + if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0) + goto done; + } else { + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0) + goto done; + } + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { +#if defined(SOLARIS) + /* + * The write system call has been reported to return the ERANGE + * error on occasion. Try to write in smaller chunks to workaround + * this bug. + */ + if (err == ERANGE) { + if (tmp_amount > 1) { + tmp_amount = tmp_amount/2; /* half the bytes */ + continue; + } + } +#endif + break; + } + } + /* + * optimization; if bytes sent is less than "amount" call + * select before returning. This is because it is likely that + * the next send() call will return EWOULDBLOCK. + */ + if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) + && (timeout != PR_INTERVAL_NO_WAIT)) { + if (_PR_IS_NATIVE_THREAD(me)) { + if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) { + rv = -1; + goto done; + } + } else { + if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) { + rv = -1; + goto done; + } + } + } + if (rv < 0) { + _PR_MD_MAP_SEND_ERROR(err); + } +done: + return(rv); +} + +PRInt32 _MD_sendto( + PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; + + addrCopy = *addr; + ((struct sockaddr *) &addrCopy)->sa_len = addrlen; + ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; + + while ((rv = sendto(osfd, buf, amount, flags, + (struct sockaddr *) &addrCopy, addrlen)) == -1) { +#else + while ((rv = sendto(osfd, buf, amount, flags, + (struct sockaddr *) addr, addrlen)) == -1) { +#endif + err = _MD_ERRNO(); + if ((err == EAGAIN) || (err == EWOULDBLOCK)) { + if (fd->secret->nonblocking) { + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) { + if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0) + goto done; + } else { + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0) + goto done; + } + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_SENDTO_ERROR(err); + } +done: + return(rv); +} + +PRInt32 _MD_writev( + PRFileDesc *fd, const PRIOVec *iov, + PRInt32 iov_size, PRIntervalTime timeout) +{ + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 index, amount = 0; + PRInt32 osfd = fd->secret->md.osfd; + + /* + * Calculate the total number of bytes to be sent; needed for + * optimization later. + * We could avoid this if this number was passed in; but it is + * probably not a big deal because iov_size is usually small (less than + * 3) + */ + if (!fd->secret->nonblocking) { + for (index=0; indexsecret->nonblocking) { + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) { + if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0) + goto done; + } else { + if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0) + goto done; + } + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + /* + * optimization; if bytes sent is less than "amount" call + * select before returning. This is because it is likely that + * the next writev() call will return EWOULDBLOCK. + */ + if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount) + && (timeout != PR_INTERVAL_NO_WAIT)) { + if (_PR_IS_NATIVE_THREAD(me)) { + if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) { + rv = -1; + goto done; + } + } else { + if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) { + rv = -1; + goto done; + } + } + } + if (rv < 0) { + _PR_MD_MAP_WRITEV_ERROR(err); + } +done: + return(rv); +} + +PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, + PRUint32 *addrlen, PRIntervalTime timeout) +{ + PRInt32 osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + while ((rv = accept(osfd, (struct sockaddr *) addr, + (_PRSockLen_t *)addrlen)) == -1) { + err = _MD_ERRNO(); + if ((err == EAGAIN) || (err == EWOULDBLOCK) || (err == ECONNABORTED)) { + if (fd->secret->nonblocking) { + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) { + if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0) + goto done; + } else { + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + goto done; + } + } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){ + continue; + } else { + break; + } + } + if (rv < 0) { + _PR_MD_MAP_ACCEPT_ERROR(err); + } +done: +#ifdef _PR_HAVE_SOCKADDR_LEN + if (rv != -1) { + /* ignore the sa_len field of struct sockaddr */ + if (addr) { + addr->raw.family = ((struct sockaddr *) addr)->sa_family; + } + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ + return(rv); +} + +extern int _connect (int s, const struct sockaddr *name, int namelen); +PRInt32 _MD_connect( + PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) +{ + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 osfd = fd->secret->md.osfd; +#ifdef IRIX +extern PRInt32 _MD_irix_connect( + PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout); +#endif +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; + + addrCopy = *addr; + ((struct sockaddr *) &addrCopy)->sa_len = addrlen; + ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; +#endif + + /* + * We initiate the connection setup by making a nonblocking connect() + * call. If the connect() call fails, there are two cases we handle + * specially: + * 1. The connect() call was interrupted by a signal. In this case + * we simply retry connect(). + * 2. The NSPR socket is nonblocking and connect() fails with + * EINPROGRESS. We first wait until the socket becomes writable. + * Then we try to find out whether the connection setup succeeded + * or failed. + */ + +retry: +#ifdef IRIX + if ((rv = _MD_irix_connect(osfd, addr, addrlen, timeout)) == -1) { +#else +#ifdef _PR_HAVE_SOCKADDR_LEN + if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) { +#else + if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) { +#endif +#endif + err = _MD_ERRNO(); + + if (err == EINTR) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + goto retry; + } + + if (!fd->secret->nonblocking && (err == EINPROGRESS)) { + if (!_PR_IS_NATIVE_THREAD(me)) { + + if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0) + return -1; + } else { + /* + * socket_io_wait() may return -1 or 1. + */ + + rv = socket_io_wait(osfd, WRITE_FD, timeout); + if (rv == -1) { + return -1; + } + } + + PR_ASSERT(rv == 1); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + err = _MD_unix_get_nonblocking_connect_error(osfd); + if (err != 0) { + _PR_MD_MAP_CONNECT_ERROR(err); + return -1; + } + return 0; + } + + _PR_MD_MAP_CONNECT_ERROR(err); + } + + return rv; +} /* _MD_connect */ + +PRInt32 _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) +{ + PRInt32 rv, err; +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; + + addrCopy = *addr; + ((struct sockaddr *) &addrCopy)->sa_len = addrlen; + ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family; + rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen); +#else + rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen); +#endif + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_BIND_ERROR(err); + } + return(rv); +} + +PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog) +{ + PRInt32 rv, err; + + rv = listen(fd->secret->md.osfd, backlog); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_LISTEN_ERROR(err); + } + return(rv); +} + +PRInt32 _MD_shutdown(PRFileDesc *fd, PRIntn how) +{ + PRInt32 rv, err; + + rv = shutdown(fd->secret->md.osfd, how); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_SHUTDOWN_ERROR(err); + } + return(rv); +} + +PRInt32 _MD_socketpair(int af, int type, int flags, + PRInt32 *osfd) +{ + PRInt32 rv, err; + + rv = socketpair(af, type, flags, osfd); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_SOCKETPAIR_ERROR(err); + } + return rv; +} + +PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, + PRUint32 *addrlen) +{ + PRInt32 rv, err; + + rv = getsockname(fd->secret->md.osfd, + (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); +#ifdef _PR_HAVE_SOCKADDR_LEN + if (rv == 0) { + /* ignore the sa_len field of struct sockaddr */ + if (addr) { + addr->raw.family = ((struct sockaddr *) addr)->sa_family; + } + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_GETSOCKNAME_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, + PRUint32 *addrlen) +{ + PRInt32 rv, err; + + rv = getpeername(fd->secret->md.osfd, + (struct sockaddr *) addr, (_PRSockLen_t *)addrlen); +#ifdef _PR_HAVE_SOCKADDR_LEN + if (rv == 0) { + /* ignore the sa_len field of struct sockaddr */ + if (addr) { + addr->raw.family = ((struct sockaddr *) addr)->sa_family; + } + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_GETPEERNAME_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, + PRInt32 optname, char* optval, PRInt32* optlen) +{ + PRInt32 rv, err; + + rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (_PRSockLen_t *)optlen); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_GETSOCKOPT_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, + PRInt32 optname, const char* optval, PRInt32 optlen) +{ + PRInt32 rv, err; + + rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen); + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_SETSOCKOPT_ERROR(err); + } + return rv==0?PR_SUCCESS:PR_FAILURE; +} + +PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable) +{ + int rv; + + rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC); + if (-1 == rv) { + PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported) +{ + if (imported) { + fd->secret->inheritable = _PR_TRI_UNKNOWN; + } else { + /* By default, a Unix fd is not closed on exec. */ +#ifdef DEBUG + { + int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0); + PR_ASSERT(0 == flags); + } +#endif + fd->secret->inheritable = _PR_TRI_TRUE; + } +} + +/************************************************************************/ +#if !defined(_PR_USE_POLL) + +/* +** Scan through io queue and find any bad fd's that triggered the error +** from _MD_SELECT +*/ +static void FindBadFDs(void) +{ + PRCList *q; + PRThread *me = _MD_CURRENT_THREAD(); + + PR_ASSERT(!_PR_IS_NATIVE_THREAD(me)); + q = (_PR_IOQ(me->cpu)).next; + _PR_IOQ_MAX_OSFD(me->cpu) = -1; + _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT; + while (q != &_PR_IOQ(me->cpu)) { + PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); + PRBool notify = PR_FALSE; + _PRUnixPollDesc *pds = pq->pds; + _PRUnixPollDesc *epds = pds + pq->npds; + PRInt32 pq_max_osfd = -1; + + q = q->next; + for (; pds < epds; pds++) { + PRInt32 osfd = pds->osfd; + pds->out_flags = 0; + PR_ASSERT(osfd >= 0 || pds->in_flags == 0); + if (pds->in_flags == 0) { + continue; /* skip this fd */ + } + if (fcntl(osfd, F_GETFL, 0) == -1) { + /* Found a bad descriptor, remove it from the fd_sets. */ + PR_LOG(_pr_io_lm, PR_LOG_MAX, + ("file descriptor %d is bad", osfd)); + pds->out_flags = _PR_UNIX_POLL_NVAL; + notify = PR_TRUE; + } + if (osfd > pq_max_osfd) { + pq_max_osfd = osfd; + } + } + + if (notify) { + PRIntn pri; + PR_REMOVE_LINK(&pq->links); + pq->on_ioq = PR_FALSE; + + /* + * Decrement the count of descriptors for each desciptor/event + * because this I/O request is being removed from the + * ioq + */ + pds = pq->pds; + for (; pds < epds; pds++) { + PRInt32 osfd = pds->osfd; + PRInt16 in_flags = pds->in_flags; + PR_ASSERT(osfd >= 0 || in_flags == 0); + if (in_flags & _PR_UNIX_POLL_READ) { + if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); + } + if (in_flags & _PR_UNIX_POLL_WRITE) { + if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); + } + if (in_flags & _PR_UNIX_POLL_EXCEPT) { + if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); + } + } + + _PR_THREAD_LOCK(pq->thr); + if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { + _PRCPU *cpu = pq->thr->cpu; + _PR_SLEEPQ_LOCK(pq->thr->cpu); + _PR_DEL_SLEEPQ(pq->thr, PR_TRUE); + _PR_SLEEPQ_UNLOCK(pq->thr->cpu); + + if (pq->thr->flags & _PR_SUSPENDING) { + /* + * set thread state to SUSPENDED; + * a Resume operation on the thread + * will move it to the runQ + */ + pq->thr->state = _PR_SUSPENDED; + _PR_MISCQ_LOCK(pq->thr->cpu); + _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu); + _PR_MISCQ_UNLOCK(pq->thr->cpu); + } else { + pri = pq->thr->priority; + pq->thr->state = _PR_RUNNABLE; + + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(pq->thr, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + } + } + _PR_THREAD_UNLOCK(pq->thr); + } else { + if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu)) + _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout; + if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd) + _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd; + } + } + if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { + if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0]) + _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0]; + } +} +#endif /* !defined(_PR_USE_POLL) */ + +/************************************************************************/ + +/* +** Called by the scheduler when there is nothing to do. This means that +** all threads are blocked on some monitor somewhere. +** +** Note: this code doesn't release the scheduler lock. +*/ +/* +** Pause the current CPU. longjmp to the cpu's pause stack +** +** This must be called with the scheduler locked +*/ +void _MD_PauseCPU(PRIntervalTime ticks) +{ + PRThread *me = _MD_CURRENT_THREAD(); +#ifdef _PR_USE_POLL + int timeout; + struct pollfd *pollfds; /* an array of pollfd structures */ + struct pollfd *pollfdPtr; /* a pointer that steps through the array */ + unsigned long npollfds; /* number of pollfd structures in array */ + unsigned long pollfds_size; + int nfd; /* to hold the return value of poll() */ +#else + struct timeval timeout, *tvp; + fd_set r, w, e; + fd_set *rp, *wp, *ep; + PRInt32 max_osfd, nfd; +#endif /* _PR_USE_POLL */ + PRInt32 rv; + PRCList *q; + PRUint32 min_timeout; + sigset_t oldset; +#ifdef IRIX +extern sigset_t ints_off; +#endif + + PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); + + _PR_MD_IOQ_LOCK(); + +#ifdef _PR_USE_POLL + /* Build up the pollfd structure array to wait on */ + + /* Find out how many pollfd structures are needed */ + npollfds = _PR_IOQ_OSFD_CNT(me->cpu); + PR_ASSERT(npollfds >= 0); + + /* + * We use a pipe to wake up a native thread. An fd is needed + * for the pipe and we poll it for reading. + */ + if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { + npollfds++; +#ifdef IRIX + /* + * On Irix, a second pipe is used to cause the primordial cpu to + * wakeup and exit, when the process is exiting because of a call + * to exit/PR_ProcessExit. + */ + if (me->cpu->id == 0) { + npollfds++; + } +#endif + } + + /* + * if the cpu's pollfd array is not big enough, release it and allocate a new one + */ + if (npollfds > _PR_IOQ_POLLFDS_SIZE(me->cpu)) { + if (_PR_IOQ_POLLFDS(me->cpu) != NULL) + PR_DELETE(_PR_IOQ_POLLFDS(me->cpu)); + pollfds_size = PR_MAX(_PR_IOQ_MIN_POLLFDS_SIZE(me->cpu), npollfds); + pollfds = (struct pollfd *) PR_MALLOC(pollfds_size * sizeof(struct pollfd)); + _PR_IOQ_POLLFDS(me->cpu) = pollfds; + _PR_IOQ_POLLFDS_SIZE(me->cpu) = pollfds_size; + } else { + pollfds = _PR_IOQ_POLLFDS(me->cpu); + } + pollfdPtr = pollfds; + + /* + * If we need to poll the pipe for waking up a native thread, + * the pipe's fd is the first element in the pollfds array. + */ + if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { + pollfdPtr->fd = _pr_md_pipefd[0]; + pollfdPtr->events = POLLIN; + pollfdPtr++; +#ifdef IRIX + /* + * On Irix, the second element is the exit pipe + */ + if (me->cpu->id == 0) { + pollfdPtr->fd = _pr_irix_primoridal_cpu_fd[0]; + pollfdPtr->events = POLLIN; + pollfdPtr++; + } +#endif + } + + min_timeout = PR_INTERVAL_NO_TIMEOUT; + for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) { + PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); + _PRUnixPollDesc *pds = pq->pds; + _PRUnixPollDesc *epds = pds + pq->npds; + + if (pq->timeout < min_timeout) { + min_timeout = pq->timeout; + } + for (; pds < epds; pds++, pollfdPtr++) { + /* + * Assert that the pollfdPtr pointer does not go + * beyond the end of the pollfds array + */ + PR_ASSERT(pollfdPtr < pollfds + npollfds); + pollfdPtr->fd = pds->osfd; + /* direct copy of poll flags */ + pollfdPtr->events = pds->in_flags; + } + } + _PR_IOQ_TIMEOUT(me->cpu) = min_timeout; +#else + /* + * assigment of fd_sets + */ + r = _PR_FD_READ_SET(me->cpu); + w = _PR_FD_WRITE_SET(me->cpu); + e = _PR_FD_EXCEPTION_SET(me->cpu); + + rp = &r; + wp = &w; + ep = &e; + + max_osfd = _PR_IOQ_MAX_OSFD(me->cpu) + 1; + min_timeout = _PR_IOQ_TIMEOUT(me->cpu); +#endif /* _PR_USE_POLL */ + /* + ** Compute the minimum timeout value: make it the smaller of the + ** timeouts specified by the i/o pollers or the timeout of the first + ** sleeping thread. + */ + q = _PR_SLEEPQ(me->cpu).next; + + if (q != &_PR_SLEEPQ(me->cpu)) { + PRThread *t = _PR_THREAD_PTR(q); + + if (t->sleep < min_timeout) { + min_timeout = t->sleep; + } + } + if (min_timeout > ticks) { + min_timeout = ticks; + } + +#ifdef _PR_USE_POLL + if (min_timeout == PR_INTERVAL_NO_TIMEOUT) + timeout = -1; + else + timeout = PR_IntervalToMilliseconds(min_timeout); +#else + if (min_timeout == PR_INTERVAL_NO_TIMEOUT) { + tvp = NULL; + } else { + timeout.tv_sec = PR_IntervalToSeconds(min_timeout); + timeout.tv_usec = PR_IntervalToMicroseconds(min_timeout) + % PR_USEC_PER_SEC; + tvp = &timeout; + } +#endif /* _PR_USE_POLL */ + + _PR_MD_IOQ_UNLOCK(); + _MD_CHECK_FOR_EXIT(); + /* + * check for i/o operations + */ +#ifndef _PR_NO_CLOCK_TIMER + /* + * Disable the clock interrupts while we are in select, if clock interrupts + * are enabled. Otherwise, when the select/poll calls are interrupted, the + * timer value starts ticking from zero again when the system call is restarted. + */ +#ifdef IRIX + /* + * SIGCHLD signal is used on Irix to detect he termination of an + * sproc by SIGSEGV, SIGBUS or SIGABRT signals when + * _nspr_terminate_on_error is set. + */ + if ((!_nspr_noclock) || (_nspr_terminate_on_error)) +#else + if (!_nspr_noclock) +#endif /* IRIX */ +#ifdef IRIX + sigprocmask(SIG_BLOCK, &ints_off, &oldset); +#else + PR_ASSERT(sigismember(&timer_set, SIGALRM)); + sigprocmask(SIG_BLOCK, &timer_set, &oldset); +#endif /* IRIX */ +#endif /* !_PR_NO_CLOCK_TIMER */ + +#ifndef _PR_USE_POLL + PR_ASSERT(FD_ISSET(_pr_md_pipefd[0],rp)); + nfd = _MD_SELECT(max_osfd, rp, wp, ep, tvp); +#else + nfd = _MD_POLL(pollfds, npollfds, timeout); +#endif /* !_PR_USE_POLL */ + +#ifndef _PR_NO_CLOCK_TIMER +#ifdef IRIX + if ((!_nspr_noclock) || (_nspr_terminate_on_error)) +#else + if (!_nspr_noclock) +#endif /* IRIX */ + sigprocmask(SIG_SETMASK, &oldset, 0); +#endif /* !_PR_NO_CLOCK_TIMER */ + + _MD_CHECK_FOR_EXIT(); + +#ifdef IRIX + _PR_MD_primordial_cpu(); +#endif + + _PR_MD_IOQ_LOCK(); + /* + ** Notify monitors that are associated with the selected descriptors. + */ +#ifdef _PR_USE_POLL + if (nfd > 0) { + pollfdPtr = pollfds; + if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { + /* + * Assert that the pipe is the first element in the + * pollfds array. + */ + PR_ASSERT(pollfds[0].fd == _pr_md_pipefd[0]); + if ((pollfds[0].revents & POLLIN) && (nfd == 1)) { + /* + * woken up by another thread; read all the data + * in the pipe to empty the pipe + */ + while ((rv = read(_pr_md_pipefd[0], _pr_md_pipebuf, + PIPE_BUF)) == PIPE_BUF){ + } + PR_ASSERT((rv > 0) || ((rv == -1) && (errno == EAGAIN))); + } + pollfdPtr++; +#ifdef IRIX + /* + * On Irix, check to see if the primordial cpu needs to exit + * to cause the process to terminate + */ + if (me->cpu->id == 0) { + PR_ASSERT(pollfds[1].fd == _pr_irix_primoridal_cpu_fd[0]); + if (pollfdPtr->revents & POLLIN) { + if (_pr_irix_process_exit) { + /* + * process exit due to a call to PR_ProcessExit + */ + prctl(PR_SETEXITSIG, SIGKILL); + _exit(_pr_irix_process_exit_code); + } else { + while ((rv = read(_pr_irix_primoridal_cpu_fd[0], + _pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) { + } + PR_ASSERT(rv > 0); + } + } + pollfdPtr++; + } +#endif + } + for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) { + PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); + PRBool notify = PR_FALSE; + _PRUnixPollDesc *pds = pq->pds; + _PRUnixPollDesc *epds = pds + pq->npds; + + for (; pds < epds; pds++, pollfdPtr++) { + /* + * Assert that the pollfdPtr pointer does not go beyond + * the end of the pollfds array. + */ + PR_ASSERT(pollfdPtr < pollfds + npollfds); + /* + * Assert that the fd's in the pollfds array (stepped + * through by pollfdPtr) are in the same order as + * the fd's in _PR_IOQ() (stepped through by q and pds). + * This is how the pollfds array was created earlier. + */ + PR_ASSERT(pollfdPtr->fd == pds->osfd); + pds->out_flags = pollfdPtr->revents; + /* Negative fd's are ignored by poll() */ + if (pds->osfd >= 0 && pds->out_flags) { + notify = PR_TRUE; + } + } + if (notify) { + PRIntn pri; + PRThread *thred; + + PR_REMOVE_LINK(&pq->links); + pq->on_ioq = PR_FALSE; + + thred = pq->thr; + _PR_THREAD_LOCK(thred); + if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { + _PRCPU *cpu = pq->thr->cpu; + _PR_SLEEPQ_LOCK(pq->thr->cpu); + _PR_DEL_SLEEPQ(pq->thr, PR_TRUE); + _PR_SLEEPQ_UNLOCK(pq->thr->cpu); + + if (pq->thr->flags & _PR_SUSPENDING) { + /* + * set thread state to SUSPENDED; + * a Resume operation on the thread + * will move it to the runQ + */ + pq->thr->state = _PR_SUSPENDED; + _PR_MISCQ_LOCK(pq->thr->cpu); + _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu); + _PR_MISCQ_UNLOCK(pq->thr->cpu); + } else { + pri = pq->thr->priority; + pq->thr->state = _PR_RUNNABLE; + + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(pq->thr, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + if (_pr_md_idle_cpus > 1) + _PR_MD_WAKEUP_WAITER(thred); + } + } + _PR_THREAD_UNLOCK(thred); + _PR_IOQ_OSFD_CNT(me->cpu) -= pq->npds; + PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0); + } + } + } else if (nfd == -1) { + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno)); + } + +#else + if (nfd > 0) { + q = _PR_IOQ(me->cpu).next; + _PR_IOQ_MAX_OSFD(me->cpu) = -1; + _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT; + while (q != &_PR_IOQ(me->cpu)) { + PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); + PRBool notify = PR_FALSE; + _PRUnixPollDesc *pds = pq->pds; + _PRUnixPollDesc *epds = pds + pq->npds; + PRInt32 pq_max_osfd = -1; + + q = q->next; + for (; pds < epds; pds++) { + PRInt32 osfd = pds->osfd; + PRInt16 in_flags = pds->in_flags; + PRInt16 out_flags = 0; + PR_ASSERT(osfd >= 0 || in_flags == 0); + if ((in_flags & _PR_UNIX_POLL_READ) && FD_ISSET(osfd, rp)) { + out_flags |= _PR_UNIX_POLL_READ; + } + if ((in_flags & _PR_UNIX_POLL_WRITE) && FD_ISSET(osfd, wp)) { + out_flags |= _PR_UNIX_POLL_WRITE; + } + if ((in_flags & _PR_UNIX_POLL_EXCEPT) && FD_ISSET(osfd, ep)) { + out_flags |= _PR_UNIX_POLL_EXCEPT; + } + pds->out_flags = out_flags; + if (out_flags) { + notify = PR_TRUE; + } + if (osfd > pq_max_osfd) { + pq_max_osfd = osfd; + } + } + if (notify == PR_TRUE) { + PRIntn pri; + PRThread *thred; + + PR_REMOVE_LINK(&pq->links); + pq->on_ioq = PR_FALSE; + + /* + * Decrement the count of descriptors for each desciptor/event + * because this I/O request is being removed from the + * ioq + */ + pds = pq->pds; + for (; pds < epds; pds++) { + PRInt32 osfd = pds->osfd; + PRInt16 in_flags = pds->in_flags; + PR_ASSERT(osfd >= 0 || in_flags == 0); + if (in_flags & _PR_UNIX_POLL_READ) { + if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); + } + if (in_flags & _PR_UNIX_POLL_WRITE) { + if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); + } + if (in_flags & _PR_UNIX_POLL_EXCEPT) { + if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); + } + } + + /* + * Because this thread can run on a different cpu right + * after being added to the run queue, do not dereference + * pq + */ + thred = pq->thr; + _PR_THREAD_LOCK(thred); + if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { + _PRCPU *cpu = thred->cpu; + _PR_SLEEPQ_LOCK(pq->thr->cpu); + _PR_DEL_SLEEPQ(pq->thr, PR_TRUE); + _PR_SLEEPQ_UNLOCK(pq->thr->cpu); + + if (pq->thr->flags & _PR_SUSPENDING) { + /* + * set thread state to SUSPENDED; + * a Resume operation on the thread + * will move it to the runQ + */ + pq->thr->state = _PR_SUSPENDED; + _PR_MISCQ_LOCK(pq->thr->cpu); + _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu); + _PR_MISCQ_UNLOCK(pq->thr->cpu); + } else { + pri = pq->thr->priority; + pq->thr->state = _PR_RUNNABLE; + + pq->thr->cpu = cpu; + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(pq->thr, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + if (_pr_md_idle_cpus > 1) + _PR_MD_WAKEUP_WAITER(thred); + } + } + _PR_THREAD_UNLOCK(thred); + } else { + if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu)) + _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout; + if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd) + _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd; + } + } + if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { + if ((FD_ISSET(_pr_md_pipefd[0], rp)) && (nfd == 1)) { + /* + * woken up by another thread; read all the data + * in the pipe to empty the pipe + */ + while ((rv = + read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF)) + == PIPE_BUF){ + } + PR_ASSERT((rv > 0) || + ((rv == -1) && (errno == EAGAIN))); + } + if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0]) + _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0]; +#ifdef IRIX + if ((me->cpu->id == 0) && + (FD_ISSET(_pr_irix_primoridal_cpu_fd[0], rp))) { + if (_pr_irix_process_exit) { + /* + * process exit due to a call to PR_ProcessExit + */ + prctl(PR_SETEXITSIG, SIGKILL); + _exit(_pr_irix_process_exit_code); + } else { + while ((rv = read(_pr_irix_primoridal_cpu_fd[0], + _pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) { + } + PR_ASSERT(rv > 0); + } + } + if (me->cpu->id == 0) { + if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_irix_primoridal_cpu_fd[0]) + _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0]; + } +#endif + } + } else if (nfd < 0) { + if (errno == EBADF) { + FindBadFDs(); + } else { + PR_LOG(_pr_io_lm, PR_LOG_MAX, ("select() failed with errno %d", + errno)); + } + } else { + PR_ASSERT(nfd == 0); + /* + * compute the new value of _PR_IOQ_TIMEOUT + */ + q = _PR_IOQ(me->cpu).next; + _PR_IOQ_MAX_OSFD(me->cpu) = -1; + _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT; + while (q != &_PR_IOQ(me->cpu)) { + PRPollQueue *pq = _PR_POLLQUEUE_PTR(q); + _PRUnixPollDesc *pds = pq->pds; + _PRUnixPollDesc *epds = pds + pq->npds; + PRInt32 pq_max_osfd = -1; + + q = q->next; + for (; pds < epds; pds++) { + if (pds->osfd > pq_max_osfd) { + pq_max_osfd = pds->osfd; + } + } + if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu)) + _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout; + if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd) + _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd; + } + if (_PR_IS_NATIVE_THREAD_SUPPORTED()) { + if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0]) + _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0]; + } + } +#endif /* _PR_USE_POLL */ + _PR_MD_IOQ_UNLOCK(); +} + +void _MD_Wakeup_CPUs() +{ + PRInt32 rv, data; + + data = 0; + rv = write(_pr_md_pipefd[1], &data, 1); + + while ((rv < 0) && (errno == EAGAIN)) { + /* + * pipe full, read all data in pipe to empty it + */ + while ((rv = + read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF)) + == PIPE_BUF) { + } + PR_ASSERT((rv > 0) || + ((rv == -1) && (errno == EAGAIN))); + rv = write(_pr_md_pipefd[1], &data, 1); + } +} + + +void _MD_InitCPUS() +{ + PRInt32 rv, flags; + PRThread *me = _MD_CURRENT_THREAD(); + + rv = pipe(_pr_md_pipefd); + PR_ASSERT(rv == 0); + _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0]; +#ifndef _PR_USE_POLL + FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu)); +#endif + + flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0); + fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK); + flags = fcntl(_pr_md_pipefd[1], F_GETFL, 0); + fcntl(_pr_md_pipefd[1], F_SETFL, flags | O_NONBLOCK); +} + +/* +** Unix SIGALRM (clock) signal handler +*/ +static void ClockInterruptHandler() +{ + int olderrno; + PRUintn pri; + _PRCPU *cpu = _PR_MD_CURRENT_CPU(); + PRThread *me = _MD_CURRENT_THREAD(); + +#ifdef SOLARIS + if (!me || _PR_IS_NATIVE_THREAD(me)) { + _pr_primordialCPU->u.missed[_pr_primordialCPU->where] |= _PR_MISSED_CLOCK; + return; + } +#endif + + if (_PR_MD_GET_INTSOFF() != 0) { + cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK; + return; + } + _PR_MD_SET_INTSOFF(1); + + olderrno = errno; + _PR_ClockInterrupt(); + errno = olderrno; + + /* + ** If the interrupt wants a resched or if some other thread at + ** the same priority needs the cpu, reschedule. + */ + pri = me->priority; + if ((cpu->u.missed[3] || (_PR_RUNQREADYMASK(me->cpu) >> pri))) { +#ifdef _PR_NO_PREEMPT + cpu->resched = PR_TRUE; + if (pr_interruptSwitchHook) { + (*pr_interruptSwitchHook)(pr_interruptSwitchHookArg); + } +#else /* _PR_NO_PREEMPT */ + /* + ** Re-enable unix interrupts (so that we can use + ** setjmp/longjmp for context switching without having to + ** worry about the signal state) + */ + sigprocmask(SIG_SETMASK, &empty_set, 0); + PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock caused context switch")); + + if(!(me->flags & _PR_IDLE_THREAD)) { + _PR_THREAD_LOCK(me); + me->state = _PR_RUNNABLE; + me->cpu = cpu; + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(me, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + _PR_THREAD_UNLOCK(me); + } else + me->state = _PR_RUNNABLE; + _MD_SWITCH_CONTEXT(me); + PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock back from context switch")); +#endif /* _PR_NO_PREEMPT */ + } + /* + * Because this thread could be running on a different cpu after + * a context switch the current cpu should be accessed and the + * value of the 'cpu' variable should not be used. + */ + _PR_MD_SET_INTSOFF(0); +} + +/* + * On HP-UX 9, we have to use the sigvector() interface to restart + * interrupted system calls, because sigaction() does not have the + * SA_RESTART flag. + */ + +#ifdef HPUX9 +static void HPUX9_ClockInterruptHandler( + int sig, + int code, + struct sigcontext *scp) +{ + ClockInterruptHandler(); + scp->sc_syscall_action = SIG_RESTART; +} +#endif /* HPUX9 */ + +/* # of milliseconds per clock tick that we will use */ +#define MSEC_PER_TICK 50 + + +void _MD_StartInterrupts() +{ + char *eval; + + if ((eval = getenv("NSPR_NOCLOCK")) != NULL) { + if (atoi(eval) == 0) + _nspr_noclock = 0; + else + _nspr_noclock = 1; + } + +#ifndef _PR_NO_CLOCK_TIMER + if (!_nspr_noclock) { + _MD_EnableClockInterrupts(); + } +#endif +} + +void _MD_StopInterrupts() +{ + sigprocmask(SIG_BLOCK, &timer_set, 0); +} + +void _MD_EnableClockInterrupts() +{ + struct itimerval itval; + extern PRUintn _pr_numCPU; +#ifdef HPUX9 + struct sigvec vec; + + vec.sv_handler = (void (*)()) HPUX9_ClockInterruptHandler; + vec.sv_mask = 0; + vec.sv_flags = 0; + sigvector(SIGALRM, &vec, 0); +#else + struct sigaction vtact; + + vtact.sa_handler = (void (*)()) ClockInterruptHandler; + sigemptyset(&vtact.sa_mask); + vtact.sa_flags = SA_RESTART; + sigaction(SIGALRM, &vtact, 0); +#endif /* HPUX9 */ + + PR_ASSERT(_pr_numCPU == 1); + itval.it_interval.tv_sec = 0; + itval.it_interval.tv_usec = MSEC_PER_TICK * PR_USEC_PER_MSEC; + itval.it_value = itval.it_interval; + setitimer(ITIMER_REAL, &itval, 0); +} + +void _MD_DisableClockInterrupts() +{ + struct itimerval itval; + extern PRUintn _pr_numCPU; + + PR_ASSERT(_pr_numCPU == 1); + itval.it_interval.tv_sec = 0; + itval.it_interval.tv_usec = 0; + itval.it_value = itval.it_interval; + setitimer(ITIMER_REAL, &itval, 0); +} + +void _MD_BlockClockInterrupts() +{ + sigprocmask(SIG_BLOCK, &timer_set, 0); +} + +void _MD_UnblockClockInterrupts() +{ + sigprocmask(SIG_UNBLOCK, &timer_set, 0); +} + +void _MD_MakeNonblock(PRFileDesc *fd) +{ + PRInt32 osfd = fd->secret->md.osfd; + int flags; + + if (osfd <= 2) { + /* Don't mess around with stdin, stdout or stderr */ + return; + } + flags = fcntl(osfd, F_GETFL, 0); + + /* + * Use O_NONBLOCK (POSIX-style non-blocking I/O) whenever possible. + * On SunOS 4, we must use FNDELAY (BSD-style non-blocking I/O), + * otherwise connect() still blocks and can be interrupted by SIGALRM. + */ + + fcntl(osfd, F_SETFL, flags | O_NONBLOCK); + } + +PRInt32 _MD_open(const char *name, PRIntn flags, PRIntn mode) +{ + PRInt32 osflags; + PRInt32 rv, err; + + if (flags & PR_RDWR) { + osflags = O_RDWR; + } else if (flags & PR_WRONLY) { + osflags = O_WRONLY; + } else { + osflags = O_RDONLY; + } + + if (flags & PR_EXCL) + osflags |= O_EXCL; + if (flags & PR_APPEND) + osflags |= O_APPEND; + if (flags & PR_TRUNCATE) + osflags |= O_TRUNC; + if (flags & PR_SYNC) { +#if defined(O_SYNC) + osflags |= O_SYNC; +#elif defined(O_FSYNC) + osflags |= O_FSYNC; +#else +#error "Neither O_SYNC nor O_FSYNC is defined on this platform" +#endif + } + + /* + ** On creations we hold the 'create' lock in order to enforce + ** the semantics of PR_Rename. (see the latter for more details) + */ + if (flags & PR_CREATE_FILE) + { + osflags |= O_CREAT; + if (NULL !=_pr_rename_lock) + PR_Lock(_pr_rename_lock); + } + +#if defined(ANDROID) + osflags |= O_LARGEFILE; +#endif + + rv = _md_iovector._open64(name, osflags, mode); + + if (rv < 0) { + err = _MD_ERRNO(); + _PR_MD_MAP_OPEN_ERROR(err); + } + + if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock)) + PR_Unlock(_pr_rename_lock); + return rv; +} + +PRIntervalTime intr_timeout_ticks; + +#if defined(SOLARIS) || defined(IRIX) +static void sigsegvhandler() { + fprintf(stderr,"Received SIGSEGV\n"); + fflush(stderr); + pause(); +} + +static void sigaborthandler() { + fprintf(stderr,"Received SIGABRT\n"); + fflush(stderr); + pause(); +} + +static void sigbushandler() { + fprintf(stderr,"Received SIGBUS\n"); + fflush(stderr); + pause(); +} +#endif /* SOLARIS, IRIX */ + +#endif /* !defined(_PR_PTHREADS) */ + +void _MD_query_fd_inheritable(PRFileDesc *fd) +{ + int flags; + + PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); + flags = fcntl(fd->secret->md.osfd, F_GETFD, 0); + PR_ASSERT(-1 != flags); + fd->secret->inheritable = (flags & FD_CLOEXEC) ? + _PR_TRI_FALSE : _PR_TRI_TRUE; +} + +PROffset32 _MD_lseek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) +{ + PROffset32 rv, where; + + switch (whence) { + case PR_SEEK_SET: + where = SEEK_SET; + break; + case PR_SEEK_CUR: + where = SEEK_CUR; + break; + case PR_SEEK_END: + where = SEEK_END; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = -1; + goto done; + } + rv = lseek(fd->secret->md.osfd,offset,where); + if (rv == -1) + { + PRInt32 syserr = _MD_ERRNO(); + _PR_MD_MAP_LSEEK_ERROR(syserr); + } +done: + return(rv); +} + +PROffset64 _MD_lseek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) +{ + PRInt32 where; + PROffset64 rv; + + switch (whence) + { + case PR_SEEK_SET: + where = SEEK_SET; + break; + case PR_SEEK_CUR: + where = SEEK_CUR; + break; + case PR_SEEK_END: + where = SEEK_END; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = minus_one; + goto done; + } + rv = _md_iovector._lseek64(fd->secret->md.osfd, offset, where); + if (LL_EQ(rv, minus_one)) + { + PRInt32 syserr = _MD_ERRNO(); + _PR_MD_MAP_LSEEK_ERROR(syserr); + } +done: + return rv; +} /* _MD_lseek64 */ + +/* +** _MD_set_fileinfo_times -- +** Set the modifyTime and creationTime of the PRFileInfo +** structure using the values in struct stat. +** +** _MD_set_fileinfo64_times -- +** Set the modifyTime and creationTime of the PRFileInfo64 +** structure using the values in _MDStat64. +*/ + +#if defined(_PR_STAT_HAS_ST_ATIM) +/* +** struct stat has st_atim, st_mtim, and st_ctim fields of +** type timestruc_t. +*/ +static void _MD_set_fileinfo_times( + const struct stat *sb, + PRFileInfo *info) +{ + PRInt64 us, s2us; + + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(info->modifyTime, sb->st_mtim.tv_sec); + LL_MUL(info->modifyTime, info->modifyTime, s2us); + LL_I2L(us, sb->st_mtim.tv_nsec / 1000); + LL_ADD(info->modifyTime, info->modifyTime, us); + LL_I2L(info->creationTime, sb->st_ctim.tv_sec); + LL_MUL(info->creationTime, info->creationTime, s2us); + LL_I2L(us, sb->st_ctim.tv_nsec / 1000); + LL_ADD(info->creationTime, info->creationTime, us); +} + +static void _MD_set_fileinfo64_times( + const _MDStat64 *sb, + PRFileInfo64 *info) +{ + PRInt64 us, s2us; + + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(info->modifyTime, sb->st_mtim.tv_sec); + LL_MUL(info->modifyTime, info->modifyTime, s2us); + LL_I2L(us, sb->st_mtim.tv_nsec / 1000); + LL_ADD(info->modifyTime, info->modifyTime, us); + LL_I2L(info->creationTime, sb->st_ctim.tv_sec); + LL_MUL(info->creationTime, info->creationTime, s2us); + LL_I2L(us, sb->st_ctim.tv_nsec / 1000); + LL_ADD(info->creationTime, info->creationTime, us); +} +#elif defined(_PR_STAT_HAS_ST_ATIM_UNION) +/* +** The st_atim, st_mtim, and st_ctim fields in struct stat are +** unions with a st__tim union member of type timestruc_t. +*/ +static void _MD_set_fileinfo_times( + const struct stat *sb, + PRFileInfo *info) +{ + PRInt64 us, s2us; + + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(info->modifyTime, sb->st_mtim.st__tim.tv_sec); + LL_MUL(info->modifyTime, info->modifyTime, s2us); + LL_I2L(us, sb->st_mtim.st__tim.tv_nsec / 1000); + LL_ADD(info->modifyTime, info->modifyTime, us); + LL_I2L(info->creationTime, sb->st_ctim.st__tim.tv_sec); + LL_MUL(info->creationTime, info->creationTime, s2us); + LL_I2L(us, sb->st_ctim.st__tim.tv_nsec / 1000); + LL_ADD(info->creationTime, info->creationTime, us); +} + +static void _MD_set_fileinfo64_times( + const _MDStat64 *sb, + PRFileInfo64 *info) +{ + PRInt64 us, s2us; + + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(info->modifyTime, sb->st_mtim.st__tim.tv_sec); + LL_MUL(info->modifyTime, info->modifyTime, s2us); + LL_I2L(us, sb->st_mtim.st__tim.tv_nsec / 1000); + LL_ADD(info->modifyTime, info->modifyTime, us); + LL_I2L(info->creationTime, sb->st_ctim.st__tim.tv_sec); + LL_MUL(info->creationTime, info->creationTime, s2us); + LL_I2L(us, sb->st_ctim.st__tim.tv_nsec / 1000); + LL_ADD(info->creationTime, info->creationTime, us); +} +#elif defined(_PR_STAT_HAS_ST_ATIMESPEC) +/* +** struct stat has st_atimespec, st_mtimespec, and st_ctimespec +** fields of type struct timespec. +*/ +#if defined(_PR_TIMESPEC_HAS_TS_SEC) +static void _MD_set_fileinfo_times( + const struct stat *sb, + PRFileInfo *info) +{ + PRInt64 us, s2us; + + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(info->modifyTime, sb->st_mtimespec.ts_sec); + LL_MUL(info->modifyTime, info->modifyTime, s2us); + LL_I2L(us, sb->st_mtimespec.ts_nsec / 1000); + LL_ADD(info->modifyTime, info->modifyTime, us); + LL_I2L(info->creationTime, sb->st_ctimespec.ts_sec); + LL_MUL(info->creationTime, info->creationTime, s2us); + LL_I2L(us, sb->st_ctimespec.ts_nsec / 1000); + LL_ADD(info->creationTime, info->creationTime, us); +} + +static void _MD_set_fileinfo64_times( + const _MDStat64 *sb, + PRFileInfo64 *info) +{ + PRInt64 us, s2us; + + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(info->modifyTime, sb->st_mtimespec.ts_sec); + LL_MUL(info->modifyTime, info->modifyTime, s2us); + LL_I2L(us, sb->st_mtimespec.ts_nsec / 1000); + LL_ADD(info->modifyTime, info->modifyTime, us); + LL_I2L(info->creationTime, sb->st_ctimespec.ts_sec); + LL_MUL(info->creationTime, info->creationTime, s2us); + LL_I2L(us, sb->st_ctimespec.ts_nsec / 1000); + LL_ADD(info->creationTime, info->creationTime, us); +} +#else /* _PR_TIMESPEC_HAS_TS_SEC */ +/* +** The POSIX timespec structure has tv_sec and tv_nsec. +*/ +static void _MD_set_fileinfo_times( + const struct stat *sb, + PRFileInfo *info) +{ + PRInt64 us, s2us; + + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(info->modifyTime, sb->st_mtimespec.tv_sec); + LL_MUL(info->modifyTime, info->modifyTime, s2us); + LL_I2L(us, sb->st_mtimespec.tv_nsec / 1000); + LL_ADD(info->modifyTime, info->modifyTime, us); + LL_I2L(info->creationTime, sb->st_ctimespec.tv_sec); + LL_MUL(info->creationTime, info->creationTime, s2us); + LL_I2L(us, sb->st_ctimespec.tv_nsec / 1000); + LL_ADD(info->creationTime, info->creationTime, us); +} + +static void _MD_set_fileinfo64_times( + const _MDStat64 *sb, + PRFileInfo64 *info) +{ + PRInt64 us, s2us; + + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(info->modifyTime, sb->st_mtimespec.tv_sec); + LL_MUL(info->modifyTime, info->modifyTime, s2us); + LL_I2L(us, sb->st_mtimespec.tv_nsec / 1000); + LL_ADD(info->modifyTime, info->modifyTime, us); + LL_I2L(info->creationTime, sb->st_ctimespec.tv_sec); + LL_MUL(info->creationTime, info->creationTime, s2us); + LL_I2L(us, sb->st_ctimespec.tv_nsec / 1000); + LL_ADD(info->creationTime, info->creationTime, us); +} +#endif /* _PR_TIMESPEC_HAS_TS_SEC */ +#elif defined(_PR_STAT_HAS_ONLY_ST_ATIME) +/* +** struct stat only has st_atime, st_mtime, and st_ctime fields +** of type time_t. +*/ +static void _MD_set_fileinfo_times( + const struct stat *sb, + PRFileInfo *info) +{ + PRInt64 s, s2us; + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(s, sb->st_mtime); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, sb->st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; +} + +static void _MD_set_fileinfo64_times( + const _MDStat64 *sb, + PRFileInfo64 *info) +{ + PRInt64 s, s2us; + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(s, sb->st_mtime); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, sb->st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; +} +#else +#error "I don't know yet" +#endif + +static int _MD_convert_stat_to_fileinfo( + const struct stat *sb, + PRFileInfo *info) +{ + if (S_IFREG & sb->st_mode) + info->type = PR_FILE_FILE; + else if (S_IFDIR & sb->st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + +#if defined(_PR_HAVE_LARGE_OFF_T) + if (0x7fffffffL < sb->st_size) + { + PR_SetError(PR_FILE_TOO_BIG_ERROR, 0); + return -1; + } +#endif /* defined(_PR_HAVE_LARGE_OFF_T) */ + info->size = sb->st_size; + + _MD_set_fileinfo_times(sb, info); + return 0; +} /* _MD_convert_stat_to_fileinfo */ + +static int _MD_convert_stat64_to_fileinfo64( + const _MDStat64 *sb, + PRFileInfo64 *info) +{ + if (S_IFREG & sb->st_mode) + info->type = PR_FILE_FILE; + else if (S_IFDIR & sb->st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + + LL_I2L(info->size, sb->st_size); + + _MD_set_fileinfo64_times(sb, info); + return 0; +} /* _MD_convert_stat64_to_fileinfo64 */ + +PRInt32 _MD_getfileinfo(const char *fn, PRFileInfo *info) +{ + PRInt32 rv; + struct stat sb; + + rv = stat(fn, &sb); + if (rv < 0) + _PR_MD_MAP_STAT_ERROR(_MD_ERRNO()); + else if (NULL != info) + rv = _MD_convert_stat_to_fileinfo(&sb, info); + return rv; +} + +PRInt32 _MD_getfileinfo64(const char *fn, PRFileInfo64 *info) +{ + _MDStat64 sb; + PRInt32 rv = _md_iovector._stat64(fn, &sb); + if (rv < 0) + _PR_MD_MAP_STAT_ERROR(_MD_ERRNO()); + else if (NULL != info) + rv = _MD_convert_stat64_to_fileinfo64(&sb, info); + return rv; +} + +PRInt32 _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info) +{ + struct stat sb; + PRInt32 rv = fstat(fd->secret->md.osfd, &sb); + if (rv < 0) + _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO()); + else if (NULL != info) + rv = _MD_convert_stat_to_fileinfo(&sb, info); + return rv; +} + +PRInt32 _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info) +{ + _MDStat64 sb; + PRInt32 rv = _md_iovector._fstat64(fd->secret->md.osfd, &sb); + if (rv < 0) + _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO()); + else if (NULL != info) + rv = _MD_convert_stat64_to_fileinfo64(&sb, info); + return rv; +} + +/* + * _md_iovector._open64 must be initialized to 'open' so that _PR_InitLog can + * open the log file during NSPR initialization, before _md_iovector is + * initialized by _PR_MD_FINAL_INIT. This means the log file cannot be a + * large file on some platforms. + */ +#ifdef SYMBIAN +struct _MD_IOVector _md_iovector; /* Will crash if NSPR_LOG_FILE is set. */ +#else +struct _MD_IOVector _md_iovector = { open }; +#endif + +/* +** These implementations are to emulate large file routines on systems that +** don't have them. Their goal is to check in case overflow occurs. Otherwise +** they will just operate as normal using 32-bit file routines. +** +** The checking might be pre- or post-op, depending on the semantics. +*/ + +#if defined(SOLARIS2_5) + +static PRIntn _MD_solaris25_fstat64(PRIntn osfd, _MDStat64 *buf) +{ + PRInt32 rv; + struct stat sb; + + rv = fstat(osfd, &sb); + if (rv >= 0) + { + /* + ** I'm only copying the fields that are immediately needed. + ** If somebody else calls this function, some of the fields + ** may not be defined. + */ + (void)memset(buf, 0, sizeof(_MDStat64)); + buf->st_mode = sb.st_mode; + buf->st_ctim = sb.st_ctim; + buf->st_mtim = sb.st_mtim; + buf->st_size = sb.st_size; + } + return rv; +} /* _MD_solaris25_fstat64 */ + +static PRIntn _MD_solaris25_stat64(const char *fn, _MDStat64 *buf) +{ + PRInt32 rv; + struct stat sb; + + rv = stat(fn, &sb); + if (rv >= 0) + { + /* + ** I'm only copying the fields that are immediately needed. + ** If somebody else calls this function, some of the fields + ** may not be defined. + */ + (void)memset(buf, 0, sizeof(_MDStat64)); + buf->st_mode = sb.st_mode; + buf->st_ctim = sb.st_ctim; + buf->st_mtim = sb.st_mtim; + buf->st_size = sb.st_size; + } + return rv; +} /* _MD_solaris25_stat64 */ +#endif /* defined(SOLARIS2_5) */ + +#if defined(_PR_NO_LARGE_FILES) || defined(SOLARIS2_5) + +static PROffset64 _MD_Unix_lseek64(PRIntn osfd, PROffset64 offset, PRIntn whence) +{ + PRUint64 maxoff; + PROffset64 rv = minus_one; + LL_I2L(maxoff, 0x7fffffff); + if (LL_CMP(offset, <=, maxoff)) + { + off_t off; + LL_L2I(off, offset); + LL_I2L(rv, lseek(osfd, off, whence)); + } + else errno = EFBIG; /* we can't go there */ + return rv; +} /* _MD_Unix_lseek64 */ + +static void* _MD_Unix_mmap64( + void *addr, PRSize len, PRIntn prot, PRIntn flags, + PRIntn fildes, PRInt64 offset) +{ + PR_SetError(PR_FILE_TOO_BIG_ERROR, 0); + return NULL; +} /* _MD_Unix_mmap64 */ +#endif /* defined(_PR_NO_LARGE_FILES) || defined(SOLARIS2_5) */ + +/* Android <= 19 doesn't have mmap64. */ +#if defined(ANDROID) && __ANDROID_API__ <= 19 +extern void *__mmap2(void *, size_t, int, int, int, size_t); + +#define ANDROID_PAGE_SIZE 4096 + +static void * +mmap64(void *addr, size_t len, int prot, int flags, int fd, loff_t offset) +{ + if (offset & (ANDROID_PAGE_SIZE - 1)) { + errno = EINVAL; + return MAP_FAILED; + } + return __mmap2(addr, len, prot, flags, fd, offset / ANDROID_PAGE_SIZE); +} +#endif + +#if defined(OSF1) && defined(__GNUC__) + +/* + * On OSF1 V5.0A, defines stat and fstat as + * macros when compiled under gcc, so it is rather tricky to + * take the addresses of the real functions the macros expend + * to. A simple solution is to define forwarder functions + * and take the addresses of the forwarder functions instead. + */ + +static int stat_forwarder(const char *path, struct stat *buffer) +{ + return stat(path, buffer); +} + +static int fstat_forwarder(int filedes, struct stat *buffer) +{ + return fstat(filedes, buffer); +} + +#endif + +static void _PR_InitIOV(void) +{ +#if defined(SOLARIS2_5) + PRLibrary *lib; + void *open64_func; + + open64_func = PR_FindSymbolAndLibrary("open64", &lib); + if (NULL != open64_func) + { + PR_ASSERT(NULL != lib); + _md_iovector._open64 = (_MD_Open64)open64_func; + _md_iovector._mmap64 = (_MD_Mmap64)PR_FindSymbol(lib, "mmap64"); + _md_iovector._fstat64 = (_MD_Fstat64)PR_FindSymbol(lib, "fstat64"); + _md_iovector._stat64 = (_MD_Stat64)PR_FindSymbol(lib, "stat64"); + _md_iovector._lseek64 = (_MD_Lseek64)PR_FindSymbol(lib, "lseek64"); + (void)PR_UnloadLibrary(lib); + } + else + { + _md_iovector._open64 = open; + _md_iovector._mmap64 = _MD_Unix_mmap64; + _md_iovector._fstat64 = _MD_solaris25_fstat64; + _md_iovector._stat64 = _MD_solaris25_stat64; + _md_iovector._lseek64 = _MD_Unix_lseek64; + } +#elif defined(_PR_NO_LARGE_FILES) + _md_iovector._open64 = open; + _md_iovector._mmap64 = _MD_Unix_mmap64; + _md_iovector._fstat64 = fstat; + _md_iovector._stat64 = stat; + _md_iovector._lseek64 = _MD_Unix_lseek64; +#elif defined(_PR_HAVE_OFF64_T) +#if defined(IRIX5_3) || defined(ANDROID) + /* + * Android doesn't have open64. We pass the O_LARGEFILE flag to open + * in _MD_open. + */ + _md_iovector._open64 = open; +#else + _md_iovector._open64 = open64; +#endif + _md_iovector._mmap64 = mmap64; + _md_iovector._fstat64 = fstat64; + _md_iovector._stat64 = stat64; + _md_iovector._lseek64 = lseek64; +#elif defined(_PR_HAVE_LARGE_OFF_T) + _md_iovector._open64 = open; + _md_iovector._mmap64 = mmap; +#if defined(OSF1) && defined(__GNUC__) + _md_iovector._fstat64 = fstat_forwarder; + _md_iovector._stat64 = stat_forwarder; +#else + _md_iovector._fstat64 = fstat; + _md_iovector._stat64 = stat; +#endif + _md_iovector._lseek64 = lseek; +#else +#error "I don't know yet" +#endif + LL_I2L(minus_one, -1); +} /* _PR_InitIOV */ + +void _PR_UnixInit(void) +{ + struct sigaction sigact; + int rv; + + sigemptyset(&timer_set); + +#if !defined(_PR_PTHREADS) + + sigaddset(&timer_set, SIGALRM); + sigemptyset(&empty_set); + intr_timeout_ticks = + PR_SecondsToInterval(_PR_INTERRUPT_CHECK_INTERVAL_SECS); + +#if defined(SOLARIS) || defined(IRIX) + + if (getenv("NSPR_SIGSEGV_HANDLE")) { + sigact.sa_handler = sigsegvhandler; + sigact.sa_flags = 0; + sigact.sa_mask = timer_set; + sigaction(SIGSEGV, &sigact, 0); + } + + if (getenv("NSPR_SIGABRT_HANDLE")) { + sigact.sa_handler = sigaborthandler; + sigact.sa_flags = 0; + sigact.sa_mask = timer_set; + sigaction(SIGABRT, &sigact, 0); + } + + if (getenv("NSPR_SIGBUS_HANDLE")) { + sigact.sa_handler = sigbushandler; + sigact.sa_flags = 0; + sigact.sa_mask = timer_set; + sigaction(SIGBUS, &sigact, 0); + } + +#endif +#endif /* !defined(_PR_PTHREADS) */ + + /* + * Under HP-UX DCE threads, sigaction() installs a per-thread + * handler, so we use sigvector() to install a process-wide + * handler. + */ +#if defined(HPUX) && defined(_PR_DCETHREADS) + { + struct sigvec vec; + + vec.sv_handler = SIG_IGN; + vec.sv_mask = 0; + vec.sv_flags = 0; + rv = sigvector(SIGPIPE, &vec, NULL); + PR_ASSERT(0 == rv); + } +#else + sigact.sa_handler = SIG_IGN; + sigemptyset(&sigact.sa_mask); + sigact.sa_flags = 0; + rv = sigaction(SIGPIPE, &sigact, 0); + PR_ASSERT(0 == rv); +#endif /* HPUX && _PR_DCETHREADS */ + + _pr_rename_lock = PR_NewLock(); + PR_ASSERT(NULL != _pr_rename_lock); + _pr_Xfe_mon = PR_NewMonitor(); + PR_ASSERT(NULL != _pr_Xfe_mon); + + _PR_InitIOV(); /* one last hack */ +} + +void _PR_UnixCleanup(void) +{ + if (_pr_rename_lock) { + PR_DestroyLock(_pr_rename_lock); + _pr_rename_lock = NULL; + } + if (_pr_Xfe_mon) { + PR_DestroyMonitor(_pr_Xfe_mon); + _pr_Xfe_mon = NULL; + } +} + +#if !defined(_PR_PTHREADS) + +/* + * Variables used by the GC code, initialized in _MD_InitSegs(). + */ +static PRInt32 _pr_zero_fd = -1; +static PRLock *_pr_md_lock = NULL; + +/* + * _MD_InitSegs -- + * + * This is Unix's version of _PR_MD_INIT_SEGS(), which is + * called by _PR_InitSegs(), which in turn is called by + * PR_Init(). + */ +void _MD_InitSegs(void) +{ +#ifdef DEBUG + /* + ** Disable using mmap(2) if NSPR_NO_MMAP is set + */ + if (getenv("NSPR_NO_MMAP")) { + _pr_zero_fd = -2; + return; + } +#endif + _pr_zero_fd = open("/dev/zero",O_RDWR , 0); + /* Prevent the fd from being inherited by child processes */ + fcntl(_pr_zero_fd, F_SETFD, FD_CLOEXEC); + _pr_md_lock = PR_NewLock(); +} + +PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr) +{ + static char *lastaddr = (char*) _PR_STACK_VMBASE; + PRStatus retval = PR_SUCCESS; + int prot; + void *rv; + + PR_ASSERT(seg != 0); + PR_ASSERT(size != 0); + + PR_Lock(_pr_md_lock); + if (_pr_zero_fd < 0) { +from_heap: + seg->vaddr = PR_MALLOC(size); + if (!seg->vaddr) { + retval = PR_FAILURE; + } + else { + seg->size = size; + } + goto exit; + } + + prot = PROT_READ|PROT_WRITE; + /* + * On Alpha Linux, the user-level thread stack needs + * to be made executable because longjmp/signal seem + * to put machine instructions on the stack. + */ +#if defined(LINUX) && defined(__alpha) + prot |= PROT_EXEC; +#endif + rv = mmap((vaddr != 0) ? vaddr : lastaddr, size, prot, + _MD_MMAP_FLAGS, + _pr_zero_fd, 0); + if (rv == (void*)-1) { + goto from_heap; + } + lastaddr += size; + seg->vaddr = rv; + seg->size = size; + seg->flags = _PR_SEG_VM; + +exit: + PR_Unlock(_pr_md_lock); + return retval; +} + +void _MD_FreeSegment(PRSegment *seg) +{ + if (seg->flags & _PR_SEG_VM) + (void) munmap(seg->vaddr, seg->size); + else + PR_DELETE(seg->vaddr); +} + +#endif /* _PR_PTHREADS */ + +/* + *----------------------------------------------------------------------- + * + * PR_Now -- + * + * Returns the current time in microseconds since the epoch. + * The epoch is midnight January 1, 1970 GMT. + * The implementation is machine dependent. This is the Unix + * implementation. + * Cf. time_t time(time_t *tp) + * + *----------------------------------------------------------------------- + */ + +PR_IMPLEMENT(PRTime) +PR_Now(void) +{ + struct timeval tv; + PRInt64 s, us, s2us; + + GETTIMEOFDAY(&tv); + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_I2L(s, tv.tv_sec); + LL_I2L(us, tv.tv_usec); + LL_MUL(s, s, s2us); + LL_ADD(s, s, us); + return s; +} + +#if defined(_MD_INTERVAL_USE_GTOD) +/* + * This version of interval times is based on the time of day + * capability offered by the system. This isn't valid for two reasons: + * 1) The time of day is neither linear nor montonically increasing + * 2) The units here are milliseconds. That's not appropriate for our use. + */ +PRIntervalTime _PR_UNIX_GetInterval() +{ + struct timeval time; + PRIntervalTime ticks; + + (void)GETTIMEOFDAY(&time); /* fallicy of course */ + ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; /* that's in milliseconds */ + ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC; /* so's that */ + return ticks; +} /* _PR_UNIX_GetInterval */ + +PRIntervalTime _PR_UNIX_TicksPerSecond() +{ + return 1000; /* this needs some work :) */ +} +#endif + +#if defined(HAVE_CLOCK_MONOTONIC) +PRIntervalTime _PR_UNIX_GetInterval2() +{ + struct timespec time; + PRIntervalTime ticks; + + if (clock_gettime(CLOCK_MONOTONIC, &time) != 0) { + fprintf(stderr, "clock_gettime failed: %d\n", errno); + abort(); + } + + ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; + ticks += (PRUint32)time.tv_nsec / PR_NSEC_PER_MSEC; + return ticks; +} + +PRIntervalTime _PR_UNIX_TicksPerSecond2() +{ + return 1000; +} +#endif + +#if !defined(_PR_PTHREADS) +/* + * Wait for I/O on multiple descriptors. + * + * Return 0 if timed out, return -1 if interrupted, + * else return the number of ready descriptors. + */ +PRInt32 _PR_WaitForMultipleFDs( + _PRUnixPollDesc *unixpds, + PRInt32 pdcnt, + PRIntervalTime timeout) +{ + PRPollQueue pq; + PRIntn is; + PRInt32 rv; + _PRCPU *io_cpu; + _PRUnixPollDesc *unixpd, *eunixpd; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + + pq.pds = unixpds; + pq.npds = pdcnt; + + _PR_INTSOFF(is); + _PR_MD_IOQ_LOCK(); + _PR_THREAD_LOCK(me); + + pq.thr = me; + io_cpu = me->cpu; + pq.on_ioq = PR_TRUE; + pq.timeout = timeout; + _PR_ADD_TO_IOQ(pq, me->cpu); + +#if !defined(_PR_USE_POLL) + eunixpd = unixpds + pdcnt; + for (unixpd = unixpds; unixpd < eunixpd; unixpd++) { + PRInt32 osfd = unixpd->osfd; + if (unixpd->in_flags & _PR_UNIX_POLL_READ) { + FD_SET(osfd, &_PR_FD_READ_SET(me->cpu)); + _PR_FD_READ_CNT(me->cpu)[osfd]++; + } + if (unixpd->in_flags & _PR_UNIX_POLL_WRITE) { + FD_SET(osfd, &_PR_FD_WRITE_SET(me->cpu)); + (_PR_FD_WRITE_CNT(me->cpu))[osfd]++; + } + if (unixpd->in_flags & _PR_UNIX_POLL_EXCEPT) { + FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); + (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++; + } + if (osfd > _PR_IOQ_MAX_OSFD(me->cpu)) { + _PR_IOQ_MAX_OSFD(me->cpu) = osfd; + } + } +#endif /* !defined(_PR_USE_POLL) */ + + if (_PR_IOQ_TIMEOUT(me->cpu) > timeout) { + _PR_IOQ_TIMEOUT(me->cpu) = timeout; + } + + _PR_IOQ_OSFD_CNT(me->cpu) += pdcnt; + + _PR_SLEEPQ_LOCK(me->cpu); + _PR_ADD_SLEEPQ(me, timeout); + me->state = _PR_IO_WAIT; + me->io_pending = PR_TRUE; + me->io_suspended = PR_FALSE; + _PR_SLEEPQ_UNLOCK(me->cpu); + _PR_THREAD_UNLOCK(me); + _PR_MD_IOQ_UNLOCK(); + + _PR_MD_WAIT(me, timeout); + + me->io_pending = PR_FALSE; + me->io_suspended = PR_FALSE; + + /* + * This thread should run on the same cpu on which it was blocked; when + * the IO request times out the fd sets and fd counts for the + * cpu are updated below. + */ + PR_ASSERT(me->cpu == io_cpu); + + /* + ** If we timed out the pollq might still be on the ioq. Remove it + ** before continuing. + */ + if (pq.on_ioq) { + _PR_MD_IOQ_LOCK(); + /* + * Need to check pq.on_ioq again + */ + if (pq.on_ioq) { + PR_REMOVE_LINK(&pq.links); +#ifndef _PR_USE_POLL + eunixpd = unixpds + pdcnt; + for (unixpd = unixpds; unixpd < eunixpd; unixpd++) { + PRInt32 osfd = unixpd->osfd; + PRInt16 in_flags = unixpd->in_flags; + + if (in_flags & _PR_UNIX_POLL_READ) { + if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu)); + } + if (in_flags & _PR_UNIX_POLL_WRITE) { + if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu)); + } + if (in_flags & _PR_UNIX_POLL_EXCEPT) { + if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0) + FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu)); + } + } +#endif /* _PR_USE_POLL */ + PR_ASSERT(pq.npds == pdcnt); + _PR_IOQ_OSFD_CNT(me->cpu) -= pdcnt; + PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0); + } + _PR_MD_IOQ_UNLOCK(); + } + /* XXX Should we use _PR_FAST_INTSON or _PR_INTSON? */ + if (1 == pdcnt) { + _PR_FAST_INTSON(is); + } else { + _PR_INTSON(is); + } + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + + rv = 0; + if (pq.on_ioq == PR_FALSE) { + /* Count the number of ready descriptors */ + while (--pdcnt >= 0) { + if (unixpds->out_flags != 0) { + rv++; + } + unixpds++; + } + } + + return rv; +} + +/* + * Unblock threads waiting for I/O + * used when interrupting threads + * + * NOTE: The thread lock should held when this function is called. + * On return, the thread lock is released. + */ +void _PR_Unblock_IO_Wait(PRThread *thr) +{ + int pri = thr->priority; + _PRCPU *cpu = thr->cpu; + + /* + * GLOBAL threads wakeup periodically to check for interrupt + */ + if (_PR_IS_NATIVE_THREAD(thr)) { + _PR_THREAD_UNLOCK(thr); + return; + } + + PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ)); + _PR_SLEEPQ_LOCK(cpu); + _PR_DEL_SLEEPQ(thr, PR_TRUE); + _PR_SLEEPQ_UNLOCK(cpu); + + PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD)); + thr->state = _PR_RUNNABLE; + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(thr, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + _PR_THREAD_UNLOCK(thr); + _PR_MD_WAKEUP_WAITER(thr); +} +#endif /* !defined(_PR_PTHREADS) */ + +/* + * When a nonblocking connect has completed, determine whether it + * succeeded or failed, and if it failed, what the error code is. + * + * The function returns the error code. An error code of 0 means + * that the nonblocking connect succeeded. + */ + +int _MD_unix_get_nonblocking_connect_error(int osfd) +{ +#if defined(NTO) + /* Neutrino does not support the SO_ERROR socket option */ + PRInt32 rv; + PRNetAddr addr; + _PRSockLen_t addrlen = sizeof(addr); + + /* Test to see if we are using the Tiny TCP/IP Stack or the Full one. */ + struct statvfs superblock; + rv = fstatvfs(osfd, &superblock); + if (rv == 0) { + if (strcmp(superblock.f_basetype, "ttcpip") == 0) { + /* Using the Tiny Stack! */ + rv = getpeername(osfd, (struct sockaddr *) &addr, + (_PRSockLen_t *) &addrlen); + if (rv == -1) { + int errno_copy = errno; /* make a copy so I don't + * accidentally reset */ + + if (errno_copy == ENOTCONN) { + struct stat StatInfo; + rv = fstat(osfd, &StatInfo); + if (rv == 0) { + time_t current_time = time(NULL); + + /* + * this is a real hack, can't explain why it + * works it just does + */ + if (abs(current_time - StatInfo.st_atime) < 5) { + return ECONNREFUSED; + } else { + return ETIMEDOUT; + } + } else { + return ECONNREFUSED; + } + } else { + return errno_copy; + } + } else { + /* No Error */ + return 0; + } + } else { + /* Have the FULL Stack which supports SO_ERROR */ + /* Hasn't been written yet, never been tested! */ + /* Jerry.Kirk@Nexwarecorp.com */ + + int err; + _PRSockLen_t optlen = sizeof(err); + + if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, + (char *) &err, &optlen) == -1) { + return errno; + } else { + return err; + } + } + } else { + return ECONNREFUSED; + } +#elif defined(UNIXWARE) + /* + * getsockopt() fails with EPIPE, so use getmsg() instead. + */ + + int rv; + int flags = 0; + rv = getmsg(osfd, NULL, NULL, &flags); + PR_ASSERT(-1 == rv || 0 == rv); + if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) { + return errno; + } + return 0; /* no error */ +#else + int err; + _PRSockLen_t optlen = sizeof(err); + if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) { + return errno; + } else { + return err; + } +#endif +} + +/************************************************************************/ + +/* +** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread +** safe. Unfortunately, neither is mozilla. To make these programs work +** in a pre-emptive threaded environment, we need to use a lock. +*/ + +void PR_XLock(void) +{ + PR_EnterMonitor(_pr_Xfe_mon); +} + +void PR_XUnlock(void) +{ + PR_ExitMonitor(_pr_Xfe_mon); +} + +PRBool PR_XIsLocked(void) +{ + return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE; +} + +void PR_XWait(int ms) +{ + PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms)); +} + +void PR_XNotify(void) +{ + PR_Notify(_pr_Xfe_mon); +} + +void PR_XNotifyAll(void) +{ + PR_NotifyAll(_pr_Xfe_mon); +} + +#if defined(HAVE_FCNTL_FILE_LOCKING) + +PRStatus +_MD_LockFile(PRInt32 f) +{ + PRInt32 rv; + struct flock arg; + + arg.l_type = F_WRLCK; + arg.l_whence = SEEK_SET; + arg.l_start = 0; + arg.l_len = 0; /* until EOF */ + rv = fcntl(f, F_SETLKW, &arg); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus +_MD_TLockFile(PRInt32 f) +{ + PRInt32 rv; + struct flock arg; + + arg.l_type = F_WRLCK; + arg.l_whence = SEEK_SET; + arg.l_start = 0; + arg.l_len = 0; /* until EOF */ + rv = fcntl(f, F_SETLK, &arg); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus +_MD_UnlockFile(PRInt32 f) +{ + PRInt32 rv; + struct flock arg; + + arg.l_type = F_UNLCK; + arg.l_whence = SEEK_SET; + arg.l_start = 0; + arg.l_len = 0; /* until EOF */ + rv = fcntl(f, F_SETLK, &arg); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +#elif defined(HAVE_BSD_FLOCK) + +#include + +PRStatus +_MD_LockFile(PRInt32 f) +{ + PRInt32 rv; + rv = flock(f, LOCK_EX); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus +_MD_TLockFile(PRInt32 f) +{ + PRInt32 rv; + rv = flock(f, LOCK_EX|LOCK_NB); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus +_MD_UnlockFile(PRInt32 f) +{ + PRInt32 rv; + rv = flock(f, LOCK_UN); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} +#else + +PRStatus +_MD_LockFile(PRInt32 f) +{ + PRInt32 rv; + rv = lockf(f, F_LOCK, 0); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus +_MD_TLockFile(PRInt32 f) +{ + PRInt32 rv; + rv = lockf(f, F_TLOCK, 0); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus +_MD_UnlockFile(PRInt32 f) +{ + PRInt32 rv; + rv = lockf(f, F_ULOCK, 0); + if (rv == 0) + return PR_SUCCESS; + _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} +#endif + +PRStatus _MD_gethostname(char *name, PRUint32 namelen) +{ + PRIntn rv; + + rv = gethostname(name, namelen); + if (0 == rv) { + return PR_SUCCESS; + } + _PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO()); + return PR_FAILURE; +} + +PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen) +{ + struct utsname info; + + PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE)); + + if (uname(&info) == -1) { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + if (PR_SI_SYSNAME == cmd) + (void)PR_snprintf(name, namelen, info.sysname); + else if (PR_SI_RELEASE == cmd) + (void)PR_snprintf(name, namelen, info.release); + else + return PR_FAILURE; + return PR_SUCCESS; +} + +/* + ******************************************************************* + * + * Memory-mapped files + * + ******************************************************************* + */ + +PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size) +{ + PRFileInfo info; + PRUint32 sz; + + LL_L2UI(sz, size); + if (sz) { + if (PR_GetOpenFileInfo(fmap->fd, &info) == PR_FAILURE) { + return PR_FAILURE; + } + if (sz > info.size) { + /* + * Need to extend the file + */ + if (fmap->prot != PR_PROT_READWRITE) { + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0); + return PR_FAILURE; + } + if (PR_Seek(fmap->fd, sz - 1, PR_SEEK_SET) == -1) { + return PR_FAILURE; + } + if (PR_Write(fmap->fd, "", 1) != 1) { + return PR_FAILURE; + } + } + } + if (fmap->prot == PR_PROT_READONLY) { + fmap->md.prot = PROT_READ; +#ifdef OSF1V4_MAP_PRIVATE_BUG + /* + * Use MAP_SHARED to work around a bug in OSF1 V4.0D + * (QAR 70220 in the OSF_QAR database) that results in + * corrupted data in the memory-mapped region. This + * bug is fixed in V5.0. + */ + fmap->md.flags = MAP_SHARED; +#else + fmap->md.flags = MAP_PRIVATE; +#endif + } else if (fmap->prot == PR_PROT_READWRITE) { + fmap->md.prot = PROT_READ | PROT_WRITE; + fmap->md.flags = MAP_SHARED; + } else { + PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY); + fmap->md.prot = PROT_READ | PROT_WRITE; + fmap->md.flags = MAP_PRIVATE; + } + return PR_SUCCESS; +} + +void * _MD_MemMap( + PRFileMap *fmap, + PRInt64 offset, + PRUint32 len) +{ + PRInt32 off; + void *addr; + + LL_L2I(off, offset); + if ((addr = mmap(0, len, fmap->md.prot, fmap->md.flags, + fmap->fd->secret->md.osfd, off)) == (void *) -1) { + _PR_MD_MAP_MMAP_ERROR(_MD_ERRNO()); + addr = NULL; + } + return addr; +} + +PRStatus _MD_MemUnmap(void *addr, PRUint32 len) +{ + if (munmap(addr, len) == 0) { + return PR_SUCCESS; + } + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; +} + +PRStatus _MD_CloseFileMap(PRFileMap *fmap) +{ + if ( PR_TRUE == fmap->md.isAnonFM ) { + PRStatus rc = PR_Close( fmap->fd ); + if ( PR_FAILURE == rc ) { + PR_LOG( _pr_io_lm, PR_LOG_DEBUG, + ("_MD_CloseFileMap(): error closing anonymnous file map osfd")); + return PR_FAILURE; + } + } + PR_DELETE(fmap); + return PR_SUCCESS; +} + +PRStatus _MD_SyncMemMap( + PRFileDesc *fd, + void *addr, + PRUint32 len) +{ + /* msync(..., MS_SYNC) alone is sufficient to flush modified data to disk + * synchronously. It is not necessary to call fsync. */ + if (msync(addr, len, MS_SYNC) == 0) { + return PR_SUCCESS; + } + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; +} + +#if defined(_PR_NEED_FAKE_POLL) + +/* + * Some platforms don't have poll(). For easier porting of code + * that calls poll(), we emulate poll() using select(). + */ + +int poll(struct pollfd *filedes, unsigned long nfds, int timeout) +{ + int i; + int rv; + int maxfd; + fd_set rd, wr, ex; + struct timeval tv, *tvp; + + if (timeout < 0 && timeout != -1) { + errno = EINVAL; + return -1; + } + + if (timeout == -1) { + tvp = NULL; + } else { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + tvp = &tv; + } + + maxfd = -1; + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); + + for (i = 0; i < nfds; i++) { + int osfd = filedes[i].fd; + int events = filedes[i].events; + PRBool fdHasEvent = PR_FALSE; + + if (osfd < 0) { + continue; /* Skip this osfd. */ + } + + /* + * Map the poll events to the select fd_sets. + * POLLIN, POLLRDNORM ===> readable + * POLLOUT, POLLWRNORM ===> writable + * POLLPRI, POLLRDBAND ===> exception + * POLLNORM, POLLWRBAND (and POLLMSG on some platforms) + * are ignored. + * + * The output events POLLERR and POLLHUP are never turned on. + * POLLNVAL may be turned on. + */ + + if (events & (POLLIN | POLLRDNORM)) { + FD_SET(osfd, &rd); + fdHasEvent = PR_TRUE; + } + if (events & (POLLOUT | POLLWRNORM)) { + FD_SET(osfd, &wr); + fdHasEvent = PR_TRUE; + } + if (events & (POLLPRI | POLLRDBAND)) { + FD_SET(osfd, &ex); + fdHasEvent = PR_TRUE; + } + if (fdHasEvent && osfd > maxfd) { + maxfd = osfd; + } + } + + rv = select(maxfd + 1, &rd, &wr, &ex, tvp); + + /* Compute poll results */ + if (rv > 0) { + rv = 0; + for (i = 0; i < nfds; i++) { + PRBool fdHasEvent = PR_FALSE; + + filedes[i].revents = 0; + if (filedes[i].fd < 0) { + continue; + } + if (FD_ISSET(filedes[i].fd, &rd)) { + if (filedes[i].events & POLLIN) { + filedes[i].revents |= POLLIN; + } + if (filedes[i].events & POLLRDNORM) { + filedes[i].revents |= POLLRDNORM; + } + fdHasEvent = PR_TRUE; + } + if (FD_ISSET(filedes[i].fd, &wr)) { + if (filedes[i].events & POLLOUT) { + filedes[i].revents |= POLLOUT; + } + if (filedes[i].events & POLLWRNORM) { + filedes[i].revents |= POLLWRNORM; + } + fdHasEvent = PR_TRUE; + } + if (FD_ISSET(filedes[i].fd, &ex)) { + if (filedes[i].events & POLLPRI) { + filedes[i].revents |= POLLPRI; + } + if (filedes[i].events & POLLRDBAND) { + filedes[i].revents |= POLLRDBAND; + } + fdHasEvent = PR_TRUE; + } + if (fdHasEvent) { + rv++; + } + } + PR_ASSERT(rv > 0); + } else if (rv == -1 && errno == EBADF) { + rv = 0; + for (i = 0; i < nfds; i++) { + filedes[i].revents = 0; + if (filedes[i].fd < 0) { + continue; + } + if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) { + filedes[i].revents = POLLNVAL; + rv++; + } + } + PR_ASSERT(rv > 0); + } + PR_ASSERT(-1 != timeout || rv != 0); + + return rv; +} +#endif /* _PR_NEED_FAKE_POLL */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/unix_errors.c nspr-4.10.7/nspr/pr/src/md/unix/unix_errors.c --- nspr-4.9.5/nspr/pr/src/md/unix/unix_errors.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/unix_errors.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,829 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#if defined(_PR_POLL_AVAILABLE) +#include +#endif +#include + +void _MD_unix_map_default_error(int err) +{ + PRErrorCode prError; + + switch (err ) { + case EACCES: + prError = PR_NO_ACCESS_RIGHTS_ERROR; + break; + case EADDRINUSE: + prError = PR_ADDRESS_IN_USE_ERROR; + break; + case EADDRNOTAVAIL: + prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; + break; + case EAFNOSUPPORT: + prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; + break; + case EAGAIN: + prError = PR_WOULD_BLOCK_ERROR; + break; + /* + * On QNX and Neutrino, EALREADY is defined as EBUSY. + */ +#if EALREADY != EBUSY + case EALREADY: + prError = PR_ALREADY_INITIATED_ERROR; + break; +#endif + case EBADF: + prError = PR_BAD_DESCRIPTOR_ERROR; + break; +#ifdef EBADMSG + case EBADMSG: + prError = PR_IO_ERROR; + break; +#endif + case EBUSY: + prError = PR_FILESYSTEM_MOUNTED_ERROR; + break; + case ECONNABORTED: + prError = PR_CONNECT_ABORTED_ERROR; + break; + case ECONNREFUSED: + prError = PR_CONNECT_REFUSED_ERROR; + break; + case ECONNRESET: + prError = PR_CONNECT_RESET_ERROR; + break; + case EDEADLK: + prError = PR_DEADLOCK_ERROR; + break; +#ifdef EDIRCORRUPTED + case EDIRCORRUPTED: + prError = PR_DIRECTORY_CORRUPTED_ERROR; + break; +#endif +#ifdef EDQUOT + case EDQUOT: + prError = PR_NO_DEVICE_SPACE_ERROR; + break; +#endif + case EEXIST: + prError = PR_FILE_EXISTS_ERROR; + break; + case EFAULT: + prError = PR_ACCESS_FAULT_ERROR; + break; + case EFBIG: + prError = PR_FILE_TOO_BIG_ERROR; + break; + case EHOSTUNREACH: + case EHOSTDOWN: + prError = PR_HOST_UNREACHABLE_ERROR; + break; + case EINPROGRESS: + prError = PR_IN_PROGRESS_ERROR; + break; + case EINTR: + prError = PR_PENDING_INTERRUPT_ERROR; + break; + case EINVAL: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case EIO: + prError = PR_IO_ERROR; + break; + case EISCONN: + prError = PR_IS_CONNECTED_ERROR; + break; + case EISDIR: + prError = PR_IS_DIRECTORY_ERROR; + break; + case ELOOP: + prError = PR_LOOP_ERROR; + break; + case EMFILE: + prError = PR_PROC_DESC_TABLE_FULL_ERROR; + break; + case EMLINK: + prError = PR_MAX_DIRECTORY_ENTRIES_ERROR; + break; + case EMSGSIZE: + prError = PR_INVALID_ARGUMENT_ERROR; + break; +#ifdef EMULTIHOP + case EMULTIHOP: + prError = PR_REMOTE_FILE_ERROR; + break; +#endif + case ENAMETOOLONG: + prError = PR_NAME_TOO_LONG_ERROR; + break; + case ENETUNREACH: + prError = PR_NETWORK_UNREACHABLE_ERROR; + break; + case ENFILE: + prError = PR_SYS_DESC_TABLE_FULL_ERROR; + break; + /* + * On SCO OpenServer 5, ENOBUFS is defined as ENOSR. + */ +#if defined(ENOBUFS) && (ENOBUFS != ENOSR) + case ENOBUFS: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; +#endif + case ENODEV: + prError = PR_FILE_NOT_FOUND_ERROR; + break; + case ENOENT: + prError = PR_FILE_NOT_FOUND_ERROR; + break; + case ENOLCK: + prError = PR_FILE_IS_LOCKED_ERROR; + break; +#ifdef ENOLINK + case ENOLINK: + prError = PR_REMOTE_FILE_ERROR; + break; +#endif + case ENOMEM: + prError = PR_OUT_OF_MEMORY_ERROR; + break; + case ENOPROTOOPT: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case ENOSPC: + prError = PR_NO_DEVICE_SPACE_ERROR; + break; +#ifdef ENOSR + case ENOSR: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; +#endif + case ENOSYS: + prError = PR_NOT_IMPLEMENTED_ERROR; + break; + case ENOTCONN: + prError = PR_NOT_CONNECTED_ERROR; + break; + case ENOTDIR: + prError = PR_NOT_DIRECTORY_ERROR; + break; + case ENOTSOCK: + prError = PR_NOT_SOCKET_ERROR; + break; + case ENXIO: + prError = PR_FILE_NOT_FOUND_ERROR; + break; + case EOPNOTSUPP: + prError = PR_NOT_TCP_SOCKET_ERROR; + break; +#ifdef EOVERFLOW + case EOVERFLOW: + prError = PR_BUFFER_OVERFLOW_ERROR; + break; +#endif + case EPERM: + prError = PR_NO_ACCESS_RIGHTS_ERROR; + break; + case EPIPE: + prError = PR_CONNECT_RESET_ERROR; + break; +#ifdef EPROTO + case EPROTO: + prError = PR_IO_ERROR; + break; +#endif + case EPROTONOSUPPORT: + prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; + break; + case EPROTOTYPE: + prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; + break; + case ERANGE: + prError = PR_INVALID_METHOD_ERROR; + break; + case EROFS: + prError = PR_READ_ONLY_FILESYSTEM_ERROR; + break; + case ESPIPE: + prError = PR_INVALID_METHOD_ERROR; + break; + case ETIMEDOUT: + prError = PR_IO_TIMEOUT_ERROR; + break; +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: + prError = PR_WOULD_BLOCK_ERROR; + break; +#endif + case EXDEV: + prError = PR_NOT_SAME_DEVICE_ERROR; + break; + default: + prError = PR_UNKNOWN_ERROR; + break; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_opendir_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_closedir_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EINVAL: + prError = PR_BAD_DESCRIPTOR_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_readdir_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case 0: + case ENOENT: + prError = PR_NO_MORE_FILES_ERROR; + break; +#ifdef EOVERFLOW + case EOVERFLOW: + prError = PR_IO_ERROR; + break; +#endif + case EINVAL: + prError = PR_IO_ERROR; + break; + case ENXIO: + prError = PR_IO_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_unlink_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EPERM: + prError = PR_IS_DIRECTORY_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_stat_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ETIMEDOUT: + prError = PR_REMOTE_FILE_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_fstat_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ETIMEDOUT: + prError = PR_REMOTE_FILE_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_rename_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EEXIST: + prError = PR_DIRECTORY_NOT_EMPTY_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_access_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ETIMEDOUT: + prError = PR_REMOTE_FILE_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_mkdir_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_rmdir_error(int err) +{ + PRErrorCode prError; + + switch (err) { + /* + * On AIX 4.3, ENOTEMPTY is defined as EEXIST. + */ +#if ENOTEMPTY != EEXIST + case ENOTEMPTY: + prError = PR_DIRECTORY_NOT_EMPTY_ERROR; + break; +#endif + case EEXIST: + prError = PR_DIRECTORY_NOT_EMPTY_ERROR; + break; + case EINVAL: + prError = PR_DIRECTORY_NOT_EMPTY_ERROR; + break; + case ETIMEDOUT: + prError = PR_REMOTE_FILE_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_read_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EINVAL: + prError = PR_INVALID_METHOD_ERROR; + break; + case ENXIO: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_write_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EINVAL: + prError = PR_INVALID_METHOD_ERROR; + break; + case ENXIO: + prError = PR_INVALID_METHOD_ERROR; + break; + case ETIMEDOUT: + prError = PR_REMOTE_FILE_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_lseek_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_fsync_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ETIMEDOUT: + prError = PR_REMOTE_FILE_ERROR; + break; + case EINVAL: + prError = PR_INVALID_METHOD_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_close_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ETIMEDOUT: + prError = PR_REMOTE_FILE_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_socket_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ENOMEM: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_socketavailable_error(int err) +{ + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); +} + +void _MD_unix_map_recv_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_recvfrom_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_send_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_sendto_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_writev_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_accept_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ENODEV: + prError = PR_NOT_TCP_SOCKET_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_connect_error(int err) +{ + PRErrorCode prError; + + switch (err) { +#if defined(UNIXWARE) + /* + * On some platforms, if we connect to a port on the local host + * (the loopback address) that no process is listening on, we get + * EIO instead of ECONNREFUSED. + */ + case EIO: + prError = PR_CONNECT_REFUSED_ERROR; + break; +#endif + case ENXIO: + prError = PR_IO_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_bind_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EINVAL: + prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_listen_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_shutdown_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_socketpair_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ENOMEM: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_getsockname_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ENOMEM: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_getpeername_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case ENOMEM: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_getsockopt_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EINVAL: + prError = PR_BUFFER_OVERFLOW_ERROR; + break; + case ENOMEM: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_setsockopt_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EINVAL: + prError = PR_BUFFER_OVERFLOW_ERROR; + break; + case ENOMEM: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_open_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EAGAIN: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case EBUSY: + prError = PR_IO_ERROR; + break; + case ENODEV: + prError = PR_FILE_NOT_FOUND_ERROR; + break; + case ENOMEM: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; +#ifdef EOVERFLOW + case EOVERFLOW: + prError = PR_FILE_TOO_BIG_ERROR; + break; +#endif + case ETIMEDOUT: + prError = PR_REMOTE_FILE_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_mmap_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EAGAIN: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case EMFILE: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case ENODEV: + prError = PR_OPERATION_NOT_SUPPORTED_ERROR; + break; + case ENXIO: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_gethostname_error(int err) +{ + _MD_unix_map_default_error(err); +} + +void _MD_unix_map_select_error(int err) +{ + _MD_unix_map_default_error(err); +} + +#if defined(_PR_POLL_AVAILABLE) || defined(_PR_NEED_FAKE_POLL) +void _MD_unix_map_poll_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EAGAIN: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_poll_revents_error(int err) +{ + if (err & POLLNVAL) + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF); + else if (err & POLLHUP) + PR_SetError(PR_CONNECT_RESET_ERROR, EPIPE); + else if (err & POLLERR) + PR_SetError(PR_IO_ERROR, EIO); + else + PR_SetError(PR_UNKNOWN_ERROR, err); +} +#endif /* _PR_POLL_AVAILABLE || _PR_NEED_FAKE_POLL */ + + +void _MD_unix_map_flock_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EINVAL: + prError = PR_BAD_DESCRIPTOR_ERROR; + break; + case EWOULDBLOCK: + prError = PR_FILE_IS_LOCKED_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_unix_map_lockf_error(int err) +{ + PRErrorCode prError; + + switch (err) { + case EACCES: + prError = PR_FILE_IS_LOCKED_ERROR; + break; + case EDEADLK: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + default: + _MD_unix_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +#ifdef AIX +void _MD_aix_map_sendfile_error(int err) +{ + _MD_unix_map_default_error(err); +} +#endif /* AIX */ + +#ifdef HPUX11 +void _MD_hpux_map_sendfile_error(int err) +{ + _MD_unix_map_default_error(err); +} +#endif /* HPUX11 */ + +#ifdef SOLARIS +void _MD_solaris_map_sendfile_error(int err) +{ + PRErrorCode prError; + + switch (err) { + /* + * Solaris defines a 0 return value for sendfile to mean end-of-file. + */ + case 0: + prError = PR_END_OF_FILE_ERROR; + break; + + default: + _MD_unix_map_default_error(err) ; + return; + } + PR_SetError(prError, err); +} +#endif /* SOLARIS */ + +#ifdef LINUX +void _MD_linux_map_sendfile_error(int err) +{ + _MD_unix_map_default_error(err) ; +} +#endif /* LINUX */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/unixware.c nspr-4.10.7/nspr/pr/src/md/unix/unixware.c --- nspr-4.9.5/nspr/pr/src/md/unix/unixware.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/unixware.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,551 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#if !defined (USE_SVR4_THREADS) + +/* + * using only NSPR threads here + */ + +#include + +void _MD_EarlyInit(void) +{ +} + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + if (isCurrent) { + (void) setjmp(CONTEXT(t)); + } + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); + return (PRWord *) CONTEXT(t); +} + +#ifdef ALARMS_BREAK_TCP /* I don't think they do */ + +PRInt32 _MD_connect(PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, + PRIntervalTime timeout) +{ + PRInt32 rv; + + _MD_BLOCK_CLOCK_INTERRUPTS(); + rv = _connect(osfd,addr,addrlen); + _MD_UNBLOCK_CLOCK_INTERRUPTS(); +} + +PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen, + PRIntervalTime timeout) +{ + PRInt32 rv; + + _MD_BLOCK_CLOCK_INTERRUPTS(); + rv = _accept(osfd,addr,addrlen); + _MD_UNBLOCK_CLOCK_INTERRUPTS(); + return(rv); +} +#endif + +/* + * These are also implemented in pratom.c using NSPR locks. Any reason + * this might be better or worse? If you like this better, define + * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h + */ +#ifdef _PR_HAVE_ATOMIC_OPS +/* Atomic operations */ +#include +static FILE *_uw_semf; + +void +_MD_INIT_ATOMIC(void) +{ + /* Sigh. Sure wish SYSV semaphores weren't such a pain to use */ + if ((_uw_semf = tmpfile()) == NULL) + PR_ASSERT(0); + + return; +} + +void +_MD_ATOMIC_INCREMENT(PRInt32 *val) +{ + flockfile(_uw_semf); + (*val)++; + unflockfile(_uw_semf); +} + +void +_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) +{ + flockfile(_uw_semf); + (*ptr) += val; + unflockfile(_uw_semf); +} + +void +_MD_ATOMIC_DECREMENT(PRInt32 *val) +{ + flockfile(_uw_semf); + (*val)--; + unflockfile(_uw_semf); +} + +void +_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) +{ + flockfile(_uw_semf); + *val = newval; + unflockfile(_uw_semf); +} +#endif + +void +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) +{ + return; +} + +PRStatus +_MD_InitializeThread(PRThread *thread) +{ + return PR_SUCCESS; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + _PR_MD_SWITCH_CONTEXT(thread); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread) { + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); + } + return PR_SUCCESS; +} + +/* These functions should not be called for Unixware */ +void +_MD_YIELD(void) +{ + PR_NOT_REACHED("_MD_YIELD should not be called for Unixware."); +} + +PRStatus +_MD_CREATE_THREAD( + PRThread *thread, + void (*start) (void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware."); +} + +#else /* USE_SVR4_THREADS */ + +/* NOTE: + * SPARC v9 (Ultras) do have an atomic test-and-set operation. But + * SPARC v8 doesn't. We should detect in the init if we are running on + * v8 or v9, and then use assembly where we can. + */ + +#include +#include + +static mutex_t _unixware_atomic = DEFAULTMUTEX; + +#define TEST_THEN_ADD(where, inc) \ + if (mutex_lock(&_unixware_atomic) != 0)\ + PR_ASSERT(0);\ + *where += inc;\ + if (mutex_unlock(&_unixware_atomic) != 0)\ + PR_ASSERT(0); + +#define TEST_THEN_SET(where, val) \ + if (mutex_lock(&_unixware_atomic) != 0)\ + PR_ASSERT(0);\ + *where = val;\ + if (mutex_unlock(&_unixware_atomic) != 0)\ + PR_ASSERT(0); + +void +_MD_INIT_ATOMIC(void) +{ +} + +void +_MD_ATOMIC_INCREMENT(PRInt32 *val) +{ + TEST_THEN_ADD(val, 1); +} + +void +_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) +{ + TEST_THEN_ADD(ptr, val); +} + +void +_MD_ATOMIC_DECREMENT(PRInt32 *val) +{ + TEST_THEN_ADD(val, 0xffffffff); +} + +void +_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) +{ + TEST_THEN_SET(val, newval); +} + +#include +#include +#include + +#include +#include +#include + + +THREAD_KEY_T threadid_key; +THREAD_KEY_T cpuid_key; +THREAD_KEY_T last_thread_key; +static sigset_t set, oldset; + +void _MD_EarlyInit(void) +{ + THR_KEYCREATE(&threadid_key, NULL); + THR_KEYCREATE(&cpuid_key, NULL); + THR_KEYCREATE(&last_thread_key, NULL); + sigemptyset(&set); + sigaddset(&set, SIGALRM); +} + +PRStatus _MD_CREATE_THREAD(PRThread *thread, + void (*start)(void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + long flags; + + /* mask out SIGALRM for native thread creation */ + thr_sigsetmask(SIG_BLOCK, &set, &oldset); + + flags = (state == PR_JOINABLE_THREAD ? THR_SUSPENDED/*|THR_NEW_LWP*/ + : THR_SUSPENDED|THR_DETACHED/*|THR_NEW_LWP*/); + if (_PR_IS_GCABLE_THREAD(thread) || + (scope == PR_GLOBAL_BOUND_THREAD)) + flags |= THR_BOUND; + + if (thr_create(NULL, thread->stack->stackSize, + (void *(*)(void *)) start, (void *) thread, + flags, + &thread->md.handle)) { + thr_sigsetmask(SIG_SETMASK, &oldset, NULL); + return PR_FAILURE; + } + + + /* When the thread starts running, then the lwpid is set to the right + * value. Until then we want to mark this as 'uninit' so that + * its register state is initialized properly for GC */ + + thread->md.lwpid = -1; + thr_sigsetmask(SIG_SETMASK, &oldset, NULL); + _MD_NEW_SEM(&thread->md.waiter_sem, 0); + + if ((scope == PR_GLOBAL_THREAD) || (scope == PR_GLOBAL_BOUND_THREAD)) { + thread->flags |= _PR_GLOBAL_SCOPE; + } + + /* + ** Set the thread priority. This will also place the thread on + ** the runQ. + ** + ** Force PR_SetThreadPriority to set the priority by + ** setting thread->priority to 100. + */ + { + int pri; + pri = thread->priority; + thread->priority = 100; + PR_SetThreadPriority( thread, pri ); + + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("(0X%x)[Start]: on to runq at priority %d", + thread, thread->priority)); + } + + /* Activate the thread */ + if (thr_continue( thread->md.handle ) ) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +void _MD_cleanup_thread(PRThread *thread) +{ + thread_t hdl; + PRMonitor *mon; + + hdl = thread->md.handle; + + /* + ** First, suspend the thread (unless it's the active one) + ** Because we suspend it first, we don't have to use LOCK_SCHEDULER to + ** prevent both of us modifying the thread structure at the same time. + */ + if ( thread != _PR_MD_CURRENT_THREAD() ) { + thr_suspend(hdl); + } + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("(0X%x)[DestroyThread]\n", thread)); + + _MD_DESTROY_SEM(&thread->md.waiter_sem); +} + +void _MD_SET_PRIORITY(_MDThread *md_thread, PRUintn newPri) +{ + if(thr_setprio((thread_t)md_thread->handle, newPri)) { + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("_PR_SetThreadPriority: can't set thread priority\n")); + } +} + +void _MD_WAIT_CV( + struct _MDCVar *md_cv, struct _MDLock *md_lock, PRIntervalTime timeout) +{ + struct timespec tt; + PRUint32 msec; + int rv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + msec = PR_IntervalToMilliseconds(timeout); + + GETTIME (&tt); + + tt.tv_sec += msec / PR_MSEC_PER_SEC; + tt.tv_nsec += (msec % PR_MSEC_PER_SEC) * PR_NSEC_PER_MSEC; + /* Check for nsec overflow - otherwise we'll get an EINVAL */ + if (tt.tv_nsec >= PR_NSEC_PER_SEC) { + tt.tv_sec++; + tt.tv_nsec -= PR_NSEC_PER_SEC; + } + me->md.sp = unixware_getsp(); + + + /* XXX Solaris 2.5.x gives back EINTR occasionally for no reason + * hence ignore EINTR for now */ + + COND_TIMEDWAIT(&md_cv->cv, &md_lock->lock, &tt); +} + +void _MD_lock(struct _MDLock *md_lock) +{ + mutex_lock(&md_lock->lock); +} + +void _MD_unlock(struct _MDLock *md_lock) +{ + mutex_unlock(&((md_lock)->lock)); +} + + +PRThread *_pr_current_thread_tls() +{ + PRThread *ret; + + thr_getspecific(threadid_key, (void **)&ret); + return ret; +} + +PRStatus +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + _MD_WAIT_SEM(&thread->md.waiter_sem); + return PR_SUCCESS; +} + +PRStatus +_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread == NULL) { + return PR_SUCCESS; + } + _MD_POST_SEM(&thread->md.waiter_sem); + return PR_SUCCESS; +} + +_PRCPU *_pr_current_cpu_tls() +{ + _PRCPU *ret; + + thr_getspecific(cpuid_key, (void **)&ret); + return ret; +} + +PRThread *_pr_last_thread_tls() +{ + PRThread *ret; + + thr_getspecific(last_thread_key, (void **)&ret); + return ret; +} + +_MDLock _pr_ioq_lock; + +void _MD_INIT_IO (void) +{ + _MD_NEW_LOCK(&_pr_ioq_lock); +} + +PRStatus _MD_InitializeThread(PRThread *thread) +{ + if (!_PR_IS_NATIVE_THREAD(thread)) + return; + /* prime the sp; substract 4 so we don't hit the assert that + * curr sp > base_stack + */ + thread->md.sp = (uint_t) thread->stack->allocBase - sizeof(long); + thread->md.lwpid = _lwp_self(); + thread->md.handle = THR_SELF(); + + /* all threads on Solaris are global threads from NSPR's perspective + * since all of them are mapped to Solaris threads. + */ + thread->flags |= _PR_GLOBAL_SCOPE; + + /* For primordial/attached thread, we don't create an underlying native thread. + * So, _MD_CREATE_THREAD() does not get called. We need to do initialization + * like allocating thread's synchronization variables and set the underlying + * native thread's priority. + */ + if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { + _MD_NEW_SEM(&thread->md.waiter_sem, 0); + _MD_SET_PRIORITY(&(thread->md), thread->priority); + } + return PR_SUCCESS; +} + +static sigset_t old_mask; /* store away original gc thread sigmask */ +static int gcprio; /* store away original gc thread priority */ +static lwpid_t *all_lwps=NULL; /* list of lwps that we suspended */ +static int num_lwps ; +static int suspendAllOn = 0; + +#define VALID_SP(sp, bottom, top) \ + (((uint_t)(sp)) > ((uint_t)(bottom)) && ((uint_t)(sp)) < ((uint_t)(top))) + +void unixware_preempt_off() +{ + sigset_t set; + (void)sigfillset(&set); + sigprocmask (SIG_SETMASK, &set, &old_mask); +} + +void unixware_preempt_on() +{ + sigprocmask (SIG_SETMASK, &old_mask, NULL); +} + +void _MD_Begin_SuspendAll() +{ + unixware_preempt_off(); + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin_SuspendAll\n")); + /* run at highest prio so I cannot be preempted */ + thr_getprio(thr_self(), &gcprio); + thr_setprio(thr_self(), 0x7fffffff); + suspendAllOn = 1; +} + +void _MD_End_SuspendAll() +{ +} + +void _MD_End_ResumeAll() +{ + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End_ResumeAll\n")); + thr_setprio(thr_self(), gcprio); + unixware_preempt_on(); + suspendAllOn = 0; +} + +void _MD_Suspend(PRThread *thr) +{ + int lwp_fd, result; + int lwp_main_proc_fd = 0; + + thr_suspend(thr->md.handle); + if (!_PR_IS_GCABLE_THREAD(thr)) + return; + /* XXX Primordial thread can't be bound to an lwp, hence there is no + * way we can assume that we can get the lwp status for primordial + * thread reliably. Hence we skip this for primordial thread, hoping + * that the SP is saved during lock and cond. wait. + * XXX - Again this is concern only for java interpreter, not for the + * server, 'cause primordial thread in the server does not do java work + */ + if (thr->flags & _PR_PRIMORDIAL) + return; + + /* if the thread is not started yet then don't do anything */ + if (!suspendAllOn || thr->md.lwpid == -1) + return; + +} +void _MD_Resume(PRThread *thr) +{ + if (!_PR_IS_GCABLE_THREAD(thr) || !suspendAllOn){ + /*XXX When the suspendAllOn is set, we will be trying to do lwp_suspend + * during that time we can't call any thread lib or libc calls. Hence + * make sure that no resume is requested for Non gcable thread + * during suspendAllOn */ + PR_ASSERT(!suspendAllOn); + thr_continue(thr->md.handle); + return; + } + if (thr->md.lwpid == -1) + return; + + if ( _lwp_continue(thr->md.lwpid) < 0) { + PR_ASSERT(0); /* ARGH, we are hosed! */ + } +} + + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ + if (isCurrent) { + (void) getcontext(CONTEXT(t)); /* XXX tune me: set md_IRIX.c */ + } + *np = NGREG; + if (t->md.lwpid == -1) + memset(&t->md.context.uc_mcontext.gregs[0], 0, NGREG * sizeof(PRWord)); + return (PRWord*) &t->md.context.uc_mcontext.gregs[0]; +} + +int +_pr_unixware_clock_gettime (struct timespec *tp) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * 1000; + return 0; +} + + +#endif /* USE_SVR4_THREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/uxpoll.c nspr-4.10.7/nspr/pr/src/md/unix/uxpoll.c --- nspr-4.9.5/nspr/pr/src/md/unix/uxpoll.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/uxpoll.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,676 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if defined(_PR_PTHREADS) + +#error "This file should not be compiled" + +#else /* defined(_PR_PTHREADS) */ + +#include "primpl.h" + +#include + +#include +#ifdef _PR_USE_POLL +#include +#endif + +#if defined(_PR_USE_POLL) +static PRInt32 NativeThreadPoll( + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + /* + * This function is mostly duplicated from ptio.s's PR_Poll(). + */ + PRInt32 ready = 0; + /* + * For restarting poll() if it is interrupted by a signal. + * We use these variables to figure out how much time has + * elapsed and how much of the timeout still remains. + */ + PRIntn index, msecs; + struct pollfd *syspoll = NULL; + PRIntervalTime start, elapsed, remaining; + + syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd)); + if (NULL == syspoll) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + for (index = 0; index < npds; ++index) + { + PRFileDesc *bottom; + PRInt16 in_flags_read = 0, in_flags_write = 0; + PRInt16 out_flags_read = 0, out_flags_write = 0; + + if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) + { + if (pds[index].in_flags & PR_POLL_READ) + { + in_flags_read = (pds[index].fd->methods->poll)( + pds[index].fd, + pds[index].in_flags & ~PR_POLL_WRITE, + &out_flags_read); + } + if (pds[index].in_flags & PR_POLL_WRITE) + { + in_flags_write = (pds[index].fd->methods->poll)( + pds[index].fd, + pds[index].in_flags & ~PR_POLL_READ, + &out_flags_write); + } + if ((0 != (in_flags_read & out_flags_read)) + || (0 != (in_flags_write & out_flags_write))) + { + /* this one is ready right now */ + if (0 == ready) + { + /* + * We will return without calling the system + * poll function. So zero the out_flags + * fields of all the poll descriptors before + * this one. + */ + int i; + for (i = 0; i < index; i++) + { + pds[i].out_flags = 0; + } + } + ready += 1; + pds[index].out_flags = out_flags_read | out_flags_write; + } + else + { + pds[index].out_flags = 0; /* pre-condition */ + /* now locate the NSPR layer at the bottom of the stack */ + bottom = PR_GetIdentitiesLayer(pds[index].fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); /* what to do about that? */ + if ((NULL != bottom) + && (_PR_FILEDESC_OPEN == bottom->secret->state)) + { + if (0 == ready) + { + syspoll[index].fd = bottom->secret->md.osfd; + syspoll[index].events = 0; /* pre-condition */ + if (in_flags_read & PR_POLL_READ) + { + pds[index].out_flags |= + _PR_POLL_READ_SYS_READ; + syspoll[index].events |= POLLIN; + } + if (in_flags_read & PR_POLL_WRITE) + { + pds[index].out_flags |= + _PR_POLL_READ_SYS_WRITE; + syspoll[index].events |= POLLOUT; + } + if (in_flags_write & PR_POLL_READ) + { + pds[index].out_flags |= + _PR_POLL_WRITE_SYS_READ; + syspoll[index].events |= POLLIN; + } + if (in_flags_write & PR_POLL_WRITE) + { + pds[index].out_flags |= + _PR_POLL_WRITE_SYS_WRITE; + syspoll[index].events |= POLLOUT; + } + if (pds[index].in_flags & PR_POLL_EXCEPT) + syspoll[index].events |= POLLPRI; + } + } + else + { + if (0 == ready) + { + int i; + for (i = 0; i < index; i++) + { + pds[i].out_flags = 0; + } + } + ready += 1; /* this will cause an abrupt return */ + pds[index].out_flags = PR_POLL_NVAL; /* bogii */ + } + } + } + else + { + /* make poll() ignore this entry */ + syspoll[index].fd = -1; + syspoll[index].events = 0; + pds[index].out_flags = 0; + } + } + + if (0 == ready) + { + switch (timeout) + { + case PR_INTERVAL_NO_WAIT: msecs = 0; break; + case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break; + default: + msecs = PR_IntervalToMilliseconds(timeout); + start = PR_IntervalNow(); + } + +retry: + ready = _MD_POLL(syspoll, npds, msecs); + if (-1 == ready) + { + PRIntn oserror = errno; + + if (EINTR == oserror) + { + if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; + else if (timeout == PR_INTERVAL_NO_WAIT) ready = 0; + else + { + elapsed = (PRIntervalTime)(PR_IntervalNow() - start); + if (elapsed > timeout) ready = 0; /* timed out */ + else + { + remaining = timeout - elapsed; + msecs = PR_IntervalToMilliseconds(remaining); + goto retry; + } + } + } + else _PR_MD_MAP_POLL_ERROR(oserror); + } + else if (ready > 0) + { + for (index = 0; index < npds; ++index) + { + PRInt16 out_flags = 0; + if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) + { + if (0 != syspoll[index].revents) + { + /* + ** Set up the out_flags so that it contains the + ** bits that the highest layer thinks are nice + ** to have. Then the client of that layer will + ** call the appropriate I/O function and maybe + ** the protocol will make progress. + */ + if (syspoll[index].revents & POLLIN) + { + if (pds[index].out_flags + & _PR_POLL_READ_SYS_READ) + { + out_flags |= PR_POLL_READ; + } + if (pds[index].out_flags + & _PR_POLL_WRITE_SYS_READ) + { + out_flags |= PR_POLL_WRITE; + } + } + if (syspoll[index].revents & POLLOUT) + { + if (pds[index].out_flags + & _PR_POLL_READ_SYS_WRITE) + { + out_flags |= PR_POLL_READ; + } + if (pds[index].out_flags + & _PR_POLL_WRITE_SYS_WRITE) + { + out_flags |= PR_POLL_WRITE; + } + } + if (syspoll[index].revents & POLLPRI) + out_flags |= PR_POLL_EXCEPT; + if (syspoll[index].revents & POLLERR) + out_flags |= PR_POLL_ERR; + if (syspoll[index].revents & POLLNVAL) + out_flags |= PR_POLL_NVAL; + if (syspoll[index].revents & POLLHUP) + out_flags |= PR_POLL_HUP; + } + } + pds[index].out_flags = out_flags; + } + } + } + + PR_DELETE(syspoll); + return ready; + +} /* NativeThreadPoll */ +#endif /* defined(_PR_USE_POLL) */ + +#if !defined(_PR_USE_POLL) +static PRInt32 NativeThreadSelect( + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + /* + * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL(). + */ + fd_set rd, wt, ex; + PRFileDesc *bottom; + PRPollDesc *pd, *epd; + PRInt32 maxfd = -1, ready, err; + PRIntervalTime remaining, elapsed, start; + + struct timeval tv, *tvp = NULL; + + FD_ZERO(&rd); + FD_ZERO(&wt); + FD_ZERO(&ex); + + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRInt16 in_flags_read = 0, in_flags_write = 0; + PRInt16 out_flags_read = 0, out_flags_write = 0; + + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + if (pd->in_flags & PR_POLL_READ) + { + in_flags_read = (pd->fd->methods->poll)( + pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); + } + if (pd->in_flags & PR_POLL_WRITE) + { + in_flags_write = (pd->fd->methods->poll)( + pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); + } + if ((0 != (in_flags_read & out_flags_read)) + || (0 != (in_flags_write & out_flags_write))) + { + /* this one's ready right now */ + if (0 == ready) + { + /* + * We will have to return without calling the + * system poll/select function. So zero the + * out_flags fields of all the poll descriptors + * before this one. + */ + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; + pd->out_flags = out_flags_read | out_flags_write; + } + else + { + pd->out_flags = 0; /* pre-condition */ + + /* make sure this is an NSPR supported stack */ + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); /* what to do about that? */ + if ((NULL != bottom) + && (_PR_FILEDESC_OPEN == bottom->secret->state)) + { + if (0 == ready) + { + PRInt32 osfd = bottom->secret->md.osfd; + if (osfd > maxfd) maxfd = osfd; + if (in_flags_read & PR_POLL_READ) + { + pd->out_flags |= _PR_POLL_READ_SYS_READ; + FD_SET(osfd, &rd); + } + if (in_flags_read & PR_POLL_WRITE) + { + pd->out_flags |= _PR_POLL_READ_SYS_WRITE; + FD_SET(osfd, &wt); + } + if (in_flags_write & PR_POLL_READ) + { + pd->out_flags |= _PR_POLL_WRITE_SYS_READ; + FD_SET(osfd, &rd); + } + if (in_flags_write & PR_POLL_WRITE) + { + pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; + FD_SET(osfd, &wt); + } + if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex); + } + } + else + { + if (0 == ready) + { + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; /* this will cause an abrupt return */ + pd->out_flags = PR_POLL_NVAL; /* bogii */ + } + } + } + else + { + pd->out_flags = 0; + } + } + + if (0 != ready) return ready; /* no need to block */ + + remaining = timeout; + start = PR_IntervalNow(); + +retry: + if (timeout != PR_INTERVAL_NO_TIMEOUT) + { + PRInt32 ticksPerSecond = PR_TicksPerSecond(); + tv.tv_sec = remaining / ticksPerSecond; + tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond ); + tvp = &tv; + } + + ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp); + + if (ready == -1 && errno == EINTR) + { + if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry; + else + { + elapsed = (PRIntervalTime) (PR_IntervalNow() - start); + if (elapsed > timeout) ready = 0; /* timed out */ + else + { + remaining = timeout - elapsed; + goto retry; + } + } + } + + /* + ** Now to unravel the select sets back into the client's poll + ** descriptor list. Is this possibly an area for pissing away + ** a few cycles or what? + */ + if (ready > 0) + { + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRInt16 out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + PRInt32 osfd; + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + + osfd = bottom->secret->md.osfd; + + if (FD_ISSET(osfd, &rd)) + { + if (pd->out_flags & _PR_POLL_READ_SYS_READ) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) + out_flags |= PR_POLL_WRITE; + } + if (FD_ISSET(osfd, &wt)) + { + if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) + out_flags |= PR_POLL_WRITE; + } + if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; + } + pd->out_flags = out_flags; + if (out_flags) ready++; + } + PR_ASSERT(ready > 0); + } + else if (ready < 0) + { + err = _MD_ERRNO(); + if (err == EBADF) + { + /* Find the bad fds */ + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + pd->out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1) + { + pd->out_flags = PR_POLL_NVAL; + ready++; + } + } + } + PR_ASSERT(ready > 0); + } + else _PR_MD_MAP_SELECT_ERROR(err); + } + + return ready; +} /* NativeThreadSelect */ +#endif /* !defined(_PR_USE_POLL) */ + +static PRInt32 LocalThreads( + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + PRPollDesc *pd, *epd; + PRInt32 ready, pdcnt; + _PRUnixPollDesc *unixpds, *unixpd; + + /* + * XXX + * PRPollDesc has a PRFileDesc field, fd, while the IOQ + * is a list of PRPollQueue structures, each of which contains + * a _PRUnixPollDesc. A _PRUnixPollDesc struct contains + * the OS file descriptor, osfd, and not a PRFileDesc. + * So, we have allocate memory for _PRUnixPollDesc structures, + * copy the flags information from the pds list and have pq + * point to this list of _PRUnixPollDesc structures. + * + * It would be better if the memory allocation can be avoided. + */ + + unixpd = unixpds = (_PRUnixPollDesc*) + PR_MALLOC(npds * sizeof(_PRUnixPollDesc)); + if (NULL == unixpds) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + + ready = 0; + for (pdcnt = 0, pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRFileDesc *bottom; + PRInt16 in_flags_read = 0, in_flags_write = 0; + PRInt16 out_flags_read = 0, out_flags_write = 0; + + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + if (pd->in_flags & PR_POLL_READ) + { + in_flags_read = (pd->fd->methods->poll)( + pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read); + } + if (pd->in_flags & PR_POLL_WRITE) + { + in_flags_write = (pd->fd->methods->poll)( + pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write); + } + if ((0 != (in_flags_read & out_flags_read)) + || (0 != (in_flags_write & out_flags_write))) + { + /* this one's ready right now */ + if (0 == ready) + { + /* + * We will have to return without calling the + * system poll/select function. So zero the + * out_flags fields of all the poll descriptors + * before this one. + */ + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; + pd->out_flags = out_flags_read | out_flags_write; + } + else + { + pd->out_flags = 0; /* pre-condition */ + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); /* what to do about that? */ + if ((NULL != bottom) + && (_PR_FILEDESC_OPEN == bottom->secret->state)) + { + if (0 == ready) + { + unixpd->osfd = bottom->secret->md.osfd; + unixpd->in_flags = 0; + if (in_flags_read & PR_POLL_READ) + { + unixpd->in_flags |= _PR_UNIX_POLL_READ; + pd->out_flags |= _PR_POLL_READ_SYS_READ; + } + if (in_flags_read & PR_POLL_WRITE) + { + unixpd->in_flags |= _PR_UNIX_POLL_WRITE; + pd->out_flags |= _PR_POLL_READ_SYS_WRITE; + } + if (in_flags_write & PR_POLL_READ) + { + unixpd->in_flags |= _PR_UNIX_POLL_READ; + pd->out_flags |= _PR_POLL_WRITE_SYS_READ; + } + if (in_flags_write & PR_POLL_WRITE) + { + unixpd->in_flags |= _PR_UNIX_POLL_WRITE; + pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; + } + if ((in_flags_read | in_flags_write) & PR_POLL_EXCEPT) + { + unixpd->in_flags |= _PR_UNIX_POLL_EXCEPT; + } + unixpd++; pdcnt++; + } + } + else + { + if (0 == ready) + { + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; /* this will cause an abrupt return */ + pd->out_flags = PR_POLL_NVAL; /* bogii */ + } + } + } + } + + if (0 != ready) + { + /* no need to block */ + PR_DELETE(unixpds); + return ready; + } + + ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout); + + /* + * Copy the out_flags from the _PRUnixPollDesc structures to the + * user's PRPollDesc structures and free the allocated memory + */ + unixpd = unixpds; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRInt16 out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + /* + * take errors from the poll operation, + * the R/W bits from the request + */ + if (0 != unixpd->out_flags) + { + if (unixpd->out_flags & _PR_UNIX_POLL_READ) + { + if (pd->out_flags & _PR_POLL_READ_SYS_READ) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) + out_flags |= PR_POLL_WRITE; + } + if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) + { + if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) + out_flags |= PR_POLL_WRITE; + } + if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) + out_flags |= PR_POLL_EXCEPT; + if (unixpd->out_flags & _PR_UNIX_POLL_ERR) + out_flags |= PR_POLL_ERR; + if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) + out_flags |= PR_POLL_NVAL; + if (unixpd->out_flags & _PR_UNIX_POLL_HUP) + out_flags |= PR_POLL_HUP; + } + unixpd++; + } + pd->out_flags = out_flags; + } + + PR_DELETE(unixpds); + + return ready; +} /* LocalThreads */ + +#if defined(_PR_USE_POLL) +#define NativeThreads NativeThreadPoll +#else +#define NativeThreads NativeThreadSelect +#endif + +PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + PRInt32 rv = 0; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) + { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (0 == npds) PR_Sleep(timeout); + else if (_PR_IS_NATIVE_THREAD(me)) + rv = NativeThreads(pds, npds, timeout); + else rv = LocalThreads(pds, npds, timeout); + + return rv; +} /* _MD_pr_poll */ + +#endif /* defined(_PR_PTHREADS) */ + +/* uxpoll.c */ + diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/uxproces.c nspr-4.10.7/nspr/pr/src/md/unix/uxproces.c --- nspr-4.9.5/nspr/pr/src/md/unix/uxproces.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/uxproces.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,885 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include +#include +#include +#include +#include +#if defined(AIX) +#include /* For dlopen, dlsym, dlclose */ +#endif + +#if defined(DARWIN) +#if defined(HAVE_CRT_EXTERNS_H) +#include +#endif +#else +PR_IMPORT_DATA(char **) environ; +#endif + +/* + * HP-UX 9 doesn't have the SA_RESTART flag. + */ +#ifndef SA_RESTART +#define SA_RESTART 0 +#endif + +/* + ********************************************************************** + * + * The Unix process routines + * + ********************************************************************** + */ + +#define _PR_SIGNALED_EXITSTATUS 256 + +typedef enum pr_PidState { + _PR_PID_DETACHED, + _PR_PID_REAPED, + _PR_PID_WAITING +} pr_PidState; + +typedef struct pr_PidRecord { + pid_t pid; + int exitStatus; + pr_PidState state; + PRCondVar *reapedCV; + struct pr_PidRecord *next; +} pr_PidRecord; + +/* + * Irix sprocs and LinuxThreads are actually a kind of processes + * that can share the virtual address space and file descriptors. + */ +#if (defined(IRIX) && !defined(_PR_PTHREADS)) \ + || ((defined(LINUX) || defined(__GNU__) || defined(__GLIBC__)) \ + && defined(_PR_PTHREADS)) +#define _PR_SHARE_CLONES +#endif + +/* + * The macro _PR_NATIVE_THREADS indicates that we are + * using native threads only, so waitpid() blocks just the + * calling thread, not the process. In this case, the waitpid + * daemon thread can safely block in waitpid(). So we don't + * need to catch SIGCHLD, and the pipe to unblock PR_Poll() is + * also not necessary. + */ + +#if defined(_PR_GLOBAL_THREADS_ONLY) \ + || (defined(_PR_PTHREADS) \ + && !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__)) +#define _PR_NATIVE_THREADS +#endif + +/* + * All the static variables used by the Unix process routines are + * collected in this structure. + */ + +static struct { + PRCallOnceType once; + PRThread *thread; + PRLock *ml; +#if defined(_PR_NATIVE_THREADS) + PRInt32 numProcs; + PRCondVar *cv; +#else + int pipefd[2]; +#endif + pr_PidRecord **pidTable; + +#ifdef _PR_SHARE_CLONES + struct pr_CreateProcOp *opHead, *opTail; +#endif + +#ifdef AIX + pid_t (*forkptr)(void); /* Newer versions of AIX (starting in 4.3.2) + * have f_fork, which is faster than the + * regular fork in a multithreaded process + * because it skips calling the fork handlers. + * So we look up the f_fork symbol to see if + * it's available and fall back on fork. + */ +#endif /* AIX */ +} pr_wp; + +#ifdef _PR_SHARE_CLONES +static int pr_waitpid_daemon_exit; + +void +_MD_unix_terminate_waitpid_daemon(void) +{ + if (pr_wp.thread) { + pr_waitpid_daemon_exit = 1; + write(pr_wp.pipefd[1], "", 1); + PR_JoinThread(pr_wp.thread); + } +} +#endif + +static PRStatus _MD_InitProcesses(void); +#if !defined(_PR_NATIVE_THREADS) +static void pr_InstallSigchldHandler(void); +#endif + +static PRProcess * +ForkAndExec( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr) +{ + PRProcess *process; + int nEnv, idx; + char *const *childEnvp; + char **newEnvp = NULL; + int flags; + + process = PR_NEW(PRProcess); + if (!process) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + childEnvp = envp; + if (attr && attr->fdInheritBuffer) { + PRBool found = PR_FALSE; + + if (NULL == childEnvp) { +#ifdef DARWIN +#ifdef HAVE_CRT_EXTERNS_H + childEnvp = *(_NSGetEnviron()); +#else + /* _NSGetEnviron() is not available on iOS. */ + PR_DELETE(process); + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +#endif +#else + childEnvp = environ; +#endif + } + + for (nEnv = 0; childEnvp[nEnv]; nEnv++) { + } + newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *)); + if (NULL == newEnvp) { + PR_DELETE(process); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + for (idx = 0; idx < nEnv; idx++) { + newEnvp[idx] = childEnvp[idx]; + if (!found && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) { + newEnvp[idx] = attr->fdInheritBuffer; + found = PR_TRUE; + } + } + if (!found) { + newEnvp[idx++] = attr->fdInheritBuffer; + } + newEnvp[idx] = NULL; + childEnvp = newEnvp; + } + +#ifdef AIX + process->md.pid = (*pr_wp.forkptr)(); +#elif defined(NTO) || defined(SYMBIAN) + /* + * fork() & exec() does not work in a multithreaded process. + * Use spawn() instead. + */ + { + int fd_map[3] = { 0, 1, 2 }; + + if (attr) { + if (attr->stdinFd && attr->stdinFd->secret->md.osfd != 0) { + fd_map[0] = dup(attr->stdinFd->secret->md.osfd); + flags = fcntl(fd_map[0], F_GETFL, 0); + if (flags & O_NONBLOCK) + fcntl(fd_map[0], F_SETFL, flags & ~O_NONBLOCK); + } + if (attr->stdoutFd && attr->stdoutFd->secret->md.osfd != 1) { + fd_map[1] = dup(attr->stdoutFd->secret->md.osfd); + flags = fcntl(fd_map[1], F_GETFL, 0); + if (flags & O_NONBLOCK) + fcntl(fd_map[1], F_SETFL, flags & ~O_NONBLOCK); + } + if (attr->stderrFd && attr->stderrFd->secret->md.osfd != 2) { + fd_map[2] = dup(attr->stderrFd->secret->md.osfd); + flags = fcntl(fd_map[2], F_GETFL, 0); + if (flags & O_NONBLOCK) + fcntl(fd_map[2], F_SETFL, flags & ~O_NONBLOCK); + } + + PR_ASSERT(attr->currentDirectory == NULL); /* not implemented */ + } + +#ifdef SYMBIAN + /* In Symbian OS, we use posix_spawn instead of fork() and exec() */ + posix_spawn(&(process->md.pid), path, NULL, NULL, argv, childEnvp); +#else + process->md.pid = spawn(path, 3, fd_map, NULL, argv, childEnvp); +#endif + + if (fd_map[0] != 0) + close(fd_map[0]); + if (fd_map[1] != 1) + close(fd_map[1]); + if (fd_map[2] != 2) + close(fd_map[2]); + } +#else + process->md.pid = fork(); +#endif + if ((pid_t) -1 == process->md.pid) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno); + PR_DELETE(process); + if (newEnvp) { + PR_DELETE(newEnvp); + } + return NULL; + } else if (0 == process->md.pid) { /* the child process */ + /* + * If the child process needs to exit, it must call _exit(). + * Do not call exit(), because exit() will flush and close + * the standard I/O file descriptors, and hence corrupt + * the parent process's standard I/O data structures. + */ + +#if !defined(NTO) && !defined(SYMBIAN) + if (attr) { + /* the osfd's to redirect stdin, stdout, and stderr to */ + int in_osfd = -1, out_osfd = -1, err_osfd = -1; + + if (attr->stdinFd + && attr->stdinFd->secret->md.osfd != 0) { + in_osfd = attr->stdinFd->secret->md.osfd; + if (dup2(in_osfd, 0) != 0) { + _exit(1); /* failed */ + } + flags = fcntl(0, F_GETFL, 0); + if (flags & O_NONBLOCK) { + fcntl(0, F_SETFL, flags & ~O_NONBLOCK); + } + } + if (attr->stdoutFd + && attr->stdoutFd->secret->md.osfd != 1) { + out_osfd = attr->stdoutFd->secret->md.osfd; + if (dup2(out_osfd, 1) != 1) { + _exit(1); /* failed */ + } + flags = fcntl(1, F_GETFL, 0); + if (flags & O_NONBLOCK) { + fcntl(1, F_SETFL, flags & ~O_NONBLOCK); + } + } + if (attr->stderrFd + && attr->stderrFd->secret->md.osfd != 2) { + err_osfd = attr->stderrFd->secret->md.osfd; + if (dup2(err_osfd, 2) != 2) { + _exit(1); /* failed */ + } + flags = fcntl(2, F_GETFL, 0); + if (flags & O_NONBLOCK) { + fcntl(2, F_SETFL, flags & ~O_NONBLOCK); + } + } + if (in_osfd != -1) { + close(in_osfd); + } + if (out_osfd != -1 && out_osfd != in_osfd) { + close(out_osfd); + } + if (err_osfd != -1 && err_osfd != in_osfd + && err_osfd != out_osfd) { + close(err_osfd); + } + if (attr->currentDirectory) { + if (chdir(attr->currentDirectory) < 0) { + _exit(1); /* failed */ + } + } + } + + if (childEnvp) { + (void)execve(path, argv, childEnvp); + } else { + /* Inherit the environment of the parent. */ + (void)execv(path, argv); + } + /* Whoops! It returned. That's a bad sign. */ + _exit(1); +#endif /* !NTO */ + } + + if (newEnvp) { + PR_DELETE(newEnvp); + } + +#if defined(_PR_NATIVE_THREADS) + PR_Lock(pr_wp.ml); + if (0 == pr_wp.numProcs++) { + PR_NotifyCondVar(pr_wp.cv); + } + PR_Unlock(pr_wp.ml); +#endif + return process; +} + +#ifdef _PR_SHARE_CLONES + +struct pr_CreateProcOp { + const char *path; + char *const *argv; + char *const *envp; + const PRProcessAttr *attr; + PRProcess *process; + PRErrorCode prerror; + PRInt32 oserror; + PRBool done; + PRCondVar *doneCV; + struct pr_CreateProcOp *next; +}; + +PRProcess * +_MD_CreateUnixProcess( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr) +{ + struct pr_CreateProcOp *op; + PRProcess *proc; + int rv; + + if (PR_CallOnce(&pr_wp.once, _MD_InitProcesses) == PR_FAILURE) { + return NULL; + } + + op = PR_NEW(struct pr_CreateProcOp); + if (NULL == op) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + op->path = path; + op->argv = argv; + op->envp = envp; + op->attr = attr; + op->done = PR_FALSE; + op->doneCV = PR_NewCondVar(pr_wp.ml); + if (NULL == op->doneCV) { + PR_DELETE(op); + return NULL; + } + PR_Lock(pr_wp.ml); + + /* add to the tail of op queue */ + op->next = NULL; + if (pr_wp.opTail) { + pr_wp.opTail->next = op; + pr_wp.opTail = op; + } else { + PR_ASSERT(NULL == pr_wp.opHead); + pr_wp.opHead = pr_wp.opTail = op; + } + + /* wake up the daemon thread */ + do { + rv = write(pr_wp.pipefd[1], "", 1); + } while (-1 == rv && EINTR == errno); + + while (op->done == PR_FALSE) { + PR_WaitCondVar(op->doneCV, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(pr_wp.ml); + PR_DestroyCondVar(op->doneCV); + proc = op->process; + if (!proc) { + PR_SetError(op->prerror, op->oserror); + } + PR_DELETE(op); + return proc; +} + +#else /* ! _PR_SHARE_CLONES */ + +PRProcess * +_MD_CreateUnixProcess( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr) +{ + if (PR_CallOnce(&pr_wp.once, _MD_InitProcesses) == PR_FAILURE) { + return NULL; + } + return ForkAndExec(path, argv, envp, attr); +} /* _MD_CreateUnixProcess */ + +#endif /* _PR_SHARE_CLONES */ + +/* + * The pid table is a hashtable. + * + * The number of buckets in the hashtable (NBUCKETS) must be a power of 2. + */ +#define NBUCKETS_LOG2 6 +#define NBUCKETS (1 << NBUCKETS_LOG2) +#define PID_HASH_MASK ((pid_t) (NBUCKETS - 1)) + +static pr_PidRecord * +FindPidTable(pid_t pid) +{ + pr_PidRecord *pRec; + int keyHash = (int) (pid & PID_HASH_MASK); + + pRec = pr_wp.pidTable[keyHash]; + while (pRec) { + if (pRec->pid == pid) { + break; + } + pRec = pRec->next; + } + return pRec; +} + +static void +InsertPidTable(pr_PidRecord *pRec) +{ + int keyHash = (int) (pRec->pid & PID_HASH_MASK); + + pRec->next = pr_wp.pidTable[keyHash]; + pr_wp.pidTable[keyHash] = pRec; +} + +static void +DeletePidTable(pr_PidRecord *pRec) +{ + int keyHash = (int) (pRec->pid & PID_HASH_MASK); + + if (pr_wp.pidTable[keyHash] == pRec) { + pr_wp.pidTable[keyHash] = pRec->next; + } else { + pr_PidRecord *pred, *cur; /* predecessor and current */ + + pred = pr_wp.pidTable[keyHash]; + cur = pred->next; + while (cur) { + if (cur == pRec) { + pred->next = cur->next; + break; + } + pred = cur; + cur = cur->next; + } + PR_ASSERT(cur != NULL); + } +} + +static int +ExtractExitStatus(int rawExitStatus) +{ + /* + * We did not specify the WCONTINUED and WUNTRACED options + * for waitpid, so these two events should not be reported. + */ + PR_ASSERT(!WIFSTOPPED(rawExitStatus)); +#ifdef WIFCONTINUED + PR_ASSERT(!WIFCONTINUED(rawExitStatus)); +#endif + if (WIFEXITED(rawExitStatus)) { + return WEXITSTATUS(rawExitStatus); + } else { + PR_ASSERT(WIFSIGNALED(rawExitStatus)); + return _PR_SIGNALED_EXITSTATUS; + } +} + +static void +ProcessReapedChildInternal(pid_t pid, int status) +{ + pr_PidRecord *pRec; + + pRec = FindPidTable(pid); + if (NULL == pRec) { + pRec = PR_NEW(pr_PidRecord); + pRec->pid = pid; + pRec->state = _PR_PID_REAPED; + pRec->exitStatus = ExtractExitStatus(status); + pRec->reapedCV = NULL; + InsertPidTable(pRec); + } else { + PR_ASSERT(pRec->state != _PR_PID_REAPED); + if (_PR_PID_DETACHED == pRec->state) { + PR_ASSERT(NULL == pRec->reapedCV); + DeletePidTable(pRec); + PR_DELETE(pRec); + } else { + PR_ASSERT(_PR_PID_WAITING == pRec->state); + PR_ASSERT(NULL != pRec->reapedCV); + pRec->exitStatus = ExtractExitStatus(status); + pRec->state = _PR_PID_REAPED; + PR_NotifyCondVar(pRec->reapedCV); + } + } +} + +#if defined(_PR_NATIVE_THREADS) + +/* + * If all the threads are native threads, the daemon thread is + * simpler. We don't need to catch the SIGCHLD signal. We can + * just have the daemon thread block in waitpid(). + */ + +static void WaitPidDaemonThread(void *unused) +{ + pid_t pid; + int status; + + while (1) { + PR_Lock(pr_wp.ml); + while (0 == pr_wp.numProcs) { + PR_WaitCondVar(pr_wp.cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(pr_wp.ml); + + while (1) { + do { + pid = waitpid((pid_t) -1, &status, 0); + } while ((pid_t) -1 == pid && EINTR == errno); + + /* + * waitpid() cannot return 0 because we did not invoke it + * with the WNOHANG option. + */ + PR_ASSERT(0 != pid); + + /* + * The only possible error code is ECHILD. But if we do + * our accounting correctly, we should only call waitpid() + * when there is a child process to wait for. + */ + PR_ASSERT((pid_t) -1 != pid); + if ((pid_t) -1 == pid) { + break; + } + + PR_Lock(pr_wp.ml); + ProcessReapedChildInternal(pid, status); + pr_wp.numProcs--; + while (0 == pr_wp.numProcs) { + PR_WaitCondVar(pr_wp.cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(pr_wp.ml); + } + } +} + +#else /* _PR_NATIVE_THREADS */ + +static void WaitPidDaemonThread(void *unused) +{ + PRPollDesc pd; + PRFileDesc *fd; + int rv; + char buf[128]; + pid_t pid; + int status; +#ifdef _PR_SHARE_CLONES + struct pr_CreateProcOp *op; +#endif + +#ifdef _PR_SHARE_CLONES + pr_InstallSigchldHandler(); +#endif + + fd = PR_ImportFile(pr_wp.pipefd[0]); + PR_ASSERT(NULL != fd); + pd.fd = fd; + pd.in_flags = PR_POLL_READ; + + while (1) { + rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(1 == rv); + +#ifdef _PR_SHARE_CLONES + if (pr_waitpid_daemon_exit) { + return; + } + PR_Lock(pr_wp.ml); +#endif + + do { + rv = read(pr_wp.pipefd[0], buf, sizeof(buf)); + } while (sizeof(buf) == rv || (-1 == rv && EINTR == errno)); + +#ifdef _PR_SHARE_CLONES + PR_Unlock(pr_wp.ml); + while ((op = pr_wp.opHead) != NULL) { + op->process = ForkAndExec(op->path, op->argv, + op->envp, op->attr); + if (NULL == op->process) { + op->prerror = PR_GetError(); + op->oserror = PR_GetOSError(); + } + PR_Lock(pr_wp.ml); + pr_wp.opHead = op->next; + if (NULL == pr_wp.opHead) { + pr_wp.opTail = NULL; + } + op->done = PR_TRUE; + PR_NotifyCondVar(op->doneCV); + PR_Unlock(pr_wp.ml); + } +#endif + + while (1) { + do { + pid = waitpid((pid_t) -1, &status, WNOHANG); + } while ((pid_t) -1 == pid && EINTR == errno); + if (0 == pid) break; + if ((pid_t) -1 == pid) { + /* must be because we have no child processes */ + PR_ASSERT(ECHILD == errno); + break; + } + + PR_Lock(pr_wp.ml); + ProcessReapedChildInternal(pid, status); + PR_Unlock(pr_wp.ml); + } + } +} + +static void pr_SigchldHandler(int sig) +{ + int errnoCopy; + int rv; + + errnoCopy = errno; + + do { + rv = write(pr_wp.pipefd[1], "", 1); + } while (-1 == rv && EINTR == errno); + +#ifdef DEBUG + if (-1 == rv && EAGAIN != errno && EWOULDBLOCK != errno) { + char *msg = "cannot write to pipe\n"; + write(2, msg, strlen(msg) + 1); + _exit(1); + } +#endif + + errno = errnoCopy; +} + +static void pr_InstallSigchldHandler() +{ +#if defined(HPUX) && defined(_PR_DCETHREADS) +#error "HP-UX DCE threads have their own SIGCHLD handler" +#endif + + struct sigaction act, oact; + int rv; + + act.sa_handler = pr_SigchldHandler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_NOCLDSTOP | SA_RESTART; + rv = sigaction(SIGCHLD, &act, &oact); + PR_ASSERT(0 == rv); + /* Make sure we are not overriding someone else's SIGCHLD handler */ +#ifndef _PR_SHARE_CLONES + PR_ASSERT(oact.sa_handler == SIG_DFL); +#endif +} + +#endif /* !defined(_PR_NATIVE_THREADS) */ + +static PRStatus _MD_InitProcesses(void) +{ +#if !defined(_PR_NATIVE_THREADS) + int rv; + int flags; +#endif + +#ifdef AIX + { + void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + pr_wp.forkptr = (pid_t (*)(void)) dlsym(handle, "f_fork"); + if (!pr_wp.forkptr) { + pr_wp.forkptr = fork; + } + dlclose(handle); + } +#endif /* AIX */ + + pr_wp.ml = PR_NewLock(); + PR_ASSERT(NULL != pr_wp.ml); + +#if defined(_PR_NATIVE_THREADS) + pr_wp.numProcs = 0; + pr_wp.cv = PR_NewCondVar(pr_wp.ml); + PR_ASSERT(NULL != pr_wp.cv); +#else + rv = pipe(pr_wp.pipefd); + PR_ASSERT(0 == rv); + flags = fcntl(pr_wp.pipefd[0], F_GETFL, 0); + fcntl(pr_wp.pipefd[0], F_SETFL, flags | O_NONBLOCK); + flags = fcntl(pr_wp.pipefd[1], F_GETFL, 0); + fcntl(pr_wp.pipefd[1], F_SETFL, flags | O_NONBLOCK); + +#ifndef _PR_SHARE_CLONES + pr_InstallSigchldHandler(); +#endif +#endif /* !_PR_NATIVE_THREADS */ + + pr_wp.thread = PR_CreateThread(PR_SYSTEM_THREAD, + WaitPidDaemonThread, NULL, PR_PRIORITY_NORMAL, +#ifdef _PR_SHARE_CLONES + PR_GLOBAL_THREAD, +#else + PR_LOCAL_THREAD, +#endif + PR_JOINABLE_THREAD, 0); + PR_ASSERT(NULL != pr_wp.thread); + + pr_wp.pidTable = (pr_PidRecord**)PR_CALLOC(NBUCKETS * sizeof(pr_PidRecord *)); + PR_ASSERT(NULL != pr_wp.pidTable); + return PR_SUCCESS; +} + +PRStatus _MD_DetachUnixProcess(PRProcess *process) +{ + PRStatus retVal = PR_SUCCESS; + pr_PidRecord *pRec; + + PR_Lock(pr_wp.ml); + pRec = FindPidTable(process->md.pid); + if (NULL == pRec) { + pRec = PR_NEW(pr_PidRecord); + if (NULL == pRec) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + retVal = PR_FAILURE; + goto done; + } + pRec->pid = process->md.pid; + pRec->state = _PR_PID_DETACHED; + pRec->reapedCV = NULL; + InsertPidTable(pRec); + } else { + PR_ASSERT(_PR_PID_REAPED == pRec->state); + if (_PR_PID_REAPED != pRec->state) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + retVal = PR_FAILURE; + } else { + DeletePidTable(pRec); + PR_ASSERT(NULL == pRec->reapedCV); + PR_DELETE(pRec); + } + } + PR_DELETE(process); + +done: + PR_Unlock(pr_wp.ml); + return retVal; +} + +PRStatus _MD_WaitUnixProcess( + PRProcess *process, + PRInt32 *exitCode) +{ + pr_PidRecord *pRec; + PRStatus retVal = PR_SUCCESS; + PRBool interrupted = PR_FALSE; + + PR_Lock(pr_wp.ml); + pRec = FindPidTable(process->md.pid); + if (NULL == pRec) { + pRec = PR_NEW(pr_PidRecord); + if (NULL == pRec) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + retVal = PR_FAILURE; + goto done; + } + pRec->pid = process->md.pid; + pRec->state = _PR_PID_WAITING; + pRec->reapedCV = PR_NewCondVar(pr_wp.ml); + if (NULL == pRec->reapedCV) { + PR_DELETE(pRec); + retVal = PR_FAILURE; + goto done; + } + InsertPidTable(pRec); + while (!interrupted && _PR_PID_REAPED != pRec->state) { + if (PR_WaitCondVar(pRec->reapedCV, + PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE + && PR_GetError() == PR_PENDING_INTERRUPT_ERROR) { + interrupted = PR_TRUE; + } + } + if (_PR_PID_REAPED == pRec->state) { + if (exitCode) { + *exitCode = pRec->exitStatus; + } + } else { + PR_ASSERT(interrupted); + retVal = PR_FAILURE; + } + DeletePidTable(pRec); + PR_DestroyCondVar(pRec->reapedCV); + PR_DELETE(pRec); + } else { + PR_ASSERT(_PR_PID_REAPED == pRec->state); + PR_ASSERT(NULL == pRec->reapedCV); + DeletePidTable(pRec); + if (exitCode) { + *exitCode = pRec->exitStatus; + } + PR_DELETE(pRec); + } + PR_DELETE(process); + +done: + PR_Unlock(pr_wp.ml); + return retVal; +} /* _MD_WaitUnixProcess */ + +PRStatus _MD_KillUnixProcess(PRProcess *process) +{ + PRErrorCode prerror; + PRInt32 oserror; + +#ifdef SYMBIAN + /* In Symbian OS, we can not kill other process with Open C */ + PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, oserror); + return PR_FAILURE; +#else + if (kill(process->md.pid, SIGKILL) == 0) { + return PR_SUCCESS; + } + oserror = errno; + switch (oserror) { + case EPERM: + prerror = PR_NO_ACCESS_RIGHTS_ERROR; + break; + case ESRCH: + prerror = PR_INVALID_ARGUMENT_ERROR; + break; + default: + prerror = PR_UNKNOWN_ERROR; + break; + } + PR_SetError(prerror, oserror); + return PR_FAILURE; +#endif +} /* _MD_KillUnixProcess */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/uxrng.c nspr-4.10.7/nspr/pr/src/md/unix/uxrng.c --- nspr-4.9.5/nspr/pr/src/md/unix/uxrng.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/uxrng.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,252 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "primpl.h" + +#include +#include +#include +#include + + +#if defined(SOLARIS) + +static size_t +GetHighResClock(void *buf, size_t maxbytes) +{ + hrtime_t t; + t = gethrtime(); + if (t) { + return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); + } + return 0; +} + +#elif defined(HPUX) + +#ifdef __ia64 +#include + +static size_t +GetHighResClock(void *buf, size_t maxbytes) +{ + PRUint64 t; + +#ifdef __GNUC__ + __asm__ __volatile__("mov %0 = ar.itc" : "=r" (t)); +#else + t = _Asm_mov_from_ar(_AREG44); +#endif + return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); +} +#else +static size_t +GetHighResClock(void *buf, size_t maxbytes) +{ + extern int ret_cr16(); + int cr16val; + + cr16val = ret_cr16(); + return(_pr_CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val))); +} +#endif + +#elif defined(OSF1) + +#include + +/* + * Use the "get the cycle counter" instruction on the alpha. + * The low 32 bits completely turn over in less than a minute. + * The high 32 bits are some non-counter gunk that changes sometimes. + */ +static size_t +GetHighResClock(void *buf, size_t maxbytes) +{ + unsigned long t; + +#ifdef __GNUC__ + __asm__("rpcc %0" : "=r" (t)); +#else + t = asm("rpcc %v0"); +#endif + return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); +} + +#elif defined(AIX) + +static size_t +GetHighResClock(void *buf, size_t maxbytes) +{ + return 0; +} + +#elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) \ + || defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD) \ + || defined(SYMBIAN) || defined(__GNU__)) +#include +#include +#include + +static int fdDevURandom; +static PRCallOnceType coOpenDevURandom; + +static PRStatus OpenDevURandom( void ) +{ + fdDevURandom = open( "/dev/urandom", O_RDONLY ); + return((-1 == fdDevURandom)? PR_FAILURE : PR_SUCCESS ); +} /* end OpenDevURandom() */ + +static size_t GetDevURandom( void *buf, size_t size ) +{ + int bytesIn; + int rc; + + rc = PR_CallOnce( &coOpenDevURandom, OpenDevURandom ); + if ( PR_FAILURE == rc ) { + _PR_MD_MAP_OPEN_ERROR( errno ); + return(0); + } + + bytesIn = read( fdDevURandom, buf, size ); + if ( -1 == bytesIn ) { + _PR_MD_MAP_READ_ERROR( errno ); + return(0); + } + + return( bytesIn ); +} /* end GetDevURandom() */ + +static size_t +GetHighResClock(void *buf, size_t maxbytes) +{ + return(GetDevURandom( buf, maxbytes )); +} + +#elif defined(IRIX) +#include +#undef PRIVATE +#include +#include +#include +#include +#include + +static size_t GetHighResClock(void *buf, size_t maxbuf) +{ + unsigned phys_addr, raddr, cycleval; + static volatile unsigned *iotimer_addr = NULL; + static int tries = 0; + static int cntr_size; + int mfd; + unsigned s0[2]; + +#ifndef SGI_CYCLECNTR_SIZE +#define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */ +#endif + + if (iotimer_addr == NULL) { + if (tries++ > 1) { + /* Don't keep trying if it didn't work */ + return 0; + } + + /* + ** For SGI machines we can use the cycle counter, if it has one, + ** to generate some truly random numbers + */ + phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval); + if (phys_addr) { + int pgsz = getpagesize(); + int pgoffmask = pgsz - 1; + + raddr = phys_addr & ~pgoffmask; + mfd = open("/dev/mmem", O_RDONLY); + if (mfd < 0) { + return 0; + } + iotimer_addr = (unsigned *) + mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr); + if (iotimer_addr == (unsigned*)-1) { + close(mfd); + iotimer_addr = NULL; + return 0; + } + iotimer_addr = (unsigned*) + ((__psint_t)iotimer_addr | (phys_addr & pgoffmask)); + /* + * The file 'mfd' is purposefully not closed. + */ + cntr_size = syssgi(SGI_CYCLECNTR_SIZE); + if (cntr_size < 0) { + struct utsname utsinfo; + + /* + * We must be executing on a 6.0 or earlier system, since the + * SGI_CYCLECNTR_SIZE call is not supported. + * + * The only pre-6.1 platforms with 64-bit counters are + * IP19 and IP21 (Challenge, PowerChallenge, Onyx). + */ + uname(&utsinfo); + if (!strncmp(utsinfo.machine, "IP19", 4) || + !strncmp(utsinfo.machine, "IP21", 4)) + cntr_size = 64; + else + cntr_size = 32; + } + cntr_size /= 8; /* Convert from bits to bytes */ + } + } + + s0[0] = *iotimer_addr; + if (cntr_size > 4) + s0[1] = *(iotimer_addr + 1); + memcpy(buf, (char *)&s0[0], cntr_size); + return _pr_CopyLowBits(buf, maxbuf, &s0, cntr_size); +} + +#elif defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \ + || defined(QNX) || defined(DARWIN) || defined(RISCOS) +#include + +static size_t +GetHighResClock(void *buf, size_t maxbytes) +{ + int ticks; + struct tms buffer; + + ticks=times(&buffer); + return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks)); +} +#else +#error! Platform undefined +#endif /* defined(SOLARIS) */ + +extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ) +{ + struct timeval tv; + int n = 0; + int s; + + n += GetHighResClock(buf, size); + size -= n; + + GETTIMEOFDAY(&tv); + + if ( size > 0 ) { + s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec)); + size -= s; + n += s; + } + if ( size > 0 ) { + s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec)); + size -= s; + n += s; + } + + return n; +} /* end _PR_MD_GetRandomNoise() */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/uxshm.c nspr-4.10.7/nspr/pr/src/md/unix/uxshm.c --- nspr-4.9.5/nspr/pr/src/md/unix/uxshm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/uxshm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,643 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** uxshm.c -- Unix Implementations NSPR Named Shared Memory +** +** +** lth. Jul-1999. +** +*/ +#include +#include +#include +#include +#include "primpl.h" +#include + +extern PRLogModuleInfo *_pr_shm_lm; + + +#define NSPR_IPC_SHM_KEY 'b' +/* +** Implementation for System V +*/ +#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY +#include +#include +#include +#include + +#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory +#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory +#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory +#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory +#define _MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory + +extern PRSharedMemory * _MD_OpenSharedMemory( + const char *name, + PRSize size, + PRIntn flags, + PRIntn mode +) +{ + PRStatus rc = PR_SUCCESS; + key_t key; + PRSharedMemory *shm; + char ipcname[PR_IPC_NAME_SIZE]; + + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); + if ( PR_FAILURE == rc ) + { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); + return( NULL ); + } + + shm = PR_NEWZAP( PRSharedMemory ); + if ( NULL == shm ) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); + return( NULL ); + } + + shm->ipcname = (char*)PR_MALLOC( strlen( ipcname ) + 1 ); + if ( NULL == shm->ipcname ) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); + PR_DELETE( shm ); + return( NULL ); + } + + /* copy args to struct */ + strcpy( shm->ipcname, ipcname ); + shm->size = size; + shm->mode = mode; + shm->flags = flags; + shm->ident = _PR_SHM_IDENT; + + /* create the file first */ + if ( flags & PR_SHM_CREATE ) { + int osfd = open( shm->ipcname, (O_RDWR | O_CREAT), shm->mode ); + if ( -1 == osfd ) { + _PR_MD_MAP_OPEN_ERROR( errno ); + PR_FREEIF( shm->ipcname ); + PR_DELETE( shm ); + return( NULL ); + } + if ( close(osfd) == -1 ) { + _PR_MD_MAP_CLOSE_ERROR( errno ); + PR_FREEIF( shm->ipcname ); + PR_DELETE( shm ); + return( NULL ); + } + } + + /* hash the shm.name to an ID */ + key = ftok( shm->ipcname, NSPR_IPC_SHM_KEY ); + if ( -1 == key ) + { + rc = PR_FAILURE; + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_OpenSharedMemory(): ftok() failed on name: %s", shm->ipcname)); + PR_FREEIF( shm->ipcname ); + PR_DELETE( shm ); + return( NULL ); + } + + /* get the shared memory */ + if ( flags & PR_SHM_CREATE ) { + shm->id = shmget( key, shm->size, ( shm->mode | IPC_CREAT|IPC_EXCL)); + if ( shm->id >= 0 ) { + return( shm ); + } + if ((errno == EEXIST) && (flags & PR_SHM_EXCL)) { + PR_SetError( PR_FILE_EXISTS_ERROR, errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_OpenSharedMemory(): shmget() exclusive failed, errno: %d", errno)); + PR_FREEIF(shm->ipcname); + PR_DELETE(shm); + return(NULL); + } + } + + shm->id = shmget( key, shm->size, shm->mode ); + if ( -1 == shm->id ) { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_OpenSharedMemory(): shmget() failed, errno: %d", errno)); + PR_FREEIF(shm->ipcname); + PR_DELETE(shm); + return(NULL); + } + + return( shm ); +} /* end _MD_OpenSharedMemory() */ + +extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) +{ + void *addr; + PRUint32 aFlags = shm->mode; + + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + aFlags |= (flags & PR_SHM_READONLY )? SHM_RDONLY : 0; + + addr = shmat( shm->id, NULL, aFlags ); + if ( (void*)-1 == addr ) + { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_AttachSharedMemory(): shmat() failed on name: %s, OsError: %d", + shm->ipcname, PR_GetOSError() )); + addr = NULL; + } + + return addr; +} + +extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) +{ + PRStatus rc = PR_SUCCESS; + PRIntn urc; + + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + urc = shmdt( addr ); + if ( -1 == urc ) + { + rc = PR_FAILURE; + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DetachSharedMemory(): shmdt() failed on name: %s", shm->ipcname )); + } + + return rc; +} + +extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) +{ + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + PR_FREEIF(shm->ipcname); + PR_DELETE(shm); + + return PR_SUCCESS; +} + +extern PRStatus _MD_DeleteSharedMemory( const char *name ) +{ + PRStatus rc = PR_SUCCESS; + key_t key; + int id; + PRIntn urc; + char ipcname[PR_IPC_NAME_SIZE]; + + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); + if ( PR_FAILURE == rc ) + { + PR_SetError( PR_UNKNOWN_ERROR , errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DeleteSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); + return(PR_FAILURE); + } + + /* create the file first */ + { + int osfd = open( ipcname, (O_RDWR | O_CREAT), 0666 ); + if ( -1 == osfd ) { + _PR_MD_MAP_OPEN_ERROR( errno ); + return( PR_FAILURE ); + } + if ( close(osfd) == -1 ) { + _PR_MD_MAP_CLOSE_ERROR( errno ); + return( PR_FAILURE ); + } + } + + /* hash the shm.name to an ID */ + key = ftok( ipcname, NSPR_IPC_SHM_KEY ); + if ( -1 == key ) + { + rc = PR_FAILURE; + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DeleteSharedMemory(): ftok() failed on name: %s", ipcname)); + } + +#ifdef SYMBIAN + /* In Symbian OS the system imposed minimum is 1 byte, instead of ZERO */ + id = shmget( key, 1, 0 ); +#else + id = shmget( key, 0, 0 ); +#endif + if ( -1 == id ) { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DeleteSharedMemory(): shmget() failed, errno: %d", errno)); + return(PR_FAILURE); + } + + urc = shmctl( id, IPC_RMID, NULL ); + if ( -1 == urc ) + { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DeleteSharedMemory(): shmctl() failed on name: %s", ipcname )); + return(PR_FAILURE); + } + + urc = unlink( ipcname ); + if ( -1 == urc ) { + _PR_MD_MAP_UNLINK_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DeleteSharedMemory(): unlink() failed: %s", ipcname )); + return(PR_FAILURE); + } + + return rc; +} /* end _MD_DeleteSharedMemory() */ + +/* +** Implementation for Posix +*/ +#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY +#include + +#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory +#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory +#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory +#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory +#define _MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory + +struct _MDSharedMemory { + int handle; +}; + +extern PRSharedMemory * _MD_OpenSharedMemory( + const char *name, + PRSize size, + PRIntn flags, + PRIntn mode +) +{ + PRStatus rc = PR_SUCCESS; + PRInt32 end; + PRSharedMemory *shm; + char ipcname[PR_IPC_NAME_SIZE]; + + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); + if ( PR_FAILURE == rc ) + { + PR_SetError( PR_UNKNOWN_ERROR , errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); + return( NULL ); + } + + shm = PR_NEWZAP( PRSharedMemory ); + if ( NULL == shm ) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); + return( NULL ); + } + + shm->ipcname = PR_MALLOC( strlen( ipcname ) + 1 ); + if ( NULL == shm->ipcname ) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); + return( NULL ); + } + + /* copy args to struct */ + strcpy( shm->ipcname, ipcname ); + shm->size = size; + shm->mode = mode; + shm->flags = flags; + shm->ident = _PR_SHM_IDENT; + + /* + ** Create the shared memory + */ + if ( flags & PR_SHM_CREATE ) { + int oflag = (O_CREAT | O_RDWR); + + if ( flags & PR_SHM_EXCL ) + oflag |= O_EXCL; + shm->id = shm_open( shm->ipcname, oflag, shm->mode ); + } else { + shm->id = shm_open( shm->ipcname, O_RDWR, shm->mode ); + } + + if ( -1 == shm->id ) { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, + ("_MD_OpenSharedMemory(): shm_open failed: %s, OSError: %d", + shm->ipcname, PR_GetOSError())); + PR_DELETE( shm->ipcname ); + PR_DELETE( shm ); + return(NULL); + } + + end = ftruncate( shm->id, shm->size ); + if ( -1 == end ) { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, + ("_MD_OpenSharedMemory(): ftruncate failed, OSError: %d", + PR_GetOSError())); + PR_DELETE( shm->ipcname ); + PR_DELETE( shm ); + return(NULL); + } + + return(shm); +} /* end _MD_OpenSharedMemory() */ + +extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) +{ + void *addr; + PRIntn prot = (PROT_READ | PROT_WRITE); + + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + if ( PR_SHM_READONLY == flags) + prot ^= PROT_WRITE; + + addr = mmap( (void*)0, shm->size, prot, MAP_SHARED, shm->id, 0 ); + if ((void*)-1 == addr ) + { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_AttachSharedMemory(): mmap failed: %s, errno: %d", + shm->ipcname, PR_GetOSError())); + addr = NULL; + } else { + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_AttachSharedMemory(): name: %s, attached at: %p", shm->ipcname, addr)); + } + + return addr; +} + +extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) +{ + PRStatus rc = PR_SUCCESS; + PRIntn urc; + + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + urc = munmap( addr, shm->size ); + if ( -1 == urc ) + { + rc = PR_FAILURE; + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DetachSharedMemory(): munmap failed: %s, errno: %d", + shm->ipcname, PR_GetOSError())); + } + return rc; +} + +extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) +{ + int urc; + + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + urc = close( shm->id ); + if ( -1 == urc ) { + _PR_MD_MAP_CLOSE_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_CloseSharedMemory(): close() failed, error: %d", PR_GetOSError())); + return(PR_FAILURE); + } + PR_DELETE( shm->ipcname ); + PR_DELETE( shm ); + return PR_SUCCESS; +} + +extern PRStatus _MD_DeleteSharedMemory( const char *name ) +{ + PRStatus rc = PR_SUCCESS; + PRUintn urc; + char ipcname[PR_IPC_NAME_SIZE]; + + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); + if ( PR_FAILURE == rc ) + { + PR_SetError( PR_UNKNOWN_ERROR , errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); + return rc; + } + + urc = shm_unlink( ipcname ); + if ( -1 == urc ) { + rc = PR_FAILURE; + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DeleteSharedMemory(): shm_unlink failed: %s, errno: %d", + ipcname, PR_GetOSError())); + } else { + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, + ("_MD_DeleteSharedMemory(): %s, success", ipcname)); + } + + return rc; +} /* end _MD_DeleteSharedMemory() */ +#endif + + + +/* +** Unix implementation for anonymous memory (file) mapping +*/ +extern PRLogModuleInfo *_pr_shma_lm; + +#include + +extern PRFileMap* _md_OpenAnonFileMap( + const char *dirName, + PRSize size, + PRFileMapProtect prot +) +{ + PRFileMap *fm = NULL; + PRFileDesc *fd; + int osfd; + PRIntn urc; + PRIntn mode = 0600; + char *genName; + pid_t pid = getpid(); /* for generating filename */ + PRThread *tid = PR_GetCurrentThread(); /* for generating filename */ + int incr; /* for generating filename */ + const int maxTries = 20; /* maximum # attempts at a unique filename */ + PRInt64 size64; /* 64-bit version of 'size' */ + + /* + ** generate a filename from input and runtime environment + ** open the file, unlink the file. + ** make maxTries number of attempts at uniqueness in the filename + */ + for ( incr = 0; incr < maxTries ; incr++ ) { +#if defined(SYMBIAN) +#define NSPR_AFM_FILENAME "%s\\NSPR-AFM-%d-%p.%d" +#else +#define NSPR_AFM_FILENAME "%s/.NSPR-AFM-%d-%p.%d" +#endif + genName = PR_smprintf( NSPR_AFM_FILENAME, + dirName, (int) pid, tid, incr ); + if ( NULL == genName ) { + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename")); + goto Finished; + } + + /* create the file */ + osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode ); + if ( -1 == osfd ) { + if ( EEXIST == errno ) { + PR_smprintf_free( genName ); + continue; /* name exists, try again */ + } else { + _PR_MD_MAP_OPEN_ERROR( errno ); + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d", + genName, PR_GetOSError())); + PR_smprintf_free( genName ); + goto Finished; + } + } + break; /* name generation and open successful, break; */ + } /* end for() */ + + if ( incr == maxTries ) { + PR_ASSERT( -1 == osfd ); + PR_ASSERT( EEXIST == errno ); + _PR_MD_MAP_OPEN_ERROR( errno ); + goto Finished; + } + + urc = unlink( genName ); +#if defined(SYMBIAN) && defined(__WINS__) + /* If it is being used by the system or another process, Symbian OS + * Emulator(WINS) considers this an error. */ + if ( -1 == urc && EACCES != errno ) { +#else + if ( -1 == urc ) { +#endif + _PR_MD_MAP_UNLINK_ERROR( errno ); + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): failed on unlink(), errno: %d", errno)); + PR_smprintf_free( genName ); + close( osfd ); + goto Finished; + } + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): unlink(): %s", genName )); + + PR_smprintf_free( genName ); + + fd = PR_ImportFile( osfd ); + if ( NULL == fd ) { + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): PR_ImportFile(): failed")); + goto Finished; + } + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): fd: %p", fd )); + + urc = ftruncate( fd->secret->md.osfd, size ); + if ( -1 == urc ) { + _PR_MD_MAP_DEFAULT_ERROR( errno ); + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): failed on ftruncate(), errno: %d", errno)); + PR_Close( fd ); + goto Finished; + } + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): ftruncate(): size: %d", size )); + + LL_UI2L(size64, size); /* PRSize (size_t) is unsigned */ + fm = PR_CreateFileMap( fd, size64, prot ); + if ( NULL == fm ) { + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("PR_OpenAnonFileMap(): failed")); + PR_Close( fd ); + goto Finished; + } + fm->md.isAnonFM = PR_TRUE; /* set fd close */ + + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): PR_CreateFileMap(): fm: %p", fm )); + +Finished: + return(fm); +} /* end md_OpenAnonFileMap() */ + +/* +** _md_ExportFileMapAsString() +** +** +*/ +extern PRStatus _md_ExportFileMapAsString( + PRFileMap *fm, + PRSize bufSize, + char *buf +) +{ + PRIntn written; + PRIntn prot = (PRIntn)fm->prot; + + written = PR_snprintf( buf, bufSize, "%ld:%d", + fm->fd->secret->md.osfd, prot ); + + return((written == -1)? PR_FAILURE : PR_SUCCESS); +} /* end _md_ExportFileMapAsString() */ + + +extern PRFileMap * _md_ImportFileMapFromString( + const char *fmstring +) +{ + PRStatus rc; + PRInt32 osfd; + PRIntn prot; /* really: a PRFileMapProtect */ + PRFileDesc *fd; + PRFileMap *fm = NULL; /* default return value */ + PRFileInfo64 info; + + PR_sscanf( fmstring, "%ld:%d", &osfd, &prot ); + + /* import the os file descriptor */ + fd = PR_ImportFile( osfd ); + if ( NULL == fd ) { + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_ImportFileMapFromString(): PR_ImportFile() failed")); + goto Finished; + } + + rc = PR_GetOpenFileInfo64( fd, &info ); + if ( PR_FAILURE == rc ) { + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_ImportFileMapFromString(): PR_GetOpenFileInfo64() failed")); + goto Finished; + } + + fm = PR_CreateFileMap( fd, info.size, (PRFileMapProtect)prot ); + if ( NULL == fm ) { + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_ImportFileMapFromString(): PR_CreateFileMap() failed")); + } + +Finished: + return(fm); +} /* end _md_ImportFileMapFromString() */ diff -Nru nspr-4.9.5/nspr/pr/src/md/unix/uxwrap.c nspr-4.10.7/nspr/pr/src/md/unix/uxwrap.c --- nspr-4.9.5/nspr/pr/src/md/unix/uxwrap.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/unix/uxwrap.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,513 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + *------------------------------------------------------------------------ + * File: uxwrap.c + * + * Our wrapped versions of the Unix select() and poll() system calls. + * + *------------------------------------------------------------------------ + */ + +#include "primpl.h" + +#if defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) || defined(QNX) +/* Do not wrap select() and poll(). */ +#else /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */ +/* The include files for select() */ +#ifdef IRIX +#include +#include +#endif + +#include +#include +#include + +#define ZAP_SET(_to, _width) \ + PR_BEGIN_MACRO \ + memset(_to, 0, \ + ((_width + 8*sizeof(int)-1) / (8*sizeof(int))) \ + * sizeof(int) \ + ); \ + PR_END_MACRO + +/* see comments in ns/cmd/xfe/mozilla.c (look for "PR_XGetXtHackFD") */ +static int _pr_xt_hack_fd = -1; + +int PR_XGetXtHackFD(void) +{ + int fds[2]; + + if (_pr_xt_hack_fd == -1) { + if (!pipe(fds)) { + _pr_xt_hack_fd = fds[0]; + } + } + return _pr_xt_hack_fd; +} + +static int (*_pr_xt_hack_okayToReleaseXLock)(void) = 0; + +void PR_SetXtHackOkayToReleaseXLockFn(int (*fn)(void)) +{ + _pr_xt_hack_okayToReleaseXLock = fn; +} + + +/* + *----------------------------------------------------------------------- + * select() -- + * + * Wrap up the select system call so that we can deschedule + * a thread that tries to wait for i/o. + * + *----------------------------------------------------------------------- + */ + +#if defined(HPUX9) +int select(size_t width, int *rl, int *wl, int *el, const struct timeval *tv) +#elif defined(AIX_RENAME_SELECT) +int wrap_select(unsigned long width, void *rl, void *wl, void *el, + struct timeval *tv) +#elif defined(_PR_SELECT_CONST_TIMEVAL) +int select(int width, fd_set *rd, fd_set *wr, fd_set *ex, + const struct timeval *tv) +#else +int select(int width, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *tv) +#endif +{ + int osfd; + _PRUnixPollDesc *unixpds, *unixpd, *eunixpd; + PRInt32 pdcnt; + PRIntervalTime timeout; + int retVal; +#if defined(HPUX9) || defined(AIX_RENAME_SELECT) + fd_set *rd = (fd_set*) rl; + fd_set *wr = (fd_set*) wl; + fd_set *ex = (fd_set*) el; +#endif + +#if 0 + /* + * Easy special case: zero timeout. Simply call the native + * select() with no fear of blocking. + */ + if (tv != NULL && tv->tv_sec == 0 && tv->tv_usec == 0) { +#if defined(HPUX9) || defined(AIX_RENAME_SELECT) + return _MD_SELECT(width, rl, wl, el, tv); +#else + return _MD_SELECT(width, rd, wr, ex, tv); +#endif + } +#endif + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + +#ifndef _PR_LOCAL_THREADS_ONLY + if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) { + return _MD_SELECT(width, rd, wr, ex, tv); + } +#endif + + if (width < 0 || width > FD_SETSIZE) { + errno = EINVAL; + return -1; + } + + /* Compute timeout */ + if (tv) { + /* + * These acceptable ranges for t_sec and t_usec are taken + * from the select() man pages. + */ + if (tv->tv_sec < 0 || tv->tv_sec > 100000000 + || tv->tv_usec < 0 || tv->tv_usec >= 1000000) { + errno = EINVAL; + return -1; + } + + /* Convert microseconds to ticks */ + timeout = PR_MicrosecondsToInterval(1000000*tv->tv_sec + tv->tv_usec); + } else { + /* tv being a NULL pointer means blocking indefinitely */ + timeout = PR_INTERVAL_NO_TIMEOUT; + } + + /* Check for no descriptors case (just doing a timeout) */ + if ((!rd && !wr && !ex) || !width) { + PR_Sleep(timeout); + return 0; + } + + /* + * Set up for PR_Poll(). The PRPollDesc array is allocated + * dynamically. If this turns out to have high performance + * penalty, one can change to use a large PRPollDesc array + * on the stack, and allocate dynamically only when it turns + * out to be not large enough. + * + * I allocate an array of size 'width', which is the maximum + * number of fds we may need to poll. + */ + unixpds = (_PRUnixPollDesc *) PR_CALLOC(width * sizeof(_PRUnixPollDesc)); + if (!unixpds) { + errno = ENOMEM; + return -1; + } + + pdcnt = 0; + unixpd = unixpds; + for (osfd = 0; osfd < width; osfd++) { + int in_flags = 0; + if (rd && FD_ISSET(osfd, rd)) { + in_flags |= _PR_UNIX_POLL_READ; + } + if (wr && FD_ISSET(osfd, wr)) { + in_flags |= _PR_UNIX_POLL_WRITE; + } + if (ex && FD_ISSET(osfd, ex)) { + in_flags |= _PR_UNIX_POLL_EXCEPT; + } + if (in_flags) { + unixpd->osfd = osfd; + unixpd->in_flags = in_flags; + unixpd->out_flags = 0; + unixpd++; + pdcnt++; + } + } + + /* + * see comments in mozilla/cmd/xfe/mozilla.c (look for + * "PR_XGetXtHackFD") + */ + { + int needToLockXAgain; + + needToLockXAgain = 0; + if (rd && (_pr_xt_hack_fd != -1) + && FD_ISSET(_pr_xt_hack_fd, rd) && PR_XIsLocked() + && (!_pr_xt_hack_okayToReleaseXLock + || _pr_xt_hack_okayToReleaseXLock())) { + PR_XUnlock(); + needToLockXAgain = 1; + } + + /* This is the potentially blocking step */ + retVal = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout); + + if (needToLockXAgain) { + PR_XLock(); + } + } + + if (retVal > 0) { + /* Compute select results */ + if (rd) ZAP_SET(rd, width); + if (wr) ZAP_SET(wr, width); + if (ex) ZAP_SET(ex, width); + + /* + * The return value can be either the number of ready file + * descriptors or the number of set bits in the three fd_set's. + */ + retVal = 0; /* we're going to recompute */ + eunixpd = unixpds + pdcnt; + for (unixpd = unixpds; unixpd < eunixpd; unixpd++) { + if (unixpd->out_flags) { + int nbits = 0; /* The number of set bits on for this fd */ + + if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) { + errno = EBADF; + PR_LOG(_pr_io_lm, PR_LOG_ERROR, + ("select returns EBADF for %d", unixpd->osfd)); + retVal = -1; + break; + } + /* + * If a socket has a pending error, it is considered + * both readable and writable. (See W. Richard Stevens, + * Unix Network Programming, Vol. 1, 2nd Ed., Section 6.3, + * pp. 153-154.) We also consider a socket readable if + * it has a hangup condition. + */ + if (rd && (unixpd->in_flags & _PR_UNIX_POLL_READ) + && (unixpd->out_flags & (_PR_UNIX_POLL_READ + | _PR_UNIX_POLL_ERR | _PR_UNIX_POLL_HUP))) { + FD_SET(unixpd->osfd, rd); + nbits++; + } + if (wr && (unixpd->in_flags & _PR_UNIX_POLL_WRITE) + && (unixpd->out_flags & (_PR_UNIX_POLL_WRITE + | _PR_UNIX_POLL_ERR))) { + FD_SET(unixpd->osfd, wr); + nbits++; + } + if (ex && (unixpd->in_flags & _PR_UNIX_POLL_WRITE) + && (unixpd->out_flags & PR_POLL_EXCEPT)) { + FD_SET(unixpd->osfd, ex); + nbits++; + } + PR_ASSERT(nbits > 0); +#if defined(HPUX) || defined(SOLARIS) || defined(OSF1) || defined(AIX) + retVal += nbits; +#else /* IRIX */ + retVal += 1; +#endif + } + } + } + + PR_ASSERT(tv || retVal != 0); + PR_LOG(_pr_io_lm, PR_LOG_MIN, ("select returns %d", retVal)); + PR_DELETE(unixpds); + + return retVal; +} + +/* + * Redefine poll, when supported on platforms, for local threads + */ + +/* + * I am commenting out the poll() wrapper for Linux for now + * because it is difficult to define _MD_POLL that works on all + * Linux varieties. People reported that glibc 2.0.7 on Debian + * 2.0 Linux machines doesn't have the __syscall_poll symbol + * defined. (WTC 30 Nov. 1998) + */ +#if defined(_PR_POLL_AVAILABLE) && !defined(LINUX) + +/* + *----------------------------------------------------------------------- + * poll() -- + * + * RETURN VALUES: + * -1: fails, errno indicates the error. + * 0: timed out, the revents bitmasks are not set. + * positive value: the number of file descriptors for which poll() + * has set the revents bitmask. + * + *----------------------------------------------------------------------- + */ + +#include + +#if defined(AIX_RENAME_SELECT) +int wrap_poll(void *listptr, unsigned long nfds, long timeout) +#elif (defined(AIX) && !defined(AIX_RENAME_SELECT)) +int poll(void *listptr, unsigned long nfds, long timeout) +#elif defined(OSF1) || (defined(HPUX) && !defined(HPUX9)) +int poll(struct pollfd filedes[], unsigned int nfds, int timeout) +#elif defined(HPUX9) +int poll(struct pollfd filedes[], int nfds, int timeout) +#elif defined(NETBSD) +int poll(struct pollfd *filedes, nfds_t nfds, int timeout) +#elif defined(OPENBSD) +int poll(struct pollfd filedes[], nfds_t nfds, int timeout) +#elif defined(FREEBSD) +int poll(struct pollfd *filedes, unsigned nfds, int timeout) +#else +int poll(struct pollfd *filedes, unsigned long nfds, int timeout) +#endif +{ +#ifdef AIX + struct pollfd *filedes = (struct pollfd *) listptr; +#endif + struct pollfd *pfd, *epfd; + _PRUnixPollDesc *unixpds, *unixpd, *eunixpd; + PRIntervalTime ticks; + PRInt32 pdcnt; + int ready; + + /* + * Easy special case: zero timeout. Simply call the native + * poll() with no fear of blocking. + */ + if (timeout == 0) { +#if defined(AIX) + return _MD_POLL(listptr, nfds, timeout); +#else + return _MD_POLL(filedes, nfds, timeout); +#endif + } + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + +#ifndef _PR_LOCAL_THREADS_ONLY + if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) { + return _MD_POLL(filedes, nfds, timeout); + } +#endif + + /* We do not support the pollmsg structures on AIX */ +#ifdef AIX + PR_ASSERT((nfds & 0xff00) == 0); +#endif + + if (timeout < 0 && timeout != -1) { + errno = EINVAL; + return -1; + } + + /* Convert timeout from miliseconds to ticks */ + if (timeout == -1) { + ticks = PR_INTERVAL_NO_TIMEOUT; + } else { + ticks = PR_MillisecondsToInterval(timeout); + } + + /* Check for no descriptor case (just do a timeout) */ + if (nfds == 0) { + PR_Sleep(ticks); + return 0; + } + + unixpds = (_PRUnixPollDesc *) + PR_MALLOC(nfds * sizeof(_PRUnixPollDesc)); + if (NULL == unixpds) { + errno = EAGAIN; + return -1; + } + + pdcnt = 0; + epfd = filedes + nfds; + unixpd = unixpds; + for (pfd = filedes; pfd < epfd; pfd++) { + /* + * poll() ignores negative fd's. + */ + if (pfd->fd >= 0) { + unixpd->osfd = pfd->fd; +#ifdef _PR_USE_POLL + unixpd->in_flags = pfd->events; +#else + /* + * Map the poll events to one of the three that can be + * represented by the select fd_sets: + * POLLIN, POLLRDNORM ===> readable + * POLLOUT, POLLWRNORM ===> writable + * POLLPRI, POLLRDBAND ===> exception + * POLLNORM, POLLWRBAND (and POLLMSG on some platforms) + * are ignored. + * + * The output events POLLERR and POLLHUP are never turned on. + * POLLNVAL may be turned on. + */ + unixpd->in_flags = 0; + if (pfd->events & (POLLIN +#ifdef POLLRDNORM + | POLLRDNORM +#endif + )) { + unixpd->in_flags |= _PR_UNIX_POLL_READ; + } + if (pfd->events & (POLLOUT +#ifdef POLLWRNORM + | POLLWRNORM +#endif + )) { + unixpd->in_flags |= _PR_UNIX_POLL_WRITE; + } + if (pfd->events & (POLLPRI +#ifdef POLLRDBAND + | POLLRDBAND +#endif + )) { + unixpd->in_flags |= PR_POLL_EXCEPT; + } +#endif /* _PR_USE_POLL */ + unixpd->out_flags = 0; + unixpd++; + pdcnt++; + } + } + + ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, ticks); + if (-1 == ready) { + if (PR_GetError() == PR_PENDING_INTERRUPT_ERROR) { + errno = EINTR; /* XXX we aren't interrupted by a signal, but... */ + } else { + errno = PR_GetOSError(); + } + } + if (ready <= 0) { + goto done; + } + + /* + * Copy the out_flags from the _PRUnixPollDesc structures to the + * user's pollfd structures and free the allocated memory + */ + unixpd = unixpds; + for (pfd = filedes; pfd < epfd; pfd++) { + pfd->revents = 0; + if (pfd->fd >= 0) { +#ifdef _PR_USE_POLL + pfd->revents = unixpd->out_flags; +#else + if (0 != unixpd->out_flags) { + if (unixpd->out_flags & _PR_UNIX_POLL_READ) { + if (pfd->events & POLLIN) { + pfd->revents |= POLLIN; + } +#ifdef POLLRDNORM + if (pfd->events & POLLRDNORM) { + pfd->revents |= POLLRDNORM; + } +#endif + } + if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) { + if (pfd->events & POLLOUT) { + pfd->revents |= POLLOUT; + } +#ifdef POLLWRNORM + if (pfd->events & POLLWRNORM) { + pfd->revents |= POLLWRNORM; + } +#endif + } + if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) { + if (pfd->events & POLLPRI) { + pfd->revents |= POLLPRI; + } +#ifdef POLLRDBAND + if (pfd->events & POLLRDBAND) { + pfd->revents |= POLLRDBAND; + } +#endif + } + if (unixpd->out_flags & _PR_UNIX_POLL_ERR) { + pfd->revents |= POLLERR; + } + if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) { + pfd->revents |= POLLNVAL; + } + if (unixpd->out_flags & _PR_UNIX_POLL_HUP) { + pfd->revents |= POLLHUP; + } + } +#endif /* _PR_USE_POLL */ + unixpd++; + } + } + +done: + PR_DELETE(unixpds); + return ready; +} + +#endif /* !defined(LINUX) */ + +#endif /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */ + +/* uxwrap.c */ + diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/.cvsignore nspr-4.10.7/nspr/pr/src/md/windows/.cvsignore --- nspr-4.9.5/nspr/pr/src/md/windows/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/Makefile.in nspr-4.10.7/nspr/pr/src/md/windows/Makefile.in --- nspr-4.9.5/nspr/pr/src/md/windows/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,72 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET))) +CSRCS = \ + ntmisc.c \ + ntsec.c \ + ntsem.c \ + ntinrval.c \ + ntgc.c \ + w95thred.c \ + w95io.c \ + w95cv.c \ + w32rng.c \ + w95sock.c \ + win32_errors.c \ + w32ipcsem.c \ + w32poll.c \ + w32shm.c \ + w95dllmain.c \ + $(NULL) +else +CSRCS = \ + ntdllmn.c \ + ntmisc.c \ + ntsec.c \ + ntsem.c \ + ntinrval.c \ + ntgc.c \ + ntthread.c \ + ntio.c \ + win32_errors.c \ + w32ipcsem.c \ + w32poll.c \ + w32rng.c \ + w32shm.c \ + $(NULL) +endif + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + +# Bug 122433 workaround: disable global optimization (-Og-) on ntio.c. +ifdef MOZ_OPTIMIZE +ifeq ($(OS_TARGET), WINNT) +ifndef NS_USE_GCC +$(OBJDIR)/ntio.$(OBJ_SUFFIX): ntio.c + @$(MAKE_OBJDIR) + $(CC) -Fo$@ -c $(CFLAGS) -Og- $< +endif +endif +endif diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/ntdllmn.c nspr-4.10.7/nspr/pr/src/md/windows/ntdllmn.c --- nspr-4.9.5/nspr/pr/src/md/windows/ntdllmn.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/ntdllmn.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * The DLL entry point (DllMain) for NSPR. + * + * The only reason we use DLLMain() now is to find out whether + * the NSPR DLL is statically or dynamically loaded. When + * dynamically loaded, we cannot use static thread-local storage. + * However, static TLS is faster than the TlsXXX() functions. + * So we want to use static TLS whenever we can. A global + * variable _pr_use_static_tls is set in DllMain() during process + * attachment to indicate whether it is safe to use static TLS + * or not. + */ + +#include +#include + +extern BOOL _pr_use_static_tls; /* defined in ntthread.c */ + +BOOL WINAPI DllMain( + HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ +PRThread *me; + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + /* + * If lpvReserved is NULL, we are dynamically loaded + * and therefore can't use static thread-local storage. + */ + if (lpvReserved == NULL) { + _pr_use_static_tls = FALSE; + } else { + _pr_use_static_tls = TRUE; + } + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + if (_pr_initialized) { + me = _MD_GET_ATTACHED_THREAD(); + if ((me != NULL) && (me->flags & _PR_ATTACHED)) + _PRI_DetachThread(); + } + break; + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/ntgc.c nspr-4.10.7/nspr/pr/src/md/windows/ntgc.c --- nspr-4.9.5/nspr/pr/src/md/windows/ntgc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/ntgc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * GC related routines + * + */ +#include +#include "primpl.h" + +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) +{ +#if defined(_X86_) + CONTEXT context; + context.ContextFlags = CONTEXT_INTEGER; + + if (_PR_IS_NATIVE_THREAD(t)) { + context.ContextFlags |= CONTEXT_CONTROL; + if (GetThreadContext(t->md.handle, &context)) { + t->md.gcContext[0] = context.Eax; + t->md.gcContext[1] = context.Ebx; + t->md.gcContext[2] = context.Ecx; + t->md.gcContext[3] = context.Edx; + t->md.gcContext[4] = context.Esi; + t->md.gcContext[5] = context.Edi; + t->md.gcContext[6] = context.Esp; + t->md.gcContext[7] = context.Ebp; + *np = PR_NUM_GCREGS; + } else { + PR_ASSERT(0);/* XXX */ + } + } else { + /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * This code is extremely machine dependant and completely + * undocumented by MS. Its only known to work experimentally. + * Ready for a walk on the wild * side? + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ + +#if !defined WIN95 // Win95 does not have fibers + int *fiberData = t->md.fiber_id; + + /* I found these offsets by disassembling SwitchToFiber(). + * Are your palms sweating yet? + */ + + /* + ** EAX is on the stack (ESP+0) + ** EDX is on the stack (ESP+4) + ** ECX is on the stack (ESP+8) + */ + t->md.gcContext[0] = 0; /* context.Eax */ + t->md.gcContext[1] = fiberData[0x2e]; /* context.Ebx */ + t->md.gcContext[2] = 0; /* context.Ecx */ + t->md.gcContext[3] = 0; /* context.Edx */ + t->md.gcContext[4] = fiberData[0x2d]; /* context.Esi */ + t->md.gcContext[5] = fiberData[0x2c]; /* context.Edi */ + t->md.gcContext[6] = fiberData[0x36]; /* context.Esp */ + t->md.gcContext[7] = fiberData[0x32]; /* context.Ebp */ + *np = PR_NUM_GCREGS; +#endif + } + return (PRWord *)&t->md.gcContext; +#else + PR_NOT_REACHED("not implemented"); + return NULL; +#endif /* defined(_X86_) */ +} + +/* This function is not used right now, but is left as a reference. + * If you ever need to get the fiberID from the currently running fiber, + * this is it. + */ +void * +GetMyFiberID() +{ +#if defined(_X86_) && !defined(__MINGW32__) + void *fiberData; + + /* A pointer to our tib entry is found at FS:[18] + * At offset 10h is the fiberData pointer. The context of the + * fiber is stored in there. + */ + __asm { + mov EDX, FS:[18h] + mov EAX, DWORD PTR [EDX+10h] + mov [fiberData], EAX + } + + return fiberData; +#else + PR_NOT_REACHED("not implemented"); + return NULL; +#endif /* defined(_X86_) */ +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/ntinrval.c nspr-4.10.7/nspr/pr/src/md/windows/ntinrval.c --- nspr-4.9.5/nspr/pr/src/md/windows/ntinrval.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/ntinrval.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * NT interval timers + * + */ + +#include "primpl.h" + +#ifdef WINCE +typedef DWORD (*IntervalFuncType)(void); +static IntervalFuncType intervalFunc; +#endif + +void +_PR_MD_INTERVAL_INIT() +{ +#ifdef WINCE + HMODULE mmtimerlib = LoadLibraryW(L"mmtimer.dll"); /* XXX leaked! */ + if (mmtimerlib) { + intervalFunc = (IntervalFuncType)GetProcAddress(mmtimerlib, + "timeGetTime"); + } else { + intervalFunc = &GetTickCount; + } +#endif +} + +PRIntervalTime +_PR_MD_GET_INTERVAL() +{ + /* milliseconds since system start */ +#ifdef WINCE + return (*intervalFunc)(); +#else + return timeGetTime(); +#endif +} + +PRIntervalTime +_PR_MD_INTERVAL_PER_SEC() +{ + return 1000; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/ntio.c nspr-4.10.7/nspr/pr/src/md/windows/ntio.c --- nspr-4.9.5/nspr/pr/src/md/windows/ntio.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/ntio.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,4609 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Windows NT IO module + * + * This module handles IO for LOCAL_SCOPE and GLOBAL_SCOPE threads. + * For LOCAL_SCOPE threads, we're using NT fibers. For GLOBAL_SCOPE threads + * we're using NT-native threads. + * + * When doing IO, we want to use completion ports for optimal performance + * with fibers. But if we use completion ports for all IO, it is difficult + * to project a blocking model with GLOBAL_SCOPE threads. To handle this + * we create an extra thread for completing IO for GLOBAL_SCOPE threads. + * We don't really want to complete IO on a separate thread for LOCAL_SCOPE + * threads because it means extra context switches, which are really slow + * on NT... Since we're using a single completion port, some IO will + * be incorrectly completed on the GLOBAL_SCOPE IO thread; this will mean + * extra context switching; but I don't think there is anything I can do + * about it. + */ + +#include "primpl.h" +#include "pprmwait.h" +#include +#include + +static HANDLE _pr_completion_port; +static PRThread *_pr_io_completion_thread; + +#define RECYCLE_SIZE 512 +static struct _MDLock _pr_recycle_lock; +static PRInt32 _pr_recycle_INET_array[RECYCLE_SIZE]; +static PRInt32 _pr_recycle_INET_tail = 0; +static PRInt32 _pr_recycle_INET6_array[RECYCLE_SIZE]; +static PRInt32 _pr_recycle_INET6_tail = 0; + +__declspec(thread) PRThread *_pr_io_restarted_io = NULL; +DWORD _pr_io_restartedIOIndex; /* The thread local storage slot for each + * thread is initialized to NULL. */ + +PRBool _nt_version_gets_lockfile_completion; + +struct _MDLock _pr_ioq_lock; +extern _MDLock _nt_idleLock; +extern PRCList _nt_idleList; +extern PRUint32 _nt_idleCount; + +#define CLOSE_TIMEOUT PR_SecondsToInterval(5) + +/* + * NSPR-to-NT access right mapping table for files. + */ +static DWORD fileAccessTable[] = { + FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_GENERIC_EXECUTE +}; + +/* + * NSPR-to-NT access right mapping table for directories. + */ +static DWORD dirAccessTable[] = { + FILE_GENERIC_READ, + FILE_GENERIC_WRITE|FILE_DELETE_CHILD, + FILE_GENERIC_EXECUTE +}; + +static PRBool IsPrevCharSlash(const char *str, const char *current); + +#define _NEED_351_FILE_LOCKING_HACK +#ifdef _NEED_351_FILE_LOCKING_HACK +#define _PR_LOCAL_FILE 1 +#define _PR_REMOTE_FILE 2 +PRBool IsFileLocalInit(); +PRInt32 IsFileLocal(HANDLE hFile); +#endif /* _NEED_351_FILE_LOCKING_HACK */ + +static PRInt32 _md_MakeNonblock(HANDLE); + +static PROsfd _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr *addr, int *addrlen, PRIntervalTime); +static PRInt32 _nt_nonblock_connect(PRFileDesc *fd, struct sockaddr *addr, int addrlen, PRIntervalTime); +static PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime); +static PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime); +static PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime); +static PRInt32 _nt_nonblock_sendto(PRFileDesc *, const char *, int, const struct sockaddr *, int, PRIntervalTime); +static PRInt32 _nt_nonblock_recvfrom(PRFileDesc *, char *, int, struct sockaddr *, int *, PRIntervalTime); + +/* + * We cannot associate a fd (a socket) with an I/O completion port + * if the fd is nonblocking or inheritable. + * + * Nonblocking socket I/O won't work if the socket is associated with + * an I/O completion port. + * + * An inheritable fd cannot be associated with an I/O completion port + * because the completion notification of async I/O initiated by the + * child process is still posted to the I/O completion port in the + * parent process. + */ +#define _NT_USE_NB_IO(fd) \ + ((fd)->secret->nonblocking || (fd)->secret->inheritable == _PR_TRI_TRUE) + +/* + * UDP support + * + * UDP is supported on NT by the continuation thread mechanism. + * The code is borrowed from ptio.c in pthreads nspr, hence the + * PT and pt prefixes. This mechanism is in fact general and + * not limited to UDP. For now, only UDP's recvfrom and sendto + * go through the continuation thread if they get WSAEWOULDBLOCK + * on first try. Recv and send on a connected UDP socket still + * goes through asychronous io. + */ + +#define PT_DEFAULT_SELECT_MSEC 100 + +typedef struct pt_Continuation pt_Continuation; +typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revent); + +typedef enum pr_ContuationStatus +{ + pt_continuation_sumbitted, + pt_continuation_inprogress, + pt_continuation_abort, + pt_continuation_done +} pr_ContuationStatus; + +struct pt_Continuation +{ + /* These objects are linked in ascending timeout order */ + pt_Continuation *next, *prev; /* self linked list of these things */ + + /* The building of the continuation operation */ + ContinuationFn function; /* what function to continue */ + union { SOCKET osfd; } arg1; /* #1 - the op's fd */ + union { void* buffer; } arg2; /* #2 - primary transfer buffer */ + union { PRIntn amount; } arg3; /* #3 - size of 'buffer' */ + union { PRIntn flags; } arg4; /* #4 - read/write flags */ + union { PRNetAddr *addr; } arg5; /* #5 - send/recv address */ + + PRIntervalTime timeout; /* representation of the timeout */ + + PRIntn event; /* flags for select()'s events */ + + /* + ** The representation and notification of the results of the operation. + ** These function can either return an int return code or a pointer to + ** some object. + */ + union { PRIntn code; void *object; } result; + + PRIntn syserrno; /* in case it failed, why (errno) */ + pr_ContuationStatus status; /* the status of the operation */ + PRCondVar *complete; /* to notify the initiating thread */ +}; + +static struct pt_TimedQueue +{ + PRLock *ml; /* a little protection */ + PRThread *thread; /* internal thread's identification */ + PRCondVar *new_op; /* new operation supplied */ + PRCondVar *finish_op; /* an existing operation finished */ + PRUintn op_count; /* number of operations in the list */ + pt_Continuation *head, *tail; /* head/tail of list of operations */ + + pt_Continuation *op; /* timed operation furthest in future */ + PRIntervalTime epoch; /* the epoch of 'timed' */ +} pt_tq; + +#if defined(DEBUG) +static struct pt_debug_s +{ + PRIntn predictionsFoiled; + PRIntn pollingListMax; + PRIntn continuationsServed; +} pt_debug; +#endif /* DEBUG */ + +static void ContinuationThread(void *arg); +static PRInt32 pt_SendTo( + SOCKET osfd, const void *buf, + PRInt32 amount, PRInt32 flags, const PRNetAddr *addr, + PRIntn addrlen, PRIntervalTime timeout); +static PRInt32 pt_RecvFrom(SOCKET osfd, void *buf, PRInt32 amount, + PRInt32 flags, PRNetAddr *addr, PRIntn *addr_len, PRIntervalTime timeout); + + +/* The key returned from GetQueuedCompletionStatus() is used to determine what + * type of completion we have. We differentiate between IO completions and + * CVAR completions. + */ +#define KEY_IO 0xaaaaaaaa +#define KEY_CVAR 0xbbbbbbbb + +PRInt32 +_PR_MD_PAUSE_CPU(PRIntervalTime ticks) +{ + int awoken = 0; + unsigned long bytes, key; + int rv; + LPOVERLAPPED olp; + _MDOverlapped *mdOlp; + PRUint32 timeout; + + if (_nt_idleCount > 0) { + PRThread *deadThread; + + _MD_LOCK(&_nt_idleLock); + while( !PR_CLIST_IS_EMPTY(&_nt_idleList) ) { + deadThread = _PR_THREAD_PTR(PR_LIST_HEAD(&_nt_idleList)); + PR_REMOVE_LINK(&deadThread->links); + + PR_ASSERT(deadThread->state == _PR_DEAD_STATE); + + /* XXXMB - cleanup to do here? */ + if ( !_PR_IS_NATIVE_THREAD(deadThread) ){ + /* Spinlock while user thread is still running. + * There is no way to use a condition variable here. The thread + * is dead, and we have to wait until we switch off the dead + * thread before we can kill the fiber completely. + */ + while ( deadThread->no_sched) + ; + + DeleteFiber(deadThread->md.fiber_id); + } + memset(deadThread, 0xa, sizeof(PRThread)); /* debugging */ + if (!deadThread->threadAllocatedOnStack) + PR_DELETE(deadThread); + _nt_idleCount--; + } + _MD_UNLOCK(&_nt_idleLock); + } + + if (ticks == PR_INTERVAL_NO_TIMEOUT) +#if 0 + timeout = INFINITE; +#else + /* + * temporary hack to poll the runq every 5 seconds because of bug in + * native threads creating user threads and not poking the right cpu. + * + * A local thread that was interrupted is bound to its current + * cpu but there is no easy way for the interrupter to poke the + * right cpu. This is a hack to poll the runq every 5 seconds. + */ + timeout = 5000; +#endif + else + timeout = PR_IntervalToMilliseconds(ticks); + + /* + * The idea of looping here is to complete as many IOs as possible before + * returning. This should minimize trips to the idle thread. + */ + while(1) { + rv = GetQueuedCompletionStatus( + _pr_completion_port, + &bytes, + &key, + &olp, + timeout); + if (rv == 0 && olp == NULL) { + /* Error in GetQueuedCompetionStatus */ + if (GetLastError() != WAIT_TIMEOUT) { + /* ARGH - what can we do here? Log an error? XXXMB */ + return -1; + } else { + /* If awoken == 0, then we just had a timeout */ + return awoken; + } + } + + if (olp == NULL) + return 0; + + mdOlp = (_MDOverlapped *)olp; + + if (mdOlp->ioModel == _MD_MultiWaitIO) { + PRRecvWait *desc; + PRWaitGroup *group; + PRThread *thred = NULL; + PRMWStatus mwstatus; + + desc = mdOlp->data.mw.desc; + PR_ASSERT(desc != NULL); + mwstatus = rv ? PR_MW_SUCCESS : PR_MW_FAILURE; + if (InterlockedCompareExchange((PVOID *)&desc->outcome, + (PVOID)mwstatus, (PVOID)PR_MW_PENDING) + == (PVOID)PR_MW_PENDING) { + if (mwstatus == PR_MW_SUCCESS) { + desc->bytesRecv = bytes; + } else { + mdOlp->data.mw.error = GetLastError(); + } + } + group = mdOlp->data.mw.group; + PR_ASSERT(group != NULL); + + _PR_MD_LOCK(&group->mdlock); + PR_APPEND_LINK(&mdOlp->data.mw.links, &group->io_ready); + PR_ASSERT(desc->fd != NULL); + NT_HashRemoveInternal(group, desc->fd); + if (!PR_CLIST_IS_EMPTY(&group->wait_list)) { + thred = _PR_THREAD_CONDQ_PTR(PR_LIST_HEAD(&group->wait_list)); + PR_REMOVE_LINK(&thred->waitQLinks); + } + _PR_MD_UNLOCK(&group->mdlock); + + if (thred) { + if (!_PR_IS_NATIVE_THREAD(thred)) { + int pri = thred->priority; + _PRCPU *lockedCPU = _PR_MD_CURRENT_CPU(); + _PR_THREAD_LOCK(thred); + if (thred->flags & _PR_ON_PAUSEQ) { + _PR_SLEEPQ_LOCK(thred->cpu); + _PR_DEL_SLEEPQ(thred, PR_TRUE); + _PR_SLEEPQ_UNLOCK(thred->cpu); + _PR_THREAD_UNLOCK(thred); + thred->cpu = lockedCPU; + thred->state = _PR_RUNNABLE; + _PR_RUNQ_LOCK(lockedCPU); + _PR_ADD_RUNQ(thred, lockedCPU, pri); + _PR_RUNQ_UNLOCK(lockedCPU); + } else { + /* + * The thread was just interrupted and moved + * from the pause queue to the run queue. + */ + _PR_THREAD_UNLOCK(thred); + } + } else { + _PR_THREAD_LOCK(thred); + thred->state = _PR_RUNNABLE; + _PR_THREAD_UNLOCK(thred); + ReleaseSemaphore(thred->md.blocked_sema, 1, NULL); + } + } + } else { + PRThread *completed_io; + + PR_ASSERT(mdOlp->ioModel == _MD_BlockingIO); + completed_io = _PR_THREAD_MD_TO_PTR(mdOlp->data.mdThread); + completed_io->md.blocked_io_status = rv; + if (rv == 0) + completed_io->md.blocked_io_error = GetLastError(); + completed_io->md.blocked_io_bytes = bytes; + + if ( !_PR_IS_NATIVE_THREAD(completed_io) ) { + int pri = completed_io->priority; + _PRCPU *lockedCPU = _PR_MD_CURRENT_CPU(); + + /* The KEY_CVAR notification only occurs when a native thread + * is notifying a user thread. For user-user notifications + * the wakeup occurs by having the notifier place the thread + * on the runq directly; for native-native notifications the + * wakeup occurs by calling ReleaseSemaphore. + */ + if ( key == KEY_CVAR ) { + PR_ASSERT(completed_io->io_pending == PR_FALSE); + PR_ASSERT(completed_io->io_suspended == PR_FALSE); + PR_ASSERT(completed_io->md.thr_bound_cpu == NULL); + + /* Thread has already been deleted from sleepQ */ + + /* Switch CPU and add to runQ */ + completed_io->cpu = lockedCPU; + completed_io->state = _PR_RUNNABLE; + _PR_RUNQ_LOCK(lockedCPU); + _PR_ADD_RUNQ(completed_io, lockedCPU, pri); + _PR_RUNQ_UNLOCK(lockedCPU); + } else { + PR_ASSERT(key == KEY_IO); + PR_ASSERT(completed_io->io_pending == PR_TRUE); + + _PR_THREAD_LOCK(completed_io); + + completed_io->io_pending = PR_FALSE; + + /* If io_suspended is true, then this IO has already resumed. + * We don't need to do anything; because the thread is + * already running. + */ + if (completed_io->io_suspended == PR_FALSE) { + if (completed_io->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) { + _PR_SLEEPQ_LOCK(completed_io->cpu); + _PR_DEL_SLEEPQ(completed_io, PR_TRUE); + _PR_SLEEPQ_UNLOCK(completed_io->cpu); + + _PR_THREAD_UNLOCK(completed_io); + + /* + * If an I/O operation is suspended, the thread + * must be running on the same cpu on which the + * I/O operation was issued. + */ + PR_ASSERT(!completed_io->md.thr_bound_cpu || + (completed_io->cpu == completed_io->md.thr_bound_cpu)); + + if (!completed_io->md.thr_bound_cpu) + completed_io->cpu = lockedCPU; + completed_io->state = _PR_RUNNABLE; + _PR_RUNQ_LOCK(completed_io->cpu); + _PR_ADD_RUNQ(completed_io, completed_io->cpu, pri); + _PR_RUNQ_UNLOCK(completed_io->cpu); + } else { + _PR_THREAD_UNLOCK(completed_io); + } + } else { + _PR_THREAD_UNLOCK(completed_io); + } + } + } else { + /* For native threads, they are only notified through this loop + * when completing IO. So, don't worry about this being a CVAR + * notification, because that is not possible. + */ + _PR_THREAD_LOCK(completed_io); + completed_io->io_pending = PR_FALSE; + if (completed_io->io_suspended == PR_FALSE) { + completed_io->state = _PR_RUNNABLE; + _PR_THREAD_UNLOCK(completed_io); + rv = ReleaseSemaphore(completed_io->md.blocked_sema, + 1, NULL); + PR_ASSERT(0 != rv); + } else { + _PR_THREAD_UNLOCK(completed_io); + } + } + } + + awoken++; + timeout = 0; /* Don't block on subsequent trips through the loop */ + } + + /* never reached */ + return 0; +} + +static PRStatus +_native_thread_md_wait(PRThread *thread, PRIntervalTime ticks) +{ + DWORD rv; + PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? + INFINITE : PR_IntervalToMilliseconds(ticks); + + /* + * thread waiting for a cvar or a joining thread + */ + rv = WaitForSingleObject(thread->md.blocked_sema, msecs); + switch(rv) { + case WAIT_OBJECT_0: + return PR_SUCCESS; + break; + case WAIT_TIMEOUT: + _PR_THREAD_LOCK(thread); + PR_ASSERT (thread->state != _PR_IO_WAIT); + if (thread->wait.cvar != NULL) { + PR_ASSERT(thread->state == _PR_COND_WAIT); + thread->wait.cvar = NULL; + thread->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(thread); + } else { + /* The CVAR was notified just as the timeout + * occurred. This left the semaphore in the + * signaled state. Call WaitForSingleObject() + * to clear the semaphore. + */ + _PR_THREAD_UNLOCK(thread); + rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE); + PR_ASSERT(rv == WAIT_OBJECT_0); + } + return PR_SUCCESS; + break; + default: + return PR_FAILURE; + break; + } + + return PR_SUCCESS; +} + +PRStatus +_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + DWORD rv; + + if (_native_threads_only) { + return(_native_thread_md_wait(thread, ticks)); + } + if ( thread->flags & _PR_GLOBAL_SCOPE ) { + PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? + INFINITE : PR_IntervalToMilliseconds(ticks); + rv = WaitForSingleObject(thread->md.blocked_sema, msecs); + switch(rv) { + case WAIT_OBJECT_0: + return PR_SUCCESS; + break; + case WAIT_TIMEOUT: + _PR_THREAD_LOCK(thread); + if (thread->state == _PR_IO_WAIT) { + if (thread->io_pending == PR_TRUE) { + thread->state = _PR_RUNNING; + thread->io_suspended = PR_TRUE; + _PR_THREAD_UNLOCK(thread); + } else { + /* The IO completed just at the same time the timeout + * occurred. This left the semaphore in the signaled + * state. Call WaitForSingleObject() to clear the + * semaphore. + */ + _PR_THREAD_UNLOCK(thread); + rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE); + PR_ASSERT(rv == WAIT_OBJECT_0); + } + } else { + if (thread->wait.cvar != NULL) { + PR_ASSERT(thread->state == _PR_COND_WAIT); + thread->wait.cvar = NULL; + thread->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(thread); + } else { + /* The CVAR was notified just as the timeout + * occurred. This left the semaphore in the + * signaled state. Call WaitForSingleObject() + * to clear the semaphore. + */ + _PR_THREAD_UNLOCK(thread); + rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE); + PR_ASSERT(rv == WAIT_OBJECT_0); + } + } + return PR_SUCCESS; + break; + default: + return PR_FAILURE; + break; + } + } else { + PRInt32 is; + + _PR_INTSOFF(is); + _PR_MD_SWITCH_CONTEXT(thread); + } + + return PR_SUCCESS; +} + +static void +_native_thread_io_nowait( + PRThread *thread, + int rv, + int bytes) +{ + int rc; + + PR_ASSERT(rv != 0); + _PR_THREAD_LOCK(thread); + if (thread->state == _PR_IO_WAIT) { + PR_ASSERT(thread->io_suspended == PR_FALSE); + PR_ASSERT(thread->io_pending == PR_TRUE); + thread->state = _PR_RUNNING; + thread->io_pending = PR_FALSE; + _PR_THREAD_UNLOCK(thread); + } else { + /* The IO completed just at the same time the + * thread was interrupted. This left the semaphore + * in the signaled state. Call WaitForSingleObject() + * to clear the semaphore. + */ + PR_ASSERT(thread->io_suspended == PR_TRUE); + PR_ASSERT(thread->io_pending == PR_TRUE); + thread->io_pending = PR_FALSE; + _PR_THREAD_UNLOCK(thread); + rc = WaitForSingleObject(thread->md.blocked_sema, INFINITE); + PR_ASSERT(rc == WAIT_OBJECT_0); + } + + thread->md.blocked_io_status = rv; + thread->md.blocked_io_bytes = bytes; + rc = ResetEvent(thread->md.thr_event); + PR_ASSERT(rc != 0); + return; +} + +static PRStatus +_native_thread_io_wait(PRThread *thread, PRIntervalTime ticks) +{ + DWORD rv, bytes; +#define _NATIVE_IO_WAIT_HANDLES 2 +#define _NATIVE_WAKEUP_EVENT_INDEX 0 +#define _NATIVE_IO_EVENT_INDEX 1 + + HANDLE wait_handles[_NATIVE_IO_WAIT_HANDLES]; + + PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? + INFINITE : PR_IntervalToMilliseconds(ticks); + + PR_ASSERT(thread->flags & _PR_GLOBAL_SCOPE); + + wait_handles[0] = thread->md.blocked_sema; + wait_handles[1] = thread->md.thr_event; + rv = WaitForMultipleObjects(_NATIVE_IO_WAIT_HANDLES, wait_handles, + FALSE, msecs); + + switch(rv) { + case WAIT_OBJECT_0 + _NATIVE_IO_EVENT_INDEX: + /* + * I/O op completed + */ + _PR_THREAD_LOCK(thread); + if (thread->state == _PR_IO_WAIT) { + + PR_ASSERT(thread->io_suspended == PR_FALSE); + PR_ASSERT(thread->io_pending == PR_TRUE); + thread->state = _PR_RUNNING; + thread->io_pending = PR_FALSE; + _PR_THREAD_UNLOCK(thread); + } else { + /* The IO completed just at the same time the + * thread was interrupted. This led to us being + * notified twice. Call WaitForSingleObject() + * to clear the semaphore. + */ + PR_ASSERT(thread->io_suspended == PR_TRUE); + PR_ASSERT(thread->io_pending == PR_TRUE); + thread->io_pending = PR_FALSE; + _PR_THREAD_UNLOCK(thread); + rv = WaitForSingleObject(thread->md.blocked_sema, + INFINITE); + PR_ASSERT(rv == WAIT_OBJECT_0); + } + + rv = GetOverlappedResult((HANDLE) thread->io_fd, + &thread->md.overlapped.overlapped, &bytes, FALSE); + + thread->md.blocked_io_status = rv; + if (rv != 0) { + thread->md.blocked_io_bytes = bytes; + } else { + thread->md.blocked_io_error = GetLastError(); + PR_ASSERT(ERROR_IO_PENDING != thread->md.blocked_io_error); + } + rv = ResetEvent(thread->md.thr_event); + PR_ASSERT(rv != 0); + break; + case WAIT_OBJECT_0 + _NATIVE_WAKEUP_EVENT_INDEX: + /* + * I/O interrupted; + */ +#ifdef DEBUG + _PR_THREAD_LOCK(thread); + PR_ASSERT(thread->io_suspended == PR_TRUE); + _PR_THREAD_UNLOCK(thread); +#endif + break; + case WAIT_TIMEOUT: + _PR_THREAD_LOCK(thread); + if (thread->state == _PR_IO_WAIT) { + thread->state = _PR_RUNNING; + thread->io_suspended = PR_TRUE; + _PR_THREAD_UNLOCK(thread); + } else { + /* + * The thread was interrupted just as the timeout + * occurred. This left the semaphore in the signaled + * state. Call WaitForSingleObject() to clear the + * semaphore. + */ + PR_ASSERT(thread->io_suspended == PR_TRUE); + _PR_THREAD_UNLOCK(thread); + rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE); + PR_ASSERT(rv == WAIT_OBJECT_0); + } + break; + default: + return PR_FAILURE; + break; + } + + return PR_SUCCESS; +} + + +static PRStatus +_NT_IO_WAIT(PRThread *thread, PRIntervalTime timeout) +{ + PRBool fWait = PR_TRUE; + + if (_native_threads_only) { + return(_native_thread_io_wait(thread, timeout)); + } + if (!_PR_IS_NATIVE_THREAD(thread)) { + + _PR_THREAD_LOCK(thread); + + /* The IO may have already completed; if so, don't add to sleepQ, + * since we are already on the runQ! + */ + if (thread->io_pending == PR_TRUE) { + _PR_SLEEPQ_LOCK(thread->cpu); + _PR_ADD_SLEEPQ(thread, timeout); + _PR_SLEEPQ_UNLOCK(thread->cpu); + } else + fWait = PR_FALSE; + _PR_THREAD_UNLOCK(thread); + } + if (fWait) + return _PR_MD_WAIT(thread, timeout); + else + return PR_SUCCESS; +} + +/* + * Unblock threads waiting for I/O + * used when interrupting threads + * + * NOTE: The thread lock should held when this function is called. + * On return, the thread lock is released. + */ +void _PR_Unblock_IO_Wait(PRThread *thr) +{ + PRStatus rv; + _PRCPU *cpu = thr->cpu; + + PR_ASSERT(thr->state == _PR_IO_WAIT); + /* + * A thread for which an I/O timed out or was interrupted cannot be + * in an IO_WAIT state except as a result of calling PR_Close or + * PR_NT_CancelIo for the FD. For these two cases, _PR_IO_WAIT state + * is not interruptible + */ + if (thr->md.interrupt_disabled == PR_TRUE) { + _PR_THREAD_UNLOCK(thr); + return; + } + thr->io_suspended = PR_TRUE; + thr->state = _PR_RUNNABLE; + + if (!_PR_IS_NATIVE_THREAD(thr)) { + PRThread *me = _PR_MD_CURRENT_THREAD(); + PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ)); + _PR_SLEEPQ_LOCK(cpu); + _PR_DEL_SLEEPQ(thr, PR_TRUE); + _PR_SLEEPQ_UNLOCK(cpu); + /* + * this thread will continue to run on the same cpu until the + * I/O is aborted by closing the FD or calling CancelIO + */ + thr->md.thr_bound_cpu = cpu; + + PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD)); + _PR_AddThreadToRunQ(me, thr); + } + _PR_THREAD_UNLOCK(thr); + rv = _PR_MD_WAKEUP_WAITER(thr); + PR_ASSERT(PR_SUCCESS == rv); +} + +/* Resume an outstanding IO; requires that after the switch, we disable */ +static PRStatus +_NT_ResumeIO(PRThread *thread, PRIntervalTime ticks) +{ + PRBool fWait = PR_TRUE; + + if (!_PR_IS_NATIVE_THREAD(thread)) { + if (_pr_use_static_tls) { + _pr_io_restarted_io = thread; + } else { + TlsSetValue(_pr_io_restartedIOIndex, thread); + } + } else { + _PR_THREAD_LOCK(thread); + if (!thread->io_pending) + fWait = PR_FALSE; + thread->io_suspended = PR_FALSE; + + _PR_THREAD_UNLOCK(thread); + } + /* We don't put ourselves back on the sleepQ yet; until we + * set the suspended bit to false, we can't do that. Just save + * the sleep time here, and then continue. The restarted_io handler + * will add us to the sleepQ if needed. + */ + thread->sleep = ticks; + + if (fWait) { + if (!_PR_IS_NATIVE_THREAD(thread)) + return _PR_MD_WAIT(thread, ticks); + else + return _NT_IO_WAIT(thread, ticks); + } + return PR_SUCCESS; +} + +PRStatus +_PR_MD_WAKEUP_WAITER(PRThread *thread) +{ + if (thread == NULL) { + /* If thread is NULL, we aren't waking a thread, we're just poking + * idle thread + */ + if ( PostQueuedCompletionStatus(_pr_completion_port, 0, + KEY_CVAR, NULL) == FALSE) + return PR_FAILURE; + return PR_SUCCESS; + } + + if ( _PR_IS_NATIVE_THREAD(thread) ) { + if (ReleaseSemaphore(thread->md.blocked_sema, 1, NULL) == FALSE) + return PR_FAILURE; + else + return PR_SUCCESS; + } else { + PRThread *me = _PR_MD_CURRENT_THREAD(); + + /* When a Native thread has to awaken a user thread, it has to poke + * the completion port because all user threads might be idle, and + * thus the CPUs are just waiting for a completion. + * + * XXXMB - can we know when we are truely idle (and not checking + * the runq)? + */ + if ((_PR_IS_NATIVE_THREAD(me) || (thread->cpu != me->cpu)) && + (!thread->md.thr_bound_cpu)) { + /* The thread should not be in any queue */ + PR_ASSERT(thread->queueCount == 0); + if ( PostQueuedCompletionStatus(_pr_completion_port, 0, + KEY_CVAR, &(thread->md.overlapped.overlapped)) == FALSE) + return PR_FAILURE; + } + return PR_SUCCESS; + } +} + +void +_PR_MD_INIT_IO() +{ + WORD WSAVersion = 0x0101; + WSADATA WSAData; + int err; + OSVERSIONINFO OSversion; + + err = WSAStartup( WSAVersion, &WSAData ); + PR_ASSERT(0 == err); + + _pr_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, + NULL, + 0, + 0); + + _MD_NEW_LOCK(&_pr_recycle_lock); + _MD_NEW_LOCK(&_pr_ioq_lock); + + OSversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (GetVersionEx(&OSversion)) { + _nt_version_gets_lockfile_completion = PR_FALSE; + if (OSversion.dwMajorVersion >= 4) { + _nt_version_gets_lockfile_completion = PR_TRUE; + } + } else + PR_ASSERT(0); + +#ifdef _NEED_351_FILE_LOCKING_HACK + IsFileLocalInit(); +#endif /* _NEED_351_FILE_LOCKING_HACK */ + + /* + * UDP support: start up the continuation thread + */ + + pt_tq.op_count = 0; + pt_tq.head = pt_tq.tail = NULL; + pt_tq.ml = PR_NewLock(); + PR_ASSERT(NULL != pt_tq.ml); + pt_tq.new_op = PR_NewCondVar(pt_tq.ml); + PR_ASSERT(NULL != pt_tq.new_op); +#if defined(DEBUG) + memset(&pt_debug, 0, sizeof(struct pt_debug_s)); +#endif + + pt_tq.thread = PR_CreateThread( + PR_SYSTEM_THREAD, ContinuationThread, NULL, + PR_PRIORITY_URGENT, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + + PR_ASSERT(NULL != pt_tq.thread); + +#ifdef DEBUG + /* Doublecheck _pr_filetime_offset's hard-coded value is correct. */ + { + SYSTEMTIME systime; + union { + PRTime prt; + FILETIME ft; + } filetime; + BOOL rv; + + systime.wYear = 1970; + systime.wMonth = 1; + /* wDayOfWeek is ignored */ + systime.wDay = 1; + systime.wHour = 0; + systime.wMinute = 0; + systime.wSecond = 0; + systime.wMilliseconds = 0; + + rv = SystemTimeToFileTime(&systime, &filetime.ft); + PR_ASSERT(0 != rv); + PR_ASSERT(filetime.prt == _pr_filetime_offset); + } +#endif /* DEBUG */ + + _PR_NT_InitSids(); +} + +/* --- SOCKET IO --------------------------------------------------------- */ + +/* _md_get_recycled_socket() + * Get a socket from the recycle bin; if no sockets are in the bin, + * create one. The socket will be passed to AcceptEx() as the + * second argument. + */ +static SOCKET +_md_get_recycled_socket(int af) +{ + SOCKET rv; + + _MD_LOCK(&_pr_recycle_lock); + if (af == AF_INET && _pr_recycle_INET_tail) { + _pr_recycle_INET_tail--; + rv = _pr_recycle_INET_array[_pr_recycle_INET_tail]; + _MD_UNLOCK(&_pr_recycle_lock); + return rv; + } + if (af == AF_INET6 && _pr_recycle_INET6_tail) { + _pr_recycle_INET6_tail--; + rv = _pr_recycle_INET6_array[_pr_recycle_INET6_tail]; + _MD_UNLOCK(&_pr_recycle_lock); + return rv; + } + _MD_UNLOCK(&_pr_recycle_lock); + + rv = _PR_MD_SOCKET(af, SOCK_STREAM, 0); + if (rv != INVALID_SOCKET && _md_Associate((HANDLE)rv) == 0) { + closesocket(rv); + return INVALID_SOCKET; + } + return rv; +} + +/* _md_put_recycled_socket() + * Add a socket to the recycle bin. + */ +static void +_md_put_recycled_socket(SOCKET newsock, int af) +{ + PR_ASSERT(_pr_recycle_INET_tail >= 0); + PR_ASSERT(_pr_recycle_INET6_tail >= 0); + + _MD_LOCK(&_pr_recycle_lock); + if (af == AF_INET && _pr_recycle_INET_tail < RECYCLE_SIZE) { + _pr_recycle_INET_array[_pr_recycle_INET_tail] = newsock; + _pr_recycle_INET_tail++; + _MD_UNLOCK(&_pr_recycle_lock); + } else if (af == AF_INET6 && _pr_recycle_INET6_tail < RECYCLE_SIZE) { + _pr_recycle_INET6_array[_pr_recycle_INET6_tail] = newsock; + _pr_recycle_INET6_tail++; + _MD_UNLOCK(&_pr_recycle_lock); + } else { + _MD_UNLOCK(&_pr_recycle_lock); + closesocket(newsock); + } + + return; +} + +/* _md_Associate() + * Associates a file with the completion port. + * Returns 0 on failure, 1 on success. + */ +PRInt32 +_md_Associate(HANDLE file) +{ + HANDLE port; + + if (!_native_threads_only) { + port = CreateIoCompletionPort((HANDLE)file, + _pr_completion_port, + KEY_IO, + 0); + + /* XXX should map error codes on failures */ + return (port == _pr_completion_port); + } else { + return 1; + } +} + +/* + * _md_MakeNonblock() + * Make a socket nonblocking. + * Returns 0 on failure, 1 on success. + */ +static PRInt32 +_md_MakeNonblock(HANDLE file) +{ + int rv; + u_long one = 1; + + rv = ioctlsocket((SOCKET)file, FIONBIO, &one); + /* XXX should map error codes on failures */ + return (rv == 0); +} + +static int missing_completions = 0; +static int max_wait_loops = 0; + +static PRInt32 +_NT_IO_ABORT(PROsfd sock) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRBool fWait; + PRInt32 rv; + int loop_count; + + /* This is a clumsy way to abort the IO, but it is all we can do. + * It looks a bit racy, but we handle all the cases. + * case 1: IO completes before calling closesocket + * case 1a: fWait is set to PR_FALSE + * This should e the most likely case. We'll properly + * not wait call _NT_IO_WAIT, since the closesocket() + * won't be forcing a completion. + * case 1b: fWait is set to PR_TRUE + * This hopefully won't happen much. When it does, this + * thread will timeout in _NT_IO_WAIT for CLOSE_INTERVAL + * before cleaning up. + * case 2: IO does not complete before calling closesocket + * case 2a: IO never completes + * This is the likely case. We'll close it and wait + * for the completion forced by the close. Return should + * be immediate. + * case 2b: IO completes just after calling closesocket + * Since the closesocket is issued, we'll either get a + * completion back for the real IO or for the close. We + * don't really care. It may not even be possible to get + * a real completion here. In any event, we'll awaken + * from NT_IO_WAIT immediately. + */ + + _PR_THREAD_LOCK(me); + fWait = me->io_pending; + if (fWait) { + /* + * If there's still I/O pending, it should have already timed + * out once before this function is called. + */ + PR_ASSERT(me->io_suspended == PR_TRUE); + + /* Set up to wait for I/O completion again */ + me->state = _PR_IO_WAIT; + me->io_suspended = PR_FALSE; + me->md.interrupt_disabled = PR_TRUE; + } + _PR_THREAD_UNLOCK(me); + + /* Close the socket if there is one */ + if (sock != INVALID_SOCKET) { + rv = closesocket((SOCKET)sock); + } + + /* If there was I/O pending before the close, wait for it to complete */ + if (fWait) { + + /* Wait and wait for the I/O to complete */ + for (loop_count = 0; fWait; ++loop_count) { + + _NT_IO_WAIT(me, CLOSE_TIMEOUT); + + _PR_THREAD_LOCK(me); + fWait = me->io_pending; + if (fWait) { + PR_ASSERT(me->io_suspended == PR_TRUE); + me->state = _PR_IO_WAIT; + me->io_suspended = PR_FALSE; + } + _PR_THREAD_UNLOCK(me); + + if (loop_count > max_wait_loops) { + max_wait_loops = loop_count; + } + } + + if (loop_count > 1) { + ++missing_completions; + } + + me->md.interrupt_disabled = PR_FALSE; + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + } + + PR_ASSERT(me->io_pending == PR_FALSE); + me->md.thr_bound_cpu = NULL; + me->io_suspended = PR_FALSE; + + return rv; +} + + +PROsfd +_PR_MD_SOCKET(int af, int type, int flags) +{ + SOCKET sock; + + sock = socket(af, type, flags); + + if (sock == INVALID_SOCKET) { + _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError()); + } + + return (PROsfd)sock; +} + +struct connect_data_s { + PRInt32 status; + PRInt32 error; + PROsfd osfd; + struct sockaddr *addr; + PRUint32 addrlen; + PRIntervalTime timeout; +}; + +void +_PR_MD_connect_thread(void *cdata) +{ + struct connect_data_s *cd = (struct connect_data_s *)cdata; + + cd->status = connect(cd->osfd, cd->addr, cd->addrlen); + + if (cd->status == SOCKET_ERROR) + cd->error = WSAGetLastError(); + + return; +} + + +PRInt32 +_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, + PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + u_long nbio; + PRInt32 rc; + + if (fd->secret->nonblocking) { + if (!fd->secret->md.io_model_committed) { + rv = _md_MakeNonblock((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + + if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) { + err = WSAGetLastError(); + _PR_MD_MAP_CONNECT_ERROR(err); + } + return rv; + } + + /* + * Temporarily make the socket non-blocking so that we can + * initiate a non-blocking connect and wait for its completion + * (with a timeout) in select. + */ + PR_ASSERT(!fd->secret->md.io_model_committed); + nbio = 1; + rv = ioctlsocket((SOCKET)osfd, FIONBIO, &nbio); + PR_ASSERT(0 == rv); + + rc = _nt_nonblock_connect(fd, (struct sockaddr *) addr, addrlen, timeout); + + /* Set the socket back to blocking. */ + nbio = 0; + rv = ioctlsocket((SOCKET)osfd, FIONBIO, &nbio); + PR_ASSERT(0 == rv); + + return rc; +} + +PRInt32 +_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) +{ + PRInt32 rv; +#if 0 + int one = 1; +#endif + + rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen); + + if (rv == SOCKET_ERROR) { + _PR_MD_MAP_BIND_ERROR(WSAGetLastError()); + return -1; + } + +#if 0 + /* Disable nagle- so far unknown if this is good or not... + */ + rv = setsockopt(fd->secret->md.osfd, + SOL_SOCKET, + TCP_NODELAY, + (const char *)&one, + sizeof(one)); + PR_ASSERT(rv == 0); +#endif + + return 0; +} + +void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd accept_sock, PROsfd listen_sock) +{ + /* Sockets accept()'d with AcceptEx need to call this setsockopt before + * calling anything other than ReadFile(), WriteFile(), send(), recv(), + * Transmitfile(), and closesocket(). In order to call any other + * winsock functions, we have to make this setsockopt call. + * + * XXXMB - For the server, we *NEVER* need this in + * the "normal" code path. But now we have to call it. This is a waste + * of a system call. We'd like to only call it before calling the + * obscure socket calls, but since we don't know at that point what the + * original socket was (or even if it is still alive) we can't do it + * at that point... + */ + setsockopt((SOCKET)accept_sock, + SOL_SOCKET, + SO_UPDATE_ACCEPT_CONTEXT, + (char *)&listen_sock, + sizeof(listen_sock)); + +} + +#define INET_ADDR_PADDED (sizeof(PRNetAddr) + 16) +PROsfd +_PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, + PRIntervalTime timeout, PRBool fast, + _PR_AcceptTimeoutCallback callback, void *callbackArg) +{ + PROsfd osfd = fd->secret->md.osfd; + PRThread *me = _PR_MD_CURRENT_THREAD(); + SOCKET accept_sock; + int bytes; + PRNetAddr *Laddr; + PRNetAddr *Raddr; + PRUint32 llen, err; + int rv; + + if (_NT_USE_NB_IO(fd)) { + if (!fd->secret->md.io_model_committed) { + rv = _md_MakeNonblock((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + /* + * The accepted socket inherits the nonblocking and + * inheritable (HANDLE_FLAG_INHERIT) attributes of + * the listening socket. + */ + accept_sock = _nt_nonblock_accept(fd, (struct sockaddr *)raddr, rlen, timeout); + if (!fd->secret->nonblocking) { + u_long zero = 0; + + rv = ioctlsocket(accept_sock, FIONBIO, &zero); + PR_ASSERT(0 == rv); + } + return accept_sock; + } + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return -1; + } + + if (!fd->secret->md.io_model_committed) { + rv = _md_Associate((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + + if (!me->md.acceptex_buf) { + me->md.acceptex_buf = PR_MALLOC(2*INET_ADDR_PADDED); + if (!me->md.acceptex_buf) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + } + + accept_sock = _md_get_recycled_socket(fd->secret->af); + if (accept_sock == INVALID_SOCKET) + return -1; + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + if (_native_threads_only) + me->md.overlapped.overlapped.hEvent = me->md.thr_event; + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + closesocket(accept_sock); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + me->io_fd = osfd; + + rv = AcceptEx((SOCKET)osfd, + accept_sock, + me->md.acceptex_buf, + 0, + INET_ADDR_PADDED, + INET_ADDR_PADDED, + &bytes, + &(me->md.overlapped.overlapped)); + + if ( (rv == 0) && ((err = WSAGetLastError()) != ERROR_IO_PENDING)) { + /* Argh! The IO failed */ + closesocket(accept_sock); + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + _PR_THREAD_UNLOCK(me); + + _PR_MD_MAP_ACCEPTEX_ERROR(err); + return -1; + } + + if (_native_threads_only && rv) { + _native_thread_io_nowait(me, rv, bytes); + } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { + PR_ASSERT(0); + closesocket(accept_sock); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); + + if (me->io_suspended) { + closesocket(accept_sock); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } + return -1; + } + + if (me->md.blocked_io_status == 0) { + closesocket(accept_sock); + _PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error); + return -1; + } + + if (!fast) + _PR_MD_UPDATE_ACCEPT_CONTEXT((SOCKET)accept_sock, (SOCKET)osfd); + + /* IO is done */ + GetAcceptExSockaddrs( + me->md.acceptex_buf, + 0, + INET_ADDR_PADDED, + INET_ADDR_PADDED, + (LPSOCKADDR *)&(Laddr), + &llen, + (LPSOCKADDR *)&(Raddr), + (unsigned int *)rlen); + + if (raddr != NULL) + memcpy((char *)raddr, (char *)&Raddr->inet, *rlen); + + PR_ASSERT(me->io_pending == PR_FALSE); + + return accept_sock; +} + +PRInt32 +_PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, PRNetAddr **raddr, + void *buf, PRInt32 amount, PRIntervalTime timeout, + PRBool fast, _PR_AcceptTimeoutCallback callback, + void *callbackArg) +{ + PROsfd sock = sd->secret->md.osfd; + PRThread *me = _PR_MD_CURRENT_THREAD(); + int bytes; + PRNetAddr *Laddr; + PRUint32 llen, rlen, err; + int rv; + PRBool isConnected; + PRBool madeCallback = PR_FALSE; + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return -1; + } + + if (!sd->secret->md.io_model_committed) { + rv = _md_Associate((HANDLE)sock); + PR_ASSERT(0 != rv); + sd->secret->md.io_model_committed = PR_TRUE; + } + + *newSock = _md_get_recycled_socket(sd->secret->af); + if (*newSock == INVALID_SOCKET) + return -1; + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + if (_native_threads_only) + me->md.overlapped.overlapped.hEvent = me->md.thr_event; + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + closesocket(*newSock); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + me->io_fd = sock; + + rv = AcceptEx((SOCKET)sock, + *newSock, + buf, + amount, + INET_ADDR_PADDED, + INET_ADDR_PADDED, + &bytes, + &(me->md.overlapped.overlapped)); + + if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING)) { + closesocket(*newSock); + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + _PR_THREAD_UNLOCK(me); + + _PR_MD_MAP_ACCEPTEX_ERROR(err); + return -1; + } + + if (_native_threads_only && rv) { + _native_thread_io_nowait(me, rv, bytes); + } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { + PR_ASSERT(0); + closesocket(*newSock); + return -1; + } + +retry: + if (me->io_suspended) { + PRInt32 err; + INT seconds; + INT bytes = sizeof(seconds); + + PR_ASSERT(timeout != PR_INTERVAL_NO_TIMEOUT); + + err = getsockopt(*newSock, + SOL_SOCKET, + SO_CONNECT_TIME, + (char *)&seconds, + (PINT)&bytes); + if ( err == NO_ERROR ) { + PRIntervalTime elapsed = PR_SecondsToInterval(seconds); + + if (seconds == 0xffffffff) + isConnected = PR_FALSE; + else + isConnected = PR_TRUE; + + if (!isConnected) { + if (madeCallback == PR_FALSE && callback) + callback(callbackArg); + madeCallback = PR_TRUE; + me->state = _PR_IO_WAIT; + if (_NT_ResumeIO(me, timeout) == PR_FAILURE) { + closesocket(*newSock); + return -1; + } + goto retry; + } + + if (elapsed < timeout) { + /* Socket is connected but time not elapsed, RESUME IO */ + timeout -= elapsed; + me->state = _PR_IO_WAIT; + if (_NT_ResumeIO(me, timeout) == PR_FAILURE) { + closesocket(*newSock); + return -1; + } + goto retry; + } + } else { + /* What to do here? Assume socket not open?*/ + PR_ASSERT(0); + isConnected = PR_FALSE; + } + + rv = _NT_IO_ABORT(*newSock); + + PR_ASSERT(me->io_pending == PR_FALSE); + PR_ASSERT(me->io_suspended == PR_FALSE); + PR_ASSERT(me->md.thr_bound_cpu == NULL); + /* If the IO is still suspended, it means we didn't get any + * completion from NT_IO_WAIT. This is not disasterous, I hope, + * but it may mean we still have an IO outstanding... Try to + * recover by just allowing ourselves to continue. + */ + me->io_suspended = PR_FALSE; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } + me->state = _PR_RUNNING; + closesocket(*newSock); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE); + PR_ASSERT(me->io_suspended == PR_FALSE); + PR_ASSERT(me->md.thr_bound_cpu == NULL); + + if (me->md.blocked_io_status == 0) { + _PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error); + closesocket(*newSock); + return -1; + } + + if (!fast) + _PR_MD_UPDATE_ACCEPT_CONTEXT((SOCKET)*newSock, (SOCKET)sock); + + /* IO is done */ + GetAcceptExSockaddrs( + buf, + amount, + INET_ADDR_PADDED, + INET_ADDR_PADDED, + (LPSOCKADDR *)&(Laddr), + &llen, + (LPSOCKADDR *)(raddr), + (unsigned int *)&rlen); + + return me->md.blocked_io_bytes; +} + +PRInt32 +_PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd, + PRInt32 flags, PRIntervalTime timeout) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRInt32 tflags; + int rv, err; + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return -1; + } + + if (!sock->secret->md.io_model_committed) { + rv = _md_Associate((HANDLE)sock->secret->md.osfd); + PR_ASSERT(0 != rv); + sock->secret->md.io_model_committed = PR_TRUE; + } + if (!me->md.xmit_bufs) { + me->md.xmit_bufs = PR_NEW(TRANSMIT_FILE_BUFFERS); + if (!me->md.xmit_bufs) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + } + me->md.xmit_bufs->Head = (void *)sfd->header; + me->md.xmit_bufs->HeadLength = sfd->hlen; + me->md.xmit_bufs->Tail = (void *)sfd->trailer; + me->md.xmit_bufs->TailLength = sfd->tlen; + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + me->md.overlapped.overlapped.Offset = sfd->file_offset; + if (_native_threads_only) + me->md.overlapped.overlapped.hEvent = me->md.thr_event; + + tflags = 0; + if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) + tflags = TF_DISCONNECT | TF_REUSE_SOCKET; + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + me->io_fd = sock->secret->md.osfd; + + rv = TransmitFile((SOCKET)sock->secret->md.osfd, + (HANDLE)sfd->fd->secret->md.osfd, + (DWORD)sfd->file_nbytes, + (DWORD)0, + (LPOVERLAPPED)&(me->md.overlapped.overlapped), + (TRANSMIT_FILE_BUFFERS *)me->md.xmit_bufs, + (DWORD)tflags); + if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + _PR_THREAD_UNLOCK(me); + + _PR_MD_MAP_TRANSMITFILE_ERROR(err); + return -1; + } + + if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { + PR_ASSERT(0); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); + + if (me->io_suspended) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } + return -1; + } + + if (me->md.blocked_io_status == 0) { + _PR_MD_MAP_TRANSMITFILE_ERROR(me->md.blocked_io_error); + return -1; + } + + if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { + _md_put_recycled_socket(sock->secret->md.osfd, sock->secret->af); + } + + PR_ASSERT(me->io_pending == PR_FALSE); + + return me->md.blocked_io_bytes; +} + +PRInt32 +_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRThread *me = _PR_MD_CURRENT_THREAD(); + int bytes; + int rv, err; + + if (_NT_USE_NB_IO(fd)) { + if (!fd->secret->md.io_model_committed) { + rv = _md_MakeNonblock((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + return _nt_nonblock_recv(fd, buf, amount, flags, timeout); + } + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return -1; + } + + if (!fd->secret->md.io_model_committed) { + rv = _md_Associate((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + if (_native_threads_only) + me->md.overlapped.overlapped.hEvent = me->md.thr_event; + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + me->io_fd = osfd; + + rv = ReadFile((HANDLE)osfd, + buf, + amount, + &bytes, + &(me->md.overlapped.overlapped)); + if ( (rv == 0) && (GetLastError() != ERROR_IO_PENDING) ) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + _PR_THREAD_UNLOCK(me); + + if ((err = GetLastError()) == ERROR_HANDLE_EOF) + return 0; + _PR_MD_MAP_READ_ERROR(err); + return -1; + } + + if (_native_threads_only && rv) { + _native_thread_io_nowait(me, rv, bytes); + } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { + PR_ASSERT(0); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); + + if (me->io_suspended) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } + return -1; + } + + if (me->md.blocked_io_status == 0) { + if (me->md.blocked_io_error == ERROR_HANDLE_EOF) + return 0; + _PR_MD_MAP_READ_ERROR(me->md.blocked_io_error); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE); + + return me->md.blocked_io_bytes; +} + +PRInt32 +_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRThread *me = _PR_MD_CURRENT_THREAD(); + int bytes; + int rv, err; + + if (_NT_USE_NB_IO(fd)) { + if (!fd->secret->md.io_model_committed) { + rv = _md_MakeNonblock((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + return _nt_nonblock_send(fd, (char *)buf, amount, timeout); + } + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return -1; + } + + if (!fd->secret->md.io_model_committed) { + rv = _md_Associate((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + if (_native_threads_only) + me->md.overlapped.overlapped.hEvent = me->md.thr_event; + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + me->io_fd = osfd; + + rv = WriteFile((HANDLE)osfd, + buf, + amount, + &bytes, + &(me->md.overlapped.overlapped)); + if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + _PR_THREAD_UNLOCK(me); + + _PR_MD_MAP_WRITE_ERROR(err); + return -1; + } + + if (_native_threads_only && rv) { + _native_thread_io_nowait(me, rv, bytes); + } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) { + PR_ASSERT(0); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); + + if (me->io_suspended) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } + return -1; + } + + if (me->md.blocked_io_status == 0) { + _PR_MD_MAP_WRITE_ERROR(me->md.blocked_io_error); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE); + + return me->md.blocked_io_bytes; +} + +PRInt32 +_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv; + + if (!fd->secret->md.io_model_committed) { + rv = _md_MakeNonblock((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + if (_NT_USE_NB_IO(fd)) + return _nt_nonblock_sendto(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout); + else + return pt_SendTo(osfd, buf, amount, flags, addr, addrlen, timeout); +} + +PRInt32 +_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv; + + if (!fd->secret->md.io_model_committed) { + rv = _md_MakeNonblock((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + if (_NT_USE_NB_IO(fd)) + return _nt_nonblock_recvfrom(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout); + else + return pt_RecvFrom(osfd, buf, amount, flags, addr, addrlen, timeout); +} + +/* XXXMB - for now this is a sockets call only */ +PRInt32 +_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + int index; + int sent = 0; + int rv; + + if (_NT_USE_NB_IO(fd)) { + if (!fd->secret->md.io_model_committed) { + rv = _md_MakeNonblock((HANDLE)osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } + return _nt_nonblock_writev(fd, iov, iov_size, timeout); + } + + for (index=0; index 0) + sent += rv; + if ( rv != iov[index].iov_len ) { + if (sent <= 0) + return -1; + return -1; + } + } + + return sent; +} + +PRInt32 +_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog) +{ + PRInt32 rv; + + rv = listen(fd->secret->md.osfd, backlog); + if (rv < 0) + _PR_MD_MAP_LISTEN_ERROR(WSAGetLastError()); + return(rv); +} + +PRInt32 +_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how) +{ + PRInt32 rv; + + rv = shutdown(fd->secret->md.osfd, how); + if (rv < 0) + _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError()); + return(rv); +} + +PRStatus +_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) +{ + PRInt32 rv; + + rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len); + if (rv==0) + return PR_SUCCESS; + else { + _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError()); + return PR_FAILURE; + } +} + +PRStatus +_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) +{ + PRInt32 rv; + + /* + * NT has a bug that, when invoked on a socket accepted by + * AcceptEx(), getpeername() returns an all-zero peer address. + * To work around this bug, we store the peer's address (returned + * by AcceptEx()) with the socket fd and use the cached peer + * address if the socket is an accepted socket. + */ + + if (fd->secret->md.accepted_socket) { + INT seconds; + INT bytes = sizeof(seconds); + + /* + * Determine if the socket is connected. + */ + + rv = getsockopt(fd->secret->md.osfd, + SOL_SOCKET, + SO_CONNECT_TIME, + (char *) &seconds, + (PINT) &bytes); + if (rv == NO_ERROR) { + if (seconds == 0xffffffff) { + PR_SetError(PR_NOT_CONNECTED_ERROR, 0); + return PR_FAILURE; + } + *len = PR_NETADDR_SIZE(&fd->secret->md.peer_addr); + memcpy(addr, &fd->secret->md.peer_addr, *len); + return PR_SUCCESS; + } else { + _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); + return PR_FAILURE; + } + } else { + rv = getpeername((SOCKET)fd->secret->md.osfd, + (struct sockaddr *) addr, len); + if (rv == 0) { + return PR_SUCCESS; + } else { + _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError()); + return PR_FAILURE; + } + } +} + +PRStatus +_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen) +{ + PRInt32 rv; + + rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); + if (rv==0) + return PR_SUCCESS; + else { + _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); + return PR_FAILURE; + } +} + +PRStatus +_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen) +{ + PRInt32 rv; + + rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); + if (rv==0) + return PR_SUCCESS; + else { + _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError()); + return PR_FAILURE; + } +} + +/* --- FILE IO ----------------------------------------------------------- */ + +PROsfd +_PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode) +{ + HANDLE file; + PRInt32 access = 0; + PRInt32 flags = 0; + PRInt32 flag6 = 0; + + if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; + + if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ; + if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE; + + if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) + flags = CREATE_NEW; + else if (osflags & PR_CREATE_FILE) + flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS; + else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING; + else flags = OPEN_EXISTING; + + + flag6 |= FILE_FLAG_OVERLAPPED; + + file = CreateFile(name, + access, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, + flags, + flag6, + NULL); + if (file == INVALID_HANDLE_VALUE) { + _PR_MD_MAP_OPEN_ERROR(GetLastError()); + return -1; + } + + if (osflags & PR_APPEND) { + if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) { + _PR_MD_MAP_LSEEK_ERROR(GetLastError()); + CloseHandle(file); + return -1; + } + } + + return (PROsfd)file; +} + +PROsfd +_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode) +{ + HANDLE file; + PRInt32 access = 0; + PRInt32 flags = 0; + PRInt32 flag6 = 0; + SECURITY_ATTRIBUTES sa; + LPSECURITY_ATTRIBUTES lpSA = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + + if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; + + if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ; + if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE; + + if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) + flags = CREATE_NEW; + else if (osflags & PR_CREATE_FILE) + flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS; + else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING; + else flags = OPEN_EXISTING; + + + flag6 |= FILE_FLAG_OVERLAPPED; + + if (osflags & PR_CREATE_FILE) { + if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable, + &pSD, &pACL) == PR_SUCCESS) { + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + lpSA = &sa; + } + } + file = CreateFile(name, + access, + FILE_SHARE_READ|FILE_SHARE_WRITE, + lpSA, + flags, + flag6, + NULL); + if (lpSA != NULL) { + _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); + } + if (file == INVALID_HANDLE_VALUE) { + _PR_MD_MAP_OPEN_ERROR(GetLastError()); + return -1; + } + + if (osflags & PR_APPEND) { + if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) { + _PR_MD_MAP_LSEEK_ERROR(GetLastError()); + CloseHandle(file); + return -1; + } + } + + return (PROsfd)file; +} + +PRInt32 +_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len) +{ + PROsfd f = fd->secret->md.osfd; + PRUint32 bytes; + int rv, err; + LONG hiOffset = 0; + LONG loOffset; + + if (!fd->secret->md.sync_file_io) { + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return -1; + } + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + + me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT); + PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR)); + + if (fd->secret->inheritable == _PR_TRI_TRUE) { + rv = ReadFile((HANDLE)f, + (LPVOID)buf, + len, + &bytes, + &me->md.overlapped.overlapped); + if (rv != 0) { + loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT); + PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR)); + return bytes; + } + err = GetLastError(); + if (err == ERROR_IO_PENDING) { + rv = GetOverlappedResult((HANDLE)f, + &me->md.overlapped.overlapped, &bytes, TRUE); + if (rv != 0) { + loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT); + PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR)); + return bytes; + } + err = GetLastError(); + } + if (err == ERROR_HANDLE_EOF) { + return 0; + } else { + _PR_MD_MAP_READ_ERROR(err); + return -1; + } + } else { + if (!fd->secret->md.io_model_committed) { + rv = _md_Associate((HANDLE)f); + PR_ASSERT(rv != 0); + fd->secret->md.io_model_committed = PR_TRUE; + } + + if (_native_threads_only) + me->md.overlapped.overlapped.hEvent = me->md.thr_event; + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + me->io_fd = f; + + rv = ReadFile((HANDLE)f, + (LPVOID)buf, + len, + &bytes, + &me->md.overlapped.overlapped); + if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + _PR_THREAD_UNLOCK(me); + + if (err == ERROR_HANDLE_EOF) { + return 0; + } + _PR_MD_MAP_READ_ERROR(err); + return -1; + } + + if (_native_threads_only && rv) { + _native_thread_io_nowait(me, rv, bytes); + } else if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + PR_ASSERT(0); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); + + if (me->io_suspended) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } + return -1; + } + + if (me->md.blocked_io_status == 0) { + if (me->md.blocked_io_error == ERROR_HANDLE_EOF) { + return 0; + } + _PR_MD_MAP_READ_ERROR(me->md.blocked_io_error); + return -1; + } + + SetFilePointer((HANDLE)f, me->md.blocked_io_bytes, 0, FILE_CURRENT); + + PR_ASSERT(me->io_pending == PR_FALSE); + + return me->md.blocked_io_bytes; + } + } else { + + rv = ReadFile((HANDLE)f, + (LPVOID)buf, + len, + &bytes, + NULL); + if (rv == 0) { + err = GetLastError(); + /* ERROR_HANDLE_EOF can only be returned by async io */ + PR_ASSERT(err != ERROR_HANDLE_EOF); + if (err == ERROR_BROKEN_PIPE) { + /* The write end of the pipe has been closed. */ + return 0; + } + _PR_MD_MAP_READ_ERROR(err); + return -1; + } + return bytes; + } +} + +PRInt32 +_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len) +{ + PROsfd f = fd->secret->md.osfd; + PRInt32 bytes; + int rv, err; + LONG hiOffset = 0; + LONG loOffset; + LARGE_INTEGER offset; /* use for the calculation of the new offset */ + + if (!fd->secret->md.sync_file_io) { + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return -1; + } + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + + me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT); + PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR)); + + if (fd->secret->inheritable == _PR_TRI_TRUE) { + rv = WriteFile((HANDLE)f, + (LPVOID)buf, + len, + &bytes, + &me->md.overlapped.overlapped); + if (rv != 0) { + loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT); + PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR)); + return bytes; + } + err = GetLastError(); + if (err == ERROR_IO_PENDING) { + rv = GetOverlappedResult((HANDLE)f, + &me->md.overlapped.overlapped, &bytes, TRUE); + if (rv != 0) { + loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT); + PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR)); + return bytes; + } + err = GetLastError(); + } + _PR_MD_MAP_READ_ERROR(err); + return -1; + } else { + if (!fd->secret->md.io_model_committed) { + rv = _md_Associate((HANDLE)f); + PR_ASSERT(rv != 0); + fd->secret->md.io_model_committed = PR_TRUE; + } + if (_native_threads_only) + me->md.overlapped.overlapped.hEvent = me->md.thr_event; + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + me->io_fd = f; + + rv = WriteFile((HANDLE)f, + buf, + len, + &bytes, + &(me->md.overlapped.overlapped)); + if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + _PR_THREAD_UNLOCK(me); + + _PR_MD_MAP_WRITE_ERROR(err); + return -1; + } + + if (_native_threads_only && rv) { + _native_thread_io_nowait(me, rv, bytes); + } else if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + PR_ASSERT(0); + return -1; + } + + PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE); + + if (me->io_suspended) { + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + } else { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } + return -1; + } + + if (me->md.blocked_io_status == 0) { + _PR_MD_MAP_WRITE_ERROR(me->md.blocked_io_error); + return -1; + } + + /* + * Moving the file pointer by a relative offset (FILE_CURRENT) + * does not work with a file on a network drive exported by a + * Win2K system. We still don't know why. A workaround is to + * move the file pointer by an absolute offset (FILE_BEGIN). + * (Bugzilla bug 70765) + */ + offset.LowPart = me->md.overlapped.overlapped.Offset; + offset.HighPart = me->md.overlapped.overlapped.OffsetHigh; + offset.QuadPart += me->md.blocked_io_bytes; + + SetFilePointer((HANDLE)f, offset.LowPart, &offset.HighPart, FILE_BEGIN); + + PR_ASSERT(me->io_pending == PR_FALSE); + + return me->md.blocked_io_bytes; + } + } else { + rv = WriteFile((HANDLE)f, + buf, + len, + &bytes, + NULL); + if (rv == 0) { + _PR_MD_MAP_WRITE_ERROR(GetLastError()); + return -1; + } + return bytes; + } +} + +PRInt32 +_PR_MD_SOCKETAVAILABLE(PRFileDesc *fd) +{ + PRInt32 result; + + if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError()); + return -1; + } + return result; +} + +PRInt32 +_PR_MD_PIPEAVAILABLE(PRFileDesc *fd) +{ + if (NULL == fd) + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return -1; +} + +PROffset32 +_PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) +{ + DWORD moveMethod; + PROffset32 rv; + + switch (whence) { + case PR_SEEK_SET: + moveMethod = FILE_BEGIN; + break; + case PR_SEEK_CUR: + moveMethod = FILE_CURRENT; + break; + case PR_SEEK_END: + moveMethod = FILE_END; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + rv = SetFilePointer((HANDLE)fd->secret->md.osfd, offset, NULL, moveMethod); + + /* + * If the lpDistanceToMoveHigh argument (third argument) is + * NULL, SetFilePointer returns 0xffffffff on failure. + */ + if (-1 == rv) { + _PR_MD_MAP_LSEEK_ERROR(GetLastError()); + } + return rv; +} + +PROffset64 +_PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) +{ + DWORD moveMethod; + LARGE_INTEGER li; + DWORD err; + + switch (whence) { + case PR_SEEK_SET: + moveMethod = FILE_BEGIN; + break; + case PR_SEEK_CUR: + moveMethod = FILE_CURRENT; + break; + case PR_SEEK_END: + moveMethod = FILE_END; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + li.QuadPart = offset; + li.LowPart = SetFilePointer((HANDLE)fd->secret->md.osfd, + li.LowPart, &li.HighPart, moveMethod); + + if (0xffffffff == li.LowPart && (err = GetLastError()) != NO_ERROR) { + _PR_MD_MAP_LSEEK_ERROR(err); + li.QuadPart = -1; + } + return li.QuadPart; +} + +/* + * This is documented to succeed on read-only files, but Win32's + * FlushFileBuffers functions fails with "access denied" in such a + * case. So we only signal an error if the error is *not* "access + * denied". + */ +PRInt32 +_PR_MD_FSYNC(PRFileDesc *fd) +{ + /* + * From the documentation: + * + * On Windows NT, the function FlushFileBuffers fails if hFile + * is a handle to console output. That is because console + * output is not buffered. The function returns FALSE, and + * GetLastError returns ERROR_INVALID_HANDLE. + * + * On the other hand, on Win95, it returns without error. I cannot + * assume that 0, 1, and 2 are console, because if someone closes + * System.out and then opens a file, they might get file descriptor + * 1. An error on *that* version of 1 should be reported, whereas + * an error on System.out (which was the original 1) should be + * ignored. So I use isatty() to ensure that such an error was + * because of this, and if it was, I ignore the error. + */ + + BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd); + + if (!ok) { + DWORD err = GetLastError(); + + if (err != ERROR_ACCESS_DENIED) { /* from winerror.h */ + _PR_MD_MAP_FSYNC_ERROR(err); + return -1; + } + } + return 0; +} + +PRInt32 +_PR_MD_CLOSE(PROsfd osfd, PRBool socket) +{ + PRInt32 rv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (socket) { + rv = closesocket((SOCKET)osfd); + if (rv < 0) + _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError()); + } else { + rv = CloseHandle((HANDLE)osfd)?0:-1; + if (rv < 0) + _PR_MD_MAP_CLOSE_ERROR(GetLastError()); + } + + if (rv == 0 && me->io_suspended) { + if (me->io_fd == osfd) { + PRBool fWait; + + _PR_THREAD_LOCK(me); + me->state = _PR_IO_WAIT; + /* The IO could have completed on another thread just after + * calling closesocket while the io_suspended flag was true. + * So we now grab the lock to do a safe check on io_pending to + * see if we need to wait or not. + */ + fWait = me->io_pending; + me->io_suspended = PR_FALSE; + me->md.interrupt_disabled = PR_TRUE; + _PR_THREAD_UNLOCK(me); + + if (fWait) + _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(me->io_suspended == PR_FALSE); + PR_ASSERT(me->io_pending == PR_FALSE); + /* + * I/O operation is no longer pending; the thread can now + * run on any cpu + */ + _PR_THREAD_LOCK(me); + me->md.interrupt_disabled = PR_FALSE; + me->md.thr_bound_cpu = NULL; + me->io_suspended = PR_FALSE; + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(me); + } + } + return rv; +} + +PRStatus +_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) +{ + BOOL rv; + + if (fd->secret->md.io_model_committed) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + rv = SetHandleInformation( + (HANDLE)fd->secret->md.osfd, + HANDLE_FLAG_INHERIT, + inheritable ? HANDLE_FLAG_INHERIT : 0); + if (0 == rv) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +void +_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported) +{ + if (imported) { + fd->secret->inheritable = _PR_TRI_UNKNOWN; + } else { + fd->secret->inheritable = _PR_TRI_FALSE; + } +} + +void +_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd) +{ + DWORD flags; + + PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); + if (fd->secret->md.io_model_committed) { + return; + } + if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) { + if (flags & HANDLE_FLAG_INHERIT) { + fd->secret->inheritable = _PR_TRI_TRUE; + } else { + fd->secret->inheritable = _PR_TRI_FALSE; + } + } +} + + +/* --- DIR IO ------------------------------------------------------------ */ +#define GetFileFromDIR(d) (d)->d_entry.cFileName +#define FileIsHidden(d) ((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + +void FlipSlashes(char *cp, int len) +{ + while (--len >= 0) { + if (cp[0] == '/') { + cp[0] = PR_DIRECTORY_SEPARATOR; + } + cp = _mbsinc(cp); + } +} /* end FlipSlashes() */ + +/* +** +** Local implementations of standard Unix RTL functions which are not provided +** by the VC RTL. +** +*/ + +PRInt32 +_PR_MD_CLOSE_DIR(_MDDir *d) +{ + if ( d ) { + if (FindClose( d->d_hdl )) { + d->magic = (PRUint32)-1; + return 0; + } else { + _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError()); + return -1; + } + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; +} + + +PRStatus +_PR_MD_OPEN_DIR(_MDDir *d, const char *name) +{ + char filename[ MAX_PATH ]; + int len; + + len = strlen(name); + /* Need 5 bytes for \*.* and the trailing null byte. */ + if (len + 5 > MAX_PATH) { + PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); + return PR_FAILURE; + } + strcpy(filename, name); + + /* + * If 'name' ends in a slash or backslash, do not append + * another backslash. + */ + if (IsPrevCharSlash(filename, filename + len)) { + len--; + } + strcpy(&filename[len], "\\*.*"); + FlipSlashes( filename, strlen(filename) ); + + d->d_hdl = FindFirstFile( filename, &(d->d_entry) ); + if ( d->d_hdl == INVALID_HANDLE_VALUE ) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return PR_FAILURE; + } + d->firstEntry = PR_TRUE; + d->magic = _MD_MAGIC_DIR; + return PR_SUCCESS; +} + +char * +_PR_MD_READ_DIR(_MDDir *d, PRIntn flags) +{ + PRInt32 err; + BOOL rv; + char *fileName; + + if ( d ) { + while (1) { + if (d->firstEntry) { + d->firstEntry = PR_FALSE; + rv = 1; + } else { + rv = FindNextFile(d->d_hdl, &(d->d_entry)); + } + if (rv == 0) { + break; + } + fileName = GetFileFromDIR(d); + if ( (flags & PR_SKIP_DOT) && + (fileName[0] == '.') && (fileName[1] == '\0')) + continue; + if ( (flags & PR_SKIP_DOT_DOT) && + (fileName[0] == '.') && (fileName[1] == '.') && + (fileName[2] == '\0')) + continue; + if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d)) + continue; + return fileName; + } + err = GetLastError(); + PR_ASSERT(NO_ERROR != err); + _PR_MD_MAP_READDIR_ERROR(err); + return NULL; + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; +} + +PRInt32 +_PR_MD_DELETE(const char *name) +{ + if (DeleteFile(name)) { + return 0; + } else { + _PR_MD_MAP_DELETE_ERROR(GetLastError()); + return -1; + } +} + +void +_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm) +{ + PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime)); + CopyMemory(prtm, filetime, sizeof(PRTime)); +#ifdef __GNUC__ + *prtm = (*prtm - _pr_filetime_offset) / 10LL; +#else + *prtm = (*prtm - _pr_filetime_offset) / 10i64; +#endif + +#ifdef DEBUG + /* Doublecheck our calculation. */ + { + SYSTEMTIME systime; + PRExplodedTime etm; + PRTime cmp; /* for comparison */ + BOOL rv; + + rv = FileTimeToSystemTime(filetime, &systime); + PR_ASSERT(0 != rv); + + /* + * PR_ImplodeTime ignores wday and yday. + */ + etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC; + etm.tm_sec = systime.wSecond; + etm.tm_min = systime.wMinute; + etm.tm_hour = systime.wHour; + etm.tm_mday = systime.wDay; + etm.tm_month = systime.wMonth - 1; + etm.tm_year = systime.wYear; + /* + * It is not well-documented what time zone the FILETIME's + * are in. WIN32_FIND_DATA is documented to be in UTC (GMT). + * But BY_HANDLE_FILE_INFORMATION is unclear about this. + * By our best judgement, we assume that FILETIME is in UTC. + */ + etm.tm_params.tp_gmt_offset = 0; + etm.tm_params.tp_dst_offset = 0; + cmp = PR_ImplodeTime(&etm); + + /* + * SYSTEMTIME is in milliseconds precision, so we convert PRTime's + * microseconds to milliseconds before doing the comparison. + */ + PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC)); + } +#endif /* DEBUG */ +} + +PRInt32 +_PR_MD_STAT(const char *fn, struct stat *info) +{ + PRInt32 rv; + + rv = _stat(fn, (struct _stat *)info); + if (-1 == rv) { + /* + * Check for MSVC runtime library _stat() bug. + * (It's really a bug in FindFirstFile().) + * If a pathname ends in a backslash or slash, + * e.g., c:\temp\ or c:/temp/, _stat() will fail. + * Note: a pathname ending in a slash (e.g., c:/temp/) + * can be handled by _stat() on NT but not on Win95. + * + * We remove the backslash or slash at the end and + * try again. + */ + + int len = strlen(fn); + if (len > 0 && len <= _MAX_PATH + && IsPrevCharSlash(fn, fn + len)) { + char newfn[_MAX_PATH + 1]; + + strcpy(newfn, fn); + newfn[len - 1] = '\0'; + rv = _stat(newfn, (struct _stat *)info); + } + } + + if (-1 == rv) { + _PR_MD_MAP_STAT_ERROR(errno); + } + return rv; +} + +#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\') + +static PRBool +IsPrevCharSlash(const char *str, const char *current) +{ + const char *prev; + + if (str >= current) + return PR_FALSE; + prev = _mbsdec(str, current); + return (prev == current - 1) && _PR_IS_SLASH(*prev); +} + +/* + * IsRootDirectory -- + * + * Return PR_TRUE if the pathname 'fn' is a valid root directory, + * else return PR_FALSE. The char buffer pointed to by 'fn' must + * be writable. During the execution of this function, the contents + * of the buffer pointed to by 'fn' may be modified, but on return + * the original contents will be restored. 'buflen' is the size of + * the buffer pointed to by 'fn'. + * + * Root directories come in three formats: + * 1. / or \, meaning the root directory of the current drive. + * 2. C:/ or C:\, where C is a drive letter. + * 3. \\\\ or + * \\\, meaning the root directory + * of a UNC (Universal Naming Convention) name. + */ + +static PRBool +IsRootDirectory(char *fn, size_t buflen) +{ + char *p; + PRBool slashAdded = PR_FALSE; + PRBool rv = PR_FALSE; + + if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') { + return PR_TRUE; + } + + if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2]) + && fn[3] == '\0') { + rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; + return rv; + } + + /* The UNC root directory */ + + if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) { + /* The 'server' part should have at least one character. */ + p = &fn[2]; + if (*p == '\0' || _PR_IS_SLASH(*p)) { + return PR_FALSE; + } + + /* look for the next slash */ + do { + p = _mbsinc(p); + } while (*p != '\0' && !_PR_IS_SLASH(*p)); + if (*p == '\0') { + return PR_FALSE; + } + + /* The 'share' part should have at least one character. */ + p++; + if (*p == '\0' || _PR_IS_SLASH(*p)) { + return PR_FALSE; + } + + /* look for the final slash */ + do { + p = _mbsinc(p); + } while (*p != '\0' && !_PR_IS_SLASH(*p)); + if (_PR_IS_SLASH(*p) && p[1] != '\0') { + return PR_FALSE; + } + if (*p == '\0') { + /* + * GetDriveType() doesn't work correctly if the + * path is of the form \\server\share, so we add + * a final slash temporarily. + */ + if ((p + 1) < (fn + buflen)) { + *p++ = '\\'; + *p = '\0'; + slashAdded = PR_TRUE; + } else { + return PR_FALSE; /* name too long */ + } + } + rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; + /* restore the 'fn' buffer */ + if (slashAdded) { + *--p = '\0'; + } + } + return rv; +} + +PRInt32 +_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) +{ + WIN32_FILE_ATTRIBUTE_DATA findFileData; + + if (NULL == fn || '\0' == *fn) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + if (!GetFileAttributesEx(fn, GetFileExInfoStandard, &findFileData)) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return -1; + } + + if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + info->type = PR_FILE_DIRECTORY; + } else { + info->type = PR_FILE_FILE; + } + + info->size = findFileData.nFileSizeHigh; + info->size = (info->size << 32) + findFileData.nFileSizeLow; + + _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime); + + if (0 == findFileData.ftCreationTime.dwLowDateTime && + 0 == findFileData.ftCreationTime.dwHighDateTime) { + info->creationTime = info->modifyTime; + } else { + _PR_FileTimeToPRTime(&findFileData.ftCreationTime, + &info->creationTime); + } + + return 0; +} + +PRInt32 +_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info) +{ + PRFileInfo64 info64; + PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64); + if (0 == rv) + { + info->type = info64.type; + info->size = (PRUint32) info64.size; + info->modifyTime = info64.modifyTime; + info->creationTime = info64.creationTime; + } + return rv; +} + +PRInt32 +_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info) +{ + int rv; + + BY_HANDLE_FILE_INFORMATION hinfo; + + rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo); + if (rv == FALSE) { + _PR_MD_MAP_FSTAT_ERROR(GetLastError()); + return -1; + } + + if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_FILE; + + info->size = hinfo.nFileSizeHigh; + info->size = (info->size << 32) + hinfo.nFileSizeLow; + + _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) ); + _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) ); + + return 0; +} + +PRInt32 +_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) +{ + int rv; + + BY_HANDLE_FILE_INFORMATION hinfo; + + rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo); + if (rv == FALSE) { + _PR_MD_MAP_FSTAT_ERROR(GetLastError()); + return -1; + } + + if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_FILE; + + info->size = hinfo.nFileSizeLow; + + _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) ); + _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) ); + + return 0; +} + +PRInt32 +_PR_MD_RENAME(const char *from, const char *to) +{ + /* Does this work with dot-relative pathnames? */ + if (MoveFile(from, to)) { + return 0; + } else { + _PR_MD_MAP_RENAME_ERROR(GetLastError()); + return -1; + } +} + +PRInt32 +_PR_MD_ACCESS(const char *name, PRAccessHow how) +{ + PRInt32 rv; + + switch (how) { + case PR_ACCESS_WRITE_OK: + rv = _access(name, 02); + break; + case PR_ACCESS_READ_OK: + rv = _access(name, 04); + break; + case PR_ACCESS_EXISTS: + rv = _access(name, 00); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + if (rv < 0) { + _PR_MD_MAP_ACCESS_ERROR(errno); + } + return rv; +} + +PRInt32 +_PR_MD_MKDIR(const char *name, PRIntn mode) +{ + /* XXXMB - how to translate the "mode"??? */ + if (CreateDirectory(name, NULL)) { + return 0; + } else { + _PR_MD_MAP_MKDIR_ERROR(GetLastError()); + return -1; + } +} + +PRInt32 +_PR_MD_MAKE_DIR(const char *name, PRIntn mode) +{ + BOOL rv; + SECURITY_ATTRIBUTES sa; + LPSECURITY_ATTRIBUTES lpSA = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + + if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable, + &pSD, &pACL) == PR_SUCCESS) { + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + lpSA = &sa; + } + rv = CreateDirectory(name, lpSA); + if (lpSA != NULL) { + _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); + } + if (rv) { + return 0; + } else { + _PR_MD_MAP_MKDIR_ERROR(GetLastError()); + return -1; + } +} + +PRInt32 +_PR_MD_RMDIR(const char *name) +{ + if (RemoveDirectory(name)) { + return 0; + } else { + _PR_MD_MAP_RMDIR_ERROR(GetLastError()); + return -1; + } +} + +PRStatus +_PR_MD_LOCKFILE(PROsfd f) +{ + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return PR_FAILURE; + } + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + + rv = LockFileEx((HANDLE)f, + LOCKFILE_EXCLUSIVE_LOCK, + 0, + 0x7fffffff, + 0, + &me->md.overlapped.overlapped); + + if (_native_threads_only) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return PR_FAILURE; + } + _PR_THREAD_UNLOCK(me); + + if (rv == FALSE) { + err = GetLastError(); + PR_ASSERT(err != ERROR_IO_PENDING); + _PR_MD_MAP_LOCKF_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; + } + + /* HACK AROUND NT BUG + * NT 3.51 has a bug. In NT 3.51, if LockFileEx returns true, you + * don't get any completion on the completion port. This is a bug. + * + * They fixed it on NT4.0 so that you do get a completion. + * + * If we pretend we won't get a completion, NSPR gets confused later + * when the unexpected completion arrives. If we assume we do get + * a completion, we hang on 3.51. Worse, Microsoft informs me that the + * behavior varies on 3.51 depending on if you are using a network + * file system or a local disk! + * + * Solution: For now, _nt_version_gets_lockfile_completion is set + * depending on whether or not this system is EITHER + * - running NT 4.0 + * - running NT 3.51 with a service pack greater than 5. + * + * In the meantime, this code may not work on network file systems. + * + */ + + if ( rv == FALSE && ((err = GetLastError()) != ERROR_IO_PENDING)) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return PR_FAILURE; + } + _PR_THREAD_UNLOCK(me); + + _PR_MD_MAP_LOCKF_ERROR(err); + return PR_FAILURE; + } +#ifdef _NEED_351_FILE_LOCKING_HACK + else if (rv) { + /* If this is NT 3.51 and the file is local, then we won't get a + * completion back from LockFile when it succeeded. + */ + if (_nt_version_gets_lockfile_completion == PR_FALSE) { + if ( IsFileLocal((HANDLE)f) == _PR_LOCAL_FILE) { + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + return PR_SUCCESS; + } + } + } +#endif /* _NEED_351_FILE_LOCKING_HACK */ + + if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(me); + return PR_FAILURE; + } + + if (me->md.blocked_io_status == 0) { + _PR_MD_MAP_LOCKF_ERROR(me->md.blocked_io_error); + return PR_FAILURE; + } + + return PR_SUCCESS; +} + +PRStatus +_PR_MD_TLOCKFILE(PROsfd f) +{ + PRInt32 rv, err; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return PR_FAILURE; + } + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + + _PR_THREAD_LOCK(me); + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return -1; + } + me->io_pending = PR_TRUE; + me->state = _PR_IO_WAIT; + _PR_THREAD_UNLOCK(me); + + rv = LockFileEx((HANDLE)f, + LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK, + 0, + 0x7fffffff, + 0, + &me->md.overlapped.overlapped); + if (_native_threads_only) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return PR_FAILURE; + } + _PR_THREAD_UNLOCK(me); + + if (rv == FALSE) { + err = GetLastError(); + PR_ASSERT(err != ERROR_IO_PENDING); + _PR_MD_MAP_LOCKF_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; + } + if ( rv == FALSE && ((err = GetLastError()) != ERROR_IO_PENDING)) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return PR_FAILURE; + } + _PR_THREAD_UNLOCK(me); + + _PR_MD_MAP_LOCKF_ERROR(err); + return PR_FAILURE; + } +#ifdef _NEED_351_FILE_LOCKING_HACK + else if (rv) { + /* If this is NT 3.51 and the file is local, then we won't get a + * completion back from LockFile when it succeeded. + */ + if (_nt_version_gets_lockfile_completion == PR_FALSE) { + if ( IsFileLocal((HANDLE)f) == _PR_LOCAL_FILE) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return PR_FAILURE; + } + _PR_THREAD_UNLOCK(me); + + return PR_SUCCESS; + } + } + } +#endif /* _NEED_351_FILE_LOCKING_HACK */ + + if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + _PR_THREAD_LOCK(me); + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + _PR_THREAD_UNLOCK(me); + return PR_FAILURE; + } + _PR_THREAD_UNLOCK(me); + + return PR_FAILURE; + } + + if (me->md.blocked_io_status == 0) { + _PR_MD_MAP_LOCKF_ERROR(me->md.blocked_io_error); + return PR_FAILURE; + } + + return PR_SUCCESS; +} + + +PRStatus +_PR_MD_UNLOCKFILE(PROsfd f) +{ + PRInt32 rv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (me->io_suspended) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return PR_FAILURE; + } + + memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED)); + + rv = UnlockFileEx((HANDLE)f, + 0, + 0x7fffffff, + 0, + &me->md.overlapped.overlapped); + + if (rv) + return PR_SUCCESS; + else { + int err = GetLastError(); + _PR_MD_MAP_LOCKF_ERROR(err); + return PR_FAILURE; + } +} + +void +_PR_MD_MAKE_NONBLOCK(PRFileDesc *f) +{ + /* + * On NT, we either call _md_Associate() or _md_MakeNonblock(), + * depending on whether the socket is blocking or not. + * + * Once we associate a socket with the io completion port, + * there is no way to disassociate it from the io completion + * port. So we have to call _md_Associate/_md_MakeNonblock + * lazily. + */ +} + +#ifdef _NEED_351_FILE_LOCKING_HACK +/*************** +** +** Lockfile hacks +** +** The following code is a hack to work around a microsoft bug with lockfile. +** The problem is that on NT 3.51, if LockFileEx() succeeds, you never +** get a completion back for files that are on local disks. So, we need to +** know if a file is local or remote so we can tell if we should expect +** a completion. +** +** The only way to check if a file is local or remote based on the handle is +** to get the serial number for the volume it is mounted on and then to +** compare that with mounted drives. This code caches the volume numbers of +** fixed disks and does a relatively quick check. +** +** Locking: Since the only thing we ever do when multithreaded is a 32bit +** assignment, we probably don't need locking. It is included just +** case anyway. +** +** Limitations: Does not work on floppies because they are too slow +** Unknown if it will work on wierdo 3rd party file systems +** +**************** +*/ + +/* There can only be 26 drive letters on NT */ +#define _PR_MAX_DRIVES 26 + +_MDLock cachedVolumeLock; +DWORD dwCachedVolumeSerialNumbers[_PR_MAX_DRIVES] = {0}; +DWORD dwLastCachedDrive = 0; +DWORD dwRemoveableDrivesToCheck = 0; /* bitmask for removeable drives */ + +PRBool IsFileLocalInit() +{ + TCHAR lpBuffer[_PR_MAX_DRIVES*5]; + DWORD nBufferLength = _PR_MAX_DRIVES*5; + DWORD nBufferNeeded = GetLogicalDriveStrings(0, NULL); + DWORD dwIndex = 0; + DWORD dwDriveType; + DWORD dwVolumeSerialNumber; + DWORD dwDriveIndex = 0; + DWORD oldmode = (DWORD) -1; + + _MD_NEW_LOCK(&cachedVolumeLock); + + nBufferNeeded = GetLogicalDriveStrings(nBufferLength, lpBuffer); + if (nBufferNeeded == 0 || nBufferNeeded > nBufferLength) + return PR_FALSE; + + // Calling GetVolumeInformation on a removeable drive where the + // disk is currently removed will cause a dialog box to the + // console. This is not good. + // Temporarily disable the SEM_FAILCRITICALERRORS to avoid the + // damn dialog. + + dwCachedVolumeSerialNumbers[dwDriveIndex] = 0; + oldmode = SetErrorMode(SEM_FAILCRITICALERRORS); + + // now loop through the logical drives + while(lpBuffer[dwIndex] != TEXT('\0')) + { + // skip the floppy drives. This is *SLOW* + if ((lpBuffer[dwIndex] == TEXT('A')) || (lpBuffer[dwIndex] == TEXT('B'))) + /* Skip over floppies */; + else + { + dwDriveIndex = (lpBuffer[dwIndex] - TEXT('A')); + + dwDriveType = GetDriveType(&lpBuffer[dwIndex]); + + switch(dwDriveType) + { + // Ignore these drive types + case 0: + case 1: + case DRIVE_REMOTE: + default: // If the drive type is unknown, ignore it. + break; + + // Removable media drives can have different serial numbers + // at different times, so cache the current serial number + // but keep track of them so they can be rechecked if necessary. + case DRIVE_REMOVABLE: + + // CDROM is a removable media + case DRIVE_CDROM: + + // no idea if ramdisks can change serial numbers or not + // but it doesn't hurt to treat them as removable. + + case DRIVE_RAMDISK: + + + // Here is where we keep track of removable drives. + dwRemoveableDrivesToCheck |= 1 << dwDriveIndex; + + // removable drives fall through to fixed drives and get cached. + + case DRIVE_FIXED: + + // cache volume serial numbers. + if (GetVolumeInformation( + &lpBuffer[dwIndex], + NULL, 0, + &dwVolumeSerialNumber, + NULL, NULL, NULL, 0) + ) + { + if (dwLastCachedDrive < dwDriveIndex) + dwLastCachedDrive = dwDriveIndex; + dwCachedVolumeSerialNumbers[dwDriveIndex] = dwVolumeSerialNumber; + } + + break; + } + } + + dwIndex += lstrlen(&lpBuffer[dwIndex]) +1; + } + + if (oldmode != (DWORD) -1) { + SetErrorMode(oldmode); + oldmode = (DWORD) -1; + } + + return PR_TRUE; +} + +PRInt32 IsFileLocal(HANDLE hFile) +{ + DWORD dwIndex = 0, dwMask; + BY_HANDLE_FILE_INFORMATION Info; + TCHAR szDrive[4] = TEXT("C:\\"); + DWORD dwVolumeSerialNumber; + DWORD oldmode = (DWORD) -1; + int rv = _PR_REMOTE_FILE; + + if (!GetFileInformationByHandle(hFile, &Info)) + return -1; + + // look to see if the volume serial number has been cached. + _MD_LOCK(&cachedVolumeLock); + while(dwIndex <= dwLastCachedDrive) + if (dwCachedVolumeSerialNumbers[dwIndex++] == Info.dwVolumeSerialNumber) + { + _MD_UNLOCK(&cachedVolumeLock); + return _PR_LOCAL_FILE; + } + _MD_UNLOCK(&cachedVolumeLock); + + // volume serial number not found in the cache. Check removable files. + // removable drives are noted as a bitmask. If the bit associated with + // a specific drive is set, then we should query its volume serial number + // as its possible it has changed. + dwMask = dwRemoveableDrivesToCheck; + dwIndex = 0; + + while(dwMask) + { + while(!(dwMask & 1)) + { + dwIndex++; + dwMask = dwMask >> 1; + } + + szDrive[0] = TEXT('A')+ (TCHAR) dwIndex; + + // Calling GetVolumeInformation on a removeable drive where the + // disk is currently removed will cause a dialog box to the + // console. This is not good. + // Temporarily disable the SEM_FAILCRITICALERRORS to avoid the + // dialog. + + oldmode = SetErrorMode(SEM_FAILCRITICALERRORS); + + if (GetVolumeInformation( + szDrive, + NULL, 0, + &dwVolumeSerialNumber, + NULL, NULL, NULL, 0) + ) + { + if (dwVolumeSerialNumber == Info.dwVolumeSerialNumber) + { + _MD_LOCK(&cachedVolumeLock); + if (dwLastCachedDrive < dwIndex) + dwLastCachedDrive = dwIndex; + dwCachedVolumeSerialNumbers[dwIndex] = dwVolumeSerialNumber; + _MD_UNLOCK(&cachedVolumeLock); + rv = _PR_LOCAL_FILE; + } + } + if (oldmode != (DWORD) -1) { + SetErrorMode(oldmode); + oldmode = (DWORD) -1; + } + + if (rv == _PR_LOCAL_FILE) + return _PR_LOCAL_FILE; + + dwIndex++; + dwMask = dwMask >> 1; + } + + return _PR_REMOTE_FILE; +} +#endif /* _NEED_351_FILE_LOCKING_HACK */ + +PR_IMPLEMENT(PRStatus) PR_NT_CancelIo(PRFileDesc *fd) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRBool fWait; + PRFileDesc *bottom; + + bottom = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER); + if (!me->io_suspended || (NULL == bottom) || + (me->io_fd != bottom->secret->md.osfd)) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return PR_FAILURE; + } + /* + * The CancelIO operation has to be issued by the same NT thread that + * issued the I/O operation + */ + PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || (me->cpu == me->md.thr_bound_cpu)); + if (me->io_pending) { + if (!CancelIo((HANDLE)bottom->secret->md.osfd)) { + PR_SetError(PR_INVALID_STATE_ERROR, GetLastError()); + return PR_FAILURE; + } + } + _PR_THREAD_LOCK(me); + fWait = me->io_pending; + me->io_suspended = PR_FALSE; + me->state = _PR_IO_WAIT; + me->md.interrupt_disabled = PR_TRUE; + _PR_THREAD_UNLOCK(me); + if (fWait) + _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(me->io_suspended == PR_FALSE); + PR_ASSERT(me->io_pending == PR_FALSE); + + _PR_THREAD_LOCK(me); + me->md.interrupt_disabled = PR_FALSE; + me->md.thr_bound_cpu = NULL; + me->io_suspended = PR_FALSE; + me->io_pending = PR_FALSE; + me->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(me); + return PR_SUCCESS; +} + +static PROsfd _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr *addr, int *addrlen, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + SOCKET sock; + PRInt32 rv, err; + fd_set rd; + struct timeval tv, *tvp; + + FD_ZERO(&rd); + FD_SET((SOCKET)osfd, &rd); + if (timeout == PR_INTERVAL_NO_TIMEOUT) { + while ((sock = accept(osfd, addr, addrlen)) == -1) { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) { + if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, + NULL)) == -1) { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + break; + } + } else { + _PR_MD_MAP_ACCEPT_ERROR(err); + break; + } + } + } else if (timeout == PR_INTERVAL_NO_WAIT) { + if ((sock = accept(osfd, addr, addrlen)) == -1) { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } else { + _PR_MD_MAP_ACCEPT_ERROR(err); + } + } + } else { +retry: + if ((sock = accept(osfd, addr, addrlen)) == -1) { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + + rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, tvp); + if (rv > 0) { + goto retry; + } else if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + } else { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + } + } else { + _PR_MD_MAP_ACCEPT_ERROR(err); + } + } + } + return (PROsfd)sock; +} + +static PRInt32 _nt_nonblock_connect(PRFileDesc *fd, struct sockaddr *addr, int addrlen, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv; + int err; + fd_set wr, ex; + struct timeval tv, *tvp; + int len; + + if ((rv = connect(osfd, addr, addrlen)) == -1) { + if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) { + if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { + tvp = NULL; + } else { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + } + FD_ZERO(&wr); + FD_ZERO(&ex); + FD_SET((SOCKET)osfd, &wr); + FD_SET((SOCKET)osfd, &ex); + if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wr, &ex, + tvp)) == -1) { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + return rv; + } + if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + return -1; + } + /* Call Sleep(0) to work around a Winsock timeing bug. */ + Sleep(0); + if (FD_ISSET((SOCKET)osfd, &ex)) { + len = sizeof(err); + if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, + (char *) &err, &len) == SOCKET_ERROR) { + _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); + return -1; + } + _PR_MD_MAP_CONNECT_ERROR(err); + return -1; + } + PR_ASSERT(FD_ISSET((SOCKET)osfd, &wr)); + rv = 0; + } else { + _PR_MD_MAP_CONNECT_ERROR(err); + } + } + return rv; +} + +static PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + struct timeval tv, *tvp; + fd_set rd; + int osflags; + + if (0 == flags) { + osflags = 0; + } else { + PR_ASSERT(PR_MSG_PEEK == flags); + osflags = MSG_PEEK; + } + while ((rv = recv(osfd,buf,len,osflags)) == -1) { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) { + FD_ZERO(&rd); + FD_SET((SOCKET)osfd, &rd); + if (timeout == PR_INTERVAL_NO_TIMEOUT) { + tvp = NULL; + } else { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + } + if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, + tvp)) == -1) { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + break; + } else if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + rv = -1; + break; + } + } else { + _PR_MD_MAP_RECV_ERROR(err); + break; + } + } + return(rv); +} + +static PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + struct timeval tv, *tvp; + fd_set wd; + PRInt32 bytesSent = 0; + + while(bytesSent < len) { + while ((rv = send(osfd,buf,len,0)) == -1) { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) { + if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { + tvp = NULL; + } else { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + } + FD_ZERO(&wd); + FD_SET((SOCKET)osfd, &wd); + if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL, + tvp)) == -1) { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + return -1; + } + if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + return -1; + } + } else { + _PR_MD_MAP_SEND_ERROR(err); + return -1; + } + } + bytesSent += rv; + if (fd->secret->nonblocking) { + break; + } + if (bytesSent < len) { + if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { + tvp = NULL; + } else { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + } + FD_ZERO(&wd); + FD_SET((SOCKET)osfd, &wd); + if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL, + tvp)) == -1) { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + return -1; + } + if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + return -1; + } + } + } + return bytesSent; +} + +static PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime timeout) +{ + int index; + int sent = 0; + int rv; + + for (index=0; index 0) + sent += rv; + if ( rv != iov[index].iov_len ) { + if (rv < 0) { + if (fd->secret->nonblocking + && (PR_GetError() == PR_WOULD_BLOCK_ERROR) + && (sent > 0)) { + return sent; + } else { + return -1; + } + } + /* Only a nonblocking socket can have partial sends */ + PR_ASSERT(fd->secret->nonblocking); + return sent; + } + } + + return sent; +} + +static PRInt32 _nt_nonblock_sendto( + PRFileDesc *fd, const char *buf, int len, + const struct sockaddr *addr, int addrlen, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + struct timeval tv, *tvp; + fd_set wd; + PRInt32 bytesSent = 0; + + while(bytesSent < len) { + while ((rv = sendto(osfd,buf,len,0, addr, addrlen)) == -1) { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) { + if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { + tvp = NULL; + } else { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + } + FD_ZERO(&wd); + FD_SET((SOCKET)osfd, &wd); + if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL, + tvp)) == -1) { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + return -1; + } + if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + return -1; + } + } else { + _PR_MD_MAP_SENDTO_ERROR(err); + return -1; + } + } + bytesSent += rv; + if (fd->secret->nonblocking) { + break; + } + if (bytesSent < len) { + if ( timeout == PR_INTERVAL_NO_TIMEOUT ) { + tvp = NULL; + } else { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + } + FD_ZERO(&wd); + FD_SET((SOCKET)osfd, &wd); + if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL, + tvp)) == -1) { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + return -1; + } + if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + return -1; + } + } + } + return bytesSent; +} + +static PRInt32 _nt_nonblock_recvfrom(PRFileDesc *fd, char *buf, int len, struct sockaddr *addr, int *addrlen, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + struct timeval tv, *tvp; + fd_set rd; + + while ((rv = recvfrom(osfd,buf,len,0,addr, addrlen)) == -1) { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) { + if (timeout == PR_INTERVAL_NO_TIMEOUT) { + tvp = NULL; + } else { + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + } + FD_ZERO(&rd); + FD_SET((SOCKET)osfd, &rd); + if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, + tvp)) == -1) { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + break; + } else if (rv == 0) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + rv = -1; + break; + } + } else { + _PR_MD_MAP_RECVFROM_ERROR(err); + break; + } + } + return(rv); +} + +/* + * UDP support: the continuation thread functions and recvfrom and sendto. + */ + +static void pt_InsertTimedInternal(pt_Continuation *op) +{ + PRInt32 delta = 0; + pt_Continuation *t_op = NULL; + PRIntervalTime now = PR_IntervalNow(), op_tmo, qd_tmo; + + /* + * If this element operation isn't timed, it gets queued at the + * end of the list (just after pt_tq.tail) and we're + * finishd early. + */ + if (PR_INTERVAL_NO_TIMEOUT == op->timeout) + { + t_op = pt_tq.tail; /* put it at the end */ + goto done; + } + + /* + * The rest of this routine actaully deals with timed ops. + */ + + if (NULL != pt_tq.op) + { + /* + * To find where in the list to put the new operation, form + * the absolute time the operations in question will expire. + * + * The new operation ('op') will expire at now() + op->timeout. + * + * The operation that will time out furthest in the future will + * do so at pt_tq.epoch + pt_tq.op->timeout. + * + * Subsequently earlier timeouts are computed based on the latter + * knowledge by subracting the timeout deltas that are stored in + * the operation list. There are operation[n]->timeout ticks + * between the expiration of operation[n-1] and operation[n].e e + * + * Therefore, the operation[n-1] will expire operation[n]->timeout + * ticks prior to operation[n]. + * + * This should be easy! + */ + t_op = pt_tq.op; /* running pointer to queued op */ + op_tmo = now + op->timeout; /* that's in absolute ticks */ + qd_tmo = pt_tq.epoch + t_op->timeout; /* likewise */ + + do + { + /* + * If 'op' expires later than t_op, then insert 'op' just + * ahead of t_op. Otherwise, compute when operation[n-1] + * expires and try again. + * + * The actual different between the expiriation of 'op' + * and the current operation what becomes the new operaton's + * timeout interval. That interval is also subtracted from + * the interval of the operation immediately following where + * we stick 'op' (unless the next one isn't timed). The new + * timeout assigned to 'op' takes into account the values of + * now() and when the previous intervals were compured. + */ + delta = op_tmo - qd_tmo; + if (delta >= 0) + { + op->timeout += (now - pt_tq.epoch); + goto done; + } + + qd_tmo -= t_op->timeout; /* previous operaton expiration */ + t_op = t_op->prev; /* point to previous operation */ + if (NULL != t_op) qd_tmo += t_op->timeout; + } while (NULL != t_op); + + /* + * If we got here we backed off the head of the list. That means that + * this timed entry has to go at the head of the list. This is just + * about like having an empty timer list. + */ + delta = op->timeout; /* $$$ is this right? */ + } + +done: + + /* + * Insert 'op' into the queue just after t_op or if t_op is null, + * at the head of the list. + * + * If t_op is NULL, the list is currently empty and this is pretty + * easy. + */ + if (NULL == t_op) + { + op->prev = NULL; + op->next = pt_tq.head; + pt_tq.head = op; + if (NULL == pt_tq.tail) pt_tq.tail = op; + else op->next->prev = op; + } + else + { + op->prev = t_op; + op->next = t_op->next; + if (NULL != op->prev) + op->prev->next = op; + if (NULL != op->next) + op->next->prev = op; + if (t_op == pt_tq.tail) + pt_tq.tail = op; + } + + /* + * Are we adjusting our epoch, etc? Are we replacing + * what was previously the element due to expire furthest + * out in the future? Is this even a timed operation? + */ + if (PR_INTERVAL_NO_TIMEOUT != op->timeout) + { + if ((NULL == pt_tq.op) /* we're the one and only */ + || (t_op == pt_tq.op)) /* we're replacing */ + { + pt_tq.op = op; + pt_tq.epoch = now; + } + } + + pt_tq.op_count += 1; + +} /* pt_InsertTimedInternal */ + +/* + * function: pt_FinishTimed + * + * Takes the finished operation out of the timed queue. It + * notifies the initiating thread that the opertions is + * complete and returns to the caller the value of the next + * operation in the list (or NULL). + */ +static pt_Continuation *pt_FinishTimedInternal(pt_Continuation *op) +{ + pt_Continuation *next; + + /* remove this one from the list */ + if (NULL == op->prev) pt_tq.head = op->next; + else op->prev->next = op->next; + if (NULL == op->next) pt_tq.tail = op->prev; + else op->next->prev = op->prev; + + /* did we happen to hit the timed op? */ + if (op == pt_tq.op) pt_tq.op = op->prev; + + next = op->next; + op->next = op->prev = NULL; + op->status = pt_continuation_done; + + pt_tq.op_count -= 1; +#if defined(DEBUG) + pt_debug.continuationsServed += 1; +#endif + PR_NotifyCondVar(op->complete); + + return next; +} /* pt_FinishTimedInternal */ + +static void ContinuationThread(void *arg) +{ + /* initialization */ + fd_set readSet, writeSet, exceptSet; + struct timeval tv; + SOCKET *pollingList = 0; /* list built for polling */ + PRIntn pollingListUsed; /* # entries used in the list */ + PRIntn pollingListNeeded; /* # entries needed this time */ + PRIntn pollingSlotsAllocated = 0; /* # entries available in list */ + PRIntervalTime mx_select_ticks = PR_MillisecondsToInterval(PT_DEFAULT_SELECT_MSEC); + + /* do some real work */ + while (1) + { + PRIntn rv; + PRStatus status; + PRIntn pollIndex; + pt_Continuation *op; + PRIntervalTime now = PR_IntervalNow(); + PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; + + PR_Lock(pt_tq.ml); + while (NULL == pt_tq.head) + { + status = PR_WaitCondVar(pt_tq.new_op, PR_INTERVAL_NO_TIMEOUT); + if ((PR_FAILURE == status) + && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break; + } + pollingListNeeded = pt_tq.op_count; + PR_Unlock(pt_tq.ml); + + /* Okay. We're history */ + if ((PR_FAILURE == status) + && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break; + + /* + * We are not holding the pt_tq.ml lock now, so more items may + * get added to pt_tq during this window of time. We hope + * that 10 more spaces in the polling list should be enough. + */ + + FD_ZERO(&readSet); + FD_ZERO(&writeSet); + FD_ZERO(&exceptSet); + pollingListNeeded += 10; + if (pollingListNeeded > pollingSlotsAllocated) + { + if (NULL != pollingList) PR_DELETE(pollingList); + pollingList = PR_MALLOC(pollingListNeeded * sizeof(PRPollDesc)); + PR_ASSERT(NULL != pollingList); + pollingSlotsAllocated = pollingListNeeded; + } + +#if defined(DEBUG) + if (pollingListNeeded > pt_debug.pollingListMax) + pt_debug.pollingListMax = pollingListUsed; +#endif + + /* + * Build up a polling list. + * This list is sorted on time. Operations that have been + * interrupted are completed and not included in the list. + * There is an assertion that the operation is in progress. + */ + pollingListUsed = 0; + PR_Lock(pt_tq.ml); + + for (op = pt_tq.head; NULL != op;) + { + if (pt_continuation_abort == op->status) + { + op->result.code = -1; + op->syserrno = WSAEINTR; + op = pt_FinishTimedInternal(op); + } + else + { + PR_ASSERT(pt_continuation_done != op->status); + op->status = pt_continuation_inprogress; + if (op->event & PR_POLL_READ) { + FD_SET(op->arg1.osfd, &readSet); + } + if (op->event & PR_POLL_WRITE) { + FD_SET(op->arg1.osfd, &writeSet); + } + if (op->event & PR_POLL_EXCEPT) { + FD_SET(op->arg1.osfd, &exceptSet); + } + pollingList[pollingListUsed] = op->arg1.osfd; + pollingListUsed += 1; + if (pollingListUsed == pollingSlotsAllocated) break; + op = op->next; + } + } + + PR_Unlock(pt_tq.ml); + + /* + * If 'op' isn't NULL at this point, then we didn't get to + * the end of the list. That means that more items got added + * to the list than we anticipated. So, forget this iteration, + * go around the horn again. + * One would hope this doesn't happen all that often. + */ + if (NULL != op) + { +#if defined(DEBUG) + pt_debug.predictionsFoiled += 1; /* keep track */ +#endif + continue; /* make it rethink things */ + } + + /* there's a chance that all ops got blown away */ + if (NULL == pt_tq.head) continue; + /* if not, we know this is the shortest timeout */ + timeout = pt_tq.head->timeout; + + /* + * We don't want to wait forever on this poll. So keep + * the interval down. The operations, if they are timed, + * still have to timeout, while those that are not timed + * should persist forever. But they may be aborted. That's + * what this anxiety is all about. + */ + if (timeout > mx_select_ticks) timeout = mx_select_ticks; + + if (PR_INTERVAL_NO_TIMEOUT != pt_tq.head->timeout) + pt_tq.head->timeout -= timeout; + tv.tv_sec = PR_IntervalToSeconds(timeout); + tv.tv_usec = PR_IntervalToMicroseconds(timeout) % PR_USEC_PER_SEC; + + rv = select(0, &readSet, &writeSet, &exceptSet, &tv); + + if (0 == rv) /* poll timed out - what about leading op? */ + { + if (0 == pt_tq.head->timeout) + { + /* + * The leading element of the timed queue has timed + * out. Get rid of it. In any case go around the + * loop again, computing the polling list, checking + * for interrupted operations. + */ + PR_Lock(pt_tq.ml); + do + { + pt_tq.head->result.code = -1; + pt_tq.head->syserrno = WSAETIMEDOUT; + op = pt_FinishTimedInternal(pt_tq.head); + } while ((NULL != op) && (0 == op->timeout)); + PR_Unlock(pt_tq.ml); + } + continue; + } + + if (-1 == rv && (WSAGetLastError() == WSAEINTR + || WSAGetLastError() == WSAEINPROGRESS)) + { + continue; /* go around the loop again */ + } + + /* + * select() says that something in our list is ready for some more + * action or is an invalid fd. Find it, load up the operation and + * see what happens. + */ + + PR_ASSERT(rv > 0 || WSAGetLastError() == WSAENOTSOCK); + + + /* + * $$$ There's a problem here. I'm running the operations list + * and I'm not holding any locks. I don't want to hold the lock + * and do the operation, so this is really messed up.. + * + * This may work out okay. The rule is that only this thread, + * the continuation thread, can remove elements from the list. + * Therefore, the list is at worst, longer than when we built + * the polling list. + */ + op = pt_tq.head; + for (pollIndex = 0; pollIndex < pollingListUsed; ++pollIndex) + { + PRInt16 revents = 0; + + PR_ASSERT(NULL != op); + + /* + * This one wants attention. Redo the operation. + * We know that there can only be more elements + * in the op list than we knew about when we created + * the poll list. Therefore, we might have to skip + * a few ops to find the right one to operation on. + */ + while (pollingList[pollIndex] != op->arg1.osfd ) + { + op = op->next; + PR_ASSERT(NULL != op); + } + + if (FD_ISSET(op->arg1.osfd, &readSet)) { + revents |= PR_POLL_READ; + } + if (FD_ISSET(op->arg1.osfd, &writeSet)) { + revents |= PR_POLL_WRITE; + } + if (FD_ISSET(op->arg1.osfd, &exceptSet)) { + revents |= PR_POLL_EXCEPT; + } + + /* + * Sip over all those not in progress. They'll be + * pruned next time we build a polling list. Call + * the continuation function. If it reports completion, + * finish off the operation. + */ + if (revents && (pt_continuation_inprogress == op->status) + && (op->function(op, revents))) + { + PR_Lock(pt_tq.ml); + op = pt_FinishTimedInternal(op); + PR_Unlock(pt_tq.ml); + } + } + } + if (NULL != pollingList) PR_DELETE(pollingList); +} /* ContinuationThread */ + +static int pt_Continue(pt_Continuation *op) +{ + PRStatus rv; + /* Finish filling in the blank slots */ + op->status = pt_continuation_sumbitted; + op->complete = PR_NewCondVar(pt_tq.ml); + + PR_Lock(pt_tq.ml); /* we provide the locking */ + + pt_InsertTimedInternal(op); /* insert in the structure */ + + PR_NotifyCondVar(pt_tq.new_op); /* notify the continuation thread */ + + while (pt_continuation_done != op->status) /* wait for completion */ + { + rv = PR_WaitCondVar(op->complete, PR_INTERVAL_NO_TIMEOUT); + /* + * If we get interrupted, we set state the continuation thread will + * see and allow it to finish the I/O operation w/ error. That way + * the rule that only the continuation thread is removing elements + * from the list is still valid. + * + * Don't call interrupt on the continuation thread. That'll just + * piss him off. He's cycling around at least every mx_select_ticks + * anyhow and should notice the request in there. + */ + if ((PR_FAILURE == rv) + && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) + op->status = pt_continuation_abort; /* our status */ + } + + PR_Unlock(pt_tq.ml); /* we provide the locking */ + + PR_DestroyCondVar(op->complete); + + return op->result.code; /* and the primary answer */ +} /* pt_Continue */ + +static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents) +{ + PRIntn bytes = sendto( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags, + (struct sockaddr*)op->arg5.addr, sizeof(*(op->arg5.addr))); + op->syserrno = WSAGetLastError(); + if (bytes > 0) /* this is progress */ + { + char *bp = op->arg2.buffer; + bp += bytes; /* adjust the buffer pointer */ + op->arg2.buffer = bp; + op->result.code += bytes; /* accumulate the number sent */ + op->arg3.amount -= bytes; /* and reduce the required count */ + return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; + } + else return ((-1 == bytes) && (WSAEWOULDBLOCK == op->syserrno)) ? + PR_FALSE : PR_TRUE; +} /* pt_sendto_cont */ + +static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents) +{ + PRIntn addr_len = sizeof(*(op->arg5.addr)); + op->result.code = recvfrom( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount, + op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len); + op->syserrno = WSAGetLastError(); + return ((-1 == op->result.code) && (WSAEWOULDBLOCK == op->syserrno)) ? + PR_FALSE : PR_TRUE; +} /* pt_recvfrom_cont */ + +static PRInt32 pt_SendTo( + SOCKET osfd, const void *buf, + PRInt32 amount, PRInt32 flags, const PRNetAddr *addr, + PRIntn addrlen, PRIntervalTime timeout) +{ + PRInt32 bytes = -1, err; + PRBool fNeedContinue = PR_FALSE; + + bytes = sendto( + osfd, buf, amount, flags, + (struct sockaddr*)addr, PR_NETADDR_SIZE(addr)); + if (bytes == -1) { + if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) + fNeedContinue = PR_TRUE; + else + _PR_MD_MAP_SENDTO_ERROR(err); + } + if (fNeedContinue == PR_TRUE) + { + pt_Continuation op; + op.arg1.osfd = osfd; + op.arg2.buffer = (void*)buf; + op.arg3.amount = amount; + op.arg4.flags = flags; + op.arg5.addr = (PRNetAddr*)addr; + op.timeout = timeout; + op.result.code = 0; /* initialize the number sent */ + op.function = pt_sendto_cont; + op.event = PR_POLL_WRITE | PR_POLL_EXCEPT; + bytes = pt_Continue(&op); + if (bytes < 0) { + WSASetLastError(op.syserrno); + _PR_MD_MAP_SENDTO_ERROR(op.syserrno); + } + } + return bytes; +} /* pt_SendTo */ + +static PRInt32 pt_RecvFrom(SOCKET osfd, void *buf, PRInt32 amount, + PRInt32 flags, PRNetAddr *addr, PRIntn *addr_len, PRIntervalTime timeout) +{ + PRInt32 bytes = -1, err; + PRBool fNeedContinue = PR_FALSE; + + bytes = recvfrom( + osfd, buf, amount, flags, + (struct sockaddr*)addr, addr_len); + if (bytes == -1) { + if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) + fNeedContinue = PR_TRUE; + else + _PR_MD_MAP_RECVFROM_ERROR(err); + } + + if (fNeedContinue == PR_TRUE) + { + pt_Continuation op; + op.arg1.osfd = osfd; + op.arg2.buffer = buf; + op.arg3.amount = amount; + op.arg4.flags = flags; + op.arg5.addr = addr; + op.timeout = timeout; + op.function = pt_recvfrom_cont; + op.event = PR_POLL_READ | PR_POLL_EXCEPT; + bytes = pt_Continue(&op); + if (bytes < 0) { + WSASetLastError(op.syserrno); + _PR_MD_MAP_RECVFROM_ERROR(op.syserrno); + } + } + return bytes; +} /* pt_RecvFrom */ diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/ntmisc.c nspr-4.10.7/nspr/pr/src/md/windows/ntmisc.c --- nspr-4.9.5/nspr/pr/src/md/windows/ntmisc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/ntmisc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1201 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * ntmisc.c + * + */ + +#include "primpl.h" +#include /* for fabs() */ +#include + +char *_PR_MD_GET_ENV(const char *name) +{ + return getenv(name); +} + +/* +** _PR_MD_PUT_ENV() -- add or change environment variable +** +** +*/ +PRIntn _PR_MD_PUT_ENV(const char *name) +{ + return(putenv(name)); +} + + +/* + ************************************************************************** + ************************************************************************** + ** + ** Date and time routines + ** + ************************************************************************** + ************************************************************************** + */ + +/* + * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME. + * We store the value in a PRTime variable for convenience. + */ +#ifdef __GNUC__ +const PRTime _pr_filetime_offset = 116444736000000000LL; +const PRTime _pr_filetime_divisor = 10LL; +#else +const PRTime _pr_filetime_offset = 116444736000000000i64; +const PRTime _pr_filetime_divisor = 10i64; +#endif + +#ifdef WINCE + +#define FILETIME_TO_INT64(ft) \ + (((PRInt64)ft.dwHighDateTime) << 32 | (PRInt64)ft.dwLowDateTime) + +static void +LowResTime(LPFILETIME lpft) +{ + GetCurrentFT(lpft); +} + +typedef struct CalibrationData { + long double freq; /* The performance counter frequency */ + long double offset; /* The low res 'epoch' */ + long double timer_offset; /* The high res 'epoch' */ + + /* The last high res time that we returned since recalibrating */ + PRInt64 last; + + PRBool calibrated; + + CRITICAL_SECTION data_lock; + CRITICAL_SECTION calibration_lock; + PRInt64 granularity; +} CalibrationData; + +static CalibrationData calibration; + +typedef void (*GetSystemTimeAsFileTimeFcn)(LPFILETIME); +static GetSystemTimeAsFileTimeFcn ce6_GetSystemTimeAsFileTime = NULL; + +static void +NowCalibrate(void) +{ + FILETIME ft, ftStart; + LARGE_INTEGER liFreq, now; + + if (calibration.freq == 0.0) { + if(!QueryPerformanceFrequency(&liFreq)) { + /* High-performance timer is unavailable */ + calibration.freq = -1.0; + } else { + calibration.freq = (long double) liFreq.QuadPart; + } + } + if (calibration.freq > 0.0) { + PRInt64 calibrationDelta = 0; + /* + * By wrapping a timeBegin/EndPeriod pair of calls around this loop, + * the loop seems to take much less time (1 ms vs 15ms) on Vista. + */ + timeBeginPeriod(1); + LowResTime(&ftStart); + do { + LowResTime(&ft); + } while (memcmp(&ftStart,&ft, sizeof(ft)) == 0); + timeEndPeriod(1); + + calibration.granularity = + (FILETIME_TO_INT64(ft) - FILETIME_TO_INT64(ftStart))/10; + + QueryPerformanceCounter(&now); + + calibration.offset = (long double) FILETIME_TO_INT64(ft); + calibration.timer_offset = (long double) now.QuadPart; + /* + * The windows epoch is around 1600. The unix epoch is around 1970. + * _pr_filetime_offset is the difference (in windows time units which + * are 10 times more highres than the JS time unit) + */ + calibration.offset -= _pr_filetime_offset; + calibration.offset *= 0.1; + calibration.last = 0; + + calibration.calibrated = PR_TRUE; + } +} + +#define CALIBRATIONLOCK_SPINCOUNT 0 +#define DATALOCK_SPINCOUNT 4096 +#define LASTLOCK_SPINCOUNT 4096 + +void +_MD_InitTime(void) +{ + /* try for CE6 GetSystemTimeAsFileTime first */ + HANDLE h = GetModuleHandleW(L"coredll.dll"); + ce6_GetSystemTimeAsFileTime = (GetSystemTimeAsFileTimeFcn) + GetProcAddressA(h, "GetSystemTimeAsFileTime"); + + /* otherwise go the slow route */ + if (ce6_GetSystemTimeAsFileTime == NULL) { + memset(&calibration, 0, sizeof(calibration)); + NowCalibrate(); + InitializeCriticalSection(&calibration.calibration_lock); + InitializeCriticalSection(&calibration.data_lock); + } +} + +void +_MD_CleanupTime(void) +{ + if (ce6_GetSystemTimeAsFileTime == NULL) { + DeleteCriticalSection(&calibration.calibration_lock); + DeleteCriticalSection(&calibration.data_lock); + } +} + +#define MUTEX_SETSPINCOUNT(m, c) + +/* + *----------------------------------------------------------------------- + * + * PR_Now -- + * + * Returns the current time in microseconds since the epoch. + * The epoch is midnight January 1, 1970 GMT. + * The implementation is machine dependent. This is the + * implementation for Windows. + * Cf. time_t time(time_t *tp) + * + *----------------------------------------------------------------------- + */ + +PR_IMPLEMENT(PRTime) +PR_Now(void) +{ + long double lowresTime, highresTimerValue; + FILETIME ft; + LARGE_INTEGER now; + PRBool calibrated = PR_FALSE; + PRBool needsCalibration = PR_FALSE; + PRInt64 returnedTime; + long double cachedOffset = 0.0; + + if (ce6_GetSystemTimeAsFileTime) { + union { + FILETIME ft; + PRTime prt; + } currentTime; + + PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime)); + + ce6_GetSystemTimeAsFileTime(¤tTime.ft); + + /* written this way on purpose, since the second term becomes + * a constant, and the entire expression is faster to execute. + */ + return currentTime.prt/_pr_filetime_divisor - + _pr_filetime_offset/_pr_filetime_divisor; + } + + do { + if (!calibration.calibrated || needsCalibration) { + EnterCriticalSection(&calibration.calibration_lock); + EnterCriticalSection(&calibration.data_lock); + + /* Recalibrate only if no one else did before us */ + if (calibration.offset == cachedOffset) { + /* + * Since calibration can take a while, make any other + * threads immediately wait + */ + MUTEX_SETSPINCOUNT(&calibration.data_lock, 0); + + NowCalibrate(); + + calibrated = PR_TRUE; + + /* Restore spin count */ + MUTEX_SETSPINCOUNT(&calibration.data_lock, DATALOCK_SPINCOUNT); + } + LeaveCriticalSection(&calibration.data_lock); + LeaveCriticalSection(&calibration.calibration_lock); + } + + /* Calculate a low resolution time */ + LowResTime(&ft); + lowresTime = + ((long double)(FILETIME_TO_INT64(ft) - _pr_filetime_offset)) * 0.1; + + if (calibration.freq > 0.0) { + long double highresTime, diff; + DWORD timeAdjustment, timeIncrement; + BOOL timeAdjustmentDisabled; + + /* Default to 15.625 ms if the syscall fails */ + long double skewThreshold = 15625.25; + + /* Grab high resolution time */ + QueryPerformanceCounter(&now); + highresTimerValue = (long double)now.QuadPart; + + EnterCriticalSection(&calibration.data_lock); + highresTime = calibration.offset + 1000000L * + (highresTimerValue-calibration.timer_offset)/calibration.freq; + cachedOffset = calibration.offset; + + /* + * On some dual processor/core systems, we might get an earlier + * time so we cache the last time that we returned. + */ + calibration.last = PR_MAX(calibration.last,(PRInt64)highresTime); + returnedTime = calibration.last; + LeaveCriticalSection(&calibration.data_lock); + + /* Get an estimate of clock ticks per second from our own test */ + skewThreshold = calibration.granularity; + /* Check for clock skew */ + diff = lowresTime - highresTime; + + /* + * For some reason that I have not determined, the skew can be + * up to twice a kernel tick. This does not seem to happen by + * itself, but I have only seen it triggered by another program + * doing some kind of file I/O. The symptoms are a negative diff + * followed by an equally large positive diff. + */ + if (fabs(diff) > 2*skewThreshold) { + if (calibrated) { + /* + * If we already calibrated once this instance, and the + * clock is still skewed, then either the processor(s) are + * wildly changing clockspeed or the system is so busy that + * we get switched out for long periods of time. In either + * case, it would be infeasible to make use of high + * resolution results for anything, so let's resort to old + * behavior for this call. It's possible that in the + * future, the user will want the high resolution timer, so + * we don't disable it entirely. + */ + returnedTime = (PRInt64)lowresTime; + needsCalibration = PR_FALSE; + } else { + /* + * It is possible that when we recalibrate, we will return + * a value less than what we have returned before; this is + * unavoidable. We cannot tell the different between a + * faulty QueryPerformanceCounter implementation and user + * changes to the operating system time. Since we must + * respect user changes to the operating system time, we + * cannot maintain the invariant that Date.now() never + * decreases; the old implementation has this behavior as + * well. + */ + needsCalibration = PR_TRUE; + } + } else { + /* No detectable clock skew */ + returnedTime = (PRInt64)highresTime; + needsCalibration = PR_FALSE; + } + } else { + /* No high resolution timer is available, so fall back */ + returnedTime = (PRInt64)lowresTime; + } + } while (needsCalibration); + + return returnedTime; +} + +#else + +PR_IMPLEMENT(PRTime) +PR_Now(void) +{ + PRTime prt; + FILETIME ft; + SYSTEMTIME st; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + _PR_FileTimeToPRTime(&ft, &prt); + return prt; +} + +#endif + +/* + *********************************************************************** + *********************************************************************** + * + * Process creation routines + * + *********************************************************************** + *********************************************************************** + */ + +/* + * Assemble the command line by concatenating the argv array. + * On success, this function returns 0 and the resulting command + * line is returned in *cmdLine. On failure, it returns -1. + */ +static int assembleCmdLine(char *const *argv, char **cmdLine) +{ + char *const *arg; + char *p, *q; + size_t cmdLineSize; + int numBackslashes; + int i; + int argNeedQuotes; + + /* + * Find out how large the command line buffer should be. + */ + cmdLineSize = 0; + for (arg = argv; *arg; arg++) { + /* + * \ and " need to be escaped by a \. In the worst case, + * every character is a \ or ", so the string of length + * may double. If we quote an argument, that needs two ". + * Finally, we need a space between arguments, and + * a null byte at the end of command line. + */ + cmdLineSize += 2 * strlen(*arg) /* \ and " need to be escaped */ + + 2 /* we quote every argument */ + + 1; /* space in between, or final null */ + } + p = *cmdLine = PR_MALLOC((PRUint32) cmdLineSize); + if (p == NULL) { + return -1; + } + + for (arg = argv; *arg; arg++) { + /* Add a space to separates the arguments */ + if (arg != argv) { + *p++ = ' '; + } + q = *arg; + numBackslashes = 0; + argNeedQuotes = 0; + + /* + * If the argument is empty or contains white space, it needs to + * be quoted. + */ + if (**arg == '\0' || strpbrk(*arg, " \f\n\r\t\v")) { + argNeedQuotes = 1; + } + + if (argNeedQuotes) { + *p++ = '"'; + } + while (*q) { + if (*q == '\\') { + numBackslashes++; + q++; + } else if (*q == '"') { + if (numBackslashes) { + /* + * Double the backslashes since they are followed + * by a quote + */ + for (i = 0; i < 2 * numBackslashes; i++) { + *p++ = '\\'; + } + numBackslashes = 0; + } + /* To escape the quote */ + *p++ = '\\'; + *p++ = *q++; + } else { + if (numBackslashes) { + /* + * Backslashes are not followed by a quote, so + * don't need to double the backslashes. + */ + for (i = 0; i < numBackslashes; i++) { + *p++ = '\\'; + } + numBackslashes = 0; + } + *p++ = *q++; + } + } + + /* Now we are at the end of this argument */ + if (numBackslashes) { + /* + * Double the backslashes if we have a quote string + * delimiter at the end. + */ + if (argNeedQuotes) { + numBackslashes *= 2; + } + for (i = 0; i < numBackslashes; i++) { + *p++ = '\\'; + } + } + if (argNeedQuotes) { + *p++ = '"'; + } + } + + *p = '\0'; + return 0; +} + +/* + * Assemble the environment block by concatenating the envp array + * (preserving the terminating null byte in each array element) + * and adding a null byte at the end. + * + * Returns 0 on success. The resulting environment block is returned + * in *envBlock. Note that if envp is NULL, a NULL pointer is returned + * in *envBlock. Returns -1 on failure. + */ +static int assembleEnvBlock(char **envp, char **envBlock) +{ + char *p; + char *q; + char **env; + char *curEnv; + char *cwdStart, *cwdEnd; + size_t envBlockSize; + + if (envp == NULL) { + *envBlock = NULL; + return 0; + } + +#ifdef WINCE + { + PRUnichar *wideCurEnv = mozce_GetEnvString(); + int len = WideCharToMultiByte(CP_ACP, 0, wideCurEnv, -1, + NULL, 0, NULL, NULL); + curEnv = (char *) PR_MALLOC(len * sizeof(char)); + WideCharToMultiByte(CP_ACP, 0, wideCurEnv, -1, + curEnv, len, NULL, NULL); + free(wideCurEnv); + } +#else + curEnv = GetEnvironmentStrings(); +#endif + + cwdStart = curEnv; + while (*cwdStart) { + if (cwdStart[0] == '=' && cwdStart[1] != '\0' + && cwdStart[2] == ':' && cwdStart[3] == '=') { + break; + } + cwdStart += strlen(cwdStart) + 1; + } + cwdEnd = cwdStart; + if (*cwdEnd) { + cwdEnd += strlen(cwdEnd) + 1; + while (*cwdEnd) { + if (cwdEnd[0] != '=' || cwdEnd[1] == '\0' + || cwdEnd[2] != ':' || cwdEnd[3] != '=') { + break; + } + cwdEnd += strlen(cwdEnd) + 1; + } + } + envBlockSize = cwdEnd - cwdStart; + + for (env = envp; *env; env++) { + envBlockSize += strlen(*env) + 1; + } + envBlockSize++; + + p = *envBlock = PR_MALLOC((PRUint32) envBlockSize); + if (p == NULL) { +#ifdef WINCE + PR_Free(curEnv); +#else + FreeEnvironmentStrings(curEnv); +#endif + return -1; + } + + q = cwdStart; + while (q < cwdEnd) { + *p++ = *q++; + } +#ifdef WINCE + PR_Free(curEnv); +#else + FreeEnvironmentStrings(curEnv); +#endif + + for (env = envp; *env; env++) { + q = *env; + while (*q) { + *p++ = *q++; + } + *p++ = '\0'; + } + *p = '\0'; + return 0; +} + +/* + * For qsort. We sort (case-insensitive) the environment strings + * before generating the environment block. + */ +static int compare(const void *arg1, const void *arg2) +{ + return _stricmp(* (char**)arg1, * (char**)arg2); +} + +PRProcess * _PR_CreateWindowsProcess( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr) +{ +#ifdef WINCE + STARTUPINFOW startupInfo; + PRUnichar *wideCmdLine; + PRUnichar *wideCwd; + int len = 0; +#else + STARTUPINFO startupInfo; +#endif + DWORD creationFlags = 0; + PROCESS_INFORMATION procInfo; + BOOL retVal; + char *cmdLine = NULL; + char *envBlock = NULL; + char **newEnvp = NULL; + const char *cwd = NULL; /* current working directory */ + PRProcess *proc = NULL; + PRBool hasFdInheritBuffer; + + proc = PR_NEW(PRProcess); + if (!proc) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto errorExit; + } + + if (assembleCmdLine(argv, &cmdLine) == -1) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto errorExit; + } + +#ifndef WINCE + /* + * If attr->fdInheritBuffer is not NULL, we need to insert + * it into the envp array, so envp cannot be NULL. + */ + hasFdInheritBuffer = (attr && attr->fdInheritBuffer); + if ((envp == NULL) && hasFdInheritBuffer) { + envp = environ; + } + + if (envp != NULL) { + int idx; + int numEnv; + PRBool found = PR_FALSE; + + numEnv = 0; + while (envp[numEnv]) { + numEnv++; + } + newEnvp = (char **) PR_MALLOC((numEnv + 2) * sizeof(char *)); + for (idx = 0; idx < numEnv; idx++) { + newEnvp[idx] = envp[idx]; + if (hasFdInheritBuffer && !found + && !strncmp(newEnvp[idx], "NSPR_INHERIT_FDS=", 17)) { + newEnvp[idx] = attr->fdInheritBuffer; + found = PR_TRUE; + } + } + if (hasFdInheritBuffer && !found) { + newEnvp[idx++] = attr->fdInheritBuffer; + } + newEnvp[idx] = NULL; + qsort((void *) newEnvp, (size_t) idx, sizeof(char *), compare); + } + if (assembleEnvBlock(newEnvp, &envBlock) == -1) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto errorExit; + } + + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + + if (attr) { + PRBool redirected = PR_FALSE; + + /* + * XXX the default value for stdin, stdout, and stderr + * should probably be the console input and output, not + * those of the parent process. + */ + startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); + if (attr->stdinFd) { + startupInfo.hStdInput = (HANDLE) attr->stdinFd->secret->md.osfd; + redirected = PR_TRUE; + } + if (attr->stdoutFd) { + startupInfo.hStdOutput = (HANDLE) attr->stdoutFd->secret->md.osfd; + redirected = PR_TRUE; + /* + * If stdout is redirected, we can assume that the process will + * not write anything useful to the console windows, and therefore + * automatically set the CREATE_NO_WINDOW flag. + */ + creationFlags |= CREATE_NO_WINDOW; + } + if (attr->stderrFd) { + startupInfo.hStdError = (HANDLE) attr->stderrFd->secret->md.osfd; + redirected = PR_TRUE; + } + if (redirected) { + startupInfo.dwFlags |= STARTF_USESTDHANDLES; + } + cwd = attr->currentDirectory; + } +#endif + +#ifdef WINCE + len = MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, NULL, 0); + wideCmdLine = (PRUnichar *)PR_MALLOC(len * sizeof(PRUnichar)); + MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, wideCmdLine, len); + len = MultiByteToWideChar(CP_ACP, 0, cwd, -1, NULL, 0); + wideCwd = PR_MALLOC(len * sizeof(PRUnichar)); + MultiByteToWideChar(CP_ACP, 0, cwd, -1, wideCwd, len); + retVal = CreateProcessW(NULL, + wideCmdLine, + NULL, /* security attributes for the new + * process */ + NULL, /* security attributes for the primary + * thread in the new process */ + TRUE, /* inherit handles */ + creationFlags, + envBlock, /* an environment block, consisting + * of a null-terminated block of + * null-terminated strings. Each + * string is in the form: + * name=value + * XXX: usually NULL */ + wideCwd, /* current drive and directory */ + &startupInfo, + &procInfo + ); + PR_Free(wideCmdLine); + PR_Free(wideCwd); +#else + retVal = CreateProcess(NULL, + cmdLine, + NULL, /* security attributes for the new + * process */ + NULL, /* security attributes for the primary + * thread in the new process */ + TRUE, /* inherit handles */ + creationFlags, + envBlock, /* an environment block, consisting + * of a null-terminated block of + * null-terminated strings. Each + * string is in the form: + * name=value + * XXX: usually NULL */ + cwd, /* current drive and directory */ + &startupInfo, + &procInfo + ); +#endif + + if (retVal == FALSE) { + /* XXX what error code? */ + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + goto errorExit; + } + + CloseHandle(procInfo.hThread); + proc->md.handle = procInfo.hProcess; + proc->md.id = procInfo.dwProcessId; + + PR_DELETE(cmdLine); + if (newEnvp) { + PR_DELETE(newEnvp); + } + if (envBlock) { + PR_DELETE(envBlock); + } + return proc; + +errorExit: + if (cmdLine) { + PR_DELETE(cmdLine); + } + if (newEnvp) { + PR_DELETE(newEnvp); + } + if (envBlock) { + PR_DELETE(envBlock); + } + if (proc) { + PR_DELETE(proc); + } + return NULL; +} /* _PR_CreateWindowsProcess */ + +PRStatus _PR_DetachWindowsProcess(PRProcess *process) +{ + CloseHandle(process->md.handle); + PR_DELETE(process); + return PR_SUCCESS; +} + +/* + * XXX: This implementation is a temporary quick solution. + * It can be called by native threads only (not by fibers). + */ +PRStatus _PR_WaitWindowsProcess(PRProcess *process, + PRInt32 *exitCode) +{ + DWORD dwRetVal; + + dwRetVal = WaitForSingleObject(process->md.handle, INFINITE); + if (dwRetVal == WAIT_FAILED) { + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + return PR_FAILURE; + } + PR_ASSERT(dwRetVal == WAIT_OBJECT_0); + if (exitCode != NULL && + GetExitCodeProcess(process->md.handle, exitCode) == FALSE) { + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + return PR_FAILURE; + } + CloseHandle(process->md.handle); + PR_DELETE(process); + return PR_SUCCESS; +} + +PRStatus _PR_KillWindowsProcess(PRProcess *process) +{ + /* + * On Unix, if a process terminates normally, its exit code is + * between 0 and 255. So here on Windows, we use the exit code + * 256 to indicate that the process is killed. + */ + if (TerminateProcess(process->md.handle, 256)) { + return PR_SUCCESS; + } + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + return PR_FAILURE; +} + +PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen) +{ + PRIntn rv; + PRInt32 syserror; + + rv = gethostname(name, (PRInt32) namelen); + if (0 == rv) { + return PR_SUCCESS; + } + syserror = WSAGetLastError(); + PR_ASSERT(WSANOTINITIALISED != syserror); + _PR_MD_MAP_GETHOSTNAME_ERROR(syserror); + return PR_FAILURE; +} + +PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen) +{ + OSVERSIONINFO osvi; + + PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE)); + + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if (! GetVersionEx (&osvi) ) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } + + switch (osvi.dwPlatformId) { + case VER_PLATFORM_WIN32_NT: + if (PR_SI_SYSNAME == cmd) + (void)PR_snprintf(name, namelen, "Windows_NT"); + else if (PR_SI_RELEASE == cmd) + (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, + osvi.dwMinorVersion); + break; + case VER_PLATFORM_WIN32_WINDOWS: + if (PR_SI_SYSNAME == cmd) { + if ((osvi.dwMajorVersion > 4) || + ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0))) + (void)PR_snprintf(name, namelen, "Windows_98"); + else + (void)PR_snprintf(name, namelen, "Windows_95"); + } else if (PR_SI_RELEASE == cmd) { + (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, + osvi.dwMinorVersion); + } + break; +#ifdef VER_PLATFORM_WIN32_CE + case VER_PLATFORM_WIN32_CE: + if (PR_SI_SYSNAME == cmd) + (void)PR_snprintf(name, namelen, "Windows_CE"); + else if (PR_SI_RELEASE == cmd) + (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, + osvi.dwMinorVersion); + break; +#endif + default: + if (PR_SI_SYSNAME == cmd) + (void)PR_snprintf(name, namelen, "Windows_Unknown"); + else if (PR_SI_RELEASE == cmd) + (void)PR_snprintf(name, namelen, "%d.%d",0,0); + break; + } + return PR_SUCCESS; +} + +PRStatus _MD_WindowsGetReleaseName(char *name, PRUint32 namelen) +{ + OSVERSIONINFO osvi; + + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if (! GetVersionEx (&osvi) ) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } + + switch (osvi.dwPlatformId) { + case VER_PLATFORM_WIN32_NT: + case VER_PLATFORM_WIN32_WINDOWS: + (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, + osvi.dwMinorVersion); + break; + default: + (void)PR_snprintf(name, namelen, "%d.%d",0,0); + break; + } + return PR_SUCCESS; +} + +/* + ********************************************************************** + * + * Memory-mapped files + * + ********************************************************************** + */ + +PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size) +{ + DWORD dwHi, dwLo; + DWORD flProtect; + PROsfd osfd; + + osfd = ( fmap->fd == (PRFileDesc*)-1 )? -1 : fmap->fd->secret->md.osfd; + + dwLo = (DWORD) (size & 0xffffffff); + dwHi = (DWORD) (((PRUint64) size >> 32) & 0xffffffff); + + if (fmap->prot == PR_PROT_READONLY) { + flProtect = PAGE_READONLY; + fmap->md.dwAccess = FILE_MAP_READ; + } else if (fmap->prot == PR_PROT_READWRITE) { + flProtect = PAGE_READWRITE; + fmap->md.dwAccess = FILE_MAP_WRITE; + } else { + PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY); +#ifdef WINCE + /* WINCE does not have FILE_MAP_COPY. */ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +#else + flProtect = PAGE_WRITECOPY; + fmap->md.dwAccess = FILE_MAP_COPY; +#endif + } + + fmap->md.hFileMap = CreateFileMapping( + (HANDLE) osfd, + NULL, + flProtect, + dwHi, + dwLo, + NULL); + + if (fmap->md.hFileMap == NULL) { + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PRInt32 _MD_GetMemMapAlignment(void) +{ + SYSTEM_INFO info; + GetSystemInfo(&info); + return info.dwAllocationGranularity; +} + +extern PRLogModuleInfo *_pr_shma_lm; + +void * _MD_MemMap( + PRFileMap *fmap, + PROffset64 offset, + PRUint32 len) +{ + DWORD dwHi, dwLo; + void *addr; + + dwLo = (DWORD) (offset & 0xffffffff); + dwHi = (DWORD) (((PRUint64) offset >> 32) & 0xffffffff); + if ((addr = MapViewOfFile(fmap->md.hFileMap, fmap->md.dwAccess, + dwHi, dwLo, len)) == NULL) { + { + LPVOID lpMsgBuf; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, ("md_memmap(): %s", lpMsgBuf )); + } + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + } + return addr; +} + +PRStatus _MD_MemUnmap(void *addr, PRUint32 len) +{ + if (UnmapViewOfFile(addr)) { + return PR_SUCCESS; + } + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; +} + +PRStatus _MD_CloseFileMap(PRFileMap *fmap) +{ + CloseHandle(fmap->md.hFileMap); + PR_DELETE(fmap); + return PR_SUCCESS; +} + +PRStatus _MD_SyncMemMap( + PRFileDesc *fd, + void *addr, + PRUint32 len) +{ + PROsfd osfd = fd->secret->md.osfd; + + /* The FlushViewOfFile page on MSDN says: + * To flush all the dirty pages plus the metadata for the file and + * ensure that they are physically written to disk, call + * FlushViewOfFile and then call the FlushFileBuffers function. + */ + if (FlushViewOfFile(addr, len) && FlushFileBuffers((HANDLE) osfd)) { + return PR_SUCCESS; + } + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; +} + +/* + *********************************************************************** + * + * Atomic increment and decrement operations for x86 processors + * + * We don't use InterlockedIncrement and InterlockedDecrement + * because on NT 3.51 and Win95, they return a number with + * the same sign as the incremented/decremented result, rather + * than the result itself. On NT 4.0 these functions do return + * the incremented/decremented result. + * + * The result is returned in the eax register by the inline + * assembly code. We disable the harmless "no return value" + * warning (4035) for these two functions. + * + *********************************************************************** + */ + +#if defined(_M_IX86) || defined(_X86_) + +#pragma warning(disable: 4035) +PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *val) +{ +#if defined(__GNUC__) + PRInt32 result; + asm volatile ("lock ; xadd %0, %1" + : "=r"(result), "=m"(*val) + : "0"(1), "m"(*val)); + return result + 1; +#else + __asm + { + mov ecx, val + mov eax, 1 + lock xadd dword ptr [ecx], eax + inc eax + } +#endif /* __GNUC__ */ +} +#pragma warning(default: 4035) + +#pragma warning(disable: 4035) +PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *val) +{ +#if defined(__GNUC__) + PRInt32 result; + asm volatile ("lock ; xadd %0, %1" + : "=r"(result), "=m"(*val) + : "0"(-1), "m"(*val)); + //asm volatile("lock ; xadd %0, %1" : "=m" (val), "=a" (result) : "-1" (1)); + return result - 1; +#else + __asm + { + mov ecx, val + mov eax, 0ffffffffh + lock xadd dword ptr [ecx], eax + dec eax + } +#endif /* __GNUC__ */ +} +#pragma warning(default: 4035) + +#pragma warning(disable: 4035) +PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *intp, PRInt32 val) +{ +#if defined(__GNUC__) + PRInt32 result; + //asm volatile("lock ; xadd %1, %0" : "=m" (intp), "=a" (result) : "1" (val)); + asm volatile ("lock ; xadd %0, %1" + : "=r"(result), "=m"(*intp) + : "0"(val), "m"(*intp)); + return result + val; +#else + __asm + { + mov ecx, intp + mov eax, val + mov edx, eax + lock xadd dword ptr [ecx], eax + add eax, edx + } +#endif /* __GNUC__ */ +} +#pragma warning(default: 4035) + +#ifdef _PR_HAVE_ATOMIC_CAS + +#pragma warning(disable: 4035) +void +PR_StackPush(PRStack *stack, PRStackElem *stack_elem) +{ +#if defined(__GNUC__) + void **tos = (void **) stack; + void *tmp; + + retry: + if (*tos == (void *) -1) + goto retry; + + __asm__("xchg %0,%1" + : "=r" (tmp), "=m"(*tos) + : "0" (-1), "m"(*tos)); + + if (tmp == (void *) -1) + goto retry; + + *(void **)stack_elem = tmp; + __asm__("" : : : "memory"); + *tos = stack_elem; +#else + __asm + { + mov ebx, stack + mov ecx, stack_elem +retry: mov eax,[ebx] + cmp eax,-1 + je retry + mov eax,-1 + xchg dword ptr [ebx], eax + cmp eax,-1 + je retry + mov [ecx],eax + mov [ebx],ecx + } +#endif /* __GNUC__ */ +} +#pragma warning(default: 4035) + +#pragma warning(disable: 4035) +PRStackElem * +PR_StackPop(PRStack *stack) +{ +#if defined(__GNUC__) + void **tos = (void **) stack; + void *tmp; + + retry: + if (*tos == (void *) -1) + goto retry; + + __asm__("xchg %0,%1" + : "=r" (tmp), "=m"(*tos) + : "0" (-1), "m"(*tos)); + + if (tmp == (void *) -1) + goto retry; + + if (tmp != (void *) 0) + { + void *next = *(void **)tmp; + *tos = next; + *(void **)tmp = 0; + } + else + *tos = tmp; + + return tmp; +#else + __asm + { + mov ebx, stack +retry: mov eax,[ebx] + cmp eax,-1 + je retry + mov eax,-1 + xchg dword ptr [ebx], eax + cmp eax,-1 + je retry + cmp eax,0 + je empty + mov ecx,[eax] + mov [ebx],ecx + mov [eax],0 + jmp done +empty: + mov [ebx],eax +done: + } +#endif /* __GNUC__ */ +} +#pragma warning(default: 4035) + +#endif /* _PR_HAVE_ATOMIC_CAS */ + +#endif /* x86 processors */ diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/ntsec.c nspr-4.10.7/nspr/pr/src/md/windows/ntsec.c --- nspr-4.9.5/nspr/pr/src/md/windows/ntsec.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/ntsec.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +/* + * ntsec.c + * + * Implement the POSIX-style mode bits (access permissions) for + * files and other securable objects in Windows NT using Windows + * NT's security descriptors with appropriate discretionary + * access-control lists. + */ + +/* + * The security identifiers (SIDs) for owner, primary group, + * and the Everyone (World) group. + * + * These SIDs are looked up during NSPR initialization and + * saved in this global structure (see _PR_NT_InitSids) so + * that _PR_NT_MakeSecurityDescriptorACL doesn't need to + * look them up every time. + */ +static struct { + PSID owner; + PSID group; + PSID everyone; +} _pr_nt_sids; + +/* + * Initialize the SIDs for owner, primary group, and the Everyone + * group in the _pr_nt_sids structure. + * + * This function needs to be called by NSPR initialization. + */ +void _PR_NT_InitSids(void) +{ +#ifdef WINCE /* not supported */ + return; +#else + SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; + HANDLE hToken = NULL; /* initialized to an arbitrary value to + * silence a Purify UMR warning */ + PSID infoBuffer[1024/sizeof(PSID)]; /* defined as an array of PSIDs + * to force proper alignment */ + PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer; + PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup + = (PTOKEN_PRIMARY_GROUP) infoBuffer; + DWORD dwLength; + BOOL rv; + + /* + * Look up and make a copy of the owner and primary group + * SIDs in the access token of the calling process. + */ + rv = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken); + if (rv == 0) { + /* + * On non-NT systems, this function is not implemented + * (error code ERROR_CALL_NOT_IMPLEMENTED), and neither are + * the other security functions. There is no point in + * going further. + * + * A process with insufficient access permissions may fail + * with the error code ERROR_ACCESS_DENIED. + */ + PR_LOG(_pr_io_lm, PR_LOG_DEBUG, + ("_PR_NT_InitSids: OpenProcessToken() failed. Error: %d", + GetLastError())); + return; + } + + rv = GetTokenInformation(hToken, TokenOwner, infoBuffer, + sizeof(infoBuffer), &dwLength); + PR_ASSERT(rv != 0); + dwLength = GetLengthSid(pTokenOwner->Owner); + _pr_nt_sids.owner = (PSID) PR_Malloc(dwLength); + PR_ASSERT(_pr_nt_sids.owner != NULL); + rv = CopySid(dwLength, _pr_nt_sids.owner, pTokenOwner->Owner); + PR_ASSERT(rv != 0); + + rv = GetTokenInformation(hToken, TokenPrimaryGroup, infoBuffer, + sizeof(infoBuffer), &dwLength); + PR_ASSERT(rv != 0); + dwLength = GetLengthSid(pTokenPrimaryGroup->PrimaryGroup); + _pr_nt_sids.group = (PSID) PR_Malloc(dwLength); + PR_ASSERT(_pr_nt_sids.group != NULL); + rv = CopySid(dwLength, _pr_nt_sids.group, + pTokenPrimaryGroup->PrimaryGroup); + PR_ASSERT(rv != 0); + + rv = CloseHandle(hToken); + PR_ASSERT(rv != 0); + + /* Create a well-known SID for the Everyone group. */ + rv = AllocateAndInitializeSid(&SIDAuthWorld, 1, + SECURITY_WORLD_RID, + 0, 0, 0, 0, 0, 0, 0, + &_pr_nt_sids.everyone); + PR_ASSERT(rv != 0); +#endif +} + +/* + * Free the SIDs for owner, primary group, and the Everyone group + * in the _pr_nt_sids structure. + * + * This function needs to be called by NSPR cleanup. + */ +void +_PR_NT_FreeSids(void) +{ +#ifdef WINCE + return; +#else + if (_pr_nt_sids.owner) { + PR_Free(_pr_nt_sids.owner); + } + if (_pr_nt_sids.group) { + PR_Free(_pr_nt_sids.group); + } + if (_pr_nt_sids.everyone) { + FreeSid(_pr_nt_sids.everyone); + } +#endif +} + +/* + * Construct a security descriptor whose discretionary access-control + * list implements the specified mode bits. The SIDs for owner, group, + * and everyone are obtained from the global _pr_nt_sids structure. + * Both the security descriptor and access-control list are returned + * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call. + * + * The accessTable array maps NSPR's read, write, and execute access + * rights to the corresponding NT access rights for the securable + * object. + */ +PRStatus +_PR_NT_MakeSecurityDescriptorACL( + PRIntn mode, + DWORD accessTable[], + PSECURITY_DESCRIPTOR *resultSD, + PACL *resultACL) +{ +#ifdef WINCE + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +#else + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + DWORD cbACL; /* size of ACL */ + DWORD accessMask; + + if (_pr_nt_sids.owner == NULL) { + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; + } + + pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); + if (pSD == NULL) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + + /* + * Construct a discretionary access-control list with three + * access-control entries, one each for owner, primary group, + * and Everyone. + */ + + cbACL = sizeof(ACL) + + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + + GetLengthSid(_pr_nt_sids.owner) + + GetLengthSid(_pr_nt_sids.group) + + GetLengthSid(_pr_nt_sids.everyone); + pACL = (PACL) PR_Malloc(cbACL); + if (pACL == NULL) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + accessMask = 0; + if (mode & 00400) accessMask |= accessTable[0]; + if (mode & 00200) accessMask |= accessTable[1]; + if (mode & 00100) accessMask |= accessTable[2]; + if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, + _pr_nt_sids.owner)) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + accessMask = 0; + if (mode & 00040) accessMask |= accessTable[0]; + if (mode & 00020) accessMask |= accessTable[1]; + if (mode & 00010) accessMask |= accessTable[2]; + if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, + _pr_nt_sids.group)) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + accessMask = 0; + if (mode & 00004) accessMask |= accessTable[0]; + if (mode & 00002) accessMask |= accessTable[1]; + if (mode & 00001) accessMask |= accessTable[2]; + if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, + _pr_nt_sids.everyone)) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + + if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + goto failed; + } + + *resultSD = pSD; + *resultACL = pACL; + return PR_SUCCESS; + +failed: + if (pSD) { + PR_Free(pSD); + } + if (pACL) { + PR_Free(pACL); + } + return PR_FAILURE; +#endif +} + +/* + * Free the specified security descriptor and access-control list + * previously created by _PR_NT_MakeSecurityDescriptorACL. + */ +void +_PR_NT_FreeSecurityDescriptorACL(PSECURITY_DESCRIPTOR pSD, PACL pACL) +{ + if (pSD) { + PR_Free(pSD); + } + if (pACL) { + PR_Free(pACL); + } +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/ntsem.c nspr-4.10.7/nspr/pr/src/md/windows/ntsem.c --- nspr-4.9.5/nspr/pr/src/md/windows/ntsem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/ntsem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * NT-specific semaphore handling code. + * + */ + + +#include "primpl.h" + + +void +_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value) +{ + md->sem = CreateSemaphore(NULL, value, 0x7fffffff, NULL); +} + +void +_PR_MD_DESTROY_SEM(_MDSemaphore *md) +{ + CloseHandle(md->sem); +} + +PRStatus +_PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks) +{ + int rv; + + rv = WaitForSingleObject(md->sem, PR_IntervalToMilliseconds(ticks)); + + if (rv == WAIT_OBJECT_0) + return PR_SUCCESS; + else + return PR_FAILURE; +} + +PRStatus +_PR_MD_WAIT_SEM(_MDSemaphore *md) +{ + return _PR_MD_TIMED_WAIT_SEM(md, PR_INTERVAL_NO_TIMEOUT); +} + +void +_PR_MD_POST_SEM(_MDSemaphore *md) +{ + ReleaseSemaphore(md->sem, 1, NULL); +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/ntthread.c nspr-4.10.7/nspr/pr/src/md/windows/ntthread.c --- nspr-4.9.5/nspr/pr/src/md/windows/ntthread.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/ntthread.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,564 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include /* for _beginthreadex() */ + +/* --- globals ------------------------------------------------ */ +PRLock *_pr_schedLock = NULL; +_PRInterruptTable _pr_interruptTable[] = { { 0 } }; + +BOOL _pr_use_static_tls = TRUE; +__declspec(thread) PRThread *_pr_current_fiber; +__declspec(thread) PRThread *_pr_fiber_last_run; +__declspec(thread) _PRCPU *_pr_current_cpu; +__declspec(thread) PRUintn _pr_ints_off; +DWORD _pr_currentFiberIndex; +DWORD _pr_lastFiberIndex; +DWORD _pr_currentCPUIndex; +DWORD _pr_intsOffIndex; + +_MDLock _nt_idleLock; +PRCList _nt_idleList; +PRUint32 _nt_idleCount; + +extern __declspec(thread) PRThread *_pr_io_restarted_io; +extern DWORD _pr_io_restartedIOIndex; + +/* Must check the restarted_io *before* decrementing no_sched to 0 */ +#define POST_SWITCH_WORK() \ + PR_BEGIN_MACRO \ + PRThread *restarted_io = \ + (_pr_use_static_tls ? _pr_io_restarted_io \ + : (PRThread *) TlsGetValue(_pr_io_restartedIOIndex)); \ + if (restarted_io) { \ + _nt_handle_restarted_io(restarted_io); \ + } \ + _PR_MD_LAST_THREAD()->no_sched = 0; \ + PR_END_MACRO + +void +_nt_handle_restarted_io(PRThread *restarted_io) +{ + /* After the switch we can resume an IO if needed. + * XXXMB - this needs to be done in create thread, since that could + * be the result for a context switch too.. + */ + PR_ASSERT(restarted_io->io_suspended == PR_TRUE); + PR_ASSERT(restarted_io->md.thr_bound_cpu == restarted_io->cpu); + + _PR_THREAD_LOCK(restarted_io); + if (restarted_io->io_pending == PR_FALSE) { + + /* The IO already completed, put us back on the runq. */ + int pri = restarted_io->priority; + + restarted_io->state = _PR_RUNNABLE; + _PR_RUNQ_LOCK(restarted_io->cpu); + _PR_ADD_RUNQ(restarted_io, restarted_io->cpu, pri); + _PR_RUNQ_UNLOCK(restarted_io->cpu); + } else { + _PR_SLEEPQ_LOCK(restarted_io->cpu); + _PR_ADD_SLEEPQ(restarted_io, restarted_io->sleep); + _PR_SLEEPQ_UNLOCK(restarted_io->cpu); + } + restarted_io->io_suspended = PR_FALSE; + restarted_io->md.thr_bound_cpu = NULL; + + _PR_THREAD_UNLOCK(restarted_io); + + if (_pr_use_static_tls) { + _pr_io_restarted_io = NULL; + } else { + TlsSetValue(_pr_io_restartedIOIndex, NULL); + } +} + +void +_PR_MD_EARLY_INIT() +{ + _MD_NEW_LOCK( &_nt_idleLock ); + _nt_idleCount = 0; + PR_INIT_CLIST(&_nt_idleList); + +#if 0 + /* Make the clock tick at least once per millisecond */ + if ( timeBeginPeriod(1) == TIMERR_NOCANDO) { + /* deep yoghurt; clock doesn't tick fast enough! */ + PR_ASSERT(0); + } +#endif + + if (!_pr_use_static_tls) { + _pr_currentFiberIndex = TlsAlloc(); + _pr_lastFiberIndex = TlsAlloc(); + _pr_currentCPUIndex = TlsAlloc(); + _pr_intsOffIndex = TlsAlloc(); + _pr_io_restartedIOIndex = TlsAlloc(); + } +} + +void _PR_MD_CLEANUP_BEFORE_EXIT(void) +{ + _PR_NT_FreeSids(); + + WSACleanup(); + + if (!_pr_use_static_tls) { + TlsFree(_pr_currentFiberIndex); + TlsFree(_pr_lastFiberIndex); + TlsFree(_pr_currentCPUIndex); + TlsFree(_pr_intsOffIndex); + TlsFree(_pr_io_restartedIOIndex); + } +} + +PRStatus +_PR_MD_INIT_THREAD(PRThread *thread) +{ + thread->md.overlapped.ioModel = _MD_BlockingIO; + thread->md.overlapped.data.mdThread = &thread->md; + + if (thread->flags & _PR_GLOBAL_SCOPE) { + if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { + /* + ** Warning: + ** -------- + ** NSPR requires a real handle to every thread. + ** GetCurrentThread() returns a pseudo-handle which + ** is not suitable for some thread operations (e.g., + ** suspending). Therefore, get a real handle from + ** the pseudo handle via DuplicateHandle(...) + */ + DuplicateHandle( + GetCurrentProcess(), /* Process of source handle */ + GetCurrentThread(), /* Pseudo Handle to dup */ + GetCurrentProcess(), /* Process of handle */ + &(thread->md.handle), /* resulting handle */ + 0L, /* access flags */ + FALSE, /* Inheritable */ + DUPLICATE_SAME_ACCESS); /* Options */ + } + + /* Create the blocking IO semaphore */ + thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL); + if (thread->md.blocked_sema == NULL) { + return PR_FAILURE; + } + if (_native_threads_only) { + /* Create the blocking IO semaphore */ + thread->md.thr_event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (thread->md.thr_event == NULL) { + return PR_FAILURE; + } + } + } + + return PR_SUCCESS; +} + +static unsigned __stdcall +pr_root(void *arg) +{ + PRThread *thread = (PRThread *)arg; + thread->md.start(thread); + return 0; +} + +PRStatus +_PR_MD_CREATE_THREAD(PRThread *thread, + void (*start)(void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + + thread->md.start = start; + thread->md.handle = (HANDLE) _beginthreadex( + NULL, + thread->stack->stackSize, + pr_root, + (void *)thread, + CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, + &(thread->id)); + if(!thread->md.handle) { + PRErrorCode prerror; + thread->md.fiber_last_error = GetLastError(); + switch (errno) { + case ENOMEM: + prerror = PR_OUT_OF_MEMORY_ERROR; + break; + case EAGAIN: + prerror = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case EINVAL: + prerror = PR_INVALID_ARGUMENT_ERROR; + break; + default: + prerror = PR_UNKNOWN_ERROR; + } + PR_SetError(prerror, errno); + return PR_FAILURE; + } + + thread->md.id = thread->id; + /* + * On windows, a thread is created with a thread priority of + * THREAD_PRIORITY_NORMAL. + */ + if (priority != PR_PRIORITY_NORMAL) { + _PR_MD_SET_PRIORITY(&(thread->md), priority); + } + + /* Activate the thread */ + if ( ResumeThread( thread->md.handle ) != -1) + return PR_SUCCESS; + + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + return PR_FAILURE; +} + +void +_PR_MD_JOIN_THREAD(_MDThread *md) +{ + DWORD rv; + + rv = WaitForSingleObject(md->handle, INFINITE); + PR_ASSERT(WAIT_OBJECT_0 == rv); +} + +void +_PR_MD_END_THREAD(void) +{ + _endthreadex(0); +} + +void +_PR_MD_YIELD(void) +{ + /* Can NT really yield at all? */ + Sleep(0); +} + +void +_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) +{ + int nativePri; + BOOL rv; + + if (newPri < PR_PRIORITY_FIRST) { + newPri = PR_PRIORITY_FIRST; + } else if (newPri > PR_PRIORITY_LAST) { + newPri = PR_PRIORITY_LAST; + } + switch (newPri) { + case PR_PRIORITY_LOW: + nativePri = THREAD_PRIORITY_BELOW_NORMAL; + break; + case PR_PRIORITY_NORMAL: + nativePri = THREAD_PRIORITY_NORMAL; + break; + case PR_PRIORITY_HIGH: + nativePri = THREAD_PRIORITY_ABOVE_NORMAL; + break; + case PR_PRIORITY_URGENT: + nativePri = THREAD_PRIORITY_HIGHEST; + } + rv = SetThreadPriority(thread->handle, nativePri); + PR_ASSERT(rv); + if (!rv) { + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("PR_SetThreadPriority: can't set thread priority\n")); + } + return; +} + +const DWORD MS_VC_EXCEPTION = 0x406D1388; + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void +_PR_MD_SET_CURRENT_THREAD_NAME(const char *name) +{ +#ifdef _MSC_VER + THREADNAME_INFO info; + + if (!IsDebuggerPresent()) + return; + + info.dwType = 0x1000; + info.szName = (char*) name; + info.dwThreadID = -1; + info.dwFlags = 0; + + __try { + RaiseException(MS_VC_EXCEPTION, + 0, + sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR*)&info); + } __except(EXCEPTION_CONTINUE_EXECUTION) { + } +#endif +} + +void +_PR_MD_CLEAN_THREAD(PRThread *thread) +{ + BOOL rv; + + if (thread->md.acceptex_buf) { + PR_DELETE(thread->md.acceptex_buf); + } + + if (thread->md.xmit_bufs) { + PR_DELETE(thread->md.xmit_bufs); + } + + if (thread->md.blocked_sema) { + rv = CloseHandle(thread->md.blocked_sema); + PR_ASSERT(rv); + thread->md.blocked_sema = 0; + } + if (_native_threads_only) { + if (thread->md.thr_event) { + rv = CloseHandle(thread->md.thr_event); + PR_ASSERT(rv); + thread->md.thr_event = 0; + } + } + + if (thread->md.handle) { + rv = CloseHandle(thread->md.handle); + PR_ASSERT(rv); + thread->md.handle = 0; + } + + /* Don't call DeleteFiber on current fiber or we'll kill the whole thread. + * Don't call free(thread) until we've switched off the thread. + * So put this fiber (or thread) on a list to be deleted by the idle + * fiber next time we have a chance. + */ + if (!(thread->flags & (_PR_ATTACHED|_PR_GLOBAL_SCOPE))) { + _MD_LOCK(&_nt_idleLock); + _nt_idleCount++; + PR_APPEND_LINK(&thread->links, &_nt_idleList); + _MD_UNLOCK(&_nt_idleLock); + } +} + +void +_PR_MD_EXIT_THREAD(PRThread *thread) +{ + BOOL rv; + + if (thread->md.acceptex_buf) { + PR_DELETE(thread->md.acceptex_buf); + } + + if (thread->md.xmit_bufs) { + PR_DELETE(thread->md.xmit_bufs); + } + + if (thread->md.blocked_sema) { + rv = CloseHandle(thread->md.blocked_sema); + PR_ASSERT(rv); + thread->md.blocked_sema = 0; + } + + if (_native_threads_only) { + if (thread->md.thr_event) { + rv = CloseHandle(thread->md.thr_event); + PR_ASSERT(rv); + thread->md.thr_event = 0; + } + } + + if (thread->md.handle) { + rv = CloseHandle(thread->md.handle); + PR_ASSERT(rv); + thread->md.handle = 0; + } + + if (thread->flags & _PR_GLOBAL_SCOPE) { + _MD_SET_CURRENT_THREAD(NULL); + } +} + + +void +_PR_MD_EXIT(PRIntn status) +{ + _exit(status); +} + +#ifdef HAVE_FIBERS + +void +_pr_fiber_mainline(void *unused) +{ + PRThread *fiber = _PR_MD_CURRENT_THREAD(); + + POST_SWITCH_WORK(); + + fiber->md.fiber_fn(fiber->md.fiber_arg); +} + +PRThread *_PR_MD_CREATE_USER_THREAD( + PRUint32 stacksize, void (*start)(void *), void *arg) +{ + PRThread *thread; + + if ( (thread = PR_NEW(PRThread)) == NULL ) { + return NULL; + } + + memset(thread, 0, sizeof(PRThread)); + thread->md.fiber_fn = start; + thread->md.fiber_arg = arg; + thread->md.fiber_stacksize = stacksize; + return thread; +} + +void +_PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *thread) +{ + thread->md.fiber_id = ConvertThreadToFiber(NULL); + PR_ASSERT(thread->md.fiber_id); + _MD_SET_CURRENT_THREAD(thread); + _MD_SET_LAST_THREAD(thread); + thread->no_sched = 1; + return; +} + +void +_PR_MD_INIT_CONTEXT(PRThread *thread, char *top, void (*start) (void), PRBool *status) +{ + thread->md.fiber_fn = (void (*)(void *))start; + thread->md.fiber_id = CreateFiber(thread->md.fiber_stacksize, + (LPFIBER_START_ROUTINE)_pr_fiber_mainline, NULL); + if (thread->md.fiber_id != 0) + *status = PR_TRUE; + else { + DWORD oserror = GetLastError(); + PRErrorCode prerror; + if (oserror == ERROR_NOT_ENOUGH_MEMORY) { + prerror = PR_OUT_OF_MEMORY_ERROR; + } else { + prerror = PR_UNKNOWN_ERROR; + } + PR_SetError(prerror, oserror); + *status = PR_FALSE; + } +} + +void +_PR_MD_SWITCH_CONTEXT(PRThread *thread) +{ + PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); + + thread->md.fiber_last_error = GetLastError(); + _PR_Schedule(); +} + +void +_PR_MD_RESTORE_CONTEXT(PRThread *thread) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); + + /* The user-level code for yielding will happily add ourselves to the runq + * and then switch to ourselves; the NT fibers can't handle switching to + * ourselves. + */ + if (thread != me) { + SetLastError(thread->md.fiber_last_error); + _MD_SET_CURRENT_THREAD(thread); + _PR_MD_SET_LAST_THREAD(me); + thread->no_sched = 1; + SwitchToFiber(thread->md.fiber_id); + POST_SWITCH_WORK(); + } +} + + +#endif /* HAVE_FIBERS */ + +PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ) +{ + int rv; + + rv = SetThreadAffinityMask(thread->md.handle, mask); + + return rv?0:-1; +} + +PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask) +{ + PRInt32 rv, system_mask; + + rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask); + + return rv?0:-1; +} + +void +_PR_MD_SUSPEND_CPU(_PRCPU *cpu) +{ + _PR_MD_SUSPEND_THREAD(cpu->thread); +} + +void +_PR_MD_RESUME_CPU(_PRCPU *cpu) +{ + _PR_MD_RESUME_THREAD(cpu->thread); +} + +void +_PR_MD_SUSPEND_THREAD(PRThread *thread) +{ + if (_PR_IS_NATIVE_THREAD(thread)) { + /* + ** There seems to be some doubt about whether or not SuspendThread + ** is a synchronous function. The test afterwards is to help veriry + ** that it is, which is what Microsoft says it is. + */ + PRUintn rv = SuspendThread(thread->md.handle); + PR_ASSERT(0xffffffffUL != rv); + } +} + +void +_PR_MD_RESUME_THREAD(PRThread *thread) +{ + if (_PR_IS_NATIVE_THREAD(thread)) { + ResumeThread(thread->md.handle); + } +} + +PRThread* +_MD_CURRENT_THREAD(void) +{ +PRThread *thread; + + thread = _MD_GET_ATTACHED_THREAD(); + + if (NULL == thread) { + thread = _PRI_AttachThread( + PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); + } + PR_ASSERT(thread != NULL); + return thread; +} + diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/objs.mk nspr-4.10.7/nspr/pr/src/md/windows/objs.mk --- nspr-4.9.5/nspr/pr/src/md/windows/objs.mk 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/objs.mk 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,48 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +ifeq ($(OS_TARGET),WINNT) +CSRCS = ntmisc.c \ + ntsec.c \ + ntsem.c \ + ntinrval.c \ + ntgc.c \ + ntio.c \ + ntthread.c \ + ntdllmn.c \ + win32_errors.c \ + w32ipcsem.c \ + w32poll.c \ + w32rng.c \ + w32shm.c +else +ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET))) +CSRCS = ntmisc.c \ + ntsec.c \ + ntsem.c \ + ntinrval.c \ + ntgc.c \ + w95thred.c \ + w95io.c \ + w95cv.c \ + w95sock.c \ + win32_errors.c \ + w32ipcsem.c \ + w32poll.c \ + w32rng.c \ + w32shm.c \ + w95dllmain.c +else +endif # win95 +endif # winnt + +CSRCS += $(PR_MD_CSRCS) +ASFILES += $(PR_MD_ASFILES) + +OBJS += $(addprefix md/windows/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \ + $(addprefix md/windows/$(OBJDIR)/,$(ASFILES:.s=.$(OBJ_SUFFIX))) + + diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w32ipcsem.c nspr-4.10.7/nspr/pr/src/md/windows/w32ipcsem.c --- nspr-4.9.5/nspr/pr/src/md/windows/w32ipcsem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w32ipcsem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,228 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: w32ipcsem.c + * Description: implements named semaphores for NT and WIN95. + */ + +#include "primpl.h" + +#ifdef WINCE +static HANDLE OpenSemaphore(DWORD inDesiredAccess, + BOOL inInheritHandle, + const char *inName) +{ + HANDLE retval = NULL; + HANDLE semaphore = NULL; + PRUnichar wideName[MAX_PATH]; /* name size is limited to MAX_PATH */ + + MultiByteToWideChar(CP_ACP, 0, inName, -1, wideName, MAX_PATH); + /* 0x7fffffff is the max count for our semaphore */ + semaphore = CreateSemaphoreW(NULL, 0, 0x7fffffff, wideName); + if (NULL != semaphore) { + DWORD lastErr = GetLastError(); + + if (ERROR_ALREADY_EXISTS != lastErr) + CloseHandle(semaphore); + else + retval = semaphore; + } + return retval; +} +#endif + +/* + * NSPR-to-NT access right mapping table for semaphore objects. + * + * The SYNCHRONIZE access is required by WaitForSingleObject. + * The SEMAPHORE_MODIFY_STATE access is required by ReleaseSemaphore. + * The OR of these three access masks must equal SEMAPHORE_ALL_ACCESS. + * This is because if a semaphore object with the specified name + * exists, CreateSemaphore requests SEMAPHORE_ALL_ACCESS access to + * the existing object. + */ +static DWORD semAccessTable[] = { + STANDARD_RIGHTS_REQUIRED|0x1, /* read (0x1 is "query state") */ + STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, /* write */ + 0 /* execute */ +}; + +#ifndef _PR_GLOBAL_THREADS_ONLY + +/* + * A fiber cannot call WaitForSingleObject because that + * will block the other fibers running on the same thread. + * If a fiber needs to wait on a (semaphore) handle, we + * create a native thread to call WaitForSingleObject and + * have the fiber join the native thread. + */ + +/* + * Arguments, return value, and error code for WaitForSingleObject + */ +struct WaitSingleArg { + HANDLE handle; + DWORD timeout; + DWORD rv; + DWORD error; +}; + +static void WaitSingleThread(void *arg) +{ + struct WaitSingleArg *warg = (struct WaitSingleArg *) arg; + + warg->rv = WaitForSingleObject(warg->handle, warg->timeout); + if (warg->rv == WAIT_FAILED) { + warg->error = GetLastError(); + } +} + +static DWORD FiberSafeWaitForSingleObject( + HANDLE hHandle, + DWORD dwMilliseconds +) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_IS_NATIVE_THREAD(me)) { + return WaitForSingleObject(hHandle, dwMilliseconds); + } else { + PRThread *waitThread; + struct WaitSingleArg warg; + PRStatus rv; + + warg.handle = hHandle; + warg.timeout = dwMilliseconds; + waitThread = PR_CreateThread( + PR_USER_THREAD, WaitSingleThread, &warg, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (waitThread == NULL) { + return WAIT_FAILED; + } + + rv = PR_JoinThread(waitThread); + PR_ASSERT(rv == PR_SUCCESS); + if (rv == PR_FAILURE) { + return WAIT_FAILED; + } + if (warg.rv == WAIT_FAILED) { + SetLastError(warg.error); + } + return warg.rv; + } +} + +#endif /* !_PR_GLOBAL_THREADS_ONLY */ + +PRSem *_PR_MD_OPEN_SEMAPHORE( + const char *osname, PRIntn flags, PRIntn mode, PRUintn value) +{ + PRSem *sem; + SECURITY_ATTRIBUTES sa; + LPSECURITY_ATTRIBUTES lpSA = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + + sem = PR_NEW(PRSem); + if (sem == NULL) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + if (flags & PR_SEM_CREATE) { + if (_PR_NT_MakeSecurityDescriptorACL(mode, semAccessTable, + &pSD, &pACL) == PR_SUCCESS) { + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + lpSA = &sa; + } +#ifdef WINCE + { + /* The size of a sem's name is limited to MAX_PATH. */ + PRUnichar wosname[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, osname, -1, wosname, MAX_PATH); + sem->sem = CreateSemaphoreW(lpSA, value, 0x7fffffff, wosname); + } +#else + sem->sem = CreateSemaphoreA(lpSA, value, 0x7fffffff, osname); +#endif + if (lpSA != NULL) { + _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); + } + if (sem->sem == NULL) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + PR_DELETE(sem); + return NULL; + } + if ((flags & PR_SEM_EXCL) && (GetLastError() == ERROR_ALREADY_EXISTS)) { + PR_SetError(PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS); + CloseHandle(sem->sem); + PR_DELETE(sem); + return NULL; + } + } else { + sem->sem = OpenSemaphore( + SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, FALSE, osname); + if (sem->sem == NULL) { + DWORD err = GetLastError(); + + /* + * If we open a nonexistent named semaphore, NT + * returns ERROR_FILE_NOT_FOUND, while Win95 + * returns ERROR_INVALID_NAME + */ + if (err == ERROR_INVALID_NAME) { + PR_SetError(PR_FILE_NOT_FOUND_ERROR, err); + } else { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + } + PR_DELETE(sem); + return NULL; + } + } + return sem; +} + +PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem) +{ + DWORD rv; + +#ifdef _PR_GLOBAL_THREADS_ONLY + rv = WaitForSingleObject(sem->sem, INFINITE); +#else + rv = FiberSafeWaitForSingleObject(sem->sem, INFINITE); +#endif + PR_ASSERT(rv == WAIT_FAILED || rv == WAIT_OBJECT_0); + if (rv == WAIT_FAILED) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } + if (rv != WAIT_OBJECT_0) { + /* Should not happen */ + PR_SetError(PR_UNKNOWN_ERROR, 0); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem) +{ + if (ReleaseSemaphore(sem->sem, 1, NULL) == FALSE) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem) +{ + if (CloseHandle(sem->sem) == FALSE) { + _PR_MD_MAP_CLOSE_ERROR(GetLastError()); + return PR_FAILURE; + } + PR_DELETE(sem); + return PR_SUCCESS; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w32poll.c nspr-4.10.7/nspr/pr/src/md/windows/w32poll.c --- nspr-4.9.5/nspr/pr/src/md/windows/w32poll.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w32poll.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,325 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This file implements _PR_MD_PR_POLL for Win32. + */ + +/* The default value of FD_SETSIZE is 64. */ +#define FD_SETSIZE 1024 + +#include "primpl.h" + +#if !defined(_PR_GLOBAL_THREADS_ONLY) + +struct select_data_s { + PRInt32 status; + PRInt32 error; + fd_set *rd, *wt, *ex; + const struct timeval *tv; +}; + +static void +_PR_MD_select_thread(void *cdata) +{ + struct select_data_s *cd = (struct select_data_s *)cdata; + + cd->status = select(0, cd->rd, cd->wt, cd->ex, cd->tv); + + if (cd->status == SOCKET_ERROR) { + cd->error = WSAGetLastError(); + } +} + +int _PR_NTFiberSafeSelect( + int nfds, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + const struct timeval *timeout) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + int ready; + + if (_PR_IS_NATIVE_THREAD(me)) { + ready = _MD_SELECT(nfds, readfds, writefds, exceptfds, timeout); + } + else + { + /* + ** Creating a new thread on each call!! + ** I guess web server doesn't use non-block I/O. + */ + PRThread *selectThread; + struct select_data_s data; + data.status = 0; + data.error = 0; + data.rd = readfds; + data.wt = writefds; + data.ex = exceptfds; + data.tv = timeout; + + selectThread = PR_CreateThread( + PR_USER_THREAD, _PR_MD_select_thread, &data, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (selectThread == NULL) return -1; + + PR_JoinThread(selectThread); + ready = data.status; + if (ready == SOCKET_ERROR) WSASetLastError(data.error); + } + return ready; +} + +#endif /* !defined(_PR_GLOBAL_THREADS_ONLY) */ + +PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + int ready, err; + fd_set rd, wt, ex; + fd_set *rdp, *wtp, *exp; + int nrd, nwt, nex; + PRFileDesc *bottom; + PRPollDesc *pd, *epd; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + struct timeval tv, *tvp = NULL; + + if (_PR_PENDING_INTERRUPT(me)) + { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + + /* + ** Is it an empty set? If so, just sleep for the timeout and return + */ + if (0 == npds) + { + PR_Sleep(timeout); + return 0; + } + + nrd = nwt = nex = 0; + FD_ZERO(&rd); + FD_ZERO(&wt); + FD_ZERO(&ex); + + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + SOCKET osfd; + PRInt16 in_flags_read = 0, in_flags_write = 0; + PRInt16 out_flags_read = 0, out_flags_write = 0; + + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + if (pd->in_flags & PR_POLL_READ) + { + in_flags_read = (pd->fd->methods->poll)( + pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_WRITE), + &out_flags_read); + } + if (pd->in_flags & PR_POLL_WRITE) + { + in_flags_write = (pd->fd->methods->poll)( + pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_READ), + &out_flags_write); + } + if ((0 != (in_flags_read & out_flags_read)) + || (0 != (in_flags_write & out_flags_write))) + { + /* this one's ready right now (buffered input) */ + if (0 == ready) + { + /* + * We will have to return without calling the + * system poll/select function. So zero the + * out_flags fields of all the poll descriptors + * before this one. + */ + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; + pd->out_flags = out_flags_read | out_flags_write; + } + else + { + pd->out_flags = 0; /* pre-condition */ + /* make sure this is an NSPR supported stack */ + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); /* what to do about that? */ + if ((NULL != bottom) + && (_PR_FILEDESC_OPEN == bottom->secret->state)) + { + if (0 == ready) + { + osfd = (SOCKET) bottom->secret->md.osfd; + if (in_flags_read & PR_POLL_READ) + { + pd->out_flags |= _PR_POLL_READ_SYS_READ; + FD_SET(osfd, &rd); + nrd++; + } + if (in_flags_read & PR_POLL_WRITE) + { + pd->out_flags |= _PR_POLL_READ_SYS_WRITE; + FD_SET(osfd, &wt); + nwt++; + } + if (in_flags_write & PR_POLL_READ) + { + pd->out_flags |= _PR_POLL_WRITE_SYS_READ; + FD_SET(osfd, &rd); + nrd++; + } + if (in_flags_write & PR_POLL_WRITE) + { + pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE; + FD_SET(osfd, &wt); + nwt++; + } + if (pd->in_flags & PR_POLL_EXCEPT) { + FD_SET(osfd, &ex); + nex++; + } + } + } + else + { + if (0 == ready) + { + PRPollDesc *prev; + for (prev = pds; prev < pd; prev++) + { + prev->out_flags = 0; + } + } + ready += 1; /* this will cause an abrupt return */ + pd->out_flags = PR_POLL_NVAL; /* bogii */ + } + } + } + else + { + pd->out_flags = 0; + } + } + + if (0 != ready) return ready; /* no need to block */ + + /* + * FD_SET does nothing if the fd_set's internal fd_array is full. If + * nrd, nwt, or nex is greater than FD_SETSIZE, we know FD_SET must + * have failed to insert an osfd into the corresponding fd_set, and + * therefore we should fail. + */ + if ((nrd > FD_SETSIZE) || (nwt > FD_SETSIZE) || (nex > FD_SETSIZE)) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + rdp = (0 == nrd) ? NULL : &rd; + wtp = (0 == nwt) ? NULL : &wt; + exp = (0 == nex) ? NULL : &ex; + + if ((NULL == rdp) && (NULL == wtp) && (NULL == exp)) { + PR_Sleep(timeout); + return 0; + } + + if (timeout != PR_INTERVAL_NO_TIMEOUT) + { + PRInt32 ticksPerSecond = PR_TicksPerSecond(); + tv.tv_sec = timeout / ticksPerSecond; + tv.tv_usec = PR_IntervalToMicroseconds( timeout % ticksPerSecond ); + tvp = &tv; + } + +#if defined(_PR_GLOBAL_THREADS_ONLY) + ready = _MD_SELECT(0, rdp, wtp, exp, tvp); +#else + ready = _PR_NTFiberSafeSelect(0, rdp, wtp, exp, tvp); +#endif + + /* + ** Now to unravel the select sets back into the client's poll + ** descriptor list. Is this possibly an area for pissing away + ** a few cycles or what? + */ + if (ready > 0) + { + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + PRInt16 out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + SOCKET osfd; + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + + osfd = (SOCKET) bottom->secret->md.osfd; + + if (FD_ISSET(osfd, &rd)) + { + if (pd->out_flags & _PR_POLL_READ_SYS_READ) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_READ) + out_flags |= PR_POLL_WRITE; + } + if (FD_ISSET(osfd, &wt)) + { + if (pd->out_flags & _PR_POLL_READ_SYS_WRITE) + out_flags |= PR_POLL_READ; + if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE) + out_flags |= PR_POLL_WRITE; + } + if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT; + } + pd->out_flags = out_flags; + if (out_flags) ready++; + } + PR_ASSERT(ready > 0); + } + else if (ready == SOCKET_ERROR) + { + err = WSAGetLastError(); + if (err == WSAENOTSOCK) + { + /* Find the bad fds */ + int optval; + int optlen = sizeof(optval); + ready = 0; + for (pd = pds, epd = pd + npds; pd < epd; pd++) + { + pd->out_flags = 0; + if ((NULL != pd->fd) && (0 != pd->in_flags)) + { + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET, + SO_TYPE, (char *) &optval, &optlen) == -1) + { + PR_ASSERT(WSAGetLastError() == WSAENOTSOCK); + if (WSAGetLastError() == WSAENOTSOCK) + { + pd->out_flags = PR_POLL_NVAL; + ready++; + } + } + } + } + PR_ASSERT(ready > 0); + } + else _PR_MD_MAP_SELECT_ERROR(err); + } + + return ready; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w32rng.c nspr-4.10.7/nspr/pr/src/md/windows/w32rng.c --- nspr-4.9.5/nspr/pr/src/md/windows/w32rng.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w32rng.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include +#include +#include +#include +#include +#include + +static BOOL +CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow) +{ + LARGE_INTEGER liCount; + + if (!QueryPerformanceCounter(&liCount)) + return FALSE; + + *lpdwHigh = liCount.u.HighPart; + *lpdwLow = liCount.u.LowPart; + return TRUE; +} + +extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size ) +{ + DWORD dwHigh, dwLow, dwVal; + size_t n = 0; + size_t nBytes; + time_t sTime; + + if (size <= 0) + return 0; + + CurrentClockTickTime(&dwHigh, &dwLow); + + // get the maximally changing bits first + nBytes = sizeof(dwLow) > size ? size : sizeof(dwLow); + memcpy((char *)buf, &dwLow, nBytes); + n += nBytes; + size -= nBytes; + + if (size <= 0) + return n; + + nBytes = sizeof(dwHigh) > size ? size : sizeof(dwHigh); + memcpy(((char *)buf) + n, &dwHigh, nBytes); + n += nBytes; + size -= nBytes; + + if (size <= 0) + return n; + + // get the number of milliseconds that have elapsed since Windows started + dwVal = GetTickCount(); + + nBytes = sizeof(dwVal) > size ? size : sizeof(dwVal); + memcpy(((char *)buf) + n, &dwVal, nBytes); + n += nBytes; + size -= nBytes; + + if (size <= 0) + return n; + + // get the time in seconds since midnight Jan 1, 1970 + time(&sTime); + nBytes = sizeof(sTime) > size ? size : sizeof(sTime); + memcpy(((char *)buf) + n, &sTime, nBytes); + n += nBytes; + + return n; +} + diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w32shm.c nspr-4.10.7/nspr/pr/src/md/windows/w32shm.c --- nspr-4.9.5/nspr/pr/src/md/windows/w32shm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w32shm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,347 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include +#include +#include +#include + +#if defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY) + +extern PRLogModuleInfo *_pr_shm_lm; + +/* + * NSPR-to-NT access right mapping table for file-mapping objects. + * + * The OR of these three access masks must equal FILE_MAP_ALL_ACCESS. + * This is because if a file-mapping object with the specified name + * exists, CreateFileMapping requests full access to the existing + * object. + */ +static DWORD filemapAccessTable[] = { + FILE_MAP_ALL_ACCESS & ~FILE_MAP_WRITE, /* read */ + FILE_MAP_ALL_ACCESS & ~FILE_MAP_READ, /* write */ + 0 /* execute */ +}; + +extern PRSharedMemory * _MD_OpenSharedMemory( + const char *name, + PRSize size, + PRIntn flags, + PRIntn mode +) +{ + char ipcname[PR_IPC_NAME_SIZE]; + PRStatus rc = PR_SUCCESS; + DWORD dwHi, dwLo; + PRSharedMemory *shm; + DWORD flProtect = ( PAGE_READWRITE ); + SECURITY_ATTRIBUTES sa; + LPSECURITY_ATTRIBUTES lpSA = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); + if ( PR_FAILURE == rc ) + { + PR_SetError(PR_UNKNOWN_ERROR, 0 ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: name is invalid")); + return(NULL); + } + + shm = PR_NEWZAP( PRSharedMemory ); + if ( NULL == shm ) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); + return(NULL); + } + + shm->ipcname = PR_MALLOC( (PRUint32) (strlen( ipcname ) + 1) ); + if ( NULL == shm->ipcname ) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); + PR_DELETE(shm); + return(NULL); + } + + /* copy args to struct */ + strcpy( shm->ipcname, ipcname ); + shm->size = size; + shm->mode = mode; + shm->flags = flags; + shm->ident = _PR_SHM_IDENT; + + if (flags & PR_SHM_CREATE ) { + dwHi = (DWORD) (((PRUint64) shm->size >> 32) & 0xffffffff); + dwLo = (DWORD) (shm->size & 0xffffffff); + + if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable, + &pSD, &pACL) == PR_SUCCESS) { + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + lpSA = &sa; + } +#ifdef WINCE + { + /* + * This is assuming that the name will never be larger than + * MAX_PATH. Should we dynamically allocate? + */ + PRUnichar wideIpcName[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, shm->ipcname, -1, + wideIpcName, MAX_PATH); + shm->handle = CreateFileMappingW( + (HANDLE)-1 , + lpSA, + flProtect, + dwHi, + dwLo, + wideIpcName); + } +#else + shm->handle = CreateFileMappingA( + (HANDLE)-1 , + lpSA, + flProtect, + dwHi, + dwLo, + shm->ipcname); +#endif + if (lpSA != NULL) { + _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); + } + + if ( NULL == shm->handle ) { + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, + ( "PR_OpenSharedMemory: CreateFileMapping() failed: %s", + shm->ipcname )); + _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); + PR_FREEIF( shm->ipcname ) + PR_DELETE( shm ); + return(NULL); + } else { + if (( flags & PR_SHM_EXCL) && ( GetLastError() == ERROR_ALREADY_EXISTS )) { + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, + ( "PR_OpenSharedMemory: Request exclusive & already exists", + shm->ipcname )); + PR_SetError( PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS ); + CloseHandle( shm->handle ); + PR_FREEIF( shm->ipcname ) + PR_DELETE( shm ); + return(NULL); + } else { + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, + ( "PR_OpenSharedMemory: CreateFileMapping() success: %s, handle: %d", + shm->ipcname, shm->handle )); + return(shm); + } + } + } else { +#ifdef WINCE + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + shm->handle = NULL; /* OpenFileMapping not supported */ +#else + shm->handle = OpenFileMapping( FILE_MAP_WRITE, TRUE, shm->ipcname ); +#endif + if ( NULL == shm->handle ) { + _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, + ( "PR_OpenSharedMemory: OpenFileMapping() failed: %s, error: %d", + shm->ipcname, PR_GetOSError())); + PR_FREEIF( shm->ipcname ); + PR_DELETE( shm ); + return(NULL); + } else { + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, + ( "PR_OpenSharedMemory: OpenFileMapping() success: %s, handle: %d", + shm->ipcname, shm->handle )); + return(shm); + } + } + /* returns from separate paths */ +} + +extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) +{ + PRUint32 access = FILE_MAP_WRITE; + void *addr; + + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + if ( PR_SHM_READONLY & flags ) + access = FILE_MAP_READ; + + addr = MapViewOfFile( shm->handle, + access, + 0, 0, + shm->size ); + + if ( NULL == addr ) { + _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); + PR_LOG( _pr_shm_lm, PR_LOG_ERROR, + ("_MD_AttachSharedMemory: MapViewOfFile() failed. OSerror: %d", PR_GetOSError())); + } + + return( addr ); +} /* end _MD_ATTACH_SHARED_MEMORY() */ + + +extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) +{ + PRStatus rc = PR_SUCCESS; + BOOL wrc; + + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + wrc = UnmapViewOfFile( addr ); + if ( FALSE == wrc ) + { + _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); + PR_LOG( _pr_shm_lm, PR_LOG_ERROR, + ("_MD_DetachSharedMemory: UnmapViewOfFile() failed. OSerror: %d", PR_GetOSError())); + rc = PR_FAILURE; + } + + return( rc ); +} + + +extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) +{ + PRStatus rc = PR_SUCCESS; + BOOL wrc; + + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); + + wrc = CloseHandle( shm->handle ); + if ( FALSE == wrc ) + { + _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); + PR_LOG( _pr_shm_lm, PR_LOG_ERROR, + ("_MD_CloseSharedMemory: CloseHandle() failed. OSerror: %d", PR_GetOSError())); + rc = PR_FAILURE; + } + PR_FREEIF( shm->ipcname ); + PR_DELETE( shm ); + + return( rc ); +} /* end _MD_CLOSE_SHARED_MEMORY() */ + +extern PRStatus _MD_DeleteSharedMemory( const char *name ) +{ + return( PR_SUCCESS ); +} + + +/* +** Windows implementation of anonymous memory (file) map +*/ +extern PRLogModuleInfo *_pr_shma_lm; + +extern PRFileMap* _md_OpenAnonFileMap( + const char *dirName, + PRSize size, + PRFileMapProtect prot +) +{ + PRFileMap *fm; + HANDLE hFileMap; + + fm = PR_CreateFileMap( (PRFileDesc*)-1, size, prot ); + if ( NULL == fm ) { + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): PR_CreateFileMap(): failed")); + goto Finished; + } + + /* + ** Make fm->md.hFileMap inheritable. We can't use + ** GetHandleInformation and SetHandleInformation + ** because these two functions fail with + ** ERROR_CALL_NOT_IMPLEMENTED on Win95. + */ + if (DuplicateHandle(GetCurrentProcess(), fm->md.hFileMap, + GetCurrentProcess(), &hFileMap, + 0, TRUE /* inheritable */, + DUPLICATE_SAME_ACCESS) == FALSE) { + PR_SetError( PR_UNKNOWN_ERROR, GetLastError() ); + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_OpenAnonFileMap(): DuplicateHandle(): failed")); + PR_CloseFileMap( fm ); + fm = NULL; + goto Finished; + } + CloseHandle(fm->md.hFileMap); + fm->md.hFileMap = hFileMap; + +Finished: + return(fm); +} /* end md_OpenAnonFileMap() */ + +/* +** _md_ExportFileMapAsString() +** +*/ +extern PRStatus _md_ExportFileMapAsString( + PRFileMap *fm, + PRSize bufSize, + char *buf +) +{ + PRIntn written; + + written = PR_snprintf( buf, (PRUint32) bufSize, "%d:%" PR_PRIdOSFD ":%ld", + (PRIntn)fm->prot, (PROsfd)fm->md.hFileMap, (PRInt32)fm->md.dwAccess ); + + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_ExportFileMapAsString(): prot: %x, hFileMap: %x, dwAccess: %x", + fm->prot, fm->md.hFileMap, fm->md.dwAccess )); + + return((written == -1)? PR_FAILURE : PR_SUCCESS); +} /* end _md_ExportFileMapAsString() */ + + +/* +** _md_ImportFileMapFromString() +** +*/ +extern PRFileMap * _md_ImportFileMapFromString( + const char *fmstring +) +{ + PRIntn prot; + PROsfd hFileMap; + PRInt32 dwAccess; + PRFileMap *fm = NULL; + + PR_sscanf( fmstring, "%d:%" PR_SCNdOSFD ":%ld", + &prot, &hFileMap, &dwAccess ); + + fm = PR_NEWZAP(PRFileMap); + if ( NULL == fm ) { + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_ImportFileMapFromString(): PR_NEWZAP(): Failed")); + return(fm); + } + + fm->prot = (PRFileMapProtect)prot; + fm->md.hFileMap = (HANDLE)hFileMap; + fm->md.dwAccess = (DWORD)dwAccess; + fm->fd = (PRFileDesc*)-1; + + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, + ("_md_ImportFileMapFromString(): fm: %p, prot: %d, hFileMap: %8.8x, dwAccess: %8.8x, fd: %x", + fm, prot, fm->md.hFileMap, fm->md.dwAccess, fm->fd)); + return(fm); +} /* end _md_ImportFileMapFromString() */ + +#else +Error! Why is PR_HAVE_WIN32_NAMED_SHARED_MEMORY not defined? +#endif /* PR_HAVE_WIN32_NAMED_SHARED_MEMORY */ +/* --- end w32shm.c --- */ diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w95cv.c nspr-4.10.7/nspr/pr/src/md/windows/w95cv.c --- nspr-4.9.5/nspr/pr/src/md/windows/w95cv.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w95cv.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,367 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * w95cv.c -- Windows 95 Machine-Dependent Code for Condition Variables + * + * We implement our own condition variable wait queue. Each thread + * has a semaphore object (thread->md.blocked_sema) to block on while + * waiting on a condition variable. + * + * We use a deferred condition notify algorithm. When PR_NotifyCondVar + * or PR_NotifyAllCondVar is called, the condition notifies are simply + * recorded in the _MDLock structure. We defer the condition notifies + * until right after we unlock the lock. This way the awakened threads + * have a better chance to reaquire the lock. + */ + +#include "primpl.h" + +/* + * AddThreadToCVWaitQueueInternal -- + * + * Add the thread to the end of the condition variable's wait queue. + * The CV's lock must be locked when this function is called. + */ + +static void +AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv) +{ + PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL) + || (cv->waitTail == NULL && cv->waitHead == NULL)); + cv->nwait += 1; + thred->md.inCVWaitQueue = PR_TRUE; + thred->md.next = NULL; + thred->md.prev = cv->waitTail; + if (cv->waitHead == NULL) { + cv->waitHead = thred; + } else { + cv->waitTail->md.next = thred; + } + cv->waitTail = thred; +} + +/* + * md_UnlockAndPostNotifies -- + * + * Unlock the lock, and then do the deferred condition notifies. + * If waitThred and waitCV are not NULL, waitThred is added to + * the wait queue of waitCV before the lock is unlocked. + * + * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK, + * the two places where a lock is unlocked. + */ +static void +md_UnlockAndPostNotifies( + _MDLock *lock, + PRThread *waitThred, + _MDCVar *waitCV) +{ + PRIntn index; + _MDNotified post; + _MDNotified *notified, *prev = NULL; + + /* + * Time to actually notify any conditions that were affected + * while the lock was held. Get a copy of the list that's in + * the lock structure and then zero the original. If it's + * linked to other such structures, we own that storage. + */ + post = lock->notified; /* a safe copy; we own the lock */ + +#if defined(DEBUG) + ZeroMemory(&lock->notified, sizeof(_MDNotified)); /* reset */ +#else + lock->notified.length = 0; /* these are really sufficient */ + lock->notified.link = NULL; +#endif + + /* + * Figure out how many threads we need to wake up. + */ + notified = &post; /* this is where we start */ + do { + for (index = 0; index < notified->length; ++index) { + _MDCVar *cv = notified->cv[index].cv; + PRThread *thred; + int i; + + /* Fast special case: no waiting threads */ + if (cv->waitHead == NULL) { + notified->cv[index].notifyHead = NULL; + continue; + } + + /* General case */ + if (-1 == notified->cv[index].times) { + /* broadcast */ + thred = cv->waitHead; + while (thred != NULL) { + thred->md.inCVWaitQueue = PR_FALSE; + thred = thred->md.next; + } + notified->cv[index].notifyHead = cv->waitHead; + cv->waitHead = cv->waitTail = NULL; + cv->nwait = 0; + } else { + thred = cv->waitHead; + i = notified->cv[index].times; + while (thred != NULL && i > 0) { + thred->md.inCVWaitQueue = PR_FALSE; + thred = thred->md.next; + i--; + } + notified->cv[index].notifyHead = cv->waitHead; + cv->waitHead = thred; + if (cv->waitHead == NULL) { + cv->waitTail = NULL; + } else { + if (cv->waitHead->md.prev != NULL) { + cv->waitHead->md.prev->md.next = NULL; + cv->waitHead->md.prev = NULL; + } + } + cv->nwait -= notified->cv[index].times - i; + } + } + notified = notified->link; + } while (NULL != notified); + + if (waitThred) { + AddThreadToCVWaitQueueInternal(waitThred, waitCV); + } + + /* Release the lock before notifying */ + LeaveCriticalSection(&lock->mutex); + + notified = &post; /* this is where we start */ + do { + for (index = 0; index < notified->length; ++index) { + PRThread *thred; + PRThread *next; + + thred = notified->cv[index].notifyHead; + while (thred != NULL) { + BOOL rv; + + next = thred->md.next; + thred->md.prev = thred->md.next = NULL; + + rv = ReleaseSemaphore(thred->md.blocked_sema, 1, NULL); + PR_ASSERT(rv != 0); + thred = next; + } + } + prev = notified; + notified = notified->link; + if (&post != prev) PR_DELETE(prev); + } while (NULL != notified); +} + +/* + * Notifies just get posted to the protecting mutex. The + * actual notification is done when the lock is released so that + * MP systems don't contend for a lock that they can't have. + */ +static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock, + PRBool broadcast) +{ + PRIntn index = 0; + _MDNotified *notified = &lock->notified; + + while (1) { + for (index = 0; index < notified->length; ++index) { + if (notified->cv[index].cv == cvar) { + if (broadcast) { + notified->cv[index].times = -1; + } else if (-1 != notified->cv[index].times) { + notified->cv[index].times += 1; + } + return; + } + } + /* if not full, enter new CV in this array */ + if (notified->length < _MD_CV_NOTIFIED_LENGTH) break; + + /* if there's no link, create an empty array and link it */ + if (NULL == notified->link) { + notified->link = PR_NEWZAP(_MDNotified); + } + + notified = notified->link; + } + + /* A brand new entry in the array */ + notified->cv[index].times = (broadcast) ? -1 : 1; + notified->cv[index].cv = cvar; + notified->length += 1; +} + +/* + * _PR_MD_NEW_CV() -- Creating new condition variable + * ... Solaris uses cond_init() in similar function. + * + * returns: -1 on failure + * 0 when it succeeds. + * + */ +PRInt32 +_PR_MD_NEW_CV(_MDCVar *cv) +{ + cv->magic = _MD_MAGIC_CV; + /* + * The waitHead, waitTail, and nwait fields are zeroed + * when the PRCondVar structure is created. + */ + return 0; +} + +void _PR_MD_FREE_CV(_MDCVar *cv) +{ + cv->magic = (PRUint32)-1; + return; +} + +/* + * _PR_MD_WAIT_CV() -- Wait on condition variable + */ +void _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout ) +{ + PRThread *thred = _PR_MD_CURRENT_THREAD(); + DWORD rv; + DWORD msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ? + INFINITE : PR_IntervalToMilliseconds(timeout); + + /* + * If we have pending notifies, post them now. + */ + if (0 != lock->notified.length) { + md_UnlockAndPostNotifies(lock, thred, cv); + } else { + AddThreadToCVWaitQueueInternal(thred, cv); + LeaveCriticalSection(&lock->mutex); + } + + /* Wait for notification or timeout; don't really care which */ + rv = WaitForSingleObject(thred->md.blocked_sema, msecs); + + EnterCriticalSection(&(lock->mutex)); + + PR_ASSERT(rv != WAIT_ABANDONED); + PR_ASSERT(rv != WAIT_FAILED); + PR_ASSERT(rv != WAIT_OBJECT_0 || thred->md.inCVWaitQueue == PR_FALSE); + + if (rv == WAIT_TIMEOUT) { + if (thred->md.inCVWaitQueue) { + PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL) + || (cv->waitTail == NULL && cv->waitHead == NULL)); + cv->nwait -= 1; + thred->md.inCVWaitQueue = PR_FALSE; + if (cv->waitHead == thred) { + cv->waitHead = thred->md.next; + if (cv->waitHead == NULL) { + cv->waitTail = NULL; + } else { + cv->waitHead->md.prev = NULL; + } + } else { + PR_ASSERT(thred->md.prev != NULL); + thred->md.prev->md.next = thred->md.next; + if (thred->md.next != NULL) { + thred->md.next->md.prev = thred->md.prev; + } else { + PR_ASSERT(cv->waitTail == thred); + cv->waitTail = thred->md.prev; + } + } + thred->md.next = thred->md.prev = NULL; + } else { + /* + * This thread must have been notified, but the + * ReleaseSemaphore call happens after WaitForSingleObject + * times out. Wait on the semaphore again to make it + * non-signaled. We assume this wait won't take long. + */ + rv = WaitForSingleObject(thred->md.blocked_sema, INFINITE); + PR_ASSERT(rv == WAIT_OBJECT_0); + } + } + PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE); + return; +} /* --- end _PR_MD_WAIT_CV() --- */ + +void _PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock) +{ + md_PostNotifyToCvar(cv, lock, PR_FALSE); + return; +} + +void _PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock) +{ + md_PostNotifyToCvar(cv, lock, PR_TRUE); + return; +} + +typedef BOOL (WINAPI *INITIALIZECRITICALSECTIONEX)( + CRITICAL_SECTION *lpCriticalSection, + DWORD dwSpinCount, + DWORD Flags); + +static INITIALIZECRITICALSECTIONEX sInitializeCriticalSectionEx; + +void _PR_MD_INIT_LOCKS(void) +{ + /* + * Starting with Windows Vista, every CRITICAL_SECTION allocates an extra + * RTL_CRITICAL_SECTION_DEBUG object. Unfortunately, this debug object is + * not reclaimed by DeleteCriticalSection(), causing an apparent memory + * leak. This is a debugging "feature", not a bug. If we are running on + * Vista or later, use InitializeCriticalSectionEx() to allocate + * CRITICAL_SECTIONs without debug objects. + */ + HMODULE hKernel32 = GetModuleHandle("kernel32.dll"); + PR_ASSERT(hKernel32); + PR_ASSERT(!sInitializeCriticalSectionEx); + sInitializeCriticalSectionEx = (INITIALIZECRITICALSECTIONEX) + GetProcAddress(hKernel32, "InitializeCriticalSectionEx"); +} + +/* + * By default, CRITICAL_SECTIONs are initialized with a spin count of 0. + * Joe Duffy's "Concurrent Programming on Windows" book suggests 1500 is + * a "reasonable starting point". On single-processor systems, the spin + * count is ignored and the critical section spin count is set to 0. + */ +#define LOCK_SPIN_COUNT 1500 + +PRStatus _PR_MD_NEW_LOCK(_MDLock *lock) +{ + CRITICAL_SECTION *cs = &lock->mutex; + BOOL ok; + + if (sInitializeCriticalSectionEx) { + ok = sInitializeCriticalSectionEx(cs, LOCK_SPIN_COUNT, + CRITICAL_SECTION_NO_DEBUG_INFO); + } else { + ok = InitializeCriticalSectionAndSpinCount(cs, LOCK_SPIN_COUNT); + } + if (!ok) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } + + lock->notified.length = 0; + lock->notified.link = NULL; + return PR_SUCCESS; +} + +void _PR_MD_UNLOCK(_MDLock *lock) +{ + if (0 != lock->notified.length) { + md_UnlockAndPostNotifies(lock, NULL, NULL); + } else { + LeaveCriticalSection(&lock->mutex); + } +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w95dllmain.c nspr-4.10.7/nspr/pr/src/md/windows/w95dllmain.c --- nspr-4.9.5/nspr/pr/src/md/windows/w95dllmain.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w95dllmain.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * The DLL entry point (DllMain) for NSPR. + * + * This is used to detach threads that were automatically attached by + * nspr. + */ + +#include +#include + +BOOL WINAPI DllMain( + HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ +PRThread *me; + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + if (_pr_initialized) { + me = _MD_GET_ATTACHED_THREAD(); + if ((me != NULL) && (me->flags & _PR_ATTACHED)) + _PRI_DetachThread(); + } + break; + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w95io.c nspr-4.10.7/nspr/pr/src/md/windows/w95io.c --- nspr-4.9.5/nspr/pr/src/md/windows/w95io.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w95io.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1372 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Windows 95 IO module + * + * Assumes synchronous I/O. + * + */ + +#include "primpl.h" +#include +#include +#ifdef MOZ_UNICODE +#include +#endif /* MOZ_UNICODE */ + +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 +}; + +static PRBool IsPrevCharSlash(const char *str, const char *current); + +void +_PR_MD_INIT_IO() +{ + WORD WSAVersion = 0x0101; + WSADATA WSAData; + int err; + + err = WSAStartup( WSAVersion, &WSAData ); + PR_ASSERT(0 == err); + +#ifdef DEBUG + /* Doublecheck _pr_filetime_offset's hard-coded value is correct. */ + { + SYSTEMTIME systime; + union { + PRTime prt; + FILETIME ft; + } filetime; + BOOL rv; + + systime.wYear = 1970; + systime.wMonth = 1; + /* wDayOfWeek is ignored */ + systime.wDay = 1; + systime.wHour = 0; + systime.wMinute = 0; + systime.wSecond = 0; + systime.wMilliseconds = 0; + + rv = SystemTimeToFileTime(&systime, &filetime.ft); + PR_ASSERT(0 != rv); + PR_ASSERT(filetime.prt == _pr_filetime_offset); + } +#endif /* DEBUG */ + + _PR_NT_InitSids(); + + _PR_MD_InitSockets(); +} + +PRStatus +_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks) +{ + DWORD rv; + + PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ? + INFINITE : PR_IntervalToMilliseconds(ticks); + rv = WaitForSingleObject(thread->md.blocked_sema, msecs); + switch(rv) + { + case WAIT_OBJECT_0: + return PR_SUCCESS; + case WAIT_TIMEOUT: + _PR_THREAD_LOCK(thread); + if (thread->state == _PR_IO_WAIT) { + ; + } else { + if (thread->wait.cvar != NULL) { + thread->wait.cvar = NULL; + _PR_THREAD_UNLOCK(thread); + } else { + /* The CVAR was notified just as the timeout + * occurred. This led to us being notified twice. + * call WaitForSingleObject() to clear the semaphore. + */ + _PR_THREAD_UNLOCK(thread); + rv = WaitForSingleObject(thread->md.blocked_sema, 0); + PR_ASSERT(rv == WAIT_OBJECT_0); + } + } + return PR_SUCCESS; + default: + return PR_FAILURE; + } +} +PRStatus +_PR_MD_WAKEUP_WAITER(PRThread *thread) +{ + if ( _PR_IS_NATIVE_THREAD(thread) ) + { + if (ReleaseSemaphore(thread->md.blocked_sema, 1, NULL) == FALSE) + return PR_FAILURE; + else + return PR_SUCCESS; + } +} + + +/* --- FILE IO ----------------------------------------------------------- */ +/* + * _PR_MD_OPEN() -- Open a file + * + * returns: a fileHandle + * + * The NSPR open flags (osflags) are translated into flags for Win95 + * + * Mode seems to be passed in as a unix style file permissions argument + * as in 0666, in the case of opening the logFile. + * + */ +PROsfd +_PR_MD_OPEN(const char *name, PRIntn osflags, int mode) +{ + HANDLE file; + PRInt32 access = 0; + PRInt32 flags = 0; + PRInt32 flag6 = 0; + + if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; + + if (osflags & PR_RDONLY || osflags & PR_RDWR) + access |= GENERIC_READ; + if (osflags & PR_WRONLY || osflags & PR_RDWR) + access |= GENERIC_WRITE; + + if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) + flags = CREATE_NEW; + else if (osflags & PR_CREATE_FILE) { + if (osflags & PR_TRUNCATE) + flags = CREATE_ALWAYS; + else + flags = OPEN_ALWAYS; + } else { + if (osflags & PR_TRUNCATE) + flags = TRUNCATE_EXISTING; + else + flags = OPEN_EXISTING; + } + + file = CreateFileA(name, + access, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, + flags, + flag6, + NULL); + if (file == INVALID_HANDLE_VALUE) { + _PR_MD_MAP_OPEN_ERROR(GetLastError()); + return -1; + } + + return (PROsfd)file; +} + +PROsfd +_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, int mode) +{ + HANDLE file; + PRInt32 access = 0; + PRInt32 flags = 0; + PRInt32 flag6 = 0; + SECURITY_ATTRIBUTES sa; + LPSECURITY_ATTRIBUTES lpSA = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + + if (osflags & PR_CREATE_FILE) { + if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable, + &pSD, &pACL) == PR_SUCCESS) { + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + lpSA = &sa; + } + } + + if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; + + if (osflags & PR_RDONLY || osflags & PR_RDWR) + access |= GENERIC_READ; + if (osflags & PR_WRONLY || osflags & PR_RDWR) + access |= GENERIC_WRITE; + + if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) + flags = CREATE_NEW; + else if (osflags & PR_CREATE_FILE) { + if (osflags & PR_TRUNCATE) + flags = CREATE_ALWAYS; + else + flags = OPEN_ALWAYS; + } else { + if (osflags & PR_TRUNCATE) + flags = TRUNCATE_EXISTING; + else + flags = OPEN_EXISTING; + } + + file = CreateFileA(name, + access, + FILE_SHARE_READ|FILE_SHARE_WRITE, + lpSA, + flags, + flag6, + NULL); + if (lpSA != NULL) { + _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); + } + if (file == INVALID_HANDLE_VALUE) { + _PR_MD_MAP_OPEN_ERROR(GetLastError()); + return -1; + } + + return (PROsfd)file; +} + +PRInt32 +_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len) +{ + PRUint32 bytes; + int rv, err; + + rv = ReadFile((HANDLE)fd->secret->md.osfd, + (LPVOID)buf, + len, + &bytes, + NULL); + + if (rv == 0) + { + err = GetLastError(); + /* ERROR_HANDLE_EOF can only be returned by async io */ + PR_ASSERT(err != ERROR_HANDLE_EOF); + if (err == ERROR_BROKEN_PIPE) + return 0; + else { + _PR_MD_MAP_READ_ERROR(err); + return -1; + } + } + return bytes; +} + +PRInt32 +_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len) +{ + PROsfd f = fd->secret->md.osfd; + PRInt32 bytes; + int rv; + + rv = WriteFile((HANDLE)f, + buf, + len, + &bytes, + NULL ); + + if (rv == 0) + { + _PR_MD_MAP_WRITE_ERROR(GetLastError()); + return -1; + } + return bytes; +} /* --- end _PR_MD_WRITE() --- */ + +PROffset32 +_PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence) +{ + DWORD moveMethod; + PROffset32 rv; + + switch (whence) { + case PR_SEEK_SET: + moveMethod = FILE_BEGIN; + break; + case PR_SEEK_CUR: + moveMethod = FILE_CURRENT; + break; + case PR_SEEK_END: + moveMethod = FILE_END; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + rv = SetFilePointer((HANDLE)fd->secret->md.osfd, offset, NULL, moveMethod); + + /* + * If the lpDistanceToMoveHigh argument (third argument) is + * NULL, SetFilePointer returns 0xffffffff on failure. + */ + if (-1 == rv) { + _PR_MD_MAP_LSEEK_ERROR(GetLastError()); + } + return rv; +} + +PROffset64 +_PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence) +{ + DWORD moveMethod; + LARGE_INTEGER li; + DWORD err; + + switch (whence) { + case PR_SEEK_SET: + moveMethod = FILE_BEGIN; + break; + case PR_SEEK_CUR: + moveMethod = FILE_CURRENT; + break; + case PR_SEEK_END: + moveMethod = FILE_END; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + li.QuadPart = offset; + li.LowPart = SetFilePointer((HANDLE)fd->secret->md.osfd, + li.LowPart, &li.HighPart, moveMethod); + + if (0xffffffff == li.LowPart && (err = GetLastError()) != NO_ERROR) { + _PR_MD_MAP_LSEEK_ERROR(err); + li.QuadPart = -1; + } + return li.QuadPart; +} + +/* + * This is documented to succeed on read-only files, but Win32's + * FlushFileBuffers functions fails with "access denied" in such a + * case. So we only signal an error if the error is *not* "access + * denied". + */ +PRInt32 +_PR_MD_FSYNC(PRFileDesc *fd) +{ + /* + * From the documentation: + * + * On Windows NT, the function FlushFileBuffers fails if hFile + * is a handle to console output. That is because console + * output is not buffered. The function returns FALSE, and + * GetLastError returns ERROR_INVALID_HANDLE. + * + * On the other hand, on Win95, it returns without error. I cannot + * assume that 0, 1, and 2 are console, because if someone closes + * System.out and then opens a file, they might get file descriptor + * 1. An error on *that* version of 1 should be reported, whereas + * an error on System.out (which was the original 1) should be + * ignored. So I use isatty() to ensure that such an error was due + * to this bogosity, and if it was, I ignore the error. + */ + + BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd); + + if (!ok) { + DWORD err = GetLastError(); + if (err != ERROR_ACCESS_DENIED) { // from winerror.h + _PR_MD_MAP_FSYNC_ERROR(err); + return -1; + } + } + return 0; +} + +PRInt32 +_MD_CloseFile(PROsfd osfd) +{ + PRInt32 rv; + + rv = (CloseHandle((HANDLE)osfd))?0:-1; + if (rv == -1) + _PR_MD_MAP_CLOSE_ERROR(GetLastError()); + return rv; +} + + +/* --- DIR IO ------------------------------------------------------------ */ +#define GetFileFromDIR(d) (d)->d_entry.cFileName +#define FileIsHidden(d) ((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + +static void FlipSlashes(char *cp, size_t len) +{ + while (len-- > 0) { + if (cp[0] == '/') { + cp[0] = PR_DIRECTORY_SEPARATOR; + } + cp = _mbsinc(cp); + } +} /* end FlipSlashes() */ + + +/* +** +** Local implementations of standard Unix RTL functions which are not provided +** by the VC RTL. +** +*/ + +PRInt32 +_PR_MD_CLOSE_DIR(_MDDir *d) +{ + if ( d ) { + if (FindClose(d->d_hdl)) { + d->magic = (PRUint32)-1; + return 0; + } else { + _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError()); + return -1; + } + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; +} + + +PRStatus +_PR_MD_OPEN_DIR(_MDDir *d, const char *name) +{ + char filename[ MAX_PATH ]; + size_t len; + + len = strlen(name); + /* Need 5 bytes for \*.* and the trailing null byte. */ + if (len + 5 > MAX_PATH) { + PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); + return PR_FAILURE; + } + strcpy(filename, name); + + /* + * If 'name' ends in a slash or backslash, do not append + * another backslash. + */ + if (IsPrevCharSlash(filename, filename + len)) { + len--; + } + strcpy(&filename[len], "\\*.*"); + FlipSlashes( filename, strlen(filename) ); + + d->d_hdl = FindFirstFileA( filename, &(d->d_entry) ); + if ( d->d_hdl == INVALID_HANDLE_VALUE ) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return PR_FAILURE; + } + d->firstEntry = PR_TRUE; + d->magic = _MD_MAGIC_DIR; + return PR_SUCCESS; +} + +char * +_PR_MD_READ_DIR(_MDDir *d, PRIntn flags) +{ + PRInt32 err; + BOOL rv; + char *fileName; + + if ( d ) { + while (1) { + if (d->firstEntry) { + d->firstEntry = PR_FALSE; + rv = 1; + } else { + rv = FindNextFileA(d->d_hdl, &(d->d_entry)); + } + if (rv == 0) { + break; + } + fileName = GetFileFromDIR(d); + if ( (flags & PR_SKIP_DOT) && + (fileName[0] == '.') && (fileName[1] == '\0')) + continue; + if ( (flags & PR_SKIP_DOT_DOT) && + (fileName[0] == '.') && (fileName[1] == '.') && + (fileName[2] == '\0')) + continue; + if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d)) + continue; + return fileName; + } + err = GetLastError(); + PR_ASSERT(NO_ERROR != err); + _PR_MD_MAP_READDIR_ERROR(err); + return NULL; + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; +} + +PRInt32 +_PR_MD_DELETE(const char *name) +{ + if (DeleteFileA(name)) { + return 0; + } else { + _PR_MD_MAP_DELETE_ERROR(GetLastError()); + return -1; + } +} + +void +_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm) +{ + PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime)); + CopyMemory(prtm, filetime, sizeof(PRTime)); +#if defined(__MINGW32__) + *prtm = (*prtm - _pr_filetime_offset) / 10LL; +#else + *prtm = (*prtm - _pr_filetime_offset) / 10i64; +#endif + +#ifdef DEBUG + /* Doublecheck our calculation. */ + { + SYSTEMTIME systime; + PRExplodedTime etm; + PRTime cmp; /* for comparison */ + BOOL rv; + + rv = FileTimeToSystemTime(filetime, &systime); + PR_ASSERT(0 != rv); + + /* + * PR_ImplodeTime ignores wday and yday. + */ + etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC; + etm.tm_sec = systime.wSecond; + etm.tm_min = systime.wMinute; + etm.tm_hour = systime.wHour; + etm.tm_mday = systime.wDay; + etm.tm_month = systime.wMonth - 1; + etm.tm_year = systime.wYear; + /* + * It is not well-documented what time zone the FILETIME's + * are in. WIN32_FIND_DATA is documented to be in UTC (GMT). + * But BY_HANDLE_FILE_INFORMATION is unclear about this. + * By our best judgement, we assume that FILETIME is in UTC. + */ + etm.tm_params.tp_gmt_offset = 0; + etm.tm_params.tp_dst_offset = 0; + cmp = PR_ImplodeTime(&etm); + + /* + * SYSTEMTIME is in milliseconds precision, so we convert PRTime's + * microseconds to milliseconds before doing the comparison. + */ + PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC)); + } +#endif /* DEBUG */ +} + +PRInt32 +_PR_MD_STAT(const char *fn, struct stat *info) +{ + PRInt32 rv; + + rv = _stat(fn, (struct _stat *)info); + if (-1 == rv) { + /* + * Check for MSVC runtime library _stat() bug. + * (It's really a bug in FindFirstFile().) + * If a pathname ends in a backslash or slash, + * e.g., c:\temp\ or c:/temp/, _stat() will fail. + * Note: a pathname ending in a slash (e.g., c:/temp/) + * can be handled by _stat() on NT but not on Win95. + * + * We remove the backslash or slash at the end and + * try again. + */ + + size_t len = strlen(fn); + if (len > 0 && len <= _MAX_PATH + && IsPrevCharSlash(fn, fn + len)) { + char newfn[_MAX_PATH + 1]; + + strcpy(newfn, fn); + newfn[len - 1] = '\0'; + rv = _stat(newfn, (struct _stat *)info); + } + } + + if (-1 == rv) { + _PR_MD_MAP_STAT_ERROR(errno); + } + return rv; +} + +#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\') + +static PRBool +IsPrevCharSlash(const char *str, const char *current) +{ + const char *prev; + + if (str >= current) + return PR_FALSE; + prev = _mbsdec(str, current); + return (prev == current - 1) && _PR_IS_SLASH(*prev); +} + +/* + * IsRootDirectory -- + * + * Return PR_TRUE if the pathname 'fn' is a valid root directory, + * else return PR_FALSE. The char buffer pointed to by 'fn' must + * be writable. During the execution of this function, the contents + * of the buffer pointed to by 'fn' may be modified, but on return + * the original contents will be restored. 'buflen' is the size of + * the buffer pointed to by 'fn'. + * + * Root directories come in three formats: + * 1. / or \, meaning the root directory of the current drive. + * 2. C:/ or C:\, where C is a drive letter. + * 3. \\\\ or + * \\\, meaning the root directory + * of a UNC (Universal Naming Convention) name. + */ + +static PRBool +IsRootDirectory(char *fn, size_t buflen) +{ + char *p; + PRBool slashAdded = PR_FALSE; + PRBool rv = PR_FALSE; + + if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') { + return PR_TRUE; + } + + if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2]) + && fn[3] == '\0') { + rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; + return rv; + } + + /* The UNC root directory */ + + if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) { + /* The 'server' part should have at least one character. */ + p = &fn[2]; + if (*p == '\0' || _PR_IS_SLASH(*p)) { + return PR_FALSE; + } + + /* look for the next slash */ + do { + p = _mbsinc(p); + } while (*p != '\0' && !_PR_IS_SLASH(*p)); + if (*p == '\0') { + return PR_FALSE; + } + + /* The 'share' part should have at least one character. */ + p++; + if (*p == '\0' || _PR_IS_SLASH(*p)) { + return PR_FALSE; + } + + /* look for the final slash */ + do { + p = _mbsinc(p); + } while (*p != '\0' && !_PR_IS_SLASH(*p)); + if (_PR_IS_SLASH(*p) && p[1] != '\0') { + return PR_FALSE; + } + if (*p == '\0') { + /* + * GetDriveType() doesn't work correctly if the + * path is of the form \\server\share, so we add + * a final slash temporarily. + */ + if ((p + 1) < (fn + buflen)) { + *p++ = '\\'; + *p = '\0'; + slashAdded = PR_TRUE; + } else { + return PR_FALSE; /* name too long */ + } + } + rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; + /* restore the 'fn' buffer */ + if (slashAdded) { + *--p = '\0'; + } + } + return rv; +} + +PRInt32 +_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info) +{ + WIN32_FILE_ATTRIBUTE_DATA findFileData; + BOOL rv; + + if (NULL == fn || '\0' == *fn) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + rv = GetFileAttributesEx(fn, GetFileExInfoStandard, &findFileData); + if (!rv) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return -1; + } + + if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + info->type = PR_FILE_DIRECTORY; + } else { + info->type = PR_FILE_FILE; + } + + info->size = findFileData.nFileSizeHigh; + info->size = (info->size << 32) + findFileData.nFileSizeLow; + + _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime); + + if (0 == findFileData.ftCreationTime.dwLowDateTime && + 0 == findFileData.ftCreationTime.dwHighDateTime) { + info->creationTime = info->modifyTime; + } else { + _PR_FileTimeToPRTime(&findFileData.ftCreationTime, + &info->creationTime); + } + + return 0; +} + +PRInt32 +_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info) +{ + PRFileInfo64 info64; + PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64); + if (0 == rv) + { + info->type = info64.type; + info->size = (PRUint32) info64.size; + info->modifyTime = info64.modifyTime; + info->creationTime = info64.creationTime; + } + return rv; +} + +PRInt32 +_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info) +{ + int rv; + + BY_HANDLE_FILE_INFORMATION hinfo; + + rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo); + if (rv == FALSE) { + _PR_MD_MAP_FSTAT_ERROR(GetLastError()); + return -1; + } + + if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_FILE; + + info->size = hinfo.nFileSizeHigh; + info->size = (info->size << 32) + hinfo.nFileSizeLow; + + _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) ); + _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) ); + + return 0; +} + +PRInt32 +_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) +{ + PRFileInfo64 info64; + int rv = _PR_MD_GETOPENFILEINFO64(fd, &info64); + if (0 == rv) + { + info->type = info64.type; + info->modifyTime = info64.modifyTime; + info->creationTime = info64.creationTime; + LL_L2I(info->size, info64.size); + } + return rv; +} + +PRStatus +_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) +{ + BOOL rv; + + /* + * The SetHandleInformation function fails with the + * ERROR_CALL_NOT_IMPLEMENTED error on Win95. + */ + rv = SetHandleInformation( + (HANDLE)fd->secret->md.osfd, + HANDLE_FLAG_INHERIT, + inheritable ? HANDLE_FLAG_INHERIT : 0); + if (0 == rv) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +void +_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported) +{ + if (imported) { + fd->secret->inheritable = _PR_TRI_UNKNOWN; + } else { + fd->secret->inheritable = _PR_TRI_FALSE; + } +} + +void +_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd) +{ + DWORD flags; + + PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); + if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) { + if (flags & HANDLE_FLAG_INHERIT) { + fd->secret->inheritable = _PR_TRI_TRUE; + } else { + fd->secret->inheritable = _PR_TRI_FALSE; + } + } +} + +PRInt32 +_PR_MD_RENAME(const char *from, const char *to) +{ + /* Does this work with dot-relative pathnames? */ + if (MoveFileA(from, to)) { + return 0; + } else { + _PR_MD_MAP_RENAME_ERROR(GetLastError()); + return -1; + } +} + +PRInt32 +_PR_MD_ACCESS(const char *name, PRAccessHow how) +{ +PRInt32 rv; + switch (how) { + case PR_ACCESS_WRITE_OK: + rv = _access(name, 02); + break; + case PR_ACCESS_READ_OK: + rv = _access(name, 04); + break; + case PR_ACCESS_EXISTS: + return _access(name, 00); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + if (rv < 0) + _PR_MD_MAP_ACCESS_ERROR(errno); + return rv; +} + +PRInt32 +_PR_MD_MKDIR(const char *name, PRIntn mode) +{ + /* XXXMB - how to translate the "mode"??? */ + if (CreateDirectoryA(name, NULL)) { + return 0; + } else { + _PR_MD_MAP_MKDIR_ERROR(GetLastError()); + return -1; + } +} + +PRInt32 +_PR_MD_MAKE_DIR(const char *name, PRIntn mode) +{ + BOOL rv; + SECURITY_ATTRIBUTES sa; + LPSECURITY_ATTRIBUTES lpSA = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + + if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable, + &pSD, &pACL) == PR_SUCCESS) { + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + lpSA = &sa; + } + rv = CreateDirectoryA(name, lpSA); + if (lpSA != NULL) { + _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); + } + if (rv) { + return 0; + } else { + _PR_MD_MAP_MKDIR_ERROR(GetLastError()); + return -1; + } +} + +PRInt32 +_PR_MD_RMDIR(const char *name) +{ + if (RemoveDirectoryA(name)) { + return 0; + } else { + _PR_MD_MAP_RMDIR_ERROR(GetLastError()); + return -1; + } +} + +PRStatus +_PR_MD_LOCKFILE(PROsfd f) +{ + PRStatus rc = PR_SUCCESS; + DWORD rv; + + rv = LockFile( (HANDLE)f, + 0l, 0l, + 0x0l, 0xffffffffl ); + if ( rv == 0 ) { + DWORD rc = GetLastError(); + PR_LOG( _pr_io_lm, PR_LOG_ERROR, + ("_PR_MD_LOCKFILE() failed. Error: %d", rc )); + rc = PR_FAILURE; + } + + return rc; +} /* end _PR_MD_LOCKFILE() */ + +PRStatus +_PR_MD_TLOCKFILE(PROsfd f) +{ + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return PR_FAILURE; +} /* end _PR_MD_TLOCKFILE() */ + + +PRStatus +_PR_MD_UNLOCKFILE(PROsfd f) +{ + PRInt32 rv; + + rv = UnlockFile( (HANDLE) f, + 0l, 0l, + 0x0l, 0xffffffffl ); + + if ( rv ) + { + return PR_SUCCESS; + } + else + { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } +} /* end _PR_MD_UNLOCKFILE() */ + +PRInt32 +_PR_MD_PIPEAVAILABLE(PRFileDesc *fd) +{ + if (NULL == fd) + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return -1; +} + +#ifdef MOZ_UNICODE + +typedef HANDLE (WINAPI *CreateFileWFn) (LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); +static CreateFileWFn createFileW = CreateFileW; +typedef HANDLE (WINAPI *FindFirstFileWFn) (LPCWSTR, LPWIN32_FIND_DATAW); +static FindFirstFileWFn findFirstFileW = FindFirstFileW; +typedef BOOL (WINAPI *FindNextFileWFn) (HANDLE, LPWIN32_FIND_DATAW); +static FindNextFileWFn findNextFileW = FindNextFileW; +typedef DWORD (WINAPI *GetFullPathNameWFn) (LPCWSTR, DWORD, LPWSTR, LPWSTR *); +static GetFullPathNameWFn getFullPathNameW = GetFullPathNameW; +typedef UINT (WINAPI *GetDriveTypeWFn) (LPCWSTR); +static GetDriveTypeWFn getDriveTypeW = GetDriveTypeW; + +#endif /* MOZ_UNICODE */ + +#ifdef MOZ_UNICODE + +/* ================ UTF16 Interfaces ================================ */ +static void FlipSlashesW(PRUnichar *cp, size_t len) +{ + while (len-- > 0) { + if (cp[0] == L'/') { + cp[0] = L'\\'; + } + cp++; + } +} /* end FlipSlashesW() */ + +PROsfd +_PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, int mode) +{ + HANDLE file; + PRInt32 access = 0; + PRInt32 flags = 0; + PRInt32 flag6 = 0; + SECURITY_ATTRIBUTES sa; + LPSECURITY_ATTRIBUTES lpSA = NULL; + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + + if (osflags & PR_CREATE_FILE) { + if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable, + &pSD, &pACL) == PR_SUCCESS) { + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = pSD; + sa.bInheritHandle = FALSE; + lpSA = &sa; + } + } + + if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH; + + if (osflags & PR_RDONLY || osflags & PR_RDWR) + access |= GENERIC_READ; + if (osflags & PR_WRONLY || osflags & PR_RDWR) + access |= GENERIC_WRITE; + + if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL ) + flags = CREATE_NEW; + else if (osflags & PR_CREATE_FILE) { + if (osflags & PR_TRUNCATE) + flags = CREATE_ALWAYS; + else + flags = OPEN_ALWAYS; + } else { + if (osflags & PR_TRUNCATE) + flags = TRUNCATE_EXISTING; + else + flags = OPEN_EXISTING; + } + + file = createFileW(name, + access, + FILE_SHARE_READ|FILE_SHARE_WRITE, + lpSA, + flags, + flag6, + NULL); + if (lpSA != NULL) { + _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); + } + if (file == INVALID_HANDLE_VALUE) { + _PR_MD_MAP_OPEN_ERROR(GetLastError()); + return -1; + } + + return (PROsfd)file; +} + +PRStatus +_PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *d, const PRUnichar *name) +{ + PRUnichar filename[ MAX_PATH ]; + int len; + + len = wcslen(name); + /* Need 5 bytes for \*.* and the trailing null byte. */ + if (len + 5 > MAX_PATH) { + PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); + return PR_FAILURE; + } + wcscpy(filename, name); + + /* + * If 'name' ends in a slash or backslash, do not append + * another backslash. + */ + if (filename[len - 1] == L'/' || filename[len - 1] == L'\\') { + len--; + } + wcscpy(&filename[len], L"\\*.*"); + FlipSlashesW( filename, wcslen(filename) ); + + d->d_hdl = findFirstFileW( filename, &(d->d_entry) ); + if ( d->d_hdl == INVALID_HANDLE_VALUE ) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return PR_FAILURE; + } + d->firstEntry = PR_TRUE; + d->magic = _MD_MAGIC_DIR; + return PR_SUCCESS; +} + +PRUnichar * +_PR_MD_READ_DIR_UTF16(_MDDirUTF16 *d, PRIntn flags) +{ + PRInt32 err; + BOOL rv; + PRUnichar *fileName; + + if ( d ) { + while (1) { + if (d->firstEntry) { + d->firstEntry = PR_FALSE; + rv = 1; + } else { + rv = findNextFileW(d->d_hdl, &(d->d_entry)); + } + if (rv == 0) { + break; + } + fileName = GetFileFromDIR(d); + if ( (flags & PR_SKIP_DOT) && + (fileName[0] == L'.') && (fileName[1] == L'\0')) + continue; + if ( (flags & PR_SKIP_DOT_DOT) && + (fileName[0] == L'.') && (fileName[1] == L'.') && + (fileName[2] == L'\0')) + continue; + if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d)) + continue; + return fileName; + } + err = GetLastError(); + PR_ASSERT(NO_ERROR != err); + _PR_MD_MAP_READDIR_ERROR(err); + return NULL; + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; +} + +PRInt32 +_PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *d) +{ + if ( d ) { + if (FindClose(d->d_hdl)) { + d->magic = (PRUint32)-1; + return 0; + } else { + _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError()); + return -1; + } + } + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; +} + +#define _PR_IS_W_SLASH(ch) ((ch) == L'/' || (ch) == L'\\') + +/* + * IsRootDirectoryW -- + * + * Return PR_TRUE if the pathname 'fn' is a valid root directory, + * else return PR_FALSE. The PRUnichar buffer pointed to by 'fn' must + * be writable. During the execution of this function, the contents + * of the buffer pointed to by 'fn' may be modified, but on return + * the original contents will be restored. 'buflen' is the size of + * the buffer pointed to by 'fn', in PRUnichars. + * + * Root directories come in three formats: + * 1. / or \, meaning the root directory of the current drive. + * 2. C:/ or C:\, where C is a drive letter. + * 3. \\\\ or + * \\\, meaning the root directory + * of a UNC (Universal Naming Convention) name. + */ + +static PRBool +IsRootDirectoryW(PRUnichar *fn, size_t buflen) +{ + PRUnichar *p; + PRBool slashAdded = PR_FALSE; + PRBool rv = PR_FALSE; + + if (_PR_IS_W_SLASH(fn[0]) && fn[1] == L'\0') { + return PR_TRUE; + } + + if (iswalpha(fn[0]) && fn[1] == L':' && _PR_IS_W_SLASH(fn[2]) + && fn[3] == L'\0') { + rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE; + return rv; + } + + /* The UNC root directory */ + + if (_PR_IS_W_SLASH(fn[0]) && _PR_IS_W_SLASH(fn[1])) { + /* The 'server' part should have at least one character. */ + p = &fn[2]; + if (*p == L'\0' || _PR_IS_W_SLASH(*p)) { + return PR_FALSE; + } + + /* look for the next slash */ + do { + p++; + } while (*p != L'\0' && !_PR_IS_W_SLASH(*p)); + if (*p == L'\0') { + return PR_FALSE; + } + + /* The 'share' part should have at least one character. */ + p++; + if (*p == L'\0' || _PR_IS_W_SLASH(*p)) { + return PR_FALSE; + } + + /* look for the final slash */ + do { + p++; + } while (*p != L'\0' && !_PR_IS_W_SLASH(*p)); + if (_PR_IS_W_SLASH(*p) && p[1] != L'\0') { + return PR_FALSE; + } + if (*p == L'\0') { + /* + * GetDriveType() doesn't work correctly if the + * path is of the form \\server\share, so we add + * a final slash temporarily. + */ + if ((p + 1) < (fn + buflen)) { + *p++ = L'\\'; + *p = L'\0'; + slashAdded = PR_TRUE; + } else { + return PR_FALSE; /* name too long */ + } + } + rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE; + /* restore the 'fn' buffer */ + if (slashAdded) { + *--p = L'\0'; + } + } + return rv; +} + +PRInt32 +_PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info) +{ + HANDLE hFindFile; + WIN32_FIND_DATAW findFileData; + PRUnichar pathbuf[MAX_PATH + 1]; + + if (NULL == fn || L'\0' == *fn) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + /* + * FindFirstFile() expands wildcard characters. So + * we make sure the pathname contains no wildcard. + */ + if (NULL != wcspbrk(fn, L"?*")) { + PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0); + return -1; + } + + hFindFile = findFirstFileW(fn, &findFileData); + if (INVALID_HANDLE_VALUE == hFindFile) { + DWORD len; + PRUnichar *filePart; + + /* + * FindFirstFile() does not work correctly on root directories. + * It also doesn't work correctly on a pathname that ends in a + * slash. So we first check to see if the pathname specifies a + * root directory. If not, and if the pathname ends in a slash, + * we remove the final slash and try again. + */ + + /* + * If the pathname does not contain ., \, and /, it cannot be + * a root directory or a pathname that ends in a slash. + */ + if (NULL == wcspbrk(fn, L".\\/")) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return -1; + } + len = getFullPathNameW(fn, sizeof(pathbuf)/sizeof(pathbuf[0]), pathbuf, + &filePart); + if (0 == len) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return -1; + } + if (len > sizeof(pathbuf)/sizeof(pathbuf[0])) { + PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); + return -1; + } + if (IsRootDirectoryW(pathbuf, sizeof(pathbuf)/sizeof(pathbuf[0]))) { + info->type = PR_FILE_DIRECTORY; + info->size = 0; + /* + * These timestamps don't make sense for root directories. + */ + info->modifyTime = 0; + info->creationTime = 0; + return 0; + } + if (!_PR_IS_W_SLASH(pathbuf[len - 1])) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return -1; + } else { + pathbuf[len - 1] = L'\0'; + hFindFile = findFirstFileW(pathbuf, &findFileData); + if (INVALID_HANDLE_VALUE == hFindFile) { + _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); + return -1; + } + } + } + + FindClose(hFindFile); + + if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + info->type = PR_FILE_DIRECTORY; + } else { + info->type = PR_FILE_FILE; + } + + info->size = findFileData.nFileSizeHigh; + info->size = (info->size << 32) + findFileData.nFileSizeLow; + + _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime); + + if (0 == findFileData.ftCreationTime.dwLowDateTime && + 0 == findFileData.ftCreationTime.dwHighDateTime) { + info->creationTime = info->modifyTime; + } else { + _PR_FileTimeToPRTime(&findFileData.ftCreationTime, + &info->creationTime); + } + + return 0; +} +/* ================ end of UTF16 Interfaces ================================ */ +#endif /* MOZ_UNICODE */ diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w95sock.c nspr-4.10.7/nspr/pr/src/md/windows/w95sock.c --- nspr-4.9.5/nspr/pr/src/md/windows/w95sock.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w95sock.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,669 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Win95 Sockets module + * + */ + +#include "primpl.h" + +#define READ_FD 1 +#define WRITE_FD 2 +#define CONNECT_FD 3 + +static PRInt32 socket_io_wait( + PROsfd osfd, + PRInt32 fd_type, + PRIntervalTime timeout); + + +/* --- SOCKET IO --------------------------------------------------------- */ + +static PRBool socketFixInet6RcvBuf = PR_FALSE; + +void _PR_MD_InitSockets(void) +{ + OSVERSIONINFO osvi; + + memset(&osvi, 0, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof(osvi); + GetVersionEx(&osvi); + + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + { + /* if Windows XP (32-bit) */ + socketFixInet6RcvBuf = PR_TRUE; + } +} + +void _PR_MD_CleanupSockets(void) +{ + socketFixInet6RcvBuf = PR_FALSE; +} + +PROsfd +_PR_MD_SOCKET(int af, int type, int flags) +{ + SOCKET sock; + u_long one = 1; + + sock = socket(af, type, flags); + + if (sock == INVALID_SOCKET ) + { + _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError()); + return (PROsfd)sock; + } + + /* + ** Make the socket Non-Blocking + */ + if (ioctlsocket( sock, FIONBIO, &one) != 0) + { + PR_SetError(PR_UNKNOWN_ERROR, WSAGetLastError()); + closesocket(sock); + return -1; + } + + if (af == AF_INET6 && socketFixInet6RcvBuf) + { + int bufsize; + int len = sizeof(bufsize); + int rv; + + /* Windows XP 32-bit returns an error on getpeername() for AF_INET6 + * sockets if the receive buffer size is greater than 65535 before + * the connection is initiated. The default receive buffer size may + * be 128000 so fix it here to always be <= 65535. See bug 513659 + * and IBM DB2 support technote "Receive/Send IPv6 Socket Size + * Problem in Windows XP SP2 & SP3". + */ + rv = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, &len); + if (rv == 0 && bufsize > 65535) + { + bufsize = 65535; + setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, len); + } + } + + return (PROsfd)sock; +} + +/* +** _MD_CloseSocket() -- Close a socket +** +*/ +PRInt32 +_MD_CloseSocket(PROsfd osfd) +{ + PRInt32 rv; + + rv = closesocket((SOCKET) osfd ); + if (rv < 0) + _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError()); + + return rv; +} + +PRInt32 +_MD_SocketAvailable(PRFileDesc *fd) +{ + PRInt32 result; + + if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError()); + return -1; + } + return result; +} + +PROsfd _MD_Accept( + PRFileDesc *fd, + PRNetAddr *raddr, + PRUint32 *rlen, + PRIntervalTime timeout ) +{ + PROsfd osfd = fd->secret->md.osfd; + SOCKET sock; + PRInt32 rv, err; + + while ((sock = accept(osfd, (struct sockaddr *) raddr, rlen)) == -1) + { + err = WSAGetLastError(); + if ((err == WSAEWOULDBLOCK) && (!fd->secret->nonblocking)) + { + if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0) + { + break; + } + } + else + { + _PR_MD_MAP_ACCEPT_ERROR(err); + break; + } + } + return(sock); +} /* end _MD_accept() */ + +PRInt32 +_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, + PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv; + int err; + + if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) + { + err = WSAGetLastError(); + if ((!fd->secret->nonblocking) && (err == WSAEWOULDBLOCK)) + { + rv = socket_io_wait(osfd, CONNECT_FD, timeout); + if ( rv < 0 ) + { + return(-1); + } + else + { + PR_ASSERT(rv > 0); + /* it's connected */ + return(0); + } + } + _PR_MD_MAP_CONNECT_ERROR(err); + } + return rv; +} + +PRInt32 +_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen) +{ + PRInt32 rv; + + rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen); + + if (rv == SOCKET_ERROR) { + _PR_MD_MAP_BIND_ERROR(WSAGetLastError()); + return -1; + } + + return 0; +} + +PRInt32 +_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog) +{ + PRInt32 rv; + + rv = listen(fd->secret->md.osfd, backlog); + + if (rv == SOCKET_ERROR) { + _PR_MD_MAP_DEFAULT_ERROR(WSAGetLastError()); + return -1; + } + + return 0; +} + +PRInt32 +_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + int osflags; + + if (0 == flags) { + osflags = 0; + } else { + PR_ASSERT(PR_MSG_PEEK == flags); + osflags = MSG_PEEK; + } + while ((rv = recv( osfd, buf, amount, osflags)) == -1) + { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) + { + rv = socket_io_wait(osfd, READ_FD, timeout); + if ( rv < 0 ) + { + return -1; + } + } + else + { + _PR_MD_MAP_RECV_ERROR(err); + break; + } + } /* end while() */ + return(rv); +} + +PRInt32 +_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRInt32 bytesSent = 0; + + while(bytesSent < amount ) + { + while ((rv = send( osfd, buf, amount, 0 )) == -1) + { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) + { + rv = socket_io_wait(osfd, WRITE_FD, timeout); + if ( rv < 0 ) + { + return -1; + } + } + else + { + _PR_MD_MAP_SEND_ERROR(err); + return -1; + } + } + bytesSent += rv; + if (fd->secret->nonblocking) + { + break; + } + if (bytesSent < amount) + { + rv = socket_io_wait(osfd, WRITE_FD, timeout); + if ( rv < 0 ) + { + return -1; + } + } + } + return bytesSent; +} + +PRInt32 +_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + PRInt32 bytesSent = 0; + + while(bytesSent < amount) + { + while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr, + addrlen)) == -1) + { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) + { + rv = socket_io_wait(osfd, WRITE_FD, timeout); + if ( rv < 0 ) + { + return -1; + } + } + else + { + _PR_MD_MAP_SENDTO_ERROR(err); + return -1; + } + } + bytesSent += rv; + if (fd->secret->nonblocking) + { + break; + } + if (bytesSent < amount) + { + rv = socket_io_wait(osfd, WRITE_FD, timeout); + if (rv < 0) + { + return -1; + } + } + } + return bytesSent; +} + +PRInt32 +_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, + PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) +{ + PROsfd osfd = fd->secret->md.osfd; + PRInt32 rv, err; + + while ((rv = recvfrom( osfd, buf, amount, 0, (struct sockaddr *) addr, + addrlen)) == -1) + { + if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) + && (!fd->secret->nonblocking)) + { + rv = socket_io_wait(osfd, READ_FD, timeout); + if ( rv < 0) + { + return -1; + } + } + else + { + _PR_MD_MAP_RECVFROM_ERROR(err); + break; + } + } + return(rv); +} + +PRInt32 +_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) +{ + int index; + int sent = 0; + int rv; + + for (index=0; index < iov_size; index++) + { + rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0, timeout); + if (rv > 0) + sent += rv; + if ( rv != iov[index].iov_len ) + { + if (rv < 0) + { + if (fd->secret->nonblocking + && (PR_GetError() == PR_WOULD_BLOCK_ERROR) + && (sent > 0)) + { + return sent; + } + else + { + return -1; + } + } + /* Only a nonblocking socket can have partial sends */ + PR_ASSERT(fd->secret->nonblocking); + return sent; + } + } + return sent; +} + +PRInt32 +_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how) +{ +PRInt32 rv; + + rv = shutdown(fd->secret->md.osfd, how); + if (rv < 0) + _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError()); + return rv; +} + +PRStatus +_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) +{ + PRInt32 rv; + + rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len); + if (rv==0) { + return PR_SUCCESS; + } else { + _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError()); + return PR_FAILURE; + } +} + +PRStatus +_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len) +{ + PRInt32 rv; + + rv = getpeername((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len); + if (rv==0) { + return PR_SUCCESS; + } else { + _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError()); + return PR_FAILURE; + } +} + +PRStatus +_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen) +{ + PRInt32 rv; + + rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); + if (rv==0) { + return PR_SUCCESS; + } else { + _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); + return PR_FAILURE; + } +} + +PRStatus +_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen) +{ + PRInt32 rv; + + rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen); + if (rv==0) { + return PR_SUCCESS; + } else { + _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError()); + return PR_FAILURE; + } +} + +void +_MD_MakeNonblock(PRFileDesc *f) +{ + return; /* do nothing */ +} + + + +/* + * socket_io_wait -- + * + * Wait for socket i/o, periodically checking for interrupt. + * + * This function returns 1 on success. On failure, it returns + * -1 and sets the error codes. It never returns 0. + */ +#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5 + +static PRInt32 socket_io_wait( + PROsfd osfd, + PRInt32 fd_type, + PRIntervalTime timeout) +{ + PRInt32 rv = -1; + struct timeval tv; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRIntervalTime elapsed, remaining; + PRBool wait_for_remaining; + fd_set rd_wr, ex; + int err, len; + + switch (timeout) { + case PR_INTERVAL_NO_WAIT: + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + break; + case PR_INTERVAL_NO_TIMEOUT: + /* + * This is a special case of the 'default' case below. + * Please see the comments there. + */ + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; + tv.tv_usec = 0; + FD_ZERO(&rd_wr); + FD_ZERO(&ex); + do { + FD_SET(osfd, &rd_wr); + FD_SET(osfd, &ex); + switch( fd_type ) + { + case READ_FD: + rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv); + break; + case WRITE_FD: + rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv); + break; + case CONNECT_FD: + rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv); + break; + default: + PR_ASSERT(0); + break; + } /* end switch() */ + if (rv == -1 ) + { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + break; + } + if ( rv > 0 && fd_type == CONNECT_FD ) + { + /* + * Call Sleep(0) to work around a Winsock timing bug. + */ + Sleep(0); + if (FD_ISSET((SOCKET)osfd, &ex)) + { + len = sizeof(err); + if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, + (char *) &err, &len) == SOCKET_ERROR) + { + _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); + return -1; + } + if (err != 0) + _PR_MD_MAP_CONNECT_ERROR(err); + else + PR_SetError(PR_UNKNOWN_ERROR, 0); + return -1; + } + if (FD_ISSET((SOCKET)osfd, &rd_wr)) + { + /* it's connected */ + return 1; + } + PR_ASSERT(0); + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + } while (rv == 0); + break; + default: + remaining = timeout; + FD_ZERO(&rd_wr); + FD_ZERO(&ex); + do { + /* + * We block in _MD_SELECT for at most + * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds, + * so that there is an upper limit on the delay + * before the interrupt bit is checked. + */ + wait_for_remaining = PR_TRUE; + tv.tv_sec = PR_IntervalToSeconds(remaining); + if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) { + wait_for_remaining = PR_FALSE; + tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS; + tv.tv_usec = 0; + } else { + tv.tv_usec = PR_IntervalToMicroseconds( + remaining - + PR_SecondsToInterval(tv.tv_sec)); + } + FD_SET(osfd, &rd_wr); + FD_SET(osfd, &ex); + switch( fd_type ) + { + case READ_FD: + rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv); + break; + case WRITE_FD: + rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv); + break; + case CONNECT_FD: + rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv); + break; + default: + PR_ASSERT(0); + break; + } /* end switch() */ + if (rv == -1) + { + _PR_MD_MAP_SELECT_ERROR(WSAGetLastError()); + break; + } + if ( rv > 0 && fd_type == CONNECT_FD ) + { + /* + * Call Sleep(0) to work around a Winsock timing bug. + */ + Sleep(0); + if (FD_ISSET((SOCKET)osfd, &ex)) + { + len = sizeof(err); + if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, + (char *) &err, &len) == SOCKET_ERROR) + { + _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError()); + return -1; + } + if (err != 0) + _PR_MD_MAP_CONNECT_ERROR(err); + else + PR_SetError(PR_UNKNOWN_ERROR, 0); + return -1; + } + if (FD_ISSET((SOCKET)osfd, &rd_wr)) + { + /* it's connected */ + return 1; + } + PR_ASSERT(0); + } + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + rv = -1; + break; + } + /* + * We loop again if _MD_SELECT timed out and the + * timeout deadline has not passed yet. + */ + if (rv == 0 ) + { + if (wait_for_remaining) { + elapsed = remaining; + } else { + elapsed = PR_SecondsToInterval(tv.tv_sec) + + PR_MicrosecondsToInterval(tv.tv_usec); + } + if (elapsed >= remaining) { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + rv = -1; + break; + } else { + remaining = remaining - elapsed; + } + } + } while (rv == 0 ); + break; + } + return(rv); +} /* end socket_io_wait() */ diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/w95thred.c nspr-4.10.7/nspr/pr/src/md/windows/w95thred.c --- nspr-4.9.5/nspr/pr/src/md/windows/w95thred.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/w95thred.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,320 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include /* for _beginthreadex() */ + +#if defined(_MSC_VER) && _MSC_VER <= 1200 +/* + * VC++ 6.0 doesn't have DWORD_PTR. + */ + +typedef DWORD DWORD_PTR; +#endif /* _MSC_VER <= 1200 */ + +/* --- globals ------------------------------------------------ */ +#ifdef _PR_USE_STATIC_TLS +__declspec(thread) struct PRThread *_pr_thread_last_run; +__declspec(thread) struct PRThread *_pr_currentThread; +__declspec(thread) struct _PRCPU *_pr_currentCPU; +#else +DWORD _pr_currentThreadIndex; +DWORD _pr_lastThreadIndex; +DWORD _pr_currentCPUIndex; +#endif +int _pr_intsOff = 0; +_PRInterruptTable _pr_interruptTable[] = { { 0 } }; + +void +_PR_MD_EARLY_INIT() +{ +#ifndef _PR_USE_STATIC_TLS + _pr_currentThreadIndex = TlsAlloc(); + _pr_lastThreadIndex = TlsAlloc(); + _pr_currentCPUIndex = TlsAlloc(); +#endif +} + +void _PR_MD_CLEANUP_BEFORE_EXIT(void) +{ + _PR_NT_FreeSids(); + + _PR_MD_CleanupSockets(); + + WSACleanup(); + +#ifndef _PR_USE_STATIC_TLS + TlsFree(_pr_currentThreadIndex); + TlsFree(_pr_lastThreadIndex); + TlsFree(_pr_currentCPUIndex); +#endif +} + +PRStatus +_PR_MD_INIT_THREAD(PRThread *thread) +{ + if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { + /* + ** Warning: + ** -------- + ** NSPR requires a real handle to every thread. + ** GetCurrentThread() returns a pseudo-handle which + ** is not suitable for some thread operations (e.g., + ** suspending). Therefore, get a real handle from + ** the pseudo handle via DuplicateHandle(...) + */ + DuplicateHandle( + GetCurrentProcess(), /* Process of source handle */ + GetCurrentThread(), /* Pseudo Handle to dup */ + GetCurrentProcess(), /* Process of handle */ + &(thread->md.handle), /* resulting handle */ + 0L, /* access flags */ + FALSE, /* Inheritable */ + DUPLICATE_SAME_ACCESS); /* Options */ + } + + /* Create the blocking IO semaphore */ + thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL); + if (thread->md.blocked_sema == NULL) + return PR_FAILURE; + else + return PR_SUCCESS; +} + +static unsigned __stdcall +pr_root(void *arg) +{ + PRThread *thread = (PRThread *)arg; + thread->md.start(thread); + return 0; +} + +PRStatus +_PR_MD_CREATE_THREAD(PRThread *thread, + void (*start)(void *), + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + + thread->md.start = start; + thread->md.handle = (HANDLE) _beginthreadex( + NULL, + thread->stack->stackSize, + pr_root, + (void *)thread, + CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, + &(thread->id)); + if(!thread->md.handle) { + return PR_FAILURE; + } + + thread->md.id = thread->id; + /* + * On windows, a thread is created with a thread priority of + * THREAD_PRIORITY_NORMAL. + */ + if (priority != PR_PRIORITY_NORMAL) { + _PR_MD_SET_PRIORITY(&(thread->md), priority); + } + + /* Activate the thread */ + if ( ResumeThread( thread->md.handle ) != -1) + return PR_SUCCESS; + + return PR_FAILURE; +} + +void +_PR_MD_YIELD(void) +{ + /* Can NT really yield at all? */ + Sleep(0); +} + +void +_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) +{ + int nativePri; + BOOL rv; + + if (newPri < PR_PRIORITY_FIRST) { + newPri = PR_PRIORITY_FIRST; + } else if (newPri > PR_PRIORITY_LAST) { + newPri = PR_PRIORITY_LAST; + } + switch (newPri) { + case PR_PRIORITY_LOW: + nativePri = THREAD_PRIORITY_BELOW_NORMAL; + break; + case PR_PRIORITY_NORMAL: + nativePri = THREAD_PRIORITY_NORMAL; + break; + case PR_PRIORITY_HIGH: + nativePri = THREAD_PRIORITY_ABOVE_NORMAL; + break; + case PR_PRIORITY_URGENT: + nativePri = THREAD_PRIORITY_HIGHEST; + } + rv = SetThreadPriority(thread->handle, nativePri); + PR_ASSERT(rv); + if (!rv) { + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("PR_SetThreadPriority: can't set thread priority\n")); + } + return; +} + +const DWORD MS_VC_EXCEPTION = 0x406D1388; + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void +_PR_MD_SET_CURRENT_THREAD_NAME(const char *name) +{ +#ifdef _MSC_VER + THREADNAME_INFO info; + + if (!IsDebuggerPresent()) + return; + + info.dwType = 0x1000; + info.szName = (char*) name; + info.dwThreadID = -1; + info.dwFlags = 0; + + __try { + RaiseException(MS_VC_EXCEPTION, + 0, + sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR*)&info); + } __except(EXCEPTION_CONTINUE_EXECUTION) { + } +#endif +} + +void +_PR_MD_CLEAN_THREAD(PRThread *thread) +{ + BOOL rv; + + if (thread->md.blocked_sema) { + rv = CloseHandle(thread->md.blocked_sema); + PR_ASSERT(rv); + thread->md.blocked_sema = 0; + } + + if (thread->md.handle) { + rv = CloseHandle(thread->md.handle); + PR_ASSERT(rv); + thread->md.handle = 0; + } +} + +void +_PR_MD_EXIT_THREAD(PRThread *thread) +{ + _PR_MD_CLEAN_THREAD(thread); + _PR_MD_SET_CURRENT_THREAD(NULL); +} + + +void +_PR_MD_EXIT(PRIntn status) +{ + _exit(status); +} + +PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask ) +{ +#ifdef WINCE + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return -1; +#else + DWORD_PTR rv; + + rv = SetThreadAffinityMask(thread->md.handle, mask); + + return rv?0:-1; +#endif +} + +PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask) +{ +#ifdef WINCE + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return -1; +#else + BOOL rv; + DWORD_PTR process_mask; + DWORD_PTR system_mask; + + rv = GetProcessAffinityMask(GetCurrentProcess(), + &process_mask, &system_mask); + if (rv) + *mask = (PRUint32)process_mask; + + return rv?0:-1; +#endif +} + +void +_PR_MD_SUSPEND_CPU(_PRCPU *cpu) +{ + _PR_MD_SUSPEND_THREAD(cpu->thread); +} + +void +_PR_MD_RESUME_CPU(_PRCPU *cpu) +{ + _PR_MD_RESUME_THREAD(cpu->thread); +} + +void +_PR_MD_SUSPEND_THREAD(PRThread *thread) +{ + if (_PR_IS_NATIVE_THREAD(thread)) { + DWORD previousSuspendCount; + /* XXXMB - SuspendThread() is not a blocking call; how do we + * know when the thread is *REALLY* suspended? + */ + previousSuspendCount = SuspendThread(thread->md.handle); + PR_ASSERT(previousSuspendCount == 0); + } +} + +void +_PR_MD_RESUME_THREAD(PRThread *thread) +{ + if (_PR_IS_NATIVE_THREAD(thread)) { + DWORD previousSuspendCount; + previousSuspendCount = ResumeThread(thread->md.handle); + PR_ASSERT(previousSuspendCount == 1); + } +} + +PRThread* +_MD_CURRENT_THREAD(void) +{ +PRThread *thread; + + thread = _MD_GET_ATTACHED_THREAD(); + + if (NULL == thread) { + thread = _PRI_AttachThread( + PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); + } + PR_ASSERT(thread != NULL); + return thread; +} diff -Nru nspr-4.9.5/nspr/pr/src/md/windows/win32_errors.c nspr-4.10.7/nspr/pr/src/md/windows/win32_errors.c --- nspr-4.9.5/nspr/pr/src/md/windows/win32_errors.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/md/windows/win32_errors.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,533 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prerror.h" +#include "prlog.h" +#include +#include + +/* + * On Win32, we map three kinds of error codes: + * - GetLastError(): for Win32 functions + * - WSAGetLastError(): for Winsock functions + * - errno: for standard C library functions + * + * GetLastError() and WSAGetLastError() return error codes in + * non-overlapping ranges, so their error codes (ERROR_* and + * WSAE*) can be mapped by the same function. On the other hand, + * errno and GetLastError() have overlapping ranges, so we need + * to use a separate function to map errno. + * + * We do not check for WSAEINPROGRESS and WSAEINTR because we do not + * use blocking Winsock 1.1 calls. + * + * Except for the 'socket' call, we do not check for WSAEINITIALISED. + * It is assumed that if Winsock is not initialized, that fact will + * be detected at the time we create new sockets. + */ + +static void _MD_win32_map_default_errno(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case EACCES: + prError = PR_NO_ACCESS_RIGHTS_ERROR; + break; + case ENOENT: + prError = PR_FILE_NOT_FOUND_ERROR; + break; + default: + prError = PR_UNKNOWN_ERROR; + break; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_default_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case ERROR_ACCESS_DENIED: + prError = PR_NO_ACCESS_RIGHTS_ERROR; + break; + case ERROR_ALREADY_EXISTS: + prError = PR_FILE_EXISTS_ERROR; + break; + case ERROR_CALL_NOT_IMPLEMENTED: + prError = PR_NOT_IMPLEMENTED_ERROR; + break; + case ERROR_DISK_CORRUPT: + prError = PR_IO_ERROR; + break; + case ERROR_DISK_FULL: + prError = PR_NO_DEVICE_SPACE_ERROR; + break; + case ERROR_DISK_OPERATION_FAILED: + prError = PR_IO_ERROR; + break; + case ERROR_DRIVE_LOCKED: + prError = PR_FILE_IS_LOCKED_ERROR; + break; + case ERROR_FILENAME_EXCED_RANGE: + prError = PR_NAME_TOO_LONG_ERROR; + break; + case ERROR_FILE_CORRUPT: + prError = PR_IO_ERROR; + break; + case ERROR_FILE_EXISTS: + prError = PR_FILE_EXISTS_ERROR; + break; + case ERROR_FILE_INVALID: + prError = PR_BAD_DESCRIPTOR_ERROR; + break; + case ERROR_FILE_NOT_FOUND: + prError = PR_FILE_NOT_FOUND_ERROR; + break; + case ERROR_HANDLE_DISK_FULL: + prError = PR_NO_DEVICE_SPACE_ERROR; + break; + case ERROR_INVALID_ADDRESS: + prError = PR_ACCESS_FAULT_ERROR; + break; + case ERROR_INVALID_HANDLE: + prError = PR_BAD_DESCRIPTOR_ERROR; + break; + case ERROR_INVALID_NAME: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case ERROR_INVALID_PARAMETER: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case ERROR_INVALID_USER_BUFFER: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case ERROR_LOCKED: + prError = PR_FILE_IS_LOCKED_ERROR; + break; + case ERROR_NETNAME_DELETED: + prError = PR_CONNECT_RESET_ERROR; + break; + case ERROR_NOACCESS: + prError = PR_ACCESS_FAULT_ERROR; + break; + case ERROR_NOT_ENOUGH_MEMORY: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case ERROR_NOT_ENOUGH_QUOTA: + prError = PR_OUT_OF_MEMORY_ERROR; + break; + case ERROR_NOT_READY: + prError = PR_IO_ERROR; + break; + case ERROR_NO_MORE_FILES: + prError = PR_NO_MORE_FILES_ERROR; + break; + case ERROR_OPEN_FAILED: + prError = PR_IO_ERROR; + break; + case ERROR_OPEN_FILES: + prError = PR_IO_ERROR; + break; + case ERROR_OPERATION_ABORTED: + prError = PR_OPERATION_ABORTED_ERROR; + break; + case ERROR_OUTOFMEMORY: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case ERROR_PATH_BUSY: + prError = PR_IO_ERROR; + break; + case ERROR_PATH_NOT_FOUND: + prError = PR_FILE_NOT_FOUND_ERROR; + break; + case ERROR_SEEK_ON_DEVICE: + prError = PR_IO_ERROR; + break; + case ERROR_SHARING_VIOLATION: + prError = PR_FILE_IS_BUSY_ERROR; + break; + case ERROR_STACK_OVERFLOW: + prError = PR_ACCESS_FAULT_ERROR; + break; + case ERROR_TOO_MANY_OPEN_FILES: + prError = PR_SYS_DESC_TABLE_FULL_ERROR; + break; + case ERROR_WRITE_PROTECT: + prError = PR_NO_ACCESS_RIGHTS_ERROR; + break; + case WSAEACCES: + prError = PR_NO_ACCESS_RIGHTS_ERROR; + break; + case WSAEADDRINUSE: + prError = PR_ADDRESS_IN_USE_ERROR; + break; + case WSAEADDRNOTAVAIL: + prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; + break; + case WSAEAFNOSUPPORT: + prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; + break; + case WSAEALREADY: + prError = PR_ALREADY_INITIATED_ERROR; + break; + case WSAEBADF: + prError = PR_BAD_DESCRIPTOR_ERROR; + break; + case WSAECONNABORTED: + prError = PR_CONNECT_ABORTED_ERROR; + break; + case WSAECONNREFUSED: + prError = PR_CONNECT_REFUSED_ERROR; + break; + case WSAECONNRESET: + prError = PR_CONNECT_RESET_ERROR; + break; + case WSAEDESTADDRREQ: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case WSAEFAULT: + prError = PR_ACCESS_FAULT_ERROR; + break; + case WSAEHOSTUNREACH: + prError = PR_HOST_UNREACHABLE_ERROR; + break; + case WSAEINVAL: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case WSAEISCONN: + prError = PR_IS_CONNECTED_ERROR; + break; + case WSAEMFILE: + prError = PR_PROC_DESC_TABLE_FULL_ERROR; + break; + case WSAEMSGSIZE: + prError = PR_BUFFER_OVERFLOW_ERROR; + break; + case WSAENETDOWN: + prError = PR_NETWORK_DOWN_ERROR; + break; + case WSAENETRESET: + prError = PR_CONNECT_ABORTED_ERROR; + break; + case WSAENETUNREACH: + prError = PR_NETWORK_UNREACHABLE_ERROR; + break; + case WSAENOBUFS: + prError = PR_INSUFFICIENT_RESOURCES_ERROR; + break; + case WSAENOPROTOOPT: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case WSAENOTCONN: + prError = PR_NOT_CONNECTED_ERROR; + break; + case WSAENOTSOCK: + prError = PR_NOT_SOCKET_ERROR; + break; + case WSAEOPNOTSUPP: + prError = PR_OPERATION_NOT_SUPPORTED_ERROR; + break; + case WSAEPROTONOSUPPORT: + prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; + break; + case WSAEPROTOTYPE: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case WSAESHUTDOWN: + prError = PR_SOCKET_SHUTDOWN_ERROR; + break; + case WSAESOCKTNOSUPPORT: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + case WSAETIMEDOUT: + prError = PR_CONNECT_ABORTED_ERROR; + break; + case WSAEWOULDBLOCK: + prError = PR_WOULD_BLOCK_ERROR; + break; + default: + prError = PR_UNKNOWN_ERROR; + break; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_opendir_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_closedir_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_unix_readdir_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_delete_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +/* The error code for stat() is in errno. */ +void _MD_win32_map_stat_error(PRInt32 err) +{ + _MD_win32_map_default_errno(err); +} + +void _MD_win32_map_fstat_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_rename_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +/* The error code for access() is in errno. */ +void _MD_win32_map_access_error(PRInt32 err) +{ + _MD_win32_map_default_errno(err); +} + +void _MD_win32_map_mkdir_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_rmdir_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_read_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_transmitfile_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_write_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_lseek_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_fsync_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +/* + * For both CloseHandle() and closesocket(). + */ +void _MD_win32_map_close_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_socket_error(PRInt32 err) +{ + PR_ASSERT(err != WSANOTINITIALISED); + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_recv_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_recvfrom_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_send_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case WSAEMSGSIZE: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + default: + _MD_win32_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_sendto_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case WSAEMSGSIZE: + prError = PR_INVALID_ARGUMENT_ERROR; + break; + default: + _MD_win32_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_accept_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case WSAEOPNOTSUPP: + prError = PR_NOT_TCP_SOCKET_ERROR; + break; + case WSAEINVAL: + prError = PR_INVALID_STATE_ERROR; + break; + default: + _MD_win32_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_acceptex_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_connect_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case WSAEWOULDBLOCK: + prError = PR_IN_PROGRESS_ERROR; + break; + case WSAEINVAL: + prError = PR_ALREADY_INITIATED_ERROR; + break; + case WSAETIMEDOUT: + prError = PR_IO_TIMEOUT_ERROR; + break; + default: + _MD_win32_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_bind_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case WSAEINVAL: + prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; + break; + default: + _MD_win32_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_listen_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case WSAEOPNOTSUPP: + prError = PR_NOT_TCP_SOCKET_ERROR; + break; + case WSAEINVAL: + prError = PR_INVALID_STATE_ERROR; + break; + default: + _MD_win32_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_shutdown_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_getsockname_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case WSAEINVAL: + prError = PR_INVALID_STATE_ERROR; + break; + default: + _MD_win32_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_getpeername_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_getsockopt_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_setsockopt_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_open_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +void _MD_win32_map_gethostname_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} + +/* Win32 select() only works on sockets. So in this +** context, WSAENOTSOCK is equivalent to EBADF on Unix. +*/ +void _MD_win32_map_select_error(PRInt32 err) +{ + PRErrorCode prError; + + switch (err) { + case WSAENOTSOCK: + prError = PR_BAD_DESCRIPTOR_ERROR; + break; + default: + _MD_win32_map_default_error(err); + return; + } + PR_SetError(prError, err); +} + +void _MD_win32_map_lockf_error(PRInt32 err) +{ + _MD_win32_map_default_error(err); +} diff -Nru nspr-4.9.5/nspr/pr/src/memory/.cvsignore nspr-4.10.7/nspr/pr/src/memory/.cvsignore --- nspr-4.9.5/nspr/pr/src/memory/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/memory/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/memory/Makefile.in nspr-4.10.7/nspr/pr/src/memory/Makefile.in --- nspr-4.9.5/nspr/pr/src/memory/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/memory/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,29 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CSRCS = prseg.c prshm.c prshma.c + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + + diff -Nru nspr-4.9.5/nspr/pr/src/memory/prseg.c nspr-4.10.7/nspr/pr/src/memory/prseg.c --- nspr-4.9.5/nspr/pr/src/memory/prseg.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/memory/prseg.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#if defined(_PR_PTHREADS) + +/* +** The pthreads version doesn't use these functions. +*/ +void _PR_InitSegs(void) +{ +} + +#else /* _PR_PTHREADS */ + +void _PR_InitSegs(void) +{ + _PR_MD_INIT_SEGS(); +} + +/* +** Allocate a memory segment. The size value is rounded up to the native +** system page size and a page aligned portion of memory is returned. +** This memory is not part of the malloc heap. If "vaddr" is not NULL +** then PR tries to allocate the segment at the desired virtual address. +*/ +PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr) +{ + PRSegment *seg; + + /* calloc the data structure for the segment */ + seg = PR_NEWZAP(PRSegment); + + if (seg) { + size = ((size + _pr_pageSize - 1) >> _pr_pageShift) << _pr_pageShift; + /* + ** Now, allocate the actual segment memory (or map under some OS) + ** The OS specific code decides from where or how to allocate memory. + */ + if (_PR_MD_ALLOC_SEGMENT(seg, size, vaddr) != PR_SUCCESS) { + PR_DELETE(seg); + return NULL; + } + } + + return seg; +} + +/* +** Free a memory segment. +*/ +void _PR_DestroySegment(PRSegment *seg) +{ + _PR_MD_FREE_SEGMENT(seg); + PR_DELETE(seg); +} + +#endif /* _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/memory/prshma.c nspr-4.10.7/nspr/pr/src/memory/prshma.c --- nspr-4.9.5/nspr/pr/src/memory/prshma.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/memory/prshma.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** prshma.h -- NSPR Anonymous Shared Memory +** +** +*/ + +#include "primpl.h" + +extern PRLogModuleInfo *_pr_shma_lm; + +#if defined(XP_UNIX) +/* defined in pr/src/md/unix/uxshm.c */ +#elif defined(WIN32) +/* defined in pr/src/md/windows/w32shm.c */ +#else +extern PRFileMap * _PR_MD_OPEN_ANON_FILE_MAP( const char *dirName, PRSize size, PRFileMapProtect prot ) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} +extern PRStatus _PR_MD_EXPORT_FILE_MAP_AS_STRING(PRFileMap *fm, PRSize bufSize, char *buf) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} +extern PRFileMap * _PR_MD_IMPORT_FILE_MAP_FROM_STRING(const char *fmstring) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} +#endif + +/* +** PR_OpenAnonFileMap() -- Creates an anonymous file-mapped shared memory +** +*/ +PR_IMPLEMENT(PRFileMap*) +PR_OpenAnonFileMap( + const char *dirName, + PRSize size, + PRFileMapProtect prot +) +{ + return(_PR_MD_OPEN_ANON_FILE_MAP( dirName, size, prot )); +} /* end PR_OpenAnonFileMap() */ + +/* +** PR_ProcessAttrSetInheritableFileMap() -- Prepare FileMap for export +** to my children processes via PR_CreateProcess() +** +** +*/ +PR_IMPLEMENT( PRStatus) +PR_ProcessAttrSetInheritableFileMap( + PRProcessAttr *attr, + PRFileMap *fm, + const char *shmname +) +{ + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return( PR_FAILURE); +} /* end PR_ProcessAttrSetInheritableFileMap() */ + +/* +** PR_GetInheritedFileMap() -- Import a PRFileMap previously exported +** by my parent process via PR_CreateProcess() +** +*/ +PR_IMPLEMENT( PRFileMap *) +PR_GetInheritedFileMap( + const char *shmname +) +{ + PRFileMap *fm = NULL; + PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); + return( fm ); +} /* end PR_GetInhteritedFileMap() */ + +/* +** PR_ExportFileMapAsString() -- Creates a string identifying a PRFileMap +** +*/ +PR_IMPLEMENT( PRStatus ) +PR_ExportFileMapAsString( + PRFileMap *fm, + PRSize bufSize, + char *buf +) +{ + return( _PR_MD_EXPORT_FILE_MAP_AS_STRING( fm, bufSize, buf )); +} /* end PR_ExportFileMapAsString() */ + +/* +** PR_ImportFileMapFromString() -- Creates a PRFileMap from the identifying string +** +** +*/ +PR_IMPLEMENT( PRFileMap * ) +PR_ImportFileMapFromString( + const char *fmstring +) +{ + return( _PR_MD_IMPORT_FILE_MAP_FROM_STRING(fmstring)); +} /* end PR_ImportFileMapFromString() */ +/* end prshma.c */ diff -Nru nspr-4.9.5/nspr/pr/src/memory/prshm.c nspr-4.10.7/nspr/pr/src/memory/prshm.c --- nspr-4.9.5/nspr/pr/src/memory/prshm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/memory/prshm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** prshm.c -- NSPR Named Shared Memory +** +** lth. Jul-1999. +*/ +#include +#include "primpl.h" + +extern PRLogModuleInfo *_pr_shm_lm; + + +#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY +/* SysV implementation is in pr/src/md/unix/uxshm.c */ +#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY +/* Posix implementation is in pr/src/md/unix/uxshm.c */ +#elif defined PR_HAVE_WIN32_NAMED_SHARED_MEMORY +/* Win32 implementation is in pr/src/md/windows/w32shm.c */ +#else +/* +** there is no named_shared_memory +*/ +extern PRSharedMemory* _MD_OpenSharedMemory( const char *name, PRSize size, PRIntn flags, PRIntn mode ) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +extern PRStatus _MD_DeleteSharedMemory( const char *name ) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} +#endif /* HAVE_SYSV_NAMED_SHARED_MEMORY */ + +/* +** FUNCTION: PR_OpenSharedMemory() +** +*/ +PR_IMPLEMENT( PRSharedMemory * ) + PR_OpenSharedMemory( + const char *name, + PRSize size, + PRIntn flags, + PRIntn mode +) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + return( _PR_MD_OPEN_SHARED_MEMORY( name, size, flags, mode )); +} /* end PR_OpenSharedMemory() */ + +/* +** FUNCTION: PR_AttachSharedMemory() +** +*/ +PR_IMPLEMENT( void * ) + PR_AttachSharedMemory( + PRSharedMemory *shm, + PRIntn flags +) +{ + return( _PR_MD_ATTACH_SHARED_MEMORY( shm, flags )); +} /* end PR_AttachSharedMemory() */ + +/* +** FUNCTION: PR_DetachSharedMemory() +** +*/ +PR_IMPLEMENT( PRStatus ) + PR_DetachSharedMemory( + PRSharedMemory *shm, + void *addr +) +{ + return( _PR_MD_DETACH_SHARED_MEMORY( shm, addr )); +} /* end PR_DetachSharedMemory() */ + +/* +** FUNCTION: PR_CloseSharedMemory() +** +*/ +PR_IMPLEMENT( PRStatus ) + PR_CloseSharedMemory( + PRSharedMemory *shm +) +{ + return( _PR_MD_CLOSE_SHARED_MEMORY( shm )); +} /* end PR_CloseSharedMemory() */ + +/* +** FUNCTION: PR_DeleteSharedMemory() +** +*/ +PR_EXTERN( PRStatus ) + PR_DeleteSharedMemory( + const char *name +) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + return(_PR_MD_DELETE_SHARED_MEMORY( name )); +} /* end PR_DestroySharedMemory() */ +/* end prshm.c */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/compile-et.pl nspr-4.10.7/nspr/pr/src/misc/compile-et.pl --- nspr-4.9.5/nspr/pr/src/misc/compile-et.pl 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/compile-et.pl 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,108 @@ +#!/usr/bin/perl + +# usage: compile-et input.et + +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +sub header +{ + local($filename, $comment) = @_; + +< 0x7fffff); + $base*256; +} + +sub code { + local($macro, $text) = @_; + $code = $table_base + $table_item_count; + + print H "\n"; + print H "/* ", $text, " */\n"; + printf H "#define %-40s (%dL)\n", $macro, $code; + + print C "\t{\"", $macro, "\", \"", $text, "\"},\n"; + + print PROPERTIES $macro, "=", $text, "\n"; + + $table_item_count++; +} + + +$filename = $ARGV[0]; +open(INPUT, "< $filename") || die "Can't read $filename: $!\n"; + +$base = "$filename"; +$base =~ s/\.et$//; +$base =~ s#.*/##; + +open(H, "> ${base}.h") || die "Can't write ${base}.h\n"; +open(C, "> ${base}.c") || die "Can't write ${base}.c\n"; +open(PROPERTIES, "> ${base}.properties") || die "Can't write ${base}.properties\n"; + +print H "/*\n", &header("${base}.h", " *"), " */\n"; +print C "/*\n", &header("${base}.c", " *"), " */\n"; +print PROPERTIES &header("${base}.properties", "#"); + +$skipone = 0; + +while ($_ = ) { + next if /^#/; + + if (/^[ \t]*(error_table|et)[ \t]+([a-zA-Z][a-zA-Z0-9_]+) *(-?[0-9]*)/) { + $table_name = $2; + if ($3) { + $table_base = $3; + } + else { + $table_base = &table_base($table_name); + } + $table_item_count = 0; + + print C "#include \"prerror.h\"\n"; + print C "static const struct PRErrorMessage text[] = {\n"; + } + elsif (/^[ \t]*(error_code|ec)[ \t]+([A-Z_0-9]+),[ \t]*$/) { + $skipone = 1; + $macro = $2; + } + elsif (/^[ \t]*(error_code|ec)[ \t]+([A-Z_0-9]+),[ \t]*"(.*)"[ \t]*$/) { + &code($2, $3); + } + elsif ($skipone && /^[ \t]*"(.*)"[ \t]*$/) { + &code($macro, $1); + } +} + +print H "\n"; +print H "extern void ", $table_name, "_InitializePRErrorTable","(void);\n"; +printf H "#define ERROR_TABLE_BASE_%s (%dL)\n", $table_name, $table_base; + +print C "\t{0, 0}\n"; +print C "};\n\n"; +printf C "static const struct PRErrorTable et = { text, \"%s\", %dL, %d };\n", + $base, $table_base, $table_item_count; +print C "\n"; +print C "void ", $table_name, "_InitializePRErrorTable", "(void) {\n"; +print C " PR_ErrorInstallTable(&et);\n"; +print C "}\n"; + +0; diff -Nru nspr-4.9.5/nspr/pr/src/misc/.cvsignore nspr-4.10.7/nspr/pr/src/misc/.cvsignore --- nspr-4.9.5/nspr/pr/src/misc/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/misc/dtoa.c nspr-4.10.7/nspr/pr/src/misc/dtoa.c --- nspr-4.9.5/nspr/pr/src/misc/dtoa.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/dtoa.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,4356 @@ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. This will cause dtoa modes 4 and 5 to be + * treated the same as modes 2 and 3 for some inputs. + * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS + * is also #defined, fegetround() will be queried for the rounding mode. + * Note that both FLT_ROUNDS and fegetround() are specified by the C99 + * standard (and are specified to be consistent, with fesetround() + * affecting the value of FLT_ROUNDS), but that some (Linux) systems + * do not work correctly in this regard, so using fegetround() is more + * portable than using FLT_ROUNDS directly. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and Honor_FLT_ROUNDS is not #defined. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic + * that rounds toward +Infinity. + * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased + * rounding when the underlying floating-point arithmetic uses + * unbiased rounding. This prevent using ordinary floating-point + * arithmetic when the result could be computed with one rounding error. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a dtoa call after a dtoa return in + * mode 3 with thousands of digits requested.) + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. The longest string dtoa can return is about 751 bytes + * long. For conversions by strtod of strings of 800 digits and + * all dtoa conversions in single-threaded executions with 8-byte + * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte + * pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK + * #defined automatically on IEEE systems. On such systems, + * when INFNAN_CHECK is #defined, strtod checks + * for Infinity and NaN (case insensitively). On some systems + * (e.g., some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtod also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the 52 fraction bits of the resulting NaN; if there are two + * or more strings of hex digits, the first is for the high 20 bits, + * the second and subsequent for the low 32 bits, with intervening + * white space ignored; but if this results in none of the 52 + * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 + * and NAN_WORD1 are used instead. + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that + * avoids underflows on inputs whose result does not underflow. + * If you #define NO_IEEE_Scale on a machine that uses IEEE-format + * floating-point numbers and flushes underflows to zero rather + * than implementing gradual underflow, then you must also #define + * Sudden_Underflow. + * #define USE_LOCALE to use the current locale's decimal_point value. + * #define SET_INEXACT if IEEE arithmetic is being used and extra + * computation should be done to set the inexact flag when the + * result is inexact and avoid setting inexact when the result + * is exact. In this case, dtoa.c must be compiled in + * an environment, perhaps provided by #include "dtoa.c" in a + * suitable wrapper, that defines two functions, + * int get_inexact(void); + * void clear_inexact(void); + * such that get_inexact() returns a nonzero value if the + * inexact bit is already set, and clear_inexact() sets the + * inexact bit to 0. When SET_INEXACT is #defined, strtod + * also does extra computations to set the underflow and overflow + * flags when appropriate (i.e., when the result is tiny and + * inexact or when it is a numeric value rounded to +-infinity). + * #define NO_ERRNO if strtod should not assign errno = ERANGE when + * the result overflows to +-Infinity or underflows to 0. + * #define NO_HEX_FP to omit recognition of hexadecimal floating-point + * values by strtod. + * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now) + * to disable logic for "fast" testing of very long input strings + * to strtod. This testing proceeds by initially truncating the + * input string, then if necessary comparing the whole string with + * a decimal expansion to decide close cases. This logic is only + * used for input more than STRTOD_DIGLIM digits long (default 40). + */ + +#ifndef Long +#define Long long +#endif +#ifndef ULong +typedef unsigned Long ULong; +#endif + +#ifdef DEBUG +#include "stdio.h" +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#include "stdlib.h" +#include "string.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + +#ifdef Honor_FLT_ROUNDS +#ifndef Trust_FLT_ROUNDS +#include +#endif +#endif + +#ifdef MALLOC +#ifdef KR_headers +extern char *MALLOC(); +#else +extern void *MALLOC(size_t); +#endif +#else +#define MALLOC malloc +#endif + +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_MC68k +#define IEEE_Arith +#endif +#ifdef IEEE_8087 +#define IEEE_Arith +#endif + +#ifdef IEEE_Arith +#ifndef NO_INFNAN_CHECK +#undef INFNAN_CHECK +#define INFNAN_CHECK +#endif +#else +#undef INFNAN_CHECK +#define NO_STRTOD_BIGCOMP +#endif + +#include "errno.h" + +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#endif /*IEEE_Arith*/ + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include "float.h" +#endif /* Bad_float_h */ + +#ifndef __MATH_H__ +#include "math.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CONST +#ifdef KR_headers +#define CONST /* blank */ +#else +#define CONST const +#endif +#endif + +#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef IEEE_8087 +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] +#else +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] +#endif +#define dval(x) (x)->d + +#ifndef STRTOD_DIGLIM +#define STRTOD_DIGLIM 40 +#endif + +#ifdef DIGLIM_DEBUG +extern int strtod_diglim; +#else +#define strtod_diglim STRTOD_DIGLIM +#endif + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) + defined(VAX) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Nbits 53 +#define Bias 1023 +#define Emax 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#ifdef Flush_Denorm /* debugging option */ +#undef Sudden_Underflow +#endif +#endif + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#ifdef Honor_FLT_ROUNDS +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + +#else /* ifndef IEEE_Arith */ +#undef Check_FLT_ROUNDS +#undef Honor_FLT_ROUNDS +#undef SET_INEXACT +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Nbits 56 +#define Bias 65 +#define Emax 248 +#define Emin (-260) +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Nbits 56 +#define Bias 129 +#define Emax 126 +#define Emin (-129) +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#else +#ifdef ROUND_BIASED_without_Round_Up +#undef ROUND_BIASED +#define ROUND_BIASED +#endif +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +#ifdef KR_headers +extern double rnd_prod(), rnd_quot(); +#else +extern double rnd_prod(double, double), rnd_quot(double, double); +#endif +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Pack_32 +#define Pack_32 +#endif + +typedef struct BCinfo BCinfo; + struct +BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; }; + +#ifdef KR_headers +#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) +#else +#define FFFFFFFF 0xffffffffUL +#endif + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#ifndef MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ +#endif + +#define Kmax 7 + +#ifdef __cplusplus +extern "C" double strtod(const char *s00, char **se); +extern "C" char *dtoa(double d, int mode, int ndigits, + int *decpt, int *sign, char **rve); +#endif + + struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; + }; + + typedef struct Bigint Bigint; + + static Bigint *freelist[Kmax+1]; + + static Bigint * +Balloc +#ifdef KR_headers + (k) int k; +#else + (int k) +#endif +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + unsigned int len; +#endif + + ACQUIRE_DTOA_LOCK(0); + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ + if (k <= Kmax && (rv = freelist[k])) + freelist[k] = rv->next; + else { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; + } + + static void +Bfree +#ifdef KR_headers + (v) Bigint *v; +#else + (Bigint *v) +#endif +{ + if (v) { + if (v->k > Kmax) +#ifdef FREE + FREE((void*)v); +#else + free((void*)v); +#endif + else { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } + } + } + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ +y->wds*sizeof(Long) + 2*sizeof(int)) + + static Bigint * +multadd +#ifdef KR_headers + (b, m, a) Bigint *b; int m, a; +#else + (Bigint *b, int m, int a) /* multiply by m and add a */ +#endif +{ + int i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; + } + + static Bigint * +s2b +#ifdef KR_headers + (s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9; +#else + (const char *s, int nd0, int nd, ULong y9, int dplen) +#endif +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0'); + while(++i < nd0); + s += dplen; + } + else + s += dplen + 9; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; + } + + static int +hi0bits +#ifdef KR_headers + (x) ULong x; +#else + (ULong x) +#endif +{ + int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; + } + + static int +lo0bits +#ifdef KR_headers + (y) ULong *y; +#else + (ULong *y) +#endif +{ + int k; + ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; + } + + static Bigint * +i2b +#ifdef KR_headers + (i) int i; +#else + (int i) +#endif +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; + } + + static Bigint * +mult +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if ((y = *xb++)) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & FFFFFFFF; + } + while(x < xae); + *xc = carry; + } + } +#else +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if (y = *xb & 0xffff) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if (y = *xb >> 16) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; + } + + static Bigint *p5s; + + static Bigint * +pow5mult +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3)) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if (!(p5 = p5s)) { + /* first time */ +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625); + p5->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p5 = p5s = i2b(625); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p51 = p5->next = mult(p5,p5); + p51->next = 0; +#endif + } + p5 = p51; + } + return b; + } + + static Bigint * +lshift +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z)) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; + } +#endif + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; + } + + static int +cmp +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; + } + + static Bigint * +diff +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; + } + + static double +ulp +#ifdef KR_headers + (x) U *x; +#else + (U *x) +#endif +{ + Long L; + U u; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(&u) = L; + word1(&u) = 0; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(&u) = 0x80000 >> L; + word1(&u) = 0; + } + else { + word0(&u) = 0; + L -= Exp_shift; + word1(&u) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif +#endif + return dval(&u); + } + + static double +b2d +#ifdef KR_headers + (a, e) Bigint *a; int *e; +#else + (Bigint *a, int *e) +#endif +{ + ULong *xa, *xa0, w, y, z; + int k; + U d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(&d) +#define d1 word1(&d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> (32 - k); + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif + ret_d: +#ifdef VAX + word0(&d) = d0 >> 16 | d0 << 16; + word1(&d) = d1 >> 16 | d1 << 16; +#else +#undef d0 +#undef d1 +#endif + return dval(&d); + } + + static Bigint * +d2b +#ifdef KR_headers + (d, e, bits) U *d; int *e, *bits; +#else + (U *d, int *e, int *bits) +#endif +{ + Bigint *b; + int de, k; + ULong *x, y, z; +#ifndef Sudden_Underflow + int i; +#endif +#ifdef VAX + ULong d0, d1; + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ((de = (int)(d0 >> Exp_shift))) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ((y = d1)) { + if ((k = lo0bits(&y))) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + b->wds = (x[1] = z) ? 2 : 1; + } + else { + k = lo0bits(&z); + x[0] = z; +#ifndef Sudden_Underflow + i = +#endif + b->wds = 1; + k += 32; + } +#else + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; + } +#undef d0 +#undef d1 + + static double +ratio +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + U da, db; + int k, ka, kb; + + dval(&da) = b2d(a, &ka); + dval(&db) = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + word0(&da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(&da) *= 1 << k; + } + else { + k = -k; + word0(&db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(&db) *= 1 << k; + } +#else + if (k > 0) + word0(&da) += k*Exp_msk1; + else { + k = -k; + word0(&db) += k*Exp_msk1; + } +#endif + return dval(&da) / dval(&db); + } + + static CONST double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif + }; + + static CONST double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, +#ifdef Avoid_Underflow + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-256 */ +#else + 1e-256 +#endif + }; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +bigtens[] = { 1e16, 1e32 }; +static CONST double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +#undef Need_Hexdig +#ifdef INFNAN_CHECK +#ifndef No_Hex_NaN +#define Need_Hexdig +#endif +#endif + +#ifndef Need_Hexdig +#ifndef NO_HEX_FP +#define Need_Hexdig +#endif +#endif + +#ifdef Need_Hexdig /*{*/ +static unsigned char hexdig[256]; + + static void +#ifdef KR_headers +htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; +#else +htinit(unsigned char *h, unsigned char *s, int inc) +#endif +{ + int i, j; + for(i = 0; (j = s[i]) !=0; i++) + h[j] = i + inc; + } + + static void +#ifdef KR_headers +hexdig_init() +#else +hexdig_init(void) +#endif +{ +#define USC (unsigned char *) + htinit(hexdig, USC "0123456789", 0x10); + htinit(hexdig, USC "abcdef", 0x10 + 10); + htinit(hexdig, USC "ABCDEF", 0x10 + 10); + } +#endif /* } Need_Hexdig */ + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + + static int +match +#ifdef KR_headers + (sp, t) char **sp, *t; +#else + (const char **sp, const char *t) +#endif +{ + int c, d; + CONST char *s = *sp; + + while((d = *t++)) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; + } + +#ifndef No_Hex_NaN + static void +hexnan +#ifdef KR_headers + (rvp, sp) U *rvp; CONST char **sp; +#else + (U *rvp, const char **sp) +#endif +{ + ULong c, x[2]; + CONST char *s; + int c1, havedig, udx0, xshift; + + if (!hexdig['0']) + hexdig_init(); + x[0] = x[1] = 0; + havedig = xshift = 0; + udx0 = 1; + s = *sp; + /* allow optional initial 0x or 0X */ + while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) + s += 2; + while((c = *(CONST unsigned char*)++s)) { + if ((c1 = hexdig[c])) + c = c1 & 0xf; + else if (c <= ' ') { + if (udx0 && havedig) { + udx0 = 0; + xshift = 1; + } + continue; + } +#ifdef GDTOA_NON_PEDANTIC_NANCHECK + else if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + else + return; /* invalid form: don't change *sp */ +#else + else { + do { + if (/*(*/ c == ')') { + *sp = s + 1; + break; + } + } while((c = *++s)); + break; + } +#endif + havedig = 1; + if (xshift) { + xshift = 0; + x[0] = x[1]; + x[1] = 0; + } + if (udx0) + x[0] = (x[0] << 4) | (x[1] >> 28); + x[1] = (x[1] << 4) | c; + } + if ((x[0] &= 0xfffff) || x[1]) { + word0(rvp) = Exp_mask | x[0]; + word1(rvp) = x[1]; + } + } +#endif /*No_Hex_NaN*/ +#endif /* INFNAN_CHECK */ + +#ifdef Pack_32 +#define ULbits 32 +#define kshift 5 +#define kmask 31 +#else +#define ULbits 16 +#define kshift 4 +#define kmask 15 +#endif + +#if !defined(NO_HEX_FP) || defined(Honor_FLT_ROUNDS) /*{*/ + static Bigint * +#ifdef KR_headers +increment(b) Bigint *b; +#else +increment(Bigint *b) +#endif +{ + ULong *x, *xe; + Bigint *b1; + + x = b->x; + xe = x + b->wds; + do { + if (*x < (ULong)0xffffffffL) { + ++*x; + return b; + } + *x++ = 0; + } while(x < xe); + { + if (b->wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1,b); + Bfree(b); + b = b1; + } + b->x[b->wds++] = 1; + } + return b; + } + +#endif /*}*/ + +#ifndef NO_HEX_FP /*{*/ + + static void +#ifdef KR_headers +rshift(b, k) Bigint *b; int k; +#else +rshift(Bigint *b, int k) +#endif +{ + ULong *x, *x1, *xe, y; + int n; + + x = x1 = b->x; + n = k >> kshift; + if (n < b->wds) { + xe = x + b->wds; + x += n; + if (k &= kmask) { + n = 32 - k; + y = *x++ >> k; + while(x < xe) { + *x1++ = (y | (*x << n)) & 0xffffffff; + y = *x++ >> k; + } + if ((*x1 = y) !=0) + x1++; + } + else + while(x < xe) + *x1++ = *x++; + } + if ((b->wds = x1 - b->x) == 0) + b->x[0] = 0; + } + + static ULong +#ifdef KR_headers +any_on(b, k) Bigint *b; int k; +#else +any_on(Bigint *b, int k) +#endif +{ + int n, nwds; + ULong *x, *x0, x1, x2; + + x = b->x; + nwds = b->wds; + n = k >> kshift; + if (n > nwds) + n = nwds; + else if (n < nwds && (k &= kmask)) { + x1 = x2 = x[n]; + x1 >>= k; + x1 <<= k; + if (x1 != x2) + return 1; + } + x0 = x; + x += n; + while(x > x0) + if (*--x) + return 1; + return 0; + } + +enum { /* rounding values: same as FLT_ROUNDS */ + Round_zero = 0, + Round_near = 1, + Round_up = 2, + Round_down = 3 + }; + + void +#ifdef KR_headers +gethex(sp, rvp, rounding, sign) + CONST char **sp; U *rvp; int rounding, sign; +#else +gethex( CONST char **sp, U *rvp, int rounding, int sign) +#endif +{ + Bigint *b; + CONST unsigned char *decpt, *s0, *s, *s1; + Long e, e1; + ULong L, lostbits, *x; + int big, denorm, esign, havedig, k, n, nbits, up, zret; +#ifdef IBM + int j; +#endif + enum { +#ifdef IEEE_Arith /*{{*/ + emax = 0x7fe - Bias - P + 1, + emin = Emin - P + 1 +#else /*}{*/ + emin = Emin - P, +#ifdef VAX + emax = 0x7ff - Bias - P + 1 +#endif +#ifdef IBM + emax = 0x7f - Bias - P +#endif +#endif /*}}*/ + }; +#ifdef USE_LOCALE + int i; +#ifdef NO_LOCALE_CACHE + const unsigned char *decimalpoint = (unsigned char*) + localeconv()->decimal_point; +#else + const unsigned char *decimalpoint; + static unsigned char *decimalpoint_cache; + if (!(s0 = decimalpoint_cache)) { + s0 = (unsigned char*)localeconv()->decimal_point; + if ((decimalpoint_cache = (unsigned char*) + MALLOC(strlen((CONST char*)s0) + 1))) { + strcpy((char*)decimalpoint_cache, (CONST char*)s0); + s0 = decimalpoint_cache; + } + } + decimalpoint = s0; +#endif +#endif + + if (!hexdig['0']) + hexdig_init(); + havedig = 0; + s0 = *(CONST unsigned char **)sp + 2; + while(s0[havedig] == '0') + havedig++; + s0 += havedig; + s = s0; + decpt = 0; + zret = 0; + e = 0; + if (hexdig[*s]) + havedig++; + else { + zret = 1; +#ifdef USE_LOCALE + for(i = 0; decimalpoint[i]; ++i) { + if (s[i] != decimalpoint[i]) + goto pcheck; + } + decpt = s += i; +#else + if (*s != '.') + goto pcheck; + decpt = ++s; +#endif + if (!hexdig[*s]) + goto pcheck; + while(*s == '0') + s++; + if (hexdig[*s]) + zret = 0; + havedig = 1; + s0 = s; + } + while(hexdig[*s]) + s++; +#ifdef USE_LOCALE + if (*s == *decimalpoint && !decpt) { + for(i = 1; decimalpoint[i]; ++i) { + if (s[i] != decimalpoint[i]) + goto pcheck; + } + decpt = s += i; +#else + if (*s == '.' && !decpt) { + decpt = ++s; +#endif + while(hexdig[*s]) + s++; + }/*}*/ + if (decpt) + e = -(((Long)(s-decpt)) << 2); + pcheck: + s1 = s; + big = esign = 0; + switch(*s) { + case 'p': + case 'P': + switch(*++s) { + case '-': + esign = 1; + /* no break */ + case '+': + s++; + } + if ((n = hexdig[*s]) == 0 || n > 0x19) { + s = s1; + break; + } + e1 = n - 0x10; + while((n = hexdig[*++s]) !=0 && n <= 0x19) { + if (e1 & 0xf8000000) + big = 1; + e1 = 10*e1 + n - 0x10; + } + if (esign) + e1 = -e1; + e += e1; + } + *sp = (char*)s; + if (!havedig) + *sp = (char*)s0 - 1; + if (zret) + goto retz1; + if (big) { + if (esign) { +#ifdef IEEE_Arith + switch(rounding) { + case Round_up: + if (sign) + break; + goto ret_tiny; + case Round_down: + if (!sign) + break; + goto ret_tiny; + } +#endif + goto retz; +#ifdef IEEE_Arith + ret_tiny: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + word0(rvp) = 0; + word1(rvp) = 1; + return; +#endif /* IEEE_Arith */ + } + switch(rounding) { + case Round_near: + goto ovfl1; + case Round_up: + if (!sign) + goto ovfl1; + goto ret_big; + case Round_down: + if (sign) + goto ovfl1; + goto ret_big; + } + ret_big: + word0(rvp) = Big0; + word1(rvp) = Big1; + return; + } + n = s1 - s0 - 1; + for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) + k++; + b = Balloc(k); + x = b->x; + n = 0; + L = 0; +#ifdef USE_LOCALE + for(i = 0; decimalpoint[i+1]; ++i); +#endif + while(s1 > s0) { +#ifdef USE_LOCALE + if (*--s1 == decimalpoint[i]) { + s1 -= i; + continue; + } +#else + if (*--s1 == '.') + continue; +#endif + if (n == ULbits) { + *x++ = L; + L = 0; + n = 0; + } + L |= (hexdig[*s1] & 0x0f) << n; + n += 4; + } + *x++ = L; + b->wds = n = x - b->x; + n = ULbits*n - hi0bits(L); + nbits = Nbits; + lostbits = 0; + x = b->x; + if (n > nbits) { + n -= nbits; + if (any_on(b,n)) { + lostbits = 1; + k = n - 1; + if (x[k>>kshift] & 1 << (k & kmask)) { + lostbits = 2; + if (k > 0 && any_on(b,k)) + lostbits = 3; + } + } + rshift(b, n); + e += n; + } + else if (n < nbits) { + n = nbits - n; + b = lshift(b, n); + e -= n; + x = b->x; + } + if (e > Emax) { + ovfl: + Bfree(b); + ovfl1: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + word0(rvp) = Exp_mask; + word1(rvp) = 0; + return; + } + denorm = 0; + if (e < emin) { + denorm = 1; + n = emin - e; + if (n >= nbits) { +#ifdef IEEE_Arith /*{*/ + switch (rounding) { + case Round_near: + if (n == nbits && (n < 2 || any_on(b,n-1))) + goto ret_tiny; + break; + case Round_up: + if (!sign) + goto ret_tiny; + break; + case Round_down: + if (sign) + goto ret_tiny; + } +#endif /* } IEEE_Arith */ + Bfree(b); + retz: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + retz1: + rvp->d = 0.; + return; + } + k = n - 1; + if (lostbits) + lostbits = 1; + else if (k > 0) + lostbits = any_on(b,k); + if (x[k>>kshift] & 1 << (k & kmask)) + lostbits |= 2; + nbits -= n; + rshift(b,n); + e = emin; + } + if (lostbits) { + up = 0; + switch(rounding) { + case Round_zero: + break; + case Round_near: + if (lostbits & 2 + && (lostbits & 1) | (x[0] & 1)) + up = 1; + break; + case Round_up: + up = 1 - sign; + break; + case Round_down: + up = sign; + } + if (up) { + k = b->wds; + b = increment(b); + x = b->x; + if (denorm) { +#if 0 + if (nbits == Nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) + denorm = 0; /* not currently used */ +#endif + } + else if (b->wds > k + || ((n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n)) { + rshift(b,1); + if (++e > Emax) + goto ovfl; + } + } + } +#ifdef IEEE_Arith + if (denorm) + word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0; + else + word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20); + word1(rvp) = b->x[0]; +#endif +#ifdef IBM + if ((j = e & 3)) { + k = b->x[0] & ((1 << j) - 1); + rshift(b,j); + if (k) { + switch(rounding) { + case Round_up: + if (!sign) + increment(b); + break; + case Round_down: + if (sign) + increment(b); + break; + case Round_near: + j = 1 << (j-1); + if (k & j && ((k & (j-1)) | lostbits)) + increment(b); + } + } + } + e >>= 2; + word0(rvp) = b->x[1] | ((e + 65 + 13) << 24); + word1(rvp) = b->x[0]; +#endif +#ifdef VAX + /* The next two lines ignore swap of low- and high-order 2 bytes. */ + /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */ + /* word1(rvp) = b->x[0]; */ + word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16); + word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16); +#endif + Bfree(b); + } +#endif /*!NO_HEX_FP}*/ + + static int +#ifdef KR_headers +dshift(b, p2) Bigint *b; int p2; +#else +dshift(Bigint *b, int p2) +#endif +{ + int rv = hi0bits(b->x[b->wds-1]) - 4; + if (p2 > 0) + rv -= p2; + return rv & kmask; + } + + static int +quorem +#ifdef KR_headers + (b, S) Bigint *b, *S; +#else + (Bigint *b, Bigint *S) +#endif +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG +#ifdef NO_STRTOD_BIGCOMP + /*debug*/ if (q > 9) +#else + /* An oversized q is possible when quorem is called from bigcomp and */ + /* the input is near, e.g., twice the smallest denormalized number. */ + /*debug*/ if (q > 15) +#endif + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; + } + +#if defined(Avoid_Underflow) || !defined(NO_STRTOD_BIGCOMP) /*{*/ + static double +sulp +#ifdef KR_headers + (x, bc) U *x; BCinfo *bc; +#else + (U *x, BCinfo *bc) +#endif +{ + U u; + double rv; + int i; + + rv = ulp(x); + if (!bc->scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) + return rv; /* Is there an example where i <= 0 ? */ + word0(&u) = Exp_1 + (i << Exp_shift); + word1(&u) = 0; + return rv * u.d; + } +#endif /*}*/ + +#ifndef NO_STRTOD_BIGCOMP + static void +bigcomp +#ifdef KR_headers + (rv, s0, bc) + U *rv; CONST char *s0; BCinfo *bc; +#else + (U *rv, const char *s0, BCinfo *bc) +#endif +{ + Bigint *b, *d; + int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; + + dsign = bc->dsign; + nd = bc->nd; + nd0 = bc->nd0; + p5 = nd + bc->e0 - 1; + speccase = 0; +#ifndef Sudden_Underflow + if (rv->d == 0.) { /* special case: value near underflow-to-zero */ + /* threshold was rounded to zero */ + b = i2b(1); + p2 = Emin - P + 1; + bbits = 1; +#ifdef Avoid_Underflow + word0(rv) = (P+2) << Exp_shift; +#else + word1(rv) = 1; +#endif + i = 0; +#ifdef Honor_FLT_ROUNDS + if (bc->rounding == 1) +#endif + { + speccase = 1; + --p2; + dsign = 0; + goto have_i; + } + } + else +#endif + b = d2b(rv, &p2, &bbits); +#ifdef Avoid_Underflow + p2 -= bc->scale; +#endif + /* floor(log2(rv)) == bbits - 1 + p2 */ + /* Check for denormal case. */ + i = P - bbits; + if (i > (j = P - Emin - 1 + p2)) { +#ifdef Sudden_Underflow + Bfree(b); + b = i2b(1); + p2 = Emin; + i = P - 1; +#ifdef Avoid_Underflow + word0(rv) = (1 + bc->scale) << Exp_shift; +#else + word0(rv) = Exp_msk1; +#endif + word1(rv) = 0; +#else + i = j; +#endif + } +#ifdef Honor_FLT_ROUNDS + if (bc->rounding != 1) { + if (i > 0) + b = lshift(b, i); + if (dsign) + b = increment(b); + } + else +#endif + { + b = lshift(b, ++i); + b->x[0] |= 1; + } +#ifndef Sudden_Underflow + have_i: +#endif + p2 -= p5 + i; + d = i2b(1); + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + */ + if (p5 > 0) + d = pow5mult(d, p5); + else if (p5 < 0) + b = pow5mult(b, -p5); + if (p2 > 0) { + b2 = p2; + d2 = 0; + } + else { + b2 = 0; + d2 = -p2; + } + i = dshift(d, d2); + if ((b2 += i) > 0) + b = lshift(b, b2); + if ((d2 += i) > 0) + d = lshift(d, d2); + + /* Now b/d = exactly half-way between the two floating-point values */ + /* on either side of the input string. Compute first digit of b/d. */ + + if (!(dig = quorem(b,d))) { + b = multadd(b, 10, 0); /* very unlikely */ + dig = quorem(b,d); + } + + /* Compare b/d with s0 */ + + for(i = 0; i < nd0; ) { + if ((dd = s0[i++] - '0' - dig)) + goto ret; + if (!b->x[0] && b->wds == 1) { + if (i < nd) + dd = 1; + goto ret; + } + b = multadd(b, 10, 0); + dig = quorem(b,d); + } + for(j = bc->dp1; i++ < nd;) { + if ((dd = s0[j++] - '0' - dig)) + goto ret; + if (!b->x[0] && b->wds == 1) { + if (i < nd) + dd = 1; + goto ret; + } + b = multadd(b, 10, 0); + dig = quorem(b,d); + } + if (b->x[0] || b->wds > 1 || dig > 0) + dd = -1; + ret: + Bfree(b); + Bfree(d); +#ifdef Honor_FLT_ROUNDS + if (bc->rounding != 1) { + if (dd < 0) { + if (bc->rounding == 0) { + if (!dsign) + goto retlow1; + } + else if (dsign) + goto rethi1; + } + else if (dd > 0) { + if (bc->rounding == 0) { + if (dsign) + goto rethi1; + goto ret1; + } + if (!dsign) + goto rethi1; + dval(rv) += 2.*sulp(rv,bc); + } + else { + bc->inexact = 0; + if (dsign) + goto rethi1; + } + } + else +#endif + if (speccase) { + if (dd <= 0) + rv->d = 0.; + } + else if (dd < 0) { + if (!dsign) /* does not happen for round-near */ +retlow1: + dval(rv) -= sulp(rv,bc); + } + else if (dd > 0) { + if (dsign) { + rethi1: + dval(rv) += sulp(rv,bc); + } + } + else { + /* Exact half-way case: apply round-even rule. */ + if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) { + i = 1 - j; + if (i <= 31) { + if (word1(rv) & (0x1 << i)) + goto odd; + } + else if (word0(rv) & (0x1 << (i-32))) + goto odd; + } + else if (word1(rv) & 1) { + odd: + if (dsign) + goto rethi1; + goto retlow1; + } + } + +#ifdef Honor_FLT_ROUNDS + ret1: +#endif + return; + } +#endif /* NO_STRTOD_BIGCOMP */ + + double +strtod +#ifdef KR_headers + (s00, se) CONST char *s00; char **se; +#else + (const char *s00, char **se) +#endif +{ + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; + int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1; + Long L; + U aadj2, adj, rv, rv0; + ULong y, z; + BCinfo bc; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef Avoid_Underflow + ULong Lsb, Lsb1; +#endif +#ifdef SET_INEXACT + int oldinexact; +#endif +#ifndef NO_STRTOD_BIGCOMP + int req_bigcomp = 0; +#endif +#ifdef Honor_FLT_ROUNDS /*{*/ +#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ + bc.rounding = Flt_Rounds; +#else /*}{*/ + bc.rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: bc.rounding = 0; break; + case FE_UPWARD: bc.rounding = 2; break; + case FE_DOWNWARD: bc.rounding = 3; + } +#endif /*}}*/ +#endif /*}*/ +#ifdef USE_LOCALE + CONST char *s2; +#endif + + sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0; + dval(&rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP /*{*/ + switch(s[1]) { + case 'x': + case 'X': +#ifdef Honor_FLT_ROUNDS + gethex(&s, &rv, bc.rounding, sign); +#else + gethex(&s, &rv, 1, sign); +#endif + goto ret; + } +#endif /*}*/ + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + bc.dp0 = bc.dp1 = s - s0; + for(s1 = s; s1 > s0 && *--s1 == '0'; ) + ++nz1; +#ifdef USE_LOCALE + s1 = localeconv()->decimal_point; + if (c == *s1) { + c = '.'; + if (*++s1) { + s2 = s; + for(;;) { + if (*++s2 != *s1) { + c = 0; + break; + } + if (!*++s1) { + s = s2; + break; + } + } + } + } +#endif + if (c == '.') { + c = *++s; + bc.dp1 = s - s0; + bc.dplen = bc.dp1 - bc.dp0; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + bc.dp0 = s0 - s; + bc.dp1 = bc.dp0 + bc.dplen; + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = nz1 = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + if (!bc.dplen) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + hexnan(&rv, &s); +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ + ret0: + s = s00; + sign = 0; + } + goto ret; + } + bc.e0 = e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(&rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(&rv) = tens[k - 9] * dval(&rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; +#ifndef ROUND_BIASED_without_Round_Up + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(&rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } +#endif + e -= i; + dval(&rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + word0(&rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if ((word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(&rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(&rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + goto ret; + } +#endif +#endif /* ROUND_BIASED_without_Round_Up */ + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + bc.inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + bc.scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if (bc.rounding >= 2) { + if (sign) + bc.rounding = bc.rounding == 2 ? 0 : 2; + else + if (bc.rounding != 2) + bc.rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15)) + dval(&rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch(bc.rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(&rv) = Big0; + word1(&rv) = Big1; + break; + default: + word0(&rv) = Exp_mask; + word1(&rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(&rv) = Exp_mask; + word1(&rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(&rv0) = 1e300; + dval(&rv0) *= dval(&rv0); +#endif +#else /*IEEE_Arith*/ + word0(&rv) = Big0; + word1(&rv) = Big1; +#endif /*IEEE_Arith*/ + range_err: + if (bd0) { + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + } +#ifndef NO_ERRNO + errno = ERANGE; +#endif + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(&rv) = Big0; + word1(&rv) = Big1; + } + else + word0(&rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15)) + dval(&rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + bc.scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= tinytens[j]; + if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; clear j low bits */ + if (j >= 32) { + if (j > 54) + goto undfl; + word1(&rv) = 0; + if (j >= 53) + word0(&rv) = (P+2)*Exp_msk1; + else + word0(&rv) &= 0xffffffff << (j-32); + } + else + word1(&rv) &= 0xffffffff << j; + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(&rv0) = dval(&rv); + dval(&rv) *= tinytens[j]; + if (!dval(&rv)) { + dval(&rv) = 2.*dval(&rv0); + dval(&rv) *= tinytens[j]; +#endif + if (!dval(&rv)) { + undfl: + dval(&rv) = 0.; + goto range_err; + } +#ifndef Avoid_Underflow + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bc.nd = nd - nz1; +#ifndef NO_STRTOD_BIGCOMP + bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ + /* to silence an erroneous warning about bc.nd0 */ + /* possibly not being initialized. */ + if (nd > strtod_diglim) { + /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ + /* minimum number of decimal digits to distinguish double values */ + /* in IEEE arithmetic. */ + i = j = 18; + if (i > nd0) + j += bc.dplen; + for(;;) { + if (--j < bc.dp1 && j >= bc.dp0) + j = bc.dp0 - 1; + if (s0[j] != '0') + break; + --i; + } + e += nd - i; + nd = i; + if (nd0 > nd) + nd0 = nd; + if (nd < 9) { /* must recompute y */ + y = 0; + for(i = 0; i < nd0; ++i) + y = 10*y + s0[i] - '0'; + for(j = bc.dp1; i < nd; ++i) + y = 10*y + s0[j++] - '0'; + } + } +#endif + bd0 = s2b(s0, nd0, nd, y, bc.dplen); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (bc.rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + Lsb = LSB; + Lsb1 = 0; + j = bbe - bc.scale; + i = j + bbbits - 1; /* logb(rv) */ + j = P + 1 - bbbits; + if (i < Emin) { /* denormal */ + i = Emin - i; + j -= i; + if (i < 32) + Lsb <<= i; + else if (i < 52) + Lsb1 = Lsb << (i-32); + else + Lsb1 = Exp_mask; + } +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += bc.scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + bc.dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifndef NO_STRTOD_BIGCOMP /*{*/ + if (bc.nd > nd && i <= 0) { + if (bc.dsign) { + /* Must use bigcomp(). */ + req_bigcomp = 1; + break; + } +#ifdef Honor_FLT_ROUNDS + if (bc.rounding != 1) { + if (i < 0) { + req_bigcomp = 1; + break; + } + } + else +#endif + i = -1; /* Discarded digits make delta smaller. */ + } +#endif /*}*/ +#ifdef Honor_FLT_ROUNDS /*{*/ + if (bc.rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + bc.inexact = 0; +#endif + break; + } + if (bc.rounding) { + if (bc.dsign) { + adj.d = 1.; + goto apply_adj; + } + } + else if (!bc.dsign) { + adj.d = -1.; + if (!word1(&rv) + && !(word0(&rv) & Frac_mask)) { + y = word0(&rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!bc.scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) + adj.d = -0.5; + } + } + apply_adj: +#ifdef Avoid_Underflow /*{*/ + if (bc.scale && (y = word0(&rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(&adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(&rv) & Exp_mask) <= + P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + dval(&rv) += adj.d*ulp(dval(&rv)); + word0(&rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow}*/ + dval(&rv) += adj.d*ulp(&rv); + } + break; + } + adj.d = ratio(delta, bs); + if (adj.d < 1.) + adj.d = 1.; + if (adj.d <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj.d; + if (y != adj.d) { + if (!((bc.rounding>>1) ^ bc.dsign)) + y++; + adj.d = y; + } + } +#ifdef Avoid_Underflow /*{*/ + if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(&adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + adj.d *= ulp(dval(&rv)); + if (bc.dsign) + dval(&rv) += adj.d; + else + dval(&rv) -= adj.d; + word0(&rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow}*/ + adj.d *= ulp(&rv); + if (bc.dsign) { + if (word0(&rv) == Big0 && word1(&rv) == Big1) + goto ovfl; + dval(&rv) += adj.d; + } + else + dval(&rv) -= adj.d; + goto cont; + } +#endif /*}Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask +#ifdef IEEE_Arith /*{*/ +#ifdef Avoid_Underflow + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(&rv) & Exp_mask) <= Exp_msk1 +#endif +#endif /*}*/ + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + bc.inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + bc.inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (bc.dsign) { + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( +#ifdef Avoid_Underflow + (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + if (word0(&rv) == Big0 && word1(&rv) == Big1) + goto ovfl; + word0(&rv) = (word0(&rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(&rv) = 0; +#ifdef Avoid_Underflow + bc.dsign = 0; +#endif + break; + } + } + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(&rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (bc.scale) { + L = word0(&rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(&rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}}*/ + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else +#ifndef NO_STRTOD_BIGCOMP + if (bc.nd > nd) + goto cont; +#endif + break; +#endif + } +#ifndef ROUND_BIASED +#ifdef Avoid_Underflow + if (Lsb1) { + if (!(word0(&rv) & Lsb1)) + break; + } + else if (!(word1(&rv) & Lsb)) + break; +#else + if (!(word1(&rv) & LSB)) + break; +#endif +#endif + if (bc.dsign) +#ifdef Avoid_Underflow + dval(&rv) += sulp(&rv, &bc); +#else + dval(&rv) += ulp(&rv); +#endif +#ifndef ROUND_BIASED + else { +#ifdef Avoid_Underflow + dval(&rv) -= sulp(&rv, &bc); +#else + dval(&rv) -= ulp(&rv); +#endif +#ifndef Sudden_Underflow + if (!dval(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } +#endif + } +#ifdef Avoid_Underflow + bc.dsign = 1 - bc.dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (bc.dsign) + aadj = aadj1 = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(&rv) == Tiny1 && !word0(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = bc.dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(bc.rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (Flt_Rounds == 0) + aadj1 += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(&rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if ((word0(&rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) + goto ovfl; + word0(&rv) = Big0; + word1(&rv) = Big1; + goto cont; + } + else + word0(&rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (bc.scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) + z = 1; + aadj = z; + aadj1 = bc.dsign ? aadj : -aadj; + } + dval(&aadj2) = aadj1; + word0(&aadj2) += (2*P+1)*Exp_msk1 - y; + aadj1 = dval(&aadj2); + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if (rv.d == 0.) +#ifdef NO_STRTOD_BIGCOMP + goto undfl; +#else + { + if (bc.nd > nd) + bc.dsign = 1; + break; + } +#endif + } + else { + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } +#else +#ifdef Sudden_Underflow + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + dval(&rv0) = dval(&rv); + word0(&rv) += P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; +#ifdef IBM + if ((word0(&rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(&rv0) == Tiny0 + && word1(&rv0) == Tiny1) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; + goto cont; + } + else + word0(&rv) -= P*Exp_msk1; + } + else { + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!bc.dsign) + aadj1 = -aadj1; + } + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(&rv) & Exp_mask; +#ifndef SET_INEXACT + if (bc.nd == nd) { +#ifdef Avoid_Underflow + if (!bc.scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + } +#endif + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); +#ifndef NO_STRTOD_BIGCOMP + if (req_bigcomp) { + bd0 = 0; + bc.e0 += nz1; + bigcomp(&rv, s0, &bc); + y = word0(&rv) & Exp_mask; + if (y == Exp_mask) + goto ovfl; + if (y == 0 && rv.d == 0.) + goto undfl; + } +#endif +#ifdef SET_INEXACT + if (bc.inexact) { + if (!oldinexact) { + word0(&rv0) = Exp_1 + (70 << Exp_shift); + word1(&rv0) = 0; + dval(&rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (bc.scale) { + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ +#ifdef IEEE_Arith + if (!(word0(&rv) & Exp_mask)) +#else + if (word0(&rv) == 0 && word1(&rv) == 0) +#endif + errno = ERANGE; +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (bc.inexact && !(word0(&rv) & Exp_mask)) { + /* set underflow bit */ + dval(&rv0) = 1e-300; + dval(&rv0) *= dval(&rv0); + } +#endif + ret: + if (se) + *se = (char *)s; + return sign ? -dval(&rv) : dval(&rv); + } + +#ifndef MULTIPLE_THREADS + static char *dtoa_result; +#endif + + static char * +#ifdef KR_headers +rv_alloc(i) int i; +#else +rv_alloc(int i) +#endif +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) + k++; + r = (int*)Balloc(k); + *r = k; + return +#ifndef MULTIPLE_THREADS + dtoa_result = +#endif + (char *)(r+1); + } + + static char * +#ifdef KR_headers +nrv_alloc(s, rve, n) char *s, **rve; int n; +#else +nrv_alloc(const char *s, char **rve, int n) +#endif +{ + char *rv, *t; + + t = rv = rv_alloc(n); + while((*t = *s++)) t++; + if (rve) + *rve = t; + return rv; + } + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + + void +#ifdef KR_headers +freedtoa(s) char *s; +#else +freedtoa(char *s) +#endif +{ + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); +#ifndef MULTIPLE_THREADS + if (s == dtoa_result) + dtoa_result = 0; +#endif + } + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + char * +dtoa +#ifdef KR_headers + (dd, mode, ndigits, decpt, sign, rve) + double dd; int mode, ndigits, *decpt, *sign; char **rve; +#else + (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) +#endif +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + U d2, eps, u; + double ds; + char *s, *s0; +#ifndef No_leftright +#ifdef IEEE_Arith + U eps1; +#endif +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS /*{*/ + int Rounding; +#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ + Rounding = Flt_Rounds; +#else /*}{*/ + Rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: Rounding = 0; break; + case FE_UPWARD: Rounding = 2; break; + case FE_DOWNWARD: Rounding = 3; + } +#endif /*}}*/ +#endif /*}*/ + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + u.d = dd; + if (word0(&u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(&u) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(&u) & Exp_mask) == Exp_mask) +#else + if (word0(&u) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + if (!word1(&u) && !(word0(&u) & 0xfffff)) + return nrv_alloc("Infinity", rve, 8); +#endif + return nrv_alloc("NaN", rve, 3); + } +#endif +#ifdef IBM + dval(&u) += 0; /* normalize */ +#endif + if (!dval(&u)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if (Rounding >= 2) { + if (*sign) + Rounding = Rounding == 2 ? 0 : 2; + else + if (Rounding != 2) + Rounding = 0; + } +#endif + + b = d2b(&u, &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { +#endif + dval(&d2) = dval(&u); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; +#ifdef IBM + if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) + dval(&d2) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) + : word1(&u) << (32 - i); + dval(&d2) = x; + word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(&u) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ + switch(mode) { + case 0: + case 1: + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && Rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(&d2) = dval(&u); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(&u) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(&u) /= ds; + } + else if ((j1 = -k)) { + dval(&u) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(&u) *= bigtens[i]; + } + } + if (k_check && dval(&u) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(&u) *= 10.; + ieps++; + } + dval(&eps) = ieps*dval(&u) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(&u) -= 5.; + if (dval(&u) > dval(&eps)) + goto one_digit; + if (dval(&u) < -dval(&eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); +#ifdef IEEE_Arith + if (k0 < 0 && j1 >= 307) { + eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */ + word0(&eps1) -= Exp_msk1 * (Bias+P-1); + dval(&eps1) *= tens[j1 & 0xf]; + for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++) + if (j & 1) + dval(&eps1) *= bigtens[i]; + if (eps.d < eps1.d) + eps.d = eps1.d; + } +#endif + for(i = 0;;) { + L = dval(&u); + dval(&u) -= L; + *s++ = '0' + (int)L; + if (1. - dval(&u) < dval(&eps)) + goto bump_up; + if (dval(&u) < dval(&eps)) + goto ret1; + if (++i >= ilim) + break; + dval(&eps) *= 10.; + dval(&u) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u)); + if (!(dval(&u) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(&u) > 0.5 + dval(&eps)) + goto bump_up; + else if (dval(&u) < 0.5 - dval(&eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(&u) = dval(&d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(&u) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u) / ds); + dval(&u) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(&u) < 0) { + L--; + dval(&u) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(&u)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(Rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(&u) += dval(&u); +#ifdef ROUND_BIASED + if (dval(&u) >= ds) +#else + if (dval(&u) > ds || (dval(&u) == ds && L & 1)) +#endif + { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ((j = b5 - m5)) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && Rounding == 1 +#endif + ) { + if (!word1(&u) && !(word0(&u) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(&u) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ + i = dshift(S, s2); + b2 += i; + m2 += i; + s2 += i; + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(&u) & 1) +#ifdef Honor_FLT_ROUNDS + && Rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(&u) & 1) +#endif + )) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(Rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); +#ifdef ROUND_BIASED + if (j1 >= 0 /*)*/ +#else + if ((j1 > 0 || (j1 == 0 && dig & 1)) +#endif + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!Rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS + keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch(Rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + j = cmp(b, S); +#ifdef ROUND_BIASED + if (j >= 0) +#else + if (j > 0 || (j == 0 && dig & 1)) +#endif + { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { +#ifdef Honor_FLT_ROUNDS + trimzeros: +#endif + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(&u) = Exp_1 + (70 << Exp_shift); + word1(&u) = 0; + dval(&u) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + } +#ifdef __cplusplus +} +#endif diff -Nru nspr-4.9.5/nspr/pr/src/misc/Makefile.in nspr-4.10.7/nspr/pr/src/misc/Makefile.in --- nspr-4.9.5/nspr/pr/src/misc/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,80 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CSRCS = \ + pralarm.c \ + pratom.c \ + prcountr.c \ + prdtoa.c \ + prenv.c \ + prerr.c \ + prerror.c \ + prerrortable.c \ + prinit.c \ + prinrval.c \ + pripc.c \ + prlog2.c \ + prlong.c \ + prnetdb.c \ + praton.c \ + prolock.c \ + prrng.c \ + prsystem.c \ + prtime.c \ + prthinfo.c \ + prtpool.c \ + prtrace.c \ + $(NULL) + +ifndef USE_PTHREADS +CSRCS += \ + pripcsem.c \ + $(NULL) +endif + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +RELEASE_BINS = $(srcdir)/compile-et.pl $(srcdir)/prerr.properties + +include $(topsrcdir)/config/rules.mk + +# Prevent floating point errors caused by MSVC 6.0 Processor Pack +# optimizations (bug 207421). This disables optimizations that +# could change the precision of floating-point calculations for +# this single compilation unit. +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) +$(OBJDIR)/prdtoa.$(OBJ_SUFFIX): prdtoa.c + @$(MAKE_OBJDIR) +ifeq (,$(filter-out 1100 1200 1300 1310,$(MSC_VER))) + $(CC) -Fo$@ -c $(CFLAGS) -Op $(call pr_abspath,$<) +else + $(CC) -Fo$@ -c $(CFLAGS) -fp:precise $(call pr_abspath,$<) +endif +endif + +# +# Generate prerr.h, prerr.c, and prerr.properties from prerr.et. +# +build_prerr: + cd $(srcdir); $(PERL) compile-et.pl prerr.et + +export:: $(TARGETS) + + diff -Nru nspr-4.9.5/nspr/pr/src/misc/pralarm.c nspr-4.10.7/nspr/pr/src/misc/pralarm.c --- nspr-4.9.5/nspr/pr/src/misc/pralarm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/pralarm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,246 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +/**********************************************************************/ +/******************************* PRALARM ******************************/ +/**********************************************************************/ + +#include "obsolete/pralarm.h" + +struct PRAlarmID { /* typedef'd in pralarm.h */ + PRCList list; /* circular list linkage */ + PRAlarm *alarm; /* back pointer to owning alarm */ + PRPeriodicAlarmFn function; /* function to call for notify */ + void *clientData; /* opaque client context */ + PRIntervalTime period; /* the client defined period */ + PRUint32 rate; /* rate of notification */ + + PRUint32 accumulator; /* keeps track of # notifies */ + PRIntervalTime epoch; /* when timer was started */ + PRIntervalTime nextNotify; /* when we'll next do our thing */ + PRIntervalTime lastNotify; /* when we last did our thing */ +}; + +typedef enum {alarm_active, alarm_inactive} _AlarmState; + +struct PRAlarm { /* typedef'd in pralarm.h */ + PRCList timers; /* base of alarm ids list */ + PRLock *lock; /* lock used to protect data */ + PRCondVar *cond; /* condition that used to wait */ + PRThread *notifier; /* thread to deliver notifies */ + PRAlarmID *current; /* current alarm being served */ + _AlarmState state; /* used to delete the alarm */ +}; + +static PRAlarmID *pr_getNextAlarm(PRAlarm *alarm, PRAlarmID *id) +{ +/* + * Puts 'id' back into the sorted list iff it's not NULL. + * Removes the first element from the list and returns it (or NULL). + * List is "assumed" to be short. + * + * NB: Caller is providing locking + */ + PRCList *timer; + PRAlarmID *result = id; + PRIntervalTime now = PR_IntervalNow(); + + if (!PR_CLIST_IS_EMPTY(&alarm->timers)) + { + if (id != NULL) /* have to put this id back in */ + { + PRIntervalTime idDelta = now - id->nextNotify; + timer = alarm->timers.next; + do + { + result = (PRAlarmID*)timer; + if ((PRIntervalTime)(now - result->nextNotify) > idDelta) + { + PR_INSERT_BEFORE(&id->list, &alarm->timers); + break; + } + timer = timer->next; + } while (timer != &alarm->timers); + } + result = (PRAlarmID*)(timer = PR_LIST_HEAD(&alarm->timers)); + PR_REMOVE_LINK(timer); /* remove it from the list */ + } + + return result; +} /* pr_getNextAlarm */ + +static PRIntervalTime pr_PredictNextNotifyTime(PRAlarmID *id) +{ + PRIntervalTime delta; + PRFloat64 baseRate = (PRFloat64)id->period / (PRFloat64)id->rate; + PRFloat64 offsetFromEpoch = (PRFloat64)id->accumulator * baseRate; + + id->accumulator += 1; /* every call advances to next period */ + id->lastNotify = id->nextNotify; /* just keeping track of things */ + id->nextNotify = (PRIntervalTime)(offsetFromEpoch + 0.5); + + delta = id->nextNotify - id->lastNotify; + return delta; +} /* pr_PredictNextNotifyTime */ + +static void PR_CALLBACK pr_alarmNotifier(void *arg) +{ + /* + * This is the root of the notifier thread. There is one such thread + * for each PRAlarm. It may service an arbitrary (though assumed to be + * small) number of alarms using the same thread and structure. It + * continues to run until the alarm is destroyed. + */ + PRAlarmID *id = NULL; + PRAlarm *alarm = (PRAlarm*)arg; + enum {notify, abort, scan} why = scan; + + while (why != abort) + { + PRIntervalTime pause; + + PR_Lock(alarm->lock); + while (why == scan) + { + alarm->current = NULL; /* reset current id */ + if (alarm->state == alarm_inactive) why = abort; /* we're toast */ + else if (why == scan) /* the dominant case */ + { + id = pr_getNextAlarm(alarm, id); /* even if it's the same */ + if (id == NULL) /* there are no alarms set */ + (void)PR_WaitCondVar(alarm->cond, PR_INTERVAL_NO_TIMEOUT); + else + { + pause = id->nextNotify - (PR_IntervalNow() - id->epoch); + if ((PRInt32)pause <= 0) /* is this one's time up? */ + { + why = notify; /* set up to do our thing */ + alarm->current = id; /* id we're about to schedule */ + } + else + (void)PR_WaitCondVar(alarm->cond, pause); /* dally */ + } + } + } + PR_Unlock(alarm->lock); + + if (why == notify) + { + (void)pr_PredictNextNotifyTime(id); + if (!id->function(id, id->clientData, ~pause)) + { + /* + * Notified function decided not to continue. Free + * the alarm id to make sure it doesn't get back on + * the list. + */ + PR_DELETE(id); /* free notifier object */ + id = NULL; /* so it doesn't get back into the list */ + } + why = scan; /* so we can cycle through the loop again */ + } + } + +} /* pr_alarm_notifier */ + +PR_IMPLEMENT(PRAlarm*) PR_CreateAlarm(void) +{ + PRAlarm *alarm = PR_NEWZAP(PRAlarm); + if (alarm != NULL) + { + if ((alarm->lock = PR_NewLock()) == NULL) goto done; + if ((alarm->cond = PR_NewCondVar(alarm->lock)) == NULL) goto done; + alarm->state = alarm_active; + PR_INIT_CLIST(&alarm->timers); + alarm->notifier = PR_CreateThread( + PR_USER_THREAD, pr_alarmNotifier, alarm, + PR_GetThreadPriority(PR_GetCurrentThread()), + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + if (alarm->notifier == NULL) goto done; + } + return alarm; + +done: + if (alarm->cond != NULL) PR_DestroyCondVar(alarm->cond); + if (alarm->lock != NULL) PR_DestroyLock(alarm->lock); + PR_DELETE(alarm); + return NULL; +} /* CreateAlarm */ + +PR_IMPLEMENT(PRStatus) PR_DestroyAlarm(PRAlarm *alarm) +{ + PRStatus rv; + + PR_Lock(alarm->lock); + alarm->state = alarm_inactive; + rv = PR_NotifyCondVar(alarm->cond); + PR_Unlock(alarm->lock); + + if (rv == PR_SUCCESS) + rv = PR_JoinThread(alarm->notifier); + if (rv == PR_SUCCESS) + { + PR_DestroyCondVar(alarm->cond); + PR_DestroyLock(alarm->lock); + PR_DELETE(alarm); + } + return rv; +} /* PR_DestroyAlarm */ + +PR_IMPLEMENT(PRAlarmID*) PR_SetAlarm( + PRAlarm *alarm, PRIntervalTime period, PRUint32 rate, + PRPeriodicAlarmFn function, void *clientData) +{ + /* + * Create a new periodic alarm an existing current structure. + * Set up the context and compute the first notify time (immediate). + * Link the new ID into the head of the list (since it's notifying + * immediately). + */ + + PRAlarmID *id = PR_NEWZAP(PRAlarmID); + + if (!id) + return NULL; + + id->alarm = alarm; + PR_INIT_CLIST(&id->list); + id->function = function; + id->clientData = clientData; + id->period = period; + id->rate = rate; + id->epoch = id->nextNotify = PR_IntervalNow(); + (void)pr_PredictNextNotifyTime(id); + + PR_Lock(alarm->lock); + PR_INSERT_BEFORE(&id->list, &alarm->timers); + PR_NotifyCondVar(alarm->cond); + PR_Unlock(alarm->lock); + + return id; +} /* PR_SetAlarm */ + +PR_IMPLEMENT(PRStatus) PR_ResetAlarm( + PRAlarmID *id, PRIntervalTime period, PRUint32 rate) +{ + /* + * Can only be called from within the notify routine. Doesn't + * need locking because it can only be called from within the + * notify routine. + */ + if (id != id->alarm->current) + return PR_FAILURE; + id->period = period; + id->rate = rate; + id->accumulator = 1; + id->epoch = PR_IntervalNow(); + (void)pr_PredictNextNotifyTime(id); + return PR_SUCCESS; +} /* PR_ResetAlarm */ + + + diff -Nru nspr-4.9.5/nspr/pr/src/misc/pratom.c nspr-4.10.7/nspr/pr/src/misc/pratom.c --- nspr-4.9.5/nspr/pr/src/misc/pratom.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/pratom.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,379 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** PR Atomic operations +*/ + + +#include "pratom.h" +#include "primpl.h" + +#include + +/* + * The following is a fallback implementation that emulates + * atomic operations for platforms without atomic operations. + * If a platform has atomic operations, it should define the + * macro _PR_HAVE_ATOMIC_OPS, and the following will not be + * compiled in. + */ + +#if !defined(_PR_HAVE_ATOMIC_OPS) + +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) +/* + * PR_AtomicDecrement() is used in NSPR's thread-specific data + * destructor. Because thread-specific data destructors may be + * invoked after a PR_Cleanup() call, we need an implementation + * of the atomic routines that doesn't need NSPR to be initialized. + */ + +/* + * We use a set of locks for all the emulated atomic operations. + * By hashing on the address of the integer to be locked the + * contention between multiple threads should be lessened. + * + * The number of atomic locks can be set by the environment variable + * NSPR_ATOMIC_HASH_LOCKS + */ + +/* + * lock counts should be a power of 2 + */ +#define DEFAULT_ATOMIC_LOCKS 16 /* should be in sync with the number of initializers + below */ +#define MAX_ATOMIC_LOCKS (4 * 1024) + +static pthread_mutex_t static_atomic_locks[DEFAULT_ATOMIC_LOCKS] = { + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }; + +#ifdef DEBUG +static PRInt32 static_hash_lock_counts[DEFAULT_ATOMIC_LOCKS]; +static PRInt32 *hash_lock_counts = static_hash_lock_counts; +#endif + +static PRUint32 num_atomic_locks = DEFAULT_ATOMIC_LOCKS; +static pthread_mutex_t *atomic_locks = static_atomic_locks; +static PRUint32 atomic_hash_mask = DEFAULT_ATOMIC_LOCKS - 1; + +#define _PR_HASH_FOR_LOCK(ptr) \ + ((PRUint32) (((PRUptrdiff) (ptr) >> 2) ^ \ + ((PRUptrdiff) (ptr) >> 8)) & \ + atomic_hash_mask) + +void _PR_MD_INIT_ATOMIC() +{ +char *eval; +int index; + + + PR_ASSERT(PR_FloorLog2(MAX_ATOMIC_LOCKS) == + PR_CeilingLog2(MAX_ATOMIC_LOCKS)); + + PR_ASSERT(PR_FloorLog2(DEFAULT_ATOMIC_LOCKS) == + PR_CeilingLog2(DEFAULT_ATOMIC_LOCKS)); + + if (((eval = getenv("NSPR_ATOMIC_HASH_LOCKS")) != NULL) && + ((num_atomic_locks = atoi(eval)) != DEFAULT_ATOMIC_LOCKS)) { + + if (num_atomic_locks > MAX_ATOMIC_LOCKS) + num_atomic_locks = MAX_ATOMIC_LOCKS; + else if (num_atomic_locks < 1) + num_atomic_locks = 1; + else { + num_atomic_locks = PR_FloorLog2(num_atomic_locks); + num_atomic_locks = 1L << num_atomic_locks; + } + atomic_locks = (pthread_mutex_t *) PR_Malloc(sizeof(pthread_mutex_t) * + num_atomic_locks); + if (atomic_locks) { + for (index = 0; index < num_atomic_locks; index++) { + if (pthread_mutex_init(&atomic_locks[index], NULL)) { + PR_DELETE(atomic_locks); + atomic_locks = NULL; + break; + } + } + } +#ifdef DEBUG + if (atomic_locks) { + hash_lock_counts = PR_CALLOC(num_atomic_locks * sizeof(PRInt32)); + if (hash_lock_counts == NULL) { + PR_DELETE(atomic_locks); + atomic_locks = NULL; + } + } +#endif + if (atomic_locks == NULL) { + /* + * Use statically allocated locks + */ + atomic_locks = static_atomic_locks; + num_atomic_locks = DEFAULT_ATOMIC_LOCKS; + #ifdef DEBUG + hash_lock_counts = static_hash_lock_counts; + #endif + } + atomic_hash_mask = num_atomic_locks - 1; + } + PR_ASSERT(PR_FloorLog2(num_atomic_locks) == + PR_CeilingLog2(num_atomic_locks)); +} + +PRInt32 +_PR_MD_ATOMIC_INCREMENT(PRInt32 *val) +{ + PRInt32 rv; + PRInt32 idx = _PR_HASH_FOR_LOCK(val); + + pthread_mutex_lock(&atomic_locks[idx]); + rv = ++(*val); +#ifdef DEBUG + hash_lock_counts[idx]++; +#endif + pthread_mutex_unlock(&atomic_locks[idx]); + return rv; +} + +PRInt32 +_PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) +{ + PRInt32 rv; + PRInt32 idx = _PR_HASH_FOR_LOCK(ptr); + + pthread_mutex_lock(&atomic_locks[idx]); + rv = ((*ptr) += val); +#ifdef DEBUG + hash_lock_counts[idx]++; +#endif + pthread_mutex_unlock(&atomic_locks[idx]); + return rv; +} + +PRInt32 +_PR_MD_ATOMIC_DECREMENT(PRInt32 *val) +{ + PRInt32 rv; + PRInt32 idx = _PR_HASH_FOR_LOCK(val); + + pthread_mutex_lock(&atomic_locks[idx]); + rv = --(*val); +#ifdef DEBUG + hash_lock_counts[idx]++; +#endif + pthread_mutex_unlock(&atomic_locks[idx]); + return rv; +} + +PRInt32 +_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) +{ + PRInt32 rv; + PRInt32 idx = _PR_HASH_FOR_LOCK(val); + + pthread_mutex_lock(&atomic_locks[idx]); + rv = *val; + *val = newval; +#ifdef DEBUG + hash_lock_counts[idx]++; +#endif + pthread_mutex_unlock(&atomic_locks[idx]); + return rv; +} +#else /* _PR_PTHREADS && !_PR_DCETHREADS */ +/* + * We use a single lock for all the emulated atomic operations. + * The lock contention should be acceptable. + */ +static PRLock *atomic_lock = NULL; +void _PR_MD_INIT_ATOMIC(void) +{ + if (atomic_lock == NULL) { + atomic_lock = PR_NewLock(); + } +} + +PRInt32 +_PR_MD_ATOMIC_INCREMENT(PRInt32 *val) +{ + PRInt32 rv; + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + PR_Lock(atomic_lock); + rv = ++(*val); + PR_Unlock(atomic_lock); + return rv; +} + +PRInt32 +_PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val) +{ + PRInt32 rv; + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + PR_Lock(atomic_lock); + rv = ((*ptr) += val); + PR_Unlock(atomic_lock); + return rv; +} + +PRInt32 +_PR_MD_ATOMIC_DECREMENT(PRInt32 *val) +{ + PRInt32 rv; + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + PR_Lock(atomic_lock); + rv = --(*val); + PR_Unlock(atomic_lock); + return rv; +} + +PRInt32 +_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval) +{ + PRInt32 rv; + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + PR_Lock(atomic_lock); + rv = *val; + *val = newval; + PR_Unlock(atomic_lock); + return rv; +} +#endif /* _PR_PTHREADS && !_PR_DCETHREADS */ + +#endif /* !_PR_HAVE_ATOMIC_OPS */ + +void _PR_InitAtomic(void) +{ + _PR_MD_INIT_ATOMIC(); +} + +PR_IMPLEMENT(PRInt32) +PR_AtomicIncrement(PRInt32 *val) +{ + return _PR_MD_ATOMIC_INCREMENT(val); +} + +PR_IMPLEMENT(PRInt32) +PR_AtomicDecrement(PRInt32 *val) +{ + return _PR_MD_ATOMIC_DECREMENT(val); +} + +PR_IMPLEMENT(PRInt32) +PR_AtomicSet(PRInt32 *val, PRInt32 newval) +{ + return _PR_MD_ATOMIC_SET(val, newval); +} + +PR_IMPLEMENT(PRInt32) +PR_AtomicAdd(PRInt32 *ptr, PRInt32 val) +{ + return _PR_MD_ATOMIC_ADD(ptr, val); +} +/* + * For platforms, which don't support the CAS (compare-and-swap) instruction + * (or an equivalent), the stack operations are implemented by use of PRLock + */ + +PR_IMPLEMENT(PRStack *) +PR_CreateStack(const char *stack_name) +{ +PRStack *stack; + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + + if ((stack = PR_NEW(PRStack)) == NULL) { + return NULL; + } + if (stack_name) { + stack->prstk_name = (char *) PR_Malloc(strlen(stack_name) + 1); + if (stack->prstk_name == NULL) { + PR_DELETE(stack); + return NULL; + } + strcpy(stack->prstk_name, stack_name); + } else + stack->prstk_name = NULL; + +#ifndef _PR_HAVE_ATOMIC_CAS + stack->prstk_lock = PR_NewLock(); + if (stack->prstk_lock == NULL) { + PR_Free(stack->prstk_name); + PR_DELETE(stack); + return NULL; + } +#endif /* !_PR_HAVE_ATOMIC_CAS */ + + stack->prstk_head.prstk_elem_next = NULL; + + return stack; +} + +PR_IMPLEMENT(PRStatus) +PR_DestroyStack(PRStack *stack) +{ + if (stack->prstk_head.prstk_elem_next != NULL) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return PR_FAILURE; + } + + if (stack->prstk_name) + PR_Free(stack->prstk_name); +#ifndef _PR_HAVE_ATOMIC_CAS + PR_DestroyLock(stack->prstk_lock); +#endif /* !_PR_HAVE_ATOMIC_CAS */ + PR_DELETE(stack); + + return PR_SUCCESS; +} + +#ifndef _PR_HAVE_ATOMIC_CAS + +PR_IMPLEMENT(void) +PR_StackPush(PRStack *stack, PRStackElem *stack_elem) +{ + PR_Lock(stack->prstk_lock); + stack_elem->prstk_elem_next = stack->prstk_head.prstk_elem_next; + stack->prstk_head.prstk_elem_next = stack_elem; + PR_Unlock(stack->prstk_lock); + return; +} + +PR_IMPLEMENT(PRStackElem *) +PR_StackPop(PRStack *stack) +{ +PRStackElem *element; + + PR_Lock(stack->prstk_lock); + element = stack->prstk_head.prstk_elem_next; + if (element != NULL) { + stack->prstk_head.prstk_elem_next = element->prstk_elem_next; + element->prstk_elem_next = NULL; /* debugging aid */ + } + PR_Unlock(stack->prstk_lock); + return element; +} +#endif /* !_PR_HAVE_ATOMIC_CAS */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/praton.c nspr-4.10.7/nspr/pr/src/misc/praton.c --- nspr-4.9.5/nspr/pr/src/misc/praton.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/praton.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,198 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/******************************************************************************* + * The following function pr_inet_aton is based on the BSD function inet_aton + * with some modifications. The license and copyright notices applying to this + * function appear below. Modifications are also according to the license below. + ******************************************************************************/ + +#include "prnetdb.h" + +/* + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define XX 127 +static const unsigned char index_hex[256] = { + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX, + XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, +}; + +static PRBool _isdigit(char c) { return c >= '0' && c <= '9'; } +static PRBool _isxdigit(char c) { return index_hex[(unsigned char) c] != XX; } +static PRBool _isspace(char c) { return c == ' ' || (c >= '\t' && c <= '\r'); } +#undef XX + +int +pr_inet_aton(const char *cp, PRUint32 *addr) +{ + PRUint32 val; + int base, n; + char c; + PRUint8 parts[4]; + PRUint8 *pp = parts; + int digit; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!_isdigit(c)) + return (0); + val = 0; base = 10; digit = 0; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else { + base = 8; + digit = 1; + } + } + for (;;) { + if (_isdigit(c)) { + if (base == 8 && (c == '8' || c == '9')) + return (0); + val = (val * base) + (c - '0'); + c = *++cp; + digit = 1; + } else if (base == 16 && _isxdigit(c)) { + val = (val << 4) + index_hex[(unsigned char) c]; + c = *++cp; + digit = 1; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3 || val > 0xffU) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && !_isspace(c)) + return (0); + /* + * Did we get a valid digit? + */ + if (!digit) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + case 1: /*%< a -- 32 bits */ + break; + + case 2: /*%< a.b -- 8.24 bits */ + if (val > 0xffffffU) + return (0); + val |= parts[0] << 24; + break; + + case 3: /*%< a.b.c -- 8.8.16 bits */ + if (val > 0xffffU) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /*%< a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xffU) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + *addr = PR_htonl(val); + return (1); +} + diff -Nru nspr-4.9.5/nspr/pr/src/misc/prcountr.c nspr-4.10.7/nspr/pr/src/misc/prcountr.c --- nspr-4.9.5/nspr/pr/src/misc/prcountr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prcountr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,474 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** prcountr.c -- NSPR Instrumentation Counters +** +** Implement the interface defined in prcountr.h +** +** Design Notes: +** +** The Counter Facility (CF) has a single anchor: qNameList. +** The anchor is a PRCList. qNameList is a list of links in QName +** structures. From qNameList any QName structure and its +** associated RName structure can be located. +** +** For each QName, a list of RName structures is anchored at +** rnLink in the QName structure. +** +** The counter itself is embedded in the RName structure. +** +** For manipulating the counter database, single lock is used to +** protect the entire list: counterLock. +** +** A PRCounterHandle, defined in prcountr.h, is really a pointer +** to a RName structure. References by PRCounterHandle are +** dead-reconed to the RName structure. The PRCounterHandle is +** "overloaded" for traversing the QName structures; only the +** function PR_FindNextQnameHandle() uses this overloading. +** +** +** ToDo (lth): decide on how to lock or atomically update +** individual counters. Candidates are: the global lock; a lock +** per RName structure; Atomic operations (Note that there are +** not adaquate atomic operations (yet) to achieve this goal). At +** this writing (6/19/98) , the update of the counter variable in +** a QName structure is unprotected. +** +*/ + +#include "prcountr.h" +#include "prclist.h" +#include "prlock.h" +#include "prlog.h" +#include "prmem.h" +#include + +/* +** +*/ +typedef struct QName +{ + PRCList link; + PRCList rNameList; + char name[PRCOUNTER_NAME_MAX+1]; +} QName; + +/* +** +*/ +typedef struct RName +{ + PRCList link; + QName *qName; + PRLock *lock; + volatile PRUint32 counter; + char name[PRCOUNTER_NAME_MAX+1]; + char desc[PRCOUNTER_DESC_MAX+1]; +} RName; + + +/* +** Define the Counter Facility database +*/ +static PRLock *counterLock; +static PRCList qNameList; +static PRLogModuleInfo *lm; + +/* +** _PR_CounterInitialize() -- Initialize the Counter Facility +** +*/ +static void _PR_CounterInitialize( void ) +{ + /* + ** This function should be called only once + */ + PR_ASSERT( counterLock == NULL ); + + counterLock = PR_NewLock(); + PR_INIT_CLIST( &qNameList ); + lm = PR_NewLogModule("counters"); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Initialization complete")); + + return; +} /* end _PR_CounterInitialize() */ + +/* +** PR_CreateCounter() -- Create a counter +** +** ValidateArguments +** Lock +** if (qName not already in database) +** NewQname +** if (rName already in database ) +** Assert +** else NewRname +** NewCounter +** link 'em up +** Unlock +** +*/ +PR_IMPLEMENT(PRCounterHandle) + PR_CreateCounter( + const char *qName, + const char *rName, + const char *description +) +{ + QName *qnp; + RName *rnp; + PRBool matchQname = PR_FALSE; + + /* Self initialize, if necessary */ + if ( counterLock == NULL ) + _PR_CounterInitialize(); + + /* Validate input arguments */ + PR_ASSERT( strlen(qName) <= PRCOUNTER_NAME_MAX ); + PR_ASSERT( strlen(rName) <= PRCOUNTER_NAME_MAX ); + PR_ASSERT( strlen(description) <= PRCOUNTER_DESC_MAX ); + + /* Lock the Facility */ + PR_Lock( counterLock ); + + /* Do we already have a matching QName? */ + if (!PR_CLIST_IS_EMPTY( &qNameList )) + { + qnp = (QName *) PR_LIST_HEAD( &qNameList ); + do { + if ( strcmp(qnp->name, qName) == 0) + { + matchQname = PR_TRUE; + break; + } + qnp = (QName *)PR_NEXT_LINK( &qnp->link ); + } while( qnp != (QName *)&qNameList ); + } + /* + ** If we did not find a matching QName, + ** allocate one and initialize it. + ** link it onto the qNameList. + ** + */ + if ( matchQname != PR_TRUE ) + { + qnp = PR_NEWZAP( QName ); + PR_ASSERT( qnp != NULL ); + PR_INIT_CLIST( &qnp->link ); + PR_INIT_CLIST( &qnp->rNameList ); + strcpy( qnp->name, qName ); + PR_APPEND_LINK( &qnp->link, &qNameList ); + } + + /* Do we already have a matching RName? */ + if (!PR_CLIST_IS_EMPTY( &qnp->rNameList )) + { + rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList ); + do { + /* + ** No duplicate RNames are allowed within a QName + ** + */ + PR_ASSERT( strcmp(rnp->name, rName)); + rnp = (RName *)PR_NEXT_LINK( &rnp->link ); + } while( rnp != (RName *)&qnp->rNameList ); + } + + /* Get a new RName structure; initialize its members */ + rnp = PR_NEWZAP( RName ); + PR_ASSERT( rnp != NULL ); + PR_INIT_CLIST( &rnp->link ); + strcpy( rnp->name, rName ); + strcpy( rnp->desc, description ); + rnp->lock = PR_NewLock(); + if ( rnp->lock == NULL ) + { + PR_ASSERT(0); + } + + PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ + rnp->qName = qnp; /* point the RName to the QName */ + + /* Unlock the Facility */ + PR_Unlock( counterLock ); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t", + qName, qnp, rName, rnp )); + + return((PRCounterHandle)rnp); +} /* end PR_CreateCounter() */ + + +/* +** +*/ +PR_IMPLEMENT(void) + PR_DestroyCounter( + PRCounterHandle handle +) +{ + RName *rnp = (RName *)handle; + QName *qnp = rnp->qName; + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s", + qnp->name, rnp->name)); + + /* Lock the Facility */ + PR_Lock( counterLock ); + + /* + ** Remove RName from the list of RNames in QName + ** and free RName + */ + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p", + rnp->name, rnp)); + PR_REMOVE_LINK( &rnp->link ); + PR_Free( rnp->lock ); + PR_DELETE( rnp ); + + /* + ** If this is the last RName within QName + ** remove QName from the qNameList and free it + */ + if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) ) + { + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p", + qnp->name, qnp)); + PR_REMOVE_LINK( &qnp->link ); + PR_DELETE( qnp ); + } + + /* Unlock the Facility */ + PR_Unlock( counterLock ); + return; +} /* end PR_DestroyCounter() */ + +/* +** +*/ +PR_IMPLEMENT(PRCounterHandle) + PR_GetCounterHandleFromName( + const char *qName, + const char *rName +) +{ + const char *qn, *rn, *desc; + PRCounterHandle qh, rh = NULL; + RName *rnp = NULL; + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounterHandleFromName:\n\t" + "QName: %s, RName: %s", qName, rName )); + + qh = PR_FindNextCounterQname( NULL ); + while (qh != NULL) + { + rh = PR_FindNextCounterRname( NULL, qh ); + while ( rh != NULL ) + { + PR_GetCounterNameFromHandle( rh, &qn, &rn, &desc ); + if ( (strcmp( qName, qn ) == 0) + && (strcmp( rName, rn ) == 0 )) + { + rnp = (RName *)rh; + goto foundIt; + } + rh = PR_FindNextCounterRname( rh, qh ); + } + qh = PR_FindNextCounterQname( NULL ); + } + +foundIt: + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp )); + return(rh); +} /* end PR_GetCounterHandleFromName() */ + +/* +** +*/ +PR_IMPLEMENT(void) + PR_GetCounterNameFromHandle( + PRCounterHandle handle, + const char **qName, + const char **rName, + const char **description +) +{ + RName *rnp = (RName *)handle; + QName *qnp = rnp->qName; + + *qName = qnp->name; + *rName = rnp->name; + *description = rnp->desc; + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterNameFromHandle: " + "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", + qnp, rnp, qnp->name, rnp->name, rnp->desc )); + + return; +} /* end PR_GetCounterNameFromHandle() */ + + +/* +** +*/ +PR_IMPLEMENT(void) + PR_IncrementCounter( + PRCounterHandle handle +) +{ + PR_Lock(((RName *)handle)->lock); + ((RName *)handle)->counter++; + PR_Unlock(((RName *)handle)->lock); + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld", + handle, ((RName *)handle)->counter )); + + return; +} /* end PR_IncrementCounter() */ + + + +/* +** +*/ +PR_IMPLEMENT(void) + PR_DecrementCounter( + PRCounterHandle handle +) +{ + PR_Lock(((RName *)handle)->lock); + ((RName *)handle)->counter--; + PR_Unlock(((RName *)handle)->lock); + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld", + handle, ((RName *)handle)->counter )); + + return; +} /* end PR_DecrementCounter() */ + + +/* +** +*/ +PR_IMPLEMENT(void) + PR_AddToCounter( + PRCounterHandle handle, + PRUint32 value +) +{ + PR_Lock(((RName *)handle)->lock); + ((RName *)handle)->counter += value; + PR_Unlock(((RName *)handle)->lock); + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld", + handle, ((RName *)handle)->counter )); + + return; +} /* end PR_AddToCounter() */ + + +/* +** +*/ +PR_IMPLEMENT(void) + PR_SubtractFromCounter( + PRCounterHandle handle, + PRUint32 value +) +{ + PR_Lock(((RName *)handle)->lock); + ((RName *)handle)->counter -= value; + PR_Unlock(((RName *)handle)->lock); + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld", + handle, ((RName *)handle)->counter )); + + return; +} /* end PR_SubtractFromCounter() */ + +/* +** +*/ +PR_IMPLEMENT(PRUint32) + PR_GetCounter( + PRCounterHandle handle +) +{ + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld", + handle, ((RName *)handle)->counter )); + + return(((RName *)handle)->counter); +} /* end PR_GetCounter() */ + +/* +** +*/ +PR_IMPLEMENT(void) + PR_SetCounter( + PRCounterHandle handle, + PRUint32 value +) +{ + ((RName *)handle)->counter = value; + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld", + handle, ((RName *)handle)->counter )); + + return; +} /* end PR_SetCounter() */ + +/* +** +*/ +PR_IMPLEMENT(PRCounterHandle) + PR_FindNextCounterQname( + PRCounterHandle handle +) +{ + QName *qnp = (QName *)handle; + + if ( PR_CLIST_IS_EMPTY( &qNameList )) + qnp = NULL; + else if ( qnp == NULL ) + qnp = (QName *)PR_LIST_HEAD( &qNameList ); + else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) + qnp = NULL; + else + qnp = (QName *)PR_NEXT_LINK( &qnp->link ); + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", + handle, qnp )); + + return((PRCounterHandle)qnp); +} /* end PR_FindNextCounterQname() */ + + +/* +** +*/ +PR_IMPLEMENT(PRCounterHandle) + PR_FindNextCounterRname( + PRCounterHandle rhandle, + PRCounterHandle qhandle +) +{ + RName *rnp = (RName *)rhandle; + QName *qnp = (QName *)qhandle; + + + if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) + rnp = NULL; + else if ( rnp == NULL ) + rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList ); + else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) + rnp = NULL; + else + rnp = (RName *)PR_NEXT_LINK( &rnp->link ); + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", + rhandle, qhandle, rnp )); + + return((PRCounterHandle)rnp); +} /* end PR_FindNextCounterRname() */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/prdtoa.c nspr-4.10.7/nspr/pr/src/misc/prdtoa.c --- nspr-4.9.5/nspr/pr/src/misc/prdtoa.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prdtoa.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,3522 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This file is based on the third-party code dtoa.c. We minimize our + * modifications to third-party code to make it easy to merge new versions. + * The author of dtoa.c was not willing to add the parentheses suggested by + * GCC, so we suppress these warnings. + */ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) +#pragma GCC diagnostic ignored "-Wparentheses" +#endif + +#include "primpl.h" +#include "prbit.h" + +#define MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK(n) PR_Lock(dtoa_lock[n]) +#define FREE_DTOA_LOCK(n) PR_Unlock(dtoa_lock[n]) + +static PRLock *dtoa_lock[2]; + +void _PR_InitDtoa(void) +{ + dtoa_lock[0] = PR_NewLock(); + dtoa_lock[1] = PR_NewLock(); +} + +void _PR_CleanupDtoa(void) +{ + PR_DestroyLock(dtoa_lock[0]); + dtoa_lock[0] = NULL; + PR_DestroyLock(dtoa_lock[1]); + dtoa_lock[1] = NULL; + + /* FIXME: deal with freelist and p5s. */ +} + +#if !defined(__ARM_EABI__) \ + && (defined(__arm) || defined(__arm__) || defined(__arm26__) \ + || defined(__arm32__)) +#define IEEE_ARM +#elif defined(IS_LITTLE_ENDIAN) +#define IEEE_8087 +#else +#define IEEE_MC68k +#endif + +#define Long PRInt32 +#define ULong PRUint32 +#define NO_LONG_LONG + +#define No_Hex_NaN + +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define IEEE_ARM for IEEE-arithmetic machines where the two words + * in a double are stored in big endian order but the two shorts + * in a word are still stored in little endian order. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and strtod and dtoa should round accordingly. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and Honor_FLT_ROUNDS is not #defined. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a dtoa call after a dtoa return in + * mode 3 with thousands of digits requested.) + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. The longest string dtoa can return is about 751 bytes + * long. For conversions by strtod of strings of 800 digits and + * all dtoa conversions in single-threaded executions with 8-byte + * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte + * pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define INFNAN_CHECK on IEEE systems to cause strtod to check for + * Infinity and NaN (case insensitively). On some systems (e.g., + * some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtod also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the 52 fraction bits of the resulting NaN; if there are two + * or more strings of hex digits, the first is for the high 20 bits, + * the second and subsequent for the low 32 bits, with intervening + * white space ignored; but if this results in none of the 52 + * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 + * and NAN_WORD1 are used instead. + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that + * avoids underflows on inputs whose result does not underflow. + * If you #define NO_IEEE_Scale on a machine that uses IEEE-format + * floating-point numbers and flushes underflows to zero rather + * than implementing gradual underflow, then you must also #define + * Sudden_Underflow. + * #define USE_LOCALE to use the current locale's decimal_point value. + * #define SET_INEXACT if IEEE arithmetic is being used and extra + * computation should be done to set the inexact flag when the + * result is inexact and avoid setting inexact when the result + * is exact. In this case, dtoa.c must be compiled in + * an environment, perhaps provided by #include "dtoa.c" in a + * suitable wrapper, that defines two functions, + * int get_inexact(void); + * void clear_inexact(void); + * such that get_inexact() returns a nonzero value if the + * inexact bit is already set, and clear_inexact() sets the + * inexact bit to 0. When SET_INEXACT is #defined, strtod + * also does extra computations to set the underflow and overflow + * flags when appropriate (i.e., when the result is tiny and + * inexact or when it is a numeric value rounded to +-infinity). + * #define NO_ERRNO if strtod should not assign errno = ERANGE when + * the result overflows to +-Infinity or underflows to 0. + */ + +#ifndef Long +#define Long long +#endif +#ifndef ULong +typedef unsigned Long ULong; +#endif + +#ifdef DEBUG +#include "stdio.h" +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#include "stdlib.h" +#include "string.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + +#ifdef MALLOC +#ifdef KR_headers +extern char *MALLOC(); +#else +extern void *MALLOC(size_t); +#endif +#else +#define MALLOC malloc +#endif + +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_MC68k +#define IEEE_Arith +#endif +#ifdef IEEE_8087 +#define IEEE_Arith +#endif +#ifdef IEEE_ARM +#define IEEE_Arith +#endif + +#include "errno.h" + +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#endif /*IEEE_Arith*/ + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include "float.h" +/* + * MacOS 10.2 defines the macro FLT_ROUNDS to an internal function + * which does not exist on 10.1. We can safely #define it to 1 here + * to allow 10.2 builds to run on 10.1, since we can't use fesetround() + * (which does not exist on 10.1 either). + */ +#if defined(XP_MACOSX) && (!defined(MAC_OS_X_VERSION_10_2) || \ + MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2) +#undef FLT_ROUNDS +#define FLT_ROUNDS 1 +#endif /* DT < 10.2 */ +#endif /* Bad_float_h */ + +#ifndef __MATH_H__ +#include "math.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CONST +#ifdef KR_headers +#define CONST /* blank */ +#else +#define CONST const +#endif +#endif + +#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_8087, IEEE_MC68k, IEEE_ARM, VAX, or IBM should be defined. +#endif + +typedef union { double d; ULong L[2]; } U; + +#define dval(x) (x).d +#ifdef IEEE_8087 +#define word0(x) (x).L[1] +#define word1(x) (x).L[0] +#else +#define word0(x) (x).L[0] +#define word1(x) (x).L[1] +#endif + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) + defined(IEEE_ARM) + defined(VAX) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#ifdef Flush_Denorm /* debugging option */ +#undef Sudden_Underflow +#endif +#endif + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + +#else /* ifndef IEEE_Arith */ +#undef Check_FLT_ROUNDS +#undef Honor_FLT_ROUNDS +#undef SET_INEXACT +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +#ifdef KR_headers +extern double rnd_prod(), rnd_quot(); +#else +extern double rnd_prod(double, double), rnd_quot(double, double); +#endif +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Pack_32 +#define Pack_32 +#endif + +#ifdef KR_headers +#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) +#else +#define FFFFFFFF 0xffffffffUL +#endif + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#ifndef MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ +#endif + +#define Kmax 7 + + struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; + }; + + typedef struct Bigint Bigint; + + static Bigint *freelist[Kmax+1]; + + static Bigint * +Balloc +#ifdef KR_headers + (k) int k; +#else + (int k) +#endif +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + unsigned int len; +#endif + + ACQUIRE_DTOA_LOCK(0); + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ + if (k <= Kmax && (rv = freelist[k])) + freelist[k] = rv->next; + else { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; + } + + static void +Bfree +#ifdef KR_headers + (v) Bigint *v; +#else + (Bigint *v) +#endif +{ + if (v) { + if (v->k > Kmax) +#ifdef FREE + FREE((void*)v); +#else + free((void*)v); +#endif + else { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } + } + } + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ +y->wds*sizeof(Long) + 2*sizeof(int)) + + static Bigint * +multadd +#ifdef KR_headers + (b, m, a) Bigint *b; int m, a; +#else + (Bigint *b, int m, int a) /* multiply by m and add a */ +#endif +{ + int i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; + } + + static Bigint * +s2b +#ifdef KR_headers + (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; +#else + (CONST char *s, int nd0, int nd, ULong y9) +#endif +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0'); + while(++i < nd0); + s++; + } + else + s += 10; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; + } + + static int +hi0bits +#ifdef KR_headers + (x) register ULong x; +#else + (register ULong x) +#endif +{ +#ifdef PR_HAVE_BUILTIN_BITSCAN32 + return( (!x) ? 32 : pr_bitscan_clz32(x) ); +#else + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +#endif /* PR_HAVE_BUILTIN_BITSCAN32 */ + } + + static int +lo0bits +#ifdef KR_headers + (y) ULong *y; +#else + (ULong *y) +#endif +{ +#ifdef PR_HAVE_BUILTIN_BITSCAN32 + int k; + ULong x = *y; + + if (x>1) + *y = ( x >> (k = pr_bitscan_ctz32(x)) ); + else + k = ((x ^ 1) << 5); +#else + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; +#endif /* PR_HAVE_BUILTIN_BITSCAN32 */ + return k; + } + + static Bigint * +i2b +#ifdef KR_headers + (i) int i; +#else + (int i) +#endif +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; + } + + static Bigint * +mult +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & FFFFFFFF; + } + while(x < xae); + *xc = carry; + } + } +#else +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if (y = *xb & 0xffff) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if (y = *xb >> 16) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; + } + + static Bigint *p5s; + + static Bigint * +pow5mult +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if (i = k & 3) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if (!(p5 = p5s)) { + /* first time */ +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625); + p5->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p5 = p5s = i2b(625); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p51 = p5->next = mult(p5,p5); + p51->next = 0; +#endif + } + p5 = p51; + } + return b; + } + + static Bigint * +lshift +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; + } +#endif + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; + } + + static int +cmp +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; + } + + static Bigint * +diff +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; + } + + static double +ulp +#ifdef KR_headers + (dx) double dx; +#else + (double dx) +#endif +{ + register Long L; + U x, a; + + dval(x) = dx; + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(a) = L; + word1(a) = 0; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif +#endif + return dval(a); + } + + static double +b2d +#ifdef KR_headers + (a, e) Bigint *a; int *e; +#else + (Bigint *a, int *e) +#endif +{ + ULong *xa, *xa0, w, y, z; + int k; + U d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> Ebits - k; + w = xa > xa0 ? *--xa : 0; + d1 = y << (32-Ebits) + k | w >> Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> 32 - k; + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> 32 - k; + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif + ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#else +#undef d0 +#undef d1 +#endif + return dval(d); + } + + static Bigint * +d2b +#ifdef KR_headers + (dd, e, bits) double dd; int *e, *bits; +#else + (double dd, int *e, int *bits) +#endif +{ + U d; + Bigint *b; + int de, k; + ULong *x, y, z; +#ifndef Sudden_Underflow + int i; +#endif +#ifdef VAX + ULong d0, d1; +#endif + + dval(d) = dd; +#ifdef VAX + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if (de = (int)(d0 >> Exp_shift)) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if (y = d1) { + if (k = lo0bits(&y)) { + x[0] = y | z << 32 - k; + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + b->wds = (x[1] = z) ? 2 : 1; + } + else { + k = lo0bits(&z); + x[0] = z; +#ifndef Sudden_Underflow + i = +#endif + b->wds = 1; + k += 32; + } +#else + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; + } +#undef d0 +#undef d1 + + static double +ratio +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + U da, db; + int k, ka, kb; + + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(da) *= 1 << k; + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(db) *= 1 << k; + } +#else + if (k > 0) + word0(da) += k*Exp_msk1; + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return dval(da) / dval(db); + } + + static CONST double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif + }; + + static CONST double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, +#ifdef Avoid_Underflow + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-53 */ +#else + 1e-256 +#endif + }; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +bigtens[] = { 1e16, 1e32 }; +static CONST double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +#ifndef IEEE_Arith +#undef INFNAN_CHECK +#endif + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + + static int +match +#ifdef KR_headers + (sp, t) char **sp, *t; +#else + (CONST char **sp, char *t) +#endif +{ + int c, d; + CONST char *s = *sp; + + while(d = *t++) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; + } + +#ifndef No_Hex_NaN + static void +hexnan +#ifdef KR_headers + (rvp, sp) double *rvp; CONST char **sp; +#else + (double *rvp, CONST char **sp) +#endif +{ + ULong c, x[2]; + CONST char *s; + int havedig, udx0, xshift; + + x[0] = x[1] = 0; + havedig = xshift = 0; + udx0 = 1; + s = *sp; + while(c = *(CONST unsigned char*)++s) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') + c += 10 - 'a'; + else if (c >= 'A' && c <= 'F') + c += 10 - 'A'; + else if (c <= ' ') { + if (udx0 && havedig) { + udx0 = 0; + xshift = 1; + } + continue; + } + else if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + else + return; /* invalid form: don't change *sp */ + havedig = 1; + if (xshift) { + xshift = 0; + x[0] = x[1]; + x[1] = 0; + } + if (udx0) + x[0] = (x[0] << 4) | (x[1] >> 28); + x[1] = (x[1] << 4) | c; + } + if ((x[0] &= 0xfffff) || x[1]) { + word0(*rvp) = Exp_mask | x[0]; + word1(*rvp) = x[1]; + } + } +#endif /*No_Hex_NaN*/ +#endif /* INFNAN_CHECK */ + + PR_IMPLEMENT(double) +PR_strtod +#ifdef KR_headers + (s00, se) CONST char *s00; char **se; +#else + (CONST char *s00, char **se) +#endif +{ +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj; + U aadj2, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef USE_LOCALE + CONST char *s2; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + sign = nz0 = nz = 0; + dval(rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + s1 = localeconv()->decimal_point; + if (c == *s1) { + c = '.'; + if (*++s1) { + s2 = s; + for(;;) { + if (*++s2 != *s1) { + c = 0; + break; + } + if (!*++s1) { + s = s2; + break; + } + } + } + } +#endif + if (c == '.') { + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + if (nd > 64 * 1024) + goto ret0; + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + hexnan(&rv, &s); +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ + ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(rv) = tens[k - 9] * dval(rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + e -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if (i = e1 & 15) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: +#ifndef NO_ERRNO + PR_SetError(PR_RANGE_ERROR, 0); +#endif + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); +#endif +#else /*IEEE_Arith*/ + word0(rv) = Big0; + word1(rv) = Big1; +#endif /*IEEE_Arith*/ + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else + word0(rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if (i = e1 & 15) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) + word0(rv) = (P+2)*Exp_msk1; + else + word0(rv) &= 0xffffffff << j-32; + } + else + word1(rv) &= 0xffffffff << j; + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; +#endif + if (!dval(rv)) { + undfl: + dval(rv) = 0.; +#ifndef NO_ERRNO + PR_SetError(PR_RANGE_ERROR, 0); +#endif + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) + adj = -0.5; + } + } + apply_adj: +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= + P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + dval(rv) += adj*ulp(dval(rv)); + } + break; + } + adj = ratio(delta, bs); + if (adj < 1.) + adj = 1.; + if (adj <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj; + if (y != adj) { + if (!((rounding>>1) ^ dsign)) + y++; + adj = y; + } + } +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + goto cont; + } +#endif /*Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif +#endif + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( +#ifdef Avoid_Underflow + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + goto undfl; + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}}*/ + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + dval(rv) += ulp(dval(rv)); +#ifndef ROUND_BIASED + else { + dval(rv) -= ulp(dval(rv)); +#ifndef Sudden_Underflow + if (!dval(rv)) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(Rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (Flt_Rounds == 0) + aadj1 += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) + z = 1; + aadj = z; + aadj1 = dsign ? aadj : -aadj; + } + dval(aadj2) = aadj1; + word0(aadj2) += (2*P+1)*Exp_msk1 - y; + aadj1 = dval(aadj2); + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(rv) & Exp_mask; +#ifndef SET_INEXACT +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } +#endif + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ + if (word0(rv) == 0 && word1(rv) == 0) + PR_SetError(PR_RANGE_ERROR, 0); +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); + } +#endif + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (se) + *se = (char *)s; + return sign ? -dval(rv) : dval(rv); + } + + static int +quorem +#ifdef KR_headers + (b, S) Bigint *b, *S; +#else + (Bigint *b, Bigint *S) +#endif +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; + } + +#ifndef MULTIPLE_THREADS + static char *dtoa_result; +#endif + + static char * +#ifdef KR_headers +rv_alloc(i) int i; +#else +rv_alloc(int i) +#endif +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) + k++; + r = (int*)Balloc(k); + *r = k; + return +#ifndef MULTIPLE_THREADS + dtoa_result = +#endif + (char *)(r+1); + } + + static char * +#ifdef KR_headers +nrv_alloc(s, rve, n) char *s, **rve; int n; +#else +nrv_alloc(char *s, char **rve, int n) +#endif +{ + char *rv, *t; + + t = rv = rv_alloc(n); + while(*t = *s++) t++; + if (rve) + *rve = t; + return rv; + } + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + + static void +#ifdef KR_headers +freedtoa(s) char *s; +#else +freedtoa(char *s) +#endif +{ + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); +#ifndef MULTIPLE_THREADS + if (s == dtoa_result) + dtoa_result = 0; +#endif + } + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + static char * +dtoa +#ifdef KR_headers + (dd, mode, ndigits, decpt, sign, rve) + double dd; int mode, ndigits, *decpt, *sign; char **rve; +#else + (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) +#endif +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + U d, d2, eps; + double ds; + char *s, *s0; +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + dval(d) = dd; + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + if (!word1(d) && !(word0(d) & 0xfffff)) + return nrv_alloc("Infinity", rve, 8); +#endif + return nrv_alloc("NaN", rve, 3); + } +#endif +#ifdef IBM + dval(d) += 0; /* normalize */ +#endif + if (!dval(d)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif + + b = d2b(dval(d), &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { +#endif + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; +#ifdef IBM + if (j = 11 - hi0bits(word0(d2) & Frac_mask)) + dval(d2) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 + : word1(d) << 32 - i; + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if (j1 = -k) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) + goto ret1; + if (1. - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) + goto bump_up; + else if (dval(d) < 0.5 - dval(eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1; i <= k+1; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if (j = b5 - m5) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && rounding == 1 +#endif + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) + i = 32 - i; +#else + if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(d) & 1) +#ifdef Honor_FLT_ROUNDS + && rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + ) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS + keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || j == 0 && dig & 1) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { +#ifdef Honor_FLT_ROUNDS + trimzeros: +#endif + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + } +#ifdef __cplusplus +} +#endif + +PR_IMPLEMENT(PRStatus) +PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits, + PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize) +{ + char *result; + PRSize resultlen; + PRStatus rv = PR_FAILURE; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (mode < 0 || mode > 3) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return rv; + } + result = dtoa(d, mode, ndigits, decpt, sign, rve); + if (!result) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return rv; + } + resultlen = strlen(result)+1; + if (bufsize < resultlen) { + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); + } else { + memcpy(buf, result, resultlen); + if (rve) { + *rve = buf + (*rve - result); + } + rv = PR_SUCCESS; + } + freedtoa(result); + return rv; +} + +/* +** conversion routines for floating point +** prcsn - number of digits of precision to generate floating +** point value. +** This should be reparameterized so that you can send in a +** prcn for the positive and negative ranges. For now, +** conform to the ECMA JavaScript spec which says numbers +** less than 1e-6 are in scientific notation. +** Also, the ECMA spec says that there should always be a +** '+' or '-' after the 'e' in scientific notation +*/ +PR_IMPLEMENT(void) +PR_cnvtf(char *buf, int bufsz, int prcsn, double dfval) +{ + PRIntn decpt, sign, numdigits; + char *num, *nump; + char *bufp = buf; + char *endnum; + U fval; + + dval(fval) = dfval; + /* If anything fails, we store an empty string in 'buf' */ + num = (char*)PR_MALLOC(bufsz); + if (num == NULL) { + buf[0] = '\0'; + return; + } + /* XXX Why use mode 1? */ + if (PR_dtoa(dval(fval),1,prcsn,&decpt,&sign,&endnum,num,bufsz) + == PR_FAILURE) { + buf[0] = '\0'; + goto done; + } + numdigits = endnum - num; + nump = num; + + if (sign && + !(word0(fval) == Sign_bit && word1(fval) == 0) && + !((word0(fval) & Exp_mask) == Exp_mask && + (word1(fval) || (word0(fval) & 0xfffff)))) { + *bufp++ = '-'; + } + + if (decpt == 9999) { + while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */ + goto done; + } + + if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) { + *bufp++ = *nump++; + if (numdigits != 1) { + *bufp++ = '.'; + } + + while (*nump != '\0') { + *bufp++ = *nump++; + } + *bufp++ = 'e'; + PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1); + } else if (decpt >= 0) { + if (decpt == 0) { + *bufp++ = '0'; + } else { + while (decpt--) { + if (*nump != '\0') { + *bufp++ = *nump++; + } else { + *bufp++ = '0'; + } + } + } + if (*nump != '\0') { + *bufp++ = '.'; + while (*nump != '\0') { + *bufp++ = *nump++; + } + } + *bufp++ = '\0'; + } else if (decpt < 0) { + *bufp++ = '0'; + *bufp++ = '.'; + while (decpt++) { + *bufp++ = '0'; + } + + while (*nump != '\0') { + *bufp++ = *nump++; + } + *bufp++ = '\0'; + } +done: + PR_DELETE(num); +} diff -Nru nspr-4.9.5/nspr/pr/src/misc/prenv.c nspr-4.10.7/nspr/pr/src/misc/prenv.c --- nspr-4.9.5/nspr/pr/src/misc/prenv.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prenv.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include "primpl.h" + +/* Lock used to lock the environment */ +#if defined(_PR_NO_PREEMPT) +#define _PR_NEW_LOCK_ENV() +#define _PR_DELETE_LOCK_ENV() +#define _PR_LOCK_ENV() +#define _PR_UNLOCK_ENV() +#elif defined(_PR_LOCAL_THREADS_ONLY) +extern _PRCPU * _pr_primordialCPU; +static PRIntn _is; +#define _PR_NEW_LOCK_ENV() +#define _PR_DELETE_LOCK_ENV() +#define _PR_LOCK_ENV() if (_pr_primordialCPU) _PR_INTSOFF(_is); +#define _PR_UNLOCK_ENV() if (_pr_primordialCPU) _PR_INTSON(_is); +#else +static PRLock *_pr_envLock = NULL; +#define _PR_NEW_LOCK_ENV() {_pr_envLock = PR_NewLock();} +#define _PR_DELETE_LOCK_ENV() \ + { if (_pr_envLock) { PR_DestroyLock(_pr_envLock); _pr_envLock = NULL; } } +#define _PR_LOCK_ENV() { if (_pr_envLock) PR_Lock(_pr_envLock); } +#define _PR_UNLOCK_ENV() { if (_pr_envLock) PR_Unlock(_pr_envLock); } +#endif + +/************************************************************************/ + +void _PR_InitEnv(void) +{ + _PR_NEW_LOCK_ENV(); +} + +void _PR_CleanupEnv(void) +{ + _PR_DELETE_LOCK_ENV(); +} + +PR_IMPLEMENT(char*) PR_GetEnv(const char *var) +{ + char *ev; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + _PR_LOCK_ENV(); + ev = _PR_MD_GET_ENV(var); + _PR_UNLOCK_ENV(); + return ev; +} + +PR_IMPLEMENT(PRStatus) PR_SetEnv(const char *string) +{ + PRIntn result; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if ( !strchr(string, '=')) return(PR_FAILURE); + + _PR_LOCK_ENV(); + result = _PR_MD_PUT_ENV(string); + _PR_UNLOCK_ENV(); + return (result)? PR_FAILURE : PR_SUCCESS; +} diff -Nru nspr-4.9.5/nspr/pr/src/misc/prerr.c nspr-4.10.7/nspr/pr/src/misc/prerr.c --- nspr-4.9.5/nspr/pr/src/misc/prerr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prerr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * prerr.c + * This file is automatically generated; please do not edit it. + */ +#include "prerror.h" +static const struct PRErrorMessage text[] = { + {"PR_OUT_OF_MEMORY_ERROR", "Memory allocation attempt failed"}, + {"PR_BAD_DESCRIPTOR_ERROR", "Invalid file descriptor"}, + {"PR_WOULD_BLOCK_ERROR", "The operation would have blocked"}, + {"PR_ACCESS_FAULT_ERROR", "Invalid memory address argument"}, + {"PR_INVALID_METHOD_ERROR", "Invalid function for file type"}, + {"PR_ILLEGAL_ACCESS_ERROR", "Invalid memory address argument"}, + {"PR_UNKNOWN_ERROR", "Some unknown error has occurred"}, + {"PR_PENDING_INTERRUPT_ERROR", "Operation interrupted by another thread"}, + {"PR_NOT_IMPLEMENTED_ERROR", "function not implemented"}, + {"PR_IO_ERROR", "I/O function error"}, + {"PR_IO_TIMEOUT_ERROR", "I/O operation timed out"}, + {"PR_IO_PENDING_ERROR", "I/O operation on busy file descriptor"}, + {"PR_DIRECTORY_OPEN_ERROR", "The directory could not be opened"}, + {"PR_INVALID_ARGUMENT_ERROR", "Invalid function argument"}, + {"PR_ADDRESS_NOT_AVAILABLE_ERROR", "Network address not available (in use?)"}, + {"PR_ADDRESS_NOT_SUPPORTED_ERROR", "Network address type not supported"}, + {"PR_IS_CONNECTED_ERROR", "Already connected"}, + {"PR_BAD_ADDRESS_ERROR", "Network address is invalid"}, + {"PR_ADDRESS_IN_USE_ERROR", "Local Network address is in use"}, + {"PR_CONNECT_REFUSED_ERROR", "Connection refused by peer"}, + {"PR_NETWORK_UNREACHABLE_ERROR", "Network address is presently unreachable"}, + {"PR_CONNECT_TIMEOUT_ERROR", "Connection attempt timed out"}, + {"PR_NOT_CONNECTED_ERROR", "Network file descriptor is not connected"}, + {"PR_LOAD_LIBRARY_ERROR", "Failure to load dynamic library"}, + {"PR_UNLOAD_LIBRARY_ERROR", "Failure to unload dynamic library"}, + {"PR_FIND_SYMBOL_ERROR", "Symbol not found in any of the loaded dynamic libraries"}, + {"PR_INSUFFICIENT_RESOURCES_ERROR", "Insufficient system resources"}, + {"PR_DIRECTORY_LOOKUP_ERROR", "A directory lookup on a network address has failed"}, + {"PR_TPD_RANGE_ERROR", "Attempt to access a TPD key that is out of range"}, + {"PR_PROC_DESC_TABLE_FULL_ERROR", "Process open FD table is full"}, + {"PR_SYS_DESC_TABLE_FULL_ERROR", "System open FD table is full"}, + {"PR_NOT_SOCKET_ERROR", "Network operation attempted on non-network file descriptor"}, + {"PR_NOT_TCP_SOCKET_ERROR", "TCP-specific function attempted on a non-TCP file descriptor"}, + {"PR_SOCKET_ADDRESS_IS_BOUND_ERROR", "TCP file descriptor is already bound"}, + {"PR_NO_ACCESS_RIGHTS_ERROR", "Access Denied"}, + {"PR_OPERATION_NOT_SUPPORTED_ERROR", "The requested operation is not supported by the platform"}, + {"PR_PROTOCOL_NOT_SUPPORTED_ERROR", "The host operating system does not support the protocol requested"}, + {"PR_REMOTE_FILE_ERROR", "Access to the remote file has been severed"}, + {"PR_BUFFER_OVERFLOW_ERROR", "The value requested is too large to be stored in the data buffer provided"}, + {"PR_CONNECT_RESET_ERROR", "TCP connection reset by peer"}, + {"PR_RANGE_ERROR", "Unused"}, + {"PR_DEADLOCK_ERROR", "The operation would have deadlocked"}, + {"PR_FILE_IS_LOCKED_ERROR", "The file is already locked"}, + {"PR_FILE_TOO_BIG_ERROR", "Write would result in file larger than the system allows"}, + {"PR_NO_DEVICE_SPACE_ERROR", "The device for storing the file is full"}, + {"PR_PIPE_ERROR", "Unused"}, + {"PR_NO_SEEK_DEVICE_ERROR", "Unused"}, + {"PR_IS_DIRECTORY_ERROR", "Cannot perform a normal file operation on a directory"}, + {"PR_LOOP_ERROR", "Symbolic link loop"}, + {"PR_NAME_TOO_LONG_ERROR", "File name is too long"}, + {"PR_FILE_NOT_FOUND_ERROR", "File not found"}, + {"PR_NOT_DIRECTORY_ERROR", "Cannot perform directory operation on a normal file"}, + {"PR_READ_ONLY_FILESYSTEM_ERROR", "Cannot write to a read-only file system"}, + {"PR_DIRECTORY_NOT_EMPTY_ERROR", "Cannot delete a directory that is not empty"}, + {"PR_FILESYSTEM_MOUNTED_ERROR", "Cannot delete or rename a file object while the file system is busy"}, + {"PR_NOT_SAME_DEVICE_ERROR", "Cannot rename a file to a file system on another device"}, + {"PR_DIRECTORY_CORRUPTED_ERROR", "The directory object in the file system is corrupted"}, + {"PR_FILE_EXISTS_ERROR", "Cannot create or rename a filename that already exists"}, + {"PR_MAX_DIRECTORY_ENTRIES_ERROR", "Directory is full. No additional filenames may be added"}, + {"PR_INVALID_DEVICE_STATE_ERROR", "The required device was in an invalid state"}, + {"PR_DEVICE_IS_LOCKED_ERROR", "The device is locked"}, + {"PR_NO_MORE_FILES_ERROR", "No more entries in the directory"}, + {"PR_END_OF_FILE_ERROR", "Encountered end of file"}, + {"PR_FILE_SEEK_ERROR", "Seek error"}, + {"PR_FILE_IS_BUSY_ERROR", "The file is busy"}, + {"PR_OPERATION_ABORTED_ERROR", "The I/O operation was aborted"}, + {"PR_IN_PROGRESS_ERROR", "Operation is still in progress (probably a non-blocking connect)"}, + {"PR_ALREADY_INITIATED_ERROR", "Operation has already been initiated (probably a non-blocking connect)"}, + {"PR_GROUP_EMPTY_ERROR", "The wait group is empty"}, + {"PR_INVALID_STATE_ERROR", "Object state improper for request"}, + {"PR_NETWORK_DOWN_ERROR", "Network is down"}, + {"PR_SOCKET_SHUTDOWN_ERROR", "Socket shutdown"}, + {"PR_CONNECT_ABORTED_ERROR", "Connection aborted"}, + {"PR_HOST_UNREACHABLE_ERROR", "Host is unreachable"}, + {"PR_LIBRARY_NOT_LOADED_ERROR", "The library is not loaded"}, + {"PR_CALL_ONCE_ERROR", "The one-time function was previously called and failed. Its error code is no longer available"}, + {"PR_MAX_ERROR", "Placeholder for the end of the list"}, + {0, 0} +}; + +static const struct PRErrorTable et = { text, "prerr", -6000L, 77 }; + +void nspr_InitializePRErrorTable(void) { + PR_ErrorInstallTable(&et); +} diff -Nru nspr-4.9.5/nspr/pr/src/misc/prerr.et nspr-4.10.7/nspr/pr/src/misc/prerr.et --- nspr-4.9.5/nspr/pr/src/misc/prerr.et 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prerr.et 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,108 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +et nspr -6000 + +ec PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed" +ec PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor" +ec PR_WOULD_BLOCK_ERROR, "The operation would have blocked" +ec PR_ACCESS_FAULT_ERROR, "Invalid memory address argument" +ec PR_INVALID_METHOD_ERROR, "Invalid function for file type" +ec PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument" +ec PR_UNKNOWN_ERROR, "Some unknown error has occurred" +ec PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread" +ec PR_NOT_IMPLEMENTED_ERROR, "function not implemented" +ec PR_IO_ERROR, "I/O function error" +ec PR_IO_TIMEOUT_ERROR, "I/O operation timed out" +ec PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor" +ec PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened" +ec PR_INVALID_ARGUMENT_ERROR, "Invalid function argument" +ec PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)" +ec PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported" +ec PR_IS_CONNECTED_ERROR, "Already connected" +ec PR_BAD_ADDRESS_ERROR, "Network address is invalid" +ec PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use" +ec PR_CONNECT_REFUSED_ERROR, "Connection refused by peer" +ec PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable" +ec PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out" +ec PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected" +ec PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library" +ec PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library" +ec PR_FIND_SYMBOL_ERROR, +"Symbol not found in any of the loaded dynamic libraries" +ec PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources" +ec PR_DIRECTORY_LOOKUP_ERROR, +"A directory lookup on a network address has failed" +ec PR_TPD_RANGE_ERROR, +"Attempt to access a TPD key that is out of range" +ec PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full" +ec PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full" +ec PR_NOT_SOCKET_ERROR, +"Network operation attempted on non-network file descriptor" +ec PR_NOT_TCP_SOCKET_ERROR, +"TCP-specific function attempted on a non-TCP file descriptor" +ec PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound" +ec PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied" +ec PR_OPERATION_NOT_SUPPORTED_ERROR, +"The requested operation is not supported by the platform" +ec PR_PROTOCOL_NOT_SUPPORTED_ERROR, +"The host operating system does not support the protocol requested" +ec PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed" +ec PR_BUFFER_OVERFLOW_ERROR, +"The value requested is too large to be stored in the data buffer provided" +ec PR_CONNECT_RESET_ERROR, "TCP connection reset by peer" +ec PR_RANGE_ERROR, "Unused" +ec PR_DEADLOCK_ERROR, "The operation would have deadlocked" +ec PR_FILE_IS_LOCKED_ERROR, "The file is already locked" +ec PR_FILE_TOO_BIG_ERROR, +"Write would result in file larger than the system allows" +ec PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full" +ec PR_PIPE_ERROR, "Unused" +ec PR_NO_SEEK_DEVICE_ERROR, "Unused" +ec PR_IS_DIRECTORY_ERROR, +"Cannot perform a normal file operation on a directory" +ec PR_LOOP_ERROR, "Symbolic link loop" +ec PR_NAME_TOO_LONG_ERROR, "File name is too long" +ec PR_FILE_NOT_FOUND_ERROR, "File not found" +ec PR_NOT_DIRECTORY_ERROR, +"Cannot perform directory operation on a normal file" +ec PR_READ_ONLY_FILESYSTEM_ERROR, +"Cannot write to a read-only file system" +ec PR_DIRECTORY_NOT_EMPTY_ERROR, +"Cannot delete a directory that is not empty" +ec PR_FILESYSTEM_MOUNTED_ERROR, +"Cannot delete or rename a file object while the file system is busy" +ec PR_NOT_SAME_DEVICE_ERROR, +"Cannot rename a file to a file system on another device" +ec PR_DIRECTORY_CORRUPTED_ERROR, +"The directory object in the file system is corrupted" +ec PR_FILE_EXISTS_ERROR, +"Cannot create or rename a filename that already exists" +ec PR_MAX_DIRECTORY_ENTRIES_ERROR, +"Directory is full. No additional filenames may be added" +ec PR_INVALID_DEVICE_STATE_ERROR, +"The required device was in an invalid state" +ec PR_DEVICE_IS_LOCKED_ERROR, "The device is locked" +ec PR_NO_MORE_FILES_ERROR, "No more entries in the directory" +ec PR_END_OF_FILE_ERROR, "Encountered end of file" +ec PR_FILE_SEEK_ERROR, "Seek error" +ec PR_FILE_IS_BUSY_ERROR, "The file is busy" +ec PR_OPERATION_ABORTED_ERROR, "The I/O operation was aborted" +ec PR_IN_PROGRESS_ERROR, +"Operation is still in progress (probably a non-blocking connect)" +ec PR_ALREADY_INITIATED_ERROR, +"Operation has already been initiated (probably a non-blocking connect)" +ec PR_GROUP_EMPTY_ERROR, "The wait group is empty" +ec PR_INVALID_STATE_ERROR, "Object state improper for request" +ec PR_NETWORK_DOWN_ERROR, "Network is down" +ec PR_SOCKET_SHUTDOWN_ERROR, "Socket shutdown" +ec PR_CONNECT_ABORTED_ERROR, "Connection aborted" +ec PR_HOST_UNREACHABLE_ERROR, "Host is unreachable" +ec PR_LIBRARY_NOT_LOADED_ERROR, "The library is not loaded" +ec PR_CALL_ONCE_ERROR, "The one-time function was previously called and failed. Its error code is no longer available" + +ec PR_MAX_ERROR, "Placeholder for the end of the list" + +end diff -Nru nspr-4.9.5/nspr/pr/src/misc/prerror.c nspr-4.10.7/nspr/pr/src/misc/prerror.c --- nspr-4.9.5/nspr/pr/src/misc/prerror.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prerror.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include + +PR_IMPLEMENT(PRErrorCode) PR_GetError(void) +{ + PRThread *thread = PR_GetCurrentThread(); + return thread->errorCode; +} + +PR_IMPLEMENT(PRInt32) PR_GetOSError(void) +{ + PRThread *thread = PR_GetCurrentThread(); + return thread->osErrorCode; +} + +PR_IMPLEMENT(void) PR_SetError(PRErrorCode code, PRInt32 osErr) +{ + PRThread *thread = PR_GetCurrentThread(); + thread->errorCode = code; + thread->osErrorCode = osErr; + thread->errorStringLength = 0; +} + +PR_IMPLEMENT(void) PR_SetErrorText(PRIntn textLength, const char *text) +{ + PRThread *thread = PR_GetCurrentThread(); + + if (0 == textLength) + { + if (NULL != thread->errorString) + PR_DELETE(thread->errorString); + thread->errorStringSize = 0; + } + else + { + PRIntn size = textLength + 31; /* actual length to allocate. Plus a little extra */ + if (thread->errorStringSize < textLength+1) /* do we have room? */ + { + if (NULL != thread->errorString) + PR_DELETE(thread->errorString); + thread->errorString = (char*)PR_MALLOC(size); + if ( NULL == thread->errorString ) { + thread->errorStringSize = 0; + thread->errorStringLength = 0; + return; + } + thread->errorStringSize = size; + } + memcpy(thread->errorString, text, textLength+1 ); + } + thread->errorStringLength = textLength; +} + +PR_IMPLEMENT(PRInt32) PR_GetErrorTextLength(void) +{ + PRThread *thread = PR_GetCurrentThread(); + return thread->errorStringLength; +} /* PR_GetErrorTextLength */ + +PR_IMPLEMENT(PRInt32) PR_GetErrorText(char *text) +{ + PRThread *thread = PR_GetCurrentThread(); + if (0 != thread->errorStringLength) + memcpy(text, thread->errorString, thread->errorStringLength+1); + return thread->errorStringLength; +} /* PR_GetErrorText */ + + diff -Nru nspr-4.9.5/nspr/pr/src/misc/prerrortable.c nspr-4.10.7/nspr/pr/src/misc/prerrortable.c --- nspr-4.9.5/nspr/pr/src/misc/prerrortable.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prerrortable.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,205 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + + + +/* + +Copyright 1987, 1988 by the Student Information Processing Board + of the Massachusetts Institute of Technology + +Permission to use, copy, modify, and distribute this software +and its documentation for any purpose and without fee is +hereby granted, provided that the above copyright notice +appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, +and that the names of M.I.T. and the M.I.T. S.I.P.B. not be +used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. +M.I.T. and the M.I.T. S.I.P.B. make no representations about +the suitability of this software for any purpose. It is +provided "as is" without express or implied warranty. + +*/ + +#include +#include +#include +#include "prmem.h" +#include "prerror.h" + +#define ERRCODE_RANGE 8 /* # of bits to shift table number */ +#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ + +#ifdef NEED_SYS_ERRLIST +extern char const * const sys_errlist[]; +extern const int sys_nerr; +#endif + +/* List of error tables */ +struct PRErrorTableList { + struct PRErrorTableList *next; + const struct PRErrorTable *table; + struct PRErrorCallbackTablePrivate *table_private; +}; +static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL; + +/* Supported languages */ +static const char * default_languages[] = { "i-default", "en", 0 }; +static const char * const * callback_languages = default_languages; + +/* Callback info */ +static struct PRErrorCallbackPrivate *callback_private = 0; +static PRErrorCallbackLookupFn *callback_lookup = 0; +static PRErrorCallbackNewTableFn *callback_newtable = 0; + + +static const char char_set[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + +static const char * +error_table_name (PRErrorCode num) +{ + static char buf[6]; /* only used if internal code problems exist */ + + long ch; + int i; + char *p; + + /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */ + p = buf; + num >>= ERRCODE_RANGE; + /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */ + num &= 077777777; + /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ + for (i = 4; i >= 0; i--) { + ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); + if (ch != 0) + *p++ = char_set[ch-1]; + } + *p = '\0'; + return(buf); +} + +PR_IMPLEMENT(const char *) +PR_ErrorToString(PRErrorCode code, PRLanguageCode language) +{ + /* static buffer only used if code is using inconsistent error message + * numbers, so just ignore the possible thread contention + */ + static char buffer[25]; + + const char *msg; + int offset; + PRErrorCode table_num; + struct PRErrorTableList *et; + int started = 0; + char *cp; + + for (et = Table_List; et; et = et->next) { + if (et->table->base <= code && + et->table->base + et->table->n_msgs > code) { + /* This is the right table */ + if (callback_lookup) { + msg = callback_lookup(code, language, et->table, + callback_private, et->table_private); + if (msg) return msg; + } + + return(et->table->msgs[code - et->table->base].en_text); + } + } + + if (code >= 0 && code < 256) { + return strerror(code); + } + + offset = (int) (code & ((1<= 100) { + *cp++ = (char)('0' + offset / 100); + offset %= 100; + started++; + } + if (started || offset >= 10) { + *cp++ = (char)('0' + offset / 10); + offset %= 10; + } + *cp++ = (char)('0' + offset); + *cp = '\0'; + return(buffer); +} + +PR_IMPLEMENT(const char *) +PR_ErrorToName(PRErrorCode code) +{ + struct PRErrorTableList *et; + + for (et = Table_List; et; et = et->next) { + if (et->table->base <= code && + et->table->base + et->table->n_msgs > code) { + /* This is the right table */ + return(et->table->msgs[code - et->table->base].name); + } + } + + return 0; +} + +PR_IMPLEMENT(const char * const *) +PR_ErrorLanguages(void) +{ + return callback_languages; +} + +PR_IMPLEMENT(PRErrorCode) +PR_ErrorInstallTable(const struct PRErrorTable *table) +{ + struct PRErrorTableList * new_et; + + new_et = (struct PRErrorTableList *) + PR_Malloc(sizeof(struct PRErrorTableList)); + if (!new_et) + return errno; /* oops */ + new_et->table = table; + if (callback_newtable) { + new_et->table_private = callback_newtable(table, callback_private); + } else { + new_et->table_private = 0; + } + new_et->next = Table_List; + Table_List = new_et; + return 0; +} + +PR_IMPLEMENT(void) +PR_ErrorInstallCallback(const char * const * languages, + PRErrorCallbackLookupFn *lookup, + PRErrorCallbackNewTableFn *newtable, + struct PRErrorCallbackPrivate *cb_private) +{ + struct PRErrorTableList *et; + + assert(strcmp(languages[0], "i-default") == 0); + assert(strcmp(languages[1], "en") == 0); + + callback_languages = languages; + callback_lookup = lookup; + callback_newtable = newtable; + callback_private = cb_private; + + if (callback_newtable) { + for (et = Table_List; et; et = et->next) { + et->table_private = callback_newtable(et->table, callback_private); + } + } +} diff -Nru nspr-4.9.5/nspr/pr/src/misc/prerr.properties nspr-4.10.7/nspr/pr/src/misc/prerr.properties --- nspr-4.9.5/nspr/pr/src/misc/prerr.properties 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prerr.properties 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,85 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# +# prerr.properties +# This file is automatically generated; please do not edit it. +PR_OUT_OF_MEMORY_ERROR=Memory allocation attempt failed +PR_BAD_DESCRIPTOR_ERROR=Invalid file descriptor +PR_WOULD_BLOCK_ERROR=The operation would have blocked +PR_ACCESS_FAULT_ERROR=Invalid memory address argument +PR_INVALID_METHOD_ERROR=Invalid function for file type +PR_ILLEGAL_ACCESS_ERROR=Invalid memory address argument +PR_UNKNOWN_ERROR=Some unknown error has occurred +PR_PENDING_INTERRUPT_ERROR=Operation interrupted by another thread +PR_NOT_IMPLEMENTED_ERROR=function not implemented +PR_IO_ERROR=I/O function error +PR_IO_TIMEOUT_ERROR=I/O operation timed out +PR_IO_PENDING_ERROR=I/O operation on busy file descriptor +PR_DIRECTORY_OPEN_ERROR=The directory could not be opened +PR_INVALID_ARGUMENT_ERROR=Invalid function argument +PR_ADDRESS_NOT_AVAILABLE_ERROR=Network address not available (in use?) +PR_ADDRESS_NOT_SUPPORTED_ERROR=Network address type not supported +PR_IS_CONNECTED_ERROR=Already connected +PR_BAD_ADDRESS_ERROR=Network address is invalid +PR_ADDRESS_IN_USE_ERROR=Local Network address is in use +PR_CONNECT_REFUSED_ERROR=Connection refused by peer +PR_NETWORK_UNREACHABLE_ERROR=Network address is presently unreachable +PR_CONNECT_TIMEOUT_ERROR=Connection attempt timed out +PR_NOT_CONNECTED_ERROR=Network file descriptor is not connected +PR_LOAD_LIBRARY_ERROR=Failure to load dynamic library +PR_UNLOAD_LIBRARY_ERROR=Failure to unload dynamic library +PR_FIND_SYMBOL_ERROR=Symbol not found in any of the loaded dynamic libraries +PR_INSUFFICIENT_RESOURCES_ERROR=Insufficient system resources +PR_DIRECTORY_LOOKUP_ERROR=A directory lookup on a network address has failed +PR_TPD_RANGE_ERROR=Attempt to access a TPD key that is out of range +PR_PROC_DESC_TABLE_FULL_ERROR=Process open FD table is full +PR_SYS_DESC_TABLE_FULL_ERROR=System open FD table is full +PR_NOT_SOCKET_ERROR=Network operation attempted on non-network file descriptor +PR_NOT_TCP_SOCKET_ERROR=TCP-specific function attempted on a non-TCP file descriptor +PR_SOCKET_ADDRESS_IS_BOUND_ERROR=TCP file descriptor is already bound +PR_NO_ACCESS_RIGHTS_ERROR=Access Denied +PR_OPERATION_NOT_SUPPORTED_ERROR=The requested operation is not supported by the platform +PR_PROTOCOL_NOT_SUPPORTED_ERROR=The host operating system does not support the protocol requested +PR_REMOTE_FILE_ERROR=Access to the remote file has been severed +PR_BUFFER_OVERFLOW_ERROR=The value requested is too large to be stored in the data buffer provided +PR_CONNECT_RESET_ERROR=TCP connection reset by peer +PR_RANGE_ERROR=Unused +PR_DEADLOCK_ERROR=The operation would have deadlocked +PR_FILE_IS_LOCKED_ERROR=The file is already locked +PR_FILE_TOO_BIG_ERROR=Write would result in file larger than the system allows +PR_NO_DEVICE_SPACE_ERROR=The device for storing the file is full +PR_PIPE_ERROR=Unused +PR_NO_SEEK_DEVICE_ERROR=Unused +PR_IS_DIRECTORY_ERROR=Cannot perform a normal file operation on a directory +PR_LOOP_ERROR=Symbolic link loop +PR_NAME_TOO_LONG_ERROR=File name is too long +PR_FILE_NOT_FOUND_ERROR=File not found +PR_NOT_DIRECTORY_ERROR=Cannot perform directory operation on a normal file +PR_READ_ONLY_FILESYSTEM_ERROR=Cannot write to a read-only file system +PR_DIRECTORY_NOT_EMPTY_ERROR=Cannot delete a directory that is not empty +PR_FILESYSTEM_MOUNTED_ERROR=Cannot delete or rename a file object while the file system is busy +PR_NOT_SAME_DEVICE_ERROR=Cannot rename a file to a file system on another device +PR_DIRECTORY_CORRUPTED_ERROR=The directory object in the file system is corrupted +PR_FILE_EXISTS_ERROR=Cannot create or rename a filename that already exists +PR_MAX_DIRECTORY_ENTRIES_ERROR=Directory is full. No additional filenames may be added +PR_INVALID_DEVICE_STATE_ERROR=The required device was in an invalid state +PR_DEVICE_IS_LOCKED_ERROR=The device is locked +PR_NO_MORE_FILES_ERROR=No more entries in the directory +PR_END_OF_FILE_ERROR=Encountered end of file +PR_FILE_SEEK_ERROR=Seek error +PR_FILE_IS_BUSY_ERROR=The file is busy +PR_OPERATION_ABORTED_ERROR=The I/O operation was aborted +PR_IN_PROGRESS_ERROR=Operation is still in progress (probably a non-blocking connect) +PR_ALREADY_INITIATED_ERROR=Operation has already been initiated (probably a non-blocking connect) +PR_GROUP_EMPTY_ERROR=The wait group is empty +PR_INVALID_STATE_ERROR=Object state improper for request +PR_NETWORK_DOWN_ERROR=Network is down +PR_SOCKET_SHUTDOWN_ERROR=Socket shutdown +PR_CONNECT_ABORTED_ERROR=Connection aborted +PR_HOST_UNREACHABLE_ERROR=Host is unreachable +PR_LIBRARY_NOT_LOADED_ERROR=The library is not loaded +PR_CALL_ONCE_ERROR=The one-time function was previously called and failed. Its error code is no longer available +PR_MAX_ERROR=Placeholder for the end of the list diff -Nru nspr-4.9.5/nspr/pr/src/misc/prinit.c nspr-4.10.7/nspr/pr/src/misc/prinit.c --- nspr-4.9.5/nspr/pr/src/misc/prinit.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prinit.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,836 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include +#include + +PRLogModuleInfo *_pr_clock_lm; +PRLogModuleInfo *_pr_cmon_lm; +PRLogModuleInfo *_pr_io_lm; +PRLogModuleInfo *_pr_cvar_lm; +PRLogModuleInfo *_pr_mon_lm; +PRLogModuleInfo *_pr_linker_lm; +PRLogModuleInfo *_pr_sched_lm; +PRLogModuleInfo *_pr_thread_lm; +PRLogModuleInfo *_pr_gc_lm; +PRLogModuleInfo *_pr_shm_lm; +PRLogModuleInfo *_pr_shma_lm; + +PRFileDesc *_pr_stdin; +PRFileDesc *_pr_stdout; +PRFileDesc *_pr_stderr; + +#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) + +PRCList _pr_active_local_threadQ = + PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ); +PRCList _pr_active_global_threadQ = + PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ); + +_MDLock _pr_cpuLock; /* lock for the CPU Q */ +PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ); + +PRUint32 _pr_utid; + +PRInt32 _pr_userActive; +PRInt32 _pr_systemActive; +PRUintn _pr_maxPTDs; + +#ifdef _PR_LOCAL_THREADS_ONLY + +struct _PRCPU *_pr_currentCPU; +PRThread *_pr_currentThread; +PRThread *_pr_lastThread; +PRInt32 _pr_intsOff; + +#endif /* _PR_LOCAL_THREADS_ONLY */ + +/* Lock protecting all "termination" condition variables of all threads */ +PRLock *_pr_terminationCVLock; + +#endif /* !defined(_PR_PTHREADS) */ + +PRLock *_pr_sleeplock; /* used in PR_Sleep(), classic and pthreads */ + +static void _PR_InitCallOnce(void); + +PRBool _pr_initialized = PR_FALSE; + + +PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion) +{ + /* + ** This is the secret handshake algorithm. + ** + ** This release has a simple version compatibility + ** check algorithm. This release is not backward + ** compatible with previous major releases. It is + ** not compatible with future major, minor, or + ** patch releases. + */ + int vmajor = 0, vminor = 0, vpatch = 0; + const char *ptr = importedVersion; + + while (isdigit(*ptr)) { + vmajor = 10 * vmajor + *ptr - '0'; + ptr++; + } + if (*ptr == '.') { + ptr++; + while (isdigit(*ptr)) { + vminor = 10 * vminor + *ptr - '0'; + ptr++; + } + if (*ptr == '.') { + ptr++; + while (isdigit(*ptr)) { + vpatch = 10 * vpatch + *ptr - '0'; + ptr++; + } + } + } + + if (vmajor != PR_VMAJOR) { + return PR_FALSE; + } + if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) { + return PR_FALSE; + } + if (vmajor == PR_VMAJOR && vminor == PR_VMINOR && vpatch > PR_VPATCH) { + return PR_FALSE; + } + return PR_TRUE; +} /* PR_VersionCheck */ + +PR_IMPLEMENT(const char*) PR_GetVersion(void) +{ + return PR_VERSION; +} + +PR_IMPLEMENT(PRBool) PR_Initialized(void) +{ + return _pr_initialized; +} + +PRInt32 _native_threads_only = 0; + +#ifdef WINNT +static void _pr_SetNativeThreadsOnlyMode(void) +{ + HMODULE mainExe; + PRBool *globalp; + char *envp; + + mainExe = GetModuleHandle(NULL); + PR_ASSERT(NULL != mainExe); + globalp = (PRBool *) GetProcAddress(mainExe, "nspr_native_threads_only"); + if (globalp) { + _native_threads_only = (*globalp != PR_FALSE); + } else if (envp = getenv("NSPR_NATIVE_THREADS_ONLY")) { + _native_threads_only = (atoi(envp) == 1); + } +} +#endif + +static void _PR_InitStuff(void) +{ + + if (_pr_initialized) return; + _pr_initialized = PR_TRUE; +#ifdef _PR_ZONE_ALLOCATOR + _PR_InitZones(); +#endif +#ifdef WINNT + _pr_SetNativeThreadsOnlyMode(); +#endif + + + (void) PR_GetPageSize(); + + _pr_clock_lm = PR_NewLogModule("clock"); + _pr_cmon_lm = PR_NewLogModule("cmon"); + _pr_io_lm = PR_NewLogModule("io"); + _pr_mon_lm = PR_NewLogModule("mon"); + _pr_linker_lm = PR_NewLogModule("linker"); + _pr_cvar_lm = PR_NewLogModule("cvar"); + _pr_sched_lm = PR_NewLogModule("sched"); + _pr_thread_lm = PR_NewLogModule("thread"); + _pr_gc_lm = PR_NewLogModule("gc"); + _pr_shm_lm = PR_NewLogModule("shm"); + _pr_shma_lm = PR_NewLogModule("shma"); + + /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */ + _PR_MD_EARLY_INIT(); + + _PR_InitLocks(); + _PR_InitAtomic(); + _PR_InitSegs(); + _PR_InitStacks(); + _PR_InitTPD(); + _PR_InitEnv(); + _PR_InitLayerCache(); + _PR_InitClock(); + + _pr_sleeplock = PR_NewLock(); + PR_ASSERT(NULL != _pr_sleeplock); + + _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + +#ifdef WIN16 + { + PRInt32 top; /* artificial top of stack, win16 */ + _pr_top_of_task_stack = (char *) ⊤ + } +#endif + +#ifndef _PR_GLOBAL_THREADS_ONLY + _PR_InitCPUs(); +#endif + +/* + * XXX: call _PR_InitMem only on those platforms for which nspr implements + * malloc, for now. + */ +#ifdef _PR_OVERRIDE_MALLOC + _PR_InitMem(); +#endif + + _PR_InitCMon(); + _PR_InitIO(); + _PR_InitNet(); + _PR_InitTime(); + _PR_InitLog(); + _PR_InitLinker(); + _PR_InitCallOnce(); + _PR_InitDtoa(); + _PR_InitMW(); + _PR_InitRWLocks(); + + nspr_InitializePRErrorTable(); + + _PR_MD_FINAL_INIT(); +} + +void _PR_ImplicitInitialization(void) +{ + _PR_InitStuff(); + + /* Enable interrupts */ +#if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) + _PR_MD_START_INTERRUPTS(); +#endif + +} + +PR_IMPLEMENT(void) PR_DisableClockInterrupts(void) +{ +#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) + if (!_pr_initialized) { + _PR_InitStuff(); + } else { + _PR_MD_DISABLE_CLOCK_INTERRUPTS(); + } +#endif +} + +PR_IMPLEMENT(void) PR_EnableClockInterrupts(void) +{ +#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) + if (!_pr_initialized) { + _PR_InitStuff(); + } + _PR_MD_ENABLE_CLOCK_INTERRUPTS(); +#endif +} + +PR_IMPLEMENT(void) PR_BlockClockInterrupts(void) +{ +#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) + _PR_MD_BLOCK_CLOCK_INTERRUPTS(); +#endif +} + +PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void) +{ +#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) + _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(); +#endif +} + +PR_IMPLEMENT(void) PR_Init( + PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs) +{ + _PR_ImplicitInitialization(); +} + +PR_IMPLEMENT(PRIntn) PR_Initialize( + PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs) +{ + PRIntn rv; + _PR_ImplicitInitialization(); + rv = prmain(argc, argv); + PR_Cleanup(); + return rv; +} /* PR_Initialize */ + +/* + *----------------------------------------------------------------------- + * + * _PR_CleanupBeforeExit -- + * + * Perform the cleanup work before exiting the process. + * We first do the cleanup generic to all platforms. Then + * we call _PR_MD_CLEANUP_BEFORE_EXIT(), where platform-dependent + * cleanup is done. This function is used by PR_Cleanup(). + * + * See also: PR_Cleanup(). + * + *----------------------------------------------------------------------- + */ +#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) + /* see ptthread.c */ +#else +static void +_PR_CleanupBeforeExit(void) +{ +/* +Do not make any calls here other than to destroy resources. For example, +do not make any calls that eventually may end up in PR_Lock. Because the +thread is destroyed, can not access current thread any more. +*/ + _PR_CleanupTPD(); + if (_pr_terminationCVLock) + /* + * In light of the comment above, this looks real suspicious. + * I'd go so far as to say it's just a problem waiting to happen. + */ + PR_DestroyLock(_pr_terminationCVLock); + + _PR_MD_CLEANUP_BEFORE_EXIT(); +} +#endif /* defined(_PR_PTHREADS) */ + +/* + *---------------------------------------------------------------------- + * + * PR_Cleanup -- + * + * Perform a graceful shutdown of the NSPR runtime. PR_Cleanup() may + * only be called from the primordial thread, typically at the + * end of the main() function. It returns when it has completed + * its platform-dependent duty and the process must not make any other + * NSPR library calls prior to exiting from main(). + * + * PR_Cleanup() first blocks the primordial thread until all the + * other user (non-system) threads, if any, have terminated. + * Then it performs cleanup in preparation for exiting the process. + * PR_Cleanup() does not exit the primordial thread (which would + * in turn exit the process). + * + * PR_Cleanup() only responds when it is called by the primordial + * thread. Calls by any other thread are silently ignored. + * + * See also: PR_ExitProcess() + * + *---------------------------------------------------------------------- + */ +#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) + /* see ptthread.c */ +#else + +PR_IMPLEMENT(PRStatus) PR_Cleanup() +{ + PRThread *me = PR_GetCurrentThread(); + PR_ASSERT((NULL != me) && (me->flags & _PR_PRIMORDIAL)); + if ((NULL != me) && (me->flags & _PR_PRIMORDIAL)) + { + PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR")); + + /* + * No more recycling of threads + */ + _pr_recycleThreads = 0; + + /* + * Wait for all other user (non-system/daemon) threads + * to terminate. + */ + PR_Lock(_pr_activeLock); + while (_pr_userActive > _pr_primordialExitCount) { + PR_WaitCondVar(_pr_primordialExitCVar, PR_INTERVAL_NO_TIMEOUT); + } + if (me->flags & _PR_SYSTEM) { + _pr_systemActive--; + } else { + _pr_userActive--; + } + PR_Unlock(_pr_activeLock); + +#ifdef IRIX + _PR_MD_PRE_CLEANUP(me); + /* + * The primordial thread must now be running on the primordial cpu + */ + PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0)); +#endif + + _PR_MD_EARLY_CLEANUP(); + + _PR_CleanupMW(); + _PR_CleanupTime(); + _PR_CleanupDtoa(); + _PR_CleanupCallOnce(); + _PR_ShutdownLinker(); + _PR_CleanupNet(); + _PR_CleanupIO(); + /* Release the primordial thread's private data, etc. */ + _PR_CleanupThread(me); + + _PR_MD_STOP_INTERRUPTS(); + + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("PR_Cleanup: clean up before destroying thread")); + _PR_LogCleanup(); + + /* + * This part should look like the end of _PR_NativeRunThread + * and _PR_UserRunThread. + */ + if (_PR_IS_NATIVE_THREAD(me)) { + _PR_MD_EXIT_THREAD(me); + _PR_NativeDestroyThread(me); + } else { + _PR_UserDestroyThread(me); + PR_DELETE(me->stack); + PR_DELETE(me); + } + + /* + * XXX: We are freeing the heap memory here so that Purify won't + * complain, but we should also free other kinds of resources + * that are allocated by the _PR_InitXXX() functions. + * Ideally, for each _PR_InitXXX(), there should be a corresponding + * _PR_XXXCleanup() that we can call here. + */ +#ifdef WINNT + _PR_CleanupCPUs(); +#endif + _PR_CleanupThreads(); + _PR_CleanupCMon(); + PR_DestroyLock(_pr_sleeplock); + _pr_sleeplock = NULL; + _PR_CleanupLayerCache(); + _PR_CleanupEnv(); + _PR_CleanupStacks(); + _PR_CleanupBeforeExit(); + _pr_initialized = PR_FALSE; + return PR_SUCCESS; + } + return PR_FAILURE; +} +#endif /* defined(_PR_PTHREADS) */ + +/* + *------------------------------------------------------------------------ + * PR_ProcessExit -- + * + * Cause an immediate, nongraceful, forced termination of the process. + * It takes a PRIntn argument, which is the exit status code of the + * process. + * + * See also: PR_Cleanup() + * + *------------------------------------------------------------------------ + */ + +#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) + /* see ptthread.c */ +#else +PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status) +{ + _PR_MD_EXIT(status); +} + +#endif /* defined(_PR_PTHREADS) */ + +PR_IMPLEMENT(PRProcessAttr *) +PR_NewProcessAttr(void) +{ + PRProcessAttr *attr; + + attr = PR_NEWZAP(PRProcessAttr); + if (!attr) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + } + return attr; +} + +PR_IMPLEMENT(void) +PR_ResetProcessAttr(PRProcessAttr *attr) +{ + PR_FREEIF(attr->currentDirectory); + PR_FREEIF(attr->fdInheritBuffer); + memset(attr, 0, sizeof(*attr)); +} + +PR_IMPLEMENT(void) +PR_DestroyProcessAttr(PRProcessAttr *attr) +{ + PR_FREEIF(attr->currentDirectory); + PR_FREEIF(attr->fdInheritBuffer); + PR_DELETE(attr); +} + +PR_IMPLEMENT(void) +PR_ProcessAttrSetStdioRedirect( + PRProcessAttr *attr, + PRSpecialFD stdioFd, + PRFileDesc *redirectFd) +{ + switch (stdioFd) { + case PR_StandardInput: + attr->stdinFd = redirectFd; + break; + case PR_StandardOutput: + attr->stdoutFd = redirectFd; + break; + case PR_StandardError: + attr->stderrFd = redirectFd; + break; + default: + PR_ASSERT(0); + } +} + +/* + * OBSOLETE + */ +PR_IMPLEMENT(void) +PR_SetStdioRedirect( + PRProcessAttr *attr, + PRSpecialFD stdioFd, + PRFileDesc *redirectFd) +{ +#if defined(DEBUG) + static PRBool warn = PR_TRUE; + if (warn) { + warn = _PR_Obsolete("PR_SetStdioRedirect()", + "PR_ProcessAttrSetStdioRedirect()"); + } +#endif + PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd); +} + +PR_IMPLEMENT(PRStatus) +PR_ProcessAttrSetCurrentDirectory( + PRProcessAttr *attr, + const char *dir) +{ + PR_FREEIF(attr->currentDirectory); + attr->currentDirectory = (char *) PR_MALLOC(strlen(dir) + 1); + if (!attr->currentDirectory) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return PR_FAILURE; + } + strcpy(attr->currentDirectory, dir); + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) +PR_ProcessAttrSetInheritableFD( + PRProcessAttr *attr, + PRFileDesc *fd, + const char *name) +{ + /* We malloc the fd inherit buffer in multiples of this number. */ +#define FD_INHERIT_BUFFER_INCR 128 + /* The length of "NSPR_INHERIT_FDS=" */ +#define NSPR_INHERIT_FDS_STRLEN 17 + /* The length of osfd (PROsfd) printed in hexadecimal with 0x prefix */ +#ifdef _WIN64 +#define OSFD_STRLEN 18 +#else +#define OSFD_STRLEN 10 +#endif + /* The length of fd type (PRDescType) printed in decimal */ +#define FD_TYPE_STRLEN 1 + PRSize newSize; + int remainder; + char *newBuffer; + int nwritten; + char *cur; + int freeSize; + + if (fd->identity != PR_NSPR_IO_LAYER) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + if (fd->secret->inheritable == _PR_TRI_UNKNOWN) { + _PR_MD_QUERY_FD_INHERITABLE(fd); + } + if (fd->secret->inheritable != _PR_TRI_TRUE) { + PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0); + return PR_FAILURE; + } + + /* + * We also need to account for the : separators and the + * terminating null byte. + */ + if (NULL == attr->fdInheritBuffer) { + /* The first time, we print "NSPR_INHERIT_FDS=::" */ + newSize = NSPR_INHERIT_FDS_STRLEN + strlen(name) + + FD_TYPE_STRLEN + OSFD_STRLEN + 2 + 1; + } else { + /* At other times, we print ":::" */ + newSize = attr->fdInheritBufferUsed + strlen(name) + + FD_TYPE_STRLEN + OSFD_STRLEN + 3 + 1; + } + if (newSize > attr->fdInheritBufferSize) { + /* Make newSize a multiple of FD_INHERIT_BUFFER_INCR */ + remainder = newSize % FD_INHERIT_BUFFER_INCR; + if (remainder != 0) { + newSize += (FD_INHERIT_BUFFER_INCR - remainder); + } + if (NULL == attr->fdInheritBuffer) { + newBuffer = (char *) PR_MALLOC(newSize); + } else { + newBuffer = (char *) PR_REALLOC(attr->fdInheritBuffer, newSize); + } + if (NULL == newBuffer) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return PR_FAILURE; + } + attr->fdInheritBuffer = newBuffer; + attr->fdInheritBufferSize = newSize; + } + cur = attr->fdInheritBuffer + attr->fdInheritBufferUsed; + freeSize = attr->fdInheritBufferSize - attr->fdInheritBufferUsed; + if (0 == attr->fdInheritBufferUsed) { + nwritten = PR_snprintf(cur, freeSize, + "NSPR_INHERIT_FDS=%s:%d:0x%" PR_PRIxOSFD, + name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); + } else { + nwritten = PR_snprintf(cur, freeSize, ":%s:%d:0x%" PR_PRIxOSFD, + name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); + } + attr->fdInheritBufferUsed += nwritten; + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRFileDesc *) PR_GetInheritedFD( + const char *name) +{ + PRFileDesc *fd; + const char *envVar; + const char *ptr; + int len = strlen(name); + PROsfd osfd; + int nColons; + PRIntn fileType; + + envVar = PR_GetEnv("NSPR_INHERIT_FDS"); + if (NULL == envVar || '\0' == envVar[0]) { + PR_SetError(PR_UNKNOWN_ERROR, 0); + return NULL; + } + + ptr = envVar; + while (1) { + if ((ptr[len] == ':') && (strncmp(ptr, name, len) == 0)) { + ptr += len + 1; + PR_sscanf(ptr, "%d:0x%" PR_SCNxOSFD, &fileType, &osfd); + switch ((PRDescType)fileType) { + case PR_DESC_FILE: + fd = PR_ImportFile(osfd); + break; + case PR_DESC_PIPE: + fd = PR_ImportPipe(osfd); + break; + case PR_DESC_SOCKET_TCP: + fd = PR_ImportTCPSocket(osfd); + break; + case PR_DESC_SOCKET_UDP: + fd = PR_ImportUDPSocket(osfd); + break; + default: + PR_ASSERT(0); + PR_SetError(PR_UNKNOWN_ERROR, 0); + fd = NULL; + break; + } + if (fd) { + /* + * An inherited FD is inheritable by default. + * The child process needs to call PR_SetFDInheritable + * to make it non-inheritable if so desired. + */ + fd->secret->inheritable = _PR_TRI_TRUE; + } + return fd; + } + /* Skip three colons */ + nColons = 0; + while (*ptr) { + if (*ptr == ':') { + if (++nColons == 3) { + break; + } + } + ptr++; + } + if (*ptr == '\0') { + PR_SetError(PR_UNKNOWN_ERROR, 0); + return NULL; + } + ptr++; + } +} + +PR_IMPLEMENT(PRProcess*) PR_CreateProcess( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr) +{ + return _PR_MD_CREATE_PROCESS(path, argv, envp, attr); +} /* PR_CreateProcess */ + +PR_IMPLEMENT(PRStatus) PR_CreateProcessDetached( + const char *path, + char *const *argv, + char *const *envp, + const PRProcessAttr *attr) +{ + PRProcess *process; + PRStatus rv; + + process = PR_CreateProcess(path, argv, envp, attr); + if (NULL == process) { + return PR_FAILURE; + } + rv = PR_DetachProcess(process); + PR_ASSERT(PR_SUCCESS == rv); + if (rv == PR_FAILURE) { + PR_DELETE(process); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_DetachProcess(PRProcess *process) +{ + return _PR_MD_DETACH_PROCESS(process); +} + +PR_IMPLEMENT(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode) +{ + return _PR_MD_WAIT_PROCESS(process, exitCode); +} /* PR_WaitProcess */ + +PR_IMPLEMENT(PRStatus) PR_KillProcess(PRProcess *process) +{ + return _PR_MD_KILL_PROCESS(process); +} + +/* + ******************************************************************** + * + * Module initialization + * + ******************************************************************** + */ + +static struct { + PRLock *ml; + PRCondVar *cv; +} mod_init; + +static void _PR_InitCallOnce(void) { + mod_init.ml = PR_NewLock(); + PR_ASSERT(NULL != mod_init.ml); + mod_init.cv = PR_NewCondVar(mod_init.ml); + PR_ASSERT(NULL != mod_init.cv); +} + +void _PR_CleanupCallOnce() +{ + PR_DestroyLock(mod_init.ml); + mod_init.ml = NULL; + PR_DestroyCondVar(mod_init.cv); + mod_init.cv = NULL; +} + +PR_IMPLEMENT(PRStatus) PR_CallOnce( + PRCallOnceType *once, + PRCallOnceFN func) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (!once->initialized) { + if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { + once->status = (*func)(); + PR_Lock(mod_init.ml); + once->initialized = 1; + PR_NotifyAllCondVar(mod_init.cv); + PR_Unlock(mod_init.ml); + } else { + PR_Lock(mod_init.ml); + while (!once->initialized) { + PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(mod_init.ml); + } + } else { + if (PR_SUCCESS != once->status) { + PR_SetError(PR_CALL_ONCE_ERROR, 0); + } + } + return once->status; +} + +PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg( + PRCallOnceType *once, + PRCallOnceWithArgFN func, + void *arg) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (!once->initialized) { + if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { + once->status = (*func)(arg); + PR_Lock(mod_init.ml); + once->initialized = 1; + PR_NotifyAllCondVar(mod_init.cv); + PR_Unlock(mod_init.ml); + } else { + PR_Lock(mod_init.ml); + while (!once->initialized) { + PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(mod_init.ml); + } + } else { + if (PR_SUCCESS != once->status) { + PR_SetError(PR_CALL_ONCE_ERROR, 0); + } + } + return once->status; +} + +PRBool _PR_Obsolete(const char *obsolete, const char *preferred) +{ +#if defined(DEBUG) + PR_fprintf( + PR_STDERR, "'%s' is obsolete. Use '%s' instead.\n", + obsolete, (NULL == preferred) ? "something else" : preferred); +#endif + return PR_FALSE; +} /* _PR_Obsolete */ + +/* prinit.c */ + + diff -Nru nspr-4.9.5/nspr/pr/src/misc/prinrval.c nspr-4.10.7/nspr/pr/src/misc/prinrval.c --- nspr-4.9.5/nspr/pr/src/misc/prinrval.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prinrval.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * file: prinrval.c + * description: implementation for the kernel interval timing functions + */ + +#include "primpl.h" + +/* + *----------------------------------------------------------------------- + * + * _PR_InitClock -- + * + * + *----------------------------------------------------------------------- + */ + +void _PR_InitClock(void) +{ + _PR_MD_INTERVAL_INIT(); +#ifdef DEBUG + { + PRIntervalTime ticksPerSec = PR_TicksPerSecond(); + + PR_ASSERT(ticksPerSec >= PR_INTERVAL_MIN); + PR_ASSERT(ticksPerSec <= PR_INTERVAL_MAX); + } +#endif /* DEBUG */ +} + +PR_IMPLEMENT(PRIntervalTime) PR_IntervalNow(void) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + return _PR_MD_GET_INTERVAL(); +} /* PR_IntervalNow */ + +PR_EXTERN(PRUint32) PR_TicksPerSecond(void) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + return _PR_MD_INTERVAL_PER_SEC(); +} /* PR_TicksPerSecond */ + +PR_IMPLEMENT(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds) +{ + return seconds * PR_TicksPerSecond(); +} /* PR_SecondsToInterval */ + +PR_IMPLEMENT(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli) +{ + PRIntervalTime ticks; + PRUint64 tock, tps, msecPerSec, rounding; + LL_UI2L(tock, milli); + LL_I2L(msecPerSec, PR_MSEC_PER_SEC); + LL_I2L(rounding, (PR_MSEC_PER_SEC >> 1)); + LL_I2L(tps, PR_TicksPerSecond()); + LL_MUL(tock, tock, tps); + LL_ADD(tock, tock, rounding); + LL_DIV(tock, tock, msecPerSec); + LL_L2UI(ticks, tock); + return ticks; +} /* PR_MillisecondsToInterval */ + +PR_IMPLEMENT(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro) +{ + PRIntervalTime ticks; + PRUint64 tock, tps, usecPerSec, rounding; + LL_UI2L(tock, micro); + LL_I2L(usecPerSec, PR_USEC_PER_SEC); + LL_I2L(rounding, (PR_USEC_PER_SEC >> 1)); + LL_I2L(tps, PR_TicksPerSecond()); + LL_MUL(tock, tock, tps); + LL_ADD(tock, tock, rounding); + LL_DIV(tock, tock, usecPerSec); + LL_L2UI(ticks, tock); + return ticks; +} /* PR_MicrosecondsToInterval */ + +PR_IMPLEMENT(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks) +{ + return ticks / PR_TicksPerSecond(); +} /* PR_IntervalToSeconds */ + +PR_IMPLEMENT(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks) +{ + PRUint32 milli; + PRUint64 tock, tps, msecPerSec, rounding; + LL_UI2L(tock, ticks); + LL_I2L(msecPerSec, PR_MSEC_PER_SEC); + LL_I2L(tps, PR_TicksPerSecond()); + LL_USHR(rounding, tps, 1); + LL_MUL(tock, tock, msecPerSec); + LL_ADD(tock, tock, rounding); + LL_DIV(tock, tock, tps); + LL_L2UI(milli, tock); + return milli; +} /* PR_IntervalToMilliseconds */ + +PR_IMPLEMENT(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks) +{ + PRUint32 micro; + PRUint64 tock, tps, usecPerSec, rounding; + LL_UI2L(tock, ticks); + LL_I2L(usecPerSec, PR_USEC_PER_SEC); + LL_I2L(tps, PR_TicksPerSecond()); + LL_USHR(rounding, tps, 1); + LL_MUL(tock, tock, usecPerSec); + LL_ADD(tock, tock, rounding); + LL_DIV(tock, tock, tps); + LL_L2UI(micro, tock); + return micro; +} /* PR_IntervalToMicroseconds */ + +/* prinrval.c */ + diff -Nru nspr-4.9.5/nspr/pr/src/misc/pripc.c nspr-4.10.7/nspr/pr/src/misc/pripc.c --- nspr-4.9.5/nspr/pr/src/misc/pripc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/pripc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: pripc.c + * + * Description: functions for IPC support + */ + +#include "primpl.h" + +#include + +/* + * A POSIX IPC name must begin with a '/'. + * A POSIX IPC name on Solaris cannot contain any '/' except + * the required leading '/'. + * A POSIX IPC name on HP-UX and OSF1 must be a valid pathname + * in the file system. + * + * The ftok() function for System V IPC requires a valid pathname + * in the file system. + * + * A Win32 IPC name cannot contain '\'. + */ + +static void _pr_ConvertSemName(char *result) +{ +#ifdef _PR_HAVE_POSIX_SEMAPHORES +#if defined(SOLARIS) + char *p; + + /* Convert '/' to '_' except for the leading '/' */ + for (p = result+1; *p; p++) { + if (*p == '/') { + *p = '_'; + } + } + return; +#else + return; +#endif +#elif defined(_PR_HAVE_SYSV_SEMAPHORES) + return; +#elif defined(WIN32) + return; +#endif +} + +static void _pr_ConvertShmName(char *result) +{ +#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY) +#if defined(SOLARIS) + char *p; + + /* Convert '/' to '_' except for the leading '/' */ + for (p = result+1; *p; p++) { + if (*p == '/') { + *p = '_'; + } + } + return; +#else + return; +#endif +#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY) + return; +#elif defined(WIN32) + return; +#else + return; +#endif +} + +PRStatus _PR_MakeNativeIPCName( + const char *name, + char *result, + PRIntn size, + _PRIPCType type) +{ + if (strlen(name) >= (PRSize)size) { + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); + return PR_FAILURE; + } + strcpy(result, name); + switch (type) { + case _PRIPCSem: + _pr_ConvertSemName(result); + break; + case _PRIPCShm: + _pr_ConvertShmName(result); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + return PR_SUCCESS; +} diff -Nru nspr-4.9.5/nspr/pr/src/misc/pripcsem.c nspr-4.10.7/nspr/pr/src/misc/pripcsem.c --- nspr-4.9.5/nspr/pr/src/misc/pripcsem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/pripcsem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: pripcsem.c + * + * Description: implements the named semaphores API in prsemipc.h + * for classic NSPR. If _PR_HAVE_NAMED_SEMAPHORES is not defined, + * the named semaphore functions all fail with the error code + * PR_NOT_IMPLEMENTED_ERROR. + */ + +#include "primpl.h" + +#ifdef _PR_PTHREADS + +#error "This file should not be compiled for the pthreads version" + +#else + +#ifndef _PR_HAVE_NAMED_SEMAPHORES + +PRSem * _PR_MD_OPEN_SEMAPHORE( + const char *osname, PRIntn flags, PRIntn mode, PRUintn value) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +#endif /* !_PR_HAVE_NAMED_SEMAPHORES */ + +PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( + const char *name, PRIntn flags, PRIntn mode, PRUintn value) +{ + char osname[PR_IPC_NAME_SIZE]; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) + == PR_FAILURE) { + return NULL; + } + return _PR_MD_OPEN_SEMAPHORE(osname, flags, mode, value); +} + +PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem) +{ + return _PR_MD_WAIT_SEMAPHORE(sem); +} + +PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem) +{ + return _PR_MD_POST_SEMAPHORE(sem); +} + +PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem) +{ + return _PR_MD_CLOSE_SEMAPHORE(sem); +} + +PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) +{ + char osname[PR_IPC_NAME_SIZE]; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) + == PR_FAILURE) { + return PR_FAILURE; + } + return _PR_MD_DELETE_SEMAPHORE(osname); +} + +#endif /* _PR_PTHREADS */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/prlog2.c nspr-4.10.7/nspr/pr/src/misc/prlog2.c --- nspr-4.9.5/nspr/pr/src/misc/prlog2.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prlog2.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prbit.h" + +/* +** Compute the log of the least power of 2 greater than or equal to n +*/ +PR_IMPLEMENT(PRIntn) PR_CeilingLog2(PRUint32 n) +{ + PRIntn log2; + PR_CEILING_LOG2(log2, n); + return log2; +} + +/* +** Compute the log of the greatest power of 2 less than or equal to n. +** This really just finds the highest set bit in the word. +*/ +PR_IMPLEMENT(PRIntn) PR_FloorLog2(PRUint32 n) +{ + PRIntn log2; + PR_FLOOR_LOG2(log2, n); + return log2; +} diff -Nru nspr-4.9.5/nspr/pr/src/misc/prlong.c nspr-4.10.7/nspr/pr/src/misc/prlong.c --- nspr-4.9.5/nspr/pr/src/misc/prlong.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prlong.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prlong.h" + +static PRInt64 ll_zero = LL_INIT( 0x00000000,0x00000000 ); +static PRInt64 ll_maxint = LL_INIT( 0x7fffffff, 0xffffffff ); +static PRInt64 ll_minint = LL_INIT( 0x80000000, 0x00000000 ); +static PRUint64 ll_maxuint = LL_INIT( 0xffffffff, 0xffffffff ); + +PR_IMPLEMENT(PRInt64) LL_Zero(void) { return ll_zero; } +PR_IMPLEMENT(PRInt64) LL_MaxInt(void) { return ll_maxint; } +PR_IMPLEMENT(PRInt64) LL_MinInt(void) { return ll_minint; } +PR_IMPLEMENT(PRUint64) LL_MaxUint(void) { return ll_maxuint; } + +#ifndef HAVE_LONG_LONG +/* +** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1. +*/ +static void norm_udivmod32(PRUint32 *qp, PRUint32 *rp, PRUint64 a, PRUint32 b) +{ + PRUint32 d1, d0, q1, q0; + PRUint32 r1, r0, m; + + d1 = _hi16(b); + d0 = _lo16(b); + r1 = a.hi % d1; + q1 = a.hi / d1; + m = q1 * d0; + r1 = (r1 << 16) | _hi16(a.lo); + if (r1 < m) { + q1--, r1 += b; + if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */ + && r1 < m) { + q1--, r1 += b; + } + } + r1 -= m; + r0 = r1 % d1; + q0 = r1 / d1; + m = q0 * d0; + r0 = (r0 << 16) | _lo16(a.lo); + if (r0 < m) { + q0--, r0 += b; + if (r0 >= b + && r0 < m) { + q0--, r0 += b; + } + } + *qp = (q1 << 16) | q0; + *rp = r0 - m; +} + +static PRUint32 CountLeadingZeros(PRUint32 a) +{ + PRUint32 t; + PRUint32 r = 32; + + if ((t = a >> 16) != 0) + r -= 16, a = t; + if ((t = a >> 8) != 0) + r -= 8, a = t; + if ((t = a >> 4) != 0) + r -= 4, a = t; + if ((t = a >> 2) != 0) + r -= 2, a = t; + if ((t = a >> 1) != 0) + r -= 1, a = t; + if (a & 1) + r--; + return r; +} + +PR_IMPLEMENT(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b) +{ + PRUint32 n0, n1, n2; + PRUint32 q0, q1; + PRUint32 rsh, lsh; + + n0 = a.lo; + n1 = a.hi; + + if (b.hi == 0) { + if (b.lo > n1) { + /* (0 q0) = (n1 n0) / (0 D0) */ + + lsh = CountLeadingZeros(b.lo); + + if (lsh) { + /* + * Normalize, i.e. make the most significant bit of the + * denominator be set. + */ + b.lo = b.lo << lsh; + n1 = (n1 << lsh) | (n0 >> (32 - lsh)); + n0 = n0 << lsh; + } + + a.lo = n0, a.hi = n1; + norm_udivmod32(&q0, &n0, a, b.lo); + q1 = 0; + + /* remainder is in n0 >> lsh */ + } else { + /* (q1 q0) = (n1 n0) / (0 d0) */ + + if (b.lo == 0) /* user wants to divide by zero! */ + b.lo = 1 / b.lo; /* so go ahead and crash */ + + lsh = CountLeadingZeros(b.lo); + + if (lsh == 0) { + /* + * From (n1 >= b.lo) + * && (the most significant bit of b.lo is set), + * conclude that + * (the most significant bit of n1 is set) + * && (the leading quotient digit q1 = 1). + * + * This special case is necessary, not an optimization + * (Shifts counts of 32 are undefined). + */ + n1 -= b.lo; + q1 = 1; + } else { + /* + * Normalize. + */ + rsh = 32 - lsh; + + b.lo = b.lo << lsh; + n2 = n1 >> rsh; + n1 = (n1 << lsh) | (n0 >> rsh); + n0 = n0 << lsh; + + a.lo = n1, a.hi = n2; + norm_udivmod32(&q1, &n1, a, b.lo); + } + + /* n1 != b.lo... */ + + a.lo = n0, a.hi = n1; + norm_udivmod32(&q0, &n0, a, b.lo); + + /* remainder in n0 >> lsh */ + } + + if (rp) { + rp->lo = n0 >> lsh; + rp->hi = 0; + } + } else { + if (b.hi > n1) { + /* (0 0) = (n1 n0) / (D1 d0) */ + + q0 = 0; + q1 = 0; + + /* remainder in (n1 n0) */ + if (rp) { + rp->lo = n0; + rp->hi = n1; + } + } else { + /* (0 q0) = (n1 n0) / (d1 d0) */ + + lsh = CountLeadingZeros(b.hi); + if (lsh == 0) { + /* + * From (n1 >= b.hi) + * && (the most significant bit of b.hi is set), + * conclude that + * (the most significant bit of n1 is set) + * && (the quotient digit q0 = 0 or 1). + * + * This special case is necessary, not an optimization. + */ + + /* + * The condition on the next line takes advantage of that + * n1 >= b.hi (true due to control flow). + */ + if (n1 > b.hi || n0 >= b.lo) { + q0 = 1; + a.lo = n0, a.hi = n1; + LL_SUB(a, a, b); + } else { + q0 = 0; + } + q1 = 0; + + if (rp) { + rp->lo = n0; + rp->hi = n1; + } + } else { + PRInt64 m; + + /* + * Normalize. + */ + rsh = 32 - lsh; + + b.hi = (b.hi << lsh) | (b.lo >> rsh); + b.lo = b.lo << lsh; + n2 = n1 >> rsh; + n1 = (n1 << lsh) | (n0 >> rsh); + n0 = n0 << lsh; + + a.lo = n1, a.hi = n2; + norm_udivmod32(&q0, &n1, a, b.hi); + LL_MUL32(m, q0, b.lo); + + if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) { + q0--; + LL_SUB(m, m, b); + } + + q1 = 0; + + /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */ + if (rp) { + a.lo = n0, a.hi = n1; + LL_SUB(a, a, m); + rp->lo = (a.hi << rsh) | (a.lo >> lsh); + rp->hi = a.hi >> lsh; + } + } + } + } + + if (qp) { + qp->lo = q0; + qp->hi = q1; + } +} +#endif /* !HAVE_LONG_LONG */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/prnetdb.c nspr-4.10.7/nspr/pr/src/misc/prnetdb.c --- nspr-4.9.5/nspr/pr/src/misc/prnetdb.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prnetdb.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,2343 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +/* + * On Unix, the error code for gethostbyname() and gethostbyaddr() + * is returned in the global variable h_errno, instead of the usual + * errno. + */ +#if defined(XP_UNIX) +#if defined(_PR_NEED_H_ERRNO) +extern int h_errno; +#endif +#define _MD_GETHOST_ERRNO() h_errno +#else +#define _MD_GETHOST_ERRNO() _MD_ERRNO() +#endif + +/* + * The meaning of the macros related to gethostbyname, gethostbyaddr, + * and gethostbyname2 is defined below. + * - _PR_HAVE_THREADSAFE_GETHOST: the gethostbyXXX functions return + * the result in thread specific storage. For example, AIX, HP-UX, + * and OSF1. + * - _PR_HAVE_GETHOST_R: have the gethostbyXXX_r functions. See next + * two macros. + * - _PR_HAVE_GETHOST_R_INT: the gethostbyXXX_r functions return an + * int. For example, Linux glibc. + * - _PR_HAVE_GETHOST_R_POINTER: the gethostbyXXX_r functions return + * a struct hostent* pointer. For example, Solaris and IRIX. + */ +#if defined(_PR_NO_PREEMPT) || defined(_PR_HAVE_GETHOST_R) \ + || defined(_PR_HAVE_THREADSAFE_GETHOST) +#define _PR_NO_DNS_LOCK +#endif + +#if defined(_PR_NO_DNS_LOCK) +#define LOCK_DNS() +#define UNLOCK_DNS() +#else +PRLock *_pr_dnsLock = NULL; +#define LOCK_DNS() PR_Lock(_pr_dnsLock) +#define UNLOCK_DNS() PR_Unlock(_pr_dnsLock) +#endif /* defined(_PR_NO_DNS_LOCK) */ + +/* + * Some platforms have the reentrant getprotobyname_r() and + * getprotobynumber_r(). However, they come in three flavors. + * Some return a pointer to struct protoent, others return + * an int, and glibc's flavor takes five arguments. + */ +#if defined(XP_BEOS) && defined(BONE_VERSION) +#include /* pick up define for inet_addr */ +#include +#define _PR_HAVE_GETPROTO_R +#define _PR_HAVE_GETPROTO_R_POINTER +#endif + +#if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \ + || (defined(LINUX) && defined(_REENTRANT) \ + && !(defined(__GLIBC__) && __GLIBC__ >= 2) \ + && !defined(ANDROID)) +#define _PR_HAVE_GETPROTO_R +#define _PR_HAVE_GETPROTO_R_POINTER +#endif + +#if defined(OSF1) \ + || defined(AIX4_3_PLUS) || (defined(AIX) && defined(_THREAD_SAFE)) \ + || (defined(HPUX10_10) && defined(_REENTRANT)) \ + || (defined(HPUX10_20) && defined(_REENTRANT)) \ + || defined(OPENBSD) +#define _PR_HAVE_GETPROTO_R +#define _PR_HAVE_GETPROTO_R_INT +#endif + +#if __FreeBSD_version >= 602000 +#define _PR_HAVE_GETPROTO_R +#define _PR_HAVE_5_ARG_GETPROTO_R +#endif + +/* BeOS has glibc but not the glibc-style getprotobyxxx_r functions. */ +#if (defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(XP_BEOS)) +#define _PR_HAVE_GETPROTO_R +#define _PR_HAVE_5_ARG_GETPROTO_R +#endif + +#if !defined(_PR_HAVE_GETPROTO_R) +PRLock* _getproto_lock = NULL; +#endif + +#if defined(_PR_INET6_PROBE) +extern PRBool _pr_ipv6_is_present(void); +#endif + +#define _PR_IN6_IS_ADDR_UNSPECIFIED(a) \ + (((a)->pr_s6_addr32[0] == 0) && \ + ((a)->pr_s6_addr32[1] == 0) && \ + ((a)->pr_s6_addr32[2] == 0) && \ + ((a)->pr_s6_addr32[3] == 0)) + +#define _PR_IN6_IS_ADDR_LOOPBACK(a) \ + (((a)->pr_s6_addr32[0] == 0) && \ + ((a)->pr_s6_addr32[1] == 0) && \ + ((a)->pr_s6_addr32[2] == 0) && \ + ((a)->pr_s6_addr[12] == 0) && \ + ((a)->pr_s6_addr[13] == 0) && \ + ((a)->pr_s6_addr[14] == 0) && \ + ((a)->pr_s6_addr[15] == 0x1U)) + +const PRIPv6Addr _pr_in6addr_any = {{{ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 }}}; + +const PRIPv6Addr _pr_in6addr_loopback = {{{ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0x1U }}}; +/* + * The values at bytes 10 and 11 are compared using pointers to + * 8-bit fields, and not 32-bit fields, to make the comparison work on + * both big-endian and little-endian systems + */ + +#define _PR_IN6_IS_ADDR_V4MAPPED(a) \ + (((a)->pr_s6_addr32[0] == 0) && \ + ((a)->pr_s6_addr32[1] == 0) && \ + ((a)->pr_s6_addr[8] == 0) && \ + ((a)->pr_s6_addr[9] == 0) && \ + ((a)->pr_s6_addr[10] == 0xff) && \ + ((a)->pr_s6_addr[11] == 0xff)) + +#define _PR_IN6_IS_ADDR_V4COMPAT(a) \ + (((a)->pr_s6_addr32[0] == 0) && \ + ((a)->pr_s6_addr32[1] == 0) && \ + ((a)->pr_s6_addr32[2] == 0)) + +#define _PR_IN6_V4MAPPED_TO_IPADDR(a) ((a)->pr_s6_addr32[3]) + +#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) + +/* + * The _pr_QueryNetIfs() function finds out if the system has + * IPv4 or IPv6 source addresses configured and sets _pr_have_inet_if + * and _pr_have_inet6_if accordingly. + * + * We have an implementation using SIOCGIFCONF ioctl and a + * default implementation that simply sets _pr_have_inet_if + * and _pr_have_inet6_if to true. A better implementation + * would be to use the routing sockets (see Chapter 17 of + * W. Richard Stevens' Unix Network Programming, Vol. 1, 2nd. Ed.) + */ + +static PRLock *_pr_query_ifs_lock = NULL; +static PRBool _pr_have_inet_if = PR_FALSE; +static PRBool _pr_have_inet6_if = PR_FALSE; + +#undef DEBUG_QUERY_IFS + +#if defined(AIX) \ + || (defined(DARWIN) && (!defined(HAVE_GETIFADDRS) \ + || (defined(XP_MACOSX) && (!defined(MAC_OS_X_VERSION_10_2) || \ + MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2)))) + +/* + * Use SIOCGIFCONF ioctl on platforms that don't have routing + * sockets. Warning: whether SIOCGIFCONF ioctl returns AF_INET6 + * network interfaces is not portable. + * + * The _pr_QueryNetIfs() function is derived from the code in + * src/lib/libc/net/getifaddrs.c in BSD Unix and the code in + * Section 16.6 of W. Richard Stevens' Unix Network Programming, + * Vol. 1, 2nd. Ed. + */ + +#include +#include +#include +#include + +#ifdef DEBUG_QUERY_IFS +static void +_pr_PrintIfreq(struct ifreq *ifr) +{ + PRNetAddr addr; + struct sockaddr *sa; + const char* family; + char addrstr[64]; + + sa = &ifr->ifr_addr; + if (sa->sa_family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + family = "inet"; + memcpy(&addr.inet.ip, &sin->sin_addr, sizeof(sin->sin_addr)); + } else if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; + family = "inet6"; + memcpy(&addr.ipv6.ip, &sin6->sin6_addr, sizeof(sin6->sin6_addr)); + } else { + return; /* skip if not AF_INET or AF_INET6 */ + } + addr.raw.family = sa->sa_family; + PR_NetAddrToString(&addr, addrstr, sizeof(addrstr)); + printf("%s: %s %s\n", ifr->ifr_name, family, addrstr); +} +#endif + +static void +_pr_QueryNetIfs(void) +{ + int sock; + int rv; + struct ifconf ifc; + struct ifreq *ifr; + struct ifreq *lifr; + PRUint32 len, lastlen; + char *buf; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + return; + } + + /* Issue SIOCGIFCONF request in a loop. */ + lastlen = 0; + len = 100 * sizeof(struct ifreq); /* initial buffer size guess */ + for (;;) { + buf = (char *)PR_Malloc(len); + if (NULL == buf) { + close(sock); + return; + } + ifc.ifc_buf = buf; + ifc.ifc_len = len; + rv = ioctl(sock, SIOCGIFCONF, &ifc); + if (rv < 0) { + if (errno != EINVAL || lastlen != 0) { + close(sock); + PR_Free(buf); + return; + } + } else { + if (ifc.ifc_len == lastlen) + break; /* success, len has not changed */ + lastlen = ifc.ifc_len; + } + len += 10 * sizeof(struct ifreq); /* increment */ + PR_Free(buf); + } + close(sock); + + ifr = ifc.ifc_req; + lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; + + while (ifr < lifr) { + struct sockaddr *sa; + int sa_len; + +#ifdef DEBUG_QUERY_IFS + _pr_PrintIfreq(ifr); +#endif + sa = &ifr->ifr_addr; + if (sa->sa_family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { + _pr_have_inet_if = PR_TRUE; + } + } else if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) + && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + _pr_have_inet6_if = PR_TRUE; + } + } + +#ifdef _PR_HAVE_SOCKADDR_LEN + sa_len = PR_MAX(sa->sa_len, sizeof(struct sockaddr)); +#else + switch (sa->sa_family) { +#ifdef AF_LINK + case AF_LINK: + sa_len = sizeof(struct sockaddr_dl); + break; +#endif + case AF_INET6: + sa_len = sizeof(struct sockaddr_in6); + break; + default: + sa_len = sizeof(struct sockaddr); + break; + } +#endif + ifr = (struct ifreq *)(((char *)sa) + sa_len); + } + PR_Free(buf); +} + +#elif (defined(DARWIN) && defined(HAVE_GETIFADDRS)) || defined(FREEBSD) \ + || defined(NETBSD) || defined(OPENBSD) + +/* + * Use the BSD getifaddrs function. + */ + +#include +#include +#include +#include + +#ifdef DEBUG_QUERY_IFS +static void +_pr_PrintIfaddrs(struct ifaddrs *ifa) +{ + struct sockaddr *sa; + const char* family; + void *addrp; + char addrstr[64]; + + sa = ifa->ifa_addr; + if (sa->sa_family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + family = "inet"; + addrp = &sin->sin_addr; + } else if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; + family = "inet6"; + addrp = &sin6->sin6_addr; + } else { + return; /* skip if not AF_INET or AF_INET6 */ + } + inet_ntop(sa->sa_family, addrp, addrstr, sizeof(addrstr)); + printf("%s: %s %s\n", ifa->ifa_name, family, addrstr); +} +#endif + +static void +_pr_QueryNetIfs(void) +{ + struct ifaddrs *ifp; + struct ifaddrs *ifa; + + if (getifaddrs(&ifp) == -1) { + return; + } + for (ifa = ifp; ifa; ifa = ifa->ifa_next) { + struct sockaddr *sa; + +#ifdef DEBUG_QUERY_IFS + _pr_PrintIfaddrs(ifa); +#endif + sa = ifa->ifa_addr; + if (sa->sa_family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { + _pr_have_inet_if = 1; + } + } else if (sa->sa_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; + if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) + && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + _pr_have_inet6_if = 1; + } + } + } + freeifaddrs(ifp); +} + +#else /* default */ + +/* + * Emulate the code in NSPR 4.2 or older. PR_GetIPNodeByName behaves + * as if the system had both IPv4 and IPv6 source addresses configured. + */ +static void +_pr_QueryNetIfs(void) +{ + _pr_have_inet_if = PR_TRUE; + _pr_have_inet6_if = PR_TRUE; +} + +#endif + +#endif /* _PR_INET6 && _PR_HAVE_GETHOSTBYNAME2 */ + +void _PR_InitNet(void) +{ +#if defined(XP_UNIX) +#ifdef HAVE_NETCONFIG + /* + * This one-liner prevents the endless re-open's and re-read's of + * /etc/netconfig on EACH and EVERY call to accept(), connect(), etc. + */ + (void)setnetconfig(); +#endif +#endif +#if !defined(_PR_NO_DNS_LOCK) + _pr_dnsLock = PR_NewLock(); +#endif +#if !defined(_PR_HAVE_GETPROTO_R) + _getproto_lock = PR_NewLock(); +#endif +#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) + _pr_query_ifs_lock = PR_NewLock(); +#endif +} + +void _PR_CleanupNet(void) +{ +#if !defined(_PR_NO_DNS_LOCK) + if (_pr_dnsLock) { + PR_DestroyLock(_pr_dnsLock); + _pr_dnsLock = NULL; + } +#endif +#if !defined(_PR_HAVE_GETPROTO_R) + if (_getproto_lock) { + PR_DestroyLock(_getproto_lock); + _getproto_lock = NULL; + } +#endif +#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) + if (_pr_query_ifs_lock) { + PR_DestroyLock(_pr_query_ifs_lock); + _pr_query_ifs_lock = NULL; + } +#endif +} + +/* +** Allocate space from the buffer, aligning it to "align" before doing +** the allocation. "align" must be a power of 2. +*/ +static char *Alloc(PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align) +{ + char *buf = *bufp; + PRIntn buflen = *buflenp; + + if (align && ((long)buf & (align - 1))) { + PRIntn skip = align - ((ptrdiff_t)buf & (align - 1)); + if (buflen < skip) { + return 0; + } + buf += skip; + buflen -= skip; + } + if (buflen < amount) { + return 0; + } + *bufp = buf + amount; + *buflenp = buflen - amount; + return buf; +} + +typedef enum _PRIPAddrConversion { + _PRIPAddrNoConversion, + _PRIPAddrIPv4Mapped, + _PRIPAddrIPv4Compat +} _PRIPAddrConversion; + +/* +** Convert an IPv4 address (v4) to an IPv4-mapped IPv6 address (v6). +*/ +static void MakeIPv4MappedAddr(const char *v4, char *v6) +{ + memset(v6, 0, 10); + memset(v6 + 10, 0xff, 2); + memcpy(v6 + 12, v4, 4); +} + +/* +** Convert an IPv4 address (v4) to an IPv4-compatible IPv6 address (v6). +*/ +static void MakeIPv4CompatAddr(const char *v4, char *v6) +{ + memset(v6, 0, 12); + memcpy(v6 + 12, v4, 4); +} + +/* +** Copy a hostent, and all of the memory that it refers to into +** (hopefully) stacked buffers. +*/ +static PRStatus CopyHostent( + struct hostent *from, + char **buf, + PRIntn *bufsize, + _PRIPAddrConversion conversion, + PRHostEnt *to) +{ + PRIntn len, na; + char **ap; + + if (conversion != _PRIPAddrNoConversion + && from->h_addrtype == AF_INET) { + PR_ASSERT(from->h_length == 4); + to->h_addrtype = PR_AF_INET6; + to->h_length = 16; + } else { +#if defined(_PR_INET6) || defined(_PR_INET6_PROBE) + if (AF_INET6 == from->h_addrtype) + to->h_addrtype = PR_AF_INET6; + else +#endif + to->h_addrtype = from->h_addrtype; + to->h_length = from->h_length; + } + + /* Copy the official name */ + if (!from->h_name) return PR_FAILURE; + len = strlen(from->h_name) + 1; + to->h_name = Alloc(len, buf, bufsize, 0); + if (!to->h_name) return PR_FAILURE; + memcpy(to->h_name, from->h_name, len); + + /* Count the aliases, then allocate storage for the pointers */ + if (!from->h_aliases) { + na = 1; + } else { + for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */ + } + to->h_aliases = (char**)Alloc( + na * sizeof(char*), buf, bufsize, sizeof(char**)); + if (!to->h_aliases) return PR_FAILURE; + + /* Copy the aliases, one at a time */ + if (!from->h_aliases) { + to->h_aliases[0] = 0; + } else { + for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) { + len = strlen(*ap) + 1; + to->h_aliases[na] = Alloc(len, buf, bufsize, 0); + if (!to->h_aliases[na]) return PR_FAILURE; + memcpy(to->h_aliases[na], *ap, len); + } + to->h_aliases[na] = 0; + } + + /* Count the addresses, then allocate storage for the pointers */ + for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++){;} /* nothing to execute */ + to->h_addr_list = (char**)Alloc( + na * sizeof(char*), buf, bufsize, sizeof(char**)); + if (!to->h_addr_list) return PR_FAILURE; + + /* Copy the addresses, one at a time */ + for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) { + to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0); + if (!to->h_addr_list[na]) return PR_FAILURE; + if (conversion != _PRIPAddrNoConversion + && from->h_addrtype == AF_INET) { + if (conversion == _PRIPAddrIPv4Mapped) { + MakeIPv4MappedAddr(*ap, to->h_addr_list[na]); + } else { + PR_ASSERT(conversion == _PRIPAddrIPv4Compat); + MakeIPv4CompatAddr(*ap, to->h_addr_list[na]); + } + } else { + memcpy(to->h_addr_list[na], *ap, to->h_length); + } + } + to->h_addr_list[na] = 0; + return PR_SUCCESS; +} + +#ifdef SYMBIAN +/* Set p_aliases by hand because Symbian's getprotobyname() returns NULL. */ +static void AssignAliases(struct protoent *Protoent, char** aliases) +{ + if (NULL == Protoent->p_aliases) { + if (0 == strcmp(Protoent->p_name, "ip")) + aliases[0] = "IP"; + else if (0 == strcmp(Protoent->p_name, "tcp")) + aliases[0] = "TCP"; + else if (0 == strcmp(Protoent->p_name, "udp")) + aliases[0] = "UDP"; + else + aliases[0] = "UNKNOWN"; + aliases[1] = NULL; + Protoent->p_aliases = aliases; + } +} +#endif + +#if !defined(_PR_HAVE_GETPROTO_R) +/* +** Copy a protoent, and all of the memory that it refers to into +** (hopefully) stacked buffers. +*/ +static PRStatus CopyProtoent( + struct protoent *from, char *buf, PRIntn bufsize, PRProtoEnt *to) +{ + PRIntn len, na; + char **ap; + + /* Do the easy stuff */ + to->p_num = from->p_proto; + + /* Copy the official name */ + if (!from->p_name) return PR_FAILURE; + len = strlen(from->p_name) + 1; + to->p_name = Alloc(len, &buf, &bufsize, 0); + if (!to->p_name) return PR_FAILURE; + memcpy(to->p_name, from->p_name, len); + + /* Count the aliases, then allocate storage for the pointers */ + for (na = 1, ap = from->p_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */ + to->p_aliases = (char**)Alloc( + na * sizeof(char*), &buf, &bufsize, sizeof(char**)); + if (!to->p_aliases) return PR_FAILURE; + + /* Copy the aliases, one at a time */ + for (na = 0, ap = from->p_aliases; *ap != 0; na++, ap++) { + len = strlen(*ap) + 1; + to->p_aliases[na] = Alloc(len, &buf, &bufsize, 0); + if (!to->p_aliases[na]) return PR_FAILURE; + memcpy(to->p_aliases[na], *ap, len); + } + to->p_aliases[na] = 0; + + return PR_SUCCESS; +} +#endif /* !defined(_PR_HAVE_GETPROTO_R) */ + +/* + * ################################################################# + * NOTE: tmphe, tmpbuf, bufsize, h, and h_err are local variables + * or arguments of PR_GetHostByName, PR_GetIPNodeByName, and + * PR_GetHostByAddr. DO NOT CHANGE THE NAMES OF THESE LOCAL + * VARIABLES OR ARGUMENTS. + * ################################################################# + */ +#if defined(_PR_HAVE_GETHOST_R_INT) + +#define GETHOSTBYNAME(name) \ + (gethostbyname_r(name, &tmphe, tmpbuf, bufsize, &h, &h_err), h) +#define GETHOSTBYNAME2(name, af) \ + (gethostbyname2_r(name, af, &tmphe, tmpbuf, bufsize, &h, &h_err), h) +#define GETHOSTBYADDR(addr, addrlen, af) \ + (gethostbyaddr_r(addr, addrlen, af, \ + &tmphe, tmpbuf, bufsize, &h, &h_err), h) + +#elif defined(_PR_HAVE_GETHOST_R_POINTER) + +#define GETHOSTBYNAME(name) \ + gethostbyname_r(name, &tmphe, tmpbuf, bufsize, &h_err) +#define GETHOSTBYNAME2(name, af) \ + gethostbyname2_r(name, af, &tmphe, tmpbuf, bufsize, &h_err) +#define GETHOSTBYADDR(addr, addrlen, af) \ + gethostbyaddr_r(addr, addrlen, af, &tmphe, tmpbuf, bufsize, &h_err) + +#else + +#define GETHOSTBYNAME(name) gethostbyname(name) +#define GETHOSTBYNAME2(name, af) gethostbyname2(name, af) +#define GETHOSTBYADDR(addr, addrlen, af) gethostbyaddr(addr, addrlen, af) + +#endif /* definition of GETHOSTBYXXX */ + +PR_IMPLEMENT(PRStatus) PR_GetHostByName( + const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp) +{ + struct hostent *h; + PRStatus rv = PR_FAILURE; +#if defined(_PR_HAVE_GETHOST_R) + char localbuf[PR_NETDB_BUF_SIZE]; + char *tmpbuf; + struct hostent tmphe; + int h_err; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + +#if defined(_PR_HAVE_GETHOST_R) + tmpbuf = localbuf; + if (bufsize > sizeof(localbuf)) + { + tmpbuf = (char *)PR_Malloc(bufsize); + if (NULL == tmpbuf) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return rv; + } + } +#endif + + LOCK_DNS(); + + h = GETHOSTBYNAME(name); + + if (NULL == h) + { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); + } + else + { + _PRIPAddrConversion conversion = _PRIPAddrNoConversion; + rv = CopyHostent(h, &buf, &bufsize, conversion, hp); + if (PR_SUCCESS != rv) + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } + UNLOCK_DNS(); +#if defined(_PR_HAVE_GETHOST_R) + if (tmpbuf != localbuf) + PR_Free(tmpbuf); +#endif + return rv; +} + +#if !defined(_PR_INET6) && \ + defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) +typedef struct hostent * (*_pr_getipnodebyname_t)(const char *, int, + int, int *); +typedef struct hostent * (*_pr_getipnodebyaddr_t)(const void *, size_t, + int, int *); +typedef void (*_pr_freehostent_t)(struct hostent *); +static void * _pr_getipnodebyname_fp; +static void * _pr_getipnodebyaddr_fp; +static void * _pr_freehostent_fp; + +/* + * Look up the addresses of getipnodebyname, getipnodebyaddr, + * and freehostent. + */ +PRStatus +_pr_find_getipnodebyname(void) +{ + PRLibrary *lib; + PRStatus rv; +#define GETIPNODEBYNAME "getipnodebyname" +#define GETIPNODEBYADDR "getipnodebyaddr" +#define FREEHOSTENT "freehostent" + + _pr_getipnodebyname_fp = PR_FindSymbolAndLibrary(GETIPNODEBYNAME, &lib); + if (NULL != _pr_getipnodebyname_fp) { + _pr_freehostent_fp = PR_FindSymbol(lib, FREEHOSTENT); + if (NULL != _pr_freehostent_fp) { + _pr_getipnodebyaddr_fp = PR_FindSymbol(lib, GETIPNODEBYADDR); + if (NULL != _pr_getipnodebyaddr_fp) + rv = PR_SUCCESS; + else + rv = PR_FAILURE; + } else + rv = PR_FAILURE; + (void)PR_UnloadLibrary(lib); + } else + rv = PR_FAILURE; + return rv; +} +#endif + +#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) +/* +** Append the V4 addresses to the end of the list +*/ +static PRStatus AppendV4AddrsToHostent( + struct hostent *from, + char **buf, + PRIntn *bufsize, + PRHostEnt *to) +{ + PRIntn na, na_old; + char **ap; + char **new_addr_list; + + /* Count the addresses, then grow storage for the pointers */ + for (na_old = 0, ap = to->h_addr_list; *ap != 0; na_old++, ap++) + {;} /* nothing to execute */ + for (na = na_old + 1, ap = from->h_addr_list; *ap != 0; na++, ap++) + {;} /* nothing to execute */ + new_addr_list = (char**)Alloc( + na * sizeof(char*), buf, bufsize, sizeof(char**)); + if (!new_addr_list) return PR_FAILURE; + + /* Copy the V6 addresses, one at a time */ + for (na = 0, ap = to->h_addr_list; *ap != 0; na++, ap++) { + new_addr_list[na] = to->h_addr_list[na]; + } + to->h_addr_list = new_addr_list; + + /* Copy the V4 addresses, one at a time */ + for (ap = from->h_addr_list; *ap != 0; na++, ap++) { + to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0); + if (!to->h_addr_list[na]) return PR_FAILURE; + MakeIPv4MappedAddr(*ap, to->h_addr_list[na]); + } + to->h_addr_list[na] = 0; + return PR_SUCCESS; +} +#endif + +PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName( + const char *name, PRUint16 af, PRIntn flags, + char *buf, PRIntn bufsize, PRHostEnt *hp) +{ + struct hostent *h = 0; + PRStatus rv = PR_FAILURE; +#if defined(_PR_HAVE_GETHOST_R) + char localbuf[PR_NETDB_BUF_SIZE]; + char *tmpbuf; + struct hostent tmphe; + int h_err; +#endif +#if defined(_PR_HAVE_GETIPNODEBYNAME) + PRUint16 md_af = af; + int error_num; + int tmp_flags = 0; +#endif +#if defined(_PR_HAVE_GETHOSTBYNAME2) + PRBool did_af_inet = PR_FALSE; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (af != PR_AF_INET && af != PR_AF_INET6) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + +#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) + PR_Lock(_pr_query_ifs_lock); + /* + * Keep querying the presence of IPv4 and IPv6 interfaces until + * at least one is up. This allows us to detect the local + * machine going from offline to online. + */ + if (!_pr_have_inet_if && !_pr_have_inet6_if) { + _pr_QueryNetIfs(); +#ifdef DEBUG_QUERY_IFS + if (_pr_have_inet_if) + printf("Have IPv4 source address\n"); + if (_pr_have_inet6_if) + printf("Have IPv6 source address\n"); +#endif + } + PR_Unlock(_pr_query_ifs_lock); +#endif + +#if defined(_PR_HAVE_GETIPNODEBYNAME) + if (flags & PR_AI_V4MAPPED) + tmp_flags |= AI_V4MAPPED; + if (flags & PR_AI_ADDRCONFIG) + tmp_flags |= AI_ADDRCONFIG; + if (flags & PR_AI_ALL) + tmp_flags |= AI_ALL; + if (af == PR_AF_INET6) + md_af = AF_INET6; + else + md_af = af; +#endif + +#if defined(_PR_HAVE_GETHOST_R) + tmpbuf = localbuf; + if (bufsize > sizeof(localbuf)) + { + tmpbuf = (char *)PR_Malloc(bufsize); + if (NULL == tmpbuf) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return rv; + } + } +#endif + + /* Do not need to lock the DNS lock if getipnodebyname() is called */ +#ifdef _PR_INET6 +#ifdef _PR_HAVE_GETHOSTBYNAME2 + LOCK_DNS(); + if (af == PR_AF_INET6) + { + if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet6_if) + { +#ifdef _PR_INET6_PROBE + if (_pr_ipv6_is_present()) +#endif + h = GETHOSTBYNAME2(name, AF_INET6); + } + if ((NULL == h) && (flags & PR_AI_V4MAPPED) + && ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if)) + { + did_af_inet = PR_TRUE; + h = GETHOSTBYNAME2(name, AF_INET); + } + } + else + { + if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if) + { + did_af_inet = PR_TRUE; + h = GETHOSTBYNAME2(name, af); + } + } +#elif defined(_PR_HAVE_GETIPNODEBYNAME) + h = getipnodebyname(name, md_af, tmp_flags, &error_num); +#else +#error "Unknown name-to-address translation function" +#endif /* _PR_HAVE_GETHOSTBYNAME2 */ +#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) + if (_pr_ipv6_is_present()) + { +#ifdef PR_GETIPNODE_NOT_THREADSAFE + LOCK_DNS(); +#endif + h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num); + } + else + { + LOCK_DNS(); + h = GETHOSTBYNAME(name); + } +#else /* _PR_INET6 */ + LOCK_DNS(); + h = GETHOSTBYNAME(name); +#endif /* _PR_INET6 */ + + if (NULL == h) + { +#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); +#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) + if (_pr_ipv6_is_present()) + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); + else + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); +#else + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); +#endif + } + else + { + _PRIPAddrConversion conversion = _PRIPAddrNoConversion; + + if (af == PR_AF_INET6) conversion = _PRIPAddrIPv4Mapped; + rv = CopyHostent(h, &buf, &bufsize, conversion, hp); + if (PR_SUCCESS != rv) + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); +#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) + freehostent(h); +#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) + if (_pr_ipv6_is_present()) + (*((_pr_freehostent_t)_pr_freehostent_fp))(h); +#endif +#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) + if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED) + && ((flags & PR_AI_ALL) + || ((flags & PR_AI_ADDRCONFIG) && _pr_have_inet_if)) + && !did_af_inet && (h = GETHOSTBYNAME2(name, AF_INET)) != 0) { + rv = AppendV4AddrsToHostent(h, &buf, &bufsize, hp); + if (PR_SUCCESS != rv) + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } +#endif + } + + /* Must match the convoluted logic above for LOCK_DNS() */ +#ifdef _PR_INET6 +#ifdef _PR_HAVE_GETHOSTBYNAME2 + UNLOCK_DNS(); +#endif /* _PR_HAVE_GETHOSTBYNAME2 */ +#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) +#ifdef PR_GETIPNODE_NOT_THREADSAFE + UNLOCK_DNS(); +#else + if (!_pr_ipv6_is_present()) + UNLOCK_DNS(); +#endif +#else /* _PR_INET6 */ + UNLOCK_DNS(); +#endif /* _PR_INET6 */ + +#if defined(_PR_HAVE_GETHOST_R) + if (tmpbuf != localbuf) + PR_Free(tmpbuf); +#endif + + return rv; +} + +PR_IMPLEMENT(PRStatus) PR_GetHostByAddr( + const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry) +{ + struct hostent *h; + PRStatus rv = PR_FAILURE; + const void *addr; + PRUint32 tmp_ip; + int addrlen; + PRInt32 af; +#if defined(_PR_HAVE_GETHOST_R) + char localbuf[PR_NETDB_BUF_SIZE]; + char *tmpbuf; + struct hostent tmphe; + int h_err; +#endif +#if defined(_PR_HAVE_GETIPNODEBYADDR) + int error_num; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (hostaddr->raw.family == PR_AF_INET6) + { +#if defined(_PR_INET6_PROBE) + af = _pr_ipv6_is_present() ? AF_INET6 : AF_INET; +#elif defined(_PR_INET6) + af = AF_INET6; +#else + af = AF_INET; +#endif +#if defined(_PR_GHBA_DISALLOW_V4MAPPED) + if (_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) + af = AF_INET; +#endif + } + else + { + PR_ASSERT(hostaddr->raw.family == AF_INET); + af = AF_INET; + } + if (hostaddr->raw.family == PR_AF_INET6) { +#if defined(_PR_INET6) || defined(_PR_INET6_PROBE) + if (af == AF_INET6) { + addr = &hostaddr->ipv6.ip; + addrlen = sizeof(hostaddr->ipv6.ip); + } + else +#endif + { + PR_ASSERT(af == AF_INET); + if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return rv; + } + tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *) + &hostaddr->ipv6.ip); + addr = &tmp_ip; + addrlen = sizeof(tmp_ip); + } + } else { + PR_ASSERT(hostaddr->raw.family == AF_INET); + PR_ASSERT(af == AF_INET); + addr = &hostaddr->inet.ip; + addrlen = sizeof(hostaddr->inet.ip); + } + +#if defined(_PR_HAVE_GETHOST_R) + tmpbuf = localbuf; + if (bufsize > sizeof(localbuf)) + { + tmpbuf = (char *)PR_Malloc(bufsize); + if (NULL == tmpbuf) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return rv; + } + } +#endif + + /* Do not need to lock the DNS lock if getipnodebyaddr() is called */ +#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6) + h = getipnodebyaddr(addr, addrlen, af, &error_num); +#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE) + if (_pr_ipv6_is_present()) + { +#ifdef PR_GETIPNODE_NOT_THREADSAFE + LOCK_DNS(); +#endif + h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen, + af, &error_num); + } + else + { + LOCK_DNS(); + h = GETHOSTBYADDR(addr, addrlen, af); + } +#else /* _PR_HAVE_GETIPNODEBYADDR */ + LOCK_DNS(); + h = GETHOSTBYADDR(addr, addrlen, af); +#endif /* _PR_HAVE_GETIPNODEBYADDR */ + if (NULL == h) + { +#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR) + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); +#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR) + if (_pr_ipv6_is_present()) + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); + else + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); +#else + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); +#endif + } + else + { + _PRIPAddrConversion conversion = _PRIPAddrNoConversion; + if (hostaddr->raw.family == PR_AF_INET6) { + if (af == AF_INET) { + if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*) + &hostaddr->ipv6.ip)) { + conversion = _PRIPAddrIPv4Mapped; + } else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *) + &hostaddr->ipv6.ip)) { + conversion = _PRIPAddrIPv4Compat; + } + } + } + rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry); + if (PR_SUCCESS != rv) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } +#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR) + freehostent(h); +#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR) + if (_pr_ipv6_is_present()) + (*((_pr_freehostent_t)_pr_freehostent_fp))(h); +#endif + } + + /* Must match the convoluted logic above for LOCK_DNS() */ +#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6) +#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE) +#ifdef PR_GETIPNODE_NOT_THREADSAFE + UNLOCK_DNS(); +#else + if (!_pr_ipv6_is_present()) + UNLOCK_DNS(); +#endif +#else /* _PR_HAVE_GETIPNODEBYADDR */ + UNLOCK_DNS(); +#endif /* _PR_HAVE_GETIPNODEBYADDR */ + +#if defined(_PR_HAVE_GETHOST_R) + if (tmpbuf != localbuf) + PR_Free(tmpbuf); +#endif + + return rv; +} + +/******************************************************************************/ +/* + * Some systems define a reentrant version of getprotobyname(). Too bad + * the signature isn't always the same. But hey, they tried. If there + * is such a definition, use it. Otherwise, grab a lock and do it here. + */ +/******************************************************************************/ + +#if !defined(_PR_HAVE_GETPROTO_R) +/* + * This may seem like a silly thing to do, but the compiler SHOULD + * complain if getprotobyname_r() is implemented on some system and + * we're not using it. For sure these signatures are different than + * any usable implementation. + */ + +#if defined(ANDROID) +/* Android's Bionic libc system includes prototypes for these in netdb.h, + * but doesn't actually include implementations. It uses the 5-arg form, + * so these functions end up not matching the prototype. So just rename + * them if not found. + */ +#define getprotobyname_r _pr_getprotobyname_r +#define getprotobynumber_r _pr_getprotobynumber_r +#endif + +static struct protoent *getprotobyname_r(const char* name) +{ + return getprotobyname(name); +} /* getprotobyname_r */ + +static struct protoent *getprotobynumber_r(PRInt32 number) +{ + return getprotobynumber(number); +} /* getprotobynumber_r */ + +#endif /* !defined(_PR_HAVE_GETPROTO_R) */ + +PR_IMPLEMENT(PRStatus) PR_GetProtoByName( + const char* name, char* buffer, PRInt32 buflen, PRProtoEnt* result) +{ + PRStatus rv = PR_SUCCESS; +#if defined(_PR_HAVE_GETPROTO_R) + struct protoent* res = (struct protoent*)result; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + +#if defined(_PR_HAVE_GETPROTO_R_INT) + { + /* + ** The protoent_data has a pointer as the first field. + ** That implies the buffer better be aligned, and char* + ** doesn't promise much. + */ + PRUptrdiff aligned = (PRUptrdiff)buffer; + if (0 != (aligned & (sizeof(struct protoent_data*) - 1))) + { + aligned += sizeof(struct protoent_data*) - 1; + aligned &= ~(sizeof(struct protoent_data*) - 1); + buflen -= (aligned - (PRUptrdiff)buffer); + buffer = (char*)aligned; + } + } +#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */ + + if (PR_NETDB_BUF_SIZE > buflen) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + +#if defined(_PR_HAVE_GETPROTO_R_POINTER) + if (NULL == getprotobyname_r(name, res, buffer, buflen)) + { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } +#elif defined(_PR_HAVE_GETPROTO_R_INT) + /* + ** The buffer needs to be zero'd, and it should be + ** at least the size of a struct protoent_data. + */ + memset(buffer, 0, buflen); + if (-1 == getprotobyname_r(name, res, (struct protoent_data*)buffer)) + { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } +#elif defined(_PR_HAVE_5_ARG_GETPROTO_R) + /* The 5th argument for getprotobyname_r() cannot be NULL */ + if (-1 == getprotobyname_r(name, res, buffer, buflen, &res)) + { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } +#else /* do it the hard way */ + { + struct protoent *staticBuf; + PR_Lock(_getproto_lock); + staticBuf = getprotobyname_r(name); + if (NULL == staticBuf) + { + rv = PR_FAILURE; + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + } + else + { +#if defined(SYMBIAN) + char* aliases[2]; + AssignAliases(staticBuf, aliases); +#endif + rv = CopyProtoent(staticBuf, buffer, buflen, result); + if (PR_FAILURE == rv) + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } + PR_Unlock(_getproto_lock); + } +#endif /* all that */ + return rv; +} + +PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber( + PRInt32 number, char* buffer, PRInt32 buflen, PRProtoEnt* result) +{ + PRStatus rv = PR_SUCCESS; +#if defined(_PR_HAVE_GETPROTO_R) + struct protoent* res = (struct protoent*)result; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + +#if defined(_PR_HAVE_GETPROTO_R_INT) + { + /* + ** The protoent_data has a pointer as the first field. + ** That implies the buffer better be aligned, and char* + ** doesn't promise much. + */ + PRUptrdiff aligned = (PRUptrdiff)buffer; + if (0 != (aligned & (sizeof(struct protoent_data*) - 1))) + { + aligned += sizeof(struct protoent_data*) - 1; + aligned &= ~(sizeof(struct protoent_data*) - 1); + buflen -= (aligned - (PRUptrdiff)buffer); + buffer = (char*)aligned; + } + } +#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */ + + if (PR_NETDB_BUF_SIZE > buflen) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + +#if defined(_PR_HAVE_GETPROTO_R_POINTER) + if (NULL == getprotobynumber_r(number, res, buffer, buflen)) + { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } + +#elif defined(_PR_HAVE_GETPROTO_R_INT) + /* + ** The buffer needs to be zero'd for these OS's. + */ + memset(buffer, 0, buflen); + if (-1 == getprotobynumber_r(number, res, (struct protoent_data*)buffer)) + { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } +#elif defined(_PR_HAVE_5_ARG_GETPROTO_R) + /* The 5th argument for getprotobynumber_r() cannot be NULL */ + if (-1 == getprotobynumber_r(number, res, buffer, buflen, &res)) + { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } +#else /* do it the hard way */ + { + struct protoent *staticBuf; + PR_Lock(_getproto_lock); + staticBuf = getprotobynumber_r(number); + if (NULL == staticBuf) + { + rv = PR_FAILURE; + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + } + else + { +#if defined(SYMBIAN) + char* aliases[2]; + AssignAliases(staticBuf, aliases); +#endif + rv = CopyProtoent(staticBuf, buffer, buflen, result); + if (PR_FAILURE == rv) + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } + PR_Unlock(_getproto_lock); + } +#endif /* all that crap */ + return rv; + +} + +PRUintn _PR_NetAddrSize(const PRNetAddr* addr) +{ + PRUintn addrsize; + + /* + * RFC 2553 added a new field (sin6_scope_id) to + * struct sockaddr_in6. PRNetAddr's ipv6 member has a + * scope_id field to match the new field. In order to + * work with older implementations supporting RFC 2133, + * we take the size of struct sockaddr_in6 instead of + * addr->ipv6. + */ + if (AF_INET == addr->raw.family) + addrsize = sizeof(addr->inet); + else if (PR_AF_INET6 == addr->raw.family) +#if defined(_PR_INET6) + addrsize = sizeof(struct sockaddr_in6); +#else + addrsize = sizeof(addr->ipv6); +#endif +#if defined(XP_UNIX) || defined(XP_OS2) + else if (AF_UNIX == addr->raw.family) + addrsize = sizeof(addr->local); +#endif + else addrsize = 0; + + return addrsize; +} /* _PR_NetAddrSize */ + +PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt( + PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address) +{ + void *addr = hostEnt->h_addr_list[enumIndex++]; + memset(address, 0, sizeof(PRNetAddr)); + if (NULL == addr) enumIndex = 0; + else + { + address->raw.family = hostEnt->h_addrtype; + if (PR_AF_INET6 == hostEnt->h_addrtype) + { + address->ipv6.port = htons(port); + address->ipv6.flowinfo = 0; + address->ipv6.scope_id = 0; + memcpy(&address->ipv6.ip, addr, hostEnt->h_length); + } + else + { + PR_ASSERT(AF_INET == hostEnt->h_addrtype); + address->inet.port = htons(port); + memcpy(&address->inet.ip, addr, hostEnt->h_length); + } + } + return enumIndex; +} /* PR_EnumerateHostEnt */ + +PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr( + PRNetAddrValue val, PRUint16 port, PRNetAddr *addr) +{ + PRStatus rv = PR_SUCCESS; + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet)); + addr->inet.family = AF_INET; + addr->inet.port = htons(port); + switch (val) + { + case PR_IpAddrNull: + break; /* don't overwrite the address */ + case PR_IpAddrAny: + addr->inet.ip = htonl(INADDR_ANY); + break; + case PR_IpAddrLoopback: + addr->inet.ip = htonl(INADDR_LOOPBACK); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; + } + return rv; +} /* PR_InitializeNetAddr */ + +PR_IMPLEMENT(PRStatus) PR_SetNetAddr( + PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr) +{ + PRStatus rv = PR_SUCCESS; + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (af == PR_AF_INET6) + { + if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->ipv6)); + addr->ipv6.family = af; + addr->ipv6.port = htons(port); + addr->ipv6.flowinfo = 0; + addr->ipv6.scope_id = 0; + switch (val) + { + case PR_IpAddrNull: + break; /* don't overwrite the address */ + case PR_IpAddrAny: + addr->ipv6.ip = _pr_in6addr_any; + break; + case PR_IpAddrLoopback: + addr->ipv6.ip = _pr_in6addr_loopback; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; + } + } + else + { + if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet)); + addr->inet.family = af; + addr->inet.port = htons(port); + switch (val) + { + case PR_IpAddrNull: + break; /* don't overwrite the address */ + case PR_IpAddrAny: + addr->inet.ip = htonl(INADDR_ANY); + break; + case PR_IpAddrLoopback: + addr->inet.ip = htonl(INADDR_LOOPBACK); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; + } + } + return rv; +} /* PR_SetNetAddr */ + +PR_IMPLEMENT(PRBool) +PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val) +{ + if (addr->raw.family == PR_AF_INET6) { + if (val == PR_IpAddrAny) { + if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) { + return PR_TRUE; + } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip) + && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip) + == htonl(INADDR_ANY)) { + return PR_TRUE; + } + } else if (val == PR_IpAddrLoopback) { + if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) { + return PR_TRUE; + } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip) + && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip) + == htonl(INADDR_LOOPBACK)) { + return PR_TRUE; + } + } else if (val == PR_IpAddrV4Mapped + && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) { + return PR_TRUE; + } + } else { + if (addr->raw.family == AF_INET) { + if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) { + return PR_TRUE; + } else if (val == PR_IpAddrLoopback + && addr->inet.ip == htonl(INADDR_LOOPBACK)) { + return PR_TRUE; + } + } + } + return PR_FALSE; +} + +extern int pr_inet_aton(const char *cp, PRUint32 *addr); + +#define XX 127 +static const unsigned char index_hex[256] = { + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX, + XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, + XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, +}; + +/* + * StringToV6Addr() returns 1 if the conversion succeeds, + * or 0 if the input is not a valid IPv6 address string. + * (Same as inet_pton(AF_INET6, string, addr).) + */ +static int StringToV6Addr(const char *string, PRIPv6Addr *addr) +{ + const unsigned char *s = (const unsigned char *)string; + int section = 0; /* index of the current section (a 16-bit + * piece of the address */ + int double_colon = -1; /* index of the section after the first + * 16-bit group of zeros represented by + * the double colon */ + unsigned int val; + int len; + + /* Handle initial (double) colon */ + if (*s == ':') { + if (s[1] != ':') return 0; + s += 2; + addr->pr_s6_addr16[0] = 0; + section = double_colon = 1; + } + + while (*s) { + if (section == 8) return 0; /* too long */ + if (*s == ':') { + if (double_colon != -1) return 0; /* two double colons */ + addr->pr_s6_addr16[section++] = 0; + double_colon = section; + s++; + continue; + } + for (len = val = 0; len < 4 && index_hex[*s] != XX; len++) { + val = (val << 4) + index_hex[*s++]; + } + if (*s == '.') { + if (len == 0) return 0; /* nothing between : and . */ + break; + } + if (*s == ':') { + s++; + if (!*s) return 0; /* cannot end with single colon */ + } else if (*s) { + return 0; /* bad character */ + } + addr->pr_s6_addr16[section++] = htons((unsigned short)val); + } + + if (*s == '.') { + /* Have a trailing v4 format address */ + if (section > 6) return 0; /* not enough room */ + + /* + * The number before the '.' is decimal, but we parsed it + * as hex. That means it is in BCD. Check it for validity + * and convert it to binary. + */ + if (val > 0x0255 || (val & 0xf0) > 0x90 || (val & 0xf) > 9) return 0; + val = (val >> 8) * 100 + ((val >> 4) & 0xf) * 10 + (val & 0xf); + addr->pr_s6_addr[2 * section] = val; + + s++; + val = index_hex[*s++]; + if (val > 9) return 0; + while (*s >= '0' && *s <= '9') { + val = val * 10 + *s++ - '0'; + if (val > 255) return 0; + } + if (*s != '.') return 0; /* must have exactly 4 decimal numbers */ + addr->pr_s6_addr[2 * section + 1] = val; + section++; + + s++; + val = index_hex[*s++]; + if (val > 9) return 0; + while (*s >= '0' && *s <= '9') { + val = val * 10 + *s++ - '0'; + if (val > 255) return 0; + } + if (*s != '.') return 0; /* must have exactly 4 decimal numbers */ + addr->pr_s6_addr[2 * section] = val; + + s++; + val = index_hex[*s++]; + if (val > 9) return 0; + while (*s >= '0' && *s <= '9') { + val = val * 10 + *s++ - '0'; + if (val > 255) return 0; + } + if (*s) return 0; /* must have exactly 4 decimal numbers */ + addr->pr_s6_addr[2 * section + 1] = val; + section++; + } + + if (double_colon != -1) { + /* Stretch the double colon */ + int tosection; + int ncopy = section - double_colon; + for (tosection = 7; ncopy--; tosection--) { + addr->pr_s6_addr16[tosection] = + addr->pr_s6_addr16[double_colon + ncopy]; + } + while (tosection >= double_colon) { + addr->pr_s6_addr16[tosection--] = 0; + } + } else if (section != 8) { + return 0; /* too short */ + } + return 1; +} +#undef XX + +#ifndef _PR_HAVE_INET_NTOP +static const char *basis_hex = "0123456789abcdef"; + +/* + * V6AddrToString() returns a pointer to the buffer containing + * the text string if the conversion succeeds, and NULL otherwise. + * (Same as inet_ntop(AF_INET6, addr, buf, size), except that errno + * is not set on failure.) + */ +static const char *V6AddrToString( + const PRIPv6Addr *addr, char *buf, PRUint32 size) +{ +#define STUFF(c) do { \ + if (!size--) return NULL; \ + *buf++ = (c); \ +} while (0) + + int double_colon = -1; /* index of the first 16-bit + * group of zeros represented + * by the double colon */ + int double_colon_length = 1; /* use double colon only if + * there are two or more 16-bit + * groups of zeros */ + int zero_length; + int section; + unsigned int val; + const char *bufcopy = buf; + + /* Scan to find the placement of the double colon */ + for (section = 0; section < 8; section++) { + if (addr->pr_s6_addr16[section] == 0) { + zero_length = 1; + section++; + while (section < 8 && addr->pr_s6_addr16[section] == 0) { + zero_length++; + section++; + } + /* Select the longest sequence of zeros */ + if (zero_length > double_colon_length) { + double_colon = section - zero_length; + double_colon_length = zero_length; + } + } + } + + /* Now start converting to a string */ + section = 0; + + if (double_colon == 0) { + if (double_colon_length == 6 || + (double_colon_length == 5 && addr->pr_s6_addr16[5] == 0xffff)) { + /* ipv4 format address */ + STUFF(':'); + STUFF(':'); + if (double_colon_length == 5) { + STUFF('f'); + STUFF('f'); + STUFF('f'); + STUFF('f'); + STUFF(':'); + } + if (addr->pr_s6_addr[12] > 99) STUFF(addr->pr_s6_addr[12]/100 + '0'); + if (addr->pr_s6_addr[12] > 9) STUFF((addr->pr_s6_addr[12]%100)/10 + '0'); + STUFF(addr->pr_s6_addr[12]%10 + '0'); + STUFF('.'); + if (addr->pr_s6_addr[13] > 99) STUFF(addr->pr_s6_addr[13]/100 + '0'); + if (addr->pr_s6_addr[13] > 9) STUFF((addr->pr_s6_addr[13]%100)/10 + '0'); + STUFF(addr->pr_s6_addr[13]%10 + '0'); + STUFF('.'); + if (addr->pr_s6_addr[14] > 99) STUFF(addr->pr_s6_addr[14]/100 + '0'); + if (addr->pr_s6_addr[14] > 9) STUFF((addr->pr_s6_addr[14]%100)/10 + '0'); + STUFF(addr->pr_s6_addr[14]%10 + '0'); + STUFF('.'); + if (addr->pr_s6_addr[15] > 99) STUFF(addr->pr_s6_addr[15]/100 + '0'); + if (addr->pr_s6_addr[15] > 9) STUFF((addr->pr_s6_addr[15]%100)/10 + '0'); + STUFF(addr->pr_s6_addr[15]%10 + '0'); + STUFF('\0'); + return bufcopy; + } + } + + while (section < 8) { + if (section == double_colon) { + STUFF(':'); + STUFF(':'); + section += double_colon_length; + continue; + } + val = ntohs(addr->pr_s6_addr16[section]); + if (val > 0xfff) { + STUFF(basis_hex[val >> 12]); + } + if (val > 0xff) { + STUFF(basis_hex[(val >> 8) & 0xf]); + } + if (val > 0xf) { + STUFF(basis_hex[(val >> 4) & 0xf]); + } + STUFF(basis_hex[val & 0xf]); + section++; + if (section < 8 && section != double_colon) STUFF(':'); + } + STUFF('\0'); + return bufcopy; +#undef STUFF +} +#endif /* !_PR_HAVE_INET_NTOP */ + +/* + * Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr + */ +PR_IMPLEMENT(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr) +{ + PRUint8 *dstp; + dstp = v6addr->pr_s6_addr; + memset(dstp, 0, 10); + memset(dstp + 10, 0xff, 2); + memcpy(dstp + 12,(char *) &v4addr, 4); +} + +PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { return ntohs(n); } +PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { return ntohl(n); } +PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { return htons(n); } +PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { return htonl(n); } +PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n) +{ +#ifdef IS_BIG_ENDIAN + return n; +#else + PRUint64 tmp; + PRUint32 hi, lo; + LL_L2UI(lo, n); + LL_SHR(tmp, n, 32); + LL_L2UI(hi, tmp); + hi = PR_ntohl(hi); + lo = PR_ntohl(lo); + LL_UI2L(n, lo); + LL_SHL(n, n, 32); + LL_UI2L(tmp, hi); + LL_ADD(n, n, tmp); + return n; +#endif +} /* ntohll */ + +PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n) +{ +#ifdef IS_BIG_ENDIAN + return n; +#else + PRUint64 tmp; + PRUint32 hi, lo; + LL_L2UI(lo, n); + LL_SHR(tmp, n, 32); + LL_L2UI(hi, tmp); + hi = htonl(hi); + lo = htonl(lo); + LL_UI2L(n, lo); + LL_SHL(n, n, 32); + LL_UI2L(tmp, hi); + LL_ADD(n, n, tmp); + return n; +#endif +} /* htonll */ + + +/* + * Implementation of PR_GetAddrInfoByName and friends + * + * Compile-time options: + * + * _PR_HAVE_GETADDRINFO Define this macro if the target system provides + * getaddrinfo. With this defined, NSPR will require + * getaddrinfo at run time. If this if not defined, + * then NSPR will attempt to dynamically resolve + * getaddrinfo, falling back to PR_GetHostByName if + * getaddrinfo does not exist on the target system. + * + * Since getaddrinfo is a relatively new system call on many systems, + * we are forced to dynamically resolve it at run time in most cases. + * The exception includes any system (such as Mac OS X) that is known to + * provide getaddrinfo in all versions that NSPR cares to support. + */ + +#if defined(_PR_HAVE_GETADDRINFO) + +#if defined(_PR_INET6) + +typedef struct addrinfo PRADDRINFO; +#define GETADDRINFO getaddrinfo +#define FREEADDRINFO freeaddrinfo +#define GETNAMEINFO getnameinfo + +#elif defined(_PR_INET6_PROBE) + +typedef struct addrinfo PRADDRINFO; + +/* getaddrinfo/freeaddrinfo/getnameinfo prototypes */ +#if defined(WIN32) +#define FUNC_MODIFIER __stdcall +#else +#define FUNC_MODIFIER +#endif +typedef int (FUNC_MODIFIER * FN_GETADDRINFO) + (const char *nodename, + const char *servname, + const PRADDRINFO *hints, + PRADDRINFO **res); +typedef int (FUNC_MODIFIER * FN_FREEADDRINFO) + (PRADDRINFO *ai); +typedef int (FUNC_MODIFIER * FN_GETNAMEINFO) + (const struct sockaddr *addr, int addrlen, + char *host, int hostlen, + char *serv, int servlen, int flags); + +/* global state */ +static FN_GETADDRINFO _pr_getaddrinfo = NULL; +static FN_FREEADDRINFO _pr_freeaddrinfo = NULL; +static FN_GETNAMEINFO _pr_getnameinfo = NULL; + +#define GETADDRINFO_SYMBOL "getaddrinfo" +#define FREEADDRINFO_SYMBOL "freeaddrinfo" +#define GETNAMEINFO_SYMBOL "getnameinfo" + +PRStatus +_pr_find_getaddrinfo(void) +{ + PRLibrary *lib; +#ifdef WIN32 + /* + * On windows, we need to search ws2_32.dll or wship6.dll + * (Microsoft IPv6 Technology Preview for Windows 2000) for + * getaddrinfo and freeaddrinfo. These libraries might not + * be loaded yet. + */ + const char *libname[] = { "ws2_32.dll", "wship6.dll" }; + int i; + + for (i = 0; i < sizeof(libname)/sizeof(libname[0]); i++) { + lib = PR_LoadLibrary(libname[i]); + if (!lib) { + continue; + } + _pr_getaddrinfo = (FN_GETADDRINFO) + PR_FindFunctionSymbol(lib, GETADDRINFO_SYMBOL); + if (!_pr_getaddrinfo) { + PR_UnloadLibrary(lib); + continue; + } + _pr_freeaddrinfo = (FN_FREEADDRINFO) + PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL); + _pr_getnameinfo = (FN_GETNAMEINFO) + PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL); + if (!_pr_freeaddrinfo || !_pr_getnameinfo) { + PR_UnloadLibrary(lib); + continue; + } + /* Keep the library loaded. */ + return PR_SUCCESS; + } + return PR_FAILURE; +#else + /* + * Resolve getaddrinfo by searching all loaded libraries. Then + * search library containing getaddrinfo for freeaddrinfo. + */ + _pr_getaddrinfo = (FN_GETADDRINFO) + PR_FindFunctionSymbolAndLibrary(GETADDRINFO_SYMBOL, &lib); + if (!_pr_getaddrinfo) { + return PR_FAILURE; + } + _pr_freeaddrinfo = (FN_FREEADDRINFO) + PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL); + _pr_getnameinfo = (FN_GETNAMEINFO) + PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL); + PR_UnloadLibrary(lib); + if (!_pr_freeaddrinfo || !_pr_getnameinfo) { + return PR_FAILURE; + } + return PR_SUCCESS; +#endif +} + +#define GETADDRINFO (*_pr_getaddrinfo) +#define FREEADDRINFO (*_pr_freeaddrinfo) +#define GETNAMEINFO (*_pr_getnameinfo) + +#endif /* _PR_INET6 */ + +#endif /* _PR_HAVE_GETADDRINFO */ + +#if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE) +/* + * If getaddrinfo does not exist, then we will fall back on + * PR_GetHostByName, which requires that we allocate a buffer for the + * PRHostEnt data structure and its members. + */ +typedef struct PRAddrInfoFB { + char buf[PR_NETDB_BUF_SIZE]; + PRHostEnt hostent; + PRBool has_cname; +} PRAddrInfoFB; + +static PRAddrInfo * +pr_GetAddrInfoByNameFB(const char *hostname, + PRUint16 af, + PRIntn flags) +{ + PRStatus rv; + PRAddrInfoFB *ai; + /* fallback on PR_GetHostByName */ + ai = PR_NEW(PRAddrInfoFB); + if (!ai) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + rv = PR_GetHostByName(hostname, ai->buf, sizeof ai->buf, &ai->hostent); + if (rv == PR_FAILURE) { + PR_Free(ai); + return NULL; + } + ai->has_cname = !(flags & PR_AI_NOCANONNAME); + + return (PRAddrInfo *) ai; +} +#endif /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */ + +PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, + PRUint16 af, + PRIntn flags) +{ + /* restrict input to supported values */ + if ((af != PR_AF_INET && af != PR_AF_UNSPEC) || + (flags & ~ PR_AI_NOCANONNAME) != PR_AI_ADDRCONFIG) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } + + if (!_pr_initialized) _PR_ImplicitInitialization(); + +#if !defined(_PR_HAVE_GETADDRINFO) + return pr_GetAddrInfoByNameFB(hostname, af, flags); +#else +#if defined(_PR_INET6_PROBE) + if (!_pr_ipv6_is_present()) { + return pr_GetAddrInfoByNameFB(hostname, af, flags); + } +#endif + { + PRADDRINFO *res, hints; + int rv; + + /* + * we assume a RFC 2553 compliant getaddrinfo. this may at some + * point need to be customized as platforms begin to adopt the + * RFC 3493. + */ + + memset(&hints, 0, sizeof(hints)); + if (!(flags & PR_AI_NOCANONNAME)) + hints.ai_flags |= AI_CANONNAME; +#ifdef AI_ADDRCONFIG + /* + * Propagate AI_ADDRCONFIG to the GETADDRINFO call if PR_AI_ADDRCONFIG + * is set. + * + * Need a workaround for loopback host addresses: + * The problem is that in glibc and Windows, AI_ADDRCONFIG applies the + * existence of an outgoing network interface to IP addresses of the + * loopback interface, due to a strict interpretation of the + * specification. For example, if a computer does not have any + * outgoing IPv6 network interface, but its loopback network interface + * supports IPv6, a getaddrinfo call on "localhost" with AI_ADDRCONFIG + * won't return the IPv6 loopback address "::1", because getaddrinfo + * thinks the computer cannot connect to any IPv6 destination, + * ignoring the remote vs. local/loopback distinction. + */ + if ((flags & PR_AI_ADDRCONFIG) && + strcmp(hostname, "localhost") != 0 && + strcmp(hostname, "localhost.localdomain") != 0 && + strcmp(hostname, "localhost6") != 0 && + strcmp(hostname, "localhost6.localdomain6") != 0) { + hints.ai_flags |= AI_ADDRCONFIG; + } +#endif + hints.ai_family = (af == PR_AF_INET) ? AF_INET : AF_UNSPEC; + + /* + * it is important to select a socket type in the hints, otherwise we + * will get back repetitive entries: one for each socket type. since + * we do not expose ai_socktype through our API, it is okay to do this + * here. the application may still choose to create a socket of some + * other type. + */ + hints.ai_socktype = SOCK_STREAM; + + rv = GETADDRINFO(hostname, NULL, &hints, &res); +#ifdef AI_ADDRCONFIG + if (rv == EAI_BADFLAGS && (hints.ai_flags & AI_ADDRCONFIG)) { + hints.ai_flags &= ~AI_ADDRCONFIG; + rv = GETADDRINFO(hostname, NULL, &hints, &res); + } +#endif + if (rv == 0) + return (PRAddrInfo *) res; + + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv); + } + return NULL; +#endif +} + +PR_IMPLEMENT(void) PR_FreeAddrInfo(PRAddrInfo *ai) +{ +#if defined(_PR_HAVE_GETADDRINFO) +#if defined(_PR_INET6_PROBE) + if (!_pr_ipv6_is_present()) + PR_Free((PRAddrInfoFB *) ai); + else +#endif + FREEADDRINFO((PRADDRINFO *) ai); +#else + PR_Free((PRAddrInfoFB *) ai); +#endif +} + +PR_IMPLEMENT(void *) PR_EnumerateAddrInfo(void *iterPtr, + const PRAddrInfo *base, + PRUint16 port, + PRNetAddr *result) +{ +#if defined(_PR_HAVE_GETADDRINFO) + PRADDRINFO *ai; +#if defined(_PR_INET6_PROBE) + if (!_pr_ipv6_is_present()) { + /* using PRAddrInfoFB */ + PRIntn iter = (PRIntn)(PRPtrdiff) iterPtr; + iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result); + if (iter < 0) + iter = 0; + return (void *)(PRPtrdiff) iter; + } +#endif + + if (iterPtr) + ai = ((PRADDRINFO *) iterPtr)->ai_next; + else + ai = (PRADDRINFO *) base; + + while (ai && ai->ai_addrlen > sizeof(PRNetAddr)) + ai = ai->ai_next; + + if (ai) { + /* copy sockaddr to PRNetAddr */ + memcpy(result, ai->ai_addr, ai->ai_addrlen); + result->raw.family = ai->ai_addr->sa_family; +#ifdef _PR_INET6 + if (AF_INET6 == result->raw.family) + result->raw.family = PR_AF_INET6; +#endif + if (ai->ai_addrlen < sizeof(PRNetAddr)) + memset(((char*)result)+ai->ai_addrlen, 0, sizeof(PRNetAddr) - ai->ai_addrlen); + + if (result->raw.family == PR_AF_INET) + result->inet.port = htons(port); + else + result->ipv6.port = htons(port); + } + + return ai; +#else + /* using PRAddrInfoFB */ + PRIntn iter = (PRIntn) iterPtr; + iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result); + if (iter < 0) + iter = 0; + return (void *) iter; +#endif +} + +PR_IMPLEMENT(const char *) PR_GetCanonNameFromAddrInfo(const PRAddrInfo *ai) +{ +#if defined(_PR_HAVE_GETADDRINFO) +#if defined(_PR_INET6_PROBE) + if (!_pr_ipv6_is_present()) { + const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai; + return fb->has_cname ? fb->hostent.h_name : NULL; + } +#endif + return ((const PRADDRINFO *) ai)->ai_canonname; +#else + const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai; + return fb->has_cname ? fb->hostent.h_name : NULL; +#endif +} + +#if defined(_PR_HAVE_GETADDRINFO) +static PRStatus pr_StringToNetAddrGAI(const char *string, PRNetAddr *addr) +{ + PRADDRINFO *res, hints; + int rv; /* 0 for success, or the error code EAI_xxx */ + PRNetAddr laddr; + PRStatus status = PR_SUCCESS; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_NUMERICHOST; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + rv = GETADDRINFO(string, NULL, &hints, &res); + if (rv != 0) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv); + return PR_FAILURE; + } + + /* pick up the first addr */ + memcpy(&laddr, res->ai_addr, res->ai_addrlen); + if (AF_INET6 == res->ai_addr->sa_family) + { + addr->ipv6.family = PR_AF_INET6; + addr->ipv6.ip = laddr.ipv6.ip; + addr->ipv6.scope_id = laddr.ipv6.scope_id; + } + else if (AF_INET == res->ai_addr->sa_family) + { + addr->inet.family = PR_AF_INET; + addr->inet.ip = laddr.inet.ip; + } + else + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + status = PR_FAILURE; + } + + FREEADDRINFO(res); + return status; +} +#endif /* _PR_HAVE_GETADDRINFO */ + +static PRStatus pr_StringToNetAddrFB(const char *string, PRNetAddr *addr) +{ + PRIntn rv; + + rv = pr_inet_aton(string, &addr->inet.ip); + if (1 == rv) + { + addr->raw.family = AF_INET; + return PR_SUCCESS; + } + + PR_ASSERT(0 == rv); + /* clean up after the failed call */ + memset(&addr->inet.ip, 0, sizeof(addr->inet.ip)); + + rv = StringToV6Addr(string, &addr->ipv6.ip); + if (1 == rv) + { + addr->raw.family = PR_AF_INET6; + return PR_SUCCESS; + } + + PR_ASSERT(0 == rv); + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (!addr || !string || !*string) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + +#if !defined(_PR_HAVE_GETADDRINFO) + return pr_StringToNetAddrFB(string, addr); +#else + /* + * getaddrinfo with AI_NUMERICHOST is much slower than pr_inet_aton on some + * platforms, such as Mac OS X (bug 404399), Linux glibc 2.10 (bug 344809), + * and most likely others. So we only use it to convert literal IP addresses + * that contain IPv6 scope IDs, which pr_inet_aton cannot convert. + */ + if (!strchr(string, '%')) + return pr_StringToNetAddrFB(string, addr); + +#if defined(_PR_INET6_PROBE) + if (!_pr_ipv6_is_present()) + return pr_StringToNetAddrFB(string, addr); +#endif + + return pr_StringToNetAddrGAI(string, addr); +#endif +} + +#if defined(_PR_HAVE_GETADDRINFO) +static PRStatus pr_NetAddrToStringGNI( + const PRNetAddr *addr, char *string, PRUint32 size) +{ + int addrlen; + const PRNetAddr *addrp = addr; +#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) + PRUint16 md_af = addr->raw.family; + PRNetAddr addrcopy; +#endif + int rv; /* 0 for success, or the error code EAI_xxx */ + +#ifdef _PR_INET6 + if (addr->raw.family == PR_AF_INET6) + { + md_af = AF_INET6; +#ifndef _PR_HAVE_SOCKADDR_LEN + addrcopy = *addr; + addrcopy.raw.family = md_af; + addrp = &addrcopy; +#endif + } +#endif + + addrlen = PR_NETADDR_SIZE(addr); +#ifdef _PR_HAVE_SOCKADDR_LEN + addrcopy = *addr; + ((struct sockaddr*)&addrcopy)->sa_len = addrlen; + ((struct sockaddr*)&addrcopy)->sa_family = md_af; + addrp = &addrcopy; +#endif + rv = GETNAMEINFO((const struct sockaddr *)addrp, addrlen, + string, size, NULL, 0, NI_NUMERICHOST); + if (rv != 0) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv); + return PR_FAILURE; + } + return PR_SUCCESS; +} +#endif /* _PR_HAVE_GETADDRINFO */ + +#if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE) +static PRStatus pr_NetAddrToStringFB( + const PRNetAddr *addr, char *string, PRUint32 size) +{ + if (PR_AF_INET6 == addr->raw.family) + { +#if defined(_PR_HAVE_INET_NTOP) + if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size)) +#else + if (NULL == V6AddrToString(&addr->ipv6.ip, string, size)) +#endif + { + /* the size of the result buffer is inadequate */ + PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0); + return PR_FAILURE; + } + } + else + { + if (size < 16) goto failed; + if (AF_INET != addr->raw.family) goto failed; + else + { + unsigned char *byte = (unsigned char*)&addr->inet.ip; + PR_snprintf(string, size, "%u.%u.%u.%u", + byte[0], byte[1], byte[2], byte[3]); + } + } + + return PR_SUCCESS; + +failed: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + +} /* pr_NetAddrToStringFB */ +#endif /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */ + +PR_IMPLEMENT(PRStatus) PR_NetAddrToString( + const PRNetAddr *addr, char *string, PRUint32 size) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + +#if !defined(_PR_HAVE_GETADDRINFO) + return pr_NetAddrToStringFB(addr, string, size); +#else +#if defined(_PR_INET6_PROBE) + if (!_pr_ipv6_is_present()) + return pr_NetAddrToStringFB(addr, string, size); +#endif + return pr_NetAddrToStringGNI(addr, string, size); +#endif +} /* PR_NetAddrToString */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/prolock.c nspr-4.10.7/nspr/pr/src/misc/prolock.c --- nspr-4.9.5/nspr/pr/src/misc/prolock.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prolock.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** prolock.c -- NSPR Ordered Lock +** +** Implement the API defined in prolock.h +** +*/ +#include "prolock.h" +#include "prlog.h" +#include "prerror.h" + +PR_IMPLEMENT(PROrderedLock *) + PR_CreateOrderedLock( + PRInt32 order, + const char *name +) +{ + PR_ASSERT(!"Not implemented"); /* Not implemented yet */ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} /* end PR_CreateOrderedLock() */ + + +PR_IMPLEMENT(void) + PR_DestroyOrderedLock( + PROrderedLock *lock +) +{ + PR_ASSERT(!"Not implemented"); /* Not implemented yet */ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); +} /* end PR_DestroyOrderedLock() */ + + +PR_IMPLEMENT(void) + PR_LockOrderedLock( + PROrderedLock *lock +) +{ + PR_ASSERT(!"Not implemented"); /* Not implemented yet */ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); +} /* end PR_LockOrderedLock() */ + + +PR_IMPLEMENT(PRStatus) + PR_UnlockOrderedLock( + PROrderedLock *lock +) +{ + PR_ASSERT(!"Not implemented"); /* Not implemented yet */ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} /* end PR_UnlockOrderedLock() */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/prrng.c nspr-4.10.7/nspr/pr/src/misc/prrng.c --- nspr-4.9.5/nspr/pr/src/misc/prrng.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prrng.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +/* + * We were not including in optimized builds. On AIX this + * caused libnspr4.so to export memcpy and some binaries linked with + * libnspr4.so resolved their memcpy references with libnspr4.so. To + * be backward compatible with old libnspr4.so binaries, we do not + * include in optimized builds for AIX. (bug 200561) + */ +#if !(defined(AIX) && !defined(DEBUG)) +#include +#endif + +PRSize _pr_CopyLowBits( + void *dst, + PRSize dstlen, + void *src, + PRSize srclen ) +{ + if (srclen <= dstlen) { + memcpy(dst, src, srclen); + return srclen; + } +#if defined IS_BIG_ENDIAN + memcpy(dst, (char*)src + (srclen - dstlen), dstlen); +#else + memcpy(dst, src, dstlen); +#endif + return dstlen; +} + +PR_IMPLEMENT(PRSize) PR_GetRandomNoise( + void *buf, + PRSize size +) +{ + return( _PR_MD_GET_RANDOM_NOISE( buf, size )); +} /* end PR_GetRandomNoise() */ +/* end prrng.c */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/prsystem.c nspr-4.10.7/nspr/pr/src/misc/prsystem.c --- nspr-4.9.5/nspr/pr/src/misc/prsystem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prsystem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,348 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include "prsystem.h" +#include "prprf.h" +#include "prlong.h" + +#if defined(BEOS) +#include +#endif + +#if defined(OS2) +#define INCL_DOS +#define INCL_DOSMISC +#include +/* define the required constant if it is not already defined in the headers */ +#ifndef QSV_NUMPROCESSORS +#define QSV_NUMPROCESSORS 26 +#endif +#endif + +/* BSD-derived systems use sysctl() to get the number of processors */ +#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \ + || defined(OPENBSD) || defined(DARWIN) +#define _PR_HAVE_SYSCTL +#include +#include +#endif + +#if defined(DARWIN) +#include +#include +#include +#endif + +#if defined(HPUX) +#include +#include +#endif + +#if defined(XP_UNIX) +#include +#include +#endif + +#if defined(LINUX) +#include +#include +#define MAX_LINE 512 +#endif + +#if defined(AIX) +#include +#include +#endif + +PR_IMPLEMENT(char) PR_GetDirectorySeparator(void) +{ + return PR_DIRECTORY_SEPARATOR; +} /* PR_GetDirectorySeparator */ + +/* +** OBSOLETE -- the function name is misspelled. +*/ +PR_IMPLEMENT(char) PR_GetDirectorySepartor(void) +{ +#if defined(DEBUG) + static PRBool warn = PR_TRUE; + if (warn) { + warn = _PR_Obsolete("PR_GetDirectorySepartor()", + "PR_GetDirectorySeparator()"); + } +#endif + return PR_GetDirectorySeparator(); +} /* PR_GetDirectorySepartor */ + +PR_IMPLEMENT(char) PR_GetPathSeparator(void) +{ + return PR_PATH_SEPARATOR; +} /* PR_GetPathSeparator */ + +PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen) +{ + PRUintn len = 0; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + switch(cmd) + { + case PR_SI_HOSTNAME: + case PR_SI_HOSTNAME_UNTRUNCATED: + if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen)) + return PR_FAILURE; + + if (cmd == PR_SI_HOSTNAME_UNTRUNCATED) + break; + /* + * On some platforms a system does not have a hostname and + * its IP address is returned instead. The following code + * should be skipped on those platforms. + */ +#ifndef _PR_GET_HOST_ADDR_AS_NAME + /* Return the unqualified hostname */ + while (buf[len] && (len < buflen)) { + if (buf[len] == '.') { + buf[len] = '\0'; + break; + } + len += 1; + } +#endif + break; + + case PR_SI_SYSNAME: + /* Return the operating system name */ +#if defined(XP_UNIX) || defined(WIN32) + if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) + return PR_FAILURE; +#else + (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME); +#endif + break; + + case PR_SI_RELEASE: + /* Return the version of the operating system */ +#if defined(XP_UNIX) || defined(WIN32) + if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) + return PR_FAILURE; +#endif +#if defined(XP_OS2) + { + ULONG os2ver[2] = {0}; + DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION, + &os2ver, sizeof(os2ver)); + /* Formatting for normal usage (2.11, 3.0, 4.0, 4.5); officially, + Warp 4 is version 2.40.00, WSeB 2.45.00 */ + if (os2ver[0] < 30) + (void)PR_snprintf(buf, buflen, "%s%lu", + "2.", os2ver[0]); + else if (os2ver[0] < 45) + (void)PR_snprintf(buf, buflen, "%lu%s%lu", + os2ver[0]/10, ".", os2ver[1]); + else + (void)PR_snprintf(buf, buflen, "%.1f", + os2ver[0]/10.0); + } +#endif /* OS2 */ + break; + + case PR_SI_ARCHITECTURE: + /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/ + (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +/* +** PR_GetNumberOfProcessors() +** +** Implementation notes: +** Every platform does it a bit different. +** numCpus is the returned value. +** for each platform's "if defined" section +** declare your local variable +** do your thing, assign to numCpus +** order of the if defined()s may be important, +** especially for unix variants. Do platform +** specific implementations before XP_UNIX. +** +*/ +PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void ) +{ + PRInt32 numCpus; +#if defined(WIN32) + SYSTEM_INFO info; + + GetSystemInfo( &info ); + numCpus = info.dwNumberOfProcessors; +#elif defined(BEOS) + system_info sysInfo; + + get_system_info(&sysInfo); + numCpus = sysInfo.cpu_count; +#elif defined(OS2) + DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus)); +#elif defined(_PR_HAVE_SYSCTL) + int mib[2]; + int rc; + size_t len = sizeof(numCpus); + + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + rc = sysctl( mib, 2, &numCpus, &len, NULL, 0 ); + if ( -1 == rc ) { + numCpus = -1; /* set to -1 for return value on error */ + _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() ); + } +#elif defined(HPUX) + numCpus = mpctl( MPC_GETNUMSPUS, 0, 0 ); + if ( numCpus < 1 ) { + numCpus = -1; /* set to -1 for return value on error */ + _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() ); + } +#elif defined(IRIX) + numCpus = sysconf( _SC_NPROC_ONLN ); +#elif defined(RISCOS) || defined(SYMBIAN) + numCpus = 1; +#elif defined(LINUX) + /* for the benefit of devices with advanced power-saving, that + actually hotplug their cpus in heavy load, try to figure out + the real number of CPUs */ + char buf[MAX_LINE]; + FILE *fin; + const char *cpu_present = "/sys/devices/system/cpu/present"; + size_t strsize; + numCpus = 0; + fin = fopen(cpu_present, "r"); + if (fin != NULL) { + if (fgets(buf, MAX_LINE, fin) != NULL) { + /* check that the format is what we expect */ + if (buf[0] == '0') { + strsize = strlen(buf); + if (strsize == 1) { + /* single core */ + numCpus = 1; + } else if (strsize >= 3 && strsize <= 5) { + /* should be of the form 0-999 */ + /* parse the part after the 0-, note count is 0-based */ + if (buf[1] == '-' && isdigit(buf[2])) { + numCpus = 1 + atoi(buf + 2); + } + } + } + } + fclose(fin); + } + /* if that fails, fall back to more standard methods */ + if (!numCpus) { + numCpus = sysconf( _SC_NPROCESSORS_CONF ); + } +#elif defined(XP_UNIX) + numCpus = sysconf( _SC_NPROCESSORS_CONF ); +#else +#error "An implementation is required" +#endif + return(numCpus); +} /* end PR_GetNumberOfProcessors() */ + +/* +** PR_GetPhysicalMemorySize() +** +** Implementation notes: +** Every platform does it a bit different. +** bytes is the returned value. +** for each platform's "if defined" section +** declare your local variable +** do your thing, assign to bytes. +** +*/ +PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void) +{ + PRUint64 bytes = 0; + +#if defined(LINUX) || defined(SOLARIS) + + long pageSize = sysconf(_SC_PAGESIZE); + long pageCount = sysconf(_SC_PHYS_PAGES); + if (pageSize >= 0 && pageCount >= 0) + bytes = (PRUint64) pageSize * pageCount; + +#elif defined(NETBSD) || defined(OPENBSD) + + int mib[2]; + int rc; + uint64_t memSize; + size_t len = sizeof(memSize); + + mib[0] = CTL_HW; + mib[1] = HW_PHYSMEM64; + rc = sysctl(mib, 2, &memSize, &len, NULL, 0); + if (-1 != rc) { + bytes = memSize; + } + +#elif defined(HPUX) + + struct pst_static info; + int result = pstat_getstatic(&info, sizeof(info), 1, 0); + if (result == 1) + bytes = (PRUint64) info.physical_memory * info.page_size; + +#elif defined(DARWIN) + + mach_port_t mach_host = mach_host_self(); + struct host_basic_info hInfo; + mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; + + int result = host_info(mach_host, + HOST_BASIC_INFO, + (host_info_t) &hInfo, + &count); + mach_port_deallocate(mach_task_self(), mach_host); + if (result == KERN_SUCCESS) + bytes = hInfo.max_mem; + +#elif defined(WIN32) + + MEMORYSTATUSEX memStat; + memStat.dwLength = sizeof(memStat); + if (GlobalMemoryStatusEx(&memStat)) + bytes = memStat.ullTotalPhys; + +#elif defined(OS2) + + ULONG ulPhysMem; + DosQuerySysInfo(QSV_TOTPHYSMEM, + QSV_TOTPHYSMEM, + &ulPhysMem, + sizeof(ulPhysMem)); + bytes = ulPhysMem; + +#elif defined(AIX) + + if (odm_initialize() == 0) { + int how_many; + struct CuAt *obj = getattr("sys0", "realmem", 0, &how_many); + if (obj != NULL) { + bytes = (PRUint64) atoi(obj->value) * 1024; + free(obj); + } + odm_terminate(); + } + +#else + + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + +#endif + + return bytes; +} /* end PR_GetPhysicalMemorySize() */ diff -Nru nspr-4.9.5/nspr/pr/src/misc/prthinfo.c nspr-4.10.7/nspr/pr/src/misc/prthinfo.c --- nspr-4.9.5/nspr/pr/src/misc/prthinfo.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prthinfo.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,206 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prlog.h" +#include "prthread.h" +#include "private/pprthred.h" +#include "primpl.h" + +PR_IMPLEMENT(PRWord *) +PR_GetGCRegisters(PRThread *t, int isCurrent, int *np) +{ + return _MD_HomeGCRegisters(t, isCurrent, np); +} + +PR_IMPLEMENT(PRStatus) +PR_ThreadScanStackPointers(PRThread* t, + PRScanStackFun scanFun, void* scanClosure) +{ + PRThread* current = PR_GetCurrentThread(); + PRWord *sp, *esp, *p0; + int n; + void **ptd; + PRStatus status; + PRUint32 index; + int stack_end; + + /* + ** Store the thread's registers in the thread structure so the GC + ** can scan them. Then scan them. + */ + p0 = _MD_HomeGCRegisters(t, t == current, &n); + status = scanFun(t, (void**)p0, n, scanClosure); + if (status != PR_SUCCESS) + return status; + + /* Scan the C stack for pointers into the GC heap */ +#if defined(XP_PC) && defined(WIN16) + /* + ** Under WIN16, the stack of the current thread is always mapped into + ** the "task stack" (at SS:xxxx). So, if t is the current thread, scan + ** the "task stack". Otherwise, scan the "cached stack" of the inactive + ** thread... + */ + if (t == current) { + sp = (PRWord*) &stack_end; + esp = (PRWord*) _pr_top_of_task_stack; + + PR_ASSERT(sp <= esp); + } else { + sp = (PRWord*) PR_GetSP(t); + esp = (PRWord*) t->stack->stackTop; + + PR_ASSERT((t->stack->stackSize == 0) || + ((sp > (PRWord*)t->stack->stackBottom) && + (sp <= (PRWord*)t->stack->stackTop))); + } +#else /* ! WIN16 */ +#ifdef HAVE_STACK_GROWING_UP + if (t == current) { + esp = (PRWord*) &stack_end; + } else { + esp = (PRWord*) PR_GetSP(t); + } + sp = (PRWord*) t->stack->stackTop; + if (t->stack->stackSize) { + PR_ASSERT((esp > (PRWord*)t->stack->stackTop) && + (esp < (PRWord*)t->stack->stackBottom)); + } +#else /* ! HAVE_STACK_GROWING_UP */ + if (t == current) { + sp = (PRWord*) &stack_end; + } else { + sp = (PRWord*) PR_GetSP(t); + } + esp = (PRWord*) t->stack->stackTop; + if (t->stack->stackSize) { + PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) && + (sp < (PRWord*)t->stack->stackTop)); + } +#endif /* ! HAVE_STACK_GROWING_UP */ +#endif /* ! WIN16 */ + +#if defined(WIN16) + { + prword_t scan; + prword_t limit; + + scan = (prword_t) sp; + limit = (prword_t) esp; + while (scan < limit) { + prword_t *test; + + test = *((prword_t **)scan); + status = scanFun(t, (void**)&test, 1, scanClosure); + if (status != PR_SUCCESS) + return status; + scan += sizeof(char); + } + } +#else + if (sp < esp) { + status = scanFun(t, (void**)sp, esp - sp, scanClosure); + if (status != PR_SUCCESS) + return status; + } +#endif + + /* + ** Mark all of the per-thread-data items attached to this thread + ** + ** The execution environment better be accounted for otherwise it + ** will be collected + */ + status = scanFun(t, (void**)&t->environment, 1, scanClosure); + if (status != PR_SUCCESS) + return status; + + /* if thread is not allocated on stack, this is redundant. */ + ptd = t->privateData; + for (index = 0; index < t->tpdLength; index++, ptd++) { + status = scanFun(t, (void**)ptd, 1, scanClosure); + if (status != PR_SUCCESS) + return status; + } + + return PR_SUCCESS; +} + +/* transducer for PR_EnumerateThreads */ +typedef struct PRScanStackData { + PRScanStackFun scanFun; + void* scanClosure; +} PRScanStackData; + +static PRStatus PR_CALLBACK +pr_ScanStack(PRThread* t, int i, void* arg) +{ + PRScanStackData* data = (PRScanStackData*)arg; + return PR_ThreadScanStackPointers(t, data->scanFun, data->scanClosure); +} + +PR_IMPLEMENT(PRStatus) +PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure) +{ + PRScanStackData data; + data.scanFun = scanFun; + data.scanClosure = scanClosure; + return PR_EnumerateThreads(pr_ScanStack, &data); +} + +PR_IMPLEMENT(PRUword) +PR_GetStackSpaceLeft(PRThread* t) +{ + PRThread *current = PR_GetCurrentThread(); + PRWord *sp, *esp; + int stack_end; + +#if defined(WIN16) + /* + ** Under WIN16, the stack of the current thread is always mapped into + ** the "task stack" (at SS:xxxx). So, if t is the current thread, scan + ** the "task stack". Otherwise, scan the "cached stack" of the inactive + ** thread... + */ + if (t == current) { + sp = (PRWord*) &stack_end; + esp = (PRWord*) _pr_top_of_task_stack; + + PR_ASSERT(sp <= esp); + } else { + sp = (PRWord*) PR_GetSP(t); + esp = (PRWord*) t->stack->stackTop; + + PR_ASSERT((t->stack->stackSize == 0) || + ((sp > (PRWord*)t->stack->stackBottom) && + (sp <= (PRWord*)t->stack->stackTop))); + } +#else /* ! WIN16 */ +#ifdef HAVE_STACK_GROWING_UP + if (t == current) { + esp = (PRWord*) &stack_end; + } else { + esp = (PRWord*) PR_GetSP(t); + } + sp = (PRWord*) t->stack->stackTop; + if (t->stack->stackSize) { + PR_ASSERT((esp > (PRWord*)t->stack->stackTop) && + (esp < (PRWord*)t->stack->stackBottom)); + } +#else /* ! HAVE_STACK_GROWING_UP */ + if (t == current) { + sp = (PRWord*) &stack_end; + } else { + sp = (PRWord*) PR_GetSP(t); + } + esp = (PRWord*) t->stack->stackTop; + if (t->stack->stackSize) { + PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) && + (sp < (PRWord*)t->stack->stackTop)); + } +#endif /* ! HAVE_STACK_GROWING_UP */ +#endif /* ! WIN16 */ + return (PRUword)t->stack->stackSize - ((PRWord)esp - (PRWord)sp); +} diff -Nru nspr-4.9.5/nspr/pr/src/misc/prtime.c nspr-4.10.7/nspr/pr/src/misc/prtime.c --- nspr-4.9.5/nspr/pr/src/misc/prtime.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prtime.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,2011 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * prtime.c -- + * + * NSPR date and time functions + * + */ + +#include "prinit.h" +#include "prtime.h" +#include "prlock.h" +#include "prprf.h" +#include "prlog.h" + +#include +#include +#include /* for EINVAL */ +#include + +/* + * The COUNT_LEAPS macro counts the number of leap years passed by + * till the start of the given year Y. At the start of the year 4 + * A.D. the number of leap years passed by is 0, while at the start of + * the year 5 A.D. this count is 1. The number of years divisible by + * 100 but not divisible by 400 (the non-leap years) is deducted from + * the count to get the correct number of leap years. + * + * The COUNT_DAYS macro counts the number of days since 01/01/01 till the + * start of the given year Y. The number of days at the start of the year + * 1 is 0 while the number of days at the start of the year 2 is 365 + * (which is ((2)-1) * 365) and so on. The reference point is 01/01/01 + * midnight 00:00:00. + */ + +#define COUNT_LEAPS(Y) ( ((Y)-1)/4 - ((Y)-1)/100 + ((Y)-1)/400 ) +#define COUNT_DAYS(Y) ( ((Y)-1)*365 + COUNT_LEAPS(Y) ) +#define DAYS_BETWEEN_YEARS(A, B) (COUNT_DAYS(B) - COUNT_DAYS(A)) + +/* + * Static variables used by functions in this file + */ + +/* + * The following array contains the day of year for the last day of + * each month, where index 1 is January, and day 0 is January 1. + */ + +static const int lastDayOfMonth[2][13] = { + {-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364}, + {-1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365} +}; + +/* + * The number of days in a month + */ + +static const PRInt8 nDays[2][12] = { + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +}; + +/* + * Declarations for internal functions defined later in this file. + */ + +static void ComputeGMT(PRTime time, PRExplodedTime *gmt); +static int IsLeapYear(PRInt16 year); +static void ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset); + +/* + *------------------------------------------------------------------------ + * + * ComputeGMT -- + * + * Caveats: + * - we ignore leap seconds + * + *------------------------------------------------------------------------ + */ + +static void +ComputeGMT(PRTime time, PRExplodedTime *gmt) +{ + PRInt32 tmp, rem; + PRInt32 numDays; + PRInt64 numDays64, rem64; + int isLeap; + PRInt64 sec; + PRInt64 usec; + PRInt64 usecPerSec; + PRInt64 secPerDay; + + /* + * We first do the usec, sec, min, hour thing so that we do not + * have to do LL arithmetic. + */ + + LL_I2L(usecPerSec, 1000000L); + LL_DIV(sec, time, usecPerSec); + LL_MOD(usec, time, usecPerSec); + LL_L2I(gmt->tm_usec, usec); + /* Correct for weird mod semantics so the remainder is always positive */ + if (gmt->tm_usec < 0) { + PRInt64 one; + + LL_I2L(one, 1L); + LL_SUB(sec, sec, one); + gmt->tm_usec += 1000000L; + } + + LL_I2L(secPerDay, 86400L); + LL_DIV(numDays64, sec, secPerDay); + LL_MOD(rem64, sec, secPerDay); + /* We are sure both of these numbers can fit into PRInt32 */ + LL_L2I(numDays, numDays64); + LL_L2I(rem, rem64); + if (rem < 0) { + numDays--; + rem += 86400L; + } + + /* Compute day of week. Epoch started on a Thursday. */ + + gmt->tm_wday = (numDays + 4) % 7; + if (gmt->tm_wday < 0) { + gmt->tm_wday += 7; + } + + /* Compute the time of day. */ + + gmt->tm_hour = rem / 3600; + rem %= 3600; + gmt->tm_min = rem / 60; + gmt->tm_sec = rem % 60; + + /* + * Compute the year by finding the 400 year period, then working + * down from there. + * + * Since numDays is originally the number of days since January 1, 1970, + * we must change it to be the number of days from January 1, 0001. + */ + + numDays += 719162; /* 719162 = days from year 1 up to 1970 */ + tmp = numDays / 146097; /* 146097 = days in 400 years */ + rem = numDays % 146097; + gmt->tm_year = tmp * 400 + 1; + + /* Compute the 100 year period. */ + + tmp = rem / 36524; /* 36524 = days in 100 years */ + rem %= 36524; + if (tmp == 4) { /* the 400th year is a leap year */ + tmp = 3; + rem = 36524; + } + gmt->tm_year += tmp * 100; + + /* Compute the 4 year period. */ + + tmp = rem / 1461; /* 1461 = days in 4 years */ + rem %= 1461; + gmt->tm_year += tmp * 4; + + /* Compute which year in the 4. */ + + tmp = rem / 365; + rem %= 365; + if (tmp == 4) { /* the 4th year is a leap year */ + tmp = 3; + rem = 365; + } + + gmt->tm_year += tmp; + gmt->tm_yday = rem; + isLeap = IsLeapYear(gmt->tm_year); + + /* Compute the month and day of month. */ + + for (tmp = 1; lastDayOfMonth[isLeap][tmp] < gmt->tm_yday; tmp++) { + } + gmt->tm_month = --tmp; + gmt->tm_mday = gmt->tm_yday - lastDayOfMonth[isLeap][tmp]; + + gmt->tm_params.tp_gmt_offset = 0; + gmt->tm_params.tp_dst_offset = 0; +} + + +/* + *------------------------------------------------------------------------ + * + * PR_ExplodeTime -- + * + * Cf. struct tm *gmtime(const time_t *tp) and + * struct tm *localtime(const time_t *tp) + * + *------------------------------------------------------------------------ + */ + +PR_IMPLEMENT(void) +PR_ExplodeTime( + PRTime usecs, + PRTimeParamFn params, + PRExplodedTime *exploded) +{ + ComputeGMT(usecs, exploded); + exploded->tm_params = params(exploded); + ApplySecOffset(exploded, exploded->tm_params.tp_gmt_offset + + exploded->tm_params.tp_dst_offset); +} + + +/* + *------------------------------------------------------------------------ + * + * PR_ImplodeTime -- + * + * Cf. time_t mktime(struct tm *tp) + * Note that 1 year has < 2^25 seconds. So an PRInt32 is large enough. + * + *------------------------------------------------------------------------ + */ +PR_IMPLEMENT(PRTime) +PR_ImplodeTime(const PRExplodedTime *exploded) +{ + PRExplodedTime copy; + PRTime retVal; + PRInt64 secPerDay, usecPerSec; + PRInt64 temp; + PRInt64 numSecs64; + PRInt32 numDays; + PRInt32 numSecs; + + /* Normalize first. Do this on our copy */ + copy = *exploded; + PR_NormalizeTime(©, PR_GMTParameters); + + numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year); + + numSecs = copy.tm_yday * 86400 + copy.tm_hour * 3600 + + copy.tm_min * 60 + copy.tm_sec; + + LL_I2L(temp, numDays); + LL_I2L(secPerDay, 86400); + LL_MUL(temp, temp, secPerDay); + LL_I2L(numSecs64, numSecs); + LL_ADD(numSecs64, numSecs64, temp); + + /* apply the GMT and DST offsets */ + LL_I2L(temp, copy.tm_params.tp_gmt_offset); + LL_SUB(numSecs64, numSecs64, temp); + LL_I2L(temp, copy.tm_params.tp_dst_offset); + LL_SUB(numSecs64, numSecs64, temp); + + LL_I2L(usecPerSec, 1000000L); + LL_MUL(temp, numSecs64, usecPerSec); + LL_I2L(retVal, copy.tm_usec); + LL_ADD(retVal, retVal, temp); + + return retVal; +} + +/* + *------------------------------------------------------------------------- + * + * IsLeapYear -- + * + * Returns 1 if the year is a leap year, 0 otherwise. + * + *------------------------------------------------------------------------- + */ + +static int IsLeapYear(PRInt16 year) +{ + if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) + return 1; + else + return 0; +} + +/* + * 'secOffset' should be less than 86400 (i.e., a day). + * 'time' should point to a normalized PRExplodedTime. + */ + +static void +ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset) +{ + time->tm_sec += secOffset; + + /* Note that in this implementation we do not count leap seconds */ + if (time->tm_sec < 0 || time->tm_sec >= 60) { + time->tm_min += time->tm_sec / 60; + time->tm_sec %= 60; + if (time->tm_sec < 0) { + time->tm_sec += 60; + time->tm_min--; + } + } + + if (time->tm_min < 0 || time->tm_min >= 60) { + time->tm_hour += time->tm_min / 60; + time->tm_min %= 60; + if (time->tm_min < 0) { + time->tm_min += 60; + time->tm_hour--; + } + } + + if (time->tm_hour < 0) { + /* Decrement mday, yday, and wday */ + time->tm_hour += 24; + time->tm_mday--; + time->tm_yday--; + if (time->tm_mday < 1) { + time->tm_month--; + if (time->tm_month < 0) { + time->tm_month = 11; + time->tm_year--; + if (IsLeapYear(time->tm_year)) + time->tm_yday = 365; + else + time->tm_yday = 364; + } + time->tm_mday = nDays[IsLeapYear(time->tm_year)][time->tm_month]; + } + time->tm_wday--; + if (time->tm_wday < 0) + time->tm_wday = 6; + } else if (time->tm_hour > 23) { + /* Increment mday, yday, and wday */ + time->tm_hour -= 24; + time->tm_mday++; + time->tm_yday++; + if (time->tm_mday > + nDays[IsLeapYear(time->tm_year)][time->tm_month]) { + time->tm_mday = 1; + time->tm_month++; + if (time->tm_month > 11) { + time->tm_month = 0; + time->tm_year++; + time->tm_yday = 0; + } + } + time->tm_wday++; + if (time->tm_wday > 6) + time->tm_wday = 0; + } +} + +PR_IMPLEMENT(void) +PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params) +{ + int daysInMonth; + PRInt32 numDays; + + /* Get back to GMT */ + time->tm_sec -= time->tm_params.tp_gmt_offset + + time->tm_params.tp_dst_offset; + time->tm_params.tp_gmt_offset = 0; + time->tm_params.tp_dst_offset = 0; + + /* Now normalize GMT */ + + if (time->tm_usec < 0 || time->tm_usec >= 1000000) { + time->tm_sec += time->tm_usec / 1000000; + time->tm_usec %= 1000000; + if (time->tm_usec < 0) { + time->tm_usec += 1000000; + time->tm_sec--; + } + } + + /* Note that we do not count leap seconds in this implementation */ + if (time->tm_sec < 0 || time->tm_sec >= 60) { + time->tm_min += time->tm_sec / 60; + time->tm_sec %= 60; + if (time->tm_sec < 0) { + time->tm_sec += 60; + time->tm_min--; + } + } + + if (time->tm_min < 0 || time->tm_min >= 60) { + time->tm_hour += time->tm_min / 60; + time->tm_min %= 60; + if (time->tm_min < 0) { + time->tm_min += 60; + time->tm_hour--; + } + } + + if (time->tm_hour < 0 || time->tm_hour >= 24) { + time->tm_mday += time->tm_hour / 24; + time->tm_hour %= 24; + if (time->tm_hour < 0) { + time->tm_hour += 24; + time->tm_mday--; + } + } + + /* Normalize month and year before mday */ + if (time->tm_month < 0 || time->tm_month >= 12) { + time->tm_year += time->tm_month / 12; + time->tm_month %= 12; + if (time->tm_month < 0) { + time->tm_month += 12; + time->tm_year--; + } + } + + /* Now that month and year are in proper range, normalize mday */ + + if (time->tm_mday < 1) { + /* mday too small */ + do { + /* the previous month */ + time->tm_month--; + if (time->tm_month < 0) { + time->tm_month = 11; + time->tm_year--; + } + time->tm_mday += nDays[IsLeapYear(time->tm_year)][time->tm_month]; + } while (time->tm_mday < 1); + } else { + daysInMonth = nDays[IsLeapYear(time->tm_year)][time->tm_month]; + while (time->tm_mday > daysInMonth) { + /* mday too large */ + time->tm_mday -= daysInMonth; + time->tm_month++; + if (time->tm_month > 11) { + time->tm_month = 0; + time->tm_year++; + } + daysInMonth = nDays[IsLeapYear(time->tm_year)][time->tm_month]; + } + } + + /* Recompute yday and wday */ + time->tm_yday = time->tm_mday + + lastDayOfMonth[IsLeapYear(time->tm_year)][time->tm_month]; + + numDays = DAYS_BETWEEN_YEARS(1970, time->tm_year) + time->tm_yday; + time->tm_wday = (numDays + 4) % 7; + if (time->tm_wday < 0) { + time->tm_wday += 7; + } + + /* Recompute time parameters */ + + time->tm_params = params(time); + + ApplySecOffset(time, time->tm_params.tp_gmt_offset + + time->tm_params.tp_dst_offset); +} + + +/* + *------------------------------------------------------------------------- + * + * PR_LocalTimeParameters -- + * + * returns the time parameters for the local time zone + * + * The following uses localtime() from the standard C library. + * (time.h) This is our fallback implementation. Unix, PC, and BeOS + * use this version. A platform may have its own machine-dependent + * implementation of this function. + * + *------------------------------------------------------------------------- + */ + +#if defined(HAVE_INT_LOCALTIME_R) + +/* + * In this case we could define the macro as + * #define MT_safe_localtime(timer, result) \ + * (localtime_r(timer, result) == 0 ? result : NULL) + * I chose to compare the return value of localtime_r with -1 so + * that I can catch the cases where localtime_r returns a pointer + * to struct tm. The macro definition above would not be able to + * detect such mistakes because it is legal to compare a pointer + * with 0. + */ + +#define MT_safe_localtime(timer, result) \ + (localtime_r(timer, result) == -1 ? NULL: result) + +#elif defined(HAVE_POINTER_LOCALTIME_R) + +#define MT_safe_localtime localtime_r + +#else + +#define HAVE_LOCALTIME_MONITOR 1 /* We use 'monitor' to serialize our calls + * to localtime(). */ +static PRLock *monitor = NULL; + +static struct tm *MT_safe_localtime(const time_t *clock, struct tm *result) +{ + struct tm *tmPtr; + int needLock = PR_Initialized(); /* We need to use a lock to protect + * against NSPR threads only when the + * NSPR thread system is activated. */ + + if (needLock) PR_Lock(monitor); + + /* + * Microsoft (all flavors) localtime() returns a NULL pointer if 'clock' + * represents a time before midnight January 1, 1970. In + * that case, we also return a NULL pointer and the struct tm + * object pointed to by 'result' is not modified. + * + * Watcom C/C++ 11.0 localtime() treats time_t as unsigned long + * hence, does not recognize negative values of clock as pre-1/1/70. + * We have to manually check (WIN16 only) for negative value of + * clock and return NULL. + * + * With negative values of clock, OS/2 returns the struct tm for + * clock plus ULONG_MAX. So we also have to check for the invalid + * structs returned for timezones west of Greenwich when clock == 0. + */ + + tmPtr = localtime(clock); + +#if defined(WIN16) || defined(XP_OS2) + if ( (PRInt32) *clock < 0 || + ( (PRInt32) *clock == 0 && tmPtr->tm_year != 70)) + result = NULL; + else + *result = *tmPtr; +#else + if (tmPtr) { + *result = *tmPtr; + } else { + result = NULL; + } +#endif /* WIN16 */ + + if (needLock) PR_Unlock(monitor); + + return result; +} + +#endif /* definition of MT_safe_localtime() */ + +void _PR_InitTime(void) +{ +#ifdef HAVE_LOCALTIME_MONITOR + monitor = PR_NewLock(); +#endif +#ifdef WINCE + _MD_InitTime(); +#endif +} + +void _PR_CleanupTime(void) +{ +#ifdef HAVE_LOCALTIME_MONITOR + if (monitor) { + PR_DestroyLock(monitor); + monitor = NULL; + } +#endif +#ifdef WINCE + _MD_CleanupTime(); +#endif +} + +#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS) + +PR_IMPLEMENT(PRTimeParameters) +PR_LocalTimeParameters(const PRExplodedTime *gmt) +{ + + PRTimeParameters retVal; + struct tm localTime; + time_t secs; + PRTime secs64; + PRInt64 usecPerSec; + PRInt64 usecPerSec_1; + PRInt64 maxInt32; + PRInt64 minInt32; + PRInt32 dayOffset; + PRInt32 offset2Jan1970; + PRInt32 offsetNew; + int isdst2Jan1970; + + /* + * Calculate the GMT offset. First, figure out what is + * 00:00:00 Jan. 2, 1970 GMT (which is exactly a day, or 86400 + * seconds, since the epoch) in local time. Then we calculate + * the difference between local time and GMT in seconds: + * gmt_offset = local_time - GMT + * + * Caveat: the validity of this calculation depends on two + * assumptions: + * 1. Daylight saving time was not in effect on Jan. 2, 1970. + * 2. The time zone of the geographic location has not changed + * since Jan. 2, 1970. + */ + + secs = 86400L; + (void) MT_safe_localtime(&secs, &localTime); + + /* GMT is 00:00:00, 2nd of Jan. */ + + offset2Jan1970 = (PRInt32)localTime.tm_sec + + 60L * (PRInt32)localTime.tm_min + + 3600L * (PRInt32)localTime.tm_hour + + 86400L * (PRInt32)((PRInt32)localTime.tm_mday - 2L); + + isdst2Jan1970 = localTime.tm_isdst; + + /* + * Now compute DST offset. We calculate the overall offset + * of local time from GMT, similar to above. The overall + * offset has two components: gmt offset and dst offset. + * We subtract gmt offset from the overall offset to get + * the dst offset. + * overall_offset = local_time - GMT + * overall_offset = gmt_offset + dst_offset + * ==> dst_offset = local_time - GMT - gmt_offset + */ + + secs64 = PR_ImplodeTime(gmt); /* This is still in microseconds */ + LL_I2L(usecPerSec, PR_USEC_PER_SEC); + LL_I2L(usecPerSec_1, PR_USEC_PER_SEC - 1); + /* Convert to seconds, truncating down (3.1 -> 3 and -3.1 -> -4) */ + if (LL_GE_ZERO(secs64)) { + LL_DIV(secs64, secs64, usecPerSec); + } else { + LL_NEG(secs64, secs64); + LL_ADD(secs64, secs64, usecPerSec_1); + LL_DIV(secs64, secs64, usecPerSec); + LL_NEG(secs64, secs64); + } + LL_I2L(maxInt32, PR_INT32_MAX); + LL_I2L(minInt32, PR_INT32_MIN); + if (LL_CMP(secs64, >, maxInt32) || LL_CMP(secs64, <, minInt32)) { + /* secs64 is too large or too small for time_t (32-bit integer) */ + retVal.tp_gmt_offset = offset2Jan1970; + retVal.tp_dst_offset = 0; + return retVal; + } + LL_L2I(secs, secs64); + + /* + * On Windows, localtime() (and our MT_safe_localtime() too) + * returns a NULL pointer for time before midnight January 1, + * 1970 GMT. In that case, we just use the GMT offset for + * Jan 2, 1970 and assume that DST was not in effect. + */ + + if (MT_safe_localtime(&secs, &localTime) == NULL) { + retVal.tp_gmt_offset = offset2Jan1970; + retVal.tp_dst_offset = 0; + return retVal; + } + + /* + * dayOffset is the offset between local time and GMT in + * the day component, which can only be -1, 0, or 1. We + * use the day of the week to compute dayOffset. + */ + + dayOffset = (PRInt32) localTime.tm_wday - gmt->tm_wday; + + /* + * Need to adjust for wrapping around of day of the week from + * 6 back to 0. + */ + + if (dayOffset == -6) { + /* Local time is Sunday (0) and GMT is Saturday (6) */ + dayOffset = 1; + } else if (dayOffset == 6) { + /* Local time is Saturday (6) and GMT is Sunday (0) */ + dayOffset = -1; + } + + offsetNew = (PRInt32)localTime.tm_sec - gmt->tm_sec + + 60L * ((PRInt32)localTime.tm_min - gmt->tm_min) + + 3600L * ((PRInt32)localTime.tm_hour - gmt->tm_hour) + + 86400L * (PRInt32)dayOffset; + + if (localTime.tm_isdst <= 0) { + /* DST is not in effect */ + retVal.tp_gmt_offset = offsetNew; + retVal.tp_dst_offset = 0; + } else { + /* DST is in effect */ + if (isdst2Jan1970 <=0) { + /* + * DST was not in effect back in 2 Jan. 1970. + * Use the offset back then as the GMT offset, + * assuming the time zone has not changed since then. + */ + retVal.tp_gmt_offset = offset2Jan1970; + retVal.tp_dst_offset = offsetNew - offset2Jan1970; + } else { + /* + * DST was also in effect back in 2 Jan. 1970. + * Then our clever trick (or rather, ugly hack) fails. + * We will just assume DST offset is an hour. + */ + retVal.tp_gmt_offset = offsetNew - 3600; + retVal.tp_dst_offset = 3600; + } + } + + return retVal; +} + +#endif /* defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS) */ + +/* + *------------------------------------------------------------------------ + * + * PR_USPacificTimeParameters -- + * + * The time parameters function for the US Pacific Time Zone. + * + *------------------------------------------------------------------------ + */ + +/* + * Returns the mday of the first sunday of the month, where + * mday and wday are for a given day in the month. + * mdays start with 1 (e.g. 1..31). + * wdays start with 0 and are in the range 0..6. 0 = Sunday. + */ +#define firstSunday(mday, wday) (((mday - wday + 7 - 1) % 7) + 1) + +/* + * Returns the mday for the N'th Sunday of the month, where + * mday and wday are for a given day in the month. + * mdays start with 1 (e.g. 1..31). + * wdays start with 0 and are in the range 0..6. 0 = Sunday. + * N has the following values: 0 = first, 1 = second (etc), -1 = last. + * ndays is the number of days in that month, the same value as the + * mday of the last day of the month. + */ +static PRInt32 +NthSunday(PRInt32 mday, PRInt32 wday, PRInt32 N, PRInt32 ndays) +{ + PRInt32 firstSun = firstSunday(mday, wday); + + if (N < 0) + N = (ndays - firstSun) / 7; + return firstSun + (7 * N); +} + +typedef struct DSTParams { + PRInt8 dst_start_month; /* 0 = January */ + PRInt8 dst_start_Nth_Sunday; /* N as defined above */ + PRInt8 dst_start_month_ndays; /* ndays as defined above */ + PRInt8 dst_end_month; /* 0 = January */ + PRInt8 dst_end_Nth_Sunday; /* N as defined above */ + PRInt8 dst_end_month_ndays; /* ndays as defined above */ +} DSTParams; + +static const DSTParams dstParams[2] = { + /* year < 2007: First April Sunday - Last October Sunday */ + { 3, 0, 30, 9, -1, 31 }, + /* year >= 2007: Second March Sunday - First November Sunday */ + { 2, 1, 31, 10, 0, 30 } +}; + +PR_IMPLEMENT(PRTimeParameters) +PR_USPacificTimeParameters(const PRExplodedTime *gmt) +{ + const DSTParams *dst; + PRTimeParameters retVal; + PRExplodedTime st; + + /* + * Based on geographic location and GMT, figure out offset of + * standard time from GMT. In this example implementation, we + * assume the local time zone is US Pacific Time. + */ + + retVal.tp_gmt_offset = -8L * 3600L; + + /* + * Make a copy of GMT. Note that the tm_params field of this copy + * is ignored. + */ + + st.tm_usec = gmt->tm_usec; + st.tm_sec = gmt->tm_sec; + st.tm_min = gmt->tm_min; + st.tm_hour = gmt->tm_hour; + st.tm_mday = gmt->tm_mday; + st.tm_month = gmt->tm_month; + st.tm_year = gmt->tm_year; + st.tm_wday = gmt->tm_wday; + st.tm_yday = gmt->tm_yday; + + /* Apply the offset to GMT to obtain the local standard time */ + ApplySecOffset(&st, retVal.tp_gmt_offset); + + if (st.tm_year < 2007) { /* first April Sunday - Last October Sunday */ + dst = &dstParams[0]; + } else { /* Second March Sunday - First November Sunday */ + dst = &dstParams[1]; + } + + /* + * Apply the rules on standard time or GMT to obtain daylight saving + * time offset. In this implementation, we use the US DST rule. + */ + if (st.tm_month < dst->dst_start_month) { + retVal.tp_dst_offset = 0L; + } else if (st.tm_month == dst->dst_start_month) { + int NthSun = NthSunday(st.tm_mday, st.tm_wday, + dst->dst_start_Nth_Sunday, + dst->dst_start_month_ndays); + if (st.tm_mday < NthSun) { /* Before starting Sunday */ + retVal.tp_dst_offset = 0L; + } else if (st.tm_mday == NthSun) { /* Starting Sunday */ + /* 01:59:59 PST -> 03:00:00 PDT */ + if (st.tm_hour < 2) { + retVal.tp_dst_offset = 0L; + } else { + retVal.tp_dst_offset = 3600L; + } + } else { /* After starting Sunday */ + retVal.tp_dst_offset = 3600L; + } + } else if (st.tm_month < dst->dst_end_month) { + retVal.tp_dst_offset = 3600L; + } else if (st.tm_month == dst->dst_end_month) { + int NthSun = NthSunday(st.tm_mday, st.tm_wday, + dst->dst_end_Nth_Sunday, + dst->dst_end_month_ndays); + if (st.tm_mday < NthSun) { /* Before ending Sunday */ + retVal.tp_dst_offset = 3600L; + } else if (st.tm_mday == NthSun) { /* Ending Sunday */ + /* 01:59:59 PDT -> 01:00:00 PST */ + if (st.tm_hour < 1) { + retVal.tp_dst_offset = 3600L; + } else { + retVal.tp_dst_offset = 0L; + } + } else { /* After ending Sunday */ + retVal.tp_dst_offset = 0L; + } + } else { + retVal.tp_dst_offset = 0L; + } + return retVal; +} + +/* + *------------------------------------------------------------------------ + * + * PR_GMTParameters -- + * + * Returns the PRTimeParameters for Greenwich Mean Time. + * Trivially, both the tp_gmt_offset and tp_dst_offset fields are 0. + * + *------------------------------------------------------------------------ + */ + +PR_IMPLEMENT(PRTimeParameters) +PR_GMTParameters(const PRExplodedTime *gmt) +{ + PRTimeParameters retVal = { 0, 0 }; + return retVal; +} + +/* + * The following code implements PR_ParseTimeString(). It is based on + * ns/lib/xp/xp_time.c, revision 1.25, by Jamie Zawinski . + */ + +/* + * We only recognize the abbreviations of a small subset of time zones + * in North America, Europe, and Japan. + * + * PST/PDT: Pacific Standard/Daylight Time + * MST/MDT: Mountain Standard/Daylight Time + * CST/CDT: Central Standard/Daylight Time + * EST/EDT: Eastern Standard/Daylight Time + * AST: Atlantic Standard Time + * NST: Newfoundland Standard Time + * GMT: Greenwich Mean Time + * BST: British Summer Time + * MET: Middle Europe Time + * EET: Eastern Europe Time + * JST: Japan Standard Time + */ + +typedef enum +{ + TT_UNKNOWN, + + TT_SUN, TT_MON, TT_TUE, TT_WED, TT_THU, TT_FRI, TT_SAT, + + TT_JAN, TT_FEB, TT_MAR, TT_APR, TT_MAY, TT_JUN, + TT_JUL, TT_AUG, TT_SEP, TT_OCT, TT_NOV, TT_DEC, + + TT_PST, TT_PDT, TT_MST, TT_MDT, TT_CST, TT_CDT, TT_EST, TT_EDT, + TT_AST, TT_NST, TT_GMT, TT_BST, TT_MET, TT_EET, TT_JST +} TIME_TOKEN; + +/* + * This parses a time/date string into a PRTime + * (microseconds after "1-Jan-1970 00:00:00 GMT"). + * It returns PR_SUCCESS on success, and PR_FAILURE + * if the time/date string can't be parsed. + * + * Many formats are handled, including: + * + * 14 Apr 89 03:20:12 + * 14 Apr 89 03:20 GMT + * Fri, 17 Mar 89 4:01:33 + * Fri, 17 Mar 89 4:01 GMT + * Mon Jan 16 16:12 PDT 1989 + * Mon Jan 16 16:12 +0130 1989 + * 6 May 1992 16:41-JST (Wednesday) + * 22-AUG-1993 10:59:12.82 + * 22-AUG-1993 10:59pm + * 22-AUG-1993 12:59am + * 22-AUG-1993 12:59 PM + * Friday, August 04, 1995 3:54 PM + * 06/21/95 04:24:34 PM + * 20/06/95 21:07 + * 95-06-08 19:32:48 EDT + * + * If the input string doesn't contain a description of the timezone, + * we consult the `default_to_gmt' to decide whether the string should + * be interpreted relative to the local time zone (PR_FALSE) or GMT (PR_TRUE). + * The correct value for this argument depends on what standard specified + * the time string which you are parsing. + */ + +PR_IMPLEMENT(PRStatus) +PR_ParseTimeStringToExplodedTime( + const char *string, + PRBool default_to_gmt, + PRExplodedTime *result) +{ + TIME_TOKEN dotw = TT_UNKNOWN; + TIME_TOKEN month = TT_UNKNOWN; + TIME_TOKEN zone = TT_UNKNOWN; + int zone_offset = -1; + int dst_offset = 0; + int date = -1; + PRInt32 year = -1; + int hour = -1; + int min = -1; + int sec = -1; + + const char *rest = string; + + int iterations = 0; + + PR_ASSERT(string && result); + if (!string || !result) return PR_FAILURE; + + while (*rest) + { + + if (iterations++ > 1000) + { + return PR_FAILURE; + } + + switch (*rest) + { + case 'a': case 'A': + if (month == TT_UNKNOWN && + (rest[1] == 'p' || rest[1] == 'P') && + (rest[2] == 'r' || rest[2] == 'R')) + month = TT_APR; + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_AST; + else if (month == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'g' || rest[2] == 'G')) + month = TT_AUG; + break; + case 'b': case 'B': + if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_BST; + break; + case 'c': case 'C': + if (zone == TT_UNKNOWN && + (rest[1] == 'd' || rest[1] == 'D') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_CDT; + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_CST; + break; + case 'd': case 'D': + if (month == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 'c' || rest[2] == 'C')) + month = TT_DEC; + break; + case 'e': case 'E': + if (zone == TT_UNKNOWN && + (rest[1] == 'd' || rest[1] == 'D') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_EDT; + else if (zone == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_EET; + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_EST; + break; + case 'f': case 'F': + if (month == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 'b' || rest[2] == 'B')) + month = TT_FEB; + else if (dotw == TT_UNKNOWN && + (rest[1] == 'r' || rest[1] == 'R') && + (rest[2] == 'i' || rest[2] == 'I')) + dotw = TT_FRI; + break; + case 'g': case 'G': + if (zone == TT_UNKNOWN && + (rest[1] == 'm' || rest[1] == 'M') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_GMT; + break; + case 'j': case 'J': + if (month == TT_UNKNOWN && + (rest[1] == 'a' || rest[1] == 'A') && + (rest[2] == 'n' || rest[2] == 'N')) + month = TT_JAN; + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_JST; + else if (month == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'l' || rest[2] == 'L')) + month = TT_JUL; + else if (month == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'n' || rest[2] == 'N')) + month = TT_JUN; + break; + case 'm': case 'M': + if (month == TT_UNKNOWN && + (rest[1] == 'a' || rest[1] == 'A') && + (rest[2] == 'r' || rest[2] == 'R')) + month = TT_MAR; + else if (month == TT_UNKNOWN && + (rest[1] == 'a' || rest[1] == 'A') && + (rest[2] == 'y' || rest[2] == 'Y')) + month = TT_MAY; + else if (zone == TT_UNKNOWN && + (rest[1] == 'd' || rest[1] == 'D') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_MDT; + else if (zone == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_MET; + else if (dotw == TT_UNKNOWN && + (rest[1] == 'o' || rest[1] == 'O') && + (rest[2] == 'n' || rest[2] == 'N')) + dotw = TT_MON; + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_MST; + break; + case 'n': case 'N': + if (month == TT_UNKNOWN && + (rest[1] == 'o' || rest[1] == 'O') && + (rest[2] == 'v' || rest[2] == 'V')) + month = TT_NOV; + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_NST; + break; + case 'o': case 'O': + if (month == TT_UNKNOWN && + (rest[1] == 'c' || rest[1] == 'C') && + (rest[2] == 't' || rest[2] == 'T')) + month = TT_OCT; + break; + case 'p': case 'P': + if (zone == TT_UNKNOWN && + (rest[1] == 'd' || rest[1] == 'D') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_PDT; + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) + zone = TT_PST; + break; + case 's': case 'S': + if (dotw == TT_UNKNOWN && + (rest[1] == 'a' || rest[1] == 'A') && + (rest[2] == 't' || rest[2] == 'T')) + dotw = TT_SAT; + else if (month == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 'p' || rest[2] == 'P')) + month = TT_SEP; + else if (dotw == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'n' || rest[2] == 'N')) + dotw = TT_SUN; + break; + case 't': case 'T': + if (dotw == TT_UNKNOWN && + (rest[1] == 'h' || rest[1] == 'H') && + (rest[2] == 'u' || rest[2] == 'U')) + dotw = TT_THU; + else if (dotw == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'e' || rest[2] == 'E')) + dotw = TT_TUE; + break; + case 'u': case 'U': + if (zone == TT_UNKNOWN && + (rest[1] == 't' || rest[1] == 'T') && + !(rest[2] >= 'A' && rest[2] <= 'Z') && + !(rest[2] >= 'a' && rest[2] <= 'z')) + /* UT is the same as GMT but UTx is not. */ + zone = TT_GMT; + break; + case 'w': case 'W': + if (dotw == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 'd' || rest[2] == 'D')) + dotw = TT_WED; + break; + + case '+': case '-': + { + const char *end; + int sign; + if (zone_offset != -1) + { + /* already got one... */ + rest++; + break; + } + if (zone != TT_UNKNOWN && zone != TT_GMT) + { + /* GMT+0300 is legal, but PST+0300 is not. */ + rest++; + break; + } + + sign = ((*rest == '+') ? 1 : -1); + rest++; /* move over sign */ + end = rest; + while (*end >= '0' && *end <= '9') + end++; + if (rest == end) /* no digits here */ + break; + + if ((end - rest) == 4) + /* offset in HHMM */ + zone_offset = (((((rest[0]-'0')*10) + (rest[1]-'0')) * 60) + + (((rest[2]-'0')*10) + (rest[3]-'0'))); + else if ((end - rest) == 2) + /* offset in hours */ + zone_offset = (((rest[0]-'0')*10) + (rest[1]-'0')) * 60; + else if ((end - rest) == 1) + /* offset in hours */ + zone_offset = (rest[0]-'0') * 60; + else + /* 3 or >4 */ + break; + + zone_offset *= sign; + zone = TT_GMT; + break; + } + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + int tmp_hour = -1; + int tmp_min = -1; + int tmp_sec = -1; + const char *end = rest + 1; + while (*end >= '0' && *end <= '9') + end++; + + /* end is now the first character after a range of digits. */ + + if (*end == ':') + { + if (hour >= 0 && min >= 0) /* already got it */ + break; + + /* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */ + if ((end - rest) > 2) + /* it is [0-9][0-9][0-9]+: */ + break; + else if ((end - rest) == 2) + tmp_hour = ((rest[0]-'0')*10 + + (rest[1]-'0')); + else + tmp_hour = (rest[0]-'0'); + + /* move over the colon, and parse minutes */ + + rest = ++end; + while (*end >= '0' && *end <= '9') + end++; + + if (end == rest) + /* no digits after first colon? */ + break; + else if ((end - rest) > 2) + /* it is [0-9][0-9][0-9]+: */ + break; + else if ((end - rest) == 2) + tmp_min = ((rest[0]-'0')*10 + + (rest[1]-'0')); + else + tmp_min = (rest[0]-'0'); + + /* now go for seconds */ + rest = end; + if (*rest == ':') + rest++; + end = rest; + while (*end >= '0' && *end <= '9') + end++; + + if (end == rest) + /* no digits after second colon - that's ok. */ + ; + else if ((end - rest) > 2) + /* it is [0-9][0-9][0-9]+: */ + break; + else if ((end - rest) == 2) + tmp_sec = ((rest[0]-'0')*10 + + (rest[1]-'0')); + else + tmp_sec = (rest[0]-'0'); + + /* If we made it here, we've parsed hour and min, + and possibly sec, so it worked as a unit. */ + + /* skip over whitespace and see if there's an AM or PM + directly following the time. + */ + if (tmp_hour <= 12) + { + const char *s = end; + while (*s && (*s == ' ' || *s == '\t')) + s++; + if ((s[0] == 'p' || s[0] == 'P') && + (s[1] == 'm' || s[1] == 'M')) + /* 10:05pm == 22:05, and 12:05pm == 12:05 */ + tmp_hour = (tmp_hour == 12 ? 12 : tmp_hour + 12); + else if (tmp_hour == 12 && + (s[0] == 'a' || s[0] == 'A') && + (s[1] == 'm' || s[1] == 'M')) + /* 12:05am == 00:05 */ + tmp_hour = 0; + } + + hour = tmp_hour; + min = tmp_min; + sec = tmp_sec; + rest = end; + break; + } + else if ((*end == '/' || *end == '-') && + end[1] >= '0' && end[1] <= '9') + { + /* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95 + or even 95-06-05... + #### But it doesn't handle 1995-06-22. + */ + int n1, n2, n3; + const char *s; + + if (month != TT_UNKNOWN) + /* if we saw a month name, this can't be. */ + break; + + s = rest; + + n1 = (*s++ - '0'); /* first 1 or 2 digits */ + if (*s >= '0' && *s <= '9') + n1 = n1*10 + (*s++ - '0'); + + if (*s != '/' && *s != '-') /* slash */ + break; + s++; + + if (*s < '0' || *s > '9') /* second 1 or 2 digits */ + break; + n2 = (*s++ - '0'); + if (*s >= '0' && *s <= '9') + n2 = n2*10 + (*s++ - '0'); + + if (*s != '/' && *s != '-') /* slash */ + break; + s++; + + if (*s < '0' || *s > '9') /* third 1, 2, 4, or 5 digits */ + break; + n3 = (*s++ - '0'); + if (*s >= '0' && *s <= '9') + n3 = n3*10 + (*s++ - '0'); + + if (*s >= '0' && *s <= '9') /* optional digits 3, 4, and 5 */ + { + n3 = n3*10 + (*s++ - '0'); + if (*s < '0' || *s > '9') + break; + n3 = n3*10 + (*s++ - '0'); + if (*s >= '0' && *s <= '9') + n3 = n3*10 + (*s++ - '0'); + } + + if ((*s >= '0' && *s <= '9') || /* followed by non-alphanum */ + (*s >= 'A' && *s <= 'Z') || + (*s >= 'a' && *s <= 'z')) + break; + + /* Ok, we parsed three 1-2 digit numbers, with / or - + between them. Now decide what the hell they are + (DD/MM/YY or MM/DD/YY or YY/MM/DD.) + */ + + if (n1 > 31 || n1 == 0) /* must be YY/MM/DD */ + { + if (n2 > 12) break; + if (n3 > 31) break; + year = n1; + if (year < 70) + year += 2000; + else if (year < 100) + year += 1900; + month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1); + date = n3; + rest = s; + break; + } + + if (n1 > 12 && n2 > 12) /* illegal */ + { + rest = s; + break; + } + + if (n3 < 70) + n3 += 2000; + else if (n3 < 100) + n3 += 1900; + + if (n1 > 12) /* must be DD/MM/YY */ + { + date = n1; + month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1); + year = n3; + } + else /* assume MM/DD/YY */ + { + /* #### In the ambiguous case, should we consult the + locale to find out the local default? */ + month = (TIME_TOKEN)(n1 + ((int)TT_JAN) - 1); + date = n2; + year = n3; + } + rest = s; + } + else if ((*end >= 'A' && *end <= 'Z') || + (*end >= 'a' && *end <= 'z')) + /* Digits followed by non-punctuation - what's that? */ + ; + else if ((end - rest) == 5) /* five digits is a year */ + year = (year < 0 + ? ((rest[0]-'0')*10000L + + (rest[1]-'0')*1000L + + (rest[2]-'0')*100L + + (rest[3]-'0')*10L + + (rest[4]-'0')) + : year); + else if ((end - rest) == 4) /* four digits is a year */ + year = (year < 0 + ? ((rest[0]-'0')*1000L + + (rest[1]-'0')*100L + + (rest[2]-'0')*10L + + (rest[3]-'0')) + : year); + else if ((end - rest) == 2) /* two digits - date or year */ + { + int n = ((rest[0]-'0')*10 + + (rest[1]-'0')); + /* If we don't have a date (day of the month) and we see a number + less than 32, then assume that is the date. + + Otherwise, if we have a date and not a year, assume this is the + year. If it is less than 70, then assume it refers to the 21st + century. If it is two digits (>= 70), assume it refers to this + century. Otherwise, assume it refers to an unambiguous year. + + The world will surely end soon. + */ + if (date < 0 && n < 32) + date = n; + else if (year < 0) + { + if (n < 70) + year = 2000 + n; + else if (n < 100) + year = 1900 + n; + else + year = n; + } + /* else what the hell is this. */ + } + else if ((end - rest) == 1) /* one digit - date */ + date = (date < 0 ? (rest[0]-'0') : date); + /* else, three or more than five digits - what's that? */ + + break; + } + } + + /* Skip to the end of this token, whether we parsed it or not. + Tokens are delimited by whitespace, or ,;-/ + But explicitly not :+-. + */ + while (*rest && + *rest != ' ' && *rest != '\t' && + *rest != ',' && *rest != ';' && + *rest != '-' && *rest != '+' && + *rest != '/' && + *rest != '(' && *rest != ')' && *rest != '[' && *rest != ']') + rest++; + /* skip over uninteresting chars. */ + SKIP_MORE: + while (*rest && + (*rest == ' ' || *rest == '\t' || + *rest == ',' || *rest == ';' || *rest == '/' || + *rest == '(' || *rest == ')' || *rest == '[' || *rest == ']')) + rest++; + + /* "-" is ignored at the beginning of a token if we have not yet + parsed a year (e.g., the second "-" in "30-AUG-1966"), or if + the character after the dash is not a digit. */ + if (*rest == '-' && ((rest > string && + isalpha((unsigned char)rest[-1]) && year < 0) || + rest[1] < '0' || rest[1] > '9')) + { + rest++; + goto SKIP_MORE; + } + + } + + if (zone != TT_UNKNOWN && zone_offset == -1) + { + switch (zone) + { + case TT_PST: zone_offset = -8 * 60; break; + case TT_PDT: zone_offset = -8 * 60; dst_offset = 1 * 60; break; + case TT_MST: zone_offset = -7 * 60; break; + case TT_MDT: zone_offset = -7 * 60; dst_offset = 1 * 60; break; + case TT_CST: zone_offset = -6 * 60; break; + case TT_CDT: zone_offset = -6 * 60; dst_offset = 1 * 60; break; + case TT_EST: zone_offset = -5 * 60; break; + case TT_EDT: zone_offset = -5 * 60; dst_offset = 1 * 60; break; + case TT_AST: zone_offset = -4 * 60; break; + case TT_NST: zone_offset = -3 * 60 - 30; break; + case TT_GMT: zone_offset = 0 * 60; break; + case TT_BST: zone_offset = 0 * 60; dst_offset = 1 * 60; break; + case TT_MET: zone_offset = 1 * 60; break; + case TT_EET: zone_offset = 2 * 60; break; + case TT_JST: zone_offset = 9 * 60; break; + default: + PR_ASSERT (0); + break; + } + } + + /* If we didn't find a year, month, or day-of-the-month, we can't + possibly parse this, and in fact, mktime() will do something random + (I'm seeing it return "Tue Feb 5 06:28:16 2036", which is no doubt + a numerologically significant date... */ + if (month == TT_UNKNOWN || date == -1 || year == -1 || year > PR_INT16_MAX) + return PR_FAILURE; + + memset(result, 0, sizeof(*result)); + if (sec != -1) + result->tm_sec = sec; + if (min != -1) + result->tm_min = min; + if (hour != -1) + result->tm_hour = hour; + if (date != -1) + result->tm_mday = date; + if (month != TT_UNKNOWN) + result->tm_month = (((int)month) - ((int)TT_JAN)); + if (year != -1) + result->tm_year = year; + if (dotw != TT_UNKNOWN) + result->tm_wday = (((int)dotw) - ((int)TT_SUN)); + /* + * Mainly to compute wday and yday, but normalized time is also required + * by the check below that works around a Visual C++ 2005 mktime problem. + */ + PR_NormalizeTime(result, PR_GMTParameters); + /* The remaining work is to set the gmt and dst offsets in tm_params. */ + + if (zone == TT_UNKNOWN && default_to_gmt) + { + /* No zone was specified, so pretend the zone was GMT. */ + zone = TT_GMT; + zone_offset = 0; + } + + if (zone_offset == -1) + { + /* no zone was specified, and we're to assume that everything + is local. */ + struct tm localTime; + time_t secs; + + PR_ASSERT(result->tm_month > -1 && + result->tm_mday > 0 && + result->tm_hour > -1 && + result->tm_min > -1 && + result->tm_sec > -1); + + /* + * To obtain time_t from a tm structure representing the local + * time, we call mktime(). However, we need to see if we are + * on 1-Jan-1970 or before. If we are, we can't call mktime() + * because mktime() will crash on win16. In that case, we + * calculate zone_offset based on the zone offset at + * 00:00:00, 2 Jan 1970 GMT, and subtract zone_offset from the + * date we are parsing to transform the date to GMT. We also + * do so if mktime() returns (time_t) -1 (time out of range). + */ + + /* month, day, hours, mins and secs are always non-negative + so we dont need to worry about them. */ + if(result->tm_year >= 1970) + { + PRInt64 usec_per_sec; + + localTime.tm_sec = result->tm_sec; + localTime.tm_min = result->tm_min; + localTime.tm_hour = result->tm_hour; + localTime.tm_mday = result->tm_mday; + localTime.tm_mon = result->tm_month; + localTime.tm_year = result->tm_year - 1900; + /* Set this to -1 to tell mktime "I don't care". If you set + it to 0 or 1, you are making assertions about whether the + date you are handing it is in daylight savings mode or not; + and if you're wrong, it will "fix" it for you. */ + localTime.tm_isdst = -1; + +#if _MSC_VER == 1400 /* 1400 = Visual C++ 2005 (8.0) */ + /* + * mktime will return (time_t) -1 if the input is a date + * after 23:59:59, December 31, 3000, US Pacific Time (not + * UTC as documented): + * http://msdn.microsoft.com/en-us/library/d1y53h2a(VS.80).aspx + * But if the year is 3001, mktime also invokes the invalid + * parameter handler, causing the application to crash. This + * problem has been reported in + * http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=266036. + * We avoid this crash by not calling mktime if the date is + * out of range. To use a simple test that works in any time + * zone, we consider year 3000 out of range as well. (See + * bug 480740.) + */ + if (result->tm_year >= 3000) { + /* Emulate what mktime would have done. */ + errno = EINVAL; + secs = (time_t) -1; + } else { + secs = mktime(&localTime); + } +#else + secs = mktime(&localTime); +#endif + if (secs != (time_t) -1) + { + PRTime usecs64; + LL_I2L(usecs64, secs); + LL_I2L(usec_per_sec, PR_USEC_PER_SEC); + LL_MUL(usecs64, usecs64, usec_per_sec); + PR_ExplodeTime(usecs64, PR_LocalTimeParameters, result); + return PR_SUCCESS; + } + } + + /* So mktime() can't handle this case. We assume the + zone_offset for the date we are parsing is the same as + the zone offset on 00:00:00 2 Jan 1970 GMT. */ + secs = 86400; + (void) MT_safe_localtime(&secs, &localTime); + zone_offset = localTime.tm_min + + 60 * localTime.tm_hour + + 1440 * (localTime.tm_mday - 2); + } + + result->tm_params.tp_gmt_offset = zone_offset * 60; + result->tm_params.tp_dst_offset = dst_offset * 60; + + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) +PR_ParseTimeString( + const char *string, + PRBool default_to_gmt, + PRTime *result) +{ + PRExplodedTime tm; + PRStatus rv; + + rv = PR_ParseTimeStringToExplodedTime(string, + default_to_gmt, + &tm); + if (rv != PR_SUCCESS) + return rv; + + *result = PR_ImplodeTime(&tm); + + return PR_SUCCESS; +} + +/* + ******************************************************************* + ******************************************************************* + ** + ** OLD COMPATIBILITY FUNCTIONS + ** + ******************************************************************* + ******************************************************************* + */ + + +/* + *----------------------------------------------------------------------- + * + * PR_FormatTime -- + * + * Format a time value into a buffer. Same semantics as strftime(). + * + *----------------------------------------------------------------------- + */ + +PR_IMPLEMENT(PRUint32) +PR_FormatTime(char *buf, int buflen, const char *fmt, const PRExplodedTime *tm) +{ + size_t rv; + struct tm a; + struct tm *ap; + + if (tm) { + ap = &a; + a.tm_sec = tm->tm_sec; + a.tm_min = tm->tm_min; + a.tm_hour = tm->tm_hour; + a.tm_mday = tm->tm_mday; + a.tm_mon = tm->tm_month; + a.tm_wday = tm->tm_wday; + a.tm_year = tm->tm_year - 1900; + a.tm_yday = tm->tm_yday; + a.tm_isdst = tm->tm_params.tp_dst_offset ? 1 : 0; + + /* + * On some platforms, for example SunOS 4, struct tm has two + * additional fields: tm_zone and tm_gmtoff. + */ + +#if (__GLIBC__ >= 2) || defined(XP_BEOS) \ + || defined(NETBSD) || defined(OPENBSD) || defined(FREEBSD) \ + || defined(DARWIN) || defined(SYMBIAN) || defined(ANDROID) + a.tm_zone = NULL; + a.tm_gmtoff = tm->tm_params.tp_gmt_offset + + tm->tm_params.tp_dst_offset; +#endif + } else { + ap = NULL; + } + + rv = strftime(buf, buflen, fmt, ap); + if (!rv && buf && buflen > 0) { + /* + * When strftime fails, the contents of buf are indeterminate. + * Some callers don't check the return value from this function, + * so store an empty string in buf in case they try to print it. + */ + buf[0] = '\0'; + } + return rv; +} + + +/* + * The following string arrays and macros are used by PR_FormatTimeUSEnglish(). + */ + +static const char* abbrevDays[] = +{ + "Sun","Mon","Tue","Wed","Thu","Fri","Sat" +}; + +static const char* days[] = +{ + "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" +}; + +static const char* abbrevMonths[] = +{ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +static const char* months[] = +{ + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" +}; + + +/* + * Add a single character to the given buffer, incrementing the buffer pointer + * and decrementing the buffer size. Return 0 on error. + */ +#define ADDCHAR( buf, bufSize, ch ) \ +do \ +{ \ + if( bufSize < 1 ) \ + { \ + *(--buf) = '\0'; \ + return 0; \ + } \ + *buf++ = ch; \ + bufSize--; \ +} \ +while(0) + + +/* + * Add a string to the given buffer, incrementing the buffer pointer + * and decrementing the buffer size appropriately. Return 0 on error. + */ +#define ADDSTR( buf, bufSize, str ) \ +do \ +{ \ + PRUint32 strSize = strlen( str ); \ + if( strSize > bufSize ) \ + { \ + if( bufSize==0 ) \ + *(--buf) = '\0'; \ + else \ + *buf = '\0'; \ + return 0; \ + } \ + memcpy(buf, str, strSize); \ + buf += strSize; \ + bufSize -= strSize; \ +} \ +while(0) + +/* Needed by PR_FormatTimeUSEnglish() */ +static unsigned int pr_WeekOfYear(const PRExplodedTime* time, + unsigned int firstDayOfWeek); + + +/*********************************************************************************** + * + * Description: + * This is a dumbed down version of strftime that will format the date in US + * English regardless of the setting of the global locale. This functionality is + * needed to write things like MIME headers which must always be in US English. + * + **********************************************************************************/ + +PR_IMPLEMENT(PRUint32) +PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize, + const char* format, const PRExplodedTime* time ) +{ + char* bufPtr = buf; + const char* fmtPtr; + char tmpBuf[ 40 ]; + const int tmpBufSize = sizeof( tmpBuf ); + + + for( fmtPtr=format; *fmtPtr != '\0'; fmtPtr++ ) + { + if( *fmtPtr != '%' ) + { + ADDCHAR( bufPtr, bufSize, *fmtPtr ); + } + else + { + switch( *(++fmtPtr) ) + { + case '%': + /* escaped '%' character */ + ADDCHAR( bufPtr, bufSize, '%' ); + break; + + case 'a': + /* abbreviated weekday name */ + ADDSTR( bufPtr, bufSize, abbrevDays[ time->tm_wday ] ); + break; + + case 'A': + /* full weekday name */ + ADDSTR( bufPtr, bufSize, days[ time->tm_wday ] ); + break; + + case 'b': + /* abbreviated month name */ + ADDSTR( bufPtr, bufSize, abbrevMonths[ time->tm_month ] ); + break; + + case 'B': + /* full month name */ + ADDSTR(bufPtr, bufSize, months[ time->tm_month ] ); + break; + + case 'c': + /* Date and time. */ + PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%a %b %d %H:%M:%S %Y", time ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'd': + /* day of month ( 01 - 31 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_mday ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'H': + /* hour ( 00 - 23 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_hour ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'I': + /* hour ( 01 - 12 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld", + (time->tm_hour%12) ? time->tm_hour%12 : (PRInt32) 12 ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'j': + /* day number of year ( 001 - 366 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.3d",time->tm_yday + 1); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'm': + /* month number ( 01 - 12 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_month+1); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'M': + /* minute ( 00 - 59 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_min ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'p': + /* locale's equivalent of either AM or PM */ + ADDSTR( bufPtr, bufSize, (time->tm_hour<12)?"AM":"PM" ); + break; + + case 'S': + /* seconds ( 00 - 61 ), allows for leap seconds */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_sec ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'U': + /* week number of year ( 00 - 53 ), Sunday is the first day of week 1 */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 0 ) ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'w': + /* weekday number ( 0 - 6 ), Sunday = 0 */ + PR_snprintf(tmpBuf,tmpBufSize,"%d",time->tm_wday ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'W': + /* Week number of year ( 00 - 53 ), Monday is the first day of week 1 */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 1 ) ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'x': + /* Date representation */ + PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%m/%d/%y", time ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'X': + /* Time representation. */ + PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%H:%M:%S", time ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'y': + /* year within century ( 00 - 99 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2d",time->tm_year % 100 ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'Y': + /* year as ccyy ( for example 1986 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.4d",time->tm_year ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'Z': + /* Time zone name or no characters if no time zone exists. + * Since time zone name is supposed to be independant of locale, we + * defer to PR_FormatTime() for this option. + */ + PR_FormatTime( tmpBuf, tmpBufSize, "%Z", time ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + default: + /* Unknown format. Simply copy format into output buffer. */ + ADDCHAR( bufPtr, bufSize, '%' ); + ADDCHAR( bufPtr, bufSize, *fmtPtr ); + break; + + } + } + } + + ADDCHAR( bufPtr, bufSize, '\0' ); + return (PRUint32)(bufPtr - buf - 1); +} + + + +/*********************************************************************************** + * + * Description: + * Returns the week number of the year (0-53) for the given time. firstDayOfWeek + * is the day on which the week is considered to start (0=Sun, 1=Mon, ...). + * Week 1 starts the first time firstDayOfWeek occurs in the year. In other words, + * a partial week at the start of the year is considered week 0. + * + **********************************************************************************/ + +static unsigned int +pr_WeekOfYear(const PRExplodedTime* time, unsigned int firstDayOfWeek) +{ + int dayOfWeek; + int dayOfYear; + + /* Get the day of the year for the given time then adjust it to represent the + * first day of the week containing the given time. + */ + dayOfWeek = time->tm_wday - firstDayOfWeek; + if (dayOfWeek < 0) + dayOfWeek += 7; + + dayOfYear = time->tm_yday - dayOfWeek; + + + if( dayOfYear <= 0 ) + { + /* If dayOfYear is <= 0, it is in the first partial week of the year. */ + return 0; + } + else + { + /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there + * are any days left over ( dayOfYear % 7 ). Because we are only counting to + * the first day of the week containing the given time, rather than to the + * actual day representing the given time, any days in week 0 will be "absorbed" + * as extra days in the given week. + */ + return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 ); + } +} + diff -Nru nspr-4.9.5/nspr/pr/src/misc/prtpool.c nspr-4.10.7/nspr/pr/src/misc/prtpool.c --- nspr-4.9.5/nspr/pr/src/misc/prtpool.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prtpool.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1187 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" + +/* + * Thread pools + * Thread pools create and manage threads to provide support for + * scheduling jobs onto one or more threads. + * + */ +#ifdef OPT_WINNT +#include +#endif + +/* + * worker thread + */ +typedef struct wthread { + PRCList links; + PRThread *thread; +} wthread; + +/* + * queue of timer jobs + */ +typedef struct timer_jobq { + PRCList list; + PRLock *lock; + PRCondVar *cv; + PRInt32 cnt; + PRCList wthreads; +} timer_jobq; + +/* + * queue of jobs + */ +typedef struct tp_jobq { + PRCList list; + PRInt32 cnt; + PRLock *lock; + PRCondVar *cv; + PRCList wthreads; +#ifdef OPT_WINNT + HANDLE nt_completion_port; +#endif +} tp_jobq; + +/* + * queue of IO jobs + */ +typedef struct io_jobq { + PRCList list; + PRPollDesc *pollfds; + PRInt32 npollfds; + PRJob **polljobs; + PRLock *lock; + PRInt32 cnt; + PRFileDesc *notify_fd; + PRCList wthreads; +} io_jobq; + +/* + * Threadpool + */ +struct PRThreadPool { + PRInt32 init_threads; + PRInt32 max_threads; + PRInt32 current_threads; + PRInt32 idle_threads; + PRUint32 stacksize; + tp_jobq jobq; + io_jobq ioq; + timer_jobq timerq; + PRLock *join_lock; /* used with jobp->join_cv */ + PRCondVar *shutdown_cv; + PRBool shutdown; +}; + +typedef enum io_op_type + { JOB_IO_READ, JOB_IO_WRITE, JOB_IO_CONNECT, JOB_IO_ACCEPT } io_op_type; + +#ifdef OPT_WINNT +typedef struct NT_notifier { + OVERLAPPED overlapped; /* must be first */ + PRJob *jobp; +} NT_notifier; +#endif + +struct PRJob { + PRCList links; /* for linking jobs */ + PRBool on_ioq; /* job on ioq */ + PRBool on_timerq; /* job on timerq */ + PRJobFn job_func; + void *job_arg; + PRCondVar *join_cv; + PRBool join_wait; /* == PR_TRUE, when waiting to join */ + PRCondVar *cancel_cv; /* for cancelling IO jobs */ + PRBool cancel_io; /* for cancelling IO jobs */ + PRThreadPool *tpool; /* back pointer to thread pool */ + PRJobIoDesc *iod; + io_op_type io_op; + PRInt16 io_poll_flags; + PRNetAddr *netaddr; + PRIntervalTime timeout; /* relative value */ + PRIntervalTime absolute; +#ifdef OPT_WINNT + NT_notifier nt_notifier; +#endif +}; + +#define JOB_LINKS_PTR(_qp) \ + ((PRJob *) ((char *) (_qp) - offsetof(PRJob, links))) + +#define WTHREAD_LINKS_PTR(_qp) \ + ((wthread *) ((char *) (_qp) - offsetof(wthread, links))) + +#define JOINABLE_JOB(_jobp) (NULL != (_jobp)->join_cv) + +#define JOIN_NOTIFY(_jobp) \ + PR_BEGIN_MACRO \ + PR_Lock(_jobp->tpool->join_lock); \ + _jobp->join_wait = PR_FALSE; \ + PR_NotifyCondVar(_jobp->join_cv); \ + PR_Unlock(_jobp->tpool->join_lock); \ + PR_END_MACRO + +#define CANCEL_IO_JOB(jobp) \ + PR_BEGIN_MACRO \ + jobp->cancel_io = PR_FALSE; \ + jobp->on_ioq = PR_FALSE; \ + PR_REMOVE_AND_INIT_LINK(&jobp->links); \ + tp->ioq.cnt--; \ + PR_NotifyCondVar(jobp->cancel_cv); \ + PR_END_MACRO + +static void delete_job(PRJob *jobp); +static PRThreadPool * alloc_threadpool(void); +static PRJob * alloc_job(PRBool joinable, PRThreadPool *tp); +static void notify_ioq(PRThreadPool *tp); +static void notify_timerq(PRThreadPool *tp); + +/* + * locks are acquired in the following order + * + * tp->ioq.lock,tp->timerq.lock + * | + * V + * tp->jobq->lock + */ + +/* + * worker thread function + */ +static void wstart(void *arg) +{ +PRThreadPool *tp = (PRThreadPool *) arg; +PRCList *head; + + /* + * execute jobs until shutdown + */ + while (!tp->shutdown) { + PRJob *jobp; +#ifdef OPT_WINNT + BOOL rv; + DWORD unused, shutdown; + LPOVERLAPPED olp; + + PR_Lock(tp->jobq.lock); + tp->idle_threads++; + PR_Unlock(tp->jobq.lock); + rv = GetQueuedCompletionStatus(tp->jobq.nt_completion_port, + &unused, &shutdown, &olp, INFINITE); + + PR_ASSERT(rv); + if (shutdown) + break; + jobp = ((NT_notifier *) olp)->jobp; + PR_Lock(tp->jobq.lock); + tp->idle_threads--; + tp->jobq.cnt--; + PR_Unlock(tp->jobq.lock); +#else + + PR_Lock(tp->jobq.lock); + while (PR_CLIST_IS_EMPTY(&tp->jobq.list) && (!tp->shutdown)) { + tp->idle_threads++; + PR_WaitCondVar(tp->jobq.cv, PR_INTERVAL_NO_TIMEOUT); + tp->idle_threads--; + } + if (tp->shutdown) { + PR_Unlock(tp->jobq.lock); + break; + } + head = PR_LIST_HEAD(&tp->jobq.list); + /* + * remove job from queue + */ + PR_REMOVE_AND_INIT_LINK(head); + tp->jobq.cnt--; + jobp = JOB_LINKS_PTR(head); + PR_Unlock(tp->jobq.lock); +#endif + + jobp->job_func(jobp->job_arg); + if (!JOINABLE_JOB(jobp)) { + delete_job(jobp); + } else { + JOIN_NOTIFY(jobp); + } + } + PR_Lock(tp->jobq.lock); + tp->current_threads--; + PR_Unlock(tp->jobq.lock); +} + +/* + * add a job to the work queue + */ +static void +add_to_jobq(PRThreadPool *tp, PRJob *jobp) +{ + /* + * add to jobq + */ +#ifdef OPT_WINNT + PR_Lock(tp->jobq.lock); + tp->jobq.cnt++; + PR_Unlock(tp->jobq.lock); + /* + * notify worker thread(s) + */ + PostQueuedCompletionStatus(tp->jobq.nt_completion_port, 0, + FALSE, &jobp->nt_notifier.overlapped); +#else + PR_Lock(tp->jobq.lock); + PR_APPEND_LINK(&jobp->links,&tp->jobq.list); + tp->jobq.cnt++; + if ((tp->idle_threads < tp->jobq.cnt) && + (tp->current_threads < tp->max_threads)) { + wthread *wthrp; + /* + * increment thread count and unlock the jobq lock + */ + tp->current_threads++; + PR_Unlock(tp->jobq.lock); + /* create new worker thread */ + wthrp = PR_NEWZAP(wthread); + if (wthrp) { + wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart, + tp, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize); + if (NULL == wthrp->thread) { + PR_DELETE(wthrp); /* this sets wthrp to NULL */ + } + } + PR_Lock(tp->jobq.lock); + if (NULL == wthrp) { + tp->current_threads--; + } else { + PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); + } + } + /* + * wakeup a worker thread + */ + PR_NotifyCondVar(tp->jobq.cv); + PR_Unlock(tp->jobq.lock); +#endif +} + +/* + * io worker thread function + */ +static void io_wstart(void *arg) +{ +PRThreadPool *tp = (PRThreadPool *) arg; +int pollfd_cnt, pollfds_used; +int rv; +PRCList *qp, *nextqp; +PRPollDesc *pollfds; +PRJob **polljobs; +int poll_timeout; +PRIntervalTime now; + + /* + * scan io_jobq + * construct poll list + * call PR_Poll + * for all fds, for which poll returns true, move the job to + * jobq and wakeup worker thread. + */ + while (!tp->shutdown) { + PRJob *jobp; + + pollfd_cnt = tp->ioq.cnt + 10; + if (pollfd_cnt > tp->ioq.npollfds) { + + /* + * re-allocate pollfd array if the current one is not large + * enough + */ + if (NULL != tp->ioq.pollfds) + PR_Free(tp->ioq.pollfds); + tp->ioq.pollfds = (PRPollDesc *) PR_Malloc(pollfd_cnt * + (sizeof(PRPollDesc) + sizeof(PRJob *))); + PR_ASSERT(NULL != tp->ioq.pollfds); + /* + * array of pollfds + */ + pollfds = tp->ioq.pollfds; + tp->ioq.polljobs = (PRJob **) (&tp->ioq.pollfds[pollfd_cnt]); + /* + * parallel array of jobs + */ + polljobs = tp->ioq.polljobs; + tp->ioq.npollfds = pollfd_cnt; + } + + pollfds_used = 0; + /* + * add the notify fd; used for unblocking io thread(s) + */ + pollfds[pollfds_used].fd = tp->ioq.notify_fd; + pollfds[pollfds_used].in_flags = PR_POLL_READ; + pollfds[pollfds_used].out_flags = 0; + polljobs[pollfds_used] = NULL; + pollfds_used++; + /* + * fill in the pollfd array + */ + PR_Lock(tp->ioq.lock); + for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) { + nextqp = qp->next; + jobp = JOB_LINKS_PTR(qp); + if (jobp->cancel_io) { + CANCEL_IO_JOB(jobp); + continue; + } + if (pollfds_used == (pollfd_cnt)) + break; + pollfds[pollfds_used].fd = jobp->iod->socket; + pollfds[pollfds_used].in_flags = jobp->io_poll_flags; + pollfds[pollfds_used].out_flags = 0; + polljobs[pollfds_used] = jobp; + + pollfds_used++; + } + if (!PR_CLIST_IS_EMPTY(&tp->ioq.list)) { + qp = tp->ioq.list.next; + jobp = JOB_LINKS_PTR(qp); + if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout) + poll_timeout = PR_INTERVAL_NO_TIMEOUT; + else if (PR_INTERVAL_NO_WAIT == jobp->timeout) + poll_timeout = PR_INTERVAL_NO_WAIT; + else { + poll_timeout = jobp->absolute - PR_IntervalNow(); + if (poll_timeout <= 0) /* already timed out */ + poll_timeout = PR_INTERVAL_NO_WAIT; + } + } else { + poll_timeout = PR_INTERVAL_NO_TIMEOUT; + } + PR_Unlock(tp->ioq.lock); + + /* + * XXXX + * should retry if more jobs have been added to the queue? + * + */ + PR_ASSERT(pollfds_used <= pollfd_cnt); + rv = PR_Poll(tp->ioq.pollfds, pollfds_used, poll_timeout); + + if (tp->shutdown) { + break; + } + + if (rv > 0) { + /* + * at least one io event is set + */ + PRStatus rval_status; + PRInt32 index; + + PR_ASSERT(pollfds[0].fd == tp->ioq.notify_fd); + /* + * reset the pollable event, if notified + */ + if (pollfds[0].out_flags & PR_POLL_READ) { + rval_status = PR_WaitForPollableEvent(tp->ioq.notify_fd); + PR_ASSERT(PR_SUCCESS == rval_status); + } + + for(index = 1; index < (pollfds_used); index++) { + PRInt16 events = pollfds[index].in_flags; + PRInt16 revents = pollfds[index].out_flags; + jobp = polljobs[index]; + + if ((revents & PR_POLL_NVAL) || /* busted in all cases */ + (revents & PR_POLL_ERR) || + ((events & PR_POLL_WRITE) && + (revents & PR_POLL_HUP))) { /* write op & hup */ + PR_Lock(tp->ioq.lock); + if (jobp->cancel_io) { + CANCEL_IO_JOB(jobp); + PR_Unlock(tp->ioq.lock); + continue; + } + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->ioq.cnt--; + jobp->on_ioq = PR_FALSE; + PR_Unlock(tp->ioq.lock); + + /* set error */ + if (PR_POLL_NVAL & revents) + jobp->iod->error = PR_BAD_DESCRIPTOR_ERROR; + else if (PR_POLL_HUP & revents) + jobp->iod->error = PR_CONNECT_RESET_ERROR; + else + jobp->iod->error = PR_IO_ERROR; + + /* + * add to jobq + */ + add_to_jobq(tp, jobp); + } else if (revents) { + /* + * add to jobq + */ + PR_Lock(tp->ioq.lock); + if (jobp->cancel_io) { + CANCEL_IO_JOB(jobp); + PR_Unlock(tp->ioq.lock); + continue; + } + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->ioq.cnt--; + jobp->on_ioq = PR_FALSE; + PR_Unlock(tp->ioq.lock); + + if (jobp->io_op == JOB_IO_CONNECT) { + if (PR_GetConnectStatus(&pollfds[index]) == PR_SUCCESS) + jobp->iod->error = 0; + else + jobp->iod->error = PR_GetError(); + } else + jobp->iod->error = 0; + + add_to_jobq(tp, jobp); + } + } + } + /* + * timeout processing + */ + now = PR_IntervalNow(); + PR_Lock(tp->ioq.lock); + for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) { + nextqp = qp->next; + jobp = JOB_LINKS_PTR(qp); + if (jobp->cancel_io) { + CANCEL_IO_JOB(jobp); + continue; + } + if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout) + break; + if ((PR_INTERVAL_NO_WAIT != jobp->timeout) && + ((PRInt32)(jobp->absolute - now) > 0)) + break; + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->ioq.cnt--; + jobp->on_ioq = PR_FALSE; + jobp->iod->error = PR_IO_TIMEOUT_ERROR; + add_to_jobq(tp, jobp); + } + PR_Unlock(tp->ioq.lock); + } +} + +/* + * timer worker thread function + */ +static void timer_wstart(void *arg) +{ +PRThreadPool *tp = (PRThreadPool *) arg; +PRCList *qp; +PRIntervalTime timeout; +PRIntervalTime now; + + /* + * call PR_WaitCondVar with minimum value of all timeouts + */ + while (!tp->shutdown) { + PRJob *jobp; + + PR_Lock(tp->timerq.lock); + if (PR_CLIST_IS_EMPTY(&tp->timerq.list)) { + timeout = PR_INTERVAL_NO_TIMEOUT; + } else { + PRCList *qp; + + qp = tp->timerq.list.next; + jobp = JOB_LINKS_PTR(qp); + + timeout = jobp->absolute - PR_IntervalNow(); + if (timeout <= 0) + timeout = PR_INTERVAL_NO_WAIT; /* already timed out */ + } + if (PR_INTERVAL_NO_WAIT != timeout) + PR_WaitCondVar(tp->timerq.cv, timeout); + if (tp->shutdown) { + PR_Unlock(tp->timerq.lock); + break; + } + /* + * move expired-timer jobs to jobq + */ + now = PR_IntervalNow(); + while (!PR_CLIST_IS_EMPTY(&tp->timerq.list)) { + qp = tp->timerq.list.next; + jobp = JOB_LINKS_PTR(qp); + + if ((PRInt32)(jobp->absolute - now) > 0) { + break; + } + /* + * job timed out + */ + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->timerq.cnt--; + jobp->on_timerq = PR_FALSE; + add_to_jobq(tp, jobp); + } + PR_Unlock(tp->timerq.lock); + } +} + +static void +delete_threadpool(PRThreadPool *tp) +{ + if (NULL != tp) { + if (NULL != tp->shutdown_cv) + PR_DestroyCondVar(tp->shutdown_cv); + if (NULL != tp->jobq.cv) + PR_DestroyCondVar(tp->jobq.cv); + if (NULL != tp->jobq.lock) + PR_DestroyLock(tp->jobq.lock); + if (NULL != tp->join_lock) + PR_DestroyLock(tp->join_lock); +#ifdef OPT_WINNT + if (NULL != tp->jobq.nt_completion_port) + CloseHandle(tp->jobq.nt_completion_port); +#endif + /* Timer queue */ + if (NULL != tp->timerq.cv) + PR_DestroyCondVar(tp->timerq.cv); + if (NULL != tp->timerq.lock) + PR_DestroyLock(tp->timerq.lock); + + if (NULL != tp->ioq.lock) + PR_DestroyLock(tp->ioq.lock); + if (NULL != tp->ioq.pollfds) + PR_Free(tp->ioq.pollfds); + if (NULL != tp->ioq.notify_fd) + PR_DestroyPollableEvent(tp->ioq.notify_fd); + PR_Free(tp); + } + return; +} + +static PRThreadPool * +alloc_threadpool(void) +{ +PRThreadPool *tp; + + tp = (PRThreadPool *) PR_CALLOC(sizeof(*tp)); + if (NULL == tp) + goto failed; + tp->jobq.lock = PR_NewLock(); + if (NULL == tp->jobq.lock) + goto failed; + tp->jobq.cv = PR_NewCondVar(tp->jobq.lock); + if (NULL == tp->jobq.cv) + goto failed; + tp->join_lock = PR_NewLock(); + if (NULL == tp->join_lock) + goto failed; +#ifdef OPT_WINNT + tp->jobq.nt_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, + NULL, 0, 0); + if (NULL == tp->jobq.nt_completion_port) + goto failed; +#endif + + tp->ioq.lock = PR_NewLock(); + if (NULL == tp->ioq.lock) + goto failed; + + /* Timer queue */ + + tp->timerq.lock = PR_NewLock(); + if (NULL == tp->timerq.lock) + goto failed; + tp->timerq.cv = PR_NewCondVar(tp->timerq.lock); + if (NULL == tp->timerq.cv) + goto failed; + + tp->shutdown_cv = PR_NewCondVar(tp->jobq.lock); + if (NULL == tp->shutdown_cv) + goto failed; + tp->ioq.notify_fd = PR_NewPollableEvent(); + if (NULL == tp->ioq.notify_fd) + goto failed; + return tp; +failed: + delete_threadpool(tp); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; +} + +/* Create thread pool */ +PR_IMPLEMENT(PRThreadPool *) +PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads, + PRUint32 stacksize) +{ +PRThreadPool *tp; +PRThread *thr; +int i; +wthread *wthrp; + + tp = alloc_threadpool(); + if (NULL == tp) + return NULL; + + tp->init_threads = initial_threads; + tp->max_threads = max_threads; + tp->stacksize = stacksize; + PR_INIT_CLIST(&tp->jobq.list); + PR_INIT_CLIST(&tp->ioq.list); + PR_INIT_CLIST(&tp->timerq.list); + PR_INIT_CLIST(&tp->jobq.wthreads); + PR_INIT_CLIST(&tp->ioq.wthreads); + PR_INIT_CLIST(&tp->timerq.wthreads); + tp->shutdown = PR_FALSE; + + PR_Lock(tp->jobq.lock); + for(i=0; i < initial_threads; ++i) { + + thr = PR_CreateThread(PR_USER_THREAD, wstart, + tp, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,stacksize); + PR_ASSERT(thr); + wthrp = PR_NEWZAP(wthread); + PR_ASSERT(wthrp); + wthrp->thread = thr; + PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); + } + tp->current_threads = initial_threads; + + thr = PR_CreateThread(PR_USER_THREAD, io_wstart, + tp, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); + PR_ASSERT(thr); + wthrp = PR_NEWZAP(wthread); + PR_ASSERT(wthrp); + wthrp->thread = thr; + PR_APPEND_LINK(&wthrp->links, &tp->ioq.wthreads); + + thr = PR_CreateThread(PR_USER_THREAD, timer_wstart, + tp, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); + PR_ASSERT(thr); + wthrp = PR_NEWZAP(wthread); + PR_ASSERT(wthrp); + wthrp->thread = thr; + PR_APPEND_LINK(&wthrp->links, &tp->timerq.wthreads); + + PR_Unlock(tp->jobq.lock); + return tp; +} + +static void +delete_job(PRJob *jobp) +{ + if (NULL != jobp) { + if (NULL != jobp->join_cv) { + PR_DestroyCondVar(jobp->join_cv); + jobp->join_cv = NULL; + } + if (NULL != jobp->cancel_cv) { + PR_DestroyCondVar(jobp->cancel_cv); + jobp->cancel_cv = NULL; + } + PR_DELETE(jobp); + } +} + +static PRJob * +alloc_job(PRBool joinable, PRThreadPool *tp) +{ + PRJob *jobp; + + jobp = PR_NEWZAP(PRJob); + if (NULL == jobp) + goto failed; + if (joinable) { + jobp->join_cv = PR_NewCondVar(tp->join_lock); + jobp->join_wait = PR_TRUE; + if (NULL == jobp->join_cv) + goto failed; + } else { + jobp->join_cv = NULL; + } +#ifdef OPT_WINNT + jobp->nt_notifier.jobp = jobp; +#endif + return jobp; +failed: + delete_job(jobp); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; +} + +/* queue a job */ +PR_IMPLEMENT(PRJob *) +PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable) +{ + PRJob *jobp; + + jobp = alloc_job(joinable, tpool); + if (NULL == jobp) + return NULL; + + jobp->job_func = fn; + jobp->job_arg = arg; + jobp->tpool = tpool; + + add_to_jobq(tpool, jobp); + return jobp; +} + +/* queue a job, when a socket is readable or writeable */ +static PRJob * +queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg, + PRBool joinable, io_op_type op) +{ + PRJob *jobp; + PRIntervalTime now; + + jobp = alloc_job(joinable, tpool); + if (NULL == jobp) { + return NULL; + } + + /* + * Add a new job to io_jobq + * wakeup io worker thread + */ + + jobp->job_func = fn; + jobp->job_arg = arg; + jobp->tpool = tpool; + jobp->iod = iod; + if (JOB_IO_READ == op) { + jobp->io_op = JOB_IO_READ; + jobp->io_poll_flags = PR_POLL_READ; + } else if (JOB_IO_WRITE == op) { + jobp->io_op = JOB_IO_WRITE; + jobp->io_poll_flags = PR_POLL_WRITE; + } else if (JOB_IO_ACCEPT == op) { + jobp->io_op = JOB_IO_ACCEPT; + jobp->io_poll_flags = PR_POLL_READ; + } else if (JOB_IO_CONNECT == op) { + jobp->io_op = JOB_IO_CONNECT; + jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT; + } else { + delete_job(jobp); + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } + + jobp->timeout = iod->timeout; + if ((PR_INTERVAL_NO_TIMEOUT == iod->timeout) || + (PR_INTERVAL_NO_WAIT == iod->timeout)) { + jobp->absolute = iod->timeout; + } else { + now = PR_IntervalNow(); + jobp->absolute = now + iod->timeout; + } + + + PR_Lock(tpool->ioq.lock); + + if (PR_CLIST_IS_EMPTY(&tpool->ioq.list) || + (PR_INTERVAL_NO_TIMEOUT == iod->timeout)) { + PR_APPEND_LINK(&jobp->links,&tpool->ioq.list); + } else if (PR_INTERVAL_NO_WAIT == iod->timeout) { + PR_INSERT_LINK(&jobp->links,&tpool->ioq.list); + } else { + PRCList *qp; + PRJob *tmp_jobp; + /* + * insert into the timeout-sorted ioq + */ + for (qp = tpool->ioq.list.prev; qp != &tpool->ioq.list; + qp = qp->prev) { + tmp_jobp = JOB_LINKS_PTR(qp); + if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { + break; + } + } + PR_INSERT_AFTER(&jobp->links,qp); + } + + jobp->on_ioq = PR_TRUE; + tpool->ioq.cnt++; + /* + * notify io worker thread(s) + */ + PR_Unlock(tpool->ioq.lock); + notify_ioq(tpool); + return jobp; +} + +/* queue a job, when a socket is readable */ +PR_IMPLEMENT(PRJob *) +PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg, + PRBool joinable) +{ + return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_READ)); +} + +/* queue a job, when a socket is writeable */ +PR_IMPLEMENT(PRJob *) +PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,void * arg, + PRBool joinable) +{ + return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE)); +} + + +/* queue a job, when a socket has a pending connection */ +PR_IMPLEMENT(PRJob *) +PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, + void * arg, PRBool joinable) +{ + return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_ACCEPT)); +} + +/* queue a job, when a socket can be connected */ +PR_IMPLEMENT(PRJob *) +PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod, + const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable) +{ + PRStatus rv; + PRErrorCode err; + + rv = PR_Connect(iod->socket, addr, PR_INTERVAL_NO_WAIT); + if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){ + /* connection pending */ + return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT)); + } else { + /* + * connection succeeded or failed; add to jobq right away + */ + if (rv == PR_FAILURE) + iod->error = err; + else + iod->error = 0; + return(PR_QueueJob(tpool, fn, arg, joinable)); + } +} + +/* queue a job, when a timer expires */ +PR_IMPLEMENT(PRJob *) +PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout, + PRJobFn fn, void * arg, PRBool joinable) +{ + PRIntervalTime now; + PRJob *jobp; + + if (PR_INTERVAL_NO_TIMEOUT == timeout) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } + if (PR_INTERVAL_NO_WAIT == timeout) { + /* + * no waiting; add to jobq right away + */ + return(PR_QueueJob(tpool, fn, arg, joinable)); + } + jobp = alloc_job(joinable, tpool); + if (NULL == jobp) { + return NULL; + } + + /* + * Add a new job to timer_jobq + * wakeup timer worker thread + */ + + jobp->job_func = fn; + jobp->job_arg = arg; + jobp->tpool = tpool; + jobp->timeout = timeout; + + now = PR_IntervalNow(); + jobp->absolute = now + timeout; + + + PR_Lock(tpool->timerq.lock); + jobp->on_timerq = PR_TRUE; + if (PR_CLIST_IS_EMPTY(&tpool->timerq.list)) + PR_APPEND_LINK(&jobp->links,&tpool->timerq.list); + else { + PRCList *qp; + PRJob *tmp_jobp; + /* + * insert into the sorted timer jobq + */ + for (qp = tpool->timerq.list.prev; qp != &tpool->timerq.list; + qp = qp->prev) { + tmp_jobp = JOB_LINKS_PTR(qp); + if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { + break; + } + } + PR_INSERT_AFTER(&jobp->links,qp); + } + tpool->timerq.cnt++; + /* + * notify timer worker thread(s) + */ + notify_timerq(tpool); + PR_Unlock(tpool->timerq.lock); + return jobp; +} + +static void +notify_timerq(PRThreadPool *tp) +{ + /* + * wakeup the timer thread(s) + */ + PR_NotifyCondVar(tp->timerq.cv); +} + +static void +notify_ioq(PRThreadPool *tp) +{ +PRStatus rval_status; + + /* + * wakeup the io thread(s) + */ + rval_status = PR_SetPollableEvent(tp->ioq.notify_fd); + PR_ASSERT(PR_SUCCESS == rval_status); +} + +/* + * cancel a job + * + * XXXX: is this needed? likely to be removed + */ +PR_IMPLEMENT(PRStatus) +PR_CancelJob(PRJob *jobp) { + + PRStatus rval = PR_FAILURE; + PRThreadPool *tp; + + if (jobp->on_timerq) { + /* + * now, check again while holding the timerq lock + */ + tp = jobp->tpool; + PR_Lock(tp->timerq.lock); + if (jobp->on_timerq) { + jobp->on_timerq = PR_FALSE; + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->timerq.cnt--; + PR_Unlock(tp->timerq.lock); + if (!JOINABLE_JOB(jobp)) { + delete_job(jobp); + } else { + JOIN_NOTIFY(jobp); + } + rval = PR_SUCCESS; + } else + PR_Unlock(tp->timerq.lock); + } else if (jobp->on_ioq) { + /* + * now, check again while holding the ioq lock + */ + tp = jobp->tpool; + PR_Lock(tp->ioq.lock); + if (jobp->on_ioq) { + jobp->cancel_cv = PR_NewCondVar(tp->ioq.lock); + if (NULL == jobp->cancel_cv) { + PR_Unlock(tp->ioq.lock); + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + return PR_FAILURE; + } + /* + * mark job 'cancelled' and notify io thread(s) + * XXXX: + * this assumes there is only one io thread; when there + * are multiple threads, the io thread processing this job + * must be notified. + */ + jobp->cancel_io = PR_TRUE; + PR_Unlock(tp->ioq.lock); /* release, reacquire ioq lock */ + notify_ioq(tp); + PR_Lock(tp->ioq.lock); + while (jobp->cancel_io) + PR_WaitCondVar(jobp->cancel_cv, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(tp->ioq.lock); + PR_ASSERT(!jobp->on_ioq); + if (!JOINABLE_JOB(jobp)) { + delete_job(jobp); + } else { + JOIN_NOTIFY(jobp); + } + rval = PR_SUCCESS; + } else + PR_Unlock(tp->ioq.lock); + } + if (PR_FAILURE == rval) + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return rval; +} + +/* join a job, wait until completion */ +PR_IMPLEMENT(PRStatus) +PR_JoinJob(PRJob *jobp) +{ + if (!JOINABLE_JOB(jobp)) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + PR_Lock(jobp->tpool->join_lock); + while(jobp->join_wait) + PR_WaitCondVar(jobp->join_cv, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(jobp->tpool->join_lock); + delete_job(jobp); + return PR_SUCCESS; +} + +/* shutdown threadpool */ +PR_IMPLEMENT(PRStatus) +PR_ShutdownThreadPool(PRThreadPool *tpool) +{ +PRStatus rval = PR_SUCCESS; + + PR_Lock(tpool->jobq.lock); + tpool->shutdown = PR_TRUE; + PR_NotifyAllCondVar(tpool->shutdown_cv); + PR_Unlock(tpool->jobq.lock); + + return rval; +} + +/* + * join thread pool + * wait for termination of worker threads + * reclaim threadpool resources + */ +PR_IMPLEMENT(PRStatus) +PR_JoinThreadPool(PRThreadPool *tpool) +{ +PRStatus rval = PR_SUCCESS; +PRCList *head; +PRStatus rval_status; + + PR_Lock(tpool->jobq.lock); + while (!tpool->shutdown) + PR_WaitCondVar(tpool->shutdown_cv, PR_INTERVAL_NO_TIMEOUT); + + /* + * wakeup worker threads + */ +#ifdef OPT_WINNT + /* + * post shutdown notification for all threads + */ + { + int i; + for(i=0; i < tpool->current_threads; i++) { + PostQueuedCompletionStatus(tpool->jobq.nt_completion_port, 0, + TRUE, NULL); + } + } +#else + PR_NotifyAllCondVar(tpool->jobq.cv); +#endif + + /* + * wakeup io thread(s) + */ + notify_ioq(tpool); + + /* + * wakeup timer thread(s) + */ + PR_Lock(tpool->timerq.lock); + notify_timerq(tpool); + PR_Unlock(tpool->timerq.lock); + + while (!PR_CLIST_IS_EMPTY(&tpool->jobq.wthreads)) { + wthread *wthrp; + + head = PR_LIST_HEAD(&tpool->jobq.wthreads); + PR_REMOVE_AND_INIT_LINK(head); + PR_Unlock(tpool->jobq.lock); + wthrp = WTHREAD_LINKS_PTR(head); + rval_status = PR_JoinThread(wthrp->thread); + PR_ASSERT(PR_SUCCESS == rval_status); + PR_DELETE(wthrp); + PR_Lock(tpool->jobq.lock); + } + PR_Unlock(tpool->jobq.lock); + while (!PR_CLIST_IS_EMPTY(&tpool->ioq.wthreads)) { + wthread *wthrp; + + head = PR_LIST_HEAD(&tpool->ioq.wthreads); + PR_REMOVE_AND_INIT_LINK(head); + wthrp = WTHREAD_LINKS_PTR(head); + rval_status = PR_JoinThread(wthrp->thread); + PR_ASSERT(PR_SUCCESS == rval_status); + PR_DELETE(wthrp); + } + + while (!PR_CLIST_IS_EMPTY(&tpool->timerq.wthreads)) { + wthread *wthrp; + + head = PR_LIST_HEAD(&tpool->timerq.wthreads); + PR_REMOVE_AND_INIT_LINK(head); + wthrp = WTHREAD_LINKS_PTR(head); + rval_status = PR_JoinThread(wthrp->thread); + PR_ASSERT(PR_SUCCESS == rval_status); + PR_DELETE(wthrp); + } + + /* + * Delete queued jobs + */ + while (!PR_CLIST_IS_EMPTY(&tpool->jobq.list)) { + PRJob *jobp; + + head = PR_LIST_HEAD(&tpool->jobq.list); + PR_REMOVE_AND_INIT_LINK(head); + jobp = JOB_LINKS_PTR(head); + tpool->jobq.cnt--; + delete_job(jobp); + } + + /* delete io jobs */ + while (!PR_CLIST_IS_EMPTY(&tpool->ioq.list)) { + PRJob *jobp; + + head = PR_LIST_HEAD(&tpool->ioq.list); + PR_REMOVE_AND_INIT_LINK(head); + tpool->ioq.cnt--; + jobp = JOB_LINKS_PTR(head); + delete_job(jobp); + } + + /* delete timer jobs */ + while (!PR_CLIST_IS_EMPTY(&tpool->timerq.list)) { + PRJob *jobp; + + head = PR_LIST_HEAD(&tpool->timerq.list); + PR_REMOVE_AND_INIT_LINK(head); + tpool->timerq.cnt--; + jobp = JOB_LINKS_PTR(head); + delete_job(jobp); + } + + PR_ASSERT(0 == tpool->jobq.cnt); + PR_ASSERT(0 == tpool->ioq.cnt); + PR_ASSERT(0 == tpool->timerq.cnt); + + delete_threadpool(tpool); + return rval; +} diff -Nru nspr-4.9.5/nspr/pr/src/misc/prtrace.c nspr-4.10.7/nspr/pr/src/misc/prtrace.c --- nspr-4.9.5/nspr/pr/src/misc/prtrace.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/misc/prtrace.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,888 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** prtrace.c -- NSPR Trace Instrumentation +** +** Implement the API defined in prtrace.h +** +** +** +*/ + +#include +#include "primpl.h" + + +#define DEFAULT_TRACE_BUFSIZE ( 1024 * 1024 ) +#define DEFAULT_BUFFER_SEGMENTS 2 + +/* +** Enumerate states in a RName structure +*/ +typedef enum TraceState +{ + Running = 1, + Suspended = 2 +} TraceState; + +/* +** Define QName structure +*/ +typedef struct QName +{ + PRCList link; + PRCList rNameList; + char name[PRTRACE_NAME_MAX+1]; +} QName; + +/* +** Define RName structure +*/ +typedef struct RName +{ + PRCList link; + PRLock *lock; + QName *qName; + TraceState state; + char name[PRTRACE_NAME_MAX+1]; + char desc[PRTRACE_DESC_MAX+1]; +} RName; + + +/* +** The Trace Facility database +** +*/ +static PRLogModuleInfo *lm; + +static PRLock *traceLock; /* Facility Lock */ +static PRCList qNameList; /* anchor to all QName structures */ +static TraceState traceState = Running; + +/* +** in-memory trace buffer controls +*/ +static PRTraceEntry *tBuf; /* pointer to buffer */ +static PRInt32 bufSize; /* size of buffer, in bytes, rounded up to sizeof(PRTraceEntry) */ +static volatile PRInt32 next; /* index to next PRTraceEntry */ +static PRInt32 last; /* index of highest numbered trace entry */ + +/* +** Real-time buffer capture controls +*/ +static PRInt32 fetchLastSeen = 0; +static PRBool fetchLostData = PR_FALSE; + +/* +** Buffer write-to-file controls +*/ +static PRLock *logLock; /* Sync lock */ +static PRCondVar *logCVar; /* Sync Condidtion Variable */ +/* +** Inter-thread state communication. +** Controling thread writes to logOrder under protection of logCVar +** the logging thread reads logOrder and sets logState on Notify. +** +** logSegments, logCount, logLostData must be read and written under +** protection of logLock, logCVar. +** +*/ +static enum LogState +{ + LogNotRunning, /* Initial state */ + LogReset, /* Causes logger to re-calc controls */ + LogActive, /* Logging in progress, set only by log thread */ + LogSuspend, /* Suspend Logging */ + LogResume, /* Resume Logging => LogActive */ + LogStop /* Stop the log thread */ +} logOrder, logState, localState; /* controlling state variables */ +static PRInt32 logSegments; /* Number of buffer segments */ +static PRInt32 logEntries; /* number of Trace Entries in the buffer */ +static PRInt32 logEntriesPerSegment; /* number of PRTraceEntries per buffer segment */ +static PRInt32 logSegSize; /* size of buffer segment */ +static PRInt32 logCount; /* number of segments pending output */ +static PRInt32 logLostData; /* number of lost log buffer segments */ + +/* +** end Trace Database +** +*/ + +/* +** _PR_InitializeTrace() -- Initialize the trace facility +*/ +static void NewTraceBuffer( PRInt32 size ) +{ + /* + ** calculate the size of the buffer + ** round down so that each segment has the same number of + ** trace entries + */ + logSegments = DEFAULT_BUFFER_SEGMENTS; + logEntries = size / sizeof(PRTraceEntry); + logEntriesPerSegment = logEntries / logSegments; + logEntries = logSegments * logEntriesPerSegment; + bufSize = logEntries * sizeof(PRTraceEntry); + logSegSize = logEntriesPerSegment * sizeof(PRTraceEntry); + PR_ASSERT( bufSize != 0); + PR_LOG( lm, PR_LOG_ERROR, + ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegment: %ld, logSegSize: %ld", + logSegments, logEntries, logEntriesPerSegment, logSegSize )); + + + tBuf = PR_Malloc( bufSize ); + if ( tBuf == NULL ) + { + PR_LOG( lm, PR_LOG_ERROR, + ("PRTrace: Failed to get trace buffer")); + PR_ASSERT( 0 ); + } + else + { + PR_LOG( lm, PR_LOG_NOTICE, + ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf)); + } + + next = 0; + last = logEntries -1; + logCount = 0; + logLostData = PR_TRUE; /* not really on first call */ + logOrder = LogReset; + +} /* end NewTraceBuffer() */ + +/* +** _PR_InitializeTrace() -- Initialize the trace facility +*/ +static void _PR_InitializeTrace( void ) +{ + /* The lock pointer better be null on this call */ + PR_ASSERT( traceLock == NULL ); + + traceLock = PR_NewLock(); + PR_ASSERT( traceLock != NULL ); + + PR_Lock( traceLock ); + + PR_INIT_CLIST( &qNameList ); + + lm = PR_NewLogModule("trace"); + + bufSize = DEFAULT_TRACE_BUFSIZE; + NewTraceBuffer( bufSize ); + + /* Initialize logging controls */ + logLock = PR_NewLock(); + logCVar = PR_NewCondVar( logLock ); + + PR_Unlock( traceLock ); + return; +} /* end _PR_InitializeTrace() */ + +/* +** Create a Trace Handle +*/ +PR_IMPLEMENT(PRTraceHandle) + PR_CreateTrace( + const char *qName, /* QName for this trace handle */ + const char *rName, /* RName for this trace handle */ + const char *description /* description for this trace handle */ +) +{ + QName *qnp; + RName *rnp; + PRBool matchQname = PR_FALSE; + + /* Self initialize, if necessary */ + if ( traceLock == NULL ) + _PR_InitializeTrace(); + + /* Validate input arguments */ + PR_ASSERT( strlen(qName) <= PRTRACE_NAME_MAX ); + PR_ASSERT( strlen(rName) <= PRTRACE_NAME_MAX ); + PR_ASSERT( strlen(description) <= PRTRACE_DESC_MAX ); + + PR_LOG( lm, PR_LOG_DEBUG, + ("PRTRACE: CreateTrace: Qname: %s, RName: %s", qName, rName)); + + /* Lock the Facility */ + PR_Lock( traceLock ); + + /* Do we already have a matching QName? */ + if (!PR_CLIST_IS_EMPTY( &qNameList )) + { + qnp = (QName *) PR_LIST_HEAD( &qNameList ); + do { + if ( strcmp(qnp->name, qName) == 0) + { + matchQname = PR_TRUE; + break; + } + qnp = (QName *)PR_NEXT_LINK( &qnp->link ); + } while( qnp != (QName *)&qNameList ); + } + /* + ** If we did not find a matching QName, + ** allocate one and initialize it. + ** link it onto the qNameList. + ** + */ + if ( matchQname != PR_TRUE ) + { + qnp = PR_NEWZAP( QName ); + PR_ASSERT( qnp != NULL ); + PR_INIT_CLIST( &qnp->link ); + PR_INIT_CLIST( &qnp->rNameList ); + strcpy( qnp->name, qName ); + PR_APPEND_LINK( &qnp->link, &qNameList ); + } + + /* Do we already have a matching RName? */ + if (!PR_CLIST_IS_EMPTY( &qnp->rNameList )) + { + rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList ); + do { + /* + ** No duplicate RNames are allowed within a QName + ** + */ + PR_ASSERT( strcmp(rnp->name, rName)); + rnp = (RName *)PR_NEXT_LINK( &rnp->link ); + } while( rnp != (RName *)&qnp->rNameList ); + } + + /* Get a new RName structure; initialize its members */ + rnp = PR_NEWZAP( RName ); + PR_ASSERT( rnp != NULL ); + PR_INIT_CLIST( &rnp->link ); + strcpy( rnp->name, rName ); + strcpy( rnp->desc, description ); + rnp->lock = PR_NewLock(); + rnp->state = Running; + if ( rnp->lock == NULL ) + { + PR_ASSERT(0); + } + + PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ + rnp->qName = qnp; /* point the RName to the QName */ + + /* Unlock the Facility */ + PR_Unlock( traceLock ); + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Create: QName: %s %p, RName: %s %p\n\t", + qName, qnp, rName, rnp )); + + return((PRTraceHandle)rnp); +} /* end PR_CreateTrace() */ + +/* +** +*/ +PR_IMPLEMENT(void) + PR_DestroyTrace( + PRTraceHandle handle /* Handle to be destroyed */ +) +{ + RName *rnp = (RName *)handle; + QName *qnp = rnp->qName; + + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s", + qnp->name, rnp->name)); + + /* Lock the Facility */ + PR_Lock( traceLock ); + + /* + ** Remove RName from the list of RNames in QName + ** and free RName + */ + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p", + rnp->name, rnp)); + PR_REMOVE_LINK( &rnp->link ); + PR_Free( rnp->lock ); + PR_DELETE( rnp ); + + /* + ** If this is the last RName within QName + ** remove QName from the qNameList and free it + */ + if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) ) + { + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p", + qnp->name, qnp)); + PR_REMOVE_LINK( &qnp->link ); + PR_DELETE( qnp ); + } + + /* Unlock the Facility */ + PR_Unlock( traceLock ); + return; +} /* end PR_DestroyTrace() */ + +/* +** Create a TraceEntry in the trace buffer +*/ +PR_IMPLEMENT(void) + PR_Trace( + PRTraceHandle handle, /* use this trace handle */ + PRUint32 userData0, /* User supplied data word 0 */ + PRUint32 userData1, /* User supplied data word 1 */ + PRUint32 userData2, /* User supplied data word 2 */ + PRUint32 userData3, /* User supplied data word 3 */ + PRUint32 userData4, /* User supplied data word 4 */ + PRUint32 userData5, /* User supplied data word 5 */ + PRUint32 userData6, /* User supplied data word 6 */ + PRUint32 userData7 /* User supplied data word 7 */ +) +{ + PRTraceEntry *tep; + PRInt32 mark; + + if ( (traceState == Suspended ) + || ( ((RName *)handle)->state == Suspended )) + return; + + /* + ** Get the next trace entry slot w/ minimum delay + */ + PR_Lock( traceLock ); + + tep = &tBuf[next++]; + if ( next > last ) + next = 0; + if ( fetchLostData == PR_FALSE && next == fetchLastSeen ) + fetchLostData = PR_TRUE; + + mark = next; + + PR_Unlock( traceLock ); + + /* + ** We have a trace entry. Fill it in. + */ + tep->thread = PR_GetCurrentThread(); + tep->handle = handle; + tep->time = PR_Now(); + tep->userData[0] = userData0; + tep->userData[1] = userData1; + tep->userData[2] = userData2; + tep->userData[3] = userData3; + tep->userData[4] = userData4; + tep->userData[5] = userData5; + tep->userData[6] = userData6; + tep->userData[7] = userData7; + + /* When buffer segment is full, signal trace log thread to run */ + if (( mark % logEntriesPerSegment) == 0 ) + { + PR_Lock( logLock ); + logCount++; + PR_NotifyCondVar( logCVar ); + PR_Unlock( logLock ); + /* + ** Gh0D! This is awful! + ** Anyway, to minimize lost trace data segments, + ** I inserted the PR_Sleep(0) to cause a context switch + ** so that the log thread could run. + ** I know, it perturbs the universe and may cause + ** funny things to happen in the optimized builds. + ** Take it out, lose data; leave it in risk Heisenberg. + */ + /* PR_Sleep(0); */ + } + + return; +} /* end PR_Trace() */ + +/* +** +*/ +PR_IMPLEMENT(void) + PR_SetTraceOption( + PRTraceOption command, /* One of the enumerated values */ + void *value /* command value or NULL */ +) +{ + RName * rnp; + + switch ( command ) + { + case PRTraceBufSize : + PR_Lock( traceLock ); + PR_Free( tBuf ); + bufSize = *(PRInt32 *)value; + NewTraceBuffer( bufSize ); + PR_Unlock( traceLock ); + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize)); + break; + + case PRTraceEnable : + rnp = *(RName **)value; + rnp->state = Running; + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceEnable: %p", rnp)); + break; + + case PRTraceDisable : + rnp = *(RName **)value; + rnp->state = Suspended; + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceDisable: %p", rnp)); + break; + + case PRTraceSuspend : + traceState = Suspended; + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceSuspend")); + break; + + case PRTraceResume : + traceState = Running; + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceResume")); + break; + + case PRTraceSuspendRecording : + PR_Lock( logLock ); + logOrder = LogSuspend; + PR_NotifyCondVar( logCVar ); + PR_Unlock( logLock ); + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceSuspendRecording")); + break; + + case PRTraceResumeRecording : + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceResumeRecording")); + if ( logState != LogSuspend ) + break; + PR_Lock( logLock ); + logOrder = LogResume; + PR_NotifyCondVar( logCVar ); + PR_Unlock( logLock ); + break; + + case PRTraceStopRecording : + PR_Lock( logLock ); + logOrder = LogStop; + PR_NotifyCondVar( logCVar ); + PR_Unlock( logLock ); + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceStopRecording")); + break; + + case PRTraceLockHandles : + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceLockTraceHandles")); + PR_Lock( traceLock ); + break; + + case PRTraceUnLockHandles : + PR_LOG( lm, PR_LOG_DEBUG, + ("PRSetTraceOption: PRTraceUnLockHandles")); + PR_Unlock( traceLock ); + break; + + default: + PR_LOG( lm, PR_LOG_ERROR, + ("PRSetTraceOption: Invalid command %ld", command )); + PR_ASSERT( 0 ); + break; + } /* end switch() */ + return; +} /* end PR_SetTraceOption() */ + +/* +** +*/ +PR_IMPLEMENT(void) + PR_GetTraceOption( + PRTraceOption command, /* One of the enumerated values */ + void *value /* command value or NULL */ +) +{ + switch ( command ) + { + case PRTraceBufSize : + *((PRInt32 *)value) = bufSize; + PR_LOG( lm, PR_LOG_DEBUG, + ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize )); + break; + + default: + PR_LOG( lm, PR_LOG_ERROR, + ("PRGetTraceOption: Invalid command %ld", command )); + PR_ASSERT( 0 ); + break; + } /* end switch() */ + return; +} /* end PR_GetTraceOption() */ + +/* +** +*/ +PR_IMPLEMENT(PRTraceHandle) + PR_GetTraceHandleFromName( + const char *qName, /* QName search argument */ + const char *rName /* RName search argument */ +) +{ + const char *qn, *rn, *desc; + PRTraceHandle qh, rh = NULL; + RName *rnp = NULL; + + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetTraceHandleFromName:\n\t" + "QName: %s, RName: %s", qName, rName )); + + qh = PR_FindNextTraceQname( NULL ); + while (qh != NULL) + { + rh = PR_FindNextTraceRname( NULL, qh ); + while ( rh != NULL ) + { + PR_GetTraceNameFromHandle( rh, &qn, &rn, &desc ); + if ( (strcmp( qName, qn ) == 0) + && (strcmp( rName, rn ) == 0 )) + { + rnp = (RName *)rh; + goto foundIt; + } + rh = PR_FindNextTraceRname( rh, qh ); + } + qh = PR_FindNextTraceQname( NULL ); + } + +foundIt: + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp )); + return(rh); +} /* end PR_GetTraceHandleFromName() */ + +/* +** +*/ +PR_IMPLEMENT(void) + PR_GetTraceNameFromHandle( + PRTraceHandle handle, /* handle as search argument */ + const char **qName, /* pointer to associated QName */ + const char **rName, /* pointer to associated RName */ + const char **description /* pointer to associated description */ +) +{ + RName *rnp = (RName *)handle; + QName *qnp = rnp->qName; + + *qName = qnp->name; + *rName = rnp->name; + *description = rnp->desc; + + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetConterNameFromHandle: " + "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", + qnp, rnp, qnp->name, rnp->name, rnp->desc )); + + return; +} /* end PR_GetTraceNameFromHandle() */ + +/* +** +*/ +PR_IMPLEMENT(PRTraceHandle) + PR_FindNextTraceQname( + PRTraceHandle handle +) +{ + QName *qnp = (QName *)handle; + + if ( PR_CLIST_IS_EMPTY( &qNameList )) + qnp = NULL; + else if ( qnp == NULL ) + qnp = (QName *)PR_LIST_HEAD( &qNameList ); + else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) + qnp = NULL; + else + qnp = (QName *)PR_NEXT_LINK( &qnp->link ); + + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p", + handle, qnp )); + + return((PRTraceHandle)qnp); +} /* end PR_FindNextTraceQname() */ + +/* +** +*/ +PR_IMPLEMENT(PRTraceHandle) + PR_FindNextTraceRname( + PRTraceHandle rhandle, + PRTraceHandle qhandle +) +{ + RName *rnp = (RName *)rhandle; + QName *qnp = (QName *)qhandle; + + + if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) + rnp = NULL; + else if ( rnp == NULL ) + rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList ); + else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) + rnp = NULL; + else + rnp = (RName *)PR_NEXT_LINK( &rnp->link ); + + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", + rhandle, qhandle, rnp )); + + return((PRTraceHandle)rnp); +} /* end PR_FindNextTraceRname() */ + +/* +** +*/ +static PRFileDesc * InitializeRecording( void ) +{ + char *logFileName; + PRFileDesc *logFile; + + /* Self initialize, if necessary */ + if ( traceLock == NULL ) + _PR_InitializeTrace(); + + PR_LOG( lm, PR_LOG_DEBUG, + ("PR_RecordTraceEntries: begins")); + + logLostData = 0; /* reset at entry */ + logState = LogReset; + +#ifdef XP_UNIX + if ((getuid() != geteuid()) || (getgid() != getegid())) { + return NULL; + } +#endif /* XP_UNIX */ + + /* Get the filename for the logfile from the environment */ + logFileName = PR_GetEnv( "NSPR_TRACE_LOG" ); + if ( logFileName == NULL ) + { + PR_LOG( lm, PR_LOG_ERROR, + ("RecordTraceEntries: Environment variable not defined. Exiting")); + return NULL; + } + + /* Open the logfile */ + logFile = PR_Open( logFileName, PR_WRONLY | PR_CREATE_FILE, 0666 ); + if ( logFile == NULL ) + { + PR_LOG( lm, PR_LOG_ERROR, + ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %ld", + logFileName, PR_GetOSError())); + return NULL; + } + return logFile; +} /* end InitializeRecording() */ + +/* +** +*/ +static void ProcessOrders( void ) +{ + switch ( logOrder ) + { + case LogReset : + logOrder = logState = localState; + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: LogReset")); + break; + + case LogSuspend : + localState = logOrder = logState = LogSuspend; + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: LogSuspend")); + break; + + case LogResume : + localState = logOrder = logState = LogActive; + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: LogResume")); + break; + + case LogStop : + logOrder = logState = LogStop; + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: LogStop")); + break; + + default : + PR_LOG( lm, PR_LOG_ERROR, + ("RecordTraceEntries: Invalid logOrder: %ld", logOrder )); + PR_ASSERT( 0 ); + break; + } /* end switch() */ + return ; +} /* end ProcessOrders() */ + +/* +** +*/ +static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount ) +{ + PRInt32 rc; + + + PR_LOG( lm, PR_LOG_ERROR, + ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount)); + rc = PR_Write( logFile, buf , amount ); + if ( rc == -1 ) + PR_LOG( lm, PR_LOG_ERROR, + ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() )); + else if ( rc != amount ) + PR_LOG( lm, PR_LOG_ERROR, + ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", amount, rc)); + else + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amount)); + + return; +} /* end WriteTraceSegment() */ + +/* +** +*/ +PR_IMPLEMENT(void) + PR_RecordTraceEntries( + void +) +{ + PRFileDesc *logFile; + PRInt32 lostSegments; + PRInt32 currentSegment = 0; + void *buf; + PRBool doWrite; + + logFile = InitializeRecording(); + if ( logFile == NULL ) + { + PR_LOG( lm, PR_LOG_DEBUG, + ("PR_RecordTraceEntries: Failed to initialize")); + return; + } + + /* Do this until told to stop */ + while ( logState != LogStop ) + { + + PR_Lock( logLock ); + + while ( (logCount == 0) && ( logOrder == logState ) ) + PR_WaitCondVar( logCVar, PR_INTERVAL_NO_TIMEOUT ); + + /* Handle state transitions */ + if ( logOrder != logState ) + ProcessOrders(); + + /* recalculate local controls */ + if ( logCount ) + { + lostSegments = logCount - logSegments; + if ( lostSegments > 0 ) + { + logLostData += ( logCount - logSegments ); + logCount = (logCount % logSegments); + currentSegment = logCount; + PR_LOG( lm, PR_LOG_DEBUG, + ("PR_RecordTraceEntries: LostData segments: %ld", logLostData)); + } + else + { + logCount--; + } + + buf = tBuf + ( logEntriesPerSegment * currentSegment ); + if (++currentSegment >= logSegments ) + currentSegment = 0; + doWrite = PR_TRUE; + } + else + doWrite = PR_FALSE; + + PR_Unlock( logLock ); + + if ( doWrite == PR_TRUE ) + { + if ( localState != LogSuspend ) + WriteTraceSegment( logFile, buf, logSegSize ); + else + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: PR_Write(): is suspended" )); + } + + } /* end while(logState...) */ + + PR_Close( logFile ); + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: exiting")); + return; +} /* end PR_RecordTraceEntries() */ + +/* +** +*/ +PR_IMPLEMENT(PRIntn) + PR_GetTraceEntries( + PRTraceEntry *buffer, /* where to write output */ + PRInt32 count, /* number to get */ + PRInt32 *found /* number you got */ +) +{ + PRInt32 rc; + PRInt32 copied = 0; + + PR_Lock( traceLock ); + + /* + ** Depending on where the LastSeen and Next indices are, + ** copy the trace buffer in one or two pieces. + */ + PR_LOG( lm, PR_LOG_ERROR, + ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen)); + + if ( fetchLastSeen <= next ) + { + while (( count-- > 0 ) && (fetchLastSeen < next )) + { + *(buffer + copied++) = *(tBuf + fetchLastSeen++); + } + PR_LOG( lm, PR_LOG_ERROR, + ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); + } + else /* copy in 2 parts */ + { + while ( count-- > 0 && fetchLastSeen <= last ) + { + *(buffer + copied++) = *(tBuf + fetchLastSeen++); + } + fetchLastSeen = 0; + + PR_LOG( lm, PR_LOG_ERROR, + ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); + + while ( count-- > 0 && fetchLastSeen < next ) + { + *(buffer + copied++) = *(tBuf + fetchLastSeen++); + } + PR_LOG( lm, PR_LOG_ERROR, + ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); + } + + *found = copied; + rc = ( fetchLostData == PR_TRUE )? 1 : 0; + fetchLostData = PR_FALSE; + + PR_Unlock( traceLock ); + return rc; +} /* end PR_GetTraceEntries() */ + +/* end prtrace.c */ diff -Nru nspr-4.9.5/nspr/pr/src/nspr.def nspr-4.10.7/nspr/pr/src/nspr.def --- nspr-4.9.5/nspr/pr/src/nspr.def 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/nspr.def 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,457 @@ +;+# +;+# This Source Code Form is subject to the terms of the Mozilla Public +;+# License, v. 2.0. If a copy of the MPL was not distributed with this +;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. +;+# +;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS +;+# 1. For all unix platforms, the string ";-" means "remove this line" +;+# 2. For all unix platforms, the string " DATA " will be removed from any +;+# line on which it occurs. +;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. +;+# On AIX, lines containing ";+" will be removed. +;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. +;+# 5. For all unix platforms, after the above processing has taken place, +;+# all characters after the first ";" on the line will be removed. +;+# And for AIX, the first ";" will also be removed. +;+# This file is passed directly to windows. Since ';' is a comment, all UNIX +;+# directives are hidden behind ";", ";+", and ";-" +;+# +;+NSPR_4.0 { +;+ global: +LIBRARY nspr4 ;- +EXPORTS ;- + LL_MaxInt; + LL_MinInt; + LL_Zero; + PR_Abort; + PR_AddToCounter; + PR_Accept; + PR_AcceptRead; + PR_Access; + PR_AddWaitFileDesc; + PR_AllocFileDesc; + PR_Assert; + PR_AtomicAdd; + PR_AtomicDecrement; + PR_AtomicIncrement; + PR_AtomicSet; + PR_AttachSharedMemory; + PR_AttachThread; + PR_Available; + PR_Available64; + PR_Bind; + PR_BlockClockInterrupts; + PR_BlockInterrupt; + PR_CEnterMonitor; + PR_CExitMonitor; + PR_CNotify; + PR_CNotifyAll; + PR_CSetOnMonitorRecycle; + PR_CWait; + PR_CallOnce; + PR_Calloc; + PR_CancelJob; + PR_CancelWaitFileDesc; + PR_CancelWaitGroup; + PR_CeilingLog2; + PR_ChangeFileDescNativeHandle; + PR_Cleanup; + PR_ClearInterrupt; + PR_ClearThreadGCAble; + PR_Close; + PR_CloseDir; + PR_CloseFileMap; + PR_CloseSemaphore; + PR_CloseSharedMemory; + PR_Connect; + PR_CreateCounter; + PR_ConvertIPv4AddrToIPv6; + PR_CreateAlarm; + PR_CreateFileMap; + PR_CreateIOLayerStub; + PR_CreateOrderedLock; + PR_CreateMWaitEnumerator; + PR_CreatePipe; + PR_CreateProcess; + PR_CreateProcessDetached; + PR_CreateSocketPollFd; + PR_CreateStack; + PR_CreateThread; + PR_CreateThreadGCAble; + PR_CreateTrace; + PR_CreateThreadPool; + PR_DecrementCounter; + PR_CreateWaitGroup; + PR_Delete; + PR_DeleteSemaphore; + PR_DeleteSharedMemory; + PR_DestroyAlarm; + PR_DestroyCounter; + PR_DestroyCondVar; + PR_DestroyLock; + PR_DestroyMWaitEnumerator; + PR_DestroyOrderedLock; + PR_DestroyMonitor; + PR_DestroyPollableEvent; + PR_DestroyProcessAttr; + PR_DestroyRWLock; + PR_DestroySem; + PR_DestroySocketPollFd; + PR_DestroyTrace; + PR_DestroyStack; + PR_DestroyWaitGroup; + PR_DetachProcess; + PR_DetachSharedMemory; + PR_DetachThread; + PR_DisableClockInterrupts; + PR_EnableClockInterrupts; + PR_EnterMonitor; + PR_EnumerateHostEnt; + PR_EnumerateThreads; + PR_EnumerateWaitGroup; + PR_ErrorInstallCallback; + PR_ErrorInstallTable; + PR_ErrorLanguages; + PR_ErrorToName; + PR_ErrorToString; + PR_ExitMonitor; + PR_ExplodeTime; + PR_ExportFileMapAsString; + PR_FD_CLR; + PR_FD_ISSET; + PR_FD_NCLR; + PR_FD_NISSET; + PR_FD_NSET; + PR_FD_SET; + PR_FD_ZERO; + PR_FileDesc2NativeHandle; + PR_FindSymbol; + PR_FindSymbolAndLibrary; + PR_FloorLog2; + PR_FormatTime; + PR_FindNextCounterQname; + PR_FindNextCounterRname; + PR_FindNextTraceQname; + PR_FindNextTraceRname; + PR_FormatTimeUSEnglish; + PR_Free; + PR_FreeLibraryName; + PR_GMTParameters; + PR_GetConnectStatus; + PR_GetCurrentThread; + PR_GetDefaultIOMethods; + PR_GetDescType; + PR_GetDirectorySeparator; + PR_GetCounter; + PR_GetCounterHandleFromName; + PR_GetCounterNameFromHandle; + PR_GetDirectorySepartor; + PR_GetEnv; + PR_GetError; + PR_GetErrorText; + PR_GetErrorTextLength; + PR_GetFileInfo; + PR_GetFileInfo64; + PR_GetFileMethods; + PR_GetGCRegisters; + PR_GetHostByAddr; + PR_GetHostByName; + PR_GetIPNodeByName; + PR_GetIdentitiesLayer; + PR_GetInheritedFD; + PR_GetInheritedFileMap; + PR_GetLayersIdentity; + PR_GetLibraryName; + PR_GetLibraryPath; + PR_GetMonitorEntryCount; + PR_GetNameForIdentity; + PR_GetOSError; + PR_GetOpenFileInfo; + PR_GetOpenFileInfo64; + PR_GetPageShift; + PR_GetPageSize; + PR_GetPeerName; + PR_GetPipeMethods; + PR_GetProtoByName; + PR_GetProtoByNumber; + PR_GetRandomNoise; + PR_GetSP; + PR_GetSockName; + PR_GetSocketOption; + PR_GetSpecialFD; + PR_GetStackSpaceLeft; + PR_GetSysfdTableMax; + PR_GetSystemInfo; + PR_GetTCPMethods; + PR_GetThreadAffinityMask; + PR_GetThreadID; + PR_GetThreadPriority; + PR_GetThreadPrivate; + PR_GetThreadScope; + PR_GetThreadState; + PR_GetThreadType; + PR_GetUDPMethods; + PR_GetUniqueIdentity; + PR_ImplodeTime; + PR_ImportFile; + PR_ImportFileMapFromString; + PR_ImportTCPSocket; + PR_ImportUDPSocket; + PR_GetTraceEntries; + PR_GetTraceHandleFromName; + PR_GetTraceNameFromHandle; + PR_GetTraceOption; + PR_Init; + PR_Initialize; + PR_InitializeNetAddr; + PR_Initialized; + PR_Interrupt; + PR_IntervalNow; + PR_IntervalToMicroseconds; + PR_IntervalToMilliseconds; + PR_IncrementCounter; + PR_IntervalToSeconds; + PR_IsNetAddrType; + PR_JoinJob; + PR_JoinThread; + PR_JoinThreadPool; + PR_KillProcess; + PR_Listen; + PR_LoadLibrary; + PR_LoadLibraryWithFlags; + PR_LoadStaticLibrary; + PR_LocalTimeParameters; + PR_Lock; + PR_LockFile; + PR_LogFlush; + PR_LogPrint; + PR_MakeDir; + PR_Malloc; + PR_MemMap; + PR_MemUnmap; + PR_MicrosecondsToInterval; + PR_MillisecondsToInterval; + PR_LockOrderedLock; + PR_MkDir; + PR_NetAddrToString; + PR_NewCondVar; + PR_NewLock; + PR_NewLogModule; + PR_NewMonitor; + PR_NewNamedMonitor; + PR_NewPollableEvent; + PR_NewProcessAttr; + PR_NewRWLock; + PR_NewSem; + PR_NewTCPSocket; + PR_NewTCPSocketPair; + PR_NewThreadPrivateIndex; + PR_NewUDPSocket; + PR_NormalizeTime; + PR_Notify; + PR_NotifyAll; + PR_NotifyAllCondVar; + PR_NotifyCondVar; + PR_Now; + PR_Open; + PR_OpenAnonFileMap; + PR_OpenDir; + PR_OpenFile; + PR_OpenSemaphore; + PR_OpenSharedMemory; + PR_OpenTCPSocket; + PR_OpenUDPSocket; + PR_ParseTimeString; + PR_Poll; + PR_PopIOLayer; + PR_PostSem; + PR_PostSemaphore; + PR_ProcessAttrSetCurrentDirectory; + PR_ProcessAttrSetInheritableFD; + PR_ProcessAttrSetInheritableFileMap; + PR_ProcessAttrSetStdioRedirect; + PR_ProcessExit; + PR_PushIOLayer; + PR_QueueJob; + PR_QueueJob_Accept; + PR_QueueJob_Connect; + PR_QueueJob_Read; + PR_QueueJob_Timer; + PR_QueueJob_Write; + PR_RWLock_Rlock; + PR_RWLock_Unlock; + PR_RWLock_Wlock; + PR_Read; + PR_ReadDir; + PR_Realloc; + PR_Recv; + PR_RecvFrom; + PR_Rename; + PR_ResetAlarm; + PR_ResetProcessAttr; + PR_ResumeAll; + PR_RmDir; + PR_ScanStackPointers; + PR_RecordTraceEntries; + PR_SecondsToInterval; + PR_Seek; + PR_Seek64; + PR_Select; + PR_Send; + PR_SendFile; + PR_SendTo; + PR_SetAlarm; + PR_SetConcurrency; + PR_SetError; + PR_SetErrorText; + PR_SetFDCacheSize; + PR_SetFDInheritable; + PR_SetLibraryPath; + PR_SetLogBuffering; + PR_SetLogFile; + PR_SetNetAddr; + PR_SetPollableEvent; + PR_SetSocketOption; + PR_SetCounter; + PR_SetStdioRedirect; + PR_SetSysfdTableSize; + PR_SetThreadAffinityMask; + PR_SetThreadDumpProc; + PR_SetThreadGCAble; + PR_SetThreadPriority; + PR_SetThreadPrivate; + PR_SetThreadRecycleMode; + PR_Shutdown; + PR_ShutdownThreadPool; + PR_Sleep; + PR_Socket; + PR_StackPop; + PR_StackPush; + PR_Stat; + PR_StringToNetAddr; + PR_SuspendAll; + PR_Sync; + PR_TLockFile; + PR_ThreadScanStackPointers; + PR_SetTraceOption; + PR_TicksPerSecond; + PR_TransmitFile; + PR_USPacificTimeParameters; + PR_UnblockClockInterrupts; + PR_UnblockInterrupt; + PR_UnloadLibrary; + PR_SubtractFromCounter; + PR_Unlock; + PR_UnlockFile; + PR_VersionCheck; + PR_Wait; + PR_WaitCondVar; + PR_WaitForPollableEvent; + PR_Trace; + PR_WaitProcess; + PR_WaitRecvReady; + PR_WaitSem; + PR_WaitSemaphore; + PR_Write; + PR_Writev; + PR_Yield; + PR_UnlockOrderedLock; + PR_cnvtf; + PR_dtoa; + PR_fprintf; + PR_htonl; + PR_htonll; + PR_htons; + PR_ntohl; + PR_ntohll; + PR_ntohs; + PR_smprintf; + PR_smprintf_free; + PR_snprintf; + PR_sprintf_append; + PR_sscanf; + PR_strtod; + PR_sxprintf; + PR_vfprintf; + PR_vsmprintf; + PR_vsnprintf; + PR_vsprintf_append; + PR_vsxprintf; + PRP_DestroyNakedCondVar; + PRP_NakedBroadcast; + PRP_NakedNotify; + PRP_NakedWait; + PRP_NewNakedCondVar; + PRP_TryLock; + libVersionPoint; +;+ local: *; +;+}; +;+ +;+NSPRprivate { +;+ global: + GetExecutionEnvironment; + PT_FPrintStats; + SetExecutionEnvironment; +;+ local: *; +;+}; +;+ +;+NSPR_4.1 { +;+ global: + PR_ConnectContinue; + PR_CreateIOLayer; + PR_EmulateAcceptRead; + PR_EmulateSendFile; + PR_FindFunctionSymbol; + PR_FindFunctionSymbolAndLibrary; + PR_GetMemMapAlignment; + PR_GetNumberOfProcessors; + PR_ImportPipe; + PR_SetEnv; +;+} NSPR_4.0; +;+ +;+NSPR_4.3 { +;+ global: + LL_MaxUint; + PR_CallOnceWithArg; + PR_GetLibraryFilePathname; +;+} NSPR_4.1; +;+ +;+NSPR_4.4 { +;+ global: + PR_GetPathSeparator; +;+} NSPR_4.3; +;+ +;+NSPR_4.5 { +;+ global: + PR_EnumerateAddrInfo; + PR_FreeAddrInfo; + PR_GetAddrInfoByName; + PR_GetCanonNameFromAddrInfo; +;+} NSPR_4.4; +;+ +;+NSPR_4.6 { +;+ global: + PR_GetPhysicalMemorySize; +;+} NSPR_4.5; +;+NSPR_4.7 { +;+ global: + PR_ParseTimeStringToExplodedTime; +;+} NSPR_4.6; +;+NSPR_4.8 { +;+ global: + PR_AssertCurrentThreadOwnsLock; + PR_AssertCurrentThreadInMonitor; +;+} NSPR_4.7; +;+NSPR_4.8.9 { +;+ global: + PR_GetVersion; +;+} NSPR_4.8; +;+NSPR_4.9.2 { +;+ global: + PR_GetThreadName; + PR_SetCurrentThreadName; +;+} NSPR_4.8.9; +;+NSPR_4.10.3 { +;+ global: + PR_SyncMemMap; +;+} NSPR_4.9.2; diff -Nru nspr-4.9.5/nspr/pr/src/nspr.rc nspr-4.10.7/nspr/pr/src/nspr.rc --- nspr-4.9.5/nspr/pr/src/nspr.rc 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/nspr.rc 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include + +#define MY_LIBNAME "nspr" +#define MY_FILEDESCRIPTION "NSPR Library" + +#define STRINGIZE(x) #x +#define STRINGIZE2(x) STRINGIZE(x) +#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR) + +#ifdef _DEBUG +#define MY_DEBUG_STR " (debug)" +#define MY_FILEFLAGS_1 VS_FF_DEBUG +#else +#define MY_DEBUG_STR "" +#define MY_FILEFLAGS_1 0x0L +#endif +#if PR_BETA +#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE +#else +#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 +#endif + +#ifdef WINNT +#define MY_FILEOS VOS_NT_WINDOWS32 +#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR +#else +#define MY_FILEOS VOS__WINDOWS32 +#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Version-information resource +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 + PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS MY_FILEFLAGS_2 + FILEOS MY_FILEOS + FILETYPE VFT_DLL + FILESUBTYPE 0x0L // not used + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" // Lang=US English, CharSet=Unicode + BEGIN + VALUE "CompanyName", "Mozilla Foundation\0" + VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" + VALUE "FileVersion", PR_VERSION "\0" + VALUE "InternalName", MY_INTERNAL_NAME "\0" + VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" + VALUE "ProductName", "Netscape Portable Runtime\0" + VALUE "ProductVersion", PR_VERSION "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff -Nru nspr-4.9.5/nspr/pr/src/os2extra.def nspr-4.10.7/nspr/pr/src/os2extra.def --- nspr-4.9.5/nspr/pr/src/os2extra.def 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/os2extra.def 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,20 @@ +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. + + ; + ; Support plugins that were explicitly linked to the Visual Age + ; version of nspr4.dll. + ; + PR_NewMonitor + PR_EnterMonitor + PR_ExitMonitor + PR_GetCurrentThread + PR_AttachThread + PR_DetachThread + ; + ; Exception handler functions that are used by nsAppRunner.cpp + ; + _PR_OS2_SetFloatExcpHandler + _PR_OS2_UnsetFloatExcpHandler + diff -Nru nspr-4.9.5/nspr/pr/src/prvrsion.c nspr-4.10.7/nspr/pr/src/prvrsion.c --- nspr-4.9.5/nspr/pr/src/prvrsion.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/prvrsion.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include "prvrsion.h" + +/************************************************************************/ +/**************************IDENTITY AND VERSIONING***********************/ +/************************************************************************/ +#include "_pr_bld.h" +#if !defined(_BUILD_TIME) +#ifdef HAVE_LONG_LONG +#define _BUILD_TIME 0 +#else +#define _BUILD_TIME {0, 0} +#endif +#endif +#if !defined(_BUILD_STRING) +#define _BUILD_STRING "" +#endif +#if !defined(_PRODUCTION) +#define _PRODUCTION "" +#endif +#if defined(DEBUG) +#define _DEBUG_STRING " (debug)" +#else +#define _DEBUG_STRING "" +#endif + +/* + * A trick to expand the PR_VMAJOR macro before concatenation. + */ +#define CONCAT(x, y) x ## y +#define CONCAT2(x, y) CONCAT(x, y) +#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libnspr, PR_VMAJOR) + +PRVersionDescription VERSION_DESC_NAME = +{ + /* version */ 2, /* this is the only one supported */ + /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */ + /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */ + /* vMajor */ PR_VMAJOR, /* NSPR's version number */ + /* vMinor */ PR_VMINOR, /* and minor version */ + /* vPatch */ PR_VPATCH, /* and patch */ + /* beta */ PR_BETA, /* beta build boolean */ +#if defined(DEBUG) + /* debug */ PR_TRUE, /* a debug build */ +#else + /* debug */ PR_FALSE, /* an optomized build */ +#endif + /* special */ PR_FALSE, /* they're all special, but ... */ + /* filename */ _PRODUCTION, /* the produced library name */ + /* description */ "Portable runtime", /* what we are */ + /* security */ "N/A", /* not applicable here */ + /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved", + /* comment */ "License information: http://www.mozilla.org/MPL/", + /* specialString */ "" +}; + +#ifdef XP_UNIX + +/* + * Version information for the 'ident' and 'what commands + * + * NOTE: the first component of the concatenated rcsid string + * must not end in a '$' to prevent rcs keyword substitution. + */ +static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING + " " _BUILD_STRING " $"; +static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING + " " _BUILD_STRING; + +#endif /* XP_UNIX */ + +PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void) +{ +#ifdef XP_UNIX + /* + * Add dummy references to rcsid and sccsid to prevent them + * from being optimized away as unused variables. + */ + const char *dummy; + + dummy = rcsid; + dummy = sccsid; +#endif + return &VERSION_DESC_NAME; +} /* versionEntryPointType */ + +/* prvrsion.c */ + diff -Nru nspr-4.9.5/nspr/pr/src/pthreads/.cvsignore nspr-4.10.7/nspr/pr/src/pthreads/.cvsignore --- nspr-4.9.5/nspr/pr/src/pthreads/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/pthreads/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/pthreads/Makefile.in nspr-4.10.7/nspr/pr/src/pthreads/Makefile.in --- nspr-4.9.5/nspr/pr/src/pthreads/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/pthreads/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,35 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CSRCS = \ + ptio.c \ + ptsynch.c \ + ptthread.c \ + ptmisc.c \ + $(NULL) + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + + diff -Nru nspr-4.9.5/nspr/pr/src/pthreads/ptio.c nspr-4.10.7/nspr/pr/src/pthreads/ptio.c --- nspr-4.9.5/nspr/pr/src/pthreads/ptio.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/pthreads/ptio.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,5012 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: ptio.c +** Descritpion: Implemenation of I/O methods for pthreads +*/ + +#if defined(_PR_PTHREADS) + +#if defined(_PR_POLL_WITH_SELECT) +#if !(defined(HPUX) && defined(_USE_BIG_FDS)) +/* set fd limit for select(), before including system header files */ +#define FD_SETSIZE (16 * 1024) +#endif +#endif + +#include +#include /* for memset() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(DARWIN) +#include /* for uname */ +#endif +#if defined(SOLARIS) || defined(UNIXWARE) +#include /* to pick up FIONREAD */ +#endif +#ifdef _PR_POLL_AVAILABLE +#include +#endif +#ifdef AIX +/* To pick up sysconf() */ +#include +#include /* for dlopen */ +#else +/* To pick up getrlimit() etc. */ +#include +#include +#endif + +#ifdef SOLARIS +/* + * Define HAVE_SENDFILEV if the system has the sendfilev() system call. + * Code built this way won't run on a system without sendfilev(). + * We can define HAVE_SENDFILEV by default when the minimum release + * of Solaris that NSPR supports has sendfilev(). + */ +#ifdef HAVE_SENDFILEV + +#include + +#define SOLARIS_SENDFILEV(a, b, c, d) sendfilev((a), (b), (c), (d)) + +#else + +#include /* for dlopen */ + +/* + * Match the definitions in . + */ +typedef struct sendfilevec { + int sfv_fd; /* input fd */ + uint_t sfv_flag; /* flags */ + off_t sfv_off; /* offset to start reading from */ + size_t sfv_len; /* amount of data */ +} sendfilevec_t; + +#define SFV_FD_SELF (-2) + +/* + * extern ssize_t sendfilev(int, const struct sendfilevec *, int, size_t *); + */ +static ssize_t (*pt_solaris_sendfilev_fptr)() = NULL; + +#define SOLARIS_SENDFILEV(a, b, c, d) \ + (*pt_solaris_sendfilev_fptr)((a), (b), (c), (d)) + +#endif /* HAVE_SENDFILEV */ +#endif /* SOLARIS */ + +/* + * The send_file() system call is available in AIX 4.3.2 or later. + * If this file is compiled on an older AIX system, it attempts to + * look up the send_file symbol at run time to determine whether + * we can use the faster PR_SendFile/PR_TransmitFile implementation based on + * send_file(). On AIX 4.3.2 or later, we can safely skip this + * runtime function dispatching and just use the send_file based + * implementation. + */ +#ifdef AIX +#ifdef SF_CLOSE +#define HAVE_SEND_FILE +#endif + +#ifdef HAVE_SEND_FILE + +#define AIX_SEND_FILE(a, b, c) send_file(a, b, c) + +#else /* HAVE_SEND_FILE */ + +/* + * The following definitions match those in + * on AIX 4.3.2. + */ + +/* + * Structure for the send_file() system call + */ +struct sf_parms { + /* --------- header parms ---------- */ + void *header_data; /* Input/Output. Points to header buf */ + uint_t header_length; /* Input/Output. Length of the header */ + /* --------- file parms ------------ */ + int file_descriptor; /* Input. File descriptor of the file */ + unsigned long long file_size; /* Output. Size of the file */ + unsigned long long file_offset; /* Input/Output. Starting offset */ + long long file_bytes; /* Input/Output. no. of bytes to send */ + /* --------- trailer parms --------- */ + void *trailer_data; /* Input/Output. Points to trailer buf */ + uint_t trailer_length; /* Input/Output. Length of the trailer */ + /* --------- return info ----------- */ + unsigned long long bytes_sent; /* Output. no. of bytes sent */ +}; + +/* + * Flags for the send_file() system call + */ +#define SF_CLOSE 0x00000001 /* close the socket after completion */ +#define SF_REUSE 0x00000002 /* reuse socket. not supported */ +#define SF_DONT_CACHE 0x00000004 /* don't apply network buffer cache */ +#define SF_SYNC_CACHE 0x00000008 /* sync/update network buffer cache */ + +/* + * prototype: size_t send_file(int *, struct sf_parms *, uint_t); + */ +static ssize_t (*pt_aix_sendfile_fptr)() = NULL; + +#define AIX_SEND_FILE(a, b, c) (*pt_aix_sendfile_fptr)(a, b, c) + +#endif /* HAVE_SEND_FILE */ +#endif /* AIX */ + +#ifdef LINUX +#include +#endif + +#include "primpl.h" + +#ifdef HAVE_NETINET_TCP_H +#include /* TCP_NODELAY, TCP_MAXSEG */ +#endif + +#ifdef LINUX +/* TCP_CORK is not defined in on Red Hat Linux 6.0 */ +#ifndef TCP_CORK +#define TCP_CORK 3 +#endif +#endif + +#ifdef _PR_IPV6_V6ONLY_PROBE +static PRBool _pr_ipv6_v6only_on_by_default; +#endif + +#if (defined(HPUX) && !defined(HPUX10_30) && !defined(HPUX11)) +#define _PRSelectFdSetArg_t int * +#elif defined(AIX4_1) +#define _PRSelectFdSetArg_t void * +#elif defined(IRIX) || (defined(AIX) && !defined(AIX4_1)) \ + || defined(OSF1) || defined(SOLARIS) \ + || defined(HPUX10_30) || defined(HPUX11) \ + || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ + || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \ + || defined(BSDI) || defined(NTO) || defined(DARWIN) \ + || defined(UNIXWARE) || defined(RISCOS) || defined(SYMBIAN) +#define _PRSelectFdSetArg_t fd_set * +#else +#error "Cannot determine architecture" +#endif + +#if defined(SOLARIS) +#ifndef PROTO_SDP +/* on solaris, SDP is a new type of protocol */ +#define PROTO_SDP 257 +#endif +#define _PR_HAVE_SDP +#elif defined(LINUX) +#ifndef AF_INET_SDP +/* on linux, SDP is a new type of address family */ +#define AF_INET_SDP 27 +#endif +#define _PR_HAVE_SDP +#endif /* LINUX */ + +static PRFileDesc *pt_SetMethods( + PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported); + +static PRLock *_pr_flock_lock; /* For PR_LockFile() etc. */ +static PRCondVar *_pr_flock_cv; /* For PR_LockFile() etc. */ +static PRLock *_pr_rename_lock; /* For PR_Rename() */ + +/**************************************************************************/ + +/* These two functions are only used in assertions. */ +#if defined(DEBUG) + +PRBool IsValidNetAddr(const PRNetAddr *addr) +{ + if ((addr != NULL) + && (addr->raw.family != AF_UNIX) + && (addr->raw.family != PR_AF_INET6) + && (addr->raw.family != AF_INET)) { + return PR_FALSE; + } + return PR_TRUE; +} + +static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len) +{ + /* + * The definition of the length of a Unix domain socket address + * is not uniform, so we don't check it. + */ + if ((addr != NULL) + && (addr->raw.family != AF_UNIX) + && (PR_NETADDR_SIZE(addr) != addr_len)) { +#if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1 + /* + * In glibc 2.1, struct sockaddr_in6 is 24 bytes. In glibc 2.2 + * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id + * field and is 28 bytes. It is possible for socket functions + * to return an addr_len greater than sizeof(struct sockaddr_in6). + * We need to allow that. (Bugzilla bug #77264) + */ + if ((PR_AF_INET6 == addr->raw.family) + && (sizeof(addr->ipv6) == addr_len)) { + return PR_TRUE; + } +#endif + return PR_FALSE; + } + return PR_TRUE; +} + +#endif /* DEBUG */ + +/*****************************************************************************/ +/************************* I/O Continuation machinery ************************/ +/*****************************************************************************/ + +/* + * The polling interval defines the maximum amount of time that a thread + * might hang up before an interrupt is noticed. + */ +#define PT_DEFAULT_POLL_MSEC 5000 +#if defined(_PR_POLL_WITH_SELECT) +#define PT_DEFAULT_SELECT_SEC (PT_DEFAULT_POLL_MSEC/PR_MSEC_PER_SEC) +#define PT_DEFAULT_SELECT_USEC \ + ((PT_DEFAULT_POLL_MSEC % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC) +#endif + +/* + * pt_SockLen is the type for the length of a socket address + * structure, used in the address length argument to bind, + * connect, accept, getsockname, getpeername, etc. Posix.1g + * defines this type as socklen_t. It is size_t or int on + * most current systems. + */ +#if defined(HAVE_SOCKLEN_T) \ + || (defined(__GLIBC__) && __GLIBC__ >= 2) +typedef socklen_t pt_SockLen; +#elif (defined(AIX) && !defined(AIX4_1)) +typedef PRSize pt_SockLen; +#else +typedef PRIntn pt_SockLen; +#endif + +typedef struct pt_Continuation pt_Continuation; +typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revents); + +typedef enum pr_ContuationStatus +{ + pt_continuation_pending, + pt_continuation_done +} pr_ContuationStatus; + +struct pt_Continuation +{ + /* The building of the continuation operation */ + ContinuationFn function; /* what function to continue */ + union { PRIntn osfd; } arg1; /* #1 - the op's fd */ + union { void* buffer; } arg2; /* #2 - primary transfer buffer */ + union { + PRSize amount; /* #3 - size of 'buffer', or */ + pt_SockLen *addr_len; /* - length of address */ +#ifdef HPUX11 + /* + * For sendfile() + */ + struct file_spec { + off_t offset; /* offset in file to send */ + size_t nbytes; /* length of file data to send */ + size_t st_size; /* file size */ + } file_spec; +#endif + } arg3; + union { PRIntn flags; } arg4; /* #4 - read/write flags */ + union { PRNetAddr *addr; } arg5; /* #5 - send/recv address */ + +#ifdef HPUX11 + /* + * For sendfile() + */ + int filedesc; /* descriptor of file to send */ + int nbytes_to_send; /* size of header and file */ +#endif /* HPUX11 */ + +#ifdef SOLARIS + /* + * For sendfilev() + */ + int nbytes_to_send; /* size of header and file */ +#endif /* SOLARIS */ + +#ifdef LINUX + /* + * For sendfile() + */ + int in_fd; /* descriptor of file to send */ + off_t offset; + size_t count; +#endif /* LINUX */ + + PRIntervalTime timeout; /* client (relative) timeout */ + + PRInt16 event; /* flags for poll()'s events */ + + /* + ** The representation and notification of the results of the operation. + ** These function can either return an int return code or a pointer to + ** some object. + */ + union { PRSize code; void *object; } result; + + PRIntn syserrno; /* in case it failed, why (errno) */ + pr_ContuationStatus status; /* the status of the operation */ +}; + +#if defined(DEBUG) + +PTDebug pt_debug; /* this is shared between several modules */ + +PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) +{ + PTDebug stats; + char buffer[100]; + PRExplodedTime tod; + PRInt64 elapsed, aMil; + stats = pt_debug; /* a copy */ + PR_ExplodeTime(stats.timeStarted, PR_LocalTimeParameters, &tod); + (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod); + + LL_SUB(elapsed, PR_Now(), stats.timeStarted); + LL_I2L(aMil, 1000000); + LL_DIV(elapsed, elapsed, aMil); + + if (NULL != msg) PR_fprintf(debug_out, "%s", msg); + PR_fprintf( + debug_out, "\tstarted: %s[%lld]\n", buffer, elapsed); + PR_fprintf( + debug_out, "\tlocks [created: %u, destroyed: %u]\n", + stats.locks_created, stats.locks_destroyed); + PR_fprintf( + debug_out, "\tlocks [acquired: %u, released: %u]\n", + stats.locks_acquired, stats.locks_released); + PR_fprintf( + debug_out, "\tcvars [created: %u, destroyed: %u]\n", + stats.cvars_created, stats.cvars_destroyed); + PR_fprintf( + debug_out, "\tcvars [notified: %u, delayed_delete: %u]\n", + stats.cvars_notified, stats.delayed_cv_deletes); +} /* PT_FPrintStats */ + +#else + +PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) +{ + /* do nothing */ +} /* PT_FPrintStats */ + +#endif /* DEBUG */ + +#if defined(_PR_POLL_WITH_SELECT) +/* + * OSF1 and HPUX report the POLLHUP event for a socket when the + * shutdown(SHUT_WR) operation is called for the remote end, even though + * the socket is still writeable. Use select(), instead of poll(), to + * workaround this problem. + */ +static void pt_poll_now_with_select(pt_Continuation *op) +{ + PRInt32 msecs; + fd_set rd, wr, *rdp, *wrp; + struct timeval tv; + PRIntervalTime epoch, now, elapsed, remaining; + PRBool wait_for_remaining; + PRThread *self = PR_GetCurrentThread(); + + PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout); + PR_ASSERT(op->arg1.osfd < FD_SETSIZE); + + switch (op->timeout) { + case PR_INTERVAL_NO_TIMEOUT: + tv.tv_sec = PT_DEFAULT_SELECT_SEC; + tv.tv_usec = PT_DEFAULT_SELECT_USEC; + do + { + PRIntn rv; + + if (op->event & POLLIN) { + FD_ZERO(&rd); + FD_SET(op->arg1.osfd, &rd); + rdp = &rd; + } else + rdp = NULL; + if (op->event & POLLOUT) { + FD_ZERO(&wr); + FD_SET(op->arg1.osfd, &wr); + wrp = ≀ + } else + wrp = NULL; + + rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv); + + if (_PT_THREAD_INTERRUPTED(self)) + { + self->state &= ~PT_THREAD_ABORTED; + op->result.code = -1; + op->syserrno = EINTR; + op->status = pt_continuation_done; + return; + } + + if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN))) + continue; /* go around the loop again */ + + if (rv > 0) + { + PRInt16 revents = 0; + + if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd)) + revents |= POLLIN; + if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr)) + revents |= POLLOUT; + + if (op->function(op, revents)) + op->status = pt_continuation_done; + } else if (rv == -1) { + op->result.code = -1; + op->syserrno = errno; + op->status = pt_continuation_done; + } + /* else, select timed out */ + } while (pt_continuation_done != op->status); + break; + default: + now = epoch = PR_IntervalNow(); + remaining = op->timeout; + do + { + PRIntn rv; + + if (op->event & POLLIN) { + FD_ZERO(&rd); + FD_SET(op->arg1.osfd, &rd); + rdp = &rd; + } else + rdp = NULL; + if (op->event & POLLOUT) { + FD_ZERO(&wr); + FD_SET(op->arg1.osfd, &wr); + wrp = ≀ + } else + wrp = NULL; + + wait_for_remaining = PR_TRUE; + msecs = (PRInt32)PR_IntervalToMilliseconds(remaining); + if (msecs > PT_DEFAULT_POLL_MSEC) { + wait_for_remaining = PR_FALSE; + msecs = PT_DEFAULT_POLL_MSEC; + } + tv.tv_sec = msecs/PR_MSEC_PER_SEC; + tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC; + rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv); + + if (_PT_THREAD_INTERRUPTED(self)) + { + self->state &= ~PT_THREAD_ABORTED; + op->result.code = -1; + op->syserrno = EINTR; + op->status = pt_continuation_done; + return; + } + + if (rv > 0) { + PRInt16 revents = 0; + + if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd)) + revents |= POLLIN; + if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr)) + revents |= POLLOUT; + + if (op->function(op, revents)) + op->status = pt_continuation_done; + + } else if ((rv == 0) || + ((errno == EINTR) || (errno == EAGAIN))) { + if (rv == 0) { /* select timed out */ + if (wait_for_remaining) + now += remaining; + else + now += PR_MillisecondsToInterval(msecs); + } else + now = PR_IntervalNow(); + elapsed = (PRIntervalTime) (now - epoch); + if (elapsed >= op->timeout) { + op->result.code = -1; + op->syserrno = ETIMEDOUT; + op->status = pt_continuation_done; + } else + remaining = op->timeout - elapsed; + } else { + op->result.code = -1; + op->syserrno = errno; + op->status = pt_continuation_done; + } + } while (pt_continuation_done != op->status); + break; + } + +} /* pt_poll_now_with_select */ + +#endif /* _PR_POLL_WITH_SELECT */ + +static void pt_poll_now(pt_Continuation *op) +{ + PRInt32 msecs; + PRIntervalTime epoch, now, elapsed, remaining; + PRBool wait_for_remaining; + PRThread *self = PR_GetCurrentThread(); + + PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout); +#if defined (_PR_POLL_WITH_SELECT) + /* + * If the fd is small enough call the select-based poll operation + */ + if (op->arg1.osfd < FD_SETSIZE) { + pt_poll_now_with_select(op); + return; + } +#endif + + switch (op->timeout) { + case PR_INTERVAL_NO_TIMEOUT: + msecs = PT_DEFAULT_POLL_MSEC; + do + { + PRIntn rv; + struct pollfd tmp_pfd; + + tmp_pfd.revents = 0; + tmp_pfd.fd = op->arg1.osfd; + tmp_pfd.events = op->event; + + rv = poll(&tmp_pfd, 1, msecs); + + if (_PT_THREAD_INTERRUPTED(self)) + { + self->state &= ~PT_THREAD_ABORTED; + op->result.code = -1; + op->syserrno = EINTR; + op->status = pt_continuation_done; + return; + } + + if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN))) + continue; /* go around the loop again */ + + if (rv > 0) + { + PRInt16 events = tmp_pfd.events; + PRInt16 revents = tmp_pfd.revents; + + if ((revents & POLLNVAL) /* busted in all cases */ + || ((events & POLLOUT) && (revents & POLLHUP))) + /* write op & hup */ + { + op->result.code = -1; + if (POLLNVAL & revents) op->syserrno = EBADF; + else if (POLLHUP & revents) op->syserrno = EPIPE; + op->status = pt_continuation_done; + } else { + if (op->function(op, revents)) + op->status = pt_continuation_done; + } + } else if (rv == -1) { + op->result.code = -1; + op->syserrno = errno; + op->status = pt_continuation_done; + } + /* else, poll timed out */ + } while (pt_continuation_done != op->status); + break; + default: + now = epoch = PR_IntervalNow(); + remaining = op->timeout; + do + { + PRIntn rv; + struct pollfd tmp_pfd; + + tmp_pfd.revents = 0; + tmp_pfd.fd = op->arg1.osfd; + tmp_pfd.events = op->event; + + wait_for_remaining = PR_TRUE; + msecs = (PRInt32)PR_IntervalToMilliseconds(remaining); + if (msecs > PT_DEFAULT_POLL_MSEC) + { + wait_for_remaining = PR_FALSE; + msecs = PT_DEFAULT_POLL_MSEC; + } + rv = poll(&tmp_pfd, 1, msecs); + + if (_PT_THREAD_INTERRUPTED(self)) + { + self->state &= ~PT_THREAD_ABORTED; + op->result.code = -1; + op->syserrno = EINTR; + op->status = pt_continuation_done; + return; + } + + if (rv > 0) + { + PRInt16 events = tmp_pfd.events; + PRInt16 revents = tmp_pfd.revents; + + if ((revents & POLLNVAL) /* busted in all cases */ + || ((events & POLLOUT) && (revents & POLLHUP))) + /* write op & hup */ + { + op->result.code = -1; + if (POLLNVAL & revents) op->syserrno = EBADF; + else if (POLLHUP & revents) op->syserrno = EPIPE; + op->status = pt_continuation_done; + } else { + if (op->function(op, revents)) + { + op->status = pt_continuation_done; + } + } + } else if ((rv == 0) || + ((errno == EINTR) || (errno == EAGAIN))) { + if (rv == 0) /* poll timed out */ + { + if (wait_for_remaining) + now += remaining; + else + now += PR_MillisecondsToInterval(msecs); + } + else + now = PR_IntervalNow(); + elapsed = (PRIntervalTime) (now - epoch); + if (elapsed >= op->timeout) { + op->result.code = -1; + op->syserrno = ETIMEDOUT; + op->status = pt_continuation_done; + } else + remaining = op->timeout - elapsed; + } else { + op->result.code = -1; + op->syserrno = errno; + op->status = pt_continuation_done; + } + } while (pt_continuation_done != op->status); + break; + } + +} /* pt_poll_now */ + +static PRIntn pt_Continue(pt_Continuation *op) +{ + op->status = pt_continuation_pending; /* set default value */ + /* + * let each thread call poll directly + */ + pt_poll_now(op); + PR_ASSERT(pt_continuation_done == op->status); + return op->result.code; +} /* pt_Continue */ + +/*****************************************************************************/ +/*********************** specific continuation functions *********************/ +/*****************************************************************************/ +static PRBool pt_connect_cont(pt_Continuation *op, PRInt16 revents) +{ + op->syserrno = _MD_unix_get_nonblocking_connect_error(op->arg1.osfd); + if (op->syserrno != 0) { + op->result.code = -1; + } else { + op->result.code = 0; + } + return PR_TRUE; /* this one is cooked */ +} /* pt_connect_cont */ + +static PRBool pt_accept_cont(pt_Continuation *op, PRInt16 revents) +{ + op->syserrno = 0; + op->result.code = accept( + op->arg1.osfd, op->arg2.buffer, op->arg3.addr_len); + if (-1 == op->result.code) + { + op->syserrno = errno; + if (EWOULDBLOCK == errno || EAGAIN == errno || ECONNABORTED == errno) + return PR_FALSE; /* do nothing - this one ain't finished */ + } + return PR_TRUE; +} /* pt_accept_cont */ + +static PRBool pt_read_cont(pt_Continuation *op, PRInt16 revents) +{ + /* + * Any number of bytes will complete the operation. It need + * not (and probably will not) satisfy the request. The only + * error we continue is EWOULDBLOCK|EAGAIN. + */ + op->result.code = read( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount); + op->syserrno = errno; + return ((-1 == op->result.code) && + (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ? + PR_FALSE : PR_TRUE; +} /* pt_read_cont */ + +static PRBool pt_recv_cont(pt_Continuation *op, PRInt16 revents) +{ + /* + * Any number of bytes will complete the operation. It need + * not (and probably will not) satisfy the request. The only + * error we continue is EWOULDBLOCK|EAGAIN. + */ +#if defined(SOLARIS) + if (0 == op->arg4.flags) + op->result.code = read( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount); + else + op->result.code = recv( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags); +#else + op->result.code = recv( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags); +#endif + op->syserrno = errno; + return ((-1 == op->result.code) && + (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ? + PR_FALSE : PR_TRUE; +} /* pt_recv_cont */ + +static PRBool pt_send_cont(pt_Continuation *op, PRInt16 revents) +{ + PRIntn bytes; +#if defined(SOLARIS) + PRInt32 tmp_amount = op->arg3.amount; +#endif + /* + * We want to write the entire amount out, no matter how many + * tries it takes. Keep advancing the buffer and the decrementing + * the amount until the amount goes away. Return the total bytes + * (which should be the original amount) when finished (or an + * error). + */ +#if defined(SOLARIS) +retry: + bytes = write(op->arg1.osfd, op->arg2.buffer, tmp_amount); +#else + bytes = send( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags); +#endif + op->syserrno = errno; + +#if defined(SOLARIS) + /* + * The write system call has been reported to return the ERANGE error + * on occasion. Try to write in smaller chunks to workaround this bug. + */ + if ((bytes == -1) && (op->syserrno == ERANGE)) + { + if (tmp_amount > 1) + { + tmp_amount = tmp_amount/2; /* half the bytes */ + goto retry; + } + } +#endif + + if (bytes >= 0) /* this is progress */ + { + char *bp = (char*)op->arg2.buffer; + bp += bytes; /* adjust the buffer pointer */ + op->arg2.buffer = bp; + op->result.code += bytes; /* accumulate the number sent */ + op->arg3.amount -= bytes; /* and reduce the required count */ + return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; + } + else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno)) + { + op->result.code = -1; + return PR_TRUE; + } + else return PR_FALSE; +} /* pt_send_cont */ + +static PRBool pt_write_cont(pt_Continuation *op, PRInt16 revents) +{ + PRIntn bytes; + /* + * We want to write the entire amount out, no matter how many + * tries it takes. Keep advancing the buffer and the decrementing + * the amount until the amount goes away. Return the total bytes + * (which should be the original amount) when finished (or an + * error). + */ + bytes = write(op->arg1.osfd, op->arg2.buffer, op->arg3.amount); + op->syserrno = errno; + if (bytes >= 0) /* this is progress */ + { + char *bp = (char*)op->arg2.buffer; + bp += bytes; /* adjust the buffer pointer */ + op->arg2.buffer = bp; + op->result.code += bytes; /* accumulate the number sent */ + op->arg3.amount -= bytes; /* and reduce the required count */ + return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; + } + else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno)) + { + op->result.code = -1; + return PR_TRUE; + } + else return PR_FALSE; +} /* pt_write_cont */ + +static PRBool pt_writev_cont(pt_Continuation *op, PRInt16 revents) +{ + PRIntn bytes; + struct iovec *iov = (struct iovec*)op->arg2.buffer; + /* + * Same rules as write, but continuing seems to be a bit more + * complicated. As the number of bytes sent grows, we have to + * redefine the vector we're pointing at. We might have to + * modify an individual vector parms or we might have to eliminate + * a pair altogether. + */ + bytes = writev(op->arg1.osfd, iov, op->arg3.amount); + op->syserrno = errno; + if (bytes >= 0) /* this is progress */ + { + PRIntn iov_index; + op->result.code += bytes; /* accumulate the number sent */ + for (iov_index = 0; iov_index < op->arg3.amount; ++iov_index) + { + /* how much progress did we make in the i/o vector? */ + if (bytes < iov[iov_index].iov_len) + { + /* this element's not done yet */ + char **bp = (char**)&(iov[iov_index].iov_base); + iov[iov_index].iov_len -= bytes; /* there's that much left */ + *bp += bytes; /* starting there */ + break; /* go off and do that */ + } + bytes -= iov[iov_index].iov_len; /* that element's consumed */ + } + op->arg2.buffer = &iov[iov_index]; /* new start of array */ + op->arg3.amount -= iov_index; /* and array length */ + return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; + } + else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno)) + { + op->result.code = -1; + return PR_TRUE; + } + else return PR_FALSE; +} /* pt_writev_cont */ + +static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents) +{ + PRIntn bytes = sendto( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags, + (struct sockaddr*)op->arg5.addr, PR_NETADDR_SIZE(op->arg5.addr)); + op->syserrno = errno; + if (bytes >= 0) /* this is progress */ + { + char *bp = (char*)op->arg2.buffer; + bp += bytes; /* adjust the buffer pointer */ + op->arg2.buffer = bp; + op->result.code += bytes; /* accumulate the number sent */ + op->arg3.amount -= bytes; /* and reduce the required count */ + return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; + } + else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno)) + { + op->result.code = -1; + return PR_TRUE; + } + else return PR_FALSE; +} /* pt_sendto_cont */ + +static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents) +{ + pt_SockLen addr_len = sizeof(PRNetAddr); + op->result.code = recvfrom( + op->arg1.osfd, op->arg2.buffer, op->arg3.amount, + op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len); + op->syserrno = errno; + return ((-1 == op->result.code) && + (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ? + PR_FALSE : PR_TRUE; +} /* pt_recvfrom_cont */ + +#ifdef AIX +static PRBool pt_aix_sendfile_cont(pt_Continuation *op, PRInt16 revents) +{ + struct sf_parms *sf_struct = (struct sf_parms *) op->arg2.buffer; + ssize_t rv; + unsigned long long saved_file_offset; + long long saved_file_bytes; + + saved_file_offset = sf_struct->file_offset; + saved_file_bytes = sf_struct->file_bytes; + sf_struct->bytes_sent = 0; + + if ((sf_struct->file_bytes > 0) && (sf_struct->file_size > 0)) + PR_ASSERT((sf_struct->file_bytes + sf_struct->file_offset) <= + sf_struct->file_size); + rv = AIX_SEND_FILE(&op->arg1.osfd, sf_struct, op->arg4.flags); + op->syserrno = errno; + + if (rv != -1) { + op->result.code += sf_struct->bytes_sent; + /* + * A bug in AIX 4.3.2 prevents the 'file_bytes' field from + * being updated. So, 'file_bytes' is maintained by NSPR to + * avoid conflict when this bug is fixed in AIX, in the future. + */ + if (saved_file_bytes != -1) + saved_file_bytes -= (sf_struct->file_offset - saved_file_offset); + sf_struct->file_bytes = saved_file_bytes; + } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) { + op->result.code = -1; + } else { + return PR_FALSE; + } + + if (rv == 1) { /* more data to send */ + return PR_FALSE; + } + + return PR_TRUE; +} +#endif /* AIX */ + +#ifdef HPUX11 +static PRBool pt_hpux_sendfile_cont(pt_Continuation *op, PRInt16 revents) +{ + struct iovec *hdtrl = (struct iovec *) op->arg2.buffer; + int count; + + count = sendfile(op->arg1.osfd, op->filedesc, op->arg3.file_spec.offset, + op->arg3.file_spec.nbytes, hdtrl, op->arg4.flags); + PR_ASSERT(count <= op->nbytes_to_send); + op->syserrno = errno; + + if (count != -1) { + op->result.code += count; + } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) { + op->result.code = -1; + } else { + return PR_FALSE; + } + if (count != -1 && count < op->nbytes_to_send) { + if (count < hdtrl[0].iov_len) { + /* header not sent */ + + hdtrl[0].iov_base = ((char *) hdtrl[0].iov_base) + count; + hdtrl[0].iov_len -= count; + + } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes)) { + /* header sent, file not sent */ + PRUint32 file_nbytes_sent = count - hdtrl[0].iov_len; + + hdtrl[0].iov_base = NULL; + hdtrl[0].iov_len = 0; + + op->arg3.file_spec.offset += file_nbytes_sent; + op->arg3.file_spec.nbytes -= file_nbytes_sent; + } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes + + hdtrl[1].iov_len)) { + PRUint32 trailer_nbytes_sent = count - (hdtrl[0].iov_len + + op->arg3.file_spec.nbytes); + + /* header sent, file sent, trailer not sent */ + + hdtrl[0].iov_base = NULL; + hdtrl[0].iov_len = 0; + /* + * set file offset and len so that no more file data is + * sent + */ + op->arg3.file_spec.offset = op->arg3.file_spec.st_size; + op->arg3.file_spec.nbytes = 0; + + hdtrl[1].iov_base =((char *) hdtrl[1].iov_base)+ trailer_nbytes_sent; + hdtrl[1].iov_len -= trailer_nbytes_sent; + } + op->nbytes_to_send -= count; + return PR_FALSE; + } + + return PR_TRUE; +} +#endif /* HPUX11 */ + +#ifdef SOLARIS +static PRBool pt_solaris_sendfile_cont(pt_Continuation *op, PRInt16 revents) +{ + struct sendfilevec *vec = (struct sendfilevec *) op->arg2.buffer; + size_t xferred; + ssize_t count; + + count = SOLARIS_SENDFILEV(op->arg1.osfd, vec, op->arg3.amount, &xferred); + op->syserrno = errno; + PR_ASSERT((count == -1) || (count == xferred)); + + if (count == -1) { + if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN + && op->syserrno != EINTR) { + op->result.code = -1; + return PR_TRUE; + } + count = xferred; + } else if (count == 0) { + /* + * We are now at EOF. The file was truncated. Solaris sendfile is + * supposed to return 0 and no error in this case, though some versions + * may return -1 and EINVAL . + */ + op->result.code = -1; + op->syserrno = 0; /* will be treated as EOF */ + return PR_TRUE; + } + PR_ASSERT(count <= op->nbytes_to_send); + + op->result.code += count; + if (count < op->nbytes_to_send) { + op->nbytes_to_send -= count; + + while (count >= vec->sfv_len) { + count -= vec->sfv_len; + vec++; + op->arg3.amount--; + } + PR_ASSERT(op->arg3.amount > 0); + + vec->sfv_off += count; + vec->sfv_len -= count; + PR_ASSERT(vec->sfv_len > 0); + op->arg2.buffer = vec; + + return PR_FALSE; + } + + return PR_TRUE; +} +#endif /* SOLARIS */ + +#ifdef LINUX +static PRBool pt_linux_sendfile_cont(pt_Continuation *op, PRInt16 revents) +{ + ssize_t rv; + off_t oldoffset; + + oldoffset = op->offset; + rv = sendfile(op->arg1.osfd, op->in_fd, &op->offset, op->count); + op->syserrno = errno; + + if (rv == -1) { + if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) { + op->result.code = -1; + return PR_TRUE; + } + rv = 0; + } + PR_ASSERT(rv == op->offset - oldoffset); + op->result.code += rv; + if (rv < op->count) { + op->count -= rv; + return PR_FALSE; + } + return PR_TRUE; +} +#endif /* LINUX */ + +void _PR_InitIO(void) +{ +#if defined(DEBUG) + memset(&pt_debug, 0, sizeof(PTDebug)); + pt_debug.timeStarted = PR_Now(); +#endif + + _pr_flock_lock = PR_NewLock(); + PR_ASSERT(NULL != _pr_flock_lock); + _pr_flock_cv = PR_NewCondVar(_pr_flock_lock); + PR_ASSERT(NULL != _pr_flock_cv); + _pr_rename_lock = PR_NewLock(); + PR_ASSERT(NULL != _pr_rename_lock); + + _PR_InitFdCache(); /* do that */ + + _pr_stdin = pt_SetMethods(0, PR_DESC_FILE, PR_FALSE, PR_TRUE); + _pr_stdout = pt_SetMethods(1, PR_DESC_FILE, PR_FALSE, PR_TRUE); + _pr_stderr = pt_SetMethods(2, PR_DESC_FILE, PR_FALSE, PR_TRUE); + PR_ASSERT(_pr_stdin && _pr_stdout && _pr_stderr); + +#ifdef _PR_IPV6_V6ONLY_PROBE + /* In Mac OS X v10.3 Panther Beta the IPV6_V6ONLY socket option + * is turned on by default, contrary to what RFC 3493, Section + * 5.3 says. So we have to turn it off. Find out whether we + * are running on such a system. + */ + { + int osfd; + osfd = socket(AF_INET6, SOCK_STREAM, 0); + if (osfd != -1) { + int on; + socklen_t optlen = sizeof(on); + if (getsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY, + &on, &optlen) == 0) { + _pr_ipv6_v6only_on_by_default = on; + } + close(osfd); + } + } +#endif +} /* _PR_InitIO */ + +void _PR_CleanupIO(void) +{ + _PR_Putfd(_pr_stdin); + _pr_stdin = NULL; + _PR_Putfd(_pr_stdout); + _pr_stdout = NULL; + _PR_Putfd(_pr_stderr); + _pr_stderr = NULL; + + _PR_CleanupFdCache(); + + if (_pr_flock_cv) + { + PR_DestroyCondVar(_pr_flock_cv); + _pr_flock_cv = NULL; + } + if (_pr_flock_lock) + { + PR_DestroyLock(_pr_flock_lock); + _pr_flock_lock = NULL; + } + if (_pr_rename_lock) + { + PR_DestroyLock(_pr_rename_lock); + _pr_rename_lock = NULL; + } +} /* _PR_CleanupIO */ + +PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd) +{ + PRFileDesc *result = NULL; + PR_ASSERT(osfd >= PR_StandardInput && osfd <= PR_StandardError); + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + switch (osfd) + { + case PR_StandardInput: result = _pr_stdin; break; + case PR_StandardOutput: result = _pr_stdout; break; + case PR_StandardError: result = _pr_stderr; break; + default: + (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + } + return result; +} /* PR_GetSpecialFD */ + +/*****************************************************************************/ +/***************************** I/O private methods ***************************/ +/*****************************************************************************/ + +static PRBool pt_TestAbort(void) +{ + PRThread *me = PR_GetCurrentThread(); + if(_PT_THREAD_INTERRUPTED(me)) + { + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + me->state &= ~PT_THREAD_ABORTED; + return PR_TRUE; + } + return PR_FALSE; +} /* pt_TestAbort */ + +static void pt_MapError(void (*mapper)(PRIntn), PRIntn syserrno) +{ + switch (syserrno) + { + case EINTR: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); break; + case ETIMEDOUT: + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); break; + default: + mapper(syserrno); + } +} /* pt_MapError */ + +static PRStatus pt_Close(PRFileDesc *fd) +{ + if ((NULL == fd) || (NULL == fd->secret) + || ((_PR_FILEDESC_OPEN != fd->secret->state) + && (_PR_FILEDESC_CLOSED != fd->secret->state))) + { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + return PR_FAILURE; + } + if (pt_TestAbort()) return PR_FAILURE; + + if (_PR_FILEDESC_OPEN == fd->secret->state) + { + if (-1 == close(fd->secret->md.osfd)) + { +#ifdef OSF1 + /* + * Bug 86941: On Tru64 UNIX V5.0A and V5.1, the close() + * system call, when called to close a TCP socket, may + * return -1 with errno set to EINVAL but the system call + * does close the socket successfully. An application + * may safely ignore the EINVAL error. This bug is fixed + * on Tru64 UNIX V5.1A and later. The defect tracking + * number is QAR 81431. + */ + if (PR_DESC_SOCKET_TCP != fd->methods->file_type + || EINVAL != errno) + { + pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno); + return PR_FAILURE; + } +#else + pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno); + return PR_FAILURE; +#endif + } + fd->secret->state = _PR_FILEDESC_CLOSED; + } + _PR_Putfd(fd); + return PR_SUCCESS; +} /* pt_Close */ + +static PRInt32 pt_Read(PRFileDesc *fd, void *buf, PRInt32 amount) +{ + PRInt32 syserrno, bytes = -1; + + if (pt_TestAbort()) return bytes; + + bytes = read(fd->secret->md.osfd, buf, amount); + syserrno = errno; + + if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) + && (!fd->secret->nonblocking)) + { + pt_Continuation op; + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = buf; + op.arg3.amount = amount; + op.timeout = PR_INTERVAL_NO_TIMEOUT; + op.function = pt_read_cont; + op.event = POLLIN | POLLPRI; + bytes = pt_Continue(&op); + syserrno = op.syserrno; + } + if (bytes < 0) + pt_MapError(_PR_MD_MAP_READ_ERROR, syserrno); + return bytes; +} /* pt_Read */ + +static PRInt32 pt_Write(PRFileDesc *fd, const void *buf, PRInt32 amount) +{ + PRInt32 syserrno, bytes = -1; + PRBool fNeedContinue = PR_FALSE; + + if (pt_TestAbort()) return bytes; + + bytes = write(fd->secret->md.osfd, buf, amount); + syserrno = errno; + + if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) ) + { + buf = (char *) buf + bytes; + amount -= bytes; + fNeedContinue = PR_TRUE; + } + if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) + && (!fd->secret->nonblocking) ) + { + bytes = 0; + fNeedContinue = PR_TRUE; + } + + if (fNeedContinue == PR_TRUE) + { + pt_Continuation op; + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = (void*)buf; + op.arg3.amount = amount; + op.timeout = PR_INTERVAL_NO_TIMEOUT; + op.result.code = bytes; /* initialize the number sent */ + op.function = pt_write_cont; + op.event = POLLOUT | POLLPRI; + bytes = pt_Continue(&op); + syserrno = op.syserrno; + } + if (bytes == -1) + pt_MapError(_PR_MD_MAP_WRITE_ERROR, syserrno); + return bytes; +} /* pt_Write */ + +static PRInt32 pt_Writev( + PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_len, PRIntervalTime timeout) +{ + PRIntn iov_index; + PRBool fNeedContinue = PR_FALSE; + PRInt32 syserrno, bytes, rv = -1; + struct iovec osiov_local[PR_MAX_IOVECTOR_SIZE], *osiov; + int osiov_len; + + if (pt_TestAbort()) return rv; + + /* Ensured by PR_Writev */ + PR_ASSERT(iov_len <= PR_MAX_IOVECTOR_SIZE); + + /* + * We can't pass iov to writev because PRIOVec and struct iovec + * may not be binary compatible. Make osiov a copy of iov and + * pass osiov to writev. We can modify osiov if we need to + * continue the operation. + */ + osiov = osiov_local; + osiov_len = iov_len; + for (iov_index = 0; iov_index < osiov_len; iov_index++) + { + osiov[iov_index].iov_base = iov[iov_index].iov_base; + osiov[iov_index].iov_len = iov[iov_index].iov_len; + } + + rv = bytes = writev(fd->secret->md.osfd, osiov, osiov_len); + syserrno = errno; + + if (!fd->secret->nonblocking) + { + if (bytes >= 0) + { + /* + * If we moved some bytes, how does that implicate the + * i/o vector list? In other words, exactly where are + * we within that array? What are the parameters for + * resumption? Maybe we're done! + */ + for ( ;osiov_len > 0; osiov++, osiov_len--) + { + if (bytes < osiov->iov_len) + { + /* this one's not done yet */ + osiov->iov_base = (char*)osiov->iov_base + bytes; + osiov->iov_len -= bytes; + break; /* go off and do that */ + } + bytes -= osiov->iov_len; /* this one's done cooked */ + } + PR_ASSERT(osiov_len > 0 || bytes == 0); + if (osiov_len > 0) + { + if (PR_INTERVAL_NO_WAIT == timeout) + { + rv = -1; + syserrno = ETIMEDOUT; + } + else fNeedContinue = PR_TRUE; + } + } + else if (syserrno == EWOULDBLOCK || syserrno == EAGAIN) + { + if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; + else + { + rv = 0; + fNeedContinue = PR_TRUE; + } + } + } + + if (fNeedContinue == PR_TRUE) + { + pt_Continuation op; + + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = (void*)osiov; + op.arg3.amount = osiov_len; + op.timeout = timeout; + op.result.code = rv; + op.function = pt_writev_cont; + op.event = POLLOUT | POLLPRI; + rv = pt_Continue(&op); + syserrno = op.syserrno; + } + if (rv == -1) pt_MapError(_PR_MD_MAP_WRITEV_ERROR, syserrno); + return rv; +} /* pt_Writev */ + +static PRInt32 pt_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence) +{ + return _PR_MD_LSEEK(fd, offset, whence); +} /* pt_Seek */ + +static PRInt64 pt_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence) +{ + return _PR_MD_LSEEK64(fd, offset, whence); +} /* pt_Seek64 */ + +static PRInt32 pt_Available_f(PRFileDesc *fd) +{ + PRInt32 result, cur, end; + + cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR); + + if (cur >= 0) + end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END); + + if ((cur < 0) || (end < 0)) { + return -1; + } + + result = end - cur; + _PR_MD_LSEEK(fd, cur, PR_SEEK_SET); + + return result; +} /* pt_Available_f */ + +static PRInt64 pt_Available64_f(PRFileDesc *fd) +{ + PRInt64 result, cur, end; + PRInt64 minus_one; + + LL_I2L(minus_one, -1); + cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR); + + if (LL_GE_ZERO(cur)) + end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END); + + if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one; + + LL_SUB(result, end, cur); + (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET); + + return result; +} /* pt_Available64_f */ + +static PRInt32 pt_Available_s(PRFileDesc *fd) +{ + PRInt32 rv, bytes = -1; + if (pt_TestAbort()) return bytes; + + rv = ioctl(fd->secret->md.osfd, FIONREAD, &bytes); + + if (rv == -1) + pt_MapError(_PR_MD_MAP_SOCKETAVAILABLE_ERROR, errno); + return bytes; +} /* pt_Available_s */ + +static PRInt64 pt_Available64_s(PRFileDesc *fd) +{ + PRInt64 rv; + LL_I2L(rv, pt_Available_s(fd)); + return rv; +} /* pt_Available64_s */ + +static PRStatus pt_FileInfo(PRFileDesc *fd, PRFileInfo *info) +{ + PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, info); + return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; +} /* pt_FileInfo */ + +static PRStatus pt_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info) +{ + PRInt32 rv = _PR_MD_GETOPENFILEINFO64(fd, info); + return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; +} /* pt_FileInfo64 */ + +static PRStatus pt_Synch(PRFileDesc *fd) +{ + return (NULL == fd) ? PR_FAILURE : PR_SUCCESS; +} /* pt_Synch */ + +static PRStatus pt_Fsync(PRFileDesc *fd) +{ + PRIntn rv = -1; + if (pt_TestAbort()) return PR_FAILURE; + + rv = fsync(fd->secret->md.osfd); + if (rv < 0) { + pt_MapError(_PR_MD_MAP_FSYNC_ERROR, errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} /* pt_Fsync */ + +static PRStatus pt_Connect( + PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) +{ + PRIntn rv = -1, syserrno; + pt_SockLen addr_len; + const PRNetAddr *addrp = addr; +#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) + PRUint16 md_af = addr->raw.family; + PRNetAddr addrCopy; +#endif + + if (pt_TestAbort()) return PR_FAILURE; + + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + addr_len = PR_NETADDR_SIZE(addr); +#if defined(_PR_INET6) + if (addr->raw.family == PR_AF_INET6) { + md_af = AF_INET6; +#ifndef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + addrCopy.raw.family = AF_INET6; + addrp = &addrCopy; +#endif + } +#endif + +#ifdef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + ((struct sockaddr*)&addrCopy)->sa_len = addr_len; + ((struct sockaddr*)&addrCopy)->sa_family = md_af; + addrp = &addrCopy; +#endif + rv = connect(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len); + syserrno = errno; + if ((-1 == rv) && (EINPROGRESS == syserrno) && (!fd->secret->nonblocking)) + { + if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; + else + { + pt_Continuation op; + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = (void*)addrp; + op.arg3.amount = addr_len; + op.timeout = timeout; + op.function = pt_connect_cont; + op.event = POLLOUT | POLLPRI; + rv = pt_Continue(&op); + syserrno = op.syserrno; + } + } + if (-1 == rv) { + pt_MapError(_PR_MD_MAP_CONNECT_ERROR, syserrno); + return PR_FAILURE; + } + return PR_SUCCESS; +} /* pt_Connect */ + +static PRStatus pt_ConnectContinue( + PRFileDesc *fd, PRInt16 out_flags) +{ + int err; + PRInt32 osfd; + + if (out_flags & PR_POLL_NVAL) + { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + return PR_FAILURE; + } + if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR + | PR_POLL_HUP)) == 0) + { + PR_ASSERT(out_flags == 0); + PR_SetError(PR_IN_PROGRESS_ERROR, 0); + return PR_FAILURE; + } + + osfd = fd->secret->md.osfd; + + err = _MD_unix_get_nonblocking_connect_error(osfd); + if (err != 0) + { + _PR_MD_MAP_CONNECT_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; +} /* pt_ConnectContinue */ + +PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd) +{ + /* Find the NSPR layer and invoke its connectcontinue method */ + PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + + if (NULL == bottom) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + return pt_ConnectContinue(bottom, pd->out_flags); +} /* PR_GetConnectStatus */ + +static PRFileDesc* pt_Accept( + PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout) +{ + PRFileDesc *newfd = NULL; + PRIntn syserrno, osfd = -1; + pt_SockLen addr_len = sizeof(PRNetAddr); +#ifdef SYMBIAN + PRNetAddr dummy_addr; +#endif + + if (pt_TestAbort()) return newfd; + +#ifdef SYMBIAN + /* On Symbian OS, accept crashes if addr is NULL. */ + if (!addr) + addr = &dummy_addr; +#endif + +#ifdef _PR_STRICT_ADDR_LEN + if (addr) + { + /* + * Set addr->raw.family just so that we can use the + * PR_NETADDR_SIZE macro. + */ + addr->raw.family = fd->secret->af; + addr_len = PR_NETADDR_SIZE(addr); + } +#endif + + osfd = accept(fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len); + syserrno = errno; + + if (osfd == -1) + { + if (fd->secret->nonblocking) goto failed; + + if (EWOULDBLOCK != syserrno && EAGAIN != syserrno + && ECONNABORTED != syserrno) + goto failed; + else + { + if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; + else + { + pt_Continuation op; + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = addr; + op.arg3.addr_len = &addr_len; + op.timeout = timeout; + op.function = pt_accept_cont; + op.event = POLLIN | POLLPRI; + osfd = pt_Continue(&op); + syserrno = op.syserrno; + } + if (osfd < 0) goto failed; + } + } +#ifdef _PR_HAVE_SOCKADDR_LEN + /* ignore the sa_len field of struct sockaddr */ + if (addr) + { + addr->raw.family = ((struct sockaddr*)addr)->sa_family; + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ +#ifdef _PR_INET6 + if (addr && (AF_INET6 == addr->raw.family)) + addr->raw.family = PR_AF_INET6; +#endif + newfd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_TRUE, PR_FALSE); + if (newfd == NULL) close(osfd); /* $$$ whoops! this doesn't work $$$ */ + else + { + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); +#ifdef LINUX + /* + * On Linux, experiments showed that the accepted sockets + * inherit the TCP_NODELAY socket option of the listening + * socket. + */ + newfd->secret->md.tcp_nodelay = fd->secret->md.tcp_nodelay; +#endif + } + return newfd; + +failed: + pt_MapError(_PR_MD_MAP_ACCEPT_ERROR, syserrno); + return NULL; +} /* pt_Accept */ + +static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr) +{ + PRIntn rv; + pt_SockLen addr_len; + const PRNetAddr *addrp = addr; +#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) + PRUint16 md_af = addr->raw.family; + PRNetAddr addrCopy; +#endif + + if (pt_TestAbort()) return PR_FAILURE; + + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + if (addr->raw.family == AF_UNIX) + { + /* Disallow relative pathnames */ + if (addr->local.path[0] != '/') + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + } + +#if defined(_PR_INET6) + if (addr->raw.family == PR_AF_INET6) { + md_af = AF_INET6; +#ifndef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + addrCopy.raw.family = AF_INET6; + addrp = &addrCopy; +#endif + } +#endif + + addr_len = PR_NETADDR_SIZE(addr); +#ifdef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + ((struct sockaddr*)&addrCopy)->sa_len = addr_len; + ((struct sockaddr*)&addrCopy)->sa_family = md_af; + addrp = &addrCopy; +#endif + rv = bind(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len); + + if (rv == -1) { + pt_MapError(_PR_MD_MAP_BIND_ERROR, errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} /* pt_Bind */ + +static PRStatus pt_Listen(PRFileDesc *fd, PRIntn backlog) +{ + PRIntn rv; + + if (pt_TestAbort()) return PR_FAILURE; + + rv = listen(fd->secret->md.osfd, backlog); + if (rv == -1) { + pt_MapError(_PR_MD_MAP_LISTEN_ERROR, errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} /* pt_Listen */ + +static PRStatus pt_Shutdown(PRFileDesc *fd, PRIntn how) +{ + PRIntn rv = -1; + if (pt_TestAbort()) return PR_FAILURE; + + rv = shutdown(fd->secret->md.osfd, how); + + if (rv == -1) { + pt_MapError(_PR_MD_MAP_SHUTDOWN_ERROR, errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} /* pt_Shutdown */ + +static PRInt16 pt_Poll(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) +{ + *out_flags = 0; + return in_flags; +} /* pt_Poll */ + +static PRInt32 pt_Recv( + PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + PRInt32 syserrno, bytes = -1; + PRIntn osflags; + + if (0 == flags) + osflags = 0; + else if (PR_MSG_PEEK == flags) + { +#ifdef SYMBIAN + /* MSG_PEEK doesn't work as expected. */ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return bytes; +#else + osflags = MSG_PEEK; +#endif + } + else + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return bytes; + } + + if (pt_TestAbort()) return bytes; + + /* recv() is a much slower call on pre-2.6 Solaris than read(). */ +#if defined(SOLARIS) + if (0 == osflags) + bytes = read(fd->secret->md.osfd, buf, amount); + else + bytes = recv(fd->secret->md.osfd, buf, amount, osflags); +#else + bytes = recv(fd->secret->md.osfd, buf, amount, osflags); +#endif + syserrno = errno; + + if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) + && (!fd->secret->nonblocking)) + { + if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; + else + { + pt_Continuation op; + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = buf; + op.arg3.amount = amount; + op.arg4.flags = osflags; + op.timeout = timeout; + op.function = pt_recv_cont; + op.event = POLLIN | POLLPRI; + bytes = pt_Continue(&op); + syserrno = op.syserrno; + } + } + if (bytes < 0) + pt_MapError(_PR_MD_MAP_RECV_ERROR, syserrno); + return bytes; +} /* pt_Recv */ + +static PRInt32 pt_SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount) +{ + return pt_Recv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); +} /* pt_SocketRead */ + +static PRInt32 pt_Send( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + PRInt32 syserrno, bytes = -1; + PRBool fNeedContinue = PR_FALSE; +#if defined(SOLARIS) + PRInt32 tmp_amount = amount; +#endif + + /* + * Under HP-UX DCE threads, pthread.h includes dce/cma_ux.h, + * which has the following: + * # define send cma_send + * extern int cma_send (int , void *, int, int ); + * So we need to cast away the 'const' of argument #2 for send(). + */ +#if defined (HPUX) && defined(_PR_DCETHREADS) +#define PT_SENDBUF_CAST (void *) +#else +#define PT_SENDBUF_CAST +#endif + + if (pt_TestAbort()) return bytes; + + /* + * On pre-2.6 Solaris, send() is much slower than write(). + * On 2.6 and beyond, with in-kernel sockets, send() and + * write() are fairly equivalent in performance. + */ +#if defined(SOLARIS) + PR_ASSERT(0 == flags); +retry: + bytes = write(fd->secret->md.osfd, PT_SENDBUF_CAST buf, tmp_amount); +#else + bytes = send(fd->secret->md.osfd, PT_SENDBUF_CAST buf, amount, flags); +#endif + syserrno = errno; + +#if defined(SOLARIS) + /* + * The write system call has been reported to return the ERANGE error + * on occasion. Try to write in smaller chunks to workaround this bug. + */ + if ((bytes == -1) && (syserrno == ERANGE)) + { + if (tmp_amount > 1) + { + tmp_amount = tmp_amount/2; /* half the bytes */ + goto retry; + } + } +#endif + + if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) ) + { + if (PR_INTERVAL_NO_WAIT == timeout) + { + bytes = -1; + syserrno = ETIMEDOUT; + } + else + { + buf = (char *) buf + bytes; + amount -= bytes; + fNeedContinue = PR_TRUE; + } + } + if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) + && (!fd->secret->nonblocking) ) + { + if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; + else + { + bytes = 0; + fNeedContinue = PR_TRUE; + } + } + + if (fNeedContinue == PR_TRUE) + { + pt_Continuation op; + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = (void*)buf; + op.arg3.amount = amount; + op.arg4.flags = flags; + op.timeout = timeout; + op.result.code = bytes; /* initialize the number sent */ + op.function = pt_send_cont; + op.event = POLLOUT | POLLPRI; + bytes = pt_Continue(&op); + syserrno = op.syserrno; + } + if (bytes == -1) + pt_MapError(_PR_MD_MAP_SEND_ERROR, syserrno); + return bytes; +} /* pt_Send */ + +static PRInt32 pt_SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount) +{ + return pt_Send(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); +} /* pt_SocketWrite */ + +static PRInt32 pt_SendTo( + PRFileDesc *fd, const void *buf, + PRInt32 amount, PRIntn flags, const PRNetAddr *addr, + PRIntervalTime timeout) +{ + PRInt32 syserrno, bytes = -1; + PRBool fNeedContinue = PR_FALSE; + pt_SockLen addr_len; + const PRNetAddr *addrp = addr; +#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) + PRUint16 md_af = addr->raw.family; + PRNetAddr addrCopy; +#endif + + if (pt_TestAbort()) return bytes; + + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); +#if defined(_PR_INET6) + if (addr->raw.family == PR_AF_INET6) { + md_af = AF_INET6; +#ifndef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + addrCopy.raw.family = AF_INET6; + addrp = &addrCopy; +#endif + } +#endif + + addr_len = PR_NETADDR_SIZE(addr); +#ifdef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + ((struct sockaddr*)&addrCopy)->sa_len = addr_len; + ((struct sockaddr*)&addrCopy)->sa_family = md_af; + addrp = &addrCopy; +#endif + bytes = sendto( + fd->secret->md.osfd, buf, amount, flags, + (struct sockaddr*)addrp, addr_len); + syserrno = errno; + if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) + && (!fd->secret->nonblocking) ) + { + if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; + else fNeedContinue = PR_TRUE; + } + if (fNeedContinue == PR_TRUE) + { + pt_Continuation op; + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = (void*)buf; + op.arg3.amount = amount; + op.arg4.flags = flags; + op.arg5.addr = (PRNetAddr*)addrp; + op.timeout = timeout; + op.result.code = 0; /* initialize the number sent */ + op.function = pt_sendto_cont; + op.event = POLLOUT | POLLPRI; + bytes = pt_Continue(&op); + syserrno = op.syserrno; + } + if (bytes < 0) + pt_MapError(_PR_MD_MAP_SENDTO_ERROR, syserrno); + return bytes; +} /* pt_SendTo */ + +static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) +{ + PRBool fNeedContinue = PR_FALSE; + PRInt32 syserrno, bytes = -1; + pt_SockLen addr_len = sizeof(PRNetAddr); + + if (pt_TestAbort()) return bytes; + + bytes = recvfrom( + fd->secret->md.osfd, buf, amount, flags, + (struct sockaddr*)addr, &addr_len); + syserrno = errno; + + if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) + && (!fd->secret->nonblocking) ) + { + if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT; + else fNeedContinue = PR_TRUE; + } + + if (fNeedContinue == PR_TRUE) + { + pt_Continuation op; + op.arg1.osfd = fd->secret->md.osfd; + op.arg2.buffer = buf; + op.arg3.amount = amount; + op.arg4.flags = flags; + op.arg5.addr = addr; + op.timeout = timeout; + op.function = pt_recvfrom_cont; + op.event = POLLIN | POLLPRI; + bytes = pt_Continue(&op); + syserrno = op.syserrno; + } + if (bytes >= 0) + { +#ifdef _PR_HAVE_SOCKADDR_LEN + /* ignore the sa_len field of struct sockaddr */ + if (addr) + { + addr->raw.family = ((struct sockaddr*)addr)->sa_family; + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ +#ifdef _PR_INET6 + if (addr && (AF_INET6 == addr->raw.family)) + addr->raw.family = PR_AF_INET6; +#endif + } + else + pt_MapError(_PR_MD_MAP_RECVFROM_ERROR, syserrno); + return bytes; +} /* pt_RecvFrom */ + +#ifdef AIX +#ifndef HAVE_SEND_FILE +static pthread_once_t pt_aix_sendfile_once_block = PTHREAD_ONCE_INIT; + +static void pt_aix_sendfile_init_routine(void) +{ + void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + pt_aix_sendfile_fptr = (ssize_t (*)()) dlsym(handle, "send_file"); + dlclose(handle); +} + +/* + * pt_AIXDispatchSendFile + */ +static PRInt32 pt_AIXDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + int rv; + + rv = pthread_once(&pt_aix_sendfile_once_block, + pt_aix_sendfile_init_routine); + PR_ASSERT(0 == rv); + if (pt_aix_sendfile_fptr) { + return pt_AIXSendFile(sd, sfd, flags, timeout); + } else { + return PR_EmulateSendFile(sd, sfd, flags, timeout); + } +} +#endif /* !HAVE_SEND_FILE */ + + +/* + * pt_AIXSendFile + * + * Send file sfd->fd across socket sd. If specified, header and trailer + * buffers are sent before and after the file, respectively. + * + * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file + * + * return number of bytes sent or -1 on error + * + * This implementation takes advantage of the send_file() system + * call available in AIX 4.3.2. + */ + +static PRInt32 pt_AIXSendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + struct sf_parms sf_struct; + uint_t send_flags; + ssize_t rv; + int syserrno; + PRInt32 count; + unsigned long long saved_file_offset; + long long saved_file_bytes; + + sf_struct.header_data = (void *) sfd->header; /* cast away the 'const' */ + sf_struct.header_length = sfd->hlen; + sf_struct.file_descriptor = sfd->fd->secret->md.osfd; + sf_struct.file_size = 0; + sf_struct.file_offset = sfd->file_offset; + if (sfd->file_nbytes == 0) + sf_struct.file_bytes = -1; + else + sf_struct.file_bytes = sfd->file_nbytes; + sf_struct.trailer_data = (void *) sfd->trailer; + sf_struct.trailer_length = sfd->tlen; + sf_struct.bytes_sent = 0; + + saved_file_offset = sf_struct.file_offset; + saved_file_bytes = sf_struct.file_bytes; + + send_flags = 0; /* flags processed at the end */ + + /* The first argument to send_file() is int*. */ + PR_ASSERT(sizeof(int) == sizeof(sd->secret->md.osfd)); + do { + rv = AIX_SEND_FILE(&sd->secret->md.osfd, &sf_struct, send_flags); + } while (rv == -1 && (syserrno = errno) == EINTR); + + if (rv == -1) { + if (syserrno == EAGAIN || syserrno == EWOULDBLOCK) { + count = 0; /* Not a real error. Need to continue. */ + } else { + count = -1; + } + } else { + count = sf_struct.bytes_sent; + /* + * A bug in AIX 4.3.2 prevents the 'file_bytes' field from + * being updated. So, 'file_bytes' is maintained by NSPR to + * avoid conflict when this bug is fixed in AIX, in the future. + */ + if (saved_file_bytes != -1) + saved_file_bytes -= (sf_struct.file_offset - saved_file_offset); + sf_struct.file_bytes = saved_file_bytes; + } + + if ((rv == 1) || ((rv == -1) && (count == 0))) { + pt_Continuation op; + + op.arg1.osfd = sd->secret->md.osfd; + op.arg2.buffer = &sf_struct; + op.arg4.flags = send_flags; + op.result.code = count; + op.timeout = timeout; + op.function = pt_aix_sendfile_cont; + op.event = POLLOUT | POLLPRI; + count = pt_Continue(&op); + syserrno = op.syserrno; + } + + if (count == -1) { + pt_MapError(_MD_aix_map_sendfile_error, syserrno); + return -1; + } + if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { + PR_Close(sd); + } + PR_ASSERT(count == (sfd->hlen + sfd->tlen + + ((sfd->file_nbytes == 0) ? + sf_struct.file_size - sfd->file_offset : + sfd->file_nbytes))); + return count; +} +#endif /* AIX */ + +#ifdef HPUX11 +/* + * pt_HPUXSendFile + * + * Send file sfd->fd across socket sd. If specified, header and trailer + * buffers are sent before and after the file, respectively. + * + * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file + * + * return number of bytes sent or -1 on error + * + * This implementation takes advantage of the sendfile() system + * call available in HP-UX B.11.00. + */ + +static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + struct stat statbuf; + size_t nbytes_to_send, file_nbytes_to_send; + struct iovec hdtrl[2]; /* optional header and trailer buffers */ + int send_flags; + PRInt32 count; + int syserrno; + + if (sfd->file_nbytes == 0) { + /* Get file size */ + if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { + _PR_MD_MAP_FSTAT_ERROR(errno); + return -1; + } + file_nbytes_to_send = statbuf.st_size - sfd->file_offset; + } else { + file_nbytes_to_send = sfd->file_nbytes; + } + nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send; + + hdtrl[0].iov_base = (void *) sfd->header; /* cast away the 'const' */ + hdtrl[0].iov_len = sfd->hlen; + hdtrl[1].iov_base = (void *) sfd->trailer; + hdtrl[1].iov_len = sfd->tlen; + /* + * SF_DISCONNECT seems to close the socket even if sendfile() + * only does a partial send on a nonblocking socket. This + * would prevent the subsequent sendfile() calls on that socket + * from working. So we don't use the SD_DISCONNECT flag. + */ + send_flags = 0; + + do { + count = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd, + sfd->file_offset, file_nbytes_to_send, hdtrl, send_flags); + } while (count == -1 && (syserrno = errno) == EINTR); + + if (count == -1 && (syserrno == EAGAIN || syserrno == EWOULDBLOCK)) { + count = 0; + } + if (count != -1 && count < nbytes_to_send) { + pt_Continuation op; + + if (count < sfd->hlen) { + /* header not sent */ + + hdtrl[0].iov_base = ((char *) sfd->header) + count; + hdtrl[0].iov_len = sfd->hlen - count; + op.arg3.file_spec.offset = sfd->file_offset; + op.arg3.file_spec.nbytes = file_nbytes_to_send; + } else if (count < (sfd->hlen + file_nbytes_to_send)) { + /* header sent, file not sent */ + + hdtrl[0].iov_base = NULL; + hdtrl[0].iov_len = 0; + + op.arg3.file_spec.offset = sfd->file_offset + count - sfd->hlen; + op.arg3.file_spec.nbytes = file_nbytes_to_send - (count - sfd->hlen); + } else if (count < (sfd->hlen + file_nbytes_to_send + sfd->tlen)) { + PRUint32 trailer_nbytes_sent; + + /* header sent, file sent, trailer not sent */ + + hdtrl[0].iov_base = NULL; + hdtrl[0].iov_len = 0; + /* + * set file offset and len so that no more file data is + * sent + */ + op.arg3.file_spec.offset = statbuf.st_size; + op.arg3.file_spec.nbytes = 0; + + trailer_nbytes_sent = count - sfd->hlen - file_nbytes_to_send; + hdtrl[1].iov_base = ((char *) sfd->trailer) + trailer_nbytes_sent; + hdtrl[1].iov_len = sfd->tlen - trailer_nbytes_sent; + } + + op.arg1.osfd = sd->secret->md.osfd; + op.filedesc = sfd->fd->secret->md.osfd; + op.arg2.buffer = hdtrl; + op.arg3.file_spec.st_size = statbuf.st_size; + op.arg4.flags = send_flags; + op.nbytes_to_send = nbytes_to_send - count; + op.result.code = count; + op.timeout = timeout; + op.function = pt_hpux_sendfile_cont; + op.event = POLLOUT | POLLPRI; + count = pt_Continue(&op); + syserrno = op.syserrno; + } + + if (count == -1) { + pt_MapError(_MD_hpux_map_sendfile_error, syserrno); + return -1; + } + if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { + PR_Close(sd); + } + PR_ASSERT(count == nbytes_to_send); + return count; +} + +#endif /* HPUX11 */ + +#ifdef SOLARIS + +/* + * pt_SolarisSendFile + * + * Send file sfd->fd across socket sd. If specified, header and trailer + * buffers are sent before and after the file, respectively. + * + * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file + * + * return number of bytes sent or -1 on error + * + * This implementation takes advantage of the sendfilev() system + * call available in Solaris 8. + */ + +static PRInt32 pt_SolarisSendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + struct stat statbuf; + size_t nbytes_to_send, file_nbytes_to_send; + struct sendfilevec sfv_struct[3]; + int sfvcnt = 0; + size_t xferred; + PRInt32 count; + int syserrno; + + if (sfd->file_nbytes == 0) { + /* Get file size */ + if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { + _PR_MD_MAP_FSTAT_ERROR(errno); + return -1; + } + file_nbytes_to_send = statbuf.st_size - sfd->file_offset; + } else { + file_nbytes_to_send = sfd->file_nbytes; + } + + nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send; + + if (sfd->hlen != 0) { + sfv_struct[sfvcnt].sfv_fd = SFV_FD_SELF; + sfv_struct[sfvcnt].sfv_flag = 0; + sfv_struct[sfvcnt].sfv_off = (off_t) sfd->header; + sfv_struct[sfvcnt].sfv_len = sfd->hlen; + sfvcnt++; + } + + if (file_nbytes_to_send != 0) { + sfv_struct[sfvcnt].sfv_fd = sfd->fd->secret->md.osfd; + sfv_struct[sfvcnt].sfv_flag = 0; + sfv_struct[sfvcnt].sfv_off = sfd->file_offset; + sfv_struct[sfvcnt].sfv_len = file_nbytes_to_send; + sfvcnt++; + } + + if (sfd->tlen != 0) { + sfv_struct[sfvcnt].sfv_fd = SFV_FD_SELF; + sfv_struct[sfvcnt].sfv_flag = 0; + sfv_struct[sfvcnt].sfv_off = (off_t) sfd->trailer; + sfv_struct[sfvcnt].sfv_len = sfd->tlen; + sfvcnt++; + } + + if (0 == sfvcnt) { + count = 0; + goto done; + } + + /* + * Strictly speaking, we may have sent some bytes when the + * sendfilev() is interrupted and we should retry it from an + * updated offset. We are not doing that here. + */ + count = SOLARIS_SENDFILEV(sd->secret->md.osfd, sfv_struct, + sfvcnt, &xferred); + + PR_ASSERT((count == -1) || (count == xferred)); + + if (count == -1) { + syserrno = errno; + if (syserrno == EINTR + || syserrno == EAGAIN || syserrno == EWOULDBLOCK) { + count = xferred; + } + } else if (count == 0) { + /* + * We are now at EOF. The file was truncated. Solaris sendfile is + * supposed to return 0 and no error in this case, though some versions + * may return -1 and EINVAL . + */ + count = -1; + syserrno = 0; /* will be treated as EOF */ + } + + if (count != -1 && count < nbytes_to_send) { + pt_Continuation op; + struct sendfilevec *vec = sfv_struct; + PRInt32 rem = count; + + while (rem >= vec->sfv_len) { + rem -= vec->sfv_len; + vec++; + sfvcnt--; + } + PR_ASSERT(sfvcnt > 0); + + vec->sfv_off += rem; + vec->sfv_len -= rem; + PR_ASSERT(vec->sfv_len > 0); + + op.arg1.osfd = sd->secret->md.osfd; + op.arg2.buffer = vec; + op.arg3.amount = sfvcnt; + op.arg4.flags = 0; + op.nbytes_to_send = nbytes_to_send - count; + op.result.code = count; + op.timeout = timeout; + op.function = pt_solaris_sendfile_cont; + op.event = POLLOUT | POLLPRI; + count = pt_Continue(&op); + syserrno = op.syserrno; + } + +done: + if (count == -1) { + pt_MapError(_MD_solaris_map_sendfile_error, syserrno); + return -1; + } + if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { + PR_Close(sd); + } + PR_ASSERT(count == nbytes_to_send); + return count; +} + +#ifndef HAVE_SENDFILEV +static pthread_once_t pt_solaris_sendfilev_once_block = PTHREAD_ONCE_INIT; + +static void pt_solaris_sendfilev_init_routine(void) +{ + void *handle; + PRBool close_it = PR_FALSE; + + /* + * We do not want to unload libsendfile.so. This handle is leaked + * intentionally. + */ + handle = dlopen("libsendfile.so", RTLD_LAZY | RTLD_GLOBAL); + PR_LOG(_pr_io_lm, PR_LOG_DEBUG, + ("dlopen(libsendfile.so) returns %p", handle)); + + if (NULL == handle) { + /* + * The dlopen(0, mode) call is to allow for the possibility that + * sendfilev() may become part of a standard system library in a + * future Solaris release. + */ + handle = dlopen(0, RTLD_LAZY | RTLD_GLOBAL); + PR_LOG(_pr_io_lm, PR_LOG_DEBUG, + ("dlopen(0) returns %p", handle)); + close_it = PR_TRUE; + } + pt_solaris_sendfilev_fptr = (ssize_t (*)()) dlsym(handle, "sendfilev"); + PR_LOG(_pr_io_lm, PR_LOG_DEBUG, + ("dlsym(sendfilev) returns %p", pt_solaris_sendfilev_fptr)); + + if (close_it) { + dlclose(handle); + } +} + +/* + * pt_SolarisDispatchSendFile + */ +static PRInt32 pt_SolarisDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + int rv; + + rv = pthread_once(&pt_solaris_sendfilev_once_block, + pt_solaris_sendfilev_init_routine); + PR_ASSERT(0 == rv); + if (pt_solaris_sendfilev_fptr) { + return pt_SolarisSendFile(sd, sfd, flags, timeout); + } else { + return PR_EmulateSendFile(sd, sfd, flags, timeout); + } +} +#endif /* !HAVE_SENDFILEV */ + +#endif /* SOLARIS */ + +#ifdef LINUX +/* + * pt_LinuxSendFile + * + * Send file sfd->fd across socket sd. If specified, header and trailer + * buffers are sent before and after the file, respectively. + * + * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file + * + * return number of bytes sent or -1 on error + * + * This implementation takes advantage of the sendfile() system + * call available in Linux kernel 2.2 or higher. + */ + +static PRInt32 pt_LinuxSendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + struct stat statbuf; + size_t file_nbytes_to_send; + PRInt32 count = 0; + ssize_t rv; + int syserrno; + off_t offset; + PRBool tcp_cork_enabled = PR_FALSE; + int tcp_cork; + + if (sfd->file_nbytes == 0) { + /* Get file size */ + if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) { + _PR_MD_MAP_FSTAT_ERROR(errno); + return -1; + } + file_nbytes_to_send = statbuf.st_size - sfd->file_offset; + } else { + file_nbytes_to_send = sfd->file_nbytes; + } + + if ((sfd->hlen != 0 || sfd->tlen != 0) + && sd->secret->md.tcp_nodelay == 0) { + tcp_cork = 1; + if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK, + &tcp_cork, sizeof tcp_cork) == 0) { + tcp_cork_enabled = PR_TRUE; + } else { + syserrno = errno; + if (syserrno != EINVAL) { + _PR_MD_MAP_SETSOCKOPT_ERROR(syserrno); + return -1; + } + /* + * The most likely reason for the EINVAL error is that + * TCP_NODELAY is set (with a function other than + * PR_SetSocketOption). This is not fatal, so we keep + * on going. + */ + PR_LOG(_pr_io_lm, PR_LOG_WARNING, + ("pt_LinuxSendFile: " + "setsockopt(TCP_CORK) failed with EINVAL\n")); + } + } + + if (sfd->hlen != 0) { + count = PR_Send(sd, sfd->header, sfd->hlen, 0, timeout); + if (count == -1) { + goto failed; + } + } + + if (file_nbytes_to_send != 0) { + offset = sfd->file_offset; + do { + rv = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd, + &offset, file_nbytes_to_send); + } while (rv == -1 && (syserrno = errno) == EINTR); + if (rv == -1) { + if (syserrno != EAGAIN && syserrno != EWOULDBLOCK) { + _MD_linux_map_sendfile_error(syserrno); + count = -1; + goto failed; + } + rv = 0; + } + PR_ASSERT(rv == offset - sfd->file_offset); + count += rv; + + if (rv < file_nbytes_to_send) { + pt_Continuation op; + + op.arg1.osfd = sd->secret->md.osfd; + op.in_fd = sfd->fd->secret->md.osfd; + op.offset = offset; + op.count = file_nbytes_to_send - rv; + op.result.code = count; + op.timeout = timeout; + op.function = pt_linux_sendfile_cont; + op.event = POLLOUT | POLLPRI; + count = pt_Continue(&op); + syserrno = op.syserrno; + if (count == -1) { + pt_MapError(_MD_linux_map_sendfile_error, syserrno); + goto failed; + } + } + } + + if (sfd->tlen != 0) { + rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout); + if (rv == -1) { + count = -1; + goto failed; + } + count += rv; + } + +failed: + if (tcp_cork_enabled) { + tcp_cork = 0; + if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK, + &tcp_cork, sizeof tcp_cork) == -1 && count != -1) { + _PR_MD_MAP_SETSOCKOPT_ERROR(errno); + count = -1; + } + } + if (count != -1) { + if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) { + PR_Close(sd); + } + PR_ASSERT(count == sfd->hlen + sfd->tlen + file_nbytes_to_send); + } + return count; +} +#endif /* LINUX */ + +#ifdef AIX +extern int _pr_aix_send_file_use_disabled; +#endif + +static PRInt32 pt_SendFile( + PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + if (pt_TestAbort()) return -1; + /* The socket must be in blocking mode. */ + if (sd->secret->nonblocking) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } +#ifdef HPUX11 + return(pt_HPUXSendFile(sd, sfd, flags, timeout)); +#elif defined(AIX) +#ifdef HAVE_SEND_FILE + /* + * A bug in AIX 4.3.2 results in corruption of data transferred by + * send_file(); AIX patch PTF U463956 contains the fix. A user can + * disable the use of send_file function in NSPR, when this patch is + * not installed on the system, by setting the envionment variable + * NSPR_AIX_SEND_FILE_USE_DISABLED to 1. + */ + if (_pr_aix_send_file_use_disabled) + return(PR_EmulateSendFile(sd, sfd, flags, timeout)); + else + return(pt_AIXSendFile(sd, sfd, flags, timeout)); +#else + return(PR_EmulateSendFile(sd, sfd, flags, timeout)); + /* return(pt_AIXDispatchSendFile(sd, sfd, flags, timeout));*/ +#endif /* HAVE_SEND_FILE */ +#elif defined(SOLARIS) +#ifdef HAVE_SENDFILEV + return(pt_SolarisSendFile(sd, sfd, flags, timeout)); +#else + return(pt_SolarisDispatchSendFile(sd, sfd, flags, timeout)); +#endif /* HAVE_SENDFILEV */ +#elif defined(LINUX) + return(pt_LinuxSendFile(sd, sfd, flags, timeout)); +#else + return(PR_EmulateSendFile(sd, sfd, flags, timeout)); +#endif +} + +static PRInt32 pt_TransmitFile( + PRFileDesc *sd, PRFileDesc *fd, const void *headers, + PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + PRSendFileData sfd; + + sfd.fd = fd; + sfd.file_offset = 0; + sfd.file_nbytes = 0; + sfd.header = headers; + sfd.hlen = hlen; + sfd.trailer = NULL; + sfd.tlen = 0; + + return(pt_SendFile(sd, &sfd, flags, timeout)); +} /* pt_TransmitFile */ + +static PRInt32 pt_AcceptRead( + PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, + void *buf, PRInt32 amount, PRIntervalTime timeout) +{ + PRInt32 rv = -1; + + if (pt_TestAbort()) return rv; + /* The socket must be in blocking mode. */ + if (sd->secret->nonblocking) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return rv; + } + + rv = PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout); + return rv; +} /* pt_AcceptRead */ + +static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr) +{ + PRIntn rv = -1; + pt_SockLen addr_len = sizeof(PRNetAddr); + + if (pt_TestAbort()) return PR_FAILURE; + + rv = getsockname( + fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len); + if (rv == -1) { + pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno); + return PR_FAILURE; + } else { +#ifdef _PR_HAVE_SOCKADDR_LEN + /* ignore the sa_len field of struct sockaddr */ + if (addr) + { + addr->raw.family = ((struct sockaddr*)addr)->sa_family; + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ +#ifdef _PR_INET6 + if (AF_INET6 == addr->raw.family) + addr->raw.family = PR_AF_INET6; +#endif + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); + return PR_SUCCESS; + } +} /* pt_GetSockName */ + +static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) +{ + PRIntn rv = -1; + pt_SockLen addr_len = sizeof(PRNetAddr); + + if (pt_TestAbort()) return PR_FAILURE; + + rv = getpeername( + fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len); + + if (rv == -1) { + pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno); + return PR_FAILURE; + } else { +#ifdef _PR_HAVE_SOCKADDR_LEN + /* ignore the sa_len field of struct sockaddr */ + if (addr) + { + addr->raw.family = ((struct sockaddr*)addr)->sa_family; + } +#endif /* _PR_HAVE_SOCKADDR_LEN */ +#ifdef _PR_INET6 + if (AF_INET6 == addr->raw.family) + addr->raw.family = PR_AF_INET6; +#endif + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); + return PR_SUCCESS; + } +} /* pt_GetPeerName */ + +static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data) +{ + PRIntn rv; + pt_SockLen length; + PRInt32 level, name; + + /* + * PR_SockOpt_Nonblocking is a special case that does not + * translate to a getsockopt() call + */ + if (PR_SockOpt_Nonblocking == data->option) + { + data->value.non_blocking = fd->secret->nonblocking; + return PR_SUCCESS; + } + + rv = _PR_MapOptionName(data->option, &level, &name); + if (PR_SUCCESS == rv) + { + switch (data->option) + { + case PR_SockOpt_Linger: + { + struct linger linger; + length = sizeof(linger); + rv = getsockopt( + fd->secret->md.osfd, level, name, (char *) &linger, &length); + PR_ASSERT((-1 == rv) || (sizeof(linger) == length)); + data->value.linger.polarity = + (linger.l_onoff) ? PR_TRUE : PR_FALSE; + data->value.linger.linger = + PR_SecondsToInterval(linger.l_linger); + break; + } + case PR_SockOpt_Reuseaddr: + case PR_SockOpt_Keepalive: + case PR_SockOpt_NoDelay: + case PR_SockOpt_Broadcast: + case PR_SockOpt_Reuseport: + { + PRIntn value; + length = sizeof(PRIntn); + rv = getsockopt( + fd->secret->md.osfd, level, name, (char*)&value, &length); + PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length)); + data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE; + break; + } + case PR_SockOpt_McastLoopback: + { + PRUint8 xbool; + length = sizeof(xbool); + rv = getsockopt( + fd->secret->md.osfd, level, name, + (char*)&xbool, &length); + PR_ASSERT((-1 == rv) || (sizeof(xbool) == length)); + data->value.mcast_loopback = (0 == xbool) ? PR_FALSE : PR_TRUE; + break; + } + case PR_SockOpt_RecvBufferSize: + case PR_SockOpt_SendBufferSize: + case PR_SockOpt_MaxSegment: + { + PRIntn value; + length = sizeof(PRIntn); + rv = getsockopt( + fd->secret->md.osfd, level, name, (char*)&value, &length); + PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length)); + data->value.recv_buffer_size = value; + break; + } + case PR_SockOpt_IpTimeToLive: + case PR_SockOpt_IpTypeOfService: + { + length = sizeof(PRUintn); + rv = getsockopt( + fd->secret->md.osfd, level, name, + (char*)&data->value.ip_ttl, &length); + PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length)); + break; + } + case PR_SockOpt_McastTimeToLive: + { + PRUint8 ttl; + length = sizeof(ttl); + rv = getsockopt( + fd->secret->md.osfd, level, name, + (char*)&ttl, &length); + PR_ASSERT((-1 == rv) || (sizeof(ttl) == length)); + data->value.mcast_ttl = ttl; + break; + } + case PR_SockOpt_AddMember: + case PR_SockOpt_DropMember: + { + struct ip_mreq mreq; + length = sizeof(mreq); + rv = getsockopt( + fd->secret->md.osfd, level, name, (char*)&mreq, &length); + PR_ASSERT((-1 == rv) || (sizeof(mreq) == length)); + data->value.add_member.mcaddr.inet.ip = + mreq.imr_multiaddr.s_addr; + data->value.add_member.ifaddr.inet.ip = + mreq.imr_interface.s_addr; + break; + } + case PR_SockOpt_McastInterface: + { + length = sizeof(data->value.mcast_if.inet.ip); + rv = getsockopt( + fd->secret->md.osfd, level, name, + (char*)&data->value.mcast_if.inet.ip, &length); + PR_ASSERT((-1 == rv) + || (sizeof(data->value.mcast_if.inet.ip) == length)); + break; + } + default: + PR_NOT_REACHED("Unknown socket option"); + break; + } + if (-1 == rv) _PR_MD_MAP_GETSOCKOPT_ERROR(errno); + } + return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; +} /* pt_GetSocketOption */ + +static PRStatus pt_SetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data) +{ + PRIntn rv; + PRInt32 level, name; + + /* + * PR_SockOpt_Nonblocking is a special case that does not + * translate to a setsockopt call. + */ + if (PR_SockOpt_Nonblocking == data->option) + { + fd->secret->nonblocking = data->value.non_blocking; + return PR_SUCCESS; + } + + rv = _PR_MapOptionName(data->option, &level, &name); + if (PR_SUCCESS == rv) + { + switch (data->option) + { + case PR_SockOpt_Linger: + { + struct linger linger; + linger.l_onoff = data->value.linger.polarity; + linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger); + rv = setsockopt( + fd->secret->md.osfd, level, name, (char*)&linger, sizeof(linger)); + break; + } + case PR_SockOpt_Reuseaddr: + case PR_SockOpt_Keepalive: + case PR_SockOpt_NoDelay: + case PR_SockOpt_Broadcast: + case PR_SockOpt_Reuseport: + { + PRIntn value = (data->value.reuse_addr) ? 1 : 0; + rv = setsockopt( + fd->secret->md.osfd, level, name, + (char*)&value, sizeof(PRIntn)); +#ifdef LINUX + /* for pt_LinuxSendFile */ + if (name == TCP_NODELAY && rv == 0) { + fd->secret->md.tcp_nodelay = value; + } +#endif + break; + } + case PR_SockOpt_McastLoopback: + { + PRUint8 xbool = data->value.mcast_loopback ? 1 : 0; + rv = setsockopt( + fd->secret->md.osfd, level, name, + (char*)&xbool, sizeof(xbool)); + break; + } + case PR_SockOpt_RecvBufferSize: + case PR_SockOpt_SendBufferSize: + case PR_SockOpt_MaxSegment: + { + PRIntn value = data->value.recv_buffer_size; + rv = setsockopt( + fd->secret->md.osfd, level, name, + (char*)&value, sizeof(PRIntn)); + break; + } + case PR_SockOpt_IpTimeToLive: + case PR_SockOpt_IpTypeOfService: + { + rv = setsockopt( + fd->secret->md.osfd, level, name, + (char*)&data->value.ip_ttl, sizeof(PRUintn)); + break; + } + case PR_SockOpt_McastTimeToLive: + { + PRUint8 ttl = data->value.mcast_ttl; + rv = setsockopt( + fd->secret->md.osfd, level, name, + (char*)&ttl, sizeof(ttl)); + break; + } + case PR_SockOpt_AddMember: + case PR_SockOpt_DropMember: + { + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = + data->value.add_member.mcaddr.inet.ip; + mreq.imr_interface.s_addr = + data->value.add_member.ifaddr.inet.ip; + rv = setsockopt( + fd->secret->md.osfd, level, name, + (char*)&mreq, sizeof(mreq)); + break; + } + case PR_SockOpt_McastInterface: + { + rv = setsockopt( + fd->secret->md.osfd, level, name, + (char*)&data->value.mcast_if.inet.ip, + sizeof(data->value.mcast_if.inet.ip)); + break; + } + default: + PR_NOT_REACHED("Unknown socket option"); + break; + } + if (-1 == rv) _PR_MD_MAP_SETSOCKOPT_ERROR(errno); + } + return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; +} /* pt_SetSocketOption */ + +/*****************************************************************************/ +/****************************** I/O method objects ***************************/ +/*****************************************************************************/ + +static PRIOMethods _pr_file_methods = { + PR_DESC_FILE, + pt_Close, + pt_Read, + pt_Write, + pt_Available_f, + pt_Available64_f, + pt_Fsync, + pt_Seek, + pt_Seek64, + pt_FileInfo, + pt_FileInfo64, + (PRWritevFN)_PR_InvalidInt, + (PRConnectFN)_PR_InvalidStatus, + (PRAcceptFN)_PR_InvalidDesc, + (PRBindFN)_PR_InvalidStatus, + (PRListenFN)_PR_InvalidStatus, + (PRShutdownFN)_PR_InvalidStatus, + (PRRecvFN)_PR_InvalidInt, + (PRSendFN)_PR_InvalidInt, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + pt_Poll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + (PRGetsocknameFN)_PR_InvalidStatus, + (PRGetpeernameFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRGetsocketoptionFN)_PR_InvalidStatus, + (PRSetsocketoptionFN)_PR_InvalidStatus, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +static PRIOMethods _pr_pipe_methods = { + PR_DESC_PIPE, + pt_Close, + pt_Read, + pt_Write, + pt_Available_s, + pt_Available64_s, + pt_Synch, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + (PRWritevFN)_PR_InvalidInt, + (PRConnectFN)_PR_InvalidStatus, + (PRAcceptFN)_PR_InvalidDesc, + (PRBindFN)_PR_InvalidStatus, + (PRListenFN)_PR_InvalidStatus, + (PRShutdownFN)_PR_InvalidStatus, + (PRRecvFN)_PR_InvalidInt, + (PRSendFN)_PR_InvalidInt, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + pt_Poll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + (PRGetsocknameFN)_PR_InvalidStatus, + (PRGetpeernameFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRGetsocketoptionFN)_PR_InvalidStatus, + (PRSetsocketoptionFN)_PR_InvalidStatus, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +static PRIOMethods _pr_tcp_methods = { + PR_DESC_SOCKET_TCP, + pt_Close, + pt_SocketRead, + pt_SocketWrite, + pt_Available_s, + pt_Available64_s, + pt_Synch, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + pt_Writev, + pt_Connect, + pt_Accept, + pt_Bind, + pt_Listen, + pt_Shutdown, + pt_Recv, + pt_Send, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + pt_Poll, + pt_AcceptRead, + pt_TransmitFile, + pt_GetSockName, + pt_GetPeerName, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + pt_GetSocketOption, + pt_SetSocketOption, + pt_SendFile, + pt_ConnectContinue, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +static PRIOMethods _pr_udp_methods = { + PR_DESC_SOCKET_UDP, + pt_Close, + pt_SocketRead, + pt_SocketWrite, + pt_Available_s, + pt_Available64_s, + pt_Synch, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + pt_Writev, + pt_Connect, + (PRAcceptFN)_PR_InvalidDesc, + pt_Bind, + pt_Listen, + pt_Shutdown, + pt_Recv, + pt_Send, + pt_RecvFrom, + pt_SendTo, + pt_Poll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + pt_GetSockName, + pt_GetPeerName, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + pt_GetSocketOption, + pt_SetSocketOption, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +static PRIOMethods _pr_socketpollfd_methods = { + (PRDescType) 0, + (PRCloseFN)_PR_InvalidStatus, + (PRReadFN)_PR_InvalidInt, + (PRWriteFN)_PR_InvalidInt, + (PRAvailableFN)_PR_InvalidInt, + (PRAvailable64FN)_PR_InvalidInt64, + (PRFsyncFN)_PR_InvalidStatus, + (PRSeekFN)_PR_InvalidInt, + (PRSeek64FN)_PR_InvalidInt64, + (PRFileInfoFN)_PR_InvalidStatus, + (PRFileInfo64FN)_PR_InvalidStatus, + (PRWritevFN)_PR_InvalidInt, + (PRConnectFN)_PR_InvalidStatus, + (PRAcceptFN)_PR_InvalidDesc, + (PRBindFN)_PR_InvalidStatus, + (PRListenFN)_PR_InvalidStatus, + (PRShutdownFN)_PR_InvalidStatus, + (PRRecvFN)_PR_InvalidInt, + (PRSendFN)_PR_InvalidInt, + (PRRecvfromFN)_PR_InvalidInt, + (PRSendtoFN)_PR_InvalidInt, + pt_Poll, + (PRAcceptreadFN)_PR_InvalidInt, + (PRTransmitfileFN)_PR_InvalidInt, + (PRGetsocknameFN)_PR_InvalidStatus, + (PRGetpeernameFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRGetsocketoptionFN)_PR_InvalidStatus, + (PRSetsocketoptionFN)_PR_InvalidStatus, + (PRSendfileFN)_PR_InvalidInt, + (PRConnectcontinueFN)_PR_InvalidStatus, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt, + (PRReservedFN)_PR_InvalidInt +}; + +#if defined(HPUX) || defined(OSF1) || defined(SOLARIS) || defined (IRIX) \ + || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \ + || defined(AIX) || defined(FREEBSD) || defined(NETBSD) \ + || defined(OPENBSD) || defined(BSDI) || defined(NTO) \ + || defined(DARWIN) || defined(UNIXWARE) || defined(RISCOS) \ + || defined(SYMBIAN) +#define _PR_FCNTL_FLAGS O_NONBLOCK +#else +#error "Can't determine architecture" +#endif + +/* + * Put a Unix file descriptor in non-blocking mode. + */ +static void pt_MakeFdNonblock(PRIntn osfd) +{ + PRIntn flags; + flags = fcntl(osfd, F_GETFL, 0); + flags |= _PR_FCNTL_FLAGS; + (void)fcntl(osfd, F_SETFL, flags); +} + +/* + * Put a Unix socket fd in non-blocking mode that can + * ideally be inherited by an accepted socket. + * + * Why doesn't pt_MakeFdNonblock do? This is to deal with + * the special case of HP-UX. HP-UX has three kinds of + * non-blocking modes for sockets: the fcntl() O_NONBLOCK + * and O_NDELAY flags and ioctl() FIOSNBIO request. Only + * the ioctl() FIOSNBIO form of non-blocking mode is + * inherited by an accepted socket. + * + * Other platforms just use the generic pt_MakeFdNonblock + * to put a socket in non-blocking mode. + */ +#ifdef HPUX +static void pt_MakeSocketNonblock(PRIntn osfd) +{ + PRIntn one = 1; + (void)ioctl(osfd, FIOSNBIO, &one); +} +#else +#define pt_MakeSocketNonblock pt_MakeFdNonblock +#endif + +static PRFileDesc *pt_SetMethods( + PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported) +{ + PRFileDesc *fd = _PR_Getfd(); + + if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + else + { + fd->secret->md.osfd = osfd; + fd->secret->state = _PR_FILEDESC_OPEN; + if (imported) fd->secret->inheritable = _PR_TRI_UNKNOWN; + else + { + /* By default, a Unix fd is not closed on exec. */ +#ifdef DEBUG + PRIntn flags; + flags = fcntl(osfd, F_GETFD, 0); + PR_ASSERT(0 == flags); +#endif + fd->secret->inheritable = _PR_TRI_TRUE; + } + switch (type) + { + case PR_DESC_FILE: + fd->methods = PR_GetFileMethods(); + break; + case PR_DESC_SOCKET_TCP: + fd->methods = PR_GetTCPMethods(); +#ifdef _PR_ACCEPT_INHERIT_NONBLOCK + if (!isAcceptedSocket) pt_MakeSocketNonblock(osfd); +#else + pt_MakeSocketNonblock(osfd); +#endif + break; + case PR_DESC_SOCKET_UDP: + fd->methods = PR_GetUDPMethods(); + pt_MakeFdNonblock(osfd); + break; + case PR_DESC_PIPE: + fd->methods = PR_GetPipeMethods(); + pt_MakeFdNonblock(osfd); + break; + default: + break; + } + } + return fd; +} /* pt_SetMethods */ + +PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void) +{ + return &_pr_file_methods; +} /* PR_GetFileMethods */ + +PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void) +{ + return &_pr_pipe_methods; +} /* PR_GetPipeMethods */ + +PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods(void) +{ + return &_pr_tcp_methods; +} /* PR_GetTCPMethods */ + +PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods(void) +{ + return &_pr_udp_methods; +} /* PR_GetUDPMethods */ + +static const PRIOMethods* PR_GetSocketPollFdMethods(void) +{ + return &_pr_socketpollfd_methods; +} /* PR_GetSocketPollFdMethods */ + +PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc( + PRInt32 osfd, const PRIOMethods *methods) +{ + PRFileDesc *fd = _PR_Getfd(); + + if (NULL == fd) goto failed; + + fd->methods = methods; + fd->secret->md.osfd = osfd; + /* Make fd non-blocking */ + if (osfd > 2) + { + /* Don't mess around with stdin, stdout or stderr */ + if (&_pr_tcp_methods == methods) pt_MakeSocketNonblock(osfd); + else pt_MakeFdNonblock(osfd); + } + fd->secret->state = _PR_FILEDESC_OPEN; + fd->secret->inheritable = _PR_TRI_UNKNOWN; + return fd; + +failed: + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return fd; +} /* PR_AllocFileDesc */ + +#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE) +PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd); +#if defined(_PR_INET6_PROBE) +extern PRBool _pr_ipv6_is_present(void); +PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket() +{ + int osfd; + +#if defined(DARWIN) + /* + * Disable IPv6 if Darwin version is less than 7.0.0 (OS X 10.3). IPv6 on + * lesser versions is not ready for general use (see bug 222031). + */ + { + struct utsname u; + if (uname(&u) != 0 || atoi(u.release) < 7) + return PR_FALSE; + } +#endif + + /* + * HP-UX only: HP-UX IPv6 Porting Guide (dated February 2001) + * suggests that we call open("/dev/ip6", O_RDWR) to determine + * whether IPv6 APIs and the IPv6 stack are on the system. + * Our portable test below seems to work fine, so I am using it. + */ + osfd = socket(AF_INET6, SOCK_STREAM, 0); + if (osfd != -1) { + close(osfd); + return PR_TRUE; + } + return PR_FALSE; +} +#endif /* _PR_INET6_PROBE */ +#endif + +PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto) +{ + PRIntn osfd; + PRDescType ftype; + PRFileDesc *fd = NULL; +#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6) + PRInt32 tmp_domain = domain; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (pt_TestAbort()) return NULL; + + if (PF_INET != domain + && PR_AF_INET6 != domain +#if defined(_PR_HAVE_SDP) + && PR_AF_INET_SDP != domain +#if defined(SOLARIS) + && PR_AF_INET6_SDP != domain +#endif /* SOLARIS */ +#endif /* _PR_HAVE_SDP */ + && PF_UNIX != domain) + { + PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); + return fd; + } + if (type == SOCK_STREAM) ftype = PR_DESC_SOCKET_TCP; + else if (type == SOCK_DGRAM) ftype = PR_DESC_SOCKET_UDP; + else + { + (void)PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0); + return fd; + } +#if defined(_PR_HAVE_SDP) +#if defined(LINUX) + if (PR_AF_INET_SDP == domain) + domain = AF_INET_SDP; +#elif defined(SOLARIS) + if (PR_AF_INET_SDP == domain) { + domain = AF_INET; + proto = PROTO_SDP; + } else if(PR_AF_INET6_SDP == domain) { + domain = AF_INET6; + proto = PROTO_SDP; + } +#endif /* SOLARIS */ +#endif /* _PR_HAVE_SDP */ +#if defined(_PR_INET6_PROBE) + if (PR_AF_INET6 == domain) + domain = _pr_ipv6_is_present() ? AF_INET6 : AF_INET; +#elif defined(_PR_INET6) + if (PR_AF_INET6 == domain) + domain = AF_INET6; +#else + if (PR_AF_INET6 == domain) + domain = AF_INET; +#endif + + osfd = socket(domain, type, proto); + if (osfd == -1) pt_MapError(_PR_MD_MAP_SOCKET_ERROR, errno); + else + { +#ifdef _PR_IPV6_V6ONLY_PROBE + if ((domain == AF_INET6) && _pr_ipv6_v6only_on_by_default) + { + int on = 0; + (void)setsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY, + &on, sizeof(on)); + } +#endif + fd = pt_SetMethods(osfd, ftype, PR_FALSE, PR_FALSE); + if (fd == NULL) close(osfd); + } +#ifdef _PR_NEED_SECRET_AF + if (fd != NULL) fd->secret->af = domain; +#endif +#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6) + if (fd != NULL) { + /* + * For platforms with no support for IPv6 + * create layered socket for IPv4-mapped IPv6 addresses + */ + if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) { + if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) { + PR_Close(fd); + fd = NULL; + } + } + } +#endif + return fd; +} /* PR_Socket */ + +/*****************************************************************************/ +/****************************** I/O public methods ***************************/ +/*****************************************************************************/ + +PR_IMPLEMENT(PRFileDesc*) PR_OpenFile( + const char *name, PRIntn flags, PRIntn mode) +{ + PRFileDesc *fd = NULL; + PRIntn syserrno, osfd = -1, osflags = 0;; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (pt_TestAbort()) return NULL; + + if (flags & PR_RDONLY) osflags |= O_RDONLY; + if (flags & PR_WRONLY) osflags |= O_WRONLY; + if (flags & PR_RDWR) osflags |= O_RDWR; + if (flags & PR_APPEND) osflags |= O_APPEND; + if (flags & PR_TRUNCATE) osflags |= O_TRUNC; + if (flags & PR_EXCL) osflags |= O_EXCL; + if (flags & PR_SYNC) + { +#if defined(O_SYNC) + osflags |= O_SYNC; +#elif defined(O_FSYNC) + osflags |= O_FSYNC; +#else +#error "Neither O_SYNC nor O_FSYNC is defined on this platform" +#endif + } + + /* + ** We have to hold the lock across the creation in order to + ** enforce the sematics of PR_Rename(). (see the latter for + ** more details) + */ + if (flags & PR_CREATE_FILE) + { + osflags |= O_CREAT; + if (NULL !=_pr_rename_lock) + PR_Lock(_pr_rename_lock); + } + + osfd = _md_iovector._open64(name, osflags, mode); + syserrno = errno; + + if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock)) + PR_Unlock(_pr_rename_lock); + + if (osfd == -1) + pt_MapError(_PR_MD_MAP_OPEN_ERROR, syserrno); + else + { + fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_FALSE); + if (fd == NULL) close(osfd); /* $$$ whoops! this is bad $$$ */ + } + return fd; +} /* PR_OpenFile */ + +PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode) +{ + return PR_OpenFile(name, flags, mode); +} /* PR_Open */ + +PR_IMPLEMENT(PRStatus) PR_Delete(const char *name) +{ + PRIntn rv = -1; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (pt_TestAbort()) return PR_FAILURE; + + rv = unlink(name); + + if (rv == -1) { + pt_MapError(_PR_MD_MAP_UNLINK_ERROR, errno); + return PR_FAILURE; + } else + return PR_SUCCESS; +} /* PR_Delete */ + +PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how) +{ + PRIntn rv; + + if (pt_TestAbort()) return PR_FAILURE; + + switch (how) + { + case PR_ACCESS_READ_OK: + rv = access(name, R_OK); + break; + case PR_ACCESS_WRITE_OK: + rv = access(name, W_OK); + break; + case PR_ACCESS_EXISTS: + default: + rv = access(name, F_OK); + } + if (0 == rv) return PR_SUCCESS; + pt_MapError(_PR_MD_MAP_ACCESS_ERROR, errno); + return PR_FAILURE; + +} /* PR_Access */ + +PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info) +{ + PRInt32 rv = _PR_MD_GETFILEINFO(fn, info); + return (0 == rv) ? PR_SUCCESS : PR_FAILURE; +} /* PR_GetFileInfo */ + +PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info) +{ + PRInt32 rv; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + rv = _PR_MD_GETFILEINFO64(fn, info); + return (0 == rv) ? PR_SUCCESS : PR_FAILURE; +} /* PR_GetFileInfo64 */ + +PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to) +{ + PRIntn rv = -1; + + if (pt_TestAbort()) return PR_FAILURE; + + /* + ** We have to acquire a lock here to stiffle anybody trying to create + ** a new file at the same time. And we have to hold that lock while we + ** test to see if the file exists and do the rename. The other place + ** where the lock is held is in PR_Open() when possibly creating a + ** new file. + */ + + PR_Lock(_pr_rename_lock); + rv = access(to, F_OK); + if (0 == rv) + { + PR_SetError(PR_FILE_EXISTS_ERROR, 0); + rv = -1; + } + else + { + rv = rename(from, to); + if (rv == -1) + pt_MapError(_PR_MD_MAP_RENAME_ERROR, errno); + } + PR_Unlock(_pr_rename_lock); + return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; +} /* PR_Rename */ + +PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir) +{ + if (pt_TestAbort()) return PR_FAILURE; + + if (NULL != dir->md.d) + { + if (closedir(dir->md.d) == -1) + { + _PR_MD_MAP_CLOSEDIR_ERROR(errno); + return PR_FAILURE; + } + dir->md.d = NULL; + PR_DELETE(dir); + } + return PR_SUCCESS; +} /* PR_CloseDir */ + +PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode) +{ + PRInt32 rv = -1; + + if (pt_TestAbort()) return PR_FAILURE; + + /* + ** This lock is used to enforce rename semantics as described + ** in PR_Rename. + */ + if (NULL !=_pr_rename_lock) + PR_Lock(_pr_rename_lock); + rv = mkdir(name, mode); + if (-1 == rv) + pt_MapError(_PR_MD_MAP_MKDIR_ERROR, errno); + if (NULL !=_pr_rename_lock) + PR_Unlock(_pr_rename_lock); + + return (-1 == rv) ? PR_FAILURE : PR_SUCCESS; +} /* PR_Makedir */ + +PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode) +{ + return PR_MakeDir(name, mode); +} /* PR_Mkdir */ + +PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name) +{ + PRInt32 rv; + + if (pt_TestAbort()) return PR_FAILURE; + + rv = rmdir(name); + if (0 == rv) { + return PR_SUCCESS; + } else { + pt_MapError(_PR_MD_MAP_RMDIR_ERROR, errno); + return PR_FAILURE; + } +} /* PR_Rmdir */ + + +PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name) +{ + DIR *osdir; + PRDir *dir = NULL; + + if (pt_TestAbort()) return dir; + + osdir = opendir(name); + if (osdir == NULL) + pt_MapError(_PR_MD_MAP_OPENDIR_ERROR, errno); + else + { + dir = PR_NEWZAP(PRDir); + if (dir) + dir->md.d = osdir; + else + (void)closedir(osdir); + } + return dir; +} /* PR_OpenDir */ + +static PRInt32 _pr_poll_with_poll( + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + PRInt32 ready = 0; + /* + * For restarting poll() if it is interrupted by a signal. + * We use these variables to figure out how much time has + * elapsed and how much of the timeout still remains. + */ + PRIntervalTime start, elapsed, remaining; + + if (pt_TestAbort()) return -1; + + if (0 == npds) PR_Sleep(timeout); + else + { +#define STACK_POLL_DESC_COUNT 64 + struct pollfd stack_syspoll[STACK_POLL_DESC_COUNT]; + struct pollfd *syspoll; + PRIntn index, msecs; + + if (npds <= STACK_POLL_DESC_COUNT) + { + syspoll = stack_syspoll; + } + else + { + PRThread *me = PR_GetCurrentThread(); + if (npds > me->syspoll_count) + { + PR_Free(me->syspoll_list); + me->syspoll_list = + (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd)); + if (NULL == me->syspoll_list) + { + me->syspoll_count = 0; + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + me->syspoll_count = npds; + } + syspoll = me->syspoll_list; + } + + for (index = 0; index < npds; ++index) + { + PRInt16 in_flags_read = 0, in_flags_write = 0; + PRInt16 out_flags_read = 0, out_flags_write = 0; + + if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) + { + if (pds[index].in_flags & PR_POLL_READ) + { + in_flags_read = (pds[index].fd->methods->poll)( + pds[index].fd, + pds[index].in_flags & ~PR_POLL_WRITE, + &out_flags_read); + } + if (pds[index].in_flags & PR_POLL_WRITE) + { + in_flags_write = (pds[index].fd->methods->poll)( + pds[index].fd, + pds[index].in_flags & ~PR_POLL_READ, + &out_flags_write); + } + if ((0 != (in_flags_read & out_flags_read)) + || (0 != (in_flags_write & out_flags_write))) + { + /* this one is ready right now */ + if (0 == ready) + { + /* + * We will return without calling the system + * poll function. So zero the out_flags + * fields of all the poll descriptors before + * this one. + */ + int i; + for (i = 0; i < index; i++) + { + pds[i].out_flags = 0; + } + } + ready += 1; + pds[index].out_flags = out_flags_read | out_flags_write; + } + else + { + /* now locate the NSPR layer at the bottom of the stack */ + PRFileDesc *bottom = PR_GetIdentitiesLayer( + pds[index].fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); /* what to do about that? */ + pds[index].out_flags = 0; /* pre-condition */ + if ((NULL != bottom) + && (_PR_FILEDESC_OPEN == bottom->secret->state)) + { + if (0 == ready) + { + syspoll[index].fd = bottom->secret->md.osfd; + syspoll[index].events = 0; + if (in_flags_read & PR_POLL_READ) + { + pds[index].out_flags |= + _PR_POLL_READ_SYS_READ; + syspoll[index].events |= POLLIN; + } + if (in_flags_read & PR_POLL_WRITE) + { + pds[index].out_flags |= + _PR_POLL_READ_SYS_WRITE; + syspoll[index].events |= POLLOUT; + } + if (in_flags_write & PR_POLL_READ) + { + pds[index].out_flags |= + _PR_POLL_WRITE_SYS_READ; + syspoll[index].events |= POLLIN; + } + if (in_flags_write & PR_POLL_WRITE) + { + pds[index].out_flags |= + _PR_POLL_WRITE_SYS_WRITE; + syspoll[index].events |= POLLOUT; + } + if (pds[index].in_flags & PR_POLL_EXCEPT) + syspoll[index].events |= POLLPRI; + } + } + else + { + if (0 == ready) + { + int i; + for (i = 0; i < index; i++) + { + pds[i].out_flags = 0; + } + } + ready += 1; /* this will cause an abrupt return */ + pds[index].out_flags = PR_POLL_NVAL; /* bogii */ + } + } + } + else + { + /* make poll() ignore this entry */ + syspoll[index].fd = -1; + syspoll[index].events = 0; + pds[index].out_flags = 0; + } + } + if (0 == ready) + { + switch (timeout) + { + case PR_INTERVAL_NO_WAIT: msecs = 0; break; + case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break; + default: + msecs = PR_IntervalToMilliseconds(timeout); + start = PR_IntervalNow(); + } + +retry: + ready = poll(syspoll, npds, msecs); + if (-1 == ready) + { + PRIntn oserror = errno; + + if (EINTR == oserror) + { + if (timeout == PR_INTERVAL_NO_TIMEOUT) + goto retry; + else if (timeout == PR_INTERVAL_NO_WAIT) + ready = 0; /* don't retry, just time out */ + else + { + elapsed = (PRIntervalTime) (PR_IntervalNow() + - start); + if (elapsed > timeout) + ready = 0; /* timed out */ + else + { + remaining = timeout - elapsed; + msecs = PR_IntervalToMilliseconds(remaining); + goto retry; + } + } + } + else + { + _PR_MD_MAP_POLL_ERROR(oserror); + } + } + else if (ready > 0) + { + for (index = 0; index < npds; ++index) + { + PRInt16 out_flags = 0; + if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) + { + if (0 != syspoll[index].revents) + { + if (syspoll[index].revents & POLLIN) + { + if (pds[index].out_flags + & _PR_POLL_READ_SYS_READ) + { + out_flags |= PR_POLL_READ; + } + if (pds[index].out_flags + & _PR_POLL_WRITE_SYS_READ) + { + out_flags |= PR_POLL_WRITE; + } + } + if (syspoll[index].revents & POLLOUT) + { + if (pds[index].out_flags + & _PR_POLL_READ_SYS_WRITE) + { + out_flags |= PR_POLL_READ; + } + if (pds[index].out_flags + & _PR_POLL_WRITE_SYS_WRITE) + { + out_flags |= PR_POLL_WRITE; + } + } + if (syspoll[index].revents & POLLPRI) + out_flags |= PR_POLL_EXCEPT; + if (syspoll[index].revents & POLLERR) + out_flags |= PR_POLL_ERR; + if (syspoll[index].revents & POLLNVAL) + out_flags |= PR_POLL_NVAL; + if (syspoll[index].revents & POLLHUP) + out_flags |= PR_POLL_HUP; + } + } + pds[index].out_flags = out_flags; + } + } + } + } + return ready; + +} /* _pr_poll_with_poll */ + +#if defined(_PR_POLL_WITH_SELECT) +/* + * OSF1 and HPUX report the POLLHUP event for a socket when the + * shutdown(SHUT_WR) operation is called for the remote end, even though + * the socket is still writeable. Use select(), instead of poll(), to + * workaround this problem. + */ +static PRInt32 _pr_poll_with_select( + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ + PRInt32 ready = 0; + /* + * For restarting select() if it is interrupted by a signal. + * We use these variables to figure out how much time has + * elapsed and how much of the timeout still remains. + */ + PRIntervalTime start, elapsed, remaining; + + if (pt_TestAbort()) return -1; + + if (0 == npds) PR_Sleep(timeout); + else + { +#define STACK_POLL_DESC_COUNT 64 + int stack_selectfd[STACK_POLL_DESC_COUNT]; + int *selectfd; + fd_set rd, wr, ex, *rdp = NULL, *wrp = NULL, *exp = NULL; + struct timeval tv, *tvp; + PRIntn index, msecs, maxfd = 0; + + if (npds <= STACK_POLL_DESC_COUNT) + { + selectfd = stack_selectfd; + } + else + { + PRThread *me = PR_GetCurrentThread(); + if (npds > me->selectfd_count) + { + PR_Free(me->selectfd_list); + me->selectfd_list = (int *)PR_MALLOC(npds * sizeof(int)); + if (NULL == me->selectfd_list) + { + me->selectfd_count = 0; + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return -1; + } + me->selectfd_count = npds; + } + selectfd = me->selectfd_list; + } + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); + + for (index = 0; index < npds; ++index) + { + PRInt16 in_flags_read = 0, in_flags_write = 0; + PRInt16 out_flags_read = 0, out_flags_write = 0; + + if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) + { + if (pds[index].in_flags & PR_POLL_READ) + { + in_flags_read = (pds[index].fd->methods->poll)( + pds[index].fd, + pds[index].in_flags & ~PR_POLL_WRITE, + &out_flags_read); + } + if (pds[index].in_flags & PR_POLL_WRITE) + { + in_flags_write = (pds[index].fd->methods->poll)( + pds[index].fd, + pds[index].in_flags & ~PR_POLL_READ, + &out_flags_write); + } + if ((0 != (in_flags_read & out_flags_read)) + || (0 != (in_flags_write & out_flags_write))) + { + /* this one is ready right now */ + if (0 == ready) + { + /* + * We will return without calling the system + * poll function. So zero the out_flags + * fields of all the poll descriptors before + * this one. + */ + int i; + for (i = 0; i < index; i++) + { + pds[i].out_flags = 0; + } + } + ready += 1; + pds[index].out_flags = out_flags_read | out_flags_write; + } + else + { + /* now locate the NSPR layer at the bottom of the stack */ + PRFileDesc *bottom = PR_GetIdentitiesLayer( + pds[index].fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); /* what to do about that? */ + pds[index].out_flags = 0; /* pre-condition */ + if ((NULL != bottom) + && (_PR_FILEDESC_OPEN == bottom->secret->state)) + { + if (0 == ready) + { + PRBool add_to_rd = PR_FALSE; + PRBool add_to_wr = PR_FALSE; + PRBool add_to_ex = PR_FALSE; + + selectfd[index] = bottom->secret->md.osfd; + if (in_flags_read & PR_POLL_READ) + { + pds[index].out_flags |= + _PR_POLL_READ_SYS_READ; + add_to_rd = PR_TRUE; + } + if (in_flags_read & PR_POLL_WRITE) + { + pds[index].out_flags |= + _PR_POLL_READ_SYS_WRITE; + add_to_wr = PR_TRUE; + } + if (in_flags_write & PR_POLL_READ) + { + pds[index].out_flags |= + _PR_POLL_WRITE_SYS_READ; + add_to_rd = PR_TRUE; + } + if (in_flags_write & PR_POLL_WRITE) + { + pds[index].out_flags |= + _PR_POLL_WRITE_SYS_WRITE; + add_to_wr = PR_TRUE; + } + if (pds[index].in_flags & PR_POLL_EXCEPT) + { + add_to_ex = PR_TRUE; + } + if ((selectfd[index] > maxfd) && + (add_to_rd || add_to_wr || add_to_ex)) + { + maxfd = selectfd[index]; + /* + * If maxfd is too large to be used with + * select, fall back to calling poll. + */ + if (maxfd >= FD_SETSIZE) + break; + } + if (add_to_rd) + { + FD_SET(bottom->secret->md.osfd, &rd); + rdp = &rd; + } + if (add_to_wr) + { + FD_SET(bottom->secret->md.osfd, &wr); + wrp = ≀ + } + if (add_to_ex) + { + FD_SET(bottom->secret->md.osfd, &ex); + exp = &ex; + } + } + } + else + { + if (0 == ready) + { + int i; + for (i = 0; i < index; i++) + { + pds[i].out_flags = 0; + } + } + ready += 1; /* this will cause an abrupt return */ + pds[index].out_flags = PR_POLL_NVAL; /* bogii */ + } + } + } + else + { + pds[index].out_flags = 0; + } + } + if (0 == ready) + { + if (maxfd >= FD_SETSIZE) + { + /* + * maxfd too large to be used with select, fall back to + * calling poll + */ + return(_pr_poll_with_poll(pds, npds, timeout)); + } + switch (timeout) + { + case PR_INTERVAL_NO_WAIT: + tv.tv_sec = 0; + tv.tv_usec = 0; + tvp = &tv; + break; + case PR_INTERVAL_NO_TIMEOUT: + tvp = NULL; + break; + default: + msecs = PR_IntervalToMilliseconds(timeout); + tv.tv_sec = msecs/PR_MSEC_PER_SEC; + tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC; + tvp = &tv; + start = PR_IntervalNow(); + } + +retry: + ready = select(maxfd + 1, rdp, wrp, exp, tvp); + if (-1 == ready) + { + PRIntn oserror = errno; + + if ((EINTR == oserror) || (EAGAIN == oserror)) + { + if (timeout == PR_INTERVAL_NO_TIMEOUT) + goto retry; + else if (timeout == PR_INTERVAL_NO_WAIT) + ready = 0; /* don't retry, just time out */ + else + { + elapsed = (PRIntervalTime) (PR_IntervalNow() + - start); + if (elapsed > timeout) + ready = 0; /* timed out */ + else + { + remaining = timeout - elapsed; + msecs = PR_IntervalToMilliseconds(remaining); + tv.tv_sec = msecs/PR_MSEC_PER_SEC; + tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * + PR_USEC_PER_MSEC; + goto retry; + } + } + } else if (EBADF == oserror) + { + /* find all the bad fds */ + ready = 0; + for (index = 0; index < npds; ++index) + { + pds[index].out_flags = 0; + if ((NULL != pds[index].fd) && + (0 != pds[index].in_flags)) + { + if (fcntl(selectfd[index], F_GETFL, 0) == -1) + { + pds[index].out_flags = PR_POLL_NVAL; + ready++; + } + } + } + } else + _PR_MD_MAP_SELECT_ERROR(oserror); + } + else if (ready > 0) + { + for (index = 0; index < npds; ++index) + { + PRInt16 out_flags = 0; + if ((NULL != pds[index].fd) && (0 != pds[index].in_flags)) + { + if (FD_ISSET(selectfd[index], &rd)) + { + if (pds[index].out_flags + & _PR_POLL_READ_SYS_READ) + { + out_flags |= PR_POLL_READ; + } + if (pds[index].out_flags + & _PR_POLL_WRITE_SYS_READ) + { + out_flags |= PR_POLL_WRITE; + } + } + if (FD_ISSET(selectfd[index], &wr)) + { + if (pds[index].out_flags + & _PR_POLL_READ_SYS_WRITE) + { + out_flags |= PR_POLL_READ; + } + if (pds[index].out_flags + & _PR_POLL_WRITE_SYS_WRITE) + { + out_flags |= PR_POLL_WRITE; + } + } + if (FD_ISSET(selectfd[index], &ex)) + out_flags |= PR_POLL_EXCEPT; + } + pds[index].out_flags = out_flags; + } + } + } + } + return ready; + +} /* _pr_poll_with_select */ +#endif /* _PR_POLL_WITH_SELECT */ + +PR_IMPLEMENT(PRInt32) PR_Poll( + PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) +{ +#if defined(_PR_POLL_WITH_SELECT) + return(_pr_poll_with_select(pds, npds, timeout)); +#else + return(_pr_poll_with_poll(pds, npds, timeout)); +#endif +} + +PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags) +{ + struct dirent *dp; + + if (pt_TestAbort()) return NULL; + + for (;;) + { + errno = 0; + dp = readdir(dir->md.d); + if (NULL == dp) + { + pt_MapError(_PR_MD_MAP_READDIR_ERROR, errno); + return NULL; + } + if ((flags & PR_SKIP_DOT) + && ('.' == dp->d_name[0]) + && (0 == dp->d_name[1])) continue; + if ((flags & PR_SKIP_DOT_DOT) + && ('.' == dp->d_name[0]) + && ('.' == dp->d_name[1]) + && (0 == dp->d_name[2])) continue; + if ((flags & PR_SKIP_HIDDEN) && ('.' == dp->d_name[0])) + continue; + break; + } + dir->d.name = dp->d_name; + return &dir->d; +} /* PR_ReadDir */ + +PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void) +{ + PRIntn domain = PF_INET; + + return PR_Socket(domain, SOCK_DGRAM, 0); +} /* PR_NewUDPSocket */ + +PR_IMPLEMENT(PRFileDesc*) PR_NewTCPSocket(void) +{ + PRIntn domain = PF_INET; + + return PR_Socket(domain, SOCK_STREAM, 0); +} /* PR_NewTCPSocket */ + +PR_IMPLEMENT(PRFileDesc*) PR_OpenUDPSocket(PRIntn af) +{ + return PR_Socket(af, SOCK_DGRAM, 0); +} /* PR_NewUDPSocket */ + +PR_IMPLEMENT(PRFileDesc*) PR_OpenTCPSocket(PRIntn af) +{ + return PR_Socket(af, SOCK_STREAM, 0); +} /* PR_NewTCPSocket */ + +PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]) +{ +#ifdef SYMBIAN + /* + * For the platforms that don't have socketpair. + * + * Copied from prsocket.c, with the parameter f[] renamed fds[] and the + * _PR_CONNECT_DOES_NOT_BIND code removed. + */ + PRFileDesc *listenSock; + PRNetAddr selfAddr, peerAddr; + PRUint16 port; + + fds[0] = fds[1] = NULL; + listenSock = PR_NewTCPSocket(); + if (listenSock == NULL) { + goto failed; + } + PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */ + if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) { + goto failed; + } + if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) { + goto failed; + } + port = ntohs(selfAddr.inet.port); + if (PR_Listen(listenSock, 5) == PR_FAILURE) { + goto failed; + } + fds[0] = PR_NewTCPSocket(); + if (fds[0] == NULL) { + goto failed; + } + PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr); + + /* + * Only a thread is used to do the connect and accept. + * I am relying on the fact that PR_Connect returns + * successfully as soon as the connect request is put + * into the listen queue (but before PR_Accept is called). + * This is the behavior of the BSD socket code. If + * connect does not return until accept is called, we + * will need to create another thread to call connect. + */ + if (PR_Connect(fds[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT) + == PR_FAILURE) { + goto failed; + } + /* + * A malicious local process may connect to the listening + * socket, so we need to verify that the accepted connection + * is made from our own socket fds[0]. + */ + if (PR_GetSockName(fds[0], &selfAddr) == PR_FAILURE) { + goto failed; + } + fds[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT); + if (fds[1] == NULL) { + goto failed; + } + if (peerAddr.inet.port != selfAddr.inet.port) { + /* the connection we accepted is not from fds[0] */ + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + goto failed; + } + PR_Close(listenSock); + return PR_SUCCESS; + +failed: + if (listenSock) { + PR_Close(listenSock); + } + if (fds[0]) { + PR_Close(fds[0]); + } + if (fds[1]) { + PR_Close(fds[1]); + } + return PR_FAILURE; +#else + PRInt32 osfd[2]; + + if (pt_TestAbort()) return PR_FAILURE; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, osfd) == -1) { + pt_MapError(_PR_MD_MAP_SOCKETPAIR_ERROR, errno); + return PR_FAILURE; + } + + fds[0] = pt_SetMethods(osfd[0], PR_DESC_SOCKET_TCP, PR_FALSE, PR_FALSE); + if (fds[0] == NULL) { + close(osfd[0]); + close(osfd[1]); + return PR_FAILURE; + } + fds[1] = pt_SetMethods(osfd[1], PR_DESC_SOCKET_TCP, PR_FALSE, PR_FALSE); + if (fds[1] == NULL) { + PR_Close(fds[0]); + close(osfd[1]); + return PR_FAILURE; + } + return PR_SUCCESS; +#endif +} /* PR_NewTCPSocketPair */ + +PR_IMPLEMENT(PRStatus) PR_CreatePipe( + PRFileDesc **readPipe, + PRFileDesc **writePipe +) +{ + int pipefd[2]; + + if (pt_TestAbort()) return PR_FAILURE; + + if (pipe(pipefd) == -1) + { + /* XXX map pipe error */ + PR_SetError(PR_UNKNOWN_ERROR, errno); + return PR_FAILURE; + } + *readPipe = pt_SetMethods(pipefd[0], PR_DESC_PIPE, PR_FALSE, PR_FALSE); + if (NULL == *readPipe) + { + close(pipefd[0]); + close(pipefd[1]); + return PR_FAILURE; + } + *writePipe = pt_SetMethods(pipefd[1], PR_DESC_PIPE, PR_FALSE, PR_FALSE); + if (NULL == *writePipe) + { + PR_Close(*readPipe); + close(pipefd[1]); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +/* +** Set the inheritance attribute of a file descriptor. +*/ +PR_IMPLEMENT(PRStatus) PR_SetFDInheritable( + PRFileDesc *fd, + PRBool inheritable) +{ + /* + * Only a non-layered, NSPR file descriptor can be inherited + * by a child process. + */ + if (fd->identity != PR_NSPR_IO_LAYER) + { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + if (fd->secret->inheritable != inheritable) + { + if (fcntl(fd->secret->md.osfd, F_SETFD, + inheritable ? 0 : FD_CLOEXEC) == -1) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + fd->secret->inheritable = (_PRTriStateBool) inheritable; + } + return PR_SUCCESS; +} + +/*****************************************************************************/ +/***************************** I/O friends methods ***************************/ +/*****************************************************************************/ + +PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PRInt32 osfd) +{ + PRFileDesc *fd; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_TRUE); + if (NULL == fd) close(osfd); + return fd; +} /* PR_ImportFile */ + +PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PRInt32 osfd) +{ + PRFileDesc *fd; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + fd = pt_SetMethods(osfd, PR_DESC_PIPE, PR_FALSE, PR_TRUE); + if (NULL == fd) close(osfd); + return fd; +} /* PR_ImportPipe */ + +PR_IMPLEMENT(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd) +{ + PRFileDesc *fd; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_FALSE, PR_TRUE); + if (NULL == fd) close(osfd); +#ifdef _PR_NEED_SECRET_AF + if (NULL != fd) fd->secret->af = PF_INET; +#endif + return fd; +} /* PR_ImportTCPSocket */ + +PR_IMPLEMENT(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd) +{ + PRFileDesc *fd; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + fd = pt_SetMethods(osfd, PR_DESC_SOCKET_UDP, PR_FALSE, PR_TRUE); + if (NULL == fd) close(osfd); + return fd; +} /* PR_ImportUDPSocket */ + +PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PRInt32 osfd) +{ + PRFileDesc *fd; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + fd = _PR_Getfd(); + + if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + else + { + fd->secret->md.osfd = osfd; + fd->secret->inheritable = _PR_TRI_FALSE; + fd->secret->state = _PR_FILEDESC_OPEN; + fd->methods = PR_GetSocketPollFdMethods(); + } + + return fd; +} /* PR_CreateSocketPollFD */ + +PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd) +{ + if (NULL == fd) + { + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + return PR_FAILURE; + } + fd->secret->state = _PR_FILEDESC_CLOSED; + _PR_Putfd(fd); + return PR_SUCCESS; +} /* PR_DestroySocketPollFd */ + +PR_IMPLEMENT(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *bottom) +{ + PRInt32 osfd = -1; + bottom = (NULL == bottom) ? + NULL : PR_GetIdentitiesLayer(bottom, PR_NSPR_IO_LAYER); + if (NULL == bottom) PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + else osfd = bottom->secret->md.osfd; + return osfd; +} /* PR_FileDesc2NativeHandle */ + +PR_IMPLEMENT(void) PR_ChangeFileDescNativeHandle(PRFileDesc *fd, + PRInt32 handle) +{ + if (fd) fd->secret->md.osfd = handle; +} /* PR_ChangeFileDescNativeHandle*/ + +PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd) +{ + PRStatus status = PR_SUCCESS; + + if (pt_TestAbort()) return PR_FAILURE; + + PR_Lock(_pr_flock_lock); + while (-1 == fd->secret->lockCount) + PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT); + if (0 == fd->secret->lockCount) + { + fd->secret->lockCount = -1; + PR_Unlock(_pr_flock_lock); + status = _PR_MD_LOCKFILE(fd->secret->md.osfd); + PR_Lock(_pr_flock_lock); + fd->secret->lockCount = (PR_SUCCESS == status) ? 1 : 0; + PR_NotifyAllCondVar(_pr_flock_cv); + } + else + { + fd->secret->lockCount += 1; + } + PR_Unlock(_pr_flock_lock); + + return status; +} /* PR_LockFile */ + +PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd) +{ + PRStatus status = PR_SUCCESS; + + if (pt_TestAbort()) return PR_FAILURE; + + PR_Lock(_pr_flock_lock); + if (0 == fd->secret->lockCount) + { + status = _PR_MD_TLOCKFILE(fd->secret->md.osfd); + if (PR_SUCCESS == status) fd->secret->lockCount = 1; + } + else fd->secret->lockCount += 1; + PR_Unlock(_pr_flock_lock); + + return status; +} /* PR_TLockFile */ + +PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd) +{ + PRStatus status = PR_SUCCESS; + + if (pt_TestAbort()) return PR_FAILURE; + + PR_Lock(_pr_flock_lock); + if (fd->secret->lockCount == 1) + { + status = _PR_MD_UNLOCKFILE(fd->secret->md.osfd); + if (PR_SUCCESS == status) fd->secret->lockCount = 0; + } + else fd->secret->lockCount -= 1; + PR_Unlock(_pr_flock_lock); + + return status; +} + +/* + * The next two entry points should not be in the API, but they are + * defined here for historical (or hysterical) reasons. + */ + +PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void) +{ +#if defined(AIX) || defined(SYMBIAN) + return sysconf(_SC_OPEN_MAX); +#else + struct rlimit rlim; + + if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) + return -1; + + return rlim.rlim_max; +#endif +} + +PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(PRIntn table_size) +{ +#if defined(AIX) || defined(SYMBIAN) + return -1; +#else + struct rlimit rlim; + PRInt32 tableMax = PR_GetSysfdTableMax(); + + if (tableMax < 0) return -1; + rlim.rlim_max = tableMax; + + /* Grow as much as we can; even if too big */ + if ( rlim.rlim_max < table_size ) + rlim.rlim_cur = rlim.rlim_max; + else + rlim.rlim_cur = table_size; + + if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) + return -1; + + return rlim.rlim_cur; +#endif +} + +/* + * PR_Stat is supported for backward compatibility; some existing Java + * code uses it. New code should use PR_GetFileInfo. + */ + +#ifndef NO_NSPR_10_SUPPORT +PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf) +{ + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete("PR_Stat", "PR_GetFileInfo"); + + if (pt_TestAbort()) return -1; + + if (-1 == stat(name, buf)) { + pt_MapError(_PR_MD_MAP_STAT_ERROR, errno); + return -1; + } else { + return 0; + } +} +#endif /* ! NO_NSPR_10_SUPPORT */ + + +PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set) +{ + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete("PR_FD_ZERO (PR_Select)", "PR_Poll"); + memset(set, 0, sizeof(PR_fd_set)); +} + +PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set) +{ + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete("PR_FD_SET (PR_Select)", "PR_Poll"); + PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC ); + + set->harray[set->hsize++] = fh; +} + +PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set) +{ + PRUint32 index, index2; + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete("PR_FD_CLR (PR_Select)", "PR_Poll"); + + for (index = 0; indexhsize; index++) + if (set->harray[index] == fh) { + for (index2=index; index2 < (set->hsize-1); index2++) { + set->harray[index2] = set->harray[index2+1]; + } + set->hsize--; + break; + } +} + +PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set) +{ + PRUint32 index; + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete("PR_FD_ISSET (PR_Select)", "PR_Poll"); + for (index = 0; indexhsize; index++) + if (set->harray[index] == fh) { + return 1; + } + return 0; +} + +PR_IMPLEMENT(void) PR_FD_NSET(PRInt32 fd, PR_fd_set *set) +{ + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete("PR_FD_NSET (PR_Select)", "PR_Poll"); + PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC ); + + set->narray[set->nsize++] = fd; +} + +PR_IMPLEMENT(void) PR_FD_NCLR(PRInt32 fd, PR_fd_set *set) +{ + PRUint32 index, index2; + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete("PR_FD_NCLR (PR_Select)", "PR_Poll"); + + for (index = 0; indexnsize; index++) + if (set->narray[index] == fd) { + for (index2=index; index2 < (set->nsize-1); index2++) { + set->narray[index2] = set->narray[index2+1]; + } + set->nsize--; + break; + } +} + +PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PRInt32 fd, PR_fd_set *set) +{ + PRUint32 index; + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete("PR_FD_NISSET (PR_Select)", "PR_Poll"); + for (index = 0; indexnsize; index++) + if (set->narray[index] == fd) { + return 1; + } + return 0; +} + +#include +#include +#if !defined(HPUX) \ + && !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__) +#include +#endif + +static PRInt32 +_PR_getset(PR_fd_set *pr_set, fd_set *set) +{ + PRUint32 index; + PRInt32 max = 0; + + if (!pr_set) + return 0; + + FD_ZERO(set); + + /* First set the pr file handle osfds */ + for (index=0; indexhsize; index++) { + FD_SET(pr_set->harray[index]->secret->md.osfd, set); + if (pr_set->harray[index]->secret->md.osfd > max) + max = pr_set->harray[index]->secret->md.osfd; + } + /* Second set the native osfds */ + for (index=0; indexnsize; index++) { + FD_SET(pr_set->narray[index], set); + if (pr_set->narray[index] > max) + max = pr_set->narray[index]; + } + return max; +} + +static void +_PR_setset(PR_fd_set *pr_set, fd_set *set) +{ + PRUint32 index, last_used; + + if (!pr_set) + return; + + for (last_used=0, index=0; indexhsize; index++) { + if ( FD_ISSET(pr_set->harray[index]->secret->md.osfd, set) ) { + pr_set->harray[last_used++] = pr_set->harray[index]; + } + } + pr_set->hsize = last_used; + + for (last_used=0, index=0; indexnsize; index++) { + if ( FD_ISSET(pr_set->narray[index], set) ) { + pr_set->narray[last_used++] = pr_set->narray[index]; + } + } + pr_set->nsize = last_used; +} + +PR_IMPLEMENT(PRInt32) PR_Select( + PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, + PR_fd_set *pr_ex, PRIntervalTime timeout) +{ + fd_set rd, wr, ex; + struct timeval tv, *tvp; + PRInt32 max, max_fd; + PRInt32 rv; + /* + * For restarting select() if it is interrupted by a Unix signal. + * We use these variables to figure out how much time has elapsed + * and how much of the timeout still remains. + */ + PRIntervalTime start, elapsed, remaining; + + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete( "PR_Select", "PR_Poll"); + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); + + max_fd = _PR_getset(pr_rd, &rd); + max_fd = (max = _PR_getset(pr_wr, &wr))>max_fd?max:max_fd; + max_fd = (max = _PR_getset(pr_ex, &ex))>max_fd?max:max_fd; + + if (timeout == PR_INTERVAL_NO_TIMEOUT) { + tvp = NULL; + } else { + tv.tv_sec = (PRInt32)PR_IntervalToSeconds(timeout); + tv.tv_usec = (PRInt32)PR_IntervalToMicroseconds( + timeout - PR_SecondsToInterval(tv.tv_sec)); + tvp = &tv; + start = PR_IntervalNow(); + } + +retry: + rv = select(max_fd + 1, (_PRSelectFdSetArg_t) &rd, + (_PRSelectFdSetArg_t) &wr, (_PRSelectFdSetArg_t) &ex, tvp); + + if (rv == -1 && errno == EINTR) { + if (timeout == PR_INTERVAL_NO_TIMEOUT) { + goto retry; + } else { + elapsed = (PRIntervalTime) (PR_IntervalNow() - start); + if (elapsed > timeout) { + rv = 0; /* timed out */ + } else { + remaining = timeout - elapsed; + tv.tv_sec = (PRInt32)PR_IntervalToSeconds(remaining); + tv.tv_usec = (PRInt32)PR_IntervalToMicroseconds( + remaining - PR_SecondsToInterval(tv.tv_sec)); + goto retry; + } + } + } + + if (rv > 0) { + _PR_setset(pr_rd, &rd); + _PR_setset(pr_wr, &wr); + _PR_setset(pr_ex, &ex); + } else if (rv == -1) { + pt_MapError(_PR_MD_MAP_SELECT_ERROR, errno); + } + return rv; +} +#endif /* defined(_PR_PTHREADS) */ + +#ifdef MOZ_UNICODE +/* ================ UTF16 Interfaces ================================ */ +PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16( + const PRUnichar *name, PRIntn flags, PRIntn mode) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDir *dir) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} +/* ================ UTF16 Interfaces ================================ */ +#endif /* MOZ_UNICODE */ + +/* ptio.c */ diff -Nru nspr-4.9.5/nspr/pr/src/pthreads/ptmisc.c nspr-4.10.7/nspr/pr/src/pthreads/ptmisc.c --- nspr-4.9.5/nspr/pr/src/pthreads/ptmisc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/pthreads/ptmisc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: ptmisc.c +** Descritpion: Implemenation of miscellaneous methods for pthreads +*/ + +#if defined(_PR_PTHREADS) + +#include "primpl.h" + +#include +#ifdef SOLARIS +#include +#endif + +#define PT_LOG(f) + +void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")} +void _PR_InitStacks(void) {PT_LOG("_PR_InitStacks")} + +PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs) +{ +#ifdef SOLARIS + thr_setconcurrency(numCPUs); +#else + PT_LOG("PR_SetConcurrency"); +#endif +} + +PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 flag) + {PT_LOG("PR_SetThreadRecycleMode")} + +#endif /* defined(_PR_PTHREADS) */ + +/* ptmisc.c */ diff -Nru nspr-4.9.5/nspr/pr/src/pthreads/ptsynch.c nspr-4.10.7/nspr/pr/src/pthreads/ptsynch.c --- nspr-4.9.5/nspr/pr/src/pthreads/ptsynch.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/pthreads/ptsynch.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1240 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: ptsynch.c +** Descritpion: Implemenation for thread synchronization using pthreads +** Exports: prlock.h, prcvar.h, prmon.h, prcmon.h +*/ + +#if defined(_PR_PTHREADS) + +#include "primpl.h" +#include "obsolete/prsem.h" + +#include +#include +#include + +static pthread_mutexattr_t _pt_mattr; +static pthread_condattr_t _pt_cvar_attr; + +#if defined(DEBUG) +extern PTDebug pt_debug; /* this is shared between several modules */ + +#if defined(_PR_DCETHREADS) +static pthread_t pt_zero_tid; /* a null pthread_t (pthread_t is a struct + * in DCE threads) to compare with */ +#endif /* defined(_PR_DCETHREADS) */ +#endif /* defined(DEBUG) */ + +#if defined(FREEBSD) +/* + * On older versions of FreeBSD, pthread_mutex_trylock returns EDEADLK. + * Newer versions return EBUSY. We still need to support both. + */ +static int +pt_pthread_mutex_is_locked(pthread_mutex_t *m) +{ + int rv = pthread_mutex_trylock(m); + return (EBUSY == rv || EDEADLK == rv); +} +#endif + +/**************************************************************/ +/**************************************************************/ +/*****************************LOCKS****************************/ +/**************************************************************/ +/**************************************************************/ + +void _PR_InitLocks(void) +{ + int rv; + rv = _PT_PTHREAD_MUTEXATTR_INIT(&_pt_mattr); + PR_ASSERT(0 == rv); + +#ifdef LINUX +#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) + rv = pthread_mutexattr_settype(&_pt_mattr, PTHREAD_MUTEX_ADAPTIVE_NP); + PR_ASSERT(0 == rv); +#endif +#endif + + rv = _PT_PTHREAD_CONDATTR_INIT(&_pt_cvar_attr); + PR_ASSERT(0 == rv); +} + +static void pt_PostNotifies(PRLock *lock, PRBool unlock) +{ + PRIntn index, rv; + _PT_Notified post; + _PT_Notified *notified, *prev = NULL; + /* + * Time to actually notify any conditions that were affected + * while the lock was held. Get a copy of the list that's in + * the lock structure and then zero the original. If it's + * linked to other such structures, we own that storage. + */ + post = lock->notified; /* a safe copy; we own the lock */ + +#if defined(DEBUG) + memset(&lock->notified, 0, sizeof(_PT_Notified)); /* reset */ +#else + lock->notified.length = 0; /* these are really sufficient */ + lock->notified.link = NULL; +#endif + + /* should (may) we release lock before notifying? */ + if (unlock) + { + rv = pthread_mutex_unlock(&lock->mutex); + PR_ASSERT(0 == rv); + } + + notified = &post; /* this is where we start */ + do + { + for (index = 0; index < notified->length; ++index) + { + PRCondVar *cv = notified->cv[index].cv; + PR_ASSERT(NULL != cv); + PR_ASSERT(0 != notified->cv[index].times); + if (-1 == notified->cv[index].times) + { + rv = pthread_cond_broadcast(&cv->cv); + PR_ASSERT(0 == rv); + } + else + { + while (notified->cv[index].times-- > 0) + { + rv = pthread_cond_signal(&cv->cv); + PR_ASSERT(0 == rv); + } + } +#if defined(DEBUG) + pt_debug.cvars_notified += 1; + if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending)) + { + pt_debug.delayed_cv_deletes += 1; + PR_DestroyCondVar(cv); + } +#else /* defined(DEBUG) */ + if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending)) + PR_DestroyCondVar(cv); +#endif /* defined(DEBUG) */ + } + prev = notified; + notified = notified->link; + if (&post != prev) PR_DELETE(prev); + } while (NULL != notified); +} /* pt_PostNotifies */ + +PR_IMPLEMENT(PRLock*) PR_NewLock(void) +{ + PRIntn rv; + PRLock *lock; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + lock = PR_NEWZAP(PRLock); + if (lock != NULL) + { + rv = _PT_PTHREAD_MUTEX_INIT(lock->mutex, _pt_mattr); + PR_ASSERT(0 == rv); + } +#if defined(DEBUG) + pt_debug.locks_created += 1; +#endif + return lock; +} /* PR_NewLock */ + +PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock) +{ + PRIntn rv; + PR_ASSERT(NULL != lock); + PR_ASSERT(PR_FALSE == lock->locked); + PR_ASSERT(0 == lock->notified.length); + PR_ASSERT(NULL == lock->notified.link); + rv = pthread_mutex_destroy(&lock->mutex); + PR_ASSERT(0 == rv); +#if defined(DEBUG) + memset(lock, 0xaf, sizeof(PRLock)); + pt_debug.locks_destroyed += 1; +#endif + PR_Free(lock); +} /* PR_DestroyLock */ + +PR_IMPLEMENT(void) PR_Lock(PRLock *lock) +{ + /* Nb: PR_Lock must not call PR_GetCurrentThread to access the |id| or + * |tid| field of the current thread's PRThread structure because + * _pt_root calls PR_Lock before setting thred->id and thred->tid. */ + PRIntn rv; + PR_ASSERT(lock != NULL); + rv = pthread_mutex_lock(&lock->mutex); + PR_ASSERT(0 == rv); + PR_ASSERT(0 == lock->notified.length); + PR_ASSERT(NULL == lock->notified.link); + PR_ASSERT(PR_FALSE == lock->locked); + /* Nb: the order of the next two statements is not critical to + * the correctness of PR_AssertCurrentThreadOwnsLock(), but + * this particular order makes the assertion more likely to + * catch errors. */ + lock->owner = pthread_self(); + lock->locked = PR_TRUE; +#if defined(DEBUG) + pt_debug.locks_acquired += 1; +#endif +} /* PR_Lock */ + +PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock) +{ + pthread_t self = pthread_self(); + PRIntn rv; + + PR_ASSERT(lock != NULL); + PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(lock->mutex)); + PR_ASSERT(PR_TRUE == lock->locked); + PR_ASSERT(pthread_equal(lock->owner, self)); + + if (!lock->locked || !pthread_equal(lock->owner, self)) + return PR_FAILURE; + + lock->locked = PR_FALSE; + if (0 == lock->notified.length) /* shortcut */ + { + rv = pthread_mutex_unlock(&lock->mutex); + PR_ASSERT(0 == rv); + } + else pt_PostNotifies(lock, PR_TRUE); + +#if defined(DEBUG) + pt_debug.locks_released += 1; +#endif + return PR_SUCCESS; +} /* PR_Unlock */ + +PR_IMPLEMENT(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock) +{ + /* Nb: the order of the |locked| and |owner==me| checks is not critical + * to the correctness of PR_AssertCurrentThreadOwnsLock(), but + * this particular order makes the assertion more likely to + * catch errors. */ + PR_ASSERT(lock->locked && pthread_equal(lock->owner, pthread_self())); +} + +/**************************************************************/ +/**************************************************************/ +/***************************CONDITIONS*************************/ +/**************************************************************/ +/**************************************************************/ + + +/* + * This code is used to compute the absolute time for the wakeup. + * It's moderately ugly, so it's defined here and called in a + * couple of places. + */ +#define PT_NANOPERMICRO 1000UL +#define PT_BILLION 1000000000UL + +static PRIntn pt_TimedWait( + pthread_cond_t *cv, pthread_mutex_t *ml, PRIntervalTime timeout) +{ + int rv; + struct timeval now; + struct timespec tmo; + PRUint32 ticks = PR_TicksPerSecond(); + + tmo.tv_sec = (PRInt32)(timeout / ticks); + tmo.tv_nsec = (PRInt32)(timeout - (tmo.tv_sec * ticks)); + tmo.tv_nsec = (PRInt32)PR_IntervalToMicroseconds(PT_NANOPERMICRO * tmo.tv_nsec); + + /* pthreads wants this in absolute time, off we go ... */ + (void)GETTIMEOFDAY(&now); + /* that one's usecs, this one's nsecs - grrrr! */ + tmo.tv_sec += now.tv_sec; + tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec); + tmo.tv_sec += tmo.tv_nsec / PT_BILLION; + tmo.tv_nsec %= PT_BILLION; + + rv = pthread_cond_timedwait(cv, ml, &tmo); + + /* NSPR doesn't report timeouts */ +#ifdef _PR_DCETHREADS + if (rv == -1) return (errno == EAGAIN) ? 0 : errno; + else return rv; +#else + return (rv == ETIMEDOUT) ? 0 : rv; +#endif +} /* pt_TimedWait */ + + +/* + * Notifies just get posted to the protecting mutex. The + * actual notification is done when the lock is released so that + * MP systems don't contend for a lock that they can't have. + */ +static void pt_PostNotifyToCvar(PRCondVar *cvar, PRBool broadcast) +{ + PRIntn index = 0; + _PT_Notified *notified = &cvar->lock->notified; + + PR_ASSERT(PR_TRUE == cvar->lock->locked); + PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self())); + PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(cvar->lock->mutex)); + + while (1) + { + for (index = 0; index < notified->length; ++index) + { + if (notified->cv[index].cv == cvar) + { + if (broadcast) + notified->cv[index].times = -1; + else if (-1 != notified->cv[index].times) + notified->cv[index].times += 1; + return; /* we're finished */ + } + } + /* if not full, enter new CV in this array */ + if (notified->length < PT_CV_NOTIFIED_LENGTH) break; + + /* if there's no link, create an empty array and link it */ + if (NULL == notified->link) + notified->link = PR_NEWZAP(_PT_Notified); + notified = notified->link; + } + + /* A brand new entry in the array */ + (void)PR_ATOMIC_INCREMENT(&cvar->notify_pending); + notified->cv[index].times = (broadcast) ? -1 : 1; + notified->cv[index].cv = cvar; + notified->length += 1; +} /* pt_PostNotifyToCvar */ + +PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock) +{ + PRCondVar *cv = PR_NEW(PRCondVar); + PR_ASSERT(lock != NULL); + if (cv != NULL) + { + int rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); + PR_ASSERT(0 == rv); + cv->lock = lock; + cv->notify_pending = 0; +#if defined(DEBUG) + pt_debug.cvars_created += 1; +#endif + } + return cv; +} /* PR_NewCondVar */ + +PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar) +{ + if (0 > PR_ATOMIC_DECREMENT(&cvar->notify_pending)) + { + PRIntn rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv); +#if defined(DEBUG) + memset(cvar, 0xaf, sizeof(PRCondVar)); + pt_debug.cvars_destroyed += 1; +#endif + PR_Free(cvar); + } +} /* PR_DestroyCondVar */ + +PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout) +{ + PRIntn rv; + PRThread *thred = PR_GetCurrentThread(); + + PR_ASSERT(cvar != NULL); + /* We'd better be locked */ + PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(cvar->lock->mutex)); + PR_ASSERT(PR_TRUE == cvar->lock->locked); + /* and it better be by us */ + PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self())); + + if (_PT_THREAD_INTERRUPTED(thred)) goto aborted; + + /* + * The thread waiting is used for PR_Interrupt + */ + thred->waiting = cvar; /* this is where we're waiting */ + + /* + * If we have pending notifies, post them now. + * + * This is not optimal. We're going to post these notifies + * while we're holding the lock. That means on MP systems + * that they are going to collide for the lock that we will + * hold until we actually wait. + */ + if (0 != cvar->lock->notified.length) + pt_PostNotifies(cvar->lock, PR_FALSE); + + /* + * We're surrendering the lock, so clear out the locked field. + */ + cvar->lock->locked = PR_FALSE; + + if (timeout == PR_INTERVAL_NO_TIMEOUT) + rv = pthread_cond_wait(&cvar->cv, &cvar->lock->mutex); + else + rv = pt_TimedWait(&cvar->cv, &cvar->lock->mutex, timeout); + + /* We just got the lock back - this better be empty */ + PR_ASSERT(PR_FALSE == cvar->lock->locked); + cvar->lock->locked = PR_TRUE; + cvar->lock->owner = pthread_self(); + + PR_ASSERT(0 == cvar->lock->notified.length); + thred->waiting = NULL; /* and now we're not */ + if (_PT_THREAD_INTERRUPTED(thred)) goto aborted; + if (rv != 0) + { + _PR_MD_MAP_DEFAULT_ERROR(rv); + return PR_FAILURE; + } + return PR_SUCCESS; + +aborted: + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + thred->state &= ~PT_THREAD_ABORTED; + return PR_FAILURE; +} /* PR_WaitCondVar */ + +PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar) +{ + PR_ASSERT(cvar != NULL); + pt_PostNotifyToCvar(cvar, PR_FALSE); + return PR_SUCCESS; +} /* PR_NotifyCondVar */ + +PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar) +{ + PR_ASSERT(cvar != NULL); + pt_PostNotifyToCvar(cvar, PR_TRUE); + return PR_SUCCESS; +} /* PR_NotifyAllCondVar */ + +/**************************************************************/ +/**************************************************************/ +/***************************MONITORS***************************/ +/**************************************************************/ +/**************************************************************/ + +/* + * Notifies just get posted to the monitor. The actual notification is done + * when the monitor is fully exited so that MP systems don't contend for a + * monitor that they can't enter. + */ +static void pt_PostNotifyToMonitor(PRMonitor *mon, PRBool broadcast) +{ + PR_ASSERT(NULL != mon); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mon); + + /* mon->notifyTimes is protected by the monitor, so we don't need to + * acquire mon->lock. + */ + if (broadcast) + mon->notifyTimes = -1; + else if (-1 != mon->notifyTimes) + mon->notifyTimes += 1; +} /* pt_PostNotifyToMonitor */ + +static void pt_PostNotifiesFromMonitor(pthread_cond_t *cv, PRIntn times) +{ + PRIntn rv; + + /* + * Time to actually notify any waits that were affected while the monitor + * was entered. + */ + PR_ASSERT(NULL != cv); + PR_ASSERT(0 != times); + if (-1 == times) + { + rv = pthread_cond_broadcast(cv); + PR_ASSERT(0 == rv); + } + else + { + while (times-- > 0) + { + rv = pthread_cond_signal(cv); + PR_ASSERT(0 == rv); + } + } +} /* pt_PostNotifiesFromMonitor */ + +PR_IMPLEMENT(PRMonitor*) PR_NewMonitor(void) +{ + PRMonitor *mon; + int rv; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + mon = PR_NEWZAP(PRMonitor); + if (mon == NULL) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + rv = _PT_PTHREAD_MUTEX_INIT(mon->lock, _pt_mattr); + PR_ASSERT(0 == rv); + if (0 != rv) + goto error1; + + _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); + + rv = _PT_PTHREAD_COND_INIT(mon->entryCV, _pt_cvar_attr); + PR_ASSERT(0 == rv); + if (0 != rv) + goto error2; + + rv = _PT_PTHREAD_COND_INIT(mon->waitCV, _pt_cvar_attr); + PR_ASSERT(0 == rv); + if (0 != rv) + goto error3; + + mon->notifyTimes = 0; + mon->entryCount = 0; + mon->refCount = 1; + mon->name = NULL; + return mon; + +error3: + pthread_cond_destroy(&mon->entryCV); +error2: + pthread_mutex_destroy(&mon->lock); +error1: + PR_Free(mon); + _PR_MD_MAP_DEFAULT_ERROR(rv); + return NULL; +} /* PR_NewMonitor */ + +PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name) +{ + PRMonitor* mon = PR_NewMonitor(); + if (mon) + mon->name = name; + return mon; +} + +PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon) +{ + int rv; + + PR_ASSERT(mon != NULL); + if (PR_ATOMIC_DECREMENT(&mon->refCount) == 0) + { + rv = pthread_cond_destroy(&mon->waitCV); PR_ASSERT(0 == rv); + rv = pthread_cond_destroy(&mon->entryCV); PR_ASSERT(0 == rv); + rv = pthread_mutex_destroy(&mon->lock); PR_ASSERT(0 == rv); +#if defined(DEBUG) + memset(mon, 0xaf, sizeof(PRMonitor)); +#endif + PR_Free(mon); + } +} /* PR_DestroyMonitor */ + +/* The GC uses this; it is quite arguably a bad interface. I'm just + * duplicating it for now - XXXMB + */ +PR_IMPLEMENT(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon) +{ + pthread_t self = pthread_self(); + PRIntn rv; + PRIntn count = 0; + + rv = pthread_mutex_lock(&mon->lock); + PR_ASSERT(0 == rv); + if (pthread_equal(mon->owner, self)) + count = mon->entryCount; + rv = pthread_mutex_unlock(&mon->lock); + PR_ASSERT(0 == rv); + return count; +} + +PR_IMPLEMENT(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon) +{ +#if defined(DEBUG) || defined(FORCE_PR_ASSERT) + PRIntn rv; + + rv = pthread_mutex_lock(&mon->lock); + PR_ASSERT(0 == rv); + PR_ASSERT(mon->entryCount != 0 && + pthread_equal(mon->owner, pthread_self())); + rv = pthread_mutex_unlock(&mon->lock); + PR_ASSERT(0 == rv); +#endif +} + +PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon) +{ + pthread_t self = pthread_self(); + PRIntn rv; + + PR_ASSERT(mon != NULL); + rv = pthread_mutex_lock(&mon->lock); + PR_ASSERT(0 == rv); + if (mon->entryCount != 0) + { + if (pthread_equal(mon->owner, self)) + goto done; + while (mon->entryCount != 0) + { + rv = pthread_cond_wait(&mon->entryCV, &mon->lock); + PR_ASSERT(0 == rv); + } + } + /* and now I have the monitor */ + PR_ASSERT(0 == mon->notifyTimes); + PR_ASSERT(_PT_PTHREAD_THR_HANDLE_IS_INVALID(mon->owner)); + _PT_PTHREAD_COPY_THR_HANDLE(self, mon->owner); + +done: + mon->entryCount += 1; + rv = pthread_mutex_unlock(&mon->lock); + PR_ASSERT(0 == rv); +} /* PR_EnterMonitor */ + +PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon) +{ + pthread_t self = pthread_self(); + PRIntn rv; + PRBool notifyEntryWaiter = PR_FALSE; + PRIntn notifyTimes = 0; + + PR_ASSERT(mon != NULL); + rv = pthread_mutex_lock(&mon->lock); + PR_ASSERT(0 == rv); + /* the entries should be > 0 and we'd better be the owner */ + PR_ASSERT(mon->entryCount > 0); + PR_ASSERT(pthread_equal(mon->owner, self)); + if (mon->entryCount == 0 || !pthread_equal(mon->owner, self)) + { + rv = pthread_mutex_unlock(&mon->lock); + PR_ASSERT(0 == rv); + return PR_FAILURE; + } + + mon->entryCount -= 1; /* reduce by one */ + if (mon->entryCount == 0) + { + /* and if it transitioned to zero - notify an entry waiter */ + /* make the owner unknown */ + _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); + notifyEntryWaiter = PR_TRUE; + notifyTimes = mon->notifyTimes; + mon->notifyTimes = 0; + /* We will access the members of 'mon' after unlocking mon->lock. + * Add a reference. */ + PR_ATOMIC_INCREMENT(&mon->refCount); + } + rv = pthread_mutex_unlock(&mon->lock); + PR_ASSERT(0 == rv); + if (notifyEntryWaiter) + { + if (notifyTimes) + pt_PostNotifiesFromMonitor(&mon->waitCV, notifyTimes); + rv = pthread_cond_signal(&mon->entryCV); + PR_ASSERT(0 == rv); + /* We are done accessing the members of 'mon'. Release the + * reference. */ + PR_DestroyMonitor(mon); + } + return PR_SUCCESS; +} /* PR_ExitMonitor */ + +PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime timeout) +{ + PRStatus rv; + PRUint32 saved_entries; + pthread_t saved_owner; + + PR_ASSERT(mon != NULL); + rv = pthread_mutex_lock(&mon->lock); + PR_ASSERT(0 == rv); + /* the entries better be positive */ + PR_ASSERT(mon->entryCount > 0); + /* and it better be owned by us */ + PR_ASSERT(pthread_equal(mon->owner, pthread_self())); + + /* tuck these away 'till later */ + saved_entries = mon->entryCount; + mon->entryCount = 0; + _PT_PTHREAD_COPY_THR_HANDLE(mon->owner, saved_owner); + _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); + /* + * If we have pending notifies, post them now. + * + * This is not optimal. We're going to post these notifies + * while we're holding the lock. That means on MP systems + * that they are going to collide for the lock that we will + * hold until we actually wait. + */ + if (0 != mon->notifyTimes) + { + pt_PostNotifiesFromMonitor(&mon->waitCV, mon->notifyTimes); + mon->notifyTimes = 0; + } + rv = pthread_cond_signal(&mon->entryCV); + PR_ASSERT(0 == rv); + + if (timeout == PR_INTERVAL_NO_TIMEOUT) + rv = pthread_cond_wait(&mon->waitCV, &mon->lock); + else + rv = pt_TimedWait(&mon->waitCV, &mon->lock, timeout); + PR_ASSERT(0 == rv); + + while (mon->entryCount != 0) + { + rv = pthread_cond_wait(&mon->entryCV, &mon->lock); + PR_ASSERT(0 == rv); + } + PR_ASSERT(0 == mon->notifyTimes); + /* reinstate the interesting information */ + mon->entryCount = saved_entries; + _PT_PTHREAD_COPY_THR_HANDLE(saved_owner, mon->owner); + + rv = pthread_mutex_unlock(&mon->lock); + PR_ASSERT(0 == rv); + return rv; +} /* PR_Wait */ + +PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon) +{ + pt_PostNotifyToMonitor(mon, PR_FALSE); + return PR_SUCCESS; +} /* PR_Notify */ + +PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon) +{ + pt_PostNotifyToMonitor(mon, PR_TRUE); + return PR_SUCCESS; +} /* PR_NotifyAll */ + +/**************************************************************/ +/**************************************************************/ +/**************************SEMAPHORES**************************/ +/**************************************************************/ +/**************************************************************/ +PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *semaphore) +{ + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete( + "PR_PostSem", "locks & condition variables"); + PR_Lock(semaphore->cvar->lock); + PR_NotifyCondVar(semaphore->cvar); + semaphore->count += 1; + PR_Unlock(semaphore->cvar->lock); +} /* PR_PostSem */ + +PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *semaphore) +{ + PRStatus status = PR_SUCCESS; + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete( + "PR_WaitSem", "locks & condition variables"); + PR_Lock(semaphore->cvar->lock); + while ((semaphore->count == 0) && (PR_SUCCESS == status)) + status = PR_WaitCondVar(semaphore->cvar, PR_INTERVAL_NO_TIMEOUT); + if (PR_SUCCESS == status) semaphore->count -= 1; + PR_Unlock(semaphore->cvar->lock); + return status; +} /* PR_WaitSem */ + +PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *semaphore) +{ + static PRBool unwarned = PR_TRUE; + if (unwarned) unwarned = _PR_Obsolete( + "PR_DestroySem", "locks & condition variables"); + PR_DestroyLock(semaphore->cvar->lock); + PR_DestroyCondVar(semaphore->cvar); + PR_Free(semaphore); +} /* PR_DestroySem */ + +PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value) +{ + PRSemaphore *semaphore; + static PRBool unwarned = PR_TRUE; + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (unwarned) unwarned = _PR_Obsolete( + "PR_NewSem", "locks & condition variables"); + + semaphore = PR_NEWZAP(PRSemaphore); + if (NULL != semaphore) + { + PRLock *lock = PR_NewLock(); + if (NULL != lock) + { + semaphore->cvar = PR_NewCondVar(lock); + if (NULL != semaphore->cvar) + { + semaphore->count = value; + return semaphore; + } + PR_DestroyLock(lock); + } + PR_Free(semaphore); + } + return NULL; +} + +/* + * Define the interprocess named semaphore functions. + * There are three implementations: + * 1. POSIX semaphore based; + * 2. System V semaphore based; + * 3. unsupported (fails with PR_NOT_IMPLEMENTED_ERROR). + */ + +#ifdef _PR_HAVE_POSIX_SEMAPHORES +#include + +PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( + const char *name, + PRIntn flags, + PRIntn mode, + PRUintn value) +{ + PRSem *sem; + char osname[PR_IPC_NAME_SIZE]; + + if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) + == PR_FAILURE) + { + return NULL; + } + + sem = PR_NEW(PRSem); + if (NULL == sem) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + if (flags & PR_SEM_CREATE) + { + int oflag = O_CREAT; + + if (flags & PR_SEM_EXCL) oflag |= O_EXCL; + sem->sem = sem_open(osname, oflag, mode, value); + } + else + { +#ifdef HPUX + /* Pass 0 as the mode and value arguments to work around a bug. */ + sem->sem = sem_open(osname, 0, 0, 0); +#else + sem->sem = sem_open(osname, 0); +#endif + } + if ((sem_t *) -1 == sem->sem) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + PR_Free(sem); + return NULL; + } + return sem; +} + +PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem) +{ + int rv; + rv = sem_wait(sem->sem); + if (0 != rv) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem) +{ + int rv; + rv = sem_post(sem->sem); + if (0 != rv) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem) +{ + int rv; + rv = sem_close(sem->sem); + if (0 != rv) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + PR_Free(sem); + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) +{ + int rv; + char osname[PR_IPC_NAME_SIZE]; + + if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) + == PR_FAILURE) + { + return PR_FAILURE; + } + rv = sem_unlink(osname); + if (0 != rv) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +#elif defined(_PR_HAVE_SYSV_SEMAPHORES) + +#include +#include + +/* + * From the semctl(2) man page in glibc 2.0 + */ +#if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \ + || defined(FREEBSD) || defined(OPENBSD) || defined(BSDI) \ + || defined(DARWIN) || defined(SYMBIAN) +/* union semun is defined by including */ +#else +/* according to X/OPEN we have to define it ourselves */ +union semun { + int val; + struct semid_ds *buf; + unsigned short *array; +}; +#endif + +/* + * 'a' (97) is the final closing price of NSCP stock. + */ +#define NSPR_IPC_KEY_ID 'a' /* the id argument for ftok() */ + +#define NSPR_SEM_MODE 0666 + +PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( + const char *name, + PRIntn flags, + PRIntn mode, + PRUintn value) +{ + PRSem *sem; + key_t key; + union semun arg; + struct sembuf sop; + struct semid_ds seminfo; +#define MAX_TRIES 60 + PRIntn i; + char osname[PR_IPC_NAME_SIZE]; + + if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) + == PR_FAILURE) + { + return NULL; + } + + /* Make sure the file exists before calling ftok. */ + if (flags & PR_SEM_CREATE) + { + int osfd = open(osname, O_RDWR|O_CREAT, mode); + if (-1 == osfd) + { + _PR_MD_MAP_OPEN_ERROR(errno); + return NULL; + } + if (close(osfd) == -1) + { + _PR_MD_MAP_CLOSE_ERROR(errno); + return NULL; + } + } + key = ftok(osname, NSPR_IPC_KEY_ID); + if ((key_t)-1 == key) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return NULL; + } + + sem = PR_NEW(PRSem); + if (NULL == sem) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + if (flags & PR_SEM_CREATE) + { + sem->semid = semget(key, 1, mode|IPC_CREAT|IPC_EXCL); + if (sem->semid >= 0) + { + /* creator of a semaphore is responsible for initializing it */ + arg.val = 0; + if (semctl(sem->semid, 0, SETVAL, arg) == -1) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + PR_Free(sem); + return NULL; + } + /* call semop to set sem_otime to nonzero */ + sop.sem_num = 0; + sop.sem_op = value; + sop.sem_flg = 0; + if (semop(sem->semid, &sop, 1) == -1) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + PR_Free(sem); + return NULL; + } + return sem; + } + + if (errno != EEXIST || flags & PR_SEM_EXCL) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + PR_Free(sem); + return NULL; + } + } + + sem->semid = semget(key, 1, NSPR_SEM_MODE); + if (sem->semid == -1) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + PR_Free(sem); + return NULL; + } + for (i = 0; i < MAX_TRIES; i++) + { + arg.buf = &seminfo; + semctl(sem->semid, 0, IPC_STAT, arg); + if (seminfo.sem_otime != 0) break; + sleep(1); + } + if (i == MAX_TRIES) + { + PR_SetError(PR_IO_TIMEOUT_ERROR, 0); + PR_Free(sem); + return NULL; + } + return sem; +} + +PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem) +{ + struct sembuf sop; + + sop.sem_num = 0; + sop.sem_op = -1; + sop.sem_flg = 0; + if (semop(sem->semid, &sop, 1) == -1) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem) +{ + struct sembuf sop; + + sop.sem_num = 0; + sop.sem_op = 1; + sop.sem_flg = 0; + if (semop(sem->semid, &sop, 1) == -1) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem) +{ + PR_Free(sem); + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) +{ + key_t key; + int semid; + /* On some systems (e.g., glibc 2.0) semctl requires a fourth argument */ + union semun unused; + char osname[PR_IPC_NAME_SIZE]; + + if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) + == PR_FAILURE) + { + return PR_FAILURE; + } + key = ftok(osname, NSPR_IPC_KEY_ID); + if ((key_t) -1 == key) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + if (unlink(osname) == -1) + { + _PR_MD_MAP_UNLINK_ERROR(errno); + return PR_FAILURE; + } + semid = semget(key, 1, NSPR_SEM_MODE); + if (-1 == semid) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + unused.val = 0; + if (semctl(semid, 0, IPC_RMID, unused) == -1) + { + _PR_MD_MAP_DEFAULT_ERROR(errno); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +#else /* neither POSIX nor System V semaphores are available */ + +PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( + const char *name, + PRIntn flags, + PRIntn mode, + PRUintn value) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) +{ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return PR_FAILURE; +} + +#endif /* end of interprocess named semaphore functions */ + +/**************************************************************/ +/**************************************************************/ +/******************ROUTINES FOR DCE EMULATION******************/ +/**************************************************************/ +/**************************************************************/ + +#include "prpdce.h" + +PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock) +{ + PRIntn rv = pthread_mutex_trylock(&lock->mutex); + if (rv == PT_TRYLOCK_SUCCESS) + { + PR_ASSERT(PR_FALSE == lock->locked); + lock->locked = PR_TRUE; + lock->owner = pthread_self(); + } + /* XXX set error code? */ + return (PT_TRYLOCK_SUCCESS == rv) ? PR_SUCCESS : PR_FAILURE; +} /* PRP_TryLock */ + +PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void) +{ + PRCondVar *cv; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + cv = PR_NEW(PRCondVar); + if (cv != NULL) + { + int rv; + rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); + PR_ASSERT(0 == rv); + cv->lock = _PR_NAKED_CV_LOCK; + } + return cv; +} /* PRP_NewNakedCondVar */ + +PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar) +{ + int rv; + rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv); +#if defined(DEBUG) + memset(cvar, 0xaf, sizeof(PRCondVar)); +#endif + PR_Free(cvar); +} /* PRP_DestroyNakedCondVar */ + +PR_IMPLEMENT(PRStatus) PRP_NakedWait( + PRCondVar *cvar, PRLock *ml, PRIntervalTime timeout) +{ + PRIntn rv; + PR_ASSERT(cvar != NULL); + /* XXX do we really want to assert this in a naked wait? */ + PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(ml->mutex)); + if (timeout == PR_INTERVAL_NO_TIMEOUT) + rv = pthread_cond_wait(&cvar->cv, &ml->mutex); + else + rv = pt_TimedWait(&cvar->cv, &ml->mutex, timeout); + if (rv != 0) + { + _PR_MD_MAP_DEFAULT_ERROR(rv); + return PR_FAILURE; + } + return PR_SUCCESS; +} /* PRP_NakedWait */ + +PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar) +{ + int rv; + PR_ASSERT(cvar != NULL); + rv = pthread_cond_signal(&cvar->cv); + PR_ASSERT(0 == rv); + return PR_SUCCESS; +} /* PRP_NakedNotify */ + +PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar) +{ + int rv; + PR_ASSERT(cvar != NULL); + rv = pthread_cond_broadcast(&cvar->cv); + PR_ASSERT(0 == rv); + return PR_SUCCESS; +} /* PRP_NakedBroadcast */ + +#endif /* defined(_PR_PTHREADS) */ + +/* ptsynch.c */ diff -Nru nspr-4.9.5/nspr/pr/src/pthreads/ptthread.c nspr-4.10.7/nspr/pr/src/pthreads/ptthread.c --- nspr-4.9.5/nspr/pr/src/pthreads/ptthread.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/pthreads/ptthread.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1814 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: ptthread.c +** Descritpion: Implemenation for threds using pthreds +** Exports: ptthread.h +*/ + +#if defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) + +#include "prlog.h" +#include "primpl.h" +#include "prpdce.h" + +#include +#include +#include +#include +#include + +#ifdef SYMBIAN +/* In Open C sched_get_priority_min/max do not work properly, so we undefine + * _POSIX_THREAD_PRIORITY_SCHEDULING here. + */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#endif + +#ifdef _PR_NICE_PRIORITY_SCHEDULING +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#include +#ifndef HAVE_GETTID +#define gettid() (syscall(SYS_gettid)) +#endif +#endif + +/* + * Record whether or not we have the privilege to set the scheduling + * policy and priority of threads. 0 means that privilege is available. + * EPERM means that privilege is not available. + */ + +static PRIntn pt_schedpriv = 0; +extern PRLock *_pr_sleeplock; + +static struct _PT_Bookeeping +{ + PRLock *ml; /* a lock to protect ourselves */ + PRCondVar *cv; /* used to signal global things */ + PRInt32 system, user; /* a count of the two different types */ + PRUintn this_many; /* number of threads allowed for exit */ + pthread_key_t key; /* thread private data key */ + PRBool keyCreated; /* whether 'key' should be deleted */ + PRThread *first, *last; /* list of threads we know about */ +#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + PRInt32 minPrio, maxPrio; /* range of scheduling priorities */ +#endif +} pt_book = {0}; + +static void _pt_thread_death(void *arg); +static void _pt_thread_death_internal(void *arg, PRBool callDestructors); +static void init_pthread_gc_support(void); + +#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) +static PRIntn pt_PriorityMap(PRThreadPriority pri) +{ +#ifdef NTO + /* This priority algorithm causes lots of problems on Neutrino + * for now I have just hard coded everything to run at priority 10 + * until I can come up with a new algorithm. + * Jerry.Kirk@Nexwarecorp.com + */ + return 10; +#else + return pt_book.minPrio + + pri * (pt_book.maxPrio - pt_book.minPrio) / PR_PRIORITY_LAST; +#endif +} +#elif defined(_PR_NICE_PRIORITY_SCHEDULING) +/* + * This functions maps higher priorities to lower nice values relative to the + * nice value specified in the |nice| parameter. The corresponding relative + * adjustments are: + * + * PR_PRIORITY_LOW +1 + * PR_PRIORITY_NORMAL 0 + * PR_PRIORITY_HIGH -1 + * PR_PRIORITY_URGENT -2 + */ +static int pt_RelativePriority(int nice, PRThreadPriority pri) +{ + return nice + (1 - pri); +} +#endif + +/* +** Initialize a stack for a native pthread thread +*/ +static void _PR_InitializeStack(PRThreadStack *ts) +{ + if( ts && (ts->stackTop == 0) ) { + ts->allocBase = (char *) &ts; + ts->allocSize = ts->stackSize; + + /* + ** Setup stackTop and stackBottom values. + */ +#ifdef HAVE_STACK_GROWING_UP + ts->stackBottom = ts->allocBase + ts->stackSize; + ts->stackTop = ts->allocBase; +#else + ts->stackTop = ts->allocBase; + ts->stackBottom = ts->allocBase - ts->stackSize; +#endif + } +} + +static void *_pt_root(void *arg) +{ + PRIntn rv; + PRThread *thred = (PRThread*)arg; + PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE; + pthread_t id = pthread_self(); +#ifdef _PR_NICE_PRIORITY_SCHEDULING + pid_t tid; +#endif + +#ifdef _PR_NICE_PRIORITY_SCHEDULING + /* + * We need to know the kernel thread ID of each thread in order to + * set its nice value hence we do it here instead of at creation time. + */ + tid = gettid(); + errno = 0; + rv = getpriority(PRIO_PROCESS, 0); + + /* If we cannot read the main thread's nice value don't try to change the + * new thread's nice value. */ + if (errno == 0) { + setpriority(PRIO_PROCESS, tid, + pt_RelativePriority(rv, thred->priority)); + } +#endif + + /* + ** DCE Threads can't detach during creation, so do it late. + ** I would like to do it only here, but that doesn't seem + ** to work. + */ +#if defined(_PR_DCETHREADS) + if (detached) + { + /* pthread_detach() modifies its argument, so we must pass a copy */ + pthread_t self = id; + rv = pthread_detach(&self); + PR_ASSERT(0 == rv); + } +#endif /* defined(_PR_DCETHREADS) */ + + /* Set up the thread stack information */ + _PR_InitializeStack(thred->stack); + + /* + * Set within the current thread the pointer to our object. + * This object will be deleted when the thread termintates, + * whether in a join or detached (see _PR_InitThreads()). + */ + rv = pthread_setspecific(pt_book.key, thred); + PR_ASSERT(0 == rv); + + /* make the thread visible to the rest of the runtime */ + PR_Lock(pt_book.ml); + /* + * Both the parent thread and this new thread set thred->id. + * The new thread must ensure that thred->id is set before + * it executes its startFunc. The parent thread must ensure + * that thred->id is set before PR_CreateThread() returns. + * Both threads set thred->id while holding pt_book.ml and + * use thred->idSet to ensure thred->id is written only once. + */ + if (!thred->idSet) + { + thred->id = id; + thred->idSet = PR_TRUE; + } + else + { + PR_ASSERT(pthread_equal(thred->id, id)); + } + +#ifdef _PR_NICE_PRIORITY_SCHEDULING + thred->tid = tid; + PR_NotifyAllCondVar(pt_book.cv); +#endif + + /* If this is a GCABLE thread, set its state appropriately */ + if (thred->suspend & PT_THREAD_SETGCABLE) + thred->state |= PT_THREAD_GCABLE; + thred->suspend = 0; + + thred->prev = pt_book.last; + if (pt_book.last) + pt_book.last->next = thred; + else + pt_book.first = thred; + thred->next = NULL; + pt_book.last = thred; + PR_Unlock(pt_book.ml); + + thred->startFunc(thred->arg); /* make visible to the client */ + + /* unhook the thread from the runtime */ + PR_Lock(pt_book.ml); + /* + * At this moment, PR_CreateThread() may not have set thred->id yet. + * It is safe for a detached thread to free thred only after + * PR_CreateThread() has accessed thred->id and thred->idSet. + */ + if (detached) + { + while (!thred->okToDelete) + PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT); + } + + if (thred->state & PT_THREAD_SYSTEM) + pt_book.system -= 1; + else if (--pt_book.user == pt_book.this_many) + PR_NotifyAllCondVar(pt_book.cv); + if (NULL == thred->prev) + pt_book.first = thred->next; + else + thred->prev->next = thred->next; + if (NULL == thred->next) + pt_book.last = thred->prev; + else + thred->next->prev = thred->prev; + PR_Unlock(pt_book.ml); + + /* + * Here we set the pthread's backpointer to the PRThread to NULL. + * Otherwise the destructor would get called eagerly as the thread + * returns to the pthread runtime. The joining thread would them be + * the proud possessor of a dangling reference. However, this is the + * last chance to delete the object if the thread is detached, so + * just let the destructor do the work. + */ + if (PR_FALSE == detached) + { + /* Call TPD destructors on this thread. */ + _PR_DestroyThreadPrivate(thred); + rv = pthread_setspecific(pt_book.key, NULL); + PR_ASSERT(0 == rv); + } + + return NULL; +} /* _pt_root */ + +static PRThread* pt_AttachThread(void) +{ + PRThread *thred = NULL; + + /* + * NSPR must have been initialized when PR_AttachThread is called. + * We cannot have PR_AttachThread call implicit initialization + * because if multiple threads call PR_AttachThread simultaneously, + * NSPR may be initialized more than once. + * We can't call any function that calls PR_GetCurrentThread() + * either (e.g., PR_SetError()) as that will result in infinite + * recursion. + */ + if (!_pr_initialized) return NULL; + + /* PR_NEWZAP must not call PR_GetCurrentThread() */ + thred = PR_NEWZAP(PRThread); + if (NULL != thred) + { + int rv; + + thred->priority = PR_PRIORITY_NORMAL; + thred->id = pthread_self(); + thred->idSet = PR_TRUE; +#ifdef _PR_NICE_PRIORITY_SCHEDULING + thred->tid = gettid(); +#endif + rv = pthread_setspecific(pt_book.key, thred); + PR_ASSERT(0 == rv); + + thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN; + PR_Lock(pt_book.ml); + + /* then put it into the list */ + thred->prev = pt_book.last; + if (pt_book.last) + pt_book.last->next = thred; + else + pt_book.first = thred; + thred->next = NULL; + pt_book.last = thred; + PR_Unlock(pt_book.ml); + + } + return thred; /* may be NULL */ +} /* pt_AttachThread */ + +static PRThread* _PR_CreateThread( + PRThreadType type, void (*start)(void *arg), + void *arg, PRThreadPriority priority, PRThreadScope scope, + PRThreadState state, PRUint32 stackSize, PRBool isGCAble) +{ + int rv; + PRThread *thred; + pthread_attr_t tattr; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if ((PRIntn)PR_PRIORITY_FIRST > (PRIntn)priority) + priority = PR_PRIORITY_FIRST; + else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)priority) + priority = PR_PRIORITY_LAST; + + rv = _PT_PTHREAD_ATTR_INIT(&tattr); + PR_ASSERT(0 == rv); + + if (EPERM != pt_schedpriv) + { +#if !defined(_PR_DCETHREADS) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + struct sched_param schedule; +#endif + +#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + rv = pthread_attr_setinheritsched(&tattr, PTHREAD_EXPLICIT_SCHED); + PR_ASSERT(0 == rv); +#endif + + /* Use the default scheduling policy */ + +#if defined(_PR_DCETHREADS) + rv = pthread_attr_setprio(&tattr, pt_PriorityMap(priority)); + PR_ASSERT(0 == rv); +#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + rv = pthread_attr_getschedparam(&tattr, &schedule); + PR_ASSERT(0 == rv); + schedule.sched_priority = pt_PriorityMap(priority); + rv = pthread_attr_setschedparam(&tattr, &schedule); + PR_ASSERT(0 == rv); +#ifdef NTO + rv = pthread_attr_setschedpolicy(&tattr, SCHED_RR); /* Round Robin */ + PR_ASSERT(0 == rv); +#endif +#endif /* !defined(_PR_DCETHREADS) */ + } + + /* + * DCE threads can't set detach state before creating the thread. + * AIX can't set detach late. Why can't we all just get along? + */ +#if !defined(_PR_DCETHREADS) + rv = pthread_attr_setdetachstate(&tattr, + ((PR_JOINABLE_THREAD == state) ? + PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED)); + PR_ASSERT(0 == rv); +#endif /* !defined(_PR_DCETHREADS) */ + + /* + * If stackSize is 0, we use the default pthread stack size. + */ + if (stackSize) + { +#ifdef _MD_MINIMUM_STACK_SIZE + if (stackSize < _MD_MINIMUM_STACK_SIZE) + stackSize = _MD_MINIMUM_STACK_SIZE; +#endif + rv = pthread_attr_setstacksize(&tattr, stackSize); + PR_ASSERT(0 == rv); + } + + thred = PR_NEWZAP(PRThread); + if (NULL == thred) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, errno); + goto done; + } + else + { + pthread_t id; + + thred->arg = arg; + thred->startFunc = start; + thred->priority = priority; + if (PR_UNJOINABLE_THREAD == state) + thred->state |= PT_THREAD_DETACHED; + + if (PR_LOCAL_THREAD == scope) + scope = PR_GLOBAL_THREAD; + + if (PR_GLOBAL_BOUND_THREAD == scope) { +#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM); + if (rv) { + /* + * system scope not supported + */ + scope = PR_GLOBAL_THREAD; + /* + * reset scope + */ + rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS); + PR_ASSERT(0 == rv); + } +#endif + } + if (PR_GLOBAL_THREAD == scope) + thred->state |= PT_THREAD_GLOBAL; + else if (PR_GLOBAL_BOUND_THREAD == scope) + thred->state |= (PT_THREAD_GLOBAL | PT_THREAD_BOUND); + else /* force it global */ + thred->state |= PT_THREAD_GLOBAL; + if (PR_SYSTEM_THREAD == type) + thred->state |= PT_THREAD_SYSTEM; + + thred->suspend =(isGCAble) ? PT_THREAD_SETGCABLE : 0; + + thred->stack = PR_NEWZAP(PRThreadStack); + if (thred->stack == NULL) { + PRIntn oserr = errno; + PR_Free(thred); /* all that work ... poof! */ + PR_SetError(PR_OUT_OF_MEMORY_ERROR, oserr); + thred = NULL; /* and for what? */ + goto done; + } + thred->stack->stackSize = stackSize; + thred->stack->thr = thred; + +#ifdef PT_NO_SIGTIMEDWAIT + pthread_mutex_init(&thred->suspendResumeMutex,NULL); + pthread_cond_init(&thred->suspendResumeCV,NULL); +#endif + + /* make the thread counted to the rest of the runtime */ + PR_Lock(pt_book.ml); + if (PR_SYSTEM_THREAD == type) + pt_book.system += 1; + else pt_book.user += 1; + PR_Unlock(pt_book.ml); + + /* + * We pass a pointer to a local copy (instead of thred->id) + * to pthread_create() because who knows what wacky things + * pthread_create() may be doing to its argument. + */ + rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred); + +#if !defined(_PR_DCETHREADS) + if (EPERM == rv) + { +#if defined(IRIX) + if (PR_GLOBAL_BOUND_THREAD == scope) { + /* + * SCOPE_SYSTEM requires appropriate privilege + * reset to process scope and try again + */ + rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS); + PR_ASSERT(0 == rv); + thred->state &= ~PT_THREAD_BOUND; + } +#else + /* Remember that we don't have thread scheduling privilege. */ + pt_schedpriv = EPERM; + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("_PR_CreateThread: no thread scheduling privilege")); + /* Try creating the thread again without setting priority. */ +#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + rv = pthread_attr_setinheritsched(&tattr, PTHREAD_INHERIT_SCHED); + PR_ASSERT(0 == rv); +#endif +#endif /* IRIX */ + rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred); + } +#endif + + if (0 != rv) + { +#if defined(_PR_DCETHREADS) + PRIntn oserr = errno; +#else + PRIntn oserr = rv; +#endif + PR_Lock(pt_book.ml); + if (thred->state & PT_THREAD_SYSTEM) + pt_book.system -= 1; + else if (--pt_book.user == pt_book.this_many) + PR_NotifyAllCondVar(pt_book.cv); + PR_Unlock(pt_book.ml); + + PR_Free(thred->stack); + PR_Free(thred); /* all that work ... poof! */ + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, oserr); + thred = NULL; /* and for what? */ + goto done; + } + + PR_Lock(pt_book.ml); + /* + * Both the parent thread and this new thread set thred->id. + * The parent thread must ensure that thred->id is set before + * PR_CreateThread() returns. (See comments in _pt_root().) + */ + if (!thred->idSet) + { + thred->id = id; + thred->idSet = PR_TRUE; + } + else + { + PR_ASSERT(pthread_equal(thred->id, id)); + } + + /* + * If the new thread is detached, tell it that PR_CreateThread() has + * accessed thred->id and thred->idSet so it's ok to delete thred. + */ + if (PR_UNJOINABLE_THREAD == state) + { + thred->okToDelete = PR_TRUE; + PR_NotifyAllCondVar(pt_book.cv); + } + PR_Unlock(pt_book.ml); + } + +done: + rv = _PT_PTHREAD_ATTR_DESTROY(&tattr); + PR_ASSERT(0 == rv); + + return thred; +} /* _PR_CreateThread */ + +PR_IMPLEMENT(PRThread*) PR_CreateThread( + PRThreadType type, void (*start)(void *arg), void *arg, + PRThreadPriority priority, PRThreadScope scope, + PRThreadState state, PRUint32 stackSize) +{ + return _PR_CreateThread( + type, start, arg, priority, scope, state, stackSize, PR_FALSE); +} /* PR_CreateThread */ + +PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble( + PRThreadType type, void (*start)(void *arg), void *arg, + PRThreadPriority priority, PRThreadScope scope, + PRThreadState state, PRUint32 stackSize) +{ + return _PR_CreateThread( + type, start, arg, priority, scope, state, stackSize, PR_TRUE); +} /* PR_CreateThreadGCAble */ + +PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thred) +{ + return thred->environment; +} /* GetExecutionEnvironment */ + +PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thred, void *env) +{ + thred->environment = env; +} /* SetExecutionEnvironment */ + +PR_IMPLEMENT(PRThread*) PR_AttachThread( + PRThreadType type, PRThreadPriority priority, PRThreadStack *stack) +{ + return PR_GetCurrentThread(); +} /* PR_AttachThread */ + + +PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thred) +{ + int rv = -1; + void *result = NULL; + PR_ASSERT(thred != NULL); + + if ((0xafafafaf == thred->state) + || (PT_THREAD_DETACHED == (PT_THREAD_DETACHED & thred->state)) + || (PT_THREAD_FOREIGN == (PT_THREAD_FOREIGN & thred->state))) + { + /* + * This might be a bad address, but if it isn't, the state should + * either be an unjoinable thread or it's already had the object + * deleted. However, the client that called join on a detached + * thread deserves all the rath I can muster.... + */ + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + PR_LogPrint( + "PR_JoinThread: %p not joinable | already smashed\n", thred); + } + else + { + pthread_t id = thred->id; + rv = pthread_join(id, &result); + PR_ASSERT(rv == 0 && result == NULL); + if (0 == rv) + { +#ifdef _PR_DCETHREADS + rv = pthread_detach(&id); + PR_ASSERT(0 == rv); +#endif + /* + * PR_FALSE, because the thread already called the TPD + * destructors before exiting _pt_root. + */ + _pt_thread_death_internal(thred, PR_FALSE); + } + else + { + PRErrorCode prerror; + switch (rv) + { + case EINVAL: /* not a joinable thread */ + case ESRCH: /* no thread with given ID */ + prerror = PR_INVALID_ARGUMENT_ERROR; + break; + case EDEADLK: /* a thread joining with itself */ + prerror = PR_DEADLOCK_ERROR; + break; + default: + prerror = PR_UNKNOWN_ERROR; + break; + } + PR_SetError(prerror, rv); + } + } + return (0 == rv) ? PR_SUCCESS : PR_FAILURE; +} /* PR_JoinThread */ + +PR_IMPLEMENT(void) PR_DetachThread(void) +{ + void *thred; + int rv; + + _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); + if (NULL == thred) return; + _pt_thread_death(thred); + rv = pthread_setspecific(pt_book.key, NULL); + PR_ASSERT(0 == rv); +} /* PR_DetachThread */ + +PR_IMPLEMENT(PRThread*) PR_GetCurrentThread(void) +{ + void *thred; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); + if (NULL == thred) thred = pt_AttachThread(); + PR_ASSERT(NULL != thred); + return (PRThread*)thred; +} /* PR_GetCurrentThread */ + +PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thred) +{ + return (thred->state & PT_THREAD_BOUND) ? + PR_GLOBAL_BOUND_THREAD : PR_GLOBAL_THREAD; +} /* PR_GetThreadScope() */ + +PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thred) +{ + return (thred->state & PT_THREAD_SYSTEM) ? + PR_SYSTEM_THREAD : PR_USER_THREAD; +} + +PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thred) +{ + return (thred->state & PT_THREAD_DETACHED) ? + PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD; +} /* PR_GetThreadState */ + +PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thred) +{ + PR_ASSERT(thred != NULL); + return thred->priority; +} /* PR_GetThreadPriority */ + +PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred, PRThreadPriority newPri) +{ + PRIntn rv = -1; + + PR_ASSERT(NULL != thred); + + if ((PRIntn)PR_PRIORITY_FIRST > (PRIntn)newPri) + newPri = PR_PRIORITY_FIRST; + else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)newPri) + newPri = PR_PRIORITY_LAST; + +#if defined(_PR_DCETHREADS) + rv = pthread_setprio(thred->id, pt_PriorityMap(newPri)); + /* pthread_setprio returns the old priority */ +#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + if (EPERM != pt_schedpriv) + { + int policy; + struct sched_param schedule; + + rv = pthread_getschedparam(thred->id, &policy, &schedule); + if(0 == rv) { + schedule.sched_priority = pt_PriorityMap(newPri); + rv = pthread_setschedparam(thred->id, policy, &schedule); + if (EPERM == rv) + { + pt_schedpriv = EPERM; + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("PR_SetThreadPriority: no thread scheduling privilege")); + } + } + if (rv != 0) + rv = -1; + } +#elif defined(_PR_NICE_PRIORITY_SCHEDULING) + PR_Lock(pt_book.ml); + while (thred->tid == 0) + PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(pt_book.ml); + + errno = 0; + rv = getpriority(PRIO_PROCESS, 0); + + /* Do not proceed unless we know the main thread's nice value. */ + if (errno == 0) { + rv = setpriority(PRIO_PROCESS, thred->tid, + pt_RelativePriority(rv, newPri)); + + if (rv == -1) + { + /* We don't set pt_schedpriv to EPERM in case errno == EPERM + * because adjusting the nice value might be permitted for certain + * ranges but not for others. */ + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("PR_SetThreadPriority: setpriority failed with error %d", + errno)); + } + } +#endif + + thred->priority = newPri; +} /* PR_SetThreadPriority */ + +PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred) +{ + /* + ** If the target thread indicates that it's waiting, + ** find the condition and broadcast to it. Broadcast + ** since we don't know which thread (if there are more + ** than one). This sounds risky, but clients must + ** test their invariants when resumed from a wait and + ** I don't expect very many threads to be waiting on + ** a single condition and I don't expect interrupt to + ** be used very often. + ** + ** I don't know why I thought this would work. Must have + ** been one of those weaker momements after I'd been + ** smelling the vapors. + ** + ** Even with the followng changes it is possible that + ** the pointer to the condition variable is pointing + ** at a bogus value. Will the unerlying code detect + ** that? + */ + PRCondVar *cv; + PR_ASSERT(NULL != thred); + if (NULL == thred) return PR_FAILURE; + + thred->state |= PT_THREAD_ABORTED; + + cv = thred->waiting; + if ((NULL != cv) && !thred->interrupt_blocked) + { + PRIntn rv; + (void)PR_ATOMIC_INCREMENT(&cv->notify_pending); + rv = pthread_cond_broadcast(&cv->cv); + PR_ASSERT(0 == rv); + if (0 > PR_ATOMIC_DECREMENT(&cv->notify_pending)) + PR_DestroyCondVar(cv); + } + return PR_SUCCESS; +} /* PR_Interrupt */ + +PR_IMPLEMENT(void) PR_ClearInterrupt(void) +{ + PRThread *me = PR_GetCurrentThread(); + me->state &= ~PT_THREAD_ABORTED; +} /* PR_ClearInterrupt */ + +PR_IMPLEMENT(void) PR_BlockInterrupt(void) +{ + PRThread *me = PR_GetCurrentThread(); + _PT_THREAD_BLOCK_INTERRUPT(me); +} /* PR_BlockInterrupt */ + +PR_IMPLEMENT(void) PR_UnblockInterrupt(void) +{ + PRThread *me = PR_GetCurrentThread(); + _PT_THREAD_UNBLOCK_INTERRUPT(me); +} /* PR_UnblockInterrupt */ + +PR_IMPLEMENT(PRStatus) PR_Yield(void) +{ + static PRBool warning = PR_TRUE; + if (warning) warning = _PR_Obsolete( + "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)"); + return PR_Sleep(PR_INTERVAL_NO_WAIT); +} + +PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks) +{ + PRStatus rv = PR_SUCCESS; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (PR_INTERVAL_NO_WAIT == ticks) + { + _PT_PTHREAD_YIELD(); + } + else + { + PRCondVar *cv; + PRIntervalTime timein; + + timein = PR_IntervalNow(); + cv = PR_NewCondVar(_pr_sleeplock); + PR_ASSERT(cv != NULL); + PR_Lock(_pr_sleeplock); + do + { + PRIntervalTime now = PR_IntervalNow(); + PRIntervalTime delta = now - timein; + if (delta > ticks) break; + rv = PR_WaitCondVar(cv, ticks - delta); + } while (PR_SUCCESS == rv); + PR_Unlock(_pr_sleeplock); + PR_DestroyCondVar(cv); + } + return rv; +} /* PR_Sleep */ + +static void _pt_thread_death(void *arg) +{ + void *thred; + int rv; + + _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); + if (NULL == thred) + { + /* + * Have PR_GetCurrentThread return the expected value to the + * destructors. + */ + rv = pthread_setspecific(pt_book.key, arg); + PR_ASSERT(0 == rv); + } + + /* PR_TRUE for: call destructors */ + _pt_thread_death_internal(arg, PR_TRUE); + + if (NULL == thred) + { + rv = pthread_setspecific(pt_book.key, NULL); + PR_ASSERT(0 == rv); + } +} + +static void _pt_thread_death_internal(void *arg, PRBool callDestructors) +{ + PRThread *thred = (PRThread*)arg; + + if (thred->state & (PT_THREAD_FOREIGN|PT_THREAD_PRIMORD)) + { + PR_Lock(pt_book.ml); + if (NULL == thred->prev) + pt_book.first = thred->next; + else + thred->prev->next = thred->next; + if (NULL == thred->next) + pt_book.last = thred->prev; + else + thred->next->prev = thred->prev; + PR_Unlock(pt_book.ml); + } + if (callDestructors) + _PR_DestroyThreadPrivate(thred); + PR_Free(thred->privateData); + if (NULL != thred->errorString) + PR_Free(thred->errorString); + if (NULL != thred->name) + PR_Free(thred->name); + PR_Free(thred->stack); + if (NULL != thred->syspoll_list) + PR_Free(thred->syspoll_list); +#if defined(_PR_POLL_WITH_SELECT) + if (NULL != thred->selectfd_list) + PR_Free(thred->selectfd_list); +#endif +#if defined(DEBUG) + memset(thred, 0xaf, sizeof(PRThread)); +#endif /* defined(DEBUG) */ + PR_Free(thred); +} /* _pt_thread_death */ + +void _PR_InitThreads( + PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs) +{ + int rv; + PRThread *thred; + + PR_ASSERT(priority == PR_PRIORITY_NORMAL); + +#ifdef _PR_NEED_PTHREAD_INIT + /* + * On BSD/OS (3.1 and 4.0), the pthread subsystem is lazily + * initialized, but pthread_self() fails to initialize + * pthreads and hence returns a null thread ID if invoked + * by the primordial thread before any other pthread call. + * So we explicitly initialize pthreads here. + */ + pthread_init(); +#endif + +#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) +#if defined(FREEBSD) + { + pthread_attr_t attr; + int policy; + /* get the min and max priorities of the default policy */ + pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_getschedpolicy(&attr, &policy); + pt_book.minPrio = sched_get_priority_min(policy); + PR_ASSERT(-1 != pt_book.minPrio); + pt_book.maxPrio = sched_get_priority_max(policy); + PR_ASSERT(-1 != pt_book.maxPrio); + pthread_attr_destroy(&attr); + } +#else + /* + ** These might be function evaluations + */ + pt_book.minPrio = PT_PRIO_MIN; + pt_book.maxPrio = PT_PRIO_MAX; +#endif +#endif + + PR_ASSERT(NULL == pt_book.ml); + pt_book.ml = PR_NewLock(); + PR_ASSERT(NULL != pt_book.ml); + pt_book.cv = PR_NewCondVar(pt_book.ml); + PR_ASSERT(NULL != pt_book.cv); + thred = PR_NEWZAP(PRThread); + PR_ASSERT(NULL != thred); + thred->arg = NULL; + thred->startFunc = NULL; + thred->priority = priority; + thred->id = pthread_self(); + thred->idSet = PR_TRUE; +#ifdef _PR_NICE_PRIORITY_SCHEDULING + thred->tid = gettid(); +#endif + + thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD); + if (PR_SYSTEM_THREAD == type) + { + thred->state |= PT_THREAD_SYSTEM; + pt_book.system += 1; + pt_book.this_many = 0; + } + else + { + pt_book.user += 1; + pt_book.this_many = 1; + } + thred->next = thred->prev = NULL; + pt_book.first = pt_book.last = thred; + + thred->stack = PR_NEWZAP(PRThreadStack); + PR_ASSERT(thred->stack != NULL); + thred->stack->stackSize = 0; + thred->stack->thr = thred; + _PR_InitializeStack(thred->stack); + + /* + * Create a key for our use to store a backpointer in the pthread + * to our PRThread object. This object gets deleted when the thread + * returns from its root in the case of a detached thread. Other + * threads delete the objects in Join. + * + * NB: The destructor logic seems to have a bug so it isn't used. + * NBB: Oh really? I'm going to give it a spin - AOF 19 June 1998. + * More info - the problem is that pthreads calls the destructor + * eagerly as the thread returns from its root, rather than lazily + * after the thread is joined. Therefore, threads that are joining + * and holding PRThread references are actually holding pointers to + * nothing. + */ + rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death); + if (0 != rv) + PR_Assert("0 == rv", __FILE__, __LINE__); + pt_book.keyCreated = PR_TRUE; + rv = pthread_setspecific(pt_book.key, thred); + PR_ASSERT(0 == rv); +} /* _PR_InitThreads */ + +#ifdef __GNUC__ +/* + * GCC supports the constructor and destructor attributes as of + * version 2.5. + */ +static void _PR_Fini(void) __attribute__ ((destructor)); +#elif defined(__SUNPRO_C) +/* + * Sun Studio compiler + */ +#pragma fini(_PR_Fini) +static void _PR_Fini(void); +#elif defined(HPUX) +/* + * Current versions of HP C compiler define __HP_cc. + * HP C compiler A.11.01.20 doesn't define __HP_cc. + */ +#if defined(__ia64) || defined(_LP64) +#pragma FINI "_PR_Fini" +static void _PR_Fini(void); +#else +/* + * Only HP-UX 10.x style initializers are supported in 32-bit links. + * Need to use the +I PR_HPUX10xInit linker option. + */ +#include + +static void _PR_Fini(void); + +void PR_HPUX10xInit(shl_t handle, int loading) +{ + /* + * This function is called when a shared library is loaded as well + * as when the shared library is unloaded. Note that it may not + * be called when the user's program terminates. + * + * handle is the shl_load API handle for the shared library being + * initialized. + * + * loading is non-zero at startup and zero at termination. + */ + if (loading) { + /* ... do some initializations ... */ + } else { + _PR_Fini(); + } +} +#endif +#elif defined(AIX) +/* Need to use the -binitfini::_PR_Fini linker option. */ +#endif + +void _PR_Fini(void) +{ + void *thred; + int rv; + + if (!_pr_initialized) { + /* Either NSPR was never successfully initialized or + * PR_Cleanup has been called already. */ + if (pt_book.keyCreated) + { + rv = pthread_key_delete(pt_book.key); + PR_ASSERT(0 == rv); + pt_book.keyCreated = PR_FALSE; + } + return; + } + + _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); + if (NULL != thred) + { + /* + * PR_FALSE, because it is unsafe to call back to the + * thread private data destructors at final cleanup. + */ + _pt_thread_death_internal(thred, PR_FALSE); + rv = pthread_setspecific(pt_book.key, NULL); + PR_ASSERT(0 == rv); + } + rv = pthread_key_delete(pt_book.key); + PR_ASSERT(0 == rv); + pt_book.keyCreated = PR_FALSE; + /* TODO: free other resources used by NSPR */ + /* _pr_initialized = PR_FALSE; */ +} /* _PR_Fini */ + +PR_IMPLEMENT(PRStatus) PR_Cleanup(void) +{ + PRThread *me = PR_GetCurrentThread(); + int rv; + PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR")); + PR_ASSERT(me->state & PT_THREAD_PRIMORD); + if (me->state & PT_THREAD_PRIMORD) + { + PR_Lock(pt_book.ml); + while (pt_book.user > pt_book.this_many) + PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT); + if (me->state & PT_THREAD_SYSTEM) + pt_book.system -= 1; + else + pt_book.user -= 1; + PR_Unlock(pt_book.ml); + + _PR_MD_EARLY_CLEANUP(); + + _PR_CleanupMW(); + _PR_CleanupTime(); + _PR_CleanupDtoa(); + _PR_CleanupCallOnce(); + _PR_ShutdownLinker(); + _PR_LogCleanup(); + _PR_CleanupNet(); + /* Close all the fd's before calling _PR_CleanupIO */ + _PR_CleanupIO(); + _PR_CleanupCMon(); + + _pt_thread_death(me); + rv = pthread_setspecific(pt_book.key, NULL); + PR_ASSERT(0 == rv); + /* + * I am not sure if it's safe to delete the cv and lock here, + * since there may still be "system" threads around. If this + * call isn't immediately prior to exiting, then there's a + * problem. + */ + if (0 == pt_book.system) + { + PR_DestroyCondVar(pt_book.cv); pt_book.cv = NULL; + PR_DestroyLock(pt_book.ml); pt_book.ml = NULL; + } + PR_DestroyLock(_pr_sleeplock); + _pr_sleeplock = NULL; + _PR_CleanupLayerCache(); + _PR_CleanupEnv(); +#ifdef _PR_ZONE_ALLOCATOR + _PR_DestroyZones(); +#endif + _pr_initialized = PR_FALSE; + return PR_SUCCESS; + } + return PR_FAILURE; +} /* PR_Cleanup */ + +PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status) +{ + _exit(status); +} + +PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thred) +{ +#if defined(_PR_DCETHREADS) + return (PRUint32)&thred->id; /* this is really a sham! */ +#else + return (PRUint32)thred->id; /* and I don't know what they will do with it */ +#endif +} + +/* + * $$$ + * The following two thread-to-processor affinity functions are not + * yet implemented for pthreads. By the way, these functions should return + * PRStatus rather than PRInt32 to indicate the success/failure status. + * $$$ + */ + +PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask) +{ + return 0; /* not implemented */ +} + +PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask ) +{ + return 0; /* not implemented */ +} + +PR_IMPLEMENT(void) +PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg) +{ + thread->dump = dump; + thread->dumpArg = arg; +} + +/* + * Garbage collection support follows. + */ + +#if defined(_PR_DCETHREADS) + +/* + * statics for Garbage Collection support. We don't need to protect these + * signal masks since the garbage collector itself is protected by a lock + * and multiple threads will not be garbage collecting at the same time. + */ +static sigset_t javagc_vtalarm_sigmask; +static sigset_t javagc_intsoff_sigmask; + +#else /* defined(_PR_DCETHREADS) */ + +/* a bogus signal mask for forcing a timed wait */ +/* Not so bogus in AIX as we really do a sigwait */ +static sigset_t sigwait_set; + +static struct timespec onemillisec = {0, 1000000L}; +#ifndef PT_NO_SIGTIMEDWAIT +static struct timespec hundredmillisec = {0, 100000000L}; +#endif + +static void suspend_signal_handler(PRIntn sig); + +#ifdef PT_NO_SIGTIMEDWAIT +static void null_signal_handler(PRIntn sig); +#endif + +#endif /* defined(_PR_DCETHREADS) */ + +/* + * Linux pthreads use SIGUSR1 and SIGUSR2 internally, which + * conflict with the use of these two signals in our GC support. + * So we don't know how to support GC on Linux pthreads. + */ +static void init_pthread_gc_support(void) +{ +#ifndef SYMBIAN + PRIntn rv; + +#if defined(_PR_DCETHREADS) + rv = sigemptyset(&javagc_vtalarm_sigmask); + PR_ASSERT(0 == rv); + rv = sigaddset(&javagc_vtalarm_sigmask, SIGVTALRM); + PR_ASSERT(0 == rv); +#else /* defined(_PR_DCETHREADS) */ + { + struct sigaction sigact_usr2; + + sigact_usr2.sa_handler = suspend_signal_handler; + sigact_usr2.sa_flags = SA_RESTART; + sigemptyset (&sigact_usr2.sa_mask); + + rv = sigaction (SIGUSR2, &sigact_usr2, NULL); + PR_ASSERT(0 == rv); + + sigemptyset (&sigwait_set); +#if defined(PT_NO_SIGTIMEDWAIT) + sigaddset (&sigwait_set, SIGUSR1); +#else + sigaddset (&sigwait_set, SIGUSR2); +#endif /* defined(PT_NO_SIGTIMEDWAIT) */ + } +#if defined(PT_NO_SIGTIMEDWAIT) + { + struct sigaction sigact_null; + sigact_null.sa_handler = null_signal_handler; + sigact_null.sa_flags = SA_RESTART; + sigemptyset (&sigact_null.sa_mask); + rv = sigaction (SIGUSR1, &sigact_null, NULL); + PR_ASSERT(0 ==rv); + } +#endif /* defined(PT_NO_SIGTIMEDWAIT) */ +#endif /* defined(_PR_DCETHREADS) */ +#endif /* SYMBIAN */ +} + +PR_IMPLEMENT(void) PR_SetThreadGCAble(void) +{ + PR_Lock(pt_book.ml); + PR_GetCurrentThread()->state |= PT_THREAD_GCABLE; + PR_Unlock(pt_book.ml); +} + +PR_IMPLEMENT(void) PR_ClearThreadGCAble(void) +{ + PR_Lock(pt_book.ml); + PR_GetCurrentThread()->state &= (~PT_THREAD_GCABLE); + PR_Unlock(pt_book.ml); +} + +#if defined(DEBUG) +static PRBool suspendAllOn = PR_FALSE; +#endif + +static PRBool suspendAllSuspended = PR_FALSE; + +PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg) +{ + PRIntn count = 0; + PRStatus rv = PR_SUCCESS; + PRThread* thred = pt_book.first; + +#if defined(DEBUG) || defined(FORCE_PR_ASSERT) +#if !defined(_PR_DCETHREADS) + PRThread *me = PR_GetCurrentThread(); +#endif +#endif + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_EnumerateThreads\n")); + /* + * $$$ + * Need to suspend all threads other than me before doing this. + * This is really a gross and disgusting thing to do. The only + * good thing is that since all other threads are suspended, holding + * the lock during a callback seems like child's play. + * $$$ + */ + PR_ASSERT(suspendAllOn); + + while (thred != NULL) + { + /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking + * qp->next after applying the function "func". In particular, "func" + * might remove the thread from the queue and put it into another one in + * which case qp->next no longer points to the next entry in the original + * queue. + * + * To get around this problem, we save qp->next in qp_next before applying + * "func" and use that saved value as the next value after applying "func". + */ + PRThread* next = thred->next; + + if (_PT_IS_GCABLE_THREAD(thred)) + { +#if !defined(_PR_DCETHREADS) + PR_ASSERT((thred == me) || (thred->suspend & PT_THREAD_SUSPENDED)); +#endif + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("In PR_EnumerateThreads callback thread %p thid = %X\n", + thred, thred->id)); + + rv = func(thred, count++, arg); + if (rv != PR_SUCCESS) + return rv; + } + thred = next; + } + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("End PR_EnumerateThreads count = %d \n", count)); + return rv; +} /* PR_EnumerateThreads */ + +/* + * PR_SuspendAll and PR_ResumeAll are called during garbage collection. The strategy + * we use is to send a SIGUSR2 signal to every gc able thread that we intend to suspend. + * The signal handler will record the stack pointer and will block until resumed by + * the resume call. Since the signal handler is the last routine called for the + * suspended thread, the stack pointer will also serve as a place where all the + * registers have been saved on the stack for the previously executing routines. + * + * Through global variables, we also make sure that PR_Suspend and PR_Resume does not + * proceed until the thread is suspended or resumed. + */ + +#if !defined(_PR_DCETHREADS) + +/* + * In the signal handler, we can not use condition variable notify or wait. + * This does not work consistently across all pthread platforms. We also can not + * use locking since that does not seem to work reliably across platforms. + * Only thing we can do is yielding while testing for a global condition + * to change. This does work on pthread supported platforms. We may have + * to play with priortities if there are any problems detected. + */ + + /* + * In AIX, you cannot use ANY pthread calls in the signal handler except perhaps + * pthread_yield. But that is horribly inefficient. Hence we use only sigwait, no + * sigtimedwait is available. We need to use another user signal, SIGUSR1. Actually + * SIGUSR1 is also used by exec in Java. So our usage here breaks the exec in Java, + * for AIX. You cannot use pthread_cond_wait or pthread_delay_np in the signal + * handler as all synchronization mechanisms just break down. + */ + +#if defined(PT_NO_SIGTIMEDWAIT) +static void null_signal_handler(PRIntn sig) +{ + return; +} +#endif + +static void suspend_signal_handler(PRIntn sig) +{ + PRThread *me = PR_GetCurrentThread(); + + PR_ASSERT(me != NULL); + PR_ASSERT(_PT_IS_GCABLE_THREAD(me)); + PR_ASSERT((me->suspend & PT_THREAD_SUSPENDED) == 0); + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("Begin suspend_signal_handler thred %p thread id = %X\n", + me, me->id)); + + /* + * save stack pointer + */ + me->sp = &me; + + /* + At this point, the thread's stack pointer has been saved, + And it is going to enter a wait loop until it is resumed. + So it is _really_ suspended + */ + + me->suspend |= PT_THREAD_SUSPENDED; + + /* + * now, block current thread + */ +#if defined(PT_NO_SIGTIMEDWAIT) + pthread_cond_signal(&me->suspendResumeCV); + while (me->suspend & PT_THREAD_SUSPENDED) + { +#if !defined(FREEBSD) && !defined(NETBSD) && !defined(OPENBSD) \ + && !defined(BSDI) && !defined(UNIXWARE) \ + && !defined(DARWIN) && !defined(RISCOS) \ + && !defined(SYMBIAN) /*XXX*/ + PRIntn rv; + sigwait(&sigwait_set, &rv); +#endif + } + me->suspend |= PT_THREAD_RESUMED; + pthread_cond_signal(&me->suspendResumeCV); +#else /* defined(PT_NO_SIGTIMEDWAIT) */ + while (me->suspend & PT_THREAD_SUSPENDED) + { + PRIntn rv = sigtimedwait(&sigwait_set, NULL, &hundredmillisec); + PR_ASSERT(-1 == rv); + } + me->suspend |= PT_THREAD_RESUMED; +#endif + + /* + * At this point, thread has been resumed, so set a global condition. + * The ResumeAll needs to know that this has really been resumed. + * So the signal handler sets a flag which PR_ResumeAll will reset. + * The PR_ResumeAll must reset this flag ... + */ + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("End suspend_signal_handler thred = %p tid = %X\n", me, me->id)); +} /* suspend_signal_handler */ + +static void pt_SuspendSet(PRThread *thred) +{ + PRIntn rv; + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("pt_SuspendSet thred %p thread id = %X\n", thred, thred->id)); + + + /* + * Check the thread state and signal the thread to suspend + */ + + PR_ASSERT((thred->suspend & PT_THREAD_SUSPENDED) == 0); + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("doing pthread_kill in pt_SuspendSet thred %p tid = %X\n", + thred, thred->id)); +#if defined(SYMBIAN) + /* All signal group functions are not implemented in Symbian OS */ + rv = 0; +#else + rv = pthread_kill (thred->id, SIGUSR2); +#endif + PR_ASSERT(0 == rv); +} + +static void pt_SuspendTest(PRThread *thred) +{ + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("Begin pt_SuspendTest thred %p thread id = %X\n", thred, thred->id)); + + + /* + * Wait for the thread to be really suspended. This happens when the + * suspend signal handler stores the stack pointer and sets the state + * to suspended. + */ + +#if defined(PT_NO_SIGTIMEDWAIT) + pthread_mutex_lock(&thred->suspendResumeMutex); + while ((thred->suspend & PT_THREAD_SUSPENDED) == 0) + { + pthread_cond_timedwait( + &thred->suspendResumeCV, &thred->suspendResumeMutex, &onemillisec); + } + pthread_mutex_unlock(&thred->suspendResumeMutex); +#else + while ((thred->suspend & PT_THREAD_SUSPENDED) == 0) + { + PRIntn rv = sigtimedwait(&sigwait_set, NULL, &onemillisec); + PR_ASSERT(-1 == rv); + } +#endif + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("End pt_SuspendTest thred %p tid %X\n", thred, thred->id)); +} /* pt_SuspendTest */ + +static void pt_ResumeSet(PRThread *thred) +{ + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("pt_ResumeSet thred %p thread id = %X\n", thred, thred->id)); + + /* + * Clear the global state and set the thread state so that it will + * continue past yield loop in the suspend signal handler + */ + + PR_ASSERT(thred->suspend & PT_THREAD_SUSPENDED); + + + thred->suspend &= ~PT_THREAD_SUSPENDED; + +#if defined(PT_NO_SIGTIMEDWAIT) +#if defined(SYMBIAN) + /* All signal group functions are not implemented in Symbian OS */ +#else + pthread_kill(thred->id, SIGUSR1); +#endif +#endif + +} /* pt_ResumeSet */ + +static void pt_ResumeTest(PRThread *thred) +{ + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("Begin pt_ResumeTest thred %p thread id = %X\n", thred, thred->id)); + + /* + * Wait for the threads resume state to change + * to indicate it is really resumed + */ +#if defined(PT_NO_SIGTIMEDWAIT) + pthread_mutex_lock(&thred->suspendResumeMutex); + while ((thred->suspend & PT_THREAD_RESUMED) == 0) + { + pthread_cond_timedwait( + &thred->suspendResumeCV, &thred->suspendResumeMutex, &onemillisec); + } + pthread_mutex_unlock(&thred->suspendResumeMutex); +#else + while ((thred->suspend & PT_THREAD_RESUMED) == 0) { + PRIntn rv = sigtimedwait(&sigwait_set, NULL, &onemillisec); + PR_ASSERT(-1 == rv); + } +#endif + + thred->suspend &= ~PT_THREAD_RESUMED; + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ( + "End pt_ResumeTest thred %p tid %X\n", thred, thred->id)); +} /* pt_ResumeTest */ + +static pthread_once_t pt_gc_support_control = PTHREAD_ONCE_INIT; + +PR_IMPLEMENT(void) PR_SuspendAll(void) +{ +#ifdef DEBUG + PRIntervalTime stime, etime; +#endif + PRThread* thred = pt_book.first; + PRThread *me = PR_GetCurrentThread(); + int rv; + + rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support); + PR_ASSERT(0 == rv); + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n")); + /* + * Stop all threads which are marked GC able. + */ + PR_Lock(pt_book.ml); +#ifdef DEBUG + suspendAllOn = PR_TRUE; + stime = PR_IntervalNow(); +#endif + while (thred != NULL) + { + if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) + pt_SuspendSet(thred); + thred = thred->next; + } + + /* Wait till they are really suspended */ + thred = pt_book.first; + while (thred != NULL) + { + if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) + pt_SuspendTest(thred); + thred = thred->next; + } + + suspendAllSuspended = PR_TRUE; + +#ifdef DEBUG + etime = PR_IntervalNow(); + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,\ + ("End PR_SuspendAll (time %dms)\n", + PR_IntervalToMilliseconds(etime - stime))); +#endif +} /* PR_SuspendAll */ + +PR_IMPLEMENT(void) PR_ResumeAll(void) +{ +#ifdef DEBUG + PRIntervalTime stime, etime; +#endif + PRThread* thred = pt_book.first; + PRThread *me = PR_GetCurrentThread(); + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n")); + /* + * Resume all previously suspended GC able threads. + */ + suspendAllSuspended = PR_FALSE; +#ifdef DEBUG + stime = PR_IntervalNow(); +#endif + + while (thred != NULL) + { + if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) + pt_ResumeSet(thred); + thred = thred->next; + } + + thred = pt_book.first; + while (thred != NULL) + { + if ((thred != me) && _PT_IS_GCABLE_THREAD(thred)) + pt_ResumeTest(thred); + thred = thred->next; + } + + PR_Unlock(pt_book.ml); +#ifdef DEBUG + suspendAllOn = PR_FALSE; + etime = PR_IntervalNow(); + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("End PR_ResumeAll (time %dms)\n", + PR_IntervalToMilliseconds(etime - stime))); +#endif +} /* PR_ResumeAll */ + +/* Return the stack pointer for the given thread- used by the GC */ +PR_IMPLEMENT(void *)PR_GetSP(PRThread *thred) +{ + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, + ("in PR_GetSP thred %p thid = %X, sp = %p\n", + thred, thred->id, thred->sp)); + return thred->sp; +} /* PR_GetSP */ + +#else /* !defined(_PR_DCETHREADS) */ + +static pthread_once_t pt_gc_support_control = pthread_once_init; + +/* + * For DCE threads, there is no pthread_kill or a way of suspending or resuming a + * particular thread. We will just disable the preemption (virtual timer alarm) and + * let the executing thread finish the garbage collection. This stops all other threads + * (GC able or not) and is very inefficient but there is no other choice. + */ +PR_IMPLEMENT(void) PR_SuspendAll() +{ + PRIntn rv; + + rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support); + PR_ASSERT(0 == rv); /* returns -1 on failure */ +#ifdef DEBUG + suspendAllOn = PR_TRUE; +#endif + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n")); + /* + * turn off preemption - i.e add virtual alarm signal to the set of + * blocking signals + */ + rv = sigprocmask( + SIG_BLOCK, &javagc_vtalarm_sigmask, &javagc_intsoff_sigmask); + PR_ASSERT(0 == rv); + suspendAllSuspended = PR_TRUE; + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_SuspendAll\n")); +} /* PR_SuspendAll */ + +PR_IMPLEMENT(void) PR_ResumeAll() +{ + PRIntn rv; + + suspendAllSuspended = PR_FALSE; + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n")); + /* turn on preemption - i.e re-enable virtual alarm signal */ + + rv = sigprocmask(SIG_SETMASK, &javagc_intsoff_sigmask, (sigset_t *)NULL); + PR_ASSERT(0 == rv); +#ifdef DEBUG + suspendAllOn = PR_FALSE; +#endif + + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_ResumeAll\n")); +} /* PR_ResumeAll */ + +/* Return the stack pointer for the given thread- used by the GC */ +PR_IMPLEMENT(void*)PR_GetSP(PRThread *thred) +{ + pthread_t tid = thred->id; + char *thread_tcb, *top_sp; + + /* + * For HPUX DCE threads, pthread_t is a struct with the + * following three fields (see pthread.h, dce/cma.h): + * cma_t_address field1; + * short int field2; + * short int field3; + * where cma_t_address is typedef'd to be either void* + * or char*. + */ + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_GetSP\n")); + thread_tcb = (char*)tid.field1; + top_sp = *(char**)(thread_tcb + 128); + PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_GetSP %p \n", top_sp)); + return top_sp; +} /* PR_GetSP */ + +#endif /* !defined(_PR_DCETHREADS) */ + +PR_IMPLEMENT(PRStatus) PR_SetCurrentThreadName(const char *name) +{ + PRThread *thread; + size_t nameLen; + int result; + + if (!name) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + thread = PR_GetCurrentThread(); + if (!thread) + return PR_FAILURE; + + PR_Free(thread->name); + nameLen = strlen(name); + thread->name = (char *)PR_Malloc(nameLen + 1); + if (!thread->name) + return PR_FAILURE; + memcpy(thread->name, name, nameLen + 1); + +#if defined(OPENBSD) || defined(FREEBSD) + result = pthread_set_name_np(thread->id, name); +#else /* not BSD */ + /* + * On OSX, pthread_setname_np is only available in 10.6 or later, so test + * for it at runtime. It also may not be available on all linux distros. + */ +#if defined(DARWIN) + int (*dynamic_pthread_setname_np)(const char*); +#else + int (*dynamic_pthread_setname_np)(pthread_t, const char*); +#endif + + *(void**)(&dynamic_pthread_setname_np) = + dlsym(RTLD_DEFAULT, "pthread_setname_np"); + if (!dynamic_pthread_setname_np) + return PR_SUCCESS; + + /* + * The 15-character name length limit is an experimentally determined + * length of a null-terminated string that most linux distros and OS X + * accept as an argument to pthread_setname_np. Otherwise the E2BIG + * error is returned by the function. + */ +#define SETNAME_LENGTH_CONSTRAINT 15 +#define SETNAME_FRAGMENT1_LENGTH (SETNAME_LENGTH_CONSTRAINT >> 1) +#define SETNAME_FRAGMENT2_LENGTH \ + (SETNAME_LENGTH_CONSTRAINT - SETNAME_FRAGMENT1_LENGTH - 1) + char name_dup[SETNAME_LENGTH_CONSTRAINT + 1]; + if (nameLen > SETNAME_LENGTH_CONSTRAINT) { + memcpy(name_dup, name, SETNAME_FRAGMENT1_LENGTH); + name_dup[SETNAME_FRAGMENT1_LENGTH] = '~'; + /* Note that this also copies the null terminator. */ + memcpy(name_dup + SETNAME_FRAGMENT1_LENGTH + 1, + name + nameLen - SETNAME_FRAGMENT2_LENGTH, + SETNAME_FRAGMENT2_LENGTH + 1); + name = name_dup; + } + +#if defined(DARWIN) + result = dynamic_pthread_setname_np(name); +#else + result = dynamic_pthread_setname_np(thread->id, name); +#endif +#endif /* not BSD */ + + if (result) { + PR_SetError(PR_UNKNOWN_ERROR, result); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) +{ + if (!thread) + return NULL; + return thread->name; +} + +#endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */ + +/* ptthread.c */ diff -Nru nspr-4.9.5/nspr/pr/src/threads/combined/.cvsignore nspr-4.10.7/nspr/pr/src/threads/combined/.cvsignore --- nspr-4.9.5/nspr/pr/src/threads/combined/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/combined/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/threads/combined/Makefile.in nspr-4.10.7/nspr/pr/src/threads/combined/Makefile.in --- nspr-4.9.5/nspr/pr/src/threads/combined/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/combined/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,40 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +ifdef USE_PTHREADS +CSRCS = \ + $(NULL) +else +CSRCS = \ + prucpu.c \ + prucv.c \ + prulock.c \ + pruthr.c \ + prustack.c \ + $(NULL) +endif + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/threads/combined/prucpu.c nspr-4.10.7/nspr/pr/src/threads/combined/prucpu.c --- nspr-4.9.5/nspr/pr/src/threads/combined/prucpu.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/combined/prucpu.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,405 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +_PRCPU *_pr_primordialCPU = NULL; + +PRInt32 _pr_md_idle_cpus; /* number of idle cpus */ +/* + * The idle threads in MxN models increment/decrement _pr_md_idle_cpus. + * If _PR_HAVE_ATOMIC_OPS is not defined, they can't use the atomic + * increment/decrement routines (which are based on PR_Lock/PR_Unlock), + * because PR_Lock asserts that the calling thread is not an idle thread. + * So we use a _MDLock to protect _pr_md_idle_cpus. + */ +#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY) +#ifndef _PR_HAVE_ATOMIC_OPS +static _MDLock _pr_md_idle_cpus_lock; +#endif +#endif +PRUintn _pr_numCPU; +PRInt32 _pr_cpus_exit; +PRUint32 _pr_cpu_affinity_mask = 0; + +#if !defined (_PR_GLOBAL_THREADS_ONLY) + +static PRUintn _pr_cpuID; + +static void PR_CALLBACK _PR_CPU_Idle(void *); + +static _PRCPU *_PR_CreateCPU(void); +static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread); + +#if !defined(_PR_LOCAL_THREADS_ONLY) +static void _PR_RunCPU(void *arg); +#endif + +void _PR_InitCPUs() +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_native_threads_only) + return; + + _pr_cpuID = 0; + _MD_NEW_LOCK( &_pr_cpuLock); +#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY) +#ifndef _PR_HAVE_ATOMIC_OPS + _MD_NEW_LOCK(&_pr_md_idle_cpus_lock); +#endif +#endif + +#ifdef _PR_LOCAL_THREADS_ONLY + +#ifdef HAVE_CUSTOM_USER_THREADS + _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me); +#endif + + /* Now start the first CPU. */ + _pr_primordialCPU = _PR_CreateCPU(); + _pr_numCPU = 1; + _PR_StartCPU(_pr_primordialCPU, me); + + _PR_MD_SET_CURRENT_CPU(_pr_primordialCPU); + + /* Initialize cpu for current thread (could be different from me) */ + _PR_MD_CURRENT_THREAD()->cpu = _pr_primordialCPU; + + _PR_MD_SET_LAST_THREAD(me); + +#else /* Combined MxN model */ + + _pr_primordialCPU = _PR_CreateCPU(); + _pr_numCPU = 1; + _PR_CreateThread(PR_SYSTEM_THREAD, + _PR_RunCPU, + _pr_primordialCPU, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0, + _PR_IDLE_THREAD); + +#endif /* _PR_LOCAL_THREADS_ONLY */ + + _PR_MD_INIT_CPUS(); +} + +#ifdef WINNT +/* + * Right now this function merely stops the CPUs and does + * not do any other cleanup. + * + * It is only implemented for WINNT because bug 161998 only + * affects the WINNT version of NSPR, but it would be nice + * to implement this function for other platforms too. + */ +void _PR_CleanupCPUs(void) +{ + PRUintn i; + PRCList *qp; + _PRCPU *cpu; + + _pr_cpus_exit = 1; + for (i = 0; i < _pr_numCPU; i++) { + _PR_MD_WAKEUP_WAITER(NULL); + } + for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) { + cpu = _PR_CPU_PTR(qp); + _PR_MD_JOIN_THREAD(&cpu->thread->md); + } +} +#endif + +static _PRCPUQueue *_PR_CreateCPUQueue(void) +{ + PRInt32 index; + _PRCPUQueue *cpuQueue; + cpuQueue = PR_NEWZAP(_PRCPUQueue); + + _MD_NEW_LOCK( &cpuQueue->runQLock ); + _MD_NEW_LOCK( &cpuQueue->sleepQLock ); + _MD_NEW_LOCK( &cpuQueue->miscQLock ); + + for (index = 0; index < PR_PRIORITY_LAST + 1; index++) + PR_INIT_CLIST( &(cpuQueue->runQ[index]) ); + PR_INIT_CLIST( &(cpuQueue->sleepQ) ); + PR_INIT_CLIST( &(cpuQueue->pauseQ) ); + PR_INIT_CLIST( &(cpuQueue->suspendQ) ); + PR_INIT_CLIST( &(cpuQueue->waitingToJoinQ) ); + + cpuQueue->numCPUs = 1; + + return cpuQueue; +} + +/* + * Create a new CPU. + * + * This function initializes enough of the _PRCPU structure so + * that it can be accessed safely by a global thread or another + * CPU. This function does not create the native thread that + * will run the CPU nor does it initialize the parts of _PRCPU + * that must be initialized by that native thread. + * + * The reason we cannot simply have the native thread create + * and fully initialize a new CPU is that we need to be able to + * create a usable _pr_primordialCPU in _PR_InitCPUs without + * assuming that the primordial CPU thread we created can run + * during NSPR initialization. For example, on Windows while + * new threads can be created by DllMain, they won't be able + * to run during DLL initialization. If NSPR is initialized + * by DllMain, the primordial CPU thread won't run until DLL + * initialization is finished. + */ +static _PRCPU *_PR_CreateCPU(void) +{ + _PRCPU *cpu; + + cpu = PR_NEWZAP(_PRCPU); + if (cpu) { + cpu->queue = _PR_CreateCPUQueue(); + if (!cpu->queue) { + PR_DELETE(cpu); + return NULL; + } + } + return cpu; +} + +/* + * Start a new CPU. + * + * 'cpu' is a _PRCPU structure created by _PR_CreateCPU(). + * 'thread' is the native thread that will run the CPU. + * + * If this function fails, 'cpu' is destroyed. + */ +static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread) +{ + /* + ** Start a new cpu. The assumption this code makes is that the + ** underlying operating system creates a stack to go with the new + ** native thread. That stack will be used by the cpu when pausing. + */ + + PR_ASSERT(!_native_threads_only); + + cpu->last_clock = PR_IntervalNow(); + + /* Before we create any threads on this CPU we have to + * set the current CPU + */ + _PR_MD_SET_CURRENT_CPU(cpu); + _PR_MD_INIT_RUNNING_CPU(cpu); + thread->cpu = cpu; + + cpu->idle_thread = _PR_CreateThread(PR_SYSTEM_THREAD, + _PR_CPU_Idle, + (void *)cpu, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0, + _PR_IDLE_THREAD); + + if (!cpu->idle_thread) { + /* didn't clean up CPU queue XXXMB */ + PR_DELETE(cpu); + return PR_FAILURE; + } + PR_ASSERT(cpu->idle_thread->cpu == cpu); + + cpu->idle_thread->no_sched = 0; + + cpu->thread = thread; + + if (_pr_cpu_affinity_mask) + PR_SetThreadAffinityMask(thread, _pr_cpu_affinity_mask); + + /* Created and started a new CPU */ + _PR_CPU_LIST_LOCK(); + cpu->id = _pr_cpuID++; + PR_APPEND_LINK(&cpu->links, &_PR_CPUQ()); + _PR_CPU_LIST_UNLOCK(); + + return PR_SUCCESS; +} + +#if !defined(_PR_GLOBAL_THREADS_ONLY) && !defined(_PR_LOCAL_THREADS_ONLY) +/* +** This code is used during a cpu's initial creation. +*/ +static void _PR_RunCPU(void *arg) +{ + _PRCPU *cpu = (_PRCPU *)arg; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT(NULL != me); + + /* + * _PR_StartCPU calls _PR_CreateThread to create the + * idle thread. Because _PR_CreateThread calls PR_Lock, + * the current thread has to remain a global thread + * during the _PR_StartCPU call so that it can wait for + * the lock if the lock is held by another thread. If + * we clear the _PR_GLOBAL_SCOPE flag in + * _PR_MD_CREATE_PRIMORDIAL_THREAD, the current thread + * will be treated as a local thread and have trouble + * waiting for the lock because the CPU is not fully + * constructed yet. + * + * After the CPU is started, it is safe to mark the + * current thread as a local thread. + */ + +#ifdef HAVE_CUSTOM_USER_THREADS + _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me); +#endif + + me->no_sched = 1; + _PR_StartCPU(cpu, me); + +#ifdef HAVE_CUSTOM_USER_THREADS + me->flags &= (~_PR_GLOBAL_SCOPE); +#endif + + _PR_MD_SET_CURRENT_CPU(cpu); + _PR_MD_SET_CURRENT_THREAD(cpu->thread); + me->cpu = cpu; + + while(1) { + PRInt32 is; + if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); + _PR_MD_START_INTERRUPTS(); + _PR_MD_SWITCH_CONTEXT(me); + } +} +#endif + +static void PR_CALLBACK _PR_CPU_Idle(void *_cpu) +{ + _PRCPU *cpu = (_PRCPU *)_cpu; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT(NULL != me); + + me->cpu = cpu; + cpu->idle_thread = me; + if (_MD_LAST_THREAD()) + _MD_LAST_THREAD()->no_sched = 0; + if (!_PR_IS_NATIVE_THREAD(me)) _PR_MD_SET_INTSOFF(0); + while(1) { + PRInt32 is; + PRIntervalTime timeout; + if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); + + _PR_RUNQ_LOCK(cpu); +#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY) +#ifdef _PR_HAVE_ATOMIC_OPS + _PR_MD_ATOMIC_INCREMENT(&_pr_md_idle_cpus); +#else + _PR_MD_LOCK(&_pr_md_idle_cpus_lock); + _pr_md_idle_cpus++; + _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock); +#endif /* _PR_HAVE_ATOMIC_OPS */ +#endif + /* If someone on runq; do a nonblocking PAUSECPU */ + if (_PR_RUNQREADYMASK(me->cpu) != 0) { + _PR_RUNQ_UNLOCK(cpu); + timeout = PR_INTERVAL_NO_WAIT; + } else { + _PR_RUNQ_UNLOCK(cpu); + + _PR_SLEEPQ_LOCK(cpu); + if (PR_CLIST_IS_EMPTY(&_PR_SLEEPQ(me->cpu))) { + timeout = PR_INTERVAL_NO_TIMEOUT; + } else { + PRThread *wakeThread; + wakeThread = _PR_THREAD_PTR(_PR_SLEEPQ(me->cpu).next); + timeout = wakeThread->sleep; + } + _PR_SLEEPQ_UNLOCK(cpu); + } + + /* Wait for an IO to complete */ + (void)_PR_MD_PAUSE_CPU(timeout); + +#ifdef WINNT + if (_pr_cpus_exit) { + /* _PR_CleanupCPUs tells us to exit */ + _PR_MD_END_THREAD(); + } +#endif + +#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY) +#ifdef _PR_HAVE_ATOMIC_OPS + _PR_MD_ATOMIC_DECREMENT(&_pr_md_idle_cpus); +#else + _PR_MD_LOCK(&_pr_md_idle_cpus_lock); + _pr_md_idle_cpus--; + _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock); +#endif /* _PR_HAVE_ATOMIC_OPS */ +#endif + + _PR_ClockInterrupt(); + + /* Now schedule any thread that is on the runq + * INTS must be OFF when calling PR_Schedule() + */ + me->state = _PR_RUNNABLE; + _PR_MD_SWITCH_CONTEXT(me); + if (!_PR_IS_NATIVE_THREAD(me)) _PR_FAST_INTSON(is); + } +} +#endif /* _PR_GLOBAL_THREADS_ONLY */ + +PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs) +{ +#if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_LOCAL_THREADS_ONLY) + + /* do nothing */ + +#else /* combined, MxN thread model */ + + PRUintn newCPU; + _PRCPU *cpu; + PRThread *thr; + + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (_native_threads_only) + return; + + _PR_CPU_LIST_LOCK(); + if (_pr_numCPU < numCPUs) { + newCPU = numCPUs - _pr_numCPU; + _pr_numCPU = numCPUs; + } else newCPU = 0; + _PR_CPU_LIST_UNLOCK(); + + for (; newCPU; newCPU--) { + cpu = _PR_CreateCPU(); + thr = _PR_CreateThread(PR_SYSTEM_THREAD, + _PR_RunCPU, + cpu, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0, + _PR_IDLE_THREAD); + } +#endif +} + +PR_IMPLEMENT(_PRCPU *) _PR_GetPrimordialCPU(void) +{ + if (_pr_primordialCPU) + return _pr_primordialCPU; + else + return _PR_MD_CURRENT_CPU(); +} diff -Nru nspr-4.9.5/nspr/pr/src/threads/combined/prucv.c nspr-4.10.7/nspr/pr/src/threads/combined/prucv.c --- nspr-4.9.5/nspr/pr/src/threads/combined/prucv.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/combined/prucv.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,655 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "primpl.h" +#include "prinrval.h" +#include "prtypes.h" + +#if defined(WIN95) +/* +** Some local variables report warnings on Win95 because the code paths +** using them are conditioned on HAVE_CUSTOME_USER_THREADS. +** The pragma suppresses the warning. +** +*/ +#pragma warning(disable : 4101) +#endif + + +/* +** Notify one thread that it has finished waiting on a condition variable +** Caller must hold the _PR_CVAR_LOCK(cv) +*/ +PRBool _PR_NotifyThread (PRThread *thread, PRThread *me) +{ + PRBool rv; + + PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); + + _PR_THREAD_LOCK(thread); + PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); + if ( !_PR_IS_NATIVE_THREAD(thread) ) { + if (thread->wait.cvar != NULL) { + thread->wait.cvar = NULL; + + _PR_SLEEPQ_LOCK(thread->cpu); + /* The notify and timeout can collide; in which case both may + * attempt to delete from the sleepQ; only let one do it. + */ + if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) + _PR_DEL_SLEEPQ(thread, PR_TRUE); + _PR_SLEEPQ_UNLOCK(thread->cpu); + + if (thread->flags & _PR_SUSPENDING) { + /* + * set thread state to SUSPENDED; a Resume operation + * on the thread will move it to the runQ + */ + thread->state = _PR_SUSPENDED; + _PR_MISCQ_LOCK(thread->cpu); + _PR_ADD_SUSPENDQ(thread, thread->cpu); + _PR_MISCQ_UNLOCK(thread->cpu); + _PR_THREAD_UNLOCK(thread); + } else { + /* Make thread runnable */ + thread->state = _PR_RUNNABLE; + _PR_THREAD_UNLOCK(thread); + + _PR_AddThreadToRunQ(me, thread); + _PR_MD_WAKEUP_WAITER(thread); + } + + rv = PR_TRUE; + } else { + /* Thread has already been notified */ + _PR_THREAD_UNLOCK(thread); + rv = PR_FALSE; + } + } else { /* If the thread is a native thread */ + if (thread->wait.cvar) { + thread->wait.cvar = NULL; + + if (thread->flags & _PR_SUSPENDING) { + /* + * set thread state to SUSPENDED; a Resume operation + * on the thread will enable the thread to run + */ + thread->state = _PR_SUSPENDED; + } else + thread->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(thread); + _PR_MD_WAKEUP_WAITER(thread); + rv = PR_TRUE; + } else { + _PR_THREAD_UNLOCK(thread); + rv = PR_FALSE; + } + } + + return rv; +} + +/* + * Notify thread waiting on cvar; called when thread is interrupted + * The thread lock is held on entry and released before return + */ +void _PR_NotifyLockedThread (PRThread *thread) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRCondVar *cvar; + PRThreadPriority pri; + + if ( !_PR_IS_NATIVE_THREAD(me)) + PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); + + cvar = thread->wait.cvar; + thread->wait.cvar = NULL; + _PR_THREAD_UNLOCK(thread); + + _PR_CVAR_LOCK(cvar); + _PR_THREAD_LOCK(thread); + + if (!_PR_IS_NATIVE_THREAD(thread)) { + _PR_SLEEPQ_LOCK(thread->cpu); + /* The notify and timeout can collide; in which case both may + * attempt to delete from the sleepQ; only let one do it. + */ + if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) + _PR_DEL_SLEEPQ(thread, PR_TRUE); + _PR_SLEEPQ_UNLOCK(thread->cpu); + + /* Make thread runnable */ + pri = thread->priority; + thread->state = _PR_RUNNABLE; + + PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); + + _PR_AddThreadToRunQ(me, thread); + _PR_THREAD_UNLOCK(thread); + + _PR_MD_WAKEUP_WAITER(thread); + } else { + if (thread->flags & _PR_SUSPENDING) { + /* + * set thread state to SUSPENDED; a Resume operation + * on the thread will enable the thread to run + */ + thread->state = _PR_SUSPENDED; + } else + thread->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(thread); + _PR_MD_WAKEUP_WAITER(thread); + } + + _PR_CVAR_UNLOCK(cvar); + return; +} + +/* +** Make the given thread wait for the given condition variable +*/ +PRStatus _PR_WaitCondVar( + PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout) +{ + PRIntn is; + PRStatus rv = PR_SUCCESS; + + PR_ASSERT(thread == _PR_MD_CURRENT_THREAD()); + PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); + +#ifdef _PR_GLOBAL_THREADS_ONLY + if (_PR_PENDING_INTERRUPT(thread)) { + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + thread->flags &= ~_PR_INTERRUPT; + return PR_FAILURE; + } + + thread->wait.cvar = cvar; + lock->owner = NULL; + _PR_MD_WAIT_CV(&cvar->md,&lock->ilock, timeout); + thread->wait.cvar = NULL; + lock->owner = thread; + if (_PR_PENDING_INTERRUPT(thread)) { + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + thread->flags &= ~_PR_INTERRUPT; + return PR_FAILURE; + } + + return PR_SUCCESS; +#else /* _PR_GLOBAL_THREADS_ONLY */ + + if ( !_PR_IS_NATIVE_THREAD(thread)) + _PR_INTSOFF(is); + + _PR_CVAR_LOCK(cvar); + _PR_THREAD_LOCK(thread); + + if (_PR_PENDING_INTERRUPT(thread)) { + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + thread->flags &= ~_PR_INTERRUPT; + _PR_CVAR_UNLOCK(cvar); + _PR_THREAD_UNLOCK(thread); + if ( !_PR_IS_NATIVE_THREAD(thread)) + _PR_INTSON(is); + return PR_FAILURE; + } + + thread->state = _PR_COND_WAIT; + thread->wait.cvar = cvar; + + /* + ** Put the caller thread on the condition variable's wait Q + */ + PR_APPEND_LINK(&thread->waitQLinks, &cvar->condQ); + + /* Note- for global scope threads, we don't put them on the + * global sleepQ, so each global thread must put itself + * to sleep only for the time it wants to. + */ + if ( !_PR_IS_NATIVE_THREAD(thread) ) { + _PR_SLEEPQ_LOCK(thread->cpu); + _PR_ADD_SLEEPQ(thread, timeout); + _PR_SLEEPQ_UNLOCK(thread->cpu); + } + _PR_CVAR_UNLOCK(cvar); + _PR_THREAD_UNLOCK(thread); + + /* + ** Release lock protecting the condition variable and thereby giving time + ** to the next thread which can potentially notify on the condition variable + */ + PR_Unlock(lock); + + PR_LOG(_pr_cvar_lm, PR_LOG_MIN, + ("PR_Wait: cvar=%p waiting for %d", cvar, timeout)); + + rv = _PR_MD_WAIT(thread, timeout); + + _PR_CVAR_LOCK(cvar); + PR_REMOVE_LINK(&thread->waitQLinks); + _PR_CVAR_UNLOCK(cvar); + + PR_LOG(_pr_cvar_lm, PR_LOG_MIN, + ("PR_Wait: cvar=%p done waiting", cvar)); + + if ( !_PR_IS_NATIVE_THREAD(thread)) + _PR_INTSON(is); + + /* Acquire lock again that we had just relinquished */ + PR_Lock(lock); + + if (_PR_PENDING_INTERRUPT(thread)) { + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + thread->flags &= ~_PR_INTERRUPT; + return PR_FAILURE; + } + + return rv; +#endif /* _PR_GLOBAL_THREADS_ONLY */ +} + +void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me) +{ +#ifdef _PR_GLOBAL_THREADS_ONLY + _PR_MD_NOTIFY_CV(&cvar->md, &cvar->lock->ilock); +#else /* _PR_GLOBAL_THREADS_ONLY */ + + PRCList *q; + PRIntn is; + + if ( !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); + + _PR_CVAR_LOCK(cvar); + q = cvar->condQ.next; + while (q != &cvar->condQ) { + PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar)); + if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar) { + if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE) + break; + } + q = q->next; + } + _PR_CVAR_UNLOCK(cvar); + + if ( !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); + +#endif /* _PR_GLOBAL_THREADS_ONLY */ +} + +/* +** Cndition variable debugging log info. +*/ +PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen) +{ + PRUint32 nb; + + if (cvar->lock->owner) { + nb = PR_snprintf(buf, buflen, "[%p] owner=%ld[%p]", + cvar, cvar->lock->owner->id, cvar->lock->owner); + } else { + nb = PR_snprintf(buf, buflen, "[%p]", cvar); + } + return nb; +} + +/* +** Expire condition variable waits that are ready to expire. "now" is the current +** time. +*/ +void _PR_ClockInterrupt(void) +{ + PRThread *thread, *me = _PR_MD_CURRENT_THREAD(); + _PRCPU *cpu = me->cpu; + PRIntervalTime elapsed, now; + + PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); + /* Figure out how much time elapsed since the last clock tick */ + now = PR_IntervalNow(); + elapsed = now - cpu->last_clock; + cpu->last_clock = now; + + PR_LOG(_pr_clock_lm, PR_LOG_MAX, + ("ExpireWaits: elapsed=%lld usec", elapsed)); + + while(1) { + _PR_SLEEPQ_LOCK(cpu); + if (_PR_SLEEPQ(cpu).next == &_PR_SLEEPQ(cpu)) { + _PR_SLEEPQ_UNLOCK(cpu); + break; + } + + thread = _PR_THREAD_PTR(_PR_SLEEPQ(cpu).next); + PR_ASSERT(thread->cpu == cpu); + + if (elapsed < thread->sleep) { + thread->sleep -= elapsed; + _PR_SLEEPQMAX(thread->cpu) -= elapsed; + _PR_SLEEPQ_UNLOCK(cpu); + break; + } + _PR_SLEEPQ_UNLOCK(cpu); + + PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread)); + + _PR_THREAD_LOCK(thread); + + if (thread->cpu != cpu) { + /* + ** The thread was switched to another CPU + ** between the time we unlocked the sleep + ** queue and the time we acquired the thread + ** lock, so it is none of our business now. + */ + _PR_THREAD_UNLOCK(thread); + continue; + } + + /* + ** Consume this sleeper's amount of elapsed time from the elapsed + ** time value. The next remaining piece of elapsed time will be + ** available for the next sleeping thread's timer. + */ + _PR_SLEEPQ_LOCK(cpu); + PR_ASSERT(!(thread->flags & _PR_ON_PAUSEQ)); + if (thread->flags & _PR_ON_SLEEPQ) { + _PR_DEL_SLEEPQ(thread, PR_FALSE); + elapsed -= thread->sleep; + _PR_SLEEPQ_UNLOCK(cpu); + } else { + /* Thread was already handled; Go get another one */ + _PR_SLEEPQ_UNLOCK(cpu); + _PR_THREAD_UNLOCK(thread); + continue; + } + + /* Notify the thread waiting on the condition variable */ + if (thread->flags & _PR_SUSPENDING) { + PR_ASSERT((thread->state == _PR_IO_WAIT) || + (thread->state == _PR_COND_WAIT)); + /* + ** Thread is suspended and its condition timeout + ** expired. Transfer thread from sleepQ to suspendQ. + */ + thread->wait.cvar = NULL; + _PR_MISCQ_LOCK(cpu); + thread->state = _PR_SUSPENDED; + _PR_ADD_SUSPENDQ(thread, cpu); + _PR_MISCQ_UNLOCK(cpu); + } else { + if (thread->wait.cvar) { + PRThreadPriority pri; + + /* Do work very similar to what _PR_NotifyThread does */ + PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); + + /* Make thread runnable */ + pri = thread->priority; + thread->state = _PR_RUNNABLE; + PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); + + PR_ASSERT(thread->cpu == cpu); + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(thread, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + + if (pri > me->priority) + _PR_SET_RESCHED_FLAG(); + + thread->wait.cvar = NULL; + + _PR_MD_WAKEUP_WAITER(thread); + + } else if (thread->io_pending == PR_TRUE) { + /* Need to put IO sleeper back on runq */ + int pri = thread->priority; + + thread->io_suspended = PR_TRUE; +#ifdef WINNT + /* + * For NT, record the cpu on which I/O was issued + * I/O cancellation is done on the same cpu + */ + thread->md.thr_bound_cpu = cpu; +#endif + + PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); + PR_ASSERT(thread->cpu == cpu); + thread->state = _PR_RUNNABLE; + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(thread, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + } + } + _PR_THREAD_UNLOCK(thread); + } +} + +/************************************************************************/ + +/* +** Create a new condition variable. +** "lock" is the lock to use with the condition variable. +** +** Condition variables are synchronization objects that threads can use +** to wait for some condition to occur. +** +** This may fail if memory is tight or if some operating system resource +** is low. +*/ +PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock) +{ + PRCondVar *cvar; + + cvar = PR_NEWZAP(PRCondVar); + if (cvar) { + if (_PR_InitCondVar(cvar, lock) != PR_SUCCESS) { + PR_DELETE(cvar); + return NULL; + } + } else { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + } + return cvar; +} + +PRStatus _PR_InitCondVar(PRCondVar *cvar, PRLock *lock) +{ + PR_ASSERT(lock != NULL); + +#ifdef _PR_GLOBAL_THREADS_ONLY + if(_PR_MD_NEW_CV(&cvar->md)) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + return PR_FAILURE; + } +#endif + if (_PR_MD_NEW_LOCK(&(cvar->ilock)) != PR_SUCCESS) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + return PR_FAILURE; + } + cvar->lock = lock; + PR_INIT_CLIST(&cvar->condQ); + return PR_SUCCESS; +} + +/* +** Destroy a condition variable. There must be no thread +** waiting on the condvar. The caller is responsible for guaranteeing +** that the condvar is no longer in use. +** +*/ +PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar) +{ + _PR_FreeCondVar(cvar); + PR_DELETE(cvar); +} + +void _PR_FreeCondVar(PRCondVar *cvar) +{ + PR_ASSERT(cvar->condQ.next == &cvar->condQ); + +#ifdef _PR_GLOBAL_THREADS_ONLY + _PR_MD_FREE_CV(&cvar->md); +#endif + _PR_MD_FREE_LOCK(&(cvar->ilock)); +} + +/* +** Wait for a notify on the condition variable. Sleep for "tiemout" amount +** of ticks (if "timeout" is zero then the sleep is indefinite). While +** the thread is waiting it unlocks lock. When the wait has +** finished the thread regains control of the condition variable after +** locking the associated lock. +** +** The thread waiting on the condvar will be resumed when the condvar is +** notified (assuming the thread is the next in line to receive the +** notify) or when the timeout elapses. +** +** Returns PR_FAILURE if the caller has not locked the lock associated +** with the condition variable or the thread has been interrupted. +*/ +extern PRThread *suspendAllThread; +PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT(cvar->lock->owner == me); + PR_ASSERT(me != suspendAllThread); + if (cvar->lock->owner != me) return PR_FAILURE; + + return _PR_WaitCondVar(me, cvar, cvar->lock, timeout); +} + +/* +** Notify the highest priority thread waiting on the condition +** variable. If a thread is waiting on the condition variable (using +** PR_Wait) then it is awakened and begins waiting on the lock. +*/ +PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT(cvar->lock->owner == me); + PR_ASSERT(me != suspendAllThread); + if (cvar->lock->owner != me) return PR_FAILURE; + + _PR_NotifyCondVar(cvar, me); + return PR_SUCCESS; +} + +/* +** Notify all of the threads waiting on the condition variable. All of +** threads are notified in turn. The highest priority thread will +** probably acquire the lock. +*/ +PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar) +{ + PRCList *q; + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT(cvar->lock->owner == me); + if (cvar->lock->owner != me) return PR_FAILURE; + +#ifdef _PR_GLOBAL_THREADS_ONLY + _PR_MD_NOTIFYALL_CV(&cvar->md, &cvar->lock->ilock); + return PR_SUCCESS; +#else /* _PR_GLOBAL_THREADS_ONLY */ + if ( !_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + _PR_CVAR_LOCK(cvar); + q = cvar->condQ.next; + while (q != &cvar->condQ) { + PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)); + _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me); + q = q->next; + } + _PR_CVAR_UNLOCK(cvar); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); + + return PR_SUCCESS; +#endif /* _PR_GLOBAL_THREADS_ONLY */ +} + + +/*********************************************************************/ +/*********************************************************************/ +/********************ROUTINES FOR DCE EMULATION***********************/ +/*********************************************************************/ +/*********************************************************************/ +#include "prpdce.h" + +PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void) +{ + PRCondVar *cvar = PR_NEWZAP(PRCondVar); + if (NULL != cvar) + { + if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) + { + PR_DELETE(cvar); cvar = NULL; + } + else + { + PR_INIT_CLIST(&cvar->condQ); + cvar->lock = _PR_NAKED_CV_LOCK; + } + + } + return cvar; +} + +PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar) +{ + PR_ASSERT(cvar->condQ.next == &cvar->condQ); + PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); + + _PR_MD_FREE_LOCK(&(cvar->ilock)); + + PR_DELETE(cvar); +} + +PR_IMPLEMENT(PRStatus) PRP_NakedWait( + PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); + return _PR_WaitCondVar(me, cvar, lock, timeout); +} /* PRP_NakedWait */ + +PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); + + _PR_NotifyCondVar(cvar, me); + + return PR_SUCCESS; +} /* PRP_NakedNotify */ + +PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar) +{ + PRCList *q; + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); + + if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); + _PR_MD_LOCK( &(cvar->ilock) ); + q = cvar->condQ.next; + while (q != &cvar->condQ) { + PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)); + _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me); + q = q->next; + } + _PR_MD_UNLOCK( &(cvar->ilock) ); + if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); + + return PR_SUCCESS; +} /* PRP_NakedBroadcast */ + diff -Nru nspr-4.9.5/nspr/pr/src/threads/combined/prulock.c nspr-4.10.7/nspr/pr/src/threads/combined/prulock.c --- nspr-4.9.5/nspr/pr/src/threads/combined/prulock.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/combined/prulock.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,446 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#if defined(WIN95) +/* +** Some local variables report warnings on Win95 because the code paths +** using them are conditioned on HAVE_CUSTOME_USER_THREADS. +** The pragma suppresses the warning. +** +*/ +#pragma warning(disable : 4101) +#endif + + +void _PR_InitLocks(void) +{ + _PR_MD_INIT_LOCKS(); +} + +/* +** Deal with delayed interrupts/requested reschedule during interrupt +** re-enables. +*/ +void _PR_IntsOn(_PRCPU *cpu) +{ + PRUintn missed, pri, i; + _PRInterruptTable *it; + PRThread *me; + + PR_ASSERT(cpu); /* Global threads don't have CPUs */ + PR_ASSERT(_PR_MD_GET_INTSOFF() > 0); + me = _PR_MD_CURRENT_THREAD(); + PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); + + /* + ** Process delayed interrupts. This logic is kinda scary because we + ** need to avoid losing an interrupt (it's ok to delay an interrupt + ** until later). + ** + ** There are two missed state words. _pr_ints.where indicates to the + ** interrupt handler which state word is currently safe for + ** modification. + ** + ** This code scans both interrupt state words, using the where flag + ** to indicate to the interrupt which state word is safe for writing. + ** If an interrupt comes in during a scan the other word will be + ** modified. This modification will be noticed during the next + ** iteration of the loop or during the next call to this routine. + */ + for (i = 0; i < 2; i++) { + cpu->where = (1 - i); + missed = cpu->u.missed[i]; + if (missed != 0) { + cpu->u.missed[i] = 0; + for (it = _pr_interruptTable; it->name; it++) { + if (missed & it->missed_bit) { + PR_LOG(_pr_sched_lm, PR_LOG_MIN, + ("IntsOn[0]: %s intr", it->name)); + (*it->handler)(); + } + } + } + } + + if (cpu->u.missed[3] != 0) { + _PRCPU *cpu; + + _PR_THREAD_LOCK(me); + me->state = _PR_RUNNABLE; + pri = me->priority; + + cpu = me->cpu; + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(me, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + _PR_THREAD_UNLOCK(me); + _PR_MD_SWITCH_CONTEXT(me); + } +} + +/* +** Unblock the first runnable waiting thread. Skip over +** threads that are trying to be suspended +** Note: Caller must hold _PR_LOCK_LOCK() +*/ +void _PR_UnblockLockWaiter(PRLock *lock) +{ + PRThread *t = NULL; + PRThread *me; + PRCList *q; + + q = lock->waitQ.next; + PR_ASSERT(q != &lock->waitQ); + while (q != &lock->waitQ) { + /* Unblock first waiter */ + t = _PR_THREAD_CONDQ_PTR(q); + + /* + ** We are about to change the thread's state to runnable and for local + ** threads, we are going to assign a cpu to it. So, protect thread's + ** data structure. + */ + _PR_THREAD_LOCK(t); + + if (t->flags & _PR_SUSPENDING) { + q = q->next; + _PR_THREAD_UNLOCK(t); + continue; + } + + /* Found a runnable thread */ + PR_ASSERT(t->state == _PR_LOCK_WAIT); + PR_ASSERT(t->wait.lock == lock); + t->wait.lock = 0; + PR_REMOVE_LINK(&t->waitQLinks); /* take it off lock's waitQ */ + + /* + ** If this is a native thread, nothing else to do except to wake it + ** up by calling the machine dependent wakeup routine. + ** + ** If this is a local thread, we need to assign it a cpu and + ** put the thread on that cpu's run queue. There are two cases to + ** take care of. If the currently running thread is also a local + ** thread, we just assign our own cpu to that thread and put it on + ** the cpu's run queue. If the the currently running thread is a + ** native thread, we assign the primordial cpu to it (on NT, + ** MD_WAKEUP handles the cpu assignment). + */ + + if ( !_PR_IS_NATIVE_THREAD(t) ) { + + t->state = _PR_RUNNABLE; + + me = _PR_MD_CURRENT_THREAD(); + + _PR_AddThreadToRunQ(me, t); + _PR_THREAD_UNLOCK(t); + } else { + t->state = _PR_RUNNING; + _PR_THREAD_UNLOCK(t); + } + _PR_MD_WAKEUP_WAITER(t); + break; + } + return; +} + +/************************************************************************/ + + +PR_IMPLEMENT(PRLock*) PR_NewLock(void) +{ + PRLock *lock; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + lock = PR_NEWZAP(PRLock); + if (lock) { + if (_PR_InitLock(lock) != PR_SUCCESS) { + PR_DELETE(lock); + return NULL; + } + } + return lock; +} + +PRStatus _PR_InitLock(PRLock *lock) +{ + if (_PR_MD_NEW_LOCK(&lock->ilock) != PR_SUCCESS) { + return PR_FAILURE; + } + PR_INIT_CLIST(&lock->links); + PR_INIT_CLIST(&lock->waitQ); + return PR_SUCCESS; +} + +/* +** Destroy the given lock "lock". There is no point in making this race +** free because if some other thread has the pointer to this lock all +** bets are off. +*/ +PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock) +{ + _PR_FreeLock(lock); + PR_DELETE(lock); +} + +void _PR_FreeLock(PRLock *lock) +{ + PR_ASSERT(lock->owner == 0); + _PR_MD_FREE_LOCK(&lock->ilock); +} + +extern PRThread *suspendAllThread; +/* +** Lock the lock. +*/ +PR_IMPLEMENT(void) PR_Lock(PRLock *lock) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRIntn is; + PRThread *t; + PRCList *q; + + PR_ASSERT(me != suspendAllThread); + PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); + PR_ASSERT(lock != NULL); +#ifdef _PR_GLOBAL_THREADS_ONLY + _PR_MD_LOCK(&lock->ilock); + PR_ASSERT(lock->owner == 0); + lock->owner = me; + return; +#else /* _PR_GLOBAL_THREADS_ONLY */ + + if (_native_threads_only) { + _PR_MD_LOCK(&lock->ilock); + PR_ASSERT(lock->owner == 0); + lock->owner = me; + return; + } + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + + PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); + +retry: + _PR_LOCK_LOCK(lock); + if (lock->owner == 0) { + /* Just got the lock */ + lock->owner = me; + lock->priority = me->priority; + /* Add the granted lock to this owning thread's lock list */ + PR_APPEND_LINK(&lock->links, &me->lockList); + _PR_LOCK_UNLOCK(lock); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_FAST_INTSON(is); + return; + } + + /* If this thread already owns this lock, then it is a deadlock */ + PR_ASSERT(lock->owner != me); + + PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); + +#if 0 + if (me->priority > lock->owner->priority) { + /* + ** Give the lock owner a priority boost until we get the + ** lock. Record the priority we boosted it to. + */ + lock->boostPriority = me->priority; + _PR_SetThreadPriority(lock->owner, me->priority); + } +#endif + + /* + Add this thread to the asked for lock's list of waiting threads. We + add this thread thread in the right priority order so when the unlock + occurs, the thread with the higher priority will get the lock. + */ + q = lock->waitQ.next; + if (q == &lock->waitQ || _PR_THREAD_CONDQ_PTR(q)->priority == + _PR_THREAD_CONDQ_PTR(lock->waitQ.prev)->priority) { + /* + * If all the threads in the lock waitQ have the same priority, + * then avoid scanning the list: insert the element at the end. + */ + q = &lock->waitQ; + } else { + /* Sort thread into lock's waitQ at appropriate point */ + /* Now scan the list for where to insert this entry */ + while (q != &lock->waitQ) { + t = _PR_THREAD_CONDQ_PTR(lock->waitQ.next); + if (me->priority > t->priority) { + /* Found a lower priority thread to insert in front of */ + break; + } + q = q->next; + } + } + PR_INSERT_BEFORE(&me->waitQLinks, q); + + /* + Now grab the threadLock since we are about to change the state. We have + to do this since a PR_Suspend or PR_SetThreadPriority type call that takes + a PRThread* as an argument could be changing the state of this thread from + a thread running on a different cpu. + */ + + _PR_THREAD_LOCK(me); + me->state = _PR_LOCK_WAIT; + me->wait.lock = lock; + _PR_THREAD_UNLOCK(me); + + _PR_LOCK_UNLOCK(lock); + + _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT); + goto retry; + +#endif /* _PR_GLOBAL_THREADS_ONLY */ +} + +/* +** Unlock the lock. +*/ +PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock) +{ + PRCList *q; + PRThreadPriority pri, boost; + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT(lock != NULL); + PR_ASSERT(lock->owner == me); + PR_ASSERT(me != suspendAllThread); + PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); + if (lock->owner != me) { + return PR_FAILURE; + } + +#ifdef _PR_GLOBAL_THREADS_ONLY + lock->owner = 0; + _PR_MD_UNLOCK(&lock->ilock); + return PR_SUCCESS; +#else /* _PR_GLOBAL_THREADS_ONLY */ + + if (_native_threads_only) { + lock->owner = 0; + _PR_MD_UNLOCK(&lock->ilock); + return PR_SUCCESS; + } + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + _PR_LOCK_LOCK(lock); + + /* Remove the lock from the owning thread's lock list */ + PR_REMOVE_LINK(&lock->links); + pri = lock->priority; + boost = lock->boostPriority; + if (boost > pri) { + /* + ** We received a priority boost during the time we held the lock. + ** We need to figure out what priority to move to by scanning + ** down our list of lock's that we are still holding and using + ** the highest boosted priority found. + */ + q = me->lockList.next; + while (q != &me->lockList) { + PRLock *ll = _PR_LOCK_PTR(q); + if (ll->boostPriority > pri) { + pri = ll->boostPriority; + } + q = q->next; + } + if (pri != me->priority) { + _PR_SetThreadPriority(me, pri); + } + } + + /* Unblock the first waiting thread */ + q = lock->waitQ.next; + if (q != &lock->waitQ) + _PR_UnblockLockWaiter(lock); + lock->boostPriority = PR_PRIORITY_LOW; + lock->owner = 0; + _PR_LOCK_UNLOCK(lock); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); + return PR_SUCCESS; +#endif /* _PR_GLOBAL_THREADS_ONLY */ +} + +/* +** If the current thread owns |lock|, this assertion is guaranteed to +** succeed. Otherwise, the behavior of this function is undefined. +*/ +PR_IMPLEMENT(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PR_ASSERT(lock->owner == me); +} + +/* +** Test and then lock the lock if it's not already locked by some other +** thread. Return PR_FALSE if some other thread owned the lock at the +** time of the call. +*/ +PR_IMPLEMENT(PRBool) PR_TestAndLock(PRLock *lock) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRBool rv = PR_FALSE; + PRIntn is; + +#ifdef _PR_GLOBAL_THREADS_ONLY + is = _PR_MD_TEST_AND_LOCK(&lock->ilock); + if (is == 0) { + lock->owner = me; + return PR_TRUE; + } + return PR_FALSE; +#else /* _PR_GLOBAL_THREADS_ONLY */ + +#ifndef _PR_LOCAL_THREADS_ONLY + if (_native_threads_only) { + is = _PR_MD_TEST_AND_LOCK(&lock->ilock); + if (is == 0) { + lock->owner = me; + return PR_TRUE; + } + return PR_FALSE; + } +#endif + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + + _PR_LOCK_LOCK(lock); + if (lock->owner == 0) { + /* Just got the lock */ + lock->owner = me; + lock->priority = me->priority; + /* Add the granted lock to this owning thread's lock list */ + PR_APPEND_LINK(&lock->links, &me->lockList); + rv = PR_TRUE; + } + _PR_LOCK_UNLOCK(lock); + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); + return rv; +#endif /* _PR_GLOBAL_THREADS_ONLY */ +} + +/************************************************************************/ +/************************************************************************/ +/***********************ROUTINES FOR DCE EMULATION***********************/ +/************************************************************************/ +/************************************************************************/ +PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock) + { return (PR_TestAndLock(lock)) ? PR_SUCCESS : PR_FAILURE; } diff -Nru nspr-4.9.5/nspr/pr/src/threads/combined/prustack.c nspr-4.10.7/nspr/pr/src/threads/combined/prustack.c --- nspr-4.9.5/nspr/pr/src/threads/combined/prustack.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/combined/prustack.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,174 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +/* List of free stack virtual memory chunks */ +PRLock *_pr_stackLock; +PRCList _pr_freeStacks = PR_INIT_STATIC_CLIST(&_pr_freeStacks); +PRIntn _pr_numFreeStacks; +PRIntn _pr_maxFreeStacks = 4; + +#ifdef DEBUG +/* +** A variable that can be set via the debugger... +*/ +PRBool _pr_debugStacks = PR_FALSE; +#endif + +/* How much space to leave between the stacks, at each end */ +#define REDZONE (2 << _pr_pageShift) + +#define _PR_THREAD_STACK_PTR(_qp) \ + ((PRThreadStack*) ((char*) (_qp) - offsetof(PRThreadStack,links))) + +void _PR_InitStacks(void) +{ + _pr_stackLock = PR_NewLock(); +} + +void _PR_CleanupStacks(void) +{ + if (_pr_stackLock) { + PR_DestroyLock(_pr_stackLock); + _pr_stackLock = NULL; + } +} + +/* +** Allocate a stack for a thread. +*/ +PRThreadStack *_PR_NewStack(PRUint32 stackSize) +{ + PRCList *qp; + PRThreadStack *ts; + PRThread *thr; + + /* + ** Trim the list of free stacks. Trim it backwards, tossing out the + ** oldest stack found first (this way more recent stacks have a + ** chance of being present in the data cache). + */ + PR_Lock(_pr_stackLock); + qp = _pr_freeStacks.prev; + while ((_pr_numFreeStacks > _pr_maxFreeStacks) && (qp != &_pr_freeStacks)) { + ts = _PR_THREAD_STACK_PTR(qp); + thr = _PR_THREAD_STACK_TO_PTR(ts); + qp = qp->prev; + /* + * skip stacks which are still being used + */ + if (thr->no_sched) + continue; + PR_REMOVE_LINK(&ts->links); + + /* Give platform OS to clear out the stack for debugging */ + _PR_MD_CLEAR_STACK(ts); + + _pr_numFreeStacks--; + _PR_DestroySegment(ts->seg); + PR_DELETE(ts); + } + + /* + ** Find a free thread stack. This searches the list of free'd up + ** virtually mapped thread stacks. + */ + qp = _pr_freeStacks.next; + ts = 0; + while (qp != &_pr_freeStacks) { + ts = _PR_THREAD_STACK_PTR(qp); + thr = _PR_THREAD_STACK_TO_PTR(ts); + qp = qp->next; + /* + * skip stacks which are still being used + */ + if ((!(thr->no_sched)) && ((ts->allocSize - 2*REDZONE) >= stackSize)) { + /* + ** Found a stack that is not in use and is big enough. Change + ** stackSize to fit it. + */ + stackSize = ts->allocSize - 2*REDZONE; + PR_REMOVE_LINK(&ts->links); + _pr_numFreeStacks--; + ts->links.next = 0; + ts->links.prev = 0; + PR_Unlock(_pr_stackLock); + goto done; + } + ts = 0; + } + PR_Unlock(_pr_stackLock); + + if (!ts) { + /* Make a new thread stack object. */ + ts = PR_NEWZAP(PRThreadStack); + if (!ts) { + return NULL; + } + + /* + ** Assign some of the virtual space to the new stack object. We + ** may not get that piece of VM, but if nothing else we will + ** advance the pointer so we don't collide (unless the OS screws + ** up). + */ + ts->allocSize = stackSize + 2*REDZONE; + ts->seg = _PR_NewSegment(ts->allocSize, 0); + if (!ts->seg) { + PR_DELETE(ts); + return NULL; + } + } + + done: + ts->allocBase = (char*)ts->seg->vaddr; + ts->flags = _PR_STACK_MAPPED; + ts->stackSize = stackSize; + +#ifdef HAVE_STACK_GROWING_UP + ts->stackTop = ts->allocBase + REDZONE; + ts->stackBottom = ts->stackTop + stackSize; +#else + ts->stackBottom = ts->allocBase + REDZONE; + ts->stackTop = ts->stackBottom + stackSize; +#endif + + PR_LOG(_pr_thread_lm, PR_LOG_NOTICE, + ("thread stack: base=0x%x limit=0x%x bottom=0x%x top=0x%x\n", + ts->allocBase, ts->allocBase + ts->allocSize - 1, + ts->allocBase + REDZONE, + ts->allocBase + REDZONE + stackSize - 1)); + + _PR_MD_INIT_STACK(ts,REDZONE); + + return ts; +} + +/* +** Free the stack for the current thread +*/ +void _PR_FreeStack(PRThreadStack *ts) +{ + if (!ts) { + return; + } + if (ts->flags & _PR_STACK_PRIMORDIAL) { + PR_DELETE(ts); + return; + } + + /* + ** Put the stack on the free list. This is done because we are still + ** using the stack. Next time a thread is created we will trim the + ** list down; it's safe to do it then because we will have had to + ** context switch to a live stack before another thread can be + ** created. + */ + PR_Lock(_pr_stackLock); + PR_APPEND_LINK(&ts->links, _pr_freeStacks.prev); + _pr_numFreeStacks++; + PR_Unlock(_pr_stackLock); +} diff -Nru nspr-4.9.5/nspr/pr/src/threads/combined/pruthr.c nspr-4.10.7/nspr/pr/src/threads/combined/pruthr.c --- nspr-4.9.5/nspr/pr/src/threads/combined/pruthr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/combined/pruthr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1889 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include +#include + +#if defined(WIN95) +/* +** Some local variables report warnings on Win95 because the code paths +** using them are conditioned on HAVE_CUSTOME_USER_THREADS. +** The pragma suppresses the warning. +** +*/ +#pragma warning(disable : 4101) +#endif + +/* _pr_activeLock protects the following global variables */ +PRLock *_pr_activeLock; +PRInt32 _pr_primordialExitCount; /* In PR_Cleanup(), the primordial thread + * waits until all other user (non-system) + * threads have terminated before it exits. + * So whenever we decrement _pr_userActive, + * it is compared with + * _pr_primordialExitCount. + * If the primordial thread is a system + * thread, then _pr_primordialExitCount + * is 0. If the primordial thread is + * itself a user thread, then + * _pr_primordialThread is 1. + */ +PRCondVar *_pr_primordialExitCVar; /* When _pr_userActive is decremented to + * _pr_primordialExitCount, this condition + * variable is notified. + */ + +PRLock *_pr_deadQLock; +PRUint32 _pr_numNativeDead; +PRUint32 _pr_numUserDead; +PRCList _pr_deadNativeQ; +PRCList _pr_deadUserQ; + +PRUint32 _pr_join_counter; + +PRUint32 _pr_local_threads; +PRUint32 _pr_global_threads; + +PRBool suspendAllOn = PR_FALSE; +PRThread *suspendAllThread = NULL; + +extern PRCList _pr_active_global_threadQ; +extern PRCList _pr_active_local_threadQ; + +static void _PR_DecrActiveThreadCount(PRThread *thread); +static PRThread *_PR_AttachThread(PRThreadType, PRThreadPriority, PRThreadStack *); +static void _PR_InitializeNativeStack(PRThreadStack *ts); +static void _PR_InitializeRecycledThread(PRThread *thread); +static void _PR_UserRunThread(void); + +void _PR_InitThreads(PRThreadType type, PRThreadPriority priority, + PRUintn maxPTDs) +{ + PRThread *thread; + PRThreadStack *stack; + + PR_ASSERT(priority == PR_PRIORITY_NORMAL); + + _pr_terminationCVLock = PR_NewLock(); + _pr_activeLock = PR_NewLock(); + +#ifndef HAVE_CUSTOM_USER_THREADS + stack = PR_NEWZAP(PRThreadStack); +#ifdef HAVE_STACK_GROWING_UP + stack->stackTop = (char*) ((((long)&type) >> _pr_pageShift) + << _pr_pageShift); +#else +#if defined(SOLARIS) || defined (UNIXWARE) && defined (USR_SVR4_THREADS) + stack->stackTop = (char*) &thread; +#else + stack->stackTop = (char*) ((((long)&type + _pr_pageSize - 1) + >> _pr_pageShift) << _pr_pageShift); +#endif +#endif +#else + /* If stack is NULL, we're using custom user threads like NT fibers. */ + stack = PR_NEWZAP(PRThreadStack); + if (stack) { + stack->stackSize = 0; + _PR_InitializeNativeStack(stack); + } +#endif /* HAVE_CUSTOM_USER_THREADS */ + + thread = _PR_AttachThread(type, priority, stack); + if (thread) { + _PR_MD_SET_CURRENT_THREAD(thread); + + if (type == PR_SYSTEM_THREAD) { + thread->flags = _PR_SYSTEM; + _pr_systemActive++; + _pr_primordialExitCount = 0; + } else { + _pr_userActive++; + _pr_primordialExitCount = 1; + } + thread->no_sched = 1; + _pr_primordialExitCVar = PR_NewCondVar(_pr_activeLock); + } + + if (!thread) PR_Abort(); +#ifdef _PR_LOCAL_THREADS_ONLY + thread->flags |= _PR_PRIMORDIAL; +#else + thread->flags |= _PR_PRIMORDIAL | _PR_GLOBAL_SCOPE; +#endif + + /* + * Needs _PR_PRIMORDIAL flag set before calling + * _PR_MD_INIT_THREAD() + */ + if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) { + /* + * XXX do what? + */ + } + + if (_PR_IS_NATIVE_THREAD(thread)) { + PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ()); + _pr_global_threads++; + } else { + PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ()); + _pr_local_threads++; + } + + _pr_recycleThreads = 0; + _pr_deadQLock = PR_NewLock(); + _pr_numNativeDead = 0; + _pr_numUserDead = 0; + PR_INIT_CLIST(&_pr_deadNativeQ); + PR_INIT_CLIST(&_pr_deadUserQ); +} + +void _PR_CleanupThreads(void) +{ + if (_pr_terminationCVLock) { + PR_DestroyLock(_pr_terminationCVLock); + _pr_terminationCVLock = NULL; + } + if (_pr_activeLock) { + PR_DestroyLock(_pr_activeLock); + _pr_activeLock = NULL; + } + if (_pr_primordialExitCVar) { + PR_DestroyCondVar(_pr_primordialExitCVar); + _pr_primordialExitCVar = NULL; + } + /* TODO _pr_dead{Native,User}Q need to be deleted */ + if (_pr_deadQLock) { + PR_DestroyLock(_pr_deadQLock); + _pr_deadQLock = NULL; + } +} + +/* +** Initialize a stack for a native thread +*/ +static void _PR_InitializeNativeStack(PRThreadStack *ts) +{ + if( ts && (ts->stackTop == 0) ) { + ts->allocSize = ts->stackSize; + + /* + ** Setup stackTop and stackBottom values. + */ +#ifdef HAVE_STACK_GROWING_UP + ts->allocBase = (char*) ((((long)&ts) >> _pr_pageShift) + << _pr_pageShift); + ts->stackBottom = ts->allocBase + ts->stackSize; + ts->stackTop = ts->allocBase; +#else + ts->allocBase = (char*) ((((long)&ts + _pr_pageSize - 1) + >> _pr_pageShift) << _pr_pageShift); + ts->stackTop = ts->allocBase; + ts->stackBottom = ts->allocBase - ts->stackSize; +#endif + } +} + +void _PR_NotifyJoinWaiters(PRThread *thread) +{ + /* + ** Handle joinable threads. Change the state to waiting for join. + ** Remove from our run Q and put it on global waiting to join Q. + ** Notify on our "termination" condition variable so that joining + ** thread will know about our termination. Switch our context and + ** come back later on to continue the cleanup. + */ + PR_ASSERT(thread == _PR_MD_CURRENT_THREAD()); + if (thread->term != NULL) { + PR_Lock(_pr_terminationCVLock); + _PR_THREAD_LOCK(thread); + thread->state = _PR_JOIN_WAIT; + if ( !_PR_IS_NATIVE_THREAD(thread) ) { + _PR_MISCQ_LOCK(thread->cpu); + _PR_ADD_JOINQ(thread, thread->cpu); + _PR_MISCQ_UNLOCK(thread->cpu); + } + _PR_THREAD_UNLOCK(thread); + PR_NotifyCondVar(thread->term); + PR_Unlock(_pr_terminationCVLock); + _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(thread->state != _PR_JOIN_WAIT); + } + +} + +/* + * Zero some of the data members of a recycled thread. + * + * Note that we can do this either when a dead thread is added to + * the dead thread queue or when it is reused. Here, we are doing + * this lazily, when the thread is reused in _PR_CreateThread(). + */ +static void _PR_InitializeRecycledThread(PRThread *thread) +{ + /* + * Assert that the following data members are already zeroed + * by _PR_CleanupThread(). + */ +#ifdef DEBUG + if (thread->privateData) { + unsigned int i; + for (i = 0; i < thread->tpdLength; i++) { + PR_ASSERT(thread->privateData[i] == NULL); + } + } +#endif + PR_ASSERT(thread->dumpArg == 0 && thread->dump == 0); + PR_ASSERT(thread->errorString == 0 && thread->errorStringSize == 0); + PR_ASSERT(thread->errorStringLength == 0); + PR_ASSERT(thread->name == 0); + + /* Reset data members in thread structure */ + thread->errorCode = thread->osErrorCode = 0; + thread->io_pending = thread->io_suspended = PR_FALSE; + thread->environment = 0; + PR_INIT_CLIST(&thread->lockList); +} + +PRStatus _PR_RecycleThread(PRThread *thread) +{ + if ( _PR_IS_NATIVE_THREAD(thread) && + _PR_NUM_DEADNATIVE < _pr_recycleThreads) { + _PR_DEADQ_LOCK; + PR_APPEND_LINK(&thread->links, &_PR_DEADNATIVEQ); + _PR_INC_DEADNATIVE; + _PR_DEADQ_UNLOCK; + return (PR_SUCCESS); + } else if ( !_PR_IS_NATIVE_THREAD(thread) && + _PR_NUM_DEADUSER < _pr_recycleThreads) { + _PR_DEADQ_LOCK; + PR_APPEND_LINK(&thread->links, &_PR_DEADUSERQ); + _PR_INC_DEADUSER; + _PR_DEADQ_UNLOCK; + return (PR_SUCCESS); + } + return (PR_FAILURE); +} + +/* + * Decrement the active thread count, either _pr_systemActive or + * _pr_userActive, depending on whether the thread is a system thread + * or a user thread. If all the user threads, except possibly + * the primordial thread, have terminated, we notify the primordial + * thread of this condition. + * + * Since this function will lock _pr_activeLock, do not call this + * function while holding the _pr_activeLock lock, as this will result + * in a deadlock. + */ + +static void +_PR_DecrActiveThreadCount(PRThread *thread) +{ + PR_Lock(_pr_activeLock); + if (thread->flags & _PR_SYSTEM) { + _pr_systemActive--; + } else { + _pr_userActive--; + if (_pr_userActive == _pr_primordialExitCount) { + PR_NotifyCondVar(_pr_primordialExitCVar); + } + } + PR_Unlock(_pr_activeLock); +} + +/* +** Detach thread structure +*/ +static void +_PR_DestroyThread(PRThread *thread) +{ + _PR_MD_FREE_LOCK(&thread->threadLock); + PR_DELETE(thread); +} + +void +_PR_NativeDestroyThread(PRThread *thread) +{ + if(thread->term) { + PR_DestroyCondVar(thread->term); + thread->term = 0; + } + if (NULL != thread->privateData) { + PR_ASSERT(0 != thread->tpdLength); + PR_DELETE(thread->privateData); + thread->tpdLength = 0; + } + PR_DELETE(thread->stack); + _PR_DestroyThread(thread); +} + +void +_PR_UserDestroyThread(PRThread *thread) +{ + if(thread->term) { + PR_DestroyCondVar(thread->term); + thread->term = 0; + } + if (NULL != thread->privateData) { + PR_ASSERT(0 != thread->tpdLength); + PR_DELETE(thread->privateData); + thread->tpdLength = 0; + } + _PR_MD_FREE_LOCK(&thread->threadLock); + if (thread->threadAllocatedOnStack == 1) { + _PR_MD_CLEAN_THREAD(thread); + /* + * Because the no_sched field is set, this thread/stack will + * will not be re-used until the flag is cleared by the thread + * we will context switch to. + */ + _PR_FreeStack(thread->stack); + } else { +#ifdef WINNT + _PR_MD_CLEAN_THREAD(thread); +#else + /* + * This assertion does not apply to NT. On NT, every fiber + * has its threadAllocatedOnStack equal to 0. Elsewhere, + * only the primordial thread has its threadAllocatedOnStack + * equal to 0. + */ + PR_ASSERT(thread->flags & _PR_PRIMORDIAL); +#endif + } +} + + +/* +** Run a thread's start function. When the start function returns the +** thread is done executing and no longer needs the CPU. If there are no +** more user threads running then we can exit the program. +*/ +void _PR_NativeRunThread(void *arg) +{ + PRThread *thread = (PRThread *)arg; + + _PR_MD_SET_CURRENT_THREAD(thread); + + _PR_MD_SET_CURRENT_CPU(NULL); + + /* Set up the thread stack information */ + _PR_InitializeNativeStack(thread->stack); + + /* Set up the thread md information */ + if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) { + /* + * thread failed to initialize itself, possibly due to + * failure to allocate per-thread resources + */ + return; + } + + while(1) { + thread->state = _PR_RUNNING; + + /* + * Add to list of active threads + */ + PR_Lock(_pr_activeLock); + PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ()); + _pr_global_threads++; + PR_Unlock(_pr_activeLock); + + (*thread->startFunc)(thread->arg); + + /* + * The following two assertions are meant for NT asynch io. + * + * The thread should have no asynch io in progress when it + * exits, otherwise the overlapped buffer, which is part of + * the thread structure, would become invalid. + */ + PR_ASSERT(thread->io_pending == PR_FALSE); + /* + * This assertion enforces the programming guideline that + * if an io function times out or is interrupted, the thread + * should close the fd to force the asynch io to abort + * before it exits. Right now, closing the fd is the only + * way to clear the io_suspended flag. + */ + PR_ASSERT(thread->io_suspended == PR_FALSE); + + /* + * remove thread from list of active threads + */ + PR_Lock(_pr_activeLock); + PR_REMOVE_LINK(&thread->active); + _pr_global_threads--; + PR_Unlock(_pr_activeLock); + + PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting")); + + /* All done, time to go away */ + _PR_CleanupThread(thread); + + _PR_NotifyJoinWaiters(thread); + + _PR_DecrActiveThreadCount(thread); + + thread->state = _PR_DEAD_STATE; + + if (!_pr_recycleThreads || (_PR_RecycleThread(thread) == + PR_FAILURE)) { + /* + * thread not recycled + * platform-specific thread exit processing + * - for stuff like releasing native-thread resources, etc. + */ + _PR_MD_EXIT_THREAD(thread); + /* + * Free memory allocated for the thread + */ + _PR_NativeDestroyThread(thread); + /* + * thread gone, cannot de-reference thread now + */ + return; + } + + /* Now wait for someone to activate us again... */ + _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT); + } +} + +static void _PR_UserRunThread(void) +{ + PRThread *thread = _PR_MD_CURRENT_THREAD(); + PRIntn is; + + if (_MD_LAST_THREAD()) + _MD_LAST_THREAD()->no_sched = 0; + +#ifdef HAVE_CUSTOM_USER_THREADS + if (thread->stack == NULL) { + thread->stack = PR_NEWZAP(PRThreadStack); + _PR_InitializeNativeStack(thread->stack); + } +#endif /* HAVE_CUSTOM_USER_THREADS */ + + while(1) { + /* Run thread main */ + if ( !_PR_IS_NATIVE_THREAD(thread)) _PR_MD_SET_INTSOFF(0); + + /* + * Add to list of active threads + */ + if (!(thread->flags & _PR_IDLE_THREAD)) { + PR_Lock(_pr_activeLock); + PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ()); + _pr_local_threads++; + PR_Unlock(_pr_activeLock); + } + + (*thread->startFunc)(thread->arg); + + /* + * The following two assertions are meant for NT asynch io. + * + * The thread should have no asynch io in progress when it + * exits, otherwise the overlapped buffer, which is part of + * the thread structure, would become invalid. + */ + PR_ASSERT(thread->io_pending == PR_FALSE); + /* + * This assertion enforces the programming guideline that + * if an io function times out or is interrupted, the thread + * should close the fd to force the asynch io to abort + * before it exits. Right now, closing the fd is the only + * way to clear the io_suspended flag. + */ + PR_ASSERT(thread->io_suspended == PR_FALSE); + + PR_Lock(_pr_activeLock); + /* + * remove thread from list of active threads + */ + if (!(thread->flags & _PR_IDLE_THREAD)) { + PR_REMOVE_LINK(&thread->active); + _pr_local_threads--; + } + PR_Unlock(_pr_activeLock); + PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting")); + + /* All done, time to go away */ + _PR_CleanupThread(thread); + + _PR_INTSOFF(is); + + _PR_NotifyJoinWaiters(thread); + + _PR_DecrActiveThreadCount(thread); + + thread->state = _PR_DEAD_STATE; + + if (!_pr_recycleThreads || (_PR_RecycleThread(thread) == + PR_FAILURE)) { + /* + ** Destroy the thread resources + */ + _PR_UserDestroyThread(thread); + } + + /* + ** Find another user thread to run. This cpu has finished the + ** previous threads main and is now ready to run another thread. + */ + { + PRInt32 is; + _PR_INTSOFF(is); + _PR_MD_SWITCH_CONTEXT(thread); + } + + /* Will land here when we get scheduled again if we are recycling... */ + } +} + +void _PR_SetThreadPriority(PRThread *thread, PRThreadPriority newPri) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRIntn is; + + if ( _PR_IS_NATIVE_THREAD(thread) ) { + _PR_MD_SET_PRIORITY(&(thread->md), newPri); + return; + } + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + _PR_THREAD_LOCK(thread); + if (newPri != thread->priority) { + _PRCPU *cpu = thread->cpu; + + switch (thread->state) { + case _PR_RUNNING: + /* Change my priority */ + + _PR_RUNQ_LOCK(cpu); + thread->priority = newPri; + if (_PR_RUNQREADYMASK(cpu) >> (newPri + 1)) { + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_SET_RESCHED_FLAG(); + } + _PR_RUNQ_UNLOCK(cpu); + break; + + case _PR_RUNNABLE: + + _PR_RUNQ_LOCK(cpu); + /* Move to different runQ */ + _PR_DEL_RUNQ(thread); + thread->priority = newPri; + PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); + _PR_ADD_RUNQ(thread, cpu, newPri); + _PR_RUNQ_UNLOCK(cpu); + + if (newPri > me->priority) { + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_SET_RESCHED_FLAG(); + } + + break; + + case _PR_LOCK_WAIT: + case _PR_COND_WAIT: + case _PR_IO_WAIT: + case _PR_SUSPENDED: + + thread->priority = newPri; + break; + } + } + _PR_THREAD_UNLOCK(thread); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); +} + +/* +** Suspend the named thread and copy its gc registers into regBuf +*/ +static void _PR_Suspend(PRThread *thread) +{ + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + PR_ASSERT(thread != me); + PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread) || (!thread->cpu)); + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + _PR_THREAD_LOCK(thread); + switch (thread->state) { + case _PR_RUNNABLE: + if (!_PR_IS_NATIVE_THREAD(thread)) { + _PR_RUNQ_LOCK(thread->cpu); + _PR_DEL_RUNQ(thread); + _PR_RUNQ_UNLOCK(thread->cpu); + + _PR_MISCQ_LOCK(thread->cpu); + _PR_ADD_SUSPENDQ(thread, thread->cpu); + _PR_MISCQ_UNLOCK(thread->cpu); + } else { + /* + * Only LOCAL threads are suspended by _PR_Suspend + */ + PR_ASSERT(0); + } + thread->state = _PR_SUSPENDED; + break; + + case _PR_RUNNING: + /* + * The thread being suspended should be a LOCAL thread with + * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state + */ + PR_ASSERT(0); + break; + + case _PR_LOCK_WAIT: + case _PR_IO_WAIT: + case _PR_COND_WAIT: + if (_PR_IS_NATIVE_THREAD(thread)) { + _PR_MD_SUSPEND_THREAD(thread); + } + thread->flags |= _PR_SUSPENDING; + break; + + default: + PR_Abort(); + } + _PR_THREAD_UNLOCK(thread); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); +} + +static void _PR_Resume(PRThread *thread) +{ + PRThreadPriority pri; + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + _PR_THREAD_LOCK(thread); + switch (thread->state) { + case _PR_SUSPENDED: + thread->state = _PR_RUNNABLE; + thread->flags &= ~_PR_SUSPENDING; + if (!_PR_IS_NATIVE_THREAD(thread)) { + _PR_MISCQ_LOCK(thread->cpu); + _PR_DEL_SUSPENDQ(thread); + _PR_MISCQ_UNLOCK(thread->cpu); + + pri = thread->priority; + + _PR_RUNQ_LOCK(thread->cpu); + _PR_ADD_RUNQ(thread, thread->cpu, pri); + _PR_RUNQ_UNLOCK(thread->cpu); + + if (pri > _PR_MD_CURRENT_THREAD()->priority) { + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_SET_RESCHED_FLAG(); + } + } else { + PR_ASSERT(0); + } + break; + + case _PR_IO_WAIT: + case _PR_COND_WAIT: + thread->flags &= ~_PR_SUSPENDING; +/* PR_ASSERT(thread->wait.monitor->stickyCount == 0); */ + break; + + case _PR_LOCK_WAIT: + { + PRLock *wLock = thread->wait.lock; + + thread->flags &= ~_PR_SUSPENDING; + + _PR_LOCK_LOCK(wLock); + if (thread->wait.lock->owner == 0) { + _PR_UnblockLockWaiter(thread->wait.lock); + } + _PR_LOCK_UNLOCK(wLock); + break; + } + case _PR_RUNNABLE: + break; + case _PR_RUNNING: + /* + * The thread being suspended should be a LOCAL thread with + * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state + */ + PR_ASSERT(0); + break; + + default: + /* + * thread should have been in one of the above-listed blocked states + * (_PR_JOIN_WAIT, _PR_IO_WAIT, _PR_UNBORN, _PR_DEAD_STATE) + */ + PR_Abort(); + } + _PR_THREAD_UNLOCK(thread); + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); + +} + +#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) +static PRThread *get_thread(_PRCPU *cpu, PRBool *wakeup_cpus) +{ + PRThread *thread; + PRIntn pri; + PRUint32 r; + PRCList *qp; + PRIntn priMin, priMax; + + _PR_RUNQ_LOCK(cpu); + r = _PR_RUNQREADYMASK(cpu); + if (r==0) { + priMin = priMax = PR_PRIORITY_FIRST; + } else if (r == (1<= priMin ; pri-- ) { + if (r & (1 << pri)) { + for (qp = _PR_RUNQ(cpu)[pri].next; + qp != &_PR_RUNQ(cpu)[pri]; + qp = qp->next) { + thread = _PR_THREAD_PTR(qp); + /* + * skip non-schedulable threads + */ + PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); + if (thread->no_sched) { + thread = NULL; + /* + * Need to wakeup cpus to avoid missing a + * runnable thread + * Waking up all CPU's need happen only once. + */ + + *wakeup_cpus = PR_TRUE; + continue; + } else if (thread->flags & _PR_BOUND_THREAD) { + /* + * Thread bound to cpu 0 + */ + + thread = NULL; +#ifdef IRIX + _PR_MD_WAKEUP_PRIMORDIAL_CPU(); +#endif + continue; + } else if (thread->io_pending == PR_TRUE) { + /* + * A thread that is blocked for I/O needs to run + * on the same cpu on which it was blocked. This is because + * the cpu's ioq is accessed without lock protection and scheduling + * the thread on a different cpu would preclude this optimization. + */ + thread = NULL; + continue; + } else { + /* Pull thread off of its run queue */ + _PR_DEL_RUNQ(thread); + _PR_RUNQ_UNLOCK(cpu); + return(thread); + } + } + } + thread = NULL; + } + _PR_RUNQ_UNLOCK(cpu); + return(thread); +} +#endif /* !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) */ + +/* +** Schedule this native thread by finding the highest priority nspr +** thread that is ready to run. +** +** Note- everyone really needs to call _PR_MD_SWITCH_CONTEXT (which calls +** PR_Schedule() rather than calling PR_Schedule. Otherwise if there +** is initialization required for switching from SWITCH_CONTEXT, +** it will not get done! +*/ +void _PR_Schedule(void) +{ + PRThread *thread, *me = _PR_MD_CURRENT_THREAD(); + _PRCPU *cpu = _PR_MD_CURRENT_CPU(); + PRIntn pri; + PRUint32 r; + PRCList *qp; + PRIntn priMin, priMax; +#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) + PRBool wakeup_cpus; +#endif + + /* Interrupts must be disabled */ + PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); + + /* Since we are rescheduling, we no longer want to */ + _PR_CLEAR_RESCHED_FLAG(); + + /* + ** Find highest priority thread to run. Bigger priority numbers are + ** higher priority threads + */ + _PR_RUNQ_LOCK(cpu); + /* + * if we are in SuspendAll mode, can schedule only the thread + * that called PR_SuspendAll + * + * The thread may be ready to run now, after completing an I/O + * operation, for example + */ + if ((thread = suspendAllThread) != 0) { + if ((!(thread->no_sched)) && (thread->state == _PR_RUNNABLE)) { + /* Pull thread off of its run queue */ + _PR_DEL_RUNQ(thread); + _PR_RUNQ_UNLOCK(cpu); + goto found_thread; + } else { + thread = NULL; + _PR_RUNQ_UNLOCK(cpu); + goto idle_thread; + } + } + r = _PR_RUNQREADYMASK(cpu); + if (r==0) { + priMin = priMax = PR_PRIORITY_FIRST; + } else if (r == (1<= priMin ; pri-- ) { + if (r & (1 << pri)) { + for (qp = _PR_RUNQ(cpu)[pri].next; + qp != &_PR_RUNQ(cpu)[pri]; + qp = qp->next) { + thread = _PR_THREAD_PTR(qp); + /* + * skip non-schedulable threads + */ + PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); + if ((thread->no_sched) && (me != thread)){ + thread = NULL; + continue; + } else { + /* Pull thread off of its run queue */ + _PR_DEL_RUNQ(thread); + _PR_RUNQ_UNLOCK(cpu); + goto found_thread; + } + } + } + thread = NULL; + } + _PR_RUNQ_UNLOCK(cpu); + +#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) + + wakeup_cpus = PR_FALSE; + _PR_CPU_LIST_LOCK(); + for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) { + if (cpu != _PR_CPU_PTR(qp)) { + if ((thread = get_thread(_PR_CPU_PTR(qp), &wakeup_cpus)) + != NULL) { + thread->cpu = cpu; + _PR_CPU_LIST_UNLOCK(); + if (wakeup_cpus == PR_TRUE) + _PR_MD_WAKEUP_CPUS(); + goto found_thread; + } + } + } + _PR_CPU_LIST_UNLOCK(); + if (wakeup_cpus == PR_TRUE) + _PR_MD_WAKEUP_CPUS(); + +#endif /* _PR_LOCAL_THREADS_ONLY */ + +idle_thread: + /* + ** There are no threads to run. Switch to the idle thread + */ + PR_LOG(_pr_sched_lm, PR_LOG_MAX, ("pausing")); + thread = _PR_MD_CURRENT_CPU()->idle_thread; + +found_thread: + PR_ASSERT((me == thread) || ((thread->state == _PR_RUNNABLE) && + (!(thread->no_sched)))); + + /* Resume the thread */ + PR_LOG(_pr_sched_lm, PR_LOG_MAX, + ("switching to %d[%p]", thread->id, thread)); + PR_ASSERT(thread->state != _PR_RUNNING); + thread->state = _PR_RUNNING; + + /* If we are on the runq, it just means that we went to sleep on some + * resource, and by the time we got here another real native thread had + * already given us the resource and put us back on the runqueue + */ + PR_ASSERT(thread->cpu == _PR_MD_CURRENT_CPU()); + if (thread != me) + _PR_MD_RESTORE_CONTEXT(thread); +#if 0 + /* XXXMB; with setjmp/longjmp it is impossible to land here, but + * it is not with fibers... Is this a bad thing? I believe it is + * still safe. + */ + PR_NOT_REACHED("impossible return from schedule"); +#endif +} + +/* +** Attaches a thread. +** Does not set the _PR_MD_CURRENT_THREAD. +** Does not specify the scope of the thread. +*/ +static PRThread * +_PR_AttachThread(PRThreadType type, PRThreadPriority priority, + PRThreadStack *stack) +{ + PRThread *thread; + char *mem; + + if (priority > PR_PRIORITY_LAST) { + priority = PR_PRIORITY_LAST; + } else if (priority < PR_PRIORITY_FIRST) { + priority = PR_PRIORITY_FIRST; + } + + mem = (char*) PR_CALLOC(sizeof(PRThread)); + if (mem) { + thread = (PRThread*) mem; + thread->priority = priority; + thread->stack = stack; + thread->state = _PR_RUNNING; + PR_INIT_CLIST(&thread->lockList); + if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) { + PR_DELETE(thread); + return 0; + } + + return thread; + } + return 0; +} + + + +PR_IMPLEMENT(PRThread*) +_PR_NativeCreateThread(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize, + PRUint32 flags) +{ + PRThread *thread; + + thread = _PR_AttachThread(type, priority, NULL); + + if (thread) { + PR_Lock(_pr_activeLock); + thread->flags = (flags | _PR_GLOBAL_SCOPE); + thread->id = ++_pr_utid; + if (type == PR_SYSTEM_THREAD) { + thread->flags |= _PR_SYSTEM; + _pr_systemActive++; + } else { + _pr_userActive++; + } + PR_Unlock(_pr_activeLock); + + thread->stack = PR_NEWZAP(PRThreadStack); + if (!thread->stack) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + goto done; + } + thread->stack->stackSize = stackSize?stackSize:_MD_DEFAULT_STACK_SIZE; + thread->stack->thr = thread; + thread->startFunc = start; + thread->arg = arg; + + /* + Set thread flags related to scope and joinable state. If joinable + thread, allocate a "termination" conidition variable. + */ + if (state == PR_JOINABLE_THREAD) { + thread->term = PR_NewCondVar(_pr_terminationCVLock); + if (thread->term == NULL) { + PR_DELETE(thread->stack); + goto done; + } + } + + thread->state = _PR_RUNNING; + if (_PR_MD_CREATE_THREAD(thread, _PR_NativeRunThread, priority, + scope,state,stackSize) == PR_SUCCESS) { + return thread; + } + if (thread->term) { + PR_DestroyCondVar(thread->term); + thread->term = NULL; + } + PR_DELETE(thread->stack); + } + +done: + if (thread) { + _PR_DecrActiveThreadCount(thread); + _PR_DestroyThread(thread); + } + return NULL; +} + +/************************************************************************/ + +PR_IMPLEMENT(PRThread*) _PR_CreateThread(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize, + PRUint32 flags) +{ + PRThread *me; + PRThread *thread = NULL; + PRThreadStack *stack; + char *top; + PRIntn is; + PRIntn native = 0; + PRIntn useRecycled = 0; + PRBool status; + + /* + First, pin down the priority. Not all compilers catch passing out of + range enum here. If we let bad values thru, priority queues won't work. + */ + if (priority > PR_PRIORITY_LAST) { + priority = PR_PRIORITY_LAST; + } else if (priority < PR_PRIORITY_FIRST) { + priority = PR_PRIORITY_FIRST; + } + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (! (flags & _PR_IDLE_THREAD)) + me = _PR_MD_CURRENT_THREAD(); + +#if defined(_PR_GLOBAL_THREADS_ONLY) + /* + * can create global threads only + */ + if (scope == PR_LOCAL_THREAD) + scope = PR_GLOBAL_THREAD; +#endif + + if (_native_threads_only) + scope = PR_GLOBAL_THREAD; + + native = (((scope == PR_GLOBAL_THREAD)|| (scope == PR_GLOBAL_BOUND_THREAD)) + && _PR_IS_NATIVE_THREAD_SUPPORTED()); + + _PR_ADJUST_STACKSIZE(stackSize); + + if (native) { + /* + * clear the IDLE_THREAD flag which applies to LOCAL + * threads only + */ + flags &= ~_PR_IDLE_THREAD; + flags |= _PR_GLOBAL_SCOPE; + if (_PR_NUM_DEADNATIVE > 0) { + _PR_DEADQ_LOCK; + + if (_PR_NUM_DEADNATIVE == 0) { /* Thread safe check */ + _PR_DEADQ_UNLOCK; + } else { + thread = _PR_THREAD_PTR(_PR_DEADNATIVEQ.next); + PR_REMOVE_LINK(&thread->links); + _PR_DEC_DEADNATIVE; + _PR_DEADQ_UNLOCK; + + _PR_InitializeRecycledThread(thread); + thread->startFunc = start; + thread->arg = arg; + thread->flags = (flags | _PR_GLOBAL_SCOPE); + if (type == PR_SYSTEM_THREAD) + { + thread->flags |= _PR_SYSTEM; + PR_ATOMIC_INCREMENT(&_pr_systemActive); + } + else PR_ATOMIC_INCREMENT(&_pr_userActive); + + if (state == PR_JOINABLE_THREAD) { + if (!thread->term) + thread->term = PR_NewCondVar(_pr_terminationCVLock); + } + else { + if(thread->term) { + PR_DestroyCondVar(thread->term); + thread->term = 0; + } + } + + thread->priority = priority; + _PR_MD_SET_PRIORITY(&(thread->md), priority); + /* XXX what about stackSize? */ + thread->state = _PR_RUNNING; + _PR_MD_WAKEUP_WAITER(thread); + return thread; + } + } + thread = _PR_NativeCreateThread(type, start, arg, priority, + scope, state, stackSize, flags); + } else { + if (_PR_NUM_DEADUSER > 0) { + _PR_DEADQ_LOCK; + + if (_PR_NUM_DEADUSER == 0) { /* thread safe check */ + _PR_DEADQ_UNLOCK; + } else { + PRCList *ptr; + + /* Go down list checking for a recycled thread with a + * large enough stack. XXXMB - this has a bad degenerate case. + */ + ptr = _PR_DEADUSERQ.next; + while( ptr != &_PR_DEADUSERQ ) { + thread = _PR_THREAD_PTR(ptr); + if ((thread->stack->stackSize >= stackSize) && + (!thread->no_sched)) { + PR_REMOVE_LINK(&thread->links); + _PR_DEC_DEADUSER; + break; + } else { + ptr = ptr->next; + thread = NULL; + } + } + + _PR_DEADQ_UNLOCK; + + if (thread) { + _PR_InitializeRecycledThread(thread); + thread->startFunc = start; + thread->arg = arg; + thread->priority = priority; + if (state == PR_JOINABLE_THREAD) { + if (!thread->term) + thread->term = PR_NewCondVar(_pr_terminationCVLock); + } else { + if(thread->term) { + PR_DestroyCondVar(thread->term); + thread->term = 0; + } + } + useRecycled++; + } + } + } + if (thread == NULL) { +#ifndef HAVE_CUSTOM_USER_THREADS + stack = _PR_NewStack(stackSize); + if (!stack) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + /* Allocate thread object and per-thread data off the top of the stack*/ + top = stack->stackTop; +#ifdef HAVE_STACK_GROWING_UP + thread = (PRThread*) top; + top = top + sizeof(PRThread); + /* + * Make stack 64-byte aligned + */ + if ((PRUptrdiff)top & 0x3f) { + top = (char*)(((PRUptrdiff)top + 0x40) & ~0x3f); + } +#else + top = top - sizeof(PRThread); + thread = (PRThread*) top; + /* + * Make stack 64-byte aligned + */ + if ((PRUptrdiff)top & 0x3f) { + top = (char*)((PRUptrdiff)top & ~0x3f); + } +#endif + stack->thr = thread; + memset(thread, 0, sizeof(PRThread)); + thread->threadAllocatedOnStack = 1; +#else + thread = _PR_MD_CREATE_USER_THREAD(stackSize, start, arg); + if (!thread) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + thread->threadAllocatedOnStack = 0; + stack = NULL; + top = NULL; +#endif + + /* Initialize thread */ + thread->tpdLength = 0; + thread->privateData = NULL; + thread->stack = stack; + thread->priority = priority; + thread->startFunc = start; + thread->arg = arg; + PR_INIT_CLIST(&thread->lockList); + + if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) { + if (thread->threadAllocatedOnStack == 1) + _PR_FreeStack(thread->stack); + else { + PR_DELETE(thread); + } + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + return NULL; + } + + if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) { + if (thread->threadAllocatedOnStack == 1) + _PR_FreeStack(thread->stack); + else { + PR_DELETE(thread->privateData); + PR_DELETE(thread); + } + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + return NULL; + } + + _PR_MD_INIT_CONTEXT(thread, top, _PR_UserRunThread, &status); + + if (status == PR_FALSE) { + _PR_MD_FREE_LOCK(&thread->threadLock); + if (thread->threadAllocatedOnStack == 1) + _PR_FreeStack(thread->stack); + else { + PR_DELETE(thread->privateData); + PR_DELETE(thread); + } + return NULL; + } + + /* + Set thread flags related to scope and joinable state. If joinable + thread, allocate a "termination" condition variable. + */ + if (state == PR_JOINABLE_THREAD) { + thread->term = PR_NewCondVar(_pr_terminationCVLock); + if (thread->term == NULL) { + _PR_MD_FREE_LOCK(&thread->threadLock); + if (thread->threadAllocatedOnStack == 1) + _PR_FreeStack(thread->stack); + else { + PR_DELETE(thread->privateData); + PR_DELETE(thread); + } + return NULL; + } + } + + } + + /* Update thread type counter */ + PR_Lock(_pr_activeLock); + thread->flags = flags; + thread->id = ++_pr_utid; + if (type == PR_SYSTEM_THREAD) { + thread->flags |= _PR_SYSTEM; + _pr_systemActive++; + } else { + _pr_userActive++; + } + + /* Make thread runnable */ + thread->state = _PR_RUNNABLE; + /* + * Add to list of active threads + */ + PR_Unlock(_pr_activeLock); + + if ((! (thread->flags & _PR_IDLE_THREAD)) && _PR_IS_NATIVE_THREAD(me) ) + thread->cpu = _PR_GetPrimordialCPU(); + else + thread->cpu = _PR_MD_CURRENT_CPU(); + + PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread)); + + if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me)) { + _PR_INTSOFF(is); + _PR_RUNQ_LOCK(thread->cpu); + _PR_ADD_RUNQ(thread, thread->cpu, priority); + _PR_RUNQ_UNLOCK(thread->cpu); + } + + if (thread->flags & _PR_IDLE_THREAD) { + /* + ** If the creating thread is a kernel thread, we need to + ** awaken the user thread idle thread somehow; potentially + ** it could be sleeping in its idle loop, and we need to poke + ** it. To do so, wake the idle thread... + */ + _PR_MD_WAKEUP_WAITER(NULL); + } else if (_PR_IS_NATIVE_THREAD(me)) { + _PR_MD_WAKEUP_WAITER(thread); + } + if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me) ) + _PR_INTSON(is); + } + + return thread; +} + +PR_IMPLEMENT(PRThread*) PR_CreateThread(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + return _PR_CreateThread(type, start, arg, priority, scope, state, + stackSize, 0); +} + +/* +** Associate a thread object with an existing native thread. +** "type" is the type of thread object to attach +** "priority" is the priority to assign to the thread +** "stack" defines the shape of the threads stack +** +** This can return NULL if some kind of error occurs, or if memory is +** tight. +** +** This call is not normally needed unless you create your own native +** thread. PR_Init does this automatically for the primordial thread. +*/ +PRThread* _PRI_AttachThread(PRThreadType type, + PRThreadPriority priority, PRThreadStack *stack, PRUint32 flags) +{ + PRThread *thread; + + if ((thread = _PR_MD_GET_ATTACHED_THREAD()) != NULL) { + return thread; + } + _PR_MD_SET_CURRENT_THREAD(NULL); + + /* Clear out any state if this thread was attached before */ + _PR_MD_SET_CURRENT_CPU(NULL); + + thread = _PR_AttachThread(type, priority, stack); + if (thread) { + PRIntn is; + + _PR_MD_SET_CURRENT_THREAD(thread); + + thread->flags = flags | _PR_GLOBAL_SCOPE | _PR_ATTACHED; + + if (!stack) { + thread->stack = PR_NEWZAP(PRThreadStack); + if (!thread->stack) { + _PR_DestroyThread(thread); + return NULL; + } + thread->stack->stackSize = _MD_DEFAULT_STACK_SIZE; + } + PR_INIT_CLIST(&thread->links); + + if (_PR_MD_INIT_ATTACHED_THREAD(thread) == PR_FAILURE) { + PR_DELETE(thread->stack); + _PR_DestroyThread(thread); + return NULL; + } + + _PR_MD_SET_CURRENT_CPU(NULL); + + if (_PR_MD_CURRENT_CPU()) { + _PR_INTSOFF(is); + PR_Lock(_pr_activeLock); + } + if (type == PR_SYSTEM_THREAD) { + thread->flags |= _PR_SYSTEM; + _pr_systemActive++; + } else { + _pr_userActive++; + } + if (_PR_MD_CURRENT_CPU()) { + PR_Unlock(_pr_activeLock); + _PR_INTSON(is); + } + } + return thread; +} + +PR_IMPLEMENT(PRThread*) PR_AttachThread(PRThreadType type, + PRThreadPriority priority, PRThreadStack *stack) +{ + return PR_GetCurrentThread(); +} + +PR_IMPLEMENT(void) PR_DetachThread(void) +{ + /* + * On IRIX, Solaris, and Windows, foreign threads are detached when + * they terminate. + */ +#if !defined(IRIX) && !defined(WIN32) \ + && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)) + PRThread *me; + if (_pr_initialized) { + me = _PR_MD_GET_ATTACHED_THREAD(); + if ((me != NULL) && (me->flags & _PR_ATTACHED)) + _PRI_DetachThread(); + } +#endif +} + +void _PRI_DetachThread(void) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (me->flags & _PR_PRIMORDIAL) { + /* + * ignore, if primordial thread + */ + return; + } + PR_ASSERT(me->flags & _PR_ATTACHED); + PR_ASSERT(_PR_IS_NATIVE_THREAD(me)); + _PR_CleanupThread(me); + PR_DELETE(me->privateData); + + _PR_DecrActiveThreadCount(me); + + _PR_MD_CLEAN_THREAD(me); + _PR_MD_SET_CURRENT_THREAD(NULL); + if (!me->threadAllocatedOnStack) + PR_DELETE(me->stack); + _PR_MD_FREE_LOCK(&me->threadLock); + PR_DELETE(me); +} + +/* +** Wait for thread termination: +** "thread" is the target thread +** +** This can return PR_FAILURE if no joinable thread could be found +** corresponding to the specified target thread. +** +** The calling thread is suspended until the target thread completes. +** Several threads cannot wait for the same thread to complete; one thread +** will complete successfully and others will terminate with an error PR_FAILURE. +** The calling thread will not be blocked if the target thread has already +** terminated. +*/ +PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thread) +{ + PRIntn is; + PRCondVar *term; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + term = thread->term; + /* can't join a non-joinable thread */ + if (term == NULL) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + goto ErrorExit; + } + + /* multiple threads can't wait on the same joinable thread */ + if (term->condQ.next != &term->condQ) { + goto ErrorExit; + } + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); + + /* wait for the target thread's termination cv invariant */ + PR_Lock (_pr_terminationCVLock); + while (thread->state != _PR_JOIN_WAIT) { + (void) PR_WaitCondVar(term, PR_INTERVAL_NO_TIMEOUT); + } + (void) PR_Unlock (_pr_terminationCVLock); + + /* + Remove target thread from global waiting to join Q; make it runnable + again and put it back on its run Q. When it gets scheduled later in + _PR_RunThread code, it will clean up its stack. + */ + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + thread->state = _PR_RUNNABLE; + if ( !_PR_IS_NATIVE_THREAD(thread) ) { + _PR_THREAD_LOCK(thread); + + _PR_MISCQ_LOCK(thread->cpu); + _PR_DEL_JOINQ(thread); + _PR_MISCQ_UNLOCK(thread->cpu); + + _PR_AddThreadToRunQ(me, thread); + _PR_THREAD_UNLOCK(thread); + } + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); + + _PR_MD_WAKEUP_WAITER(thread); + + return PR_SUCCESS; + +ErrorExit: + if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); + return PR_FAILURE; +} + +PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thread, + PRThreadPriority newPri) +{ + + /* + First, pin down the priority. Not all compilers catch passing out of + range enum here. If we let bad values thru, priority queues won't work. + */ + if ((PRIntn)newPri > (PRIntn)PR_PRIORITY_LAST) { + newPri = PR_PRIORITY_LAST; + } else if ((PRIntn)newPri < (PRIntn)PR_PRIORITY_FIRST) { + newPri = PR_PRIORITY_FIRST; + } + + if ( _PR_IS_NATIVE_THREAD(thread) ) { + thread->priority = newPri; + _PR_MD_SET_PRIORITY(&(thread->md), newPri); + } else _PR_SetThreadPriority(thread, newPri); +} + +PR_IMPLEMENT(PRStatus) PR_SetCurrentThreadName(const char *name) +{ + PRThread *thread; + size_t nameLen; + + if (!name) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + thread = PR_GetCurrentThread(); + if (!thread) + return PR_FAILURE; + + PR_Free(thread->name); + nameLen = strlen(name); + thread->name = (char *)PR_Malloc(nameLen + 1); + if (!thread->name) + return PR_FAILURE; + memcpy(thread->name, name, nameLen + 1); + _PR_MD_SET_CURRENT_THREAD_NAME(thread->name); + return PR_SUCCESS; +} + +PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) +{ + if (!thread) + return NULL; + return thread->name; +} + + +/* +** This routine prevents all other threads from running. This call is needed by +** the garbage collector. +*/ +PR_IMPLEMENT(void) PR_SuspendAll(void) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRCList *qp; + + /* + * Stop all user and native threads which are marked GC able. + */ + PR_Lock(_pr_activeLock); + suspendAllOn = PR_TRUE; + suspendAllThread = _PR_MD_CURRENT_THREAD(); + _PR_MD_BEGIN_SUSPEND_ALL(); + for (qp = _PR_ACTIVE_LOCAL_THREADQ().next; + qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) { + if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && + _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) { + _PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp)); + PR_ASSERT((_PR_ACTIVE_THREAD_PTR(qp))->state != _PR_RUNNING); + } + } + for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next; + qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) { + if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && + _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) + /* PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp)); */ + _PR_MD_SUSPEND_THREAD(_PR_ACTIVE_THREAD_PTR(qp)); + } + _PR_MD_END_SUSPEND_ALL(); +} + +/* +** This routine unblocks all other threads that were suspended from running by +** PR_SuspendAll(). This call is needed by the garbage collector. +*/ +PR_IMPLEMENT(void) PR_ResumeAll(void) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRCList *qp; + + /* + * Resume all user and native threads which are marked GC able. + */ + _PR_MD_BEGIN_RESUME_ALL(); + for (qp = _PR_ACTIVE_LOCAL_THREADQ().next; + qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) { + if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && + _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) + _PR_Resume(_PR_ACTIVE_THREAD_PTR(qp)); + } + for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next; + qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) { + if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && + _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) + _PR_MD_RESUME_THREAD(_PR_ACTIVE_THREAD_PTR(qp)); + } + _PR_MD_END_RESUME_ALL(); + suspendAllThread = NULL; + suspendAllOn = PR_FALSE; + PR_Unlock(_pr_activeLock); +} + +PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg) +{ + PRCList *qp, *qp_next; + PRIntn i = 0; + PRStatus rv = PR_SUCCESS; + PRThread* t; + + /* + ** Currently Enumerate threads happen only with suspension and + ** pr_activeLock held + */ + PR_ASSERT(suspendAllOn); + + /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking + * qp->next after applying the function "func". In particular, "func" + * might remove the thread from the queue and put it into another one in + * which case qp->next no longer points to the next entry in the original + * queue. + * + * To get around this problem, we save qp->next in qp_next before applying + * "func" and use that saved value as the next value after applying "func". + */ + + /* + * Traverse the list of local and global threads + */ + for (qp = _PR_ACTIVE_LOCAL_THREADQ().next; + qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp_next) + { + qp_next = qp->next; + t = _PR_ACTIVE_THREAD_PTR(qp); + if (_PR_IS_GCABLE_THREAD(t)) + { + rv = (*func)(t, i, arg); + if (rv != PR_SUCCESS) + return rv; + i++; + } + } + for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next; + qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp_next) + { + qp_next = qp->next; + t = _PR_ACTIVE_THREAD_PTR(qp); + if (_PR_IS_GCABLE_THREAD(t)) + { + rv = (*func)(t, i, arg); + if (rv != PR_SUCCESS) + return rv; + i++; + } + } + return rv; +} + +/* FUNCTION: _PR_AddSleepQ +** DESCRIPTION: +** Adds a thread to the sleep/pauseQ. +** RESTRICTIONS: +** Caller must have the RUNQ lock. +** Caller must be a user level thread +*/ +PR_IMPLEMENT(void) +_PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout) +{ + _PRCPU *cpu = thread->cpu; + + if (timeout == PR_INTERVAL_NO_TIMEOUT) { + /* append the thread to the global pause Q */ + PR_APPEND_LINK(&thread->links, &_PR_PAUSEQ(thread->cpu)); + thread->flags |= _PR_ON_PAUSEQ; + } else { + PRIntervalTime sleep; + PRCList *q; + PRThread *t; + + /* sort onto global sleepQ */ + sleep = timeout; + + /* Check if we are longest timeout */ + if (timeout >= _PR_SLEEPQMAX(cpu)) { + PR_INSERT_BEFORE(&thread->links, &_PR_SLEEPQ(cpu)); + thread->sleep = timeout - _PR_SLEEPQMAX(cpu); + _PR_SLEEPQMAX(cpu) = timeout; + } else { + /* Sort thread into global sleepQ at appropriate point */ + q = _PR_SLEEPQ(cpu).next; + + /* Now scan the list for where to insert this entry */ + while (q != &_PR_SLEEPQ(cpu)) { + t = _PR_THREAD_PTR(q); + if (sleep < t->sleep) { + /* Found sleeper to insert in front of */ + break; + } + sleep -= t->sleep; + q = q->next; + } + thread->sleep = sleep; + PR_INSERT_BEFORE(&thread->links, q); + + /* + ** Subtract our sleep time from the sleeper that follows us (there + ** must be one) so that they remain relative to us. + */ + PR_ASSERT (thread->links.next != &_PR_SLEEPQ(cpu)); + + t = _PR_THREAD_PTR(thread->links.next); + PR_ASSERT(_PR_THREAD_PTR(t->links.prev) == thread); + t->sleep -= sleep; + } + + thread->flags |= _PR_ON_SLEEPQ; + } +} + +/* FUNCTION: _PR_DelSleepQ +** DESCRIPTION: +** Removes a thread from the sleep/pauseQ. +** INPUTS: +** If propogate_time is true, then the thread following the deleted +** thread will be get the time from the deleted thread. This is used +** when deleting a sleeper that has not timed out. +** RESTRICTIONS: +** Caller must have the RUNQ lock. +** Caller must be a user level thread +*/ +PR_IMPLEMENT(void) +_PR_DelSleepQ(PRThread *thread, PRBool propogate_time) +{ + _PRCPU *cpu = thread->cpu; + + /* Remove from pauseQ/sleepQ */ + if (thread->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) { + if (thread->flags & _PR_ON_SLEEPQ) { + PRCList *q = thread->links.next; + if (q != &_PR_SLEEPQ(cpu)) { + if (propogate_time == PR_TRUE) { + PRThread *after = _PR_THREAD_PTR(q); + after->sleep += thread->sleep; + } else + _PR_SLEEPQMAX(cpu) -= thread->sleep; + } else { + /* Check if prev is the beggining of the list; if so, + * we are the only element on the list. + */ + if (thread->links.prev != &_PR_SLEEPQ(cpu)) + _PR_SLEEPQMAX(cpu) -= thread->sleep; + else + _PR_SLEEPQMAX(cpu) = 0; + } + thread->flags &= ~_PR_ON_SLEEPQ; + } else { + thread->flags &= ~_PR_ON_PAUSEQ; + } + PR_REMOVE_LINK(&thread->links); + } else + PR_ASSERT(0); +} + +void +_PR_AddThreadToRunQ( + PRThread *me, /* the current thread */ + PRThread *thread) /* the local thread to be added to a run queue */ +{ + PRThreadPriority pri = thread->priority; + _PRCPU *cpu = thread->cpu; + + PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread)); + +#if defined(WINNT) + /* + * On NT, we can only reliably know that the current CPU + * is not idle. We add the awakened thread to the run + * queue of its CPU if its CPU is the current CPU. + * For any other CPU, we don't really know whether it + * is busy or idle. So in all other cases, we just + * "post" the awakened thread to the IO completion port + * for the next idle CPU to execute (this is done in + * _PR_MD_WAKEUP_WAITER). + * Threads with a suspended I/O operation remain bound to + * the same cpu until I/O is cancelled + * + * NOTE: the boolean expression below must be the exact + * opposite of the corresponding boolean expression in + * _PR_MD_WAKEUP_WAITER. + */ + if ((!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) || + (thread->md.thr_bound_cpu)) { + PR_ASSERT(!thread->md.thr_bound_cpu || + (thread->md.thr_bound_cpu == cpu)); + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(thread, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + } +#else + _PR_RUNQ_LOCK(cpu); + _PR_ADD_RUNQ(thread, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + if (!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) { + if (pri > me->priority) { + _PR_SET_RESCHED_FLAG(); + } + } +#endif +} diff -Nru nspr-4.9.5/nspr/pr/src/threads/combined/README nspr-4.10.7/nspr/pr/src/threads/combined/README --- nspr-4.9.5/nspr/pr/src/threads/combined/README 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/combined/README 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,62 @@ +NSPR 2.0 evolution +------------------ + + +Phase 1- today + +Currently (Oct 10, 1996) NSPR 2.0 has two modes. Either _PR_NTHREAD +is defined, in which case the PR_CreateThread() call always creates a +native kernel thread, or _PR_NTHREAD is not defined and PR_CreateThread() +always creates user level threads within the single, original process. This +source code is reflected in two directories, nspr20/pr/src/threads/native, and +nspr20/pr/src/threads/user. Although the PR_CreateThread() function has +a paramter to specify the "scope" of a thread, this parameter is not yet +used- except on solaris where it uses it to specify bound vs unbound threads. + +Phase 2 - next week + +The next step is to provide a combination of user and native threads. The +idea, of course, is to have some small number of native threads and each of +those threads be able to run user level threads. The number of native +threads created will most likely be proportional to the number of CPUs in +the system. For this reason, the specific set of native threads which are +used to run the user-level threads will be called "CPU" threads. + +The user level threads which will be run on the CPU threads are able to +run on any of the CPU threads available, and over the course of a user-level +thread's lifetime, it may drift from one CPU thread to another. All +user-level threads will compete for processing time via a single run queue. + +Creation of a CPU thread will be primarily controlled by NSPR itself or by +the user running a function PR_Concurrency(). The details of PR_Concurrency() +have not yet been worked out; but the idea is that the user can specify to +NSPR how many CPU threads are desired. + +In this system, user-level threads are created by using PR_CreateThread() and +specifying the PR_LOCAL_SCOPE option. LOCAL_SCOPE indicates that the thread +will be under the control of the "local" scheduler. Creating threads with +GLOBAL_SCOPE, on the other hand will create a thread which is under the +control of the system's scheduler. In otherwords, this creates a native thread +which is not a CPU thread; it runs a single thread task and never has more +than one task to run. LOCAL_SCOPE is much like creating a Solaris unbound +thread, while GLOBAL_SCOPE is similar to creating a Solaris bound thread. + +To implement this architecture, the source code will still maintain the "user" +and "native" directories which is has today. However a third directory +"combined" will also exist. To compile a version of NSPR which only creates +native threads, the user can define _PR_NTHREAD. For exclusive user-level +threads, do not define _PR_NTHREAD. To get the combined threads, define +_PR_NTHREAD and _PR_USE_CPUS. + + +Phase 3 - later than next week + +The goal is to eliminate the 3 directories. Once these three models are in +place, the remaining work will be to eliminate the native and user thread +directories for all platforms, so that the entire thread model is contained +within what is today called the "combined" model. This new and glorious +source code will attempt to make the "combined" model on any platforms which +provide the necessary underlying native threading, but will also be +capable of using exclusive user-level threads on systems which don't have +native threads. + diff -Nru nspr-4.9.5/nspr/pr/src/threads/.cvsignore nspr-4.10.7/nspr/pr/src/threads/.cvsignore --- nspr-4.9.5/nspr/pr/src/threads/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/src/threads/Makefile.in nspr-4.10.7/nspr/pr/src/threads/Makefile.in --- nspr-4.9.5/nspr/pr/src/threads/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,62 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +ifdef USE_PTHREADS + DIRS = +else +ifdef USE_BTHREADS + DIRS = +else + DIRS = combined +endif +endif + +ifdef USE_PTHREADS +CSRCS = \ + prcmon.c \ + prrwlock.c \ + prtpd.c \ + $(NULL) +else +ifdef USE_BTHREADS +CSRCS = \ + prcmon.c \ + prrwlock.c \ + prtpd.c \ + $(NULL) +else +CSRCS = \ + prcmon.c \ + prdump.c \ + prmon.c \ + prsem.c \ + prrwlock.c \ + prcthr.c \ + prtpd.c \ + $(NULL) +endif +endif + +TARGETS = $(OBJS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +DEFINES += -D_NSPR_BUILD_ + +include $(topsrcdir)/config/rules.mk + +export:: $(TARGETS) + diff -Nru nspr-4.9.5/nspr/pr/src/threads/prcmon.c nspr-4.10.7/nspr/pr/src/threads/prcmon.c --- nspr-4.9.5/nspr/pr/src/threads/prcmon.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/prcmon.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,431 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include +#include + +/* Lock used to lock the monitor cache */ +#ifdef _PR_NO_PREEMPT +#define _PR_NEW_LOCK_MCACHE() +#define _PR_DESTROY_LOCK_MCACHE() +#define _PR_LOCK_MCACHE() +#define _PR_UNLOCK_MCACHE() +#else +#ifdef _PR_LOCAL_THREADS_ONLY +#define _PR_NEW_LOCK_MCACHE() +#define _PR_DESTROY_LOCK_MCACHE() +#define _PR_LOCK_MCACHE() { PRIntn _is; _PR_INTSOFF(_is) +#define _PR_UNLOCK_MCACHE() _PR_INTSON(_is); } +#else +PRLock *_pr_mcacheLock; +#define _PR_NEW_LOCK_MCACHE() (_pr_mcacheLock = PR_NewLock()) +#define _PR_DESTROY_LOCK_MCACHE() \ + PR_BEGIN_MACRO \ + if (_pr_mcacheLock) { \ + PR_DestroyLock(_pr_mcacheLock); \ + _pr_mcacheLock = NULL; \ + } \ + PR_END_MACRO +#define _PR_LOCK_MCACHE() PR_Lock(_pr_mcacheLock) +#define _PR_UNLOCK_MCACHE() PR_Unlock(_pr_mcacheLock) +#endif +#endif + +/************************************************************************/ + +typedef struct MonitorCacheEntryStr MonitorCacheEntry; + +struct MonitorCacheEntryStr { + MonitorCacheEntry* next; + void* address; + PRMonitor* mon; + long cacheEntryCount; +}; + +/* +** An array of MonitorCacheEntry's, plus a pointer to link these +** arrays together. +*/ + +typedef struct MonitorCacheEntryBlockStr MonitorCacheEntryBlock; + +struct MonitorCacheEntryBlockStr { + MonitorCacheEntryBlock* next; + MonitorCacheEntry entries[1]; +}; + +static PRUint32 hash_mask; +static PRUintn num_hash_buckets; +static PRUintn num_hash_buckets_log2; +static MonitorCacheEntry **hash_buckets; +static MonitorCacheEntry *free_entries; +static PRUintn num_free_entries; +static PRBool expanding; +static MonitorCacheEntryBlock *mcache_blocks; + +static void (*OnMonitorRecycle)(void *address); + +#define HASH(address) \ + ((PRUint32) ( ((PRUptrdiff)(address) >> 2) ^ \ + ((PRUptrdiff)(address) >> 10) ) \ + & hash_mask) + +/* +** Expand the monitor cache. This grows the hash buckets and allocates a +** new chunk of cache entries and throws them on the free list. We keep +** as many hash buckets as there are entries. +** +** Because we call malloc and malloc may need the monitor cache, we must +** ensure that there are several free monitor cache entries available for +** malloc to get. FREE_THRESHOLD is used to prevent monitor cache +** starvation during monitor cache expansion. +*/ + +#define FREE_THRESHOLD 5 + +static PRStatus ExpandMonitorCache(PRUintn new_size_log2) +{ + MonitorCacheEntry **old_hash_buckets, *p; + PRUintn i, entries, old_num_hash_buckets, added; + MonitorCacheEntry **new_hash_buckets; + MonitorCacheEntryBlock *new_block; + + entries = 1L << new_size_log2; + + /* + ** Expand the monitor-cache-entry free list + */ + new_block = (MonitorCacheEntryBlock*) + PR_CALLOC(sizeof(MonitorCacheEntryBlock) + + (entries - 1) * sizeof(MonitorCacheEntry)); + if (NULL == new_block) return PR_FAILURE; + + /* + ** Allocate system monitors for the new monitor cache entries. If we + ** run out of system monitors, break out of the loop. + */ + for (i = 0, p = new_block->entries; i < entries; i++, p++) { + p->mon = PR_NewMonitor(); + if (!p->mon) + break; + } + added = i; + if (added != entries) { + MonitorCacheEntryBlock *realloc_block; + + if (added == 0) { + /* Totally out of system monitors. Lossage abounds */ + PR_DELETE(new_block); + return PR_FAILURE; + } + + /* + ** We were able to allocate some of the system monitors. Use + ** realloc to shrink down the new_block memory. If that fails, + ** carry on with the too-large new_block. + */ + realloc_block = (MonitorCacheEntryBlock*) + PR_REALLOC(new_block, sizeof(MonitorCacheEntryBlock) + + (added - 1) * sizeof(MonitorCacheEntry)); + if (realloc_block) + new_block = realloc_block; + } + + /* + ** Now that we have allocated all of the system monitors, build up + ** the new free list. We can just update the free_list because we own + ** the mcache-lock and we aren't calling anyone who might want to use + ** it. + */ + for (i = 0, p = new_block->entries; i < added - 1; i++, p++) + p->next = p + 1; + p->next = free_entries; + free_entries = new_block->entries; + num_free_entries += added; + new_block->next = mcache_blocks; + mcache_blocks = new_block; + + /* Try to expand the hash table */ + new_hash_buckets = (MonitorCacheEntry**) + PR_CALLOC(entries * sizeof(MonitorCacheEntry*)); + if (NULL == new_hash_buckets) { + /* + ** Partial lossage. In this situation we don't get any more hash + ** buckets, which just means that the table lookups will take + ** longer. This is bad, but not fatal + */ + PR_LOG(_pr_cmon_lm, PR_LOG_WARNING, + ("unable to grow monitor cache hash buckets")); + return PR_SUCCESS; + } + + /* + ** Compute new hash mask value. This value is used to mask an address + ** until it's bits are in the right spot for indexing into the hash + ** table. + */ + hash_mask = entries - 1; + + /* + ** Expand the hash table. We have to rehash everything in the old + ** table into the new table. + */ + old_hash_buckets = hash_buckets; + old_num_hash_buckets = num_hash_buckets; + for (i = 0; i < old_num_hash_buckets; i++) { + p = old_hash_buckets[i]; + while (p) { + MonitorCacheEntry *next = p->next; + + /* Hash based on new table size, and then put p in the new table */ + PRUintn hash = HASH(p->address); + p->next = new_hash_buckets[hash]; + new_hash_buckets[hash] = p; + + p = next; + } + } + + /* + ** Switch over to new hash table and THEN call free of the old + ** table. Since free might re-enter _pr_mcache_lock, things would + ** break terribly if it used the old hash table. + */ + hash_buckets = new_hash_buckets; + num_hash_buckets = entries; + num_hash_buckets_log2 = new_size_log2; + PR_DELETE(old_hash_buckets); + + PR_LOG(_pr_cmon_lm, PR_LOG_NOTICE, + ("expanded monitor cache to %d (buckets %d)", + num_free_entries, entries)); + + return PR_SUCCESS; +} /* ExpandMonitorCache */ + +/* +** Lookup a monitor cache entry by address. Return a pointer to the +** pointer to the monitor cache entry on success, null on failure. +*/ +static MonitorCacheEntry **LookupMonitorCacheEntry(void *address) +{ + PRUintn hash; + MonitorCacheEntry **pp, *p; + + hash = HASH(address); + pp = hash_buckets + hash; + while ((p = *pp) != 0) { + if (p->address == address) { + if (p->cacheEntryCount > 0) + return pp; + return NULL; + } + pp = &p->next; + } + return NULL; +} + +/* +** Try to create a new cached monitor. If it's already in the cache, +** great - return it. Otherwise get a new free cache entry and set it +** up. If the cache free space is getting low, expand the cache. +*/ +static PRMonitor *CreateMonitor(void *address) +{ + PRUintn hash; + MonitorCacheEntry **pp, *p; + + hash = HASH(address); + pp = hash_buckets + hash; + while ((p = *pp) != 0) { + if (p->address == address) goto gotit; + + pp = &p->next; + } + + /* Expand the monitor cache if we have run out of free slots in the table */ + if (num_free_entries < FREE_THRESHOLD) { + /* Expand monitor cache */ + + /* + ** This function is called with the lock held. So what's the 'expanding' + ** boolean all about? Seems a bit redundant. + */ + if (!expanding) { + PRStatus rv; + + expanding = PR_TRUE; + rv = ExpandMonitorCache(num_hash_buckets_log2 + 1); + expanding = PR_FALSE; + if (PR_FAILURE == rv) return NULL; + + /* redo the hash because it'll be different now */ + hash = HASH(address); + } else { + /* + ** We are in process of expanding and we need a cache + ** monitor. Make sure we have enough! + */ + PR_ASSERT(num_free_entries > 0); + } + } + + /* Make a new monitor */ + p = free_entries; + free_entries = p->next; + num_free_entries--; + if (OnMonitorRecycle && p->address) + OnMonitorRecycle(p->address); + p->address = address; + p->next = hash_buckets[hash]; + hash_buckets[hash] = p; + PR_ASSERT(p->cacheEntryCount == 0); + + gotit: + p->cacheEntryCount++; + return p->mon; +} + +/* +** Initialize the monitor cache +*/ +void _PR_InitCMon(void) +{ + _PR_NEW_LOCK_MCACHE(); + ExpandMonitorCache(3); +} + +/* +** Destroy the monitor cache +*/ +void _PR_CleanupCMon(void) +{ + _PR_DESTROY_LOCK_MCACHE(); + + while (free_entries) { + PR_DestroyMonitor(free_entries->mon); + free_entries = free_entries->next; + } + num_free_entries = 0; + + while (mcache_blocks) { + MonitorCacheEntryBlock *block; + + block = mcache_blocks; + mcache_blocks = block->next; + PR_DELETE(block); + } + + PR_DELETE(hash_buckets); + hash_mask = 0; + num_hash_buckets = 0; + num_hash_buckets_log2 = 0; + + expanding = PR_FALSE; + OnMonitorRecycle = NULL; +} + +/* +** Create monitor for address. Don't enter the monitor while we have the +** mcache locked because we might block! +*/ +PR_IMPLEMENT(PRMonitor*) PR_CEnterMonitor(void *address) +{ + PRMonitor *mon; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + _PR_LOCK_MCACHE(); + mon = CreateMonitor(address); + _PR_UNLOCK_MCACHE(); + + if (!mon) return NULL; + + PR_EnterMonitor(mon); + return mon; +} + +PR_IMPLEMENT(PRStatus) PR_CExitMonitor(void *address) +{ + MonitorCacheEntry **pp, *p; + PRStatus status = PR_SUCCESS; + + _PR_LOCK_MCACHE(); + pp = LookupMonitorCacheEntry(address); + if (pp != NULL) { + p = *pp; + if (--p->cacheEntryCount == 0) { + /* + ** Nobody is using the system monitor. Put it on the cached free + ** list. We are safe from somebody trying to use it because we + ** have the mcache locked. + */ + p->address = 0; /* defensive move */ + *pp = p->next; /* unlink from hash_buckets */ + p->next = free_entries; /* link into free list */ + free_entries = p; + num_free_entries++; /* count it as free */ + } + status = PR_ExitMonitor(p->mon); + } else { + status = PR_FAILURE; + } + _PR_UNLOCK_MCACHE(); + + return status; +} + +PR_IMPLEMENT(PRStatus) PR_CWait(void *address, PRIntervalTime ticks) +{ + MonitorCacheEntry **pp; + PRMonitor *mon; + + _PR_LOCK_MCACHE(); + pp = LookupMonitorCacheEntry(address); + mon = pp ? ((*pp)->mon) : NULL; + _PR_UNLOCK_MCACHE(); + + if (mon == NULL) + return PR_FAILURE; + return PR_Wait(mon, ticks); +} + +PR_IMPLEMENT(PRStatus) PR_CNotify(void *address) +{ + MonitorCacheEntry **pp; + PRMonitor *mon; + + _PR_LOCK_MCACHE(); + pp = LookupMonitorCacheEntry(address); + mon = pp ? ((*pp)->mon) : NULL; + _PR_UNLOCK_MCACHE(); + + if (mon == NULL) + return PR_FAILURE; + return PR_Notify(mon); +} + +PR_IMPLEMENT(PRStatus) PR_CNotifyAll(void *address) +{ + MonitorCacheEntry **pp; + PRMonitor *mon; + + _PR_LOCK_MCACHE(); + pp = LookupMonitorCacheEntry(address); + mon = pp ? ((*pp)->mon) : NULL; + _PR_UNLOCK_MCACHE(); + + if (mon == NULL) + return PR_FAILURE; + return PR_NotifyAll(mon); +} + +PR_IMPLEMENT(void) +PR_CSetOnMonitorRecycle(void (*callback)(void *address)) +{ + OnMonitorRecycle = callback; +} diff -Nru nspr-4.9.5/nspr/pr/src/threads/prcthr.c nspr-4.10.7/nspr/pr/src/threads/prcthr.c --- nspr-4.9.5/nspr/pr/src/threads/prcthr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/prcthr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,395 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#if defined(WIN95) +/* +** Some local variables report warnings on Win95 because the code paths +** using them are conditioned on HAVE_CUSTOME_USER_THREADS. +** The pragma suppresses the warning. +** +*/ +#pragma warning(disable : 4101) +#endif + + +extern PRLock *_pr_sleeplock; /* allocated and initialized in prinit */ +/* +** Routines common to both native and user threads. +** +** +** Clean up a thread object, releasing all of the attached data. Do not +** free the object itself (it may not have been malloc'd) +*/ +void _PR_CleanupThread(PRThread *thread) +{ + /* Free up per-thread-data */ + _PR_DestroyThreadPrivate(thread); + + /* Free any thread dump procs */ + if (thread->dumpArg) { + PR_DELETE(thread->dumpArg); + } + thread->dump = 0; + + PR_DELETE(thread->name); + PR_DELETE(thread->errorString); + thread->errorStringSize = 0; + thread->errorStringLength = 0; + thread->environment = NULL; +} + +PR_IMPLEMENT(PRStatus) PR_Yield() +{ + static PRBool warning = PR_TRUE; + if (warning) warning = _PR_Obsolete( + "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)"); + return (PR_Sleep(PR_INTERVAL_NO_WAIT)); +} + +/* +** Make the current thread sleep until "timeout" ticks amount of time +** has expired. If "timeout" is PR_INTERVAL_NO_WAIT then the call is +** equivalent to a yield. Waiting for an infinite amount of time is +** allowed in the expectation that another thread will interrupt(). +** +** A single lock is used for all threads calling sleep. Each caller +** does get its own condition variable since each is expected to have +** a unique 'timeout'. +*/ +PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime timeout) +{ + PRStatus rv = PR_SUCCESS; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (PR_INTERVAL_NO_WAIT == timeout) + { + /* + ** This is a simple yield, nothing more, nothing less. + */ + PRIntn is; + PRThread *me = PR_GetCurrentThread(); + PRUintn pri = me->priority; + _PRCPU *cpu = _PR_MD_CURRENT_CPU(); + + if ( _PR_IS_NATIVE_THREAD(me) ) _PR_MD_YIELD(); + else + { + _PR_INTSOFF(is); + _PR_RUNQ_LOCK(cpu); + if (_PR_RUNQREADYMASK(cpu) >> pri) { + me->cpu = cpu; + me->state = _PR_RUNNABLE; + _PR_ADD_RUNQ(me, cpu, pri); + _PR_RUNQ_UNLOCK(cpu); + + PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: yielding")); + _PR_MD_SWITCH_CONTEXT(me); + PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: done")); + + _PR_FAST_INTSON(is); + } + else + { + _PR_RUNQ_UNLOCK(cpu); + _PR_INTSON(is); + } + } + } + else + { + /* + ** This is waiting for some finite period of time. + ** A thread in this state is interruptible (PR_Interrupt()), + ** but the lock and cvar used are local to the implementation + ** and not visible to the caller, therefore not notifiable. + */ + PRCondVar *cv; + PRIntervalTime timein; + + timein = PR_IntervalNow(); + cv = PR_NewCondVar(_pr_sleeplock); + PR_ASSERT(cv != NULL); + PR_Lock(_pr_sleeplock); + do + { + PRIntervalTime delta = PR_IntervalNow() - timein; + if (delta > timeout) break; + rv = PR_WaitCondVar(cv, timeout - delta); + } while (rv == PR_SUCCESS); + PR_Unlock(_pr_sleeplock); + PR_DestroyCondVar(cv); + } + return rv; +} + +PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thread) +{ + return thread->id; +} + +PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread) +{ + return (PRThreadPriority) thread->priority; +} + +PR_IMPLEMENT(PRThread *) PR_GetCurrentThread() +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + return _PR_MD_CURRENT_THREAD(); +} + +/* +** Set the interrupt flag for a thread. The thread will be unable to +** block in i/o functions when this happens. Also, any PR_Wait's in +** progress will be undone. The interrupt remains in force until +** PR_ClearInterrupt is called. +*/ +PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thread) +{ +#ifdef _PR_GLOBAL_THREADS_ONLY + PRCondVar *victim; + + _PR_THREAD_LOCK(thread); + thread->flags |= _PR_INTERRUPT; + victim = thread->wait.cvar; + _PR_THREAD_UNLOCK(thread); + if ((NULL != victim) && (!(thread->flags & _PR_INTERRUPT_BLOCKED))) { + int haveLock = (victim->lock->owner == _PR_MD_CURRENT_THREAD()); + + if (!haveLock) PR_Lock(victim->lock); + PR_NotifyAllCondVar(victim); + if (!haveLock) PR_Unlock(victim->lock); + } + return PR_SUCCESS; +#else /* ! _PR_GLOBAL_THREADS_ONLY */ + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSOFF(is); + + _PR_THREAD_LOCK(thread); + thread->flags |= _PR_INTERRUPT; + switch (thread->state) { + case _PR_COND_WAIT: + /* + * call is made with thread locked; + * on return lock is released + */ + if (!(thread->flags & _PR_INTERRUPT_BLOCKED)) + _PR_NotifyLockedThread(thread); + break; + case _PR_IO_WAIT: + /* + * Need to hold the thread lock when calling + * _PR_Unblock_IO_Wait(). On return lock is + * released. + */ +#if defined(XP_UNIX) || defined(WINNT) || defined(WIN16) + if (!(thread->flags & _PR_INTERRUPT_BLOCKED)) + _PR_Unblock_IO_Wait(thread); +#else + _PR_THREAD_UNLOCK(thread); +#endif + break; + case _PR_RUNNING: + case _PR_RUNNABLE: + case _PR_LOCK_WAIT: + default: + _PR_THREAD_UNLOCK(thread); + break; + } + if (!_PR_IS_NATIVE_THREAD(me)) + _PR_INTSON(is); + return PR_SUCCESS; +#endif /* _PR_GLOBAL_THREADS_ONLY */ +} + +/* +** Clear the interrupt flag for self. +*/ +PR_IMPLEMENT(void) PR_ClearInterrupt() +{ + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); + _PR_THREAD_LOCK(me); + me->flags &= ~_PR_INTERRUPT; + _PR_THREAD_UNLOCK(me); + if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); +} + +PR_IMPLEMENT(void) PR_BlockInterrupt() +{ + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); + _PR_THREAD_LOCK(me); + _PR_THREAD_BLOCK_INTERRUPT(me); + _PR_THREAD_UNLOCK(me); + if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); +} /* PR_BlockInterrupt */ + +PR_IMPLEMENT(void) PR_UnblockInterrupt() +{ + PRIntn is; + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); + _PR_THREAD_LOCK(me); + _PR_THREAD_UNBLOCK_INTERRUPT(me); + _PR_THREAD_UNLOCK(me); + if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); +} /* PR_UnblockInterrupt */ + +/* +** Return the thread stack pointer of the given thread. +*/ +PR_IMPLEMENT(void *) PR_GetSP(PRThread *thread) +{ + return (void *)_PR_MD_GET_SP(thread); +} + +PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thread) +{ + return thread->environment; +} + +PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thread, void *env) +{ + thread->environment = env; +} + + +PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask) +{ +#ifdef HAVE_THREAD_AFFINITY + return _PR_MD_GETTHREADAFFINITYMASK(thread, mask); +#else + return 0; +#endif +} + +PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask ) +{ +#ifdef HAVE_THREAD_AFFINITY +#ifndef IRIX + return _PR_MD_SETTHREADAFFINITYMASK(thread, mask); +#else + return 0; +#endif +#else + return 0; +#endif +} + +/* This call is thread unsafe if another thread is calling SetConcurrency() + */ +PR_IMPLEMENT(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask) +{ +#ifdef HAVE_THREAD_AFFINITY + PRCList *qp; + extern PRUint32 _pr_cpu_affinity_mask; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + _pr_cpu_affinity_mask = mask; + + qp = _PR_CPUQ().next; + while(qp != &_PR_CPUQ()) { + _PRCPU *cpu; + + cpu = _PR_CPU_PTR(qp); + PR_SetThreadAffinityMask(cpu->thread, mask); + + qp = qp->next; + } +#endif + + return 0; +} + +PRUint32 _pr_recycleThreads = 0; +PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 count) +{ + _pr_recycleThreads = count; +} + +PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + return _PR_CreateThread(type, start, arg, priority, scope, state, + stackSize, _PR_GCABLE_THREAD); +} + +#ifdef SOLARIS +PR_IMPLEMENT(PRThread*) PR_CreateThreadBound(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRUintn priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize) +{ + return _PR_CreateThread(type, start, arg, priority, scope, state, + stackSize, _PR_BOUND_THREAD); +} +#endif + + +PR_IMPLEMENT(PRThread*) PR_AttachThreadGCAble( + PRThreadType type, PRThreadPriority priority, PRThreadStack *stack) +{ + /* $$$$ not sure how to finese this one */ + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return NULL; +} + +PR_IMPLEMENT(void) PR_SetThreadGCAble() +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + PR_Lock(_pr_activeLock); + _PR_MD_CURRENT_THREAD()->flags |= _PR_GCABLE_THREAD; + PR_Unlock(_pr_activeLock); +} + +PR_IMPLEMENT(void) PR_ClearThreadGCAble() +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + PR_Lock(_pr_activeLock); + _PR_MD_CURRENT_THREAD()->flags &= (~_PR_GCABLE_THREAD); + PR_Unlock(_pr_activeLock); +} + +PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thread) +{ + if (!_pr_initialized) _PR_ImplicitInitialization(); + + if (_PR_IS_NATIVE_THREAD(thread)) { + return (thread->flags & _PR_BOUND_THREAD) ? PR_GLOBAL_BOUND_THREAD : + PR_GLOBAL_THREAD; + } else + return PR_LOCAL_THREAD; +} + +PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thread) +{ + return (thread->flags & _PR_SYSTEM) ? PR_SYSTEM_THREAD : PR_USER_THREAD; +} + +PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thread) +{ + return (NULL == thread->term) ? PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD; +} /* PR_GetThreadState */ diff -Nru nspr-4.9.5/nspr/pr/src/threads/prdump.c nspr-4.10.7/nspr/pr/src/threads/prdump.c --- nspr-4.9.5/nspr/pr/src/threads/prdump.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/prdump.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#if defined(WIN95) +/* +** Some local variables report warnings on Win95 because the code paths +** using them are conditioned on HAVE_CUSTOME_USER_THREADS. +** The pragma suppresses the warning. +** +*/ +#pragma warning(disable : 4101) +#endif + +/* XXX use unbuffered nspr stdio */ + +PRFileDesc *_pr_dumpOut; + +PRUint32 _PR_DumpPrintf(PRFileDesc *fd, const char *fmt, ...) +{ + char buf[100]; + PRUint32 nb; + va_list ap; + + va_start(ap, fmt); + nb = PR_vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + PR_Write(fd, buf, nb); + + return nb; +} + +void _PR_DumpThread(PRFileDesc *fd, PRThread *thread) +{ + +#ifndef _PR_GLOBAL_THREADS_ONLY + _PR_DumpPrintf(fd, "%05d[%08p] pri=%2d flags=0x%02x", + thread->id, thread, thread->priority, thread->flags); + switch (thread->state) { + case _PR_RUNNABLE: + case _PR_RUNNING: + break; + case _PR_LOCK_WAIT: + _PR_DumpPrintf(fd, " lock=%p", thread->wait.lock); + break; + case _PR_COND_WAIT: + _PR_DumpPrintf(fd, " condvar=%p sleep=%lldms", + thread->wait.cvar, thread->sleep); + break; + case _PR_SUSPENDED: + _PR_DumpPrintf(fd, " suspended"); + break; + } + PR_Write(fd, "\n", 1); +#endif + + /* Now call dump routine */ + if (thread->dump) { + thread->dump(fd, thread, thread->dumpArg); + } +} + +static void DumpThreadQueue(PRFileDesc *fd, PRCList *list) +{ +#ifndef _PR_GLOBAL_THREADS_ONLY + PRCList *q; + + q = list->next; + while (q != list) { + PRThread *t = _PR_THREAD_PTR(q); + _PR_DumpThread(fd, t); + q = q->next; + } +#endif +} + +void _PR_DumpThreads(PRFileDesc *fd) +{ + PRThread *t; + PRIntn i; + + _PR_DumpPrintf(fd, "Current Thread:\n"); + t = _PR_MD_CURRENT_THREAD(); + _PR_DumpThread(fd, t); + + _PR_DumpPrintf(fd, "Runnable Threads:\n"); + for (i = 0; i < 32; i++) { + DumpThreadQueue(fd, &_PR_RUNQ(t->cpu)[i]); + } + + _PR_DumpPrintf(fd, "CondVar timed wait Threads:\n"); + DumpThreadQueue(fd, &_PR_SLEEPQ(t->cpu)); + + _PR_DumpPrintf(fd, "CondVar wait Threads:\n"); + DumpThreadQueue(fd, &_PR_PAUSEQ(t->cpu)); + + _PR_DumpPrintf(fd, "Suspended Threads:\n"); + DumpThreadQueue(fd, &_PR_SUSPENDQ(t->cpu)); +} + +PR_IMPLEMENT(void) PR_ShowStatus(void) +{ + PRIntn is; + + if ( _PR_MD_CURRENT_THREAD() + && !_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) _PR_INTSOFF(is); + _pr_dumpOut = _pr_stderr; + _PR_DumpThreads(_pr_dumpOut); + if ( _PR_MD_CURRENT_THREAD() + && !_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) _PR_FAST_INTSON(is); +} + +PR_IMPLEMENT(void) +PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg) +{ + thread->dump = dump; + thread->dumpArg = arg; +} diff -Nru nspr-4.9.5/nspr/pr/src/threads/prmon.c nspr-4.10.7/nspr/pr/src/threads/prmon.c --- nspr-4.9.5/nspr/pr/src/threads/prmon.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/prmon.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,346 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +/************************************************************************/ + +/* + * Notifies just get posted to the monitor. The actual notification is done + * when the monitor is fully exited so that MP systems don't contend for a + * monitor that they can't enter. + */ +static void _PR_PostNotifyToMonitor(PRMonitor *mon, PRBool broadcast) +{ + PR_ASSERT(mon != NULL); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mon); + + /* mon->notifyTimes is protected by the monitor, so we don't need to + * acquire mon->lock. + */ + if (broadcast) + mon->notifyTimes = -1; + else if (mon->notifyTimes != -1) + mon->notifyTimes += 1; +} + +static void _PR_PostNotifiesFromMonitor(PRCondVar *cv, PRIntn times) +{ + PRStatus rv; + + /* + * Time to actually notify any waits that were affected while the monitor + * was entered. + */ + PR_ASSERT(cv != NULL); + PR_ASSERT(times != 0); + if (times == -1) { + rv = PR_NotifyAllCondVar(cv); + PR_ASSERT(rv == PR_SUCCESS); + } else { + while (times-- > 0) { + rv = PR_NotifyCondVar(cv); + PR_ASSERT(rv == PR_SUCCESS); + } + } +} + +/* +** Create a new monitor. +*/ +PR_IMPLEMENT(PRMonitor*) PR_NewMonitor() +{ + PRMonitor *mon; + PRStatus rv; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + mon = PR_NEWZAP(PRMonitor); + if (mon == NULL) { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + + rv = _PR_InitLock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + if (rv != PR_SUCCESS) + goto error1; + + mon->owner = NULL; + + rv = _PR_InitCondVar(&mon->entryCV, &mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + if (rv != PR_SUCCESS) + goto error2; + + rv = _PR_InitCondVar(&mon->waitCV, &mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + if (rv != PR_SUCCESS) + goto error3; + + mon->notifyTimes = 0; + mon->entryCount = 0; + mon->name = NULL; + return mon; + +error3: + _PR_FreeCondVar(&mon->entryCV); +error2: + _PR_FreeLock(&mon->lock); +error1: + PR_Free(mon); + return NULL; +} + +PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name) +{ + PRMonitor* mon = PR_NewMonitor(); + if (mon) + mon->name = name; + return mon; +} + +/* +** Destroy a monitor. There must be no thread waiting on the monitor's +** condition variable. The caller is responsible for guaranteeing that the +** monitor is no longer in use. +*/ +PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon) +{ + PR_ASSERT(mon != NULL); + _PR_FreeCondVar(&mon->waitCV); + _PR_FreeCondVar(&mon->entryCV); + _PR_FreeLock(&mon->lock); +#if defined(DEBUG) + memset(mon, 0xaf, sizeof(PRMonitor)); +#endif + PR_Free(mon); +} + +/* +** Enter the lock associated with the monitor. +*/ +PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRStatus rv; + + PR_ASSERT(mon != NULL); + PR_Lock(&mon->lock); + if (mon->entryCount != 0) { + if (mon->owner == me) + goto done; + while (mon->entryCount != 0) { + rv = PR_WaitCondVar(&mon->entryCV, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(rv == PR_SUCCESS); + } + } + /* and now I have the monitor */ + PR_ASSERT(mon->notifyTimes == 0); + PR_ASSERT(mon->owner == NULL); + mon->owner = me; + +done: + mon->entryCount += 1; + rv = PR_Unlock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); +} + +/* +** Test and then enter the lock associated with the monitor if it's not +** already entered by some other thread. Return PR_FALSE if some other +** thread owned the lock at the time of the call. +*/ +PR_IMPLEMENT(PRBool) PR_TestAndEnterMonitor(PRMonitor *mon) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRStatus rv; + + PR_ASSERT(mon != NULL); + PR_Lock(&mon->lock); + if (mon->entryCount != 0) { + if (mon->owner == me) + goto done; + rv = PR_Unlock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + return PR_FALSE; + } + /* and now I have the monitor */ + PR_ASSERT(mon->notifyTimes == 0); + PR_ASSERT(mon->owner == NULL); + mon->owner = me; + +done: + mon->entryCount += 1; + rv = PR_Unlock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + return PR_TRUE; +} + +/* +** Exit the lock associated with the monitor once. +*/ +PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRStatus rv; + + PR_ASSERT(mon != NULL); + PR_Lock(&mon->lock); + /* the entries should be > 0 and we'd better be the owner */ + PR_ASSERT(mon->entryCount > 0); + PR_ASSERT(mon->owner == me); + if (mon->entryCount == 0 || mon->owner != me) + { + rv = PR_Unlock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + return PR_FAILURE; + } + + mon->entryCount -= 1; /* reduce by one */ + if (mon->entryCount == 0) + { + /* and if it transitioned to zero - notify an entry waiter */ + /* make the owner unknown */ + mon->owner = NULL; + if (mon->notifyTimes != 0) { + _PR_PostNotifiesFromMonitor(&mon->waitCV, mon->notifyTimes); + mon->notifyTimes = 0; + } + rv = PR_NotifyCondVar(&mon->entryCV); + PR_ASSERT(rv == PR_SUCCESS); + } + rv = PR_Unlock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + return PR_SUCCESS; +} + +/* +** Return the number of times that the current thread has entered the +** lock. Returns zero if the current thread has not entered the lock. +*/ +PR_IMPLEMENT(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon) +{ + PRThread *me = _PR_MD_CURRENT_THREAD(); + PRStatus rv; + PRIntn count = 0; + + PR_Lock(&mon->lock); + if (mon->owner == me) + count = mon->entryCount; + rv = PR_Unlock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + return count; +} + +PR_IMPLEMENT(void) PR_AssertCurrentThreadInMonitor(PRMonitor *mon) +{ +#if defined(DEBUG) || defined(FORCE_PR_ASSERT) + PRStatus rv; + + PR_Lock(&mon->lock); + PR_ASSERT(mon->entryCount != 0 && + mon->owner == _PR_MD_CURRENT_THREAD()); + rv = PR_Unlock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); +#endif +} + +/* +** Wait for a notify on the condition variable. Sleep for "ticks" amount +** of time (if "tick" is 0 then the sleep is indefinite). While +** the thread is waiting it exits the monitors lock (as if it called +** PR_ExitMonitor as many times as it had called PR_EnterMonitor). When +** the wait has finished the thread regains control of the monitors lock +** with the same entry count as before the wait began. +** +** The thread waiting on the monitor will be resumed when the monitor is +** notified (assuming the thread is the next in line to receive the +** notify) or when the "ticks" elapses. +** +** Returns PR_FAILURE if the caller has not locked the lock associated +** with the condition variable. +** This routine can return PR_PENDING_INTERRUPT_ERROR if the waiting thread +** has been interrupted. +*/ +PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks) +{ + PRStatus rv; + PRUint32 saved_entries; + PRThread *saved_owner; + + PR_ASSERT(mon != NULL); + PR_Lock(&mon->lock); + /* the entries better be positive */ + PR_ASSERT(mon->entryCount > 0); + /* and it better be owned by us */ + PR_ASSERT(mon->owner == _PR_MD_CURRENT_THREAD()); /* XXX return failure */ + + /* tuck these away 'till later */ + saved_entries = mon->entryCount; + mon->entryCount = 0; + saved_owner = mon->owner; + mon->owner = NULL; + /* If we have pending notifies, post them now. */ + if (mon->notifyTimes != 0) { + _PR_PostNotifiesFromMonitor(&mon->waitCV, mon->notifyTimes); + mon->notifyTimes = 0; + } + rv = PR_NotifyCondVar(&mon->entryCV); + PR_ASSERT(rv == PR_SUCCESS); + + rv = PR_WaitCondVar(&mon->waitCV, ticks); + PR_ASSERT(rv == PR_SUCCESS); + + while (mon->entryCount != 0) { + rv = PR_WaitCondVar(&mon->entryCV, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(rv == PR_SUCCESS); + } + PR_ASSERT(mon->notifyTimes == 0); + /* reinstate the interesting information */ + mon->entryCount = saved_entries; + mon->owner = saved_owner; + + rv = PR_Unlock(&mon->lock); + PR_ASSERT(rv == PR_SUCCESS); + return rv; +} + +/* +** Notify the highest priority thread waiting on the condition +** variable. If a thread is waiting on the condition variable (using +** PR_Wait) then it is awakened and begins waiting on the monitor's lock. +*/ +PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon) +{ + _PR_PostNotifyToMonitor(mon, PR_FALSE); + return PR_SUCCESS; +} + +/* +** Notify all of the threads waiting on the condition variable. All of +** threads are notified in turn. The highest priority thread will +** probably acquire the monitor first when the monitor is exited. +*/ +PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon) +{ + _PR_PostNotifyToMonitor(mon, PR_TRUE); + return PR_SUCCESS; +} + +/************************************************************************/ + +PRUint32 _PR_MonitorToString(PRMonitor *mon, char *buf, PRUint32 buflen) +{ + PRUint32 nb; + + if (mon->owner) { + nb = PR_snprintf(buf, buflen, "[%p] owner=%d[%p] count=%ld", + mon, mon->owner->id, mon->owner, mon->entryCount); + } else { + nb = PR_snprintf(buf, buflen, "[%p]", mon); + } + return nb; +} diff -Nru nspr-4.9.5/nspr/pr/src/threads/prrwlock.c nspr-4.10.7/nspr/pr/src/threads/prrwlock.c --- nspr-4.9.5/nspr/pr/src/threads/prrwlock.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/prrwlock.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,483 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" + +#include + +#if defined(HPUX) && defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) + +#include +#define HAVE_UNIX98_RWLOCK +#define RWLOCK_T pthread_rwlock_t +#define RWLOCK_INIT(lock) pthread_rwlock_init(lock, NULL) +#define RWLOCK_DESTROY(lock) pthread_rwlock_destroy(lock) +#define RWLOCK_RDLOCK(lock) pthread_rwlock_rdlock(lock) +#define RWLOCK_WRLOCK(lock) pthread_rwlock_wrlock(lock) +#define RWLOCK_UNLOCK(lock) pthread_rwlock_unlock(lock) + +#elif defined(SOLARIS) && (defined(_PR_PTHREADS) \ + || defined(_PR_GLOBAL_THREADS_ONLY)) + +#include +#define HAVE_UI_RWLOCK +#define RWLOCK_T rwlock_t +#define RWLOCK_INIT(lock) rwlock_init(lock, USYNC_THREAD, NULL) +#define RWLOCK_DESTROY(lock) rwlock_destroy(lock) +#define RWLOCK_RDLOCK(lock) rw_rdlock(lock) +#define RWLOCK_WRLOCK(lock) rw_wrlock(lock) +#define RWLOCK_UNLOCK(lock) rw_unlock(lock) + +#endif + +/* + * Reader-writer lock + */ +struct PRRWLock { + char *rw_name; /* lock name */ + PRUint32 rw_rank; /* rank of the lock */ + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + RWLOCK_T rw_lock; +#else + PRLock *rw_lock; + PRInt32 rw_lock_cnt; /* == 0, if unlocked */ + /* == -1, if write-locked */ + /* > 0 , # of read locks */ + PRUint32 rw_reader_cnt; /* number of waiting readers */ + PRUint32 rw_writer_cnt; /* number of waiting writers */ + PRCondVar *rw_reader_waitq; /* cvar for readers */ + PRCondVar *rw_writer_waitq; /* cvar for writers */ +#ifdef DEBUG + PRThread *rw_owner; /* lock owner for write-lock */ +#endif +#endif +}; + +#ifdef DEBUG +#define _PR_RWLOCK_RANK_ORDER_DEBUG /* enable deadlock detection using + rank-order for locks + */ +#endif + +#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG + +static PRUintn pr_thread_rwlock_key; /* TPD key for lock stack */ +static PRUintn pr_thread_rwlock_alloc_failed; + +#define _PR_RWLOCK_RANK_ORDER_LIMIT 10 + +typedef struct thread_rwlock_stack { + PRInt32 trs_index; /* top of stack */ + PRRWLock *trs_stack[_PR_RWLOCK_RANK_ORDER_LIMIT]; /* stack of lock + pointers */ + +} thread_rwlock_stack; + +static void _PR_SET_THREAD_RWLOCK_RANK(PRRWLock *rwlock); +static PRUint32 _PR_GET_THREAD_RWLOCK_RANK(void); +static void _PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock); +static void _PR_RELEASE_LOCK_STACK(void *lock_stack); + +#endif + +/* + * Reader/Writer Locks + */ + +/* + * PR_NewRWLock + * Create a reader-writer lock, with the given lock rank and lock name + * + */ + +PR_IMPLEMENT(PRRWLock *) +PR_NewRWLock(PRUint32 lock_rank, const char *lock_name) +{ + PRRWLock *rwlock; +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + int err; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + rwlock = PR_NEWZAP(PRRWLock); + if (rwlock == NULL) + return NULL; + + rwlock->rw_rank = lock_rank; + if (lock_name != NULL) { + rwlock->rw_name = (char*) PR_Malloc(strlen(lock_name) + 1); + if (rwlock->rw_name == NULL) { + PR_DELETE(rwlock); + return(NULL); + } + strcpy(rwlock->rw_name, lock_name); + } else { + rwlock->rw_name = NULL; + } + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + err = RWLOCK_INIT(&rwlock->rw_lock); + if (err != 0) { + PR_SetError(PR_UNKNOWN_ERROR, err); + PR_Free(rwlock->rw_name); + PR_DELETE(rwlock); + return NULL; + } + return rwlock; +#else + rwlock->rw_lock = PR_NewLock(); + if (rwlock->rw_lock == NULL) { + goto failed; + } + rwlock->rw_reader_waitq = PR_NewCondVar(rwlock->rw_lock); + if (rwlock->rw_reader_waitq == NULL) { + goto failed; + } + rwlock->rw_writer_waitq = PR_NewCondVar(rwlock->rw_lock); + if (rwlock->rw_writer_waitq == NULL) { + goto failed; + } + rwlock->rw_reader_cnt = 0; + rwlock->rw_writer_cnt = 0; + rwlock->rw_lock_cnt = 0; + return rwlock; + +failed: + if (rwlock->rw_reader_waitq != NULL) { + PR_DestroyCondVar(rwlock->rw_reader_waitq); + } + if (rwlock->rw_lock != NULL) { + PR_DestroyLock(rwlock->rw_lock); + } + PR_Free(rwlock->rw_name); + PR_DELETE(rwlock); + return NULL; +#endif +} + +/* +** Destroy the given RWLock "lock". +*/ +PR_IMPLEMENT(void) +PR_DestroyRWLock(PRRWLock *rwlock) +{ +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + int err; + err = RWLOCK_DESTROY(&rwlock->rw_lock); + PR_ASSERT(err == 0); +#else + PR_ASSERT(rwlock->rw_reader_cnt == 0); + PR_DestroyCondVar(rwlock->rw_reader_waitq); + PR_DestroyCondVar(rwlock->rw_writer_waitq); + PR_DestroyLock(rwlock->rw_lock); +#endif + if (rwlock->rw_name != NULL) + PR_Free(rwlock->rw_name); + PR_DELETE(rwlock); +} + +/* +** Read-lock the RWLock. +*/ +PR_IMPLEMENT(void) +PR_RWLock_Rlock(PRRWLock *rwlock) +{ +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) +int err; +#endif + +#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG + /* + * assert that rank ordering is not violated; the rank of 'rwlock' should + * be equal to or greater than the highest rank of all the locks held by + * the thread. + */ + PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || + (rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK())); +#endif + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + err = RWLOCK_RDLOCK(&rwlock->rw_lock); + PR_ASSERT(err == 0); +#else + PR_Lock(rwlock->rw_lock); + /* + * wait if write-locked or if a writer is waiting; preference for writers + */ + while ((rwlock->rw_lock_cnt < 0) || + (rwlock->rw_writer_cnt > 0)) { + rwlock->rw_reader_cnt++; + PR_WaitCondVar(rwlock->rw_reader_waitq, PR_INTERVAL_NO_TIMEOUT); + rwlock->rw_reader_cnt--; + } + /* + * Increment read-lock count + */ + rwlock->rw_lock_cnt++; + + PR_Unlock(rwlock->rw_lock); +#endif + +#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG + /* + * update thread's lock rank + */ + if (rwlock->rw_rank != PR_RWLOCK_RANK_NONE) + _PR_SET_THREAD_RWLOCK_RANK(rwlock); +#endif +} + +/* +** Write-lock the RWLock. +*/ +PR_IMPLEMENT(void) +PR_RWLock_Wlock(PRRWLock *rwlock) +{ +#if defined(DEBUG) +PRThread *me = PR_GetCurrentThread(); +#endif +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) +int err; +#endif + +#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG + /* + * assert that rank ordering is not violated; the rank of 'rwlock' should + * be equal to or greater than the highest rank of all the locks held by + * the thread. + */ + PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || + (rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK())); +#endif + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + err = RWLOCK_WRLOCK(&rwlock->rw_lock); + PR_ASSERT(err == 0); +#else + PR_Lock(rwlock->rw_lock); + /* + * wait if read locked + */ + while (rwlock->rw_lock_cnt != 0) { + rwlock->rw_writer_cnt++; + PR_WaitCondVar(rwlock->rw_writer_waitq, PR_INTERVAL_NO_TIMEOUT); + rwlock->rw_writer_cnt--; + } + /* + * apply write lock + */ + rwlock->rw_lock_cnt--; + PR_ASSERT(rwlock->rw_lock_cnt == -1); +#ifdef DEBUG + PR_ASSERT(me != NULL); + rwlock->rw_owner = me; +#endif + PR_Unlock(rwlock->rw_lock); +#endif + +#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG + /* + * update thread's lock rank + */ + if (rwlock->rw_rank != PR_RWLOCK_RANK_NONE) + _PR_SET_THREAD_RWLOCK_RANK(rwlock); +#endif +} + +/* +** Unlock the RW lock. +*/ +PR_IMPLEMENT(void) +PR_RWLock_Unlock(PRRWLock *rwlock) +{ +#if defined(DEBUG) +PRThread *me = PR_GetCurrentThread(); +#endif +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) +int err; +#endif + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + err = RWLOCK_UNLOCK(&rwlock->rw_lock); + PR_ASSERT(err == 0); +#else + PR_Lock(rwlock->rw_lock); + /* + * lock must be read or write-locked + */ + PR_ASSERT(rwlock->rw_lock_cnt != 0); + if (rwlock->rw_lock_cnt > 0) { + + /* + * decrement read-lock count + */ + rwlock->rw_lock_cnt--; + if (rwlock->rw_lock_cnt == 0) { + /* + * lock is not read-locked anymore; wakeup a waiting writer + */ + if (rwlock->rw_writer_cnt > 0) + PR_NotifyCondVar(rwlock->rw_writer_waitq); + } + } else { + PR_ASSERT(rwlock->rw_lock_cnt == -1); + + rwlock->rw_lock_cnt = 0; +#ifdef DEBUG + PR_ASSERT(rwlock->rw_owner == me); + rwlock->rw_owner = NULL; +#endif + /* + * wakeup a writer, if present; preference for writers + */ + if (rwlock->rw_writer_cnt > 0) + PR_NotifyCondVar(rwlock->rw_writer_waitq); + /* + * else, wakeup all readers, if any + */ + else if (rwlock->rw_reader_cnt > 0) + PR_NotifyAllCondVar(rwlock->rw_reader_waitq); + } + PR_Unlock(rwlock->rw_lock); +#endif + +#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG + /* + * update thread's lock rank + */ + if (rwlock->rw_rank != PR_RWLOCK_RANK_NONE) + _PR_UNSET_THREAD_RWLOCK_RANK(rwlock); +#endif + return; +} + +#ifndef _PR_RWLOCK_RANK_ORDER_DEBUG + +void _PR_InitRWLocks(void) { } + +#else + +void _PR_InitRWLocks(void) +{ + /* + * allocated thread-private-data index for rwlock list + */ + if (PR_NewThreadPrivateIndex(&pr_thread_rwlock_key, + _PR_RELEASE_LOCK_STACK) == PR_FAILURE) { + pr_thread_rwlock_alloc_failed = 1; + return; + } +} + +/* + * _PR_SET_THREAD_RWLOCK_RANK + * Set a thread's lock rank, which is the highest of the ranks of all + * the locks held by the thread. Pointers to the locks are added to a + * per-thread list, which is anchored off a thread-private data key. + */ + +static void +_PR_SET_THREAD_RWLOCK_RANK(PRRWLock *rwlock) +{ +thread_rwlock_stack *lock_stack; +PRStatus rv; + + /* + * allocate a lock stack + */ + if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL) { + lock_stack = (thread_rwlock_stack *) + PR_CALLOC(1 * sizeof(thread_rwlock_stack)); + if (lock_stack) { + rv = PR_SetThreadPrivate(pr_thread_rwlock_key, lock_stack); + if (rv == PR_FAILURE) { + PR_DELETE(lock_stack); + pr_thread_rwlock_alloc_failed = 1; + return; + } + } else { + pr_thread_rwlock_alloc_failed = 1; + return; + } + } + /* + * add rwlock to lock stack, if limit is not exceeded + */ + if (lock_stack) { + if (lock_stack->trs_index < _PR_RWLOCK_RANK_ORDER_LIMIT) + lock_stack->trs_stack[lock_stack->trs_index++] = rwlock; + } +} + +static void +_PR_RELEASE_LOCK_STACK(void *lock_stack) +{ + PR_ASSERT(lock_stack); + PR_DELETE(lock_stack); +} + +/* + * _PR_GET_THREAD_RWLOCK_RANK + * + * return thread's lock rank. If thread-private-data for the lock + * stack is not allocated, return PR_RWLOCK_RANK_NONE. + */ + +static PRUint32 +_PR_GET_THREAD_RWLOCK_RANK(void) +{ + thread_rwlock_stack *lock_stack; + + lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key); + if (lock_stack == NULL || lock_stack->trs_index == 0) + return (PR_RWLOCK_RANK_NONE); + else + return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank); +} + +/* + * _PR_UNSET_THREAD_RWLOCK_RANK + * + * remove the rwlock from the lock stack. Since locks may not be + * unlocked in a FIFO order, the entire lock stack is searched. + */ + +static void +_PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock) +{ + thread_rwlock_stack *lock_stack; + int new_index = 0, index, done = 0; + + lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key); + + PR_ASSERT(lock_stack != NULL); + + for (index = lock_stack->trs_index - 1; index >= 0; index--) { + if (!done && (lock_stack->trs_stack[index] == rwlock)) { + /* + * reset the slot for rwlock + */ + lock_stack->trs_stack[index] = NULL; + done = 1; + } + /* + * search for the lowest-numbered empty slot, above which there are + * no non-empty slots + */ + if (!new_index && (lock_stack->trs_stack[index] != NULL)) + new_index = index + 1; + if (done && new_index) + break; + } + /* + * set top of stack to highest numbered empty slot + */ + lock_stack->trs_index = new_index; + +} + +#endif /* _PR_RWLOCK_RANK_ORDER_DEBUG */ diff -Nru nspr-4.9.5/nspr/pr/src/threads/prsem.c nspr-4.10.7/nspr/pr/src/threads/prsem.c --- nspr-4.9.5/nspr/pr/src/threads/prsem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/prsem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "primpl.h" +#include "obsolete/prsem.h" + +/************************************************************************/ + +/* +** Create a new semaphore. +*/ +PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value) +{ + PRSemaphore *sem; + PRCondVar *cvar; + PRLock *lock; + + sem = PR_NEWZAP(PRSemaphore); + if (sem) { +#ifdef HAVE_CVAR_BUILT_ON_SEM + _PR_MD_NEW_SEM(&sem->md, value); +#else + lock = PR_NewLock(); + if (!lock) { + PR_DELETE(sem); + return NULL; + } + + cvar = PR_NewCondVar(lock); + if (!cvar) { + PR_DestroyLock(lock); + PR_DELETE(sem); + return NULL; + } + sem->cvar = cvar; + sem->count = value; +#endif + } + return sem; +} + +/* +** Destroy a semaphore. There must be no thread waiting on the semaphore. +** The caller is responsible for guaranteeing that the semaphore is +** no longer in use. +*/ +PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *sem) +{ +#ifdef HAVE_CVAR_BUILT_ON_SEM + _PR_MD_DESTROY_SEM(&sem->md); +#else + PR_ASSERT(sem->waiters == 0); + + PR_DestroyLock(sem->cvar->lock); + PR_DestroyCondVar(sem->cvar); +#endif + PR_DELETE(sem); +} + +/* +** Wait on a Semaphore. +** +** This routine allows a calling thread to wait or proceed depending upon the +** state of the semahore sem. The thread can proceed only if the counter value +** of the semaphore sem is currently greater than 0. If the value of semaphore +** sem is positive, it is decremented by one and the routine returns immediately +** allowing the calling thread to continue. If the value of semaphore sem is 0, +** the calling thread blocks awaiting the semaphore to be released by another +** thread. +** +** This routine can return PR_PENDING_INTERRUPT if the waiting thread +** has been interrupted. +*/ +PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *sem) +{ + PRStatus status = PR_SUCCESS; + +#ifdef HAVE_CVAR_BUILT_ON_SEM + return _PR_MD_WAIT_SEM(&sem->md); +#else + PR_Lock(sem->cvar->lock); + while (sem->count == 0) { + sem->waiters++; + status = PR_WaitCondVar(sem->cvar, PR_INTERVAL_NO_TIMEOUT); + sem->waiters--; + if (status != PR_SUCCESS) + break; + } + if (status == PR_SUCCESS) + sem->count--; + PR_Unlock(sem->cvar->lock); +#endif + + return (status); +} + +/* +** This routine increments the counter value of the semaphore. If other threads +** are blocked for the semaphore, then the scheduler will determine which ONE +** thread will be unblocked. +*/ +PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *sem) +{ +#ifdef HAVE_CVAR_BUILT_ON_SEM + _PR_MD_POST_SEM(&sem->md); +#else + PR_Lock(sem->cvar->lock); + if (sem->waiters) + PR_NotifyCondVar(sem->cvar); + sem->count++; + PR_Unlock(sem->cvar->lock); +#endif +} + +#if DEBUG +/* +** Returns the value of the semaphore referenced by sem without affecting +** the state of the semaphore. The value represents the semaphore vaule +** at the time of the call, but may not be the actual value when the +** caller inspects it. (FOR DEBUGGING ONLY) +*/ +PR_IMPLEMENT(PRUintn) PR_GetValueSem(PRSemaphore *sem) +{ + PRUintn rv; + +#ifdef HAVE_CVAR_BUILT_ON_SEM + rv = _PR_MD_GET_VALUE_SEM(&sem->md); +#else + PR_Lock(sem->cvar->lock); + rv = sem->count; + PR_Unlock(sem->cvar->lock); +#endif + + return rv; +} +#endif diff -Nru nspr-4.9.5/nspr/pr/src/threads/prtpd.c nspr-4.10.7/nspr/pr/src/threads/prtpd.c --- nspr-4.9.5/nspr/pr/src/threads/prtpd.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/src/threads/prtpd.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,252 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Thread Private Data +** +** There is an aribitrary limit on the number of keys that will be allocated +** by the runtime. It's largish, so it is intended to be a sanity check, not +** an impediment. +** +** There is a counter, initialized to zero and incremented every time a +** client asks for a new key, that holds the high water mark for keys. All +** threads logically have the same high water mark and are permitted to +** ask for TPD up to that key value. +** +** The vector to hold the TPD are allocated when PR_SetThreadPrivate() is +** called. The size of the vector will be some value greater than or equal +** to the current high water mark. Each thread has its own TPD length and +** vector. +** +** Threads that get private data for keys they have not set (or perhaps +** don't even exist for that thread) get a NULL return. If the key is +** beyond the high water mark, an error will be returned. +*/ + +/* +** As of this time, BeOS has its own TPD implementation. Integrating +** this standard one is a TODO for anyone with a bit of spare time on +** their hand. For now, we just #ifdef out this whole file and use +** the routines in pr/src/btthreads/ +*/ + +#ifndef XP_BEOS + +#include "primpl.h" + +#include + +#if defined(WIN95) +/* +** Some local variables report warnings on Win95 because the code paths +** using them are conditioned on HAVE_CUSTOME_USER_THREADS. +** The pragma suppresses the warning. +** +*/ +#pragma warning(disable : 4101) +#endif + +#define _PR_TPD_LIMIT 128 /* arbitary limit on the TPD slots */ +static PRInt32 _pr_tpd_length = 0; /* current length of destructor vector */ +static PRInt32 _pr_tpd_highwater = 0; /* next TPD key to be assigned */ +static PRThreadPrivateDTOR *_pr_tpd_destructors = NULL; + /* the destructors are associated with + the keys, therefore asserting that + the TPD key depicts the data's 'type' */ + +/* +** Initialize the thread private data manipulation +*/ +void _PR_InitTPD(void) +{ + _pr_tpd_destructors = (PRThreadPrivateDTOR*) + PR_CALLOC(_PR_TPD_LIMIT * sizeof(PRThreadPrivateDTOR*)); + PR_ASSERT(NULL != _pr_tpd_destructors); + _pr_tpd_length = _PR_TPD_LIMIT; +} + +/* +** Clean up the thread private data manipulation +*/ +void _PR_CleanupTPD(void) +{ +} /* _PR_CleanupTPD */ + +/* +** This routine returns a new index for per-thread-private data table. +** The index is visible to all threads within a process. This index can +** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines +** to save and retrieve data associated with the index for a thread. +** +** The index independently maintains specific values for each binding thread. +** A thread can only get access to its own thread-specific-data. +** +** Upon a new index return the value associated with the index for all threads +** is NULL, and upon thread creation the value associated with all indices for +** that thread is NULL. +** +** "dtor" is the destructor function to invoke when the private +** data is set or destroyed +** +** Returns PR_FAILURE if the total number of indices will exceed the maximun +** allowed. +*/ + +PR_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndex( + PRUintn *newIndex, PRThreadPrivateDTOR dtor) +{ + PRStatus rv; + PRInt32 index; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + PR_ASSERT(NULL != newIndex); + PR_ASSERT(NULL != _pr_tpd_destructors); + + index = PR_ATOMIC_INCREMENT(&_pr_tpd_highwater) - 1; /* allocate index */ + if (_PR_TPD_LIMIT <= index) + { + PR_SetError(PR_TPD_RANGE_ERROR, 0); + rv = PR_FAILURE; /* that's just wrong */ + } + else + { + _pr_tpd_destructors[index] = dtor; /* record destructor @index */ + *newIndex = (PRUintn)index; /* copy into client's location */ + rv = PR_SUCCESS; /* that's okay */ + } + + return rv; +} + +/* +** Define some per-thread-private data. +** "index" is an index into the per-thread private data table +** "priv" is the per-thread-private data +** +** If the per-thread private data table has a previously registered +** destructor function and a non-NULL per-thread-private data value, +** the destructor function is invoked. +** +** This can return PR_FAILURE if index is invalid (ie., beyond the limit +** on the TPD slots) or memory is insufficient to allocate an expanded +** vector. +*/ + +PR_IMPLEMENT(PRStatus) PR_SetThreadPrivate(PRUintn index, void *priv) +{ + PRThread *self = PR_GetCurrentThread(); + + /* + ** To improve performance, we don't check if the index has been + ** allocated. + */ + if (index >= _PR_TPD_LIMIT) + { + PR_SetError(PR_TPD_RANGE_ERROR, 0); + return PR_FAILURE; + } + + PR_ASSERT(((NULL == self->privateData) && (0 == self->tpdLength)) + || ((NULL != self->privateData) && (0 != self->tpdLength))); + + /* + ** If this thread does not have a sufficient vector for the index + ** being set, go ahead and extend this vector now. + */ + if ((NULL == self->privateData) || (self->tpdLength <= index)) + { + void *extension = PR_CALLOC(_pr_tpd_length * sizeof(void*)); + if (NULL == extension) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return PR_FAILURE; + } + if (self->privateData) { + (void)memcpy( + extension, self->privateData, + self->tpdLength * sizeof(void*)); + PR_DELETE(self->privateData); + } + self->tpdLength = _pr_tpd_length; + self->privateData = (void**)extension; + } + /* + ** There wasn't much chance of having to call the destructor + ** unless the slot already existed. + */ + else if (self->privateData[index] && _pr_tpd_destructors[index]) + { + void *data = self->privateData[index]; + self->privateData[index] = NULL; + (*_pr_tpd_destructors[index])(data); + } + + PR_ASSERT(index < self->tpdLength); + self->privateData[index] = priv; + + return PR_SUCCESS; +} + +/* +** Recover the per-thread-private data for the current thread. "index" is +** the index into the per-thread private data table. +** +** The returned value may be NULL which is indistinguishable from an error +** condition. +** +*/ + +PR_IMPLEMENT(void*) PR_GetThreadPrivate(PRUintn index) +{ + PRThread *self = PR_GetCurrentThread(); + void *tpd = ((NULL == self->privateData) || (index >= self->tpdLength)) ? + NULL : self->privateData[index]; + + return tpd; +} + +/* +** Destroy the thread's private data, if any exists. This is called at +** thread termination time only. There should be no threading issues +** since this is being called by the thread itself. +*/ +void _PR_DestroyThreadPrivate(PRThread* self) +{ +#define _PR_TPD_DESTRUCTOR_ITERATIONS 4 + + if (NULL != self->privateData) /* we have some */ + { + PRBool clean; + PRUint32 index; + PRInt32 passes = _PR_TPD_DESTRUCTOR_ITERATIONS; + PR_ASSERT(0 != self->tpdLength); + do + { + clean = PR_TRUE; + for (index = 0; index < self->tpdLength; ++index) + { + void *priv = self->privateData[index]; /* extract */ + if (NULL != priv) /* we have data at this index */ + { + if (NULL != _pr_tpd_destructors[index]) + { + self->privateData[index] = NULL; /* precondition */ + (*_pr_tpd_destructors[index])(priv); /* destroy */ + clean = PR_FALSE; /* unknown side effects */ + } + } + } + } while ((--passes > 0) && !clean); /* limit # of passes */ + /* + ** We give up after a fixed number of passes. Any non-NULL + ** thread-private data value with a registered destructor + ** function is not destroyed. + */ + memset(self->privateData, 0, self->tpdLength * sizeof(void*)); + } +} /* _PR_DestroyThreadPrivate */ + +#endif /* !XP_BEOS */ diff -Nru nspr-4.9.5/nspr/pr/tests/accept.c nspr-4.10.7/nspr/pr/tests/accept.c --- nspr-4.9.5/nspr/pr/tests/accept.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/accept.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,487 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1996 - Netscape Communications Corporation +** +** Name: accept.c +** +** Description: Run accept() sucessful connection tests. +** +** Modification History: +** 04-Jun-97 AGarcia - Reconvert test file to return a 0 for PASS and a 1 for FAIL +** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** 12-June-97 Revert to return code 0 and 1. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ + +#include "nspr.h" +#include "prpriv.h" + +#include +#include + +#include "plgetopt.h" +#include "plerror.h" + +#define BASE_PORT 10000 + +#define CLIENT_DATA 128 + +#define ACCEPT_NORMAL 0x1 +#define ACCEPT_FAST 0x2 +#define ACCEPT_READ 0x3 +#define ACCEPT_READ_FAST 0x4 +#define ACCEPT_READ_FAST_CB 0x5 + +#define CLIENT_NORMAL 0x1 +#define CLIENT_TIMEOUT_ACCEPT 0x2 +#define CLIENT_TIMEOUT_SEND 0x3 + +#define SERVER_MAX_BIND_COUNT 100 + +#if defined(XP_OS2) || defined(SYMBIAN) +#define TIMEOUTSECS 10 +#else +#define TIMEOUTSECS 2 +#endif +PRIntervalTime timeoutTime; + +static PRInt32 count = 1; +static PRFileDesc *output; +static PRNetAddr serverAddr; +static PRThreadScope thread_scope = PR_LOCAL_THREAD; +static PRInt32 clientCommand; +static PRInt32 iterations; +static PRStatus rv; +static PRFileDesc *listenSock; +static PRFileDesc *clientSock = NULL; +static PRNetAddr listenAddr; +static PRNetAddr clientAddr; +static PRThread *clientThread; +static PRNetAddr *raddr; +static char buf[4096 + 2*sizeof(PRNetAddr) + 32]; +static PRInt32 status; +static PRInt32 bytesRead; + +PRIntn failed_already=0; +PRIntn debug_mode; + +void Test_Assert(const char *msg, const char *file, PRIntn line) +{ + failed_already=1; + if (debug_mode) { + PR_fprintf(output, "@%s:%d ", file, line); + PR_fprintf(output, msg); + } +} /* Test_Assert */ + +#define TEST_ASSERT(expr) \ + if (!(expr)) Test_Assert(#expr, __FILE__, __LINE__) + +#ifdef WINNT +#define CALLBACK_MAGIC 0x12345678 + +void timeout_callback(void *magic) +{ + TEST_ASSERT(magic == (void *)CALLBACK_MAGIC); + if (debug_mode) + PR_fprintf(output, "timeout callback called okay\n"); +} +#endif + + +static void PR_CALLBACK +ClientThread(void *_action) +{ + PRInt32 action = * (PRInt32 *) _action; + PRInt32 iterations = count; + PRFileDesc *sock = NULL; + + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = listenAddr.inet.port; + serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + + for (; iterations--;) { + PRInt32 rv; + char buf[CLIENT_DATA]; + + memset(buf, 0xaf, sizeof(buf)); /* initialize with arbitrary data */ + sock = PR_NewTCPSocket(); + if (!sock) { + if (!debug_mode) + failed_already=1; + else + PR_fprintf(output, "client: unable to create socket\n"); + return; + } + + if (action != CLIENT_TIMEOUT_ACCEPT) { + + if ((rv = PR_Connect(sock, &serverAddr, + timeoutTime)) < 0) { + if (!debug_mode) + failed_already=1; + else + PR_fprintf(output, + "client: unable to connect to server (%ld, %ld, %ld, %ld)\n", + iterations, rv, PR_GetError(), PR_GetOSError()); + goto ErrorExit; + } + + if (action != CLIENT_TIMEOUT_SEND) { + if ((rv = PR_Send(sock, buf, CLIENT_DATA, + 0, timeoutTime))< 0) { + if (!debug_mode) + failed_already=1; + else + PR_fprintf(output, + "client: unable to send to server (%d, %ld, %ld)\n", + CLIENT_DATA, rv, PR_GetError()); + goto ErrorExit; + } + } else { + PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1)); + } + } else { + PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1)); + } + if (debug_mode) + PR_fprintf(output, "."); + PR_Close(sock); + sock = NULL; + } + if (debug_mode) + PR_fprintf(output, "\n"); + +ErrorExit: + if (sock != NULL) + PR_Close(sock); +} + + +static void +RunTest(PRInt32 acceptType, PRInt32 clientAction) +{ +int i; + + /* First bind to the socket */ + listenSock = PR_NewTCPSocket(); + if (!listenSock) { + failed_already=1; + if (debug_mode) + PR_fprintf(output, "unable to create listen socket\n"); + return; + } + memset(&listenAddr, 0 , sizeof(listenAddr)); + listenAddr.inet.family = PR_AF_INET; + listenAddr.inet.port = PR_htons(BASE_PORT); + listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY); + /* + * try a few times to bind server's address, if addresses are in + * use + */ + i = 0; + while (PR_Bind(listenSock, &listenAddr) == PR_FAILURE) { + if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { + listenAddr.inet.port += 2; + if (i++ < SERVER_MAX_BIND_COUNT) + continue; + } + failed_already=1; + if (debug_mode) + PR_fprintf(output,"accept: ERROR - PR_Bind failed\n"); + return; + } + + + rv = PR_Listen(listenSock, 100); + if (rv == PR_FAILURE) { + failed_already=1; + if (debug_mode) + PR_fprintf(output, "unable to listen\n"); + return; + } + + clientCommand = clientAction; + clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread, + (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 0); + if (!clientThread) { + failed_already=1; + if (debug_mode) + PR_fprintf(output, "error creating client thread\n"); + return; + } + + iterations = count; + for (;iterations--;) { + switch (acceptType) { + case ACCEPT_NORMAL: + clientSock = PR_Accept(listenSock, &clientAddr, + timeoutTime); + switch(clientAction) { + case CLIENT_TIMEOUT_ACCEPT: + TEST_ASSERT(clientSock == 0); + TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); + break; + case CLIENT_NORMAL: + TEST_ASSERT(clientSock); + bytesRead = PR_Recv(clientSock, + buf, CLIENT_DATA, 0, timeoutTime); + TEST_ASSERT(bytesRead == CLIENT_DATA); + break; + case CLIENT_TIMEOUT_SEND: + TEST_ASSERT(clientSock); + bytesRead = PR_Recv(clientSock, + buf, CLIENT_DATA, 0, timeoutTime); + TEST_ASSERT(bytesRead == -1); + TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); + break; + } + break; + case ACCEPT_READ: + status = PR_AcceptRead(listenSock, &clientSock, + &raddr, buf, CLIENT_DATA, timeoutTime); + switch(clientAction) { + case CLIENT_TIMEOUT_ACCEPT: + /* Invalid test case */ + TEST_ASSERT(0); + break; + case CLIENT_NORMAL: + TEST_ASSERT(clientSock); + TEST_ASSERT(status == CLIENT_DATA); + break; + case CLIENT_TIMEOUT_SEND: + TEST_ASSERT(status == -1); + TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); + break; + } + break; +#ifdef WINNT + case ACCEPT_FAST: + clientSock = PR_NTFast_Accept(listenSock, + &clientAddr, timeoutTime); + switch(clientAction) { + case CLIENT_TIMEOUT_ACCEPT: + TEST_ASSERT(clientSock == 0); + if (debug_mode) + PR_fprintf(output, "PR_GetError is %ld\n", PR_GetError()); + TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); + break; + case CLIENT_NORMAL: + TEST_ASSERT(clientSock); + bytesRead = PR_Recv(clientSock, + buf, CLIENT_DATA, 0, timeoutTime); + TEST_ASSERT(bytesRead == CLIENT_DATA); + break; + case CLIENT_TIMEOUT_SEND: + TEST_ASSERT(clientSock); + bytesRead = PR_Recv(clientSock, + buf, CLIENT_DATA, 0, timeoutTime); + TEST_ASSERT(bytesRead == -1); + TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); + break; + } + break; + break; + case ACCEPT_READ_FAST: + status = PR_NTFast_AcceptRead(listenSock, + &clientSock, &raddr, buf, 4096, timeoutTime); + switch(clientAction) { + case CLIENT_TIMEOUT_ACCEPT: + /* Invalid test case */ + TEST_ASSERT(0); + break; + case CLIENT_NORMAL: + TEST_ASSERT(clientSock); + TEST_ASSERT(status == CLIENT_DATA); + break; + case CLIENT_TIMEOUT_SEND: + TEST_ASSERT(clientSock == NULL); + TEST_ASSERT(status == -1); + TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); + break; + } + break; + case ACCEPT_READ_FAST_CB: + status = PR_NTFast_AcceptRead_WithTimeoutCallback( + listenSock, &clientSock, &raddr, buf, 4096, + timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC); + switch(clientAction) { + case CLIENT_TIMEOUT_ACCEPT: + /* Invalid test case */ + TEST_ASSERT(0); + break; + case CLIENT_NORMAL: + TEST_ASSERT(clientSock); + TEST_ASSERT(status == CLIENT_DATA); + break; + case CLIENT_TIMEOUT_SEND: + if (debug_mode) + PR_fprintf(output, "clientSock = 0x%8.8lx\n", clientSock); + TEST_ASSERT(clientSock == NULL); + TEST_ASSERT(status == -1); + TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR); + break; + } + break; +#endif + } + if (clientSock != NULL) { + PR_Close(clientSock); + clientSock = NULL; + } + } + PR_Close(listenSock); + + PR_JoinThread(clientThread); +} + + +void AcceptUpdatedTest(void) +{ + RunTest(ACCEPT_NORMAL, CLIENT_NORMAL); +} +void AcceptNotUpdatedTest(void) +{ + RunTest(ACCEPT_FAST, CLIENT_NORMAL); +} +void AcceptReadTest(void) +{ + RunTest(ACCEPT_READ, CLIENT_NORMAL); +} +void AcceptReadNotUpdatedTest(void) +{ + RunTest(ACCEPT_READ_FAST, CLIENT_NORMAL); +} +void AcceptReadCallbackTest(void) +{ + RunTest(ACCEPT_READ_FAST_CB, CLIENT_NORMAL); +} + +void TimeoutAcceptUpdatedTest(void) +{ + RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_ACCEPT); +} +void TimeoutAcceptNotUpdatedTest(void) +{ + RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_ACCEPT); +} +void TimeoutAcceptReadCallbackTest(void) +{ + RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_ACCEPT); +} + +void TimeoutReadUpdatedTest(void) +{ + RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_SEND); +} +void TimeoutReadNotUpdatedTest(void) +{ + RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_SEND); +} +void TimeoutReadReadTest(void) +{ + RunTest(ACCEPT_READ, CLIENT_TIMEOUT_SEND); +} +void TimeoutReadReadNotUpdatedTest(void) +{ + RunTest(ACCEPT_READ_FAST, CLIENT_TIMEOUT_SEND); +} +void TimeoutReadReadCallbackTest(void) +{ + RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_SEND); +} + +/************************************************************************/ + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + if (debug_mode) + PR_fprintf(output, "%40s: %6.2f usec\n", msg, d / count); + +} + +int main(int argc, char **argv) +{ + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name [-d] [-c n] + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "Gdc:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'G': /* global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'c': /* loop counter */ + count = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + output = PR_STDERR; + PR_STDIO_INIT(); + + timeoutTime = PR_SecondsToInterval(TIMEOUTSECS); + if (debug_mode) + PR_fprintf(output, "\nRun accept() sucessful connection tests\n"); + + Measure(AcceptUpdatedTest, "PR_Accept()"); + Measure(AcceptReadTest, "PR_AcceptRead()"); +#ifdef WINNT + Measure(AcceptNotUpdatedTest, "PR_NTFast_Accept()"); + Measure(AcceptReadNotUpdatedTest, "PR_NTFast_AcceptRead()"); + Measure(AcceptReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()"); +#endif + if (debug_mode) + PR_fprintf(output, "\nRun accept() timeout in the accept tests\n"); +#ifdef WINNT + Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()"); +#endif + Measure(TimeoutReadUpdatedTest, "PR_Accept()"); + if (debug_mode) + PR_fprintf(output, "\nRun accept() timeout in the read tests\n"); + Measure(TimeoutReadReadTest, "PR_AcceptRead()"); +#ifdef WINNT + Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()"); + Measure(TimeoutReadReadNotUpdatedTest, "PR_NTFast_AcceptRead()"); + Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()"); +#endif + PR_fprintf(output, "%s\n", (failed_already) ? "FAIL" : "PASS"); + return failed_already; +} diff -Nru nspr-4.9.5/nspr/pr/tests/acceptread.c nspr-4.10.7/nspr/pr/tests/acceptread.c --- nspr-4.9.5/nspr/pr/tests/acceptread.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/acceptread.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,244 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define DEFAULT_PORT 12273 +#define GET "GET / HTTP/1.0\n\n" +static PRFileDesc *std_out, *err_out; +static PRIntervalTime write_dally, accept_timeout; + +static PRStatus PrintAddress(const PRNetAddr* address) +{ + char buffer[100]; + PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); + if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString"); + else PR_fprintf( + std_out, "Accepted connection from (0x%p)%s:%d\n", + address, buffer, address->inet.port); + return rv; +} /* PrintAddress */ + +static void ConnectingThread(void *arg) +{ + PRInt32 nbytes; +#ifdef SYMBIAN + char buf[256]; +#else + char buf[1024]; +#endif + PRFileDesc *sock; + PRNetAddr peer_addr, *addr; + + addr = (PRNetAddr*)arg; + + sock = PR_NewTCPSocket(); + if (sock == NULL) + { + PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed"); + PR_ProcessExit(1); + } + + if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_Connect (client) failed"); + PR_ProcessExit(1); + } + if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_GetPeerName (client) failed"); + PR_ProcessExit(1); + } + + /* + ** Then wait between the connection coming up and sending the expected + ** data. At some point in time, the server should fail due to a timeou + ** on the AcceptRead() operation, which according to the document is + ** only due to the read() portion. + */ + PR_Sleep(write_dally); + + nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT); + if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed"); + + nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); + if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed"); + else + { + PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes); + buf[sizeof(buf) - 1] = '\0'; + PR_fprintf(std_out, "%s\n", buf); + } + + if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH)) + PL_FPrintError(err_out, "PR_Shutdown (client) failed"); + + if (PR_FAILURE == PR_Close(sock)) + PL_FPrintError(err_out, "PR_Close (client) failed"); + + return; +} /* ConnectingThread */ + +#define BUF_SIZE 117 +static void AcceptingThread(void *arg) +{ + PRStatus rv; + PRInt32 bytes; + PRSize buf_size = BUF_SIZE; + PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32]; + PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg; + PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket(); + PRSocketOptionData sock_opt; + + if (NULL == listen_sock) + { + PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed"); + PR_ProcessExit(1); + } + sock_opt.option = PR_SockOpt_Reuseaddr; + sock_opt.value.reuse_addr = PR_TRUE; + rv = PR_SetSocketOption(listen_sock, &sock_opt); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_SetSocketOption (server) failed"); + PR_ProcessExit(1); + } + rv = PR_Bind(listen_sock, listen_addr); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_Bind (server) failed"); + PR_ProcessExit(1); + } + rv = PR_Listen(listen_sock, 10); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_Listen (server) failed"); + PR_ProcessExit(1); + } + bytes = PR_AcceptRead( + listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout); + + if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed"); + else + { + PrintAddress(accept_addr); + PR_fprintf( + std_out, "(Server) read [0x%p..0x%p) %s\n", + buf, &buf[BUF_SIZE], buf); + bytes = PR_Write(accept_sock, buf, bytes); + rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Shutdown (server) failed"); + } + + if (-1 != bytes) + { + rv = PR_Close(accept_sock); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Close (server) failed"); + } + + rv = PR_Close(listen_sock); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Close (server) failed"); +} /* AcceptingThread */ + +int main(int argc, char **argv) +{ + PRHostEnt he; + PRStatus status; + PRIntn next_index; + PRUint16 port_number; + char netdb_buf[PR_NETDB_BUF_SIZE]; + PRNetAddr client_addr, server_addr; + PRThread *client_thread, *server_thread; + PRIntervalTime delta = PR_MillisecondsToInterval(500); + + err_out = PR_STDERR; + std_out = PR_STDOUT; + accept_timeout = PR_SecondsToInterval(2); + + if (argc != 2 && argc != 3) port_number = DEFAULT_PORT; + else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]); + + status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr); + if (PR_SUCCESS != status) + { + PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); + PR_ProcessExit(1); + } + if (argc < 3) + { + status = PR_InitializeNetAddr( + PR_IpAddrLoopback, port_number, &client_addr); + if (PR_SUCCESS != status) + { + PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); + PR_ProcessExit(1); + } + } + else + { + status = PR_GetHostByName( + argv[1], netdb_buf, sizeof(netdb_buf), &he); + if (status == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_GetHostByName failed"); + PR_ProcessExit(1); + } + next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr); + if (next_index == -1) + { + PL_FPrintError(err_out, "PR_EnumerateHostEnt failed"); + PR_ProcessExit(1); + } + } + + for ( + write_dally = 0; + write_dally < accept_timeout + (2 * delta); + write_dally += delta) + { + PR_fprintf( + std_out, "Testing w/ write_dally = %d msec\n", + PR_IntervalToMilliseconds(write_dally)); + server_thread = PR_CreateThread( + PR_USER_THREAD, AcceptingThread, &server_addr, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (server_thread == NULL) + { + PL_FPrintError(err_out, "PR_CreateThread (server) failed"); + PR_ProcessExit(1); + } + + PR_Sleep(delta); /* let the server pot thicken */ + + client_thread = PR_CreateThread( + PR_USER_THREAD, ConnectingThread, &client_addr, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (client_thread == NULL) + { + PL_FPrintError(err_out, "PR_CreateThread (client) failed"); + PR_ProcessExit(1); + } + + if (PR_JoinThread(client_thread) == PR_FAILURE) + PL_FPrintError(err_out, "PR_JoinThread (client) failed"); + + if (PR_JoinThread(server_thread) == PR_FAILURE) + PL_FPrintError(err_out, "PR_JoinThread (server) failed"); + } + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/acceptreademu.c nspr-4.10.7/nspr/pr/tests/acceptreademu.c --- nspr-4.9.5/nspr/pr/tests/acceptreademu.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/acceptreademu.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,274 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This test is the same as acceptread.c except that it uses the + * emulated acceptread method instead of the regular acceptread. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define DEFAULT_PORT 12273 +#define GET "GET / HTTP/1.0\n\n" +static PRFileDesc *std_out, *err_out; +static PRIntervalTime write_dally, accept_timeout; +static PRDescIdentity emu_layer_ident; +static PRIOMethods emu_layer_methods; + +/* the acceptread method in emu_layer_methods */ +static PRInt32 PR_CALLBACK emu_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, + PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout) +{ + return PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout); +} + +static PRStatus PrintAddress(const PRNetAddr* address) +{ + char buffer[100]; + PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); + if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString"); + else PR_fprintf( + std_out, "Accepted connection from (0x%p)%s:%d\n", + address, buffer, address->inet.port); + return rv; +} /* PrintAddress */ + +static void ConnectingThread(void *arg) +{ + PRInt32 nbytes; +#ifdef SYMBIAN + char buf[256]; +#else + char buf[1024]; +#endif + PRFileDesc *sock; + PRNetAddr peer_addr, *addr; + + addr = (PRNetAddr*)arg; + + sock = PR_NewTCPSocket(); + if (sock == NULL) + { + PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed"); + PR_ProcessExit(1); + } + + if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_Connect (client) failed"); + PR_ProcessExit(1); + } + if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_GetPeerName (client) failed"); + PR_ProcessExit(1); + } + + /* + ** Then wait between the connection coming up and sending the expected + ** data. At some point in time, the server should fail due to a timeou + ** on the AcceptRead() operation, which according to the document is + ** only due to the read() portion. + */ + PR_Sleep(write_dally); + + nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT); + if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed"); + + nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); + if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed"); + else + { + PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes); + buf[sizeof(buf) - 1] = '\0'; + PR_fprintf(std_out, "%s\n", buf); + } + + if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH)) + PL_FPrintError(err_out, "PR_Shutdown (client) failed"); + + if (PR_FAILURE == PR_Close(sock)) + PL_FPrintError(err_out, "PR_Close (client) failed"); + + return; +} /* ConnectingThread */ + +#define BUF_SIZE 117 +static void AcceptingThread(void *arg) +{ + PRStatus rv; + PRInt32 bytes; + PRSize buf_size = BUF_SIZE; + PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32]; + PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg; + PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket(); + PRFileDesc *layer; + PRSocketOptionData sock_opt; + + if (NULL == listen_sock) + { + PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed"); + PR_ProcessExit(1); + } + layer = PR_CreateIOLayerStub(emu_layer_ident, &emu_layer_methods); + if (NULL == layer) + { + PL_FPrintError(err_out, "PR_CreateIOLayerStub (server) failed"); + PR_ProcessExit(1); + } + if (PR_PushIOLayer(listen_sock, PR_TOP_IO_LAYER, layer) == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_PushIOLayer (server) failed"); + PR_ProcessExit(1); + } + sock_opt.option = PR_SockOpt_Reuseaddr; + sock_opt.value.reuse_addr = PR_TRUE; + rv = PR_SetSocketOption(listen_sock, &sock_opt); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_SetSocketOption (server) failed"); + PR_ProcessExit(1); + } + rv = PR_Bind(listen_sock, listen_addr); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_Bind (server) failed"); + PR_ProcessExit(1); + } + rv = PR_Listen(listen_sock, 10); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_Listen (server) failed"); + PR_ProcessExit(1); + } + bytes = PR_AcceptRead( + listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout); + + if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed"); + else + { + PrintAddress(accept_addr); + PR_fprintf( + std_out, "(Server) read [0x%p..0x%p) %s\n", + buf, &buf[BUF_SIZE], buf); + bytes = PR_Write(accept_sock, buf, bytes); + rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Shutdown (server) failed"); + } + + if (-1 != bytes) + { + rv = PR_Close(accept_sock); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Close (server) failed"); + } + + rv = PR_Close(listen_sock); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Close (server) failed"); +} /* AcceptingThread */ + +int main(int argc, char **argv) +{ + PRHostEnt he; + PRStatus status; + PRIntn next_index; + PRUint16 port_number; + char netdb_buf[PR_NETDB_BUF_SIZE]; + PRNetAddr client_addr, server_addr; + PRThread *client_thread, *server_thread; + PRIntervalTime delta = PR_MillisecondsToInterval(500); + + err_out = PR_STDERR; + std_out = PR_STDOUT; + accept_timeout = PR_SecondsToInterval(2); + emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead"); + emu_layer_methods = *PR_GetDefaultIOMethods(); + emu_layer_methods.acceptread = emu_AcceptRead; + + if (argc != 2 && argc != 3) port_number = DEFAULT_PORT; + else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]); + + status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr); + if (PR_SUCCESS != status) + { + PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); + PR_ProcessExit(1); + } + if (argc < 3) + { + status = PR_InitializeNetAddr( + PR_IpAddrLoopback, port_number, &client_addr); + if (PR_SUCCESS != status) + { + PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); + PR_ProcessExit(1); + } + } + else + { + status = PR_GetHostByName( + argv[1], netdb_buf, sizeof(netdb_buf), &he); + if (status == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_GetHostByName failed"); + PR_ProcessExit(1); + } + next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr); + if (next_index == -1) + { + PL_FPrintError(err_out, "PR_EnumerateHostEnt failed"); + PR_ProcessExit(1); + } + } + + for ( + write_dally = 0; + write_dally < accept_timeout + (2 * delta); + write_dally += delta) + { + PR_fprintf( + std_out, "Testing w/ write_dally = %d msec\n", + PR_IntervalToMilliseconds(write_dally)); + server_thread = PR_CreateThread( + PR_USER_THREAD, AcceptingThread, &server_addr, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (server_thread == NULL) + { + PL_FPrintError(err_out, "PR_CreateThread (server) failed"); + PR_ProcessExit(1); + } + + PR_Sleep(delta); /* let the server pot thicken */ + + client_thread = PR_CreateThread( + PR_USER_THREAD, ConnectingThread, &client_addr, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (client_thread == NULL) + { + PL_FPrintError(err_out, "PR_CreateThread (client) failed"); + PR_ProcessExit(1); + } + + if (PR_JoinThread(client_thread) == PR_FAILURE) + PL_FPrintError(err_out, "PR_JoinThread (client) failed"); + + if (PR_JoinThread(server_thread) == PR_FAILURE) + PL_FPrintError(err_out, "PR_JoinThread (server) failed"); + } + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/addrstr.c nspr-4.10.7/nspr/pr/tests/addrstr.c --- nspr-4.9.5/nspr/pr/tests/addrstr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/addrstr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prnetdb.h" + +#include +#include +#include + +const char *testaddrs[] = { + "::", "::", + "::1", "::1", + "::ffff", "::ffff", + "::1:0", "::0.1.0.0", + "::127.0.0.1", "::127.0.0.1", + "::FFFF:127.0.0.1", "::ffff:127.0.0.1", + "::FFFE:9504:3501", "::fffe:9504:3501", + "0:0:1:0:35c:0:0:0", "0:0:1:0:35c::", + "0:0:3f4c:0:0:4552:0:0", "::3f4c:0:0:4552:0:0", + "0:0:1245:0:0:0:0567:0", "0:0:1245::567:0", + "0:1:2:3:4:5:6:7", "0:1:2:3:4:5:6:7", + "1:2:3:0:4:5:6:7", "1:2:3:0:4:5:6:7", + "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:0", + "1:2:3:4:5:6:7:8", "1:2:3:4:5:6:7:8", + "1:2:3:4:5:6::7", "1:2:3:4:5:6:0:7", + 0 +}; + +const char *badaddrs[] = { + "::.1.2.3", + "ffff::.1.2.3", + "1:2:3:4:5:6:7::8", + "1:2:3:4:5:6::7:8", + "::ff99.2.3.4", + 0 +}; + +int failed_already = 0; + +int main(int argc, char **argv) +{ + const char **nexttestaddr = testaddrs; + const char **nextbadaddr = badaddrs; + const char *in, *expected_out; + PRNetAddr addr; + char buf[256]; + PRStatus rv; + + while ((in = *nexttestaddr++) != 0) { + expected_out = *nexttestaddr++; + rv = PR_StringToNetAddr(in, &addr); + if (rv) { + printf("cannot convert %s to addr: %d\n", in, rv); + failed_already = 1; + continue; + } + rv = PR_NetAddrToString(&addr, buf, sizeof(buf)); + if (rv) { + printf("cannot convert %s back to string: %d\n", in, rv); + failed_already = 1; + continue; + } + if (strcmp(buf, expected_out)) { + /* This is not necessarily an error */ + printf("%s expected %s got %s\n", in, expected_out, buf); + } + } + while ((in = *nextbadaddr++) != 0) { + if (PR_StringToNetAddr(in, &addr) == PR_SUCCESS) { + printf("converted bad addr %s\n", in); + failed_already = 1; + } + } + if (failed_already) { + printf("FAIL\n"); + return 1; + } + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/affinity.c nspr-4.10.7/nspr/pr/tests/affinity.c --- nspr-4.9.5/nspr/pr/tests/affinity.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/affinity.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "pprthred.h" +#include "plgetopt.h" + +#include +#include +#include + +#ifndef XP_BEOS + +/* + * Test PR_GetThreadAffinityMask + * The function is called by each of local, global and global bound threads + * The test should be run on both single and multi-cpu systems + */ +static void PR_CALLBACK thread_start(void *arg) +{ +PRUint32 mask = 0; + + if (PR_GetThreadAffinityMask(PR_GetCurrentThread(), &mask)) + printf("\tthread_start: PR_GetCurrentThreadAffinityMask failed\n"); + else + printf("\tthread_start: AffinityMask = 0x%x\n",mask); + +} + +int main(int argc, char **argv) +{ + PRThread *t; + + printf("main: creating local thread\n"); + + t = PR_CreateThread(PR_USER_THREAD, + thread_start, 0, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + if (NULL == t) { + printf("main: cannot create local thread\n"); + exit(1); + } + + PR_JoinThread(t); + + printf("main: creating global thread\n"); + t = PR_CreateThread(PR_USER_THREAD, + thread_start, 0, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + if (NULL == t) { + printf("main: cannot create global thread\n"); + exit(1); + } + + PR_JoinThread(t); + + printf("main: creating global bound thread\n"); + t = PR_CreateThread(PR_USER_THREAD, + thread_start, 0, + PR_PRIORITY_NORMAL, + PR_GLOBAL_BOUND_THREAD, + PR_JOINABLE_THREAD, + 0); + + if (NULL == t) { + printf("main: cannot create global bound thread\n"); + exit(1); + } + + PR_JoinThread(t); + + return 0; +} + +#else /* !XP_BEOS */ + +int main() +{ + printf( "This test is not supported on the BeOS\n" ); + return 0; +} +#endif /* !XP_BEOS */ diff -Nru nspr-4.9.5/nspr/pr/tests/alarm.c nspr-4.10.7/nspr/pr/tests/alarm.c --- nspr-4.9.5/nspr/pr/tests/alarm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/alarm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,519 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1996 - Netscape Communications Corporation +** +** Name: alarmtst.c +** +** Description: Test alarms +** +** Modification History: +** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ + +#include "prlog.h" +#include "prinit.h" +#include "obsolete/pralarm.h" +#include "prlock.h" +#include "prlong.h" +#include "prcvar.h" +#include "prinrval.h" +#include "prtime.h" + +/* Used to get the command line option */ +#include "plgetopt.h" +#include +#include + +#if defined(XP_UNIX) +#include +#endif + +static PRIntn debug_mode; +static PRIntn failed_already=0; +static PRThreadScope thread_scope = PR_LOCAL_THREAD; + +typedef struct notifyData { + PRLock *ml; + PRCondVar *child; + PRCondVar *parent; + PRBool pending; + PRUint32 counter; +} NotifyData; + +static void Notifier(void *arg) +{ + NotifyData *notifyData = (NotifyData*)arg; + PR_Lock(notifyData->ml); + while (notifyData->counter > 0) + { + while (!notifyData->pending) + PR_WaitCondVar(notifyData->child, PR_INTERVAL_NO_TIMEOUT); + notifyData->counter -= 1; + notifyData->pending = PR_FALSE; + PR_NotifyCondVar(notifyData->parent); + } + PR_Unlock(notifyData->ml); +} /* Notifier */ +/*********************************************************************** +** PRIVATE FUNCTION: ConditionNotify +** DESCRIPTION: +** +** INPUTS: loops +** OUTPUTS: None +** RETURN: overhead +** SIDE EFFECTS: +** +** RESTRICTIONS: +** None +** MEMORY: NA +** ALGORITHM: +** +***********************************************************************/ + + +static PRIntervalTime ConditionNotify(PRUint32 loops) +{ + PRThread *thread; + NotifyData notifyData; + PRIntervalTime timein, overhead; + + timein = PR_IntervalNow(); + + notifyData.counter = loops; + notifyData.ml = PR_NewLock(); + notifyData.child = PR_NewCondVar(notifyData.ml); + notifyData.parent = PR_NewCondVar(notifyData.ml); + thread = PR_CreateThread( + PR_USER_THREAD, Notifier, ¬ifyData, + PR_GetThreadPriority(PR_GetCurrentThread()), + thread_scope, PR_JOINABLE_THREAD, 0); + + overhead = PR_IntervalNow() - timein; /* elapsed so far */ + + PR_Lock(notifyData.ml); + while (notifyData.counter > 0) + { + notifyData.pending = PR_TRUE; + PR_NotifyCondVar(notifyData.child); + while (notifyData.pending) + PR_WaitCondVar(notifyData.parent, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(notifyData.ml); + + timein = PR_IntervalNow(); + + (void)PR_JoinThread(thread); + PR_DestroyCondVar(notifyData.child); + PR_DestroyCondVar(notifyData.parent); + PR_DestroyLock(notifyData.ml); + + overhead += (PR_IntervalNow() - timein); /* more overhead */ + + return overhead; +} /* ConditionNotify */ + +static PRIntervalTime ConditionTimeout(PRUint32 loops) +{ + PRUintn count; + PRIntervalTime overhead, timein = PR_IntervalNow(); + + PRLock *ml = PR_NewLock(); + PRCondVar *cv = PR_NewCondVar(ml); + PRIntervalTime interval = PR_MillisecondsToInterval(50); + + overhead = PR_IntervalNow() - timein; + + PR_Lock(ml); + for (count = 0; count < loops; ++count) + { + overhead += interval; + PR_ASSERT(PR_WaitCondVar(cv, interval) == PR_SUCCESS); + } + PR_Unlock(ml); + + timein = PR_IntervalNow(); + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); + overhead += (PR_IntervalNow() - timein); + + return overhead; +} /* ConditionTimeout */ + +typedef struct AlarmData { + PRLock *ml; + PRCondVar *cv; + PRUint32 rate, late, times; + PRIntervalTime duration, timein, period; +} AlarmData; + +static PRBool AlarmFn1(PRAlarmID *id, void *clientData, PRUint32 late) +{ + PRStatus rv = PR_SUCCESS; + PRBool keepGoing, resetAlarm; + PRIntervalTime interval, now = PR_IntervalNow(); + AlarmData *ad = (AlarmData*)clientData; + + PR_Lock(ad->ml); + ad->late += late; + ad->times += 1; + keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ? + PR_TRUE : PR_FALSE; + if (!keepGoing) + rv = PR_NotifyCondVar(ad->cv); + resetAlarm = ((ad->times % 31) == 0) ? PR_TRUE : PR_FALSE; + + interval = (ad->period + ad->rate - 1) / ad->rate; + if (!late && (interval > 10)) + { + interval &= (now & 0x03) + 1; + PR_WaitCondVar(ad->cv, interval); + } + + PR_Unlock(ad->ml); + + if (rv != PR_SUCCESS) + { + if (!debug_mode) failed_already=1; + else + printf("AlarmFn: notify status: FAIL\n"); + + } + + if (resetAlarm) + { + ad->rate += 3; + ad->late = ad->times = 0; + if (PR_ResetAlarm(id, ad->period, ad->rate) != PR_SUCCESS) + { + if (!debug_mode) + failed_already=1; + else + printf("AlarmFn: Resetting alarm status: FAIL\n"); + + keepGoing = PR_FALSE; + } + + } + + return keepGoing; +} /* AlarmFn1 */ + +static PRIntervalTime Alarms1(PRUint32 loops) +{ + PRAlarm *alarm; + AlarmData ad; + PRIntervalTime overhead, timein = PR_IntervalNow(); + PRIntervalTime duration = PR_SecondsToInterval(3); + + PRLock *ml = PR_NewLock(); + PRCondVar *cv = PR_NewCondVar(ml); + + ad.ml = ml; + ad.cv = cv; + ad.rate = 1; + ad.times = loops; + ad.late = ad.times = 0; + ad.duration = duration; + ad.timein = PR_IntervalNow(); + ad.period = PR_SecondsToInterval(1); + + alarm = PR_CreateAlarm(); + + (void)PR_SetAlarm( + alarm, ad.period, ad.rate, AlarmFn1, &ad); + + overhead = PR_IntervalNow() - timein; + + PR_Lock(ml); + while ((PRIntervalTime)(PR_IntervalNow() - ad.timein) < duration) + PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(ml); + + timein = PR_IntervalNow(); + (void)PR_DestroyAlarm(alarm); + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); + overhead += (PR_IntervalNow() - timein); + + return duration + overhead; +} /* Alarms1 */ + +static PRBool AlarmFn2(PRAlarmID *id, void *clientData, PRUint32 late) +{ + PRBool keepGoing; + PRStatus rv = PR_SUCCESS; + AlarmData *ad = (AlarmData*)clientData; + PRIntervalTime interval, now = PR_IntervalNow(); + + PR_Lock(ad->ml); + ad->times += 1; + keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ? + PR_TRUE : PR_FALSE; + interval = (ad->period + ad->rate - 1) / ad->rate; + + if (!late && (interval > 10)) + { + interval &= (now & 0x03) + 1; + PR_WaitCondVar(ad->cv, interval); + } + + if (!keepGoing) rv = PR_NotifyCondVar(ad->cv); + + PR_Unlock(ad->ml); + + + if (rv != PR_SUCCESS) + failed_already=1;; + + return keepGoing; +} /* AlarmFn2 */ + +static PRIntervalTime Alarms2(PRUint32 loops) +{ + PRStatus rv; + PRAlarm *alarm; + PRIntervalTime overhead, timein = PR_IntervalNow(); + AlarmData ad; + PRIntervalTime duration = PR_SecondsToInterval(30); + + PRLock *ml = PR_NewLock(); + PRCondVar *cv = PR_NewCondVar(ml); + + ad.ml = ml; + ad.cv = cv; + ad.rate = 1; + ad.times = loops; + ad.late = ad.times = 0; + ad.duration = duration; + ad.timein = PR_IntervalNow(); + ad.period = PR_SecondsToInterval(1); + + alarm = PR_CreateAlarm(); + + (void)PR_SetAlarm( + alarm, ad.period, ad.rate, AlarmFn2, &ad); + + overhead = PR_IntervalNow() - timein; + + PR_Lock(ml); + while ((PRIntervalTime)(PR_IntervalNow() - ad.timein) < duration) + PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(ml); + + timein = PR_IntervalNow(); + + rv = PR_DestroyAlarm(alarm); + if (rv != PR_SUCCESS) + { + if (!debug_mode) + failed_already=1; + else + printf("***Destroying alarm status: FAIL\n"); + } + + + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); + + overhead += (PR_IntervalNow() - timein); + + return duration + overhead; +} /* Alarms2 */ + +static PRIntervalTime Alarms3(PRUint32 loops) +{ + PRIntn i; + PRStatus rv; + PRAlarm *alarm; + AlarmData ad[3]; + PRIntervalTime duration = PR_SecondsToInterval(30); + PRIntervalTime overhead, timein = PR_IntervalNow(); + + PRLock *ml = PR_NewLock(); + PRCondVar *cv = PR_NewCondVar(ml); + + for (i = 0; i < 3; ++i) + { + ad[i].ml = ml; + ad[i].cv = cv; + ad[i].rate = 1; + ad[i].times = loops; + ad[i].duration = duration; + ad[i].late = ad[i].times = 0; + ad[i].timein = PR_IntervalNow(); + ad[i].period = PR_SecondsToInterval(1); + + /* more loops, faster rate => same elapsed time */ + ad[i].times = (i + 1) * loops; + ad[i].rate = (i + 1) * 10; + } + + alarm = PR_CreateAlarm(); + + for (i = 0; i < 3; ++i) + { + (void)PR_SetAlarm( + alarm, ad[i].period, ad[i].rate, + AlarmFn2, &ad[i]); + } + + overhead = PR_IntervalNow() - timein; + + PR_Lock(ml); + for (i = 0; i < 3; ++i) + { + while ((PRIntervalTime)(PR_IntervalNow() - ad[i].timein) < duration) + PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(ml); + + timein = PR_IntervalNow(); + + if (debug_mode) + printf + ("Alarms3 finished at %u, %u, %u\n", + ad[0].timein, ad[1].timein, ad[2].timein); + + rv = PR_DestroyAlarm(alarm); + if (rv != PR_SUCCESS) + { + if (!debug_mode) + failed_already=1; + else + printf("***Destroying alarm status: FAIL\n"); + } + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); + + overhead += (duration / 3); + overhead += (PR_IntervalNow() - timein); + + return overhead; +} /* Alarms3 */ + +static PRUint32 TimeThis( + const char *msg, PRUint32 (*func)(PRUint32 loops), PRUint32 loops) +{ + PRUint32 overhead, usecs; + PRIntervalTime predicted, timein, timeout, ticks; + + if (debug_mode) + printf("Testing %s ...", msg); + + timein = PR_IntervalNow(); + predicted = func(loops); + timeout = PR_IntervalNow(); + + if (debug_mode) + printf(" done\n"); + + ticks = timeout - timein; + usecs = PR_IntervalToMicroseconds(ticks); + overhead = PR_IntervalToMicroseconds(predicted); + + if(ticks < predicted) + { + if (debug_mode) { + printf("\tFinished in negative time\n"); + printf("\tpredicted overhead was %d usecs\n", overhead); + printf("\ttest completed in %d usecs\n\n", usecs); + } + } + else + { + if (debug_mode) + printf( + "\ttotal: %d usecs\n\toverhead: %d usecs\n\tcost: %6.3f usecs\n\n", + usecs, overhead, ((double)(usecs - overhead) / (double)loops)); + } + + return overhead; +} /* TimeThis */ + +int prmain(int argc, char** argv) +{ + PRUint32 cpu, cpus = 0, loops = 0; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name [-d] + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:c:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'G': /* GLOBAL threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'l': /* loop count */ + loops = atoi(opt->value); + break; + case 'c': /* concurrency limit */ + cpus = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + + if (cpus == 0) cpus = 1; + if (loops == 0) loops = 4; + + if (debug_mode) + printf("Alarm: Using %d loops\n", loops); + + if (debug_mode) + printf("Alarm: Using %d cpu(s)\n", cpus); + + for (cpu = 1; cpu <= cpus; ++cpu) + { + if (debug_mode) + printf("\nAlarm: Using %d CPU(s)\n", cpu); + + PR_SetConcurrency(cpu); + + /* some basic time test */ + (void)TimeThis("ConditionNotify", ConditionNotify, loops); + (void)TimeThis("ConditionTimeout", ConditionTimeout, loops); + (void)TimeThis("Alarms1", Alarms1, loops); + (void)TimeThis("Alarms2", Alarms2, loops); + (void)TimeThis("Alarms3", Alarms3, loops); + } + return 0; +} + +int main(int argc, char** argv) +{ + PR_Initialize(prmain, argc, argv, 0); + PR_STDIO_INIT(); + if (failed_already) return 1; + else return 0; + +} /* main */ + + +/* alarmtst.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/anonfm.c nspr-4.10.7/nspr/pr/tests/anonfm.c --- nspr-4.9.5/nspr/pr/tests/anonfm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/anonfm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,311 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: anonfm.c +** Description: Test anonymous file map +** +** Synopsis: anonfm [options] [dirName] +** +** Options: +** -d enable debug mode +** -h display a help message +** -s size of the anonymous memory map, in KBytes. default: 100KBytes. +** -C 1 Operate this process as ClientOne() +** -C 2 Operate this process as ClientTwo() +** +** anonfn.c contains two tests, corresponding to the two protocols for +** passing an anonymous file map to a child process. +** +** ServerOne()/ClientOne() tests the passing of "raw" file map; it uses +** PR_CreateProcess() [for portability of the test case] to create the +** child process, but does not use the PRProcessAttr structure for +** passing the file map data. +** +** ServerTwo()/ClientTwo() tests the passing of the file map using the +** PRProcessAttr structure. +** +*/ +#include +#include +#include +#include +#include +#include + +/* +** Test harness infrastructure +*/ +PRLogModuleInfo *lm; +PRLogModuleLevel msgLevel = PR_LOG_NONE; +PRUint32 failed_already = 0; + +PRIntn debug = 0; +PRIntn client = 0; /* invoke client, style */ +char dirName[512] = "."; /* directory name to contain anon mapped file */ +PRSize fmSize = (100 * 1024 ); +PRUint32 fmMode = 0600; +PRFileMapProtect fmProt = PR_PROT_READWRITE; +const char *fmEnvName = "nsprFileMapEnvVariable"; + +/* +** Emit help text for this test +*/ +static void Help( void ) +{ + printf("anonfm [options] [dirName]\n"); + printf("-d -- enable debug mode\n"); + printf("dirName is alternate directory name. Default: . (current directory)\n"); + exit(1); +} /* end Help() */ + + +/* +** ClientOne() -- +*/ +static void ClientOne( void ) +{ + PRFileMap *fm; + char *fmString; + char *addr; + PRStatus rc; + + PR_LOG(lm, msgLevel, + ("ClientOne() starting")); + + fmString = PR_GetEnv( fmEnvName ); + if ( NULL == fmString ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_Getenv() failed")); + return; + } + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_Getenv(): found: %s", fmString)); + + fm = PR_ImportFileMapFromString( fmString ); + if ( NULL == fm ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_ImportFileMapFromString() failed")); + return; + } + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_ImportFileMapFromString(): fm: %p", fm )); + + addr = PR_MemMap( fm, LL_ZERO, fmSize ); + if ( NULL == addr ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_MemMap() failed, OSError: %d", PR_GetOSError() )); + return; + } + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_MemMap(): addr: %p", addr )); + + /* write to memory map to release server */ + *addr = 1; + + rc = PR_MemUnmap( addr, fmSize ); + PR_ASSERT( rc == PR_SUCCESS ); + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_MemUnap(): success" )); + + rc = PR_CloseFileMap( fm ); + if ( PR_FAILURE == rc ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_MemUnap() failed, OSError: %d", PR_GetOSError() )); + return; + } + PR_LOG(lm, msgLevel, + ("ClientOne(): PR_CloseFileMap(): success" )); + + return; +} /* end ClientOne() */ + +/* +** ClientTwo() -- +*/ +static void ClientTwo( void ) +{ + failed_already = 1; +} /* end ClientTwo() */ + +/* +** ServerOne() -- +*/ +static void ServerOne( void ) +{ + PRFileMap *fm; + PRStatus rc; + PRIntn i; + char *addr; + char fmString[256]; + char envBuf[256]; + char *child_argv[8]; + PRProcess *proc; + PRInt32 exit_status; + + PR_LOG(lm, msgLevel, + ("ServerOne() starting")); + + fm = PR_OpenAnonFileMap( dirName, fmSize, fmProt ); + if ( NULL == fm ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("PR_OpenAnonFileMap() failed")); + return; + } + PR_LOG(lm, msgLevel, + ("ServerOne(): FileMap: %p", fm )); + + rc = PR_ExportFileMapAsString( fm, sizeof(fmString), fmString ); + if ( PR_FAILURE == rc ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("PR_ExportFileMap() failed")); + return; + } + + /* + ** put the string into the environment + */ + PR_snprintf( envBuf, sizeof(envBuf), "%s=%s", fmEnvName, fmString); + putenv( envBuf ); + + addr = PR_MemMap( fm, LL_ZERO, fmSize ); + if ( NULL == addr ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("PR_MemMap() failed")); + return; + } + + /* set initial value for client */ + for (i = 0; i < (PRIntn)fmSize ; i++ ) + *(addr+i) = 0x00; + + PR_LOG(lm, msgLevel, + ("ServerOne(): PR_MemMap(): addr: %p", addr )); + + /* + ** set arguments for child process + */ + child_argv[0] = "anonfm"; + child_argv[1] = "-C"; + child_argv[2] = "1"; + child_argv[3] = NULL; + + proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); + PR_ASSERT( proc ); + PR_LOG(lm, msgLevel, + ("ServerOne(): PR_CreateProcess(): proc: %x", proc )); + + /* + ** ClientOne() will set the memory to 1 + */ + PR_LOG(lm, msgLevel, + ("ServerOne(): waiting on Client, *addr: %x", *addr )); + while( *addr == 0x00 ) { + if ( debug ) + fprintf(stderr, "."); + PR_Sleep(PR_MillisecondsToInterval(300)); + } + if ( debug ) + fprintf(stderr, "\n"); + PR_LOG(lm, msgLevel, + ("ServerOne(): Client responded" )); + + rc = PR_WaitProcess( proc, &exit_status ); + PR_ASSERT( PR_FAILURE != rc ); + + rc = PR_MemUnmap( addr, fmSize); + if ( PR_FAILURE == rc ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("PR_MemUnmap() failed")); + return; + } + PR_LOG(lm, msgLevel, + ("ServerOne(): PR_MemUnmap(): success" )); + + rc = PR_CloseFileMap(fm); + if ( PR_FAILURE == rc ) { + failed_already = 1; + PR_LOG(lm, msgLevel, + ("PR_CloseFileMap() failed")); + return; + } + PR_LOG(lm, msgLevel, + ("ServerOne(): PR_CloseFileMap() success" )); + + return; +} /* end ServerOne() */ + +/* +** ServerTwo() -- +*/ +static void ServerTwo( void ) +{ + PR_LOG(lm, msgLevel, + ("ServerTwo(): Not implemented yet" )); +} /* end ServerTwo() */ + + +int main(int argc, char **argv) +{ + { + /* + ** Get command line options + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "hdC:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'C': /* Client style */ + client = atol(opt->value); + break; + case 's': /* file size */ + fmSize = atol( opt->value ) * 1024; + break; + case 'd': /* debug */ + debug = 1; + msgLevel = PR_LOG_DEBUG; + break; + case 'h': /* help message */ + Help(); + break; + default: + strcpy(dirName, opt->value); + break; + } + } + PL_DestroyOptState(opt); + } + + lm = PR_NewLogModule("Test"); /* Initialize logging */ + + if ( client == 1 ) { + ClientOne(); + } else if ( client == 2 ) { + ClientTwo(); + } else { + ServerOne(); + if ( failed_already ) goto Finished; + ServerTwo(); + } + +Finished: + if ( debug ) + printf("%s\n", (failed_already)? "FAIL" : "PASS"); + return( (failed_already == PR_TRUE )? 1 : 0 ); +} /* main() */ +/* end anonfm.c */ + diff -Nru nspr-4.9.5/nspr/pr/tests/append.c nspr-4.10.7/nspr/pr/tests/append.c --- nspr-4.9.5/nspr/pr/tests/append.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/append.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: append.c +** Description: Testing File writes where PR_APPEND was used on open +** +** append attempts to verify that a file opened with PR_APPEND +** will always append to the end of file, regardless where the +** current file pointer is positioned. To do this, PR_Seek() is +** called before each write with the position set to beginning of +** file. Subsequent writes should always append. +** The file is read back, summing the integer data written to the +** file. If the expected result is equal, the test passes. +** +** See BugSplat: 4090 +*/ +#include "plgetopt.h" +#include "nspr.h" + +#include +#include + +PRIntn debug = 0; +PRIntn verbose = 0; +PRBool failedAlready = PR_FALSE; +const PRInt32 addedBytes = 1000; +const PRInt32 buf = 1; /* constant written to fd, addedBytes times */ +PRInt32 inBuf; /* read it back into here */ + +int main(int argc, char **argv) +{ + PRStatus rc; + PRInt32 rv; + PRFileDesc *fd; + PRIntn i; + PRInt32 sum = 0; + + { /* Get command line options */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "vd"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug */ + debug = 1; + break; + case 'v': /* verbose */ + verbose = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } /* end block "Get command line options" */ +/* ---------------------------------------------------------------------- */ + fd = PR_Open( "/tmp/nsprAppend", (PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE | PR_WRONLY), 0666 ); + if ( NULL == fd ) { + if (debug) printf("PR_Open() failed for writing: %d\n", PR_GetError()); + failedAlready = PR_TRUE; + goto Finished; + } + + for ( i = 0; i < addedBytes ; i++ ) { + rv = PR_Write( fd, &buf, sizeof(buf)); + if ( sizeof(buf) != rv ) { + if (debug) printf("PR_Write() failed: %d\n", PR_GetError()); + failedAlready = PR_TRUE; + goto Finished; + } + rv = PR_Seek( fd, 0 , PR_SEEK_SET ); + if ( -1 == rv ) { + if (debug) printf("PR_Seek() failed: %d\n", PR_GetError()); + failedAlready = PR_TRUE; + goto Finished; + } + } + rc = PR_Close( fd ); + if ( PR_FAILURE == rc ) { + if (debug) printf("PR_Close() failed after writing: %d\n", PR_GetError()); + failedAlready = PR_TRUE; + goto Finished; + } +/* ---------------------------------------------------------------------- */ + fd = PR_Open( "/tmp/nsprAppend", PR_RDONLY, 0 ); + if ( NULL == fd ) { + if (debug) printf("PR_Open() failed for reading: %d\n", PR_GetError()); + failedAlready = PR_TRUE; + goto Finished; + } + + for ( i = 0; i < addedBytes ; i++ ) { + rv = PR_Read( fd, &inBuf, sizeof(inBuf)); + if ( sizeof(inBuf) != rv) { + if (debug) printf("PR_Write() failed: %d\n", PR_GetError()); + failedAlready = PR_TRUE; + goto Finished; + } + sum += inBuf; + } + + rc = PR_Close( fd ); + if ( PR_FAILURE == rc ) { + if (debug) printf("PR_Close() failed after reading: %d\n", PR_GetError()); + failedAlready = PR_TRUE; + goto Finished; + } + if ( sum != addedBytes ) { + if (debug) printf("Uh Oh! addedBytes: %d. Sum: %d\n", addedBytes, sum); + failedAlready = PR_TRUE; + goto Finished; + } + +/* ---------------------------------------------------------------------- */ +Finished: + if (debug || verbose) printf("%s\n", (failedAlready)? "FAILED" : "PASSED" ); + return( (failedAlready)? 1 : 0 ); +} /* main() */ + +/* append.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/atomic.c nspr-4.10.7/nspr/pr/tests/atomic.c --- nspr-4.9.5/nspr/pr/tests/atomic.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/atomic.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prprf.h" +#include "pratom.h" + +/* + * TODO: create a macro to generate the six lines of code that are repeated + * for every test. Also rewrite the statement + * result = result | ((EXPRESSION) ? 0 : 1); + * as + * result |= !(EXPRESSION); + */ + +int main(int argc, char **argv) +{ + PRInt32 rv, oldval, test, result = 0; + PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput); + + /***********************/ + /* Test the functions. */ + /***********************/ + + oldval = test = -2; + rv = PR_AtomicIncrement(&test); + result = result | ((rv == -1) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicIncrement(%d) == %d: %s\n", + oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_AtomicIncrement(&test); + result = result | ((rv == 0) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicIncrement(%d) == %d: %s\n", + oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_AtomicIncrement(&test); + result = result | ((rv == 1) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicIncrement(%d) == %d: %s\n", + oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); + + oldval = test = -2; + rv = PR_AtomicAdd(&test,1); + result = result | ((rv == -1) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicAdd(%d,%d) == %d: %s\n", + oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_AtomicAdd(&test, 4); + result = result | ((rv == 3) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicAdd(%d,%d) == %d: %s\n", + oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_AtomicAdd(&test, -6); + result = result | ((rv == -3) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicAdd(%d,%d) == %d: %s\n", + oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED"); + + oldval = test = 2; + rv = PR_AtomicDecrement(&test); + result = result | ((rv == 1) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicDecrement(%d) == %d: %s\n", + oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_AtomicDecrement(&test); + result = result | ((rv == 0) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicDecrement(%d) == %d: %s\n", + oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_AtomicDecrement(&test); + result = result | ((rv == -1) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicDecrement(%d) == %d: %s\n", + oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); + + /* set to a different value */ + oldval = test = -2; + rv = PR_AtomicSet(&test, 2); + result = result | (((rv == -2) && (test == 2)) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicSet(%d, %d) == %d: %s\n", + oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED"); + + /* set to the same value */ + oldval = test = -2; + rv = PR_AtomicSet(&test, -2); + result = result | (((rv == -2) && (test == -2)) ? 0 : 1); + PR_fprintf( + output, "PR_AtomicSet(%d, %d) == %d: %s\n", + oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED"); + + /***********************/ + /* Test the macros. */ + /***********************/ + + oldval = test = -2; + rv = PR_ATOMIC_INCREMENT(&test); + result = result | ((rv == -1) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", + oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_ATOMIC_INCREMENT(&test); + result = result | ((rv == 0) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", + oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_ATOMIC_INCREMENT(&test); + result = result | ((rv == 1) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", + oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); + + oldval = test = -2; + rv = PR_ATOMIC_ADD(&test,1); + result = result | ((rv == -1) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", + oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_ATOMIC_ADD(&test, 4); + result = result | ((rv == 3) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", + oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_ATOMIC_ADD(&test, -6); + result = result | ((rv == -3) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", + oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED"); + + oldval = test = 2; + rv = PR_ATOMIC_DECREMENT(&test); + result = result | ((rv == 1) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", + oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_ATOMIC_DECREMENT(&test); + result = result | ((rv == 0) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", + oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); + oldval = test; + rv = PR_ATOMIC_DECREMENT(&test); + result = result | ((rv == -1) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", + oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); + + /* set to a different value */ + oldval = test = -2; + rv = PR_ATOMIC_SET(&test, 2); + result = result | (((rv == -2) && (test == 2)) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_SET(%d, %d) == %d: %s\n", + oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED"); + + /* set to the same value */ + oldval = test = -2; + rv = PR_ATOMIC_SET(&test, -2); + result = result | (((rv == -2) && (test == -2)) ? 0 : 1); + PR_fprintf( + output, "PR_ATOMIC_SET(%d, %d) == %d: %s\n", + oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED"); + + PR_fprintf( + output, "Atomic operations test %s\n", + (result == 0) ? "PASSED" : "FAILED"); + return result; +} /* main */ + +/* atomic.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/attach.c nspr-4.10.7/nspr/pr/tests/attach.c --- nspr-4.9.5/nspr/pr/tests/attach.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/attach.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,355 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1996 - Netscape Communications Corporation +** +** Name: attach.c +** +** Description: Platform-specific code to create a native thread. The native thread will +** repeatedly call PR_AttachThread and PR_DetachThread. The +** primordial thread waits for this new thread to finish. +** +** Modification History: +** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** 12-June-97 Revert to return code 0 and 1. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ + +/* Used to get the command line option */ +#include "nspr.h" +#include "pprthred.h" +#include "plgetopt.h" + +#include + +#ifdef WIN32 +#include +#include +#elif defined(_PR_PTHREADS) +#include +#include "md/_pth.h" +#elif defined(IRIX) +#include +#include +#include +#include +#elif defined(SOLARIS) +#include +#elif defined(OS2) +#define INCL_DOS +#define INCL_ERRORS +#include +#include +#elif defined(XP_BEOS) +#include +#endif + +#define DEFAULT_COUNT 1000 +PRIntn failed_already=0; +PRIntn debug_mode; + + +int count; + + +static void +AttachDetach(void) +{ + PRThread *me; + PRInt32 index; + + for (index=0;indexoption) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'c': /* loop count */ + count = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + +#if defined(WIN16) + printf("attach: This test is not valid for Win16\n"); + goto exit_now; +#endif + + if(0 == count) count = DEFAULT_COUNT; + + /* + * To force the implicit initialization of nspr20 + */ + PR_SetError(0, 0); + PR_STDIO_INIT(); + + /* + * Platform-specific code to create a native thread. The native + * thread will repeatedly call PR_AttachThread and PR_DetachThread. + * The primordial thread waits for this new thread to finish. + */ + +#ifdef _PR_PTHREADS + + rv = _PT_PTHREAD_ATTR_INIT(&attr); + if (debug_mode) PR_ASSERT(0 == rv); + else if (0 != rv) { + failed_already=1; + goto exit_now; + } + +#ifndef _PR_DCETHREADS + rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + if (debug_mode) PR_ASSERT(0 == rv); + else if (0 != rv) { + failed_already=1; + goto exit_now; + } +#endif /* !_PR_DCETHREADS */ + rv = _PT_PTHREAD_CREATE(&threadID, attr, threadStartFunc, NULL); + if (rv != 0) { + fprintf(stderr, "thread creation failed: error code %d\n", rv); + failed_already=1; + goto exit_now; + } + else { + if (debug_mode) + printf ("thread creation succeeded \n"); + + } + rv = _PT_PTHREAD_ATTR_DESTROY(&attr); + if (debug_mode) PR_ASSERT(0 == rv); + else if (0 != rv) { + failed_already=1; + goto exit_now; + } + rv = pthread_join(threadID, NULL); + if (debug_mode) PR_ASSERT(0 == rv); + else if (0 != rv) { + failed_already=1; + goto exit_now; + } + +#elif defined(SOLARIS) + + rv = thr_create(NULL, 0, threadStartFunc, NULL, 0, &threadID); + if (rv != 0) { + if(!debug_mode) { + failed_already=1; + goto exit_now; + } else + fprintf(stderr, "thread creation failed: error code %d\n", rv); + } + rv = thr_join(threadID, NULL, NULL); + if (debug_mode) PR_ASSERT(0 == rv); + else if (0 != rv) + { + failed_already=1; + goto exit_now; + } + + +#elif defined(WIN32) + + hThread = (HANDLE) _beginthreadex(NULL, 0, threadStartFunc, NULL, + STACK_SIZE_PARAM_IS_A_RESERVATION, &threadID); + if (hThread == 0) { + fprintf(stderr, "thread creation failed: error code %d\n", + GetLastError()); + failed_already=1; + goto exit_now; + } + rv = WaitForSingleObject(hThread, INFINITE); + if (debug_mode)PR_ASSERT(rv != WAIT_FAILED); + else if (rv == WAIT_FAILED) { + failed_already=1; + goto exit_now; + } + +#elif defined(IRIX) + + threadID = sproc(threadStartFunc, PR_SALL, NULL); + if (threadID == -1) { + + fprintf(stderr, "thread creation failed: error code %d\n", + errno); + failed_already=1; + goto exit_now; + + } + else { + if (debug_mode) + printf ("thread creation succeeded \n"); + sleep(3); + goto exit_now; + } + rv = waitpid(threadID, NULL, 0); + if (debug_mode) PR_ASSERT(rv != -1); + else if (rv != -1) { + failed_already=1; + goto exit_now; + } + +#elif defined(OS2) + + threadID = (TID) _beginthread((void *)threadStartFunc, NULL, + 32768, NULL); + if (threadID == -1) { + fprintf(stderr, "thread creation failed: error code %d\n", errno); + failed_already=1; + goto exit_now; + } + rv = DosWaitThread(&threadID, DCWW_WAIT); + if (debug_mode) { + PR_ASSERT(rv == NO_ERROR); + } else if (rv != NO_ERROR) { + failed_already=1; + goto exit_now; + } + +#elif defined(XP_BEOS) + + threadID = spawn_thread(threadStartFunc, NULL, B_NORMAL_PRIORITY, NULL); + if (threadID <= B_ERROR) { + fprintf(stderr, "thread creation failed: error code %08lx\n", threadID); + failed_already = 1; + goto exit_now; + } + if (resume_thread(threadID) != B_OK) { + fprintf(stderr, "failed starting thread: error code %08lx\n", threadID); + failed_already = 1; + goto exit_now; + } + + waitRV = wait_for_thread(threadID, &threadRV); + if (debug_mode) + PR_ASSERT(waitRV == B_OK); + else if (waitRV != B_OK) { + failed_already = 1; + goto exit_now; + } + +#else + if (!debug_mode) + failed_already=1; + else + printf("The attach test does not apply to this platform because\n" + "either this platform does not have native threads or the\n" + "test needs to be written for this platform.\n"); + goto exit_now; +#endif + +exit_now: + if(failed_already) + return 1; + else + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/bigfile2.c nspr-4.10.7/nspr/pr/tests/bigfile2.c --- nspr-4.9.5/nspr/pr/tests/bigfile2.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/bigfile2.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" + +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#define TEST_FILE_NAME "bigfile2.txt" +#ifdef WINCE +#define TEST_FILE_NAME_FOR_CREATEFILE L"bigfile2.txt" +#else +#define TEST_FILE_NAME_FOR_CREATEFILE TEST_FILE_NAME +#endif + +#define MESSAGE "Hello world!" +#define MESSAGE_SIZE 13 + +int main(int argc, char **argv) +{ + PRFileDesc *fd; + PRInt64 offset, position; + PRInt32 nbytes; + char buf[MESSAGE_SIZE]; +#ifdef _WIN32 + HANDLE hFile; + LARGE_INTEGER li; +#endif /* _WIN32 */ + + LL_I2L(offset, 1); + LL_SHL(offset, offset, 32); + + fd = PR_Open(TEST_FILE_NAME, + PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0666); + if (fd == NULL) { + fprintf(stderr, "PR_Open failed\n"); + exit(1); + } + position = PR_Seek64(fd, offset, PR_SEEK_SET); + if (!LL_GE_ZERO(position)) { + fprintf(stderr, "PR_Seek64 failed\n"); + exit(1); + } + PR_ASSERT(LL_EQ(position, offset)); + strcpy(buf, MESSAGE); + nbytes = PR_Write(fd, buf, sizeof(buf)); + if (nbytes != sizeof(buf)) { + fprintf(stderr, "PR_Write failed\n"); + exit(1); + } + if (PR_Close(fd) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + + memset(buf, 0, sizeof(buf)); + +#ifdef _WIN32 + hFile = CreateFile(TEST_FILE_NAME_FOR_CREATEFILE, GENERIC_READ, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + fprintf(stderr, "CreateFile failed\n"); + exit(1); + } + li.QuadPart = offset; + li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN); + if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) { + fprintf(stderr, "SetFilePointer failed\n"); + exit(1); + } + PR_ASSERT(li.QuadPart == offset); + if (ReadFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) { + fprintf(stderr, "ReadFile failed\n"); + exit(1); + } + PR_ASSERT(nbytes == sizeof(buf)); + if (strcmp(buf, MESSAGE)) { + fprintf(stderr, "corrupt data:$%s$\n", buf); + exit(1); + } + if (CloseHandle(hFile) == 0) { + fprintf(stderr, "CloseHandle failed\n"); + exit(1); + } +#endif /* _WIN32 */ + + if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) { + fprintf(stderr, "PR_Delete failed\n"); + exit(1); + } + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/bigfile3.c nspr-4.10.7/nspr/pr/tests/bigfile3.c --- nspr-4.9.5/nspr/pr/tests/bigfile3.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/bigfile3.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" + +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#define TEST_FILE_NAME "bigfile3.txt" +#ifdef WINCE +#define TEST_FILE_NAME_FOR_CREATEFILE L"bigfile3.txt" +#else +#define TEST_FILE_NAME_FOR_CREATEFILE TEST_FILE_NAME +#endif + +#define MESSAGE "Hello world!" +#define MESSAGE_SIZE 13 + +int main(int argc, char **argv) +{ + PRFileDesc *fd; + PRInt64 offset, position; + PRInt32 nbytes; + char buf[MESSAGE_SIZE]; +#ifdef _WIN32 + HANDLE hFile; + LARGE_INTEGER li; +#endif /* _WIN32 */ + + LL_I2L(offset, 1); + LL_SHL(offset, offset, 32); + +#ifdef _WIN32 + hFile = CreateFile(TEST_FILE_NAME_FOR_CREATEFILE, GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + fprintf(stderr, "CreateFile failed\n"); + exit(1); + } + li.QuadPart = offset; + li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN); + if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) { + fprintf(stderr, "SetFilePointer failed\n"); + exit(1); + } + PR_ASSERT(li.QuadPart == offset); + strcpy(buf, MESSAGE); + if (WriteFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) { + fprintf(stderr, "WriteFile failed\n"); + exit(1); + } + PR_ASSERT(nbytes == sizeof(buf)); + if (CloseHandle(hFile) == 0) { + fprintf(stderr, "CloseHandle failed\n"); + exit(1); + } +#endif /* _WIN32 */ + + memset(buf, 0, sizeof(buf)); + + fd = PR_Open(TEST_FILE_NAME, PR_RDONLY, 0666); + if (fd == NULL) { + fprintf(stderr, "PR_Open failed\n"); + exit(1); + } + position = PR_Seek64(fd, offset, PR_SEEK_SET); + if (!LL_GE_ZERO(position)) { + fprintf(stderr, "PR_Seek64 failed\n"); + exit(1); + } + PR_ASSERT(LL_EQ(position, offset)); + nbytes = PR_Read(fd, buf, sizeof(buf)); + if (nbytes != sizeof(buf)) { + fprintf(stderr, "PR_Read failed\n"); + exit(1); + } + if (strcmp(buf, MESSAGE)) { + fprintf(stderr, "corrupt data:$%s$\n", buf); + exit(1); + } + if (PR_Close(fd) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + + if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) { + fprintf(stderr, "PR_Delete failed\n"); + exit(1); + } + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/bigfile.c nspr-4.10.7/nspr/pr/tests/bigfile.c --- nspr-4.9.5/nspr/pr/tests/bigfile.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/bigfile.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,291 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prmem.h" +#include "prprf.h" +#include "prinit.h" +#include "prerror.h" +#include "prthread.h" + +#include "plerror.h" +#include "plgetopt.h" + +#define DEFAULT_COUNT 10 +#define DEFAULT_FILESIZE 1 +#define BUFFER_SIZE 1000000 + +typedef enum {v_silent, v_whisper, v_shout} Verbosity; +static void Verbose(Verbosity, const char*, const char*, PRIntn); + +#define VERBOSE(_l, _m) Verbose(_l, _m, __FILE__, __LINE__) + +static PRIntn test_result = 2; +static PRFileDesc *output = NULL; +static PRIntn verbose = v_silent; +static PRIntn filesize = DEFAULT_FILESIZE; + +static PRIntn Usage(void) +{ + PR_fprintf(output, "Bigfile test usage:\n"); + PR_fprintf(output, ">bigfile [-G] [-d] [-v[*v]] [-s ] \n"); + PR_fprintf(output, "\td\tdebug mode (equivalent to -vvv)\t(false)\n"); + PR_fprintf(output, "\tv\tAdditional levels of output\t(none)\n"); + PR_fprintf(output, "\tk\tKeep data file after exit\t(false)\n"); + PR_fprintf(output, "\ts \tFile size in megabytes\t\t(1 megabyte)\n"); + PR_fprintf(output, "\t\tName of test file\t(none)\n"); + return 2; /* nothing happened */ +} /* Usage */ + +static PRStatus DeleteIfFound(const char *filename) +{ + PRStatus rv; + VERBOSE(v_shout, "Checking for existing file"); + rv = PR_Access(filename, PR_ACCESS_WRITE_OK); + if (PR_SUCCESS == rv) + { + VERBOSE(v_shout, "Deleting existing file"); + rv = PR_Delete(filename); + if (PR_FAILURE == rv) VERBOSE(v_shout, "Cannot delete big file"); + } + else if (PR_FILE_NOT_FOUND_ERROR != PR_GetError()) + VERBOSE(v_shout, "Cannot access big file"); + else rv = PR_SUCCESS; + return rv; +} /* DeleteIfFound */ + +static PRIntn Error(const char *msg, const char *filename) +{ + PRInt32 error = PR_GetError(); + if (NULL != msg) + { + if (0 == error) PR_fprintf(output, msg); + else PL_FPrintError(output, msg); + } + (void)DeleteIfFound(filename); + if (v_shout == verbose) PR_Abort(); + return 1; +} /* Error */ + +static void Verbose( + Verbosity level, const char *msg, const char *file, PRIntn line) +{ + if (level <= verbose) + PR_fprintf(output, "[%s : %d]: %s\n", file, line, msg); +} /* Verbose */ + +static void PrintInfo(PRFileInfo64 *info, const char *filename) +{ + PRExplodedTime tm; + char ctime[40], mtime[40]; + static const char *types[] = {"FILE", "DIRECTORY", "OTHER"}; + PR_fprintf( + output, "[%s : %d]: File info for %s\n", + __FILE__, __LINE__, filename); + PR_fprintf( + output, " type: %s, size: %llu bytes,\n", + types[info->type - 1], info->size); + + PR_ExplodeTime(info->creationTime, PR_GMTParameters, &tm); + (void)PR_FormatTime(ctime, sizeof(ctime), "%c GMT", &tm); + PR_ExplodeTime(info->modifyTime, PR_GMTParameters, &tm); + (void)PR_FormatTime(mtime, sizeof(mtime), "%c GMT", &tm); + + PR_fprintf( + output, " creation: %s,\n modify: %s\n", ctime, mtime); +} /* PrintInfo */ + +int main(int argc, char **argv) +{ + PRStatus rv; + char *buffer; + PLOptStatus os; + PRInt32 loop, bytes; + PRFileInfo small_info; + PRFileInfo64 big_info; + PRBool keep = PR_FALSE; + PRFileDesc *file = NULL; + const char *filename = NULL; + PRIntn count = DEFAULT_COUNT; + PRInt64 filesize64, big_answer, big_size, one_meg, zero_meg, big_fragment; + PRInt64 sevenFox = LL_INIT(0,0x7fffffff); + + PLOptState *opt = PL_CreateOptState(argc, argv, "dtvhs:"); + + output = PR_GetSpecialFD(PR_StandardError); + PR_STDIO_INIT(); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: + filename = opt->value; + break; + case 'd': /* debug mode */ + verbose = v_shout; + break; + case 'k': /* keep file */ + keep = PR_TRUE; + break; + case 'v': /* verbosity */ + if (v_shout > verbose) verbose += 1; + break; + case 'c': /* loop counter */ + count = atoi(opt->value); + break; + case 's': /* filesize */ + filesize = atoi(opt->value); + break; + case 'h': /* confused */ + default: + return Usage(); + } + } + PL_DestroyOptState(opt); + + if (0 == count) count = DEFAULT_COUNT; + if (0 == filesize) filesize = DEFAULT_FILESIZE; + if (NULL == filename) + { +#ifdef SYMBIAN +#define FILE_NAME "c:\\data\\bigfile.dat" +#else +#define FILE_NAME "bigfile.dat" +#endif + if (DEFAULT_FILESIZE != filesize) return Usage(); + else filename = FILE_NAME; + } + + if (PR_FAILURE == DeleteIfFound(filename)) return 1; + + test_result = 0; + + LL_I2L(zero_meg, 0); + LL_I2L(one_meg, 1000000); + LL_I2L(filesize64, filesize); + buffer = (char*)PR_MALLOC(BUFFER_SIZE); + LL_I2L(big_fragment, BUFFER_SIZE); + LL_MUL(filesize64, filesize64, one_meg); + + for (loop = 0; loop < BUFFER_SIZE; ++loop) buffer[loop] = (char)loop; + + VERBOSE(v_whisper, "Creating big file"); + file = PR_Open(filename, PR_CREATE_FILE | PR_WRONLY, 0666); + if (NULL == file) return Error("PR_Open()", filename); + + VERBOSE(v_whisper, "Testing available space in empty file"); + big_answer = file->methods->available64(file); + if (!LL_IS_ZERO(big_answer)) return Error("empty available64()", filename); + + LL_SUB(big_size, filesize64, one_meg); + VERBOSE(v_whisper, "Creating sparse big file by seeking to end"); + big_answer = file->methods->seek64(file, big_size, PR_SEEK_SET); + if (!LL_EQ(big_answer, big_size)) return Error("seek", filename); + + VERBOSE(v_whisper, "Writing block at end of sparse file"); + bytes = file->methods->write(file, buffer, BUFFER_SIZE); + if (bytes != BUFFER_SIZE) return Error("write", filename); + + VERBOSE(v_whisper, "Testing available space at end of sparse file"); + big_answer = file->methods->available64(file); + if (!LL_IS_ZERO(big_answer)) return Error("eof available64()", filename); + + VERBOSE(v_whisper, "Getting big info on sparse big file"); + rv = file->methods->fileInfo64(file, &big_info); + if (PR_FAILURE == rv) return Error("fileInfo64()", filename); + if (v_shout <= verbose) PrintInfo(&big_info, filename); + + VERBOSE(v_whisper, "Getting small info on sparse big file"); + rv = file->methods->fileInfo(file, &small_info); + if (LL_CMP(sevenFox, <, filesize64) && (PR_SUCCESS == rv)) + { + VERBOSE(v_whisper, "Should have failed and didn't"); + return Error("fileInfo()", filename); + } + else if (LL_CMP(sevenFox, >, filesize64) && (PR_FAILURE == rv)) + { + VERBOSE(v_whisper, "Should have succeeded and didn't"); + return Error("fileInfo()", filename); + } + + VERBOSE(v_whisper, "Rewinding big file"); + big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_SET); + if (!LL_IS_ZERO(big_answer)) return Error("rewind seek64()", filename); + + VERBOSE(v_whisper, "Establishing available space in rewound file"); + big_answer = file->methods->available64(file); + if (LL_NE(filesize64, big_answer)) + return Error("bof available64()", filename); + + VERBOSE(v_whisper, "Closing big file"); + rv = file->methods->close(file); + if (PR_FAILURE == rv) return Error("close()", filename); + + VERBOSE(v_whisper, "Reopening big file"); + file = PR_Open(filename, PR_RDWR, 0666); + if (NULL == file) return Error("open failed", filename); + + VERBOSE(v_whisper, "Checking available data in reopened file"); + big_answer = file->methods->available64(file); + if (LL_NE(filesize64, big_answer)) + return Error("reopened available64()", filename); + + big_answer = zero_meg; + VERBOSE(v_whisper, "Rewriting every byte of big file data"); + do + { + bytes = file->methods->write(file, buffer, BUFFER_SIZE); + if (bytes != BUFFER_SIZE) + return Error("write", filename); + LL_ADD(big_answer, big_answer, big_fragment); + } while (LL_CMP(big_answer, <, filesize64)); + + VERBOSE(v_whisper, "Checking position at eof"); + big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_CUR); + if (LL_NE(big_answer, filesize64)) + return Error("file size error", filename); + + VERBOSE(v_whisper, "Testing available space at eof"); + big_answer = file->methods->available64(file); + if (!LL_IS_ZERO(big_answer)) + return Error("eof available64()", filename); + + VERBOSE(v_whisper, "Rewinding full file"); + big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_SET); + if (!LL_IS_ZERO(big_answer)) return Error("bof seek64()", filename); + + VERBOSE(v_whisper, "Testing available space in rewound file"); + big_answer = file->methods->available64(file); + if (LL_NE(big_answer, filesize64)) return Error("bof available64()", filename); + + VERBOSE(v_whisper, "Seeking to end of big file"); + big_answer = file->methods->seek64(file, filesize64, PR_SEEK_SET); + if (LL_NE(big_answer, filesize64)) return Error("eof seek64()", filename); + + VERBOSE(v_whisper, "Getting info on big file while it's open"); + rv = file->methods->fileInfo64(file, &big_info); + if (PR_FAILURE == rv) return Error("fileInfo64()", filename); + if (v_shout <= verbose) PrintInfo(&big_info, filename); + + VERBOSE(v_whisper, "Closing big file"); + rv = file->methods->close(file); + if (PR_FAILURE == rv) return Error("close()", filename); + + VERBOSE(v_whisper, "Getting info on big file after it's closed"); + rv = PR_GetFileInfo64(filename, &big_info); + if (PR_FAILURE == rv) return Error("fileInfo64()", filename); + if (v_shout <= verbose) PrintInfo(&big_info, filename); + + VERBOSE(v_whisper, "Deleting big file"); + rv = PR_Delete(filename); + if (PR_FAILURE == rv) return Error("PR_Delete()", filename); + + PR_DELETE(buffer); + return test_result; +} /* main */ + +/* bigfile.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/bug1test.c nspr-4.10.7/nspr/pr/tests/bug1test.c --- nspr-4.9.5/nspr/pr/tests/bug1test.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/bug1test.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,225 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +Attached is a test program that uses the nspr1 to demonstrate a bug +under NT4.0. The fix has already been mentioned (add a ResetEvent just +before leaving the critical section in _PR_CondWait in hwmon.c). +*/ + +#include "prthread.h" +#include "prtypes.h" +#include "prinit.h" +#include "prmon.h" +#include "prlog.h" + +typedef struct Arg_s +{ + PRInt32 a, b; +} Arg_t; + +PRMonitor* gMonitor; // the monitor +PRInt32 gReading; // number of read locks +PRInt32 gWriteWaiting; // number of threads waiting for write lock +PRInt32 gReadWaiting; // number of threads waiting for read lock + +PRInt32 gCounter; // a counter + + // stats +PRInt32 gReads; // number of successful reads +PRInt32 gMaxReads; // max number of simultaneous reads +PRInt32 gMaxWriteWaits; // max number of writes that waited for read +PRInt32 gMaxReadWaits; // max number of reads that waited for write wait + + +void spin (PRInt32 aDelay) +{ + PRInt32 index; + PRInt32 delay = aDelay * 1000; + + PR_Sleep(0); + + // randomize delay a bit + delay = (delay / 2) + (PRInt32)((float)delay * + ((float)rand () / (float)RAND_MAX)); + + for (index = 0; index < delay * 10; index++) + // consume a bunch of cpu cycles + ; + PR_Sleep(0); +} + +void doWriteThread (void* arg) +{ + PRInt32 last; + Arg_t *args = (Arg_t*)arg; + PRInt32 aWorkDelay = args->a, aWaitDelay = args->b; + PR_Sleep(0); + + while (1) + { + // -- enter write lock + PR_EnterMonitor (gMonitor); + + if (0 < gReading) // wait for read locks to go away + { + PRIntervalTime fiveSecs = PR_SecondsToInterval(5); + + gWriteWaiting++; + if (gWriteWaiting > gMaxWriteWaits) // stats + gMaxWriteWaits = gWriteWaiting; + while (0 < gReading) + PR_Wait (gMonitor, fiveSecs); + gWriteWaiting--; + } + // -- write lock entered + + last = gCounter; + gCounter++; + + spin (aWorkDelay); + + PR_ASSERT (gCounter == (last + 1)); // test invariance + + // -- exit write lock +// if (0 < gReadWaiting) // notify waiting reads (do it anyway to show off the CondWait bug) + PR_NotifyAll (gMonitor); + + PR_ExitMonitor (gMonitor); + // -- write lock exited + + spin (aWaitDelay); + } +} + +void doReadThread (void* arg) +{ + PRInt32 last; + Arg_t *args = (Arg_t*)arg; + PRInt32 aWorkDelay = args->a, aWaitDelay = args->b; + PR_Sleep(0); + + while (1) + { + // -- enter read lock + PR_EnterMonitor (gMonitor); + + if (0 < gWriteWaiting) // give up the monitor to waiting writes + { + PRIntervalTime fiveSecs = PR_SecondsToInterval(5); + + gReadWaiting++; + if (gReadWaiting > gMaxReadWaits) // stats + gMaxReadWaits = gReadWaiting; + while (0 < gWriteWaiting) + PR_Wait (gMonitor, fiveSecs); + gReadWaiting--; + } + + gReading++; + + gReads++; // stats + if (gReading > gMaxReads) // stats + gMaxReads = gReading; + + PR_ExitMonitor (gMonitor); + // -- read lock entered + + last = gCounter; + + spin (aWorkDelay); + + PR_ASSERT (gCounter == last); // test invariance + + // -- exit read lock + PR_EnterMonitor (gMonitor); // read unlock + gReading--; + +// if ((0 == gReading) && (0 < gWriteWaiting)) // notify waiting writes (do it anyway to show off the CondWait bug) + PR_NotifyAll (gMonitor); + PR_ExitMonitor (gMonitor); + // -- read lock exited + + spin (aWaitDelay); + } +} + + +void fireThread ( + char* aName, void (*aProc)(void *arg), Arg_t *aArg) +{ + PRThread *thread = PR_CreateThread( + PR_USER_THREAD, aProc, aArg, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); +} + +int pseudoMain (int argc, char** argv, char *pad) +{ + PRInt32 lastWriteCount = gCounter; + PRInt32 lastReadCount = gReads; + Arg_t a1 = {500, 250}; + Arg_t a2 = {500, 500}; + Arg_t a3 = {250, 500}; + Arg_t a4 = {750, 250}; + Arg_t a5 = {100, 750}; + Arg_t a6 = {100, 500}; + Arg_t a7 = {100, 750}; + + gMonitor = PR_NewMonitor (); + + fireThread ("R1", doReadThread, &a1); + fireThread ("R2", doReadThread, &a2); + fireThread ("R3", doReadThread, &a3); + fireThread ("R4", doReadThread, &a4); + + fireThread ("W1", doWriteThread, &a5); + fireThread ("W2", doWriteThread, &a6); + fireThread ("W3", doWriteThread, &a7); + + fireThread ("R5", doReadThread, &a1); + fireThread ("R6", doReadThread, &a2); + fireThread ("R7", doReadThread, &a3); + fireThread ("R8", doReadThread, &a4); + + fireThread ("W4", doWriteThread, &a5); + fireThread ("W5", doWriteThread, &a6); + fireThread ("W6", doWriteThread, &a7); + + while (1) + { + PRInt32 writeCount, readCount; + PRIntervalTime fiveSecs = PR_SecondsToInterval(5); + PR_Sleep (fiveSecs); // get out of the way + + // print some stats, not threadsafe, informative only + writeCount = gCounter; + readCount = gReads; + printf ("\ntick %d writes (+%d), %d reads (+%d) [max %d, %d, %d]", + writeCount, writeCount - lastWriteCount, + readCount, readCount - lastReadCount, + gMaxReads, gMaxWriteWaits, gMaxReadWaits); + lastWriteCount = writeCount; + lastReadCount = readCount; + gMaxReads = gMaxWriteWaits = gMaxReadWaits = 0; + } + return 0; +} + + +static void padStack (int argc, char** argv) +{ + char pad[512]; /* Work around bug in nspr on windoze */ + pseudoMain (argc, argv, pad); +} + +int main(int argc, char **argv) +{ + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + padStack (argc, argv); +} + + +/* bug1test.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/cleanup.c nspr-4.10.7/nspr/pr/tests/cleanup.c --- nspr-4.9.5/nspr/pr/tests/cleanup.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/cleanup.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prprf.h" +#include "prio.h" +#include "prinit.h" +#include "prthread.h" +#include "prinrval.h" + +#include "plgetopt.h" + +#include + +static void PR_CALLBACK Thread(void *sleep) +{ + PR_Sleep(PR_SecondsToInterval((PRUint32)sleep)); + printf("Thread exiting\n"); +} + +static void Help(void) +{ + PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); + PR_fprintf(err, "Cleanup usage: [-g] [-s n] [-t n] [-c n] [-h]\n"); + PR_fprintf(err, "\t-c Call cleanup before exiting (default: false)\n"); + PR_fprintf(err, "\t-G Use global threads only (default: local)\n"); + PR_fprintf(err, "\t-t n Number of threads involved (default: 1)\n"); + PR_fprintf(err, "\t-s n Seconds thread(s) should dally (defaut: 10)\n"); + PR_fprintf(err, "\t-S n Seconds main() should dally (defaut: 5)\n"); + PR_fprintf(err, "\t-C n Value to set concurrency (default 1)\n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + PRBool cleanup = PR_FALSE; + PRThreadScope type = PR_LOCAL_THREAD; + PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); + PLOptState *opt = PL_CreateOptState(argc, argv, "Ghs:S:t:cC:"); + PRIntn concurrency = 1, child_sleep = 10, main_sleep = 5, threads = 1; + + PR_STDIO_INIT(); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'c': /* call PR_Cleanup() before exiting */ + cleanup = PR_TRUE; + break; + case 'G': /* local vs global threads */ + type = PR_GLOBAL_THREAD; + break; + case 's': /* time to sleep */ + child_sleep = atoi(opt->value); + break; + case 'S': /* time to sleep */ + main_sleep = atoi(opt->value); + break; + case 'C': /* number of cpus to create */ + concurrency = atoi(opt->value); + break; + case 't': /* number of threads to create */ + threads = atoi(opt->value); + break; + case 'h': /* user wants some guidance */ + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_fprintf(err, "Cleanup settings\n"); + PR_fprintf(err, "\tThread type: %s\n", + (PR_LOCAL_THREAD == type) ? "LOCAL" : "GLOBAL"); + PR_fprintf(err, "\tConcurrency: %d\n", concurrency); + PR_fprintf(err, "\tNumber of threads: %d\n", threads); + PR_fprintf(err, "\tThread sleep: %d\n", child_sleep); + PR_fprintf(err, "\tMain sleep: %d\n", main_sleep); + PR_fprintf(err, "\tCleanup will %sbe called\n\n", (cleanup) ? "" : "NOT "); + + PR_SetConcurrency(concurrency); + + while (threads-- > 0) + (void)PR_CreateThread( + PR_USER_THREAD, Thread, (void*)child_sleep, PR_PRIORITY_NORMAL, + type, PR_UNJOINABLE_THREAD, 0); + PR_Sleep(PR_SecondsToInterval(main_sleep)); + + if (cleanup) PR_Cleanup(); + + PR_fprintf(err, "main() exiting\n"); + return 0; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/cltsrv.c nspr-4.10.7/nspr/pr/tests/cltsrv.c --- nspr-4.9.5/nspr/pr/tests/cltsrv.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/cltsrv.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1182 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Notes: + * [1] lth. The call to Sleep() is a hack to get the test case to run + * on Windows 95. Without it, the test case fails with an error + * WSAECONNRESET following a recv() call. The error is caused by the + * server side thread termination without a shutdown() or closesocket() + * call. Windows docmunentation suggests that this is predicted + * behavior; that other platforms get away with it is ... serindipity. + * The test case should shutdown() or closesocket() before + * thread termination. I didn't have time to figure out where or how + * to do it. The Sleep() call inserts enough delay to allow the + * client side to recv() all his data before the server side thread + * terminates. Whew! ... + * + ** Modification History: + * 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. + * The debug mode will print all of the printfs associated with this test. + * The regress mode will be the default mode. Since the regress tool limits + * the output to a one line status:PASS or FAIL,all of the printf statements + * have been handled with an if (debug_mode) statement. + */ + +#include "prclist.h" +#include "prcvar.h" +#include "prerror.h" +#include "prinit.h" +#include "prinrval.h" +#include "prio.h" +#include "prlock.h" +#include "prlog.h" +#include "prtime.h" +#include "prmem.h" +#include "prnetdb.h" +#include "prprf.h" +#include "prthread.h" + +#include "pprio.h" +#include "primpl.h" + +#include "plstr.h" +#include "plerror.h" +#include "plgetopt.h" + +#include +#include + +#if defined(XP_UNIX) +#include +#endif + +/* +** This is the beginning of the test +*/ + +#define RECV_FLAGS 0 +#define SEND_FLAGS 0 +#define DEFAULT_LOW 0 +#define DEFAULT_HIGH 0 +#define BUFFER_SIZE 1024 +#define DEFAULT_BACKLOG 5 +#define DEFAULT_PORT 12849 +#define DEFAULT_CLIENTS 1 +#define ALLOWED_IN_ACCEPT 1 +#define DEFAULT_CLIPPING 1000 +#define DEFAULT_WORKERS_MIN 1 +#define DEFAULT_WORKERS_MAX 1 +#define DEFAULT_SERVER "localhost" +#define DEFAULT_EXECUTION_TIME 10 +#define DEFAULT_CLIENT_TIMEOUT 4000 +#define DEFAULT_SERVER_TIMEOUT 4000 +#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGH + +typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t; + +static void PR_CALLBACK Worker(void *arg); +typedef struct CSPool_s CSPool_t; +typedef struct CSWorker_s CSWorker_t; +typedef struct CSServer_s CSServer_t; +typedef enum Verbosity +{ + TEST_LOG_ALWAYS, + TEST_LOG_ERROR, + TEST_LOG_WARNING, + TEST_LOG_NOTICE, + TEST_LOG_INFO, + TEST_LOG_STATUS, + TEST_LOG_VERBOSE +} Verbosity; + +static PRInt32 domain = AF_INET; +static PRInt32 protocol = 6; /* TCP */ +static PRFileDesc *debug_out = NULL; +static PRBool debug_mode = PR_FALSE; +static PRBool pthread_stats = PR_FALSE; +static Verbosity verbosity = TEST_LOG_ALWAYS; +static PRThreadScope thread_scope = PR_LOCAL_THREAD; + +struct CSWorker_s +{ + PRCList element; /* list of the server's workers */ + + PRThread *thread; /* this worker objects thread */ + CSServer_t *server; /* back pointer to server structure */ +}; + +struct CSPool_s +{ + PRCondVar *exiting; + PRCondVar *acceptComplete; + PRUint32 accepting, active, workers; +}; + +struct CSServer_s +{ + PRCList list; /* head of worker list */ + + PRLock *ml; + PRThread *thread; /* the main server thread */ + PRCondVar *stateChange; + + PRUint16 port; /* port we're listening on */ + PRUint32 backlog; /* size of our listener backlog */ + PRFileDesc *listener; /* the fd accepting connections */ + + CSPool_t pool; /* statistics on worker threads */ + CSState_t state; /* the server's state */ + struct /* controlling worker counts */ + { + PRUint32 minimum, maximum, accepting; + } workers; + + /* statistics */ + PRIntervalTime started, stopped; + PRUint32 operations, bytesTransferred; +}; + +typedef struct CSDescriptor_s +{ + PRInt32 size; /* size of transfer */ + char filename[60]; /* filename, null padded */ +} CSDescriptor_t; + +typedef struct CSClient_s +{ + PRLock *ml; + PRThread *thread; + PRCondVar *stateChange; + PRNetAddr serverAddress; + + CSState_t state; + + /* statistics */ + PRIntervalTime started, stopped; + PRUint32 operations, bytesTransferred; +} CSClient_t; + +#define TEST_LOG(l, p, a) \ + do { \ + if (debug_mode || (p <= verbosity)) printf a; \ + } while (0) + +PRLogModuleInfo *cltsrv_log_file = NULL; + +#define MY_ASSERT(_expr) \ + ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__)) + +#define TEST_ASSERT(_expr) \ + ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__)) + +static void _MY_Assert(const char *s, const char *file, PRIntn ln) +{ + PL_PrintError(NULL); + PR_Assert(s, file, ln); +} /* _MY_Assert */ + +static PRBool Aborted(PRStatus rv) +{ + return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ? + PR_TRUE : PR_FALSE; +} + +static void TimeOfDayMessage(const char *msg, PRThread* me) +{ + char buffer[100]; + PRExplodedTime tod; + PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod); + (void)PR_FormatTime(buffer, sizeof(buffer), "%H:%M:%S", &tod); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("%s(0x%p): %s\n", msg, me, buffer)); +} /* TimeOfDayMessage */ + + +static void PR_CALLBACK Client(void *arg) +{ + PRStatus rv; + PRIntn index; + char buffer[1024]; + PRFileDesc *fd = NULL; + PRUintn clipping = DEFAULT_CLIPPING; + PRThread *me = PR_GetCurrentThread(); + CSClient_t *client = (CSClient_t*)arg; + CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); + PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT); + + + for (index = 0; index < sizeof(buffer); ++index) + buffer[index] = (char)index; + + client->started = PR_IntervalNow(); + + PR_Lock(client->ml); + client->state = cs_run; + PR_NotifyCondVar(client->stateChange); + PR_Unlock(client->ml); + + TimeOfDayMessage("Client started at", me); + + while (cs_run == client->state) + { + PRInt32 bytes, descbytes, filebytes, netbytes; + + (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer)); + TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, + ("\tClient(0x%p): connecting to server at %s\n", me, buffer)); + + fd = PR_Socket(domain, SOCK_STREAM, protocol); + TEST_ASSERT(NULL != fd); + rv = PR_Connect(fd, &client->serverAddress, timeout); + if (PR_FAILURE == rv) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): conection failed (%d, %d)\n", + me, PR_GetError(), PR_GetOSError())); + goto aborted; + } + + memset(descriptor, 0, sizeof(*descriptor)); + descriptor->size = PR_htonl(descbytes = rand() % clipping); + PR_snprintf( + descriptor->filename, sizeof(descriptor->filename), + "CS%p%p-%p.dat", client->started, me, client->operations); + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes)); + bytes = PR_Send( + fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout); + if (sizeof(CSDescriptor_t) != bytes) + { + if (Aborted(PR_FAILURE)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): send descriptor timeout\n", me)); + goto retry; + } + } + TEST_ASSERT(sizeof(*descriptor) == bytes); + + netbytes = 0; + while (netbytes < descbytes) + { + filebytes = sizeof(buffer); + if ((descbytes - netbytes) < filebytes) + filebytes = descbytes - netbytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tClient(0x%p): sending %d bytes\n", me, filebytes)); + bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); + if (filebytes != bytes) + { + if (Aborted(PR_FAILURE)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): send data timeout\n", me)); + goto retry; + } + } + TEST_ASSERT(bytes == filebytes); + netbytes += bytes; + } + filebytes = 0; + while (filebytes < descbytes) + { + netbytes = sizeof(buffer); + if ((descbytes - filebytes) < netbytes) + netbytes = descbytes - filebytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tClient(0x%p): receiving %d bytes\n", me, netbytes)); + bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); + if (-1 == bytes) + { + if (Aborted(PR_FAILURE)) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): receive data aborted\n", me)); + goto aborted; + } + else if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): receive data timeout\n", me)); + else + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): receive error (%d, %d)\n", + me, PR_GetError(), PR_GetOSError())); + goto retry; + } + if (0 == bytes) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tClient(0x%p): unexpected end of stream\n", + PR_GetCurrentThread())); + break; + } + filebytes += bytes; + } + + rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); + if (Aborted(rv)) goto aborted; + TEST_ASSERT(PR_SUCCESS == rv); +retry: + (void)PR_Close(fd); fd = NULL; + TEST_LOG( + cltsrv_log_file, TEST_LOG_INFO, + ("\tClient(0x%p): disconnected from server\n", me)); + + PR_Lock(client->ml); + client->operations += 1; + client->bytesTransferred += 2 * descbytes; + rv = PR_WaitCondVar(client->stateChange, rand() % clipping); + PR_Unlock(client->ml); + if (Aborted(rv)) break; + } + +aborted: + client->stopped = PR_IntervalNow(); + + PR_ClearInterrupt(); + if (NULL != fd) rv = PR_Close(fd); + + PR_Lock(client->ml); + client->state = cs_exit; + PR_NotifyCondVar(client->stateChange); + PR_Unlock(client->ml); + PR_DELETE(descriptor); + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("\tClient(0x%p): stopped after %u operations and %u bytes\n", + PR_GetCurrentThread(), client->operations, client->bytesTransferred)); + +} /* Client */ + +static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server) +{ + PRStatus drv, rv; + char buffer[1024]; + PRFileDesc *file = NULL; + PRThread * me = PR_GetCurrentThread(); + PRInt32 bytes, descbytes, netbytes, filebytes = 0; + CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); + PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tProcessRequest(0x%p): receiving desciptor\n", me)); + bytes = PR_Recv( + fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout); + if (-1 == bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto exit; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tProcessRequest(0x%p): receive timeout\n", me)); + } + goto exit; + } + if (0 == bytes) + { + rv = PR_FAILURE; + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tProcessRequest(0x%p): unexpected end of file\n", me)); + goto exit; + } + descbytes = PR_ntohl(descriptor->size); + TEST_ASSERT(sizeof(*descriptor) == bytes); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", + me, descbytes, descriptor->filename)); + + file = PR_Open( + descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666); + if (NULL == file) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tProcessRequest(0x%p): open file timeout\n", me)); + goto aborted; + } + } + TEST_ASSERT(NULL != file); + + filebytes = 0; + while (filebytes < descbytes) + { + netbytes = sizeof(buffer); + if ((descbytes - filebytes) < netbytes) + netbytes = descbytes - filebytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)); + bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); + if (-1 == bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): receive data timeout\n", me)); + goto aborted; + } + /* + * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED) + * on NT here. This is equivalent to ECONNRESET on Unix. + * -wtc + */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_WARNING, + ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", + me, PR_GetError(), PR_GetOSError())); + goto aborted; + } + if(0 == bytes) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_WARNING, + ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)); + rv = PR_FAILURE; + goto aborted; + } + filebytes += bytes; + netbytes = bytes; + /* The byte count for PR_Write should be positive */ + MY_ASSERT(netbytes > 0); + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes)); + bytes = PR_Write(file, buffer, netbytes); + if (netbytes != bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): write file timeout\n", me)); + goto aborted; + } + } + TEST_ASSERT(bytes > 0); + } + + PR_Lock(server->ml); + server->operations += 1; + server->bytesTransferred += filebytes; + PR_Unlock(server->ml); + + rv = PR_Close(file); + if (Aborted(rv)) goto aborted; + TEST_ASSERT(PR_SUCCESS == rv); + file = NULL; + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename)); + file = PR_Open(descriptor->filename, PR_RDONLY, 0); + if (NULL == file) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): open file timeout\n", + PR_GetCurrentThread())); + goto aborted; + } + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n", + me, PR_GetError(), PR_GetOSError())); + goto aborted; + } + TEST_ASSERT(NULL != file); + + netbytes = 0; + while (netbytes < descbytes) + { + filebytes = sizeof(buffer); + if ((descbytes - netbytes) < filebytes) + filebytes = descbytes - netbytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes)); + bytes = PR_Read(file, buffer, filebytes); + if (filebytes != bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): read file timeout\n", me)); + else + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", + me, PR_GetError(), PR_GetOSError())); + goto aborted; + } + TEST_ASSERT(bytes > 0); + netbytes += bytes; + filebytes = bytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes)); + bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); + if (filebytes != bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): send data timeout\n", me)); + goto aborted; + } + break; + } + TEST_ASSERT(bytes > 0); + } + + PR_Lock(server->ml); + server->bytesTransferred += filebytes; + PR_Unlock(server->ml); + + rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); + if (Aborted(rv)) goto aborted; + + rv = PR_Close(file); + if (Aborted(rv)) goto aborted; + TEST_ASSERT(PR_SUCCESS == rv); + file = NULL; + +aborted: + PR_ClearInterrupt(); + if (NULL != file) PR_Close(file); + drv = PR_Delete(descriptor->filename); + TEST_ASSERT(PR_SUCCESS == drv); +exit: + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tProcessRequest(0x%p): Finished\n", me)); + + PR_DELETE(descriptor); + +#if defined(WIN95) + PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */ +#endif + return rv; +} /* ProcessRequest */ + +static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool) +{ + CSWorker_t *worker = PR_NEWZAP(CSWorker_t); + worker->server = server; + PR_INIT_CLIST(&worker->element); + worker->thread = PR_CreateThread( + PR_USER_THREAD, Worker, worker, + DEFAULT_SERVER_PRIORITY, thread_scope, + PR_UNJOINABLE_THREAD, 0); + if (NULL == worker->thread) + { + PR_DELETE(worker); + return PR_FAILURE; + } + + TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, + ("\tCreateWorker(0x%p): create new worker (0x%p)\n", + PR_GetCurrentThread(), worker->thread)); + + return PR_SUCCESS; +} /* CreateWorker */ + +static void PR_CALLBACK Worker(void *arg) +{ + PRStatus rv; + PRNetAddr from; + PRFileDesc *fd = NULL; + PRThread *me = PR_GetCurrentThread(); + CSWorker_t *worker = (CSWorker_t*)arg; + CSServer_t *server = worker->server; + CSPool_t *pool = &server->pool; + + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1)); + + PR_Lock(server->ml); + PR_APPEND_LINK(&worker->element, &server->list); + pool->workers += 1; /* define our existance */ + + while (cs_run == server->state) + { + while (pool->accepting >= server->workers.accepting) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tWorker(0x%p): waiting for accept slot[%d]\n", + me, pool->accepting)); + rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT); + if (Aborted(rv) || (cs_run != server->state)) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("\tWorker(0x%p): has been %s\n", + me, (Aborted(rv) ? "interrupted" : "stopped"))); + goto exit; + } + } + pool->accepting += 1; /* how many are really in accept */ + PR_Unlock(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tWorker(0x%p): calling accept\n", me)); + fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT); + + PR_Lock(server->ml); + pool->accepting -= 1; + PR_NotifyCondVar(pool->acceptComplete); + + if ((NULL == fd) && Aborted(PR_FAILURE)) + { + if (NULL != server->listener) + { + PR_Close(server->listener); + server->listener = NULL; + } + goto exit; + } + + if (NULL != fd) + { + /* + ** Create another worker of the total number of workers is + ** less than the minimum specified or we have none left in + ** accept() AND we're not over the maximum. + ** This sort of presumes that the number allowed in accept + ** is at least as many as the minimum. Otherwise we'll keep + ** creating new threads and deleting them soon after. + */ + PRBool another = + ((pool->workers < server->workers.minimum) || + ((0 == pool->accepting) + && (pool->workers < server->workers.maximum))) ? + PR_TRUE : PR_FALSE; + pool->active += 1; + PR_Unlock(server->ml); + + if (another) (void)CreateWorker(server, pool); + + rv = ProcessRequest(fd, server); + if (PR_SUCCESS != rv) + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tWorker(0x%p): server process ended abnormally\n", me)); + (void)PR_Close(fd); fd = NULL; + + PR_Lock(server->ml); + pool->active -= 1; + } + } + +exit: + PR_ClearInterrupt(); + PR_Unlock(server->ml); + + if (NULL != fd) + { + (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH); + (void)PR_Close(fd); + } + + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers)); + + PR_Lock(server->ml); + pool->workers -= 1; /* undefine our existance */ + PR_REMOVE_AND_INIT_LINK(&worker->element); + PR_NotifyCondVar(pool->exiting); + PR_Unlock(server->ml); + + PR_DELETE(worker); /* destruction of the "worker" object */ + +} /* Worker */ + +static void PR_CALLBACK Server(void *arg) +{ + PRStatus rv; + PRNetAddr serverAddress; + PRThread *me = PR_GetCurrentThread(); + CSServer_t *server = (CSServer_t*)arg; + PRSocketOptionData sockOpt; + + server->listener = PR_Socket(domain, SOCK_STREAM, protocol); + + sockOpt.option = PR_SockOpt_Reuseaddr; + sockOpt.value.reuse_addr = PR_TRUE; + rv = PR_SetSocketOption(server->listener, &sockOpt); + TEST_ASSERT(PR_SUCCESS == rv); + + memset(&serverAddress, 0, sizeof(serverAddress)); + if (PR_AF_INET6 != domain) + rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress); + else + rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, DEFAULT_PORT, + &serverAddress); + rv = PR_Bind(server->listener, &serverAddress); + TEST_ASSERT(PR_SUCCESS == rv); + + rv = PR_Listen(server->listener, server->backlog); + TEST_ASSERT(PR_SUCCESS == rv); + + server->started = PR_IntervalNow(); + TimeOfDayMessage("Server started at", me); + + PR_Lock(server->ml); + server->state = cs_run; + PR_NotifyCondVar(server->stateChange); + PR_Unlock(server->ml); + + /* + ** Create the first worker (actually, a thread that accepts + ** connections and then processes the work load as needed). + ** From this point on, additional worker threads are created + ** as they are needed by existing worker threads. + */ + rv = CreateWorker(server, &server->pool); + TEST_ASSERT(PR_SUCCESS == rv); + + /* + ** From here on this thread is merely hanging around as the contact + ** point for the main test driver. It's just waiting for the driver + ** to declare the test complete. + */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tServer(0x%p): waiting for state change\n", me)); + + PR_Lock(server->ml); + while ((cs_run == server->state) && !Aborted(rv)) + { + rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(server->ml); + PR_ClearInterrupt(); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_INFO, + ("\tServer(0x%p): shutting down workers\n", me)); + + /* + ** Get all the worker threads to exit. They know how to + ** clean up after themselves, so this is just a matter of + ** waiting for clorine in the pool to take effect. During + ** this stage we're ignoring interrupts. + */ + server->workers.minimum = server->workers.maximum = 0; + + PR_Lock(server->ml); + while (!PR_CLIST_IS_EMPTY(&server->list)) + { + PRCList *head = PR_LIST_HEAD(&server->list); + CSWorker_t *worker = (CSWorker_t*)head; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker)); + rv = PR_Interrupt(worker->thread); + TEST_ASSERT(PR_SUCCESS == rv); + PR_REMOVE_AND_INIT_LINK(head); + } + + while (server->pool.workers > 0) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("\tServer(0x%p): waiting for %u workers to exit\n", + me, server->pool.workers)); + (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT); + } + + server->state = cs_exit; + PR_NotifyCondVar(server->stateChange); + PR_Unlock(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("\tServer(0x%p): stopped after %u operations and %u bytes\n", + me, server->operations, server->bytesTransferred)); + + if (NULL != server->listener) PR_Close(server->listener); + server->stopped = PR_IntervalNow(); + +} /* Server */ + +static void WaitForCompletion(PRIntn execution) +{ + while (execution > 0) + { + PRIntn dally = (execution > 30) ? 30 : execution; + PR_Sleep(PR_SecondsToInterval(dally)); + if (pthread_stats) PT_FPrintStats(debug_out, "\nPThread Statistics\n"); + execution -= dally; + } +} /* WaitForCompletion */ + +static void Help(void) +{ + PR_fprintf(debug_out, "cltsrv test program usage:\n"); + PR_fprintf(debug_out, "\t-a threads allowed in accept (5)\n"); + PR_fprintf(debug_out, "\t-b backlock for listen (5)\n"); + PR_fprintf(debug_out, "\t-c number of clients to create (1)\n"); + PR_fprintf(debug_out, "\t-f low water mark for fd caching (0)\n"); + PR_fprintf(debug_out, "\t-F high water mark for fd caching (0)\n"); + PR_fprintf(debug_out, "\t-w minimal number of server threads (1)\n"); + PR_fprintf(debug_out, "\t-W maximum number of server threads (1)\n"); + PR_fprintf(debug_out, "\t-e duration of the test in seconds (10)\n"); + PR_fprintf(debug_out, "\t-s dsn name of server (localhost)\n"); + PR_fprintf(debug_out, "\t-G use GLOBAL threads (LOCAL)\n"); + PR_fprintf(debug_out, "\t-X use XTP as transport (TCP)\n"); + PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n"); + PR_fprintf(debug_out, "\t-v verbosity (accumulative) (0)\n"); + PR_fprintf(debug_out, "\t-p pthread statistics (FALSE)\n"); + PR_fprintf(debug_out, "\t-d debug mode (FALSE)\n"); + PR_fprintf(debug_out, "\t-h this message\n"); +} /* Help */ + +static Verbosity IncrementVerbosity(void) +{ + PRIntn verboge = (PRIntn)verbosity + 1; + return (Verbosity)verboge; +} /* IncrementVerbosity */ + +int main(int argc, char** argv) +{ + PRUintn index; + PRBool boolean; + CSClient_t *client; + PRStatus rv, joinStatus; + CSServer_t *server = NULL; + + PRUintn backlog = DEFAULT_BACKLOG; + PRUintn clients = DEFAULT_CLIENTS; + const char *serverName = DEFAULT_SERVER; + PRBool serverIsLocal = PR_TRUE; + PRUintn accepting = ALLOWED_IN_ACCEPT; + PRUintn workersMin = DEFAULT_WORKERS_MIN; + PRUintn workersMax = DEFAULT_WORKERS_MAX; + PRIntn execution = DEFAULT_EXECUTION_TIME; + PRIntn low = DEFAULT_LOW, high = DEFAULT_HIGH; + + /* + * -G use global threads + * -a threads allowed in accept + * -b backlock for listen + * -c number of clients to create + * -f low water mark for caching FDs + * -F high water mark for caching FDs + * -w minimal number of server threads + * -W maximum number of server threads + * -e duration of the test in seconds + * -s dsn name of server (implies no server here) + * -v verbosity + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:f:F:w:W:e:s:vdhp"); + + debug_out = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'G': /* use global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'X': /* use XTP as transport */ + protocol = 36; + break; + case '6': /* Use IPv6 */ + domain = PR_AF_INET6; + break; + case 'a': /* the value for accepting */ + accepting = atoi(opt->value); + break; + case 'b': /* the value for backlock */ + backlog = atoi(opt->value); + break; + case 'c': /* number of client threads */ + clients = atoi(opt->value); + break; + case 'f': /* low water fd cache */ + low = atoi(opt->value); + break; + case 'F': /* low water fd cache */ + high = atoi(opt->value); + break; + case 'w': /* minimum server worker threads */ + workersMin = atoi(opt->value); + break; + case 'W': /* maximum server worker threads */ + workersMax = atoi(opt->value); + break; + case 'e': /* program execution time in seconds */ + execution = atoi(opt->value); + break; + case 's': /* server's address */ + serverName = opt->value; + break; + case 'v': /* verbosity */ + verbosity = IncrementVerbosity(); + break; + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'p': /* pthread mode */ + pthread_stats = PR_TRUE; + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE; + if (0 == execution) execution = DEFAULT_EXECUTION_TIME; + if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX; + if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN; + if (0 == accepting) accepting = ALLOWED_IN_ACCEPT; + if (0 == backlog) backlog = DEFAULT_BACKLOG; + + if (workersMin > accepting) accepting = workersMin; + + PR_STDIO_INIT(); + TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread()); + + cltsrv_log_file = PR_NewLogModule("cltsrv_log"); + MY_ASSERT(NULL != cltsrv_log_file); + boolean = PR_SetLogFile("cltsrv.log"); + MY_ASSERT(boolean); + + rv = PR_SetFDCacheSize(low, high); + PR_ASSERT(PR_SUCCESS == rv); + + if (serverIsLocal) + { + /* Establish the server */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_INFO, + ("main(0x%p): starting server\n", PR_GetCurrentThread())); + + server = PR_NEWZAP(CSServer_t); + PR_INIT_CLIST(&server->list); + server->state = cs_init; + server->ml = PR_NewLock(); + server->backlog = backlog; + server->port = DEFAULT_PORT; + server->workers.minimum = workersMin; + server->workers.maximum = workersMax; + server->workers.accepting = accepting; + server->stateChange = PR_NewCondVar(server->ml); + server->pool.exiting = PR_NewCondVar(server->ml); + server->pool.acceptComplete = PR_NewCondVar(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("main(0x%p): creating server thread\n", PR_GetCurrentThread())); + + server->thread = PR_CreateThread( + PR_USER_THREAD, Server, server, PR_PRIORITY_HIGH, + thread_scope, PR_JOINABLE_THREAD, 0); + TEST_ASSERT(NULL != server->thread); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("main(0x%p): waiting for server init\n", PR_GetCurrentThread())); + + PR_Lock(server->ml); + while (server->state == cs_init) + PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("main(0x%p): server init complete (port #%d)\n", + PR_GetCurrentThread(), server->port)); + } + + if (clients != 0) + { + /* Create all of the clients */ + PRHostEnt host; + char buffer[BUFFER_SIZE]; + client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t)); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("main(0x%p): creating %d client threads\n", + PR_GetCurrentThread(), clients)); + + if (!serverIsLocal) + { + rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host); + if (PR_SUCCESS != rv) + { + PL_FPrintError(PR_STDERR, "PR_GetHostByName"); + return 2; + } + } + + for (index = 0; index < clients; ++index) + { + client[index].state = cs_init; + client[index].ml = PR_NewLock(); + if (serverIsLocal) + { + if (PR_AF_INET6 != domain) + (void)PR_InitializeNetAddr( + PR_IpAddrLoopback, DEFAULT_PORT, + &client[index].serverAddress); + else + rv = PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, + DEFAULT_PORT, &client[index].serverAddress); + } + else + { + (void)PR_EnumerateHostEnt( + 0, &host, DEFAULT_PORT, &client[index].serverAddress); + } + client[index].stateChange = PR_NewCondVar(client[index].ml); + TEST_LOG( + cltsrv_log_file, TEST_LOG_INFO, + ("main(0x%p): creating client threads\n", PR_GetCurrentThread())); + client[index].thread = PR_CreateThread( + PR_USER_THREAD, Client, &client[index], PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + TEST_ASSERT(NULL != client[index].thread); + PR_Lock(client[index].ml); + while (cs_init == client[index].state) + PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(client[index].ml); + } + } + + /* Then just let them go at it for a bit */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("main(0x%p): waiting for execution interval (%d seconds)\n", + PR_GetCurrentThread(), execution)); + + WaitForCompletion(execution); + + TimeOfDayMessage("Shutting down", PR_GetCurrentThread()); + + if (clients != 0) + { + for (index = 0; index < clients; ++index) + { + TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, + ("main(0x%p): notifying client(0x%p) to stop\n", + PR_GetCurrentThread(), client[index].thread)); + + PR_Lock(client[index].ml); + if (cs_run == client[index].state) + { + client[index].state = cs_stop; + PR_Interrupt(client[index].thread); + while (cs_stop == client[index].state) + PR_WaitCondVar( + client[index].stateChange, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(client[index].ml); + + TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, + ("main(0x%p): joining client(0x%p)\n", + PR_GetCurrentThread(), client[index].thread)); + + joinStatus = PR_JoinThread(client[index].thread); + TEST_ASSERT(PR_SUCCESS == joinStatus); + PR_DestroyCondVar(client[index].stateChange); + PR_DestroyLock(client[index].ml); + } + PR_DELETE(client); + } + + if (NULL != server) + { + /* All clients joined - retrieve the server */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("main(0x%p): notifying server(0x%p) to stop\n", + PR_GetCurrentThread(), server->thread)); + + PR_Lock(server->ml); + server->state = cs_stop; + PR_Interrupt(server->thread); + while (cs_exit != server->state) + PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("main(0x%p): joining server(0x%p)\n", + PR_GetCurrentThread(), server->thread)); + joinStatus = PR_JoinThread(server->thread); + TEST_ASSERT(PR_SUCCESS == joinStatus); + + PR_DestroyCondVar(server->stateChange); + PR_DestroyCondVar(server->pool.exiting); + PR_DestroyCondVar(server->pool.acceptComplete); + PR_DestroyLock(server->ml); + PR_DELETE(server); + } + + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("main(0x%p): test complete\n", PR_GetCurrentThread())); + + PT_FPrintStats(debug_out, "\nPThread Statistics\n"); + + TimeOfDayMessage("Test exiting at", PR_GetCurrentThread()); + PR_Cleanup(); + return 0; +} /* main */ + +/* cltsrv.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/concur.c nspr-4.10.7/nspr/pr/tests/concur.c --- nspr-4.9.5/nspr/pr/tests/concur.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/concur.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: concur.c +** Description: test of adding and removing concurrency options +*/ + +#include "prcvar.h" +#include "prinit.h" +#include "prinrval.h" +#include "prlock.h" +#include "prprf.h" +#include "prmem.h" +#include "prlog.h" + +#include "plgetopt.h" + +#include "private/pprio.h" + +#include + +#define DEFAULT_RANGE 10 +#define DEFAULT_LOOPS 100 + +static PRThreadScope thread_scope = PR_LOCAL_THREAD; + +typedef struct Context +{ + PRLock *ml; + PRCondVar *cv; + PRIntn want, have; +} Context; + + +/* +** Make the instance of 'context' static (not on the stack) +** for Win16 threads +*/ +static Context context = {NULL, NULL, 0, 0}; + +static void PR_CALLBACK Dull(void *arg) +{ + Context *context = (Context*)arg; + PR_Lock(context->ml); + context->have += 1; + while (context->want >= context->have) + PR_WaitCondVar(context->cv, PR_INTERVAL_NO_TIMEOUT); + context->have -= 1; + PR_Unlock(context->ml); +} /* Dull */ + +PRIntn PR_CALLBACK Concur(PRIntn argc, char **argv) +{ + PRUintn cpus; + PLOptStatus os; + PRThread **threads; + PRBool debug = PR_FALSE; + PRUintn range = DEFAULT_RANGE; + PRStatus rc; + PRUintn cnt; + PRUintn loops = DEFAULT_LOOPS; + PRIntervalTime hundredMills = PR_MillisecondsToInterval(100); + PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:r:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'G': /* GLOBAL threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'd': /* debug mode */ + debug = PR_TRUE; + break; + case 'r': /* range limit */ + range = atoi(opt->value); + break; + case 'l': /* loop counter */ + loops = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (0 == range) range = DEFAULT_RANGE; + if (0 == loops) loops = DEFAULT_LOOPS; + + context.ml = PR_NewLock(); + context.cv = PR_NewCondVar(context.ml); + + if (debug) + PR_fprintf( + PR_STDERR, "Testing with %d CPUs and %d interations\n", range, loops); + + threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * range); + while (--loops > 0) + { + for (cpus = 1; cpus <= range; ++cpus) + { + PR_SetConcurrency(cpus); + context.want = cpus; + + threads[cpus - 1] = PR_CreateThread( + PR_USER_THREAD, Dull, &context, PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + } + + PR_Sleep(hundredMills); + + for (cpus = range; cpus > 0; cpus--) + { + PR_SetConcurrency(cpus); + context.want = cpus - 1; + + PR_Lock(context.ml); + PR_NotifyCondVar(context.cv); + PR_Unlock(context.ml); + } + for(cnt = 0; cnt < range; cnt++) { + rc = PR_JoinThread(threads[cnt]); + PR_ASSERT(rc == PR_SUCCESS); + } + } + + + if (debug) + PR_fprintf( + PR_STDERR, "Waiting for %d thread(s) to exit\n", context.have); + + while (context.have > 0) PR_Sleep(hundredMills); + + if (debug) + PR_fprintf( + PR_STDERR, "Finished [want: %d, have: %d]\n", + context.want, context.have); + + PR_DestroyLock(context.ml); + PR_DestroyCondVar(context.cv); + PR_DELETE(threads); + + PR_fprintf(PR_STDERR, "PASSED\n"); + + return 0; +} /* Concur */ + +int main(int argc, char **argv) +{ + PR_STDIO_INIT(); + return PR_Initialize(Concur, argc, argv, 0); +} /* main */ + +/* concur.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/cvar2.c nspr-4.10.7/nspr/pr/tests/cvar2.c --- nspr-4.9.5/nspr/pr/tests/cvar2.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/cvar2.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,960 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1996 - Netscape Communications Corporation +** +** Name: cvar2.c +** +** Description: Simple test creates several local and global threads; +** half use a single,shared condvar, and the +** other half have their own condvar. The main thread then loops +** notifying them to wakeup. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ + +#include "nspr.h" +#include "plerror.h" +#include "plgetopt.h" + +#include +#include +#include + +int _debug_on = 0; +#define DPRINTF(arg) if (_debug_on) printf arg + +#define DEFAULT_COUNT 100 +#define DEFAULT_THREADS 5 +PRInt32 count = DEFAULT_COUNT; + +typedef struct threadinfo { + PRThread *thread; + PRInt32 id; + PRBool internal; + PRInt32 *tcount; + PRLock *lock; + PRCondVar *cvar; + PRIntervalTime timeout; + PRInt32 loops; + + PRLock *exitlock; + PRCondVar *exitcvar; + PRInt32 *exitcount; +} threadinfo; + +/* +** Make exitcount, tcount static. for Win16. +*/ +static PRInt32 exitcount=0; +static PRInt32 tcount=0; + + +/* Thread that gets notified; many threads share the same condvar */ +void PR_CALLBACK +SharedCondVarThread(void *_info) +{ + threadinfo *info = (threadinfo *)_info; + PRInt32 index; + + for (index=0; indexloops; index++) { + PR_Lock(info->lock); + if (*info->tcount == 0) + PR_WaitCondVar(info->cvar, info->timeout); +#if 0 + printf("shared thread %ld notified in loop %ld\n", info->id, index); +#endif + (*info->tcount)--; + PR_Unlock(info->lock); + + PR_Lock(info->exitlock); + (*info->exitcount)++; + PR_NotifyCondVar(info->exitcvar); + PR_Unlock(info->exitlock); + } +#if 0 + printf("shared thread %ld terminating\n", info->id); +#endif +} + +/* Thread that gets notified; no other threads use the same condvar */ +void PR_CALLBACK +PrivateCondVarThread(void *_info) +{ + threadinfo *info = (threadinfo *)_info; + PRInt32 index; + + for (index=0; indexloops; index++) { + PR_Lock(info->lock); + if (*info->tcount == 0) { + DPRINTF(("PrivateCondVarThread: thread 0x%lx waiting on cvar = 0x%lx\n", + PR_GetCurrentThread(), info->cvar)); + PR_WaitCondVar(info->cvar, info->timeout); + } +#if 0 + printf("solo thread %ld notified in loop %ld\n", info->id, index); +#endif + (*info->tcount)--; + PR_Unlock(info->lock); + + PR_Lock(info->exitlock); + (*info->exitcount)++; + PR_NotifyCondVar(info->exitcvar); +DPRINTF(("PrivateCondVarThread: thread 0x%lx notified exitcvar = 0x%lx cnt = %ld\n", + PR_GetCurrentThread(), info->exitcvar,(*info->exitcount))); + PR_Unlock(info->exitlock); + } +#if 0 + printf("solo thread %ld terminating\n", info->id); +#endif +} + +void +CreateTestThread(threadinfo *info, + PRInt32 id, + PRLock *lock, + PRCondVar *cvar, + PRInt32 loops, + PRIntervalTime timeout, + PRInt32 *tcount, + PRLock *exitlock, + PRCondVar *exitcvar, + PRInt32 *exitcount, + PRBool shared, + PRThreadScope scope) +{ + info->id = id; + info->internal = (shared) ? PR_FALSE : PR_TRUE; + info->lock = lock; + info->cvar = cvar; + info->loops = loops; + info->timeout = timeout; + info->tcount = tcount; + info->exitlock = exitlock; + info->exitcvar = exitcvar; + info->exitcount = exitcount; + info->thread = PR_CreateThread( + PR_USER_THREAD, + shared?SharedCondVarThread:PrivateCondVarThread, + info, + PR_PRIORITY_NORMAL, + scope, + PR_JOINABLE_THREAD, + 0); + if (!info->thread) + PL_PrintError("error creating thread\n"); +} + + +void +CondVarTestSUU(void *_arg) +{ + PRInt32 arg = (PRInt32)_arg; + PRInt32 index, loops; + threadinfo *list; + PRLock *sharedlock; + PRCondVar *sharedcvar; + PRLock *exitlock; + PRCondVar *exitcvar; + + exitcount=0; + tcount=0; + list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); + + sharedlock = PR_NewLock(); + sharedcvar = PR_NewCondVar(sharedlock); + exitlock = PR_NewLock(); + exitcvar = PR_NewCondVar(exitlock); + + /* Create the threads */ + for(index=0; index= arg); + exitcount -= arg; + PR_Unlock(exitlock); + } + + /* Join all the threads */ + for(index=0; index<(arg); index++) + PR_JoinThread(list[index].thread); + + PR_DestroyCondVar(sharedcvar); + PR_DestroyLock(sharedlock); + PR_DestroyCondVar(exitcvar); + PR_DestroyLock(exitlock); + + PR_DELETE(list); +} + +void +CondVarTestSUK(void *_arg) +{ + PRInt32 arg = (PRInt32)_arg; + PRInt32 index, loops; + threadinfo *list; + PRLock *sharedlock; + PRCondVar *sharedcvar; + PRLock *exitlock; + PRCondVar *exitcvar; + exitcount=0; + tcount=0; + + list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); + + sharedlock = PR_NewLock(); + sharedcvar = PR_NewCondVar(sharedlock); + exitlock = PR_NewLock(); + exitcvar = PR_NewCondVar(exitlock); + + /* Create the threads */ + for(index=0; index= arg); + exitcount -= arg; + PR_Unlock(exitlock); +#if 0 + printf("threads ready\n"); +#endif + } + + /* Join all the threads */ + for(index=0; index<(arg); index++) + PR_JoinThread(list[index].thread); + + PR_DestroyCondVar(sharedcvar); + PR_DestroyLock(sharedlock); + PR_DestroyCondVar(exitcvar); + PR_DestroyLock(exitlock); + + PR_DELETE(list); +} + +void +CondVarTestPUU(void *_arg) +{ + PRInt32 arg = (PRInt32)_arg; + PRInt32 index, loops; + threadinfo *list; + PRLock *sharedlock; + PRCondVar *sharedcvar; + PRLock *exitlock; + PRCondVar *exitcvar; + PRInt32 *tcount, *saved_tcount; + + exitcount=0; + list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); + saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4)); + + sharedlock = PR_NewLock(); + sharedcvar = PR_NewCondVar(sharedlock); + exitlock = PR_NewLock(); + exitcvar = PR_NewCondVar(exitlock); + + /* Create the threads */ + for(index=0; index= arg); + exitcount -= arg; + PR_Unlock(exitlock); + } + + /* Join all the threads */ + for(index=0; index<(arg); index++) { + DPRINTF(("CondVarTestPUU: joining thread 0x%lx\n",list[index].thread)); + PR_JoinThread(list[index].thread); + if (list[index].internal) { + PR_Lock(list[index].lock); + PR_DestroyCondVar(list[index].cvar); + PR_Unlock(list[index].lock); + PR_DestroyLock(list[index].lock); + } + } + + PR_DestroyCondVar(sharedcvar); + PR_DestroyLock(sharedlock); + PR_DestroyCondVar(exitcvar); + PR_DestroyLock(exitlock); + + PR_DELETE(list); + PR_DELETE(saved_tcount); +} + +void +CondVarTestPUK(void *_arg) +{ + PRInt32 arg = (PRInt32)_arg; + PRInt32 index, loops; + threadinfo *list; + PRLock *sharedlock; + PRCondVar *sharedcvar; + PRLock *exitlock; + PRCondVar *exitcvar; + PRInt32 *tcount, *saved_tcount; + + exitcount=0; + list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); + saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4)); + + sharedlock = PR_NewLock(); + sharedcvar = PR_NewCondVar(sharedlock); + exitlock = PR_NewLock(); + exitcvar = PR_NewCondVar(exitlock); + + /* Create the threads */ + for(index=0; index= arg); + exitcount -= arg; + PR_Unlock(exitlock); + } + + /* Join all the threads */ + for(index=0; index<(arg); index++) { + PR_JoinThread(list[index].thread); + if (list[index].internal) { + PR_Lock(list[index].lock); + PR_DestroyCondVar(list[index].cvar); + PR_Unlock(list[index].lock); + PR_DestroyLock(list[index].lock); + } + } + + PR_DestroyCondVar(sharedcvar); + PR_DestroyLock(sharedlock); + PR_DestroyCondVar(exitcvar); + PR_DestroyLock(exitlock); + + PR_DELETE(list); + PR_DELETE(saved_tcount); +} + +void +CondVarTest(void *_arg) +{ + PRInt32 arg = (PRInt32)_arg; + PRInt32 index, loops; + threadinfo *list; + PRLock *sharedlock; + PRCondVar *sharedcvar; + PRLock *exitlock; + PRCondVar *exitcvar; + PRInt32 *ptcount, *saved_ptcount; + + exitcount=0; + tcount=0; + list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); + saved_ptcount = ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4)); + + sharedlock = PR_NewLock(); + sharedcvar = PR_NewCondVar(sharedlock); + exitlock = PR_NewLock(); + exitcvar = PR_NewCondVar(exitlock); + + /* Create the threads */ + for(index=0; index= arg*4); + exitcount -= arg*4; + PR_Unlock(exitlock); +#if 0 + printf("threads ready\n"); +#endif + } + + /* Join all the threads */ + for(index=0; index<(arg*4); index++) { + PR_JoinThread(list[index].thread); + if (list[index].internal) { + PR_Lock(list[index].lock); + PR_DestroyCondVar(list[index].cvar); + PR_Unlock(list[index].lock); + PR_DestroyLock(list[index].lock); + } + } + + PR_DestroyCondVar(sharedcvar); + PR_DestroyLock(sharedlock); + PR_DestroyCondVar(exitcvar); + PR_DestroyLock(exitlock); + + PR_DELETE(list); + PR_DELETE(saved_ptcount); +} + +void +CondVarTimeoutTest(void *_arg) +{ + PRInt32 arg = (PRInt32)_arg; + PRInt32 index, loops; + threadinfo *list; + PRLock *sharedlock; + PRCondVar *sharedcvar; + PRLock *exitlock; + PRCondVar *exitcvar; + + list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); + + sharedlock = PR_NewLock(); + sharedcvar = PR_NewCondVar(sharedlock); + exitlock = PR_NewLock(); + exitcvar = PR_NewCondVar(exitlock); + + /* Create the threads */ + for(index=0; index= arg*4); + exitcount -= arg*4; + PR_Unlock(exitlock); + } + + + /* Join all the threads */ + for(index=0; index<(arg*4); index++) { + PR_JoinThread(list[index].thread); + if (list[index].internal) { + PR_Lock(list[index].lock); + PR_DestroyCondVar(list[index].cvar); + PR_Unlock(list[index].lock); + PR_DestroyLock(list[index].lock); + } + } + + PR_DestroyCondVar(sharedcvar); + PR_DestroyLock(sharedlock); + PR_DestroyCondVar(exitcvar); + PR_DestroyLock(exitlock); + + PR_DELETE(list); +} + +void +CondVarMixedTest(void *_arg) +{ + PRInt32 arg = (PRInt32)_arg; + PRInt32 index, loops; + threadinfo *list; + PRLock *sharedlock; + PRCondVar *sharedcvar; + PRLock *exitlock; + PRCondVar *exitcvar; + PRInt32 *ptcount; + + exitcount=0; + tcount=0; + list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); + ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4)); + + sharedlock = PR_NewLock(); + sharedcvar = PR_NewCondVar(sharedlock); + exitlock = PR_NewLock(); + exitcvar = PR_NewCondVar(exitlock); + + /* Create the threads */ + for(index=0; index= arg*4); + exitcount -= arg*4; + PR_Unlock(exitlock); + } + + /* Join all the threads */ + for(index=0; index<(arg*4); index++) { + PR_JoinThread(list[index].thread); + if (list[index].internal) { + PR_Lock(list[index].lock); + PR_DestroyCondVar(list[index].cvar); + PR_Unlock(list[index].lock); + PR_DestroyLock(list[index].lock); + } + } + + PR_DestroyCondVar(sharedcvar); + PR_DestroyLock(sharedlock); + + PR_DELETE(list); +} + +void +CondVarCombinedTest(void *arg) +{ + PRThread *threads[3]; + + threads[0] = PR_CreateThread(PR_USER_THREAD, + CondVarTest, + (void *)arg, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + threads[1] = PR_CreateThread(PR_USER_THREAD, + CondVarTimeoutTest, + (void *)arg, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + threads[2] = PR_CreateThread(PR_USER_THREAD, + CondVarMixedTest, + (void *)arg, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + PR_JoinThread(threads[0]); + PR_JoinThread(threads[1]); + PR_JoinThread(threads[2]); +} + +/************************************************************************/ + +static void Measure(void (*func)(void *), PRInt32 arg, const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)((void *)arg); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + + printf("%40s: %6.2f usec\n", msg, d / count); +} + +static PRIntn PR_CALLBACK RealMain(int argc, char **argv) +{ + PRInt32 threads, default_threads = DEFAULT_THREADS; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "vc:t:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'v': /* debug mode */ + _debug_on = 1; + break; + case 'c': /* loop counter */ + count = atoi(opt->value); + break; + case 't': /* number of threads involved */ + default_threads = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (0 == count) count = DEFAULT_COUNT; + if (0 == default_threads) default_threads = DEFAULT_THREADS; + + printf("\n\ +CondVar Test: \n\ + \n\ +Simple test creates several local and global threads; half use a single,\n\ +shared condvar, and the other half have their own condvar. The main \n\ +thread then loops notifying them to wakeup. \n\ + \n\ +The timeout test is very similar except that the threads are not \n\ +notified. They will all wakeup on a 1 second timeout. \n\ + \n\ +The mixed test combines the simple test and the timeout test; every \n\ +third thread is notified, the other threads are expected to timeout \n\ +correctly. \n\ + \n\ +Lastly, the combined test creates a thread for each of the above three \n\ +cases and they all run simultaneously. \n\ + \n\ +This test is run with %d, %d, %d, and %d threads of each type.\n\n", +default_threads, default_threads*2, default_threads*3, default_threads*4); + + PR_SetConcurrency(2); + + for (threads = default_threads; threads < default_threads*5; threads+=default_threads) { + printf("\n%ld Thread tests\n", threads); + Measure(CondVarTestSUU, threads, "Condvar simple test shared UU"); + Measure(CondVarTestSUK, threads, "Condvar simple test shared UK"); + Measure(CondVarTestPUU, threads, "Condvar simple test priv UU"); + Measure(CondVarTestPUK, threads, "Condvar simple test priv UK"); + Measure(CondVarTest, threads, "Condvar simple test All"); + Measure(CondVarTimeoutTest, threads, "Condvar timeout test"); +#if 0 + Measure(CondVarMixedTest, threads, "Condvar mixed timeout test"); + Measure(CondVarCombinedTest, threads, "Combined condvar test"); +#endif + } + + printf("PASS\n"); + + return 0; +} + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/cvar.c nspr-4.10.7/nspr/pr/tests/cvar.c --- nspr-4.9.5/nspr/pr/tests/cvar.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/cvar.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,291 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1996 - Netscape Communications Corporation +** +** Name: cvar.c +** +** Description: Tests Condition Variable Operations +** +** Modification History: +** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** 12-June-97 Revert to return code 0 and 1. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ + +#include "nspr.h" + +/* Used to get the command line option */ +#include "plgetopt.h" + +#include +#include +#include + +PRMonitor *mon; +#define DEFAULT_COUNT 1000 +PRInt32 count = 0; +PRIntn debug_mode; + +#define kQSIZE 1 + +typedef struct { + PRLock *bufLock; + int startIdx; + int numFull; + PRCondVar *notFull; + PRCondVar *notEmpty; + void *data[kQSIZE]; +} CircBuf; + +static PRBool failed = PR_FALSE; + +/* +** NewCB creates and initializes a new circular buffer. +*/ +static CircBuf* NewCB(void) +{ + CircBuf *cbp; + + cbp = PR_NEW(CircBuf); + if (cbp == NULL) + return (NULL); + + cbp->bufLock = PR_NewLock(); + cbp->startIdx = 0; + cbp->numFull = 0; + cbp->notFull = PR_NewCondVar(cbp->bufLock); + cbp->notEmpty = PR_NewCondVar(cbp->bufLock); + + return (cbp); +} + +/* +** DeleteCB frees a circular buffer. +*/ +static void DeleteCB(CircBuf *cbp) +{ + PR_DestroyLock(cbp->bufLock); + PR_DestroyCondVar(cbp->notFull); + PR_DestroyCondVar(cbp->notEmpty); + PR_DELETE(cbp); +} + + +/* +** PutCBData puts new data on the queue. If the queue is full, it waits +** until there is room. +*/ +static void PutCBData(CircBuf *cbp, void *data) +{ + PR_Lock(cbp->bufLock); + /* wait while the buffer is full */ + while (cbp->numFull == kQSIZE) + PR_WaitCondVar(cbp->notFull,PR_INTERVAL_NO_TIMEOUT); + cbp->data[(cbp->startIdx + cbp->numFull) % kQSIZE] = data; + cbp->numFull += 1; + + /* let a waiting reader know that there is data */ + PR_NotifyCondVar(cbp->notEmpty); + PR_Unlock(cbp->bufLock); + +} + + +/* +** GetCBData gets the oldest data on the queue. If the queue is empty, it waits +** until new data appears. +*/ +static void* GetCBData(CircBuf *cbp) +{ + void *data; + + PR_Lock(cbp->bufLock); + /* wait while the buffer is empty */ + while (cbp->numFull == 0) + PR_WaitCondVar(cbp->notEmpty,PR_INTERVAL_NO_TIMEOUT); + data = cbp->data[cbp->startIdx]; + cbp->startIdx =(cbp->startIdx + 1) % kQSIZE; + cbp->numFull -= 1; + + /* let a waiting writer know that there is room */ + PR_NotifyCondVar(cbp->notFull); + PR_Unlock(cbp->bufLock); + + return (data); +} + + +/************************************************************************/ + +static int alive; + +static void PR_CALLBACK CXReader(void *arg) +{ + CircBuf *cbp = (CircBuf *)arg; + PRInt32 i, n; + void *data; + + n = count / 2; + for (i = 0; i < n; i++) { + data = GetCBData(cbp); + if ((int)data != i) + if (debug_mode) printf("data mismatch at for i = %d usec\n", i); + } + + PR_EnterMonitor(mon); + --alive; + PR_Notify(mon); + PR_ExitMonitor(mon); +} + +static void PR_CALLBACK CXWriter(void *arg) +{ + CircBuf *cbp = (CircBuf *)arg; + PRInt32 i, n; + + n = count / 2; + for (i = 0; i < n; i++) + PutCBData(cbp, (void *)i); + + PR_EnterMonitor(mon); + --alive; + PR_Notify(mon); + PR_ExitMonitor(mon); +} + +static void CondWaitContextSwitch(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *t1, *t2; + CircBuf *cbp; + + PR_EnterMonitor(mon); + + alive = 2; + + cbp = NewCB(); + + t1 = PR_CreateThread(PR_USER_THREAD, + CXReader, cbp, + PR_PRIORITY_NORMAL, + scope1, + PR_UNJOINABLE_THREAD, + 0); + PR_ASSERT(t1); + t2 = PR_CreateThread(PR_USER_THREAD, + CXWriter, cbp, + PR_PRIORITY_NORMAL, + scope2, + PR_UNJOINABLE_THREAD, + 0); + PR_ASSERT(t2); + + /* Wait for both of the threads to exit */ + while (alive) { + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + } + + DeleteCB(cbp); + + PR_ExitMonitor(mon); +} + +static void CondWaitContextSwitchUU(void) +{ + CondWaitContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD); +} + +static void CondWaitContextSwitchUK(void) +{ + CondWaitContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); +} + +static void CondWaitContextSwitchKK(void) +{ + CondWaitContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); +} + +/************************************************************************/ + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + + if (debug_mode) printf("%40s: %6.2f usec\n", msg, d / count); + + if (0 == d) failed = PR_TRUE; +} + +static PRIntn PR_CALLBACK RealMain(int argc, char **argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name [-d] [-c n] + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dc:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'c': /* loop count */ + count = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (0 == count) count = DEFAULT_COUNT; + + mon = PR_NewMonitor(); + + Measure(CondWaitContextSwitchUU, "cond var wait context switch- user/user"); + Measure(CondWaitContextSwitchUK, "cond var wait context switch- user/kernel"); + Measure(CondWaitContextSwitchKK, "cond var wait context switch- kernel/kernel"); + + PR_DestroyMonitor(mon); + + if (debug_mode) printf("%s\n", (failed) ? "FAILED" : "PASSED"); + + if(failed) + return 1; + else + return 0; +} + + +int main(int argc, char *argv[]) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/.cvsignore nspr-4.10.7/nspr/pr/tests/.cvsignore --- nspr-4.9.5/nspr/pr/tests/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/tests/dbmalloc1.c nspr-4.10.7/nspr/pr/tests/dbmalloc1.c --- nspr-4.9.5/nspr/pr/tests/dbmalloc1.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dbmalloc1.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: dbmalloc1.c (OBSOLETE) +** +** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** +** 12-June-97 AGarcia Revert to return code 0 and 1, remove debug option (obsolete). +***********************************************************************/ + + +/*********************************************************************** +** Includes +***********************************************************************/ +#include +#include +#include "nspr.h" + +PRIntn failed_already=0; +PRIntn debug_mode; + +/* variable used for both r1 and r2 tests */ +int should_fail =0; +int actually_failed=0; + + +void +r1 +( + void +) +{ + int i; + actually_failed=0; + for( i = 0; i < 5; i++ ) + { + void *x = PR_MALLOC(128); + if( (void *)0 == x ) { + if (debug_mode) printf("\tMalloc %d failed.\n", i+1); + actually_failed = 1; + } + PR_DELETE(x); + } + + if (((should_fail != actually_failed) & (!debug_mode))) failed_already=1; + + + return; +} + +void +r2 +( + void +) +{ + int i; + + for( i = 0; i <= 5; i++ ) + { + should_fail =0; + if( 0 == i ) { + if (debug_mode) printf("No malloc should fail:\n"); + } + else { + if (debug_mode) printf("Malloc %d should fail:\n", i); + should_fail = 1; + } + PR_SetMallocCountdown(i); + r1(); + PR_ClearMallocCountdown(); + } +} + +int main(int argc, char **argv) +{ + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + r2(); + + if(failed_already) + return 1; + else + return 0; + + +} + diff -Nru nspr-4.9.5/nspr/pr/tests/dbmalloc.c nspr-4.10.7/nspr/pr/tests/dbmalloc.c --- nspr-4.9.5/nspr/pr/tests/dbmalloc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dbmalloc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,310 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: dbmalloc.c +** +** Description: Testing malloc (OBSOLETE) +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ +#include +#include +#include +#include +#include "nspr.h" + +void +usage +( + void +) +{ + fprintf(stderr, "Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename [...]\n"); + exit(0); +} + +typedef struct node_struct +{ + struct node_struct *next, *prev; + int line; + char value[4]; +} + node_t, + *node_pt; + +node_pt get_node(const char *line) +{ + node_pt rv; + int l = strlen(line); + rv = (node_pt)PR_MALLOC(sizeof(node_t) + l + 1 - 4); + if( (node_pt)0 == rv ) return (node_pt)0; + memcpy(&rv->value[0], line, l+1); + rv->next = rv->prev = (node_pt)0; + return rv; +} + +void +dump +( + const char *name, + node_pt node, + int mf, + int debug +) +{ + if( (node_pt)0 != node->prev ) dump(name, node->prev, mf, debug); + if( 0 != debug ) printf("[%s]: %6d: %s", name, node->line, node->value); + if( node->line == mf ) fprintf(stderr, "[%s]: Line %d was allocated!\n", name, node->line); + if( (node_pt)0 != node->next ) dump(name, node->next, mf, debug); + return; +} + +void +release +( + node_pt node +) +{ + if( (node_pt)0 != node->prev ) release(node->prev); + if( (node_pt)0 != node->next ) release(node->next); + PR_DELETE(node); +} + +int +t2 +( + const char *name, + int mf, + int debug +) +{ + int rv; + FILE *fp; + int l = 0; + node_pt head = (node_pt)0; + char buffer[ BUFSIZ ]; + + fp = fopen(name, "r"); + if( (FILE *)0 == fp ) + { + fprintf(stderr, "[%s]: Cannot open \"%s.\"\n", name, name); + return -1; + } + + /* fgets mallocs a buffer, first time through. */ + if( (char *)0 == fgets(buffer, BUFSIZ, fp) ) + { + fprintf(stderr, "[%s]: \"%s\" is empty.\n", name, name); + (void)fclose(fp); + return -1; + } + + rewind(fp); + + if( PR_SUCCESS != PR_ClearMallocCount() ) + { + fprintf(stderr, "[%s]: Cannot clear malloc count.\n", name); + (void)fclose(fp); + return -1; + } + + if( PR_SUCCESS != PR_SetMallocCountdown(mf) ) + { + fprintf(stderr, "[%s]: Cannot set malloc countdown to %d\n", name, mf); + (void)fclose(fp); + return -1; + } + + while( fgets(buffer, BUFSIZ, fp) ) + { + node_pt n; + node_pt *w = &head; + + if( (strlen(buffer) == (BUFSIZ-1)) && (buffer[BUFSIZ-2] != '\n') ) + buffer[BUFSIZ-2] == '\n'; + + l++; + + n = get_node(buffer); + if( (node_pt)0 == n ) + { + printf("[%s]: Line %d: malloc failure!\n", name, l); + continue; + } + + n->line = l; + + while( 1 ) + { + int comp; + + if( (node_pt)0 == *w ) + { + *w = n; + break; + } + + comp = strcmp((*w)->value, n->value); + if( comp < 0 ) w = &(*w)->next; + else w = &(*w)->prev; + } + } + + (void)fclose(fp); + + dump(name, head, mf, debug); + + rv = PR_GetMallocCount(); + PR_ClearMallocCountdown(); + + release(head); + + return rv; +} + +int nf = 0; +int debug = 0; + +void +test +( + const char *name +) +{ + int n, i; + + extern int nf, debug; + + printf("[%s]: starting test 0\n", name); + n = t2(name, 0, debug); + if( -1 == n ) return; + printf("[%s]: test 0 had %ld allocations.\n", name, n); + + if( 0 >= n ) return; + + for( i = 0; i < nf; i++ ) + { + int which = rand() % n; + if( 0 == which ) printf("[%s]: starting test %d -- no allocation should fail\n", name, i+1); + else printf("[%s]: starting test %d -- allocation %d should fail\n", name, i+1, which); + (void)t2(name, which, debug); + printf("[%s]: test %d done.\n", name, i+1); + } + + return; +} + +int main(int argc, char **argv) +{ + int okay = 0; + int multithread = 0; + + struct threadlist + { + struct threadlist *next; + PRThread *thread; + } + *threadhead = (struct threadlist *)0; + + extern int nf, debug; + + srand(time(0)); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + printf("[main]: We %s using the debugging malloc.\n", + PR_IsDebuggingMalloc() ? "ARE" : "ARE NOT"); + + while( argv++, --argc ) + { + if( '-' == argv[0][0] ) + { + switch( argv[0][1] ) + { + case 'f': + nf = atoi(argv[0][2] ? &argv[0][2] : + --argc ? *++argv : "0"); + break; + case 'd': + debug = 1; + break; + case 'n': + debug = 0; + break; + case 'm': + multithread = 1; + break; + case 's': + multithread = 0; + break; + default: + usage(); + break; + } + } + else + { + FILE *fp = fopen(*argv, "r"); + if( (FILE *)0 == fp ) + { + fprintf(stderr, "Cannot open \"%s.\"\n", *argv); + continue; + } + + okay++; + (void)fclose(fp); + if( multithread ) + { + struct threadlist *n; + + n = (struct threadlist *)malloc(sizeof(struct threadlist)); + if( (struct threadlist *)0 == n ) + { + fprintf(stderr, "This is getting tedious. \"%s\"\n", *argv); + continue; + } + + n->next = threadhead; + n->thread = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))test, + *argv, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, + 0); + if( (PRThread *)0 == n->thread ) + { + fprintf(stderr, "Can't create thread for \"%s.\"\n", *argv); + continue; + } + else + { + threadhead = n; + } + } + else + { + test(*argv); + } + } + } + + if( okay == 0 ) usage(); + else while( (struct threadlist *)0 != threadhead ) + { + struct threadlist *x = threadhead->next; + (void)PR_JoinThread(threadhead->thread); + PR_DELETE(threadhead); + threadhead = x; + } + + return 0; +} + diff -Nru nspr-4.9.5/nspr/pr/tests/dceemu.c nspr-4.10.7/nspr/pr/tests/dceemu.c --- nspr-4.9.5/nspr/pr/tests/dceemu.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dceemu.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: dceemu.c +** Description: testing the DCE emulation api +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete). +**/ + +/*********************************************************************** +** Includes +***********************************************************************/ + +#include "prlog.h" +#include "prinit.h" +#include "prpdce.h" + +#include +#include + +#if defined(_PR_DCETHREADS) + +PRIntn failed_already=0; +PRIntn debug_mode=0; + +static PRIntn prmain(PRIntn argc, char **argv) +{ + PRStatus rv; + PRLock *ml = PR_NewLock(); + PRCondVar *cv = PRP_NewNakedCondVar(); + PRIntervalTime tenmsecs = PR_MillisecondsToInterval(10); + + rv = PRP_TryLock(ml); + PR_ASSERT(PR_SUCCESS == rv); + if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; + + rv = PRP_TryLock(ml); + PR_ASSERT(PR_FAILURE == rv); + if ((rv != PR_FAILURE) & (!debug_mode)) failed_already=1; + + rv = PRP_NakedNotify(cv); + PR_ASSERT(PR_SUCCESS == rv); + if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; + + rv = PRP_NakedBroadcast(cv); + PR_ASSERT(PR_SUCCESS == rv); + if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; + + rv = PRP_NakedWait(cv, ml, tenmsecs); + PR_ASSERT(PR_SUCCESS == rv); + if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; + + PR_Unlock(ml); + + rv = PRP_NakedNotify(cv); + PR_ASSERT(PR_SUCCESS == rv); + if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; + + rv = PRP_NakedBroadcast(cv); + PR_ASSERT(PR_SUCCESS == rv); + if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; + + PRP_DestroyNakedCondVar(cv); + PR_DestroyLock(ml); + + if (debug_mode) printf("Test succeeded\n"); + + return 0; + +} /* prmain */ + +#endif /* #if defined(_PR_DCETHREADS) */ + +int main(int argc, char **argv) +{ + +#if defined(_PR_DCETHREADS) + PR_Initialize(prmain, argc, argv, 0); + if(failed_already) + return 1; + else + return 0; +#else + return 0; +#endif +} /* main */ + + +/* decemu.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/depend.c nspr-4.10.7/nspr/pr/tests/depend.c --- nspr-4.9.5/nspr/pr/tests/depend.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/depend.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1996 - Netscape Communications Corporation +** +** +** Name: depend.c +** Description: Test to enumerate the dependencies +* +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ +#include "prinit.h" + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include +#include + +static void PrintVersion( + const char *msg, const PRVersion* info, PRIntn tab) +{ + static const len = 20; + static const char *tabs = {" "}; + + tab *= 2; + if (tab > len) tab = len; + printf("%s", &tabs[len - tab]); + printf("%s ", msg); + printf("%s ", info->id); + printf("%d.%d", info->major, info->minor); + if (0 != info->patch) + printf(".p%d", info->patch); + printf("\n"); +} /* PrintDependency */ + +static void ChaseDependents(const PRVersionInfo *info, PRIntn tab) +{ + PrintVersion("exports", &info->selfExport, tab); + if (NULL != info->importEnumerator) + { + const PRDependencyInfo *dependent = NULL; + while (NULL != (dependent = info->importEnumerator(dependent))) + { + const PRVersionInfo *import = dependent->exportInfoFn(); + PrintVersion("imports", &dependent->importNeeded, tab); + ChaseDependents(import, tab + 1); + } + } +} /* ChaseDependents */ + +static PRVersionInfo hack_export; +static PRVersionInfo dummy_export; +static PRDependencyInfo dummy_imports[2]; + +static const PRVersionInfo *HackExportInfo(void) +{ + hack_export.selfExport.major = 11; + hack_export.selfExport.minor = 10; + hack_export.selfExport.patch = 200; + hack_export.selfExport.id = "Hack"; + hack_export.importEnumerator = NULL; + return &hack_export; +} + +static const PRDependencyInfo *DummyImports( + const PRDependencyInfo *previous) +{ + if (NULL == previous) return &dummy_imports[0]; + else if (&dummy_imports[0] == previous) return &dummy_imports[1]; + else if (&dummy_imports[1] == previous) return NULL; +} /* DummyImports */ + +static const PRVersionInfo *DummyLibVersion(void) +{ + dummy_export.selfExport.major = 1; + dummy_export.selfExport.minor = 0; + dummy_export.selfExport.patch = 0; + dummy_export.selfExport.id = "Dumbass application"; + dummy_export.importEnumerator = DummyImports; + + dummy_imports[0].importNeeded.major = 2; + dummy_imports[0].importNeeded.minor = 0; + dummy_imports[0].importNeeded.patch = 0; + dummy_imports[0].importNeeded.id = "Netscape Portable Runtime"; + dummy_imports[0].exportInfoFn = PR_ExportInfo; + + dummy_imports[1].importNeeded.major = 5; + dummy_imports[1].importNeeded.minor = 1; + dummy_imports[1].importNeeded.patch = 2; + dummy_imports[1].importNeeded.id = "Hack Library"; + dummy_imports[1].exportInfoFn = HackExportInfo; + + return &dummy_export; +} /* DummyLibVersion */ + +int main(int argc, char **argv) +{ + PRIntn tab = 0; + const PRVersionInfo *info = DummyLibVersion(); + const char *buildDate = __DATE__, *buildTime = __TIME__; + + printf("Depend.c build time is %s %s\n", buildDate, buildTime); + + if (NULL != info) ChaseDependents(info, tab); + + return 0; +} /* main */ + +/* depend.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/dll/.cvsignore nspr-4.10.7/nspr/pr/tests/dll/.cvsignore --- nspr-4.9.5/nspr/pr/tests/dll/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dll/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/pr/tests/dll/Makefile.in nspr-4.10.7/nspr/pr/tests/dll/Makefile.in --- nspr-4.9.5/nspr/pr/tests/dll/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dll/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,77 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +CSRCS = mygetval.c mysetval.c + +INCLUDES = -I$(dist_includedir) + +OBJS = $(OBJDIR)/mygetval.$(OBJ_SUFFIX) \ + $(OBJDIR)/mysetval.$(OBJ_SUFFIX) + +ifeq ($(OS_TARGET), WIN16) +W16OBJS = $(subst $(space),$(comma)$(space),$(OBJS)) +endif + +ifeq ($(OS_ARCH), WINNT) +ifeq ($(OS_TARGET), WIN16) +# do nothing +else +RES=$(OBJDIR)/my.res +RESNAME=../../../pr/src/nspr.rc +endif +endif + +ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) +IMPORT_LIBRARY = $(OBJDIR)/my.$(LIB_SUFFIX) +SHARED_LIBRARY = $(OBJDIR)/my.dll +ifeq ($(OS_ARCH), OS2) +MAPFILE = $(OBJDIR)/my.def +GARBAGE += $(MAPFILE) +MKSHLIB += $(MAPFILE) +endif +TARGETS = $(SHARED_LIBRARY) $(IMPORT_LIBRARY) +else +ifdef MKSHLIB +SHARED_LIBRARY = $(OBJDIR)/libmy.$(DLL_SUFFIX) +endif +TARGETS = $(SHARED_LIBRARY) +endif + +# +# To create a loadable module on Darwin, we must override +# -dynamiclib with -bundle. +# +ifeq ($(OS_ARCH),Darwin) +DSO_LDOPTS = -bundle +endif + +include $(topsrcdir)/config/rules.mk + +ifeq ($(OS_TARGET), WIN16) +# Note: The Win16 target: my.dll requires these macros +# to be overridden to build the test .dll +# default values in win16...mk are for release targets. +# +OS_DLL_OPTION = NOCASEEXACT +OS_LIB_FLAGS = -irn +endif + +ifdef SHARED_LIBRARY +export:: $(TARGETS) + +clean:: + rm -rf $(TARGETS) +endif diff -Nru nspr-4.9.5/nspr/pr/tests/dll/my.def nspr-4.10.7/nspr/pr/tests/dll/my.def --- nspr-4.9.5/nspr/pr/tests/dll/my.def 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dll/my.def 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,26 @@ +;+# +;+# This Source Code Form is subject to the terms of the Mozilla Public +;+# License, v. 2.0. If a copy of the MPL was not distributed with this +;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. +;+# +;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS +;+# 1. For all unix platforms, the string ";-" means "remove this line" +;+# 2. For all unix platforms, the string " DATA " will be removed from any +;+# line on which it occurs. +;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. +;+# On AIX, lines containing ";+" will be removed. +;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. +;+# 5. For all unix platforms, after the above processing has taken place, +;+# all characters after the first ";" on the line will be removed. +;+# And for AIX, the first ";" will also be removed. +;+# This file is passed directly to windows. Since ';' is a comment, all UNIX +;+# directives are hidden behind ";", ";+", and ";-" +;+# +;+MY_1.0 { +;+ global: +LIBRARY my ;- +EXPORTS ;- + My_GetValue; + My_SetValue; +;+ local: *; +;+}; diff -Nru nspr-4.9.5/nspr/pr/tests/dll/mygetval.c nspr-4.10.7/nspr/pr/tests/dll/mygetval.c --- nspr-4.9.5/nspr/pr/tests/dll/mygetval.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dll/mygetval.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#if defined(WIN16) +#include +#endif +#include "prtypes.h" + +extern PRIntn my_global; + +PR_IMPLEMENT(PRIntn) My_GetValue() +{ + return my_global; +} + +#if defined(WIN16) +int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg, + WORD cbHeapSize, LPSTR lpszCmdLine ) +{ + return TRUE; +} +#endif /* WIN16 */ + diff -Nru nspr-4.9.5/nspr/pr/tests/dll/mysetval.c nspr-4.10.7/nspr/pr/tests/dll/mysetval.c --- nspr-4.9.5/nspr/pr/tests/dll/mysetval.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dll/mysetval.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,13 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prtypes.h" + +PRIntn my_global = 0; + +PR_IMPLEMENT(void) My_SetValue(PRIntn val) +{ + my_global = val; +} diff -Nru nspr-4.9.5/nspr/pr/tests/dlltest.c nspr-4.10.7/nspr/pr/tests/dlltest.c --- nspr-4.9.5/nspr/pr/tests/dlltest.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dlltest.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,190 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: dlltest.c +** +** Description: test dll functionality. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** 12-June-97 Revert to return code 0 and 1. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +#include "prinit.h" +#include "prlink.h" +#include "prmem.h" +#include "prerror.h" + +#include "plstr.h" + +#include +#include + +typedef PRIntn (PR_CALLBACK *GetFcnType)(void); +typedef void (PR_CALLBACK *SetFcnType)(PRIntn); + +PRIntn failed_already=0; +PRIntn debug_mode; + +int main(int argc, char** argv) +{ + PRLibrary *lib, *lib2; /* two handles to the same library */ + GetFcnType getFcn; + SetFcnType setFcn; + PRIntn value; + PRStatus status; + char *libName; + + if (argc >= 2 && PL_strcmp(argv[1], "-d") == 0) { + debug_mode = 1; + } + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + /* + * Test 1: load the library, look up the symbols, call the functions, + * and check the results. + */ + + libName = PR_GetLibraryName("dll", "my"); + if (debug_mode) printf("Loading library %s\n", libName); + lib = PR_LoadLibrary(libName); + PR_FreeLibraryName(libName); + if (lib == NULL) { + PRInt32 textLength = PR_GetErrorTextLength(); + char *text = (char*)PR_MALLOC(textLength + 1); + text[0] = '\0'; + (void)PR_GetErrorText(text); + fprintf( + stderr, "PR_LoadLibrary failed (%d, %d, %s)\n", + PR_GetError(), PR_GetOSError(), text); + if (!debug_mode) failed_already=1; + } + getFcn = (GetFcnType) PR_FindSymbol(lib, "My_GetValue"); + setFcn = (SetFcnType) PR_FindFunctionSymbol(lib, "My_SetValue"); + (*setFcn)(888); + value = (*getFcn)(); + if (value != 888) { + fprintf(stderr, "Test 1 failed: set value to 888, but got %d\n", value); + if (!debug_mode) failed_already=1; + } + if (debug_mode) printf("Test 1 passed\n"); + + /* + * Test 2: get a second handle to the same library (this should increment + * the reference count), look up the symbols, call the functions, and + * check the results. + */ + + getFcn = (GetFcnType) PR_FindSymbolAndLibrary("My_GetValue", &lib2); + if (NULL == getFcn || lib != lib2) { + fprintf(stderr, "Test 2 failed: handles for the same library are not " + "equal: handle 1: %p, handle 2: %p\n", lib, lib2); + if (!debug_mode) failed_already=1; + } + setFcn = (SetFcnType) PR_FindSymbol(lib2, "My_SetValue"); + value = (*getFcn)(); + if (value != 888) { + fprintf(stderr, "Test 2 failed: value should be 888, but got %d\n", + value); + if (!debug_mode) failed_already=1; + } + (*setFcn)(777); + value = (*getFcn)(); + if (value != 777) { + fprintf(stderr, "Test 2 failed: set value to 777, but got %d\n", value); + if (!debug_mode) failed_already=1; + goto exit_now; + } + if (debug_mode) printf("Test 2 passed\n"); + + /* + * Test 3: unload the library. The library should still be accessible + * via the second handle. do the same things as above. + */ + + status = PR_UnloadLibrary(lib); + if (PR_FAILURE == status) { + fprintf(stderr, "Test 3 failed: cannot unload library: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + if (!debug_mode) failed_already=1; + goto exit_now; + } + getFcn = (GetFcnType) PR_FindFunctionSymbol(lib2, "My_GetValue"); + setFcn = (SetFcnType) PR_FindSymbol(lib2, "My_SetValue"); + (*setFcn)(666); + value = (*getFcn)(); + if (value != 666) { + fprintf(stderr, "Test 3 failed: set value to 666, but got %d\n", value); + if (!debug_mode) failed_already=1; + goto exit_now; + } + if (debug_mode) printf("Test 3 passed\n"); + + /* + * Test 4: unload the library, testing the reference count mechanism. + */ + + status = PR_UnloadLibrary(lib2); + if (PR_FAILURE == status) { + fprintf(stderr, "Test 4 failed: cannot unload library: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + if (!debug_mode) failed_already=1; + goto exit_now; + } + getFcn = (GetFcnType) PR_FindFunctionSymbolAndLibrary("My_GetValue", &lib2); + if (NULL != getFcn) { + fprintf(stderr, "Test 4 failed: how can we find a symbol " + "in an already unloaded library?\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + if (debug_mode) { + printf("Test 4 passed\n"); + } + + /* + ** Test 5: LoadStaticLibrary() + */ + { + PRStaticLinkTable slt[10]; + PRLibrary *lib; + + lib = PR_LoadStaticLibrary( "my.dll", slt ); + if ( lib == NULL ) + { + fprintf(stderr, "Test 5: LoadStatiLibrary() failed\n" ); + goto exit_now; + } + if (debug_mode) + { + printf("Test 5 passed\n"); + } + } + + goto exit_now; +exit_now: + PR_Cleanup(); + + if (failed_already) { + printf("FAILED\n"); + return 1; + } else { + printf("PASSED\n"); + return 0; + } +} diff -Nru nspr-4.9.5/nspr/pr/tests/dtoa.c nspr-4.10.7/nspr/pr/tests/dtoa.c --- nspr-4.9.5/nspr/pr/tests/dtoa.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/dtoa.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,213 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/****************************************************************************** + * + * This file contains a test program for the function conversion functions + * for double precision code: + * PR_strtod + * PR_dtoa + * PR_cnvtf + * + * This file was ns/nspr/tests/dtoa.c, created by rrj on 1996/06/22. + * + *****************************************************************************/ +#include +#include +#include +#include +#include +#include "prprf.h" +#include "prdtoa.h" + +static int failed_already = 0; + +int main(int argc, char **argv) +{ + double num; + double num1; + double zero = 0.0; + char cnvt[50]; + char *thousands; + + num = 1e24; + num1 = PR_strtod("1e24",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n","1e24"); + failed_already = 1; + } + + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("1e+24",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + num = 0.001e7; + num1 = PR_strtod("0.001e7",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n","0.001e7"); + failed_already = 1; + } + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("10000",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + num = 0.0000000000000753; + num1 = PR_strtod("0.0000000000000753",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n", + "0.0000000000000753"); + failed_already = 1; + } + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("7.53e-14",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + num = 1.867e73; + num1 = PR_strtod("1.867e73",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n","1.867e73"); + failed_already = 1; + } + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("1.867e+73",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + + num = -1.867e73; + num1 = PR_strtod("-1.867e73",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e73"); + failed_already = 1; + } + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("-1.867e+73",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + num = -1.867e-73; + num1 = PR_strtod("-1.867e-73",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e-73"); + failed_already = 1; + } + + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("-1.867e-73",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + /* Testing for infinity */ + num = 1.0 / zero; + num1 = PR_strtod("1.867e765",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n","1.867e765"); + failed_already = 1; + } + + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("Infinity",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + num = -1.0 / zero; + num1 = PR_strtod("-1.867e765",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e765"); + failed_already = 1; + } + + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("-Infinity",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + /* Testing for NaN. PR_strtod can't parse "NaN" and "Infinity" */ + num = zero / zero; + + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("NaN",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + num = - zero / zero; + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("NaN",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + num = 1.0000000001e21; + num1 = PR_strtod("1.0000000001e21",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n", + "1.0000000001e21"); + failed_already = 1; + } + + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("1.0000000001e+21",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + num = -1.0000000001e-21; + num1 = PR_strtod("-1.0000000001e-21",NULL); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n", + "-1.0000000001e-21"); + failed_already = 1; + } + PR_cnvtf(cnvt,sizeof(cnvt),20,num); + if(strcmp("-1.0000000001e-21",cnvt) != 0){ + fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt); + failed_already = 1; + } + + /* + * Bug 414772: should not exit with "Zero passed to d2b" in debug + * build. + */ + num1 = PR_strtod("4e-356",NULL); + + /* + * A very long input with ~384K digits. + * Bug 516396: Should not crash. + * Bug 521306: Should return 0 without converting the input. + */ +#define LENGTH (384 * 1024) + thousands = (char *)malloc(LENGTH); + thousands[0] = '0'; + thousands[1] = '.'; + memset(&thousands[2], '1', LENGTH - 3); + thousands[LENGTH - 1] = '\0'; + num = 0; + num1 = PR_strtod(thousands,NULL); + free(thousands); + if(num1 != num){ + fprintf(stderr,"Failed to convert numeric value %s\n", + "0.1111111111111111..."); + failed_already = 1; + } + + if (failed_already) { + printf("FAILED\n"); + } else { + printf("PASSED\n"); + } + return failed_already; +} diff -Nru nspr-4.9.5/nspr/pr/tests/env.c nspr-4.10.7/nspr/pr/tests/env.c --- nspr-4.9.5/nspr/pr/tests/env.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/env.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,190 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: env.c +** Description: Testing environment variable operations +** +*/ +#include "prenv.h" +#include "plgetopt.h" + +#include +#include +#include + +PRIntn debug = 0; +PRIntn verbose = 0; +PRBool failedAlready = PR_FALSE; + +#define ENVNAME "NSPR_ENVIRONMENT_TEST_VARIABLE" +#define ENVVALUE "The expected result" +#define ENVBUFSIZE 256 + +char *envBuf; /* buffer pointer. We leak memory here on purpose! */ + +static char * NewBuffer( size_t size ) +{ + char *buf = malloc( size ); + if ( NULL == buf ) { + printf("env: NewBuffer() failed\n"); + exit(1); + } + return(buf); +} /* end NewBuffer() */ + +int main(int argc, char **argv) +{ + char *value; + PRStatus rc; + + { /* Get command line options */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "vd"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug */ + debug = 1; + break; + case 'v': /* verbose */ + verbose = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } /* end block "Get command line options" */ + +#if 0 + { + /* + ** This uses Windows native environment manipulation + ** as an experiment. Note the separation of namespace! + */ + BOOL rv; + DWORD size; + rv = SetEnvironmentVariable( ENVNAME, ENVVALUE ); + if ( rv == 0 ) { + if (debug) printf("env: Shit! SetEnvironmentVariable() failed\n"); + failedAlready = PR_TRUE; + } + if (verbose) printf("env: SetEnvironmentVariable() worked\n"); + + size = GetEnvironmentVariable( ENVNAME, envBuf, ENVBUFSIZE ); + if ( size == 0 ) { + if (debug) printf("env: Shit! GetEnvironmentVariable() failed. Found: %s\n", envBuf ); + failedAlready = PR_TRUE; + } + if (verbose) printf("env: GetEnvironmentVariable() worked. Found: %s\n", envBuf); + + value = PR_GetEnv( ENVNAME ); + if ( (NULL == value ) || (strcmp( value, ENVVALUE))) { + if (debug) printf( "env: PR_GetEnv() failed retrieving WinNative. Found: %s\n", value); + failedAlready = PR_TRUE; + } + if (verbose) printf("env: PR_GetEnv() worked. Found: %s\n", value); + } +#endif + + /* set an environment variable, read it back */ + envBuf = NewBuffer( ENVBUFSIZE ); + sprintf( envBuf, ENVNAME "=" ENVVALUE ); + rc = PR_SetEnv( envBuf ); + if ( PR_FAILURE == rc ) { + if (debug) printf( "env: PR_SetEnv() failed setting\n"); + failedAlready = PR_TRUE; + } else { + if (verbose) printf("env: PR_SetEnv() worked.\n"); + } + + value = PR_GetEnv( ENVNAME ); + if ( (NULL == value ) || (strcmp( value, ENVVALUE))) { + if (debug) printf( "env: PR_GetEnv() Failed after setting\n" ); + failedAlready = PR_TRUE; + } else { + if (verbose) printf("env: PR_GetEnv() worked after setting it. Found: %s\n", value ); + } + +/* ---------------------------------------------------------------------- */ + /* un-set the variable, using RAW name... should not work */ + envBuf = NewBuffer( ENVBUFSIZE ); + sprintf( envBuf, ENVNAME ); + rc = PR_SetEnv( envBuf ); + if ( PR_FAILURE == rc ) { + if (verbose) printf( "env: PR_SetEnv() not un-set using RAW name. Good!\n"); + } else { + if (debug) printf("env: PR_SetEnv() un-set using RAW name. Bad!\n" ); + failedAlready = PR_TRUE; + } + + value = PR_GetEnv( ENVNAME ); + if ( NULL == value ) { + if (debug) printf("env: PR_GetEnv() after un-set using RAW name. Bad!\n" ); + failedAlready = PR_TRUE; + } else { + if (verbose) printf( "env: PR_GetEnv() after RAW un-set found: %s\n", value ); + } + +/* ---------------------------------------------------------------------- */ + /* set it again ... */ + envBuf = NewBuffer( ENVBUFSIZE ); + sprintf( envBuf, ENVNAME "=" ENVVALUE ); + rc = PR_SetEnv( envBuf ); + if ( PR_FAILURE == rc ) { + if (debug) printf( "env: PR_SetEnv() failed setting the second time.\n"); + failedAlready = PR_TRUE; + } else { + if (verbose) printf("env: PR_SetEnv() worked.\n"); + } + + /* un-set the variable using the form name= */ + envBuf = NewBuffer( ENVBUFSIZE ); + sprintf( envBuf, ENVNAME "=" ); + rc = PR_SetEnv( envBuf ); + if ( PR_FAILURE == rc ) { + if (debug) printf( "env: PR_SetEnv() failed un-setting using name=\n"); + failedAlready = PR_TRUE; + } else { + if (verbose) printf("env: PR_SetEnv() un-set using name= worked\n" ); + } + + value = PR_GetEnv( ENVNAME ); + if (( NULL == value ) || ( 0x00 == *value )) { + if (verbose) printf("env: PR_GetEnv() after un-set using name= worked\n" ); + } else { + if (debug) printf( "env: PR_GetEnv() after un-set using name=. Found: %s\n", value ); + failedAlready = PR_TRUE; + } +/* ---------------------------------------------------------------------- */ + /* un-set the variable using the form name= */ + envBuf = NewBuffer( ENVBUFSIZE ); + sprintf( envBuf, ENVNAME "999=" ); + rc = PR_SetEnv( envBuf ); + if ( PR_FAILURE == rc ) { + if (debug) printf( "env: PR_SetEnv() failed un-setting using name=\n"); + failedAlready = PR_TRUE; + } else { + if (verbose) printf("env: PR_SetEnv() un-set using name= worked\n" ); + } + + value = PR_GetEnv( ENVNAME "999" ); + if (( NULL == value ) || ( 0x00 == *value )) { + if (verbose) printf("env: PR_GetEnv() after un-set using name= worked\n" ); + } else { + if (debug) printf( "env: PR_GetEnv() after un-set using name=. Found: %s\n", value ); + failedAlready = PR_TRUE; + } + +/* ---------------------------------------------------------------------- */ + if (debug || verbose) printf("\n%s\n", (failedAlready)? "FAILED" : "PASSED" ); + return( (failedAlready)? 1 : 0 ); +} /* main() */ + +/* env.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/errcodes.c nspr-4.10.7/nspr/pr/tests/errcodes.c --- nspr-4.9.5/nspr/pr/tests/errcodes.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/errcodes.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: errcodes.c +** +** Description: print nspr error codes +** +*/ +#include "prerror.h" +#include "plgetopt.h" + +#include + +static int _debug_on = 0; + +struct errinfo { + PRErrorCode errcode; + char *errname; +}; + +struct errinfo errcodes[] = { +{PR_OUT_OF_MEMORY_ERROR, "PR_OUT_OF_MEMORY_ERROR"}, +{PR_BAD_DESCRIPTOR_ERROR, "PR_BAD_DESCRIPTOR_ERROR"}, +{PR_WOULD_BLOCK_ERROR, "PR_WOULD_BLOCK_ERROR"}, +{PR_ACCESS_FAULT_ERROR, "PR_ACCESS_FAULT_ERROR"}, +{PR_INVALID_METHOD_ERROR, "PR_INVALID_METHOD_ERROR"}, +{PR_ILLEGAL_ACCESS_ERROR, "PR_ILLEGAL_ACCESS_ERROR"}, +{PR_UNKNOWN_ERROR, "PR_UNKNOWN_ERROR"}, +{PR_PENDING_INTERRUPT_ERROR, "PR_PENDING_INTERRUPT_ERROR"}, +{PR_NOT_IMPLEMENTED_ERROR, "PR_NOT_IMPLEMENTED_ERROR"}, +{PR_IO_ERROR, "PR_IO_ERROR"}, +{PR_IO_TIMEOUT_ERROR, "PR_IO_TIMEOUT_ERROR"}, +{PR_IO_PENDING_ERROR, "PR_IO_PENDING_ERROR"}, +{PR_DIRECTORY_OPEN_ERROR, "PR_DIRECTORY_OPEN_ERROR"}, +{PR_INVALID_ARGUMENT_ERROR, "PR_INVALID_ARGUMENT_ERROR"}, +{PR_ADDRESS_NOT_AVAILABLE_ERROR, "PR_ADDRESS_NOT_AVAILABLE_ERROR"}, +{PR_ADDRESS_NOT_SUPPORTED_ERROR, "PR_ADDRESS_NOT_SUPPORTED_ERROR"}, +{PR_IS_CONNECTED_ERROR, "PR_IS_CONNECTED_ERROR"}, +{PR_BAD_ADDRESS_ERROR, "PR_BAD_ADDRESS_ERROR"}, +{PR_ADDRESS_IN_USE_ERROR, "PR_ADDRESS_IN_USE_ERROR"}, +{PR_CONNECT_REFUSED_ERROR, "PR_CONNECT_REFUSED_ERROR"}, +{PR_NETWORK_UNREACHABLE_ERROR, "PR_NETWORK_UNREACHABLE_ERROR"}, +{PR_CONNECT_TIMEOUT_ERROR, "PR_CONNECT_TIMEOUT_ERROR"}, +{PR_NOT_CONNECTED_ERROR, "PR_NOT_CONNECTED_ERROR"}, +{PR_LOAD_LIBRARY_ERROR, "PR_LOAD_LIBRARY_ERROR"}, +{PR_UNLOAD_LIBRARY_ERROR, "PR_UNLOAD_LIBRARY_ERROR"}, +{PR_FIND_SYMBOL_ERROR, "PR_FIND_SYMBOL_ERROR"}, +{PR_INSUFFICIENT_RESOURCES_ERROR, "PR_INSUFFICIENT_RESOURCES_ERROR"}, +{PR_DIRECTORY_LOOKUP_ERROR, "PR_DIRECTORY_LOOKUP_ERROR"}, +{PR_TPD_RANGE_ERROR, "PR_TPD_RANGE_ERROR"}, +{PR_PROC_DESC_TABLE_FULL_ERROR, "PR_PROC_DESC_TABLE_FULL_ERROR"}, +{PR_SYS_DESC_TABLE_FULL_ERROR, "PR_SYS_DESC_TABLE_FULL_ERROR"}, +{PR_NOT_SOCKET_ERROR, "PR_NOT_SOCKET_ERROR"}, +{PR_NOT_TCP_SOCKET_ERROR, "PR_NOT_TCP_SOCKET_ERROR"}, +{PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "PR_SOCKET_ADDRESS_IS_BOUND_ERROR"}, +{PR_NO_ACCESS_RIGHTS_ERROR, "PR_NO_ACCESS_RIGHTS_ERROR"}, +{PR_OPERATION_NOT_SUPPORTED_ERROR, "PR_OPERATION_NOT_SUPPORTED_ERROR"}, +{PR_PROTOCOL_NOT_SUPPORTED_ERROR, "PR_PROTOCOL_NOT_SUPPORTED_ERROR"}, +{PR_REMOTE_FILE_ERROR, "PR_REMOTE_FILE_ERROR"}, +{PR_BUFFER_OVERFLOW_ERROR, "PR_BUFFER_OVERFLOW_ERROR"}, +{PR_CONNECT_RESET_ERROR, "PR_CONNECT_RESET_ERROR"}, +{PR_RANGE_ERROR, "PR_RANGE_ERROR"}, +{PR_DEADLOCK_ERROR, "PR_DEADLOCK_ERROR"}, +{PR_FILE_IS_LOCKED_ERROR, "PR_FILE_IS_LOCKED_ERROR"}, +{PR_FILE_TOO_BIG_ERROR, "PR_FILE_TOO_BIG_ERROR"}, +{PR_NO_DEVICE_SPACE_ERROR, "PR_NO_DEVICE_SPACE_ERROR"}, +{PR_PIPE_ERROR, "PR_PIPE_ERROR"}, +{PR_NO_SEEK_DEVICE_ERROR, "PR_NO_SEEK_DEVICE_ERROR"}, +{PR_IS_DIRECTORY_ERROR, "PR_IS_DIRECTORY_ERROR"}, +{PR_LOOP_ERROR, "PR_LOOP_ERROR"}, +{PR_NAME_TOO_LONG_ERROR, "PR_NAME_TOO_LONG_ERROR"}, +{PR_FILE_NOT_FOUND_ERROR, "PR_FILE_NOT_FOUND_ERROR"}, +{PR_NOT_DIRECTORY_ERROR, "PR_NOT_DIRECTORY_ERROR"}, +{PR_READ_ONLY_FILESYSTEM_ERROR, "PR_READ_ONLY_FILESYSTEM_ERROR"}, +{PR_DIRECTORY_NOT_EMPTY_ERROR, "PR_DIRECTORY_NOT_EMPTY_ERROR"}, +{PR_FILESYSTEM_MOUNTED_ERROR, "PR_FILESYSTEM_MOUNTED_ERROR"}, +{PR_NOT_SAME_DEVICE_ERROR, "PR_NOT_SAME_DEVICE_ERROR"}, +{PR_DIRECTORY_CORRUPTED_ERROR, "PR_DIRECTORY_CORRUPTED_ERROR"}, +{PR_FILE_EXISTS_ERROR, "PR_FILE_EXISTS_ERROR"}, +{PR_MAX_DIRECTORY_ENTRIES_ERROR, "PR_MAX_DIRECTORY_ENTRIES_ERROR"}, +{PR_INVALID_DEVICE_STATE_ERROR, "PR_INVALID_DEVICE_STATE_ERROR"}, +{PR_DEVICE_IS_LOCKED_ERROR, "PR_DEVICE_IS_LOCKED_ERROR"}, +{PR_NO_MORE_FILES_ERROR, "PR_NO_MORE_FILES_ERROR"}, +{PR_END_OF_FILE_ERROR, "PR_END_OF_FILE_ERROR"}, +{PR_FILE_SEEK_ERROR, "PR_FILE_SEEK_ERROR"}, +{PR_FILE_IS_BUSY_ERROR, "PR_FILE_IS_BUSY_ERROR"}, +{PR_IN_PROGRESS_ERROR, "PR_IN_PROGRESS_ERROR"}, +{PR_ALREADY_INITIATED_ERROR, "PR_ALREADY_INITIATED_ERROR"}, +{PR_GROUP_EMPTY_ERROR, "PR_GROUP_EMPTY_ERROR"}, +{PR_INVALID_STATE_ERROR, "PR_INVALID_STATE_ERROR"}, +{PR_NETWORK_DOWN_ERROR, "PR_NETWORK_DOWN_ERROR"}, +{PR_SOCKET_SHUTDOWN_ERROR, "PR_SOCKET_SHUTDOWN_ERROR"}, +{PR_CONNECT_ABORTED_ERROR, "PR_CONNECT_ABORTED_ERROR"}, +{PR_HOST_UNREACHABLE_ERROR, "PR_HOST_UNREACHABLE_ERROR"} +}; + +int main(int argc, char **argv) +{ + + int count, errnum; + + /* + * -d debug mode + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + count = sizeof(errcodes)/sizeof(errcodes[0]); + printf("\nNumber of error codes = %d\n\n",count); + for (errnum = 0; errnum < count; errnum++) { + printf("%-40s = %d\n",errcodes[errnum].errname, + errcodes[errnum].errcode); + } + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/errset.c nspr-4.10.7/nspr/pr/tests/errset.c --- nspr-4.9.5/nspr/pr/tests/errset.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/errset.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: errset.c +** +** Description: errset.c exercises the functions in prerror.c. +** This code is a unit test of the prerror.c capability. +** +** Note: There's some fluff in here. The guts of the test +** were plagerized from another test. So, sue me. +** +** +*/ +#include "prerror.h" +#include "plgetopt.h" +#include "prlog.h" + +#include +#include + +static int _debug_on = 0; + +struct errinfo { + PRErrorCode errcode; + char *errname; +}; + +struct errinfo errcodes[] = { +{PR_OUT_OF_MEMORY_ERROR, "PR_OUT_OF_MEMORY_ERROR"}, +{PR_UNKNOWN_ERROR, "An intentionally long error message text intended to force a delete of the current errorString buffer and get another one."}, +{PR_BAD_DESCRIPTOR_ERROR, "PR_BAD_DESCRIPTOR_ERROR"}, +{PR_WOULD_BLOCK_ERROR, "PR_WOULD_BLOCK_ERROR"}, +{PR_ACCESS_FAULT_ERROR, "PR_ACCESS_FAULT_ERROR"}, +{PR_INVALID_METHOD_ERROR, "PR_INVALID_METHOD_ERROR"}, +{PR_ILLEGAL_ACCESS_ERROR, "PR_ILLEGAL_ACCESS_ERROR"}, +{PR_UNKNOWN_ERROR, "PR_UNKNOWN_ERROR"}, +{PR_PENDING_INTERRUPT_ERROR, "PR_PENDING_INTERRUPT_ERROR"}, +{PR_NOT_IMPLEMENTED_ERROR, "PR_NOT_IMPLEMENTED_ERROR"}, +{PR_IO_ERROR, "PR_IO_ERROR"}, +{PR_IO_TIMEOUT_ERROR, "PR_IO_TIMEOUT_ERROR"}, +{PR_IO_PENDING_ERROR, "PR_IO_PENDING_ERROR"}, +{PR_DIRECTORY_OPEN_ERROR, "PR_DIRECTORY_OPEN_ERROR"}, +{PR_INVALID_ARGUMENT_ERROR, "PR_INVALID_ARGUMENT_ERROR"}, +{PR_ADDRESS_NOT_AVAILABLE_ERROR, "PR_ADDRESS_NOT_AVAILABLE_ERROR"}, +{PR_ADDRESS_NOT_SUPPORTED_ERROR, "PR_ADDRESS_NOT_SUPPORTED_ERROR"}, +{PR_IS_CONNECTED_ERROR, "PR_IS_CONNECTED_ERROR"}, +{PR_BAD_ADDRESS_ERROR, "PR_BAD_ADDRESS_ERROR"}, +{PR_ADDRESS_IN_USE_ERROR, "PR_ADDRESS_IN_USE_ERROR"}, +{PR_CONNECT_REFUSED_ERROR, "PR_CONNECT_REFUSED_ERROR"}, +{PR_NETWORK_UNREACHABLE_ERROR, "PR_NETWORK_UNREACHABLE_ERROR"}, +{PR_CONNECT_TIMEOUT_ERROR, "PR_CONNECT_TIMEOUT_ERROR"}, +{PR_NOT_CONNECTED_ERROR, "PR_NOT_CONNECTED_ERROR"}, +{PR_LOAD_LIBRARY_ERROR, "PR_LOAD_LIBRARY_ERROR"}, +{PR_UNLOAD_LIBRARY_ERROR, "PR_UNLOAD_LIBRARY_ERROR"}, +{PR_FIND_SYMBOL_ERROR, "PR_FIND_SYMBOL_ERROR"}, +{PR_INSUFFICIENT_RESOURCES_ERROR, "PR_INSUFFICIENT_RESOURCES_ERROR"}, +{PR_DIRECTORY_LOOKUP_ERROR, "PR_DIRECTORY_LOOKUP_ERROR"}, +{PR_TPD_RANGE_ERROR, "PR_TPD_RANGE_ERROR"}, +{PR_PROC_DESC_TABLE_FULL_ERROR, "PR_PROC_DESC_TABLE_FULL_ERROR"}, +{PR_SYS_DESC_TABLE_FULL_ERROR, "PR_SYS_DESC_TABLE_FULL_ERROR"}, +{PR_NOT_SOCKET_ERROR, "PR_NOT_SOCKET_ERROR"}, +{PR_NOT_TCP_SOCKET_ERROR, "PR_NOT_TCP_SOCKET_ERROR"}, +{PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "PR_SOCKET_ADDRESS_IS_BOUND_ERROR"}, +{PR_NO_ACCESS_RIGHTS_ERROR, "PR_NO_ACCESS_RIGHTS_ERROR"}, +{PR_OPERATION_NOT_SUPPORTED_ERROR, "PR_OPERATION_NOT_SUPPORTED_ERROR"}, +{PR_PROTOCOL_NOT_SUPPORTED_ERROR, "PR_PROTOCOL_NOT_SUPPORTED_ERROR"}, +{PR_REMOTE_FILE_ERROR, "PR_REMOTE_FILE_ERROR"}, +{PR_BUFFER_OVERFLOW_ERROR, "PR_BUFFER_OVERFLOW_ERROR"}, +{PR_CONNECT_RESET_ERROR, "PR_CONNECT_RESET_ERROR"}, +{PR_RANGE_ERROR, "PR_RANGE_ERROR"}, +{PR_DEADLOCK_ERROR, "PR_DEADLOCK_ERROR"}, +{PR_FILE_IS_LOCKED_ERROR, "PR_FILE_IS_LOCKED_ERROR"}, +{PR_FILE_TOO_BIG_ERROR, "PR_FILE_TOO_BIG_ERROR"}, +{PR_NO_DEVICE_SPACE_ERROR, "PR_NO_DEVICE_SPACE_ERROR"}, +{PR_PIPE_ERROR, "PR_PIPE_ERROR"}, +{PR_NO_SEEK_DEVICE_ERROR, "PR_NO_SEEK_DEVICE_ERROR"}, +{PR_IS_DIRECTORY_ERROR, "PR_IS_DIRECTORY_ERROR"}, +{PR_LOOP_ERROR, "PR_LOOP_ERROR"}, +{PR_NAME_TOO_LONG_ERROR, "PR_NAME_TOO_LONG_ERROR"}, +{PR_FILE_NOT_FOUND_ERROR, "PR_FILE_NOT_FOUND_ERROR"}, +{PR_NOT_DIRECTORY_ERROR, "PR_NOT_DIRECTORY_ERROR"}, +{PR_READ_ONLY_FILESYSTEM_ERROR, "PR_READ_ONLY_FILESYSTEM_ERROR"}, +{PR_DIRECTORY_NOT_EMPTY_ERROR, "PR_DIRECTORY_NOT_EMPTY_ERROR"}, +{PR_FILESYSTEM_MOUNTED_ERROR, "PR_FILESYSTEM_MOUNTED_ERROR"}, +{PR_NOT_SAME_DEVICE_ERROR, "PR_NOT_SAME_DEVICE_ERROR"}, +{PR_DIRECTORY_CORRUPTED_ERROR, "PR_DIRECTORY_CORRUPTED_ERROR"}, +{PR_FILE_EXISTS_ERROR, "PR_FILE_EXISTS_ERROR"}, +{PR_MAX_DIRECTORY_ENTRIES_ERROR, "PR_MAX_DIRECTORY_ENTRIES_ERROR"}, +{PR_INVALID_DEVICE_STATE_ERROR, "PR_INVALID_DEVICE_STATE_ERROR"}, +{PR_DEVICE_IS_LOCKED_ERROR, "PR_DEVICE_IS_LOCKED_ERROR"}, +{PR_NO_MORE_FILES_ERROR, "PR_NO_MORE_FILES_ERROR"}, +{PR_END_OF_FILE_ERROR, "PR_END_OF_FILE_ERROR"}, +{PR_FILE_SEEK_ERROR, "PR_FILE_SEEK_ERROR"}, +{PR_FILE_IS_BUSY_ERROR, "PR_FILE_IS_BUSY_ERROR"}, +{PR_IN_PROGRESS_ERROR, "PR_IN_PROGRESS_ERROR"}, +{PR_ALREADY_INITIATED_ERROR, "PR_ALREADY_INITIATED_ERROR"}, +{PR_GROUP_EMPTY_ERROR, "PR_GROUP_EMPTY_ERROR"}, +{PR_INVALID_STATE_ERROR, "PR_INVALID_STATE_ERROR"}, +{PR_NETWORK_DOWN_ERROR, "PR_NETWORK_DOWN_ERROR"}, +{PR_SOCKET_SHUTDOWN_ERROR, "PR_SOCKET_SHUTDOWN_ERROR"}, +{PR_CONNECT_ABORTED_ERROR, "PR_CONNECT_ABORTED_ERROR"}, +{PR_HOST_UNREACHABLE_ERROR, "PR_HOST_UNREACHABLE_ERROR"} +}; + +int main(int argc, char **argv) +{ + + int count, errnum; + + /* + * -d debug mode + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + count = sizeof(errcodes)/sizeof(errcodes[0]); + printf("\nNumber of error codes = %d\n\n",count); + for (errnum = 0; errnum < count; errnum++) { + PRInt32 len1, len2, err; + char msg[256]; + + PR_SetError( errnum, -5 ); + err = PR_GetError(); + PR_ASSERT( err == errnum ); + err = PR_GetOSError(); + PR_ASSERT( err == -5 ); + PR_SetErrorText( strlen(errcodes[errnum].errname), errcodes[errnum].errname ); + len1 = PR_GetErrorTextLength(); + len2 = PR_GetErrorText( msg ); + PR_ASSERT( len1 == len2 ); + printf("%5.5d -- %s\n", errnum, msg ); + } + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/exit.c nspr-4.10.7/nspr/pr/tests/exit.c --- nspr-4.9.5/nspr/pr/tests/exit.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/exit.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prprf.h" +#include "prinit.h" +#include "prthread.h" +#include "prproces.h" +#include "prinrval.h" + +#include "plgetopt.h" + +#include + +static PRInt32 dally = 0; +static PRFileDesc *err = NULL; +static PRBool verbose = PR_FALSE, force = PR_FALSE; + +static void Help(void) +{ + PR_fprintf(err, "Usage: [-t s] [-h]\n"); + PR_fprintf(err, "\t-d Verbose output (default: FALSE)\n"); + PR_fprintf(err, "\t-x Forced termination (default: FALSE)\n"); + PR_fprintf(err, "\t-t Time for thread to block (default: 10 seconds)\n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); +} /* Help */ + +static void Dull(void *arg) +{ + PR_Sleep(PR_SecondsToInterval(dally)); + if (verbose && force) + PR_fprintf(err, "If you see this, the test failed\n"); +} /* Dull */ + +static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "ht:dx"); + + err = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* verbosity */ + verbose = PR_TRUE; + break; + case 'x': /* force exit */ + force = PR_TRUE; + break; + case 't': /* seconds to dally in child */ + dally = atoi(opt->value); + break; + case 'h': /* user wants some guidance */ + default: + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + } + } + PL_DestroyOptState(opt); + + if (0 == dally) dally = 10; + + /* + * Create LOCAL and GLOBAL threads + */ + (void)PR_CreateThread( + PR_USER_THREAD, Dull, NULL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); + + (void)PR_CreateThread( + PR_USER_THREAD, Dull, NULL, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); + + if (verbose) + PR_fprintf( + err, "Main is exiting now. Program should exit %s.\n", + (force) ? "immediately" : "after child dally time"); + + if (force) + { + PR_ProcessExit(0); + if (verbose) + { + PR_fprintf(err, "You should not have gotten here.\n"); + return 1; + } + } + return 0; + +} + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/fdcach.c nspr-4.10.7/nspr/pr/tests/fdcach.c --- nspr-4.9.5/nspr/pr/tests/fdcach.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/fdcach.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,227 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: fdcach.c + * Description: + * This test verifies that the fd cache and stack are working + * correctly. + */ + +#include "nspr.h" + +#include +#include + +/* + * Define ORDER_PRESERVED if the implementation of PR_SetFDCacheSize + * preserves the ordering of the fd's when moving them between the + * cache and the stack. + */ +#define ORDER_PRESERVED 1 + +/* + * NUM_FDS must be <= FD_CACHE_SIZE. + */ +#define FD_CACHE_SIZE 1024 +#define NUM_FDS 20 + +int main(int argc, char **argv) +{ + int i; + PRFileDesc *fds[NUM_FDS]; + PRFileDesc *savefds[NUM_FDS]; + int numfds = sizeof(fds)/sizeof(fds[0]); + + /* + * Switch between cache and stack when they are empty. + * Then start with the fd cache. + */ + PR_SetFDCacheSize(0, FD_CACHE_SIZE); + PR_SetFDCacheSize(0, 0); + PR_SetFDCacheSize(0, FD_CACHE_SIZE); + + /* Add some fd's to the fd cache. */ + for (i = 0; i < numfds; i++) { + savefds[i] = PR_NewTCPSocket(); + if (NULL == savefds[i]) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + } + for (i = 0; i < numfds; i++) { + if (PR_Close(savefds[i]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + + /* + * Create some fd's. These fd's should come from + * the fd cache. Verify the FIFO ordering of the fd + * cache. + */ + for (i = 0; i < numfds; i++) { + fds[i] = PR_NewTCPSocket(); + if (NULL == fds[i]) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + if (fds[i] != savefds[i]) { + fprintf(stderr, "fd cache malfunctioned\n"); + exit(1); + } + } + /* Put the fd's back to the fd cache. */ + for (i = 0; i < numfds; i++) { + if (PR_Close(savefds[i]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + + /* Switch to the fd stack. */ + PR_SetFDCacheSize(0, 0); + + /* + * Create some fd's. These fd's should come from + * the fd stack. + */ + for (i = 0; i < numfds; i++) { + fds[i] = PR_NewTCPSocket(); + if (NULL == fds[i]) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } +#ifdef ORDER_PRESERVED + if (fds[i] != savefds[numfds-1-i]) { + fprintf(stderr, "fd stack malfunctioned\n"); + exit(1); + } +#else + savefds[numfds-1-i] = fds[i]; +#endif + } + /* Put the fd's back to the fd stack. */ + for (i = 0; i < numfds; i++) { + if (PR_Close(savefds[i]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + + /* + * Now create some fd's and verify the LIFO ordering of + * the fd stack. + */ + for (i = 0; i < numfds; i++) { + fds[i] = PR_NewTCPSocket(); + if (NULL == fds[i]) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + if (fds[i] != savefds[numfds-1-i]) { + fprintf(stderr, "fd stack malfunctioned\n"); + exit(1); + } + } + /* Put the fd's back to the fd stack. */ + for (i = 0; i < numfds; i++) { + if (PR_Close(savefds[i]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + + /* Switch to the fd cache. */ + PR_SetFDCacheSize(0, FD_CACHE_SIZE); + + for (i = 0; i < numfds; i++) { + fds[i] = PR_NewTCPSocket(); + if (NULL == fds[i]) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } +#ifdef ORDER_PRESERVED + if (fds[i] != savefds[i]) { + fprintf(stderr, "fd cache malfunctioned\n"); + exit(1); + } +#else + savefds[i] = fds[i]; +#endif + } + for (i = 0; i < numfds; i++) { + if (PR_Close(savefds[i]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + + for (i = 0; i < numfds; i++) { + fds[i] = PR_NewTCPSocket(); + if (NULL == fds[i]) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + if (fds[i] != savefds[i]) { + fprintf(stderr, "fd cache malfunctioned\n"); + exit(1); + } + } + for (i = 0; i < numfds; i++) { + if (PR_Close(savefds[i]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + + /* Switch to the fd stack. */ + PR_SetFDCacheSize(0, 0); + + for (i = 0; i < numfds; i++) { + fds[i] = PR_NewTCPSocket(); + if (NULL == fds[i]) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } +#ifdef ORDER_PRESERVED + if (fds[i] != savefds[numfds-1-i]) { + fprintf(stderr, "fd stack malfunctioned\n"); + exit(1); + } +#else + savefds[numfds-1-i]; +#endif + } + for (i = 0; i < numfds; i++) { + if (PR_Close(savefds[i]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + + for (i = 0; i < numfds; i++) { + fds[i] = PR_NewTCPSocket(); + if (NULL == fds[i]) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + if (fds[i] != savefds[numfds-1-i]) { + fprintf(stderr, "fd stack malfunctioned\n"); + exit(1); + } + } + for (i = 0; i < numfds; i++) { + if (PR_Close(savefds[i]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + + PR_Cleanup(); + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/fileio.c nspr-4.10.7/nspr/pr/tests/fileio.c --- nspr-4.9.5/nspr/pr/tests/fileio.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/fileio.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,206 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: fileio.c +** +** Description: Program to copy one file to another. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete). +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +#include "prinit.h" +#include "prthread.h" +#include "prlock.h" +#include "prcvar.h" +#include "prmon.h" +#include "prmem.h" +#include "prio.h" +#include "prlog.h" + +#include + +#include "obsolete/prsem.h" + + +#define TBSIZE 1024 + +static PRUint8 tbuf[TBSIZE]; + +static PRFileDesc *t1, *t2; + +PRIntn failed_already=0; +PRIntn debug_mode; +static void InitialSetup(void) +{ + PRUintn i; + PRInt32 nWritten, rv; + + t1 = PR_Open("t1.tmp", PR_CREATE_FILE | PR_RDWR, 0); + PR_ASSERT(t1 != NULL); + + for (i=0; i= 0) { + buf[i].nbytes = nbytes; + PR_PostSem(fullBufs); + i = (i + 1) % 2; + } + } while (nbytes > 0); +} + +static void PR_CALLBACK writer(void *arg) +{ + PRUintn i = 0; + PRInt32 nbytes; + + do { + (void) PR_WaitSem(fullBufs); + nbytes = buf[i].nbytes; + if (nbytes > 0) { + nbytes = PR_Write((PRFileDesc*)arg, buf[i].data, nbytes); + PR_PostSem(emptyBufs); + i = (i + 1) % 2; + } + } while (nbytes > 0); +} + +int main(int argc, char **argv) +{ + PRThread *r, *w; + + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + emptyBufs = PR_NewSem(2); /* two empty buffers */ + + fullBufs = PR_NewSem(0); /* zero full buffers */ + + /* Create initial temp file setup */ + InitialSetup(); + + /* create the reader thread */ + + r = PR_CreateThread(PR_USER_THREAD, + reader, t1, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + w = PR_CreateThread(PR_USER_THREAD, + writer, t2, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + /* Do the joining for both threads */ + (void) PR_JoinThread(r); + (void) PR_JoinThread(w); + + /* Do the verification and clean up */ + VerifyAndCleanup(); + + PR_DestroySem(emptyBufs); + PR_DestroySem(fullBufs); + + PR_Cleanup(); + + if(failed_already) + { + printf("Fail\n"); + return 1; + } + else + { + printf("PASS\n"); + return 0; + } + + +} diff -Nru nspr-4.9.5/nspr/pr/tests/foreign.c nspr-4.10.7/nspr/pr/tests/foreign.c --- nspr-4.9.5/nspr/pr/tests/foreign.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/foreign.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,351 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: foreign.c +** Description: Testing various functions w/ foreign threads +** +** We create a thread and get it to call exactly one runtime function. +** The thread is allowed to be created by some other environment that +** NSPR, but it does not announce itself to the runtime prior to calling +** in. +** +** The goal: try to survive. +** +*/ + +#include "prcvar.h" +#include "prenv.h" +#include "prerror.h" +#include "prinit.h" +#include "prinrval.h" +#include "prio.h" +#include "prlock.h" +#include "prlog.h" +#include "prmem.h" +#include "prthread.h" +#include "prtypes.h" +#include "prprf.h" +#include "plgetopt.h" + +#include +#include + +static enum { + thread_nspr, thread_pthread, thread_sproc, thread_win32 +} thread_provider; + +typedef void (*StartFn)(void*); +typedef struct StartObject +{ + StartFn start; + void *arg; +} StartObject; + +static PRFileDesc *output; + +static int _debug_on = 0; + +#define DEFAULT_THREAD_COUNT 10 + +#define DPRINTF(arg) if (_debug_on) PR_fprintf arg + +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) +#include +#include "md/_pth.h" +static void *pthread_start(void *arg) +{ + StartFn start = ((StartObject*)arg)->start; + void *data = ((StartObject*)arg)->arg; + PR_Free(arg); + start(data); + return NULL; +} /* pthread_start */ +#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ + +#if defined(IRIX) && !defined(_PR_PTHREADS) +#include +#include +static void sproc_start(void *arg, PRSize size) +{ + StartObject *so = (StartObject*)arg; + StartFn start = so->start; + void *data = so->arg; + PR_Free(so); + start(data); +} /* sproc_start */ +#endif /* defined(IRIX) && !defined(_PR_PTHREADS) */ + +#if defined(WIN32) +#include +#include /* for _beginthreadex() */ + +static PRUintn __stdcall windows_start(void *arg) +{ + StartObject *so = (StartObject*)arg; + StartFn start = so->start; + void *data = so->arg; + PR_Free(so); + start(data); + return 0; +} /* windows_start */ +#endif /* defined(WIN32) */ + +static PRStatus NSPRPUB_TESTS_CreateThread(StartFn start, void *arg) +{ + PRStatus rv; + + switch (thread_provider) + { + case thread_nspr: + { + PRThread *thread = PR_CreateThread( + PR_USER_THREAD, start, arg, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS; + } + break; + case thread_pthread: +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) + { + int rv; + pthread_t id; + pthread_attr_t tattr; + StartObject *start_object; + start_object = PR_NEW(StartObject); + PR_ASSERT(NULL != start_object); + start_object->start = start; + start_object->arg = arg; + + rv = _PT_PTHREAD_ATTR_INIT(&tattr); + PR_ASSERT(0 == rv); + + rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); + PR_ASSERT(0 == rv); + + rv = pthread_attr_setstacksize(&tattr, 64 * 1024); + PR_ASSERT(0 == rv); + + rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object); + (void)_PT_PTHREAD_ATTR_DESTROY(&tattr); + return (0 == rv) ? PR_SUCCESS : PR_FAILURE; + } +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; + break; +#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ + + case thread_sproc: +#if defined(IRIX) && !defined(_PR_PTHREADS) + { + PRInt32 pid; + StartObject *start_object; + start_object = PR_NEW(StartObject); + PR_ASSERT(NULL != start_object); + start_object->start = start; + start_object->arg = arg; + pid = sprocsp( + sproc_start, PR_SALL, start_object, NULL, 64 * 1024); + rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE; + } +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; +#endif /* defined(IRIX) && !defined(_PR_PTHREADS) */ + break; + case thread_win32: +#if defined(WIN32) + { + void *th; + PRUintn id; + StartObject *start_object; + start_object = PR_NEW(StartObject); + PR_ASSERT(NULL != start_object); + start_object->start = start; + start_object->arg = arg; + th = (void*)_beginthreadex( + NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */ + 0U, /* DWORD - initial thread stack size, in bytes */ + windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */ + start_object, /* LPVOID - argument for new thread */ + STACK_SIZE_PARAM_IS_A_RESERVATION, /*DWORD dwCreationFlags - creation flags */ + &id /* LPDWORD - pointer to returned thread identifier */ ); + + rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS; + } +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; +#endif + break; + default: + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; + } + return rv; +} /* NSPRPUB_TESTS_CreateThread */ + +static void PR_CALLBACK lazyEntry(void *arg) +{ + PR_ASSERT(NULL == arg); +} /* lazyEntry */ + + +static void OneShot(void *arg) +{ + PRUintn pdkey; + PRLock *lock; + PRFileDesc *fd; + PRDir *dir; + PRFileDesc *pair[2]; + PRIntn test = (PRIntn)arg; + + for (test = 0; test < 12; ++test) { + + switch (test) + { + case 0: + lock = PR_NewLock(); + DPRINTF((output,"Thread[0x%x] called PR_NewLock\n", + PR_GetCurrentThread())); + PR_DestroyLock(lock); + break; + + case 1: + (void)PR_SecondsToInterval(1); + DPRINTF((output,"Thread[0x%x] called PR_SecondsToInterval\n", + PR_GetCurrentThread())); + break; + + case 2: (void)PR_CreateThread( + PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); + DPRINTF((output,"Thread[0x%x] called PR_CreateThread\n", + PR_GetCurrentThread())); + break; + + case 3: + fd = PR_Open("foreign.tmp", PR_CREATE_FILE | PR_RDWR, 0666); + DPRINTF((output,"Thread[0x%x] called PR_Open\n", + PR_GetCurrentThread())); + PR_Close(fd); + break; + + case 4: + fd = PR_NewUDPSocket(); + DPRINTF((output,"Thread[0x%x] called PR_NewUDPSocket\n", + PR_GetCurrentThread())); + PR_Close(fd); + break; + + case 5: + fd = PR_NewTCPSocket(); + DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocket\n", + PR_GetCurrentThread())); + PR_Close(fd); + break; + + case 6: +#ifdef SYMBIAN +#define TEMP_DIR "c:\\data\\" +#else +#define TEMP_DIR "/tmp/" +#endif + dir = PR_OpenDir(TEMP_DIR); + DPRINTF((output,"Thread[0x%x] called PR_OpenDir\n", + PR_GetCurrentThread())); + PR_CloseDir(dir); + break; + + case 7: + (void)PR_NewThreadPrivateIndex(&pdkey, NULL); + DPRINTF((output,"Thread[0x%x] called PR_NewThreadPrivateIndex\n", + PR_GetCurrentThread())); + break; + + case 8: + (void)PR_GetEnv("PATH"); + DPRINTF((output,"Thread[0x%x] called PR_GetEnv\n", + PR_GetCurrentThread())); + break; + + case 9: + (void)PR_NewTCPSocketPair(pair); + DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocketPair\n", + PR_GetCurrentThread())); + PR_Close(pair[0]); + PR_Close(pair[1]); + break; + + case 10: + PR_SetConcurrency(2); + DPRINTF((output,"Thread[0x%x] called PR_SetConcurrency\n", + PR_GetCurrentThread())); + break; + + case 11: + PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH); + DPRINTF((output,"Thread[0x%x] called PR_SetThreadPriority\n", + PR_GetCurrentThread())); + break; + + default: + break; + } /* switch() */ + } +} /* OneShot */ + +int main(int argc, char **argv) +{ + PRStatus rv; + PRInt32 thread_cnt = DEFAULT_THREAD_COUNT; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dt:"); + +#if defined(WIN32) + thread_provider = thread_win32; +#elif defined(_PR_PTHREADS) + thread_provider = thread_pthread; +#elif defined(IRIX) + thread_provider = thread_sproc; +#else + thread_provider = thread_nspr; +#endif + + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + case 't': /* thread count */ + thread_cnt = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_SetConcurrency(2); + + output = PR_GetSpecialFD(PR_StandardOutput); + + while (thread_cnt-- > 0) + { + rv = NSPRPUB_TESTS_CreateThread(OneShot, (void*)thread_cnt); + PR_ASSERT(PR_SUCCESS == rv); + PR_Sleep(PR_MillisecondsToInterval(5)); + } + PR_Sleep(PR_SecondsToInterval(3)); + return (PR_SUCCESS == PR_Cleanup()) ? 0 : 1; +} /* main */ + +/* foreign.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/forktest.c nspr-4.10.7/nspr/pr/tests/forktest.c --- nspr-4.9.5/nspr/pr/tests/forktest.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/forktest.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,311 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: forktest.c +** +** Description: UNIX test for fork functions. +** +** Modification History: +** 15-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** 12-June-97 AGarcic - Revert to return code 0 and 1, remove debug option (obsolete). +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include +#include +#include + +PRIntn failed_already=0; + +#ifdef XP_UNIX + +#include +#include +#include +#include + +static char *message = "Hello world!"; + +static void +ClientThreadFunc(void *arg) +{ + PRNetAddr addr; + PRFileDesc *sock = NULL; + PRInt32 tmp = (PRInt32)arg; + + /* + * Make sure the PR_Accept call will block + */ + + printf("Wait one second before connect\n"); + fflush(stdout); + PR_Sleep(PR_SecondsToInterval(1)); + + addr.inet.family = AF_INET; + addr.inet.ip = PR_htonl(INADDR_ANY); + addr.inet.port = 0; + if ((sock = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "failed to create TCP socket: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + if (PR_Bind(sock, &addr) != PR_SUCCESS) { + fprintf(stderr, "PR_Bind failed: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + addr.inet.ip = PR_htonl(INADDR_LOOPBACK); + addr.inet.port = PR_htons((PRInt16)tmp); + printf("Connecting to port %hu\n", PR_ntohs(addr.inet.port)); + fflush(stdout); + if (PR_Connect(sock, &addr, PR_SecondsToInterval(5)) != + PR_SUCCESS) { + fprintf(stderr, "PR_Connect failed: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + printf("Writing message \"%s\"\n", message); + fflush(stdout); + if (PR_Send(sock, message, strlen(message) + 1, 0, PR_INTERVAL_NO_TIMEOUT) == + -1) { + fprintf(stderr, "PR_Send failed: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } +finish: + if (sock) { + PR_Close(sock); + } + return; +} + +/* + * DoIO -- + * This function creates a thread that acts as a client and itself. + * acts as a server. Then it joins the client thread. + */ +static void +DoIO(void) +{ + PRThread *clientThread; + PRFileDesc *listenSock = NULL; + PRFileDesc *sock = NULL; + PRNetAddr addr; + PRInt32 nBytes; + char buf[128]; + + listenSock = PR_NewTCPSocket(); + if (!listenSock) { + fprintf(stderr, "failed to create a TCP socket: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + addr.inet.family = AF_INET; + addr.inet.ip = PR_htonl(INADDR_ANY); + addr.inet.port = 0; + if (PR_Bind(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "failed to bind socket: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "failed to get socket port number: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + if (PR_Listen(listenSock, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + clientThread = PR_CreateThread( PR_USER_THREAD, ClientThreadFunc, + (void *) PR_ntohs(addr.inet.port), PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "Cannot create client thread: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + failed_already = 1; + goto finish; + } + printf("Accepting connection at port %hu\n", PR_ntohs(addr.inet.port)); + fflush(stdout); + sock = PR_Accept(listenSock, &addr, PR_SecondsToInterval(5)); + if (!sock) { + fprintf(stderr, "PR_Accept failed: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + nBytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); + if (nBytes == -1) { + fprintf(stderr, "PR_Recv failed: error code %d\n", + PR_GetError()); + failed_already = 1; + goto finish; + } + + /* + * Make sure it has proper null byte to mark end of string + */ + + buf[sizeof(buf) - 1] = '\0'; + printf("Received \"%s\" from the client\n", buf); + fflush(stdout); + if (!strcmp(buf, message)) { + PR_JoinThread(clientThread); + + printf("The message is received correctly\n"); + fflush(stdout); + } else { + fprintf(stderr, "The message should be \"%s\"\n", + message); + failed_already = 1; + } + +finish: + if (listenSock) { + PR_Close(listenSock); + } + if (sock) { + PR_Close(sock); + } + return; +} + +#ifdef _PR_DCETHREADS + +#include + +pid_t PR_UnixFork1(void) +{ + pid_t parent = getpid(); + int rv = syscall(SYS_fork); + + if (rv == -1) { + return (pid_t) -1; + } else { + /* For each process, rv is the pid of the other process */ + if (rv == parent) { + /* the child */ + return 0; + } else { + /* the parent */ + return rv; + } + } +} + +#elif defined(SOLARIS) + +/* + * It seems like that in Solaris 2.4 one must call fork1() if the + * the child process is going to use thread functions. Solaris 2.5 + * doesn't have this problem. Calling fork() also works. + */ + +pid_t PR_UnixFork1(void) +{ + return fork1(); +} + +#else + +pid_t PR_UnixFork1(void) +{ + return fork(); +} + +#endif /* PR_DCETHREADS */ + +int main(int argc, char **argv) +{ + pid_t pid; + int rv; + + /* main test program */ + + DoIO(); + + pid = PR_UnixFork1(); + + if (pid == (pid_t) -1) { + fprintf(stderr, "Fork failed: errno %d\n", errno); + failed_already=1; + return 1; + } else if (pid > 0) { + int childStatus; + + printf("Fork succeeded. Parent process continues.\n"); + DoIO(); + if ((rv = waitpid(pid, &childStatus, 0)) != pid) { +#if defined(IRIX) && !defined(_PR_PTHREADS) + /* + * nspr may handle SIGCLD signal + */ + if ((rv < 0) && (errno == ECHILD)) { + } else +#endif + { + fprintf(stderr, "waitpid failed: %d\n", errno); + failed_already = 1; + } + } else if (!WIFEXITED(childStatus) + || WEXITSTATUS(childStatus) != 0) { + failed_already = 1; + } + printf("Parent process exits.\n"); + if (!failed_already) { + printf("PASSED\n"); + } else { + printf("FAILED\n"); + } + return failed_already; + } else { +#if defined(IRIX) && !defined(_PR_PTHREADS) + extern void _PR_IRIX_CHILD_PROCESS(void); + _PR_IRIX_CHILD_PROCESS(); +#endif + printf("Fork succeeded. Child process continues.\n"); + DoIO(); + printf("Child process exits.\n"); + return failed_already; + } +} + +#else /* XP_UNIX */ + +int main( int argc, +char *argv[] +) +{ + + printf("The fork test is applicable to Unix only.\n"); + return 0; + +} + +#endif /* XP_UNIX */ diff -Nru nspr-4.9.5/nspr/pr/tests/formattm.c nspr-4.10.7/nspr/pr/tests/formattm.c --- nspr-4.9.5/nspr/pr/tests/formattm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/formattm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A test program for PR_FormatTime and PR_FormatTimeUSEnglish */ + +#include "prtime.h" + +#include + +int main(int argc, char **argv) +{ + char buffer[256]; + char small_buffer[8]; + PRTime now; + PRExplodedTime tod; + + now = PR_Now(); + PR_ExplodeTime(now, PR_LocalTimeParameters, &tod); + + if (PR_FormatTime(buffer, sizeof(buffer), + "%a %b %d %H:%M:%S %Z %Y", &tod) != 0) { + printf("%s\n", buffer); + } else { + fprintf(stderr, "PR_FormatTime(buffer) failed\n"); + return 1; + } + + small_buffer[0] = '?'; + if (PR_FormatTime(small_buffer, sizeof(small_buffer), + "%a %b %d %H:%M:%S %Z %Y", &tod) == 0) { + if (small_buffer[0] != '\0') { + fprintf(stderr, "PR_FormatTime(small_buffer) did not output " + "an empty string on failure\n"); + return 1; + } + printf("%s\n", small_buffer); + } else { + fprintf(stderr, "PR_FormatTime(small_buffer) succeeded " + "unexpectedly\n"); + return 1; + } + + (void)PR_FormatTimeUSEnglish(buffer, sizeof(buffer), + "%a %b %d %H:%M:%S %Z %Y", &tod); + printf("%s\n", buffer); + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/freeif.c nspr-4.10.7/nspr/pr/tests/freeif.c --- nspr-4.9.5/nspr/pr/tests/freeif.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/freeif.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * A test to see if the macros PR_DELETE and PR_FREEIF are + * properly defined. (See Bugzilla bug #39110.) + */ + +#include "nspr.h" + +#include +#include + +static void Noop(void) { } + +static void Fail(void) +{ + printf("FAIL\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + int foo = 1; + char *ptr = NULL; + + /* this fails to compile with the old definition of PR_DELETE */ + if (foo) + PR_DELETE(ptr); + else + Noop(); + + /* this nests incorrectly with the old definition of PR_FREEIF */ + if (foo) + PR_FREEIF(ptr); + else + Fail(); + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/fsync.c nspr-4.10.7/nspr/pr/tests/fsync.c --- nspr-4.9.5/nspr/pr/tests/fsync.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/fsync.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prmem.h" +#include "prprf.h" +#include "prinrval.h" + +#include "plerror.h" +#include "plgetopt.h" + +static PRFileDesc *err = NULL; + +static void Help(void) +{ + PR_fprintf(err, "Usage: [-S] [-K ] [-h] \n"); + PR_fprintf(err, "\t-c Nuber of iterations (default: 10)\n"); + PR_fprintf(err, "\t-S Sync the file (default: FALSE)\n"); + PR_fprintf(err, "\t-K Size of file (K bytes) (default: 10)\n"); + PR_fprintf(err, "\t Name of file to write (default: /usr/tmp/sync.dat)\n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PRStatus rv; + PLOptStatus os; + PRUint8 *buffer; + PRFileDesc *file = NULL; + const char *filename = "sync.dat"; + PRUint32 index, loops, iterations = 10, filesize = 10; + PRIntn flags = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE; + PLOptState *opt = PL_CreateOptState(argc, argv, "hSK:c:"); + PRIntervalTime time, total = 0, shortest = 0x7fffffff, longest = 0; + + err = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: /* Name of file to create */ + filename = opt->value; + break; + case 'S': /* Use sych option on file */ + flags |= PR_SYNC; + break; + case 'K': /* Size of file to write */ + filesize = atoi(opt->value); + break; + case 'c': /* Number of iterations */ + iterations = atoi(opt->value); + break; + case 'h': /* user wants some guidance */ + default: /* user needs some guidance */ + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + } + } + PL_DestroyOptState(opt); + + file = PR_Open(filename, flags, 0666); + if (NULL == file) + { + PL_FPrintError(err, "Failed to open file"); + return 1; + } + + buffer = (PRUint8*)PR_CALLOC(1024); + if (NULL == buffer) + { + PL_FPrintError(err, "Cannot allocate buffer"); + return 1; + } + + for (index = 0; index < sizeof(buffer); ++index) + buffer[index] = (PRUint8)index; + + for (loops = 0; loops < iterations; ++loops) + { + time = PR_IntervalNow(); + for (index = 0; index < filesize; ++index) + { + PR_Write(file, buffer, 1024); + } + time = (PR_IntervalNow() - time); + + total += time; + if (time < shortest) shortest = time; + else if (time > longest) longest = time; + if (0 != PR_Seek(file, 0, PR_SEEK_SET)) + { + PL_FPrintError(err, "Rewinding file"); + return 1; + } + } + + total = total / iterations; + PR_fprintf( + err, "%u iterations over a %u kbyte %sfile: %u [%u] %u\n", + iterations, filesize, ((flags & PR_SYNC) ? "SYNCH'd " : ""), + PR_IntervalToMicroseconds(shortest), + PR_IntervalToMicroseconds(total), + PR_IntervalToMicroseconds(longest)); + + PR_DELETE(buffer); + rv = PR_Close(file); + if (PR_SUCCESS != rv) + { + PL_FPrintError(err, "Closing file failed"); + return 1; + } + rv = PR_Delete(filename); + if (PR_SUCCESS != rv) + { + PL_FPrintError(err, "Deleting file failed"); + return 1; + } + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/getai.c nspr-4.10.7/nspr/pr/tests/getai.c --- nspr-4.9.5/nspr/pr/tests/getai.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/getai.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" + +#include +#include + +int main(int argc, char **argv) +{ + PRAddrInfo *ai; + void *iter; + PRNetAddr addr; + + ai = PR_GetAddrInfoByName(argv[1], PR_AF_UNSPEC, PR_AI_ADDRCONFIG); + if (ai == NULL) { + fprintf(stderr, "PR_GetAddrInfoByName failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + printf("%s\n", PR_GetCanonNameFromAddrInfo(ai)); + iter = NULL; + while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) { + char buf[128]; + PR_NetAddrToString(&addr, buf, sizeof buf); + printf("%s\n", buf); + } + PR_FreeAddrInfo(ai); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/gethost.c nspr-4.10.7/nspr/pr/tests/gethost.c --- nspr-4.9.5/nspr/pr/tests/gethost.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/gethost.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,259 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: gethost.c + * + * Description: tests various functions in prnetdb.h + * + * Usage: gethost [-6] [hostname] + */ + +#include "prio.h" +#include "prnetdb.h" +#include "plgetopt.h" + +#include +#include + +#define DEFAULT_HOST_NAME "mcom.com" + +static void Help(void) +{ + fprintf(stderr, "Usage: gethost [-h] [hostname]\n"); + fprintf(stderr, "\t-h help\n"); + fprintf(stderr, "\thostname Name of host (default: %s)\n", + DEFAULT_HOST_NAME); +} /* Help */ + +/* + * Prints the contents of a PRHostEnt structure + */ +void PrintHostent(const PRHostEnt *he) +{ + int i; + int j; + + printf("h_name: %s\n", he->h_name); + for (i = 0; he->h_aliases[i]; i++) { + printf("h_aliases[%d]: %s\n", i, he->h_aliases[i]); + } + printf("h_addrtype: %d\n", he->h_addrtype); + printf("h_length: %d\n", he->h_length); + for (i = 0; he->h_addr_list[i]; i++) { + printf("h_addr_list[%d]: ", i); + for (j = 0; j < he->h_length; j++) { + if (j != 0) printf("."); + printf("%u", (unsigned char)he->h_addr_list[i][j]); + } + printf("\n"); + } +} + +int main(int argc, char **argv) +{ + const char *hostName = DEFAULT_HOST_NAME; + PRHostEnt he, reversehe; + char buf[PR_NETDB_BUF_SIZE]; + char reversebuf[PR_NETDB_BUF_SIZE]; + PRIntn idx; + PRNetAddr addr; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "h"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 0: /* naked */ + hostName = opt->value; + break; + case 'h': /* Help message */ + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + if (PR_GetHostByName(hostName, buf, sizeof(buf), &he) == PR_FAILURE) { + fprintf(stderr, "PR_GetHostByName failed\n"); + exit(1); + } + PrintHostent(&he); + idx = 0; + while (1) { + idx = PR_EnumerateHostEnt(idx, &he, 0, &addr); + if (idx == -1) { + fprintf(stderr, "PR_EnumerateHostEnt failed\n"); + exit(1); + } + if (idx == 0) break; /* normal loop termination */ + printf("reverse lookup\n"); + if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf), + &reversehe) == PR_FAILURE) { + fprintf(stderr, "PR_GetHostByAddr failed\n"); + exit(1); + } + PrintHostent(&reversehe); + } + + printf("PR_GetIPNodeByName with PR_AF_INET\n"); + if (PR_GetIPNodeByName(hostName, PR_AF_INET, PR_AI_DEFAULT, + buf, sizeof(buf), &he) == PR_FAILURE) { + fprintf(stderr, "PR_GetIPNodeByName failed\n"); + exit(1); + } + PrintHostent(&he); + printf("PR_GetIPNodeByName with PR_AF_INET6\n"); + if (PR_GetIPNodeByName(hostName, PR_AF_INET6, PR_AI_DEFAULT, + buf, sizeof(buf), &he) == PR_FAILURE) { + fprintf(stderr, "PR_GetIPNodeByName failed\n"); + exit(1); + } + PrintHostent(&he); + idx = 0; + printf("PR_GetHostByAddr with PR_AF_INET6\n"); + while (1) { + idx = PR_EnumerateHostEnt(idx, &he, 0, &addr); + if (idx == -1) { + fprintf(stderr, "PR_EnumerateHostEnt failed\n"); + exit(1); + } + if (idx == 0) break; /* normal loop termination */ + printf("reverse lookup\n"); + if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf), + &reversehe) == PR_FAILURE) { + fprintf(stderr, "PR_GetHostByAddr failed\n"); + exit(1); + } + PrintHostent(&reversehe); + } + printf("PR_GetHostByAddr with PR_AF_INET6 done\n"); + + PR_StringToNetAddr("::1", &addr); + if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_TRUE) { + fprintf(stderr, "addr should not be ipv4 mapped address\n"); + exit(1); + } + if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { + fprintf(stderr, "addr should be loopback address\n"); + exit(1); + } + + PR_StringToNetAddr("127.0.0.1", &addr); + if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { + fprintf(stderr, "addr should be loopback address\n"); + exit(1); + } + PR_StringToNetAddr("::FFFF:127.0.0.1", &addr); + if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_FALSE) { + fprintf(stderr, "addr should be ipv4 mapped address\n"); + exit(1); + } + if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { + fprintf(stderr, "addr should be loopback address\n"); + exit(1); + } + + if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_InitializeNetAddr failed\n"); + exit(1); + } + if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { + fprintf(stderr, "addr should be unspecified address\n"); + exit(1); + } + if (PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_InitializeNetAddr failed\n"); + exit(1); + } + if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { + fprintf(stderr, "addr should be loopback address\n"); + exit(1); + } + + if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_SetNetAddr failed\n"); + exit(1); + } + if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { + fprintf(stderr, "addr should be unspecified address\n"); + exit(1); + } + if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_SetNetAddr failed\n"); + exit(1); + } + if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { + fprintf(stderr, "addr should be loopback address\n"); + exit(1); + } + + addr.inet.family = PR_AF_INET; + addr.inet.port = 0; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { + fprintf(stderr, "addr should be unspecified address\n"); + exit(1); + } + { + char buf[256]; + PR_NetAddrToString(&addr, buf, 256); + printf("IPv4 INADDRANY: %s\n", buf); + } + addr.inet.family = PR_AF_INET; + addr.inet.port = 0; + addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { + fprintf(stderr, "addr should be loopback address\n"); + exit(1); + } + { + char buf[256]; + PR_NetAddrToString(&addr, buf, 256); + printf("IPv4 LOOPBACK: %s\n", buf); + } + + if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_SetNetAddr failed\n"); + exit(1); + } + if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) { + fprintf(stderr, "addr should be unspecified address\n"); + exit(1); + } + { + char buf[256]; + PR_NetAddrToString(&addr, buf, 256); + printf("IPv6 INADDRANY: %s\n", buf); + } + if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_SetNetAddr failed\n"); + exit(1); + } + if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) { + fprintf(stderr, "addr should be loopback address\n"); + exit(1); + } + { + char buf[256]; + PR_NetAddrToString(&addr, buf, 256); + printf("IPv6 LOOPBACK: %s\n", buf); + } + { + PRIPv6Addr v6addr; + char tmp_buf[256]; + + PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr); + + PR_ConvertIPv4AddrToIPv6(addr.inet.ip, &v6addr); + PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr); + addr.ipv6.ip = v6addr; + PR_NetAddrToString(&addr, tmp_buf, 256); + printf("IPv4-mapped IPv6 LOOPBACK: %s\n", tmp_buf); + } + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/getproto.c nspr-4.10.7/nspr/pr/tests/getproto.c --- nspr-4.9.5/nspr/pr/tests/getproto.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/getproto.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + ************************************************************************* + * + * File: getproto.c + * + * A test program for PR_GetProtoByName and PR_GetProtoByNumber + * + ************************************************************************* + */ + +#include "plstr.h" +#include "plerror.h" +#include "prinit.h" +#include "prprf.h" +#include "prnetdb.h" +#include "prerror.h" + +int main(int argc, char **argv) +{ + PRFileDesc *prstderr = PR_GetSpecialFD(PR_StandardError); + PRBool failed = PR_FALSE; + PRProtoEnt proto; + char buf[2048]; + PRStatus rv; + + PR_STDIO_INIT(); + rv = PR_GetProtoByName("tcp", buf, sizeof(buf), &proto); + if (PR_FAILURE == rv) { + failed = PR_TRUE; + PL_FPrintError(prstderr, "PR_GetProtoByName failed"); + } + else if (6 != proto.p_num) { + PR_fprintf( + prstderr,"tcp is usually 6, but is %d on this machine\n", + proto.p_num); + } + else PR_fprintf(prstderr, "tcp is protocol number %d\n", proto.p_num); + + rv = PR_GetProtoByName("udp", buf, sizeof(buf), &proto); + if (PR_FAILURE == rv) { + failed = PR_TRUE; + PL_FPrintError(prstderr, "PR_GetProtoByName failed"); + } + else if (17 != proto.p_num) { + PR_fprintf( + prstderr, "udp is usually 17, but is %d on this machine\n", + proto.p_num); + } + else PR_fprintf(prstderr, "udp is protocol number %d\n", proto.p_num); + + rv = PR_GetProtoByNumber(6, buf, sizeof(buf), &proto); + if (PR_FAILURE == rv) { + failed = PR_TRUE; + PL_FPrintError(prstderr, "PR_GetProtoByNumber failed"); + } + else if (PL_strcmp("tcp", proto.p_name)) { + PR_fprintf( + prstderr, "Protocol number 6 is usually tcp, but is %s" + " on this platform\n", proto.p_name); + } + else PR_fprintf(prstderr, "Protocol number 6 is %s\n", proto.p_name); + + rv = PR_GetProtoByNumber(17, buf, sizeof(buf), &proto); + if (PR_FAILURE == rv) { + failed = PR_TRUE; + PL_FPrintError(prstderr, "PR_GetProtoByNumber failed"); + } + else if (PL_strcmp("udp", proto.p_name)) { + PR_fprintf( + prstderr, "Protocol number 17 is usually udp, but is %s" + " on this platform\n", proto.p_name); + } + else PR_fprintf(prstderr, "Protocol number 17 is %s\n", proto.p_name); + + PR_fprintf(prstderr, (failed) ? "FAILED\n" : "PASSED\n"); + return (failed) ? 1 : 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/i2l.c nspr-4.10.7/nspr/pr/tests/i2l.c --- nspr-4.9.5/nspr/pr/tests/i2l.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/i2l.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "prio.h" +#include "prinit.h" +#include "prprf.h" +#include "prlong.h" + +#include "plerror.h" +#include "plgetopt.h" + +typedef union Overlay_i +{ + PRInt32 i; + PRInt64 l; +} Overlay_i; + +typedef union Overlay_u +{ + PRUint32 i; + PRUint64 l; +} Overlay_u; + +static PRFileDesc *err = NULL; + +static void Help(void) +{ + PR_fprintf(err, "Usage: -i n | -u n | -h\n"); + PR_fprintf(err, "\t-i n treat following number as signed integer\n"); + PR_fprintf(err, "\t-u n treat following number as unsigned integer\n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); +} /* Help */ + +static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv) +{ + Overlay_i si; + Overlay_u ui; + PLOptStatus os; + PRBool bsi = PR_FALSE, bui = PR_FALSE; + PLOptState *opt = PL_CreateOptState(argc, argv, "hi:u:"); + err = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'i': /* signed integer */ + si.i = (PRInt32)atoi(opt->value); + bsi = PR_TRUE; + break; + case 'u': /* unsigned */ + ui.i = (PRUint32)atoi(opt->value); + bui = PR_TRUE; + break; + case 'h': /* user wants some guidance */ + default: + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + } + } + PL_DestroyOptState(opt); + +#if defined(HAVE_LONG_LONG) + PR_fprintf(err, "We have long long\n"); +#else + PR_fprintf(err, "We don't have long long\n"); +#endif + + if (bsi) + { + PR_fprintf(err, "Converting %ld: ", si.i); + LL_I2L(si.l, si.i); + PR_fprintf(err, "%lld\n", si.l); + } + + if (bui) + { + PR_fprintf(err, "Converting %lu: ", ui.i); + LL_I2L(ui.l, ui.i); + PR_fprintf(err, "%llu\n", ui.l); + } + return 0; + +} /* main */ + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ + +/* i2l.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/initclk.c nspr-4.10.7/nspr/pr/tests/initclk.c --- nspr-4.9.5/nspr/pr/tests/initclk.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/initclk.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This is a regression test for the bug that the interval timer + * is not initialized when _PR_CreateCPU calls PR_IntervalNow. + * The bug would make this test program finish prematurely, + * when the SHORT_TIMEOUT period expires. The correct behavior + * is for the test to finish when the LONG_TIMEOUT period expires. + */ + +#include "prlock.h" +#include "prcvar.h" +#include "prthread.h" +#include "prinrval.h" +#include "prlog.h" +#include +#include + +/* The timeouts, in milliseconds */ +#define SHORT_TIMEOUT 1000 +#define LONG_TIMEOUT 3000 + +PRLock *lock1, *lock2; +PRCondVar *cv1, *cv2; + +void ThreadFunc(void *arg) +{ + PR_Lock(lock1); + PR_WaitCondVar(cv1, PR_MillisecondsToInterval(SHORT_TIMEOUT)); + PR_Unlock(lock1); +} + +int main(int argc, char **argv) +{ + PRThread *thread; + PRIntervalTime start, end; + PRUint32 elapsed_ms; + + lock1 = PR_NewLock(); + PR_ASSERT(NULL != lock1); + cv1 = PR_NewCondVar(lock1); + PR_ASSERT(NULL != cv1); + lock2 = PR_NewLock(); + PR_ASSERT(NULL != lock2); + cv2 = PR_NewCondVar(lock2); + PR_ASSERT(NULL != cv2); + start = PR_IntervalNow(); + thread = PR_CreateThread( + PR_USER_THREAD, + ThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, + 0); + PR_ASSERT(NULL != thread); + PR_Lock(lock2); + PR_WaitCondVar(cv2, PR_MillisecondsToInterval(LONG_TIMEOUT)); + PR_Unlock(lock2); + PR_JoinThread(thread); + end = PR_IntervalNow(); + elapsed_ms = PR_IntervalToMilliseconds((PRIntervalTime)(end - start)); + /* Allow 100ms imprecision */ + if (elapsed_ms < LONG_TIMEOUT - 100 || elapsed_ms > LONG_TIMEOUT + 100) { + printf("Elapsed time should be %u ms but is %u ms\n", + LONG_TIMEOUT, elapsed_ms); + printf("FAIL\n"); + exit(1); + } + printf("Elapsed time: %u ms, expected time: %u ms\n", + LONG_TIMEOUT, elapsed_ms); + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/inrval.c nspr-4.10.7/nspr/pr/tests/inrval.c --- nspr-4.9.5/nspr/pr/tests/inrval.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/inrval.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,206 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** file: inrval.c +** description: Interval conversion test. +** Modification History: +** 15-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +**/ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prinit.h" +#include "obsolete/pralarm.h" + +#include "prio.h" +#include "prprf.h" +#include "prlock.h" +#include "prlong.h" +#include "prcvar.h" +#include "prinrval.h" +#include "prtime.h" + +#include "plgetopt.h" + +#include +#include + +static PRIntn debug_mode; +static PRFileDesc *output; + + +static void TestConversions(void) +{ + PRIntervalTime ticks = PR_TicksPerSecond(); + + if (debug_mode) { + PR_fprintf(output, "PR_TicksPerSecond: %ld\n\n", ticks); + PR_fprintf(output, "PR_SecondsToInterval(1): %ld\n", PR_SecondsToInterval(1)); + PR_fprintf(output, "PR_MillisecondsToInterval(1000): %ld\n", PR_MillisecondsToInterval(1000)); + PR_fprintf(output, "PR_MicrosecondsToInterval(1000000): %ld\n\n", PR_MicrosecondsToInterval(1000000)); + + PR_fprintf(output, "PR_SecondsToInterval(3): %ld\n", PR_SecondsToInterval(3)); + PR_fprintf(output, "PR_MillisecondsToInterval(3000): %ld\n", PR_MillisecondsToInterval(3000)); + PR_fprintf(output, "PR_MicrosecondsToInterval(3000000): %ld\n\n", PR_MicrosecondsToInterval(3000000)); + + PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks)); + PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks)); + PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks)); + + ticks *= 3; + PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks)); + PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks)); + PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks)); + } /*end debug mode */ +} /* TestConversions */ + +static void TestIntervalOverhead(void) +{ + /* Hopefully the optimizer won't delete this function */ + PRUint32 elapsed, per_call, loops = 1000000; + + PRIntervalTime timeout, timein = PR_IntervalNow(); + while (--loops > 0) + timeout = PR_IntervalNow(); + + elapsed = 1000U * PR_IntervalToMicroseconds(timeout - timein); + per_call = elapsed / 1000000U; + PR_fprintf( + output, "Overhead of 'PR_IntervalNow()' is %u nsecs\n\n", per_call); +} /* TestIntervalOverhead */ + +static void TestNowOverhead(void) +{ + PRTime timeout, timein; + PRInt32 overhead, loops = 1000000; + PRInt64 elapsed, per_call, ten23rd, ten26th; + + LL_I2L(ten23rd, 1000); + LL_I2L(ten26th, 1000000); + + timein = PR_Now(); + while (--loops > 0) + timeout = PR_Now(); + + LL_SUB(elapsed, timeout, timein); + LL_MUL(elapsed, elapsed, ten23rd); + LL_DIV(per_call, elapsed, ten26th); + LL_L2I(overhead, per_call); + PR_fprintf( + output, "Overhead of 'PR_Now()' is %u nsecs\n\n", overhead); +} /* TestNowOverhead */ + +static void TestIntervals(void) +{ + PRStatus rv; + PRUint32 delta; + PRInt32 seconds; + PRUint64 elapsed, thousand; + PRTime timein, timeout; + PRLock *ml = PR_NewLock(); + PRCondVar *cv = PR_NewCondVar(ml); + for (seconds = 0; seconds < 10; ++seconds) + { + PRIntervalTime ticks = PR_SecondsToInterval(seconds); + PR_Lock(ml); + timein = PR_Now(); + rv = PR_WaitCondVar(cv, ticks); + timeout = PR_Now(); + PR_Unlock(ml); + LL_SUB(elapsed, timeout, timein); + LL_I2L(thousand, 1000); + LL_DIV(elapsed, elapsed, thousand); + LL_L2UI(delta, elapsed); + if (debug_mode) PR_fprintf(output, + "TestIntervals: %swaiting %ld seconds took %ld msecs\n", + ((rv == PR_SUCCESS) ? "" : "FAILED "), seconds, delta); + } + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); + if (debug_mode) PR_fprintf(output, "\n"); +} /* TestIntervals */ + +static PRIntn PR_CALLBACK RealMain(int argc, char** argv) +{ + PRUint32 vcpu, cpus = 0, loops = 1000; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + + /* main test */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dl:c:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'c': /* concurrency counter */ + cpus = atoi(opt->value); + break; + case 'l': /* loop counter */ + loops = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + output = PR_GetSpecialFD(PR_StandardOutput); + PR_fprintf(output, "inrval: Examine stdout to determine results.\n"); + + if (cpus == 0) cpus = 8; + if (loops == 0) loops = 1000; + + if (debug_mode > 0) + { + PR_fprintf(output, "Inrval: Using %d loops\n", loops); + PR_fprintf(output, "Inrval: Using 1 and %d cpu(s)\n", cpus); + } + + for (vcpu = 1; vcpu <= cpus; vcpu += cpus - 1) + { + if (debug_mode) + PR_fprintf(output, "\nInrval: Using %d CPU(s)\n\n", vcpu); + PR_SetConcurrency(vcpu); + + TestNowOverhead(); + TestIntervalOverhead(); + TestConversions(); + TestIntervals(); + } + + return 0; +} + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ + diff -Nru nspr-4.9.5/nspr/pr/tests/instrumt.c nspr-4.10.7/nspr/pr/tests/instrumt.c --- nspr-4.9.5/nspr/pr/tests/instrumt.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/instrumt.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,475 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: instrumt.c +** Description: This test is for the NSPR debug aids defined in +** prcountr.h, prtrace.h, prolock.h +** +** The test case tests the three debug aids in NSPR: +** +** Diagnostic messages can be enabled using "instrumt -v 6" +** This sets the msgLevel to something that PR_LOG() likes. +** Also define in the environment "NSPR_LOG_MODULES=Test:6" +** +** CounterTest() tests the counter facility. This test +** creates 4 threads. Each thread either increments, decrements, +** adds to or subtracts from a counter, depending on an argument +** passed to the thread at thread-create time. Each of these threads +** does COUNT_LIMIT iterations doing its thing. When all 4 threads +** are done, the result of the counter is evaluated. If all was atomic, +** the the value of the counter should be zero. +** +** TraceTest(): +** This test mingles with the counter test. Counters trace. +** A thread to extract trace entries on the fly is started. +** A thread to dump trace entries to a file is started. +** +** OrderedLockTest(): +** +** +** +** +** +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define COUNT_LIMIT (10 * ( 1024)) + +#define SMALL_TRACE_BUFSIZE ( 60 * 1024 ) + +typedef enum +{ + CountLoop = 1, + TraceLoop = 2, + TraceFlow = 3 +} TraceTypes; + + +PRLogModuleLevel msgLevel = PR_LOG_ALWAYS; + +PRBool help = PR_FALSE; +PRBool failed = PR_FALSE; + + +PRLogModuleInfo *lm; +PRMonitor *mon; +PRInt32 activeThreads = 0; +PR_DEFINE_COUNTER( hCounter ); +PR_DEFINE_TRACE( hTrace ); + +static void Help(void) +{ + printf("Help? ... Ha!\n"); +} + +static void ListCounters(void) +{ + PR_DEFINE_COUNTER( qh ); + PR_DEFINE_COUNTER( rh ); + const char *qn, *rn, *dn; + const char **qname = &qn, **rname = &rn, **desc = &dn; + PRUint32 tCtr; + + PR_INIT_COUNTER_HANDLE( qh, NULL ); + PR_FIND_NEXT_COUNTER_QNAME(qh, qh ); + while ( qh != NULL ) + { + PR_INIT_COUNTER_HANDLE( rh, NULL ); + PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh ); + while ( rh != NULL ) + { + PR_GET_COUNTER_NAME_FROM_HANDLE( rh, qname, rname, desc ); + PR_GET_COUNTER(tCtr, rh); + PR_LOG( lm, msgLevel, + ( "QName: %s RName: %s Desc: %s Value: %ld\n", + qn, rn, dn, tCtr )); + PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh ); + } + PR_FIND_NEXT_COUNTER_QNAME(qh, qh); + } + return; +} /* end ListCounters() */ + +static void ListTraces(void) +{ + PR_DEFINE_TRACE( qh ); + PR_DEFINE_TRACE( rh ); + const char *qn, *rn, *dn; + const char **qname = &qn, **rname = &rn, **desc = &dn; + + PR_INIT_TRACE_HANDLE( qh, NULL ); + PR_FIND_NEXT_TRACE_QNAME(qh, qh ); + while ( qh != NULL ) + { + PR_INIT_TRACE_HANDLE( rh, NULL ); + PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh ); + while ( rh != NULL ) + { + PR_GET_TRACE_NAME_FROM_HANDLE( rh, qname, rname, desc ); + PR_LOG( lm, msgLevel, + ( "QName: %s RName: %s Desc: %s", + qn, rn, dn )); + PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh ); + } + PR_FIND_NEXT_TRACE_QNAME(qh, qh); + } + return; +} /* end ListCounters() */ + + +static PRInt32 one = 1; +static PRInt32 two = 2; +static PRInt32 three = 3; +static PRInt32 four = 4; + +/* +** Thread to iteratively count something. +*/ +static void PR_CALLBACK CountSomething( void *arg ) +{ + PRInt32 switchVar = *((PRInt32 *)arg); + PRInt32 i; + + PR_LOG( lm, msgLevel, + ("CountSomething: begin thread %ld", switchVar )); + + for ( i = 0; i < COUNT_LIMIT ; i++) + { + switch ( switchVar ) + { + case 1 : + PR_INCREMENT_COUNTER( hCounter ); + break; + case 2 : + PR_DECREMENT_COUNTER( hCounter ); + break; + case 3 : + PR_ADD_TO_COUNTER( hCounter, 1 ); + break; + case 4 : + PR_SUBTRACT_FROM_COUNTER( hCounter, 1 ); + break; + default : + PR_ASSERT( 0 ); + break; + } + PR_TRACE( hTrace, CountLoop, switchVar, i, 0, 0, 0, 0, 0 ); + } /* end for() */ + + PR_LOG( lm, msgLevel, + ("CounterSomething: end thread %ld", switchVar )); + + PR_EnterMonitor(mon); + --activeThreads; + PR_Notify( mon ); + PR_ExitMonitor(mon); + + return; +} /* end CountSomething() */ + +/* +** Create the counter threads. +*/ +static void CounterTest( void ) +{ + PRThread *t1, *t2, *t3, *t4; + PRIntn i = 0; + PR_DEFINE_COUNTER( tc ); + PR_DEFINE_COUNTER( zCounter ); + + PR_LOG( lm, msgLevel, + ("Begin CounterTest")); + + /* + ** Test Get and Set of a counter. + ** + */ + PR_CREATE_COUNTER( zCounter, "Atomic", "get/set test", "test get and set of counter" ); + PR_SET_COUNTER( zCounter, 9 ); + PR_GET_COUNTER( i, zCounter ); + if ( i != 9 ) + { + failed = PR_TRUE; + PR_LOG( lm, msgLevel, + ("Counter set/get failed")); + } + + activeThreads += 4; + PR_CREATE_COUNTER( hCounter, "Atomic", "SMP Tests", "test atomic nature of counter" ); + + PR_GET_COUNTER_HANDLE_FROM_NAME( tc, "Atomic", "SMP Tests" ); + PR_ASSERT( tc == hCounter ); + + t1 = PR_CreateThread(PR_USER_THREAD, + CountSomething, &one, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + PR_ASSERT(t1); + + t2 = PR_CreateThread(PR_USER_THREAD, + CountSomething, &two, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + PR_ASSERT(t2); + + t3 = PR_CreateThread(PR_USER_THREAD, + CountSomething, &three, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + PR_ASSERT(t3); + + t4 = PR_CreateThread(PR_USER_THREAD, + CountSomething, &four, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + PR_ASSERT(t4); + + PR_LOG( lm, msgLevel, + ("Counter Threads started")); + + ListCounters(); + return; +} /* end CounterTest() */ + +/* +** Thread to dump trace buffer to a file. +*/ +static void PR_CALLBACK RecordTrace(void *arg ) +{ + PR_RECORD_TRACE_ENTRIES(); + + PR_EnterMonitor(mon); + --activeThreads; + PR_Notify( mon ); + PR_ExitMonitor(mon); + + return; +} /* end RecordTrace() */ + + + +#define NUM_TRACE_RECORDS ( 10000 ) +/* +** Thread to extract and print trace entries from the buffer. +*/ +static void PR_CALLBACK SampleTrace( void *arg ) +{ +#if defined(DEBUG) || defined(FORCE_NSPR_TRACE) + PRInt32 found, rc; + PRTraceEntry *foundEntries; + PRInt32 i; + + foundEntries = (PRTraceEntry *)PR_Malloc( NUM_TRACE_RECORDS * sizeof(PRTraceEntry)); + PR_ASSERT(foundEntries != NULL ); + + do + { + rc = PR_GetTraceEntries( foundEntries, NUM_TRACE_RECORDS, &found); + PR_LOG( lm, msgLevel, + ("SampleTrace: Lost Data: %ld found: %ld", rc, found )); + + if ( found != 0) + { + for ( i = 0 ; i < found; i++ ) + { + PR_LOG( lm, msgLevel, + ("SampleTrace, detail: Thread: %p, Time: %llX, UD0: %ld, UD1: %ld, UD2: %8.8ld", + (foundEntries +i)->thread, + (foundEntries +i)->time, + (foundEntries +i)->userData[0], + (foundEntries +i)->userData[1], + (foundEntries +i)->userData[2] )); + } + } + PR_Sleep(PR_MillisecondsToInterval(50)); + } + while( found != 0 && activeThreads >= 1 ); + + PR_Free( foundEntries ); + + PR_EnterMonitor(mon); + --activeThreads; + PR_Notify( mon ); + PR_ExitMonitor(mon); + + PR_LOG( lm, msgLevel, + ("SampleTrace(): exiting")); + +#endif + return; +} /* end RecordTrace() */ + +/* +** Basic trace test. +*/ +static void TraceTest( void ) +{ + PRInt32 i; + PRInt32 size; + PR_DEFINE_TRACE( th ); + PRThread *t1, *t2; + + PR_LOG( lm, msgLevel, + ("Begin TraceTest")); + + size = SMALL_TRACE_BUFSIZE; + PR_SET_TRACE_OPTION( PRTraceBufSize, &size ); + PR_GET_TRACE_OPTION( PRTraceBufSize, &i ); + + PR_CREATE_TRACE( th, "TraceTest", "tt2", "A description for the trace test" ); + PR_CREATE_TRACE( th, "TraceTest", "tt3", "A description for the trace test" ); + PR_CREATE_TRACE( th, "TraceTest", "tt4", "A description for the trace test" ); + PR_CREATE_TRACE( th, "TraceTest", "tt5", "A description for the trace test" ); + PR_CREATE_TRACE( th, "TraceTest", "tt6", "A description for the trace test" ); + PR_CREATE_TRACE( th, "TraceTest", "tt7", "A description for the trace test" ); + PR_CREATE_TRACE( th, "TraceTest", "tt8", "A description for the trace test" ); + + PR_CREATE_TRACE( th, "Trace Test", "tt0", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt1", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt2", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt3", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt4", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt5", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt6", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt7", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt8", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt9", "QName is Trace Test, not TraceTest" ); + PR_CREATE_TRACE( th, "Trace Test", "tt10", "QName is Trace Test, not TraceTest" ); + + + + activeThreads += 2; + t1 = PR_CreateThread(PR_USER_THREAD, + RecordTrace, NULL, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + PR_ASSERT(t1); + + t2 = PR_CreateThread(PR_USER_THREAD, + SampleTrace, 0, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + PR_ASSERT(t2); + + ListTraces(); + + PR_GET_TRACE_HANDLE_FROM_NAME( th, "TraceTest","tt1" ); + PR_ASSERT( th == hTrace ); + + PR_LOG( lm, msgLevel, + ("End TraceTest")); + return; +} /* end TraceTest() */ + + +/* +** Ordered lock test. +*/ +static void OrderedLockTest( void ) +{ + PR_LOG( lm, msgLevel, + ("Begin OrderedLockTest")); + + +} /* end OrderedLockTest() */ + + +int main(int argc, char **argv) +{ +#if defined(DEBUG) || defined(FORCE_NSPR_TRACE) + PRUint32 counter; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "hdv:"); + lm = PR_NewLogModule("Test"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'v': /* verbose mode */ + msgLevel = (PRLogModuleLevel)atol( opt->value); + break; + case 'h': /* help message */ + Help(); + help = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_CREATE_TRACE( hTrace, "TraceTest", "tt1", "A description for the trace test" ); + mon = PR_NewMonitor(); + PR_EnterMonitor( mon ); + + TraceTest(); + CounterTest(); + OrderedLockTest(); + + /* Wait for all threads to exit */ + while ( activeThreads > 0 ) { + if ( activeThreads == 1 ) + PR_SET_TRACE_OPTION( PRTraceStopRecording, NULL ); + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + PR_GET_COUNTER( counter, hCounter ); + } + PR_ExitMonitor( mon ); + + /* + ** Evaluate results + */ + PR_GET_COUNTER( counter, hCounter ); + if ( counter != 0 ) + { + failed = PR_TRUE; + PR_LOG( lm, msgLevel, + ("Expected counter == 0, found: %ld", counter)); + printf("FAIL\n"); + } + else + { + printf("PASS\n"); + } + + + PR_DESTROY_COUNTER( hCounter ); + + PR_DestroyMonitor( mon ); + + PR_TRACE( hTrace, TraceFlow, 0xfff,0,0,0,0,0,0); + PR_DESTROY_TRACE( hTrace ); +#else + printf("Test not defined\n"); +#endif + return 0; +} /* main() */ +/* end instrumt.c */ + diff -Nru nspr-4.9.5/nspr/pr/tests/intrio.c nspr-4.10.7/nspr/pr/tests/intrio.c --- nspr-4.9.5/nspr/pr/tests/intrio.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/intrio.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: intrio.c + * Purpose: testing i/o interrupts (see Bugzilla bug #31120) + */ + +#include "nspr.h" + +#include +#include +#include + +/* for synchronization between the main thread and iothread */ +static PRLock *lock; +static PRCondVar *cvar; +static PRBool iothread_ready; + +static void PR_CALLBACK AbortIO(void *arg) +{ + PRStatus rv; + PR_Sleep(PR_SecondsToInterval(2)); + rv = PR_Interrupt((PRThread*)arg); + PR_ASSERT(PR_SUCCESS == rv); +} /* AbortIO */ + +static void PR_CALLBACK IOThread(void *arg) +{ + PRFileDesc *sock, *newsock; + PRNetAddr addr; + + sock = PR_OpenTCPSocket(PR_AF_INET6); + if (sock == NULL) { + fprintf(stderr, "PR_OpenTCPSocket failed\n"); + exit(1); + } + memset(&addr, 0, sizeof(addr)); + if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_SetNetAddr failed\n"); + exit(1); + } + if (PR_Bind(sock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + if (PR_Listen(sock, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + /* tell the main thread that we are ready */ + PR_Lock(lock); + iothread_ready = PR_TRUE; + PR_NotifyCondVar(cvar); + PR_Unlock(lock); + newsock = PR_Accept(sock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (newsock != NULL) { + fprintf(stderr, "PR_Accept shouldn't have succeeded\n"); + exit(1); + } + if (PR_GetError() != PR_PENDING_INTERRUPT_ERROR) { + fprintf(stderr, "PR_Accept failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + printf("PR_Accept() is interrupted as expected\n"); + if (PR_Close(sock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } +} + +static void Test(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *iothread, *abortio; + + printf("A %s thread will be interrupted by a %s thread\n", + (scope1 == PR_LOCAL_THREAD ? "local" : "global"), + (scope2 == PR_LOCAL_THREAD ? "local" : "global")); + iothread_ready = PR_FALSE; + iothread = PR_CreateThread( + PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL, + scope1, PR_JOINABLE_THREAD, 0); + if (iothread == NULL) { + fprintf(stderr, "cannot create thread\n"); + exit(1); + } + PR_Lock(lock); + while (!iothread_ready) + PR_WaitCondVar(cvar, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(lock); + abortio = PR_CreateThread( + PR_USER_THREAD, AbortIO, iothread, PR_PRIORITY_NORMAL, + scope2, PR_JOINABLE_THREAD, 0); + if (abortio == NULL) { + fprintf(stderr, "cannot create thread\n"); + exit(1); + } + if (PR_JoinThread(iothread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + if (PR_JoinThread(abortio) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } +} + +int main(int argc, char **argv) +{ + PR_STDIO_INIT(); + lock = PR_NewLock(); + if (lock == NULL) { + fprintf(stderr, "PR_NewLock failed\n"); + exit(1); + } + cvar = PR_NewCondVar(lock); + if (cvar == NULL) { + fprintf(stderr, "PR_NewCondVar failed\n"); + exit(1); + } + /* test all four combinations */ + Test(PR_LOCAL_THREAD, PR_LOCAL_THREAD); + Test(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); + Test(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); + Test(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); + printf("PASSED\n"); + return 0; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/intrupt.c nspr-4.10.7/nspr/pr/tests/intrupt.c --- nspr-4.9.5/nspr/pr/tests/intrupt.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/intrupt.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,330 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: intrupt.c + * Purpose: testing thread interrupts + */ + +#include "plgetopt.h" +#include "prcvar.h" +#include "prerror.h" +#include "prinit.h" +#include "prinrval.h" +#include "prio.h" +#include "prlock.h" +#include "prlog.h" +#include "prthread.h" +#include "prtypes.h" +#include "prnetdb.h" + +#include +#include + +#define DEFAULT_TCP_PORT 12500 + +static PRLock *ml = NULL; +static PRCondVar *cv = NULL; + +static PRBool passed = PR_TRUE; +static PRBool debug_mode = PR_FALSE; +static PRThreadScope thread_scope = PR_LOCAL_THREAD; + +static void PR_CALLBACK AbortCV(void *arg) +{ + PRStatus rv; + PRThread *me = PR_GetCurrentThread(); + + /* some other thread (main) is doing the interrupt */ + PR_Lock(ml); + rv = PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); + if (debug_mode) printf( "Expected interrupt on wait CV and "); + if (PR_FAILURE == rv) + { + if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) + { + if (debug_mode) printf("got it\n"); + } + else + { + if (debug_mode) printf("got random error\n"); + passed = PR_FALSE; + } + } + else + { + if (debug_mode) printf("got a successful completion\n"); + passed = PR_FALSE; + } + + rv = PR_WaitCondVar(cv, 10); + if (debug_mode) + { + printf( + "Expected success on wait CV and %s\n", + (PR_SUCCESS == rv) ? "got it" : "failed"); + } + passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE; + + /* interrupt myself, then clear */ + PR_Interrupt(me); + PR_ClearInterrupt(); + rv = PR_WaitCondVar(cv, 10); + if (debug_mode) + { + printf("Expected success on wait CV and "); + if (PR_FAILURE == rv) + { + printf( + "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ? + "got interrupted" : "a random failure"); + } + printf("got it\n"); + } + passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE; + + /* set, then wait - interrupt - then wait again */ + PR_Interrupt(me); + rv = PR_WaitCondVar(cv, 10); + if (debug_mode) printf( "Expected interrupt on wait CV and "); + if (PR_FAILURE == rv) + { + if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) + { + if (debug_mode) printf("got it\n"); + } + else + { + if (debug_mode) printf("failed\n"); + passed = PR_FALSE; + } + } + else + { + if (debug_mode) printf("got a successful completion\n"); + passed = PR_FALSE; + } + + rv = PR_WaitCondVar(cv, 10); + if (debug_mode) + { + printf( + "Expected success on wait CV and %s\n", + (PR_SUCCESS == rv) ? "got it" : "failed"); + } + passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE; + + PR_Unlock(ml); + +} /* AbortCV */ + +static void PR_CALLBACK AbortIO(void *arg) +{ + PRStatus rv; + PR_Sleep(PR_SecondsToInterval(2)); + rv = PR_Interrupt((PRThread*)arg); + PR_ASSERT(PR_SUCCESS == rv); +} /* AbortIO */ + +static void PR_CALLBACK AbortJoin(void *arg) +{ +} /* AbortJoin */ + +static void setup_listen_socket(PRFileDesc **listner, PRNetAddr *netaddr) +{ + PRStatus rv; + PRInt16 port = DEFAULT_TCP_PORT; + + *listner = PR_NewTCPSocket(); + PR_ASSERT(*listner != NULL); + memset(netaddr, 0, sizeof(*netaddr)); + (*netaddr).inet.ip = PR_htonl(PR_INADDR_ANY); + (*netaddr).inet.family = PR_AF_INET; + do + { + (*netaddr).inet.port = PR_htons(port); + rv = PR_Bind(*listner, netaddr); + port += 1; + PR_ASSERT(port < (DEFAULT_TCP_PORT + 10)); + } while (PR_FAILURE == rv); + + rv = PR_Listen(*listner, 5); + + if (PR_GetSockName(*listner, netaddr) < 0) { + if (debug_mode) printf("intrupt: ERROR - PR_GetSockName failed\n"); + passed = PR_FALSE; + return; + } + +} + +static void PR_CALLBACK IntrBlock(void *arg) +{ + PRStatus rv; + PRNetAddr netaddr; + PRFileDesc *listner; + + /* some other thread (main) is doing the interrupt */ + /* block the interrupt */ + PR_BlockInterrupt(); + PR_Lock(ml); + rv = PR_WaitCondVar(cv, PR_SecondsToInterval(4)); + PR_Unlock(ml); + if (debug_mode) + { + printf("Expected success on wait CV and "); + if (PR_FAILURE == rv) + { + printf( + "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ? + "got interrupted" : "got a random failure"); + } else + printf("got it\n"); + } + passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE; + + setup_listen_socket(&listner, &netaddr); + PR_UnblockInterrupt(); + if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL) + { + PRInt32 error = PR_GetError(); + if (debug_mode) printf("Expected interrupt on PR_Accept() and "); + if (PR_PENDING_INTERRUPT_ERROR == error) + { + if (debug_mode) printf("got it\n"); + } + else + { + if (debug_mode) printf("failed\n"); + passed = PR_FALSE; + } + } + else + { + if (debug_mode) printf("Failed to interrupt PR_Accept()\n"); + passed = PR_FALSE; + } + + (void)PR_Close(listner); listner = NULL; +} /* TestIntrBlock */ + +void PR_CALLBACK Intrupt(void *arg) +{ + PRStatus rv; + PRNetAddr netaddr; + PRFileDesc *listner; + PRThread *abortCV, *abortIO, *abortJoin, *intrBlock; + + ml = PR_NewLock(); + cv = PR_NewCondVar(ml); + + /* Part I */ + if (debug_mode) printf("Part I\n"); + abortCV = PR_CreateThread( + PR_USER_THREAD, AbortCV, 0, PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + + PR_Sleep(PR_SecondsToInterval(2)); + rv = PR_Interrupt(abortCV); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(abortCV); + PR_ASSERT(PR_SUCCESS == rv); + + /* Part II */ + if (debug_mode) printf("Part II\n"); + abortJoin = PR_CreateThread( + PR_USER_THREAD, AbortJoin, 0, PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + PR_Sleep(PR_SecondsToInterval(2)); + if (debug_mode) printf("Expecting to interrupt an exited thread "); + rv = PR_Interrupt(abortJoin); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(abortJoin); + PR_ASSERT(PR_SUCCESS == rv); + if (debug_mode) printf("and succeeded\n"); + + /* Part III */ + if (debug_mode) printf("Part III\n"); + setup_listen_socket(&listner, &netaddr); + abortIO = PR_CreateThread( + PR_USER_THREAD, AbortIO, PR_GetCurrentThread(), PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + + if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL) + { + PRInt32 error = PR_GetError(); + if (debug_mode) printf("Expected interrupt on PR_Accept() and "); + if (PR_PENDING_INTERRUPT_ERROR == error) + { + if (debug_mode) printf("got it\n"); + } + else + { + if (debug_mode) printf("failed\n"); + passed = PR_FALSE; + } + } + else + { + if (debug_mode) printf("Failed to interrupt PR_Accept()\n"); + passed = PR_FALSE; + } + + (void)PR_Close(listner); listner = NULL; + + rv = PR_JoinThread(abortIO); + PR_ASSERT(PR_SUCCESS == rv); + /* Part VI */ + if (debug_mode) printf("Part VI\n"); + intrBlock = PR_CreateThread( + PR_USER_THREAD, IntrBlock, 0, PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + + PR_Sleep(PR_SecondsToInterval(2)); + rv = PR_Interrupt(intrBlock); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(intrBlock); + PR_ASSERT(PR_SUCCESS == rv); + + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); +} /* Intrupt */ + +int main(int argc, char **argv) +{ + PRThread *intrupt; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dG"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'G': /* use global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + } + } + PL_DestroyOptState(opt); + PR_STDIO_INIT(); + intrupt = PR_CreateThread( + PR_USER_THREAD, Intrupt, NULL, PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + if (intrupt == NULL) { + fprintf(stderr, "cannot create thread\n"); + passed = PR_FALSE; + } else { + PRStatus rv; + rv = PR_JoinThread(intrupt); + PR_ASSERT(rv == PR_SUCCESS); + } + printf("%s\n", ((passed) ? "PASSED" : "FAILED")); + return ((passed) ? 0 : 1); +} /* main */ + +/* intrupt.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/ioconthr.c nspr-4.10.7/nspr/pr/tests/ioconthr.c --- nspr-4.9.5/nspr/pr/tests/ioconthr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/ioconthr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This is a test for the io continuation thread machinery + * in pthreads. + */ + +#include "nspr.h" +#include + +int num_threads = 10; /* must be an even number */ +PRThreadScope thread_scope = PR_GLOBAL_THREAD; + +void ThreadFunc(void *arg) +{ + PRFileDesc *fd = (PRFileDesc *) arg; + char buf[1024]; + PRInt32 nbytes; + PRErrorCode err; + + nbytes = PR_Recv(fd, buf, sizeof(buf), 0, PR_SecondsToInterval(20)); + if (nbytes == -1) { + err = PR_GetError(); + if (err != PR_PENDING_INTERRUPT_ERROR) { + fprintf(stderr, "PR_Recv failed: (%d, %d)\n", + err, PR_GetOSError()); + PR_ProcessExit(1); + } + /* + * After getting an I/O interrupt, this thread must + * close the fd before it exits due to a limitation + * of our NT implementation. + */ + if (PR_Close(fd) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + PR_ProcessExit(1); + } + } else { + fprintf(stderr, "PR_Recv received %d bytes!?\n", nbytes); + PR_ProcessExit(1); + } +} + +int main(int argc, char **argv) +{ + PRFileDesc **fds; + PRThread **threads; + PRIntervalTime start, elapsed; + int index; + + fds = (PRFileDesc **) PR_MALLOC(2 * num_threads * sizeof(PRFileDesc *)); + PR_ASSERT(fds != NULL); + threads = (PRThread **) PR_MALLOC(num_threads * sizeof(PRThread *)); + PR_ASSERT(threads != NULL); + + for (index = 0; index < num_threads; index++) { + if (PR_NewTCPSocketPair(&fds[2 * index]) == PR_FAILURE) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + PR_ProcessExit(1); + } + threads[index] = PR_CreateThread( + PR_USER_THREAD, ThreadFunc, fds[2 * index], + PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 0); + if (NULL == threads[index]) { + fprintf(stderr, "PR_CreateThread failed\n"); + PR_ProcessExit(1); + } + } + + /* Let the threads block in PR_Recv */ + PR_Sleep(PR_SecondsToInterval(2)); + + printf("Interrupting the threads\n"); + fflush(stdout); + start = PR_IntervalNow(); + for (index = 0; index < num_threads; index++) { + if (PR_Interrupt(threads[index]) == PR_FAILURE) { + fprintf(stderr, "PR_Interrupt failed\n"); + PR_ProcessExit(1); + } + } + for (index = 0; index < num_threads; index++) { + if (PR_JoinThread(threads[index]) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + PR_ProcessExit(1); + } + } + elapsed = (PRIntervalTime)(PR_IntervalNow() - start); + printf("Threads terminated in %d milliseconds\n", + PR_IntervalToMilliseconds(elapsed)); + fflush(stdout); + + /* We are being very generous and allow 10 seconds. */ + if (elapsed >= PR_SecondsToInterval(10)) { + fprintf(stderr, "Interrupting threads took longer than 10 seconds!!\n"); + PR_ProcessExit(1); + } + + for (index = 0; index < num_threads; index++) { + /* fds[2 * index] was passed to and closed by threads[index]. */ + if (PR_Close(fds[2 * index + 1]) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + PR_ProcessExit(1); + } + } + PR_DELETE(threads); + PR_DELETE(fds); + printf("PASS\n"); + PR_Cleanup(); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/io_timeout.c nspr-4.10.7/nspr/pr/tests/io_timeout.c --- nspr-4.9.5/nspr/pr/tests/io_timeout.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/io_timeout.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,256 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** Test socket IO timeouts +** +** +** +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include +#include "nspr.h" + +#define NUM_THREADS 1 +#define BASE_PORT 8000 +#define DEFAULT_ACCEPT_TIMEOUT 2 + +typedef struct threadInfo { + PRInt16 id; + PRInt16 accept_timeout; + PRLock *dead_lock; + PRCondVar *dead_cv; + PRInt32 *alive; +} threadInfo; + +PRIntn failed_already = 0; +PRIntn debug_mode = 0; + +#define LOCAL_SCOPE_STRING "LOCAL scope" +#define GLOBAL_SCOPE_STRING "GLOBAL scope" +#define GLOBAL_BOUND_SCOPE_STRING "GLOBAL_BOUND scope" + +void +thread_main(void *_info) +{ + threadInfo *info = (threadInfo *)_info; + PRNetAddr listenAddr; + PRNetAddr clientAddr; + PRFileDesc *listenSock = NULL; + PRFileDesc *clientSock; + PRStatus rv; + PRThreadScope tscope; + char *scope_str; + + + if (debug_mode) + printf("thread %d is alive\n", info->id); + tscope = PR_GetThreadScope(PR_GetCurrentThread()); + + switch(tscope) { + case PR_LOCAL_THREAD: + scope_str = LOCAL_SCOPE_STRING; + break; + case PR_GLOBAL_THREAD: + scope_str = GLOBAL_SCOPE_STRING; + break; + case PR_GLOBAL_BOUND_THREAD: + scope_str = GLOBAL_BOUND_SCOPE_STRING; + break; + default: + PR_ASSERT(!"Invalid thread scope"); + break; + } + printf("thread id %d, scope %s\n", info->id, scope_str); + + listenSock = PR_NewTCPSocket(); + if (!listenSock) { + if (debug_mode) + printf("unable to create listen socket\n"); + failed_already=1; + goto dead; + } + + listenAddr.inet.family = PR_AF_INET; + listenAddr.inet.port = PR_htons(BASE_PORT + info->id); + listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY); + rv = PR_Bind(listenSock, &listenAddr); + if (rv == PR_FAILURE) { + if (debug_mode) + printf("unable to bind\n"); + failed_already=1; + goto dead; + } + + rv = PR_Listen(listenSock, 4); + if (rv == PR_FAILURE) { + if (debug_mode) + printf("unable to listen\n"); + failed_already=1; + goto dead; + } + + if (debug_mode) + printf("thread %d going into accept for %d seconds\n", + info->id, info->accept_timeout + info->id); + + clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id)); + + if (clientSock == NULL) { + if (PR_GetError() == PR_IO_TIMEOUT_ERROR) { + if (debug_mode) { + printf("PR_Accept() timeout worked!\n"); + printf("TEST PASSED! PR_Accept() returned error %d\n", + PR_IO_TIMEOUT_ERROR); + } + } else { + if (debug_mode) + printf("TEST FAILED! PR_Accept() returned error %d\n", + PR_GetError()); + failed_already=1; + } + } else { + if (debug_mode) + printf ("TEST FAILED! PR_Accept() succeeded?\n"); + failed_already=1; + PR_Close(clientSock); + } + +dead: + if (listenSock) { + PR_Close(listenSock); + } + PR_Lock(info->dead_lock); + (*info->alive)--; + PR_NotifyCondVar(info->dead_cv); + PR_Unlock(info->dead_lock); + + if (debug_mode) + printf("thread %d is dead\n", info->id); + + PR_Free(info); +} + +void +thread_test(PRThreadScope scope, PRInt32 num_threads) +{ + PRInt32 index; + PRThread *thr; + PRLock *dead_lock; + PRCondVar *dead_cv; + PRInt32 alive; + + if (debug_mode) + printf("IO Timeout test started with %d threads\n", num_threads); + + dead_lock = PR_NewLock(); + dead_cv = PR_NewCondVar(dead_lock); + alive = num_threads; + + for (index = 0; index < num_threads; index++) { + threadInfo *info = (threadInfo *)PR_Malloc(sizeof(threadInfo)); + + info->id = index; + info->dead_lock = dead_lock; + info->dead_cv = dead_cv; + info->alive = &alive; + info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT; + + thr = PR_CreateThread( PR_USER_THREAD, + thread_main, + (void *)info, + PR_PRIORITY_NORMAL, + scope, + PR_UNJOINABLE_THREAD, + 0); + + if (!thr) { + printf("Failed to create thread, error = %d(%d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + + PR_Lock(dead_lock); + alive--; + PR_Unlock(dead_lock); + } + } + + PR_Lock(dead_lock); + while(alive) { + if (debug_mode) + printf("main loop awake; alive = %d\n", alive); + PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(dead_lock); + + PR_DestroyCondVar(dead_cv); + PR_DestroyLock(dead_lock); +} + +int main(int argc, char **argv) +{ + PRInt32 num_threads = 0; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name [-d] [-t ] + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dt:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 't': /* threads to involve */ + num_threads = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + if (0 == num_threads) + num_threads = NUM_THREADS; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0); + PR_STDIO_INIT(); + + printf("test with global bound thread\n"); + thread_test(PR_GLOBAL_BOUND_THREAD, num_threads); + + printf("test with local thread\n"); + thread_test(PR_LOCAL_THREAD, num_threads); + + printf("test with global thread\n"); + thread_test(PR_GLOBAL_THREAD, num_threads); + + PR_Cleanup(); + + if (failed_already) + return 1; + else + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/io_timeoutk.c nspr-4.10.7/nspr/pr/tests/io_timeoutk.c --- nspr-4.9.5/nspr/pr/tests/io_timeoutk.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/io_timeoutk.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** name io_timeoutk.c +** Description:Test socket IO timeouts (kernel level) +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include +#include "nspr.h" + +#define NUM_THREADS 1 +#define BASE_PORT 8000 +#define DEFAULT_ACCEPT_TIMEOUT 2 + +typedef struct threadInfo { + PRInt16 id; + PRInt16 accept_timeout; + PRLock *dead_lock; + PRCondVar *dead_cv; + PRInt32 *alive; +} threadInfo; + +PRIntn failed_already=0; +PRIntn debug_mode; + + +void +thread_main(void *_info) +{ + threadInfo *info = (threadInfo *)_info; + PRNetAddr listenAddr; + PRNetAddr clientAddr; + PRFileDesc *listenSock = NULL; + PRFileDesc *clientSock; + PRStatus rv; + + if (debug_mode) printf("thread %d is alive\n", info->id); + + listenSock = PR_NewTCPSocket(); + if (!listenSock) { + if (debug_mode) printf("unable to create listen socket\n"); + goto dead; + } + + listenAddr.inet.family = AF_INET; + listenAddr.inet.port = PR_htons(BASE_PORT + info->id); + listenAddr.inet.ip = PR_htonl(INADDR_ANY); + rv = PR_Bind(listenSock, &listenAddr); + if (rv == PR_FAILURE) { + if (debug_mode) printf("unable to bind\n"); + goto dead; + } + + rv = PR_Listen(listenSock, 4); + if (rv == PR_FAILURE) { + if (debug_mode) printf("unable to listen\n"); + goto dead; + } + + if (debug_mode) printf("thread %d going into accept for %d seconds\n", + info->id, info->accept_timeout + info->id); + + clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id)); + + if (clientSock == NULL) { + if (PR_GetError() == PR_IO_TIMEOUT_ERROR) + if (debug_mode) { + printf("PR_Accept() timeout worked!\n"); + printf("TEST FAILED! PR_Accept() returned error %d\n", + PR_GetError()); + } + else failed_already=1; + } else { + if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n"); + else failed_already=1; + PR_Close(clientSock); + } + +dead: + if (listenSock) { + PR_Close(listenSock); + } + PR_Lock(info->dead_lock); + (*info->alive)--; + PR_NotifyCondVar(info->dead_cv); + PR_Unlock(info->dead_lock); + + if (debug_mode) printf("thread %d is dead\n", info->id); +} + +void +thread_test(PRInt32 scope, PRInt32 num_threads) +{ + PRInt32 index; + PRThread *thr; + PRLock *dead_lock; + PRCondVar *dead_cv; + PRInt32 alive; + + if (debug_mode) printf("IO Timeout test started with %d threads\n", num_threads); + + dead_lock = PR_NewLock(); + dead_cv = PR_NewCondVar(dead_lock); + alive = num_threads; + + for (index = 0; index < num_threads; index++) { + threadInfo *info = (threadInfo *)malloc(sizeof(threadInfo)); + + info->id = index; + info->dead_lock = dead_lock; + info->dead_cv = dead_cv; + info->alive = &alive; + info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT; + + thr = PR_CreateThread( PR_USER_THREAD, + thread_main, + (void *)info, + PR_PRIORITY_NORMAL, + scope, + PR_UNJOINABLE_THREAD, + 0); + + if (!thr) { + PR_Lock(dead_lock); + alive--; + PR_Unlock(dead_lock); + } + } + + PR_Lock(dead_lock); + while(alive) { + if (debug_mode) printf("main loop awake; alive = %d\n", alive); + PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(dead_lock); +} + +int main(int argc, char **argv) +{ + PRInt32 num_threads; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + if (argc > 2) + num_threads = atoi(argv[2]); + else + num_threads = NUM_THREADS; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0); + PR_STDIO_INIT(); + + if (debug_mode) printf("kernel level test\n"); + thread_test(PR_GLOBAL_THREAD, num_threads); + + PR_Cleanup(); + + if(failed_already) + return 1; + else + return 0; + +} diff -Nru nspr-4.9.5/nspr/pr/tests/io_timeoutu.c nspr-4.10.7/nspr/pr/tests/io_timeoutu.c --- nspr-4.9.5/nspr/pr/tests/io_timeoutu.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/io_timeoutu.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/* +** name io_timeoutu.c +** Description: Test socket IO timeouts (user level) +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include +#include "nspr.h" + +#define NUM_THREADS 1 +#define BASE_PORT 8000 +#define DEFAULT_ACCEPT_TIMEOUT 2 + +typedef struct threadInfo { + PRInt16 id; + PRInt16 accept_timeout; + PRLock *dead_lock; + PRCondVar *dead_cv; + PRInt32 *alive; +} threadInfo; +PRIntn failed_already=0; +PRIntn debug_mode; + +void +thread_main(void *_info) +{ + threadInfo *info = (threadInfo *)_info; + PRNetAddr listenAddr; + PRNetAddr clientAddr; + PRFileDesc *listenSock = NULL; + PRFileDesc *clientSock; + PRStatus rv; + + if (debug_mode) printf("thread %d is alive\n", info->id); + + listenSock = PR_NewTCPSocket(); + if (!listenSock) { + if (debug_mode) printf("unable to create listen socket\n"); + goto dead; + } + + listenAddr.inet.family = AF_INET; + listenAddr.inet.port = PR_htons(BASE_PORT + info->id); + listenAddr.inet.ip = PR_htonl(INADDR_ANY); + rv = PR_Bind(listenSock, &listenAddr); + if (rv == PR_FAILURE) { + if (debug_mode) printf("unable to bind\n"); + goto dead; + } + + rv = PR_Listen(listenSock, 4); + if (rv == PR_FAILURE) { + if (debug_mode) printf("unable to listen\n"); + goto dead; + } + + if (debug_mode) printf("thread %d going into accept for %d seconds\n", + info->id, info->accept_timeout + info->id); + + clientSock = PR_Accept( + listenSock, &clientAddr, PR_SecondsToInterval( + info->accept_timeout + info->id)); + + if (clientSock == NULL) { + if (PR_GetError() == PR_IO_TIMEOUT_ERROR) + if (debug_mode) { + printf("PR_Accept() timeout worked!\n"); + printf("TEST FAILED! PR_Accept() returned error %d\n", + } + PR_GetError()); + else failed_already=1; + } else { + if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n"); + else failed_already=1; + PR_Close(clientSock); + } + +dead: + if (listenSock) { + PR_Close(listenSock); + } + PR_Lock(info->dead_lock); + (*info->alive)--; + PR_NotifyCondVar(info->dead_cv); + PR_Unlock(info->dead_lock); + + if (debug_mode) printf("thread %d is dead\n", info->id); +} + +void +thread_test(PRInt32 scope, PRInt32 num_threads) +{ + PRInt32 index; + PRThread *thr; + PRLock *dead_lock; + PRCondVar *dead_cv; + PRInt32 alive; + + if (debug_mode) printf("IO Timeout test started with %d threads\n", num_threads); + + dead_lock = PR_NewLock(); + dead_cv = PR_NewCondVar(dead_lock); + alive = num_threads; + + for (index = 0; index < num_threads; index++) { + threadInfo *info = (threadInfo *)malloc(sizeof(threadInfo)); + + info->id = index; + info->dead_lock = dead_lock; + info->dead_cv = dead_cv; + info->alive = &alive; + info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT; + + thr = PR_CreateThread( PR_USER_THREAD, + thread_main, + (void *)info, + PR_PRIORITY_NORMAL, + scope, + PR_UNJOINABLE_THREAD, + 0); + + if (!thr) { + PR_Lock(dead_lock); + alive--; + PR_Unlock(dead_lock); + } + } + + PR_Lock(dead_lock); + while(alive) { + if (debug_mode) printf("main loop awake; alive = %d\n", alive); + PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(dead_lock); +} + +int main(int argc, char **argv) +{ + PRInt32 num_threads; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + if (argc > 2) + num_threads = atoi(argv[2]); + else + num_threads = NUM_THREADS; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0); + PR_STDIO_INIT(); + + if (debug_mode) printf("user level test\n"); + thread_test(PR_LOCAL_THREAD, num_threads); + + PR_Cleanup(); + if(failed_already) + return 1; + else + return 0; + + +} diff -Nru nspr-4.9.5/nspr/pr/tests/ipv6.c nspr-4.10.7/nspr/pr/tests/ipv6.c --- nspr-4.9.5/nspr/pr/tests/ipv6.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/ipv6.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,216 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prenv.h" +#include "prmem.h" +#include "prlink.h" +#include "prsystem.h" +#include "prnetdb.h" +#include "prprf.h" +#include "prvrsion.h" + +#include "plerror.h" +#include "plgetopt.h" +#include "obsolete/probslet.h" + +#include + +#define DNS_BUFFER 100 +#define ADDR_BUFFER 100 +#define HOST_BUFFER 1024 +#define PROTO_BUFFER 1500 + +#define NETADDR_SIZE(addr) \ + (PR_AF_INET == (addr)->raw.family ? \ + sizeof((addr)->inet) : sizeof((addr)->ipv6)) + +static PRFileDesc *err = NULL; + +static void Help(void) +{ + PR_fprintf(err, "Usage: [-V] [-h]\n"); + PR_fprintf(err, "\t Name of host to lookup (default: self)\n"); + PR_fprintf(err, "\t-V Display runtime version info (default: FALSE)\n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); +} /* Help */ + +static void DumpAddr(const PRNetAddr* address, const char *msg) +{ + PRUint32 *word = (PRUint32*)address; + PRUint32 addr_len = sizeof(PRNetAddr); + PR_fprintf(err, "%s[%d]\t", msg, NETADDR_SIZE(address)); + while (addr_len > 0) + { + PR_fprintf(err, " %08x", *word++); + addr_len -= sizeof(PRUint32); + } + PR_fprintf(err, "\n"); +} /* DumpAddr */ + +static PRStatus PrintAddress(const PRNetAddr* address) +{ + PRNetAddr translation; + char buffer[ADDR_BUFFER]; + PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); + if (PR_FAILURE == rv) PL_FPrintError(err, "PR_NetAddrToString"); + else + { + PR_fprintf(err, "\t%s\n", buffer); + memset(&translation, 0, sizeof(translation)); + rv = PR_StringToNetAddr(buffer, &translation); + if (PR_FAILURE == rv) PL_FPrintError(err, "PR_StringToNetAddr"); + else + { + PRSize addr_len = NETADDR_SIZE(address); + if (0 != memcmp(address, &translation, addr_len)) + { + PR_fprintf(err, "Address translations do not match\n"); + DumpAddr(address, "original"); + DumpAddr(&translation, "translate"); + rv = PR_FAILURE; + } + } + } + return rv; +} /* PrintAddress */ + +int main(int argc, char **argv) +{ + PRStatus rv; + PLOptStatus os; + PRHostEnt host; + PRProtoEnt proto; + const char *name = NULL; + PRBool failed = PR_FALSE, version = PR_FALSE; + PLOptState *opt = PL_CreateOptState(argc, argv, "Vh"); + + err = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: /* Name of host to lookup */ + name = opt->value; + break; + case 'V': /* Do version discovery */ + version = PR_TRUE; + break; + case 'h': /* user wants some guidance */ + default: + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + } + } + PL_DestroyOptState(opt); + + if (version) + { +#if defined(WINNT) +#define NSPR_LIB "libnspr4" +#else +#define NSPR_LIB "nspr4" +#endif + const PRVersionDescription *version_info; + char *nspr_path = PR_GetEnv("LD_LIBRARY_PATH"); + char *nspr_name = PR_GetLibraryName(nspr_path, NSPR_LIB); + PRLibrary *runtime = PR_LoadLibrary(nspr_name); + if (NULL == runtime) + PL_FPrintError(err, "PR_LoadLibrary"); + else + { + versionEntryPointType versionPoint = (versionEntryPointType) + PR_FindSymbol(runtime, "libVersionPoint"); + if (NULL == versionPoint) + PL_FPrintError(err, "PR_FindSymbol"); + else + { + char buffer[100]; + PRExplodedTime exploded; + version_info = versionPoint(); + (void)PR_fprintf(err, "Runtime library version information\n"); + PR_ExplodeTime( + version_info->buildTime, PR_GMTParameters, &exploded); + (void)PR_FormatTime( + buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded); + (void)PR_fprintf(err, " Build time: %s GMT\n", buffer); + (void)PR_fprintf( + err, " Build time: %s\n", version_info->buildTimeString); + (void)PR_fprintf( + err, " %s V%u.%u.%u (%s%s%s)\n", + version_info->description, + version_info->vMajor, + version_info->vMinor, + version_info->vPatch, + (version_info->beta ? " beta " : ""), + (version_info->debug ? " debug " : ""), + (version_info->special ? " special" : "")); + (void)PR_fprintf(err, " filename: %s\n", version_info->filename); + (void)PR_fprintf(err, " security: %s\n", version_info->security); + (void)PR_fprintf(err, " copyright: %s\n", version_info->copyright); + (void)PR_fprintf(err, " comment: %s\n", version_info->comment); + } + } + if (NULL != nspr_name) PR_FreeLibraryName(nspr_name); + } + + { + if (NULL == name) + { + char *me = (char*)PR_MALLOC(DNS_BUFFER); + rv = PR_GetSystemInfo(PR_SI_HOSTNAME, me, DNS_BUFFER); + if (PR_FAILURE == rv) + { + failed = PR_TRUE; + PL_FPrintError(err, "PR_GetSystemInfo"); + return 2; + } + name = me; /* just leak the storage */ + } + } + + { + char buffer[HOST_BUFFER]; + PR_fprintf(err, "Translating the name %s ...", name); + + rv = PR_GetHostByName(name, buffer, sizeof(buffer), &host); + if (PR_FAILURE == rv) + { + failed = PR_TRUE; + PL_FPrintError(err, "PR_GetHostByName"); + } + else + { + PRIntn index = 0; + PRNetAddr address; + memset(&address, 0, sizeof(PRNetAddr)); + PR_fprintf(err, "success .. enumerating results\n"); + do + { + index = PR_EnumerateHostEnt(index, &host, 0, &address); + if (index > 0) PrintAddress(&address); + else if (-1 == index) + { + failed = PR_TRUE; + PL_FPrintError(err, "PR_EnumerateHostEnt"); + } + } while (index > 0); + } + } + + + { + char buffer[PROTO_BUFFER]; + /* + ** Get Proto by name/number + */ + rv = PR_GetProtoByName("tcp", &buffer[1], sizeof(buffer) - 1, &proto); + rv = PR_GetProtoByNumber(6, &buffer[3], sizeof(buffer) - 3, &proto); + } + + return (failed) ? 1 : 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/join.c nspr-4.10.7/nspr/pr/tests/join.c --- nspr-4.9.5/nspr/pr/tests/join.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/join.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,220 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: dbmalloc1.c +** +** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions. +** +** Modification History: +** +** 19-May-97 AGarcia - separate the four join tests into different unit test modules. +** AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" +#include "prttools.h" + +#include "nspr.h" + +#include +#include +#include + +/*********************************************************************** +** PRIVATE FUNCTION: Test_Result +** DESCRIPTION: Used in conjunction with the regress tool, prints out the +** status of the test case. +** INPUTS: PASS/FAIL +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** +** RESTRICTIONS: +** None +** MEMORY: NA +** ALGORITHM: Determine what the status is and print accordingly. +** +***********************************************************************/ + + +static void Test_Result (int result) +{ + if (result == PASS) + printf ("PASS\n"); + else + printf ("FAIL\n"); + exit (1); +} + + +/* + Program to test joining of threads. Two threads are created. One + to be waited upon until it has started. The other to join after it has + completed. +*/ + + +static void PR_CALLBACK lowPriority(void *arg) +{ +} + +static void PR_CALLBACK highPriority(void *arg) +{ +} + +static void PR_CALLBACK unjoinable(void *arg) +{ + PR_Sleep(PR_INTERVAL_NO_TIMEOUT); +} + +void runTest(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *low,*high; + + /* create the low and high priority threads */ + + low = PR_CreateThread(PR_USER_THREAD, + lowPriority, 0, + PR_PRIORITY_LOW, + scope1, + PR_JOINABLE_THREAD, + 0); + if (!low) { + if (debug_mode) printf("\tcannot create low priority thread\n"); + else Test_Result(FAIL); + return; + } + + high = PR_CreateThread(PR_USER_THREAD, + highPriority, 0, + PR_PRIORITY_HIGH, + scope2, + PR_JOINABLE_THREAD, + 0); + if (!high) { + if (debug_mode) printf("\tcannot create high priority thread\n"); + else Test_Result(FAIL); + return; + } + + /* Do the joining for both threads */ + if (PR_JoinThread(low) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join low priority thread\n"); + else Test_Result (FAIL); + return; + } else { + if (debug_mode) printf("\tjoined low priority thread\n"); + } + if (PR_JoinThread(high) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join high priority thread\n"); + else Test_Result(FAIL); + return; + } else { + if (debug_mode) printf("\tjoined high priority thread\n"); + } +} + +void joinWithUnjoinable(void) +{ + PRThread *thread; + + /* create the unjoinable thread */ + + thread = PR_CreateThread(PR_USER_THREAD, + unjoinable, 0, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + if (!thread) { + if (debug_mode) printf("\tcannot create unjoinable thread\n"); + else Test_Result(FAIL); + return; + } + + if (PR_JoinThread(thread) == PR_SUCCESS) { + if (debug_mode) printf("\tsuccessfully joined with unjoinable thread?!\n"); + else Test_Result(FAIL); + return; + } else { + if (debug_mode) printf("\tcannot join with unjoinable thread, as expected\n"); + if (PR_GetError() != PR_INVALID_ARGUMENT_ERROR) { + if (debug_mode) printf("\tWrong error code\n"); + else Test_Result(FAIL); + return; + } + } + if (PR_Interrupt(thread) == PR_FAILURE) { + if (debug_mode) printf("\tcannot interrupt unjoinable thread\n"); + else Test_Result(FAIL); + return; + } else { + if (debug_mode) printf("\tinterrupted unjoinable thread\n"); + } +} + +static PRIntn PR_CALLBACK RealMain(int argc, char **argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + printf("User-User test\n"); + runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD); + printf("User-Kernel test\n"); + runTest(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); + printf("Kernel-User test\n"); + runTest(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); + printf("Kernel-Kernel test\n"); + runTest(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); + printf("Join with unjoinable thread\n"); + joinWithUnjoinable(); + + printf("PASSED\n"); + + return 0; +} + + + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/joinkk.c nspr-4.10.7/nspr/pr/tests/joinkk.c --- nspr-4.9.5/nspr/pr/tests/joinkk.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/joinkk.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,150 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: dbmalloc1.c +** +** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions. +** +** Modification History: +** +** 19-May-97 AGarcia - separate the four join tests into different unit test modules. +** AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; +/* + Program to test joining of threads. Two threads are created. One + to be waited upon until it has started. The other to join after it has + completed. +*/ + + +static void lowPriority(void *arg) +{ +} + +static void highPriority(void *arg) +{ +} + +void runTest(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *low,*high; + + /* create the low and high priority threads */ + + low = PR_CreateThread(PR_USER_THREAD, + lowPriority, 0, + PR_PRIORITY_LOW, + scope1, + PR_JOINABLE_THREAD, + 0); + if (!low) { + if (debug_mode) printf("\tcannot create low priority thread\n"); + else failed_already=1; + return; + } + + high = PR_CreateThread(PR_USER_THREAD, + highPriority, 0, + PR_PRIORITY_HIGH, + scope2, + PR_JOINABLE_THREAD, + 0); + if (!high) { + if (debug_mode) printf("\tcannot create high priority thread\n"); + else failed_already=1; + return; + } + + /* Do the joining for both threads */ + if (PR_JoinThread(low) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join low priority thread\n"); + else failed_already=1; + return; + } else { + if (debug_mode) printf("\tjoined low priority thread\n"); + } + if (PR_JoinThread(high) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join high priority thread\n"); + else failed_already=1; + return; + } else { + if (debug_mode) printf("\tjoined high priority thread\n"); + } +} + +static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + if (debug_mode) printf("Kernel-Kernel test\n"); + runTest(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); + + if(failed_already) + { + printf("FAIL\n"); + return 1; + } + else + { + printf("PASS\n"); + return 0; + } + +} + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/joinku.c nspr-4.10.7/nspr/pr/tests/joinku.c --- nspr-4.9.5/nspr/pr/tests/joinku.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/joinku.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: dbmalloc1.c +** +** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions. +** +** Modification History: +** +** 19-May-97 AGarcia - separate the four join tests into different unit test modules. +** AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + + +/* + Program to test joining of threads. Two threads are created. One + to be waited upon until it has started. The other to join after it has + completed. +*/ + + +static void lowPriority(void *arg) +{ +} + +static void highPriority(void *arg) +{ +} + +void runTest(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *low,*high; + + /* create the low and high priority threads */ + + low = PR_CreateThread(PR_USER_THREAD, + lowPriority, 0, + PR_PRIORITY_LOW, + scope1, + PR_JOINABLE_THREAD, + 0); + if (!low) { + if (debug_mode) printf("\tcannot create low priority thread\n"); + else failed_already=1; + return; + } + + high = PR_CreateThread(PR_USER_THREAD, + highPriority, 0, + PR_PRIORITY_HIGH, + scope2, + PR_JOINABLE_THREAD, + 0); + if (!high) { + if (debug_mode) printf("\tcannot create high priority thread\n"); + else failed_already=1; + return; + } + + /* Do the joining for both threads */ + if (PR_JoinThread(low) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join low priority thread\n"); + else failed_already=1; + return; + } else { + if (debug_mode) printf("\tjoined low priority thread\n"); + } + if (PR_JoinThread(high) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join high priority thread\n"); + else failed_already=1; + return; + } else { + if (debug_mode) printf("\tjoined high priority thread\n"); + } +} + +static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + /* main test */ + + if (debug_mode) printf("Kernel-User test\n"); + runTest(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); + + + if(failed_already) + { + printf("FAIL\n"); + return 1; + } + else + { + printf("PASS\n"); + return 0; + } + +} + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/joinuk.c nspr-4.10.7/nspr/pr/tests/joinuk.c --- nspr-4.9.5/nspr/pr/tests/joinuk.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/joinuk.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: joinuk.c +** +** Description: Join kernel - user +** +** Modification History: +** +** 19-May-97 AGarcia - separate the four join tests into different unit test modules. +** AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; +/* + Program to test joining of threads. Two threads are created. One + to be waited upon until it has started. The other to join after it has + completed. +*/ + + +static void lowPriority(void *arg) +{ +} + +static void highPriority(void *arg) +{ +} + +void runTest(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *low,*high; + + /* create the low and high priority threads */ + + low = PR_CreateThread(PR_USER_THREAD, + lowPriority, 0, + PR_PRIORITY_LOW, + scope1, + PR_JOINABLE_THREAD, + 0); + if (!low) { + if (debug_mode) printf("\tcannot create low priority thread\n"); + else failed_already=1; + return; + } + + high = PR_CreateThread(PR_USER_THREAD, + highPriority, 0, + PR_PRIORITY_HIGH, + scope2, + PR_JOINABLE_THREAD, + 0); + if (!high) { + if (debug_mode) printf("\tcannot create high priority thread\n"); + else failed_already=1; + return; + } + + /* Do the joining for both threads */ + if (PR_JoinThread(low) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join low priority thread\n"); + else failed_already=1; + return; + } else { + if (debug_mode) printf("\tjoined low priority thread\n"); + } + if (PR_JoinThread(high) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join high priority thread\n"); + else failed_already=1; + return; + } else { + if (debug_mode) printf("\tjoined high priority thread\n"); + } +} + +static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + /* main test */ + + if (debug_mode) printf("User-Kernel test\n"); + runTest(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); + + + if(failed_already) + { + printf("FAIL\n"); + return 1; + } else + { + printf("PASS\n"); + return 0; + } +} + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/joinuu.c nspr-4.10.7/nspr/pr/tests/joinuu.c --- nspr-4.9.5/nspr/pr/tests/joinuu.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/joinuu.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: dbmalloc1.c +** +** Description: Join tests user - user +** +** Modification History: +** +** 19-May-97 AGarcia - separate the four join tests into different unit test modules. +** AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + + +/* + Program to test joining of threads. Two threads are created. One + to be waited upon until it has started. The other to join after it has + completed. +*/ + + +static void lowPriority(void *arg) +{ +} + +static void highPriority(void *arg) +{ +} + +void runTest(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *low,*high; + + /* create the low and high priority threads */ + + low = PR_CreateThread(PR_USER_THREAD, + lowPriority, 0, + PR_PRIORITY_LOW, + scope1, + PR_JOINABLE_THREAD, + 0); + if (!low) { + if (debug_mode) printf("\tcannot create low priority thread\n"); + else failed_already=1; + return; + } + + high = PR_CreateThread(PR_USER_THREAD, + highPriority, 0, + PR_PRIORITY_HIGH, + scope2, + PR_JOINABLE_THREAD, + 0); + if (!high) { + if (debug_mode) printf("\tcannot create high priority thread\n"); + else failed_already=1; + return; + } + + /* Do the joining for both threads */ + if (PR_JoinThread(low) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join low priority thread\n"); + else failed_already=1; + return; + } else { + if (debug_mode) printf("\tjoined low priority thread\n"); + } + if (PR_JoinThread(high) == PR_FAILURE) { + if (debug_mode) printf("\tcannot join high priority thread\n"); + else failed_already=1; + return; + } else { + if (debug_mode) printf("\tjoined high priority thread\n"); + } +} + +static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + /* main test */ + if (debug_mode) printf("User-User test\n"); + runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD); + + if(failed_already) + { + printf("FAIL\n"); + return 1; + } else + { + printf("PASS\n"); + return 0; + } + + +} + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/layer.c nspr-4.10.7/nspr/pr/tests/layer.c --- nspr-4.9.5/nspr/pr/tests/layer.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/layer.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,434 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prprf.h" +#include "prlog.h" +#include "prnetdb.h" +#include "prthread.h" + +#include "plerror.h" +#include "plgetopt.h" +#include "prwin16.h" + +#include +#include + +/* +** Testing layering of I/O +** +** The layered server +** A thread that acts as a server. It creates a TCP listener with a dummy +** layer pushed on top. Then listens for incoming connections. Each connection +** request for connection will be layered as well, accept one request, echo +** it back and close. +** +** The layered client +** Pretty much what you'd expect. +*/ + +static PRFileDesc *logFile; +static PRDescIdentity identity; +static PRNetAddr server_address; + +static PRIOMethods myMethods; + +typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity; + +static PRIntn minor_iterations = 5; +static PRIntn major_iterations = 1; +static Verbosity verbosity = quiet; +static PRUint16 default_port = 12273; + +static PRFileDesc *PushLayer(PRFileDesc *stack) +{ + PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods); + PRStatus rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); + if (verbosity > quiet) + PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); + PR_ASSERT(PR_SUCCESS == rv); + return stack; +} /* PushLayer */ + +static PRFileDesc *PushNewLayers(PRFileDesc *stack) +{ + PRDescIdentity tmp_identity; + PRFileDesc *layer; + PRStatus rv; + + /* push a dummy layer */ + tmp_identity = PR_GetUniqueIdentity("Dummy 1"); + layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); + rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); + if (verbosity > quiet) + PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, + stack); + PR_ASSERT(PR_SUCCESS == rv); + + /* push a data procesing layer */ + layer = PR_CreateIOLayerStub(identity, &myMethods); + rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); + if (verbosity > quiet) + PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, + stack); + PR_ASSERT(PR_SUCCESS == rv); + + /* push another dummy layer */ + tmp_identity = PR_GetUniqueIdentity("Dummy 2"); + layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); + rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); + if (verbosity > quiet) + PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, + stack); + PR_ASSERT(PR_SUCCESS == rv); + return stack; +} /* PushLayer */ + +#if 0 +static PRFileDesc *PopLayer(PRFileDesc *stack) +{ + PRFileDesc *popped = PR_PopIOLayer(stack, identity); + if (verbosity > quiet) + PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack); + popped->dtor(popped); + + return stack; +} /* PopLayer */ +#endif + +static void PR_CALLBACK Client(void *arg) +{ + PRStatus rv; + PRUint8 buffer[100]; + PRIntn empty_flags = 0; + PRIntn bytes_read, bytes_sent; + PRFileDesc *stack = (PRFileDesc*)arg; + + /* Initialize the buffer so that Purify won't complain */ + memset(buffer, 0, sizeof(buffer)); + + rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(PR_SUCCESS == rv); + while (minor_iterations-- > 0) + { + bytes_sent = PR_Send( + stack, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(sizeof(buffer) == bytes_sent); + if (verbosity > chatty) + PR_fprintf(logFile, "Client sending %d bytes\n", bytes_sent); + bytes_read = PR_Recv( + stack, buffer, bytes_sent, empty_flags, PR_INTERVAL_NO_TIMEOUT); + if (verbosity > chatty) + PR_fprintf(logFile, "Client receiving %d bytes\n", bytes_read); + PR_ASSERT(bytes_read == bytes_sent); + } + + if (verbosity > quiet) + PR_fprintf(logFile, "Client shutting down stack\n"); + + rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); +} /* Client */ + +static void PR_CALLBACK Server(void *arg) +{ + PRStatus rv; + PRUint8 buffer[100]; + PRFileDesc *service; + PRUintn empty_flags = 0; + PRIntn bytes_read, bytes_sent; + PRFileDesc *stack = (PRFileDesc*)arg; + PRNetAddr client_address; + + service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT); + if (verbosity > quiet) + PR_fprintf(logFile, "Server accepting connection\n"); + + do + { + bytes_read = PR_Recv( + service, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); + if (0 != bytes_read) + { + if (verbosity > chatty) + PR_fprintf(logFile, "Server receiving %d bytes\n", bytes_read); + PR_ASSERT(bytes_read > 0); + bytes_sent = PR_Send( + service, buffer, bytes_read, empty_flags, PR_INTERVAL_NO_TIMEOUT); + if (verbosity > chatty) + PR_fprintf(logFile, "Server sending %d bytes\n", bytes_sent); + PR_ASSERT(bytes_read == bytes_sent); + } + + } while (0 != bytes_read); + + if (verbosity > quiet) + PR_fprintf(logFile, "Server shutting down and closing stack\n"); + rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); + +} /* Server */ + +static PRInt32 PR_CALLBACK MyRecv( + PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + char *b = (char*)buf; + PRFileDesc *lo = fd->lower; + PRInt32 rv, readin = 0, request = 0; + rv = lo->methods->recv(lo, &request, sizeof(request), flags, timeout); + if (verbosity > chatty) PR_fprintf( + logFile, "MyRecv sending permission for %d bytes\n", request); + if (0 < rv) + { + if (verbosity > chatty) PR_fprintf( + logFile, "MyRecv received permission request for %d bytes\n", request); + rv = lo->methods->send( + lo, &request, sizeof(request), flags, timeout); + if (0 < rv) + { + if (verbosity > chatty) PR_fprintf( + logFile, "MyRecv sending permission for %d bytes\n", request); + while (readin < request) + { + rv = lo->methods->recv( + lo, b + readin, amount - readin, flags, timeout); + if (rv <= 0) break; + if (verbosity > chatty) PR_fprintf( + logFile, "MyRecv received %d bytes\n", rv); + readin += rv; + } + rv = readin; + } + } + return rv; +} /* MyRecv */ + +static PRInt32 PR_CALLBACK MySend( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + PRFileDesc *lo = fd->lower; + const char *b = (const char*)buf; + PRInt32 rv, wroteout = 0, request; + if (verbosity > chatty) PR_fprintf( + logFile, "MySend asking permission to send %d bytes\n", amount); + rv = lo->methods->send(lo, &amount, sizeof(amount), flags, timeout); + if (0 < rv) + { + rv = lo->methods->recv( + lo, &request, sizeof(request), flags, timeout); + if (0 < rv) + { + PR_ASSERT(request == amount); + if (verbosity > chatty) PR_fprintf( + logFile, "MySend got permission to send %d bytes\n", request); + while (wroteout < request) + { + rv = lo->methods->send( + lo, b + wroteout, request - wroteout, flags, timeout); + if (rv <= 0) break; + if (verbosity > chatty) PR_fprintf( + logFile, "MySend wrote %d bytes\n", rv); + wroteout += rv; + } + rv = amount; + } + } + return rv; +} /* MySend */ + +static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta) +{ + PRIntn verbage = (PRIntn)verbosity + delta; + if (verbage < (PRIntn)silent) verbage = (PRIntn)silent; + else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy; + return (Verbosity)verbage; +} /* ChangeVerbosity */ + +int main(int argc, char **argv) +{ + PRStatus rv; + PRIntn mits; + PLOptStatus os; + PRFileDesc *client, *service; + PRFileDesc *client_stack, *service_stack; + PRNetAddr any_address; + const char *server_name = NULL; + const PRIOMethods *stubMethods; + PRThread *client_thread, *server_thread; + PRThreadScope thread_scope = PR_LOCAL_THREAD; + PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: + server_name = opt->value; + break; + case 'd': /* debug mode */ + if (verbosity < noisy) + verbosity = ChangeVerbosity(verbosity, 1); + break; + case 'q': /* debug mode */ + if (verbosity > silent) + verbosity = ChangeVerbosity(verbosity, -1); + break; + case 'G': /* use global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'C': /* number of threads waiting */ + major_iterations = atoi(opt->value); + break; + case 'c': /* number of client threads */ + minor_iterations = atoi(opt->value); + break; + case 'p': /* default port */ + default_port = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + PR_STDIO_INIT(); + + logFile = PR_GetSpecialFD(PR_StandardError); + + identity = PR_GetUniqueIdentity("Dummy"); + stubMethods = PR_GetDefaultIOMethods(); + + /* + ** The protocol we're going to implement is one where in order to initiate + ** a send, the sender must first solicit permission. Therefore, every + ** send is really a send - receive - send sequence. + */ + myMethods = *stubMethods; /* first get the entire batch */ + myMethods.recv = MyRecv; /* then override the ones we care about */ + myMethods.send = MySend; /* then override the ones we care about */ + + if (NULL == server_name) + rv = PR_InitializeNetAddr( + PR_IpAddrLoopback, default_port, &server_address); + else + { + rv = PR_StringToNetAddr(server_name, &server_address); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_InitializeNetAddr( + PR_IpAddrNull, default_port, &server_address); + } + PR_ASSERT(PR_SUCCESS == rv); + + /* one type w/o layering */ + + mits = minor_iterations; + while (major_iterations-- > 0) + { + if (verbosity > silent) + PR_fprintf(logFile, "Beginning non-layered test\n"); + client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); + service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); + rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); + + minor_iterations = mits; + server_thread = PR_CreateThread( + PR_USER_THREAD, Server, service, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != server_thread); + + client_thread = PR_CreateThread( + PR_USER_THREAD, Client, client, + PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != client_thread); + + rv = PR_JoinThread(client_thread); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(server_thread); + PR_ASSERT(PR_SUCCESS == rv); + + rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); + if (verbosity > silent) + PR_fprintf(logFile, "Ending non-layered test\n"); + + /* with layering */ + if (verbosity > silent) + PR_fprintf(logFile, "Beginning layered test\n"); + client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); + PushLayer(client); + service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); + PushLayer(service); + rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); + + minor_iterations = mits; + server_thread = PR_CreateThread( + PR_USER_THREAD, Server, service, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != server_thread); + + client_thread = PR_CreateThread( + PR_USER_THREAD, Client, client, + PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != client_thread); + + rv = PR_JoinThread(client_thread); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(server_thread); + PR_ASSERT(PR_SUCCESS == rv); + + rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); + /* with layering, using new style stack */ + if (verbosity > silent) + PR_fprintf(logFile, + "Beginning layered test with new style stack\n"); + client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); + client_stack = PR_CreateIOLayer(client); + PushNewLayers(client_stack); + service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); + service_stack = PR_CreateIOLayer(service); + PushNewLayers(service_stack); + rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); + + minor_iterations = mits; + server_thread = PR_CreateThread( + PR_USER_THREAD, Server, service_stack, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != server_thread); + + client_thread = PR_CreateThread( + PR_USER_THREAD, Client, client_stack, + PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != client_thread); + + rv = PR_JoinThread(client_thread); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(server_thread); + PR_ASSERT(PR_SUCCESS == rv); + + rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv); + if (verbosity > silent) + PR_fprintf(logFile, "Ending layered test\n"); + } + return 0; +} /* main */ + +/* layer.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/lazyinit.c nspr-4.10.7/nspr/pr/tests/lazyinit.c --- nspr-4.9.5/nspr/pr/tests/lazyinit.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/lazyinit.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: lazyinit.c +** Description: Testing lazy initialization +** +** Since you only get to initialize once, you have to rerun the test +** for each test case. The test cases are numbered. If you want to +** add more tests, take the next number and add it to the switch +** statement. +** +** This test is problematic on systems that don't support the notion +** of console output. The workarounds to emulate that feature include +** initializations themselves, which defeats the purpose here. +*/ + +#include "prcvar.h" +#include "prenv.h" +#include "prinit.h" +#include "prinrval.h" +#include "prio.h" +#include "prlock.h" +#include "prlog.h" +#include "prthread.h" +#include "prtypes.h" + +#include +#include + +static void PR_CALLBACK lazyEntry(void *arg) +{ + PR_ASSERT(NULL == arg); +} /* lazyEntry */ + + +int main(int argc, char **argv) +{ + PRUintn pdkey; + PRStatus status; + char *path = NULL; + PRDir *dir = NULL; + PRLock *ml = NULL; + PRCondVar *cv = NULL; + PRThread *thread = NULL; + PRIntervalTime interval = 0; + PRFileDesc *file, *udp, *tcp, *pair[2]; + PRIntn test; + + if ( argc < 2) + { + test = 0; + } + else + test = atoi(argv[1]); + + switch (test) + { + case 0: ml = PR_NewLock(); + break; + + case 1: interval = PR_SecondsToInterval(1); + break; + + case 2: thread = PR_CreateThread( + PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + break; + + case 3: file = PR_Open("/usr/tmp/", PR_RDONLY, 0); + break; + + case 4: udp = PR_NewUDPSocket(); + break; + + case 5: tcp = PR_NewTCPSocket(); + break; + + case 6: dir = PR_OpenDir("/usr/tmp/"); + break; + + case 7: (void)PR_NewThreadPrivateIndex(&pdkey, NULL); + break; + + case 8: path = PR_GetEnv("PATH"); + break; + + case 9: status = PR_NewTCPSocketPair(pair); + break; + + case 10: PR_SetConcurrency(2); + break; + + default: + printf( + "lazyinit: unrecognized command line argument: %s\n", + argv[1] ); + printf( "FAIL\n" ); + exit( 1 ); + break; + } /* switch() */ + return 0; +} /* Lazy */ + +/* lazyinit.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/libfilename.c nspr-4.10.7/nspr/pr/tests/libfilename.c --- nspr-4.9.5/nspr/pr/tests/libfilename.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/libfilename.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: libfilename.c +** +** Description: test PR_GetLibraryFilePathname. +** +***********************************************************************/ + +#include "nspr.h" +#include "pprio.h" +#include +#include +#include + +PRBool debug_mode = PR_FALSE; + +static PRStatus RunTest(const char *name, PRFuncPtr addr) +{ + char *pathname; + PRFileDesc *fd; + + pathname = PR_GetLibraryFilePathname(name, addr); + if (pathname == NULL) { + fprintf(stderr, "PR_GetLibraryFilePathname failed\n"); + /* we let this test pass if this function is not implemented */ + if (PR_GetError() == PR_NOT_IMPLEMENTED_ERROR) { + return PR_SUCCESS; + } + return PR_FAILURE; + } + + if (debug_mode) printf("Pathname is %s\n", pathname); + fd = PR_OpenFile(pathname, PR_RDONLY, 0); + if (fd == NULL) { + fprintf(stderr, "PR_Open failed: %d\n", (int)PR_GetError()); + return PR_FAILURE; + } + if (PR_Close(fd) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed: %d\n", (int)PR_GetError()); + return PR_FAILURE; + } + PR_Free(pathname); + return PR_SUCCESS; +} + +int main(int argc, char **argv) +{ + char *name; + PRFuncPtr addr; + PRLibrary *lib; + PRBool failed = PR_FALSE; + + if (argc >= 2 && strcmp(argv[1], "-d") == 0) { + debug_mode = PR_TRUE; + } + + /* First test a library that is implicitly linked. */ +#ifdef WINNT + name = PR_Malloc(strlen("libnspr4.dll")+1); + strcpy(name, "libnspr4.dll"); +#else + name = PR_GetLibraryName(NULL, "nspr4"); +#endif + addr = (PRFuncPtr)PR_GetTCPMethods()->close; + if (RunTest(name, addr) == PR_FAILURE) { + failed = PR_TRUE; + } + PR_FreeLibraryName(name); + + /* Next test a library that is dynamically loaded. */ + name = PR_GetLibraryName("dll", "my"); + if (debug_mode) printf("Loading library %s\n", name); + lib = PR_LoadLibrary(name); + if (!lib) { + fprintf(stderr, "PR_LoadLibrary failed\n"); + exit(1); + } + PR_FreeLibraryName(name); + name = PR_GetLibraryName(NULL, "my"); + addr = PR_FindFunctionSymbol(lib, "My_GetValue"); + if (RunTest(name, addr) == PR_FAILURE) { + failed = PR_TRUE; + } + PR_FreeLibraryName(name); + PR_UnloadLibrary(lib); + if (failed) { + printf("FAIL\n"); + return 1; + } + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/lltest.c nspr-4.10.7/nspr/pr/tests/lltest.c --- nspr-4.9.5/nspr/pr/tests/lltest.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/lltest.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,827 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** testll.c -- test suite for 64bit integer (longlong) operations +** +** Summary: testll [-d] | [-h] +** +** Where: +** -d set debug mode on; displays individual test failures +** -v verbose mode; displays progress in test, plus -d +** -h gives usage message. +** +** Description: +** lltest.c tests the functions defined in NSPR 2.0's prlong.h. +** +** Successive tests begin to depend on other LL functions working +** correctly. So, ... Do not change the order of the tests as run +** from main(). +** +** Caveats: +** Do not even begin to think that this is an exhaustive test! +** +** These tests try a little of everything, but not all boundary +** conditions and limits are tested. +** You want better coverage? ... Add it. +** +** --- +** Author: Lawrence Hardiman . +** --- +** Revision History: +** 01-Oct-1997. Original implementation. +** +*/ + +#include "nspr.h" +#include "plgetopt.h" + +/* --- Local Definitions --- */ +#define ReportProgress(m) if (verboseMode) PR_fprintf(output, (m)); + + +/* --- Global variables --- */ +static PRIntn failedAlready = 0; +static PRFileDesc* output = NULL; +static PRBool debugMode = PR_FALSE; +static PRBool verboseMode = PR_FALSE; + +/* +** Constants used in tests. +*/ +const PRInt64 bigZero = LL_INIT( 0, 0 ); +const PRInt64 bigOne = LL_INIT( 0, 1 ); +const PRInt64 bigTwo = LL_INIT( 0, 2 ); +const PRInt64 bigSixTeen = LL_INIT( 0, 16 ); +const PRInt64 bigThirtyTwo = LL_INIT( 0, 32 ); +const PRInt64 bigMinusOne = LL_INIT( 0xffffffff, 0xffffffff ); +const PRInt64 bigMinusTwo = LL_INIT( 0xffffffff, 0xfffffffe ); +const PRInt64 bigNumber = LL_INIT( 0x7fffffff, 0xffffffff ); +const PRInt64 bigMinusNumber = LL_INIT( 0x80000000, 0x00000001 ); +const PRInt64 bigMaxInt32 = LL_INIT( 0x00000000, 0x7fffffff ); +const PRInt64 big2To31 = LL_INIT( 0x00000000, 0x80000000 ); +const PRUint64 bigZeroFox = LL_INIT( 0x00000000, 0xffffffff ); +const PRUint64 bigFoxFox = LL_INIT( 0xffffffff, 0xffffffff ); +const PRUint64 bigFoxZero = LL_INIT( 0xffffffff, 0x00000000 ); +const PRUint64 bigEightZero = LL_INIT( 0x80000000, 0x00000000 ); +const PRUint64 big64K = LL_INIT( 0x00000000, 0x00010000 ); +const PRInt64 bigInt0 = LL_INIT( 0x01a00000, 0x00001000 ); +const PRInt64 bigInt1 = LL_INIT( 0x01a00000, 0x00001100 ); +const PRInt64 bigInt2 = LL_INIT( 0x01a00000, 0x00000100 ); +const PRInt64 bigInt3 = LL_INIT( 0x01a00001, 0x00001000 ); +const PRInt64 bigInt4 = LL_INIT( 0x01a00001, 0x00001100 ); +const PRInt64 bigInt5 = LL_INIT( 0x01a00001, 0x00000100 ); +const PRInt64 bigInt6 = LL_INIT( 0xb1a00000, 0x00001000 ); +const PRInt64 bigInt7 = LL_INIT( 0xb1a00000, 0x00001100 ); +const PRInt64 bigInt8 = LL_INIT( 0xb1a00000, 0x00000100 ); +const PRInt64 bigInt9 = LL_INIT( 0xb1a00001, 0x00001000 ); +const PRInt64 bigInt10 = LL_INIT( 0xb1a00001, 0x00001100 ); +const PRInt64 bigInt11 = LL_INIT( 0xb1a00001, 0x00000100 ); +const PRInt32 one = 1l; +const PRInt32 minusOne = -1l; +const PRInt32 sixteen = 16l; +const PRInt32 thirtyTwo = 32l; +const PRInt32 sixtyThree = 63l; + +/* +** SetFailed() -- Report individual test failure +** +*/ +static void +SetFailed( char *what, char *how ) +{ + failedAlready = 1; + if ( debugMode ) + PR_fprintf(output, "%s: failed: %s\n", what, how ); + return; +} + +static void +ResultFailed( char *what, char *how, PRInt64 expected, PRInt64 got) +{ + if ( debugMode) + { + SetFailed( what, how ); + PR_fprintf(output, "Expected: 0x%llx Got: 0x%llx\n", expected, got ); + } + return; +} + + +/* +** TestAssignment() -- Test the assignment +*/ +static void TestAssignment( void ) +{ + PRInt64 zero = LL_Zero(); + PRInt64 min = LL_MinInt(); + PRInt64 max = LL_MaxInt(); + if (!LL_EQ(zero, bigZero)) + SetFailed("LL_EQ(zero, bigZero)", "!="); + if (!LL_CMP(max, >, min)) + SetFailed("LL_CMP(max, >, min)", "!>"); +} + +/* +** TestComparisons() -- Test the longlong comparison operations +*/ +static void +TestComparisons( void ) +{ + ReportProgress("Testing Comparisons Operations\n"); + + /* test for zero */ + if ( !LL_IS_ZERO( bigZero )) + SetFailed( "LL_IS_ZERO", "Zero is not zero" ); + + if ( LL_IS_ZERO( bigOne )) + SetFailed( "LL_IS_ZERO", "One tests as zero" ); + + if ( LL_IS_ZERO( bigMinusOne )) + SetFailed( "LL_IS_ZERO", "Minus One tests as zero" ); + + /* test equal */ + if ( !LL_EQ( bigZero, bigZero )) + SetFailed( "LL_EQ", "zero EQ zero"); + + if ( !LL_EQ( bigOne, bigOne )) + SetFailed( "LL_EQ", "one EQ one" ); + + if ( !LL_EQ( bigNumber, bigNumber )) + SetFailed( "LL_EQ", "bigNumber EQ bigNumber" ); + + if ( !LL_EQ( bigMinusOne, bigMinusOne )) + SetFailed( "LL_EQ", "minus one EQ minus one"); + + if ( LL_EQ( bigZero, bigOne )) + SetFailed( "LL_EQ", "zero EQ one"); + + if ( LL_EQ( bigOne, bigZero )) + SetFailed( "LL_EQ", "one EQ zero" ); + + if ( LL_EQ( bigMinusOne, bigOne )) + SetFailed( "LL_EQ", "minus one EQ one"); + + if ( LL_EQ( bigNumber, bigOne )) + SetFailed( "LL_EQ", "bigNumber EQ one"); + + /* test not equal */ + if ( LL_NE( bigZero, bigZero )) + SetFailed( "LL_NE", "0 NE 0"); + + if ( LL_NE( bigOne, bigOne )) + SetFailed( "LL_NE", "1 NE 1"); + + if ( LL_NE( bigMinusOne, bigMinusOne )) + SetFailed( "LL_NE", "-1 NE -1"); + + if ( LL_NE( bigNumber, bigNumber )) + SetFailed( "LL_NE", "n NE n"); + + if ( LL_NE( bigMinusNumber, bigMinusNumber )) + SetFailed( "LL_NE", "-n NE -n"); + + if ( !LL_NE( bigZero, bigOne)) + SetFailed( "LL_NE", "0 NE 1"); + + if ( !LL_NE( bigOne, bigMinusNumber)) + SetFailed( "LL_NE", "1 NE -n"); + + /* Greater than or equal to zero */ + if ( !LL_GE_ZERO( bigZero )) + SetFailed( "LL_GE_ZERO", "0"); + + if ( !LL_GE_ZERO( bigOne )) + SetFailed( "LL_GE_ZERO", "1"); + + if ( !LL_GE_ZERO( bigNumber )) + SetFailed( "LL_GE_ZERO", "n"); + + if ( LL_GE_ZERO( bigMinusOne )) + SetFailed( "LL_GE_ZERO", "-1"); + + if ( LL_GE_ZERO( bigMinusNumber )) + SetFailed( "LL_GE_ZERO", "-n"); + + /* Algebraic Compare two values */ + if ( !LL_CMP( bigZero, ==, bigZero )) + SetFailed( "LL_CMP", "0 == 0"); + + if ( LL_CMP( bigZero, >, bigZero )) + SetFailed( "LL_CMP", "0 > 0"); + + if ( LL_CMP( bigZero, <, bigZero )) + SetFailed( "LL_CMP", "0 < 0"); + + if ( LL_CMP( bigNumber, <, bigOne )) + SetFailed( "LL_CMP", "n < 1"); + + if ( !LL_CMP( bigNumber, >, bigOne )) + SetFailed( "LL_CMP", "n <= 1"); + + if ( LL_CMP( bigOne, >, bigNumber )) + SetFailed( "LL_CMP", "1 > n"); + + if ( LL_CMP( bigMinusNumber, >, bigNumber )) + SetFailed( "LL_CMP", "-n > n"); + + if ( LL_CMP( bigNumber, !=, bigNumber)) + SetFailed( "LL_CMP", "n != n"); + + if ( !LL_CMP( bigMinusOne, >, bigMinusTwo )) + SetFailed( "LL_CMP", "-1 <= -2"); + + if ( !LL_CMP( bigMaxInt32, <, big2To31 )) + SetFailed( "LL_CMP", "Max 32-bit signed int >= 2^31"); + + /* Two positive numbers */ + if ( !LL_CMP( bigInt0, <=, bigInt0 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( !LL_CMP( bigInt0, <=, bigInt1 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( LL_CMP( bigInt0, <=, bigInt2 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( !LL_CMP( bigInt0, <=, bigInt3 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( !LL_CMP( bigInt0, <=, bigInt4 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( !LL_CMP( bigInt0, <=, bigInt5 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + /* Two negative numbers */ + if ( !LL_CMP( bigInt6, <=, bigInt6 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( !LL_CMP( bigInt6, <=, bigInt7 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( LL_CMP( bigInt6, <=, bigInt8 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( !LL_CMP( bigInt6, <=, bigInt9 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( !LL_CMP( bigInt6, <=, bigInt10 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( !LL_CMP( bigInt6, <=, bigInt11 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + /* One positive, one negative */ + if ( LL_CMP( bigInt0, <=, bigInt6 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( LL_CMP( bigInt0, <=, bigInt7 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + if ( LL_CMP( bigInt0, <=, bigInt8 )) + SetFailed( "LL_CMP", "LL_CMP(<=) failed"); + + /* Bitwise Compare two numbers */ + if ( !LL_UCMP( bigZero, ==, bigZero )) + SetFailed( "LL_UCMP", "0 == 0"); + + if ( LL_UCMP( bigZero, >, bigZero )) + SetFailed( "LL_UCMP", "0 > 0"); + + if ( LL_UCMP( bigZero, <, bigZero )) + SetFailed( "LL_UCMP", "0 < 0"); + + if ( LL_UCMP( bigNumber, <, bigOne )) + SetFailed( "LL_UCMP", "n < 1"); + + if ( !LL_UCMP( bigNumber, >, bigOne )) + SetFailed( "LL_UCMP", "n < 1"); + + if ( LL_UCMP( bigOne, >, bigNumber )) + SetFailed( "LL_UCMP", "1 > n"); + + if ( LL_UCMP( bigMinusNumber, <, bigNumber )) + SetFailed( "LL_UCMP", "-n < n"); + + /* Two positive numbers */ + if ( !LL_UCMP( bigInt0, <=, bigInt0 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt0, <=, bigInt1 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( LL_UCMP( bigInt0, <=, bigInt2 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt0, <=, bigInt3 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt0, <=, bigInt4 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt0, <=, bigInt5 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + /* Two negative numbers */ + if ( !LL_UCMP( bigInt6, <=, bigInt6 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt6, <=, bigInt7 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( LL_UCMP( bigInt6, <=, bigInt8 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt6, <=, bigInt9 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt6, <=, bigInt10 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt6, <=, bigInt11 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + /* One positive, one negative */ + if ( !LL_UCMP( bigInt0, <=, bigInt6 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt0, <=, bigInt7 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + if ( !LL_UCMP( bigInt0, <=, bigInt8 )) + SetFailed( "LL_UCMP", "LL_UCMP(<=) failed"); + + return; +} + +/* +** TestLogicalOperations() -- Tests for AND, OR, ... +** +*/ +static void +TestLogicalOperations( void ) +{ + PRUint64 result, result2; + + ReportProgress("Testing Logical Operations\n"); + + /* Test AND */ + LL_AND( result, bigZero, bigZero ); + if ( !LL_IS_ZERO( result )) + ResultFailed( "LL_AND", "0 & 0", bigZero, result ); + + LL_AND( result, bigOne, bigOne ); + if ( LL_IS_ZERO( result )) + ResultFailed( "LL_AND", "1 & 1", bigOne, result ); + + LL_AND( result, bigZero, bigOne ); + if ( !LL_IS_ZERO( result )) + ResultFailed( "LL_AND", "1 & 1", bigZero, result ); + + LL_AND( result, bigMinusOne, bigMinusOne ); + if ( !LL_UCMP( result, ==, bigMinusOne )) + ResultFailed( "LL_AND", "-1 & -1", bigMinusOne, result ); + + /* test OR */ + LL_OR( result, bigZero, bigZero ); + if ( !LL_IS_ZERO( result )) + ResultFailed( "LL_OR", "0 | 1", bigZero, result); + + LL_OR( result, bigZero, bigOne ); + if ( LL_IS_ZERO( result )) + ResultFailed( "LL_OR", "0 | 1", bigOne, result ); + + LL_OR( result, bigZero, bigMinusNumber ); + if ( !LL_UCMP( result, ==, bigMinusNumber )) + ResultFailed( "LL_OR", "0 | -n", bigMinusNumber, result); + + LL_OR( result, bigMinusNumber, bigZero ); + if ( !LL_UCMP( result, ==, bigMinusNumber )) + ResultFailed( "LL_OR", "-n | 0", bigMinusNumber, result ); + + /* test XOR */ + LL_XOR( result, bigZero, bigZero ); + if ( LL_UCMP( result, !=, bigZero )) + ResultFailed( "LL_XOR", "0 ^ 0", bigZero, result); + + LL_XOR( result, bigOne, bigZero ); + if ( LL_UCMP( result, !=, bigOne )) + ResultFailed( "LL_XOR", "1 ^ 0", bigZero, result ); + + LL_XOR( result, bigMinusNumber, bigZero ); + if ( LL_UCMP( result, !=, bigMinusNumber )) + ResultFailed( "LL_XOR", "-n ^ 0", bigMinusNumber, result ); + + LL_XOR( result, bigMinusNumber, bigMinusNumber ); + if ( LL_UCMP( result, !=, bigZero )) + ResultFailed( "LL_XOR", "-n ^ -n", bigMinusNumber, result); + + /* test OR2. */ + result = bigZero; + LL_OR2( result, bigOne ); + if ( LL_UCMP( result, !=, bigOne )) + ResultFailed( "LL_OR2", "(r=0) |= 1", bigOne, result); + + result = bigOne; + LL_OR2( result, bigNumber ); + if ( LL_UCMP( result, !=, bigNumber )) + ResultFailed( "LL_OR2", "(r=1) |= n", bigNumber, result); + + result = bigMinusNumber; + LL_OR2( result, bigMinusNumber ); + if ( LL_UCMP( result, !=, bigMinusNumber )) + ResultFailed( "LL_OR2", "(r=-n) |= -n", bigMinusNumber, result); + + /* test NOT */ + LL_NOT( result, bigMinusNumber); + LL_NOT( result2, result); + if ( LL_UCMP( result2, !=, bigMinusNumber )) + ResultFailed( "LL_NOT", "r != ~(~-n)", bigMinusNumber, result); + + /* test Negation */ + LL_NEG( result, bigMinusNumber ); + LL_NEG( result2, result ); + if ( LL_CMP( result2, !=, bigMinusNumber )) + ResultFailed( "LL_NEG", "r != -(-(-n))", bigMinusNumber, result); + + return; +} + + + +/* +** TestConversion() -- Test Conversion Operations +** +*/ +static void +TestConversion( void ) +{ + PRInt64 result; + PRInt64 resultU; + PRInt32 result32; + PRUint32 resultU32; + float resultF; + PRFloat64 resultD; + + ReportProgress("Testing Conversion Operations\n"); + + /* LL_L2I -- Convert to signed 32bit */ + LL_L2I(result32, bigOne ); + if ( result32 != one ) + SetFailed( "LL_L2I", "r != 1"); + + LL_L2I(result32, bigMinusOne ); + if ( result32 != minusOne ) + SetFailed( "LL_L2I", "r != -1"); + + /* LL_L2UI -- Convert 64bit to unsigned 32bit */ + LL_L2UI( resultU32, bigMinusOne ); + if ( resultU32 != (PRUint32) minusOne ) + SetFailed( "LL_L2UI", "r != -1"); + + LL_L2UI( resultU32, bigOne ); + if ( resultU32 != (PRUint32) one ) + SetFailed( "LL_L2UI", "r != 1"); + + /* LL_L2F -- Convert to 32bit floating point */ + LL_L2F( resultF, bigOne ); + if ( resultF != 1.0 ) + SetFailed( "LL_L2F", "r != 1.0"); + + LL_L2F( resultF, bigMinusOne ); + if ( resultF != -1.0 ) + SetFailed( "LL_L2F", "r != 1.0"); + + /* LL_L2D -- Convert to 64bit floating point */ + LL_L2D( resultD, bigOne ); + if ( resultD != 1.0L ) + SetFailed( "LL_L2D", "r != 1.0"); + + LL_L2D( resultD, bigMinusOne ); + if ( resultD != -1.0L ) + SetFailed( "LL_L2D", "r != -1.0"); + + /* LL_I2L -- Convert 32bit signed to 64bit signed */ + LL_I2L( result, one ); + if ( LL_CMP(result, !=, bigOne )) + SetFailed( "LL_I2L", "r != 1"); + + LL_I2L( result, minusOne ); + if ( LL_CMP(result, !=, bigMinusOne )) + SetFailed( "LL_I2L", "r != -1"); + + /* LL_UI2L -- Convert 32bit unsigned to 64bit unsigned */ + LL_UI2L( resultU, (PRUint32) one ); + if ( LL_CMP(resultU, !=, bigOne )) + SetFailed( "LL_UI2L", "r != 1"); + + /* [lth.] This did not behave as expected, but it is correct + */ + LL_UI2L( resultU, (PRUint32) minusOne ); + if ( LL_CMP(resultU, !=, bigZeroFox )) + ResultFailed( "LL_UI2L", "r != -1", bigZeroFox, resultU); + + /* LL_F2L -- Convert 32bit float to 64bit signed */ + LL_F2L( result, 1.0 ); + if ( LL_CMP(result, !=, bigOne )) + SetFailed( "LL_F2L", "r != 1"); + + LL_F2L( result, -1.0 ); + if ( LL_CMP(result, !=, bigMinusOne )) + SetFailed( "LL_F2L", "r != -1"); + + /* LL_D2L -- Convert 64bit Float to 64bit signed */ + LL_D2L( result, 1.0L ); + if ( LL_CMP(result, !=, bigOne )) + SetFailed( "LL_D2L", "r != 1"); + + LL_D2L( result, -1.0L ); + if ( LL_CMP(result, !=, bigMinusOne )) + SetFailed( "LL_D2L", "r != -1"); + + return; +} + +static void ShiftCompileOnly() +{ + /* + ** This function is only compiled, never called. + ** The real test is to see if it compiles w/o + ** warnings. This is no small feat, by the way. + */ + PRInt64 ia, ib; + PRUint64 ua, ub; + LL_SHR(ia, ib, 32); + LL_SHL(ia, ib, 32); + + LL_USHR(ua, ub, 32); + LL_ISHL(ia, 49, 32); + +} /* ShiftCompileOnly */ + + +/* +** TestShift() -- Test Shifting Operations +** +*/ +static void +TestShift( void ) +{ + static const PRInt64 largeTwoZero = LL_INIT( 0x00000002, 0x00000000 ); + PRInt64 result; + PRUint64 resultU; + + ReportProgress("Testing Shifting Operations\n"); + + /* LL_SHL -- Shift left algebraic */ + LL_SHL( result, bigOne, one ); + if ( LL_CMP( result, !=, bigTwo )) + ResultFailed( "LL_SHL", "r != 2", bigOne, result ); + + LL_SHL( result, bigTwo, thirtyTwo ); + if ( LL_CMP( result, !=, largeTwoZero )) + ResultFailed( "LL_SHL", "r != twoZero", largeTwoZero, result); + + /* LL_SHR -- Shift right algebraic */ + LL_SHR( result, bigFoxZero, thirtyTwo ); + if ( LL_CMP( result, !=, bigMinusOne )) + ResultFailed( "LL_SHR", "r != -1", bigMinusOne, result); + + LL_SHR( result, bigTwo, one ); + if ( LL_CMP( result, !=, bigOne )) + ResultFailed( "LL_SHR", "r != 1", bigOne, result); + + LL_SHR( result, bigFoxFox, thirtyTwo ); + if ( LL_CMP( result, !=, bigMinusOne )) + ResultFailed( "LL_SHR", "r != -1 (was ff,ff)", bigMinusOne, result); + + /* LL_USHR -- Logical shift right */ + LL_USHR( resultU, bigZeroFox, thirtyTwo ); + if ( LL_UCMP( resultU, !=, bigZero )) + ResultFailed( "LL_USHR", "r != 0 ", bigZero, result); + + LL_USHR( resultU, bigFoxFox, thirtyTwo ); + if ( LL_UCMP( resultU, !=, bigZeroFox )) + ResultFailed( "LL_USHR", "r != 0 ", bigZeroFox, result); + + /* LL_ISHL -- Shift a 32bit integer into a 64bit result */ + LL_ISHL( resultU, minusOne, thirtyTwo ); + if ( LL_UCMP( resultU, !=, bigFoxZero )) + ResultFailed( "LL_ISHL", "r != ff,00 ", bigFoxZero, result); + + LL_ISHL( resultU, one, sixtyThree ); + if ( LL_UCMP( resultU, !=, bigEightZero )) + ResultFailed( "LL_ISHL", "r != 80,00 ", bigEightZero, result); + + LL_ISHL( resultU, one, sixteen ); + if ( LL_UCMP( resultU, !=, big64K )) + ResultFailed( "LL_ISHL", "r != 64K ", big64K, resultU); + + return; +} + + +/* +** TestArithmetic() -- Test arithmetic operations. +** +*/ +static void +TestArithmetic( void ) +{ + PRInt64 largeVal = LL_INIT( 0x00000001, 0xffffffff ); + PRInt64 largeValPlusOne = LL_INIT( 0x00000002, 0x00000000 ); + PRInt64 largeValTimesTwo = LL_INIT( 0x00000003, 0xfffffffe ); + PRInt64 largeMultCand = LL_INIT( 0x00000000, 0x7fffffff ); + PRInt64 largeMinusMultCand = LL_INIT( 0xffffffff, 0x10000001 ); + PRInt64 largeMultCandx64K = LL_INIT( 0x00007fff, 0xffff0000 ); + PRInt64 largeNumSHL5 = LL_INIT( 0x0000001f, 0xffffffe0 ); + PRInt64 result, result2; + + /* Addition */ + LL_ADD( result, bigOne, bigOne ); + if ( LL_CMP( result, !=, bigTwo )) + ResultFailed( "LL_ADD", "r != 1 + 1", bigTwo, result); + + LL_ADD( result, bigMinusOne, bigOne ); + if ( LL_CMP( result, !=, bigZero )) + ResultFailed( "LL_ADD", "r != -1 + 1", bigOne, result); + + LL_ADD( result, largeVal, bigOne ); + if ( LL_CMP( result, !=, largeValPlusOne )) + ResultFailed( "LL_ADD", "lVP1 != lV + 1", largeValPlusOne, result); + + /* Subtraction */ + LL_SUB( result, bigOne, bigOne ); + if ( LL_CMP( result, !=, bigZero )) + ResultFailed( "LL_SUB", "r != 1 - 1", bigZero, result); + + LL_SUB( result, bigTwo, bigOne ); + if ( LL_CMP( result, !=, bigOne )) + ResultFailed( "LL_SUB", "r != 2 - 1", bigOne, result); + + LL_SUB( result, largeValPlusOne, bigOne ); + if ( LL_CMP( result, !=, largeVal )) + ResultFailed( "LL_SUB", "r != lVP1 - 1", largeVal, result); + + + /* Multiply */ + LL_MUL( result, largeVal, bigTwo ); + if ( LL_CMP( result, !=, largeValTimesTwo )) + ResultFailed( "LL_MUL", "r != lV*2", largeValTimesTwo, result); + + LL_MUL( result, largeMultCand, big64K ); + if ( LL_CMP( result, !=, largeMultCandx64K )) + ResultFailed( "LL_MUL", "r != lV*64K", largeMultCandx64K, result); + + LL_NEG( result2, largeMultCand ); + LL_MUL( result, largeMultCand, bigMinusOne ); + if ( LL_CMP( result, !=, result2 )) + ResultFailed( "LL_MUL", "r != -lMC", result2, result); + + LL_SHL( result2, bigZeroFox, 5); + LL_MUL( result, bigZeroFox, bigThirtyTwo ); + if ( LL_CMP( result, !=, largeNumSHL5 )) + ResultFailed( "LL_MUL", "r != 0f<<5", largeNumSHL5, result ); + + + + /* LL_DIV() Division */ + LL_DIV( result, bigOne, bigOne); + if ( LL_CMP( result, !=, bigOne )) + ResultFailed( "LL_DIV", "1 != 1", bigOne, result); + + LL_DIV( result, bigNumber, bigOne ); + if ( LL_CMP( result, !=, bigNumber )) + ResultFailed( "LL_DIV", "r != n / 1", bigNumber, result); + + LL_DIV( result, bigNumber, bigMinusOne ); + if ( LL_CMP( result, !=, bigMinusNumber )) + ResultFailed( "LL_DIV", "r != n / -1", bigMinusNumber, result); + + LL_DIV( result, bigMinusNumber, bigMinusOne ); + if ( LL_CMP( result, !=, bigNumber )) + ResultFailed( "LL_DIV", "r != -n / -1", bigNumber, result); + + LL_SHL( result2, bigZeroFox, 5 ); + LL_DIV( result, result2, bigOne ); + if ( LL_CMP( result, !=, result2 )) + ResultFailed( "LL_DIV", "0f<<5 != 0f<<5", result2, result); + + LL_SHL( result2, bigZeroFox, 5 ); + LL_NEG( result2, result2 ); + LL_DIV( result, result2, bigOne ); + if ( LL_CMP( result, !=, result2 )) + ResultFailed( "LL_DIV", "-0f<<5 != -0f<<5", result2, result); + + LL_SHL( result2, bigZeroFox, 17 ); + LL_DIV( result, result2, bigMinusOne ); + LL_NEG( result2, result2 ); + if ( LL_CMP( result, !=, result2 )) + ResultFailed( "LL_DIV", "-0f<<17 != -0f<<17", result2, result); + + + /* LL_MOD() Modulo Division */ + LL_ADD( result2, bigThirtyTwo, bigOne ); + LL_MOD( result, result2, bigSixTeen ); + if ( LL_CMP( result, !=, bigOne )) + ResultFailed( "LL_MOD", "r != 1", bigSixTeen, result); + + + LL_MUL( result2, bigZeroFox, bigThirtyTwo ); + LL_ADD( result2, result2, bigSixTeen); + LL_MOD( result, result2, bigThirtyTwo ); + if ( LL_CMP( result, !=, bigSixTeen )) + ResultFailed( "LL_MOD", "r != 16", bigSixTeen, result); + + /* LL_UDIVMOD */ + LL_DIV( result, bigOne, bigOne); + if ( LL_CMP( result, !=, bigOne )) + ResultFailed( "LL_DIV", "r != 16", bigSixTeen, result); + + + return; +} + +static void TestWellknowns(void) +{ + PRInt64 max = LL_MAXINT, min = LL_MININT, zero = LL_ZERO; + PRInt64 mmax = LL_MaxInt(), mmin = LL_MinInt(), mzero = LL_Zero(); + if (LL_NE(max, mmax)) + ResultFailed( "max, mmax", "max != mmax", max, mmax); + if (LL_NE(min, mmin)) + ResultFailed( "min, mmin", "min != mmin", max, mmin); + if (LL_NE(zero, mzero)) + ResultFailed( "zero, mzero", "zero != mzero", zero, mzero); +} /* TestWellknowns */ + +/* +** Initialize() -- Initialize the test case +** +** Parse command line options +** +*/ +static PRIntn +Initialize( PRIntn argc, char **argv ) +{ + PLOptState *opt = PL_CreateOptState(argc, argv, "dvh"); + PLOptStatus os; + + /* + ** Parse command line options + */ + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* set debug mode */ + debugMode = PR_TRUE; + break; + + case 'v': /* set verbose mode */ + verboseMode = PR_TRUE; + debugMode = PR_TRUE; + break; + + case 'h': /* user wants some guidance */ + default: + PR_fprintf(output, "You get help.\n"); + return(1); + } + } + PL_DestroyOptState(opt); + return(0); +} + +int main(int argc, char **argv) +{ + PR_STDIO_INIT(); + output = PR_GetSpecialFD(PR_StandardError); + + if ( Initialize( argc, argv )) + return(1); + + TestAssignment(); + TestComparisons(); + TestLogicalOperations(); + TestConversion(); + TestShift(); + TestArithmetic(); + TestWellknowns(); + + /* + ** That's all folks! + */ + if ( failedAlready ) + { + PR_fprintf(output, "FAIL\n");\ + } + else + { + PR_fprintf(output, "PASS\n");\ + } + return failedAlready; +} /* end main() */ diff -Nru nspr-4.9.5/nspr/pr/tests/lock.c nspr-4.10.7/nspr/pr/tests/lock.c --- nspr-4.9.5/nspr/pr/tests/lock.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/lock.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,519 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: lock.c +** Purpose: test basic locking functions +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +** +** 11-Aug-97 LarryH. Win16 port of NSPR. +** - Added "PASS", "FAIL" messages on completion. +** - Change stack variables to static scope variables +** because of shadow-stack use by Win16 +** - Added PR_CALLBACK attribute to functions called by NSPR +** - Added command line arguments: +** - l to control the number of loops +** - c to control the number of CPUs. +** (was positional argv). +** +** +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prio.h" +#include "prcmon.h" +#include "prinit.h" +#include "prinrval.h" +#include "prprf.h" +#include "prlock.h" +#include "prlog.h" +#include "prmon.h" +#include "prmem.h" +#include "prthread.h" +#include "prtypes.h" + +#include "plstr.h" + +#include + +#if defined(XP_UNIX) +#include +#endif + +static PRIntn failed_already=0; +static PRFileDesc *std_err = NULL; +static PRBool verbosity = PR_FALSE; +static PRBool debug_mode = PR_FALSE; + +const static PRIntervalTime contention_interval = 50; + +typedef struct LockContentious_s { + PRLock *ml; + PRInt32 loops; + PRUint32 contender; + PRUint32 contentious; + PRIntervalTime overhead; + PRIntervalTime interval; +} LockContentious_t; + +typedef struct MonitorContentious_s { + PRMonitor *ml; + PRInt32 loops; + PRUint32 contender; + PRUint32 contentious; + PRIntervalTime overhead; + PRIntervalTime interval; +} MonitorContentious_t; + + +static PRIntervalTime Sleeper(PRUint32 loops) +{ + PRIntervalTime predicted = 0; + while (loops-- > 0) + { + predicted += contention_interval; + (void)PR_Sleep(contention_interval); + } + return predicted; +} /* Sleeper */ + +/* +** BASIC LOCKS +*/ +static PRIntervalTime MakeLock(PRUint32 loops) +{ + PRLock *ml = NULL; + while (loops-- > 0) + { + ml = PR_NewLock(); + PR_DestroyLock(ml); + ml = NULL; + } + return 0; +} /* MakeLock */ + +static PRIntervalTime NonContentiousLock(PRUint32 loops) +{ + PRLock *ml = NULL; + ml = PR_NewLock(); + while (loops-- > 0) + { + PR_Lock(ml); + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(ml); + PR_Unlock(ml); + } + PR_DestroyLock(ml); + return 0; +} /* NonContentiousLock */ + +static void PR_CALLBACK LockContender(void *arg) +{ + LockContentious_t *contention = (LockContentious_t*)arg; + while (contention->loops-- > 0) + { + PR_Lock(contention->ml); + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml); + contention->contender+= 1; + contention->overhead += contention->interval; + PR_Sleep(contention->interval); + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml); + PR_Unlock(contention->ml); + } +} /* LockContender */ + +static PRIntervalTime ContentiousLock(PRUint32 loops) +{ + PRStatus status; + PRThread *thread = NULL; + LockContentious_t * contention; + PRIntervalTime rv, overhead, timein = PR_IntervalNow(); + + contention = PR_NEWZAP(LockContentious_t); + contention->loops = loops; + contention->overhead = 0; + contention->ml = PR_NewLock(); + contention->interval = contention_interval; + thread = PR_CreateThread( + PR_USER_THREAD, LockContender, contention, + PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + PR_ASSERT(thread != NULL); + + overhead = PR_IntervalNow() - timein; + + while (contention->loops-- > 0) + { + PR_Lock(contention->ml); + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml); + contention->contentious+= 1; + contention->overhead += contention->interval; + PR_Sleep(contention->interval); + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(contention->ml); + PR_Unlock(contention->ml); + } + + timein = PR_IntervalNow(); + status = PR_JoinThread(thread); + PR_DestroyLock(contention->ml); + overhead += (PR_IntervalNow() - timein); + rv = overhead + contention->overhead; + if (verbosity) + PR_fprintf( + std_err, "Access ratio: %u to %u\n", + contention->contentious, contention->contender); + PR_Free(contention); + return rv; +} /* ContentiousLock */ + +/* +** MONITORS +*/ +static PRIntervalTime MakeMonitor(PRUint32 loops) +{ + PRMonitor *ml = NULL; + while (loops-- > 0) + { + ml = PR_NewMonitor(); + PR_DestroyMonitor(ml); + ml = NULL; + } + return 0; +} /* MakeMonitor */ + +static PRIntervalTime NonContentiousMonitor(PRUint32 loops) +{ + PRMonitor *ml = NULL; + ml = PR_NewMonitor(); + while (loops-- > 0) + { + PR_EnterMonitor(ml); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); + PR_ExitMonitor(ml); + } + PR_DestroyMonitor(ml); + return 0; +} /* NonContentiousMonitor */ + +static void PR_CALLBACK TryEntry(void *arg) +{ + PRMonitor *ml = (PRMonitor*)arg; + if (debug_mode) PR_fprintf(std_err, "Reentrant thread created\n"); + PR_EnterMonitor(ml); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); + if (debug_mode) PR_fprintf(std_err, "Reentrant thread acquired monitor\n"); + PR_ExitMonitor(ml); + if (debug_mode) PR_fprintf(std_err, "Reentrant thread released monitor\n"); +} /* TryEntry */ + +static PRIntervalTime ReentrantMonitor(PRUint32 loops) +{ + PRStatus status; + PRThread *thread; + PRMonitor *ml = PR_NewMonitor(); + if (debug_mode) PR_fprintf(std_err, "\nMonitor created for reentrant test\n"); + + PR_EnterMonitor(ml); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); + PR_EnterMonitor(ml); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); + if (debug_mode) PR_fprintf(std_err, "Monitor acquired twice\n"); + + thread = PR_CreateThread( + PR_USER_THREAD, TryEntry, ml, + PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + PR_ASSERT(thread != NULL); + PR_Sleep(PR_SecondsToInterval(1)); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); + + PR_ExitMonitor(ml); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ml); + if (debug_mode) PR_fprintf(std_err, "Monitor released first time\n"); + + PR_ExitMonitor(ml); + if (debug_mode) PR_fprintf(std_err, "Monitor released second time\n"); + + status = PR_JoinThread(thread); + if (debug_mode) PR_fprintf(std_err, + "Reentrant thread joined %s\n", + (status == PR_SUCCESS) ? "successfully" : "in error"); + + PR_DestroyMonitor(ml); + return 0; +} /* ReentrantMonitor */ + +static void PR_CALLBACK MonitorContender(void *arg) +{ + MonitorContentious_t *contention = (MonitorContentious_t*)arg; + while (contention->loops-- > 0) + { + PR_EnterMonitor(contention->ml); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); + contention->contender+= 1; + contention->overhead += contention->interval; + PR_Sleep(contention->interval); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); + PR_ExitMonitor(contention->ml); + } +} /* MonitorContender */ + +static PRUint32 ContentiousMonitor(PRUint32 loops) +{ + PRStatus status; + PRThread *thread = NULL; + MonitorContentious_t * contention; + PRIntervalTime rv, overhead, timein = PR_IntervalNow(); + + contention = PR_NEWZAP(MonitorContentious_t); + contention->loops = loops; + contention->overhead = 0; + contention->ml = PR_NewMonitor(); + contention->interval = contention_interval; + thread = PR_CreateThread( + PR_USER_THREAD, MonitorContender, contention, + PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + PR_ASSERT(thread != NULL); + + overhead = PR_IntervalNow() - timein; + + while (contention->loops-- > 0) + { + PR_EnterMonitor(contention->ml); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); + contention->contentious+= 1; + contention->overhead += contention->interval; + PR_Sleep(contention->interval); + PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); + PR_ExitMonitor(contention->ml); + } + + timein = PR_IntervalNow(); + status = PR_JoinThread(thread); + PR_DestroyMonitor(contention->ml); + overhead += (PR_IntervalNow() - timein); + rv = overhead + contention->overhead; + if (verbosity) + PR_fprintf( + std_err, "Access ratio: %u to %u\n", + contention->contentious, contention->contender); + PR_Free(contention); + return rv; +} /* ContentiousMonitor */ + +/* +** CACHED MONITORS +*/ +static PRIntervalTime NonContentiousCMonitor(PRUint32 loops) +{ + MonitorContentious_t contention; + while (loops-- > 0) + { + PR_CEnterMonitor(&contention); + PR_CExitMonitor(&contention); + } + return 0; +} /* NonContentiousCMonitor */ + +static void PR_CALLBACK Contender(void *arg) +{ + MonitorContentious_t *contention = (MonitorContentious_t*)arg; + while (contention->loops-- > 0) + { + PR_CEnterMonitor(contention); + contention->contender+= 1; + contention->overhead += contention->interval; + PR_Sleep(contention->interval); + PR_CExitMonitor(contention); + } +} /* Contender */ + +static PRIntervalTime ContentiousCMonitor(PRUint32 loops) +{ + PRStatus status; + PRThread *thread = NULL; + MonitorContentious_t * contention; + PRIntervalTime overhead, timein = PR_IntervalNow(); + + contention = PR_NEWZAP(MonitorContentious_t); + contention->ml = NULL; + contention->loops = loops; + contention->interval = contention_interval; + thread = PR_CreateThread( + PR_USER_THREAD, Contender, contention, + PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + PR_ASSERT(thread != NULL); + + overhead = PR_IntervalNow() - timein; + + while (contention->loops-- > 0) + { + PR_CEnterMonitor(contention); + contention->contentious+= 1; + contention->overhead += contention->interval; + PR_Sleep(contention->interval); + PR_CExitMonitor(contention); + } + + timein = PR_IntervalNow(); + status = PR_JoinThread(thread); + overhead += (PR_IntervalNow() - timein); + overhead += overhead + contention->overhead; + if (verbosity) + PR_fprintf( + std_err, "Access ratio: %u to %u\n", + contention->contentious, contention->contender); + PR_Free(contention); + return overhead; +} /* ContentiousCMonitor */ + +static PRIntervalTime Test( + const char* msg, PRUint32 (*test)(PRUint32 loops), + PRUint32 loops, PRIntervalTime overhead) +{ + /* + * overhead - overhead not measured by the test. + * duration - wall clock time it took to perform test. + * predicted - extra time test says should not be counted + * + * Time accountable to the test is duration - overhead - predicted + * All times are Intervals and accumulated for all iterations. + */ + PRFloat64 elapsed; + PRIntervalTime accountable, duration; + PRUintn spaces = PL_strlen(msg); + PRIntervalTime timeout, timein = PR_IntervalNow(); + PRIntervalTime predicted = test(loops); + timeout = PR_IntervalNow(); + duration = timeout - timein; + + if (debug_mode) + { + accountable = duration - predicted; + accountable -= overhead; + elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable); + PR_fprintf(PR_STDOUT, "%s:", msg); + while (spaces++ < 50) PR_fprintf(PR_STDOUT, " "); + if ((PRInt32)accountable < 0) + PR_fprintf(PR_STDOUT, "*****.** usecs/iteration\n"); + else + PR_fprintf(PR_STDOUT, "%8.2f usecs/iteration\n", elapsed/loops); + } + return duration; +} /* Test */ + +int main(int argc, char **argv) +{ + PRBool rv = PR_TRUE; + PRIntervalTime duration; + PRUint32 cpu, cpus = 2, loops = 100; + + + PR_STDIO_INIT(); + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + { + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Command line argument -l sets the number of loops. + Command line argument -c sets the number of cpus. + Usage: lock [-d] [-l ] [-c ] + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dvl:c:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'v': /* debug mode */ + verbosity = PR_TRUE; + break; + case 'l': /* number of loops */ + loops = atoi(opt->value); + break; + case 'c': /* number of cpus */ + cpus = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } + + /* main test */ + PR_SetConcurrency(8); + + if (loops == 0) loops = 100; + if (debug_mode) + { + std_err = PR_STDERR; + PR_fprintf(std_err, "Lock: Using %d loops\n", loops); + } + + if (cpus == 0) cpus = 2; + if (debug_mode) PR_fprintf(std_err, "Lock: Using %d cpu(s)\n", cpus); + + (void)Sleeper(10); /* try filling in the caches */ + + for (cpu = 1; cpu <= cpus; ++cpu) + { + if (debug_mode) PR_fprintf(std_err, "\nLock: Using %d CPU(s)\n", cpu); + PR_SetConcurrency(cpu); + + duration = Test("Overhead of PR_Sleep", Sleeper, loops, 0); + duration = 0; + + (void)Test("Lock creation/deletion", MakeLock, loops, 0); + (void)Test("Lock non-contentious locking/unlocking", NonContentiousLock, loops, 0); + (void)Test("Lock contentious locking/unlocking", ContentiousLock, loops, duration); + (void)Test("Monitor creation/deletion", MakeMonitor, loops, 0); + (void)Test("Monitor non-contentious locking/unlocking", NonContentiousMonitor, loops, 0); + (void)Test("Monitor contentious locking/unlocking", ContentiousMonitor, loops, duration); + + (void)Test("Cached monitor non-contentious locking/unlocking", NonContentiousCMonitor, loops, 0); + (void)Test("Cached monitor contentious locking/unlocking", ContentiousCMonitor, loops, duration); + + (void)ReentrantMonitor(loops); + } + + if (debug_mode) + PR_fprintf( + std_err, "%s: test %s\n", "Lock(mutex) test", + ((rv) ? "passed" : "failed")); + else { + if (!rv) + failed_already=1; + } + + if(failed_already) + { + PR_fprintf(PR_STDOUT, "FAIL\n"); + return 1; + } + else + { + PR_fprintf(PR_STDOUT, "PASS\n"); + return 0; + } + +} /* main */ + +/* testlock.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/lockfile.c nspr-4.10.7/nspr/pr/tests/lockfile.c --- nspr-4.9.5/nspr/pr/tests/lockfile.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/lockfile.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,229 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: lockfile.c +** Purpose: test basic locking functions +** Just because this times stuff, don't think its a perforamnce +** test!!! +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prcmon.h" +#include "prerror.h" +#include "prinit.h" +#include "prinrval.h" +#include "prlock.h" +#include "prlog.h" +#include "prmon.h" +#include "prthread.h" +#include "prtypes.h" + +#include "private/pprio.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + +const static PRIntervalTime contention_interval = 50; + +typedef struct LockContentious_s { + PRLock *ml; + PRInt32 loops; + PRIntervalTime overhead; + PRIntervalTime interval; +} LockContentious_t; + +#define LOCKFILE "prlock.fil" + + + +static PRIntervalTime NonContentiousLock(PRInt32 loops) +{ + PRFileDesc *_lockfile; + while (loops-- > 0) + { + _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666); + if (!_lockfile) { + if (debug_mode) printf( + "could not create lockfile: %d [%d]\n", + PR_GetError(), PR_GetOSError()); + return PR_INTERVAL_NO_TIMEOUT; + } + PR_LockFile(_lockfile); + PR_UnlockFile(_lockfile); + PR_Close(_lockfile); + } + return 0; +} /* NonContentiousLock */ + +static void PR_CALLBACK LockContender(void *arg) +{ + LockContentious_t *contention = (LockContentious_t*)arg; + PRFileDesc *_lockfile; + while (contention->loops-- > 0) + { + _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666); + if (!_lockfile) { + if (debug_mode) printf( + "could not create lockfile: %d [%d]\n", + PR_GetError(), PR_GetOSError()); + break; + } + PR_LockFile(_lockfile); + PR_Sleep(contention->interval); + PR_UnlockFile(_lockfile); + PR_Close(_lockfile); + } + +} /* LockContender */ + +/* +** Win16 requires things passed to Threads not be on the stack +*/ +static LockContentious_t contention; + +static PRIntervalTime ContentiousLock(PRInt32 loops) +{ + PRStatus status; + PRThread *thread = NULL; + PRIntervalTime overhead, timein = PR_IntervalNow(); + + contention.loops = loops; + contention.overhead = 0; + contention.ml = PR_NewLock(); + contention.interval = contention_interval; + thread = PR_CreateThread( + PR_USER_THREAD, LockContender, &contention, + PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + PR_ASSERT(thread != NULL); + + overhead = PR_IntervalNow() - timein; + + while (contention.loops > 0) + { + PR_Lock(contention.ml); + contention.overhead += contention.interval; + PR_Sleep(contention.interval); + PR_Unlock(contention.ml); + } + + timein = PR_IntervalNow(); + status = PR_JoinThread(thread); + PR_DestroyLock(contention.ml); + overhead += (PR_IntervalNow() - timein); + return overhead + contention.overhead; +} /* ContentiousLock */ + +static PRIntervalTime Test( + const char* msg, PRIntervalTime (*test)(PRInt32 loops), + PRInt32 loops, PRIntervalTime overhead) +{ + /* + * overhead - overhead not measured by the test. + * duration - wall clock time it took to perform test. + * predicted - extra time test says should not be counted + * + * Time accountable to the test is duration - overhead - predicted + * All times are Intervals and accumulated for all iterations. + */ + PRFloat64 elapsed; + PRIntervalTime accountable, duration; + PRUintn spaces = strlen(msg); + PRIntervalTime timeout, timein = PR_IntervalNow(); + PRIntervalTime predicted = test(loops); + timeout = PR_IntervalNow(); + duration = timeout - timein; + accountable = duration - predicted; + accountable -= overhead; + elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable); + if (debug_mode) printf("%s:", msg); + while (spaces++ < 50) if (debug_mode) printf(" "); + if ((PRInt32)accountable < 0) { + if (debug_mode) printf("*****.** usecs/iteration\n"); + } else { + if (debug_mode) printf("%8.2f usecs/iteration\n", elapsed/loops); + } + return duration; +} /* Test */ + +int main(int argc, char **argv) +{ + PRIntervalTime duration; + PRUint32 cpu, cpus = 2; + PRInt32 loops = 100; + + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (argc > 1) loops = atoi(argv[1]); + if (loops == 0) loops = 100; + if (debug_mode) printf("Lock: Using %d loops\n", loops); + + cpus = (argc < 3) ? 2 : atoi(argv[2]); + if (cpus == 0) cpus = 2; + if (debug_mode) printf("Lock: Using %d cpu(s)\n", cpus); + + + for (cpu = 1; cpu <= cpus; ++cpu) + { + if (debug_mode) printf("\nLockFile: Using %d CPU(s)\n", cpu); + PR_SetConcurrency(cpu); + + duration = Test("LockFile non-contentious locking/unlocking", NonContentiousLock, loops, 0); + (void)Test("LockFile contentious locking/unlocking", ContentiousLock, loops, duration); + } + + PR_Delete(LOCKFILE); /* try to get rid of evidence */ + + if (debug_mode) printf("%s: test %s\n", "Lock(mutex) test", ((failed_already) ? "failed" : "passed")); + if(failed_already) + return 1; + else + return 0; +} /* main */ + +/* testlock.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/logfile.c nspr-4.10.7/nspr/pr/tests/logfile.c --- nspr-4.9.5/nspr/pr/tests/logfile.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/logfile.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * A regression test for bug 491441. NSPR should not crash on startup in + * PR_SetLogFile when the NSPR_LOG_MODULES and NSPR_LOG_FILE environment + * variables are set. + * + * This test could be extended to be a full-blown test for NSPR_LOG_FILE. + */ + +#include "prinit.h" +#include "prlog.h" + +#include +#include + +int main() +{ + PRLogModuleInfo *test_lm; + + if (putenv("NSPR_LOG_MODULES=all:5") != 0) { + fprintf(stderr, "putenv failed\n"); + exit(1); + } + if (putenv("NSPR_LOG_FILE=logfile.log") != 0) { + fprintf(stderr, "putenv failed\n"); + exit(1); + } + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + test_lm = PR_NewLogModule("test"); + PR_LOG(test_lm, PR_LOG_MIN, ("logfile: test log message")); + PR_Cleanup(); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/logger.c nspr-4.10.7/nspr/pr/tests/logger.c --- nspr-4.9.5/nspr/pr/tests/logger.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/logger.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: logger.c + * Description: test program for logging's basic functions + */ + +#include "prinit.h" +#include "prlog.h" +#include "prlock.h" +#include "prcvar.h" +#include "prthread.h" +#include "prinrval.h" + +#include + +/* lth. re-define PR_LOG() */ +#if 0 +#undef PR_LOG_TEST +#undef PR_LOG +#define PR_LOG_TEST(_module,_level) ((_module)->level <= (_level)) +#define PR_LOG(_module,_level,_args) \ + { \ + if (PR_LOG_TEST(_module,_level)) \ + PR_LogPrint _args ; \ + } +#endif + + +static void Error(const char* msg) +{ + printf("\t%s\n", msg); +} /* Error */ + +static void PR_CALLBACK forked(void *arg) +{ + PRIntn i; + PRLock *ml; + PRCondVar *cv; + + PR_LogPrint("%s logging creating mutex\n", (const char*)arg); + ml = PR_NewLock(); + PR_LogPrint("%s logging creating condition variable\n", (const char*)arg); + cv = PR_NewCondVar(ml); + + PR_LogPrint("%s waiting on condition timeout 10 times\n", (const char*)arg); + for (i = 0; i < 10; ++i) + { + PR_Lock(ml); + PR_WaitCondVar(cv, PR_SecondsToInterval(1)); + PR_Unlock(ml); + } + + PR_LogPrint("%s logging destroying condition variable\n", (const char*)arg); + PR_DestroyCondVar(cv); + PR_LogPrint("%s logging destroying mutex\n", (const char*)arg); + PR_DestroyLock(ml); + PR_LogPrint("%s forked thread exiting\n", (const char*)arg); +} + +static void UserLogStuff( void ) +{ + PRLogModuleInfo *myLM; + PRIntn i; + + myLM = PR_NewLogModule( "userStuff" ); + if (! myLM ) + { + printf("UserLogStuff(): can't create new log module\n" ); + return; + } + + PR_LOG( myLM, PR_LOG_NOTICE, ("Log a Notice %d\n", 1 )); + + for (i = 0; i < 10 ; i++ ) + { + PR_LOG( myLM, PR_LOG_DEBUG, ("Log Debug number: %d\n", i)); + PR_Sleep( 300 ); + } + +} /* end UserLogStuff() */ + +int main(int argc, char **argv) +{ + PRThread *thread; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (argc > 1) + { + if (!PR_SetLogFile(argv[1])) + { + Error("Access: Cannot create log file"); + goto exit; + } + } + + /* Start logging something here */ + PR_LogPrint("%s logging into %s\n", argv[0], argv[1]); + + PR_LogPrint("%s creating new thread\n", argv[0]); + + /* + ** Now change buffering. + */ + PR_SetLogBuffering( 65500 ); + thread = PR_CreateThread( + PR_USER_THREAD, forked, (void*)argv[0], PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + PR_LogPrint("%s joining thread\n", argv[0]); + + UserLogStuff(); + + PR_JoinThread(thread); + + PR_LogFlush(); + return 0; + +exit: + return -1; +} + +/* logger.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/makedir.c nspr-4.10.7/nspr/pr/tests/makedir.c --- nspr-4.9.5/nspr/pr/tests/makedir.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/makedir.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This test calls PR_MakeDir to create a bunch of directories + * with various mode bits. + */ + +#include "prio.h" + +#include +#include + +int main(int argc, char **argv) +{ + if (PR_MakeDir("tdir0400", 0400) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0200", 0200) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0100", 0100) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0500", 0500) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0600", 0600) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0300", 0300) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0700", 0700) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0640", 0640) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0660", 0660) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0644", 0644) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0664", 0664) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + if (PR_MakeDir("tdir0666", 0666) == PR_FAILURE) { + fprintf(stderr, "PR_MakeDir failed\n"); + exit(1); + } + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/Makefile.in nspr-4.10.7/nspr/pr/tests/Makefile.in --- nspr-4.9.5/nspr/pr/tests/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,504 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +#! gmake + +MOD_DEPTH = ../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +DIRS = dll + +CSRCS = \ + accept.c \ + acceptread.c \ + acceptreademu.c \ + addrstr.c \ + affinity.c \ + alarm.c \ + anonfm.c \ + append.c \ + atomic.c \ + attach.c \ + bigfile.c \ + bigfile2.c \ + bigfile3.c \ + cleanup.c \ + cltsrv.c \ + concur.c \ + cvar.c \ + cvar2.c \ + dceemu.c \ + dlltest.c \ + dtoa.c \ + env.c \ + errcodes.c \ + errset.c \ + exit.c \ + fdcach.c \ + fileio.c \ + foreign.c \ + forktest.c \ + formattm.c \ + fsync.c \ + getai.c \ + gethost.c \ + getproto.c \ + i2l.c \ + initclk.c \ + inrval.c \ + instrumt.c \ + intrio.c \ + intrupt.c \ + io_timeout.c \ + ioconthr.c \ + ipv6.c \ + join.c \ + joinkk.c \ + joinku.c \ + joinuk.c \ + joinuu.c \ + layer.c \ + lazyinit.c \ + libfilename.c \ + lltest.c \ + lock.c \ + lockfile.c \ + logfile.c \ + logger.c \ + makedir.c \ + mbcs.c \ + multiacc.c \ + multiwait.c \ + many_cv.c \ + monref.c \ + nameshm1.c \ + nbconn.c \ + nblayer.c \ + nonblock.c \ + ntioto.c \ + ntoh.c \ + obsints.c \ + op_2long.c \ + op_excl.c \ + op_filnf.c \ + op_filok.c \ + op_noacc.c \ + op_nofil.c \ + openfile.c \ + parent.c \ + parsetm.c \ + peek.c \ + perf.c \ + pipeping.c \ + pipeping2.c \ + pipepong.c \ + pipepong2.c \ + pipeself.c \ + poll_er.c \ + poll_nm.c \ + poll_to.c \ + pollable.c \ + prfdbl.c \ + prftest.c \ + prftest1.c \ + prftest2.c \ + primblok.c \ + priotest.c \ + provider.c \ + prpoll.c \ + prpollml.c \ + pushtop.c \ + ranfile.c \ + randseed.c \ + reinit.c \ + rmdir.c \ + rwlockrank.c \ + rwlocktest.c \ + sel_spd.c \ + selct_er.c \ + selct_nm.c \ + selct_to.c \ + select2.c \ + selintr.c \ + sem.c \ + sema.c \ + semaerr.c \ + semaerr1.c \ + semaping.c \ + semapong.c \ + sendzlf.c \ + server_test.c \ + servr_kk.c \ + servr_ku.c \ + servr_uk.c \ + servr_uu.c \ + short_thread.c \ + sigpipe.c \ + socket.c \ + sockopt.c \ + sockping.c \ + sockpong.c \ + sprintf.c \ + sproc_ch.c \ + sproc_p.c \ + stack.c \ + stdio.c \ + str2addr.c \ + strod.c \ + suspend.c \ + switch.c \ + system.c \ + testbit.c \ + testfile.c \ + thrpool_server.c \ + thrpool_client.c \ + threads.c \ + thruput.c \ + timemac.c \ + timetest.c \ + tmoacc.c \ + tmocon.c \ + tpd.c \ + vercheck.c \ + version.c \ + udpsrv.c \ + writev.c \ + xnotify.c \ + y2k.c \ + y2ktmo.c \ + zerolen.c \ + $(NULL) + +ifeq ($(OS_ARCH),WINCE) +CFLAGS += -FImozce_shunt.h -Zi -UDEBUG -DNDEBUG +LDOPTS += -link $(DIST)/lib/mozce_shunt.lib ws2.lib -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO -PDB:$(@:.exe=.pdb) +endif + +ifeq ($(OS_TARGET),OS2) +CSRCS += \ + sleep.c \ + stat.c \ + yield.c \ + $(NULL) +endif + +ifeq (,$(filter-out WINCE WINNT OS2,$(OS_ARCH))) +PROG_SUFFIX = .exe +DLL_SUFFIX = .dll +else +PROG_SUFFIX = +DLL_SUFFIX = +endif + +PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX))) + +TARGETS = $(PROGS) + +INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private + +ifeq ($(OS_ARCH), WINNT) +ifdef NS_USE_GCC + EXTRA_LIBS += -lws2_32 +else + EXTRA_LIBS += ws2_32.lib + LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO + ifdef PROFILE + LDOPTS += -PROFILE -MAP + endif # profile +endif # NS_USE_GCC +endif + +ifeq ($(OS_ARCH),OS2) +EXTRA_LIBS = $(OS_LIBS) +LDOPTS = -Zomf -Zlinker /PM:VIO -Zlinker /ST:0x64000 +endif + +ifneq ($(OS_ARCH), WINNT) +# Use an absolute pathname as the runtime library path (for the -R +# or -rpath linker option or the LD_RUN_PATH environment variable). +ifeq (,$(patsubst /%,,$(DIST))) +# $(DIST) is already an absolute pathname. +ABSOLUTE_LIB_DIR = $(dist_libdir) +else +# $(DIST) is a relative pathname: prepend the current directory. +PWD = $(shell pwd) +ABSOLUTE_LIB_DIR = $(PWD)/$(dist_libdir) +endif +endif + +ifeq ($(OS_ARCH), IRIX) + ifeq ($(USE_CPLUS), 1) + CC = CC + endif + LDOPTS += -rpath $(ABSOLUTE_LIB_DIR) + ifdef NS_USE_GCC + LDOPTS += -Wl,-rdata_shared + else + LDOPTS += -rdata_shared + endif +# For 6.x machines, include this flag + ifeq ($(basename $(OS_RELEASE)),6) + ifndef NS_USE_GCC + ifeq ($(USE_N32),1) + LDOPTS += -n32 + else + LDOPTS += -32 + endif + + ifeq ($(USE_PTHREADS), 1) + ifeq ($(OS_RELEASE), 6.2) + LDOPTS += -Wl,-woff,85 + endif + endif + endif + endif +endif + +ifeq ($(OS_ARCH), OSF1) + ifeq ($(USE_CPLUS), 1) + CC = cxx + endif +# I haven't figured out how to pass -rpath to cc on OSF1 V3.2, so +# we do static linking. + ifeq (,$(filter-out V2.0 V3.2,$(OS_RELEASE))) + LIBNSPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a + LIBPLC = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).a + EXTRA_LIBS = -lc_r + else + LDOPTS += -rpath $(ABSOLUTE_LIB_DIR) + endif +endif + +ifeq ($(OS_ARCH), HP-UX) + LDOPTS += -z -Wl,+s,+b,$(ABSOLUTE_LIB_DIR) + ifeq ($(USE_64),1) + LDOPTS += +DD64 + endif + ifeq ($(USE_PTHREADS),1) + EXTRA_LIBS = $(LIBPTHREAD) + endif +endif + +# AIX +ifeq ($(OS_ARCH),AIX) + LDOPTS += -blibpath:$(ABSOLUTE_LIB_DIR):/usr/lib:/lib + ifneq ($(OS_ARCH)$(OS_RELEASE),AIX4.1) + LDOPTS += -brtl + EXTRA_LIBS = -ldl + endif +endif + +# Solaris +ifeq ($(OS_ARCH), SunOS) + ifdef NS_USE_GCC + LDOPTS += -Xlinker -R -Xlinker $(ABSOLUTE_LIB_DIR) + else + ifeq ($(USE_CPLUS), 1) + CC = CC + endif + LDOPTS += -R $(ABSOLUTE_LIB_DIR) + endif + + ifdef USE_PTHREADS + EXTRA_LIBS = -lpthread + endif +endif # SunOS + +ifeq (,$(filter-out Linux GNU GNU_%,$(OS_ARCH))) + LDOPTS += -Xlinker -rpath $(ABSOLUTE_LIB_DIR) + ifeq ($(USE_PTHREADS),1) + EXTRA_LIBS = -lpthread + endif +endif + +ifeq ($(OS_ARCH), SCOOS) +# SCO Unix needs to link against -lsocket again even though we +# already linked with these system libraries when we built libnspr.so. +EXTRA_LIBS = -lsocket +# This hardcodes in the executable programs the directory to find +# libnspr.so etc. at program startup. Equivalent to the -R or -rpath +# option for ld on other platforms. +export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR) +endif + +ifeq ($(OS_ARCH),OpenUNIX) +export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR) +ifeq ($(USE_PTHREADS),1) +LDOPTS += -pthread +endif +endif + +ifeq ($(OS_ARCH), UNIXWARE) +export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR) +endif + +ifeq ($(OS_ARCH),FreeBSD) +ifeq ($(USE_PTHREADS),1) +LDOPTS += -pthread +endif +LDOPTS += -Xlinker -R $(ABSOLUTE_LIB_DIR) +endif + +ifeq ($(OS_ARCH),OpenBSD) +ifeq ($(USE_PTHREADS),1) +LDOPTS += -pthread +endif +endif + +ifeq ($(OS_ARCH),BSD_OS) +ifneq ($(OS_RELEASE),1.1) +EXTRA_LIBS = -ldl +endif +endif + +ifeq ($(OS_ARCH),RISCOS) +EXTRA_LIBS = -ldl +endif + +ifeq ($(USE_PTHREADS),1) +LIBPTHREAD = -lpthread +ifeq ($(OS_ARCH),AIX) +LIBPTHREAD = -lpthreads +endif +ifeq (,$(filter-out FreeBSD OpenBSD BSD_OS QNX Darwin OpenUNIX,$(OS_ARCH))) +LIBPTHREAD = +endif +ifeq ($(OS_ARCH)$(basename $(OS_RELEASE)),HP-UXB.10) +LIBPTHREAD = -ldce +endif +endif + +ifeq ($(OS_TARGET),Android) +LIBPTHREAD = +XCFLAGS = $(OS_CFLAGS) +endif + +##################################################### +# +# The rules +# +##################################################### + +include $(topsrcdir)/config/rules.mk + +AIX_PRE_4_2 = 0 +ifeq ($(OS_ARCH),AIX) +ifeq ($(OS_RELEASE),4.1) +ifneq ($(USE_PTHREADS), 1) +#AIX_PRE_4_2 = 1 +endif +endif +endif + +ifeq ($(AIX_PRE_4_2),1) + +# AIX releases prior to 4.2 need a special two-step linking hack +# in order to both override the system select() and be able to +# get at the original system select(). +# +# We use a pattern rule in ns/nspr20/config/rules.mk to generate +# the .$(OBJ_SUFFIX) file from the .c source file, then do the +# two-step linking hack below. + +$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) + rm -f $@ $(AIX_TMP) + $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a + $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) + rm -f $(AIX_TMP) + +else + +# All platforms that are not AIX pre-4.2. + +$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) +ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT) + link $(LDOPTS) $(EXTRA_LDOPTS) $< $(LIBPLC) $(LIBNSPR) $(EXTRA_LIBS) -out:$@ +ifdef MT + @if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ + rm -f $@.manifest; \ + fi +endif +else + $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(EXTRA_LIBS) -o $@ +endif # WINNT +endif # AIX_PRE_4_2 + +export:: $(TARGETS) +clean:: + rm -f $(TARGETS) + +# The following tests call BSD socket functions, so they need to link +# with -lsocket on some platforms. +ifeq ($(OS_ARCH),SunOS) +ifeq ($(USE_IPV6),1) +$(OBJDIR)/gethost: $(OBJDIR)/gethost.o + $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) -lsocket $(EXTRA_LIBS) -o $@ +endif +$(OBJDIR)/prpoll: $(OBJDIR)/prpoll.o + $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) -lsocket $(EXTRA_LIBS) -o $@ +endif + +ifeq ($(USE_PTHREADS), 1) +$(OBJDIR)/attach: $(OBJDIR)/attach.o + $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ +$(OBJDIR)/foreign: $(OBJDIR)/foreign.o + $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ +$(OBJDIR)/provider: $(OBJDIR)/provider.o + $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ +$(OBJDIR)/socket: $(OBJDIR)/socket.o + $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ +$(OBJDIR)/testfile: $(OBJDIR)/testfile.o + $(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ +endif + +# +# Run the test programs with no arguments +# +# Test output goes to the file pointed to by the environment variable +# NSPR_TEST_LOGFILE, if set, else to /dev/null +# +ECHO = echo +PROGRAMS = $(notdir $(PROGS)) +ifdef NSPR_TEST_LOGFILE +LOGFILE = $(NSPR_TEST_LOGFILE) +else +ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) +LOGFILE = nul +else +LOGFILE = /dev/null +endif +endif + +ifeq ($(OS_TARGET),Linux) +ECHO = /bin/echo +endif + +ALWAYS: + +runtests:: $(PROGS) ALWAYS + @$(ECHO) "\nNSPR Test Results - $(OBJDIR)\n" + @$(ECHO) "BEGIN\t\t\t`date`" + @$(ECHO) "NSPR_TEST_LOGFILE\t$(LOGFILE)\n" + @$(ECHO) "Test\t\t\tResult\n" + @cd $(OBJDIR); for i in $(PROGRAMS); do \ + $(ECHO) "$$i\c"; \ + ./$$i >> $(LOGFILE) 2>&1 ; \ + if [ 0 = $$? ] ; then \ + $(ECHO) "\t\t\tPassed"; \ + else \ + $(ECHO) "\t\t\tFAILED"; \ + fi; \ + done + @$(ECHO) "\nEND\t\t`date`\n" diff -Nru nspr-4.9.5/nspr/pr/tests/many_cv.c nspr-4.10.7/nspr/pr/tests/many_cv.c --- nspr-4.9.5/nspr/pr/tests/many_cv.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/many_cv.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include "prprf.h" +#include "prthread.h" +#include "prcvar.h" +#include "prlock.h" +#include "prlog.h" +#include "prmem.h" + +#include "primpl.h" + +#include "plgetopt.h" + +#include + +static PRInt32 RandomNum(void) +{ + PRInt32 ran = rand() >> 16; + return ran; +} /* RandomNum */ + +static void Help(void) +{ + PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); + PR_fprintf(err, "many_cv usage: [-c n] [-l n] [-h]\n"); + PR_fprintf(err, "\t-c n Number of conditions per lock (default: 10)\n"); + PR_fprintf(err, "\t-l n Number of times to loop the test (default: 1)\n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); +} /* Help */ + +static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) +{ + PLOptStatus os; + PRIntn index, nl; + PRLock *ml = NULL; + PRCondVar **cv = NULL; + PRBool stats = PR_FALSE; + PRIntn nc, loops = 1, cvs = 10; + PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); + PLOptState *opt = PL_CreateOptState(argc, argv, "hsc:l:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 's': /* number of CVs to association with lock */ + stats = PR_TRUE; + break; + case 'c': /* number of CVs to association with lock */ + cvs = atoi(opt->value); + break; + case 'l': /* number of times to run the tests */ + loops = atoi(opt->value); + break; + case 'h': /* user wants some guidance */ + default: + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + } + } + PL_DestroyOptState(opt); + + PR_fprintf(err, "Settings\n"); + PR_fprintf(err, "\tConditions / lock: %d\n", cvs); + PR_fprintf(err, "\tLoops to run test: %d\n", loops); + + ml = PR_NewLock(); + PR_ASSERT(NULL != ml); + + cv = (PRCondVar**)PR_CALLOC(sizeof(PRCondVar*) * cvs); + PR_ASSERT(NULL != cv); + + for (index = 0; index < cvs; ++index) + { + cv[index] = PR_NewCondVar(ml); + PR_ASSERT(NULL != cv[index]); + } + + for (index = 0; index < loops; ++index) + { + PR_Lock(ml); + for (nl = 0; nl < cvs; ++nl) + { + PRInt32 ran = RandomNum() % 8; + if (0 == ran) PR_NotifyAllCondVar(cv[nl]); + else for (nc = 0; nc < ran; ++nc) + PR_NotifyCondVar(cv[nl]); + } + PR_Unlock(ml); + } + + for (index = 0; index < cvs; ++index) + PR_DestroyCondVar(cv[index]); + + PR_DELETE(cv); + + PR_DestroyLock(ml); + + printf("PASS\n"); + + PT_FPrintStats(err, "\nPThread Statistics\n"); + return 0; +} + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/mbcs.c nspr-4.10.7/nspr/pr/tests/mbcs.c --- nspr-4.9.5/nspr/pr/tests/mbcs.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/mbcs.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: mbcs.c +** +** Synopsis: mbcs {dirName} +** +** where dirName is the directory to be traversed. dirName is required. +** +** Description: +** mbcs.c tests use of multi-byte characters, as would be passed to +** NSPR funtions by internationalized applications. +** +** mbcs.c, when run on any single-byte platform, should run correctly. +** In truth, running the mbcs test on a single-byte platform is +** really meaningless. mbcs.c, nor any NSPR library or test is not +** intended for use with any wide character set, including Unicode. +** mbcs.c should not be included in runtests.ksh because it requires +** extensive user intervention to set-up and run. +** +** mbcs.c should be run on a platform using some form of multi-byte +** characters. The initial platform for this test is a Japanese +** language Windows NT 4.0 machine. ... Thank you Noriko Hoshi. +** +** To run mbcs.c, the tester should create a directory tree containing +** some files in the same directory from which the test is run; i.e. +** the current working directory. The directory and files should be +** named such that when represented in the local multi-byte character +** set, one or more characters of the name is longer than a single +** byte. +** +*/ + +#include +#include +#include +#include +#include + +/* +** Test harness infrastructure +*/ +PRLogModuleInfo *lm; +PRLogModuleLevel msgLevel = PR_LOG_NONE; +PRIntn debug = 0; +PRUint32 failed_already = 0; +/* end Test harness infrastructure */ + +char *dirName = NULL; /* directory name to traverse */ + +/* +** Traverse directory +*/ +static void TraverseDirectory( unsigned char *dir ) +{ + PRDir *cwd; + PRDirEntry *dirEntry; + PRFileInfo info; + PRStatus rc; + PRInt32 err; + PRFileDesc *fd; + char nextDir[256]; + char file[256]; + + printf("Directory: %s\n", dir ); + cwd = PR_OpenDir( dir ); + if ( NULL == cwd ) { + printf("PR_OpenDir() failed on directory: %s, with error: %d, %d\n", + dir, PR_GetError(), PR_GetOSError()); + exit(1); + } + while( NULL != (dirEntry = PR_ReadDir( cwd, PR_SKIP_BOTH | PR_SKIP_HIDDEN ))) { + sprintf( file, "%s/%s", dir, dirEntry->name ); + rc = PR_GetFileInfo( file, &info ); + if ( PR_FAILURE == rc ) { + printf("PR_GetFileInfo() failed on file: %s, with error: %d, %d\n", + dirEntry->name, PR_GetError(), PR_GetOSError()); + exit(1); + } + if ( PR_FILE_FILE == info.type ) { + printf("File: %s \tsize: %ld\n", dirEntry->name, info.size ); + fd = PR_Open( file, PR_RDONLY, 0 ); + if ( NULL == fd ) { + printf("PR_Open() failed. Error: %ld, OSError: %ld\n", + PR_GetError(), PR_GetOSError()); + } + rc = PR_Close( fd ); + if ( PR_FAILURE == rc ) { + printf("PR_Close() failed. Error: %ld, OSError: %ld\n", + PR_GetError(), PR_GetOSError()); + } + } else if ( PR_FILE_DIRECTORY == info.type ) { + sprintf( nextDir, "%s/%s", dir, dirEntry->name ); + TraverseDirectory(nextDir); + } else { + printf("type is not interesting for file: %s\n", dirEntry->name ); + /* keep going */ + } + } + /* assume end-of-file, actually could be error */ + + rc = PR_CloseDir( cwd ); + if ( PR_FAILURE == rc ) { + printf("PR_CloseDir() failed on directory: %s, with error: %d, %d\n", + dir, PR_GetError(), PR_GetOSError()); + } + +} /* end TraverseDirectory() */ + +int main(int argc, char **argv) +{ + { /* get command line options */ + /* + ** Get command line options + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dv"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug */ + debug = 1; + msgLevel = PR_LOG_ERROR; + break; + case 'v': /* verbose mode */ + msgLevel = PR_LOG_DEBUG; + break; + default: + dirName = strdup(opt->value); + break; + } + } + PL_DestroyOptState(opt); + } /* end get command line options */ + + lm = PR_NewLogModule("Test"); /* Initialize logging */ + + + if ( dirName == NULL ) { + printf("you gotta specify a directory as an operand!\n"); + exit(1); + } + + TraverseDirectory( dirName ); + + if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); + return( (failed_already == PR_TRUE )? 1 : 0 ); +} /* main() */ +/* end template.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/monref.c nspr-4.10.7/nspr/pr/tests/monref.c --- nspr-4.9.5/nspr/pr/tests/monref.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/monref.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,74 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This test program demonstrates that PR_ExitMonitor needs to add a + * reference to the PRMonitor object before unlocking the internal + * mutex. + */ + +#include "prlog.h" +#include "prmon.h" +#include "prthread.h" + +#include +#include + +/* Protected by the PRMonitor 'mon' in the main function. */ +static PRBool done = PR_FALSE; + +static void ThreadFunc(void *arg) +{ + PRMonitor *mon = (PRMonitor *)arg; + PRStatus rv; + + PR_EnterMonitor(mon); + done = PR_TRUE; + rv = PR_Notify(mon); + PR_ASSERT(rv == PR_SUCCESS); + rv = PR_ExitMonitor(mon); + PR_ASSERT(rv == PR_SUCCESS); +} + +int main() +{ + PRMonitor *mon; + PRThread *thread; + PRStatus rv; + + mon = PR_NewMonitor(); + if (!mon) { + fprintf(stderr, "PR_NewMonitor failed\n"); + exit(1); + } + + thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, mon, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, 0); + if (!thread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + + PR_EnterMonitor(mon); + while (!done) { + rv = PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(rv == PR_SUCCESS); + } + rv = PR_ExitMonitor(mon); + PR_ASSERT(rv == PR_SUCCESS); + + /* + * Do you agree it should be safe to destroy 'mon' now? + * See bug 844784 comment 27. + */ + PR_DestroyMonitor(mon); + + rv = PR_JoinThread(thread); + PR_ASSERT(rv == PR_SUCCESS); + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/multiacc.c nspr-4.10.7/nspr/pr/tests/multiacc.c --- nspr-4.9.5/nspr/pr/tests/multiacc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/multiacc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,220 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: multiacc.c + * + * Description: + * This test creates multiple threads that accept on the + * same listening socket. + */ + +#include "nspr.h" + +#include +#include +#include + +#define NUM_SERVER_THREADS 10 + +static int num_server_threads = NUM_SERVER_THREADS; +static PRThreadScope thread_scope = PR_GLOBAL_THREAD; +static PRBool exit_flag = PR_FALSE; + +static void ServerThreadFunc(void *arg) +{ + PRFileDesc *listenSock = (PRFileDesc *) arg; + PRFileDesc *acceptSock; + PRErrorCode err; + PRStatus status; + + while (!exit_flag) { + acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (NULL == acceptSock) { + err = PR_GetError(); + if (PR_PENDING_INTERRUPT_ERROR == err) { + printf("server thread is interrupted\n"); + fflush(stdout); + continue; + } + fprintf(stderr, "PR_Accept failed: %d\n", err); + exit(1); + } + status = PR_Close(acceptSock); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } +} + +int main(int argc, char **argv) +{ + PRNetAddr serverAddr; + PRFileDesc *dummySock; + PRFileDesc *listenSock; + PRFileDesc *clientSock; + PRThread *dummyThread; + PRThread **serverThreads; + PRStatus status; + PRUint16 port; + int idx; + PRInt32 nbytes; + char buf[1024]; + + serverThreads = (PRThread **) + PR_Malloc(num_server_threads * sizeof(PRThread *)); + if (NULL == serverThreads) { + fprintf(stderr, "PR_Malloc failed\n"); + exit(1); + } + + /* + * Create a dummy listening socket and have the first + * (dummy) thread listen on it. This is to ensure that + * the first thread becomes the I/O continuation thread + * in the pthreads implementation (see ptio.c) and remains + * so throughout the test, so that we never have to + * recycle the I/O continuation thread. + */ + dummySock = PR_NewTCPSocket(); + if (NULL == dummySock) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + memset(&serverAddr, 0, sizeof(serverAddr)); + status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_InitializeNetAddr failed\n"); + exit(1); + } + status = PR_Bind(dummySock, &serverAddr); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + status = PR_Listen(dummySock, 5); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + + listenSock = PR_NewTCPSocket(); + if (NULL == listenSock) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + memset(&serverAddr, 0, sizeof(serverAddr)); + status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_InitializeNetAddr failed\n"); + exit(1); + } + status = PR_Bind(listenSock, &serverAddr); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + status = PR_GetSockName(listenSock, &serverAddr); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_GetSockName failed\n"); + exit(1); + } + port = PR_ntohs(serverAddr.inet.port); + status = PR_Listen(listenSock, 5); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + + printf("creating dummy thread\n"); + fflush(stdout); + dummyThread = PR_CreateThread(PR_USER_THREAD, + ServerThreadFunc, dummySock, PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + if (NULL == dummyThread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + printf("sleeping one second before creating server threads\n"); + fflush(stdout); + PR_Sleep(PR_SecondsToInterval(1)); + for (idx = 0; idx < num_server_threads; idx++) { + serverThreads[idx] = PR_CreateThread(PR_USER_THREAD, + ServerThreadFunc, listenSock, PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + if (NULL == serverThreads[idx]) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + } + + memset(&serverAddr, 0, sizeof(serverAddr)); + PR_InitializeNetAddr(PR_IpAddrLoopback, port, &serverAddr); + clientSock = PR_NewTCPSocket(); + if (NULL == clientSock) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + printf("sleeping one second before connecting\n"); + fflush(stdout); + PR_Sleep(PR_SecondsToInterval(1)); + status = PR_Connect(clientSock, &serverAddr, PR_INTERVAL_NO_TIMEOUT); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Connect failed\n"); + exit(1); + } + nbytes = PR_Read(clientSock, buf, sizeof(buf)); + if (nbytes != 0) { + fprintf(stderr, "expected 0 bytes but got %d bytes\n", nbytes); + exit(1); + } + status = PR_Close(clientSock); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + printf("sleeping one second before shutting down server threads\n"); + fflush(stdout); + PR_Sleep(PR_SecondsToInterval(1)); + + exit_flag = PR_TRUE; + status = PR_Interrupt(dummyThread); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Interrupt failed\n"); + exit(1); + } + status = PR_JoinThread(dummyThread); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + for (idx = 0; idx < num_server_threads; idx++) { + status = PR_Interrupt(serverThreads[idx]); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Interrupt failed\n"); + exit(1); + } + status = PR_JoinThread(serverThreads[idx]); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + } + PR_Free(serverThreads); + status = PR_Close(dummySock); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(listenSock); + if (PR_FAILURE == status) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/multiwait.c nspr-4.10.7/nspr/pr/tests/multiwait.c --- nspr-4.9.5/nspr/pr/tests/multiwait.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/multiwait.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,693 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prprf.h" +#include "prlog.h" +#include "prmem.h" +#include "pratom.h" +#include "prlock.h" +#include "prmwait.h" +#include "prclist.h" +#include "prerror.h" +#include "prinrval.h" +#include "prnetdb.h" +#include "prthread.h" + +#include "plstr.h" +#include "plerror.h" +#include "plgetopt.h" + +#include + +typedef struct Shared +{ + const char *title; + PRLock *list_lock; + PRWaitGroup *group; + PRIntervalTime timeout; +} Shared; + +typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity; + +static PRFileDesc *debug = NULL; +static PRInt32 desc_allocated = 0; +static PRUint16 default_port = 12273; +static enum Verbosity verbosity = quiet; +static PRInt32 ops_required = 1000, ops_done = 0; +static PRThreadScope thread_scope = PR_LOCAL_THREAD; +static PRIntn client_threads = 20, worker_threads = 2, wait_objects = 50; + +#if defined(DEBUG) +#define MW_ASSERT(_expr) \ + ((_expr)?((void)0):_MW_Assert(# _expr,__FILE__,__LINE__)) +static void _MW_Assert(const char *s, const char *file, PRIntn ln) +{ + if (NULL != debug) PL_FPrintError(debug, NULL); + PR_Assert(s, file, ln); +} /* _MW_Assert */ +#else +#define MW_ASSERT(_expr) +#endif + +static void PrintRecvDesc(PRRecvWait *desc, const char *msg) +{ + const char *tag[] = { + "PR_MW_INTERRUPT", "PR_MW_TIMEOUT", + "PR_MW_FAILURE", "PR_MW_SUCCESS", "PR_MW_PENDING"}; + PR_fprintf( + debug, "%s: PRRecvWait(@0x%x): {fd: 0x%x, outcome: %s, tmo: %u}\n", + msg, desc, desc->fd, tag[desc->outcome + 3], desc->timeout); +} /* PrintRecvDesc */ + +static Shared *MakeShared(const char *title) +{ + Shared *shared = PR_NEWZAP(Shared); + shared->group = PR_CreateWaitGroup(1); + shared->timeout = PR_SecondsToInterval(1); + shared->list_lock = PR_NewLock(); + shared->title = title; + return shared; +} /* MakeShared */ + +static void DestroyShared(Shared *shared) +{ + PRStatus rv; + if (verbosity > quiet) + PR_fprintf(debug, "%s: destroying group\n", shared->title); + rv = PR_DestroyWaitGroup(shared->group); + MW_ASSERT(PR_SUCCESS == rv); + PR_DestroyLock(shared->list_lock); + PR_DELETE(shared); +} /* DestroyShared */ + +static PRRecvWait *CreateRecvWait(PRFileDesc *fd, PRIntervalTime timeout) +{ + PRRecvWait *desc_out = PR_NEWZAP(PRRecvWait); + MW_ASSERT(NULL != desc_out); + + MW_ASSERT(NULL != fd); + desc_out->fd = fd; + desc_out->timeout = timeout; + desc_out->buffer.length = 120; + desc_out->buffer.start = PR_CALLOC(120); + + PR_AtomicIncrement(&desc_allocated); + + if (verbosity > chatty) + PrintRecvDesc(desc_out, "Allocated"); + return desc_out; +} /* CreateRecvWait */ + +static void DestroyRecvWait(PRRecvWait *desc_out) +{ + if (verbosity > chatty) + PrintRecvDesc(desc_out, "Destroying"); + PR_Close(desc_out->fd); + if (NULL != desc_out->buffer.start) + PR_DELETE(desc_out->buffer.start); + PR_Free(desc_out); + (void)PR_AtomicDecrement(&desc_allocated); +} /* DestroyRecvWait */ + +static void CancelGroup(Shared *shared) +{ + PRRecvWait *desc_out; + + if (verbosity > quiet) + PR_fprintf(debug, "%s Reclaiming wait descriptors\n", shared->title); + + do + { + desc_out = PR_CancelWaitGroup(shared->group); + if (NULL != desc_out) DestroyRecvWait(desc_out); + } while (NULL != desc_out); + + MW_ASSERT(0 == desc_allocated); + MW_ASSERT(PR_GROUP_EMPTY_ERROR == PR_GetError()); +} /* CancelGroup */ + +static void PR_CALLBACK ClientThread(void* arg) +{ + PRStatus rv; + PRInt32 bytes; + PRIntn empty_flags = 0; + PRNetAddr server_address; + unsigned char buffer[100]; + Shared *shared = (Shared*)arg; + PRFileDesc *server = PR_NewTCPSocket(); + if ((NULL == server) + && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) return; + MW_ASSERT(NULL != server); + + if (verbosity > chatty) + PR_fprintf(debug, "%s: Server socket @0x%x\n", shared->title, server); + + /* Initialize the buffer so that Purify won't complain */ + memset(buffer, 0, sizeof(buffer)); + + rv = PR_InitializeNetAddr(PR_IpAddrLoopback, default_port, &server_address); + MW_ASSERT(PR_SUCCESS == rv); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: Client opening connection\n", shared->title); + rv = PR_Connect(server, &server_address, PR_INTERVAL_NO_TIMEOUT); + + if (PR_FAILURE == rv) + { + if (verbosity > silent) PL_FPrintError(debug, "Client connect failed"); + return; + } + + while (ops_done < ops_required) + { + bytes = PR_Send( + server, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); + if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break; + MW_ASSERT(sizeof(buffer) == bytes); + if (verbosity > chatty) + PR_fprintf( + debug, "%s: Client sent %d bytes\n", + shared->title, sizeof(buffer)); + bytes = PR_Recv( + server, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); + if (verbosity > chatty) + PR_fprintf( + debug, "%s: Client received %d bytes\n", + shared->title, sizeof(buffer)); + if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break; + MW_ASSERT(sizeof(buffer) == bytes); + PR_Sleep(shared->timeout); + } + rv = PR_Close(server); + MW_ASSERT(PR_SUCCESS == rv); + +} /* ClientThread */ + +static void OneInThenCancelled(Shared *shared) +{ + PRStatus rv; + PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait); + + shared->timeout = PR_INTERVAL_NO_TIMEOUT; + + desc_in->fd = PR_NewTCPSocket(); + desc_in->timeout = shared->timeout; + + if (verbosity > chatty) PrintRecvDesc(desc_in, "Adding desc"); + + rv = PR_AddWaitFileDesc(shared->group, desc_in); + MW_ASSERT(PR_SUCCESS == rv); + + if (verbosity > chatty) PrintRecvDesc(desc_in, "Cancelling"); + rv = PR_CancelWaitFileDesc(shared->group, desc_in); + MW_ASSERT(PR_SUCCESS == rv); + + desc_out = PR_WaitRecvReady(shared->group); + MW_ASSERT(desc_out == desc_in); + MW_ASSERT(PR_MW_INTERRUPT == desc_out->outcome); + MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); + if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready"); + + rv = PR_Close(desc_in->fd); + MW_ASSERT(PR_SUCCESS == rv); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: destroying group\n", shared->title); + + PR_DELETE(desc_in); +} /* OneInThenCancelled */ + +static void OneOpOneThread(Shared *shared) +{ + PRStatus rv; + PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait); + + desc_in->fd = PR_NewTCPSocket(); + desc_in->timeout = shared->timeout; + + if (verbosity > chatty) PrintRecvDesc(desc_in, "Adding desc"); + + rv = PR_AddWaitFileDesc(shared->group, desc_in); + MW_ASSERT(PR_SUCCESS == rv); + desc_out = PR_WaitRecvReady(shared->group); + MW_ASSERT(desc_out == desc_in); + MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome); + MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError()); + if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready"); + + rv = PR_Close(desc_in->fd); + MW_ASSERT(PR_SUCCESS == rv); + + PR_DELETE(desc_in); +} /* OneOpOneThread */ + +static void ManyOpOneThread(Shared *shared) +{ + PRStatus rv; + PRIntn index; + PRRecvWait *desc_in; + PRRecvWait *desc_out; + + if (verbosity > quiet) + PR_fprintf(debug, "%s: adding %d descs\n", shared->title, wait_objects); + + for (index = 0; index < wait_objects; ++index) + { + desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout); + + rv = PR_AddWaitFileDesc(shared->group, desc_in); + MW_ASSERT(PR_SUCCESS == rv); + } + + while (ops_done < ops_required) + { + desc_out = PR_WaitRecvReady(shared->group); + MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome); + MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError()); + if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready/readding"); + rv = PR_AddWaitFileDesc(shared->group, desc_out); + MW_ASSERT(PR_SUCCESS == rv); + (void)PR_AtomicIncrement(&ops_done); + } + + CancelGroup(shared); +} /* ManyOpOneThread */ + +static void PR_CALLBACK SomeOpsThread(void *arg) +{ + PRRecvWait *desc_out; + PRStatus rv = PR_SUCCESS; + Shared *shared = (Shared*)arg; + do /* until interrupted */ + { + desc_out = PR_WaitRecvReady(shared->group); + if (NULL == desc_out) + { + MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); + if (verbosity > quiet) PR_fprintf(debug, "Aborted\n"); + break; + } + MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome); + MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError()); + if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready"); + + if (verbosity > chatty) PrintRecvDesc(desc_out, "Re-Adding"); + desc_out->timeout = shared->timeout; + rv = PR_AddWaitFileDesc(shared->group, desc_out); + PR_AtomicIncrement(&ops_done); + if (ops_done > ops_required) break; + } while (PR_SUCCESS == rv); + MW_ASSERT(PR_SUCCESS == rv); +} /* SomeOpsThread */ + +static void SomeOpsSomeThreads(Shared *shared) +{ + PRStatus rv; + PRThread **thread; + PRIntn index; + PRRecvWait *desc_in; + + thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads); + + /* Create some threads */ + + if (verbosity > quiet) + PR_fprintf(debug, "%s: creating threads\n", shared->title); + for (index = 0; index < worker_threads; ++index) + { + thread[index] = PR_CreateThread( + PR_USER_THREAD, SomeOpsThread, shared, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + } + + /* then create some operations */ + if (verbosity > quiet) + PR_fprintf(debug, "%s: creating desc\n", shared->title); + for (index = 0; index < wait_objects; ++index) + { + desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout); + rv = PR_AddWaitFileDesc(shared->group, desc_in); + MW_ASSERT(PR_SUCCESS == rv); + } + + if (verbosity > quiet) + PR_fprintf(debug, "%s: sleeping\n", shared->title); + while (ops_done < ops_required) PR_Sleep(shared->timeout); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: interrupting/joining threads\n", shared->title); + for (index = 0; index < worker_threads; ++index) + { + rv = PR_Interrupt(thread[index]); + MW_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(thread[index]); + MW_ASSERT(PR_SUCCESS == rv); + } + PR_DELETE(thread); + + CancelGroup(shared); +} /* SomeOpsSomeThreads */ + +static PRStatus ServiceRequest(Shared *shared, PRRecvWait *desc) +{ + PRInt32 bytes_out; + + if (verbosity > chatty) + PR_fprintf( + debug, "%s: Service received %d bytes\n", + shared->title, desc->bytesRecv); + + if (0 == desc->bytesRecv) goto quitting; + if ((-1 == desc->bytesRecv) + && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) goto aborted; + + bytes_out = PR_Send( + desc->fd, desc->buffer.start, desc->bytesRecv, 0, shared->timeout); + if (verbosity > chatty) + PR_fprintf( + debug, "%s: Service sent %d bytes\n", + shared->title, bytes_out); + + if ((-1 == bytes_out) + && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) goto aborted; + MW_ASSERT(bytes_out == desc->bytesRecv); + + return PR_SUCCESS; + +aborted: +quitting: + return PR_FAILURE; +} /* ServiceRequest */ + +static void PR_CALLBACK ServiceThread(void *arg) +{ + PRStatus rv = PR_SUCCESS; + PRRecvWait *desc_out = NULL; + Shared *shared = (Shared*)arg; + do /* until interrupted */ + { + if (NULL != desc_out) + { + desc_out->timeout = PR_INTERVAL_NO_TIMEOUT; + if (verbosity > chatty) + PrintRecvDesc(desc_out, "Service re-adding"); + rv = PR_AddWaitFileDesc(shared->group, desc_out); + MW_ASSERT(PR_SUCCESS == rv); + } + + desc_out = PR_WaitRecvReady(shared->group); + if (NULL == desc_out) + { + MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); + break; + } + + switch (desc_out->outcome) + { + case PR_MW_SUCCESS: + { + PR_AtomicIncrement(&ops_done); + if (verbosity > chatty) + PrintRecvDesc(desc_out, "Service ready"); + rv = ServiceRequest(shared, desc_out); + break; + } + case PR_MW_INTERRUPT: + MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); + rv = PR_FAILURE; /* if interrupted, then exit */ + break; + case PR_MW_TIMEOUT: + MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError()); + case PR_MW_FAILURE: + if (verbosity > silent) + PL_FPrintError(debug, "RecvReady failure"); + break; + default: + break; + } + } while (PR_SUCCESS == rv); + + if (NULL != desc_out) DestroyRecvWait(desc_out); + +} /* ServiceThread */ + +static void PR_CALLBACK EnumerationThread(void *arg) +{ + PRStatus rv; + PRIntn count; + PRRecvWait *desc; + Shared *shared = (Shared*)arg; + PRIntervalTime five_seconds = PR_SecondsToInterval(5); + PRMWaitEnumerator *enumerator = PR_CreateMWaitEnumerator(shared->group); + MW_ASSERT(NULL != enumerator); + + while (PR_SUCCESS == PR_Sleep(five_seconds)) + { + count = 0; + desc = NULL; + while (NULL != (desc = PR_EnumerateWaitGroup(enumerator, desc))) + { + if (verbosity > chatty) PrintRecvDesc(desc, shared->title); + count += 1; + } + if (verbosity > silent) + PR_fprintf(debug, + "%s Enumerated %d objects\n", shared->title, count); + } + + MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError()); + + + rv = PR_DestroyMWaitEnumerator(enumerator); + MW_ASSERT(PR_SUCCESS == rv); +} /* EnumerationThread */ + +static void PR_CALLBACK ServerThread(void *arg) +{ + PRStatus rv; + PRIntn index; + PRRecvWait *desc_in; + PRThread **worker_thread; + Shared *shared = (Shared*)arg; + PRFileDesc *listener, *service; + PRNetAddr server_address, client_address; + + worker_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads); + if (verbosity > quiet) + PR_fprintf(debug, "%s: Server creating worker_threads\n", shared->title); + for (index = 0; index < worker_threads; ++index) + { + worker_thread[index] = PR_CreateThread( + PR_USER_THREAD, ServiceThread, shared, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + } + + rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &server_address); + MW_ASSERT(PR_SUCCESS == rv); + + listener = PR_NewTCPSocket(); MW_ASSERT(NULL != listener); + if (verbosity > chatty) + PR_fprintf( + debug, "%s: Server listener socket @0x%x\n", + shared->title, listener); + rv = PR_Bind(listener, &server_address); MW_ASSERT(PR_SUCCESS == rv); + rv = PR_Listen(listener, 10); MW_ASSERT(PR_SUCCESS == rv); + while (ops_done < ops_required) + { + if (verbosity > quiet) + PR_fprintf(debug, "%s: Server accepting connection\n", shared->title); + service = PR_Accept(listener, &client_address, PR_INTERVAL_NO_TIMEOUT); + if (NULL == service) + { + if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) break; + PL_PrintError("Accept failed"); + MW_ASSERT(!"Accept failed"); + } + else + { + desc_in = CreateRecvWait(service, shared->timeout); + desc_in->timeout = PR_INTERVAL_NO_TIMEOUT; + if (verbosity > chatty) + PrintRecvDesc(desc_in, "Service adding"); + rv = PR_AddWaitFileDesc(shared->group, desc_in); + MW_ASSERT(PR_SUCCESS == rv); + } + } + + if (verbosity > quiet) + PR_fprintf(debug, "%s: Server interrupting worker_threads\n", shared->title); + for (index = 0; index < worker_threads; ++index) + { + rv = PR_Interrupt(worker_thread[index]); + MW_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(worker_thread[index]); + MW_ASSERT(PR_SUCCESS == rv); + } + PR_DELETE(worker_thread); + + PR_Close(listener); + + CancelGroup(shared); + +} /* ServerThread */ + +static void RealOneGroupIO(Shared *shared) +{ + /* + ** Create a server that listens for connections and then services + ** requests that come in over those connections. The server never + ** deletes a connection and assumes a basic RPC model of operation. + ** + ** Use worker_threads threads to service how every many open ports + ** there might be. + ** + ** Oh, ya. Almost forget. Create (some) clients as well. + */ + PRStatus rv; + PRIntn index; + PRThread *server_thread, *enumeration_thread, **client_thread; + + if (verbosity > quiet) + PR_fprintf(debug, "%s: creating server_thread\n", shared->title); + + server_thread = PR_CreateThread( + PR_USER_THREAD, ServerThread, shared, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: creating enumeration_thread\n", shared->title); + + enumeration_thread = PR_CreateThread( + PR_USER_THREAD, EnumerationThread, shared, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: snoozing before creating clients\n", shared->title); + PR_Sleep(5 * shared->timeout); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: creating client_threads\n", shared->title); + client_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * client_threads); + for (index = 0; index < client_threads; ++index) + { + client_thread[index] = PR_CreateThread( + PR_USER_THREAD, ClientThread, shared, + PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + } + + while (ops_done < ops_required) PR_Sleep(shared->timeout); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: interrupting/joining client_threads\n", shared->title); + for (index = 0; index < client_threads; ++index) + { + rv = PR_Interrupt(client_thread[index]); + MW_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(client_thread[index]); + MW_ASSERT(PR_SUCCESS == rv); + } + PR_DELETE(client_thread); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: interrupting/joining enumeration_thread\n", shared->title); + rv = PR_Interrupt(enumeration_thread); + MW_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(enumeration_thread); + MW_ASSERT(PR_SUCCESS == rv); + + if (verbosity > quiet) + PR_fprintf(debug, "%s: interrupting/joining server_thread\n", shared->title); + rv = PR_Interrupt(server_thread); + MW_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(server_thread); + MW_ASSERT(PR_SUCCESS == rv); +} /* RealOneGroupIO */ + +static void RunThisOne( + void (*func)(Shared*), const char *name, const char *test_name) +{ + Shared *shared; + if ((NULL == test_name) || (0 == PL_strcmp(name, test_name))) + { + if (verbosity > silent) + PR_fprintf(debug, "%s()\n", name); + shared = MakeShared(name); + ops_done = 0; + func(shared); /* run the test */ + MW_ASSERT(0 == desc_allocated); + DestroyShared(shared); + } +} /* RunThisOne */ + +static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta) +{ + PRIntn verbage = (PRIntn)verbosity; + return (Verbosity)(verbage += delta); +} /* ChangeVerbosity */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + const char *test_name = NULL; + PLOptState *opt = PL_CreateOptState(argc, argv, "dqGc:o:p:t:w:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: + test_name = opt->value; + break; + case 'd': /* debug mode */ + if (verbosity < noisy) + verbosity = ChangeVerbosity(verbosity, 1); + break; + case 'q': /* debug mode */ + if (verbosity > silent) + verbosity = ChangeVerbosity(verbosity, -1); + break; + case 'G': /* use global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'c': /* number of client threads */ + client_threads = atoi(opt->value); + break; + case 'o': /* operations to compelete */ + ops_required = atoi(opt->value); + break; + case 'p': /* default port */ + default_port = atoi(opt->value); + break; + case 't': /* number of threads waiting */ + worker_threads = atoi(opt->value); + break; + case 'w': /* number of wait objects */ + wait_objects = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (verbosity > 0) + debug = PR_GetSpecialFD(PR_StandardError); + + RunThisOne(OneInThenCancelled, "OneInThenCancelled", test_name); + RunThisOne(OneOpOneThread, "OneOpOneThread", test_name); + RunThisOne(ManyOpOneThread, "ManyOpOneThread", test_name); + RunThisOne(SomeOpsSomeThreads, "SomeOpsSomeThreads", test_name); + RunThisOne(RealOneGroupIO, "RealOneGroupIO", test_name); + return 0; +} /* main */ + +/* multwait.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/nameshm1.c nspr-4.10.7/nspr/pr/tests/nameshm1.c --- nspr-4.9.5/nspr/pr/tests/nameshm1.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/nameshm1.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,576 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: nameshm1.c -- Test Named Shared Memory +** +** Description: +** nameshm1 tests Named Shared Memory. nameshm1 performs two tests of +** named shared memory. +** +** The first test is a basic test. The basic test operates as a single +** process. The process exercises all the API elements of the facility. +** This test also attempts to write to all locations in the shared +** memory. +** +** The second test is a client-server test. The client-server test +** creates a new instance of nameshm1, passing the -C argument to the +** new process; this creates the client-side process. The server-side +** (the instance of nameshm1 created from the command line) and the +** client-side interact via inter-process semaphores to verify that the +** shared memory segment can be read and written by both sides in a +** synchronized maner. +** +** Note: Because this test runs in two processes, the log files created +** by the test are not in chronological sequence; makes it hard to read. +** As a temporary circumvention, I changed the definition(s) of the +** _PUT_LOG() macro in prlog.c to force a flushall(), or equivalent. +** This causes the log entries to be emitted in true chronological +** order. +** +** Synopsis: nameshm1 [options] [name] +** +** Options: +** -d Enables debug trace via PR_LOG() +** -v Enables verbose mode debug trace via PR_LOG() +** -w Causes the basic test to attempt to write to the segment +** mapped as read-only. When this option is specified, the +** test should crash with a seg-fault; this is a destructive +** test and is considered successful when it seg-faults. +** +** -C Causes nameshm1 to start as the client-side of a +** client-server pair of processes. Only the instance +** of nameshm1 operating as the server-side process should +** specify the -C option when creating the client-side process; +** the -C option should not be specified at the command line. +** The client-side uses the shared memory segment created by +** the server-side to communicate with the server-side +** process. +** +** -p Specify the number of iterations the client-server tests +** should perform. Default: 1000. +** +** -s Size, in KBytes (1024), of the shared memory segment. +** Default: (10 * 1024) +** +** -i Number of client-side iterations. Default: 3 +** +** name specifies the name of the shared memory segment to be used. +** Default: /tmp/xxxNSPRshm +** +** +** See also: prshm.h +** +** /lth. Aug-1999. +*/ + +#include +#include +#include +#include +#include + +#ifdef SYMBIAN +#define SEM_NAME1 "c:\\data\\nameshmSEM1" +#define SEM_NAME2 "c:\\data\\nameshmSEM2" +#define OPT_NAME "c:\\data\\xxxNSPRshm" +#define EXE_NAME "nspr_tests_nameshm1.exe" +#else +#define SEM_NAME1 "/tmp/nameshmSEM1" +#define SEM_NAME2 "/tmp/nameshmSEM2" +#define OPT_NAME "/tmp/xxxNSPRshm" +#define EXE_NAME "nameshm1" +#endif +#define SEM_MODE 0666 +#define SHM_MODE 0666 + +#define NameSize (1024) + +PRIntn debug = 0; +PRIntn failed_already = 0; +PRLogModuleLevel msgLevel = PR_LOG_NONE; +PRLogModuleInfo *lm; + +/* command line options */ +PRIntn optDebug = 0; +PRIntn optVerbose = 0; +PRUint32 optWriteRO = 0; /* test write to read-only memory. should crash */ +PRUint32 optClient = 0; +PRUint32 optCreate = 1; +PRUint32 optAttachRW = 1; +PRUint32 optAttachRO = 1; +PRUint32 optClose = 1; +PRUint32 optDelete = 1; +PRInt32 optPing = 1000; +PRUint32 optSize = (10 * 1024 ); +PRInt32 optClientIterations = 3; +char optName[NameSize] = OPT_NAME; + +char buf[1024] = ""; + + +static void BasicTest( void ) +{ + PRSharedMemory *shm; + char *addr; /* address of shared memory segment */ + PRUint32 i; + PRInt32 rc; + + PR_LOG( lm, msgLevel, + ( "nameshm1: Begin BasicTest" )); + + if ( PR_FAILURE == PR_DeleteSharedMemory( optName )) { + PR_LOG( lm, msgLevel, + ("nameshm1: Initial PR_DeleteSharedMemory() failed. No problem")); + } else + PR_LOG( lm, msgLevel, + ("nameshm1: Initial PR_DeleteSharedMemory() success")); + + + shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE ); + if ( NULL == shm ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Create: success: %p", shm )); + + addr = PR_AttachSharedMemory( shm , 0 ); + if ( NULL == addr ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Attach: success: %p", addr )); + + /* fill memory with i */ + for ( i = 0; i < optSize ; i++ ) + { + *(addr + i) = i; + } + + rc = PR_DetachSharedMemory( shm, addr ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Detach: success: " )); + + rc = PR_CloseSharedMemory( shm ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Close: success: " )); + + rc = PR_DeleteSharedMemory( optName ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Delete: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RW Delete: success: " )); + + PR_LOG( lm, msgLevel, + ("nameshm1: BasicTest(): Passed")); + + return; +} /* end BasicTest() */ + +static void ReadOnlyTest( void ) +{ + PRSharedMemory *shm; + char *roAddr; /* read-only address of shared memory segment */ + PRInt32 rc; + + PR_LOG( lm, msgLevel, + ( "nameshm1: Begin ReadOnlyTest" )); + + shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE); + if ( NULL == shm ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Create: success: %p", shm )); + + + roAddr = PR_AttachSharedMemory( shm , PR_SHM_READONLY ); + if ( NULL == roAddr ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Attach: success: %p", roAddr )); + + if ( optWriteRO ) + { + *roAddr = 0x00; /* write to read-only memory */ + failed_already = 1; + PR_LOG( lm, msgLevel, ("nameshm1: Wrote to read-only memory segment!")); + return; + } + + rc = PR_DetachSharedMemory( shm, roAddr ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Detach: success: " )); + + rc = PR_CloseSharedMemory( shm ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Close: success: " )); + + rc = PR_DeleteSharedMemory( optName ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Destroy: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: RO Destroy: success: " )); + + PR_LOG( lm, msgLevel, + ("nameshm1: ReadOnlyTest(): Passed")); + + return; +} /* end ReadOnlyTest() */ + +static void DoClient( void ) +{ + PRStatus rc; + PRSem *sem1, *sem2; + PRSharedMemory *shm; + PRUint32 *addr; + PRInt32 i; + + PR_LOG( lm, msgLevel, + ("nameshm1: DoClient(): Starting")); + + sem1 = PR_OpenSemaphore( SEM_NAME1, 0, 0, 0 ); + PR_ASSERT( sem1 ); + + sem2 = PR_OpenSemaphore( SEM_NAME2, 0, 0, 0 ); + PR_ASSERT( sem1 ); + + shm = PR_OpenSharedMemory( optName, optSize, 0, SHM_MODE ); + if ( NULL == shm ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: DoClient(): Create: Error: %ld. OSError: %ld", + PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: DoClient(): Create: success: %p", shm )); + + addr = PR_AttachSharedMemory( shm , 0 ); + if ( NULL == addr ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: DoClient(): Attach: Error: %ld. OSError: %ld", + PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: DoClient(): Attach: success: %p", addr )); + + PR_LOG( lm, msgLevel, + ( "Client found: %s", addr)); + + PR_Sleep(PR_SecondsToInterval(4)); + for ( i = 0 ; i < optPing ; i++ ) + { + rc = PR_WaitSemaphore( sem2 ); + PR_ASSERT( PR_FAILURE != rc ); + + (*addr)++; + PR_ASSERT( (*addr % 2) == 0 ); + if ( optVerbose ) + PR_LOG( lm, msgLevel, + ( "nameshm1: Client ping: %d, i: %d", *addr, i)); + + rc = PR_PostSemaphore( sem1 ); + PR_ASSERT( PR_FAILURE != rc ); + } + + rc = PR_CloseSemaphore( sem1 ); + PR_ASSERT( PR_FAILURE != rc ); + + rc = PR_CloseSemaphore( sem2 ); + PR_ASSERT( PR_FAILURE != rc ); + + rc = PR_DetachSharedMemory( shm, addr ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: DoClient(): Detach: Error: %ld. OSError: %ld", + PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: DoClient(): Detach: success: " )); + + rc = PR_CloseSharedMemory( shm ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: DoClient(): Close: Error: %ld. OSError: %ld", + PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: DoClient(): Close: success: " )); + + return; +} /* end DoClient() */ + +static void ClientServerTest( void ) +{ + PRStatus rc; + PRSem *sem1, *sem2; + PRProcess *proc; + PRInt32 exit_status; + PRSharedMemory *shm; + PRUint32 *addr; + PRInt32 i; + char *child_argv[8]; + char buf[24]; + + PR_LOG( lm, msgLevel, + ( "nameshm1: Begin ClientServerTest" )); + + rc = PR_DeleteSharedMemory( optName ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Destroy: failed. No problem")); + } else + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Destroy: success" )); + + + shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE); + if ( NULL == shm ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Create: success: %p", shm )); + + addr = PR_AttachSharedMemory( shm , 0 ); + if ( NULL == addr ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Attach: success: %p", addr )); + + sem1 = PR_OpenSemaphore( SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0 ); + PR_ASSERT( sem1 ); + + sem2 = PR_OpenSemaphore( SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 1 ); + PR_ASSERT( sem1 ); + + strcpy( (char*)addr, "FooBar" ); + + child_argv[0] = EXE_NAME; + child_argv[1] = "-C"; + child_argv[2] = "-p"; + sprintf( buf, "%d", optPing ); + child_argv[3] = buf; + child_argv[4] = optName; + child_argv[5] = NULL; + + proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); + PR_ASSERT( proc ); + + PR_Sleep( PR_SecondsToInterval(4)); + + *addr = 1; + for ( i = 0 ; i < optPing ; i++ ) + { + rc = PR_WaitSemaphore( sem1 ); + PR_ASSERT( PR_FAILURE != rc ); + + (*addr)++; + PR_ASSERT( (*addr % 2) == 1 ); + if ( optVerbose ) + PR_LOG( lm, msgLevel, + ( "nameshm1: Server pong: %d, i: %d", *addr, i)); + + + rc = PR_PostSemaphore( sem2 ); + PR_ASSERT( PR_FAILURE != rc ); + } + + rc = PR_WaitProcess( proc, &exit_status ); + PR_ASSERT( PR_FAILURE != rc ); + + rc = PR_CloseSemaphore( sem1 ); + PR_ASSERT( PR_FAILURE != rc ); + + rc = PR_CloseSemaphore( sem2 ); + PR_ASSERT( PR_FAILURE != rc ); + + rc = PR_DeleteSemaphore( SEM_NAME1 ); + PR_ASSERT( PR_FAILURE != rc ); + + rc = PR_DeleteSemaphore( SEM_NAME2 ); + PR_ASSERT( PR_FAILURE != rc ); + + rc = PR_DetachSharedMemory( shm, addr ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Detach: Error: %ld. OSError: %ld", + PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Detach: success: " )); + + rc = PR_CloseSharedMemory( shm ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Close: Error: %ld. OSError: %ld", + PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Close: success: " )); + + rc = PR_DeleteSharedMemory( optName ); + if ( PR_FAILURE == rc ) + { + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Destroy: Error: %ld. OSError: %ld", + PR_GetError(), PR_GetOSError())); + failed_already = 1; + return; + } + PR_LOG( lm, msgLevel, + ( "nameshm1: Server: Destroy: success" )); + + return; +} /* end ClientServerTest() */ + +int main(int argc, char **argv) +{ + { + /* + ** Get command line options + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "Cdvw:s:p:i:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'v': /* debug mode */ + optVerbose = 1; + /* no break! fall into debug option */ + case 'd': /* debug mode */ + debug = 1; + msgLevel = PR_LOG_DEBUG; + break; + case 'w': /* try writing to memory mapped read-only */ + optWriteRO = 1; + break; + case 'C': + optClient = 1; + break; + case 's': + optSize = atol(opt->value) * 1024; + break; + case 'p': + optPing = atol(opt->value); + break; + case 'i': + optClientIterations = atol(opt->value); + break; + default: + strcpy( optName, opt->value ); + break; + } + } + PL_DestroyOptState(opt); + } + + lm = PR_NewLogModule("Test"); /* Initialize logging */ + + PR_LOG( lm, msgLevel, + ( "nameshm1: Starting" )); + + if ( optClient ) + { + DoClient(); + } else { + BasicTest(); + if ( failed_already != 0 ) + goto Finished; + ReadOnlyTest(); + if ( failed_already != 0 ) + goto Finished; + ClientServerTest(); + } + +Finished: + if ( debug ) printf("%s\n", (failed_already)? "FAIL" : "PASS" ); + return( (failed_already)? 1 : 0 ); +} /* main() */ +/* end instrumt.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/nbconn.c nspr-4.10.7/nspr/pr/tests/nbconn.c --- nspr-4.9.5/nspr/pr/tests/nbconn.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/nbconn.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,520 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * A test for nonblocking connect. Functions tested include PR_Connect, + * PR_Poll, and PR_GetConnectStatus. + * + * The test should be invoked with a host name, for example: + * nbconn www.netscape.com + * It will do a nonblocking connect to port 80 (HTTP) on that host, + * and when connected, issue the "GET /" HTTP command. + * + * You should run this test in three ways: + * 1. To a known web site, such as www.netscape.com. The HTML of the + * top-level page at the web site should be printed. + * 2. To a machine not running a web server at port 80. This test should + * fail. Ideally the error code should be PR_CONNECT_REFUSED_ERROR. + * But it is possible to return PR_UNKNOWN_ERROR on certain platforms. + * 3. To an unreachable machine, for example, a machine that is off line. + * The test should fail after the connect times out. Ideally the + * error code should be PR_IO_TIMEOUT_ERROR, but it is possible to + * return PR_UNKNOWN_ERROR on certain platforms. + */ + +#include "nspr.h" +#include "plgetopt.h" +#include +#include + +#define SERVER_MAX_BIND_COUNT 100 +#define DATA_BUF_SIZE 256 +#define TCP_SERVER_PORT 10000 +#define TCP_UNUSED_PORT 211 + +typedef struct Server_Param { + PRFileDesc *sp_fd; /* server port */ +} Server_Param; +static void PR_CALLBACK TCP_Server(void *arg); + +int _debug_on; +#define DPRINTF(arg) if (_debug_on) printf arg + +static PRIntn connection_success_test(); +static PRIntn connection_failure_test(); + +int main(int argc, char **argv) +{ + PRHostEnt he; + char buf[1024]; + PRNetAddr addr; + PRPollDesc pd; + PRStatus rv; + PRSocketOptionData optData; + const char *hostname = NULL; + PRIntn default_case, n, bytes_read, bytes_sent; + PRInt32 failed_already = 0; + + /* + * -d debug mode + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: /* debug mode */ + hostname = opt->value; + break; + case 'd': /* debug mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_STDIO_INIT(); + if (hostname) + default_case = 0; + else + default_case = 1; + + if (default_case) { + + /* + * In the default case the following tests are executed: + * 1. successful connection: a server thread accepts a connection + * from the main thread + * 2. unsuccessful connection: the main thread tries to connect to a + * nonexistent port and expects to get an error + */ + rv = connection_success_test(); + if (rv == 0) + rv = connection_failure_test(); + return rv; + } else { + PRFileDesc *sock; + + if (PR_GetHostByName(argv[1], buf, sizeof(buf), &he) == PR_FAILURE) { + printf( "Unknown host: %s\n", argv[1]); + exit(1); + } else { + printf( "host: %s\n", buf); + } + PR_EnumerateHostEnt(0, &he, 80, &addr); + + sock = PR_NewTCPSocket(); + optData.option = PR_SockOpt_Nonblocking; + optData.value.non_blocking = PR_TRUE; + PR_SetSocketOption(sock, &optData); + rv = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); + if (rv == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) { + printf( "Connect in progress\n"); + } + + pd.fd = sock; + pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; + n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (n == -1) { + printf( "PR_Poll failed\n"); + exit(1); + } + printf( "PR_Poll returns %d\n", n); + if (pd.out_flags & PR_POLL_READ) { + printf( "PR_POLL_READ\n"); + } + if (pd.out_flags & PR_POLL_WRITE) { + printf( "PR_POLL_WRITE\n"); + } + if (pd.out_flags & PR_POLL_EXCEPT) { + printf( "PR_POLL_EXCEPT\n"); + } + if (pd.out_flags & PR_POLL_ERR) { + printf( "PR_POLL_ERR\n"); + } + if (pd.out_flags & PR_POLL_NVAL) { + printf( "PR_POLL_NVAL\n"); + } + + if (PR_GetConnectStatus(&pd) == PR_SUCCESS) { + printf("PR_GetConnectStatus: connect succeeded\n"); + PR_Write(sock, "GET /\r\n\r\n", 9); + PR_Shutdown(sock, PR_SHUTDOWN_SEND); + pd.in_flags = PR_POLL_READ; + while (1) { + n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + printf( "poll returns %d\n", n); + n = PR_Read(sock, buf, sizeof(buf)); + printf( "read returns %d\n", n); + if (n <= 0) { + break; + } + PR_Write(PR_STDOUT, buf, n); + } + } else { + if (PR_GetError() == PR_IN_PROGRESS_ERROR) { + printf( "PR_GetConnectStatus: connect still in progress\n"); + exit(1); + } + printf( "PR_GetConnectStatus: connect failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + } + PR_Close(sock); + printf( "PASS\n"); + return 0; + + } +} + + +/* + * TCP Server + * Server Thread + * Accept a connection from the client and write some data + */ +static void PR_CALLBACK +TCP_Server(void *arg) +{ + Server_Param *sp = (Server_Param *) arg; + PRFileDesc *sockfd, *newsockfd; + char data_buf[DATA_BUF_SIZE]; + PRIntn rv, bytes_read; + + sockfd = sp->sp_fd; + if ((newsockfd = PR_Accept(sockfd, NULL, + PR_INTERVAL_NO_TIMEOUT)) == NULL) { + fprintf(stderr,"ERROR - PR_Accept failed: (%d,%d)\n", + PR_GetError(), PR_GetOSError()); + return; + } + bytes_read = 0; + while (bytes_read != DATA_BUF_SIZE) { + rv = PR_Read(newsockfd, data_buf + bytes_read , + DATA_BUF_SIZE - bytes_read); + if (rv < 0) { + fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + PR_Close(newsockfd); + return; + } + PR_ASSERT(rv != 0); + bytes_read += rv; + } + DPRINTF(("Bytes read from client - %d\n",bytes_read)); + rv = PR_Write(newsockfd, data_buf,DATA_BUF_SIZE); + if (rv < 0) { + fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + PR_Close(newsockfd); + return; + } + PR_ASSERT(rv == DATA_BUF_SIZE); + DPRINTF(("Bytes written to client - %d\n",rv)); + PR_Close(newsockfd); +} + + +/* + * test for successful connection using a non-blocking socket + */ +static PRIntn +connection_success_test() +{ + PRFileDesc *sockfd = NULL, *conn_fd = NULL; + PRNetAddr netaddr; + PRInt32 i, rv; + PRPollDesc pd; + PRSocketOptionData optData; + PRThread *thr = NULL; + Server_Param sp; + char send_buf[DATA_BUF_SIZE], recv_buf[DATA_BUF_SIZE]; + PRIntn default_case, n, bytes_read, bytes_sent; + PRIntn failed_already = 0; + + /* + * Create a tcp socket + */ + if ((sockfd = PR_NewTCPSocket()) == NULL) { + fprintf(stderr,"Error - PR_NewTCPSocket failed\n"); + failed_already=1; + goto def_exit; + } + memset(&netaddr, 0 , sizeof(netaddr)); + netaddr.inet.family = PR_AF_INET; + netaddr.inet.port = PR_htons(TCP_SERVER_PORT); + netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); + /* + * try a few times to bind server's address, if addresses are in + * use + */ + i = 0; + while (PR_Bind(sockfd, &netaddr) < 0) { + if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { + netaddr.inet.port += 2; + if (i++ < SERVER_MAX_BIND_COUNT) + continue; + } + fprintf(stderr,"ERROR - PR_Bind failed: (%d,%d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + + if (PR_Listen(sockfd, 32) < 0) { + fprintf(stderr,"ERROR - PR_Listen failed: (%d,%d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + + if (PR_GetSockName(sockfd, &netaddr) < 0) { + fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + if ((conn_fd = PR_NewTCPSocket()) == NULL) { + fprintf(stderr,"Error - PR_NewTCPSocket failed\n"); + failed_already=1; + goto def_exit; + } + optData.option = PR_SockOpt_Nonblocking; + optData.value.non_blocking = PR_TRUE; + PR_SetSocketOption(conn_fd, &optData); + rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT); + if (rv == PR_FAILURE) { + if (PR_GetError() == PR_IN_PROGRESS_ERROR) { + DPRINTF(("Connect in progress\n")); + } else { + fprintf(stderr,"Error - PR_Connect failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + } + /* + * Now create a thread to accept a connection + */ + sp.sp_fd = sockfd; + thr = PR_CreateThread(PR_USER_THREAD, TCP_Server, (void *)&sp, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + if (thr == NULL) { + fprintf(stderr,"Error - PR_CreateThread failed: (%d,%d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + DPRINTF(("Created TCP_Server thread [0x%x]\n",thr)); + pd.fd = conn_fd; + pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; + n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (n == -1) { + fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + if (PR_GetConnectStatus(&pd) == PR_SUCCESS) { + PRInt32 rv; + + DPRINTF(("Connection successful\n")); + + /* + * Write some data, read it back and check data integrity to + * make sure the connection is good + */ + pd.in_flags = PR_POLL_WRITE; + bytes_sent = 0; + memset(send_buf, 'a', DATA_BUF_SIZE); + while (bytes_sent != DATA_BUF_SIZE) { + rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (rv < 0) { + fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_WRITE)); + rv = PR_Write(conn_fd, send_buf + bytes_sent, + DATA_BUF_SIZE - bytes_sent); + if (rv < 0) { + fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + PR_ASSERT(rv > 0); + bytes_sent += rv; + } + DPRINTF(("Bytes written to server - %d\n",bytes_sent)); + PR_Shutdown(conn_fd, PR_SHUTDOWN_SEND); + pd.in_flags = PR_POLL_READ; + bytes_read = 0; + memset(recv_buf, 0, DATA_BUF_SIZE); + while (bytes_read != DATA_BUF_SIZE) { + rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (rv < 0) { + fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_READ)); + rv = PR_Read(conn_fd, recv_buf + bytes_read , + DATA_BUF_SIZE - bytes_read); + if (rv < 0) { + fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + PR_ASSERT(rv != 0); + bytes_read += rv; + } + DPRINTF(("Bytes read from server - %d\n",bytes_read)); + /* + * verify the data read + */ + if (memcmp(send_buf, recv_buf, DATA_BUF_SIZE) != 0) { + fprintf(stderr,"ERROR - data corruption\n"); + failed_already=1; + goto def_exit; + } + DPRINTF(("Data integrity verified\n")); + } else { + fprintf(stderr,"PR_GetConnectStatus: connect failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already = 1; + goto def_exit; + } +def_exit: + if (thr) { + PR_JoinThread(thr); + thr = NULL; + } + if (sockfd) { + PR_Close(sockfd); + sockfd = NULL; + } + if (conn_fd) { + PR_Close(conn_fd); + conn_fd = NULL; + } + if (failed_already) + return 1; + else + return 0; + +} + +/* + * test for connection to a nonexistent port using a non-blocking socket + */ +static PRIntn +connection_failure_test() +{ + PRFileDesc *sockfd = NULL, *conn_fd = NULL; + PRNetAddr netaddr; + PRInt32 i, rv; + PRPollDesc pd; + PRSocketOptionData optData; + PRIntn n, failed_already = 0; + + /* + * Create a tcp socket + */ + if ((sockfd = PR_NewTCPSocket()) == NULL) { + fprintf(stderr,"Error - PR_NewTCPSocket failed\n"); + failed_already=1; + goto def_exit; + } + memset(&netaddr, 0 , sizeof(netaddr)); + netaddr.inet.family = PR_AF_INET; + netaddr.inet.port = PR_htons(TCP_SERVER_PORT); + netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); + /* + * try a few times to bind server's address, if addresses are in + * use + */ + i = 0; + while (PR_Bind(sockfd, &netaddr) < 0) { + if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { + netaddr.inet.port += 2; + if (i++ < SERVER_MAX_BIND_COUNT) + continue; + } + fprintf(stderr,"ERROR - PR_Bind failed: (%d,%d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + + if (PR_GetSockName(sockfd, &netaddr) < 0) { + fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } +#ifdef AIX + /* + * On AIX, set to unused/reserved port + */ + netaddr.inet.port = PR_htons(TCP_UNUSED_PORT); +#endif + if ((conn_fd = PR_NewTCPSocket()) == NULL) { + fprintf(stderr,"Error - PR_NewTCPSocket failed\n"); + failed_already=1; + goto def_exit; + } + optData.option = PR_SockOpt_Nonblocking; + optData.value.non_blocking = PR_TRUE; + PR_SetSocketOption(conn_fd, &optData); + rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT); + if (rv == PR_FAILURE) { + DPRINTF(("PR_Connect to a non-listen port failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError())); + } else { + PR_ASSERT(rv == PR_SUCCESS); + fprintf(stderr,"Error - PR_Connect succeeded, expected to fail\n"); + failed_already=1; + goto def_exit; + } + pd.fd = conn_fd; + pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; + n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (n == -1) { + fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + goto def_exit; + } + if (PR_GetConnectStatus(&pd) == PR_SUCCESS) { + PRInt32 rv; + fprintf(stderr,"PR_GetConnectStatus succeeded, expected to fail\n"); + failed_already = 1; + goto def_exit; + } + rv = PR_GetError(); + DPRINTF(("Connection failed, successfully with PR_Error %d\n",rv)); +def_exit: + if (sockfd) { + PR_Close(sockfd); + sockfd = NULL; + } + if (conn_fd) { + PR_Close(conn_fd); + conn_fd = NULL; + } + if (failed_already) + return 1; + else + return 0; + +} diff -Nru nspr-4.9.5/nspr/pr/tests/nblayer.c nspr-4.10.7/nspr/pr/tests/nblayer.c --- nspr-4.9.5/nspr/pr/tests/nblayer.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/nblayer.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,675 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prmem.h" +#include "prprf.h" +#include "prlog.h" +#include "prerror.h" +#include "prnetdb.h" +#include "prthread.h" + +#include "plerror.h" +#include "plgetopt.h" +#include "prwin16.h" + +#include +#include + +/* +** Testing layering of I/O +** +** The layered server +** A thread that acts as a server. It creates a TCP listener with a dummy +** layer pushed on top. Then listens for incoming connections. Each connection +** request for connection will be layered as well, accept one request, echo +** it back and close. +** +** The layered client +** Pretty much what you'd expect. +*/ + +static PRFileDesc *logFile; +static PRDescIdentity identity; +static PRNetAddr server_address; + +static PRIOMethods myMethods; + +typedef enum {rcv_get_debit, rcv_send_credit, rcv_data} RcvState; +typedef enum {xmt_send_debit, xmt_recv_credit, xmt_data} XmtState; + +struct PRFilePrivate +{ + RcvState rcvstate; + XmtState xmtstate; + PRInt32 rcvreq, rcvinprogress; + PRInt32 xmtreq, xmtinprogress; +}; + +typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity; + +static PRIntn minor_iterations = 5; +static PRIntn major_iterations = 1; +static Verbosity verbosity = quiet; +static PRUint16 default_port = 12273; + +static PRFileDesc *PushLayer(PRFileDesc *stack) +{ + PRStatus rv; + PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods); + layer->secret = PR_NEWZAP(PRFilePrivate); + rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); + PR_ASSERT(PR_SUCCESS == rv); + if (verbosity > quiet) + PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); + return stack; +} /* PushLayer */ + +static PRFileDesc *PopLayer(PRFileDesc *stack) +{ + PRFileDesc *popped = PR_PopIOLayer(stack, identity); + if (verbosity > quiet) + PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack); + PR_DELETE(popped->secret); + popped->dtor(popped); + return stack; +} /* PopLayer */ + +static void PR_CALLBACK Client(void *arg) +{ + PRStatus rv; + PRIntn mits; + PRInt32 ready; + PRUint8 buffer[100]; + PRPollDesc polldesc; + PRIntn empty_flags = 0; + PRIntn bytes_read, bytes_sent; + PRFileDesc *stack = (PRFileDesc*)arg; + + /* Initialize the buffer so that Purify won't complain */ + memset(buffer, 0, sizeof(buffer)); + + rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT); + if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError())) + { + if (verbosity > quiet) + PR_fprintf(logFile, "Client connect 'in progress'\n"); + do + { + polldesc.fd = stack; + polldesc.out_flags = 0; + polldesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; + ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); + if ((1 != ready) /* if not 1, then we're dead */ + || (0 == (polldesc.in_flags & polldesc.out_flags))) + { PR_ASSERT(!"Whoa!"); break; } + if (verbosity > quiet) + PR_fprintf( + logFile, "Client connect 'in progress' [0x%x]\n", + polldesc.out_flags); + rv = PR_GetConnectStatus(&polldesc); + if ((PR_FAILURE == rv) + && (PR_IN_PROGRESS_ERROR != PR_GetError())) break; + } while (PR_FAILURE == rv); + } + PR_ASSERT(PR_SUCCESS == rv); + if (verbosity > chatty) + PR_fprintf(logFile, "Client created connection\n"); + + for (mits = 0; mits < minor_iterations; ++mits) + { + bytes_sent = 0; + if (verbosity > quiet) + PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer)); + do + { + if (verbosity > chatty) + PR_fprintf( + logFile, "Client sending %d bytes\n", + sizeof(buffer) - bytes_sent); + ready = PR_Send( + stack, buffer + bytes_sent, sizeof(buffer) - bytes_sent, + empty_flags, PR_INTERVAL_NO_TIMEOUT); + if (verbosity > chatty) + PR_fprintf(logFile, "Client send status [%d]\n", ready); + if (0 < ready) bytes_sent += ready; + else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) + { + polldesc.fd = stack; + polldesc.out_flags = 0; + polldesc.in_flags = PR_POLL_WRITE; + ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); + if ((1 != ready) /* if not 1, then we're dead */ + || (0 == (polldesc.in_flags & polldesc.out_flags))) + { PR_ASSERT(!"Whoa!"); break; } + } + else break; + } while (bytes_sent < sizeof(buffer)); + PR_ASSERT(sizeof(buffer) == bytes_sent); + + bytes_read = 0; + do + { + if (verbosity > chatty) + PR_fprintf( + logFile, "Client receiving %d bytes\n", + bytes_sent - bytes_read); + ready = PR_Recv( + stack, buffer + bytes_read, bytes_sent - bytes_read, + empty_flags, PR_INTERVAL_NO_TIMEOUT); + if (verbosity > chatty) + PR_fprintf( + logFile, "Client receive status [%d]\n", ready); + if (0 < ready) bytes_read += ready; + else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) + { + polldesc.fd = stack; + polldesc.out_flags = 0; + polldesc.in_flags = PR_POLL_READ; + ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); + if ((1 != ready) /* if not 1, then we're dead */ + || (0 == (polldesc.in_flags & polldesc.out_flags))) + { PR_ASSERT(!"Whoa!"); break; } + } + else break; + } while (bytes_read < bytes_sent); + if (verbosity > chatty) + PR_fprintf(logFile, "Client received %d bytes\n", bytes_read); + PR_ASSERT(bytes_read == bytes_sent); + } + + if (verbosity > quiet) + PR_fprintf(logFile, "Client shutting down stack\n"); + + rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); +} /* Client */ + +static void PR_CALLBACK Server(void *arg) +{ + PRStatus rv; + PRInt32 ready; + PRUint8 buffer[100]; + PRFileDesc *service; + PRUintn empty_flags = 0; + struct PRPollDesc polldesc; + PRIntn bytes_read, bytes_sent; + PRFileDesc *stack = (PRFileDesc*)arg; + PRNetAddr client_address; + + do + { + if (verbosity > chatty) + PR_fprintf(logFile, "Server accepting connection\n"); + service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT); + if (verbosity > chatty) + PR_fprintf(logFile, "Server accept status [0x%p]\n", service); + if ((NULL == service) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) + { + polldesc.fd = stack; + polldesc.out_flags = 0; + polldesc.in_flags = PR_POLL_READ | PR_POLL_EXCEPT; + ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); + if ((1 != ready) /* if not 1, then we're dead */ + || (0 == (polldesc.in_flags & polldesc.out_flags))) + { PR_ASSERT(!"Whoa!"); break; } + } + } while (NULL == service); + PR_ASSERT(NULL != service); + + if (verbosity > quiet) + PR_fprintf(logFile, "Server accepting connection\n"); + + do + { + bytes_read = 0; + do + { + if (verbosity > chatty) + PR_fprintf( + logFile, "Server receiving %d bytes\n", + sizeof(buffer) - bytes_read); + ready = PR_Recv( + service, buffer + bytes_read, sizeof(buffer) - bytes_read, + empty_flags, PR_INTERVAL_NO_TIMEOUT); + if (verbosity > chatty) + PR_fprintf(logFile, "Server receive status [%d]\n", ready); + if (0 < ready) bytes_read += ready; + else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) + { + polldesc.fd = service; + polldesc.out_flags = 0; + polldesc.in_flags = PR_POLL_READ; + ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); + if ((1 != ready) /* if not 1, then we're dead */ + || (0 == (polldesc.in_flags & polldesc.out_flags))) + { PR_ASSERT(!"Whoa!"); break; } + } + else break; + } while (bytes_read < sizeof(buffer)); + + if (0 != bytes_read) + { + if (verbosity > chatty) + PR_fprintf(logFile, "Server received %d bytes\n", bytes_read); + PR_ASSERT(bytes_read > 0); + + bytes_sent = 0; + do + { + ready = PR_Send( + service, buffer + bytes_sent, bytes_read - bytes_sent, + empty_flags, PR_INTERVAL_NO_TIMEOUT); + if (0 < ready) + { + bytes_sent += ready; + } + else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) + { + polldesc.fd = service; + polldesc.out_flags = 0; + polldesc.in_flags = PR_POLL_WRITE; + ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT); + if ((1 != ready) /* if not 1, then we're dead */ + || (0 == (polldesc.in_flags & polldesc.out_flags))) + { PR_ASSERT(!"Whoa!"); break; } + } + else break; + } while (bytes_sent < bytes_read); + PR_ASSERT(bytes_read == bytes_sent); + if (verbosity > chatty) + PR_fprintf(logFile, "Server sent %d bytes\n", bytes_sent); + } + } while (0 != bytes_read); + + if (verbosity > quiet) + PR_fprintf(logFile, "Server shutting down stack\n"); + rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); + +} /* Server */ + +static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd) +{ + PR_DELETE(fd->secret); /* manage my secret file object */ + return (PR_GetDefaultIOMethods())->close(fd); /* let him do all the work */ +} /* MyClose */ + +static PRInt16 PR_CALLBACK MyPoll( + PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) +{ + PRInt16 my_flags, new_flags; + PRFilePrivate *mine = (PRFilePrivate*)fd->secret; + if (0 != (PR_POLL_READ & in_flags)) + { + /* client thinks he's reading */ + switch (mine->rcvstate) + { + case rcv_send_credit: + my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE; + break; + case rcv_data: + case rcv_get_debit: + my_flags = in_flags; + default: break; + } + } + else if (0 != (PR_POLL_WRITE & in_flags)) + { + /* client thinks he's writing */ + switch (mine->xmtstate) + { + case xmt_recv_credit: + my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ; + break; + case xmt_send_debit: + case xmt_data: + my_flags = in_flags; + default: break; + } + } + else PR_ASSERT(!"How'd I get here?"); + new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags); + if (verbosity > chatty) + PR_fprintf( + logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n", + in_flags, my_flags, *out_flags, new_flags); + return new_flags; +} /* MyPoll */ + +static PRFileDesc * PR_CALLBACK MyAccept( + PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout) +{ + PRStatus rv; + PRFileDesc *newfd, *layer = fd; + PRFileDesc *newstack; + PRFilePrivate *newsecret; + + PR_ASSERT(fd != NULL); + PR_ASSERT(fd->lower != NULL); + + newstack = PR_NEW(PRFileDesc); + if (NULL == newstack) + { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + newsecret = PR_NEW(PRFilePrivate); + if (NULL == newsecret) + { + PR_DELETE(newstack); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + *newstack = *fd; /* make a copy of the accepting layer */ + *newsecret = *fd->secret; + newstack->secret = newsecret; + + newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout); + if (NULL == newfd) + { + PR_DELETE(newsecret); + PR_DELETE(newstack); + return NULL; + } + + /* this PR_PushIOLayer call cannot fail */ + rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); + PR_ASSERT(PR_SUCCESS == rv); + return newfd; /* that's it */ +} + +static PRInt32 PR_CALLBACK MyRecv( + PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + char *b; + PRInt32 rv; + PRFileDesc *lo = fd->lower; + PRFilePrivate *mine = (PRFilePrivate*)fd->secret; + + do + { + switch (mine->rcvstate) + { + case rcv_get_debit: + b = (char*)&mine->rcvreq; + mine->rcvreq = amount; + rv = lo->methods->recv( + lo, b + mine->rcvinprogress, + sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout); + if (0 == rv) goto closed; + if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; + mine->rcvinprogress += rv; /* accumulate the read */ + if (mine->rcvinprogress < sizeof(mine->rcvreq)) break; /* loop */ + mine->rcvstate = rcv_send_credit; + mine->rcvinprogress = 0; + case rcv_send_credit: + b = (char*)&mine->rcvreq; + rv = lo->methods->send( + lo, b + mine->rcvinprogress, + sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout); + if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; + mine->rcvinprogress += rv; /* accumulate the read */ + if (mine->rcvinprogress < sizeof(mine->rcvreq)) break; /* loop */ + mine->rcvstate = rcv_data; + mine->rcvinprogress = 0; + case rcv_data: + b = (char*)buf; + rv = lo->methods->recv( + lo, b + mine->rcvinprogress, + mine->rcvreq - mine->rcvinprogress, flags, timeout); + if (0 == rv) goto closed; + if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; + mine->rcvinprogress += rv; /* accumulate the read */ + if (mine->rcvinprogress < amount) break; /* loop */ + mine->rcvstate = rcv_get_debit; + mine->rcvinprogress = 0; + return mine->rcvreq; /* << -- that's it! */ + default: + break; + } + } while (-1 != rv); + return rv; +closed: + mine->rcvinprogress = 0; + mine->rcvstate = rcv_get_debit; + return 0; +} /* MyRecv */ + +static PRInt32 PR_CALLBACK MySend( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + char *b; + PRInt32 rv; + PRFileDesc *lo = fd->lower; + PRFilePrivate *mine = (PRFilePrivate*)fd->secret; + + do + { + switch (mine->xmtstate) + { + case xmt_send_debit: + b = (char*)&mine->xmtreq; + mine->xmtreq = amount; + rv = lo->methods->send( + lo, b - mine->xmtinprogress, + sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout); + if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; + mine->xmtinprogress += rv; + if (mine->xmtinprogress < sizeof(mine->xmtreq)) break; + mine->xmtstate = xmt_recv_credit; + mine->xmtinprogress = 0; + case xmt_recv_credit: + b = (char*)&mine->xmtreq; + rv = lo->methods->recv( + lo, b + mine->xmtinprogress, + sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout); + if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; + mine->xmtinprogress += rv; + if (mine->xmtinprogress < sizeof(mine->xmtreq)) break; + mine->xmtstate = xmt_data; + mine->xmtinprogress = 0; + case xmt_data: + b = (char*)buf; + rv = lo->methods->send( + lo, b + mine->xmtinprogress, + mine->xmtreq - mine->xmtinprogress, flags, timeout); + if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break; + mine->xmtinprogress += rv; + if (mine->xmtinprogress < amount) break; + mine->xmtstate = xmt_send_debit; + mine->xmtinprogress = 0; + return mine->xmtreq; /* <<-- That's the one! */ + default: + break; + } + } while (-1 != rv); + return rv; +} /* MySend */ + +static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta) +{ + PRIntn verbage = (PRIntn)verbosity + delta; + if (verbage < (PRIntn)silent) verbage = (PRIntn)silent; + else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy; + return (Verbosity)verbage; +} /* ChangeVerbosity */ + +int main(int argc, char **argv) +{ + PRStatus rv; + PLOptStatus os; + PRFileDesc *client, *service; + PRNetAddr any_address; + const char *server_name = NULL; + const PRIOMethods *stubMethods; + PRThread *client_thread, *server_thread; + PRThreadScope thread_scope = PR_LOCAL_THREAD; + PRSocketOptionData socket_noblock, socket_nodelay; + PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: + server_name = opt->value; + break; + case 'd': /* debug mode */ + if (verbosity < noisy) + verbosity = ChangeVerbosity(verbosity, 1); + break; + case 'q': /* debug mode */ + if (verbosity > silent) + verbosity = ChangeVerbosity(verbosity, -1); + break; + case 'G': /* use global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'C': /* number of threads waiting */ + major_iterations = atoi(opt->value); + break; + case 'c': /* number of client threads */ + minor_iterations = atoi(opt->value); + break; + case 'p': /* default port */ + default_port = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + PR_STDIO_INIT(); + + logFile = PR_GetSpecialFD(PR_StandardError); + identity = PR_GetUniqueIdentity("Dummy"); + stubMethods = PR_GetDefaultIOMethods(); + + /* + ** The protocol we're going to implement is one where in order to initiate + ** a send, the sender must first solicit permission. Therefore, every + ** send is really a send - receive - send sequence. + */ + myMethods = *stubMethods; /* first get the entire batch */ + myMethods.accept = MyAccept; /* then override the ones we care about */ + myMethods.recv = MyRecv; /* then override the ones we care about */ + myMethods.send = MySend; /* then override the ones we care about */ + myMethods.close = MyClose; /* then override the ones we care about */ + myMethods.poll = MyPoll; /* then override the ones we care about */ + + if (NULL == server_name) + rv = PR_InitializeNetAddr( + PR_IpAddrLoopback, default_port, &server_address); + else + { + rv = PR_StringToNetAddr(server_name, &server_address); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_InitializeNetAddr( + PR_IpAddrNull, default_port, &server_address); + } + PR_ASSERT(PR_SUCCESS == rv); + + socket_noblock.value.non_blocking = PR_TRUE; + socket_noblock.option = PR_SockOpt_Nonblocking; + socket_nodelay.value.no_delay = PR_TRUE; + socket_nodelay.option = PR_SockOpt_NoDelay; + + /* one type w/o layering */ + + while (major_iterations-- > 0) + { + if (verbosity > silent) + PR_fprintf(logFile, "Beginning non-layered test\n"); + + client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); + service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); + + rv = PR_SetSocketOption(client, &socket_noblock); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_SetSocketOption(service, &socket_noblock); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_SetSocketOption(client, &socket_nodelay); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_SetSocketOption(service, &socket_nodelay); + PR_ASSERT(PR_SUCCESS == rv); + + rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); + + server_thread = PR_CreateThread( + PR_USER_THREAD, Server, service, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != server_thread); + + client_thread = PR_CreateThread( + PR_USER_THREAD, Client, client, + PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != client_thread); + + rv = PR_JoinThread(client_thread); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(server_thread); + PR_ASSERT(PR_SUCCESS == rv); + + rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); + if (verbosity > silent) + PR_fprintf(logFile, "Ending non-layered test\n"); + + /* with layering */ + if (verbosity > silent) + PR_fprintf(logFile, "Beginning layered test\n"); + client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); + service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); + + rv = PR_SetSocketOption(client, &socket_noblock); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_SetSocketOption(service, &socket_noblock); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_SetSocketOption(client, &socket_nodelay); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_SetSocketOption(service, &socket_nodelay); + PR_ASSERT(PR_SUCCESS == rv); + + PushLayer(client); + PushLayer(service); + + rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); + + server_thread = PR_CreateThread( + PR_USER_THREAD, Server, service, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != server_thread); + + client_thread = PR_CreateThread( + PR_USER_THREAD, Client, client, + PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 16 * 1024); + PR_ASSERT(NULL != client_thread); + + rv = PR_JoinThread(client_thread); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_JoinThread(server_thread); + PR_ASSERT(PR_SUCCESS == rv); + + rv = PR_Close(PopLayer(client)); PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Close(PopLayer(service)); PR_ASSERT(PR_SUCCESS == rv); + if (verbosity > silent) + PR_fprintf(logFile, "Ending layered test\n"); + } + return 0; +} /* main */ + +/* nblayer.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/nonblock.c nspr-4.10.7/nspr/pr/tests/nonblock.c --- nspr-4.9.5/nspr/pr/tests/nonblock.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/nonblock.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,225 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "prio.h" +#include "prerror.h" +#include "prlog.h" +#include "prprf.h" +#include "prnetdb.h" +#include "plerror.h" +#include "obsolete/probslet.h" + +#include +#include +#include + +#define NUMBER_ROUNDS 5 + +#if defined(WIN16) +/* +** Make win16 unit_time interval 300 milliseconds, others get 100 +*/ +#define UNIT_TIME 200 /* unit time in milliseconds */ +#elif defined(SYMBIAN) +#define UNIT_TIME 5000 /* unit time in milliseconds */ +#else +#define UNIT_TIME 100 /* unit time in milliseconds */ +#endif +#define CHUNK_SIZE 10 +#undef USE_PR_SELECT /* If defined, we use PR_Select. + * If not defined, use PR_Poll instead. */ + +#if defined(USE_PR_SELECT) +#include "pprio.h" +#endif + +static void PR_CALLBACK +clientThreadFunc(void *arg) +{ + PRUintn port = (PRUintn)arg; + PRFileDesc *sock; + PRNetAddr addr; + char buf[CHUNK_SIZE]; + int i; + PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME); + PRSocketOptionData optval; + PRStatus retVal; + PRInt32 nBytes; + + /* Initialize the buffer so that Purify won't complain */ + memset(buf, 0, sizeof(buf)); + + addr.inet.family = PR_AF_INET; + addr.inet.port = PR_htons((PRUint16)port); + addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip); + + /* time 1 */ + PR_Sleep(unitTime); + sock = PR_NewTCPSocket(); + optval.option = PR_SockOpt_Nonblocking; + optval.value.non_blocking = PR_TRUE; + PR_SetSocketOption(sock, &optval); + retVal = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); + if (retVal == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) { +#if !defined(USE_PR_SELECT) + PRPollDesc pd; + PRInt32 n; + fprintf(stderr, "connect: EWOULDBLOCK, good\n"); + pd.fd = sock; + pd.in_flags = PR_POLL_WRITE; + n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(n == 1); + PR_ASSERT(pd.out_flags == PR_POLL_WRITE); +#else + PR_fd_set writeSet; + PRInt32 n; + fprintf(stderr, "connect: EWOULDBLOCK, good\n"); + PR_FD_ZERO(&writeSet); + PR_FD_SET(sock, &writeSet); + n = PR_Select(0, NULL, &writeSet, NULL, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(n == 1); + PR_ASSERT(PR_FD_ISSET(sock, &writeSet)); +#endif + } + printf("client connected\n"); + fflush(stdout); + + /* time 4, 7, 11, etc. */ + for (i = 0; i < NUMBER_ROUNDS; i++) { + PR_Sleep(3 * unitTime); + nBytes = PR_Write(sock, buf, sizeof(buf)); + if (nBytes == -1) { + if (PR_GetError() == PR_WOULD_BLOCK_ERROR) { + fprintf(stderr, "write: EWOULDBLOCK\n"); + exit(1); + } else { + fprintf(stderr, "write: failed\n"); + } + } + printf("client sent %d bytes\n", nBytes); + fflush(stdout); + } + + PR_Close(sock); +} + +static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) +{ + PRFileDesc *listenSock, *sock; + PRUint16 listenPort; + PRNetAddr addr; + char buf[CHUNK_SIZE]; + PRThread *clientThread; + PRInt32 retVal; + PRSocketOptionData optval; + PRIntn i; + PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME); + + /* Create a listening socket */ + if ((listenSock = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + exit(1); + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + exit(1); + } + if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + exit(1); + } + listenPort = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + exit(1); + } + + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on port %hu\n\n", + listenPort); + printf("%s", buf); + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + exit(1); + } + + printf("client thread created.\n"); + + optval.option = PR_SockOpt_Nonblocking; + optval.value.non_blocking = PR_TRUE; + PR_SetSocketOption(listenSock, &optval); + /* time 0 */ + sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (sock != NULL || PR_GetError() != PR_WOULD_BLOCK_ERROR) { + PL_PrintError("First Accept\n"); + fprintf(stderr, "First PR_Accept() xxx\n" ); + exit(1); + } + printf("accept: EWOULDBLOCK, good\n"); + fflush(stdout); + /* time 2 */ + PR_Sleep(2 * unitTime); + sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (sock == NULL) { + PL_PrintError("Second Accept\n"); + fprintf(stderr, "Second PR_Accept() failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + printf("accept: succeeded, good\n"); + fflush(stdout); + PR_Close(listenSock); + + PR_SetSocketOption(sock, &optval); + + /* time 3, 5, 6, 8, etc. */ + for (i = 0; i < NUMBER_ROUNDS; i++) { + PR_Sleep(unitTime); + retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); + if (retVal != -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR) { + PL_PrintError("First Receive:\n"); + fprintf(stderr, "First PR_Recv: retVal: %ld, Error: %ld\n", + retVal, PR_GetError()); + exit(1); + } + printf("read: EWOULDBLOCK, good\n"); + fflush(stdout); + PR_Sleep(2 * unitTime); + retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); + if (retVal != CHUNK_SIZE) { + PL_PrintError("Second Receive:\n"); + fprintf(stderr, "Second PR_Recv: retVal: %ld, Error: %ld\n", + retVal, PR_GetError()); + exit(1); + } + printf("read: %d bytes, good\n", retVal); + fflush(stdout); + } + PR_Close(sock); + + printf("All tests finished\n"); + printf("PASS\n"); + return 0; +} + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ + diff -Nru nspr-4.9.5/nspr/pr/tests/ntioto.c nspr-4.10.7/nspr/pr/tests/ntioto.c --- nspr-4.9.5/nspr/pr/tests/ntioto.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/ntioto.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,286 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: ntioto.c +** Description: +** This test, ntioto.c, was designed to reproduce a bug reported by NES +** on WindowsNT (fibers implementation). NSPR was asserting in ntio.c +** after PR_AcceptRead() had timed out. I/O performed subsequent to the +** call to PR_AcceptRead() could complete on a CPU other than the one +** on which it was started. The assert in ntio.c detected this, then +** asserted. +** +** Design: +** This test will fail with an assert in ntio.c if the problem it was +** designed to catch occurs. It returns 0 otherwise. +** +** The main() thread initializes and tears things down. A file is +** opened for writing; this file will be written to by AcceptThread() +** and JitterThread(). Main() creates a socket for reading, listens +** and binds the socket. +** +** ConnectThread() connects to the socket created by main, then polls +** the "state" variable. When state is AllDone, ConnectThread() exits. +** +** AcceptThread() calls PR_AcceptRead() on the socket. He fully expects +** it to time out. After the timeout, AccpetThread() interacts with +** JitterThread() via a common condition variable and the state +** variable. The two threads ping-pong back and forth, each thread +** writes the the file opened by main. This should provoke the +** condition reported by NES (if we didn't fix it). +** +** The failure is not solid. It may fail within a few ping-pongs between +** AcceptThread() and JitterThread() or may take a while. The default +** iteration count, jitter, is set by DEFAULT_JITTER. This may be +** modified at the command line with the -j option. +** +*/ + +#include +#include +#include +#include +#include + +/* +** Test harness infrastructure +*/ +PRLogModuleInfo *lm; +PRLogModuleLevel msgLevel = PR_LOG_NONE; +PRIntn debug = 0; +PRIntn verbose = 0; +PRUint32 failed_already = 0; +/* end Test harness infrastructure */ + +/* JITTER_DEFAULT: the number of times AcceptThread() and JitterThread() ping-pong */ +#define JITTER_DEFAULT 100000 +#define BASE_PORT 9867 + +PRIntervalTime timeout; +PRNetAddr listenAddr; +PRFileDesc *listenSock; +PRLock *ml; +PRCondVar *cv; +volatile enum { + RunJitter, + RunAcceptRead, + AllDone +} state = RunAcceptRead; +PRFileDesc *file1; +PRIntn iCounter = 0; +PRIntn jitter = JITTER_DEFAULT; +PRBool resume = PR_FALSE; + +/* +** Emit help text for this test +*/ +static void Help( void ) +{ + printf("Template: Help(): display your help message(s) here"); + exit(1); +} /* end Help() */ + + +/* +** static computation of PR_AcceptRead() buffer size. +*/ +#define ACCEPT_READ_DATASIZE 10 +#define ACCEPT_READ_BUFSIZE (PR_ACCEPT_READ_BUF_OVERHEAD + ACCEPT_READ_DATASIZE) + +static void AcceptThread(void *arg) +{ + PRIntn bytesRead; + char dataBuf[ACCEPT_READ_BUFSIZE]; + PRFileDesc *arSock; + PRNetAddr *arAddr; + + bytesRead = PR_AcceptRead( listenSock, + &arSock, + &arAddr, + dataBuf, + ACCEPT_READ_DATASIZE, + PR_SecondsToInterval(1)); + + if ( bytesRead == -1 && PR_GetError() == PR_IO_TIMEOUT_ERROR ) { + if ( debug ) printf("AcceptRead timed out\n"); + } else { + if ( debug ) printf("Oops! read: %d, error: %d\n", bytesRead, PR_GetError()); + } + + while( state != AllDone ) { + PR_Lock( ml ); + while( state != RunAcceptRead ) + PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT ); + if ( ++iCounter >= jitter ) + state = AllDone; + else + state = RunJitter; + if ( verbose ) printf("."); + PR_NotifyCondVar( cv ); + PR_Unlock( ml ); + PR_Write( file1, ".", 1 ); + } + + return; +} /* end AcceptThread() */ + +static void JitterThread(void *arg) +{ + while( state != AllDone ) { + PR_Lock( ml ); + while( state != RunJitter && state != AllDone ) + PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT ); + if ( state != AllDone) + state = RunAcceptRead; + if ( verbose ) printf("+"); + PR_NotifyCondVar( cv ); + PR_Unlock( ml ); + PR_Write( file1, "+", 1 ); + } + return; +} /* end Goofy() */ + +static void ConnectThread( void *arg ) +{ + PRStatus rv; + PRFileDesc *clientSock; + PRNetAddr serverAddress; + clientSock = PR_NewTCPSocket(); + + PR_ASSERT(clientSock); + + if ( resume ) { + if ( debug ) printf("pausing 3 seconds before connect\n"); + PR_Sleep( PR_SecondsToInterval(3)); + } + + memset(&serverAddress, 0, sizeof(serverAddress)); + rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddress); + PR_ASSERT( PR_SUCCESS == rv ); + rv = PR_Connect( clientSock, + &serverAddress, + PR_SecondsToInterval(1)); + PR_ASSERT( PR_SUCCESS == rv ); + + /* that's all we do. ... Wait for the acceptread() to timeout */ + while( state != AllDone ) + PR_Sleep( PR_SecondsToInterval(1)); + return; +} /* end ConnectThread() */ + + +int main(int argc, char **argv) +{ + PRThread *tJitter; + PRThread *tAccept; + PRThread *tConnect; + PRStatus rv; + /* This test if valid for WinNT only! */ + +#if !defined(WINNT) + return 0; +#endif + + { + /* + ** Get command line options + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "hdrvj:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug */ + debug = 1; + msgLevel = PR_LOG_ERROR; + break; + case 'v': /* verbose mode */ + verbose = 1; + msgLevel = PR_LOG_DEBUG; + break; + case 'j': + jitter = atoi(opt->value); + if ( jitter == 0) + jitter = JITTER_DEFAULT; + break; + case 'r': + resume = PR_TRUE; + break; + case 'h': /* help message */ + Help(); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } + + lm = PR_NewLogModule("Test"); /* Initialize logging */ + + /* set concurrency */ + PR_SetConcurrency( 4 ); + + /* setup thread synchronization mechanics */ + ml = PR_NewLock(); + cv = PR_NewCondVar( ml ); + + /* setup a tcp socket */ + memset(&listenAddr, 0, sizeof(listenAddr)); + rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr); + PR_ASSERT( PR_SUCCESS == rv ); + + listenSock = PR_NewTCPSocket(); + PR_ASSERT( listenSock ); + + rv = PR_Bind( listenSock, &listenAddr); + PR_ASSERT( PR_SUCCESS == rv ); + + rv = PR_Listen( listenSock, 5 ); + PR_ASSERT( PR_SUCCESS == rv ); + + /* open a file for writing, provoke bug */ + file1 = PR_Open("xxxTestFile", PR_CREATE_FILE | PR_RDWR, 666); + + /* create Connect thread */ + tConnect = PR_CreateThread( + PR_USER_THREAD, ConnectThread, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, 0 ); + PR_ASSERT( tConnect ); + + /* create jitter off thread */ + tJitter = PR_CreateThread( + PR_USER_THREAD, JitterThread, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, 0 ); + PR_ASSERT( tJitter ); + + /* create acceptread thread */ + tAccept = PR_CreateThread( + PR_USER_THREAD, AcceptThread, NULL, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, 0 ); + PR_ASSERT( tAccept ); + + /* wait for all threads to quit, then terminate gracefully */ + PR_JoinThread( tConnect ); + PR_JoinThread( tAccept ); + PR_JoinThread( tJitter ); + PR_Close( listenSock ); + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); + PR_Close( file1 ); + PR_Delete( "xxxTestFile"); + + /* test return and exit */ + if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); + return( (failed_already == PR_TRUE )? 1 : 0 ); +} /* main() */ +/* end ntioto.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/ntoh.c nspr-4.10.7/nspr/pr/tests/ntoh.c --- nspr-4.9.5/nspr/pr/tests/ntoh.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/ntoh.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * A test program for PR_htons, PR_ntohs, PR_htonl, PR_ntohl, + * PR_htonll, and PR_ntohll. + */ + +#include "prnetdb.h" + +#include +#include +#include + +/* Byte sequence in network byte order */ +static unsigned char bytes_n[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + +/* Integers in host byte order */ +static PRUint16 s_h = 0x0102; +static PRUint32 l_h = 0x01020304; +static PRUint64 ll_h = LL_INIT(0x01020304, 0x05060708); + +int main(int argc, char **argv) +{ + union { + PRUint16 s; + PRUint32 l; + PRUint64 ll; + unsigned char bytes[8]; + } un; + + un.s = s_h; + printf("%u %u\n", + un.bytes[0], un.bytes[1]); + un.s = PR_htons(un.s); + printf("%u %u\n", + un.bytes[0], un.bytes[1]); + if (memcmp(un.bytes, bytes_n, 2)) { + fprintf(stderr, "PR_htons failed\n"); + exit(1); + } + un.s = PR_ntohs(un.s); + printf("%u %u\n", + un.bytes[0], un.bytes[1]); + if (un.s != s_h) { + fprintf(stderr, "PR_ntohs failed\n"); + exit(1); + } + + un.l = l_h; + printf("%u %u %u %u\n", + un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]); + un.l = PR_htonl(un.l); + printf("%u %u %u %u\n", + un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]); + if (memcmp(un.bytes, bytes_n, 4)) { + fprintf(stderr, "PR_htonl failed\n"); + exit(1); + } + un.l = PR_ntohl(un.l); + printf("%u %u %u %u\n", + un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]); + if (un.l != l_h) { + fprintf(stderr, "PR_ntohl failed\n"); + exit(1); + } + + un.ll = ll_h; + printf("%u %u %u %u %u %u %u %u\n", + un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3], + un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]); + un.ll = PR_htonll(un.ll); + printf("%u %u %u %u %u %u %u %u\n", + un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3], + un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]); + if (memcmp(un.bytes, bytes_n, 8)) { + fprintf(stderr, "PR_htonll failed\n"); + exit(1); + } + un.ll = PR_ntohll(un.ll); + printf("%u %u %u %u %u %u %u %u\n", + un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3], + un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]); + if (LL_NE(un.ll, ll_h)) { + fprintf(stderr, "PR_ntohll failed\n"); + exit(1); + } + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/obsints.c nspr-4.10.7/nspr/pr/tests/obsints.c --- nspr-4.9.5/nspr/pr/tests/obsints.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/obsints.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test: obsints.c + * + * Description: make sure that protypes.h defines the obsolete integer + * types intn, uintn, uint, int8, uint8, int16, uint16, int32, uint32, + * int64, and uint64. + */ + +#include + +#ifdef NO_NSPR_10_SUPPORT + +/* nothing to do */ +int main(int argc, char **argv) +{ + printf("PASS\n"); + return 0; +} + +#else /* NO_NSPR_10_SUPPORT */ + +#include "prtypes.h" /* which includes protypes.h */ + +int main(int argc, char **argv) +{ + /* + * Compilation fails if any of these integer types are not + * defined by protypes.h. + */ + intn in; + uintn uin; + uint ui; + int8 i8; + uint8 ui8; + int16 i16; + uint16 ui16; + int32 i32; + uint32 ui32; + int64 i64; + uint64 ui64; + + printf("PASS\n"); + return 0; +} + +#endif /* NO_NSPR_10_SUPPORT */ diff -Nru nspr-4.9.5/nspr/pr/tests/op_2long.c nspr-4.10.7/nspr/pr/tests/op_2long.c --- nspr-4.9.5/nspr/pr/tests/op_2long.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/op_2long.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: op_2long.c +** +** Description: Test Program to verify the PR_NAME_TOO_LONG_ERROR +** +** Modification History: +** 03-June-97 AGarcia- Initial version +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "prinit.h" +#include "prmem.h" +#include "prio.h" +#include "prerror.h" +#include +#include "plerror.h" +#include "plgetopt.h" + +static PRFileDesc *t1; +PRIntn error_code; + +/* + * should exceed any system's maximum file name length + * Note: was set at 4096. This is legal on some unix (Linux 2.1+) platforms. + * + */ +#define TOO_LONG 5000 + +int main(int argc, char **argv) +{ + char nameTooLong[TOO_LONG]; + int i; + + /* Generate a really long pathname */ + for (i = 0; i < TOO_LONG - 1; i++) { + if (i % 10 == 0) { + nameTooLong[i] = '/'; + } else { + nameTooLong[i] = 'a'; + } + } + nameTooLong[TOO_LONG - 1] = 0; + + PR_STDIO_INIT(); + t1 = PR_Open(nameTooLong, PR_RDWR, 0666); + if (t1 == NULL) { + if (PR_GetError() == PR_NAME_TOO_LONG_ERROR) { + PL_PrintError("error code is"); + printf ("PASS\n"); + return 0; + } + else { + PL_PrintError("error code is"); + printf ("FAIL\n"); + return 1; + } + } + + else { + printf ("Test passed\n"); + return 0; + } + + + +} diff -Nru nspr-4.9.5/nspr/pr/tests/openfile.c nspr-4.10.7/nspr/pr/tests/openfile.c --- nspr-4.9.5/nspr/pr/tests/openfile.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/openfile.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This test calls PR_OpenFile to create a bunch of files + * with various file modes. + */ + +#include "prio.h" +#include "prerror.h" +#include "prinit.h" + +#include +#include + +#define TEMPLATE_FILE_NAME "template.txt" + +int main(int argc, char **argv) +{ + FILE *template; + char buf[32]; + PRInt32 nbytes; + PRFileDesc *fd; + + + /* Write in text mode. Let stdio deal with line endings. */ + template = fopen(TEMPLATE_FILE_NAME, "w"); + fputs("line 1\nline 2\n", template); + fclose(template); + + /* Read in binary mode */ + fd = PR_OpenFile(TEMPLATE_FILE_NAME, PR_RDONLY, 0666); + nbytes = PR_Read(fd, buf, sizeof(buf)); + PR_Close(fd); + PR_Delete(TEMPLATE_FILE_NAME); + + fd = PR_OpenFile("tfil0700.txt", PR_RDWR | PR_CREATE_FILE, 0700); + if (NULL == fd) { + fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + PR_Write(fd, buf, nbytes); + PR_Close(fd); + + fd = PR_OpenFile("tfil0500.txt", PR_RDWR | PR_CREATE_FILE, 0500); + if (NULL == fd) { + fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + PR_Write(fd, buf, nbytes); + PR_Close(fd); + + fd = PR_OpenFile("tfil0400.txt", PR_RDWR | PR_CREATE_FILE, 0400); + if (NULL == fd) { + fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + PR_Write(fd, buf, nbytes); + PR_Close(fd); + + fd = PR_OpenFile("tfil0644.txt", PR_RDWR | PR_CREATE_FILE, 0644); + if (NULL == fd) { + fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + PR_Write(fd, buf, nbytes); + PR_Close(fd); + + fd = PR_OpenFile("tfil0664.txt", PR_RDWR | PR_CREATE_FILE, 0664); + if (NULL == fd) { + fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + PR_Write(fd, buf, nbytes); + PR_Close(fd); + + fd = PR_OpenFile("tfil0660.txt", PR_RDWR | PR_CREATE_FILE, 0660); + if (NULL == fd) { + fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + PR_Write(fd, buf, nbytes); + PR_Close(fd); + + fd = PR_OpenFile("tfil0666.txt", PR_RDWR | PR_CREATE_FILE, 0666); + if (NULL == fd) { + fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + PR_Write(fd, buf, nbytes); + PR_Close(fd); + + fd = PR_OpenFile("tfil0640.txt", PR_RDWR | PR_CREATE_FILE, 0640); + if (NULL == fd) { + fprintf(stderr, "PR_OpenFile failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + PR_Write(fd, buf, nbytes); + PR_Close(fd); + + PR_Cleanup(); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/op_excl.c nspr-4.10.7/nspr/pr/tests/op_excl.c --- nspr-4.9.5/nspr/pr/tests/op_excl.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/op_excl.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: op_excl.c +** +** Description: Test Program to verify function of PR_EXCL open flag +** +** Modification History: +** 27-Oct-1999 lth. Initial version +***********************************************************************/ + +#include +#include +#include +#include + +/* +** Test harness infrastructure +*/ +PRLogModuleInfo *lm; +PRLogModuleLevel msgLevel = PR_LOG_NONE; +PRIntn debug = 0; +PRUint32 failed_already = 0; +/* end Test harness infrastructure */ +/* +** Emit help text for this test +*/ +static void Help( void ) +{ + printf("op_excl: Help"); + printf("op_excl [-d]"); + printf("-d enables debug messages"); + exit(1); +} /* end Help() */ + + + +int main(int argc, char **argv) +{ + PRFileDesc *fd; + PRStatus rv; + PRInt32 written; + char outBuf[] = "op_excl.c test file"; +#define OUT_SIZE sizeof(outBuf) +#define NEW_FILENAME "xxxExclNewFile" + + { + /* + ** Get command line options + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "hd"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug */ + debug = 1; + msgLevel = PR_LOG_ERROR; + break; + case 'h': /* help message */ + Help(); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } + + lm = PR_NewLogModule("Test"); /* Initialize logging */ + + /* + ** First, open a file, PR_EXCL, we believe not to exist + */ + fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 ); + if ( NULL == fd ) { + if (debug) fprintf( stderr, "Open exclusive. Expected success, got failure\n"); + failed_already = 1; + goto Finished; + } + + written = PR_Write( fd, outBuf, OUT_SIZE ); + if ( OUT_SIZE != written ) { + if (debug) fprintf( stderr, "Write after open exclusive failed\n"); + failed_already = 1; + goto Finished; + } + + rv = PR_Close(fd); + if ( PR_FAILURE == rv ) { + if (debug) fprintf( stderr, "Close after open exclusive failed\n"); + failed_already = 1; + goto Finished; + } + + /* + ** Second, open the same file, PR_EXCL, expect it to fail + */ + fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 ); + if ( NULL != fd ) { + if (debug) fprintf( stderr, "Open exclusive. Expected failure, got success\n"); + failed_already = 1; + PR_Close(fd); + } + + rv = PR_Delete( NEW_FILENAME ); + if ( PR_FAILURE == rv ) { + if (debug) fprintf( stderr, "PR_Delete() failed\n"); + failed_already = 1; + } + +Finished: + if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); + return( (failed_already == PR_TRUE )? 1 : 0 ); +} /* main() */ +/* end op_excl.c */ + diff -Nru nspr-4.9.5/nspr/pr/tests/op_filnf.c nspr-4.10.7/nspr/pr/tests/op_filnf.c --- nspr-4.9.5/nspr/pr/tests/op_filnf.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/op_filnf.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: op_filnf.c +** +** Description: Test Program to verify the PR_FILE_NOT_FOUND_ERROR +** This test program also uses the TRUNCATE option +** +** Modification History: +** 03-June-97 AGarcia- Initial version +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "prinit.h" +#include "prmem.h" +#include "prio.h" +#include "prerror.h" +#include +#include "plgetopt.h" + +static PRFileDesc *t1; +PRIntn error_code; + +int main(int argc, char **argv) +{ + PR_STDIO_INIT(); + t1 = PR_Open("/usr/tmp/ttools/err03.tmp", PR_TRUNCATE | PR_RDWR, 0666); + if (t1 == NULL) { + if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) { + printf ("error code is %d \n", PR_GetError()); + printf ("PASS\n"); + return 0; + } + else { + printf ("error code is %d \n", PR_GetError()); + printf ("FAIL\n"); + return 1; + } + } + PR_Close(t1); + printf ("opened a file that should not exist\n"); + printf ("FAIL\n"); + return 1; +} diff -Nru nspr-4.9.5/nspr/pr/tests/op_filok.c nspr-4.10.7/nspr/pr/tests/op_filok.c --- nspr-4.9.5/nspr/pr/tests/op_filok.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/op_filok.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: op_filok.c +** +** Description: Test Program to verify the PR_Open finding an existing file. +** +** Modification History: +** 03-June-97 AGarcia- Initial version +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "prinit.h" +#include "prmem.h" +#include "prio.h" +#include "prerror.h" +#include + +static PRFileDesc *t1; + +int main(int argc, char **argv) +{ + PR_STDIO_INIT(); + + t1 = PR_Open(argv[0], PR_RDONLY, 0666); + + if (t1 == NULL) { + printf ("error code is %d \n", PR_GetError()); + printf ("File %s should be found\n", argv[0]); + return 1; + } else { + if (PR_Close(t1) == PR_SUCCESS) { + printf ("Test passed \n"); + return 0; + } else { + printf ("cannot close file\n"); + printf ("error code is %d\n", PR_GetError()); + return 1; + } + } +} diff -Nru nspr-4.9.5/nspr/pr/tests/op_noacc.c nspr-4.10.7/nspr/pr/tests/op_noacc.c --- nspr-4.9.5/nspr/pr/tests/op_noacc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/op_noacc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: op_noacc.c +** +** Description: Test Program to verify the PR_NO_ACCESS_RIGHTS_ERROR in PR_Open +** +** Modification History: +** 03-June-97 AGarcia- Initial version +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "prinit.h" +#include "prmem.h" +#include "prio.h" +#include "prerror.h" +#include +#include "plgetopt.h" + +static PRFileDesc *err01; +PRIntn error_code; + +int main(int argc, char **argv) +{ +#ifdef XP_PC + printf("op_noacc: Test not valid on MS-Windows.\n\tNo concept of 'mode' on Open() call\n"); + return(0); +#endif + + + PR_STDIO_INIT(); + err01 = PR_Open("err01.tmp", PR_CREATE_FILE | PR_RDWR, 0); + if (err01 == NULL) { + int error = PR_GetError(); + printf ("error code is %d\n", error); + if (error == PR_NO_ACCESS_RIGHTS_ERROR) { + printf ("PASS\n"); + return 0; + } + } + printf ("FAIL\n"); + return 1; +} + diff -Nru nspr-4.9.5/nspr/pr/tests/op_nofil.c nspr-4.10.7/nspr/pr/tests/op_nofil.c --- nspr-4.9.5/nspr/pr/tests/op_nofil.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/op_nofil.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: op_nofil.c +** +** Description: Test Program to verify the PR_FILE_NOT_FOUND_ERROR +** +** Modification History: +** 03-June-97 AGarcia- Initial version +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "prinit.h" +#include "prmem.h" +#include "prio.h" +#include "prerror.h" +#include +#include "plgetopt.h" + +/* + * A file name that cannot exist + */ +#define NO_SUCH_FILE "/no/such/file.tmp" + +static PRFileDesc *t1; + +int main(int argc, char **argv) +{ + PR_STDIO_INIT(); + t1 = PR_Open(NO_SUCH_FILE, PR_RDONLY, 0666); + if (t1 == NULL) { + if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) { + printf ("error code is PR_FILE_NOT_FOUND_ERROR, as expected\n"); + printf ("PASS\n"); + return 0; + } else { + printf ("error code is %d \n", PR_GetError()); + printf ("FAIL\n"); + return 1; + } + } + printf ("File %s exists on this machine!?\n", NO_SUCH_FILE); + if (PR_Close(t1) == PR_FAILURE) { + printf ("cannot close file\n"); + printf ("error code is %d \n", PR_GetError()); + } + printf ("FAIL\n"); + return 1; +} diff -Nru nspr-4.9.5/nspr/pr/tests/parent.c nspr-4.10.7/nspr/pr/tests/parent.c --- nspr-4.9.5/nspr/pr/tests/parent.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/parent.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** file: parent.c +** description: test the process machinery +*/ + +#include "prmem.h" +#include "prprf.h" +#include "prinit.h" +#include "prproces.h" +#include "prinrval.h" + +typedef struct Child +{ + const char *name; + char **argv; + PRProcess *process; + PRProcessAttr *attr; +} Child; + +/* for the default test 'cvar -c 2000' */ +static char *default_argv[] = {"cvar", "-c", "2000", NULL}; + +static void PrintUsage(void) +{ + PR_fprintf(PR_GetSpecialFD(PR_StandardError), + "Usage: parent [-d] child [options]\n"); +} + +int main(int argc, char **argv) +{ + PRStatus rv; + PRInt32 test_status = 1; + PRIntervalTime t_start, t_elapsed; + PRFileDesc *debug = NULL; + Child *child = PR_NEWZAP(Child); + + if (1 == argc) + { + /* no command-line arguments: run the default test */ + child->argv = default_argv; + } + else + { + argv += 1; /* don't care about our program name */ + while (*argv != NULL && argv[0][0] == '-') + { + if (argv[0][1] == 'd') + debug = PR_GetSpecialFD(PR_StandardError); + else + { + PrintUsage(); + return 2; /* not sufficient */ + } + argv += 1; + } + child->argv = argv; + } + + if (NULL == *child->argv) + { + PrintUsage(); + return 2; + } + + child->name = *child->argv; + if (NULL != debug) PR_fprintf(debug, "Forking %s\n", child->name); + + child->attr = PR_NewProcessAttr(); + PR_ProcessAttrSetStdioRedirect( + child->attr, PR_StandardOutput, + PR_GetSpecialFD(PR_StandardOutput)); + PR_ProcessAttrSetStdioRedirect( + child->attr, PR_StandardError, + PR_GetSpecialFD(PR_StandardError)); + + t_start = PR_IntervalNow(); + child->process = PR_CreateProcess( + child->name, child->argv, NULL, child->attr); + t_elapsed = (PRIntervalTime) (PR_IntervalNow() - t_start); + + PR_DestroyProcessAttr(child->attr); + + test_status = (NULL == child->process) ? 1 : 0; + if (NULL != debug) + { + PR_fprintf( + debug, "Child was %sforked\n", + (0 == test_status) ? "" : "NOT "); + if (0 == test_status) + PR_fprintf( + debug, "PR_CreateProcess took %lu microseconds\n", + PR_IntervalToMicroseconds(t_elapsed)); + } + + if (0 == test_status) + { + if (NULL != debug) PR_fprintf(debug, "Waiting for child to exit\n"); + rv = PR_WaitProcess(child->process, &test_status); + if (PR_SUCCESS == rv) + { + if (NULL != debug) + PR_fprintf( + debug, "Child exited %s\n", + (0 == test_status) ? "successfully" : "with error"); + } + else + { + test_status = 1; + if (NULL != debug) + PR_fprintf(debug, "PR_WaitProcess failed\n"); + } + } + PR_DELETE(child); + PR_Cleanup(); + return test_status; + +} /* main */ + +/* parent.c */ + diff -Nru nspr-4.9.5/nspr/pr/tests/parsetm.c nspr-4.10.7/nspr/pr/tests/parsetm.c --- nspr-4.9.5/nspr/pr/tests/parsetm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/parsetm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This test program should eventually become a full-blown test for + * PR_ParseTimeString. Right now it just verifies that PR_ParseTimeString + * doesn't crash on an out-of-range time string (bug 480740). + */ + +#include "prtime.h" + +#include +#include +#include +#include + +PRBool debug_mode = PR_TRUE; + +static char *dayOfWeek[] = + { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; +static char *month[] = + { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; + +static void PrintExplodedTime(const PRExplodedTime *et) { + PRInt32 totalOffset; + PRInt32 hourOffset, minOffset; + const char *sign; + + /* Print day of the week, month, day, hour, minute, and second */ + if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ", + dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, + et->tm_hour, et->tm_min, et->tm_sec); + + /* Print time zone */ + totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; + if (totalOffset == 0) { + if (debug_mode) printf("UTC "); + } else { + sign = "+"; + if (totalOffset < 0) { + totalOffset = -totalOffset; + sign = "-"; + } + hourOffset = totalOffset / 3600; + minOffset = (totalOffset % 3600) / 60; + if (debug_mode) + printf("%s%02ld%02ld ", sign, hourOffset, minOffset); + } + + /* Print year */ + if (debug_mode) printf("%hd", et->tm_year); +} + +int main(int argc, char **argv) +{ + PRTime ct; + PRExplodedTime et; + PRStatus rv; + char *sp1 = "Sat, 1 Jan 3001 00:00:00"; /* no time zone */ + char *sp2 = "Fri, 31 Dec 3000 23:59:60"; /* no time zone, not normalized */ + +#if _MSC_VER >= 1400 && !defined(WINCE) + /* Run this test in the US Pacific Time timezone. */ + _putenv_s("TZ", "PST8PDT"); + _tzset(); +#endif + + rv = PR_ParseTimeString(sp1, PR_FALSE, &ct); + printf("rv = %d\n", rv); + PR_ExplodeTime(ct, PR_GMTParameters, &et); + PrintExplodedTime(&et); + printf("\n"); + + rv = PR_ParseTimeString(sp2, PR_FALSE, &ct); + printf("rv = %d\n", rv); + PR_ExplodeTime(ct, PR_GMTParameters, &et); + PrintExplodedTime(&et); + printf("\n"); + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/peek.c nspr-4.10.7/nspr/pr/tests/peek.c --- nspr-4.9.5/nspr/pr/tests/peek.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/peek.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,360 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * A test case for the PR_MSG_PEEK flag of PR_Recv(). + * + * Test both blocking and non-blocking sockets. + */ + +#include "nspr.h" + +#include +#include +#include + +#define BUFFER_SIZE 1024 + +static int iterations = 10; + +/* + * In iteration i, recv_amount[i] is the number of bytes we + * wish to receive, and send_amount[i] is the number of bytes + * we actually send. Therefore, the number of elements in the + * recv_amount or send_amount array should equal to 'iterations'. + * For this test to pass we need to ensure that + * recv_amount[i] <= BUFFER_SIZE, + * send_amount[i] <= BUFFER_SIZE, + * send_amount[i] <= recv_amount[i]. + */ +static PRInt32 recv_amount[10] = { + 16, 128, 256, 1024, 512, 512, 128, 256, 32, 32}; +static PRInt32 send_amount[10] = { + 16, 64, 128, 1024, 512, 256, 128, 64, 16, 32}; + +/* Blocking I/O */ +static void ServerB(void *arg) +{ + PRFileDesc *listenSock = (PRFileDesc *) arg; + PRFileDesc *sock; + char buf[BUFFER_SIZE]; + PRInt32 nbytes; + int i; + int j; + + sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (NULL == sock) { + fprintf(stderr, "PR_Accept failed\n"); + exit(1); + } + + for (i = 0; i < iterations; i++) { + memset(buf, 0, sizeof(buf)); + nbytes = PR_Recv(sock, buf, recv_amount[i], + PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); + if (-1 == nbytes) { + fprintf(stderr, "PR_Recv failed\n"); + exit(1); + } + if (send_amount[i] != nbytes) { + fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); + exit(1); + } + for (j = 0; j < nbytes; j++) { + if (buf[j] != 2*i) { + fprintf(stderr, "byte %d should be %d but is %d\n", + j, 2*i, buf[j]); + exit(1); + } + } + fprintf(stderr, "server: peeked expected data\n"); + + memset(buf, 0, sizeof(buf)); + nbytes = PR_Recv(sock, buf, recv_amount[i], + PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); + if (-1 == nbytes) { + fprintf(stderr, "PR_Recv failed\n"); + exit(1); + } + if (send_amount[i] != nbytes) { + fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); + exit(1); + } + for (j = 0; j < nbytes; j++) { + if (buf[j] != 2*i) { + fprintf(stderr, "byte %d should be %d but is %d\n", + j, 2*i, buf[j]); + exit(1); + } + } + fprintf(stderr, "server: peeked expected data\n"); + + memset(buf, 0, sizeof(buf)); + nbytes = PR_Recv(sock, buf, recv_amount[i], + 0, PR_INTERVAL_NO_TIMEOUT); + if (-1 == nbytes) { + fprintf(stderr, "PR_Recv failed\n"); + exit(1); + } + if (send_amount[i] != nbytes) { + fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); + exit(1); + } + for (j = 0; j < nbytes; j++) { + if (buf[j] != 2*i) { + fprintf(stderr, "byte %d should be %d but is %d\n", + j, 2*i, buf[j]); + exit(1); + } + } + fprintf(stderr, "server: received expected data\n"); + + PR_Sleep(PR_SecondsToInterval(1)); + memset(buf, 2*i+1, send_amount[i]); + nbytes = PR_Send(sock, buf, send_amount[i], + 0, PR_INTERVAL_NO_TIMEOUT); + if (-1 == nbytes) { + fprintf(stderr, "PR_Send failed\n"); + exit(1); + } + if (send_amount[i] != nbytes) { + fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes); + exit(1); + } + } + if (PR_Close(sock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } +} + +/* Non-blocking I/O */ +static void ClientNB(void *arg) +{ + PRFileDesc *sock; + PRSocketOptionData opt; + PRUint16 port = (PRUint16) arg; + PRNetAddr addr; + char buf[BUFFER_SIZE]; + PRPollDesc pd; + PRInt32 npds; + PRInt32 nbytes; + int i; + int j; + + sock = PR_OpenTCPSocket(PR_AF_INET6); + if (NULL == sock) { + fprintf(stderr, "PR_OpenTCPSocket failed\n"); + exit(1); + } + opt.option = PR_SockOpt_Nonblocking; + opt.value.non_blocking = PR_TRUE; + if (PR_SetSocketOption(sock, &opt) == PR_FAILURE) { + fprintf(stderr, "PR_SetSocketOption failed\n"); + exit(1); + } + memset(&addr, 0, sizeof(addr)); + if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, port, &addr) + == PR_FAILURE) { + fprintf(stderr, "PR_SetNetAddr failed\n"); + exit(1); + } + if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + if (PR_GetError() != PR_IN_PROGRESS_ERROR) { + fprintf(stderr, "PR_Connect failed\n"); + exit(1); + } + pd.fd = sock; + pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; + npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (-1 == npds) { + fprintf(stderr, "PR_Poll failed\n"); + exit(1); + } + if (1 != npds) { + fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); + exit(1); + } + if (PR_GetConnectStatus(&pd) == PR_FAILURE) { + fprintf(stderr, "PR_GetConnectStatus failed\n"); + exit(1); + } + } + + for (i = 0; i < iterations; i++) { + PR_Sleep(PR_SecondsToInterval(1)); + memset(buf, 2*i, send_amount[i]); + while ((nbytes = PR_Send(sock, buf, send_amount[i], + 0, PR_INTERVAL_NO_TIMEOUT)) == -1) { + if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { + fprintf(stderr, "PR_Send failed\n"); + exit(1); + } + pd.fd = sock; + pd.in_flags = PR_POLL_WRITE; + npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (-1 == npds) { + fprintf(stderr, "PR_Poll failed\n"); + exit(1); + } + if (1 != npds) { + fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); + exit(1); + } + } + if (send_amount[i] != nbytes) { + fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes); + exit(1); + } + + memset(buf, 0, sizeof(buf)); + while ((nbytes = PR_Recv(sock, buf, recv_amount[i], + PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT)) == -1) { + if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { + fprintf(stderr, "PR_Recv failed\n"); + exit(1); + } + pd.fd = sock; + pd.in_flags = PR_POLL_READ; + npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (-1 == npds) { + fprintf(stderr, "PR_Poll failed\n"); + exit(1); + } + if (1 != npds) { + fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); + exit(1); + } + } + if (send_amount[i] != nbytes) { + fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); + exit(1); + } + for (j = 0; j < nbytes; j++) { + if (buf[j] != 2*i+1) { + fprintf(stderr, "byte %d should be %d but is %d\n", + j, 2*i+1, buf[j]); + exit(1); + } + } + fprintf(stderr, "client: peeked expected data\n"); + + memset(buf, 0, sizeof(buf)); + nbytes = PR_Recv(sock, buf, recv_amount[i], + PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); + if (-1 == nbytes) { + fprintf(stderr, "PR_Recv failed\n"); + exit(1); + } + if (send_amount[i] != nbytes) { + fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); + exit(1); + } + for (j = 0; j < nbytes; j++) { + if (buf[j] != 2*i+1) { + fprintf(stderr, "byte %d should be %d but is %d\n", + j, 2*i+1, buf[j]); + exit(1); + } + } + fprintf(stderr, "client: peeked expected data\n"); + + memset(buf, 0, sizeof(buf)); + nbytes = PR_Recv(sock, buf, recv_amount[i], + 0, PR_INTERVAL_NO_TIMEOUT); + if (-1 == nbytes) { + fprintf(stderr, "PR_Recv failed\n"); + exit(1); + } + if (send_amount[i] != nbytes) { + fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); + exit(1); + } + for (j = 0; j < nbytes; j++) { + if (buf[j] != 2*i+1) { + fprintf(stderr, "byte %d should be %d but is %d\n", + j, 2*i+1, buf[j]); + exit(1); + } + } + fprintf(stderr, "client: received expected data\n"); + } + if (PR_Close(sock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } +} + +static void +RunTest(PRThreadScope scope, PRFileDesc *listenSock, PRUint16 port) +{ + PRThread *server, *client; + + server = PR_CreateThread(PR_USER_THREAD, ServerB, listenSock, + PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); + if (NULL == server) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + client = PR_CreateThread( + PR_USER_THREAD, ClientNB, (void *) port, + PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); + if (NULL == client) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + + if (PR_JoinThread(server) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + if (PR_JoinThread(client) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } +} + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock; + PRNetAddr addr; + PRUint16 port; + + listenSock = PR_OpenTCPSocket(PR_AF_INET6); + if (NULL == listenSock) { + fprintf(stderr, "PR_OpenTCPSocket failed\n"); + exit(1); + } + memset(&addr, 0, sizeof(addr)); + if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_SetNetAddr failed\n"); + exit(1); + } + if (PR_Bind(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + exit(1); + } + port = PR_ntohs(addr.ipv6.port); + if (PR_Listen(listenSock, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + + fprintf(stderr, "Running the test with local threads\n"); + RunTest(PR_LOCAL_THREAD, listenSock, port); + fprintf(stderr, "Running the test with global threads\n"); + RunTest(PR_GLOBAL_THREAD, listenSock, port); + + if (PR_Close(listenSock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/perf.c nspr-4.10.7/nspr/pr/tests/perf.c --- nspr-4.9.5/nspr/pr/tests/perf.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/perf.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,442 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "plgetopt.h" + +#include +#include +#include + +int _debug_on = 0; +#define DPRINTF(arg) if (_debug_on) printf arg + +#include "obsolete/prsem.h" + +PRLock *lock; +PRMonitor *mon; +PRMonitor *mon2; + +#define DEFAULT_COUNT 1000 + +PRInt32 count; + +static void nop(int a, int b, int c) +{ +} + +static void LocalProcedureCall(void) +{ + PRInt32 i; + + for (i = 0; i < count; i++) { + nop(i, i, 5); + } +} + +static void DLLProcedureCall(void) +{ + PRInt32 i; + PRThreadState state; + PRThread *self = PR_GetCurrentThread(); + + for (i = 0; i < count; i++) { + state = PR_GetThreadState(self); + } +} + +static void Now(void) +{ + PRInt32 i; + PRTime time; + + for (i = 0; i < count; i++) { + time = PR_Now(); + } +} + +static void Interval(void) +{ + PRInt32 i; + PRIntervalTime time; + + for (i = 0; i < count; i++) { + time = PR_IntervalNow(); + } +} + +static void IdleLock(void) +{ + PRInt32 i; + + for (i = 0; i < count; i++) { + PR_Lock(lock); + PR_Unlock(lock); + } +} + +static void IdleMonitor(void) +{ + PRInt32 i; + + for (i = 0; i < count; i++) { + PR_EnterMonitor(mon); + PR_ExitMonitor(mon); + } +} + +static void IdleCMonitor(void) +{ + PRInt32 i; + + for (i = 0; i < count; i++) { + PR_CEnterMonitor((void*)7); + PR_CExitMonitor((void*)7); + } +} + +/************************************************************************/ + +static void PR_CALLBACK dull(void *arg) +{ +} + +static void CDThread(void) +{ + PRInt32 i; + int num_threads = count; + + /* + * Cannot create too many threads + */ + if (num_threads > 1000) + num_threads = 1000; + + for (i = 0; i < num_threads; i++) { + PRThread *t = PR_CreateThread(PR_USER_THREAD, + dull, 0, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + if (NULL == t) { + fprintf(stderr, "CDThread: cannot create thread %3d\n", i); + } else { + DPRINTF(("CDThread: created thread %3d \n",i)); + } + PR_Sleep(0); + } +} + +static int alive; +static int cxq; + +static void PR_CALLBACK CXReader(void *arg) +{ + PRInt32 i, n; + + PR_EnterMonitor(mon); + n = count / 2; + for (i = 0; i < n; i++) { + while (cxq == 0) { + DPRINTF(("CXReader: thread = 0x%lx waiting\n", + PR_GetCurrentThread())); + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + } + --cxq; + PR_Notify(mon); + } + PR_ExitMonitor(mon); + + PR_EnterMonitor(mon2); + --alive; + PR_Notify(mon2); + PR_ExitMonitor(mon2); + DPRINTF(("CXReader: thread = 0x%lx exiting\n", PR_GetCurrentThread())); +} + +static void PR_CALLBACK CXWriter(void *arg) +{ + PRInt32 i, n; + + PR_EnterMonitor(mon); + n = count / 2; + for (i = 0; i < n; i++) { + while (cxq == 1) { + DPRINTF(("CXWriter: thread = 0x%lx waiting\n", + PR_GetCurrentThread())); + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + } + ++cxq; + PR_Notify(mon); + } + PR_ExitMonitor(mon); + + PR_EnterMonitor(mon2); + --alive; + PR_Notify(mon2); + PR_ExitMonitor(mon2); + DPRINTF(("CXWriter: thread = 0x%lx exiting\n", PR_GetCurrentThread())); +} + +static void ContextSwitch(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *t1, *t2; + + PR_EnterMonitor(mon2); + alive = 2; + cxq = 0; + + t1 = PR_CreateThread(PR_USER_THREAD, + CXReader, 0, + PR_PRIORITY_NORMAL, + scope1, + PR_UNJOINABLE_THREAD, + 0); + if (NULL == t1) { + fprintf(stderr, "ContextSwitch: cannot create thread\n"); + } else { + DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n", + (scope1 == PR_GLOBAL_THREAD ? + "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"), + t1)); + } + t2 = PR_CreateThread(PR_USER_THREAD, + CXWriter, 0, + PR_PRIORITY_NORMAL, + scope2, + PR_UNJOINABLE_THREAD, + 0); + if (NULL == t2) { + fprintf(stderr, "ContextSwitch: cannot create thread\n"); + } else { + DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n", + (scope2 == PR_GLOBAL_THREAD ? + "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"), + t2)); + } + + /* Wait for both of the threads to exit */ + while (alive) { + PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); + } + PR_ExitMonitor(mon2); +} + +static void ContextSwitchUU(void) +{ + ContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD); +} + +static void ContextSwitchUK(void) +{ + ContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); +} + +static void ContextSwitchKU(void) +{ + ContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); +} + +static void ContextSwitchKK(void) +{ + ContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); +} + +/************************************************************************/ + +static void PR_CALLBACK SemaThread(void *argSema) +{ + PRSemaphore **sem = (PRSemaphore **)argSema; + PRInt32 i, n; + + n = count / 2; + for (i = 0; i < n; i++) { + DPRINTF(("SemaThread: thread = 0x%lx waiting on sem = 0x%lx\n", + PR_GetCurrentThread(), sem[0])); + PR_WaitSem(sem[0]); + DPRINTF(("SemaThread: thread = 0x%lx posting on sem = 0x%lx\n", + PR_GetCurrentThread(), sem[1])); + PR_PostSem(sem[1]); + } + + PR_EnterMonitor(mon2); + --alive; + PR_Notify(mon2); + PR_ExitMonitor(mon2); + DPRINTF(("SemaThread: thread = 0x%lx exiting\n", PR_GetCurrentThread())); +} + +static PRSemaphore *sem_set1[2]; +static PRSemaphore *sem_set2[2]; + +static void SemaContextSwitch(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *t1, *t2; + sem_set1[0] = PR_NewSem(1); + sem_set1[1] = PR_NewSem(0); + sem_set2[0] = sem_set1[1]; + sem_set2[1] = sem_set1[0]; + + PR_EnterMonitor(mon2); + alive = 2; + cxq = 0; + + t1 = PR_CreateThread(PR_USER_THREAD, + SemaThread, + sem_set1, + PR_PRIORITY_NORMAL, + scope1, + PR_UNJOINABLE_THREAD, + 0); + if (NULL == t1) { + fprintf(stderr, "SemaContextSwitch: cannot create thread\n"); + } else { + DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n", + (scope1 == PR_GLOBAL_THREAD ? + "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"), + t1)); + } + t2 = PR_CreateThread(PR_USER_THREAD, + SemaThread, + sem_set2, + PR_PRIORITY_NORMAL, + scope2, + PR_UNJOINABLE_THREAD, + 0); + if (NULL == t2) { + fprintf(stderr, "SemaContextSwitch: cannot create thread\n"); + } else { + DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n", + (scope2 == PR_GLOBAL_THREAD ? + "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"), + t2)); + } + + /* Wait for both of the threads to exit */ + while (alive) { + PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); + } + PR_ExitMonitor(mon2); + + PR_DestroySem(sem_set1[0]); + PR_DestroySem(sem_set1[1]); +} + +static void SemaContextSwitchUU(void) +{ + SemaContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD); +} + +static void SemaContextSwitchUK(void) +{ + SemaContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD); +} + +static void SemaContextSwitchKU(void) +{ + SemaContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD); +} + +static void SemaContextSwitchKK(void) +{ + SemaContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD); +} + + +/************************************************************************/ + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow() - start; + d = (double)PR_IntervalToMicroseconds(stop); + + printf("%40s: %6.2f usec\n", msg, d / count); +} + +int main(int argc, char **argv) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dc:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + case 'c': /* loop count */ + count = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (0 == count) count = DEFAULT_COUNT; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_BlockClockInterrupts(); + PR_UnblockClockInterrupts(); + PR_STDIO_INIT(); + + lock = PR_NewLock(); + mon = PR_NewMonitor(); + mon2 = PR_NewMonitor(); + + Measure(LocalProcedureCall, "local procedure call overhead"); + Measure(DLLProcedureCall, "DLL procedure call overhead"); + Measure(Now, "current calendar time"); + Measure(Interval, "interval time"); + Measure(IdleLock, "idle lock lock/unlock pair"); + Measure(IdleMonitor, "idle monitor entry/exit pair"); + Measure(IdleCMonitor, "idle cache monitor entry/exit pair"); + Measure(CDThread, "create/destroy thread pair"); + Measure(ContextSwitchUU, "context switch - user/user"); + Measure(ContextSwitchUK, "context switch - user/kernel"); + Measure(ContextSwitchKU, "context switch - kernel/user"); + Measure(ContextSwitchKK, "context switch - kernel/kernel"); + Measure(SemaContextSwitchUU, "sema context switch - user/user"); + Measure(SemaContextSwitchUK, "sema context switch - user/kernel"); + Measure(SemaContextSwitchKU, "sema context switch - kernel/user"); + Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel"); + + printf("--------------\n"); + printf("Adding 7 additional CPUs\n"); + + PR_SetConcurrency(8); + printf("--------------\n"); + + Measure(LocalProcedureCall, "local procedure call overhead"); + Measure(DLLProcedureCall, "DLL procedure call overhead"); + Measure(Now, "current calendar time"); + Measure(Interval, "interval time"); + Measure(IdleLock, "idle lock lock/unlock pair"); + Measure(IdleMonitor, "idle monitor entry/exit pair"); + Measure(IdleCMonitor, "idle cache monitor entry/exit pair"); + Measure(CDThread, "create/destroy thread pair"); + Measure(ContextSwitchUU, "context switch - user/user"); + Measure(ContextSwitchUK, "context switch - user/kernel"); + Measure(ContextSwitchKU, "context switch - kernel/user"); + Measure(ContextSwitchKK, "context switch - kernel/kernel"); + Measure(SemaContextSwitchUU, "sema context switch - user/user"); + Measure(SemaContextSwitchUK, "sema context switch - user/kernel"); + Measure(SemaContextSwitchKU, "sema context switch - kernel/user"); + Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel"); + + PR_DestroyLock(lock); + PR_DestroyMonitor(mon); + PR_DestroyMonitor(mon2); + + PR_Cleanup(); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/pipeping2.c nspr-4.10.7/nspr/pr/tests/pipeping2.c --- nspr-4.9.5/nspr/pr/tests/pipeping2.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/pipeping2.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,160 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: pipeping2.c + * + * Description: + * This test runs in conjunction with the pipepong2 test. + * This test creates two pipes and passes two pipe fd's + * to the pipepong2 test. Then this test writes "ping" to + * to the pipepong2 test and the pipepong2 test writes "pong" + * back. To run this pair of tests, just invoke pipeping2. + * + * Tested areas: process creation, pipes, file descriptor + * inheritance. + */ + +#include "prerror.h" +#include "prio.h" +#include "prproces.h" + +#include +#include +#include + +#define NUM_ITERATIONS 10 + +static char *child_argv[] = { "pipepong2", NULL }; + +int main(int argc, char **argv) +{ + PRFileDesc *in_pipe[2]; + PRFileDesc *out_pipe[2]; + PRStatus status; + PRProcess *process; + PRProcessAttr *attr; + char buf[1024]; + PRInt32 nBytes; + PRInt32 exitCode; + int idx; + + status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_CreatePipe failed\n"); + exit(1); + } + status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_CreatePipe failed\n"); + exit(1); + } + + status = PR_SetFDInheritable(in_pipe[0], PR_FALSE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + status = PR_SetFDInheritable(in_pipe[1], PR_TRUE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + status = PR_SetFDInheritable(out_pipe[0], PR_TRUE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + status = PR_SetFDInheritable(out_pipe[1], PR_FALSE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + + attr = PR_NewProcessAttr(); + if (attr == NULL) { + fprintf(stderr, "PR_NewProcessAttr failed\n"); + exit(1); + } + + status = PR_ProcessAttrSetInheritableFD(attr, out_pipe[0], "PIPE_READ"); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); + exit(1); + } + status = PR_ProcessAttrSetInheritableFD(attr, in_pipe[1], "PIPE_WRITE"); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); + exit(1); + } + + process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr); + if (process == NULL) { + fprintf(stderr, "PR_CreateProcess failed\n"); + exit(1); + } + PR_DestroyProcessAttr(attr); + status = PR_Close(out_pipe[0]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(in_pipe[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + + for (idx = 0; idx < NUM_ITERATIONS; idx++) { + strcpy(buf, "ping"); + printf("ping process: sending \"%s\"\n", buf); + nBytes = PR_Write(out_pipe[1], buf, 5); + if (nBytes == -1) { + fprintf(stderr, "PR_Write failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + memset(buf, 0, sizeof(buf)); + nBytes = PR_Read(in_pipe[0], buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed\n"); + exit(1); + } + printf("ping process: received \"%s\"\n", buf); + if (nBytes != 5) { + fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n", + nBytes); + exit(1); + } + if (strcmp(buf, "pong") != 0) { + fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", + buf); + exit(1); + } + } + + status = PR_Close(in_pipe[0]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(out_pipe[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_WaitProcess(process, &exitCode); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_WaitProcess failed\n"); + exit(1); + } + if (exitCode == 0) { + printf("PASS\n"); + return 0; + } else { + printf("FAIL\n"); + return 1; + } +} diff -Nru nspr-4.9.5/nspr/pr/tests/pipeping.c nspr-4.10.7/nspr/pr/tests/pipeping.c --- nspr-4.9.5/nspr/pr/tests/pipeping.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/pipeping.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,158 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: pipeping.c + * + * Description: + * This test runs in conjunction with the pipepong test. + * This test creates two pipes and redirects the stdin and + * stdout of the pipepong test to the pipes. Then this + * test writes "ping" to the pipepong test and the pipepong + * test writes "pong" back. To run this pair of tests, + * just invoke pipeping. + * + * Tested areas: process creation, pipes, file descriptor + * inheritance, standard I/O redirection. + */ + +#include "prerror.h" +#include "prio.h" +#include "prproces.h" + +#include +#include +#include + +#ifdef XP_OS2 +static char *child_argv[] = { "pipepong.exe", NULL }; +#else +static char *child_argv[] = { "pipepong", NULL }; +#endif + +#define NUM_ITERATIONS 10 + +int main(int argc, char **argv) +{ + PRFileDesc *in_pipe[2]; + PRFileDesc *out_pipe[2]; + PRStatus status; + PRProcess *process; + PRProcessAttr *attr; + char buf[1024]; + PRInt32 nBytes; + PRInt32 exitCode; + int idx; + + status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_CreatePipe failed\n"); + exit(1); + } + status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_CreatePipe failed\n"); + exit(1); + } + + status = PR_SetFDInheritable(in_pipe[0], PR_FALSE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + status = PR_SetFDInheritable(in_pipe[1], PR_TRUE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + status = PR_SetFDInheritable(out_pipe[0], PR_TRUE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + status = PR_SetFDInheritable(out_pipe[1], PR_FALSE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + + attr = PR_NewProcessAttr(); + if (attr == NULL) { + fprintf(stderr, "PR_NewProcessAttr failed\n"); + exit(1); + } + + PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, out_pipe[0]); + PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, in_pipe[1]); + + process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr); + if (process == NULL) { + fprintf(stderr, "PR_CreateProcess failed\n"); + exit(1); + } + PR_DestroyProcessAttr(attr); + status = PR_Close(out_pipe[0]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(in_pipe[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + + for (idx = 0; idx < NUM_ITERATIONS; idx++) { + strcpy(buf, "ping"); + printf("ping process: sending \"%s\"\n", buf); + nBytes = PR_Write(out_pipe[1], buf, 5); + if (nBytes == -1) { + fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + exit(1); + } + memset(buf, 0, sizeof(buf)); + nBytes = PR_Read(in_pipe[0], buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + printf("ping process: received \"%s\"\n", buf); + if (nBytes != 5) { + fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n", + nBytes); + exit(1); + } + if (strcmp(buf, "pong") != 0) { + fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", + buf); + exit(1); + } + } + + status = PR_Close(in_pipe[0]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(out_pipe[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_WaitProcess(process, &exitCode); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_WaitProcess failed\n"); + exit(1); + } + if (exitCode == 0) { + printf("PASS\n"); + return 0; + } else { + printf("FAIL\n"); + return 1; + } +} diff -Nru nspr-4.9.5/nspr/pr/tests/pipepong2.c nspr-4.10.7/nspr/pr/tests/pipepong2.c --- nspr-4.9.5/nspr/pr/tests/pipepong2.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/pipepong2.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: pipepong2.c + * + * Description: + * This test runs in conjunction with the pipeping2 test. + * The pipeping2 test creates two pipes and passes two + * pipe fd's to this test. Then the pipeping2 test writes + * "ping" to this test and this test writes "pong" back. + * To run this pair of tests, just invoke pipeping2. + * + * Tested areas: process creation, pipes, file descriptor + * inheritance. + */ + +#include "prerror.h" +#include "prio.h" + +#include +#include +#include + +#define NUM_ITERATIONS 10 + +int main(int argc, char **argv) +{ + PRFileDesc *pipe_read, *pipe_write; + PRStatus status; + char buf[1024]; + PRInt32 nBytes; + int idx; + + pipe_read = PR_GetInheritedFD("PIPE_READ"); + if (pipe_read == NULL) { + fprintf(stderr, "PR_GetInheritedFD failed\n"); + exit(1); + } + status = PR_SetFDInheritable(pipe_read, PR_FALSE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + pipe_write = PR_GetInheritedFD("PIPE_WRITE"); + if (pipe_write == NULL) { + fprintf(stderr, "PR_GetInheritedFD failed\n"); + exit(1); + } + status = PR_SetFDInheritable(pipe_write, PR_FALSE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + + for (idx = 0; idx < NUM_ITERATIONS; idx++) { + memset(buf, 0, sizeof(buf)); + nBytes = PR_Read(pipe_read, buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + printf("pong process: received \"%s\"\n", buf); + if (nBytes != 5) { + fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n", + nBytes); + exit(1); + } + if (strcmp(buf, "ping") != 0) { + fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n", + buf); + exit(1); + } + + strcpy(buf, "pong"); + printf("pong process: sending \"%s\"\n", buf); + nBytes = PR_Write(pipe_write, buf, 5); + if (nBytes == -1) { + fprintf(stderr, "PR_Write failed\n"); + exit(1); + } + } + + status = PR_Close(pipe_read); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(pipe_write); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/pipepong.c nspr-4.10.7/nspr/pr/tests/pipepong.c --- nspr-4.9.5/nspr/pr/tests/pipepong.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/pipepong.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: pipepong.c + * + * Description: + * This test runs in conjunction with the pipeping test. + * The pipeping test creates two pipes and redirects the + * stdin and stdout of this test to the pipes. Then the + * pipeping test writes "ping" to this test and this test + * writes "pong" back. Note that this test does not depend + * on NSPR at all. To run this pair of tests, just invoke + * pipeping. + * + * Tested areas: process creation, pipes, file descriptor + * inheritance, standard I/O redirection. + */ + +#include +#include +#include + +#define NUM_ITERATIONS 10 + +int main(int argc, char **argv) +{ + char buf[1024]; + size_t nBytes; + int idx; + + for (idx = 0; idx < NUM_ITERATIONS; idx++) { + memset(buf, 0, sizeof(buf)); + nBytes = fread(buf, 1, 5, stdin); + fprintf(stderr, "pong process: received \"%s\"\n", buf); + if (nBytes != 5) { + fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n", + nBytes); + exit(1); + } + if (strcmp(buf, "ping") != 0) { + fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n", + buf); + exit(1); + } + + strcpy(buf, "pong"); + fprintf(stderr, "pong process: sending \"%s\"\n", buf); + nBytes = fwrite(buf, 1, 5, stdout); + if (nBytes != 5) { + fprintf(stderr, "pong process: fwrite failed\n"); + exit(1); + } + fflush(stdout); + } + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/pipeself.c nspr-4.10.7/nspr/pr/tests/pipeself.c --- nspr-4.9.5/nspr/pr/tests/pipeself.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/pipeself.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,228 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: pipeself.c + * + * Description: + * This test has two threads communicating with each other using + * two unidirectional pipes. The primordial thread is the ping + * thread and the other thread is the pong thread. The ping + * thread writes "ping" to the pong thread and the pong thread + * writes "pong" back. + */ + +#include "prio.h" +#include "prerror.h" +#include "prthread.h" + +#include +#include +#include + +#define NUM_ITERATIONS 10 + +static PRFileDesc *ping_in, *ping_out; +static PRFileDesc *pong_in, *pong_out; + +static void PongThreadFunc(void *arg) +{ + char buf[1024]; + int idx; + PRInt32 nBytes; + PRStatus status; + + for (idx = 0; idx < NUM_ITERATIONS; idx++) { + memset(buf, 0, sizeof(buf)); + nBytes = PR_Read(pong_in, buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed\n"); + exit(1); + } + printf("pong thread: received \"%s\"\n", buf); + if (nBytes != 5) { + fprintf(stderr, "pong thread: expected 5 bytes but got %d bytes\n", + nBytes); + exit(1); + } + if (strcmp(buf, "ping") != 0) { + fprintf(stderr, "pong thread: expected \"ping\" but got \"%s\"\n", + buf); + exit(1); + } + strcpy(buf, "pong"); + printf("pong thread: sending \"%s\"\n", buf); + nBytes = PR_Write(pong_out, buf, 5); + if (nBytes == -1) { + fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + exit(1); + } + } + + status = PR_Close(pong_in); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(pong_out); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } +} + +int main(int argc, char **argv) +{ + PRStatus status; + PRThread *pongThread; + char buf[1024]; + PRInt32 nBytes; + int idx; + + status = PR_CreatePipe(&ping_in, &pong_out); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_CreatePipe failed\n"); + exit(1); + } + status = PR_CreatePipe(&pong_in, &ping_out); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_CreatePipe failed\n"); + exit(1); + } + + pongThread = PR_CreateThread(PR_USER_THREAD, PongThreadFunc, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (pongThread == NULL) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + + for (idx = 0; idx < NUM_ITERATIONS; idx++) { + strcpy(buf, "ping"); + printf("ping thread: sending \"%s\"\n", buf); + nBytes = PR_Write(ping_out, buf, 5); + if (nBytes == -1) { + fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + exit(1); + } + memset(buf, 0, sizeof(buf)); + nBytes = PR_Read(ping_in, buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed\n"); + exit(1); + } + printf("ping thread: received \"%s\"\n", buf); + if (nBytes != 5) { + fprintf(stderr, "ping thread: expected 5 bytes but got %d bytes\n", + nBytes); + exit(1); + } + if (strcmp(buf, "pong") != 0) { + fprintf(stderr, "ping thread: expected \"pong\" but got \"%s\"\n", + buf); + exit(1); + } + } + + status = PR_Close(ping_in); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(ping_out); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_JoinThread(pongThread); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + +#if defined(XP_UNIX) && !defined(SYMBIAN) + /* + * Test PR_Available for pipes + */ + status = PR_CreatePipe(&ping_in, &ping_out); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_CreatePipe failed\n"); + exit(1); + } + nBytes = PR_Write(ping_out, buf, 250); + if (nBytes == -1) { + fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + exit(1); + } + nBytes = PR_Available(ping_in); + if (nBytes < 0) { + fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + exit(1); + } else if (nBytes != 250) { + fprintf(stderr, "PR_Available: expected 250 bytes but got %d bytes\n", + nBytes); + exit(1); + } + printf("PR_Available: expected %d, got %d bytes\n",250, nBytes); + /* read some data */ + nBytes = PR_Read(ping_in, buf, 7); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed\n"); + exit(1); + } + /* check available data */ + nBytes = PR_Available(ping_in); + if (nBytes < 0) { + fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + exit(1); + } else if (nBytes != (250 - 7)) { + fprintf(stderr, "PR_Available: expected 243 bytes but got %d bytes\n", + nBytes); + exit(1); + } + printf("PR_Available: expected %d, got %d bytes\n",243, nBytes); + /* read all data */ + nBytes = PR_Read(ping_in, buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed\n"); + exit(1); + } else if (nBytes != 243) { + fprintf(stderr, "PR_Read failed: expected %d, got %d bytes\n", + 243, nBytes); + exit(1); + } + /* check available data */ + nBytes = PR_Available(ping_in); + if (nBytes < 0) { + fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + exit(1); + } else if (nBytes != 0) { + fprintf(stderr, "PR_Available: expected 0 bytes but got %d bytes\n", + nBytes); + exit(1); + } + printf("PR_Available: expected %d, got %d bytes\n", 0, nBytes); + + status = PR_Close(ping_in); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_Close(ping_out); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } +#endif /* XP_UNIX */ + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/pollable.c nspr-4.10.7/nspr/pr/tests/pollable.c --- nspr-4.9.5/nspr/pr/tests/pollable.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/pollable.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * A test for the pollable events. + * + * A number of threads are in a ring configuration, each waiting on + * a pollable event that is set by its upstream neighbor. + */ + +#include "prinit.h" +#include "prio.h" +#include "prthread.h" +#include "prerror.h" +#include "prmem.h" +#include "prlog.h" +#include "prprf.h" + +#include "plgetopt.h" + +#include + +#define DEFAULT_THREADS 10 +#define DEFAULT_LOOPS 100 + +PRIntn numThreads = DEFAULT_THREADS; +PRIntn numIterations = DEFAULT_LOOPS; +PRIntervalTime dally = PR_INTERVAL_NO_WAIT; +PRFileDesc *debug_out = NULL; +PRBool debug_mode = PR_FALSE; +PRBool verbosity = PR_FALSE; + +typedef struct ThreadData { + PRFileDesc *event; + int index; + struct ThreadData *next; +} ThreadData; + +void ThreadRoutine(void *arg) +{ + ThreadData *data = (ThreadData *) arg; + PRIntn i; + PRPollDesc pd; + PRInt32 rv; + + pd.fd = data->event; + pd.in_flags = PR_POLL_READ; + + for (i = 0; i < numIterations; i++) { + rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (rv == -1) { + PR_fprintf(PR_STDERR, "PR_Poll failed\n"); + exit(1); + } + if (verbosity) { + PR_fprintf(debug_out, "thread %d awakened\n", data->index); + } + PR_ASSERT(rv != 0); + PR_ASSERT(pd.out_flags & PR_POLL_READ); + if (PR_WaitForPollableEvent(data->event) == PR_FAILURE) { + PR_fprintf(PR_STDERR, "consume event failed\n"); + exit(1); + } + if (dally != PR_INTERVAL_NO_WAIT) { + PR_Sleep(dally); + } + if (verbosity) { + PR_fprintf(debug_out, "thread %d posting event\n", data->index); + } + if (PR_SetPollableEvent(data->next->event) == PR_FAILURE) { + PR_fprintf(PR_STDERR, "post event failed\n"); + exit(1); + } + } +} + +static void Help(void) +{ + debug_out = PR_STDOUT; + + PR_fprintf( + debug_out, "Usage: pollable [-c n] [-t n] [-d] [-v] [-G] [-C n] [-D n]\n"); + PR_fprintf( + debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS); + PR_fprintf( + debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS); + PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n"); + PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n"); + PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n"); + PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n"); + PR_fprintf(debug_out, "-D n\tdally setting (msecs) (default: 0)\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + ThreadData selfData; + ThreadData *data; + PRThread **thread; + void *block; + PRIntn i; + PRIntervalTime timeStart, timeEnd; + PRPollDesc pd; + PRInt32 rv; + PRThreadScope thread_scope = PR_LOCAL_THREAD; + PRBool help = PR_FALSE; + PRUintn concurrency = 1; + PRUintn average; + PLOptStatus os; + PLOptState *opt; + + PR_STDIO_INIT(); + + opt = PL_CreateOptState(argc, argv, "hdvc:t:C:GD:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) { + continue; + } + switch (opt->option) { + case 'v': /* verbose mode */ + verbosity = PR_TRUE; + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'c': /* loop counter */ + numIterations = atoi(opt->value); + break; + case 't': /* thread limit */ + numThreads = atoi(opt->value); + break; + case 'C': /* Concurrency limit */ + concurrency = atoi(opt->value); + break; + case 'G': /* global threads only */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'D': /* dally */ + dally = PR_MillisecondsToInterval(atoi(opt->value)); + break; + case 'h': /* help message */ + Help(); + help = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (help) { + return 1; + } + + if (concurrency > 1) { + PR_SetConcurrency(concurrency); + } + + if (PR_TRUE == debug_mode) { + debug_out = PR_STDOUT; + PR_fprintf(debug_out, "Test parameters\n"); + PR_fprintf(debug_out, "\tThreads involved: %d\n", numThreads); + PR_fprintf(debug_out, "\tIteration limit: %d\n", numIterations); + PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency); + PR_fprintf(debug_out, "\tThread type: %s\n", + (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); + } + + /* + * Malloc a block of memory and divide it into data and thread. + */ + block = PR_MALLOC(numThreads * (sizeof(ThreadData) + sizeof(PRThread *))); + if (block == NULL) { + PR_fprintf(PR_STDERR, "cannot malloc, failed\n"); + exit(1); + } + data = (ThreadData *) block; + thread = (PRThread **) &data[numThreads]; + + /* Pollable event */ + selfData.event = PR_NewPollableEvent(); + if (selfData.event == NULL) { + PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + selfData.next = &data[0]; + for (i = 0; i < numThreads; i++) { + data[i].event = PR_NewPollableEvent(); + if (data[i].event == NULL) { + PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + data[i].index = i; + if (i != numThreads - 1) { + data[i].next = &data[i + 1]; + } else { + data[i].next = &selfData; + } + + thread[i] = PR_CreateThread(PR_USER_THREAD, + ThreadRoutine, &data[i], PR_PRIORITY_NORMAL, + thread_scope, PR_JOINABLE_THREAD, 0); + if (thread[i] == NULL) { + PR_fprintf(PR_STDERR, "cannot create thread\n"); + exit(1); + } + } + + timeStart = PR_IntervalNow(); + pd.fd = selfData.event; + pd.in_flags = PR_POLL_READ; + for (i = 0; i < numIterations; i++) { + if (dally != PR_INTERVAL_NO_WAIT) { + PR_Sleep(dally); + } + if (verbosity) { + PR_fprintf(debug_out, "main thread posting event\n"); + } + if (PR_SetPollableEvent(selfData.next->event) == PR_FAILURE) { + PR_fprintf(PR_STDERR, "set event failed\n"); + exit(1); + } + rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); + if (rv == -1) { + PR_fprintf(PR_STDERR, "wait failed\n"); + exit(1); + } + PR_ASSERT(rv != 0); + PR_ASSERT(pd.out_flags & PR_POLL_READ); + if (verbosity) { + PR_fprintf(debug_out, "main thread awakened\n"); + } + if (PR_WaitForPollableEvent(selfData.event) == PR_FAILURE) { + PR_fprintf(PR_STDERR, "consume event failed\n"); + exit(1); + } + } + timeEnd = PR_IntervalNow(); + + if (debug_mode) { + average = PR_IntervalToMicroseconds(timeEnd - timeStart) + / (numIterations * numThreads); + PR_fprintf(debug_out, "Average switch times %d usecs for %d threads\n", + average, numThreads); + } + + for (i = 0; i < numThreads; i++) { + if (PR_JoinThread(thread[i]) == PR_FAILURE) { + PR_fprintf(PR_STDERR, "join thread failed\n"); + exit(1); + } + PR_DestroyPollableEvent(data[i].event); + } + PR_DELETE(block); + PR_DestroyPollableEvent(selfData.event); + + PR_fprintf(PR_STDOUT, "PASSED\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/poll_er.c nspr-4.10.7/nspr/pr/tests/poll_er.c --- nspr-4.9.5/nspr/pr/tests/poll_er.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/poll_er.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,210 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: prpoll_err.c +** +** Description: This program tests PR_Poll with sockets. +** error reporting operation is tested +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +#ifdef XP_BEOS +#include +int main() +{ + printf( "This test is not ported to the BeOS\n" ); + return 0; +} +#else + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "primpl.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + +static void +ClientThreadFunc(void *arg) +{ + PRFileDesc *badFD = (PRFileDesc *) arg; + /* + * Make the fd invalid + */ +#if defined(XP_UNIX) + close(PR_FileDesc2NativeHandle(badFD)); +#elif defined(XP_OS2) + soclose(PR_FileDesc2NativeHandle(badFD)); +#elif defined(WIN32) || defined(WIN16) + closesocket(PR_FileDesc2NativeHandle(badFD)); +#else +#error "Unknown architecture" +#endif +} + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock1, *listenSock2; + PRFileDesc *badFD; + PRUint16 listenPort1, listenPort2; + PRNetAddr addr; + char buf[128]; + PRPollDesc pds0[10], pds1[10], *pds, *other_pds; + PRIntn npds; + PRInt32 retVal; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (debug_mode) { + printf("This program tests PR_Poll with sockets.\n"); + printf("error reporting is tested.\n\n"); + } + + /* Create two listening sockets */ + if ((listenSock1 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = AF_INET; + addr.inet.ip = PR_htonl(INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort1 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock1, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + + if ((listenSock2 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = AF_INET; + addr.inet.ip = PR_htonl(INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort2 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock2, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu and %hu\n\n", + listenPort1, listenPort2); + if (debug_mode) printf("%s", buf); + + /* Set up the poll descriptor array */ + pds = pds0; + other_pds = pds1; + memset(pds, 0, sizeof(pds)); + pds[0].fd = listenSock1; + pds[0].in_flags = PR_POLL_READ; + pds[1].fd = listenSock2; + pds[1].in_flags = PR_POLL_READ; + npds = 2; + + + /* Testing bad fd */ + if (debug_mode) printf("PR_Poll should detect a bad file descriptor\n"); + if ((badFD = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a TCP socket\n"); + goto exit_now; + } + + pds[2].fd = badFD; + pds[2].in_flags = PR_POLL_READ; + npds = 3; + + if (PR_CreateThread(PR_USER_THREAD, ClientThreadFunc, + badFD, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0) == NULL) { + fprintf(stderr, "cannot create thread\n"); + exit(1); + } + + retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); + if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) { + fprintf(stderr, "Failed to detect the bad fd: " + "PR_Poll returns %d, out_flags is 0x%hx\n", + retVal, pds[2].out_flags); + failed_already=1; + goto exit_now; + } + if (debug_mode) printf("PR_Poll detected the bad fd. Test passed.\n\n"); + PR_Cleanup(); + goto exit_now; +exit_now: + if(failed_already) + return 1; + else + return 0; +} + +#endif /* XP_BEOS */ diff -Nru nspr-4.9.5/nspr/pr/tests/poll_nm.c nspr-4.10.7/nspr/pr/tests/poll_nm.c --- nspr-4.9.5/nspr/pr/tests/poll_nm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/poll_nm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,345 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: prpoll_norm.c +** +** Description: This program tests PR_Poll with sockets. +** Normal operation are tested +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prinit.h" +#include "prio.h" +#include "prlog.h" +#include "prprf.h" +#include "prnetdb.h" +#include "obsolete/probslet.h" + +#include "private/pprio.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + +#define NUM_ITERATIONS 5 + +static void PR_CALLBACK +clientThreadFunc(void *arg) +{ + PRUintn port = (PRUintn) arg; + PRFileDesc *sock; + PRNetAddr addr; + char buf[128]; + int i; + PRStatus sts; + PRInt32 n; + + addr.inet.family = PR_AF_INET; + addr.inet.port = PR_htons((PRUint16)port); + addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + memset(buf, 0, sizeof(buf)); + PR_snprintf(buf, sizeof(buf), "%hu", port); + + for (i = 0; i < NUM_ITERATIONS; i++) { + sock = PR_NewTCPSocket(); + PR_ASSERT(sock != NULL); + + sts = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(sts == PR_SUCCESS); + + n = PR_Write(sock, buf, sizeof(buf)); + PR_ASSERT(n >= 0); + + sts = PR_Close(sock); + PR_ASSERT(sts == PR_SUCCESS); + } +} + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL; + PRUint16 listenPort1, listenPort2; + PRNetAddr addr; + char buf[128]; + PRThread *clientThread; + PRPollDesc pds0[20], pds1[20], *pds, *other_pds; + PRIntn npds; + PRInt32 retVal; + PRIntn i, j; + PRSocketOptionData optval; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (debug_mode) { + printf("This program tests PR_Poll with sockets.\n"); + printf("Normal operation are tested.\n\n"); + } + + /* Create two listening sockets */ + if ((listenSock1 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + memset(&addr, 0, sizeof(addr)); + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort1 = PR_ntohs(addr.inet.port); + optval.option = PR_SockOpt_Nonblocking; + optval.value.non_blocking = PR_TRUE; + PR_SetSocketOption(listenSock1, &optval); + if (PR_Listen(listenSock1, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + + if ((listenSock2 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort2 = PR_ntohs(addr.inet.port); + PR_SetSocketOption(listenSock2, &optval); + if (PR_Listen(listenSock2, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu and %hu\n\n", + listenPort1, listenPort2); + if (debug_mode) printf("%s", buf); + + /* Set up the poll descriptor array */ + pds = pds0; + other_pds = pds1; + memset(pds, 0, sizeof(pds)); + pds[0].fd = listenSock1; + pds[0].in_flags = PR_POLL_READ; + pds[1].fd = listenSock2; + pds[1].in_flags = PR_POLL_READ; + /* Add some unused entries to test if they are ignored by PR_Poll() */ + memset(&pds[2], 0, sizeof(pds[2])); + memset(&pds[3], 0, sizeof(pds[3])); + memset(&pds[4], 0, sizeof(pds[4])); + npds = 5; + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort1, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + failed_already=1; + goto exit_now; + } + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort2, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + failed_already=1; + goto exit_now; + } + + if (debug_mode) { + printf("Two client threads are created. Each of them will\n"); + printf("send data to one of the two ports the server is listening on.\n"); + printf("The data they send is the port number. Each of them send\n"); + printf("the data five times, so you should see ten lines below,\n"); + printf("interleaved in an arbitrary order.\n"); + } + + /* two clients, three events per iteration: accept, read, close */ + i = 0; + while (i < 2 * 3 * NUM_ITERATIONS) { + PRPollDesc *tmp; + int nextIndex; + int nEvents = 0; + + retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(retVal != 0); /* no timeout */ + if (retVal == -1) { + fprintf(stderr, "PR_Poll failed\n"); + failed_already=1; + goto exit_now; + } + + nextIndex = 2; + /* the two listening sockets */ + for (j = 0; j < 2; j++) { + other_pds[j] = pds[j]; + PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 + && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); + if (pds[j].out_flags & PR_POLL_READ) { + PRFileDesc *sock; + + nEvents++; + sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT); + if (sock == NULL) { + fprintf(stderr, "PR_Accept() failed\n"); + failed_already=1; + goto exit_now; + } + other_pds[nextIndex].fd = sock; + other_pds[nextIndex].in_flags = PR_POLL_READ; + nextIndex++; + } else if (pds[j].out_flags & PR_POLL_ERR) { + fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); + failed_already=1; + goto exit_now; + } else if (pds[j].out_flags & PR_POLL_NVAL) { + fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n", + PR_FileDesc2NativeHandle(pds[j].fd)); + failed_already=1; + goto exit_now; + } + } + + for (j = 2; j < npds; j++) { + if (NULL == pds[j].fd) { + /* + * Keep the unused entries in the poll descriptor array + * for testing purposes. + */ + other_pds[nextIndex] = pds[j]; + nextIndex++; + continue; + } + + PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 + && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); + if (pds[j].out_flags & PR_POLL_READ) { + PRInt32 nAvail; + PRInt32 nRead; + + nEvents++; + nAvail = PR_Available(pds[j].fd); + nRead = PR_Read(pds[j].fd, buf, sizeof(buf)); + PR_ASSERT(nAvail == nRead); + if (nRead == -1) { + fprintf(stderr, "PR_Read() failed\n"); + failed_already=1; + goto exit_now; + } else if (nRead == 0) { + PR_Close(pds[j].fd); + continue; + } else { + /* Just to be safe */ + buf[127] = '\0'; + if (debug_mode) printf("The server received \"%s\" from a client\n", buf); + } + } else if (pds[j].out_flags & PR_POLL_ERR) { + fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); + failed_already=1; + goto exit_now; + } else if (pds[j].out_flags & PR_POLL_NVAL) { + fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n"); + failed_already=1; + goto exit_now; + } + other_pds[nextIndex] = pds[j]; + nextIndex++; + } + + PR_ASSERT(retVal == nEvents); + /* swap */ + tmp = pds; + pds = other_pds; + other_pds = tmp; + npds = nextIndex; + i += nEvents; + } + + if (debug_mode) printf("Tests passed\n"); + +exit_now: + + if (listenSock1) { + PR_Close(listenSock1); + } + if (listenSock2) { + PR_Close(listenSock2); + } + + PR_Cleanup(); + + if(failed_already) + return 1; + else + return 0; + +} diff -Nru nspr-4.9.5/nspr/pr/tests/poll_to.c nspr-4.10.7/nspr/pr/tests/poll_to.c --- nspr-4.9.5/nspr/pr/tests/poll_to.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/poll_to.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,181 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: prpoll_to.c +** +** Description: This program tests PR_Poll with sockets. +** Timeout operation is tested +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prinit.h" +#include "prio.h" +#include "prlog.h" +#include "prprf.h" +#include "prnetdb.h" + +#include "private/pprio.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL; + PRUint16 listenPort1, listenPort2; + PRNetAddr addr; + char buf[128]; + PRPollDesc pds0[10], pds1[10], *pds, *other_pds; + PRIntn npds; + PRInt32 retVal; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (debug_mode) { + printf("This program tests PR_Poll with sockets.\n"); + printf("Timeout is tested.\n\n"); + } + + /* Create two listening sockets */ + if ((listenSock1 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + memset(&addr, 0, sizeof(addr)); + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + listenPort1 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock1, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + + if ((listenSock2 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + listenPort2 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock2, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + if (!debug_mode) failed_already=1; + goto exit_now; + } + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu and %hu\n\n", + listenPort1, listenPort2); + if (debug_mode) printf("%s", buf); + + /* Set up the poll descriptor array */ + pds = pds0; + other_pds = pds1; + memset(pds, 0, sizeof(pds)); + pds[0].fd = listenSock1; + pds[0].in_flags = PR_POLL_READ; + pds[1].fd = listenSock2; + pds[1].in_flags = PR_POLL_READ; + npds = 2; + + /* Testing timeout */ + if (debug_mode) printf("PR_Poll should time out in 5 seconds\n"); + retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5)); + if (retVal != 0) { + PR_snprintf(buf, sizeof(buf), + "PR_Poll should time out and return 0, but it returns %ld\n", + retVal); + fprintf(stderr, "%s", buf); + if (!debug_mode) failed_already=1; + goto exit_now; + } + if (debug_mode) printf("PR_Poll timed out. Test passed.\n\n"); + +exit_now: + + if (listenSock1) { + PR_Close(listenSock1); + } + if (listenSock2) { + PR_Close(listenSock2); + } + + PR_Cleanup(); + + if(failed_already) + return 1; + else + return 0; + +} diff -Nru nspr-4.9.5/nspr/pr/tests/prfdbl.c nspr-4.10.7/nspr/pr/tests/prfdbl.c --- nspr-4.9.5/nspr/pr/tests/prfdbl.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/prfdbl.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This is a simple test of the PR_fprintf() function for doubles. + */ + +#include "prprf.h" + +int main() +{ + double pi = 3.1415926; + double e = 2.71828; + double root2 = 1.414; + double zero = 0.0; + double nan = zero / zero; + + PR_fprintf(PR_STDOUT, "pi is %f.\n", pi); + PR_fprintf(PR_STDOUT, "e is %f.\n", e); + PR_fprintf(PR_STDOUT, "The square root of 2 is %f.\n", root2); + PR_fprintf(PR_STDOUT, "NaN is %f.\n", nan); + + PR_fprintf(PR_STDOUT, "pi is %301f.\n", pi); + PR_fprintf(PR_STDOUT, "e is %65416.123f.\n", e); + PR_fprintf(PR_STDOUT, "e is %0000000000000000000065416.123f.\n", e); + PR_fprintf(PR_STDOUT, "NaN is %1024.1f.\n", nan); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/prftest1.c nspr-4.10.7/nspr/pr/tests/prftest1.c --- nspr-4.9.5/nspr/pr/tests/prftest1.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/prftest1.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prftest1.c +** Description: +** This is a simple test of the PR_snprintf() function defined +** in prprf.c. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" +#include "prttools.h" + +#include "prinit.h" +#include "prlong.h" +#include "prprf.h" + +#include + +#define BUF_SIZE 128 + +/*********************************************************************** +** PRIVATE FUNCTION: Test_Result +** DESCRIPTION: Used in conjunction with the regress tool, prints out the +** status of the test case. +** INPUTS: PASS/FAIL +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** +** RESTRICTIONS: +** None +** MEMORY: NA +** ALGORITHM: Determine what the status is and print accordingly. +** +***********************************************************************/ + + +static void Test_Result (int result) +{ + if (result == PASS) + printf ("PASS\n"); + else + printf ("FAIL\n"); +} + +int main(int argc, char **argv) +{ + PRInt16 i16; + PRIntn n; + PRInt32 i32; + PRInt64 i64; + char buf[BUF_SIZE]; + char answer[BUF_SIZE]; + int i; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + PR_STDIO_INIT(); + + i16 = -1; + n = -1; + i32 = -1; + LL_I2L(i64, i32); + + PR_snprintf(buf, BUF_SIZE, "%hx %x %lx %llx", i16, n, i32, i64); + strcpy(answer, "ffff "); + for (i = PR_BYTES_PER_INT * 2; i; i--) { + strcat(answer, "f"); + } + strcat(answer, " ffffffff ffffffffffffffff"); + + if (!strcmp(buf, answer)) { + if (debug_mode) printf("PR_snprintf test 1 passed\n"); + else Test_Result (PASS); + } else { + if (debug_mode) { + printf("PR_snprintf test 1 failed\n"); + printf("Converted string is %s\n", buf); + printf("Should be %s\n", answer); + } + else + Test_Result (FAIL); + } + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/prftest2.c nspr-4.10.7/nspr/pr/tests/prftest2.c --- nspr-4.9.5/nspr/pr/tests/prftest2.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/prftest2.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: prftest2.c +** Description: +** This is a simple test of the PR_snprintf() function defined +** in prprf.c. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prlong.h" +#include "prinit.h" +#include "prprf.h" + +#include + +#define BUF_SIZE 128 + +PRIntn failed_already=0; +PRIntn debug_mode; + +int main(int argc, char **argv) +{ + PRInt16 i16; + PRIntn n; + PRInt32 i32; + PRInt64 i64; + char buf[BUF_SIZE]; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + + PR_STDIO_INIT(); + i16 = -32; + n = 30; + i32 = 64; + LL_I2L(i64, 333); + PR_snprintf(buf, BUF_SIZE, "%d %hd %lld %ld", n, i16, i64, i32); + if (!strcmp(buf, "30 -32 333 64")) { + if (debug_mode) printf("PR_snprintf test 2 passed\n"); + } else { + if (debug_mode) { + printf("PR_snprintf test 2 failed\n"); + printf("Converted string is %s\n", buf); + printf("Should be 30 -32 333 64\n"); + } + else failed_already=1; + } + if(failed_already) + { + printf("FAILED\n"); + return 1; + } + else + { + printf("PASSED\n"); + return 0; + } +} diff -Nru nspr-4.9.5/nspr/pr/tests/prftest.c nspr-4.10.7/nspr/pr/tests/prftest.c --- nspr-4.9.5/nspr/pr/tests/prftest.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/prftest.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: prftest.c + * Description: + * This is a simple test of the PR_snprintf() function defined + * in prprf.c. + */ + +#include "prlong.h" +#include "prprf.h" + +#include + +#define BUF_SIZE 128 + +int main(int argc, char **argv) +{ + PRInt16 i16; + PRIntn n; + PRInt32 i32; + PRInt64 i64; + char buf[BUF_SIZE]; + char answer[BUF_SIZE]; + int i, rv = 0; + + i16 = -1; + n = -1; + i32 = -1; + LL_I2L(i64, i32); + + PR_snprintf(buf, BUF_SIZE, "%hx %x %lx %llx", i16, n, i32, i64); + strcpy(answer, "ffff "); + for (i = PR_BYTES_PER_INT * 2; i; i--) { + strcat(answer, "f"); + } + strcat(answer, " ffffffff ffffffffffffffff"); + + if (!strcmp(buf, answer)) { + printf("PR_snprintf test 1 passed\n"); + } else { + printf("PR_snprintf test 1 failed\n"); + printf("Converted string is %s\n", buf); + printf("Should be %s\n", answer); + rv = 1; + } + + i16 = -32; + n = 30; + i32 = 64; + LL_I2L(i64, 333); + PR_snprintf(buf, BUF_SIZE, "%d %hd %lld %ld", n, i16, i64, i32); + if (!strcmp(buf, "30 -32 333 64")) { + printf("PR_snprintf test 2 passed\n"); + } else { + printf("PR_snprintf test 2 failed\n"); + printf("Converted string is %s\n", buf); + printf("Should be 30 -32 333 64\n"); + rv = 1; + } + + return rv; +} diff -Nru nspr-4.9.5/nspr/pr/tests/primblok.c nspr-4.10.7/nspr/pr/tests/primblok.c --- nspr-4.9.5/nspr/pr/tests/primblok.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/primblok.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: primblok.c + * Purpose: testing whether the primordial thread can block in a + * native blocking function without affecting the correct + * functioning of NSPR I/O functions (Bugzilla bug #30746) + */ + +#if !defined(WINNT) + +#include + +int main(int argc, char **argv) +{ + printf("This test is not relevant on this platform\n"); + return 0; +} + +#else /* WINNT */ + +#include "nspr.h" + +#include +#include +#include +#include + +#define TEST_FILE_NAME "primblok.dat" + +/* use InterlockedExchange to update this variable */ +static LONG iothread_done; + +static void PR_CALLBACK IOThread(void *arg) +{ + PRFileDesc *fd; + char buf[32]; + PRInt32 nbytes; + + /* Give the primordial thread one second to block */ + Sleep(1000); + + /* + * See if our PR_Write call will hang when the primordial + * thread is blocking in a native blocking function. + */ + fd = PR_Open(TEST_FILE_NAME, PR_WRONLY|PR_CREATE_FILE, 0666); + if (NULL == fd) { + fprintf(stderr, "PR_Open failed\n"); + exit(1); + } + memset(buf, 0xaf, sizeof(buf)); + fprintf(stderr, "iothread: calling PR_Write\n"); + nbytes = PR_Write(fd, buf, sizeof(buf)); + fprintf(stderr, "iothread: PR_Write returned\n"); + if (nbytes != sizeof(buf)) { + fprintf(stderr, "PR_Write returned %d\n", nbytes); + exit(1); + } + if (PR_Close(fd) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) { + fprintf(stderr, "PR_Delete failed\n"); + exit(1); + } + + /* Tell the main thread that we are done */ + InterlockedExchange(&iothread_done, 1); +} + +int main(int argc, char **argv) +{ + PRThread *iothread; + + /* Must be a global thread */ + iothread = PR_CreateThread( + PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (iothread == NULL) { + fprintf(stderr, "cannot create thread\n"); + exit(1); + } + + /* + * Block in a native blocking function. + * Give iothread 5 seconds to finish its task. + */ + Sleep(5000); + + /* + * Is iothread done or is it hung? + * + * I'm actually only interested in reading the value + * of iothread_done. I'm using InterlockedExchange as + * a thread-safe way to read iothread_done. + */ + if (InterlockedExchange(&iothread_done, 1) == 0) { + fprintf(stderr, "iothread is hung\n"); + fprintf(stderr, "FAILED\n"); + exit(1); + } + + if (PR_JoinThread(iothread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + printf("PASSED\n"); + return 0; +} /* main */ + +#endif /* WINNT */ diff -Nru nspr-4.9.5/nspr/pr/tests/priotest.c nspr-4.10.7/nspr/pr/tests/priotest.c --- nspr-4.9.5/nspr/pr/tests/priotest.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/priotest.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,194 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: priotest.c + * Purpose: testing priorities + */ + +#include "prcmon.h" +#include "prinit.h" +#include "prinrval.h" +#include "prlock.h" +#include "prlog.h" +#include "prmon.h" +#include "prprf.h" +#include "prthread.h" +#include "prtypes.h" + +#include "plerror.h" +#include "plgetopt.h" + +#include +#include + +#define DEFAULT_DURATION 5 + +static PRBool failed = PR_FALSE; +static PRIntervalTime oneSecond; +static PRFileDesc *debug_out = NULL; +static PRBool debug_mode = PR_FALSE; + +static PRUint32 PerSecond(PRIntervalTime timein) +{ + PRUint32 loop = 0; + while (((PRIntervalTime)(PR_IntervalNow()) - timein) < oneSecond) + loop += 1; + return loop; +} /* PerSecond */ + +static void PR_CALLBACK Low(void *arg) +{ + PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg; + while (1) + { + t0 = PerSecond(PR_IntervalNow()); + *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8; + t3 = t2; t2 = t1; t1 = t0; + } +} /* Low */ + +static void PR_CALLBACK High(void *arg) +{ + PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg; + while (1) + { + PRIntervalTime timein = PR_IntervalNow(); + PR_Sleep(oneSecond >> 2); /* 0.25 seconds */ + t0 = PerSecond(timein); + *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8; + t3 = t2; t2 = t1; t1 = t0; + } +} /* High */ + +static void Help(void) +{ + PR_fprintf( + debug_out, "Usage: priotest [-d] [-c n]\n"); + PR_fprintf( + debug_out, "-c n\tduration of test in seconds (default: %d)\n", DEFAULT_DURATION); + PR_fprintf( + debug_out, "-d\tturn on debugging output (default: FALSE)\n"); +} /* Help */ + +static void RudimentaryTests(void) +{ + /* + ** Try some rudimentary tests like setting valid priority and + ** getting it back, or setting invalid priorities and getting + ** back a valid answer. + */ + PRThreadPriority priority; + PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT); + priority = PR_GetThreadPriority(PR_GetCurrentThread()); + failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority)) + ? PR_TRUE : PR_FALSE; + if (debug_mode && (PR_PRIORITY_URGENT != priority)) + { + PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n"); + } + + + PR_SetThreadPriority( + PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1)); + priority = PR_GetThreadPriority(PR_GetCurrentThread()); + failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority)) + ? PR_TRUE : PR_FALSE; + if (debug_mode && (PR_PRIORITY_FIRST != priority)) + { + PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n"); + } + + PR_SetThreadPriority( + PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1)); + priority = PR_GetThreadPriority(PR_GetCurrentThread()); + failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority)) + ? PR_TRUE : PR_FALSE; + if (debug_mode && (PR_PRIORITY_LAST != priority)) + { + PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n"); + } + +} /* RudimentataryTests */ + +static void CreateThreads(PRUint32 *lowCount, PRUint32 *highCount) +{ + (void)PR_CreateThread( + PR_USER_THREAD, Low, lowCount, PR_PRIORITY_LOW, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + (void)PR_CreateThread( + PR_USER_THREAD, High, highCount, PR_PRIORITY_HIGH, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); +} /* CreateThreads */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + PRIntn duration = DEFAULT_DURATION; + PRUint32 totalCount, highCount = 0, lowCount = 0; + PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:"); + + debug_out = PR_STDOUT; + oneSecond = PR_SecondsToInterval(1); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'c': /* test duration */ + duration = atoi(opt->value); + break; + case 'h': /* help message */ + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + PR_STDIO_INIT(); + + if (duration == 0) duration = DEFAULT_DURATION; + + RudimentaryTests(); + + printf("Priority test: running for %d seconds\n\n", duration); + + (void)PerSecond(PR_IntervalNow()); + totalCount = PerSecond(PR_IntervalNow()); + + PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT); + + if (debug_mode) + { + PR_fprintf(debug_out, + "The high priority thread should get approximately three\n"); + PR_fprintf( debug_out, + "times what the low priority thread manages. A maximum of \n"); + PR_fprintf( debug_out, "%d cycles are available.\n\n", totalCount); + } + + duration = (duration + 4) / 5; + CreateThreads(&lowCount, &highCount); + while (duration--) + { + PRIntn loop = 5; + while (loop--) PR_Sleep(oneSecond); + if (debug_mode) + PR_fprintf(debug_out, "high : low :: %d : %d\n", highCount, lowCount); + } + + + PR_ProcessExit((failed) ? 1 : 0); + + PR_ASSERT(!"You can't get here -- but you did!"); + return 1; /* or here */ + +} /* main */ + +/* priotest.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/provider.c nspr-4.10.7/nspr/pr/tests/provider.c --- nspr-4.9.5/nspr/pr/tests/provider.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/provider.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,1354 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Notes: + * [1] lth. The call to Sleep() is a hack to get the test case to run + * on Windows 95. Without it, the test case fails with an error + * WSAECONNRESET following a recv() call. The error is caused by the + * server side thread termination without a shutdown() or closesocket() + * call. Windows docmunentation suggests that this is predicted + * behavior; that other platforms get away with it is ... serindipity. + * The test case should shutdown() or closesocket() before + * thread termination. I didn't have time to figure out where or how + * to do it. The Sleep() call inserts enough delay to allow the + * client side to recv() all his data before the server side thread + * terminates. Whew! ... + * + ** Modification History: + * 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. + * The debug mode will print all of the printfs associated with this test. + * The regress mode will be the default mode. Since the regress tool limits + * the output to a one line status:PASS or FAIL,all of the printf statements + * have been handled with an if (debug_mode) statement. + */ + +#include "prclist.h" +#include "prcvar.h" +#include "prerror.h" +#include "prinit.h" +#include "prinrval.h" +#include "prio.h" +#include "prlock.h" +#include "prlog.h" +#include "prtime.h" +#include "prmem.h" +#include "prnetdb.h" +#include "prprf.h" +#include "prthread.h" + +#include "pprio.h" +#include "primpl.h" + +#include "plstr.h" +#include "plerror.h" +#include "plgetopt.h" + +#include +#include + +#if defined(XP_UNIX) +#include +#endif + +/* +** This is the beginning of the test +*/ + +#define RECV_FLAGS 0 +#define SEND_FLAGS 0 +#define BUFFER_SIZE 1024 +#define DEFAULT_BACKLOG 5 +#define DEFAULT_PORT 13000 +#define DEFAULT_CLIENTS 1 +#define ALLOWED_IN_ACCEPT 1 +#define DEFAULT_CLIPPING 1000 +#define DEFAULT_WORKERS_MIN 1 +#define DEFAULT_WORKERS_MAX 1 +#define DEFAULT_SERVER "localhost" +#define DEFAULT_EXECUTION_TIME 10 +#define DEFAULT_CLIENT_TIMEOUT 4000 +#define DEFAULT_SERVER_TIMEOUT 4000 +#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGH + +typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t; + +static void PR_CALLBACK Worker(void *arg); +typedef struct CSPool_s CSPool_t; +typedef struct CSWorker_s CSWorker_t; +typedef struct CSServer_s CSServer_t; +typedef enum Verbosity +{ + TEST_LOG_ALWAYS, + TEST_LOG_ERROR, + TEST_LOG_WARNING, + TEST_LOG_NOTICE, + TEST_LOG_INFO, + TEST_LOG_STATUS, + TEST_LOG_VERBOSE +} Verbosity; + +static enum { + thread_nspr, thread_pthread, thread_sproc, thread_win32 +} thread_provider; + +static PRInt32 domain = AF_INET; +static PRInt32 protocol = 6; /* TCP */ +static PRFileDesc *debug_out = NULL; +static PRBool debug_mode = PR_FALSE; +static PRBool pthread_stats = PR_FALSE; +static Verbosity verbosity = TEST_LOG_ALWAYS; +static PRThreadScope thread_scope = PR_LOCAL_THREAD; + +struct CSWorker_s +{ + PRCList element; /* list of the server's workers */ + + PRThread *thread; /* this worker objects thread */ + CSServer_t *server; /* back pointer to server structure */ +}; + +struct CSPool_s +{ + PRCondVar *exiting; + PRCondVar *acceptComplete; + PRUint32 accepting, active, workers; +}; + +struct CSServer_s +{ + PRCList list; /* head of worker list */ + + PRLock *ml; + PRThread *thread; /* the main server thread */ + PRCondVar *stateChange; + + PRUint16 port; /* port we're listening on */ + PRUint32 backlog; /* size of our listener backlog */ + PRFileDesc *listener; /* the fd accepting connections */ + + CSPool_t pool; /* statistics on worker threads */ + CSState_t state; /* the server's state */ + struct /* controlling worker counts */ + { + PRUint32 minimum, maximum, accepting; + } workers; + + /* statistics */ + PRIntervalTime started, stopped; + PRUint32 operations, bytesTransferred; +}; + +typedef struct CSDescriptor_s +{ + PRInt32 size; /* size of transfer */ + char filename[60]; /* filename, null padded */ +} CSDescriptor_t; + +typedef struct CSClient_s +{ + PRLock *ml; + PRThread *thread; + PRCondVar *stateChange; + PRNetAddr serverAddress; + + CSState_t state; + + /* statistics */ + PRIntervalTime started, stopped; + PRUint32 operations, bytesTransferred; +} CSClient_t; + +#define TEST_LOG(l, p, a) \ + do { \ + if (debug_mode || (p <= verbosity)) printf a; \ + } while (0) + +PRLogModuleInfo *cltsrv_log_file = NULL; + +#define MY_ASSERT(_expr) \ + ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__)) + +#define TEST_ASSERT(_expr) \ + ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__)) + +static void _MY_Assert(const char *s, const char *file, PRIntn ln) +{ + PL_PrintError(NULL); + PR_Assert(s, file, ln); +} /* _MY_Assert */ + +static PRBool Aborted(PRStatus rv) +{ + return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ? + PR_TRUE : PR_FALSE; +} + +static void TimeOfDayMessage(const char *msg, PRThread* me) +{ + char buffer[100]; + PRExplodedTime tod; + PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod); + (void)PR_FormatTime(buffer, sizeof(buffer), "%H:%M:%S", &tod); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("%s(0x%p): %s\n", msg, me, buffer)); +} /* TimeOfDayMessage */ + + +static void PR_CALLBACK Client(void *arg) +{ + PRStatus rv; + PRIntn index; + char buffer[1024]; + PRFileDesc *fd = NULL; + PRUintn clipping = DEFAULT_CLIPPING; + CSClient_t *client = (CSClient_t*)arg; + PRThread *me = client->thread = PR_GetCurrentThread(); + CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); + PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT); + + + for (index = 0; index < sizeof(buffer); ++index) + buffer[index] = (char)index; + + client->started = PR_IntervalNow(); + + PR_Lock(client->ml); + client->state = cs_run; + PR_NotifyCondVar(client->stateChange); + PR_Unlock(client->ml); + + TimeOfDayMessage("Client started at", me); + + while (cs_run == client->state) + { + PRInt32 bytes, descbytes, filebytes, netbytes; + + (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer)); + TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, + ("\tClient(0x%p): connecting to server at %s\n", me, buffer)); + + fd = PR_Socket(domain, SOCK_STREAM, protocol); + TEST_ASSERT(NULL != fd); + rv = PR_Connect(fd, &client->serverAddress, timeout); + if (PR_FAILURE == rv) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): conection failed\n", me)); + goto aborted; + } + + memset(descriptor, 0, sizeof(*descriptor)); + descriptor->size = PR_htonl(descbytes = rand() % clipping); + PR_snprintf( + descriptor->filename, sizeof(descriptor->filename), + "CS%p%p-%p.dat", client->started, me, client->operations); + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes)); + bytes = PR_Send( + fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout); + if (sizeof(CSDescriptor_t) != bytes) + { + if (Aborted(PR_FAILURE)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): send descriptor timeout\n", me)); + goto retry; + } + } + TEST_ASSERT(sizeof(*descriptor) == bytes); + + netbytes = 0; + while (netbytes < descbytes) + { + filebytes = sizeof(buffer); + if ((descbytes - netbytes) < filebytes) + filebytes = descbytes - netbytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tClient(0x%p): sending %d bytes\n", me, filebytes)); + bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); + if (filebytes != bytes) + { + if (Aborted(PR_FAILURE)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): send data timeout\n", me)); + goto retry; + } + } + TEST_ASSERT(bytes == filebytes); + netbytes += bytes; + } + filebytes = 0; + while (filebytes < descbytes) + { + netbytes = sizeof(buffer); + if ((descbytes - filebytes) < netbytes) + netbytes = descbytes - filebytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tClient(0x%p): receiving %d bytes\n", me, netbytes)); + bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); + if (-1 == bytes) + { + if (Aborted(PR_FAILURE)) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): receive data aborted\n", me)); + goto aborted; + } + else if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): receive data timeout\n", me)); + else + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tClient(0x%p): receive error (%d, %d)\n", + me, PR_GetError(), PR_GetOSError())); + goto retry; + } + if (0 == bytes) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tClient(0x%p): unexpected end of stream\n", + PR_GetCurrentThread())); + break; + } + filebytes += bytes; + } + + rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); + if (Aborted(rv)) goto aborted; + TEST_ASSERT(PR_SUCCESS == rv); +retry: + (void)PR_Close(fd); fd = NULL; + TEST_LOG( + cltsrv_log_file, TEST_LOG_INFO, + ("\tClient(0x%p): disconnected from server\n", me)); + + PR_Lock(client->ml); + client->operations += 1; + client->bytesTransferred += 2 * descbytes; + rv = PR_WaitCondVar(client->stateChange, rand() % clipping); + PR_Unlock(client->ml); + if (Aborted(rv)) break; + } + +aborted: + client->stopped = PR_IntervalNow(); + + PR_ClearInterrupt(); + if (NULL != fd) rv = PR_Close(fd); + + PR_Lock(client->ml); + client->state = cs_exit; + PR_NotifyCondVar(client->stateChange); + PR_Unlock(client->ml); + PR_DELETE(descriptor); + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("\tClient(0x%p): stopped after %u operations and %u bytes\n", + PR_GetCurrentThread(), client->operations, client->bytesTransferred)); + +} /* Client */ + +static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server) +{ + PRStatus drv, rv; + char buffer[1024]; + PRFileDesc *file = NULL; + PRThread * me = PR_GetCurrentThread(); + PRInt32 bytes, descbytes, netbytes, filebytes = 0; + CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); + PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tProcessRequest(0x%p): receiving desciptor\n", me)); + bytes = PR_Recv( + fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout); + if (-1 == bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto exit; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tProcessRequest(0x%p): receive timeout\n", me)); + } + goto exit; + } + if (0 == bytes) + { + rv = PR_FAILURE; + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tProcessRequest(0x%p): unexpected end of file\n", me)); + goto exit; + } + descbytes = PR_ntohl(descriptor->size); + TEST_ASSERT(sizeof(*descriptor) == bytes); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", + me, descbytes, descriptor->filename)); + + file = PR_Open( + descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666); + if (NULL == file) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\tProcessRequest(0x%p): open file timeout\n", me)); + goto aborted; + } + } + TEST_ASSERT(NULL != file); + + filebytes = 0; + while (filebytes < descbytes) + { + netbytes = sizeof(buffer); + if ((descbytes - filebytes) < netbytes) + netbytes = descbytes - filebytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)); + bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); + if (-1 == bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): receive data timeout\n", me)); + goto aborted; + } + /* + * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED) + * on NT here. This is equivalent to ECONNRESET on Unix. + * -wtc + */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_WARNING, + ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", + me, PR_GetError(), PR_GetOSError())); + goto aborted; + } + if(0 == bytes) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_WARNING, + ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)); + rv = PR_FAILURE; + goto aborted; + } + filebytes += bytes; + netbytes = bytes; + /* The byte count for PR_Write should be positive */ + MY_ASSERT(netbytes > 0); + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes)); + bytes = PR_Write(file, buffer, netbytes); + if (netbytes != bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): write file timeout\n", me)); + goto aborted; + } + } + TEST_ASSERT(bytes > 0); + } + + PR_Lock(server->ml); + server->operations += 1; + server->bytesTransferred += filebytes; + PR_Unlock(server->ml); + + rv = PR_Close(file); file = NULL; + if (Aborted(rv)) goto aborted; + TEST_ASSERT(PR_SUCCESS == rv); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename)); + file = PR_Open(descriptor->filename, PR_RDONLY, 0); + if (NULL == file) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): open file timeout\n", + PR_GetCurrentThread())); + goto aborted; + } + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n", + me, PR_GetError(), PR_GetOSError())); + goto aborted; + } + TEST_ASSERT(NULL != file); + + netbytes = 0; + while (netbytes < descbytes) + { + filebytes = sizeof(buffer); + if ((descbytes - netbytes) < filebytes) + filebytes = descbytes - netbytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes)); + bytes = PR_Read(file, buffer, filebytes); + if (filebytes != bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): read file timeout\n", me)); + else + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", + me, PR_GetError(), PR_GetOSError())); + goto aborted; + } + TEST_ASSERT(bytes > 0); + netbytes += bytes; + filebytes = bytes; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes)); + bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); + if (filebytes != bytes) + { + rv = PR_FAILURE; + if (Aborted(rv)) goto aborted; + if (PR_IO_TIMEOUT_ERROR == PR_GetError()) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tProcessRequest(0x%p): send data timeout\n", me)); + goto aborted; + } + break; + } + TEST_ASSERT(bytes > 0); + } + + PR_Lock(server->ml); + server->bytesTransferred += filebytes; + PR_Unlock(server->ml); + + rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); + if (Aborted(rv)) goto aborted; + + rv = PR_Close(file); file = NULL; + if (Aborted(rv)) goto aborted; + TEST_ASSERT(PR_SUCCESS == rv); + +aborted: + PR_ClearInterrupt(); + if (NULL != file) PR_Close(file); + drv = PR_Delete(descriptor->filename); + TEST_ASSERT(PR_SUCCESS == drv); +exit: + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tProcessRequest(0x%p): Finished\n", me)); + + PR_DELETE(descriptor); + +#if defined(WIN95) + PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */ +#endif + return rv; +} /* ProcessRequest */ + +typedef void (*StartFn)(void*); +typedef struct StartObject +{ + StartFn start; + void *arg; +} StartObject; + +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) +#include "md/_pth.h" +#include + +static void *pthread_start(void *arg) +{ + StartObject *so = (StartObject*)arg; + StartFn start = so->start; + void *data = so->arg; + PR_Free(so); + start(data); + return NULL; +} /* pthread_start */ +#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ + +#if defined(IRIX) && !defined(_PR_PTHREADS) +#include +#include +static void sproc_start(void *arg, PRSize size) +{ + StartObject *so = (StartObject*)arg; + StartFn start = so->start; + void *data = so->arg; + PR_Free(so); + start(data); +} /* sproc_start */ +#endif /* defined(IRIX) && !defined(_PR_PTHREADS) */ + +#if defined(WIN32) +#include /* for _beginthreadex() */ + +static PRUintn __stdcall windows_start(void *arg) +{ + StartObject *so = (StartObject*)arg; + StartFn start = so->start; + void *data = so->arg; + PR_Free(so); + start(data); + return 0; +} /* windows_start */ +#endif /* defined(WIN32) */ + +static PRStatus JoinThread(PRThread *thread) +{ + PRStatus rv; + switch (thread_provider) + { + case thread_nspr: + rv = PR_JoinThread(thread); + break; + case thread_pthread: +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) + rv = PR_SUCCESS; + break; +#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ + case thread_win32: +#if defined(WIN32) + rv = PR_SUCCESS; + break; +#endif + default: + rv = PR_FAILURE; + break; + } + return rv; +} /* JoinThread */ + +static PRStatus NewThread( + StartFn start, void *arg, PRThreadPriority prio, PRThreadState state) +{ + PRStatus rv; + + switch (thread_provider) + { + case thread_nspr: + { + PRThread *thread = PR_CreateThread( + PR_USER_THREAD, start, arg, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, 0); + rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS; + } + break; + case thread_pthread: +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) + { + int rv; + pthread_t id; + pthread_attr_t tattr; + StartObject *start_object; + start_object = PR_NEW(StartObject); + PR_ASSERT(NULL != start_object); + start_object->start = start; + start_object->arg = arg; + + rv = _PT_PTHREAD_ATTR_INIT(&tattr); + PR_ASSERT(0 == rv); + + rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); + PR_ASSERT(0 == rv); + + rv = pthread_attr_setstacksize(&tattr, 64 * 1024); + PR_ASSERT(0 == rv); + + rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object); + (void)_PT_PTHREAD_ATTR_DESTROY(&tattr); + return (0 == rv) ? PR_SUCCESS : PR_FAILURE; + } +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; +#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */ + break; + + case thread_sproc: +#if defined(IRIX) && !defined(_PR_PTHREADS) + { + PRInt32 pid; + StartObject *start_object; + start_object = PR_NEW(StartObject); + PR_ASSERT(NULL != start_object); + start_object->start = start; + start_object->arg = arg; + pid = sprocsp( + sproc_start, PR_SALL, start_object, NULL, 64 * 1024); + rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE; + } +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; +#endif /* defined(IRIX) && !defined(_PR_PTHREADS) */ + break; + case thread_win32: +#if defined(WIN32) + { + void *th; + PRUintn id; + StartObject *start_object; + start_object = PR_NEW(StartObject); + PR_ASSERT(NULL != start_object); + start_object->start = start; + start_object->arg = arg; + th = (void*)_beginthreadex( + NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */ + 0U, /* DWORD - initial thread stack size, in bytes */ + windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */ + start_object, /* LPVOID - argument for new thread */ + STACK_SIZE_PARAM_IS_A_RESERVATION, /*DWORD dwCreationFlags - creation flags */ + &id /* LPDWORD - pointer to returned thread identifier */ ); + + rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS; + } +#else + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; +#endif + break; + default: + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + rv = PR_FAILURE; + } + return rv; +} /* NewThread */ + +static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool) +{ + PRStatus rv; + CSWorker_t *worker = PR_NEWZAP(CSWorker_t); + worker->server = server; + PR_INIT_CLIST(&worker->element); + rv = NewThread( + Worker, worker, DEFAULT_SERVER_PRIORITY, PR_UNJOINABLE_THREAD); + if (PR_FAILURE == rv) PR_DELETE(worker); + + TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, + ("\tCreateWorker(0x%p): create new worker (0x%p)\n", + PR_GetCurrentThread(), worker->thread)); + + return rv; +} /* CreateWorker */ + +static void PR_CALLBACK Worker(void *arg) +{ + PRStatus rv; + PRNetAddr from; + PRFileDesc *fd = NULL; + CSWorker_t *worker = (CSWorker_t*)arg; + CSServer_t *server = worker->server; + CSPool_t *pool = &server->pool; + + PRThread *me = worker->thread = PR_GetCurrentThread(); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1)); + + PR_Lock(server->ml); + PR_APPEND_LINK(&worker->element, &server->list); + pool->workers += 1; /* define our existance */ + + while (cs_run == server->state) + { + while (pool->accepting >= server->workers.accepting) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tWorker(0x%p): waiting for accept slot[%d]\n", + me, pool->accepting)); + rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT); + if (Aborted(rv) || (cs_run != server->state)) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("\tWorker(0x%p): has been %s\n", + me, (Aborted(rv) ? "interrupted" : "stopped"))); + goto exit; + } + } + pool->accepting += 1; /* how many are really in accept */ + PR_Unlock(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\t\tWorker(0x%p): calling accept\n", me)); + fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT); + + PR_Lock(server->ml); + pool->accepting -= 1; + PR_NotifyCondVar(pool->acceptComplete); + + if ((NULL == fd) && Aborted(PR_FAILURE)) + { + if (NULL != server->listener) + { + PR_Close(server->listener); + server->listener = NULL; + } + goto exit; + } + + if (NULL != fd) + { + /* + ** Create another worker of the total number of workers is + ** less than the minimum specified or we have none left in + ** accept() AND we're not over the maximum. + ** This sort of presumes that the number allowed in accept + ** is at least as many as the minimum. Otherwise we'll keep + ** creating new threads and deleting them soon after. + */ + PRBool another = + ((pool->workers < server->workers.minimum) || + ((0 == pool->accepting) + && (pool->workers < server->workers.maximum))) ? + PR_TRUE : PR_FALSE; + pool->active += 1; + PR_Unlock(server->ml); + + if (another) (void)CreateWorker(server, pool); + + rv = ProcessRequest(fd, server); + if (PR_SUCCESS != rv) + TEST_LOG( + cltsrv_log_file, TEST_LOG_ERROR, + ("\t\tWorker(0x%p): server process ended abnormally\n", me)); + (void)PR_Close(fd); fd = NULL; + + PR_Lock(server->ml); + pool->active -= 1; + } + } + +exit: + PR_ClearInterrupt(); + PR_Unlock(server->ml); + + if (NULL != fd) + { + (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH); + (void)PR_Close(fd); + } + + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers)); + + PR_Lock(server->ml); + pool->workers -= 1; /* undefine our existance */ + PR_REMOVE_AND_INIT_LINK(&worker->element); + PR_NotifyCondVar(pool->exiting); + PR_Unlock(server->ml); + + PR_DELETE(worker); /* destruction of the "worker" object */ + +} /* Worker */ + +static void PR_CALLBACK Server(void *arg) +{ + PRStatus rv; + PRNetAddr serverAddress; + CSServer_t *server = (CSServer_t*)arg; + PRThread *me = server->thread = PR_GetCurrentThread(); + PRSocketOptionData sockOpt; + + server->listener = PR_Socket(domain, SOCK_STREAM, protocol); + + sockOpt.option = PR_SockOpt_Reuseaddr; + sockOpt.value.reuse_addr = PR_TRUE; + rv = PR_SetSocketOption(server->listener, &sockOpt); + TEST_ASSERT(PR_SUCCESS == rv); + + memset(&serverAddress, 0, sizeof(serverAddress)); + rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress); + + rv = PR_Bind(server->listener, &serverAddress); + TEST_ASSERT(PR_SUCCESS == rv); + + rv = PR_Listen(server->listener, server->backlog); + TEST_ASSERT(PR_SUCCESS == rv); + + server->started = PR_IntervalNow(); + TimeOfDayMessage("Server started at", me); + + PR_Lock(server->ml); + server->state = cs_run; + PR_NotifyCondVar(server->stateChange); + PR_Unlock(server->ml); + + /* + ** Create the first worker (actually, a thread that accepts + ** connections and then processes the work load as needed). + ** From this point on, additional worker threads are created + ** as they are needed by existing worker threads. + */ + rv = CreateWorker(server, &server->pool); + TEST_ASSERT(PR_SUCCESS == rv); + + /* + ** From here on this thread is merely hanging around as the contact + ** point for the main test driver. It's just waiting for the driver + ** to declare the test complete. + */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tServer(0x%p): waiting for state change\n", me)); + + PR_Lock(server->ml); + while ((cs_run == server->state) && !Aborted(rv)) + { + rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(server->ml); + PR_ClearInterrupt(); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_INFO, + ("\tServer(0x%p): shutting down workers\n", me)); + + /* + ** Get all the worker threads to exit. They know how to + ** clean up after themselves, so this is just a matter of + ** waiting for clorine in the pool to take effect. During + ** this stage we're ignoring interrupts. + */ + server->workers.minimum = server->workers.maximum = 0; + + PR_Lock(server->ml); + while (!PR_CLIST_IS_EMPTY(&server->list)) + { + PRCList *head = PR_LIST_HEAD(&server->list); + CSWorker_t *worker = (CSWorker_t*)head; + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker)); + rv = PR_Interrupt(worker->thread); + TEST_ASSERT(PR_SUCCESS == rv); + PR_REMOVE_AND_INIT_LINK(head); + } + + while (server->pool.workers > 0) + { + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("\tServer(0x%p): waiting for %u workers to exit\n", + me, server->pool.workers)); + (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT); + } + + server->state = cs_exit; + PR_NotifyCondVar(server->stateChange); + PR_Unlock(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("\tServer(0x%p): stopped after %u operations and %u bytes\n", + me, server->operations, server->bytesTransferred)); + + if (NULL != server->listener) PR_Close(server->listener); + server->stopped = PR_IntervalNow(); + +} /* Server */ + +static void WaitForCompletion(PRIntn execution) +{ + while (execution > 0) + { + PRIntn dally = (execution > 30) ? 30 : execution; + PR_Sleep(PR_SecondsToInterval(dally)); + if (pthread_stats) PT_FPrintStats(debug_out, "\nPThread Statistics\n"); + execution -= dally; + } +} /* WaitForCompletion */ + +static void Help(void) +{ + PR_fprintf(debug_out, "cltsrv test program usage:\n"); + PR_fprintf(debug_out, "\t-a threads allowed in accept (5)\n"); + PR_fprintf(debug_out, "\t-b backlock for listen (5)\n"); + PR_fprintf(debug_out, "\t-c number of clients to create (1)\n"); + PR_fprintf(debug_out, "\t-w minimal number of server threads (1)\n"); + PR_fprintf(debug_out, "\t-W maximum number of server threads (1)\n"); + PR_fprintf(debug_out, "\t-e duration of the test in seconds (10)\n"); + PR_fprintf(debug_out, "\t-s dsn name of server (localhost)\n"); + PR_fprintf(debug_out, "\t-G use GLOBAL threads (LOCAL)\n"); + PR_fprintf(debug_out, "\t-T thread provider ('n' | 'p' | 'w')(n)\n"); + PR_fprintf(debug_out, "\t-X use XTP as transport (TCP)\n"); + PR_fprintf(debug_out, "\t-6 Use IPv6 (IPv4)\n"); + PR_fprintf(debug_out, "\t-v verbosity (accumulative) (0)\n"); + PR_fprintf(debug_out, "\t-p pthread statistics (FALSE)\n"); + PR_fprintf(debug_out, "\t-d debug mode (FALSE)\n"); + PR_fprintf(debug_out, "\t-h this message\n"); +} /* Help */ + +static Verbosity IncrementVerbosity(void) +{ + PRIntn verboge = (PRIntn)verbosity + 1; + return (Verbosity)verboge; +} /* IncrementVerbosity */ + +int main(int argc, char **argv) +{ + PRUintn index; + PRBool boolean; + CSClient_t *client; + PRStatus rv, joinStatus; + CSServer_t *server = NULL; + char *thread_type; + + PRUintn backlog = DEFAULT_BACKLOG; + PRUintn clients = DEFAULT_CLIENTS; + const char *serverName = DEFAULT_SERVER; + PRBool serverIsLocal = PR_TRUE; + PRUintn accepting = ALLOWED_IN_ACCEPT; + PRUintn workersMin = DEFAULT_WORKERS_MIN; + PRUintn workersMax = DEFAULT_WORKERS_MAX; + PRIntn execution = DEFAULT_EXECUTION_TIME; + + /* + * -G use global threads + * -a threads allowed in accept + * -b backlock for listen + * -c number of clients to create + * -w minimal number of server threads + * -W maximum number of server threads + * -e duration of the test in seconds + * -s dsn name of server (implies no server here) + * -v verbosity + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:w:W:e:s:T:vdhp"); + +#if defined(WIN32) + thread_provider = thread_win32; +#elif defined(_PR_PTHREADS) + thread_provider = thread_pthread; +#elif defined(IRIX) + thread_provider = thread_sproc; +#else + thread_provider = thread_nspr; +#endif + + debug_out = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'G': /* use global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'X': /* use XTP as transport */ + protocol = 36; + break; + case '6': /* Use IPv6 */ + domain = PR_AF_INET6; + break; + case 'a': /* the value for accepting */ + accepting = atoi(opt->value); + break; + case 'b': /* the value for backlock */ + backlog = atoi(opt->value); + break; + case 'T': /* the thread provider */ + if ('n' == *opt->value) thread_provider = thread_nspr; + else if ('p' == *opt->value) thread_provider = thread_pthread; + else if ('w' == *opt->value) thread_provider = thread_win32; + else {Help(); return 2; } + break; + case 'c': /* number of client threads */ + clients = atoi(opt->value); + break; + case 'w': /* minimum server worker threads */ + workersMin = atoi(opt->value); + break; + case 'W': /* maximum server worker threads */ + workersMax = atoi(opt->value); + break; + case 'e': /* program execution time in seconds */ + execution = atoi(opt->value); + break; + case 's': /* server's address */ + serverName = opt->value; + break; + case 'v': /* verbosity */ + verbosity = IncrementVerbosity(); + break; + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'p': /* pthread mode */ + pthread_stats = PR_TRUE; + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE; + if (0 == execution) execution = DEFAULT_EXECUTION_TIME; + if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX; + if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN; + if (0 == accepting) accepting = ALLOWED_IN_ACCEPT; + if (0 == backlog) backlog = DEFAULT_BACKLOG; + + if (workersMin > accepting) accepting = workersMin; + + PR_STDIO_INIT(); + TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread()); + + cltsrv_log_file = PR_NewLogModule("cltsrv_log"); + MY_ASSERT(NULL != cltsrv_log_file); + boolean = PR_SetLogFile("cltsrv.log"); + MY_ASSERT(boolean); + + if (serverIsLocal) + { + /* Establish the server */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_INFO, + ("main(0x%p): starting server\n", PR_GetCurrentThread())); + + server = PR_NEWZAP(CSServer_t); + PR_INIT_CLIST(&server->list); + server->state = cs_init; + server->ml = PR_NewLock(); + server->backlog = backlog; + server->port = DEFAULT_PORT; + server->workers.minimum = workersMin; + server->workers.maximum = workersMax; + server->workers.accepting = accepting; + server->stateChange = PR_NewCondVar(server->ml); + server->pool.exiting = PR_NewCondVar(server->ml); + server->pool.acceptComplete = PR_NewCondVar(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("main(0x%p): creating server thread\n", PR_GetCurrentThread())); + + rv = NewThread( + Server, server, PR_PRIORITY_HIGH, PR_JOINABLE_THREAD); + TEST_ASSERT(PR_SUCCESS == rv); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("main(0x%p): waiting for server init\n", PR_GetCurrentThread())); + + PR_Lock(server->ml); + while (server->state == cs_init) + PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("main(0x%p): server init complete (port #%d)\n", + PR_GetCurrentThread(), server->port)); + } + + if (clients != 0) + { + /* Create all of the clients */ + PRHostEnt host; + char buffer[BUFFER_SIZE]; + client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t)); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_VERBOSE, + ("main(0x%p): creating %d client threads\n", + PR_GetCurrentThread(), clients)); + + if (!serverIsLocal) + { + rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host); + if (PR_SUCCESS != rv) + { + PL_FPrintError(PR_STDERR, "PR_GetHostByName"); + return 2; + } + } + + for (index = 0; index < clients; ++index) + { + client[index].state = cs_init; + client[index].ml = PR_NewLock(); + if (serverIsLocal) + { + (void)PR_InitializeNetAddr( + PR_IpAddrLoopback, DEFAULT_PORT, + &client[index].serverAddress); + } + else + { + (void)PR_EnumerateHostEnt( + 0, &host, DEFAULT_PORT, &client[index].serverAddress); + } + client[index].stateChange = PR_NewCondVar(client[index].ml); + TEST_LOG( + cltsrv_log_file, TEST_LOG_INFO, + ("main(0x%p): creating client threads\n", PR_GetCurrentThread())); + rv = NewThread( + Client, &client[index], PR_PRIORITY_NORMAL, PR_JOINABLE_THREAD); + TEST_ASSERT(PR_SUCCESS == rv); + PR_Lock(client[index].ml); + while (cs_init == client[index].state) + PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(client[index].ml); + } + } + + /* Then just let them go at it for a bit */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("main(0x%p): waiting for execution interval (%d seconds)\n", + PR_GetCurrentThread(), execution)); + + WaitForCompletion(execution); + + TimeOfDayMessage("Shutting down", PR_GetCurrentThread()); + + if (clients != 0) + { + for (index = 0; index < clients; ++index) + { + TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, + ("main(0x%p): notifying client(0x%p) to stop\n", + PR_GetCurrentThread(), client[index].thread)); + + PR_Lock(client[index].ml); + if (cs_run == client[index].state) + { + client[index].state = cs_stop; + PR_Interrupt(client[index].thread); + while (cs_stop == client[index].state) + PR_WaitCondVar( + client[index].stateChange, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(client[index].ml); + + TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, + ("main(0x%p): joining client(0x%p)\n", + PR_GetCurrentThread(), client[index].thread)); + + joinStatus = JoinThread(client[index].thread); + TEST_ASSERT(PR_SUCCESS == joinStatus); + PR_DestroyCondVar(client[index].stateChange); + PR_DestroyLock(client[index].ml); + } + PR_DELETE(client); + } + + if (NULL != server) + { + /* All clients joined - retrieve the server */ + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("main(0x%p): notifying server(0x%p) to stop\n", + PR_GetCurrentThread(), server->thread)); + + PR_Lock(server->ml); + server->state = cs_stop; + PR_Interrupt(server->thread); + while (cs_exit != server->state) + PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(server->ml); + + TEST_LOG( + cltsrv_log_file, TEST_LOG_NOTICE, + ("main(0x%p): joining server(0x%p)\n", + PR_GetCurrentThread(), server->thread)); + joinStatus = JoinThread(server->thread); + TEST_ASSERT(PR_SUCCESS == joinStatus); + + PR_DestroyCondVar(server->stateChange); + PR_DestroyCondVar(server->pool.exiting); + PR_DestroyCondVar(server->pool.acceptComplete); + PR_DestroyLock(server->ml); + PR_DELETE(server); + } + + TEST_LOG( + cltsrv_log_file, TEST_LOG_ALWAYS, + ("main(0x%p): test complete\n", PR_GetCurrentThread())); + + if (thread_provider == thread_win32) + thread_type = "\nWin32 Thread Statistics\n"; + else if (thread_provider == thread_pthread) + thread_type = "\npthread Statistics\n"; + else if (thread_provider == thread_sproc) + thread_type = "\nsproc Statistics\n"; + else { + PR_ASSERT(thread_provider == thread_nspr); + thread_type = "\nPRThread Statistics\nn"; + } + + PT_FPrintStats(debug_out, thread_type); + + TimeOfDayMessage("Test exiting at", PR_GetCurrentThread()); + PR_Cleanup(); + return 0; +} /* main */ + +/* cltsrv.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/prpoll.c nspr-4.10.7/nspr/pr/tests/prpoll.c --- nspr-4.9.5/nspr/pr/tests/prpoll.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/prpoll.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,351 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifdef WIN32 +#include +#endif + +#ifdef XP_UNIX +#include /* for close() */ +#endif + +#include "prinit.h" +#include "prio.h" +#include "prlog.h" +#include "prprf.h" +#include "prnetdb.h" + +#include "private/pprio.h" + +#define CLIENT_LOOPS 5 +#define BUF_SIZE 128 + +#include +#include +#include + +#ifdef WINCE + +int main(int argc, char **argv) +{ + fprintf(stderr, "Invalid/Broken Test for WinCE/WinMobile\n"); + exit(1); +} + +#else + +static void +clientThreadFunc(void *arg) +{ + PRUint16 port = (PRUint16) arg; + PRFileDesc *sock; + PRNetAddr addr; + char buf[BUF_SIZE]; + int i; + + addr.inet.family = PR_AF_INET; + addr.inet.port = PR_htons(port); + addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + PR_snprintf(buf, sizeof(buf), "%hu", port); + + for (i = 0; i < 5; i++) { + sock = PR_NewTCPSocket(); + PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); + + PR_Write(sock, buf, sizeof(buf)); + PR_Close(sock); + } +} + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock1, *listenSock2; + PRFileDesc *badFD; + PRUint16 listenPort1, listenPort2; + PRNetAddr addr; + char buf[BUF_SIZE]; + PRThread *clientThread; + PRPollDesc pds0[10], pds1[10], *pds, *other_pds; + PRIntn npds; + PRInt32 retVal; + PRInt32 rv; + PROsfd sd; + struct sockaddr_in saddr; + PRIntn saddr_len; + PRUint16 listenPort3; + PRFileDesc *socket_poll_fd; + PRIntn i, j; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + printf("This program tests PR_Poll with sockets.\n"); + printf("Timeout, error reporting, and normal operation are tested.\n\n"); + + /* Create two listening sockets */ + if ((listenSock1 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + exit(1); + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + exit(1); + } + if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + exit(1); + } + listenPort1 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock1, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + exit(1); + } + + if ((listenSock2 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + exit(1); + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + exit(1); + } + if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + exit(1); + } + listenPort2 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock2, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + exit(1); + } + /* Set up the poll descriptor array */ + pds = pds0; + other_pds = pds1; + memset(pds, 0, sizeof(pds)); + npds = 0; + pds[npds].fd = listenSock1; + pds[npds].in_flags = PR_POLL_READ; + npds++; + pds[npds].fd = listenSock2; + pds[npds].in_flags = PR_POLL_READ; + npds++; + + sd = socket(AF_INET, SOCK_STREAM, 0); + PR_ASSERT(sd >= 0); + memset((char *) &saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + saddr.sin_port = htons(0); + + rv = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr)); + PR_ASSERT(rv == 0); + saddr_len = sizeof(saddr); + rv = getsockname(sd, (struct sockaddr *) &saddr, &saddr_len); + PR_ASSERT(rv == 0); + listenPort3 = ntohs(saddr.sin_port); + + rv = listen(sd, 5); + PR_ASSERT(rv == 0); + pds[npds].fd = socket_poll_fd = PR_CreateSocketPollFd(sd); + PR_ASSERT(pds[npds].fd); + pds[npds].in_flags = PR_POLL_READ; + npds++; + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu, %hu and %hu\n\n", + listenPort1, listenPort2, listenPort3); + printf("%s", buf); + + /* Testing timeout */ + printf("PR_Poll should time out in 5 seconds\n"); + retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5)); + if (retVal != 0) { + PR_snprintf(buf, sizeof(buf), + "PR_Poll should time out and return 0, but it returns %ld\n", + retVal); + fprintf(stderr, "%s", buf); + exit(1); + } + printf("PR_Poll timed out. Test passed.\n\n"); + + /* Testing bad fd */ + printf("PR_Poll should detect a bad file descriptor\n"); + if ((badFD = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a TCP socket\n"); + exit(1); + } + + pds[npds].fd = badFD; + pds[npds].in_flags = PR_POLL_READ; + npds++; + PR_Close(badFD); /* make the fd bad */ +#if 0 + retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); + if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) { + fprintf(stderr, "Failed to detect the bad fd: " + "PR_Poll returns %d, out_flags is 0x%hx\n", + retVal, pds[npds - 1].out_flags); + exit(1); + } + printf("PR_Poll detected the bad fd. Test passed.\n\n"); +#endif + npds--; + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort1, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + exit(1); + } + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort2, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + exit(1); + } + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort3, + PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + exit(1); + } + + + printf("Three client threads are created. Each of them will\n"); + printf("send data to one of the three ports the server is listening on.\n"); + printf("The data they send is the port number. Each of them send\n"); + printf("the data five times, so you should see ten lines below,\n"); + printf("interleaved in an arbitrary order.\n"); + + /* 30 events total */ + i = 0; + while (i < 30) { + PRPollDesc *tmp; + int nextIndex; + int nEvents = 0; + + retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(retVal != 0); /* no timeout */ + if (retVal == -1) { + fprintf(stderr, "PR_Poll failed\n"); + exit(1); + } + + nextIndex = 3; + /* the three listening sockets */ + for (j = 0; j < 3; j++) { + other_pds[j] = pds[j]; + PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 + && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); + if (pds[j].out_flags & PR_POLL_READ) { + PRFileDesc *sock; + + nEvents++; + if (j == 2) { + PROsfd newsd; + newsd = accept(PR_FileDesc2NativeHandle(pds[j].fd), NULL, 0); + if (newsd == -1) { + fprintf(stderr, "accept() failed\n"); + exit(1); + } + other_pds[nextIndex].fd = PR_CreateSocketPollFd(newsd); + PR_ASSERT(other_pds[nextIndex].fd); + other_pds[nextIndex].in_flags = PR_POLL_READ; + } else { + sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT); + if (sock == NULL) { + fprintf(stderr, "PR_Accept() failed\n"); + exit(1); + } + other_pds[nextIndex].fd = sock; + other_pds[nextIndex].in_flags = PR_POLL_READ; + } + nextIndex++; + } else if (pds[j].out_flags & PR_POLL_ERR) { + fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); + exit(1); + } else if (pds[j].out_flags & PR_POLL_NVAL) { + fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n", + PR_FileDesc2NativeHandle(pds[j].fd)); + exit(1); + } + } + + for (j = 3; j < npds; j++) { + PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0 + && (pds[j].out_flags & PR_POLL_EXCEPT) == 0); + if (pds[j].out_flags & PR_POLL_READ) { + PRInt32 nBytes; + + nEvents++; + /* XXX: This call is a hack and should be fixed */ + if (PR_GetDescType(pds[j].fd) == (PRDescType) 0) { + nBytes = recv(PR_FileDesc2NativeHandle(pds[j].fd), buf, + sizeof(buf), 0); + if (nBytes == -1) { + fprintf(stderr, "recv() failed\n"); + exit(1); + } + printf("Server read %d bytes from native fd %d\n",nBytes, + PR_FileDesc2NativeHandle(pds[j].fd)); +#ifdef WIN32 + closesocket((SOCKET)PR_FileDesc2NativeHandle(pds[j].fd)); +#else + close(PR_FileDesc2NativeHandle(pds[j].fd)); +#endif + PR_DestroySocketPollFd(pds[j].fd); + } else { + nBytes = PR_Read(pds[j].fd, buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read() failed\n"); + exit(1); + } + PR_Close(pds[j].fd); + } + /* Just to be safe */ + buf[BUF_SIZE - 1] = '\0'; + printf("The server received \"%s\" from a client\n", buf); + } else if (pds[j].out_flags & PR_POLL_ERR) { + fprintf(stderr, "PR_Poll() indicates that an fd has error\n"); + exit(1); + } else if (pds[j].out_flags & PR_POLL_NVAL) { + fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n"); + exit(1); + } else { + other_pds[nextIndex] = pds[j]; + nextIndex++; + } + } + + PR_ASSERT(retVal == nEvents); + /* swap */ + tmp = pds; + pds = other_pds; + other_pds = tmp; + npds = nextIndex; + i += nEvents; + } + PR_DestroySocketPollFd(socket_poll_fd); + + printf("All tests finished\n"); + PR_Cleanup(); + return 0; +} + + +#endif /* ifdef WINCE */ diff -Nru nspr-4.9.5/nspr/pr/tests/prpollml.c nspr-4.10.7/nspr/pr/tests/prpollml.c --- nspr-4.9.5/nspr/pr/tests/prpollml.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/prpollml.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * This test exercises the code that allocates and frees the syspoll_list + * array of PRThread in the pthreads version. This test is intended to be + * run under Purify to verify that there is no memory leak. + */ + +#include "nspr.h" + +#include +#include +#include + +#ifdef SYMBIAN +#define POLL_DESC_COUNT 128 +#else +#define POLL_DESC_COUNT 256 /* This should be greater than the + * STACK_POLL_DESC_COUNT macro in + * ptio.c to cause syspoll_list to + * be created. */ +#endif + +static PRPollDesc pd[POLL_DESC_COUNT]; + +static void Test(void) +{ + int i; + PRInt32 rv; + PRIntervalTime timeout; + + timeout = PR_MillisecondsToInterval(10); + /* cause syspoll_list to grow */ + for (i = 1; i <= POLL_DESC_COUNT; i++) { + rv = PR_Poll(pd, i, timeout); + if (rv != 0) { + fprintf(stderr, + "PR_Poll should time out but returns %d (%d, %d)\n", + (int) rv, (int) PR_GetError(), (int) PR_GetOSError()); + exit(1); + } + } + /* syspoll_list should be large enough for all these */ + for (i = POLL_DESC_COUNT; i >= 1; i--) { + rv = PR_Poll(pd, i, timeout); + if (rv != 0) { + fprintf(stderr, "PR_Poll should time out but returns %d\n", + (int) rv); + exit(1); + } + } +} + +static void ThreadFunc(void *arg) +{ + Test(); +} + +int main(int argc, char **argv) +{ + int i; + PRThread *thread; + PRFileDesc *sock; + PRNetAddr addr; + + memset(&addr, 0, sizeof(addr)); + addr.inet.family = PR_AF_INET; + addr.inet.port = PR_htons(0); + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + for (i = 0; i < POLL_DESC_COUNT; i++) { + sock = PR_NewTCPSocket(); + if (sock == NULL) { + fprintf(stderr, "PR_NewTCPSocket failed (%d, %d)\n", + (int) PR_GetError(), (int) PR_GetOSError()); + fprintf(stderr, "Ensure the per process file descriptor limit " + "is greater than %d.", POLL_DESC_COUNT); + exit(1); + } + if (PR_Bind(sock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_Bind failed (%d, %d)\n", + (int) PR_GetError(), (int) PR_GetOSError()); + exit(1); + } + if (PR_Listen(sock, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed (%d, %d)\n", + (int) PR_GetError(), (int) PR_GetOSError()); + exit(1); + } + + pd[i].fd = sock; + pd[i].in_flags = PR_POLL_READ; + } + + /* first run the test on the primordial thread */ + Test(); + + /* then run the test on all three kinds of threads */ + thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + if (NULL == thread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + if (PR_JoinThread(thread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (NULL == thread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + if (PR_JoinThread(thread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD, PR_JOINABLE_THREAD, 0); + if (NULL == thread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + if (PR_JoinThread(thread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + for (i = 0; i < POLL_DESC_COUNT; i++) { + if (PR_Close(pd[i].fd) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + } + PR_Cleanup(); + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/prselect.c nspr-4.10.7/nspr/pr/tests/prselect.c --- nspr-4.9.5/nspr/pr/tests/prselect.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/prselect.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,340 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1997 - Netscape Communications Corporation +** +** Name: prselect_err.c +** +** Description: tests PR_Select with sockets Error condition functions. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" +#include "prttools.h" + + +#include "prinit.h" +#include "prio.h" +#include "prlog.h" +#include "prprf.h" +#include "prerror.h" +#include "prnetdb.h" + +#include +#include +#include + +/*********************************************************************** +** PRIVATE FUNCTION: Test_Result +** DESCRIPTION: Used in conjunction with the regress tool, prints out the +** status of the test case. +** INPUTS: PASS/FAIL +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** +** RESTRICTIONS: +** None +** MEMORY: NA +** ALGORITHM: Determine what the status is and print accordingly. +** +***********************************************************************/ + + +static Test_Result (int result) +{ + if (result == PASS) + printf ("PASS\n"); + else + printf ("FAIL\n"); +} + +static void +clientThreadFunc(void *arg) +{ + PRUint16 port = (PRUint16) arg; + PRFileDesc *sock; + PRNetAddr addr; + char buf[128]; + int i; + + addr.inet.family = AF_INET; + addr.inet.port = PR_htons(port); + addr.inet.ip = PR_htonl(INADDR_LOOPBACK); + PR_snprintf(buf, sizeof(buf), "%hu", port); + + for (i = 0; i < 5; i++) { + sock = PR_NewTCPSocket(); + PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); + PR_Write(sock, buf, sizeof(buf)); + PR_Close(sock); + } +} + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock1, *listenSock2; + PRFileDesc *badFD; + PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds; + PRIntn nfds; + PRUint16 listenPort1, listenPort2; + PRNetAddr addr; + PR_fd_set readFdSet; + char buf[128]; + PRThread *clientThread; + PRInt32 retVal; + PRIntn i, j; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (debug_mode) { + printf("This program tests PR_Select with sockets. Timeout, error\n"); + printf("reporting, and normal operation are tested.\n\n"); + } + + /* Create two listening sockets */ + if ((listenSock1 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + if (!debug_mode) Test_Result(FAIL); + exit(1); + } + addr.inet.family = AF_INET; + addr.inet.ip = PR_htonl(INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + if (!debug_mode) Test_Result(FAIL); + exit(1); + } + if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + if (!debug_mode) Test_Result(FAIL); + exit(1); + } + listenPort1 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock1, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + if (!debug_mode) Test_Result(FAIL); + exit(1); + } + + if ((listenSock2 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + if (!debug_mode) Test_Result(FAIL); + exit(1); + } + addr.inet.family = AF_INET; + addr.inet.ip = PR_htonl(INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + if (!debug_mode) Test_Result(FAIL); + exit(1); + } + if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + if (!debug_mode) Test_Result(FAIL); + exit(1); + } + listenPort2 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock2, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + if (!debug_mode) Test_Result(FAIL); + exit(1); + } + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu and %hu\n\n", + listenPort1, listenPort2); + printf("%s", buf); + + /* Set up the fd set */ + PR_FD_ZERO(&readFdSet); + PR_FD_SET(listenSock1, &readFdSet); + PR_FD_SET(listenSock2, &readFdSet); + + /* Testing timeout */ + if (debug_mode) printf("PR_Select should time out in 5 seconds\n"); + retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, + PR_SecondsToInterval(5)); + if (retVal != 0) { + PR_snprintf(buf, sizeof(buf), + "PR_Select should time out and return 0, but it returns %ld\n", + retVal); + fprintf(stderr, "%s", buf); + if (retVal == -1) { + fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), + PR_GetOSError()); + if (!debug_mode) Test_Result(FAIL); + } + exit(1); + } + if (debug_mode) printf("PR_Select timed out. Test passed.\n\n"); + else Test_Result(PASS); + + /* Testing bad fd */ + printf("PR_Select should detect a bad file descriptor\n"); + if ((badFD = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a TCP socket\n"); + exit(1); + } + + PR_FD_SET(listenSock1, &readFdSet); + PR_FD_SET(listenSock2, &readFdSet); + PR_FD_SET(badFD, &readFdSet); + PR_Close(badFD); /* make the fd bad */ + retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, + PR_INTERVAL_NO_TIMEOUT); + if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) { + fprintf(stderr, "Failed to detect the bad fd: " + "PR_Select returns %d\n", retVal); + if (retVal == -1) { + fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), + PR_GetOSError()); + } + exit(1); + } + printf("PR_Select detected a bad fd. Test passed.\n\n"); + PR_FD_CLR(badFD, &readFdSet); + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort1, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + exit(1); + } + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort2, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + exit(1); + } + + printf("Two client threads are created. Each of them will\n"); + printf("send data to one of the two ports the server is listening on.\n"); + printf("The data they send is the port number. Each of them send\n"); + printf("the data five times, so you should see ten lines below,\n"); + printf("interleaved in an arbitrary order.\n"); + + /* set up the fd array */ + fds = fds0; + other_fds = fds1; + fds[0] = listenSock1; + fds[1] = listenSock2; + nfds = 2; + PR_FD_SET(listenSock1, &readFdSet); + PR_FD_SET(listenSock2, &readFdSet); + + /* 20 events total */ + i = 0; + while (i < 20) { + PRFileDesc **tmp; + int nextIndex; + int nEvents = 0; + + retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, + PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(retVal != 0); /* no timeout */ + if (retVal == -1) { + fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + exit(1); + } + + nextIndex = 2; + /* the two listening sockets */ + for (j = 0; j < 2; j++) { + other_fds[j] = fds[j]; + if (PR_FD_ISSET(fds[j], &readFdSet)) { + PRFileDesc *sock; + + nEvents++; + sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT); + if (sock == NULL) { + fprintf(stderr, "PR_Accept() failed\n"); + exit(1); + } + other_fds[nextIndex] = sock; + PR_FD_SET(sock, &readFdSet); + nextIndex++; + } + PR_FD_SET(fds[j], &readFdSet); + } + + for (j = 2; j < nfds; j++) { + if (PR_FD_ISSET(fds[j], &readFdSet)) { + PRInt32 nBytes; + + PR_FD_CLR(fds[j], &readFdSet); + nEvents++; + nBytes = PR_Read(fds[j], buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read() failed\n"); + exit(1); + } + /* Just to be safe */ + buf[127] = '\0'; + PR_Close(fds[j]); + printf("The server received \"%s\" from a client\n", buf); + } else { + PR_FD_SET(fds[j], &readFdSet); + other_fds[nextIndex] = fds[j]; + nextIndex++; + } + } + + PR_ASSERT(retVal == nEvents); + /* swap */ + tmp = fds; + fds = other_fds; + other_fds = tmp; + nfds = nextIndex; + i += nEvents; + } + + printf("All tests finished\n"); + PR_Cleanup(); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/prttools.h nspr-4.10.7/nspr/pr/tests/prttools.h --- nspr-4.9.5/nspr/pr/tests/prttools.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/prttools.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,11 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Used in Regress Tool */ +#define NOSTATUS 2 +#define PASS 1 +#define FAIL 0 + +PRIntn debug_mode=0; diff -Nru nspr-4.9.5/nspr/pr/tests/pushtop.c nspr-4.10.7/nspr/pr/tests/pushtop.c --- nspr-4.9.5/nspr/pr/tests/pushtop.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/pushtop.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* A regression test for bug 794316 */ + +#include +#include + +#include "prio.h" + +static PRIOMethods dummyMethods; + +int main() +{ + PRDescIdentity topId, middleId, bottomId; + PRFileDesc *top, *middle, *bottom; + PRFileDesc *fd; + + topId = PR_GetUniqueIdentity("top"); + middleId = PR_GetUniqueIdentity("middle"); + bottomId = PR_GetUniqueIdentity("bottom"); + + top = PR_CreateIOLayerStub(topId, &dummyMethods); + middle = PR_CreateIOLayerStub(middleId, &dummyMethods); + bottom = PR_CreateIOLayerStub(bottomId, &dummyMethods); + + fd = bottom; + PR_PushIOLayer(fd, PR_TOP_IO_LAYER, middle); + PR_PushIOLayer(fd, PR_TOP_IO_LAYER, top); + + top = fd; + middle = top->lower; + bottom = middle->lower; + + /* Verify that the higher pointers are correct. */ + if (middle->higher != top) { + fprintf(stderr, "middle->higher is wrong\n"); + fprintf(stderr, "FAILED\n"); + exit(1); + } + if (bottom->higher != middle) { + fprintf(stderr, "bottom->higher is wrong\n"); + fprintf(stderr, "FAILED\n"); + exit(1); + } + + top = PR_PopIOLayer(fd, topId); + top->dtor(top); + + middle = fd; + bottom = middle->lower; + + /* Verify that the higher pointer is correct. */ + if (bottom->higher != middle) { + fprintf(stderr, "bottom->higher is wrong\n"); + fprintf(stderr, "FAILED\n"); + exit(1); + } + + middle = PR_PopIOLayer(fd, middleId); + middle->dtor(middle); + if (fd->identity != bottomId) { + fprintf(stderr, "The bottom layer has the wrong identity\n"); + fprintf(stderr, "FAILED\n"); + exit(1); + } + fd->dtor(fd); + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/randseed.c nspr-4.10.7/nspr/pr/tests/randseed.c --- nspr-4.9.5/nspr/pr/tests/randseed.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/randseed.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: rngseed.c +** Description: +** Test NSPR's Random Number Seed generator +** +** Initial test: Just make sure it outputs some data. +** +** ... more? ... check some iterations to ensure it is random (no dupes) +** ... more? ... histogram distribution of random numbers +*/ + +#include "plgetopt.h" +#include "nspr.h" +#include "prrng.h" +#include +#include +#include + +/* +** Test harness infrastructure +*/ +PRLogModuleInfo *lm; +PRLogModuleLevel msgLevel = PR_LOG_NONE; +PRIntn debug = 0; +PRUint32 failed_already = 0; +/* end Test harness infrastructure */ + +PRIntn optRandCount = 30; +char buf[40]; +PRSize bufSize = sizeof(buf); +PRSize rSize; +PRIntn i; + +/* +** Emit help text for this test +*/ +static void Help( void ) +{ + printf("Template: Help(): display your help message(s) here"); + exit(1); +} /* end Help() */ + +static void PrintRand( void *buf, PRIntn size ) +{ + PRUint32 *rp = buf; + PRIntn i; + + printf("%4.4d--\n", size ); + while (size > 0 ) { + switch( size ) { + case 1 : + printf("%2.2X\n", *(rp++) ); + size -= 4; + break; + case 2 : + printf("%4.4X\n", *(rp++) ); + size -= 4; + break; + case 3 : + printf("%6.6X\n", *(rp++) ); + size -= 4; + break; + default: + while ( size >= 4) { + PRIntn i = 3; + do { + printf("%8.8X ", *(rp++) ); + size -= 4; + } while( i-- ); + i = 3; + printf("\n"); + } + break; + } /* end switch() */ + } /* end while() */ +} /* end PrintRand() */ + + +int main(int argc, char **argv) +{ + { + /* + ** Get command line options + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "hdv"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug */ + debug = 1; + msgLevel = PR_LOG_ERROR; + break; + case 'v': /* verbose mode */ + msgLevel = PR_LOG_DEBUG; + break; + case 'h': /* help message */ + Help(); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } + + lm = PR_NewLogModule("Test"); /* Initialize logging */ + for ( i = 0; i < optRandCount ; i++ ) { + memset( buf, 0, bufSize ); + rSize = PR_GetRandomNoise( buf, bufSize ); + if (!rSize) { + fprintf(stderr, "Not implemented\n" ); + failed_already = PR_TRUE; + break; + } + if (debug) PrintRand( buf, rSize ); + } + + if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); + return( (failed_already == PR_TRUE )? 1 : 0 ); +} /* main() */ +/* end template.c */ + diff -Nru nspr-4.9.5/nspr/pr/tests/ranfile.c nspr-4.10.7/nspr/pr/tests/ranfile.c --- nspr-4.9.5/nspr/pr/tests/ranfile.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/ranfile.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,390 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Contact: AOF +** +** Name: ranfile.c +** +** Description: Test to hammer on various components of NSPR +** Modification History: +** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prinit.h" +#include "prthread.h" +#include "prlock.h" +#include "prcvar.h" +#include "prmem.h" +#include "prinrval.h" +#include "prio.h" + +#include +#include + +static PRIntn debug_mode = 0; +static PRIntn failed_already=0; +static PRThreadScope thread_scope = PR_LOCAL_THREAD; + +typedef enum {sg_go, sg_stop, sg_done} Action; +typedef enum {sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem; + +typedef struct Hammer_s { + PRLock *ml; + PRCondVar *cv; + PRUint32 id; + PRUint32 limit; + PRUint32 writes; + PRThread *thread; + PRIntervalTime timein; + Action action; + Problem problem; +} Hammer_t; + +#define DEFAULT_LIMIT 10 +#define DEFAULT_THREADS 2 +#define DEFAULT_LOOPS 1 + +static PRInt32 pageSize = 1024; +static const char* baseName = "./"; +static const char *programName = "Random File"; + +/*********************************************************************** +** PRIVATE FUNCTION: RandomNum +** DESCRIPTION: +** Generate a pseudo-random number +** INPUTS: None +** OUTPUTS: None +** RETURN: A pseudo-random unsigned number, 32-bits wide +** SIDE EFFECTS: +** Updates random seed (a static) +** RESTRICTIONS: +** None +** MEMORY: NA +** ALGORITHM: +** Uses the current interval timer value, promoted to a 64 bit +** float as a multiplier for a static residue (which begins +** as an uninitialized variable). The result is bits [16..48) +** of the product. Seed is then updated with the return value +** promoted to a float-64. +***********************************************************************/ +static PRUint32 RandomNum(void) +{ + PRUint32 rv; + PRUint64 shift; + static PRFloat64 seed = 0x58a9382; /* Just make sure it isn't 0! */ + PRFloat64 random = seed * (PRFloat64)PR_IntervalNow(); + LL_USHR(shift, *((PRUint64*)&random), 16); + LL_L2UI(rv, shift); + seed = (PRFloat64)rv; + return rv; +} /* RandomNum */ + +/*********************************************************************** +** PRIVATE FUNCTION: Thread +** DESCRIPTION: +** Hammer on the file I/O system +** INPUTS: A pointer to the thread's private data +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** Creates, accesses and deletes a file +** RESTRICTIONS: +** (Currently) must have file create permission in "/usr/tmp". +** MEMORY: NA +** ALGORITHM: +** This function is a root of a thread +** 1) Creates a (hopefully) unique file in /usr/tmp/ +** 2) Writes a zero to a random number of sequential pages +** 3) Closes the file +** 4) Reopens the file +** 5) Seeks to a random page within the file +** 6) Writes a one byte on that page +** 7) Repeat steps [5..6] for each page in the file +** 8) Close and delete the file +** 9) Repeat steps [1..8] until told to stop +** 10) Notify complete and return +***********************************************************************/ +static void PR_CALLBACK Thread(void *arg) +{ + PRUint32 index; + char filename[30]; + const char zero = 0; + PRFileDesc *file = NULL; + PRStatus rv = PR_SUCCESS; + Hammer_t *cd = (Hammer_t*)arg; + + (void)sprintf(filename, "%ssg%04ld.dat", baseName, cd->id); + + if (debug_mode) printf("Starting work on %s\n", filename); + + while (PR_TRUE) + { + PRUint32 bytes; + PRUint32 minor = (RandomNum() % cd->limit) + 1; + PRUint32 random = (RandomNum() % cd->limit) + 1; + PRUint32 pages = (RandomNum() % cd->limit) + 10; + while (minor-- > 0) + { + cd->problem = sg_okay; + if (cd->action != sg_go) goto finished; + cd->problem = sg_open; + file = PR_Open(filename, PR_RDWR|PR_CREATE_FILE, 0666); + if (file == NULL) goto finished; + for (index = 0; index < pages; index++) + { + cd->problem = sg_okay; + if (cd->action != sg_go) goto close; + cd->problem = sg_seek; + bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET); + if (bytes != pageSize * index) goto close; + cd->problem = sg_write; + bytes = PR_Write(file, &zero, sizeof(zero)); + if (bytes <= 0) goto close; + cd->writes += 1; + } + cd->problem = sg_close; + rv = PR_Close(file); + if (rv != PR_SUCCESS) goto purge; + + cd->problem = sg_okay; + if (cd->action != sg_go) goto purge; + + cd->problem = sg_open; + file = PR_Open(filename, PR_RDWR, 0666); + for (index = 0; index < pages; index++) + { + cd->problem = sg_okay; + if (cd->action != sg_go) goto close; + cd->problem = sg_seek; + bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET); + if (bytes != pageSize * index) goto close; + cd->problem = sg_write; + bytes = PR_Write(file, &zero, sizeof(zero)); + if (bytes <= 0) goto close; + cd->writes += 1; + random = (random + 511) % pages; + } + cd->problem = sg_close; + rv = PR_Close(file); + if (rv != PR_SUCCESS) goto purge; + cd->problem = sg_delete; + rv = PR_Delete(filename); + if (rv != PR_SUCCESS) goto finished; + } + } + +close: + (void)PR_Close(file); +purge: + (void)PR_Delete(filename); +finished: + PR_Lock(cd->ml); + cd->action = sg_done; + PR_NotifyCondVar(cd->cv); + PR_Unlock(cd->ml); + + if (debug_mode) printf("Ending work on %s\n", filename); + + return; +} /* Thread */ + +static Hammer_t hammer[100]; +static PRCondVar *cv; +/*********************************************************************** +** PRIVATE FUNCTION: main +** DESCRIPTION: +** Hammer on the file I/O system +** INPUTS: The usual argc and argv +** argv[0] - program name (not used) +** argv[1] - the number of times to execute the major loop +** argv[2] - the number of threads to toss into the batch +** argv[3] - the clipping number applied to randoms +** default values: loops = 2, threads = 10, limit = 57 +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** Creates, accesses and deletes lots of files +** RESTRICTIONS: +** (Currently) must have file create permission in "/usr/tmp". +** MEMORY: NA +** ALGORITHM: +** 1) Fork a "Thread()" +** 2) Wait for 'interleave' seconds +** 3) For [0..'threads') repeat [1..2] +** 4) Mark all objects to stop +** 5) Collect the threads, accumulating the results +** 6) For [0..'loops') repeat [1..5] +** 7) Print accumulated results and exit +** +** Characteristic output (from IRIX) +** Random File: Using loops = 2, threads = 10, limit = 57 +** Random File: [min [avg] max] writes/sec average +***********************************************************************/ +int main(int argc, char **argv) +{ + PRLock *ml; + PRUint32 id = 0; + int active, poll; + PRIntervalTime interleave; + PRIntervalTime duration = 0; + int limit = 0, loops = 0, threads = 0, times; + PRUint32 writes, writesMin = 0x7fffffff, writesTot = 0, durationTot = 0, writesMax = 0; + + const char *where[] = {"okay", "open", "close", "delete", "write", "seek"}; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'G': /* global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'l': /* limiting number */ + limit = atoi(opt->value); + break; + case 't': /* number of threads */ + threads = atoi(opt->value); + break; + case 'i': /* iteration counter */ + loops = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + interleave = PR_SecondsToInterval(10); + + ml = PR_NewLock(); + cv = PR_NewCondVar(ml); + + if (loops == 0) loops = DEFAULT_LOOPS; + if (limit == 0) limit = DEFAULT_LIMIT; + if (threads == 0) threads = DEFAULT_THREADS; + + if (debug_mode) printf( + "%s: Using loops = %d, threads = %d, limit = %d and %s threads\n", + programName, loops, threads, limit, + (thread_scope == PR_LOCAL_THREAD) ? "LOCAL" : "GLOBAL"); + + for (times = 0; times < loops; ++times) + { + if (debug_mode) printf("%s: Setting concurrency level to %d\n", programName, times + 1); + PR_SetConcurrency(times + 1); + for (active = 0; active < threads; active++) + { + hammer[active].ml = ml; + hammer[active].cv = cv; + hammer[active].id = id++; + hammer[active].writes = 0; + hammer[active].action = sg_go; + hammer[active].problem = sg_okay; + hammer[active].limit = (RandomNum() % limit) + 1; + hammer[active].timein = PR_IntervalNow(); + hammer[active].thread = PR_CreateThread( + PR_USER_THREAD, Thread, &hammer[active], + PR_GetThreadPriority(PR_GetCurrentThread()), + thread_scope, PR_JOINABLE_THREAD, 0); + + PR_Lock(ml); + PR_WaitCondVar(cv, interleave); /* start new ones slowly */ + PR_Unlock(ml); + } + + /* + * The last thread started has had the opportunity to run for + * 'interleave' seconds. Now gather them all back in. + */ + PR_Lock(ml); + for (poll = 0; poll < threads; poll++) + { + if (hammer[poll].action == sg_go) /* don't overwrite done */ + hammer[poll].action = sg_stop; /* ask him to stop */ + } + PR_Unlock(ml); + + while (active > 0) + { + for (poll = 0; poll < threads; poll++) + { + PR_Lock(ml); + while (hammer[poll].action < sg_done) + PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(ml); + + active -= 1; /* this is another one down */ + (void)PR_JoinThread(hammer[poll].thread); + hammer[poll].thread = NULL; + if (hammer[poll].problem == sg_okay) + { + duration = PR_IntervalToMilliseconds( + PR_IntervalNow() - hammer[poll].timein); + writes = hammer[poll].writes * 1000 / duration; + if (writes < writesMin) + writesMin = writes; + if (writes > writesMax) + writesMax = writes; + writesTot += hammer[poll].writes; + durationTot += duration; + } + else + if (debug_mode) printf( + "%s: test failed %s after %ld seconds\n", + programName, where[hammer[poll].problem], duration); + else failed_already=1; + } + } + } + if (debug_mode) printf( + "%s: [%ld [%ld] %ld] writes/sec average\n", + programName, writesMin, writesTot * 1000 / durationTot, writesMax); + + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); + + if (failed_already) + { + printf("FAIL\n"); + return 1; + } + else + { + printf("PASS\n"); + return 0; + } +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/README.TXT nspr-4.10.7/nspr/pr/tests/README.TXT --- nspr-4.9.5/nspr/pr/tests/README.TXT 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/README.TXT 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,407 @@ +File: pr/tests/readme + +This document describes the test cases in the NSPR directory +pr/tests. + +===================================================================== +There is a sub-directory here: + +dll + sources for the .dll(.so) used by test dlltest.c + +===================================================================== +The individual files are described here. + +The script 'runtests.ksh' enumerates and runs test cases that are +expected to run on all platforms. + + +accept.c + Tests PR_Accept() and related socket functions. + +acceptread.c + Tests PR_AcceptRead() + +alarm.c + Tests alarm functions declared in obsolete/pralarm.h. + The alarm functions are obsolete, so is this test. + +atomic.c + Tests Atomic operations defined in pratom.h + +attach.c + Test PR_AttachThread() + Note: This is an NSPR private function. + +bigfile.c + Test 64bit file offset functions declared in prio.h + +bug1test.c + Demonstrates a bug on NT. + +cleanup.c + Tests PR_Cleanup() declared in prinit.h + +cltsrv.c + Tests many socket functions. + +concur.c + Tests threading functions and concurrent operations. + +cvar.c + Tests condition variables. + +cvar2.c + Tests condition variables. A rather abusive test. + +dbmalloc.c + Obsolete. Originally for testing debug builds of NSPR's malloc. + +dbmalloc1.c + Obsolete. Originally for testing debug builds of NSPR's malloc. + +dceemu.c + Tests special functions for DCE emulation. + +depend.c + Obsoltet. Tests early spec for library dependency. + +dlltest.c + Tests dynamic library functions. Used with dll/my.c + +dtoa.c + Tests conversions of double to string. + +exit.c + Tests PR_ProcessExit() declared in prinit.h + +fileio.c + Tests NSPR semaphores a bit of file i/o and threading + functions. + +foreign.c + Test auto-attach of a thread created by something other than + NSPR. + +forktest.c + Limited use. Tests unix fork() and related functions. + +fsync.c + Tests use of PR_Sync() declared in prio.h + +getproto.c + Tests socket functions PR_GetProtoByName(), etc. + +i2l.c + Tests LongLong functions for converting 32bit integer to 64bit + integer. + +initclk.c + Tests timing on minimal use of condition variable + +inrval.c + Tests interval timing functions. + +instrumt.c + Tests instrumentation functions. prcountr.h prtrace.h + +intrupt.c + Tests PR_Interrupt() + +ioconthr.c + Tests i/o continuation mechanism in pthreads. + +io_timeout.c + Test socket i/o timeouts. + +io_timeoutk.c + Obsolete. Subsumed in io_timeout.c + +io_timeoutu.c + Obsolete. Subsumed in io_timeout.c + +ipv6.c + Tests IPv6. IPv6 is not used by NSPR clients. + +join.c + Tests PR_JoinThread() + +joinkk.c + Tests PR_JoinThread() + +joinku.c + Tests PR_JoinThread() + +joinuk.c + Tests PR_JoinThread() + +joinuu.c + Tests PR_JoinThread() + +layer.c + Tests layered I/O. + +lazyinit.c + Tests implicit initialization. + +lltest.c + Tests LongLong (64bit integer) arithmentic and conversions. + +lock.c + Tests PR_Lock() in heavily threaded environment. + +lockfile.c + Test PR_Lockfile(). + +logger.c + Tests PR_LOG() + +makefile + The makefile that builds all the tests + +many_cv.c + Tests aquiring a large number of condition variables. + +multiwait.c + ??? + +nbconn.c + Test non-blocking connect. + +nblayer.c + Tests NSPR's layered I/O capability. + +nonblock.c + Tests operations on non-blocking socket. + +op_2long.c + Tests PR_Open() where filename is too long. + +op_filnf.c + Tests PR_Open() where filename is NotFound. + +op_filok.c + Tests PR_Open() where filename is accessable. + +op_noacc.c + Tests PR_Open() where file permissions are wrong. + Limited use. Windows has no concept of Unix style file permissions. + +op_nofil.c + Tests PR_Open() where filename does not exist. + +parent.c + Test parent/child process capability + +perf.c + Tests and measures context switch times for various thread + syncronization functions. + +pipeping.c + Tests inter-process pipes. Run with pipepong.c + +pipepong.c + Tests inter-process pipes. Run with pipeping.c + +pipeself.c + Tests inter-thread pipes. + +pollable.c + Tests pollable events. prio.h + +poll_er.c + Tests PR_Poll() where an error is expected. + +poll_nm.c + Tests PR_Poll() where normal operation is expected. + +poll_to.c + Tests PR_Poll() where timeout is expected. + +prftest.c + Tests printf-like formatting. + +prftest1.c + Obsolete. Subsumed in prftest.c + +prftest2.c + Obsolete. Subsumed in prftest.c + +priotest.c + Limited use. Tests NSPR thread dispatching priority. + +provider.c + +prpoll.c + Tests PR_Poll(). + +prselect.c + Obsolete. PR_Select() is obsolete. + +prttools.h + Unused file. + +ranfile.c + Tests random file access. + +readme + This file. + +runtests.ksh + A korn shell script that runs a set of tests that should run + on any of the NSPR supported platforms. + +runtests.pl + A perl script to run the test cases. This srcipt runs tests + common to all platforms and runs tests applicable to specific + platforms. Uses file runtests.txt to control execution. + +runtests.txt + Control file for perl script: runtests.pl + +rwlocktest.c + Tests Reader/Writer lock + +selct_er.c + Obsolete. PR_Select() is obsolete. + +selct_nm.c + Obsolete. PR_Select() is obsolete. + +selct_to.c + Obsolete. PR_Select() is obsolete. + +select2.c + Obsolete. PR_Select() is obsolete. + +sel_spd.c + Obsolete. PR_Select() is obsolete. + +sem.c + Obsolete. Semaphores are not supported. + +server_test.c + Tests sockets by simulating a server in loopback mode. + Makes its own client threads. + +servr_kk.c + Tests client/server sockets, threads using system threads. + +servr_ku.c + Tests client/server sockets, threads using system and user threads. + +servr_uk.c + Tests client/server sockets, threads using system and user threads. + +servr_uu.c + Tests client/server sockets, threads user threads. + +short_thread.c + Tests short-running threads. Useful for testing for race conditions. + +sigpipe.c + Tests NSPR's SIGPIPE handler. Unix only. + +sleep.c + Limited use. Tests sleep capability of platform. + +socket.c + Tests many socket functions. + +sockopt.c + Tests setting and getting socket options. + +sprintf.c + Tests sprintf. + +sproc_ch.c + Obsolete. Tests IRIX sproc-based threads. + +sproc_p.c + Obsolete. Tests IRIX sproc-based threads. + +stack.c + Test atomic stack operations. + +stat.c + Tests performance of getfileinfo() vs. stat() + +stdio.c + Tests NSPR's handling of stdin, stdout, stderr. + +strod.c + Tests formatting of double precision floating point. + +suspend.c + Private interfaces PR_SuspendAll(), PR_ResumeAll(), etc. + +switch.c + Tests thread switching + +system.c + Tests PR_GetSystemInfo() + +testbit.c + Tests bit arrays. + +testfile.c + Tests many file I/O functions. + +threads.c + Tests thread caching. + +thruput.c + Tests socket thruput. Must be run by hand as client/server. + Does not self terminate. + +time.c + Incomplete. Limited use. + +timemac.c + Test time and date functions. Originally for Mac. + +timetest.c + Tests time conversion over a wide range of dates. + +tmoacc.c + Server to tmocon.c and writev.c + Do not run it by itself. + +tmocon.c + Client thread to tmoacc.c + +tpd.c + Tests thread private data. + +udpsrv.c + Tests UDP socket functions. + +ut_ttools.h + unused file. + +version.c + Extract and print library version data. + +vercheck.c + Test PR_VersionCheck(). + +writev.c + Tests gather-write on a socket. Requires tmoacc.c + +xnotify.c + Tests cached monitors. + +yield.c + Limited use + +y2k.c + Test to verify NSPR's date functions as Y2K compliant. + +dll\Makefile + makefile for mygetval.c, mysetval.c + +dll\mygetval.c + Dynamic library test. See also dlltest.c + +dll\mysetval.c + Dynamic library test. See also dlltest.c diff -Nru nspr-4.9.5/nspr/pr/tests/reinit.c nspr-4.10.7/nspr/pr/tests/reinit.c --- nspr-4.9.5/nspr/pr/tests/reinit.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/reinit.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* This test verifies that NSPR can be cleaned up and reinitialized. */ + +#include "nspr.h" +#include + +int main() +{ + PRStatus rv; + + fprintf(stderr, "Init 1\n"); + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + fprintf(stderr, "Cleanup 1\n"); + rv = PR_Cleanup(); + if (rv != PR_SUCCESS) { + fprintf(stderr, "FAIL\n"); + return 1; + } + + fprintf(stderr, "Init 2\n"); + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + fprintf(stderr, "Cleanup 2\n"); + rv = PR_Cleanup(); + if (rv != PR_SUCCESS) { + fprintf(stderr, "FAIL\n"); + return 1; + } + + fprintf(stderr, "PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/rmdir.c nspr-4.10.7/nspr/pr/tests/rmdir.c --- nspr-4.9.5/nspr/pr/tests/rmdir.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/rmdir.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: rmdir.c +** Description: Demonstrate bugzilla 80884. +** +** after fix to unix_errors.c, message should report correct +** failure of PR_Rmdir(). +** +** +** +*/ + +#include +#include +#include +#include +#include "plgetopt.h" + +#define DIRNAME "xxxBug80884/" +#define FILENAME "file80883" + +PRBool failed_already = PR_FALSE; +PRBool debug_mode = PR_FALSE; + +PRLogModuleInfo *lm; + +/* +** Help() -- print Usage information +*/ +static void Help( void ) { + fprintf(stderr, "template usage:\n" + "\t-d debug mode\n" + ); +} /* --- end Help() */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dh"); + PRFileDesc* fd; + PRErrorCode err; + + /* parse command line options */ + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + lm = PR_NewLogModule( "testcase" ); + + (void) PR_MkDir( DIRNAME, 0777); + fd = PR_Open( DIRNAME FILENAME, PR_CREATE_FILE|PR_RDWR, 0666); + if (fd == 0) { + PRErrorCode err = PR_GetError(); + fprintf(stderr, "create file fails: %d: %s\n", err, + PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); + failed_already = PR_TRUE; + goto Finished; + } + + PR_Close(fd); + + if (PR_RmDir( DIRNAME ) == PR_SUCCESS) { + fprintf(stderr, "remove directory succeeds\n"); + failed_already = PR_TRUE; + goto Finished; + } + + err = PR_GetError(); + fprintf(stderr, "remove directory fails with: %d: %s\n", err, + PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); + + (void) PR_Delete( DIRNAME FILENAME); + (void) PR_RmDir( DIRNAME ); + + return 0; + +Finished: + if ( debug_mode ) printf("%s\n", ( failed_already ) ? "FAILED" : "PASS" ); + return( (failed_already)? 1 : 0 ); +} /* --- end main() */ +/* --- end template.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/runtests.pl nspr-4.10.7/nspr/pr/tests/runtests.pl --- nspr-4.9.5/nspr/pr/tests/runtests.pl 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/runtests.pl 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,370 @@ +#!/usr/bin/perl +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use POSIX qw(:sys_wait_h); +use POSIX qw(setsid); +use FileHandle; + +# Constants +$WINOS = "MSWin32"; + +$osname = $^O; + +use Cwd; +if ($osname =~ $WINOS) { + # Windows + require Win32::Process; + require Win32; +} + +# Get environment variables. +$output_file = $ENV{NSPR_TEST_LOGFILE}; +$timeout = $ENV{TEST_TIMEOUT}; + +$timeout = 0 if (!defined($timeout)); + +sub getTime { + ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(); + + $year = 1900 + $yearOffset; + + $theTime = sprintf("%04d-%02d-%02d %02d:%02d:%02d",$year,$month,$dayOfMonth,$hour,$minute,$second); + return $theTime; +} + +sub open_log { + + if (!defined($output_file)) { + print "No output file.\n"; + # null device + if ($osname =~ $WINOS) { + $output_file = "nul"; + } else { + $output_file = "/dev/null"; + } + } + + # use STDOUT for OF (to print summary of test results) + open(OF, ">&STDOUT") or die "Can't reuse STDOUT for OF\n"; + OF->autoflush; + # reassign STDOUT to $output_file (to print details of test results) + open(STDOUT, ">$output_file") or die "Can't open file $output_file for STDOUT\n"; + STDOUT->autoflush; + # redirect STDERR to STDOUT + open(STDERR, ">&STDOUT") or die "Can't redirect STDERR to STDOUT\n"; + STDERR->autoflush; + + # Print header test in summary + $now = getTime; + print OF "\nNSPR Test Results - tests\n"; + print OF "\nBEGIN\t\t\t$now\n"; + print OF "NSPR_TEST_LOGFILE\t$output_file\n"; + print OF "TEST_TIMEOUT\t$timeout\n\n"; + print OF "\nTest\t\t\tResult\n\n"; +} + +sub close_log { + # end of test marker in summary + $now = getTime; + print OF "END\t\t\t$now\n"; + + close(OF) or die "Can't close file OF\n"; + close(STDERR) or die "Can't close STDERR\n"; + close(STDOUT) or die "Can't close STDOUT\n"; +} + +sub print_begin { +$lprog = shift; + + # Summary output + print OF "$prog"; + # Full output + $now = getTime; + print "BEGIN TEST: $lprog ($now)\n\n"; +} + +sub print_end { +($lprog, $exit_status, $exit_signal, $exit_core) = @_; + + if (($exit_status == 0) && ($exit_signal == 0) && ($exit_core == 0)) { + $str_status = "Passed"; + } else { + $str_status = "FAILED"; + } + if ($exit_signal != 0) { + $str_signal = " - signal $exit_signal"; + } else { + $str_signal = ""; + } + if ($exit_core != 0) { + $str_core = " - core dumped"; + } else { + $str_core = ""; + } + $now = getTime; + # Full output + print "\nEND TEST: $lprog ($now)\n"; + print "TEST STATUS: $lprog = $str_status (exit status " . $exit_status . $str_signal . $str_core . ")\n"; + print "--------------------------------------------------\n\n"; + # Summary output + print OF "\t\t\t$str_status\n"; +} + +sub ux_start_prog { +# parameters: +$lprog = shift; # command to run + + # Create a process group for the child + # so we can kill all of it if needed + setsid or die "setsid failed: $!"; + # Start test program + exec("./$lprog"); + # We should not be here unless exec failed. + print "Faild to exec $lprog"; + exit 1 << 8; +} + +sub ux_wait_timeout { +# parameters: +$lpid = shift; # child process id +$ltimeout = shift; # timeout + + if ($ltimeout == 0) { + # No timeout: use blocking wait + $ret = waitpid($lpid,0); + # Exit and don't kill + $lstatus = $?; + $ltimeout = -1; + } else { + while ($ltimeout > 0) { + # Check status of child using non blocking wait + $ret = waitpid($lpid, WNOHANG); + if ($ret == 0) { + # Child still running + # print "Time left=$ltimeout\n"; + sleep 1; + $ltimeout--; + } else { + # Child has ended + $lstatus = $?; + # Exit the wait loop and don't kill + $ltimeout = -1; + } + } + } + + if ($ltimeout == 0) { + # we ran all the timeout: it's time to kill the child + print "Timeout ! Kill child process $lpid\n"; + # Kill the child process and group + kill(-9,$lpid); + $lstatus = 9; + } + + return $lstatus; +} + +sub ux_test_prog { +# parameters: +$prog = shift; # Program to test + + $child_pid = fork; + if ($child_pid == 0) { + # we are in the child process + print_begin($prog); + ux_start_prog($prog); + } else { + # we are in the parent process + $status = ux_wait_timeout($child_pid,$timeout); + # See Perlvar for documentation of $? + # exit status = $status >> 8 + # exit signal = $status & 127 (no signal = 0) + # core dump = $status & 128 (no core = 0) + print_end($prog, $status >> 8, $status & 127, $status & 128); + } + + return $status; +} + +sub win_path { +$lpath = shift; + + # MSYS drive letter = /c/ -> c:/ + $lpath =~ s/^\/(\w)\//$1:\//; + # Cygwin drive letter = /cygdrive/c/ -> c:/ + $lpath =~ s/^\/cygdrive\/(\w)\//$1:\//; + # replace / with \\ + $lpath =~ s/\//\\\\/g; + + return $lpath; +} + +sub win_ErrorReport{ + print Win32::FormatMessage( Win32::GetLastError() ); +} + +sub win_test_prog { +# parameters: +$prog = shift; # Program to test + + $status = 1; + $curdir = getcwd; + $curdir = win_path($curdir); + $prog_path = "$curdir\\$prog.exe"; + + print_begin($prog); + + Win32::Process::Create($ProcessObj, + "$prog_path", + "$prog", + 0, + NORMAL_PRIORITY_CLASS, + ".")|| die win_ErrorReport(); + $retwait = $ProcessObj->Wait($timeout * 1000); + + if ( $retwait == 0) { + # the prog didn't finish after the timeout: kill + $ProcessObj->Kill($status); + print "Timeout ! Process killed with exit status $status\n"; + } else { + # the prog finished before the timeout: get exit status + $ProcessObj->GetExitCode($status); + } + # There is no signal, no core on Windows + print_end($prog, $status, 0, 0); + + return $status +} + +# MAIN --------------- +@progs = ( +"accept", +"acceptread", +"acceptreademu", +"affinity", +"alarm", +"anonfm", +"atomic", +"attach", +"bigfile", +"cleanup", +"cltsrv", +"concur", +"cvar", +"cvar2", +"dlltest", +"dtoa", +"errcodes", +"exit", +"fdcach", +"fileio", +"foreign", +"formattm", +"fsync", +"gethost", +"getproto", +"i2l", +"initclk", +"inrval", +"instrumt", +"intrio", +"intrupt", +"io_timeout", +"ioconthr", +"join", +"joinkk", +"joinku", +"joinuk", +"joinuu", +"layer", +"lazyinit", +"libfilename", +"lltest", +"lock", +"lockfile", +"logfile", +"logger", +"many_cv", +"multiwait", +"nameshm1", +"nblayer", +"nonblock", +"ntioto", +"ntoh", +"op_2long", +"op_excl", +"op_filnf", +"op_filok", +"op_nofil", +"parent", +"parsetm", +"peek", +"perf", +"pipeping", +"pipeping2", +"pipeself", +"poll_nm", +"poll_to", +"pollable", +"prftest", +"primblok", +"provider", +"prpollml", +"pushtop", +"ranfile", +"randseed", +"reinit", +"rwlocktest", +"sel_spd", +"selct_er", +"selct_nm", +"selct_to", +"selintr", +"sema", +"semaerr", +"semaping", +"sendzlf", +"server_test", +"servr_kk", +"servr_uk", +"servr_ku", +"servr_uu", +"short_thread", +"sigpipe", +"socket", +"sockopt", +"sockping", +"sprintf", +"stack", +"stdio", +"str2addr", +"strod", +"switch", +"system", +"testbit", +"testfile", +"threads", +"timemac", +"timetest", +"tpd", +"udpsrv", +"vercheck", +"version", +"writev", +"xnotify", +"zerolen"); + +open_log; + +foreach $current_prog (@progs) { + if ($osname =~ $WINOS) { + win_test_prog($current_prog); + } else { + ux_test_prog($current_prog); + } +} + +close_log; diff -Nru nspr-4.9.5/nspr/pr/tests/runtests.sh nspr-4.10.7/nspr/pr/tests/runtests.sh --- nspr-4.9.5/nspr/pr/tests/runtests.sh 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/runtests.sh 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,270 @@ +#!/bin/sh +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# +# runtests.sh +# Bourne shell script for nspr tests +# + +SYSTEM_INFO=`uname -a` +OS_ARCH=`uname -s` + +if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "OS/2" ] +then + NULL_DEVICE=nul +else + NULL_DEVICE=/dev/null + FILE_D=`ulimit -n` + if [ $FILE_D -lt 512 ] + then + ulimit -n 512 + fi +fi + +# +# Irrevelant tests +# +#bug1test - used to demonstrate a bug on NT +#bigfile2 - requires 4Gig file creation. See BugZilla #5451 +#bigfile3 - requires 4Gig file creation. See BugZilla #5451 +#dbmalloc - obsolete; originally for testing debug version of nspr's malloc +#dbmalloc1 - obsolete; originally for testing debug version of nspr's malloc +#depend - obsolete; used to test a initial spec for library dependencies +#dceemu - used to tests special functions in NSPR for DCE emulation +#ipv6 - IPV6 not in use by NSPR clients +#mbcs - tests use of multi-byte charset for filenames. See BugZilla #25140 +#sproc_ch - obsolete; sproc-based tests for Irix +#sproc_p - obsolete; sproc-based tests for Irix +#io_timeoutk - obsolete; subsumed in io_timeout +#io_timeoutu - obsolete; subsumed in io_timeout +#prftest1 - obsolete; subsumed by prftest +#prftest2 - obsolete; subsumed by prftest +#prselect - obsolete; PR_Select is obsolete +#select2 - obsolete; PR_Select is obsolete +#sem - obsolete; PRSemaphore is obsolete +#stat - for OS2? +#suspend - private interfaces PR_SuspendAll, PR_ResumeAll, etc.. +#thruput - needs to be run manually as client/server +#time - used to measure time with native calls and nspr calls +#tmoacc - should be run with tmocon +#tmocon - should be run with tmoacc +#op_noacc - limited use +#yield - limited use for PR_Yield + +# +# Tests not run (but should) +# + +#forktest (failed on IRIX) +#nbconn - fails on some platforms +#poll_er - fails on some platforms? limited use? +#prpoll - the bad-FD test needs to be moved to a different test +#sleep - specific to OS/2 + +LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE} + +# +# Tests run on all platforms +# + +TESTS=" +accept +acceptread +acceptreademu +affinity +alarm +anonfm +atomic +attach +bigfile +cleanup +cltsrv +concur +cvar +cvar2 +dlltest +dtoa +errcodes +exit +fdcach +fileio +foreign +formattm +fsync +gethost +getproto +i2l +initclk +inrval +instrumt +intrio +intrupt +io_timeout +ioconthr +join +joinkk +joinku +joinuk +joinuu +layer +lazyinit +libfilename +lltest +lock +lockfile +logfile +logger +many_cv +multiwait +nameshm1 +nblayer +nonblock +ntioto +ntoh +op_2long +op_excl +op_filnf +op_filok +op_nofil +parent +parsetm +peek +perf +pipeping +pipeping2 +pipeself +poll_nm +poll_to +pollable +prftest +primblok +provider +prpollml +pushtop +ranfile +randseed +reinit +rwlocktest +sel_spd +selct_er +selct_nm +selct_to +selintr +sema +semaerr +semaping +sendzlf +server_test +servr_kk +servr_uk +servr_ku +servr_uu +short_thread +sigpipe +socket +sockopt +sockping +sprintf +stack +stdio +str2addr +strod +switch +system +testbit +testfile +threads +timemac +timetest +tpd +udpsrv +vercheck +version +writev +xnotify +zerolen" + +rval=0 + + +# +# When set, value of the environment variable TEST_TIMEOUT is the maximum +# time (secs) allowed for a test program beyond which it is terminated. +# If TEST_TIMEOUT is not set or if it's value is 0, then test programs +# don't timeout. +# +# Running runtests.ksh under MKS toolkit on NT, 95, 98 does not cause +# timeout detection correctly. For these platforms, do not attempt timeout +# test. (lth). +# +# + +OS_PLATFORM=`uname` +OBJDIR=`basename $PWD` +printf "\nNSPR Test Results - $OBJDIR\n\n" +printf "BEGIN\t\t\t`date`\n" +printf "NSPR_TEST_LOGFILE\t${LOGFILE}\n\n" +printf "Test\t\t\tResult\n\n" +if [ $OS_PLATFORM = "Windows_95" ] || [ $OS_PLATFORM = "Windows_98" ] || [ $OS_PLATFORM = "Windows_NT" ] || [ $OS_PLATFORM = "OS/2" ] ; then + for prog in $TESTS + do + printf "$prog" + printf "\nBEGIN TEST: $prog\n\n" >> ${LOGFILE} 2>&1 + ./$prog >> ${LOGFILE} 2>&1 + if [ 0 = $? ] ; then + printf "\t\t\tPassed\n"; + else + printf "\t\t\tFAILED\n"; + rval=1 + fi; + printf "\nEND TEST: $prog\n\n" >> ${LOGFILE} 2>&1 + done +else + for prog in $TESTS + do + printf "$prog" + printf "\nBEGIN TEST: $prog\n\n" >> ${LOGFILE} 2>&1 + export test_rval + ./$prog >> ${LOGFILE} 2>&1 & + test_pid=$! + sleep_pid=0 + if test -n "$TEST_TIMEOUT" && test "$TEST_TIMEOUT" -gt 0 + then + (sleep $TEST_TIMEOUT; kill $test_pid >/dev/null 2>&1 ) & + sleep_pid=$! + fi + wait $test_pid + test_rval=$? + [ $sleep_pid -eq 0 ] || kill $sleep_pid >/dev/null 2>&1 + if [ 0 = $test_rval ] ; then + printf "\t\t\tPassed\n"; + else + printf "\t\t\tFAILED\n"; + rval=1 + fi; + printf "\nEND TEST: $prog\n\n" >> ${LOGFILE} 2>&1 + done +fi; + +printf "END\t\t\t`date`\n" +exit $rval + + + + + + + + + + + + + + + + + diff -Nru nspr-4.9.5/nspr/pr/tests/runy2ktests.ksh nspr-4.10.7/nspr/pr/tests/runy2ktests.ksh --- nspr-4.9.5/nspr/pr/tests/runy2ktests.ksh 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/runy2ktests.ksh 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,237 @@ +#!/bin/ksh +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# +# runy2ktests.ksh +# Set system clock to Y2K dates of interest and run the Y2K tests. +# Needs root/administrator privilege +# +# WARNING: Because this script needs to be run with root/administrator +# privilege, thorough understanding of the script and extreme +# caution are urged. +# + +# +# SECTION I +# Define variables +# + +SYSTEM_INFO=`uname -a` +OS_ARCH=`uname -s` +if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "Windows_95" ] +then + NULL_DEVICE=nul +else + NULL_DEVICE=/dev/null +fi + +# +# Test dates for NSPR Y2K tests +# +Y2KDATES=" 123123591998.55 + 090923591999.55 + 123123591999.55 + 022823592000.55 + 022923592000.55 + 123123592000.55" + +Y2KDATES_AIX=" 12312359.5598 + 09092359.5599 + 12312359.5599 + 02282359.5500 + 02292359.5500 + 12312359.5500" + +Y2KDATES_HPUX=" 123123591998 + 090923591999 + 123123591999 + 022823592000 + 022923592000 + 123123592000" + +Y2KDATES_MKS=" 1231235998.55 + 0909235999.55 + 1231235999.55 + 0228235900.55 + 0229235900.55 + 1231235900.55" + +# +# NSPR Y2K tests +# +Y2KTESTS=" +y2k \n +y2ktmo \n +y2k \n +../runtests.ksh" + +Y2KTESTS_HPUX=" +y2k \n +y2ktmo -l 60\n +y2k \n +../runtests.ksh" + +# +# SECTION II +# Define functions +# + +save_date() +{ + case $OS_ARCH in + AIX) + SAVED_DATE=`date "+%m%d%H%M.%S%y"` + ;; + HP-UX) + SAVED_DATE=`date "+%m%d%H%M%Y"` + ;; + Windows_NT) + SAVED_DATE=`date "+%m%d%H%M%y.%S"` + ;; + Windows_95) + SAVED_DATE=`date "+%m%d%H%M%y.%S"` + ;; + *) + SAVED_DATE=`date "+%m%d%H%M%Y.%S"` + ;; + esac +} + +set_date() +{ + case $OS_ARCH in + Windows_NT) +# +# The date command in MKS Toolkit releases 5.1 and 5.2 +# uses the current DST status for the date we want to +# set the system clock to. However, the DST status for +# that date may be different from the current DST status. +# We can work around this problem by invoking the date +# command with the same date twice. +# + date "$1" > $NULL_DEVICE + date "$1" > $NULL_DEVICE + ;; + *) + date "$1" > $NULL_DEVICE + ;; + esac +} + +restore_date() +{ + set_date "$SAVED_DATE" +} + +savedate() +{ + case $OS_ARCH in + AIX) + SAVED_DATE=`date "+%m%d%H%M.%S%y"` + ;; + HP-UX) + SAVED_DATE=`date "+%m%d%H%M%Y"` + ;; + Windows_NT) + SAVED_DATE=`date "+%m%d%H%M%y.%S"` + ;; + Windows_95) + SAVED_DATE=`date "+%m%d%H%M%y.%S"` + ;; + *) + SAVED_DATE=`date "+%m%d%H%M%Y.%S"` + ;; + esac +} + +set_y2k_test_parameters() +{ +# +# set dates +# + case $OS_ARCH in + AIX) + DATES=$Y2KDATES_AIX + ;; + HP-UX) + DATES=$Y2KDATES_HPUX + ;; + Windows_NT) + DATES=$Y2KDATES_MKS + ;; + Windows_95) + DATES=$Y2KDATES_MKS + ;; + *) + DATES=$Y2KDATES + ;; + esac + +# +# set tests +# + case $OS_ARCH in + HP-UX) + TESTS=$Y2KTESTS_HPUX + ;; + *) + TESTS=$Y2KTESTS + ;; + esac +} + +# +# runtests: +# - runs each test in $TESTS after setting the +# system clock to each date in $DATES +# + +runtests() +{ +for newdate in ${DATES} +do + set_date $newdate + echo $newdate + echo "BEGIN\t\t\t`date`" + echo "Date\t\t\t\t\tTest\t\t\tResult" + echo $TESTS | while read prog + do + echo "`date`\t\t\c" + echo "$prog\c" + ./$prog >> ${LOGFILE} 2>&1 + if [ 0 = $? ] ; then + echo "\t\t\tPassed"; + else + echo "\t\t\tFAILED"; + fi; + done + echo "END\t\t\t`date`\n" +done + +} + +# +# SECTION III +# Run tests +# + +LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE} +OBJDIR=`basename $PWD` +echo "\nNSPR Year 2000 Test Results - $OBJDIR\n" +echo "SYSTEM:\t\t\t${SYSTEM_INFO}" +echo "NSPR_TEST_LOGFILE:\t${LOGFILE}\n" + + +save_date + +# +# Run NSPR Y2k and standard tests +# + +set_y2k_test_parameters +runtests + +restore_date diff -Nru nspr-4.9.5/nspr/pr/tests/rwlockrank.c nspr-4.10.7/nspr/pr/tests/rwlockrank.c --- nspr-4.9.5/nspr/pr/tests/rwlockrank.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/rwlockrank.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,120 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * RWLock rank tests + */ + +#include "nspr.h" +#include "plgetopt.h" + +static int _debug_on; +static PRRWLock *rwlock0; +static PRRWLock *rwlock1; +static PRRWLock *rwlock2; + +static void rwtest(void *args) +{ + PR_RWLock_Rlock(rwlock1); + PR_RWLock_Unlock(rwlock1); + + PR_RWLock_Rlock(rwlock1); + PR_RWLock_Unlock(rwlock1); + + // Test correct lock rank. + PR_RWLock_Rlock(rwlock1); + PR_RWLock_Rlock(rwlock2); + PR_RWLock_Unlock(rwlock2); + PR_RWLock_Unlock(rwlock1); + + PR_RWLock_Rlock(rwlock1); + PR_RWLock_Rlock(rwlock2); + PR_RWLock_Unlock(rwlock1); + PR_RWLock_Unlock(rwlock2); + + PR_RWLock_Rlock(rwlock1); + PR_RWLock_Rlock(rwlock0); + PR_RWLock_Rlock(rwlock2); + PR_RWLock_Unlock(rwlock2); + PR_RWLock_Unlock(rwlock0); + PR_RWLock_Unlock(rwlock1); + +#if 0 + // Test incorrect lock rank. + PR_RWLock_Rlock(rwlock2); + PR_RWLock_Rlock(rwlock1); + PR_RWLock_Unlock(rwlock1); + PR_RWLock_Unlock(rwlock2); + + PR_RWLock_Rlock(rwlock2); + PR_RWLock_Rlock(rwlock0); + PR_RWLock_Rlock(rwlock1); + PR_RWLock_Unlock(rwlock1); + PR_RWLock_Unlock(rwlock0); + PR_RWLock_Unlock(rwlock2); +#endif +} + +int main(int argc, char **argv) +{ + PRStatus rc; + PRThread *thread; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 'd': /* debug mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + rwlock0 = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "Lock 0"); + if (rwlock0 == NULL) { + fprintf(stderr, "PR_NewRWLock failed - error %d\n", + (int)PR_GetError()); + return 1; + } + rwlock1 = PR_NewRWLock(1, "Lock 1"); + if (rwlock1 == NULL) { + fprintf(stderr, "PR_NewRWLock failed - error %d\n", + (int)PR_GetError()); + return 1; + } + rwlock2 = PR_NewRWLock(2, "Lock 2"); + if (rwlock2 == NULL) { + fprintf(stderr, "PR_NewRWLock failed - error %d\n", + (int)PR_GetError()); + return 1; + } + + thread = PR_CreateThread(PR_USER_THREAD, rwtest, NULL, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (thread == NULL) { + fprintf(stderr, "PR_CreateThread failed - error %d\n", + (int)PR_GetError()); + PR_ProcessExit(2); + } + if (_debug_on) { + printf("%s: created thread = %p\n", argv[0], thread); + } + + rc = PR_JoinThread(thread); + PR_ASSERT(rc == PR_SUCCESS); + + PR_DestroyRWLock(rwlock0); + rwlock0 = NULL; + PR_DestroyRWLock(rwlock1); + rwlock1 = NULL; + PR_DestroyRWLock(rwlock2); + rwlock2 = NULL; + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/rwlocktest.c nspr-4.10.7/nspr/pr/tests/rwlocktest.c --- nspr-4.9.5/nspr/pr/tests/rwlocktest.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/rwlocktest.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,209 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/* + * + * RWLock tests + * + * Several threads are created to access and modify data arrays using + * PRRWLocks for synchronization. Two data arrays, array_A and array_B, are + * initialized with random data and a third array, array_C, is initialized + * with the sum of the first 2 arrays. + * + * Each one of the threads acquires a read lock to verify that the sum of + * the arrays A and B is equal to array C, and acquires a write lock to + * consistently update arrays A and B so that their is equal to array C. + * + */ + +#include "nspr.h" +#include "plgetopt.h" +#include "prrwlock.h" + +static int _debug_on; +static void rwtest(void *args); +static PRInt32 *array_A,*array_B,*array_C; +static void update_array(void); +static void check_array(void); + +typedef struct thread_args { + PRRWLock *rwlock; + PRInt32 loop_cnt; +} thread_args; + +PRFileDesc *output; +PRFileDesc *errhandle; + +#define DEFAULT_THREAD_CNT 4 +#define DEFAULT_LOOP_CNT 100 +#define TEST_ARRAY_SIZE 100 + +int main(int argc, char **argv) +{ + PRInt32 cnt; + PRStatus rc; + PRInt32 i; + + PRInt32 thread_cnt = DEFAULT_THREAD_CNT; + PRInt32 loop_cnt = DEFAULT_LOOP_CNT; + PRThread **threads; + thread_args *params; + PRRWLock *rwlock1; + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + case 't': /* thread count */ + thread_cnt = atoi(opt->value); + break; + case 'c': /* loop count */ + loop_cnt = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_SetConcurrency(4); + + output = PR_GetSpecialFD(PR_StandardOutput); + errhandle = PR_GetSpecialFD(PR_StandardError); + + rwlock1 = PR_NewRWLock(0,"Lock 1"); + if (rwlock1 == NULL) { + PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n", + PR_GetError()); + return 1; + } + + threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt); + params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt); + + /* + * allocate and initialize data arrays + */ + array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); + array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); + array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); + cnt = 0; + for (i=0; i < TEST_ARRAY_SIZE;i++) { + array_A[i] = cnt++; + array_B[i] = cnt++; + array_C[i] = array_A[i] + array_B[i]; + } + + if (_debug_on) + PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0], + thread_cnt, loop_cnt); + for(cnt = 0; cnt < thread_cnt; cnt++) { + PRThreadScope scope; + + params[cnt].rwlock = rwlock1; + params[cnt].loop_cnt = loop_cnt; + + /* + * create LOCAL and GLOBAL threads alternately + */ + if (cnt & 1) + scope = PR_LOCAL_THREAD; + else + scope = PR_GLOBAL_THREAD; + + threads[cnt] = PR_CreateThread(PR_USER_THREAD, + rwtest, ¶ms[cnt], + PR_PRIORITY_NORMAL, + scope, + PR_JOINABLE_THREAD, + 0); + if (threads[cnt] == NULL) { + PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n", + PR_GetError()); + PR_ProcessExit(2); + } + if (_debug_on) + PR_fprintf(output,"%s: created thread = %p\n", argv[0], + threads[cnt]); + } + + for(cnt = 0; cnt < thread_cnt; cnt++) { + rc = PR_JoinThread(threads[cnt]); + PR_ASSERT(rc == PR_SUCCESS); + + } + + PR_DELETE(threads); + PR_DELETE(params); + + PR_DELETE(array_A); + PR_DELETE(array_B); + PR_DELETE(array_C); + + PR_DestroyRWLock(rwlock1); + + + printf("PASS\n"); + return 0; +} + +static void rwtest(void *args) +{ + PRInt32 index; + thread_args *arg = (thread_args *) args; + + + for (index = 0; index < arg->loop_cnt; index++) { + + /* + * verify sum, update arrays and verify sum again + */ + + PR_RWLock_Rlock(arg->rwlock); + check_array(); + PR_RWLock_Unlock(arg->rwlock); + + PR_RWLock_Wlock(arg->rwlock); + update_array(); + PR_RWLock_Unlock(arg->rwlock); + + PR_RWLock_Rlock(arg->rwlock); + check_array(); + PR_RWLock_Unlock(arg->rwlock); + } + if (_debug_on) + PR_fprintf(output, + "Thread[0x%x] lock = 0x%x exiting\n", + PR_GetCurrentThread(), arg->rwlock); + +} + +static void check_array(void) +{ +PRInt32 i; + + for (i=0; i < TEST_ARRAY_SIZE;i++) + if (array_C[i] != (array_A[i] + array_B[i])) { + PR_fprintf(output, "Error - data check failed\n"); + PR_ProcessExit(1); + } +} + +static void update_array(void) +{ +PRInt32 i; + + for (i=0; i < TEST_ARRAY_SIZE;i++) { + array_A[i] += i; + array_B[i] -= i; + } +} diff -Nru nspr-4.9.5/nspr/pr/tests/selct_er.c nspr-4.10.7/nspr/pr/tests/selct_er.c --- nspr-4.9.5/nspr/pr/tests/selct_er.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/selct_er.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,200 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1997 - Netscape Communications Corporation +** +** Name: prselect_err.c +** +** Description: tests PR_Select with sockets Error condition functions. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +#ifdef XP_BEOS +#include +int main() +{ + printf( "This test is not ported to the BeOS\n" ); + return 0; +} +#else + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "primpl.h" +#include "pprio.h" +#include "prnetdb.h" + +#include +#include +#include + + +PRIntn failed_already=0; +PRIntn debug_mode; + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock1, *listenSock2; + PRFileDesc *badFD; + PRUint16 listenPort1, listenPort2; + PRNetAddr addr; + PR_fd_set readFdSet; + char buf[128]; + PRInt32 retVal; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (debug_mode) { + printf("This program tests PR_Select with sockets. Error\n"); + printf("reporting operations are tested.\n\n"); + } + + /* Create two listening sockets */ + if ((listenSock1 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = AF_INET; + addr.inet.ip = PR_htonl(INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort1 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock1, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + + if ((listenSock2 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = AF_INET; + addr.inet.ip = PR_htonl(INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort2 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock2, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu and %hu\n\n", + listenPort1, listenPort2); + if (debug_mode) printf("%s", buf); + + /* Set up the fd set */ + PR_FD_ZERO(&readFdSet); + PR_FD_SET(listenSock1, &readFdSet); + PR_FD_SET(listenSock2, &readFdSet); + + + /* Testing bad fd */ + if (debug_mode) printf("PR_Select should detect a bad file descriptor\n"); + if ((badFD = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a TCP socket\n"); + failed_already=1; + goto exit_now; + } + + PR_FD_SET(badFD, &readFdSet); + /* + * Make the fd invalid + */ +#if defined(XP_UNIX) + close(PR_FileDesc2NativeHandle(badFD)); +#elif defined(XP_OS2) + soclose(PR_FileDesc2NativeHandle(badFD)); +#elif defined(WIN32) || defined(WIN16) + closesocket(PR_FileDesc2NativeHandle(badFD)); +#else +#error "Unknown architecture" +#endif + + retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, + PR_INTERVAL_NO_TIMEOUT); + if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) { + fprintf(stderr, "Failed to detect the bad fd: " + "PR_Select returns %d\n", retVal); + if (retVal == -1) { + fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), + PR_GetOSError()); + failed_already=1; + } + goto exit_now; + } + if (debug_mode) printf("PR_Select detected a bad fd. Test passed.\n\n"); + PR_FD_CLR(badFD, &readFdSet); + + PR_Cleanup(); + goto exit_now; +exit_now: + if(failed_already) + return 1; + else + return 0; + +} + +#endif /* XP_BEOS */ diff -Nru nspr-4.9.5/nspr/pr/tests/selct_nm.c nspr-4.10.7/nspr/pr/tests/selct_nm.c --- nspr-4.9.5/nspr/pr/tests/selct_nm.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/selct_nm.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,284 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1997 - Netscape Communications Corporation +** +** Name: prselect_norm.c +** +** Description: tests PR_Select with sockets - Normal operations. +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prinit.h" +#include "prio.h" +#include "prlog.h" +#include "prprf.h" +#include "prerror.h" +#include "prnetdb.h" + +#include "obsolete/probslet.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + +static void +clientThreadFunc(void *arg) +{ + PRUintn port = (PRUintn) arg; + PRFileDesc *sock; + PRNetAddr addr; + char buf[128]; + int i; + + addr.inet.family = PR_AF_INET; + addr.inet.port = PR_htons((PRUint16)port); + addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port); + + for (i = 0; i < 5; i++) { + sock = PR_NewTCPSocket(); + PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); + PR_Write(sock, buf, sizeof(buf)); + PR_Close(sock); + } +} + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock1, *listenSock2; + PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds; + PRIntn nfds; + PRUint16 listenPort1, listenPort2; + PRNetAddr addr; + PR_fd_set readFdSet; + char buf[128]; + PRThread *clientThread; + PRInt32 retVal; + PRIntn i, j; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (debug_mode) { + printf("This program tests PR_Select with sockets. \n"); + printf(" Normal operation are tested.\n\n"); + } + + /* Create two listening sockets */ + if ((listenSock1 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort1 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock1, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + + if ((listenSock2 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort2 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock2, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); +failed_already=1; + goto exit_now; + } + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu and %hu\n\n", + listenPort1, listenPort2); + if (debug_mode) printf("%s", buf); + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort1, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + failed_already=1; + goto exit_now; + } + + clientThread = PR_CreateThread(PR_USER_THREAD, + clientThreadFunc, (void *) listenPort2, + PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (clientThread == NULL) { + fprintf(stderr, "can't create thread\n"); + failed_already=1; + goto exit_now; + } + + if (debug_mode) { + printf("Two client threads are created. Each of them will\n"); + printf("send data to one of the two ports the server is listening on.\n"); + printf("The data they send is the port number. Each of them send\n"); + printf("the data five times, so you should see ten lines below,\n"); + printf("interleaved in an arbitrary order.\n"); + } + /* set up the fd array */ + fds = fds0; + other_fds = fds1; + fds[0] = listenSock1; + fds[1] = listenSock2; + nfds = 2; + /* Set up the fd set */ + PR_FD_ZERO(&readFdSet); + PR_FD_SET(listenSock1, &readFdSet); + PR_FD_SET(listenSock2, &readFdSet); + + /* 20 events total */ + i = 0; + while (i < 20) { + PRFileDesc **tmp; + int nextIndex; + int nEvents = 0; + + retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, + PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(retVal != 0); /* no timeout */ + if (retVal == -1) { + fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + failed_already=1; + goto exit_now; + } + + nextIndex = 2; + /* the two listening sockets */ + for (j = 0; j < 2; j++) { + other_fds[j] = fds[j]; + if (PR_FD_ISSET(fds[j], &readFdSet)) { + PRFileDesc *sock; + + nEvents++; + sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT); + if (sock == NULL) { + fprintf(stderr, "PR_Accept() failed\n"); + failed_already=1; + goto exit_now; + } + other_fds[nextIndex] = sock; + PR_FD_SET(sock, &readFdSet); + nextIndex++; + } + PR_FD_SET(fds[j], &readFdSet); + } + + for (j = 2; j < nfds; j++) { + if (PR_FD_ISSET(fds[j], &readFdSet)) { + PRInt32 nBytes; + + PR_FD_CLR(fds[j], &readFdSet); + nEvents++; + nBytes = PR_Read(fds[j], buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read() failed\n"); + failed_already=1; + goto exit_now; + } + /* Just to be safe */ + buf[127] = '\0'; + PR_Close(fds[j]); + if (debug_mode) printf("The server received \"%s\" from a client\n", buf); + } else { + PR_FD_SET(fds[j], &readFdSet); + other_fds[nextIndex] = fds[j]; + nextIndex++; + } + } + + PR_ASSERT(retVal == nEvents); + /* swap */ + tmp = fds; + fds = other_fds; + other_fds = tmp; + nfds = nextIndex; + i += nEvents; + } + + if (debug_mode) printf("Test passed\n"); + + PR_Cleanup(); + goto exit_now; +exit_now: + if(failed_already) + return 1; + else + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/selct_to.c nspr-4.10.7/nspr/pr/tests/selct_to.c --- nspr-4.9.5/nspr/pr/tests/selct_to.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/selct_to.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** 1997 - Netscape Communications Corporation +** +** Name: prselect_to.c +** +** Description: tests PR_Select with sockets. Time out functions +** +** Modification History: +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prinit.h" +#include "prio.h" +#include "prlog.h" +#include "prprf.h" +#include "prnetdb.h" + +#include "obsolete/probslet.h" + +#include "prerror.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock1, *listenSock2; + PRUint16 listenPort1, listenPort2; + PRNetAddr addr; + PR_fd_set readFdSet; + char buf[128]; + PRInt32 retVal; + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (debug_mode) { + printf("This program tests PR_Select with sockets. Timeout \n"); + printf("operations are tested.\n\n"); + } + + /* Create two listening sockets */ + if ((listenSock1 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort1 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock1, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + + if ((listenSock2 = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Can't create a new TCP socket\n"); + failed_already=1; + goto exit_now; + } + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + addr.inet.port = PR_htons(0); + if (PR_Bind(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "Can't bind socket\n"); + failed_already=1; + goto exit_now; + } + if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + failed_already=1; + goto exit_now; + } + listenPort2 = PR_ntohs(addr.inet.port); + if (PR_Listen(listenSock2, 5) == PR_FAILURE) { + fprintf(stderr, "Can't listen on a socket\n"); + failed_already=1; + goto exit_now; + } + PR_snprintf(buf, sizeof(buf), + "The server thread is listening on ports %hu and %hu\n\n", + listenPort1, listenPort2); + if (debug_mode) printf("%s", buf); + + /* Set up the fd set */ + PR_FD_ZERO(&readFdSet); + PR_FD_SET(listenSock1, &readFdSet); + PR_FD_SET(listenSock2, &readFdSet); + + /* Testing timeout */ + if (debug_mode) printf("PR_Select should time out in 5 seconds\n"); + retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL, + PR_SecondsToInterval(5)); + if (retVal != 0) { + PR_snprintf(buf, sizeof(buf), + "PR_Select should time out and return 0, but it returns %ld\n", + retVal); + fprintf(stderr, "%s", buf); + if (retVal == -1) { + fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(), + PR_GetOSError()); + failed_already=1; + } + goto exit_now; + } + if (debug_mode) printf("PR_Select timed out. Test passed.\n\n"); + + PR_Cleanup(); + +exit_now: + if(failed_already) + return 1; + else + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/select2.c nspr-4.10.7/nspr/pr/tests/select2.c --- nspr-4.9.5/nspr/pr/tests/select2.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/select2.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,322 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: select2.c +** +** Description: Measure PR_Select and Empty_Select performance. +** +** Modification History: +** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" +#include "prttools.h" +#include "primpl.h" + +#include +#include +#include +#if defined(OS2) +#include +#endif + +#define PORT 8000 +#define DEFAULT_COUNT 10 +PRInt32 count; + + +/*********************************************************************** +** PRIVATE FUNCTION: Test_Result +** DESCRIPTION: Used in conjunction with the regress tool, prints out the +** status of the test case. +** INPUTS: PASS/FAIL +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** +** RESTRICTIONS: +** None +** MEMORY: NA +** ALGORITHM: Determine what the status is and print accordingly. +** +***********************************************************************/ + + +static void Test_Result (int result) +{ + switch (result) + { + case PASS: + printf ("PASS\n"); + break; + case FAIL: + printf ("FAIL\n"); + break; + default: + printf ("NOSTATUS\n"); + break; + } +} + +static void EmptyPRSelect(void) +{ + PRInt32 index = count; + PRInt32 rv; + + for (; index--;) + rv = PR_Select(0, NULL, NULL, NULL, PR_INTERVAL_NO_WAIT); +} + +static void EmptyNativeSelect(void) +{ + PRInt32 rv; + PRInt32 index = count; + struct timeval timeout; + + timeout.tv_sec = timeout.tv_usec = 0; + for (; index--;) + rv = select(0, NULL, NULL, NULL, &timeout); +} + +static void PRSelectTest(void) +{ + PRFileDesc *listenSocket; + PRNetAddr serverAddr; + + if ( (listenSocket = PR_NewTCPSocket()) == NULL) { + if (debug_mode) printf("\tServer error creating listen socket\n"); + return; + } + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(INADDR_ANY); + + if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { + if (debug_mode) printf("\tServer error binding to server address\n"); + PR_Close(listenSocket); + return; + } + + if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { + if (debug_mode) printf("\tServer error listening to server socket\n"); + PR_Close(listenSocket); + return; + } + if (debug_mode) printf("Listening on port %d\n", PORT); + + { + PRFileDesc *newSock; + PRNetAddr rAddr; + PRInt32 loops = 0; + PR_fd_set rdset; + PRInt32 rv; + PRInt32 bytesRead; + char buf[11]; + + loops++; + + if (debug_mode) printf("Going into accept\n"); + + newSock = PR_Accept(listenSocket, + &rAddr, + PR_INTERVAL_NO_TIMEOUT); + + if (newSock) { + if (debug_mode) printf("Got connection!\n"); + } else { + if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError()); + else Test_Result (FAIL); + } + + PR_FD_ZERO(&rdset); + PR_FD_SET(newSock, &rdset); + + if (debug_mode) printf("Going into select \n"); + + rv = PR_Select(0, &rdset, 0, 0, PR_INTERVAL_NO_TIMEOUT); + + if (debug_mode) printf("return from select is %d\n", rv); + + if (PR_FD_ISSET(newSock, &rdset)) { + if (debug_mode) printf("I can't believe it- the socket is ready okay!\n"); + } else { + if (debug_mode) printf("Damn; the select test failed...\n"); + else Test_Result (FAIL); + } + + strcpy(buf, "XXXXXXXXXX"); + bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT); + buf[10] = '\0'; + + if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf); + + PR_Close(newSock); + } + +} + +#if defined(XP_UNIX) + +static void NativeSelectTest(void) +{ + PRFileDesc *listenSocket; + PRNetAddr serverAddr; + + if ( (listenSocket = PR_NewTCPSocket()) == NULL) { + if (debug_mode) printf("\tServer error creating listen socket\n"); + return; + } + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(INADDR_ANY); + + if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { + if (debug_mode) printf("\tServer error binding to server address\n"); + PR_Close(listenSocket); + return; + } + + if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { + if (debug_mode) printf("\tServer error listening to server socket\n"); + PR_Close(listenSocket); + return; + } + if (debug_mode) printf("Listening on port %d\n", PORT); + + { + PRIntn osfd; + char buf[11]; + fd_set rdset; + PRNetAddr rAddr; + PRFileDesc *newSock; + struct timeval timeout; + PRInt32 bytesRead, rv, loops = 0; + + loops++; + + if (debug_mode) printf("Going into accept\n"); + + newSock = PR_Accept(listenSocket, &rAddr, PR_INTERVAL_NO_TIMEOUT); + + if (newSock) { + if (debug_mode) printf("Got connection!\n"); + } else { + if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError()); + else Test_Result (FAIL); + } + + osfd = PR_FileDesc2NativeHandle(newSock); + FD_ZERO(&rdset); + FD_SET(osfd, &rdset); + + if (debug_mode) printf("Going into select \n"); + + + timeout.tv_sec = 2; timeout.tv_usec = 0; + rv = select(osfd + 1, &rdset, NULL, NULL, &timeout); + + if (debug_mode) printf("return from select is %d\n", rv); + + if (FD_ISSET(osfd, &rdset)) { + if (debug_mode) + printf("I can't believe it- the socket is ready okay!\n"); + } else { + if (debug_mode) printf("Damn; the select test failed...\n"); + else Test_Result (FAIL); + } + + strcpy(buf, "XXXXXXXXXX"); + bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT); + buf[10] = '\0'; + + if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf); + + PR_Close(newSock); + } + +} /* NativeSelectTest */ + +#endif /* defined(XP_UNIX) */ + +/************************************************************************/ + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + PRInt32 tot; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + tot = PR_IntervalToMilliseconds(stop-start); + + if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot); +} + +int main(int argc, char **argv) +{ + + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (argc > 2) { + count = atoi(argv[2]); + } else { + count = DEFAULT_COUNT; + } + +#if defined(XP_UNIX) + Measure(NativeSelectTest, "time to call 1 element select()"); +#endif + Measure(EmptyPRSelect, "time to call Empty PR_select()"); + Measure(EmptyNativeSelect, "time to call Empty select()"); + Measure(PRSelectTest, "time to call 1 element PR_select()"); + + if (!debug_mode) Test_Result (NOSTATUS); + PR_Cleanup(); + + +} diff -Nru nspr-4.9.5/nspr/pr/tests/selintr.c nspr-4.10.7/nspr/pr/tests/selintr.c --- nspr-4.9.5/nspr/pr/tests/selintr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/selintr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test whether classic NSPR's select() wrapper properly blocks + * the periodic SIGALRM clocks. On some platforms (such as + * HP-UX and SINIX) an interrupted select() system call is + * restarted with the originally specified timeout, ignoring + * the time that has elapsed. If a select() call is interrupted + * repeatedly, it will never time out. (See Bugzilla bug #39674.) + */ + +#if !defined(XP_UNIX) + +/* + * This test is applicable to Unix only. + */ + +int main() +{ + return 0; +} + +#else /* XP_UNIX */ + +#include "nspr.h" + +#include +#include +#ifdef SYMBIAN +#include +#endif + +int main(int argc, char **argv) +{ + struct timeval timeout; + int rv; + + PR_SetError(0, 0); /* force NSPR to initialize */ + PR_EnableClockInterrupts(); + + /* 2 seconds timeout */ + timeout.tv_sec = 2; + timeout.tv_usec = 0; + rv = select(1, NULL, NULL, NULL, &timeout); + printf("select returned %d\n", rv); + return 0; +} + +#endif /* XP_UNIX */ diff -Nru nspr-4.9.5/nspr/pr/tests/sel_spd.c nspr-4.10.7/nspr/pr/tests/sel_spd.c --- nspr-4.9.5/nspr/pr/tests/sel_spd.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sel_spd.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,523 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test the speed of select within NSPR + * + */ + +#include "nspr.h" +#include "prpriv.h" + +#include +#include +#include +#include +#ifdef SYMBIAN +#include +#endif + +#define PORT_BASE 19000 + +typedef struct timer_slot_t { + unsigned long d_connect; + unsigned long d_cl_data; + unsigned long d_sv_data; + unsigned long d_close; + unsigned long d_total; + unsigned long requests; +} timer_slot_t; + +static long _iterations = 5; +static long _client_data = 8192; + +#ifdef SYMBIAN +/* + * Symbian OS does not scale well specially the requirement for thread stack + * space and buffer allocation space. It is easy to get into a fragmented + * memory and not be able to allocate thread stack or client/server data + * buffer. + */ +static long _server_data = (8*1024); +static long _threads_max = 10, _threads = 10; +#else +static long _server_data = (128*1024); +static long _threads_max = 10, _threads = 10; +#endif + +static int verbose=0; +static PRMonitor *exit_cv; +static long _thread_exit_count; +static timer_slot_t *timer_data; +static PRThreadScope scope1, scope2; + +void tally_results(int); + +/* return the diff in microseconds */ +unsigned long _delta(PRIntervalTime *start, PRIntervalTime *stop) +{ + /* + * Will C do the right thing with unsigned arithemtic? + */ + return PR_IntervalToMicroseconds(*stop - *start); +} + +int _readn(PRFileDesc *sock, char *buf, int len) +{ + int rem; + int bytes; + + for (rem=len; rem; rem -= bytes) { + bytes = PR_Recv(sock, buf+len-rem, rem, 0, PR_INTERVAL_NO_TIMEOUT); + if (bytes <= 0) + return -1; + } + return len; +} + +void +_thread_exit(int id) +{ + PR_EnterMonitor(exit_cv); +#ifdef DEBUG + fprintf(stdout, "Thread %d EXIT\n", id); +#endif + + _thread_exit_count--; + if (_thread_exit_count == 0) { +#ifdef DEBUG + fprintf(stdout, "Thread %d EXIT triggered notify\n", id); +#endif + PR_Notify(exit_cv); + } + PR_ExitMonitor(exit_cv); +} + +void +_server_thread(void *arg_id) +{ + void _client_thread(void *); + PRThread *thread; + int *id = (int *)arg_id; + PRFileDesc *sock; + PRSocketOptionData sockopt; + PRNetAddr sa; + PRFileDesc * newsock; + char *data_buffer = NULL; + int data_buffer_size; + int index; + PRIntervalTime start, + connect_done, + read_done, + write_done, + close_done; + + +#ifdef DEBUG + fprintf(stdout, "server thread %d alive\n", *id); +#endif + + data_buffer_size = (_client_data>_server_data?_client_data:_server_data); + + if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL ) { + fprintf(stderr, "Error creating buffer in server thread %d\n", *id); + goto done; + } + + + if ( (sock = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Error creating socket in server thread %d\n", *id); + goto done; + } + + sockopt.option = PR_SockOpt_Reuseaddr; + sockopt.value.reuse_addr = PR_TRUE; + if ( PR_SetSocketOption(sock, &sockopt) == PR_FAILURE) { + fprintf(stderr, "Error setting socket option in server thread %d\n", *id); + goto done; + } + + memset(&sa, 0 , sizeof(sa)); + sa.inet.family = PR_AF_INET; + sa.inet.port = PR_htons(PORT_BASE + *id); + sa.inet.ip = PR_htonl(PR_INADDR_ANY); + + if ( PR_Bind(sock, &sa) < 0) { + fprintf(stderr, "Error binding socket in server thread %d errno = %d\n", *id, errno); + goto done; + } + + if ( PR_Listen(sock, 32) < 0 ) { + fprintf(stderr, "Error listening to socket in server thread %d\n", *id); + goto done; + } + + /* Tell the client to start */ + if ( (thread = PR_CreateThread(PR_USER_THREAD, + _client_thread, + id, + PR_PRIORITY_NORMAL, + scope2, + PR_UNJOINABLE_THREAD, + 0)) == NULL) + fprintf(stderr, "Error creating client thread %d\n", *id); + + for (index = 0; index< _iterations; index++) { + +#ifdef DEBUG + fprintf(stdout, "server thread %d loop %d\n", *id, index); +#endif + + start = PR_IntervalNow(); + + if ( (newsock = PR_Accept(sock, &sa, + PR_INTERVAL_NO_TIMEOUT)) == NULL) { + fprintf(stderr, "Error accepting connection %d in server thread %d\n", + index, *id); + goto done; + } +#ifdef DEBUG + fprintf(stdout, "server thread %d got connection %d\n", *id, newsock); +#endif + + + connect_done = PR_IntervalNow(); + + if ( _readn(newsock, data_buffer, _client_data) < _client_data) { + fprintf(stderr, "Error reading client data for iteration %d in server thread %d\n", index, *id ); + goto done; + } + +#ifdef DEBUG + fprintf(stdout, "server thread %d read %d bytes\n", *id, _client_data); +#endif + read_done = PR_IntervalNow(); + + if ( PR_Send(newsock, data_buffer, _server_data, 0, + PR_INTERVAL_NO_TIMEOUT) < _server_data) { + fprintf(stderr, "Error sending client data for iteration %d in server thread %d\n", index, *id ); + goto done; + } + +#ifdef DEBUG + fprintf(stdout, "server thread %d write %d bytes\n", *id, _server_data); +#endif + + write_done = PR_IntervalNow(); + + PR_Close(newsock); + + close_done = PR_IntervalNow(); + + timer_data[2*(*id)].d_connect += _delta(&start, &connect_done); + timer_data[2*(*id)].d_cl_data += _delta(&connect_done, &read_done); + timer_data[2*(*id)].d_sv_data += _delta(&read_done, &write_done); + timer_data[2*(*id)].d_close += _delta(&write_done, &close_done); + timer_data[2*(*id)].d_total += _delta(&start, &close_done); + timer_data[2*(*id)].requests++; + + +#ifdef DEBUG + fprintf(stdout, "server: %d %d %d %d %d\n", + _delta(&start, &connect_done), _delta(&connect_done, &read_done), + _delta(&read_done, &write_done), _delta(&write_done, &close_done), + _delta(&start, &close_done)); +#endif + } + +done: + if (data_buffer != NULL) PR_Free (data_buffer); + if (sock) PR_Close(sock); + _thread_exit(*id); + return; +} + +void +_client_thread(void *arg_id) +{ + int *id = (int *)arg_id; + int index; + PRNetAddr sa; + PRFileDesc *sock_h; + char *data_buffer = NULL; + int data_buffer_size; + int bytes; + PRIntervalTime start, + connect_done, + read_done, + write_done, + close_done; + PRStatus rv; + +#ifdef DEBUG + fprintf(stdout, "client thread %d alive\n", *id); +#endif + + data_buffer_size = (_client_data>_server_data?_client_data:_server_data); + + if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL) { + fprintf(stderr, "Error creating buffer in server thread %d\n", *id); + goto done; + } + + memset(&sa, 0 , sizeof(sa)); + rv = PR_InitializeNetAddr(PR_IpAddrLoopback, PORT_BASE + *id, &sa); + PR_ASSERT(PR_SUCCESS == rv); + + for (index = 0; index< _iterations; index++) { + +#ifdef DEBUG + fprintf(stdout, "client thread %d loop %d\n", *id, index); +#endif + + start = PR_IntervalNow(); + if ( (sock_h = PR_NewTCPSocket()) == NULL) { + fprintf(stderr, "Error creating socket %d in client thread %d\n", + index, *id); + goto done; + } + +#ifdef DEBUG + fprintf(stdout, "client thread %d socket created %d\n", *id, sock_h); +#endif + + if ( PR_Connect(sock_h, &sa, + PR_INTERVAL_NO_TIMEOUT) < 0) { + fprintf(stderr, "Error accepting connection %d in client thread %d\n", + index, *id); + goto done; + } + +#ifdef DEBUG + fprintf(stdout, "client thread %d socket connected %d\n", *id, sock_h); +#endif + + connect_done = PR_IntervalNow(); + if ( PR_Send(sock_h, data_buffer, _client_data, 0, + PR_INTERVAL_NO_TIMEOUT) < _client_data) { + fprintf(stderr, "Error sending client data for iteration %d in client thread %d\n", index, *id ); + goto done; + } + +#ifdef DEBUG + fprintf(stdout, "client thread %d socket wrote %d\n", *id, _client_data); +#endif + + write_done = PR_IntervalNow(); + if ( (bytes = _readn(sock_h, data_buffer, _server_data)) < _server_data) { + fprintf(stderr, "Error reading server data for iteration %d in client thread %d (read %d bytes)\n", index, *id, bytes ); + goto done; + } + +#ifdef DEBUG + fprintf(stdout, "client thread %d socket read %d\n", *id, _server_data); +#endif + + read_done = PR_IntervalNow(); + PR_Close(sock_h); + close_done = PR_IntervalNow(); + + timer_data[2*(*id)+1].d_connect += _delta(&start, &connect_done); + timer_data[2*(*id)+1].d_cl_data += _delta(&connect_done, &write_done); + timer_data[2*(*id)+1].d_sv_data += _delta(&write_done, &read_done); + timer_data[2*(*id)+1].d_close += _delta(&read_done, &close_done); + timer_data[2*(*id)+1].d_total += _delta(&start, &close_done); + timer_data[2*(*id)+1].requests++; + } +done: + if (data_buffer != NULL) PR_Free (data_buffer); + _thread_exit(*id); + + return; +} + +static +void do_work(void) +{ + int index; + + _thread_exit_count = _threads * 2; + for (index=0; index<_threads; index++) { + PRThread *thread; + int *id = (int *)PR_Malloc(sizeof(int)); + + *id = index; + + if ( (thread = PR_CreateThread(PR_USER_THREAD, + _server_thread, + id, + PR_PRIORITY_NORMAL, + scope1, + PR_UNJOINABLE_THREAD, + 0)) == NULL) + fprintf(stderr, "Error creating server thread %d\n", index); + } + + PR_EnterMonitor(exit_cv); + while (_thread_exit_count > 0) + PR_Wait(exit_cv, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(exit_cv); + + fprintf(stdout, "TEST COMPLETE!\n"); + + tally_results(verbose); + +} + +static void do_workUU(void) +{ + scope1 = PR_LOCAL_THREAD; + scope2 = PR_LOCAL_THREAD; + do_work(); +} + +static void do_workUK(void) +{ + scope1 = PR_LOCAL_THREAD; + scope2 = PR_GLOBAL_THREAD; + do_work(); +} + +static void do_workKU(void) +{ + scope1 = PR_GLOBAL_THREAD; + scope2 = PR_LOCAL_THREAD; + do_work(); +} + +static void do_workKK(void) +{ + scope1 = PR_GLOBAL_THREAD; + scope2 = PR_GLOBAL_THREAD; + do_work(); +} + + + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + + printf("%40s: %6.2f usec\n", msg, d / _iterations); +} + + +int main(int argc, char **argv) +{ +#if defined(XP_UNIX) || defined(XP_OS2) + int opt; + PR_IMPORT_DATA(char *) optarg; +#endif + +#if defined(XP_UNIX) || defined(XP_OS2) + while ( (opt = getopt(argc, argv, "c:s:i:t:v")) != EOF) { + switch(opt) { + case 'i': + _iterations = atoi(optarg); + break; + case 't': + _threads_max = _threads = atoi(optarg); + break; + case 'c': + _client_data = atoi(optarg); + break; + case 's': + _server_data = atoi(optarg); + break; + case 'v': + verbose = 1; + break; + default: + break; + } + } +#endif + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + fprintf(stdout, "Running test for %d iterations with %d simultaneous threads.\n", + _iterations, _threads); + fprintf(stdout, "\tWill send %d bytes of client data and %d bytes of server data\n", + _client_data, _server_data); + + if ( (exit_cv = PR_NewMonitor()) == NULL) + fprintf(stderr, "Error creating monitor for exit cv\n"); + if ( (timer_data = (timer_slot_t *)PR_Malloc(2*_threads * sizeof(timer_slot_t))) == NULL) + fprintf(stderr, "error allocating thread time results array\n"); + memset(timer_data, 0 , 2*_threads*sizeof(timer_slot_t)); + + Measure(do_workUU, "select loop user/user"); + Measure(do_workUK, "select loop user/kernel"); + Measure(do_workKU, "select loop kernel/user"); + Measure(do_workKK, "select loop kernel/kernel"); + + + return 0; +} + +void +tally_results(int verbose) +{ + int index; + unsigned long tot_connect = 0; + unsigned long tot_cl_data = 0; + unsigned long tot_sv_data = 0; + unsigned long tot_close = 0; + unsigned long tot_all = 0; + unsigned long tot_requests = 0; + + fprintf(stdout, "Server results:\n\n"); + for (index=0; index<_threads_max*2; index+=2) { + + if (verbose) + fprintf(stdout, "server thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n", + index, timer_data[index].requests, timer_data[index].d_connect, + timer_data[index].d_cl_data, timer_data[index].d_sv_data, + timer_data[index].d_close, timer_data[index].d_total); + + tot_connect += timer_data[index].d_connect / _threads; + tot_cl_data += timer_data[index].d_cl_data / _threads; + tot_sv_data += timer_data[index].d_sv_data / _threads; + tot_close += timer_data[index].d_close / _threads; + tot_all += timer_data[index].d_total / _threads; + tot_requests += timer_data[index].requests / _threads; + } + fprintf(stdout, "----------\n"); + fprintf(stdout, "server per thread totals %u\t%u\t%u\t%u\t%u\n", + tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close); + fprintf(stdout, "server per thread elapsed time %u\n", tot_all); + fprintf(stdout, "----------\n"); + + tot_connect = tot_cl_data = tot_sv_data = tot_close = tot_all = tot_requests = 0; + fprintf(stdout, "Client results:\n\n"); + for (index=1; index<_threads_max*2; index+=2) { + + if (verbose) + fprintf(stdout, "client thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n", + index, timer_data[index].requests, timer_data[index].d_connect, + timer_data[index].d_cl_data, timer_data[index].d_sv_data, + timer_data[index].d_close, timer_data[index].d_total); + + tot_connect += timer_data[index].d_connect / _threads; + tot_cl_data += timer_data[index].d_cl_data / _threads; + tot_sv_data += timer_data[index].d_sv_data / _threads; + tot_close += timer_data[index].d_close / _threads; + tot_all += timer_data[index].d_total / _threads; + tot_requests += timer_data[index].requests / _threads; + } + fprintf(stdout, "----------\n"); + fprintf(stdout, "client per thread totals %u\t%u\t%u\t%u\t%u\n", + tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close); + fprintf(stdout, "client per thread elapsed time %u\n", tot_all); +} + diff -Nru nspr-4.9.5/nspr/pr/tests/sema.c nspr-4.10.7/nspr/pr/tests/sema.c --- nspr-4.9.5/nspr/pr/tests/sema.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sema.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "plgetopt.h" + +#include + +#define SEM_NAME1 "/tmp/foo.sem" +#define SEM_NAME2 "/tmp/bar.sem" +#define SEM_MODE 0666 +#define ITERATIONS 1000 + +static PRBool debug_mode = PR_FALSE; +static PRIntn iterations = ITERATIONS; +static PRIntn counter; +static PRSem *sem1, *sem2; + +/* + * Thread 2 waits on semaphore 2 and posts to semaphore 1. + */ +void ThreadFunc(void *arg) +{ + PRIntn i; + + for (i = 0; i < iterations; i++) { + if (PR_WaitSemaphore(sem2) == PR_FAILURE) { + fprintf(stderr, "PR_WaitSemaphore failed\n"); + exit(1); + } + if (counter == 2*i+1) { + if (debug_mode) printf("thread 2: counter = %d\n", counter); + } else { + fprintf(stderr, "thread 2: counter should be %d but is %d\n", + 2*i+1, counter); + exit(1); + } + counter++; + if (PR_PostSemaphore(sem1) == PR_FAILURE) { + fprintf(stderr, "PR_PostSemaphore failed\n"); + exit(1); + } + } +} + +static void Help(void) +{ + fprintf(stderr, "sema test program usage:\n"); + fprintf(stderr, "\t-d debug mode (FALSE)\n"); + fprintf(stderr, "\t-c loop count (%d)\n", ITERATIONS); + fprintf(stderr, "\t-h this message\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PRThread *thred; + PRIntn i; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'c': /* loop count */ + iterations = atoi(opt->value); + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) { + fprintf(stderr, "warning: removed semaphore %s left over " + "from previous run\n", SEM_NAME1); + } + if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) { + fprintf(stderr, "warning: removed semaphore %s left over " + "from previous run\n", SEM_NAME2); + } + + sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1); + if (NULL == sem1) { + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0); + if (NULL == sem2) { + fprintf(stderr, "PR_OpenSemaphore failed\n"); + exit(1); + } + thred = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (NULL == thred) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + + /* + * Thread 1 waits on semaphore 1 and posts to semaphore 2. + */ + for (i = 0; i < iterations; i++) { + if (PR_WaitSemaphore(sem1) == PR_FAILURE) { + fprintf(stderr, "PR_WaitSemaphore failed\n"); + exit(1); + } + if (counter == 2*i) { + if (debug_mode) printf("thread 1: counter = %d\n", counter); + } else { + fprintf(stderr, "thread 1: counter should be %d but is %d\n", + 2*i, counter); + exit(1); + } + counter++; + if (PR_PostSemaphore(sem2) == PR_FAILURE) { + fprintf(stderr, "PR_PostSemaphore failed\n"); + exit(1); + } + } + + if (PR_JoinThread(thred) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + + if (PR_CloseSemaphore(sem1) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + } + if (PR_CloseSemaphore(sem2) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + } + if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) { + fprintf(stderr, "PR_DeleteSemaphore failed\n"); + } + if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) { + fprintf(stderr, "PR_DeleteSemaphore failed\n"); + } + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/semaerr1.c nspr-4.10.7/nspr/pr/tests/semaerr1.c --- nspr-4.9.5/nspr/pr/tests/semaerr1.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/semaerr1.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "plgetopt.h" + +#include + +#ifdef SYMBIAN +#define SEM_NAME1 "c:\\data\\foo.sem" +#define SEM_NAME2 "c:\\data\\bar.sem" +#else +#define SEM_NAME1 "/tmp/foo.sem" +#define SEM_NAME2 "/tmp/bar.sem" +#endif +#define SEM_MODE 0666 + +static PRBool debug_mode = PR_FALSE; + +static void Help(void) +{ + fprintf(stderr, "semaerr1 test program usage:\n"); + fprintf(stderr, "\t-d debug mode (FALSE)\n"); + fprintf(stderr, "\t-h this message\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dh"); + PRSem *sem; + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + /* + * PR_SEM_CREATE|PR_SEM_EXCL should be able to + * create a nonexistent semaphore. + */ + (void) PR_DeleteSemaphore(SEM_NAME2); + sem = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0); + if (sem == NULL) { + fprintf(stderr, "PR_OpenSemaphore failed\n"); + exit(1); + } + if (PR_CloseSemaphore(sem) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + exit(1); + } + if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) { + fprintf(stderr, "PR_DeleteSemaphore failed\n"); + exit(1); + } + + /* + * Opening an existing semaphore with PR_SEM_CREATE|PR_SEM_EXCL. + * should fail with PR_FILE_EXISTS_ERROR. + */ + sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0); + if (sem != NULL) { + fprintf(stderr, "PR_OpenSemaphore should fail but succeeded\n"); + exit(1); + } + if (PR_GetError() != PR_FILE_EXISTS_ERROR) { + fprintf(stderr, "Expect %d but got %d\n", PR_FILE_EXISTS_ERROR, + PR_GetError()); + exit(1); + } + + /* + * Try again, with just PR_SEM_CREATE. This should succeed. + */ + sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0); + if (sem == NULL) { + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + if (PR_CloseSemaphore(sem) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + exit(1); + } + + sem = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0); + if (sem == NULL) { + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + if (PR_CloseSemaphore(sem) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + exit(1); + } + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/semaerr.c nspr-4.10.7/nspr/pr/tests/semaerr.c --- nspr-4.9.5/nspr/pr/tests/semaerr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/semaerr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,117 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "plgetopt.h" + +#include + +#ifdef SYMBIAN +#define NO_SUCH_SEM_NAME "c:\\data\\nosuchsem.sem" +#define SEM_NAME1 "c:\\data\\foo.sem" +#define EXE_NAME "nspr_tests_semaerr1.exe" +#else +#define NO_SUCH_SEM_NAME "/tmp/nosuchsem.sem" +#define SEM_NAME1 "/tmp/foo.sem" +#define EXE_NAME "semaerr1" +#endif +#define SEM_MODE 0666 + +static PRBool debug_mode = PR_FALSE; + +static void Help(void) +{ + fprintf(stderr, "semaerr test program usage:\n"); + fprintf(stderr, "\t-d debug mode (FALSE)\n"); + fprintf(stderr, "\t-h this message\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dh"); + PRSem *sem; + char *child_argv[32]; + char **child_arg; + PRProcess *proc; + PRInt32 exit_code; + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + /* + * Open a nonexistent semaphore without the PR_SEM_CREATE + * flag should fail with PR_FILE_NOT_FOUND_ERROR. + */ + (void) PR_DeleteSemaphore(NO_SUCH_SEM_NAME); + sem = PR_OpenSemaphore(NO_SUCH_SEM_NAME, 0, 0, 0); + if (NULL != sem) { + fprintf(stderr, "Opening nonexistent semaphore %s " + "without the PR_SEM_CREATE flag should fail " + "but succeeded\n", NO_SUCH_SEM_NAME); + exit(1); + } + if (PR_GetError() != PR_FILE_NOT_FOUND_ERROR) { + fprintf(stderr, "Expected error is %d but got (%d, %d)\n", + PR_FILE_NOT_FOUND_ERROR, PR_GetError(), PR_GetOSError()); + exit(1); + } + + /* + * Create a semaphore and let the another process + * try PR_SEM_CREATE and PR_SEM_CREATE|PR_SEM_EXCL. + */ + if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) { + fprintf(stderr, "warning: deleted semaphore %s from previous " + "run of the test\n", SEM_NAME1); + } + sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0); + if (sem == NULL) { + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + child_arg = child_argv; + *child_arg++ = EXE_NAME; + if (debug_mode) { + *child_arg++ = "-d"; + } + *child_arg = NULL; + proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); + if (proc == NULL) { + fprintf(stderr, "PR_CreateProcess failed\n"); + exit(1); + } + if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) { + fprintf(stderr, "PR_WaitProcess failed\n"); + exit(1); + } + if (exit_code != 0) { + fprintf(stderr, "process semaerr1 failed\n"); + exit(1); + } + if (PR_CloseSemaphore(sem) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + exit(1); + } + if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) { + fprintf(stderr, "PR_DeleteSemaphore failed\n"); + exit(1); + } + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/semaping.c nspr-4.10.7/nspr/pr/tests/semaping.c --- nspr-4.9.5/nspr/pr/tests/semaping.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/semaping.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,179 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "plgetopt.h" + +#include + +#ifdef SYMBIAN +#define SHM_NAME "c:\\data\\counter" +#define SEM_NAME1 "c:\\data\\foo.sem" +#define SEM_NAME2 "c:\\data\\bar.sem" +#define EXE_NAME "nspr_tests_semapong.exe" +#else +#define SHM_NAME "/tmp/counter" +#define SEM_NAME1 "/tmp/foo.sem" +#define SEM_NAME2 "/tmp/bar.sem" +#define EXE_NAME "semapong" +#endif +#define SEM_MODE 0666 +#define SHM_MODE 0666 +#define ITERATIONS 1000 + +static PRBool debug_mode = PR_FALSE; +static PRIntn iterations = ITERATIONS; +static PRSem *sem1, *sem2; + +static void Help(void) +{ + fprintf(stderr, "semaping test program usage:\n"); + fprintf(stderr, "\t-d debug mode (FALSE)\n"); + fprintf(stderr, "\t-c loop count (%d)\n", ITERATIONS); + fprintf(stderr, "\t-h this message\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PRProcess *proc; + PRIntn i; + char *child_argv[32]; + char **child_arg; + char iterations_buf[32]; + PRSharedMemory *shm; + PRIntn *counter_addr; + PRInt32 exit_code; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'c': /* loop count */ + iterations = atoi(opt->value); + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + if (PR_DeleteSharedMemory(SHM_NAME) == PR_SUCCESS) { + fprintf(stderr, "warning: removed shared memory %s left over " + "from previous run\n", SHM_NAME); + } + if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) { + fprintf(stderr, "warning: removed semaphore %s left over " + "from previous run\n", SEM_NAME1); + } + if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) { + fprintf(stderr, "warning: removed semaphore %s left over " + "from previous run\n", SEM_NAME2); + } + + shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), PR_SHM_CREATE, SHM_MODE); + if (NULL == shm) { + fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + counter_addr = PR_AttachSharedMemory(shm, 0); + if (NULL == counter_addr) { + fprintf(stderr, "PR_AttachSharedMemory failed\n"); + exit(1); + } + *counter_addr = 0; + sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1); + if (NULL == sem1) { + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0); + if (NULL == sem2) { + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + + child_arg = &child_argv[0]; + *child_arg++ = EXE_NAME; + if (debug_mode != PR_FALSE) { + *child_arg++ = "-d"; + } + if (iterations != ITERATIONS) { + *child_arg++ = "-c"; + PR_snprintf(iterations_buf, sizeof(iterations_buf), "%d", iterations); + *child_arg++ = iterations_buf; + } + *child_arg = NULL; + proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL); + if (NULL == proc) { + fprintf(stderr, "PR_CreateProcess failed\n"); + exit(1); + } + + /* + * Process 1 waits on semaphore 1 and posts to semaphore 2. + */ + for (i = 0; i < iterations; i++) { + if (PR_WaitSemaphore(sem1) == PR_FAILURE) { + fprintf(stderr, "PR_WaitSemaphore failed\n"); + exit(1); + } + if (*counter_addr == 2*i) { + if (debug_mode) printf("process 1: counter = %d\n", *counter_addr); + } else { + fprintf(stderr, "process 1: counter should be %d but is %d\n", + 2*i, *counter_addr); + exit(1); + } + (*counter_addr)++; + if (PR_PostSemaphore(sem2) == PR_FAILURE) { + fprintf(stderr, "PR_PostSemaphore failed\n"); + exit(1); + } + } + if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) { + fprintf(stderr, "PR_DetachSharedMemory failed\n"); + exit(1); + } + if (PR_CloseSharedMemory(shm) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSharedMemory failed\n"); + exit(1); + } + if (PR_CloseSemaphore(sem1) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + } + if (PR_CloseSemaphore(sem2) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + } + + if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) { + fprintf(stderr, "PR_WaitProcess failed\n"); + exit(1); + } + if (exit_code != 0) { + fprintf(stderr, "process 2 failed with exit code %d\n", exit_code); + exit(1); + } + + if (PR_DeleteSharedMemory(SHM_NAME) == PR_FAILURE) { + fprintf(stderr, "PR_DeleteSharedMemory failed\n"); + } + if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) { + fprintf(stderr, "PR_DeleteSemaphore failed\n"); + } + if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) { + fprintf(stderr, "PR_DeleteSemaphore failed\n"); + } + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/semapong.c nspr-4.10.7/nspr/pr/tests/semapong.c --- nspr-4.9.5/nspr/pr/tests/semapong.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/semapong.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "plgetopt.h" + +#include + +#ifdef SYMBIAN +#define SHM_NAME "c:\\data\\counter" +#define SEM_NAME1 "c:\\data\\foo.sem" +#define SEM_NAME2 "c:\\data\\bar.sem" +#else +#define SHM_NAME "/tmp/counter" +#define SEM_NAME1 "/tmp/foo.sem" +#define SEM_NAME2 "/tmp/bar.sem" +#endif +#define ITERATIONS 1000 + +static PRBool debug_mode = PR_FALSE; +static PRIntn iterations = ITERATIONS; +static PRSem *sem1, *sem2; + +static void Help(void) +{ + fprintf(stderr, "semapong test program usage:\n"); + fprintf(stderr, "\t-d debug mode (FALSE)\n"); + fprintf(stderr, "\t-c loop count (%d)\n", ITERATIONS); + fprintf(stderr, "\t-h this message\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PRIntn i; + PRSharedMemory *shm; + PRIntn *counter_addr; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'c': /* loop count */ + iterations = atoi(opt->value); + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), 0, 0666); + if (NULL == shm) { + fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + sem1 = PR_OpenSemaphore(SEM_NAME1, 0, 0, 0); + if (NULL == sem1) { + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + sem2 = PR_OpenSemaphore(SEM_NAME2, 0, 0, 0); + if (NULL == sem2) { + fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + + counter_addr = PR_AttachSharedMemory(shm, 0); + if (NULL == counter_addr) { + fprintf(stderr, "PR_AttachSharedMemory failed\n"); + exit(1); + } + + /* + * Process 2 waits on semaphore 2 and posts to semaphore 1. + */ + for (i = 0; i < iterations; i++) { + if (PR_WaitSemaphore(sem2) == PR_FAILURE) { + fprintf(stderr, "PR_WaitSemaphore failed\n"); + exit(1); + } + if (*counter_addr == 2*i+1) { + if (debug_mode) printf("process 2: counter = %d\n", *counter_addr); + } else { + fprintf(stderr, "process 2: counter should be %d but is %d\n", + 2*i+1, *counter_addr); + exit(1); + } + (*counter_addr)++; + if (PR_PostSemaphore(sem1) == PR_FAILURE) { + fprintf(stderr, "PR_PostSemaphore failed\n"); + exit(1); + } + } + if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) { + fprintf(stderr, "PR_DetachSharedMemory failed\n"); + exit(1); + } + if (PR_CloseSharedMemory(shm) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSharedMemory failed\n"); + exit(1); + } + if (PR_CloseSemaphore(sem1) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + } + if (PR_CloseSemaphore(sem2) == PR_FAILURE) { + fprintf(stderr, "PR_CloseSemaphore failed\n"); + } + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/sem.c nspr-4.10.7/nspr/pr/tests/sem.c --- nspr-4.9.5/nspr/pr/tests/sem.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sem.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,209 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: sem.c +** +** Description: Tests Semaphonre functions. +** +** Modification History: +** 20-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include "prpriv.h" + +#include +#include +#include + +PRIntn failed_already=0; +PRIntn debug_mode; + +/* + Since we don't have stdin, stdout everywhere, we will fake + it with our in-memory buffers called stdin and stdout. +*/ + +#define SBSIZE 1024 + +#include "obsolete/prsem.h" + +static char stdinBuf[SBSIZE]; +static char stdoutBuf[SBSIZE]; + +static PRUintn stdinBufIdx = 0; +static PRUintn stdoutBufIdx = 0; +static PRStatus finalResult = PR_SUCCESS; + + +static size_t dread (PRUintn device, char *buf, size_t bufSize) +{ + PRUintn i; + + /* during first read call, initialize the stdinBuf buffer*/ + if (stdinBufIdx == 0) { + for (i=0; i 0); +} + +static void writer(void) +{ + PRUintn i = 0; + size_t nbytes; + + do { + (void) PR_WaitSem(fullBufs); + nbytes = buf[i].nbytes; + if (nbytes > 0) { + nbytes = dwrite(1, buf[i].data, nbytes); + PR_PostSem(emptyBufs); + i = (i + 1) % 2; + } + } while (nbytes > 0); +} + +int main(int argc, char **argv) +{ + PRThread *r; + + PR_STDIO_INIT(); + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + + { + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } + + /* main test */ + + emptyBufs = PR_NewSem(2); /* two empty buffers */ + + fullBufs = PR_NewSem(0); /* zero full buffers */ + + /* create the reader thread */ + + r = PR_CreateThread(PR_USER_THREAD, + reader, 0, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + + /* Do the writer operation in this thread */ + writer(); + + PR_DestroySem(emptyBufs); + PR_DestroySem(fullBufs); + + if (finalResult == PR_SUCCESS) { + if (debug_mode) printf("sem Test Passed.\n"); + } + else{ + if (debug_mode) printf("sem Test Failed.\n"); + failed_already=1; + } + PR_Cleanup(); + if(failed_already) + return 1; + else + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/sendzlf.c nspr-4.10.7/nspr/pr/tests/sendzlf.c --- nspr-4.9.5/nspr/pr/tests/sendzlf.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sendzlf.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test: sendzlf.c + * + * Description: send a zero-length file with PR_SendFile and + * PR_TransmitFile. + */ + +#define ZERO_LEN_FILE_NAME "zerolen.tmp" +#define HEADER_STR "Header" +#define HEADER_LEN 6 /* length of HEADER_STR, not counting the null byte */ +#define TRAILER_STR "Trailer" +#define TRAILER_LEN 7 /* length of TRAILER_STR, not counting the null byte */ + +#include "nspr.h" + +#include +#include +#include + +static void ClientThread(void *arg) +{ + PRFileDesc *sock; + PRNetAddr addr; + PRUint16 port = (PRUint16) arg; + char buf[1024]; + char *bufPtr; + PRInt32 nbytes; + PRInt32 ntotal; + PRInt32 nexpected; + + sock = PR_NewTCPSocket(); + if (NULL == sock) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_InitializeNetAddr failed\n"); + exit(1); + } + if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + fprintf(stderr, "PR_Connect failed\n"); + exit(1); + } + ntotal = 0; + bufPtr = buf; + while ((nbytes = PR_Read(sock, bufPtr, sizeof(buf)-ntotal)) > 0) { + ntotal += nbytes; + bufPtr += nbytes; + } + if (-1 == nbytes) { + fprintf(stderr, "PR_Read failed\n"); + exit(1); + } + nexpected = HEADER_LEN+TRAILER_LEN+TRAILER_LEN+HEADER_LEN+HEADER_LEN; + if (ntotal != nexpected) { + fprintf(stderr, "total bytes read should be %d but is %d\n", + nexpected, ntotal); + exit(1); + } + if (memcmp(buf, HEADER_STR TRAILER_STR TRAILER_STR HEADER_STR HEADER_STR, + nexpected) != 0) { + fprintf(stderr, "wrong data is received\n"); + exit(1); + } + if (PR_Close(sock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } +} + +static void ServerThread(void *arg) +{ + PRFileDesc *listenSock = (PRFileDesc *) arg; + PRFileDesc *acceptSock; + PRFileDesc *file; + PRSendFileData sfd; + char header[1024], trailer[1024]; + PRInt32 nbytes; + + /* Create a zero-length file */ + file = PR_Open(ZERO_LEN_FILE_NAME, + PR_CREATE_FILE|PR_TRUNCATE|PR_RDWR, 0666); + if (NULL == file) { + fprintf(stderr, "PR_Open failed\n"); + exit(1); + } + sfd.fd = file; + sfd.file_offset = 0; + sfd.file_nbytes = 0; + memcpy(header, HEADER_STR, HEADER_LEN); + memcpy(trailer, TRAILER_STR, TRAILER_LEN); + sfd.header = header; + sfd.hlen = HEADER_LEN; + sfd.trailer = trailer; + sfd.tlen = TRAILER_LEN; + acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (NULL == acceptSock) { + fprintf(stderr, "PR_Accept failed\n"); + exit(1); + } + /* Send both header and trailer */ + nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + if (HEADER_LEN+TRAILER_LEN != nbytes) { + fprintf(stderr, "PR_SendFile should return %d but returned %d\n", + HEADER_LEN+TRAILER_LEN, nbytes); + exit(1); + } + /* Trailer only, no header */ + sfd.hlen = 0; + nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + if (TRAILER_LEN != nbytes) { + fprintf(stderr, "PR_SendFile should return %d but returned %d\n", + TRAILER_LEN, nbytes); + exit(1); + } + /* Header only, no trailer */ + sfd.hlen = HEADER_LEN; + sfd.tlen = 0; + nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + if (HEADER_LEN != nbytes) { + fprintf(stderr, "PR_SendFile should return %d but returned %d\n", + HEADER_LEN, nbytes); + exit(1); + } + /* Try PR_TransmitFile */ + nbytes = PR_TransmitFile(acceptSock, file, header, HEADER_LEN, + PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT); + if (HEADER_LEN != nbytes) { + fprintf(stderr, "PR_TransmitFile should return %d but returned %d\n", + HEADER_LEN, nbytes); + exit(1); + } + if (PR_Close(acceptSock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + if (PR_Close(file) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + if (PR_Delete(ZERO_LEN_FILE_NAME) == PR_FAILURE) { + fprintf(stderr, "PR_Delete failed\n"); + exit(1); + } +} + +int main(int argc, char **argv) +{ + PRFileDesc *listenSock; + PRThread *clientThread; + PRThread *serverThread; + PRNetAddr addr; + PRThreadScope scope = PR_GLOBAL_THREAD; + + listenSock = PR_NewTCPSocket(); + if (NULL == listenSock) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_InitializeNetAddr failed\n"); + exit(1); + } + if (PR_Bind(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + /* Find out what port number we are bound to. */ + if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + exit(1); + } + if (PR_Listen(listenSock, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + + clientThread = PR_CreateThread(PR_USER_THREAD, + ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)), + PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); + if (NULL == clientThread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + serverThread = PR_CreateThread(PR_USER_THREAD, + ServerThread, listenSock, + PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); + if (NULL == serverThread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + if (PR_JoinThread(clientThread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + if (PR_JoinThread(serverThread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + if (PR_Close(listenSock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/server_test.c nspr-4.10.7/nspr/pr/tests/server_test.c --- nspr-4.9.5/nspr/pr/tests/server_test.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/server_test.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,610 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** This server simulates a server running in loopback mode. +** +** The idea is that a single server is created. The server initially creates +** a number of worker threads. Then, with the server running, a number of +** clients are created which start requesting service from the server. +** +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include "pprthred.h" + +#include + +#define PORT 15004 +#define THREAD_STACKSIZE 0 + +#define PASS 0 +#define FAIL 1 +static int debug_mode = 0; + +static int _iterations = 1000; +static int _clients = 1; +static int _client_data = 250; +static int _server_data = (8*1024); + +static PRThreadScope ServerScope, ClientScope; + +#define SERVER "Server" +#define MAIN "Main" + +#define SERVER_STATE_STARTUP 0 +#define SERVER_STATE_READY 1 +#define SERVER_STATE_DYING 2 +#define SERVER_STATE_DEAD 4 +int ServerState; +PRLock *ServerStateCVLock; +PRCondVar *ServerStateCV; + +#undef DEBUGPRINTS +#ifdef DEBUGPRINTS +#define DPRINTF printf +#else +#define DPRINTF +#endif + + +/*********************************************************************** +** PRIVATE FUNCTION: Test_Result +** DESCRIPTION: Used in conjunction with the regress tool, prints out the +** status of the test case. +** INPUTS: PASS/FAIL +** OUTPUTS: None +** RETURN: None +** SIDE EFFECTS: +** +** RESTRICTIONS: +** None +** MEMORY: NA +** ALGORITHM: Determine what the status is and print accordingly. +** +***********************************************************************/ + + +static void Test_Result (int result) +{ + switch (result) + { + case PASS: + printf ("PASS\n"); + break; + case FAIL: + printf ("FAIL\n"); + break; + default: + break; + } +} + +static void do_work(void); + +/* --- Server state functions --------------------------------------------- */ +void +SetServerState(char *waiter, PRInt32 state) +{ + PR_Lock(ServerStateCVLock); + ServerState = state; + PR_NotifyCondVar(ServerStateCV); + + if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); + + PR_Unlock(ServerStateCVLock); +} + +int +WaitServerState(char *waiter, PRInt32 state) +{ + PRInt32 rv; + + PR_Lock(ServerStateCVLock); + + if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); + + while(!(ServerState & state)) + PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); + rv = ServerState; + + if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", + waiter, state, ServerState); + PR_Unlock(ServerStateCVLock); + + return rv; +} + +/* --- Server Functions ------------------------------------------- */ + +PRLock *workerThreadsLock; +PRInt32 workerThreads; +PRInt32 workerThreadsBusy; + +void +WorkerThreadFunc(void *_listenSock) +{ + PRFileDesc *listenSock = (PRFileDesc *)_listenSock; + PRInt32 bytesRead; + PRInt32 bytesWritten; + char *dataBuf; + char *sendBuf; + + if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", + _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); + dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); + if (!dataBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + + if (debug_mode) DPRINTF("\tServer worker thread running\n"); + + while(1) { + PRInt32 bytesToRead = _client_data; + PRInt32 bytesToWrite = _server_data; + PRFileDesc *newSock; + PRNetAddr *rAddr; + PRInt32 loops = 0; + + loops++; + + if (debug_mode) DPRINTF("\tServer thread going into accept\n"); + + bytesRead = PR_AcceptRead(listenSock, + &newSock, + &rAddr, + dataBuf, + bytesToRead, + PR_INTERVAL_NO_TIMEOUT); + + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); + continue; + } + + if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); + + PR_AtomicIncrement(&workerThreadsBusy); +#ifdef SYMBIAN + if (workerThreadsBusy == workerThreads && workerThreads<1) { +#else + if (workerThreadsBusy == workerThreads) { +#endif + PR_Lock(workerThreadsLock); + if (workerThreadsBusy == workerThreads) { + PRThread *WorkerThread; + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSock, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("Error creating client thread %d\n", workerThreads); + } else { + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); + } + } + PR_Unlock(workerThreadsLock); + } + + bytesToRead -= bytesRead; + while (bytesToRead) { + bytesRead = PR_Recv(newSock, + dataBuf, + bytesToRead, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); + continue; + } + if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); + } + + bytesWritten = PR_Send(newSock, + sendBuf, + bytesToWrite, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesWritten != _server_data) { + if (debug_mode) printf("\tError sending data to client (%d, %d)\n", + bytesWritten, PR_GetOSError()); + } else { + if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); + } + + PR_Close(newSock); + PR_AtomicDecrement(&workerThreadsBusy); + } +} + +PRFileDesc * +ServerSetup(void) +{ + PRFileDesc *listenSocket; + PRNetAddr serverAddr; + PRThread *WorkerThread; + + if ( (listenSocket = PR_NewTCPSocket()) == NULL) { + if (debug_mode) printf("\tServer error creating listen socket\n"); + else Test_Result(FAIL); + return NULL; + } + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); + + if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { + if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", + PR_GetOSError()); + else Test_Result(FAIL); + PR_Close(listenSocket); + return NULL; + } + + if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { + if (debug_mode) printf("\tServer error listening to server socket\n"); + else Test_Result(FAIL); + PR_Close(listenSocket); + + return NULL; + } + + /* Create Clients */ + workerThreads = 0; + workerThreadsBusy = 0; + + workerThreadsLock = PR_NewLock(); + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSocket, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("error creating working thread\n"); + PR_Close(listenSocket); + return NULL; + } + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); + + return listenSocket; +} + +/* The main server loop */ +void +ServerThreadFunc(void *unused) +{ + PRFileDesc *listenSocket; + + /* Do setup */ + listenSocket = ServerSetup(); + + if (!listenSocket) { + SetServerState(SERVER, SERVER_STATE_DEAD); + } else { + + if (debug_mode) DPRINTF("\tServer up\n"); + + /* Tell clients they can start now. */ + SetServerState(SERVER, SERVER_STATE_READY); + + /* Now wait for server death signal */ + WaitServerState(SERVER, SERVER_STATE_DYING); + + /* Cleanup */ + SetServerState(SERVER, SERVER_STATE_DEAD); + } +} + +/* --- Client Functions ------------------------------------------- */ + +PRInt32 numRequests; +PRInt32 numClients; +PRMonitor *clientMonitor; + +void +ClientThreadFunc(void *unused) +{ + PRNetAddr serverAddr; + PRFileDesc *clientSocket; + char *sendBuf; + char *recvBuf; + PRInt32 rv; + PRInt32 bytesNeeded; + + sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); + if (!recvBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + + while(numRequests > 0) { + + if ( (numRequests % 10) == 0 ) + if (debug_mode) printf("."); + if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); + + clientSocket = PR_NewTCPSocket(); + if (!clientSocket) { + if (debug_mode) printf("Client error creating socket: OS error %d\n", + PR_GetOSError()); + continue; + } + + if (debug_mode) DPRINTF("\tClient connecting\n"); + + rv = PR_Connect(clientSocket, + &serverAddr, + PR_INTERVAL_NO_TIMEOUT); + if (!clientSocket) { + if (debug_mode) printf("\tClient error connecting\n"); + continue; + } + + if (debug_mode) DPRINTF("\tClient connected\n"); + + rv = PR_Send(clientSocket, + sendBuf, + _client_data, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv != _client_data) { + if (debug_mode) printf("Client error sending data (%d)\n", rv); + PR_Close(clientSocket); + continue; + } + + if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); + + bytesNeeded = _server_data; + while(bytesNeeded) { + rv = PR_Recv(clientSocket, + recvBuf, + bytesNeeded, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv <= 0) { + if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", + rv, (_server_data - bytesNeeded), _server_data); + break; + } + if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); + bytesNeeded -= rv; + } + + PR_Close(clientSocket); + + PR_AtomicDecrement(&numRequests); + } + + PR_EnterMonitor(clientMonitor); + --numClients; + PR_Notify(clientMonitor); + PR_ExitMonitor(clientMonitor); + + PR_DELETE(sendBuf); + PR_DELETE(recvBuf); +} + +void +RunClients(void) +{ + PRInt32 index; + + numRequests = _iterations; + numClients = _clients; + clientMonitor = PR_NewMonitor(); + + for (index=0; index<_clients; index++) { + PRThread *clientThread; + + + clientThread = PR_CreateThread( + PR_USER_THREAD, + ClientThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ClientScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!clientThread) { + if (debug_mode) printf("\terror creating client thread %d\n", index); + } else + if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); + + } + + PR_EnterMonitor(clientMonitor); + while(numClients) + PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(clientMonitor); +} + +/* --- Main Function ---------------------------------------------- */ + +static +void do_work() +{ + PRThread *ServerThread; + PRInt32 state; + + SetServerState(MAIN, SERVER_STATE_STARTUP); + ServerThread = PR_CreateThread( + PR_USER_THREAD, + ServerThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ServerScope, + PR_JOINABLE_THREAD, + THREAD_STACKSIZE); + if (!ServerThread) { + if (debug_mode) printf("error creating main server thread\n"); + return; + } + + /* Wait for server to be ready */ + state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); + + if (!(state & SERVER_STATE_DEAD)) { + /* Run Test Clients */ + RunClients(); + + /* Send death signal to server */ + SetServerState(MAIN, SERVER_STATE_DYING); + } + + PR_JoinThread(ServerThread); +} + +static void do_workUU(void) +{ + ServerScope = PR_LOCAL_THREAD; + ClientScope = PR_LOCAL_THREAD; + do_work(); +} + +static void do_workUK(void) +{ + ServerScope = PR_LOCAL_THREAD; + ClientScope = PR_GLOBAL_THREAD; + do_work(); +} + +static void do_workKU(void) +{ + ServerScope = PR_GLOBAL_THREAD; + ClientScope = PR_LOCAL_THREAD; + do_work(); +} + +static void do_workKK(void) +{ + ServerScope = PR_GLOBAL_THREAD; + ClientScope = PR_GLOBAL_THREAD; + do_work(); +} + + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + + if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); +} + + +int main(int argc, char **argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ +#ifndef SYMBIAN + if (debug_mode) { + printf("Enter number of iterations: \n"); + scanf("%d", &_iterations); + printf("Enter number of clients : \n"); + scanf("%d", &_clients); + printf("Enter size of client data : \n"); + scanf("%d", &_client_data); + printf("Enter size of server data : \n"); + scanf("%d", &_server_data); + } + else +#endif + { + + _iterations = 10; + _clients = 1; + _client_data = 10; + _server_data = 10; + } + + if (debug_mode) { + printf("\n\n%d iterations with %d client threads.\n", + _iterations, _clients); + printf("Sending %d bytes of client data and %d bytes of server data\n", + _client_data, _server_data); + } + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + ServerStateCVLock = PR_NewLock(); + ServerStateCV = PR_NewCondVar(ServerStateCVLock); + + Measure(do_workUU, "server loop user/user"); + #if 0 + Measure(do_workUK, "server loop user/kernel"); + Measure(do_workKU, "server loop kernel/user"); + Measure(do_workKK, "server loop kernel/kernel"); + #endif + + PR_Cleanup(); + + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/servr_kk.c nspr-4.10.7/nspr/pr/tests/servr_kk.c --- nspr-4.9.5/nspr/pr/tests/servr_kk.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/servr_kk.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,588 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** This server simulates a server running in loopback mode. +** +** The idea is that a single server is created. The server initially creates +** a number of worker threads. Then, with the server running, a number of +** clients are created which start requesting service from the server. +** +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include "pprthred.h" + +#include + +#define PORT 15004 +#define THREAD_STACKSIZE 0 + +static int _iterations = 1000; +static int _clients = 1; +static int _client_data = 250; +static int _server_data = (8*1024); + +static PRThreadScope ServerScope, ClientScope; + +#define SERVER "Server" +#define MAIN "Main" + +#define SERVER_STATE_STARTUP 0 +#define SERVER_STATE_READY 1 +#define SERVER_STATE_DYING 2 +#define SERVER_STATE_DEAD 4 +int ServerState; +PRLock *ServerStateCVLock; +PRCondVar *ServerStateCV; + +#ifdef DEBUGPRINTS +#define DPRINTF printf +#else +#define DPRINTF +#endif + +PRIntn failed_already=0; +PRIntn debug_mode; +static void do_work(void); + +/* --- Server state functions --------------------------------------------- */ +void +SetServerState(char *waiter, PRInt32 state) +{ + PR_Lock(ServerStateCVLock); + ServerState = state; + PR_NotifyCondVar(ServerStateCV); + + if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); + + PR_Unlock(ServerStateCVLock); +} + +int +WaitServerState(char *waiter, PRInt32 state) +{ + PRInt32 rv; + + PR_Lock(ServerStateCVLock); + + if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); + + while(!(ServerState & state)) + PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); + rv = ServerState; + + if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", + waiter, state, ServerState); + PR_Unlock(ServerStateCVLock); + + return rv; +} + +/* --- Server Functions ------------------------------------------- */ + +PRLock *workerThreadsLock; +PRInt32 workerThreads; +PRInt32 workerThreadsBusy; + +void +WorkerThreadFunc(void *_listenSock) +{ + PRFileDesc *listenSock = (PRFileDesc *)_listenSock; + PRInt32 bytesRead; + PRInt32 bytesWritten; + char *dataBuf; + char *sendBuf; + + if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", + _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); + dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); + if (!dataBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + + if (debug_mode) DPRINTF("\tServer worker thread running\n"); + + while(1) { + PRInt32 bytesToRead = _client_data; + PRInt32 bytesToWrite = _server_data; + PRFileDesc *newSock; + PRNetAddr *rAddr; + PRInt32 loops = 0; + + loops++; + + if (debug_mode) DPRINTF("\tServer thread going into accept\n"); + + bytesRead = PR_AcceptRead(listenSock, + &newSock, + &rAddr, + dataBuf, + bytesToRead, + PR_INTERVAL_NO_TIMEOUT); + + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); + continue; + } + + if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); + + PR_AtomicIncrement(&workerThreadsBusy); +#ifdef SYMBIAN + if (workerThreadsBusy == workerThreads && workerThreads<1) { +#else + if (workerThreadsBusy == workerThreads) { +#endif + PR_Lock(workerThreadsLock); + if (workerThreadsBusy == workerThreads) { + PRThread *WorkerThread; + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSock, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("Error creating client thread %d\n", workerThreads); + } else { + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); + } + } + PR_Unlock(workerThreadsLock); + } + + bytesToRead -= bytesRead; + while (bytesToRead) { + bytesRead = PR_Recv(newSock, + dataBuf, + bytesToRead, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); + continue; + } + if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); + } + + bytesWritten = PR_Send(newSock, + sendBuf, + bytesToWrite, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesWritten != _server_data) { + if (debug_mode) printf("\tError sending data to client (%d, %d)\n", + bytesWritten, PR_GetOSError()); + } else { + if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); + } + + PR_Close(newSock); + PR_AtomicDecrement(&workerThreadsBusy); + } +} + +PRFileDesc * +ServerSetup(void) +{ + PRFileDesc *listenSocket; + PRSocketOptionData sockOpt; + PRNetAddr serverAddr; + PRThread *WorkerThread; + + if ( (listenSocket = PR_NewTCPSocket()) == NULL) { + if (debug_mode) printf("\tServer error creating listen socket\n"); + else failed_already=1; + return NULL; + } + + sockOpt.option = PR_SockOpt_Reuseaddr; + sockOpt.value.reuse_addr = PR_TRUE; + if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { + if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", + PR_GetOSError()); + else failed_already=1; + PR_Close(listenSocket); + return NULL; + } + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); + + if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { + if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", + PR_GetOSError()); + else failed_already=1; + PR_Close(listenSocket); + return NULL; + } + + if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { + if (debug_mode) printf("\tServer error listening to server socket\n"); + else failed_already=1; + PR_Close(listenSocket); + + return NULL; + } + + /* Create Clients */ + workerThreads = 0; + workerThreadsBusy = 0; + + workerThreadsLock = PR_NewLock(); + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSocket, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("error creating working thread\n"); + PR_Close(listenSocket); + return NULL; + } + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); + + return listenSocket; +} + +/* The main server loop */ +void +ServerThreadFunc(void *unused) +{ + PRFileDesc *listenSocket; + + /* Do setup */ + listenSocket = ServerSetup(); + + if (!listenSocket) { + SetServerState(SERVER, SERVER_STATE_DEAD); + } else { + + if (debug_mode) DPRINTF("\tServer up\n"); + + /* Tell clients they can start now. */ + SetServerState(SERVER, SERVER_STATE_READY); + + /* Now wait for server death signal */ + WaitServerState(SERVER, SERVER_STATE_DYING); + + /* Cleanup */ + SetServerState(SERVER, SERVER_STATE_DEAD); + } +} + +/* --- Client Functions ------------------------------------------- */ + +PRInt32 numRequests; +PRInt32 numClients; +PRMonitor *clientMonitor; + +void +ClientThreadFunc(void *unused) +{ + PRNetAddr serverAddr; + PRFileDesc *clientSocket; + char *sendBuf; + char *recvBuf; + PRInt32 rv; + PRInt32 bytesNeeded; + + sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); + if (!recvBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + + while(numRequests > 0) { + + if ( (numRequests % 10) == 0 ) + if (debug_mode) printf("."); + if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); + + clientSocket = PR_NewTCPSocket(); + if (!clientSocket) { + if (debug_mode) printf("Client error creating socket: OS error %d\n", + PR_GetOSError()); + continue; + } + + if (debug_mode) DPRINTF("\tClient connecting\n"); + + rv = PR_Connect(clientSocket, + &serverAddr, + PR_INTERVAL_NO_TIMEOUT); + if (!clientSocket) { + if (debug_mode) printf("\tClient error connecting\n"); + continue; + } + + if (debug_mode) DPRINTF("\tClient connected\n"); + + rv = PR_Send(clientSocket, + sendBuf, + _client_data, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv != _client_data) { + if (debug_mode) printf("Client error sending data (%d)\n", rv); + PR_Close(clientSocket); + continue; + } + + if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); + + bytesNeeded = _server_data; + while(bytesNeeded) { + rv = PR_Recv(clientSocket, + recvBuf, + bytesNeeded, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv <= 0) { + if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", + rv, (_server_data - bytesNeeded), _server_data); + break; + } + if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); + bytesNeeded -= rv; + } + + PR_Close(clientSocket); + + PR_AtomicDecrement(&numRequests); + } + + PR_EnterMonitor(clientMonitor); + --numClients; + PR_Notify(clientMonitor); + PR_ExitMonitor(clientMonitor); + + PR_DELETE(sendBuf); + PR_DELETE(recvBuf); +} + +void +RunClients(void) +{ + PRInt32 index; + + numRequests = _iterations; + numClients = _clients; + clientMonitor = PR_NewMonitor(); + + for (index=0; index<_clients; index++) { + PRThread *clientThread; + + + clientThread = PR_CreateThread( + PR_USER_THREAD, + ClientThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ClientScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!clientThread) { + if (debug_mode) printf("\terror creating client thread %d\n", index); + } else + if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); + + } + + PR_EnterMonitor(clientMonitor); + while(numClients) + PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(clientMonitor); +} + +/* --- Main Function ---------------------------------------------- */ + +static +void do_work() +{ + PRThread *ServerThread; + PRInt32 state; + + SetServerState(MAIN, SERVER_STATE_STARTUP); + ServerThread = PR_CreateThread( + PR_USER_THREAD, + ServerThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ServerScope, + PR_JOINABLE_THREAD, + THREAD_STACKSIZE); + if (!ServerThread) { + if (debug_mode) printf("error creating main server thread\n"); + return; + } + + /* Wait for server to be ready */ + state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); + + if (!(state & SERVER_STATE_DEAD)) { + /* Run Test Clients */ + RunClients(); + + /* Send death signal to server */ + SetServerState(MAIN, SERVER_STATE_DYING); + } + + PR_JoinThread(ServerThread); +} + +static void do_workUU(void) +{ + ServerScope = PR_LOCAL_THREAD; + ClientScope = PR_LOCAL_THREAD; + do_work(); +} + +static void do_workUK(void) +{ + ServerScope = PR_LOCAL_THREAD; + ClientScope = PR_GLOBAL_THREAD; + do_work(); +} + +static void do_workKU(void) +{ + ServerScope = PR_GLOBAL_THREAD; + ClientScope = PR_LOCAL_THREAD; + do_work(); +} + +static void do_workKK(void) +{ + ServerScope = PR_GLOBAL_THREAD; + ClientScope = PR_GLOBAL_THREAD; + do_work(); +} + + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + + if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); +} + + +int main(int argc, char **argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ +#ifndef SYMBIAN + if (debug_mode) { + printf("Enter number of iterations: \n"); + scanf("%d", &_iterations); + printf("Enter number of clients : \n"); + scanf("%d", &_clients); + printf("Enter size of client data : \n"); + scanf("%d", &_client_data); + printf("Enter size of server data : \n"); + scanf("%d", &_server_data); + } + else +#endif + { + _iterations = 7; + _clients = 7; + _client_data = 100; + _server_data = 100; + } + + if (debug_mode) { + printf("\n\n%d iterations with %d client threads.\n", + _iterations, _clients); + printf("Sending %d bytes of client data and %d bytes of server data\n", + _client_data, _server_data); + } + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + PR_SetThreadRecycleMode(64); + + ServerStateCVLock = PR_NewLock(); + ServerStateCV = PR_NewCondVar(ServerStateCVLock); + + + Measure(do_workKK, "server loop kernel/kernel"); + + PR_Cleanup(); + + if(failed_already) + return 1; + else + return 0; + +} diff -Nru nspr-4.9.5/nspr/pr/tests/servr_ku.c nspr-4.10.7/nspr/pr/tests/servr_ku.c --- nspr-4.9.5/nspr/pr/tests/servr_ku.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/servr_ku.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,568 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** This server simulates a server running in loopback mode. +** +** The idea is that a single server is created. The server initially creates +** a number of worker threads. Then, with the server running, a number of +** clients are created which start requesting service from the server. +** +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include "pprthred.h" + +#include + +#define PORT 15004 +#define THREAD_STACKSIZE 0 + +static int _iterations = 1000; +static int _clients = 1; +static int _client_data = 250; +static int _server_data = (8*1024); + +static PRThreadScope ServerScope, ClientScope; + +#define SERVER "Server" +#define MAIN "Main" + +#define SERVER_STATE_STARTUP 0 +#define SERVER_STATE_READY 1 +#define SERVER_STATE_DYING 2 +#define SERVER_STATE_DEAD 4 +int ServerState; +PRLock *ServerStateCVLock; +PRCondVar *ServerStateCV; + +#ifdef DEBUGPRINTS +#define DPRINTF printf +#else +#define DPRINTF +#endif + +PRIntn failed_already=0; +PRIntn debug_mode; + +static void do_work(void); + +/* --- Server state functions --------------------------------------------- */ +void +SetServerState(char *waiter, PRInt32 state) +{ + PR_Lock(ServerStateCVLock); + ServerState = state; + PR_NotifyCondVar(ServerStateCV); + + if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); + + PR_Unlock(ServerStateCVLock); +} + +int +WaitServerState(char *waiter, PRInt32 state) +{ + PRInt32 rv; + + PR_Lock(ServerStateCVLock); + + if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); + + while(!(ServerState & state)) + PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); + rv = ServerState; + + if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", + waiter, state, ServerState); + PR_Unlock(ServerStateCVLock); + + return rv; +} + +/* --- Server Functions ------------------------------------------- */ + +PRLock *workerThreadsLock; +PRInt32 workerThreads; +PRInt32 workerThreadsBusy; + +void +WorkerThreadFunc(void *_listenSock) +{ + PRFileDesc *listenSock = (PRFileDesc *)_listenSock; + PRInt32 bytesRead; + PRInt32 bytesWritten; + char *dataBuf; + char *sendBuf; + + if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", + _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); + dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); + if (!dataBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + + if (debug_mode) DPRINTF("\tServer worker thread running\n"); + + while(1) { + PRInt32 bytesToRead = _client_data; + PRInt32 bytesToWrite = _server_data; + PRFileDesc *newSock; + PRNetAddr *rAddr; + PRInt32 loops = 0; + + loops++; + + if (debug_mode) DPRINTF("\tServer thread going into accept\n"); + + bytesRead = PR_AcceptRead(listenSock, + &newSock, + &rAddr, + dataBuf, + bytesToRead, + PR_INTERVAL_NO_TIMEOUT); + + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); + continue; + } + + if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); + + PR_AtomicIncrement(&workerThreadsBusy); +#ifdef SYMBIAN + if (workerThreadsBusy == workerThreads && workerThreads<1) { +#else + if (workerThreadsBusy == workerThreads) { +#endif + PR_Lock(workerThreadsLock); + if (workerThreadsBusy == workerThreads) { + PRThread *WorkerThread; + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSock, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("Error creating client thread %d\n", workerThreads); + } else { + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); + } + } + PR_Unlock(workerThreadsLock); + } + + bytesToRead -= bytesRead; + while (bytesToRead) { + bytesRead = PR_Recv(newSock, + dataBuf, + bytesToRead, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); + continue; + } + if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); + } + + bytesWritten = PR_Send(newSock, + sendBuf, + bytesToWrite, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesWritten != _server_data) { + if (debug_mode) printf("\tError sending data to client (%d, %d)\n", + bytesWritten, PR_GetOSError()); + } else { + if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); + } + + PR_Close(newSock); + PR_AtomicDecrement(&workerThreadsBusy); + } +} + +PRFileDesc * +ServerSetup(void) +{ + PRFileDesc *listenSocket; + PRSocketOptionData sockOpt; + PRNetAddr serverAddr; + PRThread *WorkerThread; + + if ( (listenSocket = PR_NewTCPSocket()) == NULL) { + if (debug_mode) printf("\tServer error creating listen socket\n"); + else failed_already=1; + return NULL; + } + + sockOpt.option = PR_SockOpt_Reuseaddr; + sockOpt.value.reuse_addr = PR_TRUE; + if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { + if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", + PR_GetOSError()); + else failed_already=1; + PR_Close(listenSocket); + return NULL; + } + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); + + if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { + if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", + PR_GetOSError()); + else failed_already=1; + PR_Close(listenSocket); + return NULL; + } + + if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { + if (debug_mode) printf("\tServer error listening to server socket\n"); + else failed_already=1; + PR_Close(listenSocket); + + return NULL; + } + + /* Create Clients */ + workerThreads = 0; + workerThreadsBusy = 0; + + workerThreadsLock = PR_NewLock(); + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSocket, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("error creating working thread\n"); + PR_Close(listenSocket); + return NULL; + } + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); + + return listenSocket; +} + +/* The main server loop */ +void +ServerThreadFunc(void *unused) +{ + PRFileDesc *listenSocket; + + /* Do setup */ + listenSocket = ServerSetup(); + + if (!listenSocket) { + SetServerState(SERVER, SERVER_STATE_DEAD); + } else { + + if (debug_mode) DPRINTF("\tServer up\n"); + + /* Tell clients they can start now. */ + SetServerState(SERVER, SERVER_STATE_READY); + + /* Now wait for server death signal */ + WaitServerState(SERVER, SERVER_STATE_DYING); + + /* Cleanup */ + SetServerState(SERVER, SERVER_STATE_DEAD); + } +} + +/* --- Client Functions ------------------------------------------- */ + +PRInt32 numRequests; +PRInt32 numClients; +PRMonitor *clientMonitor; + +void +ClientThreadFunc(void *unused) +{ + PRNetAddr serverAddr; + PRFileDesc *clientSocket; + char *sendBuf; + char *recvBuf; + PRInt32 rv; + PRInt32 bytesNeeded; + + sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); + if (!recvBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + + while(numRequests > 0) { + + if ( (numRequests % 10) == 0 ) + if (debug_mode) printf("."); + if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); + + clientSocket = PR_NewTCPSocket(); + if (!clientSocket) { + if (debug_mode) printf("Client error creating socket: OS error %d\n", + PR_GetOSError()); + continue; + } + + if (debug_mode) DPRINTF("\tClient connecting\n"); + + rv = PR_Connect(clientSocket, + &serverAddr, + PR_INTERVAL_NO_TIMEOUT); + if (!clientSocket) { + if (debug_mode) printf("\tClient error connecting\n"); + continue; + } + + if (debug_mode) DPRINTF("\tClient connected\n"); + + rv = PR_Send(clientSocket, + sendBuf, + _client_data, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv != _client_data) { + if (debug_mode) printf("Client error sending data (%d)\n", rv); + PR_Close(clientSocket); + continue; + } + + if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); + + bytesNeeded = _server_data; + while(bytesNeeded) { + rv = PR_Recv(clientSocket, + recvBuf, + bytesNeeded, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv <= 0) { + if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", + rv, (_server_data - bytesNeeded), _server_data); + break; + } + if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); + bytesNeeded -= rv; + } + + PR_Close(clientSocket); + + PR_AtomicDecrement(&numRequests); + } + + PR_EnterMonitor(clientMonitor); + --numClients; + PR_Notify(clientMonitor); + PR_ExitMonitor(clientMonitor); + + PR_DELETE(sendBuf); + PR_DELETE(recvBuf); +} + +void +RunClients(void) +{ + PRInt32 index; + + numRequests = _iterations; + numClients = _clients; + clientMonitor = PR_NewMonitor(); + + for (index=0; index<_clients; index++) { + PRThread *clientThread; + + + clientThread = PR_CreateThread( + PR_USER_THREAD, + ClientThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ClientScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!clientThread) { + if (debug_mode) printf("\terror creating client thread %d\n", index); + } else + if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); + + } + + PR_EnterMonitor(clientMonitor); + while(numClients) + PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(clientMonitor); +} + +/* --- Main Function ---------------------------------------------- */ + +static +void do_work() +{ + PRThread *ServerThread; + PRInt32 state; + + SetServerState(MAIN, SERVER_STATE_STARTUP); + ServerThread = PR_CreateThread( + PR_USER_THREAD, + ServerThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ServerScope, + PR_JOINABLE_THREAD, + THREAD_STACKSIZE); + if (!ServerThread) { + if (debug_mode) printf("error creating main server thread\n"); + return; + } + + /* Wait for server to be ready */ + state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); + + if (!(state & SERVER_STATE_DEAD)) { + /* Run Test Clients */ + RunClients(); + + /* Send death signal to server */ + SetServerState(MAIN, SERVER_STATE_DYING); + } + + PR_JoinThread(ServerThread); +} + + +static void do_workKU(void) +{ + ServerScope = PR_GLOBAL_THREAD; + ClientScope = PR_LOCAL_THREAD; + do_work(); +} + + + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + + if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); +} + + +int main(int argc, char **argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ +#ifndef SYMBIAN + if (debug_mode) { + printf("Enter number of iterations: \n"); + scanf("%d", &_iterations); + printf("Enter number of clients : \n"); + scanf("%d", &_clients); + printf("Enter size of client data : \n"); + scanf("%d", &_client_data); + printf("Enter size of server data : \n"); + scanf("%d", &_server_data); + } + else +#endif + { + _iterations = 7; + _clients = 7; + _client_data = 100; + _server_data = 100; + } + + if (debug_mode) { + printf("\n\n%d iterations with %d client threads.\n", + _iterations, _clients); + printf("Sending %d bytes of client data and %d bytes of server data\n", + _client_data, _server_data); + } + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + PR_SetThreadRecycleMode(64); + + ServerStateCVLock = PR_NewLock(); + ServerStateCV = PR_NewCondVar(ServerStateCVLock); + + Measure(do_workKU, "server loop kernel/user"); + + PR_Cleanup(); + if(failed_already) + return 1; + else + return 0; + +} diff -Nru nspr-4.9.5/nspr/pr/tests/servr_uk.c nspr-4.10.7/nspr/pr/tests/servr_uk.c --- nspr-4.9.5/nspr/pr/tests/servr_uk.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/servr_uk.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,570 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** This server simulates a server running in loopback mode. +** +** The idea is that a single server is created. The server initially creates +** a number of worker threads. Then, with the server running, a number of +** clients are created which start requesting service from the server. +** +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include "pprthred.h" + +#include + +#define PORT 15004 +#define THREAD_STACKSIZE 0 + +static int _iterations = 1000; +static int _clients = 1; +static int _client_data = 250; +static int _server_data = (8*1024); + +static PRThreadScope ServerScope, ClientScope; + +#define SERVER "Server" +#define MAIN "Main" + +#define SERVER_STATE_STARTUP 0 +#define SERVER_STATE_READY 1 +#define SERVER_STATE_DYING 2 +#define SERVER_STATE_DEAD 4 +int ServerState; +PRLock *ServerStateCVLock; +PRCondVar *ServerStateCV; + +#ifdef DEBUGPRINTS +#define DPRINTF printf +#else +#define DPRINTF +#endif + +PRIntn failed_already=0; +PRIntn debug_mode; + + + +static void do_work(void); + +/* --- Server state functions --------------------------------------------- */ +void +SetServerState(char *waiter, PRInt32 state) +{ + PR_Lock(ServerStateCVLock); + ServerState = state; + PR_NotifyCondVar(ServerStateCV); + + if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); + + PR_Unlock(ServerStateCVLock); +} + +int +WaitServerState(char *waiter, PRInt32 state) +{ + PRInt32 rv; + + PR_Lock(ServerStateCVLock); + + if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); + + while(!(ServerState & state)) + PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); + rv = ServerState; + + if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", + waiter, state, ServerState); + PR_Unlock(ServerStateCVLock); + + return rv; +} + +/* --- Server Functions ------------------------------------------- */ + +PRLock *workerThreadsLock; +PRInt32 workerThreads; +PRInt32 workerThreadsBusy; + +void +WorkerThreadFunc(void *_listenSock) +{ + PRFileDesc *listenSock = (PRFileDesc *)_listenSock; + PRInt32 bytesRead; + PRInt32 bytesWritten; + char *dataBuf; + char *sendBuf; + + if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", + _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); + dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); + if (!dataBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + + if (debug_mode) DPRINTF("\tServer worker thread running\n"); + + while(1) { + PRInt32 bytesToRead = _client_data; + PRInt32 bytesToWrite = _server_data; + PRFileDesc *newSock; + PRNetAddr *rAddr; + PRInt32 loops = 0; + + loops++; + + if (debug_mode) DPRINTF("\tServer thread going into accept\n"); + + bytesRead = PR_AcceptRead(listenSock, + &newSock, + &rAddr, + dataBuf, + bytesToRead, + PR_INTERVAL_NO_TIMEOUT); + + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); + continue; + } + + if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); + + PR_AtomicIncrement(&workerThreadsBusy); +#ifdef SYMBIAN + if (workerThreadsBusy == workerThreads && workerThreads<1) { +#else + if (workerThreadsBusy == workerThreads) { +#endif + PR_Lock(workerThreadsLock); + if (workerThreadsBusy == workerThreads) { + PRThread *WorkerThread; + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSock, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("Error creating client thread %d\n", workerThreads); + } else { + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); + } + } + PR_Unlock(workerThreadsLock); + } + + bytesToRead -= bytesRead; + while (bytesToRead) { + bytesRead = PR_Recv(newSock, + dataBuf, + bytesToRead, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); + continue; + } + if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); + } + + bytesWritten = PR_Send(newSock, + sendBuf, + bytesToWrite, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesWritten != _server_data) { + if (debug_mode) printf("\tError sending data to client (%d, %d)\n", + bytesWritten, PR_GetOSError()); + } else { + if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); + } + + PR_Close(newSock); + PR_AtomicDecrement(&workerThreadsBusy); + } +} + +PRFileDesc * +ServerSetup(void) +{ + PRFileDesc *listenSocket; + PRSocketOptionData sockOpt; + PRNetAddr serverAddr; + PRThread *WorkerThread; + + if ( (listenSocket = PR_NewTCPSocket()) == NULL) { + if (debug_mode) printf("\tServer error creating listen socket\n"); + else + return NULL; + } + + sockOpt.option = PR_SockOpt_Reuseaddr; + sockOpt.value.reuse_addr = PR_TRUE; + if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { + if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", + PR_GetOSError()); + else failed_already=1; + PR_Close(listenSocket); + return NULL; + } + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); + + if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { + if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", + PR_GetOSError()); + else failed_already=1; + PR_Close(listenSocket); + return NULL; + } + + if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { + if (debug_mode) printf("\tServer error listening to server socket\n"); + else failed_already=1; + PR_Close(listenSocket); + + return NULL; + } + + /* Create Clients */ + workerThreads = 0; + workerThreadsBusy = 0; + + workerThreadsLock = PR_NewLock(); + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSocket, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("error creating working thread\n"); + PR_Close(listenSocket); + return NULL; + } + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); + + return listenSocket; +} + +/* The main server loop */ +void +ServerThreadFunc(void *unused) +{ + PRFileDesc *listenSocket; + + /* Do setup */ + listenSocket = ServerSetup(); + + if (!listenSocket) { + SetServerState(SERVER, SERVER_STATE_DEAD); + } else { + + if (debug_mode) DPRINTF("\tServer up\n"); + + /* Tell clients they can start now. */ + SetServerState(SERVER, SERVER_STATE_READY); + + /* Now wait for server death signal */ + WaitServerState(SERVER, SERVER_STATE_DYING); + + /* Cleanup */ + SetServerState(SERVER, SERVER_STATE_DEAD); + } +} + +/* --- Client Functions ------------------------------------------- */ + +PRInt32 numRequests; +PRInt32 numClients; +PRMonitor *clientMonitor; + +void +ClientThreadFunc(void *unused) +{ + PRNetAddr serverAddr; + PRFileDesc *clientSocket; + char *sendBuf; + char *recvBuf; + PRInt32 rv; + PRInt32 bytesNeeded; + + sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); + if (!recvBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + + while(numRequests > 0) { + + if ( (numRequests % 10) == 0 ) + if (debug_mode) printf("."); + if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); + + clientSocket = PR_NewTCPSocket(); + if (!clientSocket) { + if (debug_mode) printf("Client error creating socket: OS error %d\n", + PR_GetOSError()); + continue; + } + + if (debug_mode) DPRINTF("\tClient connecting\n"); + + rv = PR_Connect(clientSocket, + &serverAddr, + PR_INTERVAL_NO_TIMEOUT); + if (!clientSocket) { + if (debug_mode) printf("\tClient error connecting\n"); + continue; + } + + if (debug_mode) DPRINTF("\tClient connected\n"); + + rv = PR_Send(clientSocket, + sendBuf, + _client_data, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv != _client_data) { + if (debug_mode) printf("Client error sending data (%d)\n", rv); + PR_Close(clientSocket); + continue; + } + + if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); + + bytesNeeded = _server_data; + while(bytesNeeded) { + rv = PR_Recv(clientSocket, + recvBuf, + bytesNeeded, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv <= 0) { + if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", + rv, (_server_data - bytesNeeded), _server_data); + break; + } + if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); + bytesNeeded -= rv; + } + + PR_Close(clientSocket); + + PR_AtomicDecrement(&numRequests); + } + + PR_EnterMonitor(clientMonitor); + --numClients; + PR_Notify(clientMonitor); + PR_ExitMonitor(clientMonitor); + + PR_DELETE(sendBuf); + PR_DELETE(recvBuf); +} + +void +RunClients(void) +{ + PRInt32 index; + + numRequests = _iterations; + numClients = _clients; + clientMonitor = PR_NewMonitor(); + + for (index=0; index<_clients; index++) { + PRThread *clientThread; + + + clientThread = PR_CreateThread( + PR_USER_THREAD, + ClientThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ClientScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!clientThread) { + if (debug_mode) printf("\terror creating client thread %d\n", index); + } else + if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); + + } + + PR_EnterMonitor(clientMonitor); + while(numClients) + PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(clientMonitor); +} + +/* --- Main Function ---------------------------------------------- */ + +static +void do_work() +{ + PRThread *ServerThread; + PRInt32 state; + + SetServerState(MAIN, SERVER_STATE_STARTUP); + ServerThread = PR_CreateThread( + PR_USER_THREAD, + ServerThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ServerScope, + PR_JOINABLE_THREAD, + THREAD_STACKSIZE); + if (!ServerThread) { + if (debug_mode) printf("error creating main server thread\n"); + return; + } + + /* Wait for server to be ready */ + state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); + + if (!(state & SERVER_STATE_DEAD)) { + /* Run Test Clients */ + RunClients(); + + /* Send death signal to server */ + SetServerState(MAIN, SERVER_STATE_DYING); + } + + PR_JoinThread(ServerThread); +} + + +static void do_workUK(void) +{ + ServerScope = PR_LOCAL_THREAD; + ClientScope = PR_GLOBAL_THREAD; + do_work(); +} + + + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + + if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); +} + + +int main(int argc, char **argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ +#ifndef SYMBIAN + if (debug_mode) { + printf("Enter number of iterations: \n"); + scanf("%d", &_iterations); + printf("Enter number of clients : \n"); + scanf("%d", &_clients); + printf("Enter size of client data : \n"); + scanf("%d", &_client_data); + printf("Enter size of server data : \n"); + scanf("%d", &_server_data); + } + else +#endif + { + _iterations = 7; + _clients = 7; + _client_data = 100; + _server_data = 100; + } + + if (debug_mode) { + printf("\n\n%d iterations with %d client threads.\n", + _iterations, _clients); + printf("Sending %d bytes of client data and %d bytes of server data\n", + _client_data, _server_data); + } + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + PR_SetThreadRecycleMode(64); + + ServerStateCVLock = PR_NewLock(); + ServerStateCV = PR_NewCondVar(ServerStateCVLock); + + Measure(do_workUK, "server loop user/kernel"); + + PR_Cleanup(); + + if(failed_already) + return 1; + else + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/servr_uu.c nspr-4.10.7/nspr/pr/tests/servr_uu.c --- nspr-4.9.5/nspr/pr/tests/servr_uu.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/servr_uu.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,569 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** This server simulates a server running in loopback mode. +** +** The idea is that a single server is created. The server initially creates +** a number of worker threads. Then, with the server running, a number of +** clients are created which start requesting service from the server. +** +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include "pprthred.h" + +#include + +#define PORT 15004 +#define THREAD_STACKSIZE 0 + +static int _iterations = 1000; +static int _clients = 1; +static int _client_data = 250; +static int _server_data = (8*1024); + +static PRThreadScope ServerScope, ClientScope; + +#define SERVER "Server" +#define MAIN "Main" + +#define SERVER_STATE_STARTUP 0 +#define SERVER_STATE_READY 1 +#define SERVER_STATE_DYING 2 +#define SERVER_STATE_DEAD 4 +int ServerState; +PRLock *ServerStateCVLock; +PRCondVar *ServerStateCV; + +#ifdef DEBUGPRINTS +#define DPRINTF printf +#else +#define DPRINTF +#endif + +PRIntn failed_already=0; +PRIntn debug_mode; + +static void do_work(void); + +/* --- Server state functions --------------------------------------------- */ +void +SetServerState(char *waiter, PRInt32 state) +{ + PR_Lock(ServerStateCVLock); + ServerState = state; + PR_NotifyCondVar(ServerStateCV); + + if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); + + PR_Unlock(ServerStateCVLock); +} + +int +WaitServerState(char *waiter, PRInt32 state) +{ + PRInt32 rv; + + PR_Lock(ServerStateCVLock); + + if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state); + + while(!(ServerState & state)) + PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT); + rv = ServerState; + + if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", + waiter, state, ServerState); + PR_Unlock(ServerStateCVLock); + + return rv; +} + +/* --- Server Functions ------------------------------------------- */ + +PRLock *workerThreadsLock; +PRInt32 workerThreads; +PRInt32 workerThreadsBusy; + +void +WorkerThreadFunc(void *_listenSock) +{ + PRFileDesc *listenSock = (PRFileDesc *)_listenSock; + PRInt32 bytesRead; + PRInt32 bytesWritten; + char *dataBuf; + char *sendBuf; + + if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n", + _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32); + dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32); + if (!dataBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tServer could not malloc space!?\n"); + + if (debug_mode) DPRINTF("\tServer worker thread running\n"); + + while(1) { + PRInt32 bytesToRead = _client_data; + PRInt32 bytesToWrite = _server_data; + PRFileDesc *newSock; + PRNetAddr *rAddr; + PRInt32 loops = 0; + + loops++; + + if (debug_mode) DPRINTF("\tServer thread going into accept\n"); + + bytesRead = PR_AcceptRead(listenSock, + &newSock, + &rAddr, + dataBuf, + bytesToRead, + PR_INTERVAL_NO_TIMEOUT); + + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead); + continue; + } + + if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead); + + PR_AtomicIncrement(&workerThreadsBusy); +#ifdef SYMBIAN + if (workerThreadsBusy == workerThreads && workerThreads<1) { +#else + if (workerThreadsBusy == workerThreads) { +#endif + + PR_Lock(workerThreadsLock); + if (workerThreadsBusy == workerThreads) { + PRThread *WorkerThread; + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSock, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("Error creating client thread %d\n", workerThreads); + } else { + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads); + } + } + PR_Unlock(workerThreadsLock); + } + + bytesToRead -= bytesRead; + while (bytesToRead) { + bytesRead = PR_Recv(newSock, + dataBuf, + bytesToRead, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead); + continue; + } + if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead); + } + + bytesWritten = PR_Send(newSock, + sendBuf, + bytesToWrite, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (bytesWritten != _server_data) { + if (debug_mode) printf("\tError sending data to client (%d, %d)\n", + bytesWritten, PR_GetOSError()); + } else { + if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten); + } + + PR_Close(newSock); + PR_AtomicDecrement(&workerThreadsBusy); + } +} + +PRFileDesc * +ServerSetup(void) +{ + PRFileDesc *listenSocket; + PRSocketOptionData sockOpt; + PRNetAddr serverAddr; + PRThread *WorkerThread; + + if ( (listenSocket = PR_NewTCPSocket()) == NULL) { + if (debug_mode) printf("\tServer error creating listen socket\n"); + else failed_already=1; + return NULL; + } + + sockOpt.option = PR_SockOpt_Reuseaddr; + sockOpt.value.reuse_addr = PR_TRUE; + if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) { + if (debug_mode) printf("\tServer error setting socket option: OS error %d\n", + PR_GetOSError()); + else failed_already=1; + PR_Close(listenSocket); + return NULL; + } + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY); + + if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) { + if (debug_mode) printf("\tServer error binding to server address: OS error %d\n", + PR_GetOSError()); + else failed_already=1; + PR_Close(listenSocket); + return NULL; + } + + if ( PR_Listen(listenSocket, 128) == PR_FAILURE) { + if (debug_mode) printf("\tServer error listening to server socket\n"); + else failed_already=1; + PR_Close(listenSocket); + + return NULL; + } + + /* Create Clients */ + workerThreads = 0; + workerThreadsBusy = 0; + + workerThreadsLock = PR_NewLock(); + + WorkerThread = PR_CreateThread( + PR_SYSTEM_THREAD, + WorkerThreadFunc, + listenSocket, + PR_PRIORITY_NORMAL, + ServerScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!WorkerThread) { + if (debug_mode) printf("error creating working thread\n"); + PR_Close(listenSocket); + return NULL; + } + PR_AtomicIncrement(&workerThreads); + if (debug_mode) DPRINTF("\tServer created primordial worker thread\n"); + + return listenSocket; +} + +/* The main server loop */ +void +ServerThreadFunc(void *unused) +{ + PRFileDesc *listenSocket; + + /* Do setup */ + listenSocket = ServerSetup(); + + if (!listenSocket) { + SetServerState(SERVER, SERVER_STATE_DEAD); + } else { + + if (debug_mode) DPRINTF("\tServer up\n"); + + /* Tell clients they can start now. */ + SetServerState(SERVER, SERVER_STATE_READY); + + /* Now wait for server death signal */ + WaitServerState(SERVER, SERVER_STATE_DYING); + + /* Cleanup */ + SetServerState(SERVER, SERVER_STATE_DEAD); + } +} + +/* --- Client Functions ------------------------------------------- */ + +PRInt32 numRequests; +PRInt32 numClients; +PRMonitor *clientMonitor; + +void +ClientThreadFunc(void *unused) +{ + PRNetAddr serverAddr; + PRFileDesc *clientSocket; + char *sendBuf; + char *recvBuf; + PRInt32 rv; + PRInt32 bytesNeeded; + + sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char)); + if (!sendBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char)); + if (!recvBuf) + if (debug_mode) printf("\tClient could not malloc space!?\n"); + + memset(&serverAddr, 0, sizeof(PRNetAddr)); + serverAddr.inet.family = PR_AF_INET; + serverAddr.inet.port = PR_htons(PORT); + serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + + while(numRequests > 0) { + + if ( (numRequests % 10) == 0 ) + if (debug_mode) printf("."); + if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests); + + clientSocket = PR_NewTCPSocket(); + if (!clientSocket) { + if (debug_mode) printf("Client error creating socket: OS error %d\n", + PR_GetOSError()); + continue; + } + + if (debug_mode) DPRINTF("\tClient connecting\n"); + + rv = PR_Connect(clientSocket, + &serverAddr, + PR_INTERVAL_NO_TIMEOUT); + if (!clientSocket) { + if (debug_mode) printf("\tClient error connecting\n"); + continue; + } + + if (debug_mode) DPRINTF("\tClient connected\n"); + + rv = PR_Send(clientSocket, + sendBuf, + _client_data, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv != _client_data) { + if (debug_mode) printf("Client error sending data (%d)\n", rv); + PR_Close(clientSocket); + continue; + } + + if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv); + + bytesNeeded = _server_data; + while(bytesNeeded) { + rv = PR_Recv(clientSocket, + recvBuf, + bytesNeeded, + 0, + PR_INTERVAL_NO_TIMEOUT); + if (rv <= 0) { + if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", + rv, (_server_data - bytesNeeded), _server_data); + break; + } + if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv); + bytesNeeded -= rv; + } + + PR_Close(clientSocket); + + PR_AtomicDecrement(&numRequests); + } + + PR_EnterMonitor(clientMonitor); + --numClients; + PR_Notify(clientMonitor); + PR_ExitMonitor(clientMonitor); + + PR_DELETE(sendBuf); + PR_DELETE(recvBuf); +} + +void +RunClients(void) +{ + PRInt32 index; + + numRequests = _iterations; + numClients = _clients; + clientMonitor = PR_NewMonitor(); + + for (index=0; index<_clients; index++) { + PRThread *clientThread; + + + clientThread = PR_CreateThread( + PR_USER_THREAD, + ClientThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ClientScope, + PR_UNJOINABLE_THREAD, + THREAD_STACKSIZE); + + if (!clientThread) { + if (debug_mode) printf("\terror creating client thread %d\n", index); + } else + if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients); + + } + + PR_EnterMonitor(clientMonitor); + while(numClients) + PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(clientMonitor); +} + +/* --- Main Function ---------------------------------------------- */ + +static +void do_work() +{ + PRThread *ServerThread; + PRInt32 state; + + SetServerState(MAIN, SERVER_STATE_STARTUP); + ServerThread = PR_CreateThread( + PR_USER_THREAD, + ServerThreadFunc, + NULL, + PR_PRIORITY_NORMAL, + ServerScope, + PR_JOINABLE_THREAD, + THREAD_STACKSIZE); + if (!ServerThread) { + if (debug_mode) printf("error creating main server thread\n"); + return; + } + + /* Wait for server to be ready */ + state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD); + + if (!(state & SERVER_STATE_DEAD)) { + /* Run Test Clients */ + RunClients(); + + /* Send death signal to server */ + SetServerState(MAIN, SERVER_STATE_DYING); + } + + PR_JoinThread(ServerThread); +} + +static void do_workUU(void) +{ + ServerScope = PR_LOCAL_THREAD; + ClientScope = PR_LOCAL_THREAD; + do_work(); +} + + + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + + if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations); +} + + +int main(int argc, char **argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ +#ifndef SYMBIAN + if (debug_mode) { + printf("Enter number of iterations: \n"); + scanf("%d", &_iterations); + printf("Enter number of clients : \n"); + scanf("%d", &_clients); + printf("Enter size of client data : \n"); + scanf("%d", &_client_data); + printf("Enter size of server data : \n"); + scanf("%d", &_server_data); + } + else +#endif + { + _iterations = 7; + _clients = 7; + _client_data = 100; + _server_data = 100; + } + + if (debug_mode) { + printf("\n\n%d iterations with %d client threads.\n", + _iterations, _clients); + printf("Sending %d bytes of client data and %d bytes of server data\n", + _client_data, _server_data); + } + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + PR_SetThreadRecycleMode(64); + + ServerStateCVLock = PR_NewLock(); + ServerStateCV = PR_NewCondVar(ServerStateCVLock); + + Measure(do_workUU, "server loop user/user"); + + PR_Cleanup(); + + if(failed_already) + return 1; + else + return 0; + +} diff -Nru nspr-4.9.5/nspr/pr/tests/short_thread.c nspr-4.10.7/nspr/pr/tests/short_thread.c --- nspr-4.9.5/nspr/pr/tests/short_thread.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/short_thread.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include "nspr.h" +#include "plgetopt.h" + +/* + * Create a thread that exits right away; useful for testing race conditions in thread + * creation + */ + +int _debug_on = 0; +#define DPRINTF(arg) if (_debug_on) printf arg + +static void housecleaning(void *cur_time); + +int main (int argc, char **argv) +{ + static PRIntervalTime thread_start_time; + static PRThread *housekeeping_tid = NULL; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (( housekeeping_tid = + PR_CreateThread (PR_USER_THREAD, housecleaning, (void*)&thread_start_time, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0)) + == NULL ) { + fprintf(stderr, + "simple_test: Error - PR_CreateThread failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + exit( 1 ); + } + PR_Cleanup(); + return(0); +} + +static void +housecleaning (void *cur_time) +{ + DPRINTF(("Child Thread exiting\n")); +} diff -Nru nspr-4.9.5/nspr/pr/tests/sigpipe.c nspr-4.10.7/nspr/pr/tests/sigpipe.c --- nspr-4.9.5/nspr/pr/tests/sigpipe.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sigpipe.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + ************************************************************************* + * + * Test: sigpipe.c + * + * Test the SIGPIPE handler in NSPR. This test applies to Unix only. + * + ************************************************************************* + */ + +#if !defined(XP_UNIX) && !defined(XP_OS2) + +int main(void) +{ + /* This test applies to Unix and OS/2. */ + return 0; +} + +#else /* XP_UNIX && OS/2 */ + +#include "nspr.h" + +#ifdef XP_OS2 +#define INCL_DOSQUEUES +#define INCL_DOSERRORS +#include +#endif + +#include +#include +#include + +static void Test(void *arg) +{ +#ifdef XP_OS2 + HFILE pipefd[2]; +#else + int pipefd[2]; +#endif + int rv; + char c = '\0'; + +#ifdef XP_OS2 + if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) { +#else + if (pipe(pipefd) == -1) { +#endif + fprintf(stderr, "cannot create pipe: %d\n", errno); + exit(1); + } + close(pipefd[0]); + + rv = write(pipefd[1], &c, 1); + if (rv != -1) { + fprintf(stderr, "write to broken pipe should have failed with EPIPE but returned %d\n", rv); + exit(1); + } +#ifdef SYMBIAN + /* Have mercy on the unknown 142 errno, it seems ok */ + if (errno != EPIPE && errno != 142) { +#else + if (errno != EPIPE) { +#endif + fprintf(stderr, "write to broken pipe failed but with wrong errno: %d\n", errno); + exit(1); + } + close(pipefd[1]); + printf("write to broken pipe failed with EPIPE, as expected\n"); +} + +int main(int argc, char **argv) +{ + PRThread *thread; + + /* This initializes NSPR. */ + PR_SetError(0, 0); + + thread = PR_CreateThread(PR_USER_THREAD, Test, NULL, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (thread == NULL) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + if (PR_JoinThread(thread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + Test(NULL); + + printf("PASSED\n"); + return 0; +} + +#endif /* XP_UNIX */ diff -Nru nspr-4.9.5/nspr/pr/tests/sleep.c nspr-4.10.7/nspr/pr/tests/sleep.c --- nspr-4.9.5/nspr/pr/tests/sleep.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sleep.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" + +#if defined(XP_UNIX) || defined(XP_OS2) + +#include + +#ifndef XP_OS2 +#include +#endif +#include + +#if defined(HAVE_SVID_GETTOD) +#define GTOD(_a) gettimeofday(_a) +#else +#define GTOD(_a) gettimeofday((_a), NULL) +#endif + +static PRIntn rv = 0; + +static void Other(void *unused) +{ + PRIntn didit = 0; + while (PR_SUCCESS == PR_Sleep(PR_MillisecondsToInterval(250))) + { + fprintf(stderr, "."); + didit += 1; + } + if (didit < 5) rv = 1; +} + +int main(int argc, char **argv) +{ + PRUint32 elapsed; + PRThread *thread; + struct timeval timein, timeout; + PRInt32 onePercent = 3000000UL / 100UL; + + fprintf (stderr, "First sleep will sleep 3 seconds.\n"); + fprintf (stderr, " sleep 1 begin\n"); + (void)GTOD(&timein); + sleep (3); + (void)GTOD(&timeout); + fprintf (stderr, " sleep 1 end\n"); + elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec); + elapsed += (timeout.tv_usec - timein.tv_usec); + fprintf(stderr, "elapsed %u usecs\n", elapsed); + if (labs(elapsed - 3000000UL) > onePercent) rv = 1; + + PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 100); + PR_STDIO_INIT(); + + fprintf (stderr, "Second sleep should do the same (does it?).\n"); + fprintf (stderr, " sleep 2 begin\n"); + (void)GTOD(&timein); + sleep (3); + (void)GTOD(&timeout); + fprintf (stderr, " sleep 2 end\n"); + elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec); + elapsed += (timeout.tv_usec - timein.tv_usec); + fprintf(stderr, "elapsed %u usecs\n", elapsed); + if (labs(elapsed - 3000000UL) > onePercent) rv = 1; + + fprintf (stderr, "What happens to other threads?\n"); + fprintf (stderr, "You should see dots every quarter second.\n"); + fprintf (stderr, "If you don't, you're probably running on classic NSPR.\n"); + thread = PR_CreateThread( + PR_USER_THREAD, Other, NULL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + fprintf (stderr, " sleep 2 begin\n"); + (void)GTOD(&timein); + sleep (3); + (void)GTOD(&timeout); + fprintf (stderr, " sleep 2 end\n"); + PR_Interrupt(thread); + PR_JoinThread(thread); + elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec); + elapsed += (timeout.tv_usec - timein.tv_usec); + fprintf(stderr, "elapsed %u usecs\n", elapsed); + if (labs(elapsed - 3000000UL) > onePercent) rv = 1; + fprintf(stderr, "%s\n", (0 == rv) ? "PASSED" : "FAILED"); + return rv; +} + +#else /* defined(XP_UNIX) */ + +PRIntn main() +{ + return 2; +} + +#endif /* defined(XP_UNIX) */ + diff -Nru nspr-4.9.5/nspr/pr/tests/socket.c nspr-4.10.7/nspr/pr/tests/socket.c --- nspr-4.9.5/nspr/pr/tests/socket.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/socket.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,2322 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: socket.c +** +** Description: Test socket functionality. +** +** Modification History: +*/ +#include "primpl.h" + +#include "plgetopt.h" + +#include +#include +#include +#ifdef XP_UNIX +#include +#endif +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) +#include +#endif + +#ifdef WIN32 +#include +#endif + +static int _debug_on = 0; +static int test_cancelio = 0; + +#include "obsolete/prsem.h" + +#ifdef XP_PC +#define mode_t int +#endif + +#define DPRINTF(arg) if (_debug_on) printf arg + +#ifdef XP_PC +char *TEST_DIR = "prdir"; +char *SMALL_FILE_NAME = "prsmallf"; +char *LARGE_FILE_NAME = "prlargef"; +#elif defined(SYMBIAN) +char *TEST_DIR = "c:\\data\\prsocket"; +char *SMALL_FILE_NAME = "c:\\data\\prsocket\\small_file"; +char *LARGE_FILE_NAME = "c:\\data\\prsocket\\large_file"; +#else +char *TEST_DIR = "/tmp/prsocket_test_dir"; +char *SMALL_FILE_NAME = "/tmp/prsocket_test_dir/small_file"; +char *LARGE_FILE_NAME = "/tmp/prsocket_test_dir/large_file"; +#endif +#define SMALL_FILE_SIZE (3 * 1024) /* 3 KB */ +#define SMALL_FILE_OFFSET_1 (512) +#define SMALL_FILE_LEN_1 (1 * 1024) /* 1 KB */ +#define SMALL_FILE_OFFSET_2 (75) +#define SMALL_FILE_LEN_2 (758) +#define SMALL_FILE_OFFSET_3 (1024) +#define SMALL_FILE_LEN_3 (SMALL_FILE_SIZE - SMALL_FILE_OFFSET_3) +#define SMALL_FILE_HEADER_SIZE (64) /* 64 bytes */ +#define SMALL_FILE_TRAILER_SIZE (128) /* 128 bytes */ + +#define LARGE_FILE_SIZE (3 * 1024 * 1024) /* 3 MB */ +#define LARGE_FILE_OFFSET_1 (0) +#define LARGE_FILE_LEN_1 (2 * 1024 * 1024) /* 2 MB */ +#define LARGE_FILE_OFFSET_2 (64) +#define LARGE_FILE_LEN_2 (1 * 1024 * 1024 + 75) +#define LARGE_FILE_OFFSET_3 (2 * 1024 * 1024 - 128) +#define LARGE_FILE_LEN_3 (LARGE_FILE_SIZE - LARGE_FILE_OFFSET_3) +#define LARGE_FILE_OFFSET_4 PR_GetPageSize() +#define LARGE_FILE_LEN_4 769 +#define LARGE_FILE_HEADER_SIZE (512) +#define LARGE_FILE_TRAILER_SIZE (64) + +#define BUF_DATA_SIZE (2 * 1024) +#define TCP_MESG_SIZE 1024 +/* + * set UDP datagram size small enough that datagrams sent to a port on the + * local host will not be lost + */ +#define UDP_DGRAM_SIZE 128 +#define NUM_TCP_CLIENTS 5 /* for a listen queue depth of 5 */ +#define NUM_UDP_CLIENTS 10 + +#ifdef SYMBIAN +#define NUM_TRANSMITFILE_CLIENTS 1 +#else +#define NUM_TRANSMITFILE_CLIENTS 4 +#endif + +#define NUM_TCP_CONNECTIONS_PER_CLIENT 5 +#define NUM_TCP_MESGS_PER_CONNECTION 10 +#define NUM_UDP_DATAGRAMS_PER_CLIENT 5 +#define TCP_SERVER_PORT 10000 +#define UDP_SERVER_PORT TCP_SERVER_PORT +#define SERVER_MAX_BIND_COUNT 100 + +#ifdef WINCE +#define perror(s) +#endif + +static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS; +static PRInt32 num_udp_clients = NUM_UDP_CLIENTS; +static PRInt32 num_transmitfile_clients = NUM_TRANSMITFILE_CLIENTS; +static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT; +static PRInt32 tcp_mesg_size = TCP_MESG_SIZE; +static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION; +static PRInt32 num_udp_datagrams_per_client = NUM_UDP_DATAGRAMS_PER_CLIENT; +static PRInt32 udp_datagram_size = UDP_DGRAM_SIZE; + +static PRInt32 thread_count; +PRUint16 server_domain = PR_AF_INET, client_domain = PR_AF_INET; + +/* an I/O layer that uses the emulated senfile method */ +static PRDescIdentity emuSendFileIdentity; +static PRIOMethods emuSendFileMethods; + +int failed_already=0; +typedef struct buffer { + char data[BUF_DATA_SIZE]; +} buffer; + +PRNetAddr tcp_server_addr, udp_server_addr; + +typedef struct Serve_Client_Param { + PRFileDesc *sockfd; /* socket to read from/write to */ + PRInt32 datalen; /* bytes of data transfered in each read/write */ +} Serve_Client_Param; + +typedef struct Server_Param { + PRSemaphore *addr_sem; /* sem to post on, after setting up the address */ + PRMonitor *exit_mon; /* monitor to signal on exit */ + PRInt32 *exit_counter; /* counter to decrement, before exit */ + PRInt32 datalen; /* bytes of data transfered in each read/write */ +} Server_Param; + + +typedef struct Client_Param { + PRNetAddr server_addr; + PRMonitor *exit_mon; /* monitor to signal on exit */ + PRInt32 *exit_counter; /* counter to decrement, before exit */ + PRInt32 datalen; + PRInt32 udp_connect; /* if set clients connect udp sockets */ +} Client_Param; + +/* the sendfile method in emuSendFileMethods */ +static PRInt32 PR_CALLBACK +emu_SendFile(PRFileDesc *sd, PRSendFileData *sfd, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + return PR_EmulateSendFile(sd, sfd, flags, timeout); +} + +/* the transmitfile method in emuSendFileMethods */ +static PRInt32 PR_CALLBACK +emu_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, const void *headers, + PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + PRSendFileData sfd; + + sfd.fd = fd; + sfd.file_offset = 0; + sfd.file_nbytes = 0; + sfd.header = headers; + sfd.hlen = hlen; + sfd.trailer = NULL; + sfd.tlen = 0; + return emu_SendFile(sd, &sfd, flags, timeout); +} + +/* + * readn + * read data from sockfd into buf + */ +static PRInt32 +readn(PRFileDesc *sockfd, char *buf, int len) +{ + int rem; + int bytes; + int offset = 0; + int err; + PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; + + if (test_cancelio) + timeout = PR_SecondsToInterval(2); + + for (rem=len; rem; offset += bytes, rem -= bytes) { + DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n", + PR_GetCurrentThread(), rem)); +retry: + bytes = PR_Recv(sockfd, buf + offset, rem, 0, + timeout); + DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n", + PR_GetCurrentThread(), bytes)); + if (bytes < 0) { +#ifdef WINNT + printf("PR_Recv: error = %d oserr = %d\n",(err = PR_GetError()), + PR_GetOSError()); + if ((test_cancelio) && (err == PR_IO_TIMEOUT_ERROR)) { + if (PR_NT_CancelIo(sockfd) != PR_SUCCESS) + printf("PR_NT_CancelIO: error = %d\n",PR_GetError()); + timeout = PR_INTERVAL_NO_TIMEOUT; + goto retry; + } +#endif + return -1; + } + } + return len; +} + +/* + * writen + * write data from buf to sockfd + */ +static PRInt32 +writen(PRFileDesc *sockfd, char *buf, int len) +{ + int rem; + int bytes; + int offset = 0; + + for (rem=len; rem; offset += bytes, rem -= bytes) { + DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n", + PR_GetCurrentThread(), rem)); + bytes = PR_Send(sockfd, buf + offset, rem, 0, + PR_INTERVAL_NO_TIMEOUT); + DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n", + PR_GetCurrentThread(), bytes)); + if (bytes <= 0) + return -1; + } + return len; +} + +/* + * Serve_Client + * Thread, started by the server, for serving a client connection. + * Reads data from socket and writes it back, unmodified, and + * closes the socket + */ +static void PR_CALLBACK +Serve_Client(void *arg) +{ + Serve_Client_Param *scp = (Serve_Client_Param *) arg; + PRFileDesc *sockfd; + buffer *in_buf; + PRInt32 bytes, j; + + sockfd = scp->sockfd; + bytes = scp->datalen; + in_buf = PR_NEW(buffer); + if (in_buf == NULL) { + fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); + failed_already=1; + goto exit; + } + + + for (j = 0; j < num_tcp_mesgs_per_connection; j++) { + /* + * Read data from client and send it back to the client unmodified + */ + if (readn(sockfd, in_buf->data, bytes) < bytes) { + fprintf(stderr,"prsocket_test: ERROR - Serve_Client:readn\n"); + failed_already=1; + goto exit; + } + /* Shutdown only RCV will cause error on Symbian OS */ +#if !defined(SYMBIAN) + /* + * shutdown reads, after the last read + */ + if (j == num_tcp_mesgs_per_connection - 1) + if (PR_Shutdown(sockfd, PR_SHUTDOWN_RCV) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); + } +#endif + DPRINTF(("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n",PR_GetCurrentThread(), + (*((int *) in_buf->data)))); + if (writen(sockfd, in_buf->data, bytes) < bytes) { + fprintf(stderr,"prsocket_test: ERROR - Serve_Client:writen\n"); + failed_already=1; + goto exit; + } + } + /* + * shutdown reads and writes + */ + if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); + failed_already=1; + } + +exit: + PR_Close(sockfd); + if (in_buf) { + PR_DELETE(in_buf); + } +} + +PRThread* create_new_thread(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize, PRInt32 index) +{ +PRInt32 native_thread = 0; + + PR_ASSERT(state == PR_UNJOINABLE_THREAD); +#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) + switch(index % 4) { + case 0: + scope = (PR_LOCAL_THREAD); + break; + case 1: + scope = (PR_GLOBAL_THREAD); + break; + case 2: + scope = (PR_GLOBAL_BOUND_THREAD); + break; + case 3: + native_thread = 1; + break; + default: + PR_ASSERT(!"Invalid scope"); + break; + } + if (native_thread) { +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) + pthread_t tid; + if (!pthread_create(&tid, NULL, (void * (*)(void *)) start, arg)) + return((PRThread *) tid); + else + return (NULL); +#else + HANDLE thandle; + unsigned tid; + + thandle = (HANDLE) _beginthreadex( + NULL, + stackSize, + (unsigned (__stdcall *)(void *))start, + arg, + STACK_SIZE_PARAM_IS_A_RESERVATION, + &tid); + return((PRThread *) thandle); +#endif + } else { + return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); + } +#else + return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); +#endif +} + +/* + * TCP Server + * Server Thread + * Bind an address to a socket and listen for incoming connections + * Start a Serve_Client thread for each incoming connection. + */ +static void PR_CALLBACK +TCP_Server(void *arg) +{ + PRThread *t; + Server_Param *sp = (Server_Param *) arg; + Serve_Client_Param *scp; + PRFileDesc *sockfd, *newsockfd; + PRNetAddr netaddr; + PRInt32 i; + /* + * Create a tcp socket + */ + if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL) { + fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); + goto exit; + } + memset(&netaddr, 0 , sizeof(netaddr)); + + if (PR_SetNetAddr(PR_IpAddrAny, server_domain, TCP_SERVER_PORT, + &netaddr) == PR_FAILURE) { + fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); + goto exit; + } + /* + * try a few times to bind server's address, if addresses are in + * use + */ + i = 0; + + while (PR_Bind(sockfd, &netaddr) < 0) { + if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { + netaddr.inet.port += 2; + if (i++ < SERVER_MAX_BIND_COUNT) + continue; + } + fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); + perror("PR_Bind"); + failed_already=1; + goto exit; + } + + if (PR_Listen(sockfd, 32) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); + failed_already=1; + goto exit; + } + + if (PR_GetSockName(sockfd, &netaddr) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); + failed_already=1; + goto exit; + } + + DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", + netaddr.inet.ip, netaddr.inet.port)); + if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain, + PR_ntohs(PR_NetAddrInetPort(&netaddr)), + &tcp_server_addr) == PR_FAILURE) { + fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); + goto exit; + } + if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET)) + PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK), + &tcp_server_addr.ipv6.ip); + + /* + * Wake up parent thread because server address is bound and made + * available in the global variable 'tcp_server_addr' + */ + PR_PostSem(sp->addr_sem); + + for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) { + /* test both null and non-null 'addr' argument to PR_Accept */ + PRNetAddr *addrp = (i%2 ? &netaddr: NULL); + + DPRINTF(("TCP_Server: Accepting connection\n")); + if ((newsockfd = PR_Accept(sockfd, addrp, + PR_INTERVAL_NO_TIMEOUT)) == NULL) { + fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n"); + goto exit; + } + DPRINTF(("TCP_Server: Accepted connection\n")); + scp = PR_NEW(Serve_Client_Param); + if (scp == NULL) { + fprintf(stderr,"prsocket_test: PR_NEW failed\n"); + goto exit; + } + + /* + * Start a Serve_Client thread for each incoming connection + */ + scp->sockfd = newsockfd; + scp->datalen = sp->datalen; + + t = create_new_thread(PR_USER_THREAD, + Serve_Client, (void *)scp, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0, i); + if (t == NULL) { + fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); + failed_already=1; + goto exit; + } + DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t)); + } + +exit: + if (sockfd) { + PR_Close(sockfd); + } + + /* + * Decrement exit_counter and notify parent thread + */ + + PR_EnterMonitor(sp->exit_mon); + --(*sp->exit_counter); + PR_Notify(sp->exit_mon); + PR_ExitMonitor(sp->exit_mon); + DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread())); +} + +/* + * UDP Server + * Server Thread + * Bind an address to a socket, read data from clients and send data + * back to clients + */ +static void PR_CALLBACK +UDP_Server(void *arg) +{ + Server_Param *sp = (Server_Param *) arg; + PRFileDesc *sockfd; + buffer *in_buf; + PRNetAddr netaddr; + PRInt32 bytes, i, rv = 0; + + + bytes = sp->datalen; + /* + * Create a udp socket + */ + if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) { + fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n"); + failed_already=1; + return; + } + memset(&netaddr, 0 , sizeof(netaddr)); + if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT, + &netaddr) == PR_FAILURE) { + fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); + failed_already=1; + return; + } + /* + * try a few times to bind server's address, if addresses are in + * use + */ + i = 0; + while (PR_Bind(sockfd, &netaddr) < 0) { + if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { + netaddr.inet.port += 2; + if (i++ < SERVER_MAX_BIND_COUNT) + continue; + } + fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); + perror("PR_Bind"); + failed_already=1; + return; + } + + if (PR_GetSockName(sockfd, &netaddr) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); + failed_already=1; + return; + } + + DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", + netaddr.inet.ip, netaddr.inet.port)); + /* + * We can't use the IP address returned by PR_GetSockName in + * netaddr.inet.ip because netaddr.inet.ip is returned + * as 0 (= PR_INADDR_ANY). + */ + + if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain, + PR_ntohs(PR_NetAddrInetPort(&netaddr)), + &udp_server_addr) == PR_FAILURE) { + fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); + failed_already=1; + return; + } + if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET)) + PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK), + &udp_server_addr.ipv6.ip); + + /* + * Wake up parent thread because server address is bound and made + * available in the global variable 'udp_server_addr' + */ + PR_PostSem(sp->addr_sem); + + bytes = sp->datalen; + in_buf = PR_NEW(buffer); + if (in_buf == NULL) { + fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); + failed_already=1; + return; + } + /* + * Receive datagrams from clients and send them back, unmodified, to the + * clients + */ + memset(&netaddr, 0 , sizeof(netaddr)); + for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) { + DPRINTF(("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", + netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data, + in_buf->data[0])); + + rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, + PR_INTERVAL_NO_TIMEOUT); + DPRINTF(("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", + netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, + in_buf->data[0])); + if (rv != bytes) { + return; + } + rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr, + PR_INTERVAL_NO_TIMEOUT); + if (rv != bytes) { + return; + } + } + + PR_DELETE(in_buf); + PR_Close(sockfd); + + /* + * Decrement exit_counter and notify parent thread + */ + PR_EnterMonitor(sp->exit_mon); + --(*sp->exit_counter); + PR_Notify(sp->exit_mon); + PR_ExitMonitor(sp->exit_mon); + DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread())); +} + +/* + * TCP_Client + * Client Thread + * Connect to the server at the address specified in the argument. + * Fill in a buffer, write data to server, read it back and check + * for data corruption. + * Close the socket for server connection + */ +static void PR_CALLBACK +TCP_Client(void *arg) +{ + Client_Param *cp = (Client_Param *) arg; + PRFileDesc *sockfd; + buffer *in_buf, *out_buf; + union PRNetAddr netaddr; + PRInt32 bytes, i, j; + + + bytes = cp->datalen; + out_buf = PR_NEW(buffer); + if (out_buf == NULL) { + fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); + failed_already=1; + return; + } + in_buf = PR_NEW(buffer); + if (in_buf == NULL) { + fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); + failed_already=1; + return; + } + netaddr = cp->server_addr; + + for (i = 0; i < num_tcp_connections_per_client; i++) { + if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL) { + fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n"); + failed_already=1; + return; + } + if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ + fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + return; + } + for (j = 0; j < num_tcp_mesgs_per_connection; j++) { + /* + * fill in random data + */ + memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes); + /* + * write to server + */ +#ifdef WINNT + if (test_cancelio && (j == 0)) + PR_Sleep(PR_SecondsToInterval(12)); +#endif + if (writen(sockfd, out_buf->data, bytes) < bytes) { + fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n"); + failed_already=1; + return; + } + DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", + PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); + if (readn(sockfd, in_buf->data, bytes) < bytes) { + fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n"); + failed_already=1; + return; + } + /* + * verify the data read + */ + if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { + fprintf(stderr,"prsocket_test: ERROR - data corruption\n"); + failed_already=1; + return; + } + } + /* + * shutdown reads and writes + */ + if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); +#if defined(SYMBIAN) + if (EPIPE != errno) +#endif + failed_already=1; + } + PR_Close(sockfd); + } + + PR_DELETE(out_buf); + PR_DELETE(in_buf); + + /* + * Decrement exit_counter and notify parent thread + */ + + PR_EnterMonitor(cp->exit_mon); + --(*cp->exit_counter); + PR_Notify(cp->exit_mon); + PR_ExitMonitor(cp->exit_mon); + DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread())); +} + +/* + * UDP_Client + * Client Thread + * Create a socket and bind an address + * Communicate with the server at the address specified in the argument. + * Fill in a buffer, write data to server, read it back and check + * for data corruption. + * Close the socket + */ +static void PR_CALLBACK +UDP_Client(void *arg) +{ + Client_Param *cp = (Client_Param *) arg; + PRFileDesc *sockfd; + buffer *in_buf, *out_buf; + union PRNetAddr netaddr; + PRInt32 bytes, i, rv; + + + bytes = cp->datalen; + out_buf = PR_NEW(buffer); + if (out_buf == NULL) { + fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); + failed_already=1; + return; + } + in_buf = PR_NEW(buffer); + if (in_buf == NULL) { + fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); + failed_already=1; + return; + } + if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) { + fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n"); + failed_already=1; + return; + } + + /* + * bind an address for the client, let the system chose the port + * number + */ + memset(&netaddr, 0 , sizeof(netaddr)); + if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0, + &netaddr) == PR_FAILURE) { + fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); + failed_already=1; + return; + } + if (PR_Bind(sockfd, &netaddr) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); + perror("PR_Bind"); + return; + } + + if (PR_GetSockName(sockfd, &netaddr) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); + failed_already=1; + return; + } + + DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", + netaddr.inet.ip, netaddr.inet.port)); + + netaddr = cp->server_addr; + + if (cp->udp_connect) { + if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ + fprintf(stderr,"prsocket_test: PR_Connect failed\n"); + failed_already=1; + return; + } + } + + for (i = 0; i < num_udp_datagrams_per_client; i++) { + /* + * fill in random data + */ + DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n", + PR_GetCurrentThread(), out_buf->data, bytes)); + memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes); + /* + * write to server + */ + if (cp->udp_connect) + rv = PR_Send(sockfd, out_buf->data, bytes, 0, + PR_INTERVAL_NO_TIMEOUT); + else + rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr, + PR_INTERVAL_NO_TIMEOUT); + if (rv != bytes) { + return; + } + DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", + PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); + if (cp->udp_connect) + rv = PR_Recv(sockfd, in_buf->data, bytes, 0, + PR_INTERVAL_NO_TIMEOUT); + else + rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, + PR_INTERVAL_NO_TIMEOUT); + if (rv != bytes) { + return; + } + DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n", + PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data)))); + /* + * verify the data read + */ + if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { + fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n"); + failed_already=1; + return; + } + } + PR_Close(sockfd); + + PR_DELETE(in_buf); + PR_DELETE(out_buf); + + /* + * Decrement exit_counter and notify parent thread + */ + + PR_EnterMonitor(cp->exit_mon); + --(*cp->exit_counter); + PR_Notify(cp->exit_mon); + PR_ExitMonitor(cp->exit_mon); + PR_DELETE(cp); + DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread())); +} + +/* + * TCP_Socket_Client_Server_Test - concurrent server test + * + * One server and several clients are started + * Each client connects to the server and sends a chunk of data + * For each connection, server starts another thread to read the data + * from the client and send it back to the client, unmodified. + * Each client checks that data received from server is same as the + * data it sent to the server. + * + */ + +static PRInt32 +TCP_Socket_Client_Server_Test(void) +{ + int i; + PRThread *t; + PRSemaphore *server_sem; + Server_Param *sparamp; + Client_Param *cparamp; + PRMonitor *mon2; + PRInt32 datalen; + + + datalen = tcp_mesg_size; + thread_count = 0; + /* + * start the server thread + */ + sparamp = PR_NEW(Server_Param); + if (sparamp == NULL) { + fprintf(stderr,"prsocket_test: PR_NEW failed\n"); + failed_already=1; + return -1; + } + server_sem = PR_NewSem(0); + if (server_sem == NULL) { + fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); + failed_already=1; + return -1; + } + mon2 = PR_NewMonitor(); + if (mon2 == NULL) { + fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); + failed_already=1; + return -1; + } + PR_EnterMonitor(mon2); + + sparamp->addr_sem = server_sem; + sparamp->exit_mon = mon2; + sparamp->exit_counter = &thread_count; + sparamp->datalen = datalen; + t = PR_CreateThread(PR_USER_THREAD, + TCP_Server, (void *)sparamp, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + if (t == NULL) { + fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); + failed_already=1; + return -1; + } + DPRINTF(("Created TCP server = 0x%lx\n", t)); + thread_count++; + + /* + * wait till the server address is setup + */ + PR_WaitSem(server_sem); + + /* + * Now start a bunch of client threads + */ + + cparamp = PR_NEW(Client_Param); + if (cparamp == NULL) { + fprintf(stderr,"prsocket_test: PR_NEW failed\n"); + failed_already=1; + return -1; + } + cparamp->server_addr = tcp_server_addr; + cparamp->exit_mon = mon2; + cparamp->exit_counter = &thread_count; + cparamp->datalen = datalen; + for (i = 0; i < num_tcp_clients; i++) { + t = create_new_thread(PR_USER_THREAD, + TCP_Client, (void *) cparamp, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0, i); + if (t == NULL) { + fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); + failed_already=1; + return -1; + } + DPRINTF(("Created TCP client = 0x%lx\n", t)); + thread_count++; + } + /* Wait for server and client threads to exit */ + while (thread_count) { + PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); + DPRINTF(("TCP Server - thread_count = %d\n", thread_count)); + } + PR_ExitMonitor(mon2); + printf("%30s","TCP_Socket_Client_Server_Test:"); + printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l, + num_tcp_clients, num_tcp_connections_per_client); + printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":", + num_tcp_mesgs_per_connection, tcp_mesg_size); + + return 0; +} + +/* + * UDP_Socket_Client_Server_Test - iterative server test + * + * One server and several clients are started + * Each client connects to the server and sends a chunk of data + * For each connection, server starts another thread to read the data + * from the client and send it back to the client, unmodified. + * Each client checks that data received from server is same as the + * data it sent to the server. + * + */ + +static PRInt32 +UDP_Socket_Client_Server_Test(void) +{ + int i; + PRThread *t; + PRSemaphore *server_sem; + Server_Param *sparamp; + Client_Param *cparamp; + PRMonitor *mon2; + PRInt32 datalen; + PRInt32 udp_connect = 1; + + + datalen = udp_datagram_size; + thread_count = 0; + /* + * start the server thread + */ + sparamp = PR_NEW(Server_Param); + if (sparamp == NULL) { + fprintf(stderr,"prsocket_test: PR_NEW failed\n"); + failed_already=1; + return -1; + } + server_sem = PR_NewSem(0); + if (server_sem == NULL) { + fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); + failed_already=1; + return -1; + } + mon2 = PR_NewMonitor(); + if (mon2 == NULL) { + fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); + failed_already=1; + return -1; + } + PR_EnterMonitor(mon2); + + sparamp->addr_sem = server_sem; + sparamp->exit_mon = mon2; + sparamp->exit_counter = &thread_count; + sparamp->datalen = datalen; + DPRINTF(("Creating UDP server")); + t = PR_CreateThread(PR_USER_THREAD, + UDP_Server, (void *)sparamp, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + if (t == NULL) { + fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); + failed_already=1; + return -1; + } + thread_count++; + + /* + * wait till the server address is setup + */ + PR_WaitSem(server_sem); + + /* + * Now start a bunch of client threads + */ + + for (i = 0; i < num_udp_clients; i++) { + cparamp = PR_NEW(Client_Param); + if (cparamp == NULL) { + fprintf(stderr,"prsocket_test: PR_NEW failed\n"); + failed_already=1; + return -1; + } + cparamp->server_addr = udp_server_addr; + cparamp->exit_mon = mon2; + cparamp->exit_counter = &thread_count; + cparamp->datalen = datalen; + /* + * Cause every other client thread to connect udp sockets + */ + cparamp->udp_connect = udp_connect; + if (udp_connect) + udp_connect = 0; + else + udp_connect = 1; + DPRINTF(("Creating UDP client %d\n", i)); + t = PR_CreateThread(PR_USER_THREAD, + UDP_Client, (void *) cparamp, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + if (t == NULL) { + fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); + failed_already=1; + return -1; + } + thread_count++; + } + /* Wait for server and client threads to exit */ + while (thread_count) { + PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); + DPRINTF(("UDP Server - thread_count = %d\n", thread_count)); + } + PR_ExitMonitor(mon2); + printf("%30s","UDP_Socket_Client_Server_Test: "); + printf("%2ld Server %2ld Clients\n",1l, num_udp_clients); + printf("%30s %2ld datagrams_per_client %4ld bytes_per_datagram\n",":", + num_udp_datagrams_per_client, udp_datagram_size); + + return 0; +} + +static PRFileDesc *small_file_fd, *large_file_fd; +static void *small_file_addr, *small_file_header, *large_file_addr; +static void *small_file_trailer, *large_file_header, *large_file_trailer; +/* + * TransmitFile_Client + * Client Thread + */ +static void +TransmitFile_Client(void *arg) +{ + PRFileDesc *sockfd; + union PRNetAddr netaddr; + char *small_buf, *large_buf; + Client_Param *cp = (Client_Param *) arg; + PRInt32 rlen; + + small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE + + SMALL_FILE_TRAILER_SIZE); + if (small_buf == NULL) { + fprintf(stderr,"prsocket_test: failed to alloc buffer\n"); + failed_already=1; + return; + } + large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE + LARGE_FILE_HEADER_SIZE + + LARGE_FILE_TRAILER_SIZE); + if (large_buf == NULL) { + fprintf(stderr,"prsocket_test: failed to alloc buffer\n"); + failed_already=1; + return; + } + netaddr.inet.family = cp->server_addr.inet.family; + netaddr.inet.port = cp->server_addr.inet.port; + netaddr.inet.ip = cp->server_addr.inet.ip; + + if ((sockfd = PR_NewTCPSocket()) == NULL) { + fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n"); + failed_already=1; + return; + } + + if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ + fprintf(stderr,"prsocket_test: PR_Connect failed\n"); + failed_already=1; + return; + } + /* + * read the small file and verify the data + */ + if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE) + != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) { + fprintf(stderr, + "prsocket_test: TransmitFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + /* File transmission test can not be done because of large file's size */ + if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ + fprintf(stderr, + "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n"); + failed_already=1; + return; + } + if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE, + SMALL_FILE_SIZE) != 0) { + fprintf(stderr, + "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n"); + failed_already=1; + return; + } +#endif + /* + * read the large file and verify the data + */ + if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) { + fprintf(stderr, + "prsocket_test: TransmitFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) { + fprintf(stderr, + "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n"); + failed_already=1; + } +#endif + + + /* + * receive data from PR_SendFile + */ + /* + * case 1: small file with header and trailer + */ + rlen = SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE + + SMALL_FILE_TRAILER_SIZE; + if (readn(sockfd, small_buf, rlen) != rlen) { + fprintf(stderr, + "prsocket_test: SendFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ + fprintf(stderr, + "SendFile 1. ERROR - small file header corruption\n"); + failed_already=1; + return; + } + if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE, + SMALL_FILE_SIZE) != 0) { + fprintf(stderr, + "SendFile 1. ERROR - small file data corruption\n"); + failed_already=1; + return; + } + if (memcmp(small_file_trailer, + small_buf + SMALL_FILE_HEADER_SIZE + SMALL_FILE_SIZE, + SMALL_FILE_TRAILER_SIZE) != 0) { + fprintf(stderr, + "SendFile 1. ERROR - small file trailer corruption\n"); + failed_already=1; + return; + } +#endif + /* + * case 2: partial large file at zero offset, file with header and trailer + */ + rlen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE + + LARGE_FILE_TRAILER_SIZE; + if (readn(sockfd, large_buf, rlen) != rlen) { + fprintf(stderr, + "prsocket_test: SendFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ + fprintf(stderr, + "SendFile 2. ERROR - large file header corruption\n"); + failed_already=1; + return; + } + if (memcmp(large_file_addr, large_buf + LARGE_FILE_HEADER_SIZE, + LARGE_FILE_LEN_1) != 0) { + fprintf(stderr, + "SendFile 2. ERROR - large file data corruption\n"); + failed_already=1; + return; + } + if (memcmp(large_file_trailer, + large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_1, + LARGE_FILE_TRAILER_SIZE) != 0) { + fprintf(stderr, + "SendFile 2. ERROR - large file trailer corruption\n"); + failed_already=1; + return; + } +#endif + /* + * case 3: partial small file at non-zero offset, with header + */ + rlen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE; + if (readn(sockfd, small_buf, rlen) != rlen) { + fprintf(stderr, + "prsocket_test: SendFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ + fprintf(stderr, + "SendFile 3. ERROR - small file header corruption\n"); + failed_already=1; + return; + } + if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_1, + small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_1) != 0) { + fprintf(stderr, + "SendFile 3. ERROR - small file data corruption\n"); + failed_already=1; + return; + } +#endif + /* + * case 4: partial small file at non-zero offset, with trailer + */ + rlen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE; + if (readn(sockfd, small_buf, rlen) != rlen) { + fprintf(stderr, + "prsocket_test: SendFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_2, small_buf, + SMALL_FILE_LEN_2) != 0) { + fprintf(stderr, + "SendFile 4. ERROR - small file data corruption\n"); + failed_already=1; + return; + } + if (memcmp(small_file_trailer, small_buf + SMALL_FILE_LEN_2, + SMALL_FILE_TRAILER_SIZE) != 0) { + fprintf(stderr, + "SendFile 4. ERROR - small file trailer corruption\n"); + failed_already=1; + return; + } +#endif + /* + * case 5: partial large file at non-zero offset, file with header + */ + rlen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE; + if (readn(sockfd, large_buf, rlen) != rlen) { + fprintf(stderr, + "prsocket_test: SendFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ + fprintf(stderr, + "SendFile 5. ERROR - large file header corruption\n"); + failed_already=1; + return; + } + if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_2, + large_buf + LARGE_FILE_HEADER_SIZE, + LARGE_FILE_LEN_2) != 0) { + fprintf(stderr, + "SendFile 5. ERROR - large file data corruption\n"); + failed_already=1; + return; + } +#endif + /* + * case 6: partial small file at non-zero offset, with header + */ + rlen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE; + if (readn(sockfd, small_buf, rlen) != rlen) { + fprintf(stderr, + "prsocket_test: SendFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){ + fprintf(stderr, + "SendFile 6. ERROR - small file header corruption\n"); + return; + } + if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_3, + small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_3) != 0) { +#if 0 + char *i, *j; + int k; + + i = (char *) small_file_addr + SMALL_FILE_OFFSET_3; + j = small_buf + SMALL_FILE_HEADER_SIZE; + k = SMALL_FILE_LEN_3; + while (k-- > 0) { + if (*i++ != *j++) + printf("i = %d j = %d\n", + (int) (i - ((char *) small_file_addr + SMALL_FILE_OFFSET_3)), + (int) (j - (small_buf + SMALL_FILE_HEADER_SIZE))); + } +#endif + fprintf(stderr, + "SendFile 6. ERROR - small file data corruption\n"); + failed_already=1; + return; + } +#endif + /* + * case 7: partial large file at non-zero offset, with header + */ + rlen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE; + if (readn(sockfd, large_buf, rlen) != rlen) { + fprintf(stderr, + "prsocket_test: SendFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ + fprintf(stderr, + "SendFile 7. ERROR - large file header corruption\n"); + failed_already=1; + return; + } + if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_3, + large_buf + LARGE_FILE_HEADER_SIZE, + LARGE_FILE_LEN_3) != 0) { + fprintf(stderr, + "SendFile 7. ERROR - large file data corruption\n"); + failed_already=1; + return; + } +#endif + /* + * case 8: partial large file at non-zero, page-aligned offset, with + * header and trailer + */ + rlen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE + + LARGE_FILE_TRAILER_SIZE; + if (readn(sockfd, large_buf, rlen) != rlen) { + fprintf(stderr, + "prsocket_test: SendFile_Client failed to receive file\n"); + failed_already=1; + return; + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){ + fprintf(stderr, + "SendFile 2. ERROR - large file header corruption\n"); + failed_already=1; + return; + } + if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_4, + large_buf + LARGE_FILE_HEADER_SIZE, + LARGE_FILE_LEN_4) != 0) { + fprintf(stderr, + "SendFile 2. ERROR - large file data corruption\n"); + failed_already=1; + return; + } + if (memcmp(large_file_trailer, + large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_4, + LARGE_FILE_TRAILER_SIZE) != 0) { + fprintf(stderr, + "SendFile 2. ERROR - large file trailer corruption\n"); + failed_already=1; + return; + } +#endif + PR_DELETE(small_buf); + PR_DELETE(large_buf); + PR_Close(sockfd); + + + /* + * Decrement exit_counter and notify parent thread + */ + + PR_EnterMonitor(cp->exit_mon); + --(*cp->exit_counter); + PR_Notify(cp->exit_mon); + PR_ExitMonitor(cp->exit_mon); + DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread())); +} + +/* + * Serve_TransmitFile_Client + * Thread, started by the server, for serving a client connection. + * Trasmits a small file, with a header, and a large file, without + * a header + */ +static void +Serve_TransmitFile_Client(void *arg) +{ + Serve_Client_Param *scp = (Serve_Client_Param *) arg; + PRFileDesc *sockfd; + PRInt32 bytes; + PRFileDesc *local_small_file_fd=NULL; + PRFileDesc *local_large_file_fd=NULL; + PRSendFileData sfd; + PRInt32 slen; + + sockfd = scp->sockfd; + local_small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDONLY,0); + + if (local_small_file_fd == NULL) { + fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n", + SMALL_FILE_NAME); + failed_already=1; + goto done; + } + local_large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDONLY,0); + + if (local_large_file_fd == NULL) { + fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n", + LARGE_FILE_NAME); + failed_already=1; + goto done; + } + bytes = PR_TransmitFile(sockfd, local_small_file_fd, small_file_header, + SMALL_FILE_HEADER_SIZE, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + if (bytes != (SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE)) { + fprintf(stderr, + "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + bytes = PR_TransmitFile(sockfd, local_large_file_fd, NULL, 0, + PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT); + if (bytes != LARGE_FILE_SIZE) { + fprintf(stderr, + "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + + /* + * PR_SendFile test cases + */ + + /* + * case 1: small file with header and trailer + */ + sfd.fd = local_small_file_fd; + sfd.file_offset = 0; + sfd.file_nbytes = 0; + sfd.header = small_file_header; + sfd.hlen = SMALL_FILE_HEADER_SIZE; + sfd.trailer = small_file_trailer; + sfd.tlen = SMALL_FILE_TRAILER_SIZE; + bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + slen = SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE + + SMALL_FILE_TRAILER_SIZE; + if (bytes != slen) { + fprintf(stderr, + "socket: Error - 1. PR_SendFile send_size = %d, bytes sent = %d\n", + slen, bytes); + fprintf(stderr, + "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + + /* + * case 2: partial large file at zero offset, file with header and trailer + */ + sfd.fd = local_large_file_fd; + sfd.file_offset = 0; + sfd.file_nbytes = LARGE_FILE_LEN_1; + sfd.header = large_file_header; + sfd.hlen = LARGE_FILE_HEADER_SIZE; + sfd.trailer = large_file_trailer; + sfd.tlen = LARGE_FILE_TRAILER_SIZE; + bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + slen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE + + LARGE_FILE_TRAILER_SIZE; + if (bytes != slen) { + fprintf(stderr, + "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n", + slen, bytes); + fprintf(stderr, + "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + /* + * case 3: partial small file at non-zero offset, with header + */ + sfd.fd = local_small_file_fd; + sfd.file_offset = SMALL_FILE_OFFSET_1; + sfd.file_nbytes = SMALL_FILE_LEN_1; + sfd.header = small_file_header; + sfd.hlen = SMALL_FILE_HEADER_SIZE; + sfd.trailer = NULL; + sfd.tlen = 0; + bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + slen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE; + if (bytes != slen) { + fprintf(stderr, + "socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n", + slen, bytes); + fprintf(stderr, + "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + /* + * case 4: partial small file at non-zero offset, with trailer + */ + sfd.fd = local_small_file_fd; + sfd.file_offset = SMALL_FILE_OFFSET_2; + sfd.file_nbytes = SMALL_FILE_LEN_2; + sfd.header = NULL; + sfd.hlen = 0; + sfd.trailer = small_file_trailer; + sfd.tlen = SMALL_FILE_TRAILER_SIZE; + bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + slen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE; + if (bytes != slen) { + fprintf(stderr, + "socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n", + slen, bytes); + fprintf(stderr, + "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + /* + * case 5: partial large file at non-zero offset, file with header + */ + sfd.fd = local_large_file_fd; + sfd.file_offset = LARGE_FILE_OFFSET_2; + sfd.file_nbytes = LARGE_FILE_LEN_2; + sfd.header = large_file_header; + sfd.hlen = LARGE_FILE_HEADER_SIZE; + sfd.trailer = NULL; + sfd.tlen = 0; + bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + slen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE; + if (bytes != slen) { + fprintf(stderr, + "socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n", + slen, bytes); + fprintf(stderr, + "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + /* + * case 6: partial small file from non-zero offset till end of file, with header + */ + sfd.fd = local_small_file_fd; + sfd.file_offset = SMALL_FILE_OFFSET_3; + sfd.file_nbytes = 0; /* data from offset to end-of-file */ + sfd.header = small_file_header; + sfd.hlen = SMALL_FILE_HEADER_SIZE; + sfd.trailer = NULL; + sfd.tlen = 0; + bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + slen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE; + if (bytes != slen) { + fprintf(stderr, + "socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n", + slen, bytes); + fprintf(stderr, + "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + /* + * case 7: partial large file at non-zero offset till end-of-file, with header + */ + sfd.fd = local_large_file_fd; + sfd.file_offset = LARGE_FILE_OFFSET_3; + sfd.file_nbytes = 0; /* data until end-of-file */ + sfd.header = large_file_header; + sfd.hlen = LARGE_FILE_HEADER_SIZE; + sfd.trailer = NULL; + sfd.tlen = 0; + bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + slen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE; + if (bytes != slen) { + fprintf(stderr, + "socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n", + slen, bytes); + fprintf(stderr, + "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } + /* + * case 8: partial large file at non-zero page-aligned offset, + * with header and trailer + */ + sfd.fd = local_large_file_fd; + sfd.file_offset = LARGE_FILE_OFFSET_4; + sfd.file_nbytes = LARGE_FILE_LEN_4; + sfd.header = large_file_header; + sfd.hlen = LARGE_FILE_HEADER_SIZE; + sfd.trailer = large_file_trailer; + sfd.tlen = LARGE_FILE_TRAILER_SIZE; + bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_CLOSE_SOCKET, + PR_INTERVAL_NO_TIMEOUT); + slen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE + + LARGE_FILE_TRAILER_SIZE; + if (bytes != slen) { + fprintf(stderr, + "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n", + slen, bytes); + fprintf(stderr, + "prsocket_test: PR_SendFile failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + } +done: + if (local_small_file_fd != NULL) + PR_Close(local_small_file_fd); + if (local_large_file_fd != NULL) + PR_Close(local_large_file_fd); +} + +/* + * TransmitFile Server + * Server Thread + * Bind an address to a socket and listen for incoming connections + * Create worker threads to service clients + */ +static void +TransmitFile_Server(void *arg) +{ + PRThread **t = NULL; /* an array of PRThread pointers */ + Server_Param *sp = (Server_Param *) arg; + Serve_Client_Param *scp; + PRFileDesc *sockfd = NULL, *newsockfd; + PRNetAddr netaddr; + PRInt32 i; + + t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *)); + if (t == NULL) { + fprintf(stderr, "prsocket_test: run out of memory\n"); + failed_already=1; + goto exit; + } + /* + * Create a tcp socket + */ + if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) { + fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n"); + failed_already=1; + goto exit; + } + memset(&netaddr, 0 , sizeof(netaddr)); + netaddr.inet.family = PR_AF_INET; + netaddr.inet.port = PR_htons(TCP_SERVER_PORT); + netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); + /* + * try a few times to bind server's address, if addresses are in + * use + */ + i = 0; + while (PR_Bind(sockfd, &netaddr) < 0) { + if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { + netaddr.inet.port += 2; + if (i++ < SERVER_MAX_BIND_COUNT) + continue; + } + fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); + failed_already=1; + perror("PR_Bind"); + goto exit; + } + + if (PR_Listen(sockfd, 32) < 0) { + fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); + failed_already=1; + goto exit; + } + + if (PR_GetSockName(sockfd, &netaddr) < 0) { + fprintf(stderr, + "prsocket_test: ERROR - PR_GetSockName failed\n"); + failed_already=1; + goto exit; + } + + DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", + netaddr.inet.ip, netaddr.inet.port)); + tcp_server_addr.inet.family = netaddr.inet.family; + tcp_server_addr.inet.port = netaddr.inet.port; + tcp_server_addr.inet.ip = netaddr.inet.ip; + + /* + * Wake up parent thread because server address is bound and made + * available in the global variable 'tcp_server_addr' + */ + PR_PostSem(sp->addr_sem); + + for (i = 0; i < num_transmitfile_clients ; i++) { + /* test both null and non-null 'addr' argument to PR_Accept */ + PRNetAddr *addrp = (i%2 ? &netaddr: NULL); + + if ((newsockfd = PR_Accept(sockfd, addrp, + PR_INTERVAL_NO_TIMEOUT)) == NULL) { + fprintf(stderr, + "prsocket_test: ERROR - PR_Accept failed\n"); + failed_already=1; + goto exit; + } + /* test both regular and emulated PR_SendFile */ + if (i%2) { + PRFileDesc *layer = PR_CreateIOLayerStub( + emuSendFileIdentity, &emuSendFileMethods); + if (layer == NULL) { + fprintf(stderr, + "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n"); + failed_already=1; + goto exit; + } + if (PR_PushIOLayer(newsockfd, PR_TOP_IO_LAYER, layer) + == PR_FAILURE) { + fprintf(stderr, + "prsocket_test: ERROR - PR_PushIOLayer failed\n"); + failed_already=1; + goto exit; + } + } + scp = PR_NEW(Serve_Client_Param); + if (scp == NULL) { + fprintf(stderr,"prsocket_test: PR_NEW failed\n"); + failed_already=1; + goto exit; + } + + /* + * Start a Serve_Client thread for each incoming connection + */ + scp->sockfd = newsockfd; + scp->datalen = sp->datalen; + + t[i] = PR_CreateThread(PR_USER_THREAD, + Serve_TransmitFile_Client, (void *)scp, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, + 0); + if (t[i] == NULL) { + fprintf(stderr, + "prsocket_test: PR_CreateThread failed\n"); + failed_already=1; + goto exit; + } + DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t)); + } + + /* + * Wait for all the worker threads to end, so that we know + * they are no longer using the small and large file fd's. + */ + + for (i = 0; i < num_transmitfile_clients; i++) { + PR_JoinThread(t[i]); + } + +exit: + if (t) { + PR_DELETE(t); + } + if (sockfd) { + PR_Close(sockfd); + } + + /* + * Decrement exit_counter and notify parent thread + */ + + PR_EnterMonitor(sp->exit_mon); + --(*sp->exit_counter); + PR_Notify(sp->exit_mon); + PR_ExitMonitor(sp->exit_mon); + DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread())); +} + +/* + * Socket_Misc_Test - test miscellaneous functions + * + */ +static PRInt32 +Socket_Misc_Test(void) +{ + PRIntn i, rv = 0, bytes, count, len; + PRThread *t; + PRSemaphore *server_sem; + Server_Param *sparamp; + Client_Param *cparamp; + PRMonitor *mon2; + PRInt32 datalen; + + /* + * We deliberately pick a buffer size that is not a nice multiple + * of 1024. + */ +#define TRANSMITFILE_BUF_SIZE (4 * 1024 - 11) + + typedef struct { + char data[TRANSMITFILE_BUF_SIZE]; + } file_buf; + file_buf *buf = NULL; + + /* + * create file(s) to be transmitted + */ + if ((PR_MkDir(TEST_DIR, 0777)) < 0) { + printf("prsocket_test failed to create dir %s\n",TEST_DIR); + failed_already=1; + return -1; + } + + small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777); + + if (small_file_fd == NULL) { + fprintf(stderr,"prsocket_test failed to create/open file %s\n", + SMALL_FILE_NAME); + failed_already=1; + rv = -1; + goto done; + } + buf = PR_NEW(file_buf); + if (buf == NULL) { + fprintf(stderr,"prsocket_test failed to allocate buffer\n"); + failed_already=1; + rv = -1; + goto done; + } + /* + * fill in random data + */ + for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) { + buf->data[i] = i; + } + count = 0; + do { + len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ? + TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count); + bytes = PR_Write(small_file_fd, buf->data, len); + if (bytes <= 0) { + fprintf(stderr, + "prsocket_test failed to write to file %s\n", + SMALL_FILE_NAME); + failed_already=1; + rv = -1; + goto done; + } + count += bytes; + } while (count < SMALL_FILE_SIZE); +#ifdef XP_UNIX + /* + * map the small file; used in checking for data corruption + */ + small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ, + MAP_SHARED, small_file_fd->secret->md.osfd, 0); + if (small_file_addr == (void *) -1) { + fprintf(stderr,"prsocket_test failed to mmap file %s\n", + SMALL_FILE_NAME); + failed_already=1; + rv = -1; + goto done; + } +#endif + /* + * header for small file + */ + small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE); + if (small_file_header == NULL) { + fprintf(stderr,"prsocket_test failed to malloc header file\n"); + failed_already=1; + rv = -1; + goto done; + } + memset(small_file_header, (int) PR_IntervalNow(), + SMALL_FILE_HEADER_SIZE); + /* + * trailer for small file + */ + small_file_trailer = PR_MALLOC(SMALL_FILE_TRAILER_SIZE); + if (small_file_trailer == NULL) { + fprintf(stderr,"prsocket_test failed to malloc header trailer\n"); + failed_already=1; + rv = -1; + goto done; + } + memset(small_file_trailer, (int) PR_IntervalNow(), + SMALL_FILE_TRAILER_SIZE); + /* + * setup large file + */ + large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777); + + if (large_file_fd == NULL) { + fprintf(stderr,"prsocket_test failed to create/open file %s\n", + LARGE_FILE_NAME); + failed_already=1; + rv = -1; + goto done; + } + /* + * fill in random data + */ + for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) { + buf->data[i] = i; + } + count = 0; + do { + len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ? + TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count); + bytes = PR_Write(large_file_fd, buf->data, len); + if (bytes <= 0) { + fprintf(stderr, + "prsocket_test failed to write to file %s: (%ld, %ld)\n", + LARGE_FILE_NAME, + PR_GetError(), PR_GetOSError()); + failed_already=1; + rv = -1; + goto done; + } + count += bytes; + } while (count < LARGE_FILE_SIZE); +#if defined(XP_UNIX) && !defined(SYMBIAN) + /* + * map the large file; used in checking for data corruption + */ + large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ, + MAP_SHARED, large_file_fd->secret->md.osfd, 0); + if (large_file_addr == (void *) -1) { + fprintf(stderr,"prsocket_test failed to mmap file %s\n", + LARGE_FILE_NAME); + failed_already=1; + rv = -1; + goto done; + } +#endif + /* + * header for large file + */ + large_file_header = PR_MALLOC(LARGE_FILE_HEADER_SIZE); + if (large_file_header == NULL) { + fprintf(stderr,"prsocket_test failed to malloc header file\n"); + failed_already=1; + rv = -1; + goto done; + } + memset(large_file_header, (int) PR_IntervalNow(), + LARGE_FILE_HEADER_SIZE); + /* + * trailer for large file + */ + large_file_trailer = PR_MALLOC(LARGE_FILE_TRAILER_SIZE); + if (large_file_trailer == NULL) { + fprintf(stderr,"prsocket_test failed to malloc header trailer\n"); + failed_already=1; + rv = -1; + goto done; + } + memset(large_file_trailer, (int) PR_IntervalNow(), + LARGE_FILE_TRAILER_SIZE); + + datalen = tcp_mesg_size; + thread_count = 0; + /* + * start the server thread + */ + sparamp = PR_NEW(Server_Param); + if (sparamp == NULL) { + fprintf(stderr,"prsocket_test: PR_NEW failed\n"); + failed_already=1; + rv = -1; + goto done; + } + server_sem = PR_NewSem(0); + if (server_sem == NULL) { + fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); + failed_already=1; + rv = -1; + goto done; + } + mon2 = PR_NewMonitor(); + if (mon2 == NULL) { + fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); + failed_already=1; + rv = -1; + goto done; + } + PR_EnterMonitor(mon2); + + sparamp->addr_sem = server_sem; + sparamp->exit_mon = mon2; + sparamp->exit_counter = &thread_count; + sparamp->datalen = datalen; + t = PR_CreateThread(PR_USER_THREAD, + TransmitFile_Server, (void *)sparamp, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0); + if (t == NULL) { + fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); + failed_already=1; + rv = -1; + goto done; + } + DPRINTF(("Created TCP server = 0x%x\n", t)); + thread_count++; + + /* + * wait till the server address is setup + */ + PR_WaitSem(server_sem); + + /* + * Now start a bunch of client threads + */ + + cparamp = PR_NEW(Client_Param); + if (cparamp == NULL) { + fprintf(stderr,"prsocket_test: PR_NEW failed\n"); + failed_already=1; + rv = -1; + goto done; + } + cparamp->server_addr = tcp_server_addr; + cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + cparamp->exit_mon = mon2; + cparamp->exit_counter = &thread_count; + cparamp->datalen = datalen; + for (i = 0; i < num_transmitfile_clients; i++) { + t = create_new_thread(PR_USER_THREAD, + TransmitFile_Client, (void *) cparamp, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0, i); + if (t == NULL) { + fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); + rv = -1; + failed_already=1; + goto done; + } + DPRINTF(("Created TransmitFile client = 0x%lx\n", t)); + thread_count++; + } + /* Wait for server and client threads to exit */ + while (thread_count) { + PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); + DPRINTF(("Socket_Misc_Test - thread_count = %d\n", thread_count)); + } + PR_ExitMonitor(mon2); +done: + if (buf) { + PR_DELETE(buf); + } +#if defined(XP_UNIX) && !defined(SYMBIAN) + munmap((char*)small_file_addr, SMALL_FILE_SIZE); + munmap((char*)large_file_addr, LARGE_FILE_SIZE); +#endif + PR_Close(small_file_fd); + PR_Close(large_file_fd); + if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) { + fprintf(stderr,"prsocket_test: failed to unlink file %s\n", + SMALL_FILE_NAME); + failed_already=1; + } + if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) { + fprintf(stderr,"prsocket_test: failed to unlink file %s\n", + LARGE_FILE_NAME); + failed_already=1; + } + if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) { + fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + failed_already=1; + } + + printf("%-29s%s","Socket_Misc_Test",":"); + printf("%2d Server %2d Clients\n",1, num_transmitfile_clients); + printf("%30s Sizes of Transmitted Files - %4d KB, %2d MB \n",":", + SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024)); + + + return rv; +} +/************************************************************************/ + +/* + * Test Socket NSPR APIs + */ + +int main(int argc, char **argv) +{ + /* + * -d debug mode + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + PR_SetConcurrency(4); + + emuSendFileIdentity = PR_GetUniqueIdentity("Emulated SendFile"); + emuSendFileMethods = *PR_GetDefaultIOMethods(); + emuSendFileMethods.transmitfile = emu_TransmitFile; + emuSendFileMethods.sendfile = emu_SendFile; + + /* + * run client-server test with TCP, Ipv4-Ipv4 + */ + printf("TCP Client/Server Test - IPv4/Ipv4\n"); + if (TCP_Socket_Client_Server_Test() < 0) { + printf("TCP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("TCP_Socket_Client_Server_Test Passed\n"); + /* + * client-server test, Ipv6-Ipv4 + */ + client_domain = PR_AF_INET6; + printf("TCP Client/Server Test - IPv6/Ipv4\n"); + if (TCP_Socket_Client_Server_Test() < 0) { + printf("TCP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("TCP_Socket_Client_Server_Test Passed\n"); + /* + * client-server test, Ipv4-Ipv6 + */ + client_domain = PR_AF_INET; + server_domain = PR_AF_INET6; + printf("TCP Client/Server Test - IPv4/Ipv6\n"); + if (TCP_Socket_Client_Server_Test() < 0) { + printf("TCP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("TCP_Socket_Client_Server_Test Passed\n"); + /* + * client-server test, Ipv6-Ipv6 + */ + client_domain = PR_AF_INET6; + server_domain = PR_AF_INET6; + printf("TCP Client/Server Test - IPv6/Ipv6\n"); + if (TCP_Socket_Client_Server_Test() < 0) { + printf("TCP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("TCP_Socket_Client_Server_Test Passed\n"); + test_cancelio = 0; + +#if defined(SYMBIAN) && !defined(__WINSCW__) + /* UDP tests only run on Symbian devices but not emulator */ + /* + * run client-server test with UDP, IPv4/IPv4 + */ + printf("UDP Client/Server Test - IPv4/Ipv4\n"); + client_domain = PR_AF_INET; + server_domain = PR_AF_INET; + if (UDP_Socket_Client_Server_Test() < 0) { + printf("UDP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("UDP_Socket_Client_Server_Test Passed\n"); + /* + * run client-server test with UDP, IPv6/IPv4 + */ + printf("UDP Client/Server Test - IPv6/Ipv4\n"); + client_domain = PR_AF_INET6; + server_domain = PR_AF_INET; + if (UDP_Socket_Client_Server_Test() < 0) { + printf("UDP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("UDP_Socket_Client_Server_Test Passed\n"); + /* + * run client-server test with UDP,IPv4-IPv6 + */ + printf("UDP Client/Server Test - IPv4/Ipv6\n"); + client_domain = PR_AF_INET; + server_domain = PR_AF_INET6; + if (UDP_Socket_Client_Server_Test() < 0) { + printf("UDP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("UDP_Socket_Client_Server_Test Passed\n"); + /* + * run client-server test with UDP,IPv6-IPv6 + */ + printf("UDP Client/Server Test - IPv6/Ipv6\n"); + client_domain = PR_AF_INET6; + server_domain = PR_AF_INET6; + if (UDP_Socket_Client_Server_Test() < 0) { + printf("UDP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("UDP_Socket_Client_Server_Test Passed\n"); +#endif + + /* + * Misc socket tests - including transmitfile, etc. + */ + + /* File transmission test can not be done in Symbian OS because of + * large file's size and the incomplete mmap() implementation. */ +#if !defined(WIN16) && !defined(SYMBIAN) + /* +** The 'transmit file' test does not run because +** transmit file is not implemented in NSPR yet. +** +*/ + if (Socket_Misc_Test() < 0) { + printf("Socket_Misc_Test failed\n"); + failed_already=1; + goto done; + } else + printf("Socket_Misc_Test passed\n"); + + /* + * run client-server test with TCP again to test + * recycling used sockets from PR_TransmitFile(). + */ + if (TCP_Socket_Client_Server_Test() < 0) { + printf("TCP_Socket_Client_Server_Test failed\n"); + goto done; + } else + printf("TCP_Socket_Client_Server_Test Passed\n"); +#endif + +done: + PR_Cleanup(); + if (failed_already) return 1; + else return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/sockopt.c nspr-4.10.7/nspr/pr/tests/sockopt.c --- nspr-4.9.5/nspr/pr/tests/sockopt.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sockopt.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "prio.h" +#include "prinit.h" +#include "prprf.h" +#include "obsolete/probslet.h" + +#include "plerror.h" + +#ifdef XP_UNIX +#include /* SO_REUSEPORT */ +#endif + +static PRFileDesc *err = NULL; +static PRBool failed = PR_FALSE; + +static void Failed(const char *msg1, const char *msg2) +{ + if (NULL != msg1) PR_fprintf(err, "%s ", msg1); + PL_FPrintError(err, msg2); + failed = PR_TRUE; +} /* Failed */ + +static PRSockOption Incr(PRSockOption *option) +{ + PRIntn val = ((PRIntn)*option) + 1; + *option = (PRSockOption)val; + return (PRSockOption)val; +} /* Incr */ + +int main(int argc, char **argv) +{ + PRStatus rv; + PRFileDesc *udp = PR_NewUDPSocket(); + PRFileDesc *tcp = PR_NewTCPSocket(); + const char *tag[] = + { + "PR_SockOpt_Nonblocking", /* nonblocking io */ + "PR_SockOpt_Linger", /* linger on close if data present */ + "PR_SockOpt_Reuseaddr", /* allow local address reuse */ + "PR_SockOpt_Keepalive", /* keep connections alive */ + "PR_SockOpt_RecvBufferSize", /* send buffer size */ + "PR_SockOpt_SendBufferSize", /* receive buffer size */ + + "PR_SockOpt_IpTimeToLive", /* time to live */ + "PR_SockOpt_IpTypeOfService", /* type of service and precedence */ + + "PR_SockOpt_AddMember", /* add an IP group membership */ + "PR_SockOpt_DropMember", /* drop an IP group membership */ + "PR_SockOpt_McastInterface", /* multicast interface address */ + "PR_SockOpt_McastTimeToLive", /* multicast timetolive */ + "PR_SockOpt_McastLoopback", /* multicast loopback */ + + "PR_SockOpt_NoDelay", /* don't delay send to coalesce packets */ + "PR_SockOpt_MaxSegment", /* maximum segment size */ + "PR_SockOpt_Broadcast", /* Enable broadcast */ + "PR_SockOpt_Reuseport", /* allow local address & port reuse */ + "PR_SockOpt_Last" + }; + + err = PR_GetSpecialFD(PR_StandardError); + PR_STDIO_INIT(); + + if (NULL == udp) Failed("PR_NewUDPSocket()", NULL); + else if (NULL == tcp) Failed("PR_NewTCPSocket()", NULL); + else + { + PRSockOption option; + PRUint32 segment = 1024; + PRNetAddr addr; + + rv = PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr); + if (PR_FAILURE == rv) Failed("PR_InitializeNetAddr()", NULL); + rv = PR_Bind(udp, &addr); + if (PR_FAILURE == rv) Failed("PR_Bind()", NULL); + for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option)) + { + PRSocketOptionData data; + PRFileDesc *fd = tcp; + data.option = option; + switch (option) + { + case PR_SockOpt_Nonblocking: + data.value.non_blocking = PR_TRUE; + break; +#ifndef SYMBIAN + case PR_SockOpt_Linger: + data.value.linger.polarity = PR_TRUE; + data.value.linger.linger = PR_SecondsToInterval(2); + break; +#endif + case PR_SockOpt_Reuseaddr: + data.value.reuse_addr = PR_TRUE; + break; + case PR_SockOpt_Keepalive: + data.value.keep_alive = PR_TRUE; + break; + case PR_SockOpt_RecvBufferSize: + data.value.recv_buffer_size = segment; + break; + case PR_SockOpt_SendBufferSize: + data.value.send_buffer_size = segment; + break; +#ifndef SYMBIAN + case PR_SockOpt_IpTimeToLive: + data.value.ip_ttl = 64; + break; + case PR_SockOpt_IpTypeOfService: + data.value.tos = 0; + break; + case PR_SockOpt_McastTimeToLive: + fd = udp; + data.value.mcast_ttl = 4; + break; + case PR_SockOpt_McastLoopback: + fd = udp; + data.value.mcast_loopback = PR_TRUE; + break; +#endif + case PR_SockOpt_NoDelay: + data.value.no_delay = PR_TRUE; + break; +#ifndef WIN32 + case PR_SockOpt_MaxSegment: + data.value.max_segment = segment; + break; +#endif +#ifndef SYMBIAN + case PR_SockOpt_Broadcast: + fd = udp; + data.value.broadcast = PR_TRUE; + break; +#endif +#ifdef SO_REUSEPORT + case PR_SockOpt_Reuseport: + data.value.reuse_port = PR_TRUE; + break; +#endif + default: continue; + } + + /* + * TCP_MAXSEG can only be read, not set + */ + if (option != PR_SockOpt_MaxSegment) { +#ifdef WIN32 + if (option != PR_SockOpt_McastLoopback) +#endif + { + rv = PR_SetSocketOption(fd, &data); + if (PR_FAILURE == rv) + Failed("PR_SetSocketOption()", tag[option]); + } + } + + rv = PR_GetSocketOption(fd, &data); + if (PR_FAILURE == rv) Failed("PR_GetSocketOption()", tag[option]); + } + PR_Close(udp); + PR_Close(tcp); + } + PR_fprintf(err, "%s\n", (failed) ? "FAILED" : "PASSED"); + return (failed) ? 1 : 0; +} /* main */ + +/* sockopt.c */ + diff -Nru nspr-4.9.5/nspr/pr/tests/sockping.c nspr-4.10.7/nspr/pr/tests/sockping.c --- nspr-4.9.5/nspr/pr/tests/sockping.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sockping.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: sockping.c + * + * Description: + * This test runs in conjunction with the sockpong test. + * This test creates a socket pair and passes one socket + * to the sockpong test. Then this test writes "ping" to + * to the sockpong test and the sockpong test writes "pong" + * back. To run this pair of tests, just invoke sockping. + * + * Tested areas: process creation, socket pairs, file + * descriptor inheritance. + */ + +#include "prerror.h" +#include "prio.h" +#include "prproces.h" + +#include +#include +#include + +#define NUM_ITERATIONS 10 + +static char *child_argv[] = { "sockpong", NULL }; + +int main(int argc, char **argv) +{ + PRFileDesc *sock[2]; + PRStatus status; + PRProcess *process; + PRProcessAttr *attr; + char buf[1024]; + PRInt32 nBytes; + PRInt32 exitCode; + int idx; + + status = PR_NewTCPSocketPair(sock); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_NewTCPSocketPair failed\n"); + exit(1); + } + + status = PR_SetFDInheritable(sock[0], PR_FALSE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + status = PR_SetFDInheritable(sock[1], PR_TRUE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + + attr = PR_NewProcessAttr(); + if (attr == NULL) { + fprintf(stderr, "PR_NewProcessAttr failed\n"); + exit(1); + } + + status = PR_ProcessAttrSetInheritableFD(attr, sock[1], "SOCKET"); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n"); + exit(1); + } + + process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr); + if (process == NULL) { + fprintf(stderr, "PR_CreateProcess failed\n"); + exit(1); + } + PR_DestroyProcessAttr(attr); + status = PR_Close(sock[1]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + + for (idx = 0; idx < NUM_ITERATIONS; idx++) { + strcpy(buf, "ping"); + printf("ping process: sending \"%s\"\n", buf); + nBytes = PR_Write(sock[0], buf, 5); + if (nBytes == -1) { + fprintf(stderr, "PR_Write failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + memset(buf, 0, sizeof(buf)); + nBytes = PR_Read(sock[0], buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + printf("ping process: received \"%s\"\n", buf); + if (nBytes != 5) { + fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n", + nBytes); + exit(1); + } + if (strcmp(buf, "pong") != 0) { + fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", + buf); + exit(1); + } + } + + status = PR_Close(sock[0]); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + status = PR_WaitProcess(process, &exitCode); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_WaitProcess failed\n"); + exit(1); + } + if (exitCode == 0) { + printf("PASS\n"); + return 0; + } else { + printf("FAIL\n"); + return 1; + } +} diff -Nru nspr-4.9.5/nspr/pr/tests/sockpong.c nspr-4.10.7/nspr/pr/tests/sockpong.c --- nspr-4.9.5/nspr/pr/tests/sockpong.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sockpong.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: sockpong.c + * + * Description: + * This test runs in conjunction with the sockping test. + * The sockping test creates a socket pair and passes one + * socket to this test. Then the sockping test writes + * "ping" to this test and this test writes "pong" back. + * To run this pair of tests, just invoke sockping. + * + * Tested areas: process creation, socket pairs, file + * descriptor inheritance. + */ + +#include "prerror.h" +#include "prio.h" + +#include +#include +#include + +#define NUM_ITERATIONS 10 + +int main(int argc, char **argv) +{ + PRFileDesc *sock; + PRStatus status; + char buf[1024]; + PRInt32 nBytes; + int idx; + + sock = PR_GetInheritedFD("SOCKET"); + if (sock == NULL) { + fprintf(stderr, "PR_GetInheritedFD failed\n"); + exit(1); + } + status = PR_SetFDInheritable(sock, PR_FALSE); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_SetFDInheritable failed\n"); + exit(1); + } + + for (idx = 0; idx < NUM_ITERATIONS; idx++) { + memset(buf, 0, sizeof(buf)); + nBytes = PR_Read(sock, buf, sizeof(buf)); + if (nBytes == -1) { + fprintf(stderr, "PR_Read failed: (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + exit(1); + } + printf("pong process: received \"%s\"\n", buf); + if (nBytes != 5) { + fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n", + nBytes); + exit(1); + } + if (strcmp(buf, "ping") != 0) { + fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n", + buf); + exit(1); + } + + strcpy(buf, "pong"); + printf("pong process: sending \"%s\"\n", buf); + nBytes = PR_Write(sock, buf, 5); + if (nBytes == -1) { + fprintf(stderr, "PR_Write failed\n"); + exit(1); + } + } + + status = PR_Close(sock); + if (status == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/sprintf.c nspr-4.10.7/nspr/pr/tests/sprintf.c --- nspr-4.9.5/nspr/pr/tests/sprintf.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sprintf.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,431 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: sprintf.c + * Description: + * This is a test program for the PR_snprintf() functions defined + * in prprf.c. This test program is based on ns/nspr/tests/sprintf.c, + * revision 1.10. + * Modification History: + * 20-May-1997 AGarcia replaced printf statment to return PASS\n. This is to be used by the + * regress tool parsing routine. + ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to + * recognize the return code from tha main program. + */ + +#include "prinit.h" +#include "prprf.h" +#include "prlog.h" +#include "prlong.h" +#include +#include +#include + +static char sbuf[20000]; + + +/* +** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf. +** Make sure the results are identical +*/ +static void test_i(char *pattern, int i) +{ + char *s; + char buf[200]; + int n; + + /* try all three routines */ + s = PR_smprintf(pattern, i); + PR_ASSERT(s != 0); + n = PR_snprintf(buf, sizeof(buf), pattern, i); + PR_ASSERT(n <= sizeof(buf)); + sprintf(sbuf, pattern, i); + + /* compare results */ + if ((strncmp(s, buf, sizeof(buf)) != 0) || + (strncmp(s, sbuf, sizeof(sbuf)) != 0)) { + fprintf(stderr, + "pattern='%s' i=%d\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", + pattern, i, s, buf, sbuf); + PR_smprintf_free(s); + exit(-1); + } + PR_smprintf_free(s); +} + +static void TestI(void) +{ + static int nums[] = { + 0, 1, -1, 10, -10, + 32767, -32768, + }; + static char *signs[] = { + "", + "0", "-", "+", " ", + "0-", "0+", "0 ", "-0", "-+", "- ", + "+0", "+-", "+ ", " 0", " -", " +", + "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +", + "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +", + "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -", + " 0-", " 0+", " -0", " -+", " +0", " +-", + "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-", + "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0", + "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0", + " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0", + }; + static char *precs[] = { + "", "3", "5", "43", + "7.3", "7.5", "7.11", "7.43", + }; + static char *formats[] = { + "d", "o", "x", "u", + "hd", "ho", "hx", "hu" + }; + int f, s, n, p; + char fmt[20]; + + for (f = 0; f < PR_ARRAY_SIZE(formats); f++) { + for (s = 0; s < PR_ARRAY_SIZE(signs); s++) { + for (p = 0; p < PR_ARRAY_SIZE(precs); p++) { + fmt[0] = '%'; + fmt[1] = 0; + if (signs[s]) strcat(fmt, signs[s]); + if (precs[p]) strcat(fmt, precs[p]); + if (formats[f]) strcat(fmt, formats[f]); + for (n = 0; n < PR_ARRAY_SIZE(nums); n++) { + test_i(fmt, nums[n]); + } + } + } + } +} + +/************************************************************************/ + +/* +** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf. +** Make sure the results are identical +*/ +static void test_l(char *pattern, char *spattern, PRInt32 l) +{ + char *s; + char buf[200]; + int n; + + /* try all three routines */ + s = PR_smprintf(pattern, l); + PR_ASSERT(s != 0); + n = PR_snprintf(buf, sizeof(buf), pattern, l); + PR_ASSERT(n <= sizeof(buf)); + sprintf(sbuf, spattern, l); + + /* compare results */ + if ((strncmp(s, buf, sizeof(buf)) != 0) || + (strncmp(s, sbuf, sizeof(sbuf)) != 0)) { + fprintf(stderr, + "pattern='%s' l=%ld\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", + pattern, l, s, buf, sbuf); + PR_smprintf_free(s); + exit(-1); + } + PR_smprintf_free(s); +} + +static void TestL(void) +{ + static PRInt32 nums[] = { + 0, + 1, + -1, + 10, + -10, + 32767, + -32768, + PR_INT32(0x7fffffff), /* 2147483647L */ + -1 - PR_INT32(0x7fffffff) /* -2147483648L */ + }; + static char *signs[] = { + "", + "0", "-", "+", " ", + "0-", "0+", "0 ", "-0", "-+", "- ", + "+0", "+-", "+ ", " 0", " -", " +", + "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +", + "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +", + "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -", + " 0-", " 0+", " -0", " -+", " +0", " +-", + "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-", + "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0", + "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0", + " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0", + }; + static char *precs[] = { + "", "3", "5", "43", + ".3", ".43", + "7.3", "7.5", "7.11", "7.43", + }; + static char *formats[] = { "ld", "lo", "lx", "lu" }; + +#if PR_BYTES_PER_INT == 4 + static char *sformats[] = { "d", "o", "x", "u" }; +#elif PR_BYTES_PER_LONG == 4 + static char *sformats[] = { "ld", "lo", "lx", "lu" }; +#else +#error Neither int nor long is 4 bytes on this platform +#endif + + int f, s, n, p; + char fmt[40], sfmt[40]; + + for (f = 0; f < PR_ARRAY_SIZE(formats); f++) { + for (s = 0; s < PR_ARRAY_SIZE(signs); s++) { + for (p = 0; p < PR_ARRAY_SIZE(precs); p++) { + fmt[0] = '%'; + fmt[1] = 0; + if (signs[s]) strcat(fmt, signs[s]); + if (precs[p]) strcat(fmt, precs[p]); + strcpy(sfmt, fmt); + if (formats[f]) strcat(fmt, formats[f]); + if (sformats[f]) strcat(sfmt, sformats[f]); + for (n = 0; n < PR_ARRAY_SIZE(nums); n++) { + test_l(fmt, sfmt, nums[n]); + } + } + } + } +} + +/************************************************************************/ + +/* +** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf. +** Make sure the results are identical +*/ +static void test_ll(char *pattern, char *spattern, PRInt64 l) +{ + char *s; + char buf[200]; + int n; + + /* try all three routines */ + s = PR_smprintf(pattern, l); + PR_ASSERT(s != 0); + n = PR_snprintf(buf, sizeof(buf), pattern, l); + PR_ASSERT(n <= sizeof(buf)); +#if defined(HAVE_LONG_LONG) + sprintf(sbuf, spattern, l); + + /* compare results */ + if ((strncmp(s, buf, sizeof(buf)) != 0) || + (strncmp(s, sbuf, sizeof(sbuf)) != 0)) { +#if PR_BYTES_PER_LONG == 8 +#define FORMAT_SPEC "%ld" +#elif defined(WIN16) +#define FORMAT_SPEC "%Ld" +#elif defined(WIN32) +#define FORMAT_SPEC "%I64d" +#else +#define FORMAT_SPEC "%lld" +#endif + fprintf(stderr, + "pattern='%s' ll=" FORMAT_SPEC "\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", + pattern, l, s, buf, sbuf); + printf("FAIL\n"); + PR_smprintf_free(s); + exit(-1); + } + PR_smprintf_free(s); +#else + /* compare results */ + if ((strncmp(s, buf, sizeof(buf)) != 0)) { + fprintf(stderr, + "pattern='%s'\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", + pattern, s, buf, sbuf); + printf("FAIL\n"); + PR_smprintf_free(s); + exit(-1); + } + PR_smprintf_free(s); +#endif +} + +static void TestLL(void) +{ + static PRInt64 nums[] = { + LL_INIT(0, 0), + LL_INIT(0, 1), + LL_INIT(0xffffffff, 0xffffffff), /* -1 */ + LL_INIT(0, 10), + LL_INIT(0xffffffff, 0xfffffff6), /* -10 */ + LL_INIT(0, 32767), + LL_INIT(0xffffffff, 0xffff8000), /* -32768 */ + LL_INIT(0, 0x7fffffff), /* 2147483647 */ + LL_INIT(0xffffffff, 0x80000000), /* -2147483648 */ + LL_INIT(0x7fffffff, 0xffffffff), /* 9223372036854775807 */ + LL_INIT(0x80000000, 0), /* -9223372036854775808 */ + PR_INT64(0), + PR_INT64(1), + PR_INT64(-1), + PR_INT64(10), + PR_INT64(-10), + PR_INT64(32767), + PR_INT64(-32768), + PR_INT64(2147483647), + PR_INT64(-2147483648), + PR_INT64(9223372036854775807), + PR_INT64(-9223372036854775808) + }; + + static char *signs[] = { + "", + "0", "-", "+", " ", + "0-", "0+", "0 ", "-0", "-+", "- ", + "+0", "+-", "+ ", " 0", " -", " +", + "0-+", "0- ", "0+-", "0+ ", "0 -", "0 +", + "-0+", "-0 ", "-+0", "-+ ", "- 0", "- +", + "+0-", "+0 ", "+-0", "+- ", "+ 0", "+ -", + " 0-", " 0+", " -0", " -+", " +0", " +-", + "0-+ ", "0- +", "0+- ", "0+ -", "0 -+", "0 +-", + "-0+ ", "-0 +", "-+0 ", "-+ 0", "- 0+", "- +0", + "+0- ", "+0 -", "+-0 ", "+- 0", "+ 0-", "+ -0", + " 0-+", " 0+-", " -0+", " -+0", " +0-", " +-0", + }; + static char *precs[] = { + "", "3", "5", "43", + ".3", ".43", + "7.3", "7.5", "7.11", "7.43", + }; + static char *formats[] = { "lld", "llo", "llx", "llu" }; + +#if PR_BYTES_PER_LONG == 8 + static char *sformats[] = { "ld", "lo", "lx", "lu" }; +#elif defined(WIN16) + /* Watcom uses the format string "%Ld" instead of "%lld". */ + static char *sformats[] = { "Ld", "Lo", "Lx", "Lu" }; +#elif defined(WIN32) + static char *sformats[] = { "I64d", "I64o", "I64x", "I64u" }; +#else + static char *sformats[] = { "lld", "llo", "llx", "llu" }; +#endif + + int f, s, n, p; + char fmt[40], sfmt[40]; + + for (f = 0; f < PR_ARRAY_SIZE(formats); f++) { + for (s = 0; s < PR_ARRAY_SIZE(signs); s++) { + for (p = 0; p < PR_ARRAY_SIZE(precs); p++) { + fmt[0] = '%'; + fmt[1] = 0; + if (signs[s]) strcat(fmt, signs[s]); + if (precs[p]) strcat(fmt, precs[p]); + strcpy(sfmt, fmt); + if (formats[f]) strcat(fmt, formats[f]); + if (sformats[f]) strcat(sfmt, sformats[f]); + for (n = 0; n < PR_ARRAY_SIZE(nums); n++) { + test_ll(fmt, sfmt, nums[n]); + } + } + } + } +} + +/************************************************************************/ + +/* +** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf. +** Make sure the results are identical +*/ +static void test_s(char *pattern, char *ss) +{ + char *s; + unsigned char before[8]; + char buf[200]; + unsigned char after[8]; + int n; + + memset(before, 0xBB, 8); + memset(after, 0xAA, 8); + + /* try all three routines */ + s = PR_smprintf(pattern, ss); + PR_ASSERT(s != 0); + n = PR_snprintf(buf, sizeof(buf), pattern, ss); + PR_ASSERT(n <= sizeof(buf)); + sprintf(sbuf, pattern, ss); + + for (n = 0; n < 8; n++) { + PR_ASSERT(before[n] == 0xBB); + PR_ASSERT(after[n] == 0xAA); + } + + /* compare results */ + if ((strncmp(s, buf, sizeof(buf)) != 0) || + (strncmp(s, sbuf, sizeof(sbuf)) != 0)) { + fprintf(stderr, + "pattern='%s' ss=%.20s\nPR_smprintf='%s'\nPR_snprintf='%s'\n sprintf='%s'\n", + pattern, ss, s, buf, sbuf); + printf("FAIL\n"); + PR_smprintf_free(s); + exit(-1); + } + PR_smprintf_free(s); +} + +static void TestS(void) +{ + static char *strs[] = { + "", + "a", + "abc", + "abcde", + "abcdefABCDEF", + "abcdefghijklmnopqrstuvwxyz0123456789!@#$" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$" + "abcdefghijklmnopqrstuvwxyz0123456789!@#$", + }; + /* '0' is not relevant to printing strings */ + static char *signs[] = { + "", + "-", "+", " ", + "-+", "- ", "+-", "+ ", " -", " +", + "-+ ", "- +", "+- ", "+ -", " -+", " +-", + }; + static char *precs[] = { + "", "3", "5", "43", + ".3", ".43", + "7.3", "7.5", "7.11", "7.43", + }; + static char *formats[] = { "s" }; + int f, s, n, p; + char fmt[40]; + + for (f = 0; f < PR_ARRAY_SIZE(formats); f++) { + for (s = 0; s < PR_ARRAY_SIZE(signs); s++) { + for (p = 0; p < PR_ARRAY_SIZE(precs); p++) { + fmt[0] = '%'; + fmt[1] = 0; + if (signs[s]) strcat(fmt+strlen(fmt), signs[s]); + if (precs[p]) strcat(fmt+strlen(fmt), precs[p]); + if (formats[f]) strcat(fmt+strlen(fmt), formats[f]); + for (n = 0; n < PR_ARRAY_SIZE(strs); n++) { + test_s(fmt, strs[n]); + } + } + } + } +} + +/************************************************************************/ + +int main(int argc, char **argv) +{ + PR_STDIO_INIT(); + TestI(); + TestL(); + TestLL(); + TestS(); + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/sproc_ch.c nspr-4.10.7/nspr/pr/tests/sproc_ch.c --- nspr-4.9.5/nspr/pr/tests/sproc_ch.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sproc_ch.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test sproc_ch.c + * + * The purpose of this test and the sproc_p.c test is to test the shutdown + * of all the IRIX sprocs in a program when one of them dies due to an error. + * + * There are three sprocs in this test: the parent, the child, and the + * grandchild. The parent and child sprocs never stop on their own. + * The grandchild sproc gets a segmentation fault and dies. You should + * You should use "ps" to see if the parent and child sprocs are killed + * after the grandchild dies. + */ + +#include "prinit.h" +#include + +#if !defined(IRIX) + +int main(int argc, char **argv) +{ + printf("This test applies to IRIX only.\n"); + return 0; +} + +#else /* IRIX */ + +#include "prthread.h" +#include +#include + +void SegFault(void *unused) +{ + int *p = 0; + + printf("The grandchild sproc has pid %d.\n", getpid()); + printf("The grandchild sproc will get a segmentation fault and die.\n"); + printf("The parent and child sprocs should be killed after the " + "grandchild sproc dies.\n"); + printf("Use 'ps' to make sure this is so.\n"); + fflush(stdout); + /* Force a segmentation fault */ + *p = 0; +} + +void NeverStops(void *unused) +{ + int i = 0; + + printf("The child sproc has pid %d.\n", getpid()); + printf("The child sproc won't stop on its own.\n"); + fflush(stdout); + + /* create the grandchild sproc */ + PR_CreateThread(PR_USER_THREAD, SegFault, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); + + while (1) { + i++; + } +} + +int main() +{ + int i= 0; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + + printf("The parent sproc has pid %d.\n", getpid()); + printf("The parent sproc won't stop on its own.\n"); + fflush(stdout); + + /* create the child sproc */ + PR_CreateThread(PR_USER_THREAD, NeverStops, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); + + while (1) { + i++; + } + return 0; +} + +#endif /* IRIX */ diff -Nru nspr-4.9.5/nspr/pr/tests/sproc_p.c nspr-4.10.7/nspr/pr/tests/sproc_p.c --- nspr-4.9.5/nspr/pr/tests/sproc_p.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/sproc_p.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test sproc_p.c + * + * The purpose of this test and the sproc_ch.c test is to test the shutdown + * of all the IRIX sprocs in a program when one of them dies due to an error. + * + * In this test, the parent sproc gets a segmentation fault and dies. + * The child sproc never stops on its own. You should use "ps" to see if + * the child sproc is killed after the parent dies. + */ + +#include "prinit.h" +#include + +#if !defined(IRIX) + +int main(int argc, char **argv) +{ + printf("This test applies to IRIX only.\n"); + return 0; +} + +#else /* IRIX */ + +#include "prthread.h" +#include +#include + +void NeverStops(void *unused) +{ + int i = 0; + + printf("The child sproc has pid %d.\n", getpid()); + printf("The child sproc won't stop on its own.\n"); + fflush(stdout); + + /* I never stop */ + while (1) { + i++; + } +} + +int main() +{ + int *p = 0; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + + printf("The parent sproc has pid %d.\n", getpid()); + printf("The parent sproc will first create a child sproc.\n"); + printf("Then the parent sproc will get a segmentation fault and die.\n"); + printf("The child sproc should be killed after the parent sproc dies.\n"); + printf("Use 'ps' to make sure this is so.\n"); + fflush(stdout); + + PR_CreateThread(PR_USER_THREAD, NeverStops, NULL, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); + + /* Force a segmentation fault */ + *p = 0; + return 0; +} + +#endif /* IRIX */ diff -Nru nspr-4.9.5/nspr/pr/tests/stack.c nspr-4.10.7/nspr/pr/tests/stack.c --- nspr-4.9.5/nspr/pr/tests/stack.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/stack.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,280 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/* + * + * Test atomic stack operations + * + * Two stacks are created and threads add data items (each containing + * one of the first n integers) to the first stack, remove data items + * from the first stack and add them to the second stack. The primordial + * thread compares the sum of the first n integers to the sum of the + * integers in the data items in the second stack. The test succeeds if + * they are equal. + */ + +#include "nspr.h" +#include "plgetopt.h" + +typedef struct _DataRecord { + PRInt32 data; + PRStackElem link; +} DataRecord; + +#define RECORD_LINK_PTR(lp) ((DataRecord*) ((char*) (lp) - offsetof(DataRecord,link))) + +#define MAX_THREAD_CNT 100 +#define DEFAULT_THREAD_CNT 4 +#define DEFAULT_DATA_CNT 100 +#define DEFAULT_LOOP_CNT 10000 + +/* + * sum of the first n numbers using the formula n*(n+1)/2 + */ +#define SUM_OF_NUMBERS(n) ((n & 1) ? (((n + 1)/2) * n) : ((n/2) * (n+1))) + +typedef struct stack_data { + PRStack *list1; + PRStack *list2; + PRInt32 initial_data_value; + PRInt32 data_cnt; + PRInt32 loops; +} stack_data; + +static void stackop(void *arg); + +static int _debug_on; + +PRFileDesc *output; +PRFileDesc *errhandle; + +int main(int argc, char **argv) +{ +#if !(defined(SYMBIAN) && defined(__WINS__)) + PRInt32 rv, cnt, sum; + DataRecord *Item; + PRStack *list1, *list2; + PRStackElem *node; + PRStatus rc; + + PRInt32 thread_cnt = DEFAULT_THREAD_CNT; + PRInt32 data_cnt = DEFAULT_DATA_CNT; + PRInt32 loops = DEFAULT_LOOP_CNT; + PRThread **threads; + stack_data *thread_args; + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:l:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + case 't': /* thread count */ + thread_cnt = atoi(opt->value); + break; + case 'c': /* data count */ + data_cnt = atoi(opt->value); + break; + case 'l': /* loop count */ + loops = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_SetConcurrency(4); + + output = PR_GetSpecialFD(PR_StandardOutput); + errhandle = PR_GetSpecialFD(PR_StandardError); + list1 = PR_CreateStack("Stack_1"); + if (list1 == NULL) { + PR_fprintf(errhandle, "PR_CreateStack failed - error %d\n", + PR_GetError()); + return 1; + } + + list2 = PR_CreateStack("Stack_2"); + if (list2 == NULL) { + PR_fprintf(errhandle, "PR_CreateStack failed - error %d\n", + PR_GetError()); + return 1; + } + + + threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt); + thread_args = (stack_data *) PR_CALLOC(sizeof(stack_data) * thread_cnt); + + if (_debug_on) + PR_fprintf(output,"%s: thread_cnt = %d data_cnt = %d\n", argv[0], + thread_cnt, data_cnt); + for(cnt = 0; cnt < thread_cnt; cnt++) { + PRThreadScope scope; + + thread_args[cnt].list1 = list1; + thread_args[cnt].list2 = list2; + thread_args[cnt].loops = loops; + thread_args[cnt].data_cnt = data_cnt; + thread_args[cnt].initial_data_value = 1 + cnt * data_cnt; + + if (cnt & 1) + scope = PR_GLOBAL_THREAD; + else + scope = PR_LOCAL_THREAD; + + + threads[cnt] = PR_CreateThread(PR_USER_THREAD, + stackop, &thread_args[cnt], + PR_PRIORITY_NORMAL, + scope, + PR_JOINABLE_THREAD, + 0); + if (threads[cnt] == NULL) { + PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n", + PR_GetError()); + PR_ProcessExit(2); + } + if (_debug_on) + PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0], + threads[cnt]); + } + + for(cnt = 0; cnt < thread_cnt; cnt++) { + rc = PR_JoinThread(threads[cnt]); + PR_ASSERT(rc == PR_SUCCESS); + } + + node = PR_StackPop(list1); + /* + * list1 should be empty + */ + if (node != NULL) { + PR_fprintf(errhandle, "Error - Stack 1 not empty\n"); + PR_ASSERT(node == NULL); + PR_ProcessExit(4); + } + + cnt = data_cnt * thread_cnt; + sum = 0; + while (cnt-- > 0) { + node = PR_StackPop(list2); + /* + * There should be at least 'cnt' number of records + */ + if (node == NULL) { + PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n"); + PR_ProcessExit(3); + } + Item = RECORD_LINK_PTR(node); + sum += Item->data; + } + node = PR_StackPop(list2); + /* + * there should be exactly 'cnt' number of records + */ + if (node != NULL) { + PR_fprintf(errhandle, "Error - Stack 2 not empty\n"); + PR_ASSERT(node == NULL); + PR_ProcessExit(4); + } + PR_DELETE(threads); + PR_DELETE(thread_args); + + PR_DestroyStack(list1); + PR_DestroyStack(list2); + + if (sum == SUM_OF_NUMBERS(data_cnt * thread_cnt)) { + PR_fprintf(output, "%s successful\n", argv[0]); + PR_fprintf(output, "\t\tsum = 0x%x, expected = 0x%x\n", sum, + SUM_OF_NUMBERS(thread_cnt * data_cnt)); + return 0; + } else { + PR_fprintf(output, "%s failed: sum = 0x%x, expected = 0x%x\n", + argv[0], sum, + SUM_OF_NUMBERS(data_cnt * thread_cnt)); + return 2; + } +#endif +} + +static void stackop(void *thread_arg) +{ + PRInt32 val, cnt, index, loops; + DataRecord *Items, *Item; + PRStack *list1, *list2; + PRStackElem *node; + stack_data *arg = (stack_data *) thread_arg; + + val = arg->initial_data_value; + cnt = arg->data_cnt; + loops = arg->loops; + list1 = arg->list1; + list2 = arg->list2; + + /* + * allocate memory for the data records + */ + Items = (DataRecord *) PR_CALLOC(sizeof(DataRecord) * cnt); + PR_ASSERT(Items != NULL); + index = 0; + + if (_debug_on) + PR_fprintf(output, + "Thread[0x%x] init_val = %d cnt = %d data1 = 0x%x datan = 0x%x\n", + PR_GetCurrentThread(), val, cnt, &Items[0], &Items[cnt-1]); + + + /* + * add the data records to list1 + */ + while (cnt-- > 0) { + Items[index].data = val++; + PR_StackPush(list1, &Items[index].link); + index++; + } + + /* + * pop data records from list1 and add them back to list1 + * generates contention for the stack accesses + */ + while (loops-- > 0) { + cnt = arg->data_cnt; + while (cnt-- > 0) { + node = PR_StackPop(list1); + if (node == NULL) { + PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n"); + PR_ASSERT(node != NULL); + PR_ProcessExit(3); + } + PR_StackPush(list1, node); + } + } + /* + * remove the data records from list1 and add them to list2 + */ + cnt = arg->data_cnt; + while (cnt-- > 0) { + node = PR_StackPop(list1); + if (node == NULL) { + PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n"); + PR_ASSERT(node != NULL); + PR_ProcessExit(3); + } + PR_StackPush(list2, node); + } + if (_debug_on) + PR_fprintf(output, + "Thread[0x%x] init_val = %d cnt = %d exiting\n", + PR_GetCurrentThread(), val, cnt); + +} + diff -Nru nspr-4.9.5/nspr/pr/tests/stat.c nspr-4.10.7/nspr/pr/tests/stat.c --- nspr-4.9.5/nspr/pr/tests/stat.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/stat.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Program to test different ways to get file info; right now it + * only works for solaris and OS/2. + * + */ +#include "nspr.h" +#include "prpriv.h" +#include "prinrval.h" + +#include +#include +#include + +#ifdef XP_OS2 +#include +#include +#include +#endif + +#define DEFAULT_COUNT 100000 +PRInt32 count; + +#ifndef XP_PC +char *filename = "/etc/passwd"; +#else +char *filename = "..\\stat.c"; +#endif + +static void statPRStat(void) +{ + PRFileInfo finfo; + PRInt32 index = count; + + for (;index--;) { + PR_GetFileInfo(filename, &finfo); + } +} + +static void statStat(void) +{ + struct stat finfo; + PRInt32 index = count; + + for (;index--;) { + stat(filename, &finfo); + } +} + +/************************************************************************/ + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + PRInt32 tot; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + tot = PR_IntervalToMilliseconds(stop-start); + + printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot); +} + +int main(int argc, char **argv) +{ + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (argc > 1) { + count = atoi(argv[1]); + } else { + count = DEFAULT_COUNT; + } + + Measure(statPRStat, "time to call PR_GetFileInfo()"); + Measure(statStat, "time to call stat()"); + + PR_Cleanup(); +} diff -Nru nspr-4.9.5/nspr/pr/tests/stdio.c nspr-4.10.7/nspr/pr/tests/stdio.c --- nspr-4.9.5/nspr/pr/tests/stdio.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/stdio.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: stdio.c + * Description: testing the "special" fds + * Modification History: + * 20-May-1997 AGarcia - Replace Test succeeded status with PASS. This is used by the + * regress tool parsing code. + ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to +** recognize the return code from tha main program. + */ + + +#include "prlog.h" +#include "prinit.h" +#include "prio.h" + +#include +#include + +static PRIntn PR_CALLBACK stdio(PRIntn argc, char **argv) +{ + PRInt32 rv; + + PRFileDesc *out = PR_GetSpecialFD(PR_StandardOutput); + PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); + + rv = PR_Write( + out, "This to standard out\n", + strlen("This to standard out\n")); + PR_ASSERT((PRInt32)strlen("This to standard out\n") == rv); + rv = PR_Write( + err, "This to standard err\n", + strlen("This to standard err\n")); + PR_ASSERT((PRInt32)strlen("This to standard err\n") == rv); + + return 0; + +} /* stdio */ + +int main(int argc, char **argv) +{ + PR_STDIO_INIT(); + return PR_Initialize(stdio, argc, argv, 0); +} /* main */ + + +/* stdio.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/str2addr.c nspr-4.10.7/nspr/pr/tests/str2addr.c --- nspr-4.9.5/nspr/pr/tests/str2addr.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/str2addr.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: str2addr.c + * Description: a test for PR_StringToNetAddr + */ + +#include "nspr.h" + +#include +#include + +/* Address string to convert */ +#define DEFAULT_IPV4_ADDR_STR "207.200.73.41" + +/* Expected conversion result, in network byte order */ +static unsigned char default_ipv4_addr[] = {207, 200, 73, 41}; + +int main(int argc, char **argv) +{ + PRNetAddr addr; + const char *addrStr; + unsigned char *bytes; + int idx; + + addrStr = DEFAULT_IPV4_ADDR_STR; + if (PR_StringToNetAddr(addrStr, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_StringToNetAddr failed\n"); + exit(1); + } + if (addr.inet.family != PR_AF_INET) { + fprintf(stderr, "addr.inet.family should be %d but is %d\n", + PR_AF_INET, addr.inet.family); + exit(1); + } + bytes = (unsigned char *) &addr.inet.ip; + for (idx = 0; idx < 4; idx++) { + if (bytes[idx] != default_ipv4_addr[idx]) { + fprintf(stderr, "byte %d of IPv4 addr should be %d but is %d\n", + idx, default_ipv4_addr[idx], bytes[idx]); + exit(1); + } + } + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/strod.c nspr-4.10.7/nspr/pr/tests/strod.c --- nspr-4.9.5/nspr/pr/tests/strod.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/strod.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prinit.h" +#include "prio.h" +#include "prprf.h" +#include "prdtoa.h" +#include "plgetopt.h" + +#include + +static void Help(void) +{ + PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); + PR_fprintf(err, "Usage: /.strod [-n n] [-l n] [-h]\n"); + PR_fprintf(err, "\t-n n Number to translate (default: 1234567890123456789)\n"); + PR_fprintf(err, "\t-l n Times to loop the test (default: 1)\n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); +} /* Help */ + +static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv) +{ + PLOptStatus os; + PRIntn loops = 1; + PRFloat64 answer; + const char *number = "1234567890123456789"; + PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); + PLOptState *opt = PL_CreateOptState(argc, argv, "hc:l:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'n': /* number to translate */ + number = opt->value; + break; + case 'l': /* number of times to run the tests */ + loops = atoi(opt->value); + break; + case 'h': /* user wants some guidance */ + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_fprintf(err, "Settings\n"); + PR_fprintf(err, "\tNumber to translate %s\n", number); + PR_fprintf(err, "\tLoops to run test: %d\n", loops); + + while (loops--) + { + answer = PR_strtod(number, NULL); + PR_fprintf(err, "Translation = %20.0f\n", answer); + } + return 0; +} + + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ diff -Nru nspr-4.9.5/nspr/pr/tests/suspend.c nspr-4.10.7/nspr/pr/tests/suspend.c --- nspr-4.9.5/nspr/pr/tests/suspend.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/suspend.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifdef XP_BEOS +#include +int main() +{ + printf( "This test is not ported to the BeOS\n" ); + return 0; +} +#else + +#include "nspr.h" +#include "prpriv.h" +#include "prinrval.h" + +#include +#include +#include + +PRMonitor *mon; +PRInt32 count; +PRInt32 alive; + +#define SLEEP_TIME 4 /* secs */ + +void PR_CALLBACK +Level_2_Thread(void *arg) +{ + PR_Sleep(PR_MillisecondsToInterval(4 * 1000)); + printf("Level_2_Thread[0x%lx] exiting\n",PR_GetCurrentThread()); + return; +} + +void PR_CALLBACK +Level_1_Thread(void *arg) +{ + PRUint32 tmp = (PRUint32)arg; + PRThreadScope scope = (PRThreadScope) tmp; + PRThread *thr; + + thr = PR_CreateThreadGCAble(PR_USER_THREAD, + Level_2_Thread, + NULL, + PR_PRIORITY_HIGH, + scope, + PR_JOINABLE_THREAD, + 0); + + if (!thr) { + printf("Could not create thread!\n"); + } else { + printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n", + PR_GetCurrentThread(), + (scope == PR_GLOBAL_THREAD) ? + "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", + thr); + PR_JoinThread(thr); + } + PR_EnterMonitor(mon); + alive--; + PR_Notify(mon); + PR_ExitMonitor(mon); + printf("Thread[0x%lx] exiting\n",PR_GetCurrentThread()); +} + +static PRStatus PR_CALLBACK print_thread(PRThread *thread, int i, void *arg) +{ + PRInt32 words; + PRWord *registers; + + printf( + "\nprint_thread[0x%lx]: %-20s - i = %ld\n",thread, + (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ? + "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", i); + registers = PR_GetGCRegisters(thread, 0, (int *)&words); + if (registers) + printf("Registers R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n", + registers[0],registers[1],registers[2],registers[3]); + printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread)); + return PR_SUCCESS; +} + +static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *thr; + PRThread *me = PR_GetCurrentThread(); + int n; + PRInt32 words; + PRWord *registers; + + alive = 0; + mon = PR_NewMonitor(); + + alive = count; + for (n=0; n 1) { + count = atoi(argv[1]); + } else { + count = 5; + } + + printf("\n\n%20s%30s\n\n"," ","Suspend_Resume Test"); + CreateThreadsUU(); + CreateThreadsUK(); + CreateThreadsKU(); + CreateThreadsKK(); + PR_SetConcurrency(2); + + printf("\n%20s%30s\n\n"," ","Added 2nd CPU\n"); + + CreateThreadsUK(); + CreateThreadsKK(); + CreateThreadsUU(); + CreateThreadsKU(); + PR_Cleanup(); + + return 0; +} + +#endif /* XP_BEOS */ diff -Nru nspr-4.9.5/nspr/pr/tests/switch.c nspr-4.10.7/nspr/pr/tests/switch.c --- nspr-4.9.5/nspr/pr/tests/switch.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/switch.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,237 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: switch.c +** Description: trying to time context switches +*/ + +#include "prinit.h" +#include "prcvar.h" +#include "prmem.h" +#include "prinrval.h" +#include "prlock.h" +#include "prlog.h" +#include "prthread.h" +#include "prprf.h" + +#include "plerror.h" +#include "plgetopt.h" + +#include "private/pprio.h" + +#include + +#define INNER_LOOPS 100 +#define DEFAULT_LOOPS 100 +#define DEFAULT_THREADS 10 + +static PRFileDesc *debug_out = NULL; +static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE; + +typedef struct Shared +{ + PRLock *ml; + PRCondVar *cv; + PRBool twiddle; + PRThread *thread; + struct Shared *next; +} Shared; + +static void Help(void) +{ + debug_out = PR_STDOUT; + + PR_fprintf( + debug_out, "Usage: >./switch [-c n] [-t n] [-d] [-v] [-G] [-C n]\n"); + PR_fprintf( + debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS); + PR_fprintf( + debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS); + PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n"); + PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n"); + PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n"); + PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n"); +} /* Help */ + +static void PR_CALLBACK Notified(void *arg) +{ + Shared *shared = (Shared*)arg; + PRStatus status = PR_SUCCESS; + while (PR_SUCCESS == status) + { + PR_Lock(shared->ml); + while (shared->twiddle && (PR_SUCCESS == status)) + status = PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT); + if (verbosity) PR_fprintf(debug_out, "+"); + shared->twiddle = PR_TRUE; + shared->next->twiddle = PR_FALSE; + PR_NotifyCondVar(shared->next->cv); + PR_Unlock(shared->ml); + } +} /* Notified */ + +static Shared home; +PRIntn PR_CALLBACK Switch(PRIntn argc, char **argv) +{ + PLOptStatus os; + PRStatus status; + PRBool help = PR_FALSE; + PRUintn concurrency = 1; + Shared *shared, *link; + PRIntervalTime timein, timeout; + PRThreadScope thread_scope = PR_LOCAL_THREAD; + PRUintn thread_count, inner_count, loop_count, average; + PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS; + PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'v': /* verbose mode */ + verbosity = PR_TRUE; + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'c': /* loop counter */ + loop_limit = atoi(opt->value); + break; + case 't': /* thread limit */ + thread_limit = atoi(opt->value); + break; + case 'C': /* Concurrency limit */ + concurrency = atoi(opt->value); + break; + case 'G': /* global threads only */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'h': /* help message */ + Help(); + help = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (help) return -1; + + if (PR_TRUE == debug_mode) + { + debug_out = PR_STDOUT; + PR_fprintf(debug_out, "Test parameters\n"); + PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit); + PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit); + PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency); + PR_fprintf( + debug_out, "\tThread type: %s\n", + (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); + } + + PR_SetConcurrency(concurrency); + + link = &home; + home.ml = PR_NewLock(); + home.cv = PR_NewCondVar(home.ml); + home.twiddle = PR_FALSE; + home.next = NULL; + + timeout = 0; + + for (thread_count = 1; thread_count <= thread_limit; ++thread_count) + { + shared = PR_NEWZAP(Shared); + + shared->ml = home.ml; + shared->cv = PR_NewCondVar(home.ml); + shared->twiddle = PR_TRUE; + shared->next = link; + link = shared; + + shared->thread = PR_CreateThread( + PR_USER_THREAD, Notified, shared, + PR_PRIORITY_HIGH, thread_scope, + PR_JOINABLE_THREAD, 0); + PR_ASSERT(shared->thread != NULL); + if (NULL == shared->thread) + failed = PR_TRUE; + } + + for (loop_count = 1; loop_count <= loop_limit; ++loop_count) + { + timein = PR_IntervalNow(); + for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count) + { + PR_Lock(home.ml); + home.twiddle = PR_TRUE; + shared->twiddle = PR_FALSE; + PR_NotifyCondVar(shared->cv); + while (home.twiddle) + { + status = PR_WaitCondVar(home.cv, PR_INTERVAL_NO_TIMEOUT); + if (PR_FAILURE == status) + failed = PR_TRUE; + } + PR_Unlock(home.ml); + } + timeout += (PR_IntervalNow() - timein); + } + + if (debug_mode) + { + average = PR_IntervalToMicroseconds(timeout) + / (INNER_LOOPS * loop_limit * thread_count); + PR_fprintf( + debug_out, "Average switch times %d usecs for %d threads\n", + average, thread_limit); + } + + link = shared; + for (thread_count = 1; thread_count <= thread_limit; ++thread_count) + { + if (&home == link) break; + status = PR_Interrupt(link->thread); + if (PR_SUCCESS != status) + { + failed = PR_TRUE; + if (debug_mode) + PL_FPrintError(debug_out, "Failed to interrupt"); + } + link = link->next; + } + + for (thread_count = 1; thread_count <= thread_limit; ++thread_count) + { + link = shared->next; + status = PR_JoinThread(shared->thread); + if (PR_SUCCESS != status) + { + failed = PR_TRUE; + if (debug_mode) + PL_FPrintError(debug_out, "Failed to join"); + } + PR_DestroyCondVar(shared->cv); + PR_DELETE(shared); + if (&home == link) break; + shared = link; + } + PR_DestroyCondVar(home.cv); + PR_DestroyLock(home.ml); + + PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n")); + return ((failed) ? 1 : 0); +} /* Switch */ + +int main(int argc, char **argv) +{ + PRIntn result; + PR_STDIO_INIT(); + result = PR_Initialize(Switch, argc, argv, 0); + return result; +} /* main */ + +/* switch.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/system.c nspr-4.10.7/nspr/pr/tests/system.c --- nspr-4.9.5/nspr/pr/tests/system.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/system.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prmem.h" +#include "prprf.h" +#include "prsystem.h" + +#include "plerror.h" + +static char *tag[] = +{ + "PR_SI_HOSTNAME", + "PR_SI_SYSNAME", + "PR_SI_RELEASE", + "PR_SI_ARCHITECTURE" +}; + +static PRSysInfo Incr(PRSysInfo *cmd) +{ + PRIntn tmp = (PRIntn)*cmd + 1; + *cmd = (PRSysInfo)tmp; + return (PRSysInfo)tmp; +} /* Incr */ + +int main(int argc, char **argv) +{ + PRStatus rv; + PRSysInfo cmd; + PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput); + + char *info = (char*)PR_Calloc(SYS_INFO_BUFFER_LENGTH, 1); + for (cmd = PR_SI_HOSTNAME; cmd <= PR_SI_ARCHITECTURE; Incr(&cmd)) + { + rv = PR_GetSystemInfo(cmd, info, SYS_INFO_BUFFER_LENGTH); + if (PR_SUCCESS == rv) PR_fprintf(output, "%s: %s\n", tag[cmd], info); + else PL_FPrintError(output, tag[cmd]); + } + PR_DELETE(info); + + PR_fprintf(output, "Host page size is %d\n", PR_GetPageSize()); + PR_fprintf(output, "Page shift is %d\n", PR_GetPageShift()); + PR_fprintf(output, "Memory map alignment is %ld\n", PR_GetMemMapAlignment()); + PR_fprintf(output, "Number of processors is: %d\n", PR_GetNumberOfProcessors()); + PR_fprintf(output, "Physical memory size is: %llu\n", PR_GetPhysicalMemorySize()); + + return 0; +} /* main */ + +/* system.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/testbit.c nspr-4.10.7/nspr/pr/tests/testbit.c --- nspr-4.9.5/nspr/pr/tests/testbit.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/testbit.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: lazyinit.c +** Description: Test the functions and macros declared in prbit.h +** +*/ + +#include "nspr.h" + +#define ErrorReport(x) { printf((x)); failed = 1; } + +prbitmap_t myMap[512/32] = { 0 }; + +PRInt32 rc; +PRInt32 i; +PRIntn failed = 0; + +int main(int argc, char **argv) +{ + /* + ** Test bitmap things. + */ + if ( PR_TEST_BIT( myMap, 0 )) + ErrorReport("Test 0.0: Failed\n"); + + if ( PR_TEST_BIT( myMap, 31 )) + ErrorReport("Test 0.1: Failed\n"); + + if ( PR_TEST_BIT( myMap, 128 )) + ErrorReport("Test 0.2: Failed\n"); + + if ( PR_TEST_BIT( myMap, 129 )) + ErrorReport("Test 0.3: Failed\n"); + + + PR_SET_BIT( myMap, 0 ); + if ( !PR_TEST_BIT( myMap, 0 )) + ErrorReport("Test 1.0: Failed\n"); + + PR_CLEAR_BIT( myMap, 0 ); + if ( PR_TEST_BIT( myMap, 0 )) + ErrorReport("Test 1.0.1: Failed\n"); + + PR_SET_BIT( myMap, 31 ); + if ( !PR_TEST_BIT( myMap, 31 )) + ErrorReport("Test 1.1: Failed\n"); + + PR_CLEAR_BIT( myMap, 31 ); + if ( PR_TEST_BIT( myMap, 31 )) + ErrorReport("Test 1.1.1: Failed\n"); + + PR_SET_BIT( myMap, 128 ); + if ( !PR_TEST_BIT( myMap, 128 )) + ErrorReport("Test 1.2: Failed\n"); + + PR_CLEAR_BIT( myMap, 128 ); + if ( PR_TEST_BIT( myMap, 128 )) + ErrorReport("Test 1.2.1: Failed\n"); + + PR_SET_BIT( myMap, 129 ); + if ( !PR_TEST_BIT( myMap, 129 )) + ErrorReport("Test 1.3: Failed\n"); + + PR_CLEAR_BIT( myMap, 129 ); + if ( PR_TEST_BIT( myMap, 129 )) + ErrorReport("Test 1.3.1: Failed\n"); + + + /* + ** Test Ceiling and Floor functions and macros + */ + if ((rc = PR_CeilingLog2(32)) != 5 ) + ErrorReport("Test 10.0: Failed\n"); + + if ((rc = PR_FloorLog2(32)) != 5 ) + ErrorReport("Test 10.1: Failed\n"); + + + /* + ** Evaluate results and exit + */ + if (failed) + { + printf("FAILED\n"); + return(1); + } + else + { + printf("PASSED\n"); + return(0); + } +} /* end main() */ +/* end testbit.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/testfile.c nspr-4.10.7/nspr/pr/tests/testfile.c --- nspr-4.9.5/nspr/pr/tests/testfile.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/testfile.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,961 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "prpriv.h" + +#include +#include +#include +#ifdef WIN32 +#include +#include +#endif +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) +#include +#endif +#ifdef SYMBIAN +#include +#endif + +#if defined(XP_OS2) +#define INCL_DOSFILEMGR +#include +#include +#include +#endif /* XP_OS2 */ + +static int _debug_on = 0; + +#ifdef WINCE +#define setbuf(x,y) +#endif + +#ifdef XP_WIN +#define mode_t int +#endif + +#define DPRINTF(arg) if (_debug_on) printf arg + +PRLock *lock; +PRMonitor *mon; +PRInt32 count; +int thread_count; + +#ifdef WIN16 +#define BUF_DATA_SIZE 256 * 120 +#else +#define BUF_DATA_SIZE 256 * 1024 +#endif + +#define NUM_RDWR_THREADS 10 +#define NUM_DIRTEST_THREADS 4 +#define CHUNK_SIZE 512 + +typedef struct buffer { + char data[BUF_DATA_SIZE]; +} buffer; + +typedef struct File_Rdwr_Param { + char *pathname; + char *buf; + int offset; + int len; +} File_Rdwr_Param; + +#ifdef XP_PC +#ifdef XP_OS2 +char *TEST_DIR = "prdir"; +#else +char *TEST_DIR = "C:\\temp\\prdir"; +#endif +char *FILE_NAME = "pr_testfile"; +char *HIDDEN_FILE_NAME = "hidden_pr_testfile"; +#else +#ifdef SYMBIAN +char *TEST_DIR = "c:\\data\\testfile_dir"; +#else +char *TEST_DIR = "/tmp/testfile_dir"; +#endif +char *FILE_NAME = "pr_testfile"; +char *HIDDEN_FILE_NAME = ".hidden_pr_testfile"; +#endif +buffer *in_buf, *out_buf; +char pathname[256], renamename[256]; +#ifdef WINCE +WCHAR wPathname[256]; +#endif +#define TMPDIR_LEN 64 +char testdir[TMPDIR_LEN]; +static PRInt32 PR_CALLBACK DirTest(void *argunused); +PRInt32 dirtest_failed = 0; + +PRThread* create_new_thread(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize, PRInt32 index) +{ +PRInt32 native_thread = 0; + + PR_ASSERT(state == PR_UNJOINABLE_THREAD); + +#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) || defined(XP_OS2) + + switch(index % 4) { + case 0: + scope = (PR_LOCAL_THREAD); + break; + case 1: + scope = (PR_GLOBAL_THREAD); + break; + case 2: + scope = (PR_GLOBAL_BOUND_THREAD); + break; + case 3: + native_thread = 1; + break; + default: + PR_ASSERT(!"Invalid scope"); + break; + } + if (native_thread) { +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) + pthread_t tid; + if (!pthread_create(&tid, NULL, start, arg)) + return((PRThread *) tid); + else + return (NULL); +#elif defined(XP_OS2) + TID tid; + + tid = (TID)_beginthread((void(* _Optlink)(void*))start, + NULL, 32768, arg); + if (tid == -1) { + printf("_beginthread failed. errno %d\n", errno); + return (NULL); + } + else + return((PRThread *) tid); +#else + HANDLE thandle; + unsigned tid; + + thandle = (HANDLE) _beginthreadex( + NULL, + stackSize, + (unsigned (__stdcall *)(void *))start, + arg, + STACK_SIZE_PARAM_IS_A_RESERVATION, + &tid); + return((PRThread *) thandle); +#endif + } else { + return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); + } +#else + return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); +#endif +} + +static void PR_CALLBACK File_Write(void *arg) +{ +PRFileDesc *fd_file; +File_Rdwr_Param *fp = (File_Rdwr_Param *) arg; +char *name, *buf; +int offset, len; + + setbuf(stdout, NULL); + name = fp->pathname; + buf = fp->buf; + offset = fp->offset; + len = fp->len; + + fd_file = PR_Open(name, PR_RDWR | PR_CREATE_FILE, 0777); + if (fd_file == NULL) { + printf("testfile failed to create/open file %s\n",name); + return; + } + if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { + printf("testfile failed to seek in file %s\n",name); + return; + } + if ((PR_Write(fd_file, buf, len)) < 0) { + printf("testfile failed to write to file %s\n",name); + return; + } + DPRINTF(("Write out_buf[0] = 0x%x\n",(*((int *) buf)))); + PR_Close(fd_file); + PR_DELETE(fp); + + PR_EnterMonitor(mon); + --thread_count; + PR_Notify(mon); + PR_ExitMonitor(mon); +} + +static void PR_CALLBACK File_Read(void *arg) +{ +PRFileDesc *fd_file; +File_Rdwr_Param *fp = (File_Rdwr_Param *) arg; +char *name, *buf; +int offset, len; + + setbuf(stdout, NULL); + name = fp->pathname; + buf = fp->buf; + offset = fp->offset; + len = fp->len; + + fd_file = PR_Open(name, PR_RDONLY, 0); + if (fd_file == NULL) { + printf("testfile failed to open file %s\n",name); + return; + } + if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) { + printf("testfile failed to seek in file %s\n",name); + return; + } + if ((PR_Read(fd_file, buf, len)) < 0) { + printf("testfile failed to read to file %s\n",name); + return; + } + DPRINTF(("Read in_buf[0] = 0x%x\n",(*((int *) buf)))); + PR_Close(fd_file); + PR_DELETE(fp); + + PR_EnterMonitor(mon); + --thread_count; + PR_Notify(mon); + PR_ExitMonitor(mon); +} + + +static PRInt32 Misc_File_Tests(char *pathname) +{ +PRFileDesc *fd_file; +int len, rv = 0; +PRFileInfo file_info, file_info1; +char tmpname[1024]; + + setbuf(stdout, NULL); + /* + * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access + */ + + fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); + + if (fd_file == NULL) { + printf("testfile failed to create/open file %s\n",pathname); + return -1; + } + if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { + printf("testfile PR_GetFileInfo failed on file %s\n",pathname); + rv = -1; + goto cleanup; + } + if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) { + printf("testfile PR_Access failed on file %s\n",pathname); + rv = -1; + goto cleanup; + } + if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) { + printf("testfile PR_Access failed on file %s\n",pathname); + rv = -1; + goto cleanup; + } + if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) { + printf("testfile PR_Access failed on file %s\n",pathname); + rv = -1; + goto cleanup; + } + + + if (PR_GetFileInfo(pathname, &file_info) < 0) { + printf("testfile PR_GetFileInfo failed on file %s\n",pathname); + rv = -1; + goto cleanup; + } + if (file_info.type != PR_FILE_FILE) { + printf( + "testfile: Error - PR_GetFileInfo returned incorrect type for file %s\n", + pathname); + rv = -1; + goto cleanup; + } + if (file_info.size != 0) { + printf( + "testfile PR_GetFileInfo returned incorrect size (%d should be 0) for file %s\n", + file_info.size, pathname); + rv = -1; + goto cleanup; + } + file_info1 = file_info; + + len = PR_Available(fd_file); + if (len < 0) { + printf("testfile PR_Available failed on file %s\n",pathname); + rv = -1; + goto cleanup; + } else if (len != 0) { + printf( + "testfile PR_Available failed: expected/returned = %d/%d bytes\n", + 0, len); + rv = -1; + goto cleanup; + } + if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { + printf("testfile PR_GetFileInfo failed on file %s\n",pathname); + goto cleanup; + } + if (LL_NE(file_info.creationTime , file_info1.creationTime)) { + printf( + "testfile PR_GetFileInfo returned incorrect status-change time: %s\n", + pathname); + printf("ft = %lld, ft1 = %lld\n",file_info.creationTime, + file_info1.creationTime); + rv = -1; + goto cleanup; + } + len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); + if (len < 0) { + printf("testfile failed to write to file %s\n",pathname); + rv = -1; + goto cleanup; + } + if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { + printf("testfile PR_GetFileInfo failed on file %s\n",pathname); + goto cleanup; + } + if (file_info.size != CHUNK_SIZE) { + printf( + "testfile PR_GetFileInfo returned incorrect size (%d should be %d) for file %s\n", + file_info.size, CHUNK_SIZE, pathname); + rv = -1; + goto cleanup; + } + if (LL_CMP(file_info.modifyTime, < , file_info1.modifyTime)) { + printf( + "testfile PR_GetFileInfo returned incorrect modify time: %s\n", + pathname); + printf("ft = %lld, ft1 = %lld\n",file_info.modifyTime, + file_info1.modifyTime); + rv = -1; + goto cleanup; + } + + len = PR_Available(fd_file); + if (len < 0) { + printf("testfile PR_Available failed on file %s\n",pathname); + rv = -1; + goto cleanup; + } else if (len != 0) { + printf( + "testfile PR_Available failed: expected/returned = %d/%d bytes\n", + 0, len); + rv = -1; + goto cleanup; + } + + PR_Seek(fd_file, 0, PR_SEEK_SET); + len = PR_Available(fd_file); + if (len < 0) { + printf("testfile PR_Available failed on file %s\n",pathname); + rv = -1; + goto cleanup; + } else if (len != CHUNK_SIZE) { + printf( + "testfile PR_Available failed: expected/returned = %d/%d bytes\n", + CHUNK_SIZE, len); + rv = -1; + goto cleanup; + } + PR_Close(fd_file); + + strcpy(tmpname,pathname); + strcat(tmpname,".RENAMED"); + if (PR_FAILURE == PR_Rename(pathname, tmpname)) { + printf("testfile failed to rename file %s\n",pathname); + rv = -1; + goto cleanup; + } + + fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); + len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); + PR_Close(fd_file); + if (PR_SUCCESS == PR_Rename(pathname, tmpname)) { + printf("testfile renamed to existing file %s\n",pathname); + } + + if ((PR_Delete(tmpname)) < 0) { + printf("testfile failed to unlink file %s\n",tmpname); + rv = -1; + } + +cleanup: + if ((PR_Delete(pathname)) < 0) { + printf("testfile failed to unlink file %s\n",pathname); + rv = -1; + } + return rv; +} + + +static PRInt32 PR_CALLBACK FileTest(void) +{ +PRDir *fd_dir; +int i, offset, len, rv = 0; +PRThread *t; +PRThreadScope scope = PR_GLOBAL_THREAD; +File_Rdwr_Param *fparamp; + + /* + * Create Test dir + */ + if ((PR_MkDir(TEST_DIR, 0777)) < 0) { + printf("testfile failed to create dir %s\n",TEST_DIR); + return -1; + } + fd_dir = PR_OpenDir(TEST_DIR); + if (fd_dir == NULL) { + printf("testfile failed to open dir %s\n",TEST_DIR); + rv = -1; + goto cleanup; + } + + PR_CloseDir(fd_dir); + + strcat(pathname, TEST_DIR); + strcat(pathname, "/"); + strcat(pathname, FILE_NAME); + + in_buf = PR_NEW(buffer); + if (in_buf == NULL) { + printf( + "testfile failed to alloc buffer struct\n"); + rv = -1; + goto cleanup; + } + out_buf = PR_NEW(buffer); + if (out_buf == NULL) { + printf( + "testfile failed to alloc buffer struct\n"); + rv = -1; + goto cleanup; + } + + /* + * Start a bunch of writer threads + */ + offset = 0; + len = CHUNK_SIZE; + PR_EnterMonitor(mon); + for (i = 0; i < NUM_RDWR_THREADS; i++) { + fparamp = PR_NEW(File_Rdwr_Param); + if (fparamp == NULL) { + printf( + "testfile failed to alloc File_Rdwr_Param struct\n"); + rv = -1; + goto cleanup; + } + fparamp->pathname = pathname; + fparamp->buf = out_buf->data + offset; + fparamp->offset = offset; + fparamp->len = len; + memset(fparamp->buf, i, len); + + t = create_new_thread(PR_USER_THREAD, + File_Write, (void *)fparamp, + PR_PRIORITY_NORMAL, + scope, + PR_UNJOINABLE_THREAD, + 0, i); + offset += len; + } + thread_count = i; + /* Wait for writer threads to exit */ + while (thread_count) { + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + } + PR_ExitMonitor(mon); + + + /* + * Start a bunch of reader threads + */ + offset = 0; + len = CHUNK_SIZE; + PR_EnterMonitor(mon); + for (i = 0; i < NUM_RDWR_THREADS; i++) { + fparamp = PR_NEW(File_Rdwr_Param); + if (fparamp == NULL) { + printf( + "testfile failed to alloc File_Rdwr_Param struct\n"); + rv = -1; + goto cleanup; + } + fparamp->pathname = pathname; + fparamp->buf = in_buf->data + offset; + fparamp->offset = offset; + fparamp->len = len; + + t = create_new_thread(PR_USER_THREAD, + File_Read, (void *)fparamp, + PR_PRIORITY_NORMAL, + scope, + PR_UNJOINABLE_THREAD, + 0, i); + offset += len; + if ((offset + len) > BUF_DATA_SIZE) + break; + } + thread_count = i; + + /* Wait for reader threads to exit */ + while (thread_count) { + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + } + PR_ExitMonitor(mon); + + if (memcmp(in_buf->data, out_buf->data, offset) != 0) { + printf("File Test failed: file data corrupted\n"); + rv = -1; + goto cleanup; + } + + if ((PR_Delete(pathname)) < 0) { + printf("testfile failed to unlink file %s\n",pathname); + rv = -1; + goto cleanup; + } + + /* + * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access + */ + if (Misc_File_Tests(pathname) < 0) { + rv = -1; + } + +cleanup: + if ((PR_RmDir(TEST_DIR)) < 0) { + printf("testfile failed to rmdir %s\n", TEST_DIR); + rv = -1; + } + return rv; +} + +struct dirtest_arg { + PRMonitor *mon; + PRInt32 done; +}; + +static PRInt32 RunDirTest(void) +{ +int i; +PRThread *t; +PRMonitor *mon; +struct dirtest_arg thrarg; + + mon = PR_NewMonitor(); + if (!mon) { + printf("RunDirTest: Error - failed to create monitor\n"); + dirtest_failed = 1; + return -1; + } + thrarg.mon = mon; + + for (i = 0; i < NUM_DIRTEST_THREADS; i++) { + + thrarg.done= 0; + t = create_new_thread(PR_USER_THREAD, + DirTest, &thrarg, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0, i); + if (!t) { + printf("RunDirTest: Error - failed to create thread\n"); + dirtest_failed = 1; + return -1; + } + PR_EnterMonitor(mon); + while (!thrarg.done) + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(mon); + + } + PR_DestroyMonitor(mon); + return 0; +} + +static PRInt32 PR_CALLBACK DirTest(void *arg) +{ +struct dirtest_arg *tinfo = (struct dirtest_arg *) arg; +PRFileDesc *fd_file; +PRDir *fd_dir; +int i; +int path_len; +PRDirEntry *dirEntry; +PRFileInfo info; +PRInt32 num_files = 0; +#if defined(XP_PC) && defined(WIN32) +HANDLE hfile; +#endif + +#define FILES_IN_DIR 20 + + /* + * Create Test dir + */ + DPRINTF(("Creating test dir %s\n",TEST_DIR)); + if ((PR_MkDir(TEST_DIR, 0777)) < 0) { + printf( + "testfile failed to create dir %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + fd_dir = PR_OpenDir(TEST_DIR); + if (fd_dir == NULL) { + printf( + "testfile failed to open dirctory %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + + strcpy(pathname, TEST_DIR); + strcat(pathname, "/"); + strcat(pathname, FILE_NAME); + path_len = strlen(pathname); + + for (i = 0; i < FILES_IN_DIR; i++) { + + sprintf(pathname + path_len,"%d%s",i,""); + + DPRINTF(("Creating test file %s\n",pathname)); + + fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); + + if (fd_file == NULL) { + printf( + "testfile failed to create/open file %s [%d, %d]\n", + pathname, PR_GetError(), PR_GetOSError()); + return -1; + } + PR_Close(fd_file); + } +#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) + /* + * Create a hidden file - a platform-dependent operation + */ + strcpy(pathname, TEST_DIR); + strcat(pathname, "/"); + strcat(pathname, HIDDEN_FILE_NAME); +#if defined(XP_UNIX) || defined(XP_BEOS) + DPRINTF(("Creating hidden test file %s\n",pathname)); + fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777); + + if (fd_file == NULL) { + printf( + "testfile failed to create/open hidden file %s [%d, %d]\n", + pathname, PR_GetError(), PR_GetOSError()); + return -1; + } + + PR_Close(fd_file); + +#elif defined(WINCE) + DPRINTF(("Creating hidden test file %s\n",pathname)); + MultiByteToWideChar(CP_ACP, 0, pathname, -1, wPathname, 256); + hfile = CreateFile(wPathname, GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, + CREATE_NEW, + FILE_ATTRIBUTE_HIDDEN, + NULL); + if (hfile == INVALID_HANDLE_VALUE) { + printf("testfile failed to create/open hidden file %s [0, %d]\n", + pathname, GetLastError()); + return -1; + } + CloseHandle(hfile); + +#elif defined(XP_PC) && defined(WIN32) + DPRINTF(("Creating hidden test file %s\n",pathname)); + hfile = CreateFile(pathname, GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, + CREATE_NEW, + FILE_ATTRIBUTE_HIDDEN, + NULL); + if (hfile == INVALID_HANDLE_VALUE) { + printf("testfile failed to create/open hidden file %s [0, %d]\n", + pathname, GetLastError()); + return -1; + } + CloseHandle(hfile); + +#elif defined(OS2) + DPRINTF(("Creating hidden test file %s\n",pathname)); + fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, (int)FILE_HIDDEN); + + if (fd_file == NULL) { + printf("testfile failed to create/open hidden file %s [%d, %d]\n", + pathname, PR_GetError(), PR_GetOSError()); + return -1; + } + PR_Close(fd_file); +#endif /* XP_UNIX */ + +#endif /* XP_UNIX || (XP_PC && WIN32) */ + + + if (PR_FAILURE == PR_CloseDir(fd_dir)) + { + printf( + "testfile failed to close dirctory %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + fd_dir = PR_OpenDir(TEST_DIR); + if (fd_dir == NULL) { + printf( + "testfile failed to reopen dirctory %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + + /* + * List all files, including hidden files + */ + DPRINTF(("Listing all files in directory %s\n",TEST_DIR)); +#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) + num_files = FILES_IN_DIR + 1; +#else + num_files = FILES_IN_DIR; +#endif + while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) { + num_files--; + strcpy(pathname, TEST_DIR); + strcat(pathname, "/"); + strcat(pathname, dirEntry->name); + DPRINTF(("\t%s\n",dirEntry->name)); + + if ((PR_GetFileInfo(pathname, &info)) < 0) { + printf( + "testfile failed to GetFileInfo file %s [%d, %d]\n", + pathname, PR_GetError(), PR_GetOSError()); + return -1; + } + + if (info.type != PR_FILE_FILE) { + printf( + "testfile incorrect fileinfo for file %s [%d, %d]\n", + pathname, PR_GetError(), PR_GetOSError()); + return -1; + } + } + if (num_files != 0) + { + printf( + "testfile failed to find all files in directory %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + + PR_CloseDir(fd_dir); + +#if defined(XP_UNIX) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS) + + /* + * List all files, except hidden files + */ + + fd_dir = PR_OpenDir(TEST_DIR); + if (fd_dir == NULL) { + printf( + "testfile failed to reopen dirctory %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + + DPRINTF(("Listing non-hidden files in directory %s\n",TEST_DIR)); + while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_HIDDEN)) != NULL) { + DPRINTF(("\t%s\n",dirEntry->name)); + if (!strcmp(HIDDEN_FILE_NAME, dirEntry->name)) { + printf("testfile found hidden file %s\n", pathname); + return -1; + } + + } + /* + * Delete hidden file + */ + strcpy(pathname, TEST_DIR); + strcat(pathname, "/"); + strcat(pathname, HIDDEN_FILE_NAME); + if (PR_FAILURE == PR_Delete(pathname)) { + printf( + "testfile failed to delete hidden file %s [%d, %d]\n", + pathname, PR_GetError(), PR_GetOSError()); + return -1; + } + + PR_CloseDir(fd_dir); +#endif /* XP_UNIX || (XP_PC && WIN32) */ + + strcpy(renamename, TEST_DIR); + strcat(renamename, ".RENAMED"); + if (PR_FAILURE == PR_Rename(TEST_DIR, renamename)) { + printf( + "testfile failed to rename directory %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + + if (PR_FAILURE == PR_MkDir(TEST_DIR, 0777)) { + printf( + "testfile failed to recreate dir %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + if (PR_SUCCESS == PR_Rename(renamename, TEST_DIR)) { + printf( + "testfile renamed directory to existing name %s\n", + renamename); + return -1; + } + + if (PR_FAILURE == PR_RmDir(TEST_DIR)) { + printf( + "testfile failed to rmdir %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + + if (PR_FAILURE == PR_Rename(renamename, TEST_DIR)) { + printf( + "testfile failed to rename directory %s [%d, %d]\n", + renamename, PR_GetError(), PR_GetOSError()); + return -1; + } + fd_dir = PR_OpenDir(TEST_DIR); + if (fd_dir == NULL) { + printf( + "testfile failed to reopen directory %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + + strcpy(pathname, TEST_DIR); + strcat(pathname, "/"); + strcat(pathname, FILE_NAME); + path_len = strlen(pathname); + + for (i = 0; i < FILES_IN_DIR; i++) { + + sprintf(pathname + path_len,"%d%s",i,""); + + if (PR_FAILURE == PR_Delete(pathname)) { + printf( + "testfile failed to delete file %s [%d, %d]\n", + pathname, PR_GetError(), PR_GetOSError()); + return -1; + } + } + + PR_CloseDir(fd_dir); + + if (PR_FAILURE == PR_RmDir(TEST_DIR)) { + printf( + "testfile failed to rmdir %s [%d, %d]\n", + TEST_DIR, PR_GetError(), PR_GetOSError()); + return -1; + } + PR_EnterMonitor(tinfo->mon); + tinfo->done = 1; + PR_Notify(tinfo->mon); + PR_ExitMonitor(tinfo->mon); + + return 0; +} +/************************************************************************/ + +/* + * Test file and directory NSPR APIs + */ + +int main(int argc, char **argv) +{ +#ifdef WIN32 + PRUint32 len; +#endif +#if defined(XP_UNIX) || defined(XP_OS2) + int opt; + extern char *optarg; + extern int optind; +#endif +#if defined(XP_UNIX) || defined(XP_OS2) + while ((opt = getopt(argc, argv, "d")) != EOF) { + switch(opt) { + case 'd': + _debug_on = 1; + break; + default: + break; + } + } +#endif + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + mon = PR_NewMonitor(); + if (mon == NULL) { + printf("testfile: PR_NewMonitor failed\n"); + exit(2); + } +#ifdef WIN32 + +#ifdef WINCE + { + WCHAR tdir[TMPDIR_LEN]; + len = GetTempPath(TMPDIR_LEN, tdir); + if ((len > 0) && (len < (TMPDIR_LEN - 6))) { + /* + * enough space for prdir + */ + WideCharToMultiByte(CP_ACP, 0, tdir, -1, testdir, TMPDIR_LEN, 0, 0); + } + } +#else + len = GetTempPath(TMPDIR_LEN, testdir); +#endif /* WINCE */ + + if ((len > 0) && (len < (TMPDIR_LEN - 6))) { + /* + * enough space for prdir + */ + strcpy((testdir + len),"prdir"); + TEST_DIR = testdir; + printf("TEST_DIR = %s\n",TEST_DIR); + } +#endif /* WIN32 */ + + if (FileTest() < 0) { + printf("File Test failed\n"); + exit(2); + } + printf("File Test passed\n"); + if ((RunDirTest() < 0) || dirtest_failed) { + printf("Dir Test failed\n"); + exit(2); + } + printf("Dir Test passed\n"); + + PR_DestroyMonitor(mon); + PR_Cleanup(); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/threads.c nspr-4.10.7/nspr/pr/tests/threads.c --- nspr-4.9.5/nspr/pr/tests/threads.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/threads.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,203 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" +#include "prinrval.h" +#include "plgetopt.h" +#include "pprthred.h" +#include +#include +#include + +PRMonitor *mon; +PRInt32 count, iterations, alive; + +PRBool debug_mode = PR_FALSE, passed = PR_TRUE; + +void +PR_CALLBACK +ReallyDumbThread(void *arg) +{ + return; +} + +void +PR_CALLBACK +DumbThread(void *arg) +{ + PRInt32 tmp = (PRInt32)arg; + PRThreadScope scope = (PRThreadScope)tmp; + PRThread *thr; + + thr = PR_CreateThread(PR_USER_THREAD, + ReallyDumbThread, + NULL, + PR_PRIORITY_NORMAL, + scope, + PR_JOINABLE_THREAD, + 0); + + if (!thr) { + if (debug_mode) { + printf("Could not create really dumb thread (%d, %d)!\n", + PR_GetError(), PR_GetOSError()); + } + passed = PR_FALSE; + } else { + PR_JoinThread(thr); + } + PR_EnterMonitor(mon); + alive--; + PR_Notify(mon); + PR_ExitMonitor(mon); +} + +static void CreateThreads(PRThreadScope scope1, PRThreadScope scope2) +{ + PRThread *thr; + int n; + + alive = 0; + mon = PR_NewMonitor(); + + alive = count; + for (n=0; noption) + { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'c': /* loop counter */ + count = atoi(opt->value); + break; + case 'i': /* loop counter */ + iterations = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } + + if (0 == count) count = 50; + if (0 == iterations) iterations = 10; + + if (debug_mode) + { + printf("\ +** Tests lots of thread creations. \n\ +** Create %ld native threads %ld times. \n\ +** Create %ld user threads %ld times \n", iterations,count,iterations,count); + } + + for (index=0; index +#include +#include +#ifdef XP_UNIX +#include +#endif +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) +#include +#endif + +#ifdef WIN32 +#include +#endif + +static int _debug_on = 0; +static int server_port = -1; +static char *program_name = NULL; + +#include "obsolete/prsem.h" + +#ifdef XP_PC +#define mode_t int +#endif + +#define DPRINTF(arg) if (_debug_on) printf arg + +#define BUF_DATA_SIZE (2 * 1024) +#define TCP_MESG_SIZE 1024 +#define NUM_TCP_CLIENTS 10 /* for a listen queue depth of 5 */ + +#define NUM_TCP_CONNECTIONS_PER_CLIENT 10 +#define NUM_TCP_MESGS_PER_CONNECTION 10 +#define TCP_SERVER_PORT 10000 + +static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS; +static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT; +static PRInt32 tcp_mesg_size = TCP_MESG_SIZE; +static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION; + +int failed_already=0; + +typedef struct buffer { + char data[BUF_DATA_SIZE]; +} buffer; + +PRNetAddr tcp_server_addr, udp_server_addr; + +typedef struct Client_Param { + PRNetAddr server_addr; + PRMonitor *exit_mon; /* monitor to signal on exit */ + PRInt32 *exit_counter; /* counter to decrement, before exit */ + PRInt32 datalen; +} Client_Param; + +/* + * readn + * read data from sockfd into buf + */ +static PRInt32 +readn(PRFileDesc *sockfd, char *buf, int len) +{ + int rem; + int bytes; + int offset = 0; + PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; + + for (rem=len; rem; offset += bytes, rem -= bytes) { + DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n", + PR_GetCurrentThread(), rem)); + bytes = PR_Recv(sockfd, buf + offset, rem, 0, + timeout); + DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n", + PR_GetCurrentThread(), bytes)); + if (bytes < 0) { + return -1; + } + } + return len; +} + +/* + * writen + * write data from buf to sockfd + */ +static PRInt32 +writen(PRFileDesc *sockfd, char *buf, int len) +{ + int rem; + int bytes; + int offset = 0; + + for (rem=len; rem; offset += bytes, rem -= bytes) { + DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n", + PR_GetCurrentThread(), rem)); + bytes = PR_Send(sockfd, buf + offset, rem, 0, + PR_INTERVAL_NO_TIMEOUT); + DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n", + PR_GetCurrentThread(), bytes)); + if (bytes <= 0) + return -1; + } + return len; +} + +/* + * TCP_Client + * Client job + * Connect to the server at the address specified in the argument. + * Fill in a buffer, write data to server, read it back and check + * for data corruption. + * Close the socket for server connection + */ +static void PR_CALLBACK +TCP_Client(void *arg) +{ + Client_Param *cp = (Client_Param *) arg; + PRFileDesc *sockfd; + buffer *in_buf, *out_buf; + union PRNetAddr netaddr; + PRInt32 bytes, i, j; + + + DPRINTF(("TCP client started\n")); + bytes = cp->datalen; + out_buf = PR_NEW(buffer); + if (out_buf == NULL) { + fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name); + failed_already=1; + return; + } + in_buf = PR_NEW(buffer); + if (in_buf == NULL) { + fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name); + failed_already=1; + return; + } + netaddr.inet.family = cp->server_addr.inet.family; + netaddr.inet.port = cp->server_addr.inet.port; + netaddr.inet.ip = cp->server_addr.inet.ip; + + for (i = 0; i < num_tcp_connections_per_client; i++) { + if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) { + fprintf(stderr,"%s: PR_OpenTCPSocket failed\n", program_name); + failed_already=1; + return; + } + + DPRINTF(("TCP client connecting to server:%d\n", server_port)); + if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ + fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n", + PR_GetError(), PR_GetOSError()); + failed_already=1; + return; + } + for (j = 0; j < num_tcp_mesgs_per_connection; j++) { + /* + * fill in random data + */ + memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes); + /* + * write to server + */ + if (writen(sockfd, out_buf->data, bytes) < bytes) { + fprintf(stderr,"%s: ERROR - TCP_Client:writen\n", program_name); + failed_already=1; + return; + } + /* + DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", + PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); + */ + if (readn(sockfd, in_buf->data, bytes) < bytes) { + fprintf(stderr,"%s: ERROR - TCP_Client:readn\n", program_name); + failed_already=1; + return; + } + /* + * verify the data read + */ + if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { + fprintf(stderr,"%s: ERROR - data corruption\n", program_name); + failed_already=1; + return; + } + } + /* + * shutdown reads and writes + */ + if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { + fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name); + failed_already=1; + } + PR_Close(sockfd); + } + + PR_DELETE(out_buf); + PR_DELETE(in_buf); + + /* + * Decrement exit_counter and notify parent thread + */ + + PR_EnterMonitor(cp->exit_mon); + --(*cp->exit_counter); + PR_Notify(cp->exit_mon); + PR_ExitMonitor(cp->exit_mon); + DPRINTF(("TCP_Client exiting\n")); +} + +/* + * TCP_Socket_Client_Server_Test - concurrent server test + * + * Each client connects to the server and sends a chunk of data + * For each connection, server reads the data + * from the client and sends it back to the client, unmodified. + * Each client checks that data received from server is same as the + * data it sent to the server. + * + */ + +static PRInt32 +TCP_Socket_Client_Server_Test(void) +{ + int i; + Client_Param *cparamp; + PRMonitor *mon2; + PRInt32 datalen; + PRInt32 connections = 0; + PRThread *thr; + + datalen = tcp_mesg_size; + connections = 0; + + mon2 = PR_NewMonitor(); + if (mon2 == NULL) { + fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name); + failed_already=1; + return -1; + } + + /* + * Start client jobs + */ + cparamp = PR_NEW(Client_Param); + if (cparamp == NULL) { + fprintf(stderr,"%s: PR_NEW failed\n", program_name); + failed_already=1; + return -1; + } + cparamp->server_addr.inet.family = PR_AF_INET; + cparamp->server_addr.inet.port = PR_htons(server_port); + cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); + cparamp->exit_mon = mon2; + cparamp->exit_counter = &connections; + cparamp->datalen = datalen; + for (i = 0; i < num_tcp_clients; i++) { + thr = PR_CreateThread(PR_USER_THREAD, TCP_Client, (void *)cparamp, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); + if (NULL == thr) { + fprintf(stderr,"%s: PR_CreateThread failed\n", program_name); + failed_already=1; + return -1; + } + PR_EnterMonitor(mon2); + connections++; + PR_ExitMonitor(mon2); + DPRINTF(("Created TCP client = 0x%lx\n", thr)); + } + /* Wait for client jobs to exit */ + PR_EnterMonitor(mon2); + while (0 != connections) { + PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); + DPRINTF(("Client job count = %d\n", connections)); + } + PR_ExitMonitor(mon2); + printf("%30s","TCP_Socket_Client_Server_Test:"); + printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l, + num_tcp_clients, num_tcp_connections_per_client); + printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":", + num_tcp_mesgs_per_connection, tcp_mesg_size); + + PR_DELETE(cparamp); + return 0; +} + +/************************************************************************/ + +int main(int argc, char **argv) +{ + /* + * -d debug mode + */ + PLOptStatus os; + PLOptState *opt; + program_name = argv[0]; + + opt = PL_CreateOptState(argc, argv, "dp:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + case 'p': + server_port = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + PR_SetConcurrency(4); + + TCP_Socket_Client_Server_Test(); + + PR_Cleanup(); + if (failed_already) + return 1; + else + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/thrpool_server.c nspr-4.10.7/nspr/pr/tests/thrpool_server.c --- nspr-4.9.5/nspr/pr/tests/thrpool_server.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/thrpool_server.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,572 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: thrpool.c +** +** Description: Test threadpool functionality. +** +** Modification History: +*/ +#include "primpl.h" + +#include "plgetopt.h" + +#include +#include +#include +#ifdef XP_UNIX +#include +#endif +#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) +#include +#endif + +/* for getcwd */ +#if defined(XP_UNIX) || defined (XP_OS2) || defined(XP_BEOS) +#include +#elif defined(XP_PC) +#include +#endif + +#ifdef WIN32 +#include +#endif + +static int _debug_on = 0; +static char *program_name = NULL; +static void serve_client_write(void *arg); + +#include "obsolete/prsem.h" + +#ifdef XP_PC +#define mode_t int +#endif + +#define DPRINTF(arg) if (_debug_on) printf arg + + +#define BUF_DATA_SIZE (2 * 1024) +#define TCP_MESG_SIZE 1024 +#define NUM_TCP_CLIENTS 10 /* for a listen queue depth of 5 */ + + +#define NUM_TCP_CONNECTIONS_PER_CLIENT 10 +#define NUM_TCP_MESGS_PER_CONNECTION 10 +#define TCP_SERVER_PORT 10000 +#define SERVER_MAX_BIND_COUNT 100 + +#ifdef WINCE +char *getcwd(char *buf, size_t size) +{ + wchar_t wpath[MAX_PATH]; + _wgetcwd(wpath, MAX_PATH); + WideCharToMultiByte(CP_ACP, 0, wpath, -1, buf, size, 0, 0); +} + +#define perror(s) +#endif + +static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS; +static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT; +static PRInt32 tcp_mesg_size = TCP_MESG_SIZE; +static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION; +static void TCP_Server_Accept(void *arg); + + +int failed_already=0; +typedef struct buffer { + char data[BUF_DATA_SIZE]; +} buffer; + + +typedef struct Server_Param { + PRJobIoDesc iod; /* socket to read from/write to */ + PRInt32 datalen; /* bytes of data transfered in each read/write */ + PRNetAddr netaddr; + PRMonitor *exit_mon; /* monitor to signal on exit */ + PRInt32 *job_counterp; /* counter to decrement, before exit */ + PRInt32 conn_counter; /* counter to decrement, before exit */ + PRThreadPool *tp; +} Server_Param; + +typedef struct Serve_Client_Param { + PRJobIoDesc iod; /* socket to read from/write to */ + PRInt32 datalen; /* bytes of data transfered in each read/write */ + PRMonitor *exit_mon; /* monitor to signal on exit */ + PRInt32 *job_counterp; /* counter to decrement, before exit */ + PRThreadPool *tp; +} Serve_Client_Param; + +typedef struct Session { + PRJobIoDesc iod; /* socket to read from/write to */ + buffer *in_buf; + PRInt32 bytes; + PRInt32 msg_num; + PRInt32 bytes_read; + PRMonitor *exit_mon; /* monitor to signal on exit */ + PRInt32 *job_counterp; /* counter to decrement, before exit */ + PRThreadPool *tp; +} Session; + +static void +serve_client_read(void *arg) +{ + Session *sp = (Session *) arg; + int rem; + int bytes; + int offset; + PRFileDesc *sockfd; + char *buf; + PRJob *jobp; + + PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; + + sockfd = sp->iod.socket; + buf = sp->in_buf->data; + + PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection); + PR_ASSERT(sp->bytes_read < sp->bytes); + + offset = sp->bytes_read; + rem = sp->bytes - offset; + bytes = PR_Recv(sockfd, buf + offset, rem, 0, timeout); + if (bytes < 0) { + return; + } + sp->bytes_read += bytes; + sp->iod.timeout = PR_SecondsToInterval(60); + if (sp->bytes_read < sp->bytes) { + jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp, + PR_FALSE); + PR_ASSERT(NULL != jobp); + return; + } + PR_ASSERT(sp->bytes_read == sp->bytes); + DPRINTF(("serve_client: read complete, msg(%d) \n", sp->msg_num)); + + sp->iod.timeout = PR_SecondsToInterval(60); + jobp = PR_QueueJob_Write(sp->tp, &sp->iod, serve_client_write, sp, + PR_FALSE); + PR_ASSERT(NULL != jobp); + + return; +} + +static void +serve_client_write(void *arg) +{ + Session *sp = (Session *) arg; + int bytes; + PRFileDesc *sockfd; + char *buf; + PRJob *jobp; + + sockfd = sp->iod.socket; + buf = sp->in_buf->data; + + PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection); + + bytes = PR_Send(sockfd, buf, sp->bytes, 0, PR_INTERVAL_NO_TIMEOUT); + PR_ASSERT(bytes == sp->bytes); + + if (bytes < 0) { + return; + } + DPRINTF(("serve_client: write complete, msg(%d) \n", sp->msg_num)); + sp->msg_num++; + if (sp->msg_num < num_tcp_mesgs_per_connection) { + sp->bytes_read = 0; + sp->iod.timeout = PR_SecondsToInterval(60); + jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp, + PR_FALSE); + PR_ASSERT(NULL != jobp); + return; + } + + DPRINTF(("serve_client: read/write complete, msg(%d) \n", sp->msg_num)); + if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { + fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name); + } + + PR_Close(sockfd); + PR_EnterMonitor(sp->exit_mon); + --(*sp->job_counterp); + PR_Notify(sp->exit_mon); + PR_ExitMonitor(sp->exit_mon); + + PR_DELETE(sp->in_buf); + PR_DELETE(sp); + + return; +} + +/* + * Serve_Client + * Thread, started by the server, for serving a client connection. + * Reads data from socket and writes it back, unmodified, and + * closes the socket + */ +static void PR_CALLBACK +Serve_Client(void *arg) +{ + Serve_Client_Param *scp = (Serve_Client_Param *) arg; + buffer *in_buf; + Session *sp; + PRJob *jobp; + + sp = PR_NEW(Session); + sp->iod = scp->iod; + + in_buf = PR_NEW(buffer); + if (in_buf == NULL) { + fprintf(stderr,"%s: failed to alloc buffer struct\n",program_name); + failed_already=1; + return; + } + + sp->in_buf = in_buf; + sp->bytes = scp->datalen; + sp->msg_num = 0; + sp->bytes_read = 0; + sp->tp = scp->tp; + sp->exit_mon = scp->exit_mon; + sp->job_counterp = scp->job_counterp; + + sp->iod.timeout = PR_SecondsToInterval(60); + jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp, + PR_FALSE); + PR_ASSERT(NULL != jobp); + PR_DELETE(scp); +} + +static void +print_stats(void *arg) +{ + Server_Param *sp = (Server_Param *) arg; + PRThreadPool *tp = sp->tp; + PRInt32 counter; + PRJob *jobp; + + PR_EnterMonitor(sp->exit_mon); + counter = (*sp->job_counterp); + PR_ExitMonitor(sp->exit_mon); + + printf("PRINT_STATS: #client connections = %d\n",counter); + + + jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(500), + print_stats, sp, PR_FALSE); + + PR_ASSERT(NULL != jobp); +} + +static int job_counter = 0; +/* + * TCP Server + * Server binds an address to a socket, starts a client process and + * listens for incoming connections. + * Each client connects to the server and sends a chunk of data + * Starts a Serve_Client job for each incoming connection, to read + * the data from the client and send it back to the client, unmodified. + * Each client checks that data received from server is same as the + * data it sent to the server. + * Finally, the threadpool is shutdown + */ +static void PR_CALLBACK +TCP_Server(void *arg) +{ + PRThreadPool *tp = (PRThreadPool *) arg; + Server_Param *sp; + PRFileDesc *sockfd; + PRNetAddr netaddr; + PRMonitor *sc_mon; + PRJob *jobp; + int i; + PRStatus rval; + + /* + * Create a tcp socket + */ + if ((sockfd = PR_NewTCPSocket()) == NULL) { + fprintf(stderr,"%s: PR_NewTCPSocket failed\n", program_name); + return; + } + memset(&netaddr, 0 , sizeof(netaddr)); + netaddr.inet.family = PR_AF_INET; + netaddr.inet.port = PR_htons(TCP_SERVER_PORT); + netaddr.inet.ip = PR_htonl(PR_INADDR_ANY); + /* + * try a few times to bind server's address, if addresses are in + * use + */ + i = 0; + while (PR_Bind(sockfd, &netaddr) < 0) { + if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { + netaddr.inet.port += 2; + if (i++ < SERVER_MAX_BIND_COUNT) + continue; + } + fprintf(stderr,"%s: ERROR - PR_Bind failed\n", program_name); + perror("PR_Bind"); + failed_already=1; + return; + } + + if (PR_Listen(sockfd, 32) < 0) { + fprintf(stderr,"%s: ERROR - PR_Listen failed\n", program_name); + failed_already=1; + return; + } + + if (PR_GetSockName(sockfd, &netaddr) < 0) { + fprintf(stderr,"%s: ERROR - PR_GetSockName failed\n", program_name); + failed_already=1; + return; + } + + DPRINTF(( + "TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", + netaddr.inet.ip, netaddr.inet.port)); + + sp = PR_NEW(Server_Param); + if (sp == NULL) { + fprintf(stderr,"%s: PR_NEW failed\n", program_name); + failed_already=1; + return; + } + sp->iod.socket = sockfd; + sp->iod.timeout = PR_SecondsToInterval(60); + sp->datalen = tcp_mesg_size; + sp->exit_mon = sc_mon; + sp->job_counterp = &job_counter; + sp->conn_counter = 0; + sp->tp = tp; + sp->netaddr = netaddr; + + /* create and cancel an io job */ + jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp, + PR_FALSE); + PR_ASSERT(NULL != jobp); + rval = PR_CancelJob(jobp); + PR_ASSERT(PR_SUCCESS == rval); + + /* + * create the client process + */ + { +#define MAX_ARGS 4 + char *argv[MAX_ARGS + 1]; + int index = 0; + char port[32]; + char path[1024 + sizeof("/thrpool_client")]; + + getcwd(path, sizeof(path)); + + (void)strcat(path, "/thrpool_client"); +#ifdef XP_PC + (void)strcat(path, ".exe"); +#endif + argv[index++] = path; + sprintf(port,"%d",PR_ntohs(netaddr.inet.port)); + if (_debug_on) + { + argv[index++] = "-d"; + argv[index++] = "-p"; + argv[index++] = port; + argv[index++] = NULL; + } else { + argv[index++] = "-p"; + argv[index++] = port; + argv[index++] = NULL; + } + PR_ASSERT(MAX_ARGS >= (index - 1)); + + DPRINTF(("creating client process %s ...\n", path)); + if (PR_FAILURE == PR_CreateProcessDetached(path, argv, NULL, NULL)) { + fprintf(stderr, + "thrpool_server: ERROR - PR_CreateProcessDetached failed\n"); + failed_already=1; + return; + } + } + + sc_mon = PR_NewMonitor(); + if (sc_mon == NULL) { + fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name); + failed_already=1; + return; + } + + sp->iod.socket = sockfd; + sp->iod.timeout = PR_SecondsToInterval(60); + sp->datalen = tcp_mesg_size; + sp->exit_mon = sc_mon; + sp->job_counterp = &job_counter; + sp->conn_counter = 0; + sp->tp = tp; + sp->netaddr = netaddr; + + /* create and cancel a timer job */ + jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(5000), + print_stats, sp, PR_FALSE); + PR_ASSERT(NULL != jobp); + rval = PR_CancelJob(jobp); + PR_ASSERT(PR_SUCCESS == rval); + + DPRINTF(("TCP_Server: Accepting connections \n")); + + jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp, + PR_FALSE); + PR_ASSERT(NULL != jobp); + return; +} + +static void +TCP_Server_Accept(void *arg) +{ + Server_Param *sp = (Server_Param *) arg; + PRThreadPool *tp = sp->tp; + Serve_Client_Param *scp; + PRFileDesc *newsockfd; + PRJob *jobp; + + if ((newsockfd = PR_Accept(sp->iod.socket, &sp->netaddr, + PR_INTERVAL_NO_TIMEOUT)) == NULL) { + fprintf(stderr,"%s: ERROR - PR_Accept failed\n", program_name); + failed_already=1; + goto exit; + } + scp = PR_NEW(Serve_Client_Param); + if (scp == NULL) { + fprintf(stderr,"%s: PR_NEW failed\n", program_name); + failed_already=1; + goto exit; + } + + /* + * Start a Serve_Client job for each incoming connection + */ + scp->iod.socket = newsockfd; + scp->iod.timeout = PR_SecondsToInterval(60); + scp->datalen = tcp_mesg_size; + scp->exit_mon = sp->exit_mon; + scp->job_counterp = sp->job_counterp; + scp->tp = sp->tp; + + PR_EnterMonitor(sp->exit_mon); + (*sp->job_counterp)++; + PR_ExitMonitor(sp->exit_mon); + jobp = PR_QueueJob(tp, Serve_Client, scp, + PR_FALSE); + + PR_ASSERT(NULL != jobp); + DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", jobp)); + + /* + * single-threaded update; no lock needed + */ + sp->conn_counter++; + if (sp->conn_counter < + (num_tcp_clients * num_tcp_connections_per_client)) { + jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp, + PR_FALSE); + PR_ASSERT(NULL != jobp); + return; + } + jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(500), + print_stats, sp, PR_FALSE); + + PR_ASSERT(NULL != jobp); + DPRINTF(("TCP_Server: Created print_stats timer job = 0x%lx\n", jobp)); + +exit: + PR_EnterMonitor(sp->exit_mon); + /* Wait for server jobs to finish */ + while (0 != *sp->job_counterp) { + PR_Wait(sp->exit_mon, PR_INTERVAL_NO_TIMEOUT); + DPRINTF(("TCP_Server: conn_counter = %d\n", + *sp->job_counterp)); + } + + PR_ExitMonitor(sp->exit_mon); + if (sp->iod.socket) { + PR_Close(sp->iod.socket); + } + PR_DestroyMonitor(sp->exit_mon); + printf("%30s","TCP_Socket_Client_Server_Test:"); + printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l, + num_tcp_clients, num_tcp_connections_per_client); + printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":", + num_tcp_mesgs_per_connection, tcp_mesg_size); + + DPRINTF(("%s: calling PR_ShutdownThreadPool\n", program_name)); + PR_ShutdownThreadPool(sp->tp); + PR_DELETE(sp); +} + +/************************************************************************/ + +#define DEFAULT_INITIAL_THREADS 4 +#define DEFAULT_MAX_THREADS 100 +#define DEFAULT_STACKSIZE (512 * 1024) + +int main(int argc, char **argv) +{ + PRInt32 initial_threads = DEFAULT_INITIAL_THREADS; + PRInt32 max_threads = DEFAULT_MAX_THREADS; + PRInt32 stacksize = DEFAULT_STACKSIZE; + PRThreadPool *tp = NULL; + PRStatus rv; + PRJob *jobp; + + /* + * -d debug mode + */ + PLOptStatus os; + PLOptState *opt; + + program_name = argv[0]; + opt = PL_CreateOptState(argc, argv, "d"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + PR_SetConcurrency(4); + + tp = PR_CreateThreadPool(initial_threads, max_threads, stacksize); + if (NULL == tp) { + printf("PR_CreateThreadPool failed\n"); + failed_already=1; + goto done; + } + jobp = PR_QueueJob(tp, TCP_Server, tp, PR_TRUE); + rv = PR_JoinJob(jobp); + PR_ASSERT(PR_SUCCESS == rv); + + DPRINTF(("%s: calling PR_JoinThreadPool\n", program_name)); + rv = PR_JoinThreadPool(tp); + PR_ASSERT(PR_SUCCESS == rv); + DPRINTF(("%s: returning from PR_JoinThreadPool\n", program_name)); + +done: + PR_Cleanup(); + if (failed_already) return 1; + else return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/thruput.c nspr-4.10.7/nspr/pr/tests/thruput.c --- nspr-4.9.5/nspr/pr/tests/thruput.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/thruput.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,379 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: thruput.c +** Description: Test server's throughput capability comparing various +** implmentation strategies. +** +** Note: Requires a server machine and an aribitrary number of +** clients to bang on it. Trust the numbers on the server +** more than those being displayed by the various clients. +*/ + +#include "prerror.h" +#include "prinrval.h" +#include "prinit.h" +#include "prio.h" +#include "prlock.h" +#include "prmem.h" +#include "prnetdb.h" +#include "prprf.h" +#include "prthread.h" +#include "pprio.h" +#include "plerror.h" +#include "plgetopt.h" + +#define ADDR_BUFFER 100 +#define PORT_NUMBER 51877 +#define SAMPLING_INTERVAL 10 +#define BUFFER_SIZE (32 * 1024) + +static PRInt32 domain = PR_AF_INET; +static PRInt32 protocol = 6; /* TCP */ +static PRFileDesc *err = NULL; +static PRIntn concurrency = 1; +static PRInt32 xport_buffer = -1; +static PRUint32 initial_streams = 1; +static PRInt32 buffer_size = BUFFER_SIZE; +static PRThreadScope thread_scope = PR_LOCAL_THREAD; + +typedef struct Shared +{ + PRLock *ml; + PRUint32 sampled; + PRUint32 threads; + PRIntervalTime timein; + PRNetAddr server_address; +} Shared; + +static Shared *shared = NULL; + +static PRStatus PrintAddress(const PRNetAddr* address) +{ + char buffer[ADDR_BUFFER]; + PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); + if (PR_SUCCESS == rv) + PR_fprintf(err, "%s:%u\n", buffer, PR_ntohs(address->inet.port)); + else PL_FPrintError(err, "PR_NetAddrToString"); + return rv; +} /* PrintAddress */ + + +static void PR_CALLBACK Clientel(void *arg) +{ + PRStatus rv; + PRFileDesc *xport; + PRInt32 bytes, sampled; + PRIntervalTime now, interval; + PRBool do_display = PR_FALSE; + Shared *shared = (Shared*)arg; + char *buffer = (char*)PR_Malloc(buffer_size); + PRNetAddr *server_address = &shared->server_address; + PRIntervalTime connect_timeout = PR_SecondsToInterval(5); + PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL); + + PR_fprintf(err, "Client connecting to "); + (void)PrintAddress(server_address); + + do + { + xport = PR_Socket(domain, PR_SOCK_STREAM, protocol); + if (NULL == xport) + { + PL_FPrintError(err, "PR_Socket"); + return; + } + + if (xport_buffer != -1) + { + PRSocketOptionData data; + data.option = PR_SockOpt_RecvBufferSize; + data.value.recv_buffer_size = (PRSize)xport_buffer; + rv = PR_SetSocketOption(xport, &data); + if (PR_FAILURE == rv) + PL_FPrintError(err, "PR_SetSocketOption - ignored"); + data.option = PR_SockOpt_SendBufferSize; + data.value.send_buffer_size = (PRSize)xport_buffer; + rv = PR_SetSocketOption(xport, &data); + if (PR_FAILURE == rv) + PL_FPrintError(err, "PR_SetSocketOption - ignored"); + } + + rv = PR_Connect(xport, server_address, connect_timeout); + if (PR_FAILURE == rv) + { + PL_FPrintError(err, "PR_Connect"); + if (PR_IO_TIMEOUT_ERROR != PR_GetError()) + PR_Sleep(connect_timeout); + PR_Close(xport); /* delete it and start over */ + } + } while (PR_FAILURE == rv); + + do + { + bytes = PR_Recv( + xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT); + PR_Lock(shared->ml); + now = PR_IntervalNow(); + shared->sampled += bytes; + interval = now - shared->timein; + if (interval > sampling_interval) + { + sampled = shared->sampled; + shared->timein = now; + shared->sampled = 0; + do_display = PR_TRUE; + } + PR_Unlock(shared->ml); + + if (do_display) + { + PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval); + PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate); + do_display = PR_FALSE; + } + + } while (bytes > 0); +} /* Clientel */ + +static void Client(const char *server_name) +{ + PRStatus rv; + PRHostEnt host; + char buffer[PR_NETDB_BUF_SIZE]; + PRIntervalTime dally = PR_SecondsToInterval(60); + PR_fprintf(err, "Translating the name %s\n", server_name); + rv = PR_GetHostByName(server_name, buffer, sizeof(buffer), &host); + if (PR_FAILURE == rv) + PL_FPrintError(err, "PR_GetHostByName"); + else + { + if (PR_EnumerateHostEnt( + 0, &host, PORT_NUMBER, &shared->server_address) < 0) + PL_FPrintError(err, "PR_EnumerateHostEnt"); + else + { + do + { + shared->threads += 1; + (void)PR_CreateThread( + PR_USER_THREAD, Clientel, shared, + PR_PRIORITY_NORMAL, thread_scope, + PR_UNJOINABLE_THREAD, 8 * 1024); + if (shared->threads == initial_streams) + { + PR_Sleep(dally); + initial_streams += 1; + } + } while (PR_TRUE); + } + } +} + +static void PR_CALLBACK Servette(void *arg) +{ + PRInt32 bytes, sampled; + PRIntervalTime now, interval; + PRBool do_display = PR_FALSE; + PRFileDesc *client = (PRFileDesc*)arg; + char *buffer = (char*)PR_Malloc(buffer_size); + PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL); + + if (xport_buffer != -1) + { + PRStatus rv; + PRSocketOptionData data; + data.option = PR_SockOpt_RecvBufferSize; + data.value.recv_buffer_size = (PRSize)xport_buffer; + rv = PR_SetSocketOption(client, &data); + if (PR_FAILURE == rv) + PL_FPrintError(err, "PR_SetSocketOption - ignored"); + data.option = PR_SockOpt_SendBufferSize; + data.value.send_buffer_size = (PRSize)xport_buffer; + rv = PR_SetSocketOption(client, &data); + if (PR_FAILURE == rv) + PL_FPrintError(err, "PR_SetSocketOption - ignored"); + } + + do + { + bytes = PR_Send( + client, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT); + + PR_Lock(shared->ml); + now = PR_IntervalNow(); + shared->sampled += bytes; + interval = now - shared->timein; + if (interval > sampling_interval) + { + sampled = shared->sampled; + shared->timein = now; + shared->sampled = 0; + do_display = PR_TRUE; + } + PR_Unlock(shared->ml); + + if (do_display) + { + PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval); + PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate); + do_display = PR_FALSE; + } + } while (bytes > 0); +} /* Servette */ + +static void Server(void) +{ + PRStatus rv; + PRNetAddr server_address, client_address; + PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol); + + if (NULL == xport) + { + PL_FPrintError(err, "PR_Socket"); + return; + } + + rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER, &server_address); + if (PR_FAILURE == rv) PL_FPrintError(err, "PR_InitializeNetAddr"); + else + { + rv = PR_Bind(xport, &server_address); + if (PR_FAILURE == rv) PL_FPrintError(err, "PR_Bind"); + else + { + PRFileDesc *client; + rv = PR_Listen(xport, 10); + PR_fprintf(err, "Server listening on "); + (void)PrintAddress(&server_address); + do + { + client = PR_Accept( + xport, &client_address, PR_INTERVAL_NO_TIMEOUT); + if (NULL == client) PL_FPrintError(err, "PR_Accept"); + else + { + PR_fprintf(err, "Server accepting from "); + (void)PrintAddress(&client_address); + shared->threads += 1; + (void)PR_CreateThread( + PR_USER_THREAD, Servette, client, + PR_PRIORITY_NORMAL, thread_scope, + PR_UNJOINABLE_THREAD, 8 * 1024); + } + } while (PR_TRUE); + + } + } +} /* Server */ + +static void Help(void) +{ + PR_fprintf(err, "Usage: [-h] []\n"); + PR_fprintf(err, "\t-s Initial # of connections (default: 1)\n"); + PR_fprintf(err, "\t-C Set 'concurrency' (default: 1)\n"); + PR_fprintf(err, "\t-b Client buffer size (default: 32k)\n"); + PR_fprintf(err, "\t-B Transport recv/send buffer size (default: sys)\n"); + PR_fprintf(err, "\t-G Use GLOBAL threads (default: LOCAL)\n"); + PR_fprintf(err, "\t-X Use XTP transport (default: TCP)\n"); + PR_fprintf(err, "\t-6 Use IPv6 (default: IPv4)\n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); + PR_fprintf(err, "\t DNS name of server\n"); + PR_fprintf(err, "\t\tIf is not specified, this host will be\n"); + PR_fprintf(err, "\t\tthe server and not act as a client.\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + const char *server_name = NULL; + PLOptState *opt = PL_CreateOptState(argc, argv, "hGX6C:b:s:B:"); + + err = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: /* Name of server */ + server_name = opt->value; + break; + case 'G': /* Globular threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'X': /* Use XTP as the transport */ + protocol = 36; + break; + case '6': /* Use IPv6 */ + domain = PR_AF_INET6; + break; + case 's': /* initial_streams */ + initial_streams = atoi(opt->value); + break; + case 'C': /* concurrency */ + concurrency = atoi(opt->value); + break; + case 'b': /* buffer size */ + buffer_size = 1024 * atoi(opt->value); + break; + case 'B': /* buffer size */ + xport_buffer = 1024 * atoi(opt->value); + break; + case 'h': /* user wants some guidance */ + default: + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + } + } + PL_DestroyOptState(opt); + + shared = PR_NEWZAP(Shared); + shared->ml = PR_NewLock(); + + PR_fprintf(err, + "This machine is %s\n", + (NULL == server_name) ? "the SERVER" : "a CLIENT"); + + PR_fprintf(err, + "Transport being used is %s\n", + (6 == protocol) ? "TCP" : "XTP"); + + if (PR_GLOBAL_THREAD == thread_scope) + { + if (1 != concurrency) + { + PR_fprintf(err, " **Concurrency > 1 and GLOBAL threads!?!?\n"); + PR_fprintf(err, " **Ignoring concurrency\n"); + concurrency = 1; + } + } + + if (1 != concurrency) + { + PR_SetConcurrency(concurrency); + PR_fprintf(err, "Concurrency set to %u\n", concurrency); + } + + PR_fprintf(err, + "All threads will be %s\n", + (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); + + PR_fprintf(err, "Client buffer size will be %u\n", buffer_size); + + if (-1 != xport_buffer) + PR_fprintf( + err, "Transport send & receive buffer size will be %u\n", xport_buffer); + + + if (NULL == server_name) Server(); + else Client(server_name); + + return 0; +} /* main */ + +/* thruput.c */ + diff -Nru nspr-4.9.5/nspr/pr/tests/time.c nspr-4.10.7/nspr/pr/tests/time.c --- nspr-4.9.5/nspr/pr/tests/time.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/time.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,169 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Program to test different ways to get the time; right now it is tuned + * only for solaris. + * solaris results (100000 iterations): + * time to get time with time(): 4.63 usec avg, 463 msec total + * time to get time with gethrtime(): 2.17 usec avg, 217 msec total + * time to get time with gettimeofday(): 1.25 usec avg, 125 msec total + * + * + */ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include "prpriv.h" +#include "prinrval.h" + +#include +#include +#include +#include + +#define DEFAULT_COUNT 100000 +PRInt32 count; + +time_t itime; +hrtime_t ihrtime; + +void +ftime_init() +{ + itime = time(NULL); + ihrtime = gethrtime(); +} + +time_t +ftime() +{ + hrtime_t now = gethrtime(); + + return itime + ((now - ihrtime) / 1000000000ll); +} + +static void timeTime(void) +{ + PRInt32 index = count; + time_t rv; + + for (;index--;) + rv = time(NULL); +} + +static void timeGethrtime(void) +{ + PRInt32 index = count; + time_t rv; + + for (;index--;) + rv = ftime(); +} + +static void timeGettimeofday(void) +{ + PRInt32 index = count; + time_t rv; + struct timeval tp; + + for (;index--;) + rv = gettimeofday(&tp, NULL); +} + +static void timePRTime32(void) +{ + PRInt32 index = count; + PRInt32 rv32; + PRTime q; + PRTime rv; + + LL_I2L(q, 1000000); + + for (;index--;) { + rv = PR_Now(); + LL_DIV(rv, rv, q); + LL_L2I(rv32, rv); + } +} + +static void timePRTime64(void) +{ + PRInt32 index = count; + PRTime rv; + + for (;index--;) + rv = PR_Now(); +} + +/************************************************************************/ + +static void Measure(void (*func)(void), const char *msg) +{ + PRIntervalTime start, stop; + double d; + PRInt32 tot; + + start = PR_IntervalNow(); + (*func)(); + stop = PR_IntervalNow(); + + d = (double)PR_IntervalToMicroseconds(stop - start); + tot = PR_IntervalToMilliseconds(stop-start); + + if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot); +} + +int main(int argc, char **argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + + if (argc > 1) { + count = atoi(argv[1]); + } else { + count = DEFAULT_COUNT; + } + + ftime_init(); + + Measure(timeTime, "time to get time with time()"); + Measure(timeGethrtime, "time to get time with gethrtime()"); + Measure(timeGettimeofday, "time to get time with gettimeofday()"); + Measure(timePRTime32, "time to get time with PR_Time() (32bit)"); + Measure(timePRTime64, "time to get time with PR_Time() (64bit)"); + + PR_Cleanup(); + return 0; +} + + + diff -Nru nspr-4.9.5/nspr/pr/tests/timemac.c nspr-4.10.7/nspr/pr/tests/timemac.c --- nspr-4.9.5/nspr/pr/tests/timemac.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/timemac.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * file: timemac.c + * description: test time and date routines on the Mac + */ +#include +#include "prinit.h" +#include "prtime.h" + + +static char *dayOfWeek[] = + { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; +static char *month[] = + { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; + +static void printExplodedTime(const PRExplodedTime *et) { + PRInt32 totalOffset; + PRInt32 hourOffset, minOffset; + const char *sign; + + /* Print day of the week, month, day, hour, minute, and second */ + printf( "%s %s %ld %02ld:%02ld:%02ld ", + dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, + et->tm_hour, et->tm_min, et->tm_sec); + + /* Print time zone */ + totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; + if (totalOffset == 0) { + printf("UTC "); + } else { + sign = ""; + if (totalOffset < 0) { + totalOffset = -totalOffset; + sign = "-"; + } + hourOffset = totalOffset / 3600; + minOffset = (totalOffset % 3600) / 60; + printf("%s%02ld%02ld ", sign, hourOffset, minOffset); + } + + /* Print year */ + printf("%d", et->tm_year); +} + +int main(int argc, char** argv) +{ + PR_STDIO_INIT(); + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + + + /* + ************************************************************* + ** + ** Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime + ** on the current time + ** + ************************************************************* + */ + + { + PRTime t1, t2; + PRExplodedTime et; + + printf("*********************************************\n"); + printf("** **\n"); + printf("** Testing PR_Now(), PR_ExplodeTime, and **\n"); + printf("** PR_ImplodeTime on the current time **\n"); + printf("** **\n"); + printf("*********************************************\n\n"); + t1 = PR_Now(); + + /* First try converting to UTC */ + + PR_ExplodeTime(t1, PR_GMTParameters, &et); + if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) { + printf("ERROR: UTC has nonzero gmt or dst offset.\n"); + return 1; + } + printf("Current UTC is "); + printExplodedTime(&et); + printf("\n"); + + t2 = PR_ImplodeTime(&et); + if (LL_NE(t1, t2)) { + printf("ERROR: Explode and implode are NOT inverse.\n"); + return 1; + } + + /* Next, try converting to local (US Pacific) time */ + + PR_ExplodeTime(t1, PR_LocalTimeParameters, &et); + printf("Current local time is "); + printExplodedTime(&et); + printf("\n"); + printf("GMT offset is %ld, DST offset is %ld\n", + et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset); + t2 = PR_ImplodeTime(&et); + if (LL_NE(t1, t2)) { + printf("ERROR: Explode and implode are NOT inverse.\n"); + return 1; + } + } + + printf("Please examine the results\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/timetest.c nspr-4.10.7/nspr/pr/tests/timetest.c --- nspr-4.9.5/nspr/pr/tests/timetest.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/timetest.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,739 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * file: timetest.c + * description: test time and date routines + */ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prinit.h" +#include "prtime.h" +#include "prprf.h" + +#include +#include +#include + +int failed_already=0; +PRBool debug_mode = PR_FALSE; + +static char *dayOfWeek[] = + { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; +static char *month[] = + { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; + +static void PrintExplodedTime(const PRExplodedTime *et) { + PRInt32 totalOffset; + PRInt32 hourOffset, minOffset; + const char *sign; + + /* Print day of the week, month, day, hour, minute, and second */ + if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ", + dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, + et->tm_hour, et->tm_min, et->tm_sec); + + /* Print time zone */ + totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; + if (totalOffset == 0) { + if (debug_mode) printf("UTC "); + } else { + sign = "+"; + if (totalOffset < 0) { + totalOffset = -totalOffset; + sign = "-"; + } + hourOffset = totalOffset / 3600; + minOffset = (totalOffset % 3600) / 60; + if (debug_mode) + printf("%s%02ld%02ld ", sign, hourOffset, minOffset); + } + + /* Print year */ + if (debug_mode) printf("%hd", et->tm_year); +} + +static int ExplodedTimeIsEqual(const PRExplodedTime *et1, + const PRExplodedTime *et2) +{ + if (et1->tm_usec == et2->tm_usec && + et1->tm_sec == et2->tm_sec && + et1->tm_min == et2->tm_min && + et1->tm_hour == et2->tm_hour && + et1->tm_mday == et2->tm_mday && + et1->tm_month == et2->tm_month && + et1->tm_year == et2->tm_year && + et1->tm_wday == et2->tm_wday && + et1->tm_yday == et2->tm_yday && + et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset && + et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) { + return 1; + } else { + return 0; + } +} + +static void +testParseTimeString(PRTime t) +{ + PRExplodedTime et; + PRTime t2; + char timeString[128]; + char buf[128]; + PRInt32 totalOffset; + PRInt32 hourOffset, minOffset; + const char *sign; + PRInt64 usec_per_sec; + + /* Truncate the microsecond part of PRTime */ + LL_I2L(usec_per_sec, PR_USEC_PER_SEC); + LL_DIV(t, t, usec_per_sec); + LL_MUL(t, t, usec_per_sec); + + PR_ExplodeTime(t, PR_LocalTimeParameters, &et); + + /* Print day of the week, month, day, hour, minute, and second */ + PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ", + dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday, + et.tm_hour, et.tm_min, et.tm_sec); + /* Print time zone */ + totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset; + if (totalOffset == 0) { + strcat(timeString, "GMT "); /* I wanted to use "UTC" here, but + * PR_ParseTimeString doesn't + * understand "UTC". */ + } else { + sign = "+"; + if (totalOffset < 0) { + totalOffset = -totalOffset; + sign = "-"; + } + hourOffset = totalOffset / 3600; + minOffset = (totalOffset % 3600) / 60; + PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset); + strcat(timeString, buf); + } + /* Print year */ + PR_snprintf(buf, 128, "%hd", et.tm_year); + strcat(timeString, buf); + + if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) { + fprintf(stderr, "PR_ParseTimeString() failed\n"); + exit(1); + } + if (LL_NE(t, t2)) { + fprintf(stderr, "PR_ParseTimeString() incorrect\n"); + PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n", + t, t2, timeString); + fprintf(stderr, "%s\n", buf); + exit(1); + } +} + +int main(int argc, char** argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt; + + PR_STDIO_INIT(); + opt = PL_CreateOptState(argc, argv, "d"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + + /* Testing zero PRTime (the epoch) */ + { + PRTime t; + PRExplodedTime et; + + LL_I2L(t, 0); + if (debug_mode) printf("The NSPR epoch is:\n"); + PR_ExplodeTime(t, PR_LocalTimeParameters, &et); + PrintExplodedTime(&et); + if (debug_mode) printf("\n"); + PR_ExplodeTime(t, PR_GMTParameters, &et); + PrintExplodedTime(&et); + if (debug_mode) printf("\n\n"); + testParseTimeString(t); + } + + /* + ************************************************************* + ** + ** Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime + ** on the current time + ** + ************************************************************* + */ + + { + PRTime t1, t2; + PRExplodedTime et; + + if (debug_mode) { + printf("*********************************************\n"); + printf("** **\n"); + printf("** Testing PR_Now(), PR_ExplodeTime, and **\n"); + printf("** PR_ImplodeTime on the current time **\n"); + printf("** **\n"); + printf("*********************************************\n\n"); + } + t1 = PR_Now(); + + /* First try converting to UTC */ + + PR_ExplodeTime(t1, PR_GMTParameters, &et); + if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) { + if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n"); + else failed_already=1; + return 1; + } + if (debug_mode) printf("Current UTC is "); + PrintExplodedTime(&et); + if (debug_mode) printf("\n"); + + t2 = PR_ImplodeTime(&et); + if (LL_NE(t1, t2)) { + if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n"); + else printf("FAIL\n"); + return 1; + } + + /* Next, try converting to local (US Pacific) time */ + + PR_ExplodeTime(t1, PR_LocalTimeParameters, &et); + if (debug_mode) printf("Current local time is "); + PrintExplodedTime(&et); + if (debug_mode) printf("\n"); + if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n", + et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset); + t2 = PR_ImplodeTime(&et); + if (LL_NE(t1, t2)) { + if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n"); + return 1; + } + + if (debug_mode) printf("Please examine the results\n"); + testParseTimeString(t1); + } + + + /* + ******************************************* + ** + ** Testing PR_NormalizeTime() + ** + ******************************************* + */ + + /* July 4, 2001 is Wednesday */ + { + PRExplodedTime et; + + if (debug_mode) { + printf("\n"); + printf("**********************************\n"); + printf("** **\n"); + printf("** Testing PR_NormalizeTime() **\n"); + printf("** **\n"); + printf("**********************************\n\n"); + } + et.tm_year = 2001; + et.tm_month = 7 - 1; + et.tm_mday = 4; + et.tm_hour = 0; + et.tm_min = 0; + et.tm_sec = 0; + et.tm_usec = 0; + et.tm_params = PR_GMTParameters(&et); + + PR_NormalizeTime(&et, PR_GMTParameters); + + if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]); + if (et.tm_wday == 3) { + if (debug_mode) printf("PASS\n"); + } else { + if (debug_mode) printf("ERROR: It should be Wednesday\n"); + else failed_already=1; + return 1; + } + testParseTimeString(PR_ImplodeTime(&et)); + + /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */ + et.tm_year = 1997; + et.tm_month = 6 - 1; + et.tm_mday = 12; + et.tm_hour = 23; + et.tm_min = 0; + et.tm_sec = 0; + et.tm_usec = 0; + et.tm_params.tp_gmt_offset = -8 * 3600; + et.tm_params.tp_dst_offset = 0; + + PR_NormalizeTime(&et, PR_USPacificTimeParameters); + + if (debug_mode) { + printf("Thu Jun 12, 1997 23:00:00 PST is "); + } + PrintExplodedTime(&et); + if (debug_mode) printf(".\n"); + if (et.tm_wday == 5) { + if (debug_mode) printf("PASS\n"); + } else { + if (debug_mode) printf("ERROR: It should be Friday\n"); + else failed_already=1; + return 1; + } + testParseTimeString(PR_ImplodeTime(&et)); + + /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */ + et.tm_year = 1997; + et.tm_month = 2 - 1; + et.tm_mday = 14; + et.tm_hour = 0; + et.tm_min = 0; + et.tm_sec = 0; + et.tm_usec = 0; + et.tm_params.tp_gmt_offset = -8 * 3600; + et.tm_params.tp_dst_offset = 3600; + + PR_NormalizeTime(&et, PR_USPacificTimeParameters); + + if (debug_mode) { + printf("Fri Feb 14, 1997 00:00:00 PDT is "); + } + PrintExplodedTime(&et); + if (debug_mode) printf(".\n"); + if (et.tm_wday == 4) { + if (debug_mode) printf("PASS\n"); + } else { + if (debug_mode) printf("ERROR: It should be Thursday\n"); + else failed_already=1; + return 1; + } + testParseTimeString(PR_ImplodeTime(&et)); + + /* What time is Nov. 7, 1996, 18:29:23 PDT? */ + et.tm_year = 1996; + et.tm_month = 11 - 1; + et.tm_mday = 7; + et.tm_hour = 18; + et.tm_min = 29; + et.tm_sec = 23; + et.tm_usec = 0; + et.tm_params.tp_gmt_offset = -8 * 3600; /* PDT */ + et.tm_params.tp_dst_offset = 3600; + + PR_NormalizeTime(&et, PR_LocalTimeParameters); + if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is "); + PrintExplodedTime(&et); + if (debug_mode) printf(".\n"); + testParseTimeString(PR_ImplodeTime(&et)); + + /* What time is Oct. 7, 1995, 18:29:23 PST? */ + et.tm_year = 1995; + et.tm_month = 10 - 1; + et.tm_mday = 7; + et.tm_hour = 18; + et.tm_min = 29; + et.tm_sec = 23; + et.tm_params.tp_gmt_offset = -8 * 3600; /* PST */ + et.tm_params.tp_dst_offset = 0; + + PR_NormalizeTime(&et, PR_LocalTimeParameters); + if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is "); + PrintExplodedTime(&et); + if (debug_mode) printf(".\n"); + testParseTimeString(PR_ImplodeTime(&et)); + + if (debug_mode) printf("Please examine the results\n"); + } + + /* + ************************************************************** + ** + ** Testing range of years + ** + ************************************************************** + */ + + { + PRExplodedTime et1, et2; + PRTime ttt; + PRTime secs; + + if (debug_mode) { + printf("\n"); + printf("***************************************\n"); + printf("** **\n"); + printf("** Testing range of years **\n"); + printf("** **\n"); + printf("***************************************\n\n"); + } + /* April 4, 1917 GMT */ + et1.tm_usec = 0; + et1.tm_sec = 0; + et1.tm_min = 0; + et1.tm_hour = 0; + et1.tm_mday = 4; + et1.tm_month = 4 - 1; + et1.tm_year = 1917; + et1.tm_params = PR_GMTParameters(&et1); + PR_NormalizeTime(&et1, PR_LocalTimeParameters); + secs = PR_ImplodeTime(&et1); + if (LL_GE_ZERO(secs)) { + if (debug_mode) + printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n"); + failed_already = 1; + return 1; + } + PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2); + if (!ExplodedTimeIsEqual(&et1, &et2)) { + if (debug_mode) + printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n"); + failed_already=1; + return 1; + } + ttt = PR_ImplodeTime(&et1); + testParseTimeString( ttt ); + + if (debug_mode) printf("Test passed for April 4, 1917\n"); + + /* July 4, 2050 */ + et1.tm_usec = 0; + et1.tm_sec = 0; + et1.tm_min = 0; + et1.tm_hour = 0; + et1.tm_mday = 4; + et1.tm_month = 7 - 1; + et1.tm_year = 2050; + et1.tm_params = PR_GMTParameters(&et1); + PR_NormalizeTime(&et1, PR_LocalTimeParameters); + secs = PR_ImplodeTime(&et1); + if (!LL_GE_ZERO(secs)) { + if (debug_mode) + printf("ERROR: July 4, 2050 GMT returns a negative second count\n"); + failed_already = 1; + return 1; + } + PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2); + if (!ExplodedTimeIsEqual(&et1, &et2)) { + if (debug_mode) + printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n"); + failed_already=1; + return 1; + } + testParseTimeString(PR_ImplodeTime(&et1)); + + if (debug_mode) printf("Test passed for July 4, 2050\n"); + + } + + /* + ************************************************************** + ** + ** Stress test + * + ** Go through four years, starting from + ** 00:00:00 PST Jan. 1, 2005, incrementing + ** every 10 minutes. + ** + ************************************************************** + */ + + { + PRExplodedTime et, et1, et2; + PRInt64 usecPer10Min; + int day, hour, min; + PRTime usecs; + int dstInEffect = 0; + + if (debug_mode) { + printf("\n"); + printf("*******************************************************\n"); + printf("** **\n"); + printf("** Stress test Pacific Time **\n"); + printf("** Starting from midnight Jan. 1, 2005 PST, **\n"); + printf("** going through four years in 10-minute increment **\n"); + printf("** **\n"); + printf("*******************************************************\n\n"); + } + LL_I2L(usecPer10Min, 600000000L); + + /* 00:00:00 PST Jan. 1, 2005 */ + et.tm_usec = 0; + et.tm_sec = 0; + et.tm_min = 0; + et.tm_hour = 0; + et.tm_mday = 1; + et.tm_month = 0; + et.tm_year = 2005; + et.tm_params.tp_gmt_offset = -8 * 3600; + et.tm_params.tp_dst_offset = 0; + usecs = PR_ImplodeTime(&et); + + for (day = 0; day < 4 * 365 + 1; day++) { + for (hour = 0; hour < 24; hour++) { + for (min = 0; min < 60; min += 10) { + LL_ADD(usecs, usecs, usecPer10Min); + PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1); + + et2 = et; + et2.tm_usec += 600000000L; + PR_NormalizeTime(&et2, PR_USPacificTimeParameters); + + if (!ExplodedTimeIsEqual(&et1, &et2)) { + printf("ERROR: componentwise comparison failed\n"); + PrintExplodedTime(&et1); + printf("\n"); + PrintExplodedTime(&et2); + printf("\n"); + failed_already=1; + return 1; + } + + if (LL_NE(usecs, PR_ImplodeTime(&et1))) { + printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); + PrintExplodedTime(&et1); + printf("\n"); + failed_already=1; + return 1; + } + testParseTimeString(usecs); + + if (!dstInEffect && et1.tm_params.tp_dst_offset) { + dstInEffect = 1; + if (debug_mode) { + printf("DST changeover from "); + PrintExplodedTime(&et); + printf(" to "); + PrintExplodedTime(&et1); + printf(".\n"); + } + } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { + dstInEffect = 0; + if (debug_mode) { + printf("DST changeover from "); + PrintExplodedTime(&et); + printf(" to "); + PrintExplodedTime(&et1); + printf(".\n"); + } + } + + et = et1; + } + } + } + if (debug_mode) printf("Test passed\n"); + } + + + /* Same stress test, but with PR_LocalTimeParameters */ + + { + PRExplodedTime et, et1, et2; + PRInt64 usecPer10Min; + int day, hour, min; + PRTime usecs; + int dstInEffect = 0; + + if (debug_mode) { + printf("\n"); + printf("*******************************************************\n"); + printf("** **\n"); + printf("** Stress test Local Time **\n"); + printf("** Starting from midnight Jan. 1, 2005 PST, **\n"); + printf("** going through four years in 10-minute increment **\n"); + printf("** **\n"); + printf("*******************************************************\n\n"); + } + + LL_I2L(usecPer10Min, 600000000L); + + /* 00:00:00 PST Jan. 1, 2005 */ + et.tm_usec = 0; + et.tm_sec = 0; + et.tm_min = 0; + et.tm_hour = 0; + et.tm_mday = 1; + et.tm_month = 0; + et.tm_year = 2005; + et.tm_params.tp_gmt_offset = -8 * 3600; + et.tm_params.tp_dst_offset = 0; + usecs = PR_ImplodeTime(&et); + + for (day = 0; day < 4 * 365 + 1; day++) { + for (hour = 0; hour < 24; hour++) { + for (min = 0; min < 60; min += 10) { + LL_ADD(usecs, usecs, usecPer10Min); + PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1); + + et2 = et; + et2.tm_usec += 600000000L; + PR_NormalizeTime(&et2, PR_LocalTimeParameters); + + if (!ExplodedTimeIsEqual(&et1, &et2)) { + printf("ERROR: componentwise comparison failed\n"); + PrintExplodedTime(&et1); + printf("\n"); + PrintExplodedTime(&et2); + printf("\n"); + return 1; + } + + if (LL_NE(usecs, PR_ImplodeTime(&et1))) { + printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); + PrintExplodedTime(&et1); + printf("\n"); + failed_already=1; + return 1; + } + testParseTimeString(usecs); + + if (!dstInEffect && et1.tm_params.tp_dst_offset) { + dstInEffect = 1; + if (debug_mode) { + printf("DST changeover from "); + PrintExplodedTime(&et); + printf(" to "); + PrintExplodedTime(&et1); + printf(".\n"); + } + } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { + dstInEffect = 0; + if (debug_mode) { + printf("DST changeover from "); + PrintExplodedTime(&et); + printf(" to "); + PrintExplodedTime(&et1); + printf(".\n"); + } + } + + et = et1; + } + } + } + if (debug_mode) printf("Test passed\n"); + } + + /* Same stress test, but with PR_LocalTimeParameters and going backward */ + + { + PRExplodedTime et, et1, et2; + PRInt64 usecPer10Min; + int day, hour, min; + PRTime usecs; + int dstInEffect = 0; + + if (debug_mode) { + printf("\n"); + printf("*******************************************************\n"); + printf("** **\n"); + printf("** Stress test Local Time **\n"); + printf("** Starting from midnight Jan. 1, 2009 PST, **\n"); + printf("** going back four years in 10-minute increment **\n"); + printf("** **\n"); + printf("*******************************************************\n\n"); + } + + LL_I2L(usecPer10Min, 600000000L); + + /* 00:00:00 PST Jan. 1, 2009 */ + et.tm_usec = 0; + et.tm_sec = 0; + et.tm_min = 0; + et.tm_hour = 0; + et.tm_mday = 1; + et.tm_month = 0; + et.tm_year = 2009; + et.tm_params.tp_gmt_offset = -8 * 3600; + et.tm_params.tp_dst_offset = 0; + usecs = PR_ImplodeTime(&et); + + for (day = 0; day < 4 * 365 + 1; day++) { + for (hour = 0; hour < 24; hour++) { + for (min = 0; min < 60; min += 10) { + LL_SUB(usecs, usecs, usecPer10Min); + PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1); + + et2 = et; + et2.tm_usec -= 600000000L; + PR_NormalizeTime(&et2, PR_LocalTimeParameters); + + if (!ExplodedTimeIsEqual(&et1, &et2)) { + printf("ERROR: componentwise comparison failed\n"); + PrintExplodedTime(&et1); + printf("\n"); + PrintExplodedTime(&et2); + printf("\n"); + return 1; + } + + if (LL_NE(usecs, PR_ImplodeTime(&et1))) { + printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n"); + PrintExplodedTime(&et1); + printf("\n"); + failed_already=1; + return 1; + } + testParseTimeString(usecs); + + if (!dstInEffect && et1.tm_params.tp_dst_offset) { + dstInEffect = 1; + if (debug_mode) { + printf("DST changeover from "); + PrintExplodedTime(&et); + printf(" to "); + PrintExplodedTime(&et1); + printf(".\n"); + } + } else if (dstInEffect && !et1.tm_params.tp_dst_offset) { + dstInEffect = 0; + if (debug_mode) { + printf("DST changeover from "); + PrintExplodedTime(&et); + printf(" to "); + PrintExplodedTime(&et1); + printf(".\n"); + } + } + + et = et1; + } + } + } + } + + if (failed_already) return 1; + else return 0; + +} diff -Nru nspr-4.9.5/nspr/pr/tests/tmoacc.c nspr-4.10.7/nspr/pr/tests/tmoacc.c --- nspr-4.9.5/nspr/pr/tests/tmoacc.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/tmoacc.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,296 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" + +#include +#include + +#include "plerror.h" +#include "plgetopt.h" + +#define BASE_PORT 9867 +#define DEFAULT_THREADS 1 +#define DEFAULT_BACKLOG 10 +#define DEFAULT_TIMEOUT 10 +#define RANDOM_RANGE 100 /* should be significantly smaller than RAND_MAX */ + +typedef enum {running, stopped} Status; + +typedef struct Shared +{ + PRLock *ml; + PRCondVar *cv; + PRBool passed; + PRBool random; + PRFileDesc *debug; + PRIntervalTime timeout; + PRFileDesc *listenSock; + Status status; +} Shared; + +static PRIntervalTime Timeout(const Shared *shared) +{ + PRIntervalTime timeout = shared->timeout; + if (shared->random) + { + PRIntervalTime half = timeout >> 1; /* one half of the interval */ + PRIntervalTime quarter = half >> 1; /* one quarter of the interval */ + /* something in [0..timeout / 2) */ + PRUint32 random = (rand() % RANDOM_RANGE) * half / RANDOM_RANGE; + timeout = (3 * quarter) + random; /* [75..125)% */ + } + return timeout; +} /* Timeout */ + +static void Accept(void *arg) +{ + PRStatus rv; + char *buffer = NULL; + PRNetAddr clientAddr; + Shared *shared = (Shared*)arg; + PRInt32 recv_length = 0, flags = 0; + PRFileDesc *clientSock; + PRIntn toread, byte, bytes, loop = 0; + struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor; + + do + { + PRUint32 checksum = 0; + if (NULL != shared->debug) + PR_fprintf(shared->debug, "[%d]accepting ... ", loop++); + clientSock = PR_Accept( + shared->listenSock, &clientAddr, Timeout(shared)); + if (clientSock != NULL) + { + if (NULL != shared->debug) + PR_fprintf(shared->debug, "reading length ... "); + bytes = PR_Recv( + clientSock, &descriptor, sizeof(descriptor), + flags, Timeout(shared)); + if (sizeof(descriptor) == bytes) + { + /* and, before doing something stupid ... */ + descriptor.length = PR_ntohl(descriptor.length); + descriptor.checksum = PR_ntohl(descriptor.checksum); + if (NULL != shared->debug) + PR_fprintf(shared->debug, "%d bytes ... ", descriptor.length); + toread = descriptor.length; + if (recv_length < descriptor.length) + { + if (NULL != buffer) PR_DELETE(buffer); + buffer = (char*)PR_MALLOC(descriptor.length); + recv_length = descriptor.length; + } + for (toread = descriptor.length; toread > 0; toread -= bytes) + { + bytes = PR_Recv( + clientSock, &buffer[descriptor.length - toread], + toread, flags, Timeout(shared)); + if (-1 == bytes) + { + if (NULL != shared->debug) + PR_fprintf(shared->debug, "read data failed..."); + bytes = 0; + } + } + } + else if (NULL != shared->debug) + { + PR_fprintf(shared->debug, "read desciptor failed..."); + descriptor.length = -1; + } + if (NULL != shared->debug) + PR_fprintf(shared->debug, "closing"); + rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH); + if ((PR_FAILURE == rv) && (NULL != shared->debug)) + { + PR_fprintf(shared->debug, " failed"); + shared->passed = PR_FALSE; + } + rv = PR_Close(clientSock); + if (PR_FAILURE == rv) if (NULL != shared->debug) + { + PR_fprintf(shared->debug, " failed"); + shared->passed = PR_FALSE; + } + if (descriptor.length > 0) + { + for (byte = 0; byte < descriptor.length; ++byte) + { + PRUint32 overflow = checksum & 0x80000000; + checksum = (checksum << 1); + if (0x00000000 != overflow) checksum += 1; + checksum += buffer[byte]; + } + if ((descriptor.checksum != checksum) && (NULL != shared->debug)) + { + PR_fprintf(shared->debug, " ... data mismatch"); + shared->passed = PR_FALSE; + } + } + else if (0 == descriptor.length) + { + PR_Lock(shared->ml); + shared->status = stopped; + PR_NotifyCondVar(shared->cv); + PR_Unlock(shared->ml); + } + if (NULL != shared->debug) + PR_fprintf(shared->debug, "\n"); + } + else + { + if (PR_PENDING_INTERRUPT_ERROR != PR_GetError()) + { + if (NULL != shared->debug) PL_PrintError("Accept"); + shared->passed = PR_FALSE; + } + } + } while (running == shared->status); + if (NULL != buffer) PR_DELETE(buffer); +} /* Accept */ + +PRIntn Tmoacc(PRIntn argc, char **argv) +{ + PRStatus rv; + PRIntn exitStatus; + PRIntn index; + Shared *shared; + PLOptStatus os; + PRThread **thread; + PRNetAddr listenAddr; + PRSocketOptionData sockOpt; + PRIntn timeout = DEFAULT_TIMEOUT; + PRIntn threads = DEFAULT_THREADS; + PRIntn backlog = DEFAULT_BACKLOG; + PRThreadScope thread_scope = PR_LOCAL_THREAD; + + PLOptState *opt = PL_CreateOptState(argc, argv, "dGb:t:T:R"); + + shared = PR_NEWZAP(Shared); + + shared->debug = NULL; + shared->passed = PR_TRUE; + shared->random = PR_TRUE; + shared->status = running; + shared->ml = PR_NewLock(); + shared->cv = PR_NewCondVar(shared->ml); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + shared->debug = PR_GetSpecialFD(PR_StandardError); + break; + case 'G': /* use global threads */ + thread_scope = PR_GLOBAL_THREAD; + break; + case 'b': /* size of listen backlog */ + backlog = atoi(opt->value); + break; + case 't': /* number of threads doing accept */ + threads = atoi(opt->value); + break; + case 'T': /* timeout used for network operations */ + timeout = atoi(opt->value); + break; + case 'R': /* randomize the timeout values */ + shared->random = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + if (0 == threads) threads = DEFAULT_THREADS; + if (0 == backlog) backlog = DEFAULT_BACKLOG; + if (0 == timeout) timeout = DEFAULT_TIMEOUT; + + PR_STDIO_INIT(); + memset(&listenAddr, 0, sizeof(listenAddr)); + rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr); + PR_ASSERT(PR_SUCCESS == rv); + + shared->timeout = PR_SecondsToInterval(timeout); + + /* First bind to the socket */ + shared->listenSock = PR_NewTCPSocket(); + if (shared->listenSock) + { + sockOpt.option = PR_SockOpt_Reuseaddr; + sockOpt.value.reuse_addr = PR_TRUE; + rv = PR_SetSocketOption(shared->listenSock, &sockOpt); + PR_ASSERT(PR_SUCCESS == rv); + rv = PR_Bind(shared->listenSock, &listenAddr); + if (rv != PR_FAILURE) + { + rv = PR_Listen(shared->listenSock, threads + backlog); + if (PR_SUCCESS == rv) + { + thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*)); + for (index = 0; index < threads; ++index) + { + thread[index] = PR_CreateThread( + PR_USER_THREAD, Accept, shared, + PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 0); + PR_ASSERT(NULL != thread[index]); + } + + PR_Lock(shared->ml); + while (shared->status == running) + PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT); + PR_Unlock(shared->ml); + for (index = 0; index < threads; ++index) + { + rv = PR_Interrupt(thread[index]); + PR_ASSERT(PR_SUCCESS== rv); + rv = PR_JoinThread(thread[index]); + PR_ASSERT(PR_SUCCESS== rv); + } + PR_DELETE(thread); + } + else + { + if (shared->debug) PL_PrintError("Listen"); + shared->passed = PR_FALSE; + } + } + else + { + if (shared->debug) PL_PrintError("Bind"); + shared->passed = PR_FALSE; + } + + PR_Close(shared->listenSock); + } + else + { + if (shared->debug) PL_PrintError("Create"); + shared->passed = PR_FALSE; + } + + PR_DestroyCondVar(shared->cv); + PR_DestroyLock(shared->ml); + + PR_fprintf( + PR_GetSpecialFD(PR_StandardError), "%s\n", + ((shared->passed) ? "PASSED" : "FAILED")); + + exitStatus = (shared->passed) ? 0 : 1; + PR_DELETE(shared); + return exitStatus; +} + +int main(int argc, char **argv) +{ + return (PR_VersionCheck(PR_VERSION)) ? + PR_Initialize(Tmoacc, argc, argv, 4) : -1; +} /* main */ + +/* tmoacc */ diff -Nru nspr-4.9.5/nspr/pr/tests/tmocon.c nspr-4.10.7/nspr/pr/tests/tmocon.c --- nspr-4.9.5/nspr/pr/tests/tmocon.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/tmocon.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,378 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*********************************************************************** +** +** Name: tmocon.c +** +** Description: test client socket connection. +** +** Modification History: +** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag. +** The debug mode will print all of the printfs associated with this test. +** The regress mode will be the default mode. Since the regress tool limits +** the output to a one line status:PASS or FAIL,all of the printf statements +** have been handled with an if (debug_mode) statement. +***********************************************************************/ + +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "nspr.h" +#include "pprio.h" + +#include "plerror.h" +#include "plgetopt.h" + +#include +#include +#include + +/* for getcwd */ +#if defined(XP_UNIX) || defined (XP_OS2) || defined(XP_BEOS) +#include +#elif defined(XP_PC) +#include +#endif + +#ifdef WINCE +#include +char *getcwd(char *buf, size_t size) +{ + wchar_t wpath[MAX_PATH]; + _wgetcwd(wpath, MAX_PATH); + WideCharToMultiByte(CP_ACP, 0, wpath, -1, buf, size, 0, 0); +} +#endif + +#define BASE_PORT 9867 + +#define DEFAULT_DALLY 1 +#define DEFAULT_THREADS 1 +#define DEFAULT_TIMEOUT 10 +#define DEFAULT_MESSAGES 100 +#define DEFAULT_MESSAGESIZE 100 + +static PRFileDesc *debug_out = NULL; + +typedef struct Shared +{ + PRBool random; + PRBool failed; + PRBool intermittant; + PRIntn debug; + PRInt32 messages; + PRIntervalTime dally; + PRIntervalTime timeout; + PRInt32 message_length; + PRNetAddr serverAddress; +} Shared; + +static PRIntervalTime Timeout(const Shared *shared) +{ + PRIntervalTime timeout = shared->timeout; + if (shared->random) + { + PRIntervalTime quarter = timeout >> 2; /* one quarter of the interval */ + PRUint32 random = rand() % quarter; /* something in[0..timeout / 4) */ + timeout = (((3 * quarter) + random) >> 2) + quarter; /* [75..125)% */ + } + return timeout; +} /* Timeout */ + +static void CauseTimeout(const Shared *shared) +{ + if (shared->intermittant) PR_Sleep(Timeout(shared)); +} /* CauseTimeout */ + +static PRStatus MakeReceiver(Shared *shared) +{ + PRStatus rv = PR_FAILURE; + if (PR_IsNetAddrType(&shared->serverAddress, PR_IpAddrLoopback)) + { + char *argv[3]; + char path[1024 + sizeof("/tmoacc")]; + + getcwd(path, sizeof(path)); + + (void)strcat(path, "/tmoacc"); +#ifdef XP_PC + (void)strcat(path, ".exe"); +#endif + argv[0] = path; + if (shared->debug > 0) + { + argv[1] = "-d"; + argv[2] = NULL; + } + else argv[1] = NULL; + if (shared->debug > 1) + PR_fprintf(debug_out, " creating accept process %s ...", path); + fflush(stdout); + rv = PR_CreateProcessDetached(path, argv, NULL, NULL); + if (PR_SUCCESS == rv) + { + if (shared->debug > 1) + PR_fprintf(debug_out, " wait 5 seconds"); + if (shared->debug > 1) + PR_fprintf(debug_out, " before connecting to accept process ..."); + fflush(stdout); + PR_Sleep(PR_SecondsToInterval(5)); + return rv; + } + shared->failed = PR_TRUE; + if (shared->debug > 0) + PL_FPrintError(debug_out, "PR_CreateProcessDetached failed"); + } + return rv; +} /* MakeReceiver */ + +static void Connect(void *arg) +{ + PRStatus rv; + char *buffer = NULL; + PRFileDesc *clientSock; + Shared *shared = (Shared*)arg; + PRInt32 loop, bytes, flags = 0; + struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor; + debug_out = (0 == shared->debug) ? NULL : PR_GetSpecialFD(PR_StandardError); + + buffer = (char*)PR_MALLOC(shared->message_length); + + for (bytes = 0; bytes < shared->message_length; ++bytes) + buffer[bytes] = (char)bytes; + + descriptor.checksum = 0; + for (bytes = 0; bytes < shared->message_length; ++bytes) + { + PRUint32 overflow = descriptor.checksum & 0x80000000; + descriptor.checksum = (descriptor.checksum << 1); + if (0x00000000 != overflow) descriptor.checksum += 1; + descriptor.checksum += buffer[bytes]; + } + descriptor.checksum = PR_htonl(descriptor.checksum); + + for (loop = 0; loop < shared->messages; ++loop) + { + if (shared->debug > 1) + PR_fprintf(debug_out, "[%d]socket ... ", loop); + clientSock = PR_NewTCPSocket(); + if (clientSock) + { + /* + * We need to slow down the rate of generating connect requests, + * otherwise the listen backlog queue on the accept side may + * become full and we will get connection refused or timeout + * error. + */ + + PR_Sleep(shared->dally); + if (shared->debug > 1) + { + char buf[128]; + PR_NetAddrToString(&shared->serverAddress, buf, sizeof(buf)); + PR_fprintf(debug_out, "connecting to %s ... ", buf); + } + rv = PR_Connect( + clientSock, &shared->serverAddress, Timeout(shared)); + if (PR_SUCCESS == rv) + { + PRInt32 descriptor_length = (loop < (shared->messages - 1)) ? + shared->message_length : 0; + descriptor.length = PR_htonl(descriptor_length); + if (shared->debug > 1) + PR_fprintf( + debug_out, "sending %d bytes ... ", descriptor_length); + CauseTimeout(shared); /* might cause server to timeout */ + bytes = PR_Send( + clientSock, &descriptor, sizeof(descriptor), + flags, Timeout(shared)); + if (bytes != sizeof(descriptor)) + { + shared->failed = PR_TRUE; + if (shared->debug > 0) + PL_FPrintError(debug_out, "PR_Send failed"); + } + if (0 != descriptor_length) + { + CauseTimeout(shared); + bytes = PR_Send( + clientSock, buffer, descriptor_length, + flags, Timeout(shared)); + if (bytes != descriptor_length) + { + shared->failed = PR_TRUE; + if (shared->debug > 0) + PL_FPrintError(debug_out, "PR_Send failed"); + } + } + if (shared->debug > 1) PR_fprintf(debug_out, "closing ... "); + rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH); + rv = PR_Close(clientSock); + if (shared->debug > 1) + { + if (PR_SUCCESS == rv) PR_fprintf(debug_out, "\n"); + else PL_FPrintError(debug_out, "shutdown failed"); + } + } + else + { + if (shared->debug > 1) PL_FPrintError(debug_out, "connect failed"); + PR_Close(clientSock); + if ((loop == 0) && (PR_GetError() == PR_CONNECT_REFUSED_ERROR)) + { + if (MakeReceiver(shared) == PR_FAILURE) break; + } + else + { + if (shared->debug > 1) PR_fprintf(debug_out, " exiting\n"); + break; + } + } + } + else + { + shared->failed = PR_TRUE; + if (shared->debug > 0) PL_FPrintError(debug_out, "create socket"); + break; + } + } + + PR_DELETE(buffer); +} /* Connect */ + +int Tmocon(int argc, char **argv) +{ + /* + * USAGE + * -d turn on debugging output (default = off) + * -v turn on verbose output (default = off) + * -h dns name of host serving the connection (default = self) + * -i dally intermittantly to cause timeouts (default = off) + * -m number of messages to send (default = 100) + * -s size of each message (default = 100) + * -t number of threads sending (default = 1) + * -G use global threads (default = local) + * -T timeout on I/O operations (seconds) (default = 10) + * -D dally between connect requests (seconds)(default = 0) + * -R randomize the dally types around 'T' (default = no) + */ + + PRStatus rv; + int exitStatus; + PLOptStatus os; + Shared *shared = NULL; + PRThread **thread = NULL; + PRIntn index, threads = DEFAULT_THREADS; + PRThreadScope thread_scope = PR_LOCAL_THREAD; + PRInt32 dally = DEFAULT_DALLY, timeout = DEFAULT_TIMEOUT; + PLOptState *opt = PL_CreateOptState(argc, argv, "divGRh:m:s:t:T:D:"); + + shared = PR_NEWZAP(Shared); + + shared->debug = 0; + shared->failed = PR_FALSE; + shared->random = PR_FALSE; + shared->messages = DEFAULT_MESSAGES; + shared->message_length = DEFAULT_MESSAGESIZE; + + PR_STDIO_INIT(); + memset(&shared->serverAddress, 0, sizeof(shared->serverAddress)); + rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &shared->serverAddress); + PR_ASSERT(PR_SUCCESS == rv); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': + if (0 == shared->debug) shared->debug = 1; + break; + case 'v': + if (0 == shared->debug) shared->debug = 2; + break; + case 'i': + shared->intermittant = PR_TRUE; + break; + case 'R': + shared->random = PR_TRUE; + break; + case 'G': + thread_scope = PR_GLOBAL_THREAD; + break; + case 'h': /* the value for backlock */ + { + PRIntn es = 0; + PRHostEnt host; + char buffer[1024]; + (void)PR_GetHostByName( + opt->value, buffer, sizeof(buffer), &host); + es = PR_EnumerateHostEnt( + es, &host, BASE_PORT, &shared->serverAddress); + PR_ASSERT(es > 0); + } + break; + case 'm': /* number of messages to send */ + shared->messages = atoi(opt->value); + break; + case 't': /* number of threads sending */ + threads = atoi(opt->value); + break; + case 'D': /* dally time between transmissions */ + dally = atoi(opt->value); + break; + case 'T': /* timeout on I/O operations */ + timeout = atoi(opt->value); + break; + case 's': /* total size of each message */ + shared->message_length = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (0 == timeout) timeout = DEFAULT_TIMEOUT; + if (0 == threads) threads = DEFAULT_THREADS; + if (0 == shared->messages) shared->messages = DEFAULT_MESSAGES; + if (0 == shared->message_length) shared->message_length = DEFAULT_MESSAGESIZE; + + shared->dally = PR_SecondsToInterval(dally); + shared->timeout = PR_SecondsToInterval(timeout); + + thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*)); + + for (index = 0; index < threads; ++index) + thread[index] = PR_CreateThread( + PR_USER_THREAD, Connect, shared, + PR_PRIORITY_NORMAL, thread_scope, + PR_JOINABLE_THREAD, 0); + for (index = 0; index < threads; ++index) + rv = PR_JoinThread(thread[index]); + + PR_DELETE(thread); + + PR_fprintf( + PR_GetSpecialFD(PR_StandardError), "%s\n", + ((shared->failed) ? "FAILED" : "PASSED")); + exitStatus = (shared->failed) ? 1 : 0; + PR_DELETE(shared); + return exitStatus; +} + +int main(int argc, char **argv) +{ + return (PR_VersionCheck(PR_VERSION)) ? + PR_Initialize(Tmocon, argc, argv, 4) : -1; +} /* main */ + +/* tmocon.c */ + + diff -Nru nspr-4.9.5/nspr/pr/tests/tpd.c nspr-4.10.7/nspr/pr/tests/tpd.c --- nspr-4.9.5/nspr/pr/tests/tpd.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/tpd.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,298 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +** File: tpd.c +** Description: Exercising the thread private data bailywick. +*/ + +#include "prmem.h" +#include "prinit.h" +#include "prlog.h" +#include "prprf.h" +#include "prthread.h" +#include "prtypes.h" + +#include "private/pprio.h" + +#include "plgetopt.h" + +static PRUintn key[128]; +static PRIntn debug = 0; +static PRBool failed = PR_FALSE; +static PRBool should = PR_TRUE; +static PRBool did = PR_TRUE; +static PRFileDesc *fout = NULL; + +static void PrintProgress(PRIntn line) +{ + failed = failed || (should && !did); + failed = failed || (!should && did); + if (debug > 0) + { +#if defined(WIN16) + printf( + "@ line %d destructor should%s have been called and was%s\n", + line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); +#else + PR_fprintf( + fout, "@ line %d destructor should%s have been called and was%s\n", + line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); +#endif + } +} /* PrintProgress */ + +static void MyAssert(const char *expr, const char *file, PRIntn line) +{ + if (debug > 0) + (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line); +} /* MyAssert */ + +#define MY_ASSERT(_expr) \ + ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__)) + + +static void PR_CALLBACK Destructor(void *data) +{ + MY_ASSERT(NULL != data); + if (should) did = PR_TRUE; + else failed = PR_TRUE; + /* + * We don't actually free the storage since it's actually allocated + * on the stack. Normally, this would not be the case and this is + * the opportunity to free whatever. + PR_Free(data); + */ +} /* Destructor */ + +static void PR_CALLBACK Thread(void *null) +{ + void *pd; + PRStatus rv; + PRUintn keys; + char *key_string[] = { + "Key #0", "Key #1", "Key #2", "Key #3", + "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; + + did = should = PR_FALSE; + for (keys = 0; keys < 8; ++keys) + { + pd = PR_GetThreadPrivate(key[keys]); + MY_ASSERT(NULL == pd); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 4; keys < 8; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_FAILURE == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + + /* put in keys and leave them there for thread exit */ + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + did = PR_FALSE; should = PR_TRUE; + +} /* Thread */ + +static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv) +{ + void *pd; + PRStatus rv; + PRUintn keys; + PRThread *thread; + char *key_string[] = { + "Key #0", "Key #1", "Key #2", "Key #3", + "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"}; + + fout = PR_STDOUT; + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 8; ++keys) + { + pd = PR_GetThreadPrivate(key[keys]); + MY_ASSERT(NULL == pd); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + for (keys = 4; keys < 8; ++keys) + key[keys] = 4096; /* set to invalid value */ + did = should = PR_FALSE; + for (keys = 4; keys < 8; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_FAILURE == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], key_string[keys]); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 0; keys < 4; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_NewThreadPrivateIndex(&key[keys], Destructor); + MY_ASSERT(PR_SUCCESS == rv); + rv = PR_SetThreadPrivate(key[keys], "EXTENSION"); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = PR_FALSE; should = PR_TRUE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + PrintProgress(__LINE__); + + did = should = PR_FALSE; + for (keys = 8; keys < 127; ++keys) + { + rv = PR_SetThreadPrivate(key[keys], NULL); + MY_ASSERT(PR_SUCCESS == rv); + } + + thread = PR_CreateThread( + PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + + (void)PR_JoinThread(thread); + + PrintProgress(__LINE__); + +#if defined(WIN16) + printf( + "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); +#else + (void)PR_fprintf( + fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED")); +#endif + + return 0; + +} /* Tpd */ + +int main(int argc, char **argv) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dl:r:"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + PR_STDIO_INIT(); + return PR_Initialize(Tpd, argc, argv, 0); +} /* main */ + +/* tpd.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/udpsrv.c nspr-4.10.7/nspr/pr/tests/udpsrv.c --- nspr-4.9.5/nspr/pr/tests/udpsrv.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/udpsrv.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,530 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/******************************************************************* +** udpsrc.c -- Test basic function of UDP server +** +** udpsrv operates on the same machine with program udpclt. +** udpsrv is the server side of a udp sockets application. +** udpclt is the client side of a udp sockets application. +** +** The test is designed to assist developers in porting/debugging +** the UDP socket functions of NSPR. +** +** This test is not a stress test. +** +** main() starts two threads: UDP_Server() and UDP_Client(); +** main() uses PR_JoinThread() to wait for the threads to complete. +** +** UDP_Server() does repeated recvfrom()s from a socket. +** He detects an EOF condition set by UDP_Client(). For each +** packet received by UDP_Server(), he checks its content for +** expected content, then sends the packet back to UDP_Client(). +** +** UDP_Client() sends packets to UDP_Server() using sendto() +** he recieves packets back from the server via recvfrom(). +** After he sends enough packets containing UDP_AMOUNT_TO_WRITE +** bytes of data, he sends an EOF message. +** +** The test issues a pass/fail message at end. +** +** Notes: +** The variable "_debug_on" can be set to 1 to cause diagnostic +** messages related to client/server synchronization. Useful when +** the test hangs. +** +** Error messages are written to stdout. +** +******************************************************************** +*/ +/* --- include files --- */ +#include "nspr.h" +#include "prpriv.h" + +#include "plgetopt.h" +#include "prttools.h" + +#include +#include +#include +#include + +#ifdef XP_PC +#define mode_t int +#endif + +#define UDP_BUF_SIZE 4096 +#define UDP_DGRAM_SIZE 128 +#define UDP_AMOUNT_TO_WRITE (PRInt32)((UDP_DGRAM_SIZE * 1000l) +1) +#define NUM_UDP_CLIENTS 1 +#define NUM_UDP_DATAGRAMS_PER_CLIENT 5 +#define UDP_SERVER_PORT 9050 +#define UDP_CLIENT_PORT 9053 +#define MY_INADDR PR_INADDR_ANY +#define PEER_INADDR PR_INADDR_LOOPBACK + +#define UDP_TIMEOUT 400000 +/* #define UDP_TIMEOUT PR_INTERVAL_NO_TIMEOUT */ + +/* --- static data --- */ +static PRIntn _debug_on = 0; +static PRBool passed = PR_TRUE; +static PRUint32 cltBytesRead = 0; +static PRUint32 srvBytesRead = 0; +static PRFileDesc *output = NULL; + +/* --- static function declarations --- */ +#define DPRINTF(arg) if (_debug_on) PR_fprintf(output, arg) + + + +/******************************************************************* +** ListNetAddr() -- Display the Net Address on stdout +** +** Description: displays the component parts of a PRNetAddr struct +** +** Arguments: address of PRNetAddr structure to display +** +** Returns: void +** +** Notes: +** +******************************************************************** +*/ +void ListNetAddr( char *msg, PRNetAddr *na ) +{ + char mbuf[256]; + + sprintf( mbuf, "ListNetAddr: %s family: %d, port: %d, ip: %8.8X\n", + msg, na->inet.family, PR_ntohs( na->inet.port), PR_ntohl(na->inet.ip) ); +#if 0 + DPRINTF( mbuf ); +#endif +} /* --- end ListNetAddr() --- */ + +/******************************************************************** +** UDP_Server() -- Test a UDP server application +** +** Description: The Server side of a UDP Client/Server application. +** +** Arguments: none +** +** Returns: void +** +** Notes: +** +** +******************************************************************** +*/ +static void PR_CALLBACK UDP_Server( void *arg ) +{ + static char svrBuf[UDP_BUF_SIZE]; + PRFileDesc *svrSock; + PRInt32 rv; + PRNetAddr netaddr; + PRBool bound = PR_FALSE; + PRBool endOfInput = PR_FALSE; + PRInt32 numBytes = UDP_DGRAM_SIZE; + + DPRINTF("udpsrv: UDP_Server(): starting\n" ); + + /* --- Create the socket --- */ + DPRINTF("udpsrv: UDP_Server(): Creating UDP Socket\n" ); + svrSock = PR_NewUDPSocket(); + if ( svrSock == NULL ) + { + passed = PR_FALSE; + if (debug_mode) + PR_fprintf(output, + "udpsrv: UDP_Server(): PR_NewUDPSocket() returned NULL\n" ); + return; + } + + /* --- Initialize the sockaddr_in structure --- */ + memset( &netaddr, 0, sizeof( netaddr )); + netaddr.inet.family = PR_AF_INET; + netaddr.inet.port = PR_htons( UDP_SERVER_PORT ); + netaddr.inet.ip = PR_htonl( MY_INADDR ); + + /* --- Bind the socket --- */ + while ( !bound ) + { + DPRINTF("udpsrv: UDP_Server(): Binding socket\n" ); + rv = PR_Bind( svrSock, &netaddr ); + if ( rv < 0 ) + { + if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR ) + { + if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \ + PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n"); + PR_Sleep( PR_MillisecondsToInterval( 2000 )); + continue; + } + else + { + passed = PR_FALSE; + if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \ + PR_Bind(): failed: %ld with error: %ld\n", + rv, PR_GetError() ); + PR_Close( svrSock ); + return; + } + } + else + bound = PR_TRUE; + } + ListNetAddr( "UDP_Server: after bind", &netaddr ); + + /* --- Recv the socket --- */ + while( !endOfInput ) + { + DPRINTF("udpsrv: UDP_Server(): RecvFrom() socket\n" ); + rv = PR_RecvFrom( svrSock, svrBuf, numBytes, 0, &netaddr, UDP_TIMEOUT ); + if ( rv == -1 ) + { + passed = PR_FALSE; + if (debug_mode) + PR_fprintf(output, + "udpsrv: UDP_Server(): PR_RecvFrom(): failed with error: %ld\n", + PR_GetError() ); + PR_Close( svrSock ); + return; + } + ListNetAddr( "UDP_Server after RecvFrom", &netaddr ); + + srvBytesRead += rv; + + if ( svrBuf[0] == 'E' ) + { + DPRINTF("udpsrv: UDP_Server(): EOF on input detected\n" ); + endOfInput = PR_TRUE; + } + + /* --- Send the socket --- */ + DPRINTF("udpsrv: UDP_Server(): SendTo(): socket\n" ); + rv = PR_SendTo( svrSock, svrBuf, rv, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT ); + if ( rv == -1 ) + { + passed = PR_FALSE; + if (debug_mode) + PR_fprintf(output, + "udpsrv: UDP_Server(): PR_SendTo(): failed with error: %ld\n", + PR_GetError() ); + PR_Close( svrSock ); + return; + } + ListNetAddr( "UDP_Server after SendTo", &netaddr ); + } + + /* --- Close the socket --- */ + DPRINTF("udpsrv: UDP_Server(): Closing socket\n" ); + rv = PR_Close( svrSock ); + if ( rv != PR_SUCCESS ) + { + passed = PR_FALSE; + if (debug_mode) + PR_fprintf(output, + "udpsrv: UDP_Server(): PR_Close(): failed to close socket\n" ); + return; + } + + DPRINTF("udpsrv: UDP_Server(): Normal end\n" ); +} /* --- end UDP_Server() --- */ + + +static char cltBuf[UDP_BUF_SIZE]; +static char cltBufin[UDP_BUF_SIZE]; +/******************************************************************** +** UDP_Client() -- Test a UDP client application +** +** Description: +** +** Arguments: +** +** +** Returns: +** 0 -- Successful execution +** 1 -- Test failed. +** +** Notes: +** +** +******************************************************************** +*/ +static void PR_CALLBACK UDP_Client( void *arg ) +{ + PRFileDesc *cltSock; + PRInt32 rv; + PRBool bound = PR_FALSE; + PRNetAddr netaddr; + PRNetAddr netaddrx; + PRBool endOfInput = PR_FALSE; + PRInt32 numBytes = UDP_DGRAM_SIZE; + PRInt32 writeThisMany = UDP_AMOUNT_TO_WRITE; + int i; + + + DPRINTF("udpsrv: UDP_Client(): starting\n" ); + + /* --- Create the socket --- */ + cltSock = PR_NewUDPSocket(); + if ( cltSock == NULL ) + { + passed = PR_FALSE; + if (debug_mode) + PR_fprintf(output, + "udpsrv: UDP_Client(): PR_NewUDPSocket() returned NULL\n" ); + return; + } + + /* --- Initialize the sockaddr_in structure --- */ + memset( &netaddr, 0, sizeof( netaddr )); + netaddr.inet.family = PR_AF_INET; + netaddr.inet.ip = PR_htonl( MY_INADDR ); + netaddr.inet.port = PR_htons( UDP_CLIENT_PORT ); + + /* --- Initialize the write buffer --- */ + for ( i = 0; i < UDP_BUF_SIZE ; i++ ) + cltBuf[i] = i; + + /* --- Bind the socket --- */ + while ( !bound ) + { + DPRINTF("udpsrv: UDP_Client(): Binding socket\n" ); + rv = PR_Bind( cltSock, &netaddr ); + if ( rv < 0 ) + { + if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR ) + { + if (debug_mode) + PR_fprintf(output, + "udpsrv: UDP_Client(): PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n"); + PR_Sleep( PR_MillisecondsToInterval( 2000 )); + continue; + } + else + { + passed = PR_FALSE; + if (debug_mode) + PR_fprintf(output, + "udpsrv: UDP_Client(): PR_Bind(): failed: %ld with error: %ld\n", + rv, PR_GetError() ); + PR_Close( cltSock ); + return; + } + } + else + bound = PR_TRUE; + } + ListNetAddr( "UDP_Client after Bind", &netaddr ); + + /* --- Initialize the sockaddr_in structure --- */ + memset( &netaddr, 0, sizeof( netaddr )); + netaddr.inet.family = PR_AF_INET; + netaddr.inet.ip = PR_htonl( PEER_INADDR ); + netaddr.inet.port = PR_htons( UDP_SERVER_PORT ); + + /* --- send and receive packets until no more data left */ + while( !endOfInput ) + { + /* + ** Signal EOF in the data stream on the last packet + */ + if ( writeThisMany <= UDP_DGRAM_SIZE ) + { + DPRINTF("udpsrv: UDP_Client(): Send EOF packet\n" ); + cltBuf[0] = 'E'; + endOfInput = PR_TRUE; + } + + /* --- SendTo the socket --- */ + if ( writeThisMany > UDP_DGRAM_SIZE ) + numBytes = UDP_DGRAM_SIZE; + else + numBytes = writeThisMany; + writeThisMany -= numBytes; + { + char mbuf[256]; + sprintf( mbuf, "udpsrv: UDP_Client(): write_this_many: %d, numbytes: %d\n", + writeThisMany, numBytes ); + DPRINTF( mbuf ); + } + + DPRINTF("udpsrv: UDP_Client(): SendTo(): socket\n" ); + rv = PR_SendTo( cltSock, cltBuf, numBytes, 0, &netaddr, UDP_TIMEOUT ); + if ( rv == -1 ) + { + passed = PR_FALSE; + if (debug_mode) + PR_fprintf(output, + "udpsrv: UDP_Client(): PR_SendTo(): failed with error: %ld\n", + PR_GetError() ); + PR_Close( cltSock ); + return; + } + ListNetAddr( "UDP_Client after SendTo", &netaddr ); + + /* --- RecvFrom the socket --- */ + memset( cltBufin, 0, UDP_BUF_SIZE ); + DPRINTF("udpsrv: UDP_Client(): RecvFrom(): socket\n" ); + rv = PR_RecvFrom( cltSock, cltBufin, numBytes, 0, &netaddrx, UDP_TIMEOUT ); + if ( rv == -1 ) + { + passed = PR_FALSE; + if (debug_mode) PR_fprintf(output, + "udpsrv: UDP_Client(): PR_RecvFrom(): failed with error: %ld\n", + PR_GetError() ); + PR_Close( cltSock ); + return; + } + ListNetAddr( "UDP_Client after RecvFrom()", &netaddr ); + cltBytesRead += rv; + + /* --- verify buffer --- */ + for ( i = 0; i < rv ; i++ ) + { + if ( cltBufin[i] != i ) + { + /* --- special case, end of input --- */ + if ( endOfInput && i == 0 && cltBufin[0] == 'E' ) + continue; + passed = PR_FALSE; + if (debug_mode) PR_fprintf(output, + "udpsrv: UDP_Client(): return data mismatch\n" ); + PR_Close( cltSock ); + return; + } + } + if (debug_mode) PR_fprintf(output, "."); + } + + /* --- Close the socket --- */ + DPRINTF("udpsrv: UDP_Server(): Closing socket\n" ); + rv = PR_Close( cltSock ); + if ( rv != PR_SUCCESS ) + { + passed = PR_FALSE; + if (debug_mode) PR_fprintf(output, + "udpsrv: UDP_Client(): PR_Close(): failed to close socket\n" ); + return; + } + DPRINTF("udpsrv: UDP_Client(): ending\n" ); +} /* --- end UDP_Client() --- */ + +/******************************************************************** +** main() -- udpsrv +** +** arguments: +** +** Returns: +** 0 -- Successful execution +** 1 -- Test failed. +** +** Description: +** +** Standard test case setup. +** +** Calls the function UDP_Server() +** +******************************************************************** +*/ + +int main(int argc, char **argv) +{ + PRThread *srv, *clt; +/* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d -v + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dv"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = 1; + break; + case 'v': /* verbose mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PR_STDIO_INIT(); + output = PR_STDERR; + + PR_SetConcurrency(4); + + /* + ** Create the Server thread + */ + DPRINTF( "udpsrv: Creating Server Thread\n" ); + srv = PR_CreateThread( PR_USER_THREAD, + UDP_Server, + (void *) 0, + PR_PRIORITY_LOW, + PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, + 0 ); + if ( srv == NULL ) + { + if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" ); + passed = PR_FALSE; + } + + /* + ** Give the Server time to Start + */ + DPRINTF( "udpsrv: Pausing to allow Server to start\n" ); + PR_Sleep( PR_MillisecondsToInterval(200) ); + + /* + ** Create the Client thread + */ + DPRINTF( "udpsrv: Creating Client Thread\n" ); + clt = PR_CreateThread( PR_USER_THREAD, + UDP_Client, + (void *) 0, + PR_PRIORITY_LOW, + PR_LOCAL_THREAD, + PR_JOINABLE_THREAD, + 0 ); + if ( clt == NULL ) + { + if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" ); + passed = PR_FALSE; + } + + /* + ** + */ + DPRINTF("udpsrv: Waiting to join Server & Client Threads\n" ); + PR_JoinThread( srv ); + PR_JoinThread( clt ); + + /* + ** Evaluate test results + */ + if (debug_mode) PR_fprintf(output, "\n\nudpsrv: main(): cltBytesRead(%ld), \ + srvBytesRead(%ld), expected(%ld)\n", + cltBytesRead, srvBytesRead, UDP_AMOUNT_TO_WRITE ); + if ( cltBytesRead != srvBytesRead || cltBytesRead != UDP_AMOUNT_TO_WRITE ) + { + passed = PR_FALSE; + } + PR_Cleanup(); + if ( passed ) + return 0; + else + return 1; +} /* --- end main() --- */ diff -Nru nspr-4.9.5/nspr/pr/tests/ut_ttools.h nspr-4.10.7/nspr/pr/tests/ut_ttools.h --- nspr-4.9.5/nspr/pr/tests/ut_ttools.h 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/ut_ttools.h 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,11 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Used in Regress Tool */ +#define NOSTATUS 2 +#define PASS 1 +#define FAIL 0 + +PRIntn debug_mode=0; diff -Nru nspr-4.9.5/nspr/pr/tests/vercheck.c nspr-4.10.7/nspr/pr/tests/vercheck.c --- nspr-4.9.5/nspr/pr/tests/vercheck.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/vercheck.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * File: vercheck.c + * + * Description: + * This test tests the PR_VersionCheck() function. The + * compatible_version and incompatible_version arrays + * need to be updated for each patch or release. + * + * Tested areas: library version compatibility check. + */ + +#include "prinit.h" + +#include +#include + +/* + * This release (4.10.7) is backward compatible with the + * 4.0.x, 4.1.x, 4.2.x, 4.3.x, 4.4.x, 4.5.x, 4.6.x, 4.7.x, + * 4.8.x, 4.9.x, 4.10, 4.10.1, 4.10.2, 4.10.3, 4.10.4, + * 4.10.5, and 4.10.6 releases. + * It, of course, is compatible with itself. + */ +static char *compatible_version[] = { + "4.0", "4.0.1", "4.1", "4.1.1", "4.1.2", "4.1.3", + "4.2", "4.2.1", "4.2.2", "4.3", "4.4", "4.4.1", + "4.5", "4.5.1", + "4.6", "4.6.1", "4.6.2", "4.6.3", "4.6.4", "4.6.5", + "4.6.6", "4.6.7", "4.6.8", + "4.7", "4.7.1", "4.7.2", "4.7.3", "4.7.4", "4.7.5", + "4.7.6", + "4.8", "4.8.1", "4.8.2", "4.8.3", "4.8.4", "4.8.5", + "4.8.6", "4.8.7", "4.8.8", "4.8.9", + "4.9", "4.9.1", "4.9.2", "4.9.3", "4.9.4", "4.9.5", + "4.9.6", + "4.10", "4.10.1", "4.10.2", "4.10.3", "4.10.4", + "4.10.5", "4.10.6", + PR_VERSION +}; + +/* + * This release is not backward compatible with the old + * NSPR 2.1 and 3.x releases. + * + * Any release is incompatible with future releases and + * patches. + */ +static char *incompatible_version[] = { + "2.1 19980529", + "3.0", "3.0.1", + "3.1", "3.1.1", "3.1.2", "3.1.3", + "3.5", "3.5.1", + "4.10.8", + "4.11", "4.11.1", + "10.0", "11.1", "12.14.20" +}; + +int main(int argc, char **argv) +{ + int idx; + int num_compatible = sizeof(compatible_version) / sizeof(char *); + int num_incompatible = sizeof(incompatible_version) / sizeof(char *); + + printf("NSPR release %s:\n", PR_VERSION); + for (idx = 0; idx < num_compatible; idx++) { + if (PR_VersionCheck(compatible_version[idx]) == PR_FALSE) { + fprintf(stderr, "Should be compatible with version %s\n", + compatible_version[idx]); + exit(1); + } + printf("Compatible with version %s\n", compatible_version[idx]); + } + + for (idx = 0; idx < num_incompatible; idx++) { + if (PR_VersionCheck(incompatible_version[idx]) == PR_TRUE) { + fprintf(stderr, "Should be incompatible with version %s\n", + incompatible_version[idx]); + exit(1); + } + printf("Incompatible with version %s\n", incompatible_version[idx]); + } + + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/version.c nspr-4.10.7/nspr/pr/tests/version.c --- nspr-4.9.5/nspr/pr/tests/version.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/version.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prprf.h" +#include "prlink.h" +#include "prvrsion.h" + +#include "plerror.h" +#include "plgetopt.h" + +PR_IMPORT(const PRVersionDescription *) libVersionPoint(void); + +int main(int argc, char **argv) +{ + PRIntn rv = 1; + PLOptStatus os; + PRIntn verbosity = 0; + PRLibrary *runtime = NULL; + const char *library_name = NULL; + const PRVersionDescription *version_info; + char buffer[100]; + PRExplodedTime exploded; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + + PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: /* fully qualified library name */ + library_name = opt->value; + break; + case 'd': /* verbodity */ + verbosity += 1; + break; + default: + PR_fprintf(err, "Usage: version [-d] {fully qualified library name}\n"); + return 2; /* but not a lot else */ + } + } + PL_DestroyOptState(opt); + + if (NULL != library_name) + { + runtime = PR_LoadLibrary(library_name); + if (NULL == runtime) { + PL_FPrintError(err, "PR_LoadLibrary"); + return 3; + } else { + versionEntryPointType versionPoint = (versionEntryPointType) + PR_FindSymbol(runtime, "libVersionPoint"); + if (NULL == versionPoint) { + PL_FPrintError(err, "PR_FindSymbol"); + return 4; + } + version_info = versionPoint(); + } + } else + version_info = libVersionPoint(); /* NSPR's version info */ + + (void)PR_fprintf(err, "Runtime library version information\n"); + PR_ExplodeTime( + version_info->buildTime, PR_GMTParameters, &exploded); + (void)PR_FormatTime( + buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded); + (void)PR_fprintf(err, " Build time: %s GMT\n", buffer); + (void)PR_fprintf( + err, " Build time: %s\n", version_info->buildTimeString); + (void)PR_fprintf( + err, " %s V%u.%u.%u (%s%s%s)\n", + version_info->description, + version_info->vMajor, + version_info->vMinor, + version_info->vPatch, + (version_info->beta ? " beta " : ""), + (version_info->debug ? " debug " : ""), + (version_info->special ? " special" : "")); + (void)PR_fprintf(err, " filename: %s\n", version_info->filename); + (void)PR_fprintf(err, " security: %s\n", version_info->security); + (void)PR_fprintf(err, " copyright: %s\n", version_info->copyright); + (void)PR_fprintf(err, " comment: %s\n", version_info->comment); + rv = 0; + return rv; +} + +/* version.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/writev.c nspr-4.10.7/nspr/pr/tests/writev.c --- nspr-4.9.5/nspr/pr/tests/writev.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/writev.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,197 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nspr.h" + +#include "plgetopt.h" + +#include +#include + + +#ifndef IOV_MAX +#define IOV_MAX 16 +#endif + +#define BASE_PORT 9867 + +int PR_CALLBACK Writev(int argc, char **argv) +{ + + PRStatus rv; + PRNetAddr serverAddr; + PRFileDesc *clientSock, *debug = NULL; + + char *buffer = NULL; + PRIOVec *iov = NULL; + PRBool passed = PR_TRUE; + PRIntervalTime timein, elapsed, timeout; + PRIntervalTime tmo_min = 0x7fffffff, tmo_max = 0, tmo_elapsed = 0; + PRInt32 tmo_counted = 0, iov_index, loop, bytes, number_fragments; + PRInt32 message_length = 100, fragment_length = 100, messages = 100; + struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor; + + /* + * USAGE + * -h dns name of host serving the connection (default = self) + * -m number of messages to send (default = 100) + * -s size of each message (default = 100) + * -f size of each message fragment (default = 100) + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dh:m:s:f:"); + + PR_STDIO_INIT(); + rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddr); + PR_ASSERT(PR_SUCCESS == rv); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'h': /* the remote host */ + { + PRIntn es = 0; + PRHostEnt host; + char buffer[1024]; + (void)PR_GetHostByName(opt->value, buffer, sizeof(buffer), &host); + es = PR_EnumerateHostEnt(es, &host, BASE_PORT, &serverAddr); + PR_ASSERT(es > 0); + } + break; + case 'd': /* debug mode */ + debug = PR_GetSpecialFD(PR_StandardError); + break; + case 'm': /* number of messages to send */ + messages = atoi(opt->value); + break; + case 's': /* total size of each message */ + message_length = atoi(opt->value); + break; + case 'f': /* size of each message fragment */ + fragment_length = atoi(opt->value); + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + buffer = (char*)malloc(message_length); + + number_fragments = (message_length + fragment_length - 1) / fragment_length + 1; + while (IOV_MAX < number_fragments) + { + fragment_length = message_length / (IOV_MAX - 2); + number_fragments = (message_length + fragment_length - 1) / + fragment_length + 1; + if (NULL != debug) PR_fprintf(debug, + "Too many fragments - reset fragment length to %ld\n", fragment_length); + } + iov = (PRIOVec*)malloc(number_fragments * sizeof(PRIOVec)); + + iov[0].iov_base = (char*)&descriptor; + iov[0].iov_len = sizeof(descriptor); + for (iov_index = 1; iov_index < number_fragments; ++iov_index) + { + iov[iov_index].iov_base = buffer + (iov_index - 1) * fragment_length; + iov[iov_index].iov_len = fragment_length; + } + + for (bytes = 0; bytes < message_length; ++bytes) + buffer[bytes] = (char)bytes; + + timeout = PR_SecondsToInterval(1); + + for (loop = 0; loop < messages; ++loop) + { + if (NULL != debug) + PR_fprintf(debug, "[%d]socket ... ", loop); + clientSock = PR_NewTCPSocket(); + if (clientSock) + { + timein = PR_IntervalNow(); + if (NULL != debug) + PR_fprintf(debug, "connecting ... "); + rv = PR_Connect(clientSock, &serverAddr, timeout); + if (PR_SUCCESS == rv) + { + descriptor.checksum = 0; + descriptor.length = (loop < (messages - 1)) ? message_length : 0; + if (0 == descriptor.length) number_fragments = 1; + else + for (iov_index = 0; iov_index < descriptor.length; ++iov_index) + { + PRUint32 overflow = descriptor.checksum & 0x80000000; + descriptor.checksum = (descriptor.checksum << 1); + if (0x00000000 != overflow) descriptor.checksum += 1; + descriptor.checksum += buffer[iov_index]; + } + if (NULL != debug) PR_fprintf( + debug, "sending %d bytes ... ", descriptor.length); + + /* then, at the last moment ... */ + descriptor.length = PR_ntohl(descriptor.length); + descriptor.checksum = PR_ntohl(descriptor.checksum); + + bytes = PR_Writev(clientSock, iov, number_fragments, timeout); + if (NULL != debug) + PR_fprintf(debug, "closing ... "); + rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH); + rv = PR_Close(clientSock); + if (NULL != debug) PR_fprintf( + debug, "%s\n", ((PR_SUCCESS == rv) ? "good" : "bad")); + elapsed = PR_IntervalNow() - timein; + if (elapsed < tmo_min) tmo_min = elapsed; + else if (elapsed > tmo_max) tmo_max = elapsed; + tmo_elapsed += elapsed; + tmo_counted += 1; + } + else + { + if (NULL != debug) PR_fprintf( + debug, "failed - retrying (%d, %d)\n", + PR_GetError(), PR_GetOSError()); + PR_Close(clientSock); + } + } + else if (NULL != debug) + { + PR_fprintf(debug, "unable to create client socket\n"); + passed = PR_FALSE; + } + } + if (NULL != debug) { + if (0 == tmo_counted) { + PR_fprintf(debug, "No connection made\n"); + } else { + PR_fprintf( + debug, "\nTimings: %d [%d] %d (microseconds)\n", + PR_IntervalToMicroseconds(tmo_min), + PR_IntervalToMicroseconds(tmo_elapsed / tmo_counted), + PR_IntervalToMicroseconds(tmo_max)); + } + } + + PR_DELETE(buffer); + PR_DELETE(iov); + + PR_fprintf( + PR_GetSpecialFD(PR_StandardError), + "%s\n", (passed) ? "PASSED" : "FAILED"); + return (passed) ? 0 : 1; +} + +int main(int argc, char **argv) +{ + return (PR_VersionCheck(PR_VERSION)) ? + PR_Initialize(Writev, argc, argv, 4) : -1; +} /* main */ + +/* writev.c */ + + diff -Nru nspr-4.9.5/nspr/pr/tests/xnotify.c nspr-4.10.7/nspr/pr/tests/xnotify.c --- nspr-4.9.5/nspr/pr/tests/xnotify.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/xnotify.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,357 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "plerror.h" +#include "plgetopt.h" + +#include "prinit.h" +#include "prprf.h" +#include "prio.h" +#include "prcvar.h" +#include "prmon.h" +#include "prcmon.h" +#include "prlock.h" +#include "prerror.h" +#include "prinit.h" +#include "prinrval.h" +#include "prthread.h" + +static PRLock *ml = NULL; +static PRIntervalTime base; +static PRFileDesc *err = NULL; + +typedef struct CMonShared +{ + PRInt32 o1, o2; +} CMonShared; + +typedef struct MonShared +{ + PRMonitor *o1, *o2; +} MonShared; + +typedef struct LockShared +{ + PRLock *o1, *o2; + PRCondVar *cv1, *cv2; +} LockShared; + +static void LogNow(const char *msg, PRStatus rv) +{ + PRIntervalTime now = PR_IntervalNow(); + PR_Lock(ml); + PR_fprintf(err, "%6ld: %s", (now - base), msg); + if (PR_FAILURE == rv) PL_FPrintError(err, " "); + else PR_fprintf(err, "\n"); + PR_Unlock(ml); +} /* LogNow */ + +static void Help(void) +{ + PR_fprintf(err, "Usage: [-[d][l][m][c]] [-h]\n"); + PR_fprintf(err, "\t-d debug mode (default: FALSE)\n"); + PR_fprintf(err, "\t-l test with locks (default: FALSE)\n"); + PR_fprintf(err, "\t-m tests with monitors (default: FALSE)\n"); + PR_fprintf(err, "\t-c tests with cmonitors (default: FALSE)\n"); + PR_fprintf(err, "\t-h help\n"); +} /* Help */ + +static void PR_CALLBACK T2CMon(void *arg) +{ + PRStatus rv; + CMonShared *shared = (CMonShared*)arg; + + PR_CEnterMonitor(&shared->o1); + LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS); + rv = PR_CWait(&shared->o1, PR_SecondsToInterval(5)); + if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv); + else LogNow("T2 wait failed on o1", rv); + + rv = PR_CNotify(&shared->o1); + if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv); + else LogNow("T2 notify on o1 failed", rv); + + PR_CExitMonitor(&shared->o1); +} /* T2CMon */ + +static void PR_CALLBACK T3CMon(void *arg) +{ + PRStatus rv; + CMonShared *shared = (CMonShared*)arg; + + PR_CEnterMonitor(&shared->o2); + LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS); + rv = PR_CWait(&shared->o2, PR_SecondsToInterval(5)); + if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv); + else LogNow("T3 wait failed on o2", rv); + rv = PR_CNotify(&shared->o2); + LogNow("T3 notify on o2", rv); + PR_CExitMonitor(&shared->o2); + +} /* T3CMon */ + +static CMonShared sharedCM; + +static void T1CMon(void) +{ + PRStatus rv; + PRThread *t2, *t3; + + PR_fprintf(err, "\n**********************************\n"); + PR_fprintf(err, " CACHED MONITORS\n"); + PR_fprintf(err, "**********************************\n"); + + base = PR_IntervalNow(); + + PR_CEnterMonitor(&sharedCM.o1); + LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS); + rv = PR_CWait(&sharedCM.o1, PR_SecondsToInterval(3)); + if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv); + else LogNow("T1 wait on o1 failed", rv); + PR_CExitMonitor(&sharedCM.o1); + + LogNow("T1 creating T2", PR_SUCCESS); + t2 = PR_CreateThread( + PR_USER_THREAD, T2CMon, &sharedCM, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + + LogNow("T1 creating T3", PR_SUCCESS); + t3 = PR_CreateThread( + PR_USER_THREAD, T3CMon, &sharedCM, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + + PR_CEnterMonitor(&sharedCM.o2); + LogNow("T1 waiting forever on o2", PR_SUCCESS); + rv = PR_CWait(&sharedCM.o2, PR_INTERVAL_NO_TIMEOUT); + if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv); + else LogNow("T1 wait on o2 failed", rv); + PR_CExitMonitor(&sharedCM.o2); + + (void)PR_JoinThread(t2); + (void)PR_JoinThread(t3); + +} /* T1CMon */ + +static void PR_CALLBACK T2Mon(void *arg) +{ + PRStatus rv; + MonShared *shared = (MonShared*)arg; + + PR_EnterMonitor(shared->o1); + LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS); + rv = PR_Wait(shared->o1, PR_SecondsToInterval(5)); + if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv); + else LogNow("T2 wait failed on o1", rv); + + rv = PR_Notify(shared->o1); + if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv); + else LogNow("T2 notify on o1 failed", rv); + + PR_ExitMonitor(shared->o1); +} /* T2Mon */ + +static void PR_CALLBACK T3Mon(void *arg) +{ + PRStatus rv; + MonShared *shared = (MonShared*)arg; + + PR_EnterMonitor(shared->o2); + LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS); + rv = PR_Wait(shared->o2, PR_SecondsToInterval(5)); + if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv); + else LogNow("T3 wait failed on o2", rv); + rv = PR_Notify(shared->o2); + LogNow("T3 notify on o2", rv); + PR_ExitMonitor(shared->o2); + +} /* T3Mon */ + +static MonShared sharedM; +static void T1Mon(void) +{ + PRStatus rv; + PRThread *t2, *t3; + + PR_fprintf(err, "\n**********************************\n"); + PR_fprintf(err, " MONITORS\n"); + PR_fprintf(err, "**********************************\n"); + + sharedM.o1 = PR_NewMonitor(); + sharedM.o2 = PR_NewMonitor(); + + base = PR_IntervalNow(); + + PR_EnterMonitor(sharedM.o1); + LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS); + rv = PR_Wait(sharedM.o1, PR_SecondsToInterval(3)); + if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv); + else LogNow("T1 wait on o1 failed", rv); + PR_ExitMonitor(sharedM.o1); + + LogNow("T1 creating T2", PR_SUCCESS); + t2 = PR_CreateThread( + PR_USER_THREAD, T2Mon, &sharedM, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + + LogNow("T1 creating T3", PR_SUCCESS); + t3 = PR_CreateThread( + PR_USER_THREAD, T3Mon, &sharedM, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + + PR_EnterMonitor(sharedM.o2); + LogNow("T1 waiting forever on o2", PR_SUCCESS); + rv = PR_Wait(sharedM.o2, PR_INTERVAL_NO_TIMEOUT); + if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv); + else LogNow("T1 wait on o2 failed", rv); + PR_ExitMonitor(sharedM.o2); + + (void)PR_JoinThread(t2); + (void)PR_JoinThread(t3); + + PR_DestroyMonitor(sharedM.o1); + PR_DestroyMonitor(sharedM.o2); + +} /* T1Mon */ + +static void PR_CALLBACK T2Lock(void *arg) +{ + PRStatus rv; + LockShared *shared = (LockShared*)arg; + + PR_Lock(shared->o1); + LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS); + rv = PR_WaitCondVar(shared->cv1, PR_SecondsToInterval(5)); + if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv); + else LogNow("T2 wait failed on o1", rv); + + rv = PR_NotifyCondVar(shared->cv1); + if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv); + else LogNow("T2 notify on o1 failed", rv); + + PR_Unlock(shared->o1); +} /* T2Lock */ + +static void PR_CALLBACK T3Lock(void *arg) +{ + PRStatus rv; + LockShared *shared = (LockShared*)arg; + + PR_Lock(shared->o2); + LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS); + rv = PR_WaitCondVar(shared->cv2, PR_SecondsToInterval(5)); + if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv); + else LogNow("T3 wait failed on o2", rv); + rv = PR_NotifyCondVar(shared->cv2); + LogNow("T3 notify on o2", rv); + PR_Unlock(shared->o2); + +} /* T3Lock */ + +/* +** Make shared' a static variable for Win16 +*/ +static LockShared sharedL; + +static void T1Lock(void) +{ + PRStatus rv; + PRThread *t2, *t3; + sharedL.o1 = PR_NewLock(); + sharedL.o2 = PR_NewLock(); + sharedL.cv1 = PR_NewCondVar(sharedL.o1); + sharedL.cv2 = PR_NewCondVar(sharedL.o2); + + PR_fprintf(err, "\n**********************************\n"); + PR_fprintf(err, " LOCKS\n"); + PR_fprintf(err, "**********************************\n"); + + base = PR_IntervalNow(); + + PR_Lock(sharedL.o1); + LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS); + rv = PR_WaitCondVar(sharedL.cv1, PR_SecondsToInterval(3)); + if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv); + else LogNow("T1 wait on o1 failed", rv); + PR_Unlock(sharedL.o1); + + LogNow("T1 creating T2", PR_SUCCESS); + t2 = PR_CreateThread( + PR_USER_THREAD, T2Lock, &sharedL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + + LogNow("T1 creating T3", PR_SUCCESS); + t3 = PR_CreateThread( + PR_USER_THREAD, T3Lock, &sharedL, PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + + PR_Lock(sharedL.o2); + LogNow("T1 waiting forever on o2", PR_SUCCESS); + rv = PR_WaitCondVar(sharedL.cv2, PR_INTERVAL_NO_TIMEOUT); + if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv); + else LogNow("T1 wait on o2 failed", rv); + PR_Unlock(sharedL.o2); + + (void)PR_JoinThread(t2); + (void)PR_JoinThread(t3); + + PR_DestroyLock(sharedL.o1); + PR_DestroyLock(sharedL.o2); + PR_DestroyCondVar(sharedL.cv1); + PR_DestroyCondVar(sharedL.cv2); +} /* T1Lock */ + +static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) +{ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dhlmc"); + PRBool locks = PR_FALSE, monitors = PR_FALSE, cmonitors = PR_FALSE; + + err = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode (noop) */ + break; + case 'l': /* locks */ + locks = PR_TRUE; + break; + case 'm': /* monitors */ + monitors = PR_TRUE; + break; + case 'c': /* cached monitors */ + cmonitors = PR_TRUE; + break; + case 'h': /* needs guidance */ + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + ml = PR_NewLock(); + if (locks) T1Lock(); + if (monitors) T1Mon(); + if (cmonitors) T1CMon(); + + PR_DestroyLock(ml); + + PR_fprintf(err, "Done!\n"); + return 0; +} /* main */ + + +int main(int argc, char **argv) +{ + PRIntn rv; + + PR_STDIO_INIT(); + rv = PR_Initialize(RealMain, argc, argv, 0); + return rv; +} /* main */ +/* xnotify.c */ diff -Nru nspr-4.9.5/nspr/pr/tests/y2k.c nspr-4.10.7/nspr/pr/tests/y2k.c --- nspr-4.9.5/nspr/pr/tests/y2k.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/y2k.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,786 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * file: y2k.c + * description: Test for y2k compliance for NSPR. + * + * Sep 1999. lth. Added "Sun" specified dates to the test data. + */ +/*********************************************************************** +** Includes +***********************************************************************/ +/* Used to get the command line option */ +#include "plgetopt.h" + +#include "prinit.h" +#include "prtime.h" +#include "prprf.h" +#include "prlog.h" + +#include +#include +#include + +#define PRINT_DETAILS + +int failed_already=0; +PRBool debug_mode = PR_FALSE; + +static char *dayOfWeek[] = + { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" }; +static char *month[] = + { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" }; + +PRLogModuleInfo *lm; + +static void PrintExplodedTime(const PRExplodedTime *et) { + PRInt32 totalOffset; + PRInt32 hourOffset, minOffset; + const char *sign; + + /* Print day of the week, month, day, hour, minute, and second */ + printf("%s %s %2ld %02ld:%02ld:%02ld ", + dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday, + et->tm_hour, et->tm_min, et->tm_sec); + + /* Print year */ + printf("%hd ", et->tm_year); + + /* Print time zone */ + totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset; + if (totalOffset == 0) { + printf("UTC "); + } else { + sign = "+"; + if (totalOffset < 0) { + totalOffset = -totalOffset; + sign = "-"; + } + hourOffset = totalOffset / 3600; + minOffset = (totalOffset % 3600) / 60; + printf("%s%02ld%02ld ", sign, hourOffset, minOffset); + } +#ifdef PRINT_DETAILS + printf("{%d, %d, %d, %d, %d, %d, %d, %d, %d, { %d, %d}}\n",et->tm_usec, + et->tm_sec, + et->tm_min, + et->tm_hour, + et->tm_mday, + et->tm_month, + et->tm_year, + et->tm_wday, + et->tm_yday, + et->tm_params.tp_gmt_offset, + et->tm_params.tp_dst_offset); +#endif +} + +static int ExplodedTimeIsEqual(const PRExplodedTime *et1, + const PRExplodedTime *et2) +{ + if (et1->tm_usec == et2->tm_usec && + et1->tm_sec == et2->tm_sec && + et1->tm_min == et2->tm_min && + et1->tm_hour == et2->tm_hour && + et1->tm_mday == et2->tm_mday && + et1->tm_month == et2->tm_month && + et1->tm_year == et2->tm_year && + et1->tm_wday == et2->tm_wday && + et1->tm_yday == et2->tm_yday && + et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset && + et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) { + return 1; + } else { + return 0; + } +} + +/* + * TEST 1: TestExplodeImplodeTime + * Description: + * For each given timestamp T (a PRTime value), call PR_ExplodeTime + * with GMT, US Pacific, and local time parameters. Compare the + * resulting calendar (exploded) time values with the expected + * values. + * + * Note: the expected local time values depend on the local time + * zone. The local time values stored in this test are for the US + * Pacific Time Zone. If you are running this test in a different + * time zone, you need to modify the values in the localt array. + * An example is provided below. + * + * Call PR_ImplodeTime for each of the exploded values and compare + * the resulting PRTime values with the original input. + * + * This test is run for the values of time T corresponding to the + * following dates: + * - 12/31/99 - before 2000 + * - 01/01/00 - after 2000 + * - Leap year - Feb 29, 2000 + * - March 1st, 2001 (after 1 year) + * - March 1st, 2005 (after second leap year) + * - 09/09/99 (used by some programs as an end of file marker) + * + * Call PR_Now, convert to calendar time using PR_ExplodeTime and + * manually check the result for correctness. The time should match + * the system clock. + * + * Tested functions: PR_Now, PR_ExplodeTime, PR_ImplodeTime, + * PR_LocalTimeParameters, PR_GMTParameters. + */ + +static PRTime prt[] = { + LL_INIT(220405, 2133125120), /* 946634400000000 */ + LL_INIT(220425, 2633779200), /* 946720800000000 */ + LL_INIT(221612, 2107598848), /* 951818400000000 */ + LL_INIT(228975, 663398400), /* 983440800000000 */ + LL_INIT(258365, 1974568960), /* 1109671200000000 */ + LL_INIT(218132, 1393788928), /* 936871200000000 */ + /* Sun's dates follow */ + LL_INIT( 213062, 4077979648 ), /* Dec 31 1998 10:00:00 */ + LL_INIT( 218152, 1894443008 ), /* Sep 10 1999 10:00:00 */ + LL_INIT( 221592, 1606944768 ), /* Feb 28 2000 10:00:00 */ + LL_INIT( 227768, 688924672 ), /* Dec 31 2000 10:00:00 */ + LL_INIT( 227788, 1189578752 ), /* Jan 1 2001 10:00:00 */ +}; + +static PRExplodedTime gmt[] = { + { 0, 0, 0, 10, 31, 11, 1999, 5, 364, {0, 0}}, /* 1999/12/31 10:00:00 GMT */ + { 0, 0, 0, 10, 1, 0, 2000, 6, 0, {0, 0}}, /* 2000/01/01 10:00:00 GMT */ + { 0, 0, 0, 10, 29, 1, 2000, 2, 59, {0, 0}}, /* 2000/02/29 10:00:00 GMT */ + { 0, 0, 0, 10, 1, 2, 2001, 4, 59, {0, 0}}, /* 2001/3/1 10:00:00 GMT */ + { 0, 0, 0, 10, 1, 2, 2005, 2, 59, {0, 0}}, /* 2005/3/1 10:00:00 GMT */ + { 0, 0, 0, 10, 9, 8, 1999, 4, 251, {0, 0}}, /* 1999/9/9 10:00:00 GMT */ + /* Sun's dates follow */ + { 0, 0, 0, 10, 31, 11, 1998, 4, 364, {0, 0}}, /* 12/31/1998 10:00:00 GMT */ + { 0, 0, 0, 10, 10, 8, 1999, 5, 252, {0, 0}}, /* 9/10/1999 10:00:00 GMT */ + { 0, 0, 0, 10, 28, 1, 2000, 1, 58, {0, 0}}, /* 2/28/2000 10:00:00 GMT */ + { 0, 0, 0, 10, 31, 11, 2000, 0, 365, {0, 0}}, /* 12/31/2000 10:00:00 GMT */ + { 0, 0, 0, 10, 1, 0, 2001, 1, 0, {0, 0}} /* 1/1/2001 10:00:00 GMT */ +}; + +static PRExplodedTime uspt[] = { +{ 0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST */ +{ 0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */ +{ 0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */ +{ 0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */ +{ 0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */ +{ 0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}}, /* 1999/9/9 3:00:00 PDT */ + /* Sun's dates follow */ + { 0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}}, /* 12/31/1998 00:00:00 GMT */ + { 0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}}, /* 9/10/1999 00:00:00 GMT */ + { 0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}}, /* 2/28/2000 00:00:00 GMT */ + { 0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}}, /* 12/31/2000 00:00:00 GMT */ + { 0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}} /* 1/1/2001 00:00:00 GMT */ +}; + +/* + * This test assumes that we are in US Pacific Time Zone. + * If you are running this test in a different time zone, + * you need to modify the localt array and fill in the + * expected results. The localt array for US Eastern Time + * Zone is provided as an example. + */ +static PRExplodedTime localt[] = { +{ 0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST */ +{ 0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */ +{ 0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */ +{ 0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */ +{ 0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */ +{ 0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}}, /* 1999/9/9 3:00:00 PDT */ + /* Sun's dates follow */ + { 0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}}, /* 12/31/1998 00:00:00 GMT */ + { 0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}}, /* 9/10/1999 00:00:00 GMT */ + { 0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}}, /* 2/28/2000 00:00:00 GMT */ + { 0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}}, /* 12/31/2000 00:00:00 GMT */ + { 0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}} /* 1/1/2001 00:00:00 GMT */ +}; + +#ifdef US_EASTERN_TIME +static PRExplodedTime localt[] = { +{ 0, 0, 0, 5, 31, 11, 1999, 5, 364, {-18000, 0}}, /* 1999/12/31 2:00:00 EST */ +{ 0, 0, 0, 5, 1, 0, 2000, 6, 0, {-18000, 0}}, /* 2000/01/01 2:00:00 EST */ +{ 0, 0, 0, 5, 29, 1, 2000, 2, 59, {-18000, 0}}, /* 2000/02/29 2:00:00 EST */ +{ 0, 0, 0, 5, 1, 2, 2001, 4, 59, {-18000, 0}}, /* 2001/3/1 2:00:00 EST */ +{ 0, 0, 0, 5, 1, 2, 2005, 2, 59, {-18000, 0}}, /* 2005/3/1 2:00:00 EST */ +{ 0, 0, 0, 6, 9, 8, 1999, 4, 251, {-18000, 3600}}, /* 1999/9/9 3:00:00 EDT */ + /* Sun's dates follow */ + { 0, 0, 0, 5, 31, 11, 1998, 4, 364, {-18000 0}}, /* 12/31/1998 00:00:00 GMT */ + { 0, 0, 0, 6, 10, 8, 1999, 5, 252, {-18000 3600}}, /* 9/10/1999 00:00:00 GMT */ + { 0, 0, 0, 5, 28, 1, 2000, 1, 58, {-18000 0}}, /* 2/28/2000 00:00:00 GMT */ + { 0, 0, 0, 5, 31, 11, 2000, 0, 365, {-18000 0}}, /* 12/31/2000 00:00:00 GMT */ + { 0, 0, 0, 5, 1, 0, 2001, 1, 0, {-18000 0}} /* 1/1/2001 00:00:00 GMT */ +}; +#endif + +static PRStatus TestExplodeImplodeTime(void) +{ + PRTime prt_tmp; + PRTime now; + int idx; + int array_size = sizeof(prt) / sizeof(PRTime); + PRExplodedTime et_tmp; + char buf[1024]; + + for (idx = 0; idx < array_size; idx++) { + PR_snprintf(buf, sizeof(buf), "%lld", prt[idx]); + if (debug_mode) printf("Time stamp %s\n", buf); + PR_ExplodeTime(prt[idx], PR_GMTParameters, &et_tmp); + if (!ExplodedTimeIsEqual(&et_tmp, &gmt[idx])) { + fprintf(stderr, "GMT not equal\n"); + PrintExplodedTime(&et_tmp); + PrintExplodedTime(&gmt[idx]); + exit(1); + } + prt_tmp = PR_ImplodeTime(&et_tmp); + if (LL_NE(prt_tmp, prt[idx])) { + fprintf(stderr, "PRTime not equal\n"); + exit(1); + } + if (debug_mode) { + printf("GMT: "); + PrintExplodedTime(&et_tmp); + printf("\n"); + } + + PR_ExplodeTime(prt[idx], PR_USPacificTimeParameters, &et_tmp); + if (!ExplodedTimeIsEqual(&et_tmp, &uspt[idx])) { + fprintf(stderr, "US Pacific Time not equal\n"); + PrintExplodedTime(&et_tmp); + PrintExplodedTime(&uspt[idx]); + exit(1); + } + prt_tmp = PR_ImplodeTime(&et_tmp); + if (LL_NE(prt_tmp, prt[idx])) { + fprintf(stderr, "PRTime not equal\n"); + exit(1); + } + if (debug_mode) { + printf("US Pacific Time: "); + PrintExplodedTime(&et_tmp); + printf("\n"); + } + + PR_ExplodeTime(prt[idx], PR_LocalTimeParameters, &et_tmp); + if (!ExplodedTimeIsEqual(&et_tmp, &localt[idx])) { + fprintf(stderr, "not equal\n"); + PrintExplodedTime(&et_tmp); + PrintExplodedTime(&localt[idx]); + exit(1); + } + prt_tmp = PR_ImplodeTime(&et_tmp); + if (LL_NE(prt_tmp, prt[idx])) { + fprintf(stderr, "not equal\n"); + exit(1); + } + if (debug_mode) { + printf("Local time:"); + PrintExplodedTime(&et_tmp); + printf("\n\n"); + } + } + + now = PR_Now(); + PR_ExplodeTime(now, PR_GMTParameters, &et_tmp); + printf("Current GMT is "); + PrintExplodedTime(&et_tmp); + printf("\n"); + prt_tmp = PR_ImplodeTime(&et_tmp); + if (LL_NE(prt_tmp, now)) { + fprintf(stderr, "not equal\n"); + exit(1); + } + PR_ExplodeTime(now, PR_USPacificTimeParameters, &et_tmp); + printf("Current US Pacific Time is "); + PrintExplodedTime(&et_tmp); + printf("\n"); + prt_tmp = PR_ImplodeTime(&et_tmp); + if (LL_NE(prt_tmp, now)) { + fprintf(stderr, "not equal\n"); + exit(1); + } + PR_ExplodeTime(now, PR_LocalTimeParameters, &et_tmp); + printf("Current local time is "); + PrintExplodedTime(&et_tmp); + printf("\n"); + prt_tmp = PR_ImplodeTime(&et_tmp); + if (LL_NE(prt_tmp, now)) { + fprintf(stderr, "not equal\n"); + exit(1); + } + printf("Please verify the results\n\n"); + + if (debug_mode) printf("Test 1 passed\n"); + return PR_SUCCESS; +} +/* End of Test 1: TestExplodeImplodeTime */ + +/* + * Test 2: Normalize Time + */ + +/* + * time increment for addition to PRExplodeTime + */ +typedef struct time_increment { + PRInt32 ti_usec; + PRInt32 ti_sec; + PRInt32 ti_min; + PRInt32 ti_hour; +} time_increment_t; + +/* + * Data for testing PR_Normalize + * Add the increment to base_time, normalize it to GMT and US Pacific + * Time zone. + */ +typedef struct normalize_test_data { + PRExplodedTime base_time; + time_increment_t increment; + PRExplodedTime expected_gmt_time; + PRExplodedTime expected_uspt_time; +} normalize_test_data_t; + + +/* + * Test data - the base time values cover dates of interest including y2k - 1, + * y2k + 1, y2k leap year, y2k leap date + 1year, + * y2k leap date + 4 years + */ +normalize_test_data_t normalize_test_array[] = { + /*usec sec min hour mday mo year wday yday {gmtoff, dstoff }*/ + + /* Fri 12/31/1999 19:32:48 PST */ + {{0, 48, 32, 19, 31, 11, 1999, 5, 364, { -28800, 0}}, + {0, 0, 30, 20}, + {0, 48, 2, 0, 2, 0, 2000, 0, 1, { 0, 0}}, /*Sun Jan 2 00:02:48 UTC 2000*/ + {0, 48, 2, 16, 1, 0, 2000, 6, 0, { -28800, 0}},/* Sat Jan 1 16:02:48 + PST 2000*/ + }, + /* Fri 99-12-31 23:59:02 GMT */ + {{0, 2, 59, 23, 31, 11, 1999, 5, 364, { 0, 0}}, + {0, 0, 45, 0}, + {0, 2, 44, 0, 1, 0, 2000, 6, 0, { 0, 0}},/* Sat Jan 1 00:44:02 UTC 2000*/ + {0, 2, 44, 16, 31, 11, 1999, 5, 364, { -28800, 0}}/*Fri Dec 31 16:44:02 + PST 1999*/ + }, + /* 99-12-25 12:00:00 GMT */ + {{0, 0, 0, 12, 25, 11, 1999, 6, 358, { 0, 0}}, + {0, 0, 0, 364 * 24}, + {0, 0, 0, 12, 23, 11, 2000, 6, 357, { 0, 0}},/*Sat Dec 23 12:00:00 + 2000 UTC*/ + {0, 0, 0, 4, 23, 11, 2000, 6, 357, { -28800, 0}}/*Sat Dec 23 04:00:00 + 2000 -0800*/ + }, + /* 00-01-1 00:00:00 PST */ + {{0, 0, 0, 0, 1, 0, 2000, 6, 0, { -28800, 0}}, + {0, 0, 0, 48}, + {0, 0, 0, 8, 3, 0, 2000, 1, 2, { 0, 0}},/*Mon Jan 3 08:00:00 2000 UTC*/ + {0, 0, 0, 0, 3, 0, 2000, 1, 2, { -28800, 0}}/*Mon Jan 3 00:00:00 2000 + -0800*/ + }, + /* 00-01-10 12:00:00 PST */ + {{0, 0, 0, 12, 10, 0, 2000, 1, 9, { -28800, 0}}, + {0, 0, 0, 364 * 5 * 24}, + {0, 0, 0, 20, 3, 0, 2005, 1, 2, { 0, 0}},/*Mon Jan 3 20:00:00 2005 UTC */ + {0, 0, 0, 12, 3, 0, 2005, 1, 2, { -28800, 0}}/*Mon Jan 3 12:00:00 + 2005 -0800*/ + }, + /* 00-02-28 15:39 GMT */ + {{0, 0, 39, 15, 28, 1, 2000, 1, 58, { 0, 0}}, + {0, 0, 0, 24}, + {0, 0, 39, 15, 29, 1, 2000, 2, 59, { 0, 0}}, /*Tue Feb 29 15:39:00 2000 + UTC*/ + {0, 0, 39, 7, 29, 1, 2000, 2, 59, { -28800, 0}}/*Tue Feb 29 07:39:00 + 2000 -0800*/ + }, + /* 01-03-01 12:00 PST */ + {{0, 0, 0, 12, 3, 0, 2001, 3, 2, { -28800, 0}},/*Wed Jan 3 12:00:00 + -0800 2001*/ + {0, 30, 30,45}, + {0, 30, 30, 17, 5, 0, 2001, 5, 4, { 0, 0}}, /*Fri Jan 5 17:30:30 2001 + UTC*/ + {0, 30, 30, 9, 5, 0, 2001, 5, 4, { -28800, 0}} /*Fri Jan 5 09:30:30 + 2001 -0800*/ + }, + /* 2004-04-26 12:00 GMT */ + {{0, 0, 0, 20, 3, 0, 2001, 3, 2, { 0, 0}}, + {0, 0, 30,0}, + {0, 0, 30, 20, 3, 0, 2001, 3, 2, { 0, 0}},/*Wed Jan 3 20:30:00 2001 UTC*/ + {0, 0, 30, 12, 3, 0, 2001, 3, 2, { -28800, 0}}/*Wed Jan 3 12:30:00 + 2001 -0800*/ + }, + /* 99-09-09 00:00 GMT */ + {{0, 0, 0, 0, 9, 8, 1999, 4, 251, { 0, 0}}, + {0, 0, 0, 12}, + {0, 0, 0, 12, 9, 8, 1999, 4, 251, { 0, 0}},/*Thu Sep 9 12:00:00 1999 UTC*/ + {0, 0, 0, 5, 9, 8, 1999, 4, 251, { -28800, 3600}}/*Thu Sep 9 05:00:00 + 1999 -0700*/ + } +}; + +void add_time_increment(PRExplodedTime *et1, time_increment_t *it) +{ + et1->tm_usec += it->ti_usec; + et1->tm_sec += it->ti_sec; + et1->tm_min += it->ti_min; + et1->tm_hour += it->ti_hour; +} + +/* +** TestNormalizeTime() -- Test PR_NormalizeTime() +** For each data item, add the time increment to the base_time and then +** normalize it for GMT and local time zones. This test assumes that +** the local time zone is the Pacific Time Zone. The normalized values +** should match the expected values in the data item. +** +*/ +PRStatus TestNormalizeTime(void) +{ +int idx, count; +normalize_test_data_t *itemp; +time_increment_t *itp; + + count = sizeof(normalize_test_array)/sizeof(normalize_test_array[0]); + for (idx = 0; idx < count; idx++) { + itemp = &normalize_test_array[idx]; + if (debug_mode) { + printf("%2d. %15s",idx +1,"Base time: "); + PrintExplodedTime(&itemp->base_time); + printf("\n"); + } + itp = &itemp->increment; + if (debug_mode) { + printf("%20s %2d hrs %2d min %3d sec\n","Add",itp->ti_hour, + itp->ti_min, itp->ti_sec); + } + add_time_increment(&itemp->base_time, &itemp->increment); + PR_NormalizeTime(&itemp->base_time, PR_LocalTimeParameters); + if (debug_mode) { + printf("%19s","PST time: "); + PrintExplodedTime(&itemp->base_time); + printf("\n"); + } + if (!ExplodedTimeIsEqual(&itemp->base_time, + &itemp->expected_uspt_time)) { + printf("PR_NormalizeTime failed\n"); + if (debug_mode) + PrintExplodedTime(&itemp->expected_uspt_time); + return PR_FAILURE; + } + PR_NormalizeTime(&itemp->base_time, PR_GMTParameters); + if (debug_mode) { + printf("%19s","GMT time: "); + PrintExplodedTime(&itemp->base_time); + printf("\n"); + } + + if (!ExplodedTimeIsEqual(&itemp->base_time, + &itemp->expected_gmt_time)) { + printf("PR_NormalizeTime failed\n"); + return PR_FAILURE; + } + } + return PR_SUCCESS; +} + + +/* +** ParseTest. Structure defining a string time and a matching exploded time +** +*/ +typedef struct ParseTest +{ + char *sDate; /* string to be converted using PR_ParseTimeString() */ + PRExplodedTime et; /* expected result of the conversion */ +} ParseTest; + +static ParseTest parseArray[] = +{ + /* |<----- expected result ------------------------------------------->| */ + /* "string to test" usec sec min hour day mo year wday julian {gmtoff, dstoff }*/ + { "Thursday 1 Jan 1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "1 Jan 1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "1-Jan-1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "01-Jan-1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "January 1, 1970", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "January 1, 1970 00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "January 01, 1970 00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "January 01 1970 00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "January 01 1970 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "01-01-1970", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "01/01/1970", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "01/01/70", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "01/01/70 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "70/01/01 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "70/1/1 00:00:", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "00:00 Thursday, January 1, 1970",{ 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "1-Jan-70 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "70-01-01 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + { "70/01/01 00:00:00", { 000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0 }}}, + + /* 31-Dec-1969 */ + { "Wed 31 Dec 1969 00:00:00", { 000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0 }}}, + { "31 Dec 1969 00:00:00", { 000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0 }}}, + { "12/31/69 00:00:00", { 000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0 }}}, + { "12/31/1969 00:00:00", { 000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0 }}}, + { "12-31-69 00:00:00", { 000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0 }}}, + { "12-31-1969 00:00:00", { 000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0 }}}, + { "69-12-31 00:00:00", { 000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0 }}}, + { "69/12/31 00:00:00", { 000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0 }}}, + + /* "Sun". 31-Dec-1998 (?) */ + { "Thu 31 Dec 1998 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, + { "12/31/98 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, + { "12/31/1998 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, + { "12-31-98 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, + { "12-31-1998 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, + { "98-12-31 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, + { "98/12/31 00:00:00", { 00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0 }}}, + + /* 09-Sep-1999. Interesting because of its use as an eof marker? */ + { "09 Sep 1999 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, + { "9/9/99 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, + { "9/9/1999 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, + { "9-9-99 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, + { "9-9-1999 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, + { "09-09-99 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, + { "09-09-1999 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, + { "99-09-09 00:00:00", { 000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600 }}}, + + /* "Sun". 10-Sep-1999. Because Sun said so. */ + { "10 Sep 1999 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, + { "9/10/99 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, + { "9/10/1999 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, + { "9-10-99 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, + { "9-10-1999 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, + { "09-10-99 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, + { "09-10-1999 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, + { "99-09-10 00:00:00", { 000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600 }}}, + + /* 31-Dec-1999 */ + { "31 Dec 1999 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, + { "12/31/99 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, + { "12/31/1999 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, + { "12-31-99 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, + { "12-31-1999 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, + { "99-12-31 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, + { "99/12/31 00:00:00", { 000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0 }}}, + + /* 01-Jan-2000 */ + { "01 Jan 2000 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, + { "1/1/00 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, + { "1/1/2000 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, + { "1-1-00 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, + { "1-1-2000 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, + { "01-01-00 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, + { "Saturday 01-01-2000 00:00:00", { 000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0 }}}, + + /* "Sun". 28-Feb-2000 */ + { "28 Feb 2000 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, + { "2/28/00 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, + { "2/28/2000 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, + { "2-28-00 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, + { "2-28-2000 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, + { "02-28-00 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, + { "02-28-2000 00:00:00", { 000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0 }}}, + + /* 29-Feb-2000 */ + { "29 Feb 2000 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, + { "2/29/00 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, + { "2/29/2000 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, + { "2-29-00 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, + { "2-29-2000 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, + { "02-29-00 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, + { "02-29-2000 00:00:00", { 000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0 }}}, + + /* 01-Mar-2000 */ + { "01 Mar 2000 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, + { "3/1/00 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, + { "3/1/2000 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, + { "3-1-00 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, + { "03-01-00 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, + { "03-01-2000 00:00:00", { 000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0 }}}, + + /* "Sun". 31-Dec-2000 */ + { "31 Dec 2000 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, + { "12/31/00 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, + { "12/31/2000 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, + { "12-31-00 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, + { "12-31-2000 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, + { "00-12-31 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, + { "00/12/31 00:00:00", { 000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0 }}}, + + /* "Sun". 01-Jan-2001 */ + { "01 Jan 2001 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, + { "1/1/01 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, + { "1/1/2001 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, + { "1-1-01 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, + { "1-1-2001 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, + { "01-01-01 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, + { "Saturday 01-01-2001 00:00:00", { 000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0 }}}, + + /* 01-Mar-2001 */ + { "01 Mar 2001 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, + { "3/1/01 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, + { "3/1/2001 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, + { "3-1-01 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, + { "3-1-2001 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, + { "03-01-01 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, + { "03-01-2001 00:00:00", { 000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0 }}}, + + /* 29-Feb-2004 */ + { "29 Feb 2004 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, + { "2/29/04 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, + { "2/29/2004 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, + { "2-29-04 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, + { "2-29-2004 00:00:00", { 000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0 }}}, + + /* 01-Mar-2004 */ + { "01 Mar 2004 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, + { "3/1/04 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, + { "3/1/2004 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, + { "3-1-04 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, + { "3-1-2004 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, + { "03-01-04 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, + { "03-01-2004 00:00:00", { 000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0 }}}, + + /* 01-Mar-2005 */ + { "01 Mar 2005 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, + { "3/1/05 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, + { "3/1/2005 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, + { "3-1-05 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, + { "3-1-2005 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, + { "03-01-05 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, + { "03-01-2005 00:00:00", { 000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0 }}}, + + /* last element. string must be null */ + { NULL } +}; /* end array of ParseTest */ + +/* +** TestParseTime() -- Test PR_ParseTimeString() for y2k compliance +** +** TestParseTime() loops thru the array parseArray. For each element in +** the array, he calls PR_ParseTimeString() with sDate as the conversion +** argument. The result (ct) is then converted to a PRExplodedTime structure +** and compared with the exploded time value (parseArray[n].et) in the +** array element; if equal, the element passes the test. +** +** The array parseArray[] contains entries that are interesting to the +** y2k problem. +** +** +*/ +static PRStatus TestParseTime( void ) +{ + ParseTest *ptp = parseArray; + PRTime ct; + PRExplodedTime cet; + char *sp = ptp->sDate; + PRStatus rc; + PRStatus rv = PR_SUCCESS; + + while ( sp != NULL) + { + rc = PR_ParseTimeString( sp, PR_FALSE, &ct ); + if ( PR_FAILURE == rc ) + { + printf("TestParseTime(): PR_ParseTimeString() failed to convert: %s\n", sp ); + rv = PR_FAILURE; + failed_already = 1; + } + else + { + PR_ExplodeTime( ct, PR_LocalTimeParameters , &cet ); + + if ( !ExplodedTimeIsEqual( &cet, &ptp->et )) + { + printf("TestParseTime(): Exploded time compare failed: %s\n", sp ); + if ( debug_mode ) + { + PrintExplodedTime( &cet ); + printf("\n"); + PrintExplodedTime( &ptp->et ); + printf("\n"); + } + + rv = PR_FAILURE; + failed_already = 1; + } + } + + /* point to next element in array, keep going */ + ptp++; + sp = ptp->sDate; + } /* end while() */ + + return( rv ); +} /* end TestParseTime() */ + +int main(int argc, char** argv) +{ + /* The command line argument: -d is used to determine if the test is being run + in debug mode. The regress tool requires only one line output:PASS or FAIL. + All of the printfs associated with this test has been handled with a if (debug_mode) + test. + Usage: test_name -d + */ + PLOptStatus os; + PLOptState *opt; + + PR_STDIO_INIT(); + opt = PL_CreateOptState(argc, argv, "d"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + /* main test */ + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + lm = PR_NewLogModule("test"); + + if ( PR_FAILURE == TestExplodeImplodeTime()) + { + PR_LOG( lm, PR_LOG_ERROR, + ("TestExplodeImplodeTime() failed")); + } + else + printf("Test 1: Calendar Time Test passed\n"); + + if ( PR_FAILURE == TestNormalizeTime()) + { + PR_LOG( lm, PR_LOG_ERROR, + ("TestNormalizeTime() failed")); + } + else + printf("Test 2: Normalize Time Test passed\n"); + + if ( PR_FAILURE == TestParseTime()) + { + PR_LOG( lm, PR_LOG_ERROR, + ("TestParseTime() failed")); + } + else + printf("Test 3: Parse Time Test passed\n"); + + if (failed_already) + return 1; + else + return 0; +} /* end main() y2k.c */ + diff -Nru nspr-4.9.5/nspr/pr/tests/y2ktmo.c nspr-4.10.7/nspr/pr/tests/y2ktmo.c --- nspr-4.9.5/nspr/pr/tests/y2ktmo.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/y2ktmo.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,550 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Test: y2ktmo + * + * Description: + * This test tests the interval time facilities in NSPR for Y2K + * compliance. All the functions that take a timeout argument + * are tested: PR_Sleep, socket I/O (PR_Accept is taken as a + * representative), PR_Poll, PR_WaitCondVar, PR_Wait, and + * PR_CWait. A thread of each thread scope (local, global, and + * global bound) is created to call each of these functions. + * The test should be started at the specified number of seconds + * (called the lead time) before a Y2K rollover test date. The + * timeout values for these threads will span over the rollover + * date by at least the specified number of seconds. For + * example, if the lead time is 5 seconds, the test should + * be started at time (D - 5), where D is a rollover date, and + * the threads will time out at or after time (D + 5). The + * timeout values for the threads are spaced one second apart. + * + * When a thread times out, it calls PR_IntervalNow() to verify + * that it did wait for the specified time. In addition, it + * calls a platform-native function to verify the actual elapsed + * time again, to rule out the possibility that PR_IntervalNow() + * is broken. We allow the actual elapsed time to deviate from + * the specified timeout by a certain tolerance (in milliseconds). + */ + +#include "nspr.h" +#include "plgetopt.h" + +#include +#include +#include +#if defined(XP_UNIX) +#include /* for gettimeofday */ +#endif +#if defined(WIN32) +#if defined(WINCE) +#include +#else +#include +#include /* for _ftime */ +#endif +#endif + +#define DEFAULT_LEAD_TIME_SECS 5 +#define DEFAULT_TOLERANCE_MSECS 500 + +static PRBool debug_mode = PR_FALSE; +static PRInt32 lead_time_secs = DEFAULT_LEAD_TIME_SECS; +static PRInt32 tolerance_msecs = DEFAULT_TOLERANCE_MSECS; +static PRIntervalTime start_time; +static PRIntervalTime tolerance; + +#if defined(XP_UNIX) +static struct timeval start_time_tv; +#endif +#if defined(WIN32) +#if defined(WINCE) +static DWORD start_time_tick; +#else +static struct _timeb start_time_tb; +#endif +#endif + +static void SleepThread(void *arg) +{ + PRIntervalTime timeout = (PRIntervalTime) arg; + PRIntervalTime elapsed; +#if defined(XP_UNIX) || defined(WIN32) + PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); + PRInt32 elapsed_msecs; +#endif +#if defined(XP_UNIX) + struct timeval end_time_tv; +#endif +#if defined(WIN32) && !defined(WINCE) + struct _timeb end_time_tb; +#endif + + if (PR_Sleep(timeout) == PR_FAILURE) { + fprintf(stderr, "PR_Sleep failed\n"); + exit(1); + } + elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); + if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#if defined(XP_UNIX) + gettimeofday(&end_time_tv, NULL); + elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; +#endif +#if defined(WIN32) +#if defined(WINCE) + elapsed_msecs = GetTickCount() - start_time_tick; +#else + _ftime(&end_time_tb); + elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + + (end_time_tb.millitm - start_time_tb.millitm); +#endif +#endif +#if defined(XP_UNIX) || defined(WIN32) + if (elapsed_msecs + tolerance_msecs < timeout_msecs + || elapsed_msecs > timeout_msecs + tolerance_msecs) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#endif + if (debug_mode) { + fprintf(stderr, "Sleep thread (scope %d) done\n", + PR_GetThreadScope(PR_GetCurrentThread())); + } +} + +static void AcceptThread(void *arg) +{ + PRIntervalTime timeout = (PRIntervalTime) arg; + PRIntervalTime elapsed; +#if defined(XP_UNIX) || defined(WIN32) + PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); + PRInt32 elapsed_msecs; +#endif +#if defined(XP_UNIX) + struct timeval end_time_tv; +#endif +#if defined(WIN32) && !defined(WINCE) + struct _timeb end_time_tb; +#endif + PRFileDesc *sock; + PRNetAddr addr; + PRFileDesc *accepted; + + sock = PR_NewTCPSocket(); + if (sock == NULL) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + memset(&addr, 0, sizeof(addr)); + addr.inet.family = PR_AF_INET; + addr.inet.port = 0; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + if (PR_Bind(sock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + if (PR_Listen(sock, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + accepted = PR_Accept(sock, NULL, timeout); + if (accepted != NULL || PR_GetError() != PR_IO_TIMEOUT_ERROR) { + fprintf(stderr, "PR_Accept did not time out\n"); + exit(1); + } + elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); + if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#if defined(XP_UNIX) + gettimeofday(&end_time_tv, NULL); + elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; +#endif +#if defined(WIN32) +#if defined(WINCE) + elapsed_msecs = GetTickCount() - start_time_tick; +#else + _ftime(&end_time_tb); + elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + + (end_time_tb.millitm - start_time_tb.millitm); +#endif +#endif +#if defined(XP_UNIX) || defined(WIN32) + if (elapsed_msecs + tolerance_msecs < timeout_msecs + || elapsed_msecs > timeout_msecs + tolerance_msecs) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#endif + if (PR_Close(sock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + if (debug_mode) { + fprintf(stderr, "Accept thread (scope %d) done\n", + PR_GetThreadScope(PR_GetCurrentThread())); + } +} + +static void PollThread(void *arg) +{ + PRIntervalTime timeout = (PRIntervalTime) arg; + PRIntervalTime elapsed; +#if defined(XP_UNIX) || defined(WIN32) + PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); + PRInt32 elapsed_msecs; +#endif +#if defined(XP_UNIX) + struct timeval end_time_tv; +#endif +#if defined(WIN32) && !defined(WINCE) + struct _timeb end_time_tb; +#endif + PRFileDesc *sock; + PRNetAddr addr; + PRPollDesc pd; + PRIntn rv; + + sock = PR_NewTCPSocket(); + if (sock == NULL) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + memset(&addr, 0, sizeof(addr)); + addr.inet.family = PR_AF_INET; + addr.inet.port = 0; + addr.inet.ip = PR_htonl(PR_INADDR_ANY); + if (PR_Bind(sock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + if (PR_Listen(sock, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + pd.fd = sock; + pd.in_flags = PR_POLL_READ; + rv = PR_Poll(&pd, 1, timeout); + if (rv != 0) { + fprintf(stderr, "PR_Poll did not time out\n"); + exit(1); + } + elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); + if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#if defined(XP_UNIX) + gettimeofday(&end_time_tv, NULL); + elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; +#endif +#if defined(WIN32) +#if defined(WINCE) + elapsed_msecs = GetTickCount() - start_time_tick; +#else + _ftime(&end_time_tb); + elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + + (end_time_tb.millitm - start_time_tb.millitm); +#endif +#endif +#if defined(XP_UNIX) || defined(WIN32) + if (elapsed_msecs + tolerance_msecs < timeout_msecs + || elapsed_msecs > timeout_msecs + tolerance_msecs) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#endif + if (PR_Close(sock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + if (debug_mode) { + fprintf(stderr, "Poll thread (scope %d) done\n", + PR_GetThreadScope(PR_GetCurrentThread())); + } +} + +static void WaitCondVarThread(void *arg) +{ + PRIntervalTime timeout = (PRIntervalTime) arg; + PRIntervalTime elapsed; +#if defined(XP_UNIX) || defined(WIN32) + PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); + PRInt32 elapsed_msecs; +#endif +#if defined(XP_UNIX) + struct timeval end_time_tv; +#endif +#if defined(WIN32) && !defined(WINCE) + struct _timeb end_time_tb; +#endif + PRLock *ml; + PRCondVar *cv; + + ml = PR_NewLock(); + if (ml == NULL) { + fprintf(stderr, "PR_NewLock failed\n"); + exit(1); + } + cv = PR_NewCondVar(ml); + if (cv == NULL) { + fprintf(stderr, "PR_NewCondVar failed\n"); + exit(1); + } + PR_Lock(ml); + PR_WaitCondVar(cv, timeout); + PR_Unlock(ml); + elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); + if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#if defined(XP_UNIX) + gettimeofday(&end_time_tv, NULL); + elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; +#endif +#if defined(WIN32) +#if defined(WINCE) + elapsed_msecs = GetTickCount() - start_time_tick; +#else + _ftime(&end_time_tb); + elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + + (end_time_tb.millitm - start_time_tb.millitm); +#endif +#endif +#if defined(XP_UNIX) || defined(WIN32) + if (elapsed_msecs + tolerance_msecs < timeout_msecs + || elapsed_msecs > timeout_msecs + tolerance_msecs) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#endif + PR_DestroyCondVar(cv); + PR_DestroyLock(ml); + if (debug_mode) { + fprintf(stderr, "wait cond var thread (scope %d) done\n", + PR_GetThreadScope(PR_GetCurrentThread())); + } +} + +static void WaitMonitorThread(void *arg) +{ + PRIntervalTime timeout = (PRIntervalTime) arg; + PRIntervalTime elapsed; +#if defined(XP_UNIX) || defined(WIN32) + PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); + PRInt32 elapsed_msecs; +#endif +#if defined(XP_UNIX) + struct timeval end_time_tv; +#endif +#if defined(WIN32) && !defined(WINCE) + struct _timeb end_time_tb; +#endif + PRMonitor *mon; + + mon = PR_NewMonitor(); + if (mon == NULL) { + fprintf(stderr, "PR_NewMonitor failed\n"); + exit(1); + } + PR_EnterMonitor(mon); + PR_Wait(mon, timeout); + PR_ExitMonitor(mon); + elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); + if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#if defined(XP_UNIX) + gettimeofday(&end_time_tv, NULL); + elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; +#endif +#if defined(WIN32) +#if defined(WINCE) + elapsed_msecs = GetTickCount() - start_time_tick; +#else + _ftime(&end_time_tb); + elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + + (end_time_tb.millitm - start_time_tb.millitm); +#endif +#endif +#if defined(XP_UNIX) || defined(WIN32) + if (elapsed_msecs + tolerance_msecs < timeout_msecs + || elapsed_msecs > timeout_msecs + tolerance_msecs) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#endif + PR_DestroyMonitor(mon); + if (debug_mode) { + fprintf(stderr, "wait monitor thread (scope %d) done\n", + PR_GetThreadScope(PR_GetCurrentThread())); + } +} + +static void WaitCMonitorThread(void *arg) +{ + PRIntervalTime timeout = (PRIntervalTime) arg; + PRIntervalTime elapsed; +#if defined(XP_UNIX) || defined(WIN32) + PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout); + PRInt32 elapsed_msecs; +#endif +#if defined(XP_UNIX) + struct timeval end_time_tv; +#endif +#if defined(WIN32) && !defined(WINCE) + struct _timeb end_time_tb; +#endif + int dummy; + + PR_CEnterMonitor(&dummy); + PR_CWait(&dummy, timeout); + PR_CExitMonitor(&dummy); + elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time); + if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#if defined(XP_UNIX) + gettimeofday(&end_time_tv, NULL); + elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec) + + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000; +#endif +#if defined(WIN32) +#if defined(WINCE) + elapsed_msecs = GetTickCount() - start_time_tick; +#else + _ftime(&end_time_tb); + elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time) + + (end_time_tb.millitm - start_time_tb.millitm); +#endif +#endif +#if defined(XP_UNIX) || defined(WIN32) + if (elapsed_msecs + tolerance_msecs < timeout_msecs + || elapsed_msecs > timeout_msecs + tolerance_msecs) { + fprintf(stderr, "timeout wrong\n"); + exit(1); + } +#endif + if (debug_mode) { + fprintf(stderr, "wait cached monitor thread (scope %d) done\n", + PR_GetThreadScope(PR_GetCurrentThread())); + } +} + +typedef void (*NSPRThreadFunc)(void*); + +static NSPRThreadFunc threadFuncs[] = { + SleepThread, AcceptThread, PollThread, + WaitCondVarThread, WaitMonitorThread, WaitCMonitorThread}; + +static PRThreadScope threadScopes[] = { + PR_LOCAL_THREAD, PR_GLOBAL_THREAD, PR_GLOBAL_BOUND_THREAD}; + +static void Help(void) +{ + fprintf(stderr, "y2ktmo test program usage:\n"); + fprintf(stderr, "\t-d debug mode (FALSE)\n"); + fprintf(stderr, "\t-l lead time (%d)\n", + DEFAULT_LEAD_TIME_SECS); + fprintf(stderr, "\t-t tolerance (%d)\n", + DEFAULT_TOLERANCE_MSECS); + fprintf(stderr, "\t-h this message\n"); +} /* Help */ + +int main(int argc, char **argv) +{ + PRThread **threads; + int num_thread_funcs = sizeof(threadFuncs)/sizeof(NSPRThreadFunc); + int num_thread_scopes = sizeof(threadScopes)/sizeof(PRThreadScope); + int i, j; + int idx; + PRInt32 secs; + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "dl:t:h"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { + if (PL_OPT_BAD == os) continue; + switch (opt->option) { + case 'd': /* debug mode */ + debug_mode = PR_TRUE; + break; + case 'l': /* lead time */ + lead_time_secs = atoi(opt->value); + break; + case 't': /* tolerance */ + tolerance_msecs = atoi(opt->value); + break; + case 'h': + default: + Help(); + return 2; + } + } + PL_DestroyOptState(opt); + + if (debug_mode) { + fprintf(stderr, "lead time: %d secs\n", lead_time_secs); + fprintf(stderr, "tolerance: %d msecs\n", tolerance_msecs); + } + + start_time = PR_IntervalNow(); +#if defined(XP_UNIX) + gettimeofday(&start_time_tv, NULL); +#endif +#if defined(WIN32) +#ifdef WINCE + start_time_tick = GetTickCount(); +#else + _ftime(&start_time_tb); +#endif +#endif + tolerance = PR_MillisecondsToInterval(tolerance_msecs); + + threads = PR_Malloc( + num_thread_scopes * num_thread_funcs * sizeof(PRThread*)); + if (threads == NULL) { + fprintf(stderr, "PR_Malloc failed\n"); + exit(1); + } + + /* start to time out 5 seconds after a rollover date */ + secs = lead_time_secs + 5; + idx = 0; + for (i = 0; i < num_thread_scopes; i++) { + for (j = 0; j < num_thread_funcs; j++) { + threads[idx] = PR_CreateThread(PR_USER_THREAD, threadFuncs[j], + (void*)PR_SecondsToInterval(secs), PR_PRIORITY_NORMAL, + threadScopes[i], PR_JOINABLE_THREAD, 0); + if (threads[idx] == NULL) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + secs++; + idx++; + } + } + for (idx = 0; idx < num_thread_scopes*num_thread_funcs; idx++) { + if (PR_JoinThread(threads[idx]) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + } + PR_Free(threads); + printf("PASS\n"); + return 0; +} diff -Nru nspr-4.9.5/nspr/pr/tests/yield.c nspr-4.10.7/nspr/pr/tests/yield.c --- nspr-4.9.5/nspr/pr/tests/yield.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/pr/tests/yield.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include "prthread.h" +#include "prinit.h" +#ifndef XP_OS2 +#include "private/pprmisc.h" +#include +#else +#include "primpl.h" +#include +#endif + +#define THREADS 10 + + +void +threadmain(void *_id) +{ + int id = (int)_id; + int index; + + printf("thread %d alive\n", id); + for (index=0; index<10; index++) { + printf("thread %d yielding\n", id); + PR_Sleep(0); + printf("thread %d awake\n", id); + } + printf("thread %d dead\n", id); + +} + +int main(int argc, char **argv) +{ + int index; + PRThread *a[THREADS]; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 5); + PR_STDIO_INIT(); + + for (index=0; index + +int main(int argc, char **argv) +{ + printf("PASS\n"); + return 0; +} + +#else /* XP_UNIX */ + +#include "nspr.h" +#include "private/pprio.h" + +#include +#include +#include +#include +#include + +static void ClientThread(void *arg) +{ + PRFileDesc *sock; + PRNetAddr addr; + PRUint16 port = (PRUint16) arg; + char buf[1024]; + PRInt32 nbytes; + + sock = PR_NewTCPSocket(); + if (NULL == sock) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_InitializeNetAddr failed\n"); + exit(1); + } + if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + fprintf(stderr, "PR_Connect failed\n"); + exit(1); + } + /* + * Sleep 5 seconds to force the server thread to get EAGAIN. + */ + if (PR_Sleep(PR_SecondsToInterval(5)) == PR_FAILURE) { + fprintf(stderr, "PR_Sleep failed\n"); + exit(1); + } + /* + * Then start reading. + */ + while ((nbytes = PR_Read(sock, buf, sizeof(buf))) > 0) { + /* empty loop body */ + } + if (-1 == nbytes) { + fprintf(stderr, "PR_Read failed\n"); + exit(1); + } + if (PR_Close(sock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } +} + +int main() +{ + PRFileDesc *listenSock; + PRFileDesc *acceptSock; + int osfd; + PRThread *clientThread; + PRNetAddr addr; + char buf[1024]; + PRInt32 nbytes; + PRIOVec iov; +#ifdef SYMBIAN + int loopcount=0; +#endif + + memset(buf, 0, sizeof(buf)); /* Initialize the buffer. */ + listenSock = PR_NewTCPSocket(); + if (NULL == listenSock) { + fprintf(stderr, "PR_NewTCPSocket failed\n"); + exit(1); + } + if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_InitializeNetAddr failed\n"); + exit(1); + } + if (PR_Bind(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + /* Find out what port number we are bound to. */ + if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_GetSockName failed\n"); + exit(1); + } + if (PR_Listen(listenSock, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + + /* + * First test PR_Writev. + */ + clientThread = PR_CreateThread(PR_USER_THREAD, + ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)), + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (NULL == clientThread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } + acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (NULL == acceptSock) { + fprintf(stderr, "PR_Accept failed\n"); + exit(1); + } + osfd = PR_FileDesc2NativeHandle(acceptSock); + while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) { + /* empty loop body */ +#ifdef SYMBIAN + if (loopcount++>64) break; +#endif + } + if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) { + fprintf(stderr, "write failed\n"); + exit(1); + } + iov.iov_base = buf; + iov.iov_len = 0; + printf("calling PR_Writev with a zero-length buffer\n"); + fflush(stdout); + nbytes = PR_Writev(acceptSock, &iov, 1, PR_INTERVAL_NO_TIMEOUT); + if (nbytes != 0) { + fprintf(stderr, "PR_Writev should return 0 but returns %d\n", nbytes); + exit(1); + } + if (PR_Close(acceptSock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + if (PR_JoinThread(clientThread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + + /* + * Then test PR_Write. + */ + clientThread = PR_CreateThread(PR_USER_THREAD, + ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)), + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (NULL == clientThread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } +#ifdef SYMBIAN + loopcount = 0; +#endif + acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (NULL == acceptSock) { + fprintf(stderr, "PR_Accept failed\n"); + exit(1); + } + osfd = PR_FileDesc2NativeHandle(acceptSock); + while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) { + /* empty loop body */ +#ifdef SYMBIAN + if (loopcount++>64) break; +#endif + } + if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) { + fprintf(stderr, "write failed\n"); + exit(1); + } + printf("calling PR_Write with a zero-length buffer\n"); + fflush(stdout); + nbytes = PR_Write(acceptSock, buf, 0); + if (nbytes != 0) { + fprintf(stderr, "PR_Write should return 0 but returns %d\n", nbytes); + exit(1); + } + if (PR_Close(acceptSock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + if (PR_JoinThread(clientThread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + + /* + * Finally test PR_Send. + */ + clientThread = PR_CreateThread(PR_USER_THREAD, + ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)), + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (NULL == clientThread) { + fprintf(stderr, "PR_CreateThread failed\n"); + exit(1); + } +#ifdef SYMBIAN + loopcount = 0; +#endif + acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + if (NULL == acceptSock) { + fprintf(stderr, "PR_Accept failed\n"); + exit(1); + } + osfd = PR_FileDesc2NativeHandle(acceptSock); + while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) { + /* empty loop body */ +#ifdef SYMBIAN + if (loopcount++>64) break; +#endif + } + if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) { + fprintf(stderr, "write failed\n"); + exit(1); + } + printf("calling PR_Send with a zero-length buffer\n"); + fflush(stdout); + nbytes = PR_Send(acceptSock, buf, 0, 0, PR_INTERVAL_NO_TIMEOUT); + if (nbytes != 0) { + fprintf(stderr, "PR_Send should return 0 but returns %d\n", nbytes); + exit(1); + } + if (PR_Close(acceptSock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + if (PR_JoinThread(clientThread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + + if (PR_Close(listenSock) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + printf("PASS\n"); + return 0; +} + +#endif /* XP_UNIX */ diff -Nru nspr-4.9.5/nspr/tools/.cvsignore nspr-4.10.7/nspr/tools/.cvsignore --- nspr-4.9.5/nspr/tools/.cvsignore 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/tools/.cvsignore 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1 @@ +Makefile diff -Nru nspr-4.9.5/nspr/tools/httpget.c nspr-4.10.7/nspr/tools/httpget.c --- nspr-4.9.5/nspr/tools/httpget.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/tools/httpget.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,433 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/* + * Author: Wan-Teh Chang + * + * Given an HTTP URL, httpget uses the GET method to fetch the file. + * The fetched file is written to stdout by default, or can be + * saved in an output file. + * + * This is a single-threaded program. + */ + +#include "prio.h" +#include "prnetdb.h" +#include "prlog.h" +#include "prerror.h" +#include "prprf.h" +#include "prinit.h" + +#include +#include +#include /* for atoi */ + +#define FCOPY_BUFFER_SIZE (16 * 1024) +#define INPUT_BUFFER_SIZE 1024 +#define LINE_SIZE 512 +#define HOST_SIZE 256 +#define PORT_SIZE 32 +#define PATH_SIZE 512 + +/* + * A buffer for storing the excess input data for ReadLine. + * The data in the buffer starts from (including) the element pointed to + * by inputHead, and ends just before (not including) the element pointed + * to by inputTail. The buffer is empty if inputHead == inputTail. + */ + +static char inputBuf[INPUT_BUFFER_SIZE]; +/* + * inputBufEnd points just past the end of inputBuf + */ +static char *inputBufEnd = inputBuf + sizeof(inputBuf); +static char *inputHead = inputBuf; +static char *inputTail = inputBuf; + +static PRBool endOfStream = PR_FALSE; + +/* + * ReadLine -- + * + * Read in a line of text, terminated by CRLF or LF, from fd into buf. + * The terminating CRLF or LF is included (always as '\n'). The text + * in buf is terminated by a null byte. The excess bytes are stored in + * inputBuf for use in the next ReadLine call or FetchFile call. + * Returns the number of bytes in buf. 0 means end of stream. Returns + * -1 if read fails. + */ + +PRInt32 ReadLine(PRFileDesc *fd, char *buf, PRUint32 bufSize) +{ + char *dst = buf; + char *bufEnd = buf + bufSize; /* just past the end of buf */ + PRBool lineFound = PR_FALSE; + char *crPtr = NULL; /* points to the CR ('\r') character */ + PRInt32 nRead; + +loop: + PR_ASSERT(inputBuf <= inputHead && inputHead <= inputTail + && inputTail <= inputBufEnd); + while (lineFound == PR_FALSE && inputHead != inputTail + && dst < bufEnd - 1) { + if (*inputHead == '\r') { + crPtr = dst; + } else if (*inputHead == '\n') { + lineFound = PR_TRUE; + if (crPtr == dst - 1) { + dst--; + } + } + *(dst++) = *(inputHead++); + } + if (lineFound == PR_TRUE || dst == bufEnd - 1 || endOfStream == PR_TRUE) { + *dst = '\0'; + return dst - buf; + } + + /* + * The input buffer should be empty now + */ + PR_ASSERT(inputHead == inputTail); + + nRead = PR_Read(fd, inputBuf, sizeof(inputBuf)); + if (nRead == -1) { + *dst = '\0'; + return -1; + } else if (nRead == 0) { + endOfStream = PR_TRUE; + *dst = '\0'; + return dst - buf; + } + inputHead = inputBuf; + inputTail = inputBuf + nRead; + goto loop; +} + +PRInt32 DrainInputBuffer(char *buf, PRUint32 bufSize) +{ + PRInt32 nBytes = inputTail - inputHead; + + if (nBytes == 0) { + if (endOfStream) { + return -1; + } else { + return 0; + } + } + if ((PRInt32) bufSize < nBytes) { + nBytes = bufSize; + } + memcpy(buf, inputHead, nBytes); + inputHead += nBytes; + return nBytes; +} + +PRStatus FetchFile(PRFileDesc *in, PRFileDesc *out) +{ + char buf[FCOPY_BUFFER_SIZE]; + PRInt32 nBytes; + + while ((nBytes = DrainInputBuffer(buf, sizeof(buf))) > 0) { + if (PR_Write(out, buf, nBytes) != nBytes) { + fprintf(stderr, "httpget: cannot write to file\n"); + return PR_FAILURE; + } + } + if (nBytes < 0) { + /* Input buffer is empty and end of stream */ + return PR_SUCCESS; + } + while ((nBytes = PR_Read(in, buf, sizeof(buf))) > 0) { + if (PR_Write(out, buf, nBytes) != nBytes) { + fprintf(stderr, "httpget: cannot write to file\n"); + return PR_FAILURE; + } + } + if (nBytes < 0) { + fprintf(stderr, "httpget: cannot read from socket\n"); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PRStatus FastFetchFile(PRFileDesc *in, PRFileDesc *out, PRUint32 size) +{ + PRInt32 nBytes; + PRFileMap *outfMap; + void *addr; + char *start; + PRUint32 rem; + PRUint32 bytesToRead; + PRStatus rv; + PRInt64 sz64; + + LL_UI2L(sz64, size); + outfMap = PR_CreateFileMap(out, sz64, PR_PROT_READWRITE); + PR_ASSERT(outfMap); + addr = PR_MemMap(outfMap, LL_ZERO, size); + if (addr == NULL) { + fprintf(stderr, "cannot memory-map file: (%d, %d)\n", PR_GetError(), + PR_GetOSError()); + + PR_CloseFileMap(outfMap); + return PR_FAILURE; + } + start = (char *) addr; + rem = size; + while ((nBytes = DrainInputBuffer(start, rem)) > 0) { + start += nBytes; + rem -= nBytes; + } + if (nBytes < 0) { + /* Input buffer is empty and end of stream */ + return PR_SUCCESS; + } + bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE; + while (rem > 0 && (nBytes = PR_Read(in, start, bytesToRead)) > 0) { + start += nBytes; + rem -= nBytes; + bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE; + } + if (nBytes < 0) { + fprintf(stderr, "httpget: cannot read from socket\n"); + return PR_FAILURE; + } + rv = PR_MemUnmap(addr, size); + PR_ASSERT(rv == PR_SUCCESS); + rv = PR_CloseFileMap(outfMap); + PR_ASSERT(rv == PR_SUCCESS); + return PR_SUCCESS; +} + +PRStatus ParseURL(char *url, char *host, PRUint32 hostSize, + char *port, PRUint32 portSize, char *path, PRUint32 pathSize) +{ + char *start, *end; + char *dst; + char *hostEnd; + char *portEnd; + char *pathEnd; + + if (strncmp(url, "http", 4)) { + fprintf(stderr, "httpget: the protocol must be http\n"); + return PR_FAILURE; + } + if (strncmp(url + 4, "://", 3) || url[7] == '\0') { + fprintf(stderr, "httpget: malformed URL: %s\n", url); + return PR_FAILURE; + } + + start = end = url + 7; + dst = host; + hostEnd = host + hostSize; + while (*end && *end != ':' && *end != '/') { + if (dst == hostEnd - 1) { + fprintf(stderr, "httpget: host name too long\n"); + return PR_FAILURE; + } + *(dst++) = *(end++); + } + *dst = '\0'; + + if (*end == '\0') { + PR_snprintf(port, portSize, "%d", 80); + PR_snprintf(path, pathSize, "%s", "/"); + return PR_SUCCESS; + } + + if (*end == ':') { + end++; + dst = port; + portEnd = port + portSize; + while (*end && *end != '/') { + if (dst == portEnd - 1) { + fprintf(stderr, "httpget: port number too long\n"); + return PR_FAILURE; + } + *(dst++) = *(end++); + } + *dst = '\0'; + if (*end == '\0') { + PR_snprintf(path, pathSize, "%s", "/"); + return PR_SUCCESS; + } + } else { + PR_snprintf(port, portSize, "%d", 80); + } + + dst = path; + pathEnd = path + pathSize; + while (*end) { + if (dst == pathEnd - 1) { + fprintf(stderr, "httpget: file pathname too long\n"); + return PR_FAILURE; + } + *(dst++) = *(end++); + } + *dst = '\0'; + return PR_SUCCESS; +} + +void PrintUsage(void) { + fprintf(stderr, "usage: httpget url\n" + " httpget -o outputfile url\n" + " httpget url -o outputfile\n"); +} + +int main(int argc, char **argv) +{ + PRHostEnt hostentry; + char buf[PR_NETDB_BUF_SIZE]; + PRNetAddr addr; + PRFileDesc *socket = NULL, *file = NULL; + PRIntn cmdSize; + char host[HOST_SIZE]; + char port[PORT_SIZE]; + char path[PATH_SIZE]; + char line[LINE_SIZE]; + int exitStatus = 0; + PRBool endOfHeader = PR_FALSE; + char *url; + char *fileName = NULL; + PRUint32 fileSize; + + if (argc != 2 && argc != 4) { + PrintUsage(); + exit(1); + } + + if (argc == 2) { + /* + * case 1: httpget url + */ + url = argv[1]; + } else { + if (strcmp(argv[1], "-o") == 0) { + /* + * case 2: httpget -o outputfile url + */ + fileName = argv[2]; + url = argv[3]; + } else { + /* + * case 3: httpget url -o outputfile + */ + url = argv[1]; + if (strcmp(argv[2], "-o") != 0) { + PrintUsage(); + exit(1); + } + fileName = argv[3]; + } + } + + if (ParseURL(url, host, sizeof(host), port, sizeof(port), + path, sizeof(path)) == PR_FAILURE) { + exit(1); + } + + if (PR_GetHostByName(host, buf, sizeof(buf), &hostentry) + == PR_FAILURE) { + fprintf(stderr, "httpget: unknown host name: %s\n", host); + exit(1); + } + + addr.inet.family = PR_AF_INET; + addr.inet.port = PR_htons((short) atoi(port)); + addr.inet.ip = *((PRUint32 *) hostentry.h_addr_list[0]); + + socket = PR_NewTCPSocket(); + if (socket == NULL) { + fprintf(stderr, "httpget: cannot create new tcp socket\n"); + exit(1); + } + + if (PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + fprintf(stderr, "httpget: cannot connect to http server\n"); + exitStatus = 1; + goto done; + } + + if (fileName == NULL) { + file = PR_STDOUT; + } else { + file = PR_Open(fileName, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, + 00777); + if (file == NULL) { + fprintf(stderr, "httpget: cannot open file %s: (%d, %d)\n", + fileName, PR_GetError(), PR_GetOSError()); + exitStatus = 1; + goto done; + } + } + + cmdSize = PR_snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n", path); + PR_ASSERT(cmdSize == (PRIntn) strlen("GET HTTP/1.0\r\n\r\n") + + (PRIntn) strlen(path)); + if (PR_Write(socket, buf, cmdSize) != cmdSize) { + fprintf(stderr, "httpget: cannot write to http server\n"); + exitStatus = 1; + goto done; + } + + if (ReadLine(socket, line, sizeof(line)) <= 0) { + fprintf(stderr, "httpget: cannot read line from http server\n"); + exitStatus = 1; + goto done; + } + + /* HTTP response: 200 == OK */ + if (strstr(line, "200") == NULL) { + fprintf(stderr, "httpget: %s\n", line); + exitStatus = 1; + goto done; + } + + while (ReadLine(socket, line, sizeof(line)) > 0) { + if (line[0] == '\n') { + endOfHeader = PR_TRUE; + break; + } + if (strncmp(line, "Content-Length", 14) == 0 + || strncmp(line, "Content-length", 14) == 0) { + char *p = line + 14; + + while (*p == ' ' || *p == '\t') { + p++; + } + if (*p != ':') { + continue; + } + p++; + while (*p == ' ' || *p == '\t') { + p++; + } + fileSize = 0; + while ('0' <= *p && *p <= '9') { + fileSize = 10 * fileSize + (*p - '0'); + p++; + } + } + } + if (endOfHeader == PR_FALSE) { + fprintf(stderr, "httpget: cannot read line from http server\n"); + exitStatus = 1; + goto done; + } + + if (fileName == NULL || fileSize == 0) { + FetchFile(socket, file); + } else { + FastFetchFile(socket, file, fileSize); + } + +done: + if (socket) PR_Close(socket); + if (file) PR_Close(file); + PR_Cleanup(); + return exitStatus; +} diff -Nru nspr-4.9.5/nspr/tools/Makefile.in nspr-4.10.7/nspr/tools/Makefile.in --- nspr-4.9.5/nspr/tools/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/tools/Makefile.in 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,184 @@ +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#! gmake + +MOD_DEPTH = .. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(MOD_DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/config.mk + +ifeq ($(OS_TARGET), WIN16) +OS_CFLAGS = $(OS_EXE_CFLAGS) +endif + + +DIRS = + +CSRCS = \ + httpget.c \ + tail.c \ + $(NULL) + +ifeq (,$(filter-out WINNT OS2,$(OS_ARCH))) +PROG_SUFFIX = .exe +else +PROG_SUFFIX = +endif + +PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX))) + +TARGETS = $(PROGS) + +INCLUDES = -I$(dist_includedir) + +NSPR_VERSION = 3 + +# Setting the variables LDOPTS and LIBPR. We first initialize +# them to the default values, then adjust them for some platforms. +LDOPTS = -L$(dist_libdir) +LIBPR = -lnspr$(NSPR_VERSION) +LIBPLC = -lplc$(NSPR_VERSION) + +ifeq ($(OS_ARCH), WINNT) +ifeq ($(OS_TARGET), WIN16) + LIBPR = $(dist_libdir)/nspr$(NSPR_VERSION).lib + LIBPLC= $(dist_libdir)/plc$(NSPR_VERSION).lib +else +LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO +LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).$(LIB_SUFFIX) +LIBPLC= $(dist_libdir)/libplc$(NSPR_VERSION).$(LIB_SUFFIX) +endif +endif + +ifeq ($(OS_ARCH),OS2) +LDOPTS += -Zomf -Zlinker /PM:VIO +endif + +ifneq ($(OS_ARCH), WINNT) +PWD = $(shell pwd) +endif + +ifeq ($(OS_ARCH), IRIX) +LDOPTS += -rpath $(PWD)/$(dist_libdir) +endif + +ifeq ($(OS_ARCH), OSF1) +LDOPTS += -rpath $(PWD)/$(dist_libdir) -lpthread +endif + +ifeq ($(OS_ARCH), HP-UX) +LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir) +endif + +# AIX +ifeq ($(OS_ARCH),AIX) +LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib +LIBPR = -lnspr$(NSPR_VERSION)_shr +LIBPLC = -lplc$(NSPR_VERSION)_shr +endif + +# Solaris +ifeq ($(OS_ARCH), SunOS) +ifdef NS_USE_GCC +LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir) +else +LDOPTS += -R $(PWD)/$(dist_libdir) +endif + +# SunOS 5.5 needs to link with -lpthread, even though we already +# linked with this system library when we built libnspr.so. +ifeq ($(OS_RELEASE), 5.5) +ifdef USE_PTHREADS +EXTRA_LIBS = -lpthread +endif +endif +endif # SunOS + +ifeq ($(OS_ARCH), SCOOS) +# SCO Unix needs to link against -lsocket again even though we +# already linked with these system libraries when we built libnspr.so. +EXTRA_LIBS = -lsocket +# This hardcodes in the executable programs the directory to find +# libnspr.so etc. at program startup. Equivalent to the -R or -rpath +# option for ld on other platforms. +export LD_RUN_PATH = $(PWD)/$(dist_libdir) +endif + +##################################################### +# +# The rules +# +##################################################### + +include $(topsrcdir)/config/rules.mk + +AIX_PRE_4_2 = 0 +ifeq ($(OS_ARCH),AIX) +ifneq ($(OS_RELEASE),4.2) +ifneq ($(USE_PTHREADS), 1) +#AIX_PRE_4_2 = 1 +endif +endif +endif + +ifeq ($(AIX_PRE_4_2),1) + +# AIX releases prior to 4.2 need a special two-step linking hack +# in order to both override the system select() and be able to +# get at the original system select(). +# +# We use a pattern rule in ns/nspr20/config/rules.mk to generate +# the .$(OBJ_SUFFIX) file from the .c source file, then do the +# two-step linking hack below. + +$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) + rm -f $@ $(AIX_TMP) + $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(NSPR_VERSION).a + $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP) + rm -f $(AIX_TMP) + +else + +# All platforms that are not AIX pre-4.2. + +$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH), WINNT) +ifeq ($(OS_TARGET),WIN16) + echo system windows >w16link + echo option map >>w16link + echo option stack=10K >>w16link + echo option heapsize=32K >>w16link + echo debug $(DEBUGTYPE) all >>w16link + echo name $@ >>w16link + echo file >>w16link + echo $< >>w16link + echo library >>w16link + echo $(LIBPR), >>w16link + echo $(LIBPLC), >>w16link + echo winsock.lib >>w16link + wlink @w16link. +else + link $(LDOPTS) $< $(LIBPR) $(LIBPLC) ws2_32.lib -out:$@ +endif +else +ifeq ($(OS_ARCH),OS2) + $(LINK) $(LDOPTS) $< $(LIBPR) $(LIBPLC) $(OS_LIBS) $(EXTRA_LIBS) -o $@ +else + $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPLC) $(EXTRA_LIBS) -o $@ +endif +endif +endif + +export:: $(TARGETS) +clean:: + rm -f $(TARGETS) + diff -Nru nspr-4.9.5/nspr/tools/tail.c nspr-4.10.7/nspr/tools/tail.c --- nspr-4.9.5/nspr/tools/tail.c 1970-01-01 00:00:00.000000000 +0000 +++ nspr-4.10.7/nspr/tools/tail.c 2014-08-12 15:40:57.000000000 +0000 @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "prio.h" +#include "prprf.h" +#include "prinit.h" +#include "prthread.h" +#include "prinrval.h" + +#include "plerror.h" +#include "plgetopt.h" + +#include + +#define BUFFER_SIZE 500 + +static PRFileDesc *out = NULL, *err = NULL; + +static void Help(void) +{ + PR_fprintf(err, "Usage: tail [-n ] [-f] [-h] \n"); + PR_fprintf(err, "\t-t Dally time in milliseconds\n"); + PR_fprintf(err, "\t-n Number of bytes before \n"); + PR_fprintf(err, "\t-f Follow the \n"); + PR_fprintf(err, "\t-h This message and nothing else\n"); +} /* Help */ + +PRIntn main(PRIntn argc, char **argv) +{ + PRIntn rv = 0; + PLOptStatus os; + PRStatus status; + PRFileDesc *file; + PRFileInfo fileInfo; + PRIntervalTime dally; + char buffer[BUFFER_SIZE]; + PRBool follow = PR_FALSE; + const char *filename = NULL; + PRUint32 position = 0, seek = 0, time = 0; + PLOptState *opt = PL_CreateOptState(argc, argv, "hfn:"); + + out = PR_GetSpecialFD(PR_StandardOutput); + err = PR_GetSpecialFD(PR_StandardError); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 0: /* it's the filename */ + filename = opt->value; + break; + case 'n': /* bytes before end of file */ + seek = atoi(opt->value); + break; + case 't': /* dally time */ + time = atoi(opt->value); + break; + case 'f': /* follow the end of file */ + follow = PR_TRUE; + break; + case 'h': /* user wants some guidance */ + Help(); /* so give him an earful */ + return 2; /* but not a lot else */ + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + if (0 == time) time = 1000; + dally = PR_MillisecondsToInterval(time); + + if (NULL == filename) + { + (void)PR_fprintf(out, "Input file not specified\n"); + rv = 1; goto done; + } + file = PR_Open(filename, PR_RDONLY, 0); + if (NULL == file) + { + PL_FPrintError(err, "File cannot be opened for reading"); + return 1; + } + + status = PR_GetOpenFileInfo(file, &fileInfo); + if (PR_FAILURE == status) + { + PL_FPrintError(err, "Cannot acquire status of file"); + rv = 1; goto done; + } + if (seek > 0) + { + if (seek > fileInfo.size) seek = 0; + position = PR_Seek(file, (fileInfo.size - seek), PR_SEEK_SET); + if (-1 == (PRInt32)position) + PL_FPrintError(err, "Cannot seek to starting position"); + } + + do + { + while (position < fileInfo.size) + { + PRInt32 read, bytes = fileInfo.size - position; + if (bytes > sizeof(buffer)) bytes = sizeof(buffer); + read = PR_Read(file, buffer, bytes); + if (read != bytes) + PL_FPrintError(err, "Cannot read to eof"); + position += read; + PR_Write(out, buffer, read); + } + + if (follow) + { + PR_Sleep(dally); + status = PR_GetOpenFileInfo(file, &fileInfo); + if (PR_FAILURE == status) + { + PL_FPrintError(err, "Cannot acquire status of file"); + rv = 1; goto done; + } + } + } while (follow); + +done: + PR_Close(file); + + return rv; +} /* main */ + +/* tail.c */